From 24aba92e6087055045dab309e4a95b2f5f1f5f8c Mon Sep 17 00:00:00 2001 From: Maxwell Fortney Date: Sat, 23 Oct 2021 23:18:23 -0400 Subject: [PATCH] Fixes type issues and incorrect error messaging --- hooks/useCandyMachine.tsx | 8 +- hooks/useHashTable.ts | 118 ++++--- utils/candyMachine.ts | 727 +++++++++++++++++++------------------- 3 files changed, 434 insertions(+), 419 deletions(-) diff --git a/hooks/useCandyMachine.tsx b/hooks/useCandyMachine.tsx index f4e77f69..6c015e11 100644 --- a/hooks/useCandyMachine.tsx +++ b/hooks/useCandyMachine.tsx @@ -128,8 +128,8 @@ export default function useCandyMachine() { } } } catch (error: any) { - let message = error.msg || "Minting failed! Please try again!"; - if (!error.msg) { + let message = error.message || "Minting failed! Please try again!"; + if (!error.message) { if (error.message.indexOf("0x138")) { } else if (error.message.indexOf("0x137")) { message = `SOLD OUT!`; @@ -233,8 +233,8 @@ export default function useCandyMachine() { } } } catch (error: any) { - let message = error.msg || "Minting failed! Please try again!"; - if (!error.msg) { + let message = error.message || "Minting failed! Please try again!"; + if (!error.message) { if (error.message.indexOf("0x138")) { } else if (error.message.indexOf("0x137")) { message = `SOLD OUT!`; diff --git a/hooks/useHashTable.ts b/hooks/useHashTable.ts index 78fb512a..883fb159 100644 --- a/hooks/useHashTable.ts +++ b/hooks/useHashTable.ts @@ -11,73 +11,75 @@ export const MAX_SYMBOL_LENGTH = 10; export const MAX_CREATOR_LEN = 32 + 1 + 1; export async function fetchHashTable( - hash: string, - metadataEnabled?: boolean + hash: string, + metadataEnabled?: boolean ): Promise { - const metadataAccounts = await MetadataProgram.getProgramAccounts( - connection, - { - filters: [ + const metadataAccounts = await MetadataProgram.getProgramAccounts( + connection, { - memcmp: { - offset: - 1 + - 32 + - 32 + - 4 + - MAX_NAME_LENGTH + - 4 + - MAX_URI_LENGTH + - 4 + - MAX_SYMBOL_LENGTH + - 2 + - 1 + - 4 + - 0 * MAX_CREATOR_LEN, - bytes: hash, - }, - }, - ], - } - ); + filters: [ + { + memcmp: { + offset: + 1 + + 32 + + 32 + + 4 + + MAX_NAME_LENGTH + + 4 + + MAX_URI_LENGTH + + 4 + + MAX_SYMBOL_LENGTH + + 2 + + 1 + + 4 + + 0 * MAX_CREATOR_LEN, + bytes: hash, + }, + }, + ], + } + ); - const mintHashes: any = []; + const mintHashes: any = []; - for (let index = 0; index < metadataAccounts.length; index++) { - const account = metadataAccounts[index]; - const accountInfo = await connection.getParsedAccountInfo(account.pubkey); - const metadata: any = new Metadata(hash.toString(), accountInfo.value); - if (metadataEnabled) mintHashes.push(metadata.data); - else mintHashes.push(metadata.data.mint); - } + for (let index = 0; index < metadataAccounts.length; index++) { + const account = metadataAccounts[index]; + const accountInfo: any = await connection.getParsedAccountInfo( + account.pubkey + ); + const metadata: any = new Metadata(hash.toString(), accountInfo.value); + if (metadataEnabled) mintHashes.push(metadata.data); + else mintHashes.push(metadata.data.mint); + } - return mintHashes; + return mintHashes; } export function useHashTable(candyMachineId: string, metadataEnabled: boolean) { - const [hashTable, setHashTable] = useState([]); - const [isLoading, setIsLoading] = useState(false); + const [hashTable, setHashTable] = useState([]); + const [isLoading, setIsLoading] = useState(false); - const getHashTable = async () => { - if (!candyMachineId || !candyMachineId.length) { - toast.error("Please type the Candy Machine ID in the input box."); + const getHashTable = async () => { + if (!candyMachineId || !candyMachineId.length) { + toast.error("Please type the Candy Machine ID in the input box."); - return; - } - try { - setIsLoading(true); - const data = await fetchHashTable(candyMachineId, metadataEnabled); - setHashTable(data); - if (data.length === 0) - toast.success( - "Zero mint hashes have been found so far for this candy machine." - ); - } catch (error) { - console.error(error); - toast.error("An error happened! Please try again later!"); - } - setIsLoading(false); - }; + return; + } + try { + setIsLoading(true); + const data = await fetchHashTable(candyMachineId, metadataEnabled); + setHashTable(data); + if (data.length === 0) + toast.success( + "Zero mint hashes have been found so far for this candy machine." + ); + } catch (error) { + console.error(error); + toast.error("An error happened! Please try again later!"); + } + setIsLoading(false); + }; - return { hashTable, isLoading, getHashTable }; + return { hashTable, isLoading, getHashTable }; } diff --git a/utils/candyMachine.ts b/utils/candyMachine.ts index 25cf8af0..05c769f3 100644 --- a/utils/candyMachine.ts +++ b/utils/candyMachine.ts @@ -6,431 +6,444 @@ import { sendTransactions, sleep } from "."; import { fetchHashTable } from "../hooks/useHashTable"; export const CANDY_MACHINE_PROGRAM = new anchor.web3.PublicKey( - "cndyAnrLdpjq1Ssp1z8xxDsB8dxe7u4HL5Nxi2K5WXZ" + "cndyAnrLdpjq1Ssp1z8xxDsB8dxe7u4HL5Nxi2K5WXZ" ); const SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = new anchor.web3.PublicKey( - "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" ); const TOKEN_METADATA_PROGRAM_ID = new anchor.web3.PublicKey( - "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" + "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" ); export interface CandyMachine { - id: anchor.web3.PublicKey; - connection: anchor.web3.Connection; - program: anchor.Program; + id: anchor.web3.PublicKey; + connection: anchor.web3.Connection; + program: anchor.Program; } interface CandyMachineState { - candyMachine: CandyMachine; - itemsAvailable: number; - itemsRedeemed: number; - itemsRemaining: number; - goLiveDate: Date; + candyMachine: CandyMachine; + itemsAvailable: number; + itemsRedeemed: number; + itemsRemaining: number; + goLiveDate: Date; } export const awaitTransactionSignatureConfirmation = async ( - txid: anchor.web3.TransactionSignature, - timeout: number, - connection: anchor.web3.Connection, - commitment: anchor.web3.Commitment = "recent", - queryStatus = false + txid: anchor.web3.TransactionSignature, + timeout: number, + connection: anchor.web3.Connection, + commitment: anchor.web3.Commitment = "recent", + queryStatus = false ): Promise => { - let done = false; - let status: anchor.web3.SignatureStatus | null | void = { - slot: 0, - confirmations: 0, - err: null, - }; - let subId = 0; - status = await new Promise(async (resolve, reject) => { - setTimeout(() => { - if (done) { - return; - } - done = true; - console.log("Rejecting for timeout..."); - reject({ timeout: true }); - }, timeout); - try { - subId = connection.onSignature( - txid, - (result: any, context: any) => { - done = true; - status = { - err: result.err, - slot: context.slot, - confirmations: 0, - }; - if (result.err) { - console.log("Rejected via websocket", result.err); - reject(status); - } else { - console.log("Resolved via websocket", result); - resolve(status); - } - }, - commitment - ); - } catch (e) { - done = true; - console.error("WS error in setup", txid, e); - } - while (!done && queryStatus) { - (async () => { - try { - const signatureStatuses = await connection.getSignatureStatuses([ - txid, - ]); - status = signatureStatuses && signatureStatuses.value[0]; - if (!done) { - if (!status) { - console.log("REST null result for", txid, status); - } else if (status.err) { - console.log("REST error for", txid, status); - done = true; - reject(status.err); - } else if (!status.confirmations) { - console.log("REST no confirmations for", txid, status); - } else { - console.log("REST confirmation for", txid, status); - done = true; - resolve(status); + let done = false; + let status: anchor.web3.SignatureStatus | null | void = { + slot: 0, + confirmations: 0, + err: null, + }; + let subId = 0; + status = await new Promise(async (resolve, reject) => { + setTimeout(() => { + if (done) { + return; } - } + done = true; + console.log("Rejecting for timeout..."); + reject({ timeout: true }); + }, timeout); + try { + subId = connection.onSignature( + txid, + (result: any, context: any) => { + done = true; + status = { + err: result.err, + slot: context.slot, + confirmations: 0, + }; + if (result.err) { + console.log("Rejected via websocket", result.err); + reject(status); + } else { + console.log("Resolved via websocket", result); + resolve(status); + } + }, + commitment + ); } catch (e) { - if (!done) { - console.log("REST connection error: txid", txid, e); - } + done = true; + console.error("WS error in setup", txid, e); } - })(); - await sleep(2000); - } - }); + while (!done && queryStatus) { + (async () => { + try { + const signatureStatuses = + await connection.getSignatureStatuses([txid]); + status = signatureStatuses && signatureStatuses.value[0]; + if (!done) { + if (!status) { + console.log("REST null result for", txid, status); + } else if (status.err) { + console.log("REST error for", txid, status); + done = true; + reject(status.err); + } else if (!status.confirmations) { + console.log( + "REST no confirmations for", + txid, + status + ); + } else { + console.log("REST confirmation for", txid, status); + done = true; + resolve(status); + } + } + } catch (e) { + if (!done) { + console.log("REST connection error: txid", txid, e); + } + } + })(); + await sleep(2000); + } + }); - //@ts-ignore - if (connection._signatureSubscriptions[subId]) { - connection.removeSignatureListener(subId); - } - done = true; - console.log("Returning status", status); - return status; + //@ts-ignore + if (connection._signatureSubscriptions[subId]) { + connection.removeSignatureListener(subId); + } + done = true; + console.log("Returning status", status); + return status; }; const createAssociatedTokenAccountInstruction = ( - associatedTokenAddress: anchor.web3.PublicKey, - payer: anchor.web3.PublicKey, - walletAddress: anchor.web3.PublicKey, - splTokenMintAddress: anchor.web3.PublicKey + associatedTokenAddress: anchor.web3.PublicKey, + payer: anchor.web3.PublicKey, + walletAddress: anchor.web3.PublicKey, + splTokenMintAddress: anchor.web3.PublicKey ) => { - const keys = [ - { pubkey: payer, isSigner: true, isWritable: true }, - { pubkey: associatedTokenAddress, isSigner: false, isWritable: true }, - { pubkey: walletAddress, isSigner: false, isWritable: false }, - { pubkey: splTokenMintAddress, isSigner: false, isWritable: false }, - { - pubkey: anchor.web3.SystemProgram.programId, - isSigner: false, - isWritable: false, - }, - { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, - { - pubkey: anchor.web3.SYSVAR_RENT_PUBKEY, - isSigner: false, - isWritable: false, - }, - ]; - return new anchor.web3.TransactionInstruction({ - keys, - programId: SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID, - data: Buffer.from([]), - }); + const keys = [ + { pubkey: payer, isSigner: true, isWritable: true }, + { pubkey: associatedTokenAddress, isSigner: false, isWritable: true }, + { pubkey: walletAddress, isSigner: false, isWritable: false }, + { pubkey: splTokenMintAddress, isSigner: false, isWritable: false }, + { + pubkey: anchor.web3.SystemProgram.programId, + isSigner: false, + isWritable: false, + }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + { + pubkey: anchor.web3.SYSVAR_RENT_PUBKEY, + isSigner: false, + isWritable: false, + }, + ]; + return new anchor.web3.TransactionInstruction({ + keys, + programId: SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID, + data: Buffer.from([]), + }); }; export const getCandyMachineState = async ( - anchorWallet: anchor.Wallet, - candyMachineId: anchor.web3.PublicKey, - connection: anchor.web3.Connection + anchorWallet: anchor.Wallet, + candyMachineId: anchor.web3.PublicKey, + connection: anchor.web3.Connection ): Promise => { - const provider = new anchor.Provider(connection, anchorWallet, { - preflightCommitment: "recent", - }); + const provider = new anchor.Provider(connection, anchorWallet, { + preflightCommitment: "recent", + }); - const idl = await anchor.Program.fetchIdl(CANDY_MACHINE_PROGRAM, provider); + const idl = await anchor.Program.fetchIdl(CANDY_MACHINE_PROGRAM, provider); - if (idl) { - const program = new anchor.Program(idl, CANDY_MACHINE_PROGRAM, provider); - const candyMachine = { - id: candyMachineId, - connection, - program, - }; - const state: any = await program.account.candyMachine.fetch(candyMachineId); - const itemsAvailable = state.data.itemsAvailable.toNumber(); - const itemsRedeemed = state.itemsRedeemed.toNumber(); - const itemsRemaining = itemsAvailable - itemsRedeemed; + if (idl) { + const program = new anchor.Program( + idl, + CANDY_MACHINE_PROGRAM, + provider + ); + const candyMachine = { + id: candyMachineId, + connection, + program, + }; + const state: any = await program.account.candyMachine.fetch( + candyMachineId + ); + const itemsAvailable = state.data.itemsAvailable.toNumber(); + const itemsRedeemed = state.itemsRedeemed.toNumber(); + const itemsRemaining = itemsAvailable - itemsRedeemed; - let goLiveDate = state.data.goLiveDate.toNumber(); - goLiveDate = new Date(goLiveDate * 1000); + let goLiveDate = state.data.goLiveDate.toNumber(); + goLiveDate = new Date(goLiveDate * 1000); - return { - candyMachine, - itemsAvailable, - itemsRedeemed, - itemsRemaining, - goLiveDate, - }; - } else { - throw new Error(`Fetching idl returned null: check CANDY_MACHINE_PROGRAM`); - } + return { + candyMachine, + itemsAvailable, + itemsRedeemed, + itemsRemaining, + goLiveDate, + }; + } else { + throw new Error( + `Fetching idl returned null: check CANDY_MACHINE_PROGRAM` + ); + } }; const getMasterEdition = async ( - mint: anchor.web3.PublicKey + mint: anchor.web3.PublicKey ): Promise => { - return ( - await anchor.web3.PublicKey.findProgramAddress( - [ - Buffer.from("metadata"), - TOKEN_METADATA_PROGRAM_ID.toBuffer(), - mint.toBuffer(), - Buffer.from("edition"), - ], - TOKEN_METADATA_PROGRAM_ID - ) - )[0]; + return ( + await anchor.web3.PublicKey.findProgramAddress( + [ + Buffer.from("metadata"), + TOKEN_METADATA_PROGRAM_ID.toBuffer(), + mint.toBuffer(), + Buffer.from("edition"), + ], + TOKEN_METADATA_PROGRAM_ID + ) + )[0]; }; const getMetadata = async ( - mint: anchor.web3.PublicKey + mint: anchor.web3.PublicKey ): Promise => { - return ( - await anchor.web3.PublicKey.findProgramAddress( - [ - Buffer.from("metadata"), - TOKEN_METADATA_PROGRAM_ID.toBuffer(), - mint.toBuffer(), - ], - TOKEN_METADATA_PROGRAM_ID - ) - )[0]; + return ( + await anchor.web3.PublicKey.findProgramAddress( + [ + Buffer.from("metadata"), + TOKEN_METADATA_PROGRAM_ID.toBuffer(), + mint.toBuffer(), + ], + TOKEN_METADATA_PROGRAM_ID + ) + )[0]; }; const getTokenWallet = async ( - wallet: anchor.web3.PublicKey, - mint: anchor.web3.PublicKey + wallet: anchor.web3.PublicKey, + mint: anchor.web3.PublicKey ) => { - return ( - await anchor.web3.PublicKey.findProgramAddress( - [wallet.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()], - SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID - ) - )[0]; + return ( + await anchor.web3.PublicKey.findProgramAddress( + [wallet.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()], + SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID + ) + )[0]; }; export async function getNFTsForOwner( - connection: anchor.web3.Connection, - ownerAddress: anchor.web3.PublicKey + connection: anchor.web3.Connection, + ownerAddress: anchor.web3.PublicKey ) { - const allMintsCandyMachine = await fetchHashTable( - process.env.NEXT_PUBLIC_CANDY_MACHINE_ID! - ); - const allTokens = []; - const tokenAccounts = await connection.getParsedTokenAccountsByOwner( - ownerAddress, - { - programId: TOKEN_PROGRAM_ID, - } - ); + const allMintsCandyMachine = await fetchHashTable( + process.env.NEXT_PUBLIC_CANDY_MACHINE_ID! + ); + 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; + 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" && - allMintsCandyMachine.includes(tokenAccount.account.data.parsed.info.mint) - ) { - 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); + if ( + tokenAmount.amount == "1" && + tokenAmount.decimals == "0" && + allMintsCandyMachine.includes( + tokenAccount.account.data.parsed.info.mint + ) + ) { + 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: any = await connection.getParsedAccountInfo(pda); - const metadata: any = new Metadata( - ownerAddress.toString(), - accountInfo.value - ); - const dataRes = await fetch(metadata.data.data.uri); - if (dataRes.status === 200) { - allTokens.push(await dataRes.json()); - } + const metadata: any = new Metadata( + ownerAddress.toString(), + accountInfo.value + ); + const dataRes = await fetch(metadata.data.data.uri); + if (dataRes.status === 200) { + allTokens.push(await dataRes.json()); + } + } } - } - return allTokens; + return allTokens; } export const mintOneToken = async ( - candyMachine: CandyMachine, - config: anchor.web3.PublicKey, // feels like this should be part of candyMachine? - payer: anchor.web3.PublicKey, - treasury: anchor.web3.PublicKey + candyMachine: CandyMachine, + config: anchor.web3.PublicKey, // feels like this should be part of candyMachine? + payer: anchor.web3.PublicKey, + treasury: anchor.web3.PublicKey ): Promise => { - const mint = anchor.web3.Keypair.generate(); - const token = await getTokenWallet(payer, mint.publicKey); - const { connection, program } = candyMachine; - const metadata = await getMetadata(mint.publicKey); - const masterEdition = await getMasterEdition(mint.publicKey); + const mint = anchor.web3.Keypair.generate(); + const token = await getTokenWallet(payer, mint.publicKey); + const { connection, program } = candyMachine; + const metadata = await getMetadata(mint.publicKey); + const masterEdition = await getMasterEdition(mint.publicKey); - const rent = await connection.getMinimumBalanceForRentExemption( - MintLayout.span - ); + const rent = await connection.getMinimumBalanceForRentExemption( + MintLayout.span + ); - return await program.rpc.mintNft({ - accounts: { - config, - candyMachine: candyMachine.id, - payer: payer, - wallet: treasury, - mint: mint.publicKey, - metadata, - masterEdition, - mintAuthority: payer, - updateAuthority: payer, - tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID, - tokenProgram: TOKEN_PROGRAM_ID, - systemProgram: anchor.web3.SystemProgram.programId, - rent: anchor.web3.SYSVAR_RENT_PUBKEY, - clock: anchor.web3.SYSVAR_CLOCK_PUBKEY, - }, - signers: [mint], - instructions: [ - anchor.web3.SystemProgram.createAccount({ - fromPubkey: payer, - newAccountPubkey: mint.publicKey, - space: MintLayout.span, - lamports: rent, - programId: TOKEN_PROGRAM_ID, - }), - Token.createInitMintInstruction( - TOKEN_PROGRAM_ID, - mint.publicKey, - 0, - payer, - payer - ), - createAssociatedTokenAccountInstruction( - token, - payer, - payer, - mint.publicKey - ), - Token.createMintToInstruction( - TOKEN_PROGRAM_ID, - mint.publicKey, - token, - payer, - [], - 1 - ), - ], - }); + return await program.rpc.mintNft({ + accounts: { + config, + candyMachine: candyMachine.id, + payer: payer, + wallet: treasury, + mint: mint.publicKey, + metadata, + masterEdition, + mintAuthority: payer, + updateAuthority: payer, + tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID, + tokenProgram: TOKEN_PROGRAM_ID, + systemProgram: anchor.web3.SystemProgram.programId, + rent: anchor.web3.SYSVAR_RENT_PUBKEY, + clock: anchor.web3.SYSVAR_CLOCK_PUBKEY, + }, + signers: [mint], + instructions: [ + anchor.web3.SystemProgram.createAccount({ + fromPubkey: payer, + newAccountPubkey: mint.publicKey, + space: MintLayout.span, + lamports: rent, + programId: TOKEN_PROGRAM_ID, + }), + Token.createInitMintInstruction( + TOKEN_PROGRAM_ID, + mint.publicKey, + 0, + payer, + payer + ), + createAssociatedTokenAccountInstruction( + token, + payer, + payer, + mint.publicKey + ), + Token.createMintToInstruction( + TOKEN_PROGRAM_ID, + mint.publicKey, + token, + payer, + [], + 1 + ), + ], + }); }; export const mintMultipleToken = async ( - candyMachine: any, - config: anchor.web3.PublicKey, - payer: anchor.web3.PublicKey, - treasury: anchor.web3.PublicKey, - quantity: number = 2 + candyMachine: any, + config: anchor.web3.PublicKey, + payer: anchor.web3.PublicKey, + treasury: anchor.web3.PublicKey, + quantity: number = 2 ) => { - const signersMatrix = []; - const instructionsMatrix = []; + const signersMatrix = []; + const instructionsMatrix = []; - for (let index = 0; index < quantity; index++) { - const mint = anchor.web3.Keypair.generate(); - const token = await getTokenWallet(payer, mint.publicKey); - const { connection } = candyMachine; - const rent = await connection.getMinimumBalanceForRentExemption( - MintLayout.span - ); - const instructions = [ - anchor.web3.SystemProgram.createAccount({ - fromPubkey: payer, - newAccountPubkey: mint.publicKey, - space: MintLayout.span, - lamports: rent, - programId: TOKEN_PROGRAM_ID, - }), - Token.createInitMintInstruction( - TOKEN_PROGRAM_ID, - mint.publicKey, - 0, - payer, - payer - ), - createAssociatedTokenAccountInstruction( - token, - payer, - payer, - mint.publicKey - ), - Token.createMintToInstruction( - TOKEN_PROGRAM_ID, - mint.publicKey, - token, - payer, - [], - 1 - ), - ]; - const masterEdition = await getMasterEdition(mint.publicKey); - const metadata = await getMetadata(mint.publicKey); + for (let index = 0; index < quantity; index++) { + const mint = anchor.web3.Keypair.generate(); + const token = await getTokenWallet(payer, mint.publicKey); + const { connection } = candyMachine; + const rent = await connection.getMinimumBalanceForRentExemption( + MintLayout.span + ); + const instructions = [ + anchor.web3.SystemProgram.createAccount({ + fromPubkey: payer, + newAccountPubkey: mint.publicKey, + space: MintLayout.span, + lamports: rent, + programId: TOKEN_PROGRAM_ID, + }), + Token.createInitMintInstruction( + TOKEN_PROGRAM_ID, + mint.publicKey, + 0, + payer, + payer + ), + createAssociatedTokenAccountInstruction( + token, + payer, + payer, + mint.publicKey + ), + Token.createMintToInstruction( + TOKEN_PROGRAM_ID, + mint.publicKey, + token, + payer, + [], + 1 + ), + ]; + const masterEdition = await getMasterEdition(mint.publicKey); + const metadata = await getMetadata(mint.publicKey); - instructions.push( - await candyMachine.program.instruction.mintNft({ - accounts: { - config, - candyMachine: candyMachine.id, - payer: payer, - wallet: treasury, - mint: mint.publicKey, - metadata, - masterEdition, - mintAuthority: payer, - updateAuthority: payer, - tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID, - tokenProgram: TOKEN_PROGRAM_ID, - systemProgram: anchor.web3.SystemProgram.programId, - rent: anchor.web3.SYSVAR_RENT_PUBKEY, - clock: anchor.web3.SYSVAR_CLOCK_PUBKEY, - }, - }) - ); - const signers: anchor.web3.Keypair[] = [mint]; + instructions.push( + await candyMachine.program.instruction.mintNft({ + accounts: { + config, + candyMachine: candyMachine.id, + payer: payer, + wallet: treasury, + mint: mint.publicKey, + metadata, + masterEdition, + mintAuthority: payer, + updateAuthority: payer, + tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID, + tokenProgram: TOKEN_PROGRAM_ID, + systemProgram: anchor.web3.SystemProgram.programId, + rent: anchor.web3.SYSVAR_RENT_PUBKEY, + clock: anchor.web3.SYSVAR_CLOCK_PUBKEY, + }, + }) + ); + const signers: anchor.web3.Keypair[] = [mint]; - signersMatrix.push(signers); - instructionsMatrix.push(instructions); - } + signersMatrix.push(signers); + instructionsMatrix.push(instructions); + } - return await sendTransactions( - candyMachine.program.provider.connection, - candyMachine.program.provider.wallet, - instructionsMatrix, - signersMatrix - ); + return await sendTransactions( + candyMachine.program.provider.connection, + candyMachine.program.provider.wallet, + instructionsMatrix, + signersMatrix + ); }; export const shortenAddress = (address: string, chars = 4): string => { - return `${address.slice(0, chars)}...${address.slice(-chars)}`; + return `${address.slice(0, chars)}...${address.slice(-chars)}`; };