You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何过滤getSignaturesForAddress结果中的SPL Token转账记录

过滤Solana SPL Token转账记录并获取金额

无需依赖LogMessage,解析交易指令更可靠

SPL Token转账本质是调用Token程序的transfer或transferChecked指令,直接从parsedTransaction的指令列表里筛选是最准确的方式,不用依赖LogMessage(部分转账可能没有输出日志):

  • 先遍历交易的所有指令,筛选出程序ID匹配Token主网地址(TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)的指令
  • 判断指令类型是否为transfer或transferChecked
  • 检查指令中的destination字段是否等于你的钱包地址,确保是转入而非转出记录

获取SPL Token转账数量的方法

  • 对于transfer指令:直接取amount字段,注意这个值是Token的最小单位(比如USDC的最小单位是1e-6),需要除以对应Token的decimals转换为可读金额
  • 对于transferChecked指令:除了amount,还能直接拿到decimals字段,省去单独查询Mint信息的步骤
  • 如果需要decimals,可通过getParsedAccountInfo查询对应Token Mint账户的信息

修改后的示例代码

import * as web3 from '@solana/web3.js';

// Solana主网Token程序地址
const TOKEN_PROGRAM_ID = new web3.PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
const solanaConnection = new web3.Connection(web3.clusterApiUrl("mainnet-beta"));

// 获取Token Mint的decimals
const getTokenDecimals = async (mintAddress) => {
  const mintPubkey = new web3.PublicKey(mintAddress);
  const mintInfo = await solanaConnection.getParsedAccountInfo(mintPubkey);
  return mintInfo.value?.data.parsed.info.decimals || 0;
};

const getTransactions = async(address, lastTransaction) => {
  const pubKey = new web3.PublicKey(address);
  const transactionList = await solanaConnection.getSignaturesForAddress(pubKey, {until: lastTransaction});
  const signatureList = transactionList.map(tx => tx.signature);

  for await (const sig of signatureList) {
    // 加上交易版本参数,兼容版本化交易
    const parsedTx = await solanaConnection.getParsedTransaction(sig, {maxSupportedTransactionVersion: 0});
    if (!parsedTx) continue;

    // 遍历所有指令筛选SPL转入记录
    for (const instr of parsedTx.transaction.message.instructions) {
      if (!instr.programId.equals(TOKEN_PROGRAM_ID)) continue;

      const parsedInstr = instr.parsed;
      if (['transfer', 'transferChecked'].includes(parsedInstr.type) && 
          parsedInstr.info.destination === address) {
        
        const mintAddress = parsedInstr.info.mint;
        const rawAmount = parsedInstr.info.amount;
        // 若为transferChecked可直接用parsedInstr.info.decimals,无需单独查询
        const decimals = parsedInstr.type === 'transferChecked' 
          ? parsedInstr.info.decimals 
          : await getTokenDecimals(mintAddress);
        const displayAmount = rawAmount / (10 ** decimals);

        console.log(`收到Token: ${displayAmount} (Mint地址: ${mintAddress})`);
        // 此处执行数据库更新逻辑
      }
    }
  }
}

// 替换为你的钱包地址和上次处理的交易签名
getTransactions("你的钱包地址", lastTransaction);

注意事项

  • 加上maxSupportedTransactionVersion: 0参数,避免解析版本化交易时失败
  • 务必校验destination字段,防止把你主动转出的交易误判为转入
  • 若处理大量交易,建议批量获取解析,减少getParsedTransaction的调用次数,提升效率

内容的提问来源于stack exchange,提问作者oijafoijf asnjksdjn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 06:25:39