diff --git a/nft/2-dapp/README.md b/nft/2-dapp/README.md index 0eee25c..e0be026 100644 --- a/nft/2-dapp/README.md +++ b/nft/2-dapp/README.md @@ -2,7 +2,7 @@ ## Getting Started -Frontend of our [NFT dApp](https://docs.aelf.dev/quick-start/developers/nft-dapp/#step-4---interact-with-deployed-multi-token-smart-contract). +Frontend of our [NFT dApp](https://docs.aelf.com/quick-start/developers/nft-dapp/#step-4---interact-with-deployed-multi-token-smart-contract). ## Pre-requisites @@ -20,7 +20,7 @@ git clone https://github.com/AElfProject/aelf-samples.git 2. Navigate to the project directory: ```bash -cd aelf-samples/nft-dapp-tutorials +cd aelf-samples/nft/2-dapp ``` 3. Install the necessary dependencies & libraries diff --git a/nft/2-dapp/src/hooks/useNFTSmartContract.ts b/nft/2-dapp/src/hooks/useNFTSmartContract.ts index 70f3174..8839bac 100644 --- a/nft/2-dapp/src/hooks/useNFTSmartContract.ts +++ b/nft/2-dapp/src/hooks/useNFTSmartContract.ts @@ -1,7 +1,6 @@ import { IPortkeyProvider, IChain } from "@portkey/provider-types"; import { useEffect, useState } from "react"; - -type IContract = ReturnType; +import { IContract } from "@/lib/types"; // Custom Hook for interacting with NFT Smart Contracts const useNFTSmartContract = (provider: IPortkeyProvider | null) => { @@ -9,15 +8,11 @@ const useNFTSmartContract = (provider: IPortkeyProvider | null) => { const [mainChainSmartContract, setMainChainSmartContract] = useState>(); const [sideChainSmartContract, setSideChainSmartContract] = useState>(); - //Step A - Function to fetch a smart contract based on chain symbol and contract address - const fetchContract = async () => { - - }; +//Step A - Function to fetch a smart contract based on the chain symbol and the contract address +const fetchContract = async () => {}; - // Step B - Effect hook to initialize and fetch the smart contracts when the provider changes - useEffect(() => { - - }, []); // Dependency array ensures this runs when the provider changes +// Step B - Effect hook to initialize and fetch the smart contracts when the provider changes +useEffect(() => {}, []); // Dependency array ensures this runs when the provider changes // Return the smart contract instances return { diff --git a/nft/2-dapp/src/lib/commonFunctions.ts b/nft/2-dapp/src/lib/commonFunctions.ts index 00001af..53a1403 100644 --- a/nft/2-dapp/src/lib/commonFunctions.ts +++ b/nft/2-dapp/src/lib/commonFunctions.ts @@ -1,3 +1,5 @@ +import { IContract } from "@/lib/types"; + interface Nft { nftSymbol: string; balance?: number; // Adding an optional balance property for clarity diff --git a/nft/2-dapp/src/lib/types.ts b/nft/2-dapp/src/lib/types.ts new file mode 100644 index 0000000..acc2e42 --- /dev/null +++ b/nft/2-dapp/src/lib/types.ts @@ -0,0 +1,3 @@ +import { IChain } from "@portkey/provider-types"; + +export type IContract = ReturnType; diff --git a/nft/2-dapp/src/lib/utils.tsx b/nft/2-dapp/src/lib/utils.tsx index 9ea5b40..d515482 100644 --- a/nft/2-dapp/src/lib/utils.tsx +++ b/nft/2-dapp/src/lib/utils.tsx @@ -1,5 +1,5 @@ import { type ClassValue, clsx } from "clsx"; -import { toast } from "react-toastify"; +import { Id, toast } from "react-toastify"; import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { @@ -19,3 +19,20 @@ export const CustomToast = ({ title, message }: any) => (

{message}

); + +export const handleError = (loadingId: Id, error: unknown) => { + if (error instanceof Error) { + toast.update(loadingId, { + render: error.message, + type: "error", + isLoading: false, + }); + } else { + toast.update(loadingId, { + render: "An unexpected error occurred.", + type: "error", + isLoading: false, + }); + } + removeNotification(loadingId); +}; \ No newline at end of file diff --git a/nft/2-dapp/src/pages/create-nft/index.tsx b/nft/2-dapp/src/pages/create-nft/index.tsx index c8c14bd..360bb8c 100644 --- a/nft/2-dapp/src/pages/create-nft/index.tsx +++ b/nft/2-dapp/src/pages/create-nft/index.tsx @@ -5,7 +5,7 @@ import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; // @ts-ignore import AElf from "aelf-sdk"; import { Buffer } from "buffer"; -import { toast } from "react-toastify"; +import { Id, toast } from "react-toastify"; import { IPortkeyProvider } from "@portkey/provider-types"; import { zodResolver } from "@hookform/resolvers/zod"; @@ -23,8 +23,14 @@ import { Button } from "@/components/ui/button"; import useNFTSmartContract from "@/hooks/useNFTSmartContract"; import "./create-nft.scss"; -import { CustomToast, delay, removeNotification } from "@/lib/utils"; +import { + CustomToast, + delay, + handleError, + removeNotification, +} from "@/lib/utils"; import { InfoIcon } from "@/components/ui/icons"; +import { IWalletInfo } from "aelf-sdk/types/wallet"; const formSchema = z.object({ tokenName: z.string(), @@ -53,7 +59,7 @@ interface INftParams { interface INftValidateResult { parentChainHeight: string | number; signedTx: string; - merklePath: { merklePathNodes: any }; + merklePath: { merklePathNodes: { hash: string; isLeftChildNode: boolean }[] }; } const wallet = AElf.wallet.getWalletByPrivateKey( @@ -66,7 +72,8 @@ const CreateNftPage = ({ currentWalletAddress: string; }) => { const [provider, setProvider] = useState(null); - const { mainChainSmartContract, sideChainSmartContract } = useNFTSmartContract(provider); + const { mainChainSmartContract, sideChainSmartContract } = + useNFTSmartContract(provider); const [transactionStatus, setTransactionStatus] = useState(false); const [isNftCollectionCreated, setIsNftCollectionCreated] = useState(false); @@ -113,7 +120,7 @@ const CreateNftPage = ({ const form = useForm>(); // Get Token Contract - const getTokenContract = async (aelf: any, wallet: any) => { + const getTokenContract = async (aelf: AElf, wallet: IWalletInfo) => { const tokenContractName = "AElf.ContractNames.Token"; // get chain status const chainStatus = await aelf.chain.getChainStatus(); @@ -134,9 +141,9 @@ const CreateNftPage = ({ }; // Get CrossChain Contract - const getCrossChainContract = async (aelf:any, wallet: any) => { + const getCrossChainContract = async (aelf: AElf, wallet: IWalletInfo) => { const crossChainContractName = "AElf.ContractNames.CrossChain"; - + // get chain status const chainStatus = await aelf.chain.getChainStatus(); // get genesis contract address @@ -151,7 +158,7 @@ const CreateNftPage = ({ await zeroContract.GetContractAddressByName.call( AElf.utils.sha256(crossChainContractName) ); - + return await aelf.chain.contractAt(crossChainContractAddress, wallet); }; @@ -166,27 +173,24 @@ const CreateNftPage = ({ // Step 3: Get the parent chain height const GetParentChainHeight = async () => {}; - // step 4 - Fetch the Merkle path by Transaction Id - const getMerklePathByTxId = async (aelf: any, txId: string) => {}; + // step 4 - Fetch the merkle path by transaction Id + const getMerklePathByTxId = async () => {}; - // step 5 - Create a Collection on SideChain + // step 5 - Create a collection on the dAppChain const createCollectionOnSideChain = async () => {}; - //============== Create NFT Token Steps =================// - // step 6 - Create a Collection on SideChain + // step 6 - Create an NFT on the mainchain const createNFTOnMainChain = async () => {}; // step 7 - Validate a NFT Token on MainChain - const validateNftToken = async () => { - }; + const validateNftToken = async () => {}; - // step 8 - Create a NFT on SideChain. - const createNftTokenOnSideChain = async () => { - }; + // step 8 - Create a NFT on dAppChain. + const createNftTokenOnSideChain = async () => {}; - // step 9 - Issue a NFT Function which has been Created on SideChain + // step 9 - Issue a NFT Function which has been Created on dAppChain const issueNftOnSideChain = async () => {}; // step 10 - Call Necessary Function for Create NFT @@ -195,8 +199,7 @@ const CreateNftPage = ({ //============== Handle Submit Form =================// // Step 11 - Handle Submit Form - const onSubmit = async (values: z.infer) => { - }; + const onSubmit = async () => {}; return (
@@ -229,7 +232,9 @@ const CreateNftPage = ({ name="symbol" render={({ field }) => ( - Symbol + + Symbol + diff --git a/nft/2-dapp/src/pages/home/index.tsx b/nft/2-dapp/src/pages/home/index.tsx index 838eeea..0690ed6 100644 --- a/nft/2-dapp/src/pages/home/index.tsx +++ b/nft/2-dapp/src/pages/home/index.tsx @@ -8,6 +8,7 @@ import { NFT_IMAGES } from "@/lib/constant"; import { Button } from "@/components/ui/button"; import useNFTSmartContract from "@/hooks/useNFTSmartContract"; import { fetchUserNftData } from "@/lib/commonFunctions"; +import { IContract } from "@/lib/types"; const HomePage = ({ provider, diff --git a/nft/2-dapp/src/pages/profile/index.tsx b/nft/2-dapp/src/pages/profile/index.tsx index c3e577c..d305fa8 100644 --- a/nft/2-dapp/src/pages/profile/index.tsx +++ b/nft/2-dapp/src/pages/profile/index.tsx @@ -8,6 +8,7 @@ import { NFT_IMAGES } from "@/lib/constant"; import { toast } from "react-toastify"; import { CopyIcon } from "@/components/ui/icons"; import { fetchUserNftData } from "@/lib/commonFunctions"; +import { IContract } from "@/lib/types"; const ProfilePage = ({ provider, diff --git a/nft/2-dapp/src/pages/transfer-nft/index.tsx b/nft/2-dapp/src/pages/transfer-nft/index.tsx index 1c3a720..5c356e7 100644 --- a/nft/2-dapp/src/pages/transfer-nft/index.tsx +++ b/nft/2-dapp/src/pages/transfer-nft/index.tsx @@ -17,7 +17,7 @@ import "./transfer-nft.scss"; import { Button } from "@/components/ui/button"; import { NFT_IMAGES } from "@/lib/constant"; import useNFTSmartContract from "@/hooks/useNFTSmartContract"; -import { delay, removeNotification } from "@/lib/utils"; +import { delay, handleError, removeNotification } from "@/lib/utils"; import { zodResolver } from "@hookform/resolvers/zod"; const formSchema = z.object({