diff --git a/package.json b/package.json index 1a83788e..7ee5a010 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@solana/wallet-adapter-react-ui": "^0.2.0", "@solana/wallet-adapter-wallets": "^0.8.0", "@solana/web3.js": "^1.26.0", + "axios": "^0.21.4", "next": "11.1.2", "patch-package": "^6.4.7", "postinstall-postinstall": "^2.1.0", diff --git a/src/hooks/use-candy-machine.ts b/src/hooks/use-candy-machine.ts index 35cd20a8..ec23b0e7 100644 --- a/src/hooks/use-candy-machine.ts +++ b/src/hooks/use-candy-machine.ts @@ -27,8 +27,13 @@ export default function useCandyMachine() { const [, setBalance] = useWalletBalance() const [candyMachine, setCandyMachine] = useState(); const wallet = useWallet(); - const [isMinting, setIsMinting] = useState(false); // true when user got to press MINT - const [isSoldOut, setIsSoldOut] = useState(false); // true when items remaining is zero + const [nftsData, setNftsData] = useState({} = { + itemsRemaining: 0, + itemsRedeemed: 0, + itemsAvailable: 0 + } as any); + const [isMinting, setIsMinting] = useState(false); + const [isSoldOut, setIsSoldOut] = useState(false); const [mintStartDate, setMintStartDate] = useState(new Date(parseInt(process.env.NEXT_PUBLIC_CANDY_START_DATE!, 10))); useEffect(() => { @@ -61,6 +66,27 @@ export default function useCandyMachine() { })(); }, [wallet, candyMachineId, connection]); + useEffect(() => { + (async () => { + if (!isMinting) { + const anchorWallet = { + publicKey: wallet.publicKey, + signAllTransactions: wallet.signAllTransactions, + signTransaction: wallet.signTransaction, + } as anchor.Wallet; + + const { itemsRemaining, itemsRedeemed, itemsAvailable } = + await getCandyMachineState( + anchorWallet, + candyMachineId, + connection + ); + + setNftsData({ itemsRemaining, itemsRedeemed, itemsAvailable }); + } + })(); + }, [wallet, candyMachineId, connection, isMinting]); + const onMint = async () => { try { setIsMinting(true); @@ -81,7 +107,7 @@ export default function useCandyMachine() { ); if (!status?.err) { - toast.success("Congratulations! Mint succeeded!") + toast.success("Congratulations! Mint succeeded! Check on your wallet :)") } else { toast.error("Mint failed! Please try again!") } @@ -114,5 +140,5 @@ export default function useCandyMachine() { }; - return { isSoldOut, mintStartDate, isMinting, onMint } + return { isSoldOut, mintStartDate, isMinting, nftsData, onMint } } \ No newline at end of file diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 8d3e9cbd..64b7045e 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -18,7 +18,7 @@ const Home = () => { const [isActive, setIsActive] = useState(false); // true when countdown completes const wallet = useWallet(); - const { isSoldOut, mintStartDate, isMinting, onMint } = useCandyMachine() + const { isSoldOut, mintStartDate, isMinting, onMint, nftsData } = useCandyMachine() return (
@@ -34,7 +34,10 @@ const Home = () => { } {wallet.connected && -

Balance: {(balance || 0).toLocaleString()} SOL

+ <> +

Balance: {(balance || 0).toLocaleString()} SOL

+

Available/Minted/Total: {nftsData.itemsRemaining}/{nftsData.itemsRedeemed}/{nftsData.itemsAvailable}

+ }
@@ -60,7 +63,7 @@ const Home = () => {
- +
); diff --git a/src/utils/candy-machine.ts b/src/utils/candy-machine.ts index 2be550f1..87bcd51a 100644 --- a/src/utils/candy-machine.ts +++ b/src/utils/candy-machine.ts @@ -5,7 +5,9 @@ import { TOKEN_PROGRAM_ID, Token, } from "@solana/spl-token"; -import { LAMPORTS_PER_SOL } from "@solana/web3.js"; +import { Metadata } from '../libs/metaplex/index.esm'; +import axios from "axios"; + export const CANDY_MACHINE_PROGRAM = new anchor.web3.PublicKey( "cndyAnrLdpjq1Ssp1z8xxDsB8dxe7u4HL5Nxi2K5WXZ" ); @@ -117,11 +119,11 @@ export const awaitTransactionSignatureConfirmation = async ( connection.removeSignatureListener(subId); } done = true; - console.log("Returning status", status); + console.log("Returning status ", status); return status; } -/* export */ const createAssociatedTokenAccountInstruction = ( +const createAssociatedTokenAccountInstruction = ( associatedTokenAddress: anchor.web3.PublicKey, payer: anchor.web3.PublicKey, walletAddress: anchor.web3.PublicKey, @@ -231,6 +233,35 @@ const getTokenWallet = async ( )[0]; }; +export async function getNftsForOwner(connection: anchor.web3.Connection, ownerAddress: anchor.web3.PublicKey) { + const allTokens = [] + const tokenAccounts = await connection.getParsedTokenAccountsByOwner(ownerAddress, { + programId: TOKEN_PROGRAM_ID + }); + + for (let index = 0; index < tokenAccounts.value.length; index++) { + const tokenAccount = tokenAccounts.value[index]; + const tokenAmount = tokenAccount.account.data.parsed.info.tokenAmount; + + if (tokenAmount.amount == "1" && tokenAmount.decimals == "0") { + + let [pda] = await anchor.web3.PublicKey.findProgramAddress([ + Buffer.from("metadata"), + TOKEN_METADATA_PROGRAM_ID.toBuffer(), + (new anchor.web3.PublicKey(tokenAccount.account.data.parsed.info.mint)).toBuffer(), + ], TOKEN_METADATA_PROGRAM_ID); + const accountInfo = await connection.getParsedAccountInfo(pda); + + const metadata: any = new Metadata(ownerAddress.toString(), accountInfo.value); + + const { data } = await axios.get(metadata.data.data.uri) + allTokens.push(data) + } + } + + return allTokens +} + export const mintOneToken = async ( candyMachine: CandyMachine, config: anchor.web3.PublicKey, @@ -242,7 +273,6 @@ export const mintOneToken = async ( const { connection, program } = candyMachine; const metadata = await getMetadata(mint.publicKey); const masterEdition = await getMasterEdition(mint.publicKey); - const rent = await connection.getMinimumBalanceForRentExemption( MintLayout.span ); diff --git a/yarn.lock b/yarn.lock index 70fc011e..2ef0dfcb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -932,7 +932,7 @@ axios@^0.18.0: follow-redirects "1.5.10" is-buffer "^2.0.2" -axios@^0.21.0: +axios@^0.21.0, axios@^0.21.4: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==