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
main.ts
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 destinationconst instructions = destinations.map((toAddress) => {return SystemProgram.transfer({ fromPubkey: fromAddress, toPubkey: new PublicKey(toAddress), lamports: lamportsToSend,})})// Create a single transaction with all instructionsconst 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