跳转到主要内容
测试版:钱包 API 目前处于测试阶段。API 和响应格式可能会更改。

概览

Token Transfers 端点检索 Solana 钱包的所有代币转账活动,包括详细的发送方/接收方信息。与完整交易历史不同,此端点专注于转账,非常适合支付跟踪和转账监控。

API 参考

查看详细的代币转账 API 文档

何时使用

当您需要以下操作时,请使用 Token Transfers API:
  • 跟踪支付:监控付款处理器的入款
  • 构建转账动态:显示简单的“发送/接收”活动动态
  • 监控特定代币:跟踪特定代币的转账(例如 USDC 支付)
  • 识别交易对手:查看谁发送或接收了代币
  • 生成收据:创建包含发送方/接收方详细信息的付款收据
  • 检测可疑活动:监控异常转账模式

快速开始

基本转账查询

获取最近的进出转账:
const getWalletTransfers = async (address) => {
  const url = `https://api.helius.xyz/v1/wallet/${address}/transfers?api-key=YOUR_API_KEY`;

  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }

  const data = await response.json();

  console.log(`Found ${data.data.length} transfers`);

  // Display recent transfers
  data.data.forEach(transfer => {
    const date = new Date(transfer.timestamp * 1000).toLocaleString();
    const direction = transfer.direction === 'in' ? 'Received' : 'Sent';
    const counterparty = transfer.counterparty.slice(0, 8) + '...';

    console.log(`\n${direction} - ${date}`);
    console.log(`Amount: ${transfer.amount} ${transfer.symbol || transfer.mint.slice(0, 8) + '...'}`);
    console.log(`${transfer.direction === 'in' ? 'From' : 'To'}: ${counterparty}`);
    console.log(`Signature: ${transfer.signature.slice(0, 20)}...`);
  });

  return data;
};

getWalletTransfers("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY");

按方向筛选

仅获取入账或出账转账:
const getIncomingTransfers = async (address) => {
  const data = await getWalletTransfers(address);

  const incoming = data.data.filter(t => t.direction === 'in');

  console.log(`Received ${incoming.length} incoming transfers`);

  incoming.forEach(transfer => {
    console.log(`Received ${transfer.amount} ${transfer.symbol} from ${transfer.counterparty.slice(0, 8)}...`);
  });

  return incoming;
};

查询参数

参数类型默认值描述
limitinteger50返回的最大转账数 (1-100)
cursorstring-上一次响应的分页游标

响应格式

{
  "data": [
    {
      "signature": "5wHu1qwD7Jsj3xqWjdSEJmYr3Q5f5RjXqjqQJ7jqEj7jqEj7jqEj7jqEj7jqEj7jqE",
      "timestamp": 1704067200,
      "direction": "in",
      "counterparty": "HXsKP7wrBWaQ8T2Vtjry3Nj3oUgwYcqq9vrHDM12G664",
      "mint": "So11111111111111111111111111111111111111112",
      "symbol": "SOL",
      "amount": 1.5,
      "amountRaw": "1500000000",
      "decimals": 9
    },
    {
      "signature": "4aHu2qwD8Jtj4xqWjdSEJmYr3Q5f5RjXqjqQJ7jqEj7jqEj7jqEj7jqEj7jqEj7jqE",
      "timestamp": 1704067100,
      "direction": "out",
      "counterparty": "2ojv9BAiHUrvsm9gxDe7fJSzbNZSJcxZvf8dqmWGHG8S",
      "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "symbol": "USDC",
      "amount": 100.0,
      "amountRaw": "100000000",
      "decimals": 6
    }
  ],
  "pagination": {
    "hasMore": true,
    "nextCursor": "5wHu1qwD7Jsj3xqWjdSEJmYr3Q5f5RjXqjqQJ7jqEj7jqEj7jqEj7jqEj7jqEj7jqE"
  }
}
  • amount: 可读的转账金额,已被 decimals 除。用于显示(例如,1.5 SOL,100.0 USDC)。
  • amountRaw: 在小数点调整前作为原始整数字符串的相同金额(例如,"1500000000" 的 1.5 SOL)。序列化为字符串以避免浮点精度损失。用于链上指令或精确算术:amount = parseInt(amountRaw) / 10**decimals
  • mint: 代币铸造地址(原生 SOL 的 So11111111111111111111111111111111111111112)。

理解方向

direction 字段是相对于您查询的钱包的:
  • in: 钱包接收的代币(入账支付)
  • out: 钱包发送的代币(出账支付)
counterparty 字段为:
  • 对于 in 转账: 发送方(将代币发送到此钱包的人)
  • 对于 out 转账: 接收方(从此钱包接收代币的人)

使用案例

跟踪商户付款历史

监控入账的 USDC 付款:
const trackMerchantPayments = async (merchantWallet) => {
  const data = await getWalletTransfers(merchantWallet);

  // Filter for incoming USDC transfers
  const usdcPayments = data.data.filter(t =>
    t.direction === 'in' &&
    t.mint === 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // USDC
  );

  console.log(`Received ${usdcPayments.length} USDC payments`);

  const totalReceived = usdcPayments.reduce((sum, t) => sum + t.amount, 0);
  console.log(`Total USDC Received: $${totalReceived.toFixed(2)}`);

  // Display each payment
  usdcPayments.forEach(payment => {
    const date = new Date(payment.timestamp * 1000).toLocaleString();
    console.log(`${date}: $${payment.amount} from ${payment.counterparty}`);
  });

  return {
    count: usdcPayments.length,
    total: totalReceived,
    payments: usdcPayments
  };
};

生成付款收据

为特定转账创建详细收据:
const generatePaymentReceipt = async (address, signature) => {
  const data = await getWalletTransfers(address);

  const transfer = data.data.find(t => t.signature === signature);

  if (!transfer) {
    console.log('Transfer not found');
    return null;
  }

  const receipt = {
    receiptId: transfer.signature.slice(0, 16),
    date: new Date(transfer.timestamp * 1000).toISOString(),
    type: transfer.direction === 'in' ? 'Payment Received' : 'Payment Sent',
    amount: `${transfer.amount} ${transfer.symbol || 'tokens'}`,
    from: transfer.direction === 'in' ? transfer.counterparty : address,
    to: transfer.direction === 'out' ? transfer.counterparty : address,
    transactionUrl: `https://orbmarkets.io/tx/${transfer.signature}`
  };

  console.log('--- PAYMENT RECEIPT ---');
  Object.entries(receipt).forEach(([key, value]) => {
    console.log(`${key}: ${value}`);
  });

  return receipt;
};

监控可疑转账模式

检测异常转账活动:
const detectSuspiciousActivity = async (address) => {
  const data = await getWalletTransfers(address);

  const recentTransfers = data.data.filter(t => {
    const hourAgo = Date.now() / 1000 - 3600;
    return t.timestamp > hourAgo;
  });

  // Check for high frequency
  if (recentTransfers.length > 100) {
    console.log(`Warning: ${recentTransfers.length} transfers in the last hour`);
  }

  // Check for large amounts
  const largeTransfers = recentTransfers.filter(t => {
    // Assuming USDC/stablecoins
    return t.amount > 10000 && t.decimals === 6;
  });

  if (largeTransfers.length > 0) {
    console.log(`Warning: ${largeTransfers.length} large transfers (>$10k) in the last hour`);
  }

  // Check for transfers to same address
  const counterparties = recentTransfers.map(t => t.counterparty);
  const duplicates = counterparties.filter((item, index) => counterparties.indexOf(item) !== index);

  if (duplicates.length > 5) {
    console.log(`Warning: Multiple transfers to the same address`);
  }

  return {
    recentCount: recentTransfers.length,
    largeTransfers: largeTransfers.length,
    suspiciousPatterns: duplicates.length > 5
  };
};

构建转账活动动态

创建用户友好的活动动态:
const buildTransferFeed = async (address) => {
  const data = await getWalletTransfers(address);

  const feed = data.data.map(transfer => {
    const date = new Date(transfer.timestamp * 1000);
    const timeAgo = getTimeAgo(date);

    return {
      id: transfer.signature,
      icon: transfer.direction === 'in' ? '📥' : '📤',
      title: transfer.direction === 'in' ? 'Received' : 'Sent',
      subtitle: `${transfer.amount} ${transfer.symbol || 'tokens'}`,
      description: transfer.direction === 'in'
        ? `from ${transfer.counterparty.slice(0, 8)}...`
        : `to ${transfer.counterparty.slice(0, 8)}...`,
      timeAgo,
      explorerUrl: `https://orbmarkets.io/tx/${transfer.signature}`
    };
  });

  return feed;
};

function getTimeAgo(date) {
  const seconds = Math.floor((new Date() - date) / 1000);

  if (seconds < 60) return 'Just now';
  if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
  if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
  return `${Math.floor(seconds / 86400)}d ago`;
}

对账付款

将转账与预期付款匹配:
const reconcilePayments = async (address, expectedPayments) => {
  const data = await getWalletTransfers(address);

  const recentTransfers = data.data.filter(t =>
    t.direction === 'in' &&
    t.mint === 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // USDC
  );

  const reconciliation = expectedPayments.map(expected => {
    const match = recentTransfers.find(t =>
      Math.abs(t.amount - expected.amount) < 0.01 &&
      t.counterparty === expected.from
    );

    return {
      orderId: expected.orderId,
      expectedAmount: expected.amount,
      status: match ? 'Received' : 'Pending',
      receivedAmount: match?.amount,
      signature: match?.signature,
      timestamp: match?.timestamp
    };
  });

  console.log('Payment Reconciliation:');
  reconciliation.forEach(r => {
    console.log(`Order ${r.orderId}: ${r.status}`);
  });

  return reconciliation;
};

// Example usage
const expected = [
  { orderId: 'ORDER-001', amount: 100.00, from: 'ABC...' },
  { orderId: 'ORDER-002', amount: 250.50, from: 'XYZ...' }
];

reconcilePayments("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY", expected);

分页

对于有大量转账的钱包,使用分页获取所有结果:
const getAllTransfers = async (address) => {
  let allTransfers = [];
  let cursor = null;

  do {
    const url = cursor
      ? `https://api.helius.xyz/v1/wallet/${address}/transfers?api-key=YOUR_API_KEY&cursor=${cursor}`
      : `https://api.helius.xyz/v1/wallet/${address}/transfers?api-key=YOUR_API_KEY`;

    const response = await fetch(url);
    const data = await response.json();

    allTransfers = allTransfers.concat(data.data);
    cursor = data.pagination.hasMore ? data.pagination.nextCursor : null;

    console.log(`Fetched ${allTransfers.length} transfers so far...`);

  } while (cursor);

  console.log(`\nTotal transfers: ${allTransfers.length}`);
  return allTransfers;
};

最佳实践

API 返回所有代币转账。在客户端通过 mint 地址过滤以跟踪特定代币,如 USDC 或 SOL。
使用身份 API 显示已知对手(交易所、协议等)的可读名称。
转账数据不会改变。缓存结果,只获取自上次查询以来的新转账。
实现分页以高效处理有数千次转账的钱包。
并非所有代币都有 symbol 字段。当 symbolnull 时,退而显示铸币地址。

转账与交易历史

功能转账交易历史
重点仅代币转账所有交易类型
数据发件人/收件人信息所有代币的余额变化
用例付款跟踪完整活动日志
性能更快,更简单更全面
当您只关注付款时,请使用转账。当您需要完整的余额变化数据时,请使用交易历史

常见错误

错误代码描述解决方案
400无效的钱包地址格式验证地址是否为有效的 base58 Solana 地址
401缺少或无效的 API 密钥确保请求中包含您的 API 密钥
429超出速率限制减少请求频率或升级您的计划

需要帮助?

API 参考

查看详细的 API 规格与请求/响应模式

联系支持

获得我们的团队帮助