115 lines
3.3 KiB
JavaScript
115 lines
3.3 KiB
JavaScript
#!/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,
|
|
createInitializeNonTransferableMintInstruction,
|
|
createInitializePermanentDelegateInstruction,
|
|
} = require("@solana/spl-token");
|
|
const {
|
|
parseEnvConfig,
|
|
assertRequired,
|
|
resolveConfigPath,
|
|
loadKeypair,
|
|
saveKeypair,
|
|
parseCluster,
|
|
nowStamp,
|
|
} = require("./_common");
|
|
|
|
async function main() {
|
|
const configPath = resolveConfigPath(process.argv[2]);
|
|
const cfg = parseEnvConfig(configPath);
|
|
assertRequired(cfg, "GT_CLUSTER");
|
|
assertRequired(cfg, "GT_OPERATOR_KEYPAIR_PATH");
|
|
assertRequired(cfg, "GT_RUNS_DIR");
|
|
|
|
const operator = loadKeypair(path.resolve(cfg.GT_OPERATOR_KEYPAIR_PATH));
|
|
const connection = new Connection(parseCluster(cfg.GT_CLUSTER), "confirmed");
|
|
|
|
let mint;
|
|
if (cfg.GT_MINT_KEYPAIR_PATH) {
|
|
mint = loadKeypair(path.resolve(cfg.GT_MINT_KEYPAIR_PATH));
|
|
} else {
|
|
mint = Keypair.generate();
|
|
}
|
|
|
|
const extensions = [ExtensionType.NonTransferable, ExtensionType.PermanentDelegate];
|
|
const mintLen = getMintLen(extensions);
|
|
const rent = await connection.getMinimumBalanceForRentExemption(mintLen, "confirmed");
|
|
|
|
const tx = new Transaction().add(
|
|
SystemProgram.createAccount({
|
|
fromPubkey: operator.publicKey,
|
|
newAccountPubkey: mint.publicKey,
|
|
space: mintLen,
|
|
lamports: rent,
|
|
programId: TOKEN_2022_PROGRAM_ID,
|
|
}),
|
|
createInitializeNonTransferableMintInstruction(mint.publicKey, TOKEN_2022_PROGRAM_ID),
|
|
createInitializePermanentDelegateInstruction(
|
|
mint.publicKey,
|
|
operator.publicKey,
|
|
TOKEN_2022_PROGRAM_ID
|
|
),
|
|
createInitializeMintInstruction(
|
|
mint.publicKey,
|
|
0,
|
|
operator.publicKey,
|
|
operator.publicKey,
|
|
TOKEN_2022_PROGRAM_ID
|
|
)
|
|
);
|
|
|
|
const sig = await sendAndConfirmTransaction(connection, tx, [operator, mint], {
|
|
commitment: "confirmed",
|
|
});
|
|
|
|
const runsDir = path.resolve(cfg.GT_RUNS_DIR);
|
|
fs.mkdirSync(runsDir, { recursive: true });
|
|
|
|
const outMintPath =
|
|
cfg.GT_MINT_KEYPAIR_PATH && cfg.GT_MINT_KEYPAIR_PATH.trim()
|
|
? path.resolve(cfg.GT_MINT_KEYPAIR_PATH)
|
|
: path.join(runsDir, `${nowStamp()}_mint-keypair.json`);
|
|
saveKeypair(outMintPath, mint);
|
|
|
|
const report = {
|
|
createdAt: new Date().toISOString(),
|
|
cluster: cfg.GT_CLUSTER,
|
|
operator: operator.publicKey.toBase58(),
|
|
mint: mint.publicKey.toBase58(),
|
|
tokenProgram: TOKEN_2022_PROGRAM_ID.toBase58(),
|
|
nonTransferable: true,
|
|
permanentDelegate: operator.publicKey.toBase58(),
|
|
mintAuthority: operator.publicKey.toBase58(),
|
|
freezeAuthority: operator.publicKey.toBase58(),
|
|
mintKeypairPath: outMintPath,
|
|
txCreateMint: sig,
|
|
};
|
|
const reportPath = path.join(runsDir, `${nowStamp()}_create_token.json`);
|
|
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
|
|
console.log("Governance token создан.");
|
|
console.log("Mint:", mint.publicKey.toBase58());
|
|
console.log("Mint keypair:", outMintPath);
|
|
console.log("Tx:", sig);
|
|
console.log("Report:", reportPath);
|
|
}
|
|
|
|
main().catch((e) => {
|
|
console.error("Ошибка создания governance token:", e?.message || e);
|
|
process.exit(1);
|
|
});
|