Real-World Examples

Complete, copy-paste-ready recipes for common Solana development tasks. Each example includes RPC, WebSocket, and gRPC approaches where applicable.

Wallet Balance & Token List

Fetch a wallet's SOL balance and list all SPL tokens with their balances. This is the most common dashboard use case.

import {
  Connection, PublicKey, LAMPORTS_PER_SOL
} from '@solana/web3.js'

const connection = new Connection('https://api.falconq.xyz/v1/rpc', {
  httpHeaders: { Authorization: 'Bearer fq_rpc_live_YOUR_KEY' },
  commitment: 'confirmed',
})

async function getWalletPortfolio(walletAddress) {
  const pubkey = new PublicKey(walletAddress)

  // 1. Get SOL balance
  const solBalance = await connection.getBalance(pubkey)

  // 2. Get all token accounts
  const tokenAccounts = await connection.getTokenAccountsByOwner(
    pubkey,
    { programId: new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA') },
    'confirmed'
  )

  // 3. Parse token balances
  const tokens = tokenAccounts.value.map(({ pubkey: ata, account }) => {
    const parsed = account.data.parsed.info
    return {
      ata: ata.toBase58(),
      mint: parsed.mint,
      balance: parsed.tokenAmount.uiAmountString,
      decimals: parsed.tokenAmount.decimals,
    }
  })

  return {
    sol: solBalance / LAMPORTS_PER_SOL,
    tokens,
    tokenCount: tokens.length,
  }
}

// Usage
const portfolio = await getWalletPortfolio('vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg')
console.log('SOL:', portfolio.sol)
console.log('Tokens:', portfolio.tokens)

Transaction History

Build paginated transaction history for a wallet, then fetch full details for each transaction.

async function getTransactionHistory(connection, walletAddress, options = {}) {
  const { limit = 10, before = undefined } = options
  const pubkey = new PublicKey(walletAddress)

  // 1. Get signatures
  const signatures = await connection.getSignaturesForAddress(pubkey, {
    limit,
    before,
    commitment: 'confirmed',
  })

  // 2. Fetch full transaction details in parallel
  const transactions = await Promise.all(
    signatures.map(async (sig) => {
      const tx = await connection.getTransaction(sig.signature, {
        commitment: 'confirmed',
        maxSupportedTransactionVersion: 0,
      })
      return {
        signature: sig.signature,
        timestamp: sig.blockTime ? new Date(sig.blockTime * 1000) : null,
        status: sig.err ? 'failed' : 'success',
        fee: tx?.meta?.fee ?? 0,
        instructions: tx?.transaction.message.instructions ?? [],
      }
    })
  )

  return {
    transactions,
    nextBefore: signatures[signatures.length - 1]?.signature,
  }
}

// Usage — first page
const page1 = await getTransactionHistory(
  connection, 'vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg', { limit: 10 }
)

// Next page
const page2 = await getTransactionHistory(
  connection, 'vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg',
  { limit: 10, before: page1.nextBefore }
)

Token Transfer

Build, sign, and send an SPL token transfer with priority fee and proper error handling.

import {
  Connection, Transaction, PublicKey,
  ComputeBudgetProgram, sendAndConfirmTransaction
} from '@solana/web3.js'
import {
  getAssociatedTokenAddress,
  createTransferInstruction,
  TOKEN_PROGRAM_ID
} from '@solana/spl-token'

async function transferToken(
  connection,
  payer,               // Keypair — the sender
  recipientAddress,    // string — recipient wallet
  mintAddress,         // string — token mint
  amount               // number — token amount (in smallest unit)
) {
  const recipient = new PublicKey(recipientAddress)
  const mint = new PublicKey(mintAddress)

  // 1. Get sender and recipient ATAs
  const senderAta = await getAssociatedTokenAddress(mint, payer.publicKey)
  const recipientAta = await getAssociatedTokenAddress(mint, recipient)

  // 2. Build transfer instruction
  const transferIx = createTransferInstruction(
    senderAta,
    recipientAta,
    payer.publicKey,
    amount,
    [],
    TOKEN_PROGRAM_ID
  )

  // 3. Add priority fee
  const tx = new Transaction()
    .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 40_000 }))
    .add(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 10_000 }))
    .add(transferIx)

  // 4. Send and confirm
  const signature = await sendAndConfirmTransaction(
    connection,
    tx,
    [payer],
    { commitment: 'confirmed' }
  )

  return signature
}

// Usage: Transfer 100 USDC (6 decimals)
const sig = await transferToken(
  connection,
  myKeypair,
  '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri',
  'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
  100_000_000 // 100 * 10^6
)

Real-Time Account Monitor

Monitor a wallet in real time and push notifications when the balance changes or specific tokens are received.

const WebSocket = require('ws')

function monitorWallet(address, onUpdate) {
  const ws = new WebSocket(
    'wss://api.falconq.xyz/v1/ws?api-key=fq_rpc_live_YOUR_KEY'
  )

  ws.on('open', () => {
    // Subscribe to wallet balance changes
    ws.send(JSON.stringify({
      jsonrpc: '2.0', id: 1,
      method: 'accountSubscribe',
      params: [address, { commitment: 'confirmed', encoding: 'jsonParsed' }]
    }))

    // Subscribe to token program logs mentioning this wallet
    ws.send(JSON.stringify({
      jsonrpc: '2.0', id: 2,
      method: 'logsSubscribe',
      params: [
        { mentions: [address] },
        { commitment: 'confirmed' }
      ]
    }))
  })

  ws.on('message', (data) => {
    const msg = JSON.parse(data.toString())

    if (msg.method === 'accountNotification') {
      const lamports = msg.params.result.value.lamports
      onUpdate({ type: 'balance', lamports })
    }

    if (msg.method === 'logsNotification') {
      const { signature, logs } = msg.params.result.value
      onUpdate({ type: 'transaction', signature, logs })
    }
  })

  ws.on('error', (err) => {
    console.error('Monitor error:', err.message)
  })

  ws.on('close', () => {
    console.log('Monitor disconnected, reconnecting...')
    setTimeout(() => monitorWallet(address, onUpdate), 2000)
  })

  return ws
}

// Usage
monitorWallet('vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg', (update) => {
  if (update.type === 'balance') {
    console.log('New balance:', update.lamports / 1e9, 'SOL')
  }
  if (update.type === 'transaction') {
    console.log('Transaction:', update.signature)
  }
})

DEX Pool Monitoring with gRPC

Stream real-time DEX pool activity using Yellowstone gRPC. Monitor new pools, swaps, and liquidity changes.

const grpc = require('@grpc/grpc-js')
const protoLoader = require('@grpc/proto-loader')

const packageDefinition = protoLoader.loadSync('geyser.proto', {
  keepCase: true, longs: String, enums: String, defaults: true, oneofs: true,
})
const geyser = grpc.loadPackageDefinition(packageDefinition)

async function monitorRaydiumPools(onPoolUpdate) {
  const client = new geyser.Geyser(
    'grpc.falconq.xyz:50051',
    grpc.credentials.createInsecure()
  )

  const metadata = new grpc.Metadata()
  metadata.set('x-token', 'fq_grpc_live_YOUR_KEY')

  // Raydium V4 program ID
  const RAYDIUM_V4 = '675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8'

  const request = {
    slots: {},
    accounts: {
      raydiumPools: {
        owner: [RAYDIUM_V4],
        filters: [
          { memcmp: { offset: '40', base58: 'srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX' } }
        ],
      },
    },
    transactions: {
      raydiumSwaps: {
        vote: false, failed: false,
        accountInclude: [RAYDIUM_V4],
      },
    },
    blocks: {}, blocksMeta: {},
    accountsDataSlice: [],
    commitment: 'processed',
  }

  const stream = client.Subscribe(request, metadata)

  stream.on('data', (update) => {
    if (update.account) {
      const acc = update.account.account
      onPoolUpdate({
        type: 'account',
        pubkey: acc.pubkey.toString(),
        lamports: acc.lamports,
        slot: update.account.slot,
      })
    }

    if (update.transaction) {
      const tx = update.transaction.transaction
      onPoolUpdate({
        type: 'swap',
        signature: tx.transaction?.signatures[0],
        slot: tx.slot,
      })
    }
  })

  stream.on('error', (err) => {
    console.error('Pool monitor error:', err)
    setTimeout(() => monitorRaydiumPools(onPoolUpdate), 5000)
  })
}

// Usage
monitorRaydiumPools((event) => {
  if (event.type === 'account') {
    console.log('Pool account updated:', event.pubkey)
  }
  if (event.type === 'swap') {
    console.log('Swap detected:', event.signature)
  }
})

New Token Launch Detection

Monitor the Token Program for new mint accounts being created. Useful for early token discovery tools.

import { PublicKey } from '@solana/web3.js'

const TOKEN_PROGRAM = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA')

// Use gRPC to monitor new mint accounts
const request = {
  slots: {},
  accounts: {
    newMints: {
      owner: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
      // Mint accounts have no dataSize filter available; we detect by owner change
    },
  },
  transactions: {},
  blocks: {}, blocksMeta: {},
  accountsDataSlice: [],
  commitment: 'confirmed',
}

const stream = client.Subscribe(request, metadata)

stream.on('data', (update) => {
  if (update.account) {
    const acc = update.account.account
    const owner = acc.owner.toString()

    if (owner === TOKEN_PROGRAM.toBase58()) {
      // New token account — could be a mint, token account, or multisig
      console.log('New token-related account:', acc.pubkey.toString())
      console.log('Data length:', acc.data.length)

      // Mint accounts typically have data length 82
      if (acc.data.length === 82) {
        console.log('=> Likely new mint!')
      }
    }
  }
})

Compute Unit Optimization

Minimize transaction costs by simulating transactions first, then setting exact compute unit limits.

import {
  Transaction, ComputeBudgetProgram
} from '@solana/web3.js'

async function optimizeCompute(tx, connection, payer) {
  // 1. Simulate with replaceRecentBlockhash to skip signature verification
  const simulation = await connection.simulateTransaction(tx, {
    replaceRecentBlockhash: true,
    sigVerify: false,
  })

  if (simulation.value.err) {
    throw new Error('Simulation failed: ' + JSON.stringify(simulation.value.err))
  }

  const unitsConsumed = simulation.value.unitsConsumed ?? 200_000
  const cuLimit = Math.ceil(unitsConsumed * 1.2) // 20% headroom

  // 2. Rebuild transaction with exact CU limit
  const optimized = new Transaction()
  optimized.add(ComputeBudgetProgram.setComputeUnitLimit({ units: cuLimit }))
  optimized.add(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 10_000 }))
  // ... add your actual instructions

  return optimized
}

// Usage
const baseTx = new Transaction().add(myInstruction)
const optimized = await optimizeCompute(baseTx, connection, payer)
optimized.feePayer = payer.publicKey
optimized.recentBlockhash = blockhash
optimized.sign(payer)

const sig = await connection.sendRawTransaction(optimized.serialize())

Multi-Signature Transaction

Build transactions that require multiple signers, such as multi-sig wallets or escrow contracts.

import { Transaction, SystemProgram } from '@solana/web3.js'

async function createMultiSigTransfer(
  connection,
  signers,        // Keypair[] — all required signers
  recipient,      // PublicKey
  amount          // lamports
) {
  const tx = new Transaction()
    .add(SystemProgram.transfer({
      fromPubkey: signers[0].publicKey, // The multi-sig address
      toPubkey: recipient,
      lamports: amount,
    }))

  // The multi-sig address is the first signer; additional signers must sign too
  tx.feePayer = signers[0].publicKey

  const { blockhash } = await connection.getLatestBlockhash('confirmed')
  tx.recentBlockhash = blockhash

  // Partial sign with all signers
  tx.partialSign(...signers)

  // Send the fully signed transaction
  const signature = await connection.sendRawTransaction(tx.serialize())

  await connection.confirmTransaction(signature, 'confirmed')
  return signature
}

NFT Metadata Fetching

Fetch NFT metadata by reading the Metaplex Token Metadata account associated with a mint.

import { PublicKey } from '@solana/web3.js'

const METAPLEX_PROGRAM = new PublicKey('metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s')

function getMetadataPDA(mint) {
  const [pda] = PublicKey.findProgramAddressSync(
    [
      Buffer.from('metadata'),
      METAPLEX_PROGRAM.toBuffer(),
      mint.toBuffer(),
    ],
    METAPLEX_PROGRAM
  )
  return pda
}

async function fetchNFTMetadata(connection, mintAddress) {
  const mint = new PublicKey(mintAddress)
  const metadataPDA = getMetadataPDA(mint)

  const account = await connection.getAccountInfo(metadataPDA)
  if (!account) return null

  // Parse metadata account (simplified — use @metaplex-foundation/js for production)
  const data = account.data
  // Offset 1: key (1 byte)
  // Offset 2: update authority (32 bytes)
  // Offset 34: mint (32 bytes)
  // Offset 66: name length (4 bytes)
  // ... etc

  // In production, use @metaplex-foundation/js
  return { mint, metadataPDA: metadataPDA.toBase58(), dataLength: data.length }
}

Validator Health Check

Build a health monitoring script that checks RPC health, current slot, and cluster nodes.

async function healthCheck(connection) {
  const start = Date.now()

  const results = {
    timestamp: new Date().toISOString(),
    checks: {},
  }

  try {
    const health = await connection.getHealth()
    results.checks.health = { status: health, latency: Date.now() - start }
  } catch (err) {
    results.checks.health = { status: 'ERROR', error: err.message }
  }

  try {
    const slot = await connection.getSlot()
    results.checks.slot = { status: 'OK', value: slot }
  } catch (err) {
    results.checks.slot = { status: 'ERROR', error: err.message }
  }

  try {
    const version = await connection.getVersion()
    results.checks.version = { status: 'OK', value: version['solana-core'] }
  } catch (err) {
    results.checks.version = { status: 'ERROR', error: err.message }
  }

  try {
    const epoch = await connection.getEpochInfo()
    results.checks.epoch = { status: 'OK', epoch: epoch.epoch, progress: (epoch.slotIndex / epoch.slotsInEpoch).toFixed(2) }
  } catch (err) {
    results.checks.epoch = { status: 'ERROR', error: err.message }
  }

  return results
}

// Run every 30 seconds
setInterval(async () => {
  const report = await healthCheck(connection)
  console.log('Health report:', JSON.stringify(report, null, 2))
}, 30000)