Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt

Use this file to discover all available pages before exploring further.

Overview

This guide shows you how to sign Solana transactions using Dynamic’s Node SDK. You’ll learn how to create, sign, and send Solana transactions.

Prerequisites

Step 1: Install Dependencies

bun add @solana/web3.js

Step 2: Create and Sign a Transaction

The approach for signing transactions depends on how you created your wallet: If you created your wallet with backUpToClientShareService: true, you can sign directly without retrieving key shares:
import { DynamicSvmWalletClient } from '@dynamic-labs-wallet/node-svm';
import { Connection, PublicKey, Transaction, SystemProgram, LAMPORTS_PER_SOL } from '@solana/web3.js';

// Create authenticated client
export const authenticatedSvmClient = async () => {
  const client = new DynamicSvmWalletClient({
    environmentId: process.env.DYNAMIC_ENVIRONMENT_ID!,
  });

  await client.authenticateApiToken(process.env.DYNAMIC_AUTH_TOKEN!);
  return client;
};

const svmClient = await authenticatedSvmClient();

// Create a simple SOL transfer transaction
const fromPubkey = new PublicKey('YourSolanaWalletAddress');
const toPubkey = new PublicKey('11111111111111111111111111111112');
const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey,
    toPubkey,
    lamports: LAMPORTS_PER_SOL * 0.001, // 0.001 SOL
  })
);

// ✅ Simple signing - no externalServerKeyShares needed
const signedTransaction = await svmClient.signTransaction({
  senderAddress: 'YourSolanaWalletAddress',
  transaction: transaction,
});

console.log('Transaction signed successfully');

With Manual Backup

If you created your wallet with backUpToClientShareService: false, you must retrieve and provide external key shares:
// ⚠️ First, get external server key shares (required for manual backup)
const keyShares = await svmClient.getExternalServerKeyShares({
  accountAddress: 'YourSolanaWalletAddress',
});

// Or retrieve your stored encrypted key shares
// const keyShares = await retrieveStoredKeyShares('YourSolanaWalletAddress');

console.log('Key shares retrieved:', keyShares.length);

// Sign the transaction with external key shares
const signedTransaction = await svmClient.signTransaction({
  senderAddress: 'YourSolanaWalletAddress',
  externalServerKeyShares: keyShares, // Required for manual backup!
  transaction: transaction,
  password: 'your-password', // Only if wallet was created with password
});

console.log('Transaction signed successfully');
Password Handling Notes:
  • If your wallet was created without a password, omit the password parameter
  • If your wallet was created with a password, you must provide it for all operations
  • The password parameter is always optional in the API, but required if the wallet is password-protected

Step 3: Send the Transaction

import { Connection, sendAndConfirmTransaction } from '@solana/web3.js';

const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
const txHash = await sendAndConfirmTransaction(connection, signedTransaction);
console.log('Transaction hash:', txHash);

Complete Example: Send SOL

export const sendSol = async ({
  fromAddress,
  toAddress,
  amount,
}: {
  fromAddress: string;
  toAddress: string;
  amount: number; // Amount in SOL
}) => {
  const svmClient = await authenticatedSvmClient();

  // Create transaction
  const fromPubkey = new PublicKey(fromAddress);
  const toPubkey = new PublicKey(toAddress);
  const transaction = new Transaction().add(
    SystemProgram.transfer({
      fromPubkey,
      toPubkey,
      lamports: LAMPORTS_PER_SOL * amount,
    })
  );

  // Sign transaction
  // Note: If using manual backup (backUpToClientShareService: false),
  // you'll need to provide externalServerKeyShares here
  const signedTransaction = await svmClient.signTransaction({
    senderAddress: fromAddress,
    transaction,
  });

  // Send transaction
  const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
  const txHash = await sendAndConfirmTransaction(connection, signedTransaction);

  return txHash;
};

// Usage
const txHash = await sendSol({
  fromAddress: 'YourSolanaWalletAddress',
  toAddress: 'RecipientAddress',
  amount: 0.001,
});

console.log('SOL sent:', txHash);

Common Transaction Types

SOL Transfer

const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: new PublicKey('YourAddress'),
    toPubkey: new PublicKey('RecipientAddress'),
    lamports: LAMPORTS_PER_SOL * 0.1,
  })
);

SPL Token Transfer

import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';

const transaction = new Transaction().add(
  Token.createTransferInstruction(
    TOKEN_PROGRAM_ID,
    fromTokenAccount,
    toTokenAccount,
    fromPubkey,
    [],
    amount
  )
);

Next Steps