UNPKG

candy-machine-assistant

Version:

A tool to assist in the connecting to candy machines, mint accounts and confirm NFT transactions based on Solana's Metaplex NFTs.

571 lines (570 loc) 32.8 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.shortenAddress = exports.mintOneToken = exports.createAccountsForMint = exports.getCollectionAuthorityRecordPDA = exports.getCollectionPDA = exports.getCandyMachineCreator = exports.getMetadataPDA = exports.getCandyMachineState = exports.awaitTransactionSignatureConfirmation = exports.TOKEN_METADATA_PROGRAM_ID = exports.CANDY_MACHINE_PROGRAM = void 0; /* eslint-disable */ var anchor = __importStar(require("@project-serum/anchor")); var spl_token_1 = require("@solana/spl-token"); var web3_js_1 = require("@solana/web3.js"); var connection_1 = require("./connection"); var utils_1 = require("./utils"); exports.CANDY_MACHINE_PROGRAM = new anchor.web3.PublicKey("cndy3Z4yapfJBmL3ShUp5exZKqR3z33thTzeNMm2gRZ"); exports.TOKEN_METADATA_PROGRAM_ID = new anchor.web3.PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"); var awaitTransactionSignatureConfirmation = function (txid, timeout, connection, queryStatus) { if (queryStatus === void 0) { queryStatus = false; } return __awaiter(void 0, void 0, void 0, function () { var done, status, subId; return __generator(this, function (_a) { switch (_a.label) { case 0: done = false; status = { slot: 0, confirmations: 0, err: null, }; subId = 0; return [4 /*yield*/, new Promise(function (resolve, reject) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: setTimeout(function () { if (done) { return; } done = true; console.log("Rejecting for timeout..."); reject({ timeout: true }); }, timeout); _a.label = 1; case 1: if (!(!done && queryStatus)) return [3 /*break*/, 3]; // eslint-disable-next-line no-loop-func (function () { return __awaiter(void 0, void 0, void 0, function () { var signatureStatuses, e_1; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, connection.getSignatureStatuses([txid])]; case 1: signatureStatuses = _a.sent(); 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); } } return [3 /*break*/, 3]; case 2: e_1 = _a.sent(); if (!done) { console.log("REST connection error: txid", txid, e_1); } return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); })(); return [4 /*yield*/, sleep(2000)]; case 2: _a.sent(); return [3 /*break*/, 1]; case 3: return [2 /*return*/]; } }); }); })]; case 1: status = _a.sent(); //@ts-ignore try { connection.removeSignatureListener(subId); } catch (e) { // ignore } done = true; return [2 /*return*/, status]; } }); }); }; exports.awaitTransactionSignatureConfirmation = awaitTransactionSignatureConfirmation; var createAssociatedTokenAccountInstruction = function (associatedTokenAddress, payer, walletAddress, splTokenMintAddress) { var 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: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: anchor.web3.SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false, }, ]; return new anchor.web3.TransactionInstruction({ keys: keys, programId: utils_1.SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID, data: Buffer.from([]), }); }; var getCandyMachineState = function (anchorWallet, candyMachineId, connection) { return __awaiter(void 0, void 0, void 0, function () { var provider, getProgramState, getCurrentBlockTime, _a, _b, program, state, currentBlockTime, itemsAvailable, itemsRedeemed, itemsRemaining, timeDiff, goLiveDate; return __generator(this, function (_c) { switch (_c.label) { case 0: provider = new anchor.Provider(connection, anchorWallet, { preflightCommitment: "processed", }); getProgramState = function () { return __awaiter(void 0, void 0, void 0, function () { var idl, program, state; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, anchor.Program.fetchIdl(exports.CANDY_MACHINE_PROGRAM, provider)]; case 1: idl = _a.sent(); program = new anchor.Program(idl, exports.CANDY_MACHINE_PROGRAM, provider); return [4 /*yield*/, program.account.candyMachine.fetch(candyMachineId)]; case 2: state = _a.sent(); return [2 /*return*/, [program, state]]; } }); }); }; getCurrentBlockTime = function () { return __awaiter(void 0, void 0, void 0, function () { var slot; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, connection.getSlot()]; case 1: slot = _b.sent(); return [4 /*yield*/, connection.getBlockTime(slot)]; case 2: return [2 /*return*/, (_a = (_b.sent())) !== null && _a !== void 0 ? _a : new Date().getTime() / 1000]; } }); }); }; return [4 /*yield*/, Promise.all([getProgramState(), getCurrentBlockTime()])]; case 1: _a = _c.sent(), _b = _a[0], program = _b[0], state = _b[1], currentBlockTime = _a[1]; itemsAvailable = state.data.itemsAvailable.toNumber(); itemsRedeemed = state.itemsRedeemed.toNumber(); itemsRemaining = itemsAvailable - itemsRedeemed; timeDiff = new Date().getTime() / 1000 - currentBlockTime; goLiveDate = state.data.goLiveDate !== null ? state.data.goLiveDate + timeDiff : null; return [2 /*return*/, { id: candyMachineId, program: program, state: { authority: state.authority, itemsAvailable: itemsAvailable, itemsRedeemed: itemsRedeemed, itemsRemaining: 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, }, }]; } }); }); }; exports.getCandyMachineState = getCandyMachineState; var getMasterEdition = function (mint) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, anchor.web3.PublicKey.findProgramAddress([Buffer.from("metadata"), exports.TOKEN_METADATA_PROGRAM_ID.toBuffer(), mint.toBuffer(), Buffer.from("edition")], exports.TOKEN_METADATA_PROGRAM_ID)]; case 1: return [2 /*return*/, (_a.sent())[0]]; } }); }); }; var getMetadataPDA = function (mint) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, anchor.web3.PublicKey.findProgramAddress([Buffer.from("metadata"), exports.TOKEN_METADATA_PROGRAM_ID.toBuffer(), mint.toBuffer()], exports.TOKEN_METADATA_PROGRAM_ID)]; case 1: return [2 /*return*/, (_a.sent())[0]]; } }); }); }; exports.getMetadataPDA = getMetadataPDA; var getCandyMachineCreator = function (candyMachine) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, anchor.web3.PublicKey.findProgramAddress([Buffer.from("candy_machine"), candyMachine.toBuffer()], exports.CANDY_MACHINE_PROGRAM)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; exports.getCandyMachineCreator = getCandyMachineCreator; var getCollectionPDA = function (candyMachineAddress) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, anchor.web3.PublicKey.findProgramAddress([Buffer.from("collection"), candyMachineAddress.toBuffer()], exports.CANDY_MACHINE_PROGRAM)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; exports.getCollectionPDA = getCollectionPDA; var getCollectionAuthorityRecordPDA = function (mint, newAuthority) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, anchor.web3.PublicKey.findProgramAddress([ Buffer.from("metadata"), exports.TOKEN_METADATA_PROGRAM_ID.toBuffer(), mint.toBuffer(), Buffer.from("collection_authority"), newAuthority.toBuffer(), ], exports.TOKEN_METADATA_PROGRAM_ID)]; case 1: return [2 /*return*/, (_a.sent())[0]]; } }); }); }; exports.getCollectionAuthorityRecordPDA = getCollectionAuthorityRecordPDA; var createAccountsForMint = function (candyMachine, payer) { return __awaiter(void 0, void 0, void 0, function () { var mint, userTokenAccountAddress, signers, instructions, _a, _b; var _c, _d; return __generator(this, function (_e) { switch (_e.label) { case 0: mint = anchor.web3.Keypair.generate(); return [4 /*yield*/, (0, utils_1.getAtaForMint)(mint.publicKey, payer)]; case 1: userTokenAccountAddress = (_e.sent())[0]; signers = [mint]; _b = (_a = anchor.web3.SystemProgram).createAccount; _c = { fromPubkey: payer, newAccountPubkey: mint.publicKey, space: spl_token_1.MintLayout.span }; return [4 /*yield*/, candyMachine.program.provider.connection.getMinimumBalanceForRentExemption(spl_token_1.MintLayout.span)]; case 2: instructions = [ _b.apply(_a, [(_c.lamports = _e.sent(), _c.programId = spl_token_1.TOKEN_PROGRAM_ID, _c)]), spl_token_1.Token.createInitMintInstruction(spl_token_1.TOKEN_PROGRAM_ID, mint.publicKey, 0, payer, payer), createAssociatedTokenAccountInstruction(userTokenAccountAddress, payer, payer, mint.publicKey), spl_token_1.Token.createMintToInstruction(spl_token_1.TOKEN_PROGRAM_ID, mint.publicKey, userTokenAccountAddress, payer, [], 1) ]; _d = { mint: mint, userTokenAccount: userTokenAccountAddress }; return [4 /*yield*/, (0, connection_1.sendTransactions)(candyMachine.program.provider.connection, candyMachine.program.provider.wallet, [instructions], [signers], connection_1.SequenceType.StopOnFailure, "singleGossip", function () { }, function () { return false; }, undefined, [], [])]; case 3: return [2 /*return*/, (_d.transaction = (_e.sent()).txs[0].txid, _d)]; } }); }); }; exports.createAccountsForMint = createAccountsForMint; var mintOneToken = function (candyMachine, payer, beforeTransactions, afterTransactions, setupState) { if (beforeTransactions === void 0) { beforeTransactions = []; } if (afterTransactions === void 0) { afterTransactions = []; } return __awaiter(void 0, void 0, void 0, function () { var mint, userTokenAccountAddress, userPayingAccountAddress, _a, candyMachineAddress, remainingAccounts, instructions, signers, _b, _c, _d, _e, _f, _g, _h, _j, _k, mint_1, whitelistToken, metadataAddress, masterEdition, _l, candyMachineCreator, creatorBump, _m, _o, collectionPDA, collectionPDAAccount, collectionData, collectionMint, collectionAuthorityRecord, collectionMetadata, collectionMasterEdition, _p, _q, error_1, instructionsMatrix, signersMatrix, txns, mintTxn, e_2; var _r, _s, _t; var _u; return __generator(this, function (_v) { switch (_v.label) { case 0: mint = (_u = setupState === null || setupState === void 0 ? void 0 : setupState.mint) !== null && _u !== void 0 ? _u : anchor.web3.Keypair.generate(); return [4 /*yield*/, (0, utils_1.getAtaForMint)(mint.publicKey, payer)]; case 1: userTokenAccountAddress = (_v.sent())[0]; if (!candyMachine.state.tokenMint) return [3 /*break*/, 3]; return [4 /*yield*/, (0, utils_1.getAtaForMint)(candyMachine.state.tokenMint, payer)]; case 2: _a = (_v.sent())[0]; return [3 /*break*/, 4]; case 3: _a = payer; _v.label = 4; case 4: userPayingAccountAddress = _a; candyMachineAddress = candyMachine.id; remainingAccounts = []; instructions = []; signers = []; console.log("SetupState: ", setupState); if (!!setupState) return [3 /*break*/, 6]; signers.push(mint); _c = (_b = instructions.push).apply; _d = [instructions]; _f = (_e = anchor.web3.SystemProgram).createAccount; _r = { fromPubkey: payer, newAccountPubkey: mint.publicKey, space: spl_token_1.MintLayout.span }; return [4 /*yield*/, candyMachine.program.provider.connection.getMinimumBalanceForRentExemption(spl_token_1.MintLayout.span)]; case 5: _c.apply(_b, _d.concat([[ _f.apply(_e, [(_r.lamports = _v.sent(), _r.programId = spl_token_1.TOKEN_PROGRAM_ID, _r)]), spl_token_1.Token.createInitMintInstruction(spl_token_1.TOKEN_PROGRAM_ID, mint.publicKey, 0, payer, payer), createAssociatedTokenAccountInstruction(userTokenAccountAddress, payer, payer, mint.publicKey), spl_token_1.Token.createMintToInstruction(spl_token_1.TOKEN_PROGRAM_ID, mint.publicKey, userTokenAccountAddress, payer, [], 1) ]])); _v.label = 6; case 6: if (!candyMachine.state.gatekeeper) return [3 /*break*/, 9]; _h = (_g = remainingAccounts).push; _s = {}; return [4 /*yield*/, (0, utils_1.getNetworkToken)(payer, candyMachine.state.gatekeeper.gatekeeperNetwork)]; case 7: _h.apply(_g, [(_s.pubkey = (_v.sent())[0], _s.isWritable = true, _s.isSigner = false, _s)]); if (!candyMachine.state.gatekeeper.expireOnUse) return [3 /*break*/, 9]; remainingAccounts.push({ pubkey: utils_1.CIVIC, isWritable: false, isSigner: false, }); _k = (_j = remainingAccounts).push; _t = {}; return [4 /*yield*/, (0, utils_1.getNetworkExpire)(candyMachine.state.gatekeeper.gatekeeperNetwork)]; case 8: _k.apply(_j, [(_t.pubkey = (_v.sent())[0], _t.isWritable = false, _t.isSigner = false, _t)]); _v.label = 9; case 9: if (!candyMachine.state.whitelistMintSettings) return [3 /*break*/, 11]; mint_1 = new anchor.web3.PublicKey(candyMachine.state.whitelistMintSettings.mint); return [4 /*yield*/, (0, utils_1.getAtaForMint)(mint_1, payer)]; case 10: whitelistToken = (_v.sent())[0]; remainingAccounts.push({ pubkey: whitelistToken, isWritable: true, isSigner: false, }); if (candyMachine.state.whitelistMintSettings.mode.burnEveryTime) { remainingAccounts.push({ pubkey: mint_1, isWritable: true, isSigner: false, }); remainingAccounts.push({ pubkey: payer, isWritable: false, isSigner: true, }); } _v.label = 11; case 11: if (candyMachine.state.tokenMint) { remainingAccounts.push({ pubkey: userPayingAccountAddress, isWritable: true, isSigner: false, }); remainingAccounts.push({ pubkey: payer, isWritable: false, isSigner: true, }); } return [4 /*yield*/, (0, exports.getMetadataPDA)(mint.publicKey)]; case 12: metadataAddress = _v.sent(); return [4 /*yield*/, getMasterEdition(mint.publicKey)]; case 13: masterEdition = _v.sent(); return [4 /*yield*/, (0, exports.getCandyMachineCreator)(candyMachineAddress)]; case 14: _l = _v.sent(), candyMachineCreator = _l[0], creatorBump = _l[1]; console.log(remainingAccounts.map(function (rm) { return rm.pubkey.toBase58(); })); _o = (_m = instructions).push; return [4 /*yield*/, candyMachine.program.instruction.mintNft(creatorBump, { accounts: { candyMachine: candyMachineAddress, candyMachineCreator: candyMachineCreator, payer: payer, wallet: candyMachine.state.treasury, mint: mint.publicKey, metadata: metadataAddress, masterEdition: masterEdition, mintAuthority: payer, updateAuthority: payer, tokenMetadataProgram: exports.TOKEN_METADATA_PROGRAM_ID, tokenProgram: spl_token_1.TOKEN_PROGRAM_ID, systemProgram: web3_js_1.SystemProgram.programId, rent: anchor.web3.SYSVAR_RENT_PUBKEY, clock: anchor.web3.SYSVAR_CLOCK_PUBKEY, recentBlockhashes: web3_js_1.SYSVAR_SLOT_HASHES_PUBKEY, instructionSysvarAccount: anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY, }, remainingAccounts: remainingAccounts.length > 0 ? remainingAccounts : undefined, })]; case 15: _o.apply(_m, [_v.sent()]); return [4 /*yield*/, (0, exports.getCollectionPDA)(candyMachineAddress)]; case 16: collectionPDA = (_v.sent())[0]; return [4 /*yield*/, candyMachine.program.provider.connection.getAccountInfo(collectionPDA)]; case 17: collectionPDAAccount = _v.sent(); if (!(collectionPDAAccount && candyMachine.state.retainAuthority)) return [3 /*break*/, 26]; _v.label = 18; case 18: _v.trys.push([18, 25, , 26]); return [4 /*yield*/, candyMachine.program.account.collectionPda.fetch(collectionPDA)]; case 19: collectionData = (_v.sent()); collectionMint = collectionData.mint; return [4 /*yield*/, (0, exports.getCollectionAuthorityRecordPDA)(collectionMint, collectionPDA)]; case 20: collectionAuthorityRecord = _v.sent(); if (!collectionMint) return [3 /*break*/, 24]; return [4 /*yield*/, (0, exports.getMetadataPDA)(collectionMint)]; case 21: collectionMetadata = _v.sent(); return [4 /*yield*/, getMasterEdition(collectionMint)]; case 22: collectionMasterEdition = _v.sent(); console.log("Collection PDA: ", collectionPDA.toBase58()); console.log("Authority: ", candyMachine.state.authority.toBase58()); _q = (_p = instructions).push; return [4 /*yield*/, candyMachine.program.instruction.setCollectionDuringMint({ accounts: { candyMachine: candyMachineAddress, metadata: metadataAddress, payer: payer, collectionPda: collectionPDA, tokenMetadataProgram: exports.TOKEN_METADATA_PROGRAM_ID, instructions: anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY, collectionMint: collectionMint, collectionMetadata: collectionMetadata, collectionMasterEdition: collectionMasterEdition, authority: candyMachine.state.authority, collectionAuthorityRecord: collectionAuthorityRecord, }, })]; case 23: _q.apply(_p, [_v.sent()]); _v.label = 24; case 24: return [3 /*break*/, 26]; case 25: error_1 = _v.sent(); console.error(error_1); return [3 /*break*/, 26]; case 26: instructionsMatrix = [instructions]; signersMatrix = [signers]; _v.label = 27; case 27: _v.trys.push([27, 29, , 30]); return [4 /*yield*/, (0, connection_1.sendTransactions)(candyMachine.program.provider.connection, candyMachine.program.provider.wallet, instructionsMatrix, signersMatrix, connection_1.SequenceType.StopOnFailure, "singleGossip", function () { }, function () { return false; }, undefined, beforeTransactions, afterTransactions)]; case 28: txns = (_v.sent()).txs.map(function (t) { return t.txid; }); mintTxn = txns[0]; return [2 /*return*/, { mintTxId: mintTxn, metadataKey: metadataAddress, }]; case 29: e_2 = _v.sent(); console.log(e_2); return [3 /*break*/, 30]; case 30: return [2 /*return*/, null]; } }); }); }; exports.mintOneToken = mintOneToken; var shortenAddress = function (address, chars) { if (chars === void 0) { chars = 4; } return "".concat(address.slice(0, chars), "...").concat(address.slice(-chars)); }; exports.shortenAddress = shortenAddress; var sleep = function (ms) { return new Promise(function (resolve) { return setTimeout(resolve, ms); }); };