Create and manage SPL token accounts for holding tokens on Solana. This includes creating Associated Token Accounts (ATAs) and closing empty accounts to reclaim SOL.Documentation Index
Fetch the complete documentation index at: https://docs.getpara.com/llms.txt
Use this file to discover all available pages before exploring further.
- @solana/kit
- @solana/web3.js
- Anchor
import { useParaSolanaSigner, useParaSolanaSignAndSend } from "@getpara/react-native-wallet/solana";
import {
createSolanaRpc,
pipe,
createTransactionMessage,
setTransactionMessageFeePayer,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction,
address
} from '@solana/kit';
import {
getCreateAssociatedTokenAccountInstruction,
findAssociatedTokenPda,
getCloseAccountInstruction
} from '@solana-program/token';
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
function ManageTokenAccounts() {
const { solanaSigner, isLoading } = useParaSolanaSigner({ rpc });
const { signAndSendAsync, isPending } = useParaSolanaSignAndSend(solanaSigner);
const createTokenAccount = async (mint: string, owner?: string) => {
if (!solanaSigner) return;
const mintAddress = address(mint);
const ownerAddress = owner ? address(owner) : solanaSigner.address;
const [ata] = await findAssociatedTokenPda({
mint: mintAddress,
owner: ownerAddress,
});
const accountInfo = await rpc.getAccountInfo(ata).send();
if (accountInfo.value) {
console.log("Token account already exists:", ata);
return ata;
}
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
tx => setTransactionMessageFeePayer(solanaSigner.address, tx),
tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
tx => appendTransactionMessageInstruction(
getCreateAssociatedTokenAccountInstruction({
ata,
mint: mintAddress,
owner: ownerAddress,
payer: solanaSigner,
}),
tx
)
);
try {
const signature = await signAndSendAsync({ transactionMessage });
console.log("Created token account:", ata);
console.log("Transaction signature:", signature);
return ata;
} catch (error) {
console.error("Failed to create token account:", error);
throw error;
}
};
const closeTokenAccount = async (tokenAccount: string) => {
if (!solanaSigner) return;
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
tx => setTransactionMessageFeePayer(solanaSigner.address, tx),
tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
tx => appendTransactionMessageInstruction(
getCloseAccountInstruction({
account: address(tokenAccount),
destination: solanaSigner.address,
authority: solanaSigner,
}),
tx
)
);
try {
const signature = await signAndSendAsync({ transactionMessage });
console.log("Closed token account:", tokenAccount);
console.log("Transaction signature:", signature);
return signature;
} catch (error) {
console.error("Failed to close token account:", error);
throw error;
}
};
return (
<div>
<button onClick={() => createTokenAccount("USDC_MINT_ADDRESS")}>
Create USDC Account
</button>
<button onClick={() => closeTokenAccount("TOKEN_ACCOUNT_ADDRESS")}>
Close Token Account
</button>
</div>
);
}
import { useParaSolana } from './hooks/useParaSolana';
import { Transaction, PublicKey } from '@solana/web3.js';
import {
createAssociatedTokenAccountInstruction,
getAssociatedTokenAddress,
createCloseAccountInstruction,
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
} from '@solana/spl-token';
function ManageTokenAccounts() {
const { connection, signer } = useParaSolana();
const createTokenAccount = async (mint: string, owner?: string) => {
const mintPubkey = new PublicKey(mint);
const ownerPubkey = owner ? new PublicKey(owner) : signer.sender;
const ata = await getAssociatedTokenAddress(mintPubkey, ownerPubkey);
const accountInfo = await connection.getAccountInfo(ata);
if (accountInfo) {
console.log("Token account already exists:", ata.toString());
return ata;
}
const transaction = new Transaction().add(
createAssociatedTokenAccountInstruction(
signer.sender,
ata,
ownerPubkey,
mintPubkey,
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
)
);
try {
const signature = await signer.sendTransaction(transaction);
console.log("Created token account:", ata.toString());
console.log("Transaction signature:", signature);
return ata;
} catch (error) {
console.error("Failed to create token account:", error);
throw error;
}
};
const closeTokenAccount = async (tokenAccount: string) => {
const tokenAccountPubkey = new PublicKey(tokenAccount);
const transaction = new Transaction().add(
createCloseAccountInstruction(
tokenAccountPubkey,
signer.sender,
signer.sender,
[],
TOKEN_PROGRAM_ID
)
);
try {
const signature = await signer.sendTransaction(transaction);
console.log("Closed token account:", tokenAccount);
console.log("Transaction signature:", signature);
return signature;
} catch (error) {
console.error("Failed to close token account:", error);
throw error;
}
};
return (
<div>
<button onClick={() => createTokenAccount("USDC_MINT_ADDRESS")}>
Create USDC Account
</button>
<button onClick={() => closeTokenAccount("TOKEN_ACCOUNT_ADDRESS")}>
Close Token Account
</button>
</div>
);
}
import { useParaAnchor } from './hooks/useParaAnchor';
import { Transaction, PublicKey } from '@solana/web3.js';
import {
createAssociatedTokenAccountInstruction,
getAssociatedTokenAddress,
createCloseAccountInstruction,
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
} from '@solana/spl-token';
function ManageTokenAccounts() {
const provider = useParaAnchor();
const createTokenAccount = async (mint: string, owner?: string) => {
const mintPubkey = new PublicKey(mint);
const ownerPubkey = owner ? new PublicKey(owner) : provider.publicKey;
const ata = await getAssociatedTokenAddress(mintPubkey, ownerPubkey);
const accountInfo = await provider.connection.getAccountInfo(ata);
if (accountInfo) {
console.log("Token account already exists:", ata.toString());
return ata;
}
const transaction = new Transaction().add(
createAssociatedTokenAccountInstruction(
provider.publicKey,
ata,
ownerPubkey,
mintPubkey,
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
)
);
try {
const signature = await provider.sendAndConfirm(transaction);
console.log("Created token account:", ata.toString());
console.log("Transaction signature:", signature);
return ata;
} catch (error) {
console.error("Failed to create token account:", error);
throw error;
}
};
const closeTokenAccount = async (tokenAccount: string) => {
const tokenAccountPubkey = new PublicKey(tokenAccount);
const transaction = new Transaction().add(
createCloseAccountInstruction(
tokenAccountPubkey,
provider.publicKey,
provider.publicKey,
[],
TOKEN_PROGRAM_ID
)
);
try {
const signature = await provider.sendAndConfirm(transaction);
console.log("Closed token account:", tokenAccount);
console.log("Transaction signature:", signature);
return signature;
} catch (error) {
console.error("Failed to close token account:", error);
throw error;
}
};
return (
<div>
<button onClick={() => createTokenAccount("USDC_MINT_ADDRESS")}>
Create USDC Account
</button>
<button onClick={() => closeTokenAccount("TOKEN_ACCOUNT_ADDRESS")}>
Close Token Account
</button>
</div>
);
}