ミントのクローズ
MintCloseAuthority拡張機能を有効にする方法
MintCloseAuthority
拡張機能により、mint
accountをクローズしてrentを回収することが可能になります。この拡張機能はmintの作成時に初期化する必要があります。
指定されたクローズ権限を持つ者だけがmint accountをクローズできます。token accountがトークン残高がゼロの場合にのみクローズできるのと同様に、この拡張機能を持つmint accountは、トークンの供給量全体がゼロに減少した場合にのみクローズできます。
Typescript
import {airdropFactory,appendTransactionMessageInstructions,createSolanaRpc,createSolanaRpcSubscriptions,createTransactionMessage,generateKeyPairSigner,getSignatureFromTransaction,lamports,pipe,sendAndConfirmTransactionFactory,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,signTransactionMessageWithSigners} from "@solana/kit";import { getCreateAccountInstruction } from "@solana-program/system";import {getInitializeMintInstruction,getMintSize,TOKEN_2022_PROGRAM_ADDRESS,extension,getInitializeMintCloseAuthorityInstruction,getCloseAccountInstruction} from "@solana-program/token-2022";// Create Connection, local validator in this exampleconst rpc = createSolanaRpc("http://localhost:8899");const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");// Generate the authority for the mint, (will also act as the fee payer)// and destination to receive recovered SOL after closing the mintconst authority = await generateKeyPairSigner();const destination = await generateKeyPairSigner();// Fund authority/fee payerawait airdropFactory({ rpc, rpcSubscriptions })({recipientAddress: authority.address,lamports: lamports(5_000_000_000n), // 5 SOLcommitment: "confirmed"});// Generate keypair to use as address of mintconst mint = await generateKeyPairSigner();// And a mint close authority extension.const mintCloseAuthorityExtension = extension("MintCloseAuthority", {closeAuthority: authority.address});// Get default mint account size (in bytes), with the close mint extensionconst space = BigInt(getMintSize([mintCloseAuthorityExtension]));// Get minimum balance for rent exemptionconst rent = await rpc.getMinimumBalanceForRentExemption(space).send();// Get latest blockhash to include in transactionconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();// Instruction to create new account for mint (token program)// Invokes the system programconst createAccountInstruction = getCreateAccountInstruction({payer: authority,newAccount: mint,lamports: rent,space,programAddress: TOKEN_2022_PROGRAM_ADDRESS});// Instruction to initialize the close mint authority extensionconst initializeCloseMintInstruction =getInitializeMintCloseAuthorityInstruction({mint: mint.address,closeAuthority: mintCloseAuthorityExtension.closeAuthority});// Instruction to initialize mint account data// Invokes the token programconst initializeMintInstruction = getInitializeMintInstruction({mint: mint.address,decimals: 9,mintAuthority: authority.address});const instructions = [createAccountInstruction,initializeCloseMintInstruction,initializeMintInstruction];// Create transaction messageconst transactionMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(authority, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),(tx) => appendTransactionMessageInstructions(instructions, tx));// Sign transaction message with all required signersconst signedTransaction =await signTransactionMessageWithSigners(transactionMessage);// Send and confirm transactionawait sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction,{ commitment: "confirmed", skipPreflight: true });// // Get transaction signatureconst transactionSignature = getSignatureFromTransaction(signedTransaction);console.log("Mint Address:", mint.address.toString());console.log("Transaction Signature:", transactionSignature);// Get a fresh blockhash for the close mint extension instructionconst { value: latestBlockhash2 } = await rpc.getLatestBlockhash().send();const closeMintInstruction = getCloseAccountInstruction({account: mint.address,destination: destination.address,owner: authority});// Create transaction message for close mint extensionconst closeMintMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(authority, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash2, tx),(tx) => appendTransactionMessageInstructions([closeMintInstruction], tx));// Sign transaction message with all required signersconst signedCloseMintTx =await signTransactionMessageWithSigners(closeMintMessage);// Send and confirm transactionawait sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedCloseMintTx,{ commitment: "confirmed" });// Get transaction signatureconst closeMintTxSig = getSignatureFromTransaction(signedCloseMintTx);console.log("\nDestination Address:", destination.address.toString());console.log("Transaction Signature:", closeMintTxSig);
Console
Click to execute the code.
Rust
use anyhow::Result;use solana_client::nonblocking::rpc_client::RpcClient;use solana_sdk::{commitment_config::CommitmentConfig,signature::{Keypair, Signer},system_instruction::create_account,transaction::Transaction,};use spl_token_2022::{ID as TOKEN_2022_ID,extension::ExtensionType,instruction::{close_account, initialize_mint, initialize_mint_close_authority},state::Mint,};#[tokio::main]async fn main() -> Result<()> {// Create connection to local validatorlet client = RpcClient::new_with_commitment(String::from("http://localhost:8899"),CommitmentConfig::confirmed(),);let latest_blockhash = client.get_latest_blockhash().await?;// Generate a new keypair for the fee payerlet fee_payer = Keypair::new();// Generate a keypair for the destinationlet destination = Keypair::new();// Airdrop 5 SOL to fee payerlet airdrop_signature = client.request_airdrop(&fee_payer.pubkey(), 5_000_000_000).await?;client.confirm_transaction(&airdrop_signature).await?;loop {let confirmed = client.confirm_transaction(&airdrop_signature).await?;if confirmed {break;}}// Generate keypair to use as address of mintlet mint = Keypair::new();// Get default mint account size (in bytes),let mint_space =ExtensionType::try_calculate_account_len::<Mint>(&[ExtensionType::MintCloseAuthority])?;// get the rent in lamports for the mint accountlet mint_rent = client.get_minimum_balance_for_rent_exemption(mint_space).await?;// Instruction to create new account for mint (token program)let create_account_instruction = create_account(&fee_payer.pubkey(), // payer&mint.pubkey(), // new account (mint)mint_rent, // lamportsmint_space as u64, // space&TOKEN_2022_ID, // program id);let initialize_close_mint_instruction = initialize_mint_close_authority(&TOKEN_2022_ID, // token program&mint.pubkey(), // mintSome(&fee_payer.pubkey()), // close authority)?;// Instruction to initialize mint account datalet initialize_mint_instruction = initialize_mint(&TOKEN_2022_ID, // token program&mint.pubkey(), // mint&fee_payer.pubkey(), // mint authoritySome(&fee_payer.pubkey()), // freeze authority9, // decimals)?;// Create transaction and add instructionslet transaction = Transaction::new_signed_with_payer(&[create_account_instruction,initialize_close_mint_instruction,initialize_mint_instruction,],Some(&fee_payer.pubkey()),&[&fee_payer, &mint],latest_blockhash,);// Send and confirm transactionlet transaction_signature = client.send_and_confirm_transaction(&transaction).await?;println!("Mint Address: {}", mint.pubkey());println!("\nTransaction Signature: {}", transaction_signature);// Get the latest blockhash for the close transactionlet latest_blockhash = client.get_latest_blockhash().await?;let close_mint_instruction = close_account(&TOKEN_2022_ID, // token program&mint.pubkey(), // mint&destination.pubkey(), // destination&fee_payer.pubkey(), // authority&[&fee_payer.pubkey()], // signer keys)?;// Create transaction for closing the mint accountlet transaction = Transaction::new_signed_with_payer(&[close_mint_instruction],Some(&fee_payer.pubkey()),&[&fee_payer],latest_blockhash,);// Send and confirm transactionlet transaction_signature = client.send_and_confirm_transaction(&transaction).await?;println!("\nDestination Address: {}", destination.pubkey());println!("Transaction Signature: {}", transaction_signature);Ok(())}
Console
Click to execute the code.
Is this page helpful?