Solana CookbookTokens
How to Use Wrapped SOL
Wrapped SOL is just like any other token mint. The difference is using
syncNative
and creating token accounts specifically on the NATIVE_MINT
address.
Create Token Account
Like creating
SPL token accounts but
replace mint with NATIVE_MINT
import { NATIVE_MINT } from "@solana/spl-token";
Add Balance
There are two ways to add balance for Wrapped SOL
1. By SOL Transfer
import { getTransferSolInstruction } from "@solana-program/system";import {findAssociatedTokenPda,getCreateAssociatedTokenInstructionAsync,getSyncNativeInstruction,TOKEN_PROGRAM_ADDRESS} from "@solana-program/token";import {address,airdropFactory,appendTransactionMessageInstructions,createSolanaRpc,createSolanaRpcSubscriptions,createTransactionMessage,generateKeyPairSigner,getSignatureFromTransaction,lamports,pipe,sendAndConfirmTransactionFactory,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,signTransactionMessageWithSigners} from "@solana/kit";const rpc = createSolanaRpc("http://localhost:8899");const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");/* constants */const AUTHORITY = await generateKeyPairSigner();const NATIVE_MINT = address("So11111111111111111111111111111111111111112");const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();await requestAirdrop();const [associatedTokenAddress] = await findAssociatedTokenPda({mint: NATIVE_MINT,owner: AUTHORITY.address,tokenProgram: TOKEN_PROGRAM_ADDRESS});let amount = 1_000_000_000n;const createAuthorityATAInstruction =await getCreateAssociatedTokenInstructionAsync({payer: AUTHORITY,mint: NATIVE_MINT,owner: AUTHORITY.address});const transferSolIx = getTransferSolInstruction({source: AUTHORITY,destination: associatedTokenAddress,amount});const syncNativeInstruction = getSyncNativeInstruction({account: associatedTokenAddress});const instructions = [createAuthorityATAInstruction,transferSolIx,syncNativeInstruction];const transactionMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(AUTHORITY, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),(tx) => appendTransactionMessageInstructions(instructions, tx));const signedTransaction =await signTransactionMessageWithSigners(transactionMessage);await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction,{ commitment: "confirmed" });const txSignature = getSignatureFromTransaction(signedTransaction);console.log("Transaction Signature:", txSignature);async function requestAirdrop() {await airdropFactory({ rpc, rpcSubscriptions })({recipientAddress: AUTHORITY.address,lamports: lamports(5_000_000_000n), // 5 SOLcommitment: "confirmed"});}
2. By Token Transfer
import { getCreateAccountInstruction } from "@solana-program/system";import {findAssociatedTokenPda,getCloseAccountInstruction,getCreateAssociatedTokenInstructionAsync,getInitializeAccountInstruction,getTokenSize,getTransferCheckedInstruction,TOKEN_PROGRAM_ADDRESS} from "@solana-program/token";import {address,airdropFactory,appendTransactionMessageInstructions,createSolanaRpc,createSolanaRpcSubscriptions,createTransactionMessage,generateKeyPairSigner,getSignatureFromTransaction,lamports,pipe,sendAndConfirmTransactionFactory,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,signTransactionMessageWithSigners} from "@solana/kit";const rpc = createSolanaRpc("http://localhost:8899");const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");/* constants */const SENDER = await generateKeyPairSigner();const SENDER_TEMPORARY_TOKEN_ACCOUNT = await generateKeyPairSigner();const RECIPIENT = await generateKeyPairSigner();const NATIVE_MINT = address("So11111111111111111111111111111111111111112");const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();await requestAirdrop();const [recipientATA] = await findAssociatedTokenPda({mint: NATIVE_MINT,owner: RECIPIENT.address,tokenProgram: TOKEN_PROGRAM_ADDRESS});const amount = 1_000_000_000n; // 1 WSOLconst tokenAccountLen = getTokenSize();const tokenAccountRent = await rpc.getMinimumBalanceForRentExemption(BigInt(tokenAccountLen)).send();// create temporary token account// adds extra transfer amount lamports to token accountconst createAccountInstruction = getCreateAccountInstruction({payer: SENDER,newAccount: SENDER_TEMPORARY_TOKEN_ACCOUNT,lamports: tokenAccountRent + amount,programAddress: TOKEN_PROGRAM_ADDRESS,space: tokenAccountLen});// initialize temporary token accountconst initAccountInstruction = getInitializeAccountInstruction({account: SENDER_TEMPORARY_TOKEN_ACCOUNT.address,mint: NATIVE_MINT,owner: SENDER.address});// create recipient wrapped sol token accountconst createRecipientATAInstruction =await getCreateAssociatedTokenInstructionAsync({payer: SENDER,mint: NATIVE_MINT,owner: RECIPIENT.address});// transfer WSOLconst transferTokenInstruction = getTransferCheckedInstruction({source: SENDER_TEMPORARY_TOKEN_ACCOUNT.address,mint: NATIVE_MINT,destination: recipientATA,authority: SENDER,amount: amount, // 1 WSOLdecimals: 9});// close temp accountconst closeTokenAccountInstruction = getCloseAccountInstruction({account: SENDER_TEMPORARY_TOKEN_ACCOUNT.address,destination: SENDER.address,owner: SENDER});const instructions = [createAccountInstruction,initAccountInstruction,createRecipientATAInstruction,transferTokenInstruction,closeTokenAccountInstruction];const transactionMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(SENDER, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),(tx) => appendTransactionMessageInstructions(instructions, tx));const signedTransaction =await signTransactionMessageWithSigners(transactionMessage);await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction,{ commitment: "confirmed", skipPreflight: true });const txSignature = getSignatureFromTransaction(signedTransaction);console.log("Transaction Signature:", txSignature);async function requestAirdrop() {await airdropFactory({ rpc, rpcSubscriptions })({recipientAddress: SENDER.address,lamports: lamports(5_000_000_000n), // 5 SOLcommitment: "confirmed"});}
Is this page helpful?