Overview

This guide covers the fundamentals of sending transactions on Solana using the CDP v2 Server Wallet. You will learn how to construct transactions and submit them to the Solana network. Solana transactions benefit from a single API that supports signing and broadcasting. With CDP, signing keys are securely managed in the platform’s infrastructure.
  1. Create transaction: Build a transaction with one or more instructions
  2. Send transaction: Use CDP to send the serialized transaction
  3. Confirm transaction: Wait for network confirmation

Prerequisites

It is assumed you have:
  • Completed the Quickstart guide
  • Basic understanding of Solana accounts
  • Installed dependencies:
    • For TypeScript: @solana/web3.js, @coinbase/cdp-sdk, and dotenv
    • For Python: solana, solders, cdp-sdk, and python-dotenv
The following steps break down the transaction flow into digestible pieces. If you prefer to see the full working code immediately, skip to the Complete example section below.

1. Create a Solana account

First, create or retrieve a Solana account using CDP. The below example uses solana-devnet and will source SOL from CDP faucet to transfer.
import { CdpClient } from "@coinbase/cdp-sdk";
import "dotenv/config";

const cdp = new CdpClient();

const account = await cdp.solana.createAccount({
  name: "test-sol-account",
});

let fromAddress: string;
fromAddress = account.address;
console.log("Successfully created new SOL account:", fromAddress);

// Request SOL from faucet
const faucetResp = await cdp.solana.requestFaucet({
  address: fromAddress,
  token: "sol",
});
console.log(
  "Successfully requested SOL from faucet:",
  faucetResp.signature
);

2. Build the transaction

Prepare a transaction with one or more instructions. The transaction may contain several instructions, each of which may require signatures from different account keys. Here is a simple SOL transfer.
We set the blockhash to a static value temporarily since the CDP v2 Server Wallet will update it before it is sent to the network.
import {
  PublicKey,
  SystemProgram,
  SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
  Transaction,
} from "@solana/web3.js";

// Required: Destination address to send SOL to (replace with your recipient)
const destinationAddress = "3KzDtddx4i53FBkvCzuDmRbaMozTZoJBb1TToWhz3JfE";

// Amount of lamports to send (default: 1000 = 0.000001 SOL)
const lamportsToSend = 1000;

// Assumes fromAddress is defined from step 1
let fromAddress: string; // Your Solana account address

const transaction = new Transaction();
transaction.add(
  SystemProgram.transfer({
    fromPubkey: new PublicKey(fromAddress),
    toPubkey: new PublicKey(destinationAddress),
    lamports: lamportsToSend,
  })
);
transaction.recentBlockhash = SYSVAR_RECENT_BLOCKHASHES_PUBKEY.toBase58();
transaction.feePayer = new PublicKey(fromAddress);

3. Serialize transaction

Serialize the transaction for signing:
const serializedTx = Buffer.from(
  transaction.serialize({ requireAllSignatures: false })
).toString("base64");

console.log("Transaction serialized successfully");

4. Send the transaction

Use CDP to send the serialized transaction:
import { CdpClient } from "@coinbase/cdp-sdk";

// Assumes cdp client is initialized from step 1
const cdp = new CdpClient();

const txResult = await cdp.solana.sendTransaction({
    network: "solana-devnet",
    transaction: serializedTx,
});

const signature = txResult.signature;
console.log("Solana transaction hash:", signature);

5. Confirm

Wait for confirmation after you submitted the transaction to the network.
console.log("Waiting for transaction to be confirmed");
const latestBlockhash = await connection.getLatestBlockhash();
const confirmation = await connection.confirmTransaction({
  signature,
  blockhash: latestBlockhash.blockhash,
  lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
});

if (confirmation.value.err) {
  throw new Error(
    `Transaction failed: ${confirmation.value.err.toString()}`
  );
}

console.log(
  "Transaction confirmed:",
  confirmation.value.err ? "failed" : "success"
);
console.log(
  `Transaction explorer link: https://explorer.solana.com/tx/${signature}?cluster=devnet`
);

Complete example

More code samples are available in our TypeScript and Python SDK repositories.

Bring your own node

Use a custom node provider to build and broadcast the transaction instead of relying on the CDP SDK. You will still call CDP to sign the transaction, but you can query the recent blockhash and broadcast the transaction using your own node.