Solana CookbookAccounts
How to Create an Account
Creating an account requires using the System Program createAccount
instruction. The Solana runtime will grant the owner program of an account,
access to write to its data or transfer lamports. When creating an account, we
have to preallocate a fixed storage space in bytes (space) and enough lamports
to cover the rent.
create-account.ts
import {pipe,createSolanaRpc,appendTransactionMessageInstructions,createSolanaRpcSubscriptions,createTransactionMessage,generateKeyPairSigner,getSignatureFromTransaction,sendAndConfirmTransactionFactory,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,signTransactionMessageWithSigners,} from "@solana/web3.js";import { getSetComputeUnitPriceInstruction } from "@solana-program/compute-budget";import {getCreateAccountInstruction,SYSTEM_PROGRAM_ADDRESS,} from "@solana-program/system";const rpc = createSolanaRpc("https://api.devnet.solana.com");const rpcSubscriptions = createSolanaRpcSubscriptions("wss://api.devnet.solana.com",);const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({rpc,rpcSubscriptions,});const space = 0n; // any extra space in the accountconst rentLamports = await rpc.getMinimumBalanceForRentExemption(space).send();console.log("Minimum balance for rent exception:", rentLamports);// todo: load your own signer with SOLconst signer = await generateKeyPairSigner();// generate a new keypair and address to createconst newAccountKeypair = await generateKeyPairSigner();console.log("New account address:", newAccountKeypair.address);const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();const transactionMessage = pipe(createTransactionMessage({ version: "legacy" }),tx => setTransactionMessageFeePayerSigner(signer, tx),tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),tx =>appendTransactionMessageInstructions([// add a priority feegetSetComputeUnitPriceInstruction({microLamports: 200_000,}),// create the new accountgetCreateAccountInstruction({lamports: rentLamports,newAccount: newAccountKeypair,payer: signer,space: space,// "wallet" accounts are owned by the system programprogramAddress: SYSTEM_PROGRAM_ADDRESS,}),],tx,),);const signedTransaction =await signTransactionMessageWithSigners(transactionMessage);const signature = getSignatureFromTransaction(signedTransaction);await sendAndConfirmTransaction(signedTransaction, {commitment: "confirmed",});console.log("Signature:", signature);