概述

交易监控使您能够实时跟踪 Solana 上的交易执行、成功/失败状态、程序交互和代币余额变化。本指南涵盖了不同交易监控用例的过滤策略和实际实现。
先决条件: 本指南假设您已完成 Yellowstone gRPC 快速入门 并已设置好工作流。

交易过滤选项

监控涉及特定程序的交易跟踪所有与您的程序交互的交易:
const subscribeRequest: SubscribeRequest = {
  transactions: {
    client: {
      accountInclude: [
        "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // Token Program
        "11111111111111111111111111111111",              // System Program
        "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"  // Your program
      ],
      accountExclude: [],
      accountRequired: [],
      vote: false,
      failed: false
    }
  },
  commitment: CommitmentLevel.CONFIRMED
};
最佳用途: 程序特定监控、DeFi 协议跟踪、智能合约交互

实用示例

示例 1:监控 DEX 交易

跟踪所有涉及流行 DEX 程序的交易:
import { StreamManager } from './stream-manager'; // From quickstart guide

async function monitorDEXTransactions() {
  const streamManager = new StreamManager(
    "your-grpc-endpoint",
    "your-api-key",
    handleDEXTransaction
  );

  const subscribeRequest: SubscribeRequest = {
    transactions: {
      client: {
        accountInclude: [
          "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM", // Raydium V4
          "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8", // Raydium V5
          "CAMMCzo5YL8w4VFF8KVHrK22GGUQpMpTFb6xRmpLFGNnSm", // Raydium CLMM
          "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"   // Jupiter
        ],
        vote: false,
        failed: false
      }
    },
    commitment: CommitmentLevel.CONFIRMED
  };

  await streamManager.connect(subscribeRequest);
}

function handleDEXTransaction(data: any): void {
  if (data.transaction?.transaction) {
    const tx = data.transaction.transaction;
    console.log(`\n🔄 DEX Transaction:`);
    console.log(`  Signature: ${tx.signature}`);
    console.log(`  Slot: ${data.transaction.slot}`);
    console.log(`  Status: ${tx.meta?.err ? 'Failed' : 'Success'}`);
    console.log(`  Fee: ${tx.meta?.fee || 0} lamports`);
    console.log(`  Compute Units: ${tx.meta?.computeUnitsConsumed || 0}`);
    
    // Show token balance changes
    if (tx.meta?.preTokenBalances?.length > 0) {
      console.log(`  Token Balance Changes:`);
      tx.meta.preTokenBalances.forEach((preBalance: any, index: number) => {
        const postBalance = tx.meta.postTokenBalances[index];
        if (preBalance && postBalance) {
          const change = postBalance.uiTokenAmount.uiAmount - preBalance.uiTokenAmount.uiAmount;
          if (change !== 0) {
            console.log(`    ${preBalance.mint}: ${change > 0 ? '+' : ''}${change}`);
          }
        }
      });
    }
  }
}

示例 2:监控失败的交易

跟踪失败的交易以识别问题:
async function monitorFailedTransactions() {
  const streamManager = new StreamManager(
    "your-grpc-endpoint",
    "your-api-key",
    handleFailedTransaction
  );

  const subscribeRequest: SubscribeRequest = {
    transactions: {
      client: {
        accountInclude: ["YourProgramId"], // Your program
        vote: false,
        failed: true // Only failed transactions
      }
    },
    commitment: CommitmentLevel.CONFIRMED
  };

  await streamManager.connect(subscribeRequest);
}

function handleFailedTransaction(data: any): void {
  if (data.transaction?.transaction?.meta?.err) {
    const tx = data.transaction.transaction;
    console.log(`\n❌ Failed Transaction:`);
    console.log(`  Signature: ${tx.signature}`);
    console.log(`  Slot: ${data.transaction.slot}`);
    console.log(`  Error: ${JSON.stringify(tx.meta.err)}`);
    console.log(`  Fee: ${tx.meta.fee} lamports`);
    console.log(`  Compute Units: ${tx.meta.computeUnitsConsumed || 0}`);
    
    // Log instruction details for debugging
    if (tx.transaction?.message?.instructions) {
      console.log(`  Instructions:`);
      tx.transaction.message.instructions.forEach((inst: any, i: number) => {
        console.log(`    ${i}: Program ${inst.programIdIndex}, Data: ${inst.data}`);
      });
    }
  }
}

示例 3:监控高价值交易

跟踪具有显著 SOL 转移的交易:
async function monitorHighValueTransactions() {
  const streamManager = new StreamManager(
    "your-grpc-endpoint",
    "your-api-key",
    handleHighValueTransaction
  );

  const subscribeRequest: SubscribeRequest = {
    transactions: {
      client: {
        accountInclude: ["11111111111111111111111111111111"], // System Program
        vote: false,
        failed: false
      }
    },
    commitment: CommitmentLevel.CONFIRMED
  };

  await streamManager.connect(subscribeRequest);
}

function handleHighValueTransaction(data: any): void {
  if (data.transaction?.transaction?.meta) {
    const tx = data.transaction.transaction;
    const preBalances = tx.meta.preBalances || [];
    const postBalances = tx.meta.postBalances || [];
    
    // Calculate largest balance change
    let maxChange = 0;
    preBalances.forEach((preBalance: number, index: number) => {
      const postBalance = postBalances[index] || 0;
      const change = Math.abs(postBalance - preBalance);
      maxChange = Math.max(maxChange, change);
    });
    
    // Only log transactions with > 10 SOL moved
    const changeInSOL = maxChange / 1e9;
    if (changeInSOL > 10) {
      console.log(`\n💰 High-Value Transaction:`);
      console.log(`  Signature: ${tx.signature}`);
      console.log(`  Slot: ${data.transaction.slot}`);
      console.log(`  Max SOL Transfer: ${changeInSOL.toFixed(2)} SOL`);
      console.log(`  Fee: ${tx.meta.fee / 1e9} SOL`);
      console.log(`  Accounts: ${tx.transaction?.message?.accountKeys?.length || 0}`);
    }
  }
}

交易数据结构

理解交易数据结构有助于提取相关信息:

过滤逻辑参考

包含逻辑 (OR)

accountInclude: 交易必须涉及这些账户中的任意一个示例: ["A", "B"] 匹配涉及账户A或账户B的交易

必需逻辑 (AND)

accountRequired: 交易必须涉及所有这些账户示例: ["A", "B"] 匹配涉及账户A和账户B的交易

排除逻辑 (NOT)

accountExclude: 交易不得涉及任何这些账户示例: ["A", "B"] 排除涉及账户A或账户B的交易

组合逻辑

最终过滤器: (accountInclude OR empty) AND (accountRequired AND all) AND NOT (accountExclude OR any)

性能考虑

交易流可能是高流量的
  • 从特定程序过滤器开始
  • 适当地使用承诺级别
  • 监控您的处理能力
  • 实施背压处理
// Rate limiting example
let transactionCount = 0;
const startTime = Date.now();

function handleTransaction(data: any): void {
  transactionCount++;
  
  if (transactionCount % 100 === 0) {
    const elapsed = (Date.now() - startTime) / 1000;
    const rate = transactionCount / elapsed;
    console.log(`Processing ${rate.toFixed(1)} tx/sec`);
  }
  
  // Your transaction processing logic
}

错误处理

常见的交易监控错误及解决方案:

下一步