跳转到主要内容

概述

getTransactionsForAddress 将交易签名查找和完整交易检索合并为一次高效调用。无需分别请求 getSignaturesForAddress 然后对每个签名调用 getTransaction,您可以在单次请求中获得所有内容。 此方法支持:
  • 双向排序(最旧优先或最新优先)
  • 基于时间和 slot 的过滤
  • 交易状态过滤(成功/失败)
  • 代币账户过滤
  • 基于游标的分页

为什么使用此方法

N+1 问题

使用标准 Solana RPC 方法获取交易历史需要多次调用:
  1. 调用 getSignaturesForAddress 获取交易签名列表
  2. 每个签名调用 getTransaction 获取完整交易数据
对于有 100 笔交易的钱包,这意味着 101 次 API 调用。对于 1,000 笔交易,则是 1,001 次调用。这会造成延迟、复杂性和更高的成本。 getTransactionsForAddress 通过单次调用返回完整交易数据解决了这个问题——每次请求最多 100 笔完整交易或 1,000 个签名。

附加功能

除了效率之外,此方法还提供标准 RPC 中不可用的功能:
  • 双向排序:以最旧优先(asc)查询,从第一笔交易开始追溯地址
  • 基于时间的过滤:检索特定日期范围内的交易
  • 基于 slot 的过滤:查询特定区块范围的交易
  • 状态过滤:仅获取成功或仅获取失败的交易
  • 代币账户包含:捕获关联代币账户的交易

代币账户支持

标准 getSignaturesForAddress 仅返回直接引用查询地址的交易。这会遗漏一个重要类别:代币转账 当代币被发送到钱包时,交易引用的是钱包的关联代币账户(ATA),而非钱包地址本身。这意味着标准方法给您的是不完整的画面。 带有 tokenAccounts: "all"getTransactionsForAddress 自动包含该地址拥有的所有代币账户的交易,为您提供完整的交易历史。
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "WALLET_ADDRESS",
    {
      "filters": {
        "tokenAccounts": "all"
      }
    }
  ]
}'
如果您只想获取直接引用该地址的交易,请设置 tokenAccounts: "none"

参数

address
string
必填
要查询的 Solana 地址(base-58 编码的公钥)
options
object

响应

响应格式取决于 transactionDetails 参数。

transactionDetails: "full"

result
array
完整交易对象数组,每个包含:

transactionDetails: "signatures"

result
array
签名对象数组,每个包含:

代码示例

基本请求

获取地址的最新交易:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "ADDRESS_HERE"
  ]
}'

仅获取签名

检索最多 1000 个签名,不含完整交易数据:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "ADDRESS_HERE",
    {
      "transactionDetails": "signatures",
      "limit": 1000
    }
  ]
}'

最旧优先并按时间过滤

获取特定时间范围内的交易,按最旧优先排序:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "ADDRESS_HERE",
    {
      "sortOrder": "asc",
      "filters": {
        "afterTime": 1704067200,
        "beforeTime": 1706745600
      }
    }
  ]
}'

仅成功交易

仅过滤返回成功的交易:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "ADDRESS_HERE",
    {
      "filters": {
        "status": "success"
      }
    }
  ]
}'

分页请求

使用基于游标的分页获取更多结果:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "ADDRESS_HERE",
    {
      "limit": 100,
      "before": "LAST_SIGNATURE_FROM_PREVIOUS_RESPONSE"
    }
  ]
}'

TypeScript 示例

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

const connection = new Connection('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY');

interface GetTransactionsOptions {
  transactionDetails?: 'full' | 'signatures';
  limit?: number;
  sortOrder?: 'asc' | 'desc';
  before?: string;
  after?: string;
  filters?: {
    tokenAccounts?: 'all' | 'none';
    beforeTime?: number;
    afterTime?: number;
    beforeSlot?: number;
    afterSlot?: number;
    status?: 'success' | 'failed';
  };
}

async function getTransactionsForAddress(
  address: string,
  options: GetTransactionsOptions = {}
) {
  const response = await fetch('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 1,
      method: 'getTransactionsForAddress',
      params: [address, options],
    }),
  });

  const data = await response.json();
  return data.result;
}

// Get recent transactions
const recent = await getTransactionsForAddress('ADDRESS_HERE');

// Get oldest transactions first with time filter
const historical = await getTransactionsForAddress('ADDRESS_HERE', {
  sortOrder: 'asc',
  filters: {
    afterTime: Math.floor(Date.now() / 1000) - 86400 * 30, // Last 30 days
  },
});

// Paginate through all transactions
async function getAllTransactions(address: string) {
  const allTransactions = [];
  let before: string | undefined;

  while (true) {
    const batch = await getTransactionsForAddress(address, {
      limit: 100,
      before,
    });

    if (!batch || batch.length === 0) break;

    allTransactions.push(...batch);
    before = batch[batch.length - 1].signature;
  }

  return allTransactions;
}

使用场景

代币发行分析

查找代币铸造的最早交易,以识别首批铸造者和早期持有者。使用 sortOrder: "asc" 从最早开始:
const earlyActivity = await getTransactionsForAddress(tokenMintAddress, {
  sortOrder: 'asc',
  limit: 100,
  filters: {
    tokenAccounts: 'all',
  },
});

钱包资金来源历史

通过查询完整交易历史追溯钱包资金来源:
const fundingHistory = await getTransactionsForAddress(walletAddress, {
  sortOrder: 'asc',
  filters: {
    tokenAccounts: 'all',
  },
  transactionDetails: 'full',
});

// First transactions often reveal funding sources
const firstTransactions = fundingHistory.slice(0, 10);

失败交易分析

通过过滤仅显示失败交易来调试交易失败:
const failedTxs = await getTransactionsForAddress(walletAddress, {
  filters: {
    status: 'failed',
  },
  transactionDetails: 'full',
});

// Analyze error logs to understand failure reasons
failedTxs.forEach(tx => {
  console.log(tx.signature, tx.meta?.err, tx.meta?.logMessages);
});

构建钱包交易动态

为钱包界面创建分页交易历史:
async function getWalletFeed(wallet: string, cursor?: string) {
  return getTransactionsForAddress(wallet, {
    limit: 20,
    before: cursor,
    transactionDetails: 'full',
    filters: {
      tokenAccounts: 'all',
    },
  });
}

交易模式分析

过滤特定时间窗口内的成功交易:
const trades = await getTransactionsForAddress(traderWallet, {
  filters: {
    status: 'success',
    afterTime: startOfMonth,
    beforeTime: endOfMonth,
  },
  transactionDetails: 'full',
});

合规审计

为监管合规构建完整的交易历史:
async function auditAddress(address: string) {
  const allTxs = await getAllTransactions(address);

  return {
    totalTransactions: allTxs.length,
    successful: allTxs.filter(tx => !tx.err).length,
    failed: allTxs.filter(tx => tx.err).length,
    firstTransaction: allTxs[allTxs.length - 1],
    lastTransaction: allTxs[0],
  };
}

分页

对于交易量大的地址,您需要对结果进行分页。该方法支持使用 beforeafter 参数的基于游标的分页。

获取较新的交易(默认)

使用 sortOrder: "desc"(默认),交易按最新优先返回。使用 before 获取更旧的交易:
// First request
const page1 = await getTransactionsForAddress(address, { limit: 100 });

// Get next page using last signature as cursor
const lastSignature = page1[page1.length - 1].signature;
const page2 = await getTransactionsForAddress(address, {
  limit: 100,
  before: lastSignature,
});

优先获取较旧的交易

使用 sortOrder: "asc",交易按最旧优先返回。使用 after 获取更新的交易:
// Get oldest transactions first
const page1 = await getTransactionsForAddress(address, {
  sortOrder: 'asc',
  limit: 100,
});

// Continue forward in time
const lastSignature = page1[page1.length - 1].signature;
const page2 = await getTransactionsForAddress(address, {
  sortOrder: 'asc',
  limit: 100,
  after: lastSignature,
});

完整分页示例

获取地址的所有交易:
async function getAllTransactions(address: string) {
  const allTransactions = [];
  let cursor: string | undefined;

  while (true) {
    const batch = await getTransactionsForAddress(address, {
      limit: 100,
      before: cursor,
      transactionDetails: 'full',
    });

    if (!batch || batch.length === 0) break;

    allTransactions.push(...batch);
    cursor = batch[batch.length - 1].signature;

    // Optional: Add delay to respect rate limits
    await new Promise(resolve => setTimeout(resolve, 100));
  }

  return allTransactions;
}

最佳实践

  1. 使用 signatures 模式进行计数:当您只需要计数或列出交易时,使用 transactionDetails: "signatures" 以获得更好的性能和更高的限制。
  2. 尽早过滤:应用时间、slot 或状态过滤器以减少返回的数据量并改善响应时间。
  3. 实施分页:对于交易量大的地址,始终使用 before 游标进行分页。
  4. 缓存结果:交易数据一旦确认就不可变。缓存历史结果以避免冗余请求。
  5. 处理速率限制:在进行多次连续请求时实施指数退避。

常见错误

代码消息解决方案
-32600Invalid request检查 JSON-RPC 格式和必需字段
-32602Invalid params验证地址格式和选项值
-32005Request limit exceeded减少限制或实施速率限制

与标准方法的对比

功能getSignaturesForAddress + getTransactiongetTransactionsForAddress
API 调用次数多次(1 + N)单次
排序仅最新优先双向
时间过滤不支持支持
状态过滤不支持支持
最大签名数每次调用 1000每次调用 1000
最大完整交易数受调用次数限制每次调用 100