A Solana transaction is a list of instructions that are executed in order. This allows developers to batch multiple instructions into a single transaction, reducing the number of transactions required to complete a complex multi-step process.
Create and send transaction with multiple instructions
In this example, we will:
Create a Solana account
Construct multiple instructions to be executed in the transaction
Sign the transaction with the Solana account
Send the transaction to the Solana network
Copy
Ask AI
import { Connection, PublicKey, SystemProgram, Transaction,} from "@solana/web3.js";import { CdpClient } from "@coinbase/cdp-sdk";import dotenv from "dotenv";dotenv.config();const cdp = new CdpClient();const connection = new Connection("https://api.devnet.solana.com");async function createAccount() { const account = await cdp.solana.createAccount(); console.log(`Created account: ${account.address}`); return account;}async function requestFaucet(address: string) { await cdp.solana.requestFaucet({ address, token: "sol", });}async function waitForBalance(address: string) { let balance = 0; let attempts = 0; const maxAttempts = 30; while (balance === 0 && attempts < maxAttempts) { balance = await connection.getBalance(new PublicKey(address)); if (balance === 0) { console.log("Waiting for funds..."); await new Promise(resolve => setTimeout(resolve, 1000)); attempts++; } else { console.log("Account funded with", balance / 1e9, "SOL"); } } if (balance === 0) { throw new Error("Account not funded after multiple attempts"); }}async function sendTransaction(address: string) { // Amount of lamports to send (default: 1000 = 0.000001 SOL) const lamportsToSend = 1000; const fromAddress = new PublicKey(address) const destinations = [ "ANVUJaJoVaJZELtV2AvRp7V5qPV1B84o29zAwDhPj1c2", "EeVPcnRE1mhcY85wAh3uPJG1uFiTNya9dCJjNUPABXzo", "4PkiqJkUvxr9P8C1UsMqGN8NJsUcep9GahDRLfmeu8UK", ] const { blockhash } = await connection.getLatestBlockhash(); // Create instructions for each destination const instructions = destinations.map((toAddress) => { return SystemProgram.transfer({ fromPubkey: fromAddress, toPubkey: new PublicKey(toAddress), lamports: lamportsToSend, }) }) // Create a single transaction with all instructions const transaction = new Transaction(); transaction.add(...instructions); transaction.recentBlockhash = blockhash; transaction.feePayer = fromAddress; const serializedTx = Buffer.from( transaction.serialize({ requireAllSignatures: false }) ).toString("base64"); const { signature: txSignature } = await cdp.solana.signTransaction({ address, transaction: serializedTx, }); const decodedSignedTx = Buffer.from(txSignature, "base64"); console.log("Sending transaction..."); const txSendSignature = await connection.sendRawTransaction(decodedSignedTx); const latestBlockhash = await connection.getLatestBlockhash(); console.log("Waiting for transaction to be confirmed..."); const confirmation = await connection.confirmTransaction({ signature: txSendSignature, blockhash: latestBlockhash.blockhash, lastValidBlockHeight: latestBlockhash.lastValidBlockHeight, }); if (confirmation.value.err) { throw new Error(`Transaction failed: ${confirmation.value.err.toString()}`); } console.log(`Sent SOL: https://explorer.solana.com/tx/${txSendSignature}?cluster=devnet`);}async function main() { const account = await createAccount(); await requestFaucet(account.address); await waitForBalance(account.address); await sendTransaction(account.address);}main().catch(console.error)
After running the above snippet, you should see output similar to the following:
Copy
Ask AI
Created account: Af8cVHK2DZXcT4WhK6VDZ3h2zFxbEfgamsRkrB7dUcfFWaiting for funds...Account funded with 0.00125 SOL (1250000 lamports)Sending transaction...Waiting for transaction to be confirmed...Sent SOL: https://explorer.solana.com/tx/56oRrY2nHSbncysmrW6vtBaUoyvWnRrMqN1joGNzaY3TNmPSTM653skDjbj2jDEdMA4QqFo9c4GY4hTnRhScgJk5?cluster=devnet