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://127.0.0.1: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://127.0.0.1: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?