Skip to content

Instantly share code, notes, and snippets.

@0xMukesh
Last active June 12, 2022 06:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0xMukesh/3f6c2450803588adcf6ffc2d15a6f356 to your computer and use it in GitHub Desktop.
Save 0xMukesh/3f6c2450803588adcf6ffc2d15a6f356 to your computer and use it in GitHub Desktop.
import * as anchor from "@project-serum/anchor";
import { MintLayout, TOKEN_PROGRAM_ID, Token } from "@solana/spl-token";
import {
SystemProgram,
SYSVAR_SLOT_HASHES_PUBKEY,
Keypair,
} from "@solana/web3.js";
import { sendTransactions, SequenceType } from "./transaction";
import {
CANDY_MACHINE_PROGRAM,
TOKEN_METADATA_PROGRAM_ID,
CIVIC,
SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
} from "../constants/constants";
import { CandyMachineAccount } from "../types/getCandyMachineState";
import { SetupState } from "../types/candyMachine/setupState";
import { MintResult } from "../types/mintResult";
export const awaitTransactionSignatureConfirmation = async (
txid: anchor.web3.TransactionSignature,
timeout: number,
connection: anchor.web3.Connection,
queryStatus = false
): Promise<anchor.web3.SignatureStatus | null | void> => {
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);
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);
}
}
})();
}
});
//@ts-ignore
if (connection._signatureSubscriptions[subId]) {
connection.removeSignatureListener(subId);
}
done = true;
console.log("Returning status", status);
return status;
};
export const createAccountsForMint = async (
candyMachine: CandyMachineAccount,
payer: anchor.web3.PublicKey
): Promise<SetupState> => {
const mint = anchor.web3.Keypair.generate();
const userTokenAccountAddress = (
await getAtaForMint(mint.publicKey, payer)
)[0];
const signers: anchor.web3.Keypair[] = [mint];
const instructions = [
anchor.web3.SystemProgram.createAccount({
fromPubkey: payer,
newAccountPubkey: mint.publicKey,
space: MintLayout.span,
lamports:
await candyMachine.program.provider.connection.getMinimumBalanceForRentExemption(
MintLayout.span
),
programId: TOKEN_PROGRAM_ID,
}),
Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
0,
payer,
payer
),
createAssociatedTokenAccountInstruction(
userTokenAccountAddress,
payer,
payer,
mint.publicKey
),
Token.createMintToInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
userTokenAccountAddress,
payer,
[],
1
),
];
return {
mint: mint,
userTokenAccount: userTokenAccountAddress,
transaction: (
await sendTransactions(
candyMachine.program.provider.connection,
candyMachine.program.provider.wallet,
[instructions],
[signers],
SequenceType.StopOnFailure,
"singleGossip",
() => {},
() => false,
undefined,
[],
[]
)
).txs[0].txid,
};
};
export const getAtaForMint = async (
mint: anchor.web3.PublicKey,
buyer: anchor.web3.PublicKey
): Promise<[anchor.web3.PublicKey, number]> => {
return await anchor.web3.PublicKey.findProgramAddress(
[buyer.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()],
SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID
);
};
export const createAssociatedTokenAccountInstruction = (
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([]),
});
};
export const getNetworkToken = async (
wallet: anchor.web3.PublicKey,
gatekeeperNetwork: anchor.web3.PublicKey
): Promise<[anchor.web3.PublicKey, number]> => {
return await anchor.web3.PublicKey.findProgramAddress(
[
wallet.toBuffer(),
Buffer.from("gateway"),
Buffer.from([0, 0, 0, 0, 0, 0, 0, 0]),
gatekeeperNetwork.toBuffer(),
],
CIVIC
);
};
export const getNetworkExpire = async (
gatekeeperNetwork: anchor.web3.PublicKey
): Promise<[anchor.web3.PublicKey, number]> => {
return await anchor.web3.PublicKey.findProgramAddress(
[gatekeeperNetwork.toBuffer(), Buffer.from("expire")],
CIVIC
);
};
export const getCandyMachineState = async (
anchorWallet: anchor.Wallet,
candyMachineId: anchor.web3.PublicKey,
connection: anchor.web3.Connection
): Promise<CandyMachineAccount> => {
const provider = new anchor.Provider(connection, anchorWallet, {
preflightCommitment: "processed",
});
const idl = await anchor.Program.fetchIdl(CANDY_MACHINE_PROGRAM, provider);
const program = new anchor.Program(idl!, CANDY_MACHINE_PROGRAM, provider);
const state: any = await program.account.candyMachine.fetch(candyMachineId);
const itemsAvailable = state.data.itemsAvailable.toNumber();
const itemsRedeemed = state.itemsRedeemed.toNumber();
const itemsRemaining = itemsAvailable - itemsRedeemed;
return {
id: candyMachineId,
program,
state: {
authority: state.authority,
itemsAvailable,
itemsRedeemed,
itemsRemaining,
isSoldOut: itemsRemaining === 0,
isActive: false,
isPresale: false,
isWhitelistOnly: false,
goLiveDate: state.data.goLiveDate,
treasury: state.wallet,
tokenMint: state.tokenMint,
gatekeeper: state.data.gatekeeper,
endSettings: state.data.endSettings,
whitelistMintSettings: state.data.whitelistMintSettings,
hiddenSettings: state.data.hiddenSettings,
price: state.data.price,
retainAuthority: state.data.retainAuthority,
},
};
};
export const getMasterEdition = async (
mint: anchor.web3.PublicKey
): Promise<anchor.web3.PublicKey> => {
return (
await anchor.web3.PublicKey.findProgramAddress(
[
Buffer.from("metadata"),
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
mint.toBuffer(),
Buffer.from("edition"),
],
TOKEN_METADATA_PROGRAM_ID
)
)[0];
};
export const getMetadata = async (
mint: anchor.web3.PublicKey
): Promise<anchor.web3.PublicKey> => {
return (
await anchor.web3.PublicKey.findProgramAddress(
[
Buffer.from("metadata"),
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
mint.toBuffer(),
],
TOKEN_METADATA_PROGRAM_ID
)
)[0];
};
export const getCandyMachineCreator = async (
candyMachine: anchor.web3.PublicKey
): Promise<[anchor.web3.PublicKey, number]> => {
return await anchor.web3.PublicKey.findProgramAddress(
[Buffer.from("candy_machine"), candyMachine.toBuffer()],
CANDY_MACHINE_PROGRAM
);
};
export const getCollectionPDA = async (
candyMachineAddress: anchor.web3.PublicKey
): Promise<[anchor.web3.PublicKey, number]> => {
return await anchor.web3.PublicKey.findProgramAddress(
[Buffer.from("collection"), candyMachineAddress.toBuffer()],
CANDY_MACHINE_PROGRAM
);
};
export interface CollectionData {
mint: anchor.web3.PublicKey;
candyMachine: anchor.web3.PublicKey;
}
export const getCollectionAuthorityRecordPDA = async (
mint: anchor.web3.PublicKey,
newAuthority: anchor.web3.PublicKey
): Promise<anchor.web3.PublicKey> => {
return (
await anchor.web3.PublicKey.findProgramAddress(
[
Buffer.from("metadata"),
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
mint.toBuffer(),
Buffer.from("collection_authority"),
newAuthority.toBuffer(),
],
TOKEN_METADATA_PROGRAM_ID
)
)[0];
};
export const mintOneToken = async (
candyMachine: CandyMachineAccount,
payer: anchor.web3.PublicKey,
setupState?: SetupState
): Promise<MintResult | null> => {
const mint = setupState?.mint ?? anchor.web3.Keypair.generate();
const userTokenAccountAddress = (
await getAtaForMint(mint.publicKey, payer)
)[0];
const userPayingAccountAddress = candyMachine.state.tokenMint
? (await getAtaForMint(candyMachine.state.tokenMint, payer))[0]
: payer;
const candyMachineAddress = candyMachine.id;
const remainingAccounts = [];
const instructions = [];
const signers: anchor.web3.Keypair[] = [];
console.log("SetupState: ", setupState);
if (!setupState) {
signers.push(mint);
instructions.push(
...[
anchor.web3.SystemProgram.createAccount({
fromPubkey: payer,
newAccountPubkey: mint.publicKey,
space: MintLayout.span,
lamports:
await candyMachine.program.provider.connection.getMinimumBalanceForRentExemption(
MintLayout.span
),
programId: TOKEN_PROGRAM_ID,
}),
Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
0,
payer,
payer
),
createAssociatedTokenAccountInstruction(
userTokenAccountAddress,
payer,
payer,
mint.publicKey
),
Token.createMintToInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
userTokenAccountAddress,
payer,
[],
1
),
]
);
}
if (candyMachine.state.gatekeeper) {
remainingAccounts.push({
pubkey: (
await getNetworkToken(
payer,
candyMachine.state.gatekeeper.gatekeeperNetwork
)
)[0],
isWritable: true,
isSigner: false,
});
if (candyMachine.state.gatekeeper.expireOnUse) {
remainingAccounts.push({
pubkey: CIVIC,
isWritable: false,
isSigner: false,
});
remainingAccounts.push({
pubkey: (
await getNetworkExpire(
candyMachine.state.gatekeeper.gatekeeperNetwork
)
)[0],
isWritable: false,
isSigner: false,
});
}
}
if (candyMachine.state.whitelistMintSettings) {
const mint = new anchor.web3.PublicKey(
candyMachine.state.whitelistMintSettings.mint
);
const whitelistToken = (await getAtaForMint(mint, payer))[0];
remainingAccounts.push({
pubkey: whitelistToken,
isWritable: true,
isSigner: false,
});
if (candyMachine.state.whitelistMintSettings.mode.burnEveryTime) {
remainingAccounts.push({
pubkey: mint,
isWritable: true,
isSigner: false,
});
remainingAccounts.push({
pubkey: payer,
isWritable: false,
isSigner: true,
});
}
}
if (candyMachine.state.tokenMint) {
remainingAccounts.push({
pubkey: userPayingAccountAddress,
isWritable: true,
isSigner: false,
});
remainingAccounts.push({
pubkey: payer,
isWritable: false,
isSigner: true,
});
}
const metadataAddress = await getMetadata(mint.publicKey);
const masterEdition = await getMasterEdition(mint.publicKey);
const [candyMachineCreator, creatorBump] = await getCandyMachineCreator(
candyMachineAddress
);
console.log(remainingAccounts.map((rm) => rm.pubkey.toBase58()));
instructions.push(
await candyMachine.program.instruction.mintNft(creatorBump, {
accounts: {
candyMachine: candyMachineAddress,
candyMachineCreator,
payer: payer,
wallet: candyMachine.state.treasury,
mint: mint.publicKey,
metadata: metadataAddress,
masterEdition,
mintAuthority: payer,
updateAuthority: payer,
tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
tokenProgram: TOKEN_PROGRAM_ID,
systemProgram: SystemProgram.programId,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
recentBlockhashes: SYSVAR_SLOT_HASHES_PUBKEY,
instructionSysvarAccount: anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY,
},
remainingAccounts:
remainingAccounts.length > 0 ? remainingAccounts : undefined,
})
);
const [collectionPDA] = await getCollectionPDA(candyMachineAddress);
const collectionPDAAccount =
await candyMachine.program.provider.connection.getAccountInfo(
collectionPDA
);
if (collectionPDAAccount && candyMachine.state.retainAuthority) {
try {
const collectionData =
(await candyMachine.program.account.collectionPda.fetch(
collectionPDA
)) as CollectionData;
console.log(collectionData);
const collectionMint = collectionData.mint;
const collectionAuthorityRecord = await getCollectionAuthorityRecordPDA(
collectionMint,
collectionPDA
);
console.log(collectionMint);
if (collectionMint) {
const collectionMetadata = await getMetadata(collectionMint);
const collectionMasterEdition = await getMasterEdition(collectionMint);
console.log("Collection PDA: ", collectionPDA.toBase58());
console.log("Authority: ", candyMachine.state.authority.toBase58());
instructions.push(
await candyMachine.program.instruction.setCollectionDuringMint({
accounts: {
candyMachine: candyMachineAddress,
metadata: metadataAddress,
payer: payer,
collectionPda: collectionPDA,
tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
instructions: anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY,
collectionMint,
collectionMetadata,
collectionMasterEdition,
authority: candyMachine.state.authority,
collectionAuthorityRecord,
},
})
);
}
} catch (error) {
console.error(error);
}
}
const instructionsMatrix = [instructions];
const signersMatrix = [signers];
try {
const txns = (
await sendTransactions(
candyMachine.program.provider.connection,
candyMachine.program.provider.wallet,
instructionsMatrix,
signersMatrix,
SequenceType.StopOnFailure,
"singleGossip",
() => {},
() => false,
undefined
)
).txs.map((t) => t.txid);
const mintTxn = txns[0];
return {
mintTxId: mintTxn,
metadataKey: metadataAddress,
};
} catch (e) {
console.log(e);
}
return null;
};
export async function loadCandyProgramV2(
walletKeyPair: Keypair,
env: string,
customRpcUrl?: string
) {
if (customRpcUrl) console.log("USING CUSTOM URL", customRpcUrl);
// @ts-ignore
const solConnection = new anchor.web3.Connection(
//@ts-ignore
customRpcUrl || getCluster(env)
);
const walletWrapper = new anchor.Wallet(walletKeyPair);
const provider = new anchor.Provider(solConnection, walletWrapper, {
preflightCommitment: "recent",
});
const idl = await anchor.Program.fetchIdl(CANDY_MACHINE_PROGRAM, provider);
const program = new anchor.Program(idl, CANDY_MACHINE_PROGRAM, provider);
console.log("Program ID from anchor", program.programId.toBase58());
return program;
}
import { Request, Response } from "express";
import * as anchor from "@project-serum/anchor";
import {
PublicKey,
Connection,
Transaction,
TransactionInstruction,
SYSVAR_SLOT_HASHES_PUBKEY,
SystemProgram,
Keypair,
} from "@solana/web3.js";
import { MintLayout, TOKEN_PROGRAM_ID, Token } from "@solana/spl-token";
import fetchData from "../utils/fetchData";
import {
getAtaForMint,
createAssociatedTokenAccountInstruction,
getNetworkToken,
getNetworkExpire,
getMetadata,
getMasterEdition,
getCandyMachineCreator,
getCollectionPDA,
CollectionData,
getCollectionAuthorityRecordPDA,
getCandyMachineState,
} from "../utils/candyMachine";
import Scans from "../models/scans";
import { CIVIC, TOKEN_METADATA_PROGRAM_ID } from "../constants/constants";
import { MakeTransactionInputData } from "../types/makeTxn";
const mint = async (req: Request, res: Response) => {
const qrCodeId = req.query.id;
if (!qrCodeId) {
return res.status(400).json({
error: "ERR-MISSING-QR-CODE-ID",
message:
"Missing qrCodeId parameter. The qrCodeId is a required parameter",
});
}
if (req.method === "GET") {
return res.status(200).json({
label: (await fetchData(qrCodeId as string)).label,
icon: (await fetchData(qrCodeId as string)).icon,
});
}
if (req.method === "POST") {
try {
const reference = Keypair.generate().publicKey;
const qrCodeId = req.query.id;
const { account } = req.body as MakeTransactionInputData;
if (!account) {
return res.status(400).json({ error: "No account provided" });
}
const dummy_key_pair = new anchor.web3.Keypair();
const walletWrapper = new anchor.Wallet(dummy_key_pair);
const candyMachine = await getCandyMachineState(
walletWrapper,
new anchor.web3.PublicKey(
(
await fetchData(qrCodeId as string)
).candyMachineId
),
new anchor.web3.Connection((await fetchData(qrCodeId as string)).rpcUrl)
);
const candyMachineAddress = candyMachine.id;
const payer = new PublicKey(account);
const mint = anchor.web3.Keypair.generate();
const platformAddress = new anchor.web3.PublicKey(process.env.SHOP!);
console.log("Platform address: ", platformAddress.toString());
const mintPrice = candyMachine.state.price.toNumber();
console.log("Mint price: ", mintPrice);
const serviceFee = mintPrice / 100;
console.log("Service fee: ", serviceFee);
const userTokenAccountAddress = (
await getAtaForMint(mint.publicKey, payer)
)[0];
const transferIx = SystemProgram.transfer({
fromPubkey: payer,
toPubkey: platformAddress,
lamports: serviceFee,
});
const userPayingAccountAddress = payer;
const instructions: TransactionInstruction[] = [];
const remainingAccounts = [];
const signers: anchor.web3.Keypair[] = [];
instructions.push(transferIx);
if (mint) {
signers.push(mint);
instructions.push(
...[
anchor.web3.SystemProgram.createAccount({
fromPubkey: payer,
newAccountPubkey: mint.publicKey,
space: MintLayout.span,
lamports:
await candyMachine.program.provider.connection.getMinimumBalanceForRentExemption(
MintLayout.span
),
programId: TOKEN_PROGRAM_ID,
}),
Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
0,
payer,
payer
),
createAssociatedTokenAccountInstruction(
userTokenAccountAddress,
payer,
payer,
mint.publicKey
),
Token.createMintToInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
userTokenAccountAddress,
payer,
[],
1
),
]
);
}
if (candyMachine.state.gatekeeper) {
remainingAccounts.push({
pubkey: (
await getNetworkToken(
payer,
candyMachine.state.gatekeeper.gatekeeperNetwork
)
)[0],
isWritable: true,
isSigner: false,
});
if (candyMachine.state.gatekeeper.expireOnUse) {
remainingAccounts.push({
pubkey: CIVIC,
isWritable: false,
isSigner: false,
});
remainingAccounts.push({
pubkey: (
await getNetworkExpire(
candyMachine.state.gatekeeper.gatekeeperNetwork
)
)[0],
isWritable: false,
isSigner: false,
});
}
}
if (candyMachine.state.whitelistMintSettings) {
const mint = new anchor.web3.PublicKey(
candyMachine.state.whitelistMintSettings.mint
);
const whitelistToken = (await getAtaForMint(mint, payer))[0];
remainingAccounts.push({
pubkey: whitelistToken,
isWritable: true,
isSigner: false,
});
if (candyMachine.state.whitelistMintSettings.mode.burnEveryTime) {
remainingAccounts.push({
pubkey: mint,
isWritable: true,
isSigner: false,
});
remainingAccounts.push({
pubkey: payer,
isWritable: false,
isSigner: true,
});
}
}
if (candyMachine.state.tokenMint) {
remainingAccounts.push({
pubkey: userPayingAccountAddress,
isWritable: true,
isSigner: false,
});
remainingAccounts.push({
pubkey: payer,
isWritable: false,
isSigner: true,
});
}
const metadataAddress = await getMetadata(mint.publicKey);
const masterEdition = await getMasterEdition(mint.publicKey);
const [candyMachineCreator, creatorBump] = await getCandyMachineCreator(
candyMachineAddress
);
console.log(remainingAccounts.map((rm) => rm.pubkey.toBase58()));
instructions.push(
await candyMachine.program.instruction.mintNft(creatorBump, {
accounts: {
candyMachine: candyMachineAddress,
candyMachineCreator,
payer: payer,
wallet: candyMachine.state.treasury,
mint: mint.publicKey,
metadata: metadataAddress,
masterEdition,
mintAuthority: payer,
updateAuthority: payer,
tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
tokenProgram: TOKEN_PROGRAM_ID,
systemProgram: SystemProgram.programId,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
recentBlockhashes: SYSVAR_SLOT_HASHES_PUBKEY,
instructionSysvarAccount: anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY,
},
remainingAccounts:
remainingAccounts.length > 0 ? remainingAccounts : undefined,
})
);
const [collectionPDA] = await getCollectionPDA(candyMachineAddress);
const collectionPDAAccount =
await candyMachine.program.provider.connection.getAccountInfo(
collectionPDA
);
if (collectionPDAAccount && candyMachine.state.retainAuthority) {
try {
const collectionData =
(await candyMachine.program.account.collectionPda.fetch(
collectionPDA
)) as CollectionData;
console.log(collectionData);
const collectionMint = collectionData.mint;
const collectionAuthorityRecord =
await getCollectionAuthorityRecordPDA(
collectionMint,
collectionPDA
);
console.log(collectionMint);
if (collectionMint) {
const collectionMetadata = await getMetadata(collectionMint);
const collectionMasterEdition = await getMasterEdition(
collectionMint
);
console.log("Collection PDA: ", collectionPDA.toBase58());
console.log("Authority: ", candyMachine.state.authority.toBase58());
const setCollectionInst =
await candyMachine.program.instruction.setCollectionDuringMint({
accounts: {
candyMachine: candyMachineAddress,
metadata: metadataAddress,
payer: payer,
collectionPda: collectionPDA,
tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
instructions: anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY,
collectionMint,
collectionMetadata,
collectionMasterEdition,
authority: candyMachine.state.authority,
collectionAuthorityRecord,
},
});
setCollectionInst.keys.push({
pubkey: new PublicKey(reference),
isSigner: false,
isWritable: false,
});
instructions.push(setCollectionInst);
}
} catch (error) {
console.error(error);
}
}
const connection = new Connection(
(await fetchData(qrCodeId as string)).rpcUrl
);
const { blockhash } = await connection.getLatestBlockhash("finalized");
const transaction = new Transaction({
recentBlockhash: blockhash,
feePayer: payer,
});
console.log("INX", instructions);
transaction.add(...instructions);
transaction.partialSign(mint);
console.log("Transaction Before Serialize", transaction);
const serializedTransaction = transaction.serialize({
requireAllSignatures: false,
});
const base64 = serializedTransaction.toString("base64");
console.log("Serialized Transaction: ", base64);
const message = "Thanks for minting NFTs!";
const scan = new Scans({
user: account,
qrCodeId: qrCodeId,
candyMachineId: (await fetchData(qrCodeId as string)).candyMachineId,
reference: reference,
serviceFee: serviceFee / 1e9,
candyMachinePrice: mintPrice / 1e9,
});
await scan.save();
return res.status(200).json({
transaction: base64,
message,
});
} catch (err) {
console.error(err);
return res.status(500).json({
message: "Error while creating the txn",
});
}
}
};
export default mint;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment