Wallets

Sign Transactions on Solana

Learn how to build transactions and sign them with our server-side SDK.

This tutorial walks you through creating a developer-controlled wallet to sign transactions on Solana.

Before you begin:

When creating a developer-controlled wallet, pass SOL-DEVNET or SOL in the blockchains field. This wallet can be used to sign transactions.

The following example code shows how to create a wallet using the Circle Developer SDK.

const response = await circleDeveloperSdk.createWallets({
  accountType: "EOA",
  blockchains: ["SOLANA-DEVNET"],
  count: 2,
  walletSetId: "<wallet-set-id>",
});

For Solana, you can sign a raw transaction using the API or SDK.

The following example code shows how to prepare a raw transaction for swapping tokens on Jupiter. Note that this code is purely for example purposes only.

// Get quote for swapping SOL to USDC with input 0.01 SOL and 0.5% slippage
const quoteResponse = await (
  await fetch(
    "https://quote-api.jup.ag/v6/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=10000000&slippageBps=50",
  )
).json();
// Get serialized transactions for the swap
const { swapTransaction } = await (
  await fetch("https://quote-api.jup.ag/v6/swap", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      // quoteResponse from /quote API
      quoteResponse,
      // User public key to be used for the swap
      userPublicKey: "FILL-YOUR-WALLET-ADDRESS",
      // Auto wrap and unwrap SOL. Default is true
      wrapAndUnwrapSol: true,
    }),
  })
).json();

The following example code shows how to sign the raw transaction.

const response = await circleDeveloperSdk.signTransaction({
  walletId: "FILL-YOUR-SOL-WALLET-ID",
  rawTransaction: swapTransaction,
});

The following example code shows how you can encode a raw transaction to a Base64 encoded string in JavaScript.

const web3 = require("@solana/web3.js");
const {
  initiateDeveloperControlledWalletsClient,
} = require("@circle-fin/developer-controlled-wallets");
const circleDeveloperSdk = initiateDeveloperControlledWalletsClient({
  baseUrl: "https://api.circle.com",
  apiKey: "YOUR-API-KEY",
  entitySecret: "YOUR-ENTITY-SECRET", // Make sure to enter the entity secret from the step above.
});

async function transferNativeToken() {
  const connection = new web3.Connection(
    web3.clusterApiUrl("devnet"),
    "confirmed",
  );

  // Amount to send (in SOL)
  const amount = 0.1;

  // Convert SOL to lamports
  const lamports = web3.LAMPORTS_PER_SOL * amount;

  const fromPubKey = new web3.PublicKey("YOUR-WALLET-ADDRESS");
  const toPubKey = new web3.PublicKey("DESTINATION-WALLET-ADDRESS");

  // Create a transfer instruction
  const instruction = web3.SystemProgram.transfer({
    fromPubkey: fromPubKey,
    toPubkey: toPubKey,
    lamports: lamports,
  });

  // Get the latest blockhash
  const { blockhash } = await connection.getLatestBlockhash();

  // Create the transaction
  const transaction = new web3.Transaction().add(instruction);

  // Set the recent blockhash and the paying account
  transaction.recentBlockhash = blockhash;
  transaction.feePayer = fromPubKey;

  // Serialize the transaction
  const rawTransaction = transaction.serialize({
    requireAllSignatures: false,
    verifySignatures: false,
  });

  //   // sign the transaction
  const response = await circleDeveloperSdk.signTransaction({
    walletId: "YOUR-WALLET-ADDRESS-WALLET-ID",
    memo: "TEST-SIGN-RAW-TX",
    rawTransaction: rawTransaction.toString("base64"),
  });

  const rawTransactionBuf = Buffer.from(
    response.data.signedTransaction,
    "base64",
  );
  const txid = await connection.sendRawTransaction(rawTransactionBuf, {
    skipPreflight: false,
    maxRetries: 2,
  });
  console.log(`txid:${txid}`);

  await connection.confirmTransaction(txid);
  console.log(`https://solscan.io/tx/${txid}`);
}

transferNativeToken();
Did this page help you?
© 2023-2025 Circle Technology Services, LLC. All rights reserved.