O Que Significa Fechar uma Conta de Token?
Fechar uma conta de token exclui a conta e retorna os lamports de rent da conta de token para uma conta de destino.
O saldo de tokens deve ser zero antes que a conta possa ser fechada. Uma conta congelada ainda pode ser fechada se o saldo de tokens da conta congelada for zero. As contas de token de SOL encapsulado são a exceção e podem ser fechadas com saldo de tokens para recuperar o SOL subjacente. O proprietário da conta ou a autoridade de fechamento da conta assina a instrução de fechamento.
Como Fechar uma Conta de Token
Fechar uma conta de token usa a instrução CloseAccount do Token Program.
A instrução CloseAccount transfere os lamports da conta de origem para uma
conta de destino, limpa a conta de origem e exclui a conta de origem. O Token
Extension Program aplica verificações adicionais de fechamento para certas
extensões, mas o fluxo básico de fechamento é o mesmo.
Referência da Fonte
| Item | Descrição | Token Program | Token Extension Program |
|---|---|---|---|
Account | O estado da conta de token armazena o saldo, status nativo e autoridade de fechamento usados durante o fechamento da conta. | Fonte | Fonte |
CloseAccount | Uma instrução que fecha uma conta de token e transfere os lamports da conta de token para uma conta de destino. | Fonte | Fonte |
process_close_account | Lógica de processador compartilhada para fechamento de conta de token. | Fonte | Fonte |
Typescript
Os exemplos abaixo mostram a abordagem recomendada usando @solana/kit.
Exemplos legados usando @solana/web3.js estão incluídos para referência.
Kit
import { generateKeyPairSigner } from "@solana/kit";import { createLocalClient } from "@solana/kit-client-rpc";import {findAssociatedTokenPda,getCreateAssociatedTokenInstructionAsync,tokenProgram,TOKEN_PROGRAM_ADDRESS} from "@solana-program/token";const client = await createLocalClient().use(tokenProgram());const mint = await generateKeyPairSigner();const destination = client.payer.address;const [tokenAccount] = await findAssociatedTokenPda({mint: mint.address,owner: client.payer.address,tokenProgram: TOKEN_PROGRAM_ADDRESS});const result = await client.token.instructions.closeAccount({account: tokenAccount, // Token account to close.destination, // Account receiving the reclaimed SOL.owner: client.payer // Owner approving the account closure.}).sendTransaction();const tokenAccountData =await client.token.accounts.token.fetchMaybe(tokenAccount);console.log("Mint Address:", mint.address);console.log("\nToken Account Address:", tokenAccount);console.log("Token Account:", tokenAccountData);console.log("\nDestination Address:", destination);console.log("\nTransaction Signature:", result.context.signature);
Web3.js
import { Connection, Keypair, LAMPORTS_PER_SOL } from "@solana/web3.js";import {createAssociatedTokenAccount,closeAccount,createMint,TOKEN_PROGRAM_ID} from "@solana/spl-token";const result = await closeAccount(connection, // Connection to the local validator.feePayer, // Account paying transaction fees.associatedTokenAccount, // Token account to close.destination, // Account receiving the reclaimed SOL.feePayer, // Owner approving the account closure.[], // Additional multisig signers.{commitment: "confirmed" // Confirmation options for the transaction.},TOKEN_PROGRAM_ID // Token program to invoke.);const tokenAccountData = await connection.getAccountInfo(associatedTokenAccount,"confirmed");console.log("Mint Address:", mintPubkey.toBase58());console.log("\nAssociated Token Account Address:",associatedTokenAccount.toBase58());console.log("Associated Token Account:", tokenAccountData);console.log("\nDestination Address:", destination.toBase58());console.log("\nTransaction Signature:", result);
Rust
use anyhow::Result;use solana_client::nonblocking::rpc_client::RpcClient;use solana_commitment_config::CommitmentConfig;use solana_sdk::{program_pack::Pack,signature::{Keypair, Signer},transaction::Transaction,};use solana_system_interface::instruction::create_account;use spl_associated_token_account_interface::{address::get_associated_token_address, instruction::create_associated_token_account,};use spl_token_interface::{id as token_program_id,instruction::{close_account, initialize_mint},state::{Account, Mint},};#[tokio::main]async fn main() -> Result<()> {let client = RpcClient::new_with_commitment(String::from("http://localhost:8899"),CommitmentConfig::confirmed(),);let associated_token_address = get_associated_token_address(&fee_payer.pubkey(), &mint.pubkey());let destination = fee_payer.pubkey();let transaction = Transaction::new_signed_with_payer(&[close_account(&token_program_id(), // Token program to invoke.&associated_token_address, // Token account to close.&destination, // Account receiving the reclaimed SOL.&fee_payer.pubkey(), // Owner approving the account closure.&[], // Additional multisig signers.)?,],Some(&fee_payer.pubkey()),&[&fee_payer],latest_blockhash,);let transaction_signature = client.send_and_confirm_transaction(&transaction).await?;let token_data = match client.get_account(&associated_token_address).await {Ok(account) => Some(Account::unpack(&account.data)?),Err(_) => None,};println!("Mint Address: {}", mint.pubkey());println!("\nAssociated Token Account Address: {}",associated_token_address);println!("Associated Token Account: {:#?}", token_data);println!("\nDestination Address: {}", destination);println!("\nTransaction Signature: {}", transaction_signature);Ok(())}
Python
#!/usr/bin/env python3import asyncioimport jsonfrom solana.rpc.async_api import AsyncClientfrom solders.keypair import Keypairfrom solders.message import Messagefrom solders.system_program import create_account, CreateAccountParamsfrom solders.transaction import Transactionfrom spl.token.async_client import AsyncTokenfrom spl.token.instructions import (close_account,CloseAccountParams,create_associated_token_account,get_associated_token_address,initialize_mint,InitializeMintParams,)from spl.token.constants import MINT_LEN, TOKEN_PROGRAM_IDasync def main():rpc = AsyncClient("http://localhost:8899")async with rpc:close_account_instruction = close_account(CloseAccountParams(program_id=TOKEN_PROGRAM_ID, # Token program to invoke.account=token_account_address, # Token account to close.dest=fee_payer.pubkey(), # Account receiving the reclaimed lamports.owner=fee_payer.pubkey(), # Account allowed to close the token account.))latest_blockhash = await rpc.get_latest_blockhash()transaction = Transaction([fee_payer],Message([close_account_instruction], fee_payer.pubkey()),latest_blockhash.value.blockhash,)result = await rpc.send_transaction(transaction)closed_token_account = (await rpc.get_account_info(token_account_address)).valueprint("Mint Address:", mint.pubkey())print("\nToken Account Address:", token_account_address)print("Token Account:")print(json.dumps(closed_token_account, indent=2))print("\nTransaction Signature:", result.value)if __name__ == "__main__":asyncio.run(main())
Is this page helpful?