Solana CookbookTransactions
How to Optimize Compute Requested
Optimizing the Compute Requested on a transaction is important to ensure that the transaction is both processed in a timely manner as well as to avoid paying too much in priority fees.
For more information about requesting optimal compute, check out the full guide. You can also find more information about using priority fees in this detailed guide.
import {Connection,TransactionInstruction,ComputeBudgetProgram,SystemProgram,Keypair,LAMPORTS_PER_SOL,PublicKey,sendAndConfirmTransaction,Transaction} from "@solana/web3.js";async function getSimulationComputeUnits(connection: Connection,instructions: Array<TransactionInstruction>,payerKey: PublicKey) {try {const recentBlockhash = await connection.getLatestBlockhash();// Include compute budget instructions in simulationconst simulationInstructions = [ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 100 }),ComputeBudgetProgram.setComputeUnitLimit({ units: 400000 }), // High limit for simulation...instructions];const transaction = new Transaction();transaction.recentBlockhash = recentBlockhash.blockhash;transaction.feePayer = payerKey;transaction.add(...simulationInstructions);const simulation = await connection.simulateTransaction(transaction);console.log("Simulated Transaction:", simulation);if (simulation.value.err) {console.error("Simulation error:", simulation.value.err);return 200000; // Fallback value}return simulation.value.unitsConsumed || 200000;} catch (error) {console.error("Error during simulation:", error);return 200000; // Fallback value}}async function buildOptimalTransaction(connection: Connection,instructions: Array<TransactionInstruction>,signer: Keypair,priorityFee: number) {const [computeUnits, recentBlockhash] = await Promise.all([getSimulationComputeUnits(connection, instructions, signer.publicKey),connection.getLatestBlockhash()]);const finalInstructions: TransactionInstruction[] = [];finalInstructions.push(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priorityFee }));if (computeUnits) {const unitsWithMargin = Math.floor(computeUnits * 1.1); // add 10% margin of errorconsole.log("Compute Units with extra 10% margin:", unitsWithMargin);finalInstructions.push(ComputeBudgetProgram.setComputeUnitLimit({ units: unitsWithMargin }));}finalInstructions.push(...instructions);const transaction = new Transaction();transaction.recentBlockhash = recentBlockhash.blockhash;transaction.feePayer = signer.publicKey;transaction.add(...finalInstructions);return {transaction};}async function main() {const connection = new Connection("http://localhost:8899", {commitment: "confirmed"});const sender = Keypair.generate();const recipient = Keypair.generate();const amount = LAMPORTS_PER_SOL / 2; // 0.5 SOLconst signature = await connection.requestAirdrop(sender.publicKey,LAMPORTS_PER_SOL);const { blockhash, lastValidBlockHeight } =await connection.getLatestBlockhash();await connection.confirmTransaction({blockhash,lastValidBlockHeight,signature});// Create transfer instructionconst transferInstruction = SystemProgram.transfer({fromPubkey: sender.publicKey,toPubkey: recipient.publicKey,lamports: amount});const priorityFee = 100; // microLamports// Build optimal transactionconst transaction = await buildOptimalTransaction(connection,[transferInstruction],sender,priorityFee);const transactionSignature = await sendAndConfirmTransaction(connection,transaction.transaction,[sender]);console.log("Transaction sent:", transactionSignature);}main().catch(console.error);
Console
Click to execute the code.
Is this page helpful?