#!/usr/bin/env node "use strict"; const fs = require("fs"); const path = require("path"); const { Connection, Keypair, SystemProgram, Transaction, sendAndConfirmTransaction } = require("@solana/web3.js"); const { TOKEN_2022_PROGRAM_ID, ExtensionType, getMintLen, createInitializeMintInstruction, createInitializePermanentDelegateInstruction, createInitializeNonTransferableMintInstruction, createSetAuthorityInstruction, AuthorityType, } = require("@solana/spl-token"); const { parseEnvConfig, resolveConfigPath, loadKeypair, clusterUrl, nowStamp, PublicKey } = require("./js_common"); async function main() { const cfg = parseEnvConfig(resolveConfigPath(process.argv[2])); const conn = new Connection(clusterUrl(cfg.CLUSTER), "confirmed"); const main = loadKeypair(path.resolve(__dirname, cfg.MAIN_KEYPAIR)); const governance = new PublicKey(cfg.GOVERNANCE); const mint = Keypair.generate(); const mintLen = getMintLen([ExtensionType.NonTransferable, ExtensionType.PermanentDelegate]); const rentMint = await conn.getMinimumBalanceForRentExemption(mintLen, "confirmed"); const tx = new Transaction().add( SystemProgram.createAccount({ fromPubkey: main.publicKey, newAccountPubkey: mint.publicKey, space: mintLen, lamports: rentMint, programId: TOKEN_2022_PROGRAM_ID }), createInitializeNonTransferableMintInstruction(mint.publicKey, TOKEN_2022_PROGRAM_ID), createInitializePermanentDelegateInstruction(mint.publicKey, main.publicKey, TOKEN_2022_PROGRAM_ID), createInitializeMintInstruction(mint.publicKey, 0, main.publicKey, main.publicKey, TOKEN_2022_PROGRAM_ID), createSetAuthorityInstruction(mint.publicKey, main.publicKey, AuthorityType.MintTokens, governance, [], TOKEN_2022_PROGRAM_ID), createSetAuthorityInstruction(mint.publicKey, main.publicKey, AuthorityType.FreezeAccount, governance, [], TOKEN_2022_PROGRAM_ID), createSetAuthorityInstruction(mint.publicKey, main.publicKey, AuthorityType.PermanentDelegate, governance, [], TOKEN_2022_PROGRAM_ID) ); const sig = await sendAndConfirmTransaction(conn, tx, [main, mint], { commitment: "confirmed" }); const runs = path.resolve(__dirname, cfg.RUNS_DIR || "./runs"); fs.mkdirSync(runs, { recursive: true }); const rp = path.join(runs, `${nowStamp()}_empty_nft_template.json`); fs.writeFileSync(rp, JSON.stringify({ mint: mint.publicKey.toBase58(), tx: sig, createdAt: new Date().toISOString() }, null, 2)); console.log("EMPTY NFT template created"); console.log("mint:", mint.publicKey.toBase58()); console.log("report:", rp); } main().catch((e)=>{console.error(e?.message||e);process.exit(1);});