参数
账户地址(base-58 编码)
响应
代码示例
基本请求
复制
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": "getSignaturesForAddress",
"params": [
"ADDRESS"
]
}'
带配置的请求
复制
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": "getSignaturesForAddress",
"params": [
"ADDRESS",
{
"limit": 100,
"before": "SIGNATURE",
"commitment": "confirmed"
}
]
}'
使用 web3.js
复制
import { Connection, PublicKey } from '@solana/web3.js';
const connection = new Connection('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY');
// Get signatures for address
const signatures = await connection.getSignaturesForAddress(
new PublicKey('ADDRESS')
);
console.log('Signatures:', signatures);
// Get paginated signatures
async function getPaginatedSignatures(
address: PublicKey,
limit: number = 100,
before?: string
) {
const signatures = await connection.getSignaturesForAddress(address, {
limit,
before
});
return signatures.map(signature => ({
signature: signature.signature,
slot: signature.slot,
success: !signature.err,
timestamp: signature.blockTime,
status: signature.confirmationStatus
}));
}
注意事项
- 返回地址的已确认交易签名
- 结果按时间倒序返回
- 可以使用
before参数实现分页 - 响应是即时的,因为它从当前状态读取
- 可以指定不同的 commitment 级别
最佳实践
- 根据需求使用适当的限制数量
- 对大型结果集实现分页
- 在适当时缓存结果以减少 RPC 负载
- 考虑使用 WebSocket 订阅获取实时更新
- 适当处理网络错误并重试
常见错误
| 错误码 | 消息 | 解决方案 |
|---|---|---|
| -32601 | Method not found | 验证是否连接到 Solana RPC 节点 |
| -32602 | Invalid params | 检查地址和配置参数 |
| -32007 | Signature information unavailable | 节点可能正在启动或同步中 |
用例
-
交易历史
复制
interface TransactionHistory { transactions: Array<{ signature: string; slot: number; success: boolean; timestamp: number; status: string; }>; metadata: { total: number; startTime: number; endTime: number; }; } async function getTransactionHistory( address: PublicKey, limit: number = 100 ): Promise<TransactionHistory> { const signatures = await connection.getSignaturesForAddress(address, { limit }); return { transactions: signatures.map(signature => ({ signature: signature.signature, slot: signature.slot, success: !signature.err, timestamp: signature.blockTime || 0, status: signature.confirmationStatus || 'unknown' })), metadata: { total: signatures.length, startTime: signatures[0]?.blockTime || 0, endTime: signatures[signatures.length - 1]?.blockTime || 0 } }; } -
交易监控
复制
interface TransactionAlert { type: 'new' | 'failed' | 'status_change'; signature: string; previousStatus: string | null; currentStatus: string; metadata: { timestamp: number; slot: number; }; } class TransactionMonitor { private previousSignatures: Map<string, any> = new Map(); async monitorTransactions( address: PublicKey, interval: number = 5000 ): Promise<TransactionAlert[]> { const signatures = await connection.getSignaturesForAddress(address, { limit: 10 }); const alerts: TransactionAlert[] = []; signatures.forEach(signature => { const previous = this.previousSignatures.get(signature.signature); if (!previous) { alerts.push({ type: 'new', signature: signature.signature, previousStatus: null, currentStatus: signature.confirmationStatus || 'unknown', metadata: { timestamp: Date.now(), slot: signature.slot } }); } else if (previous.confirmationStatus !== signature.confirmationStatus) { alerts.push({ type: 'status_change', signature: signature.signature, previousStatus: previous.confirmationStatus, currentStatus: signature.confirmationStatus || 'unknown', metadata: { timestamp: Date.now(), slot: signature.slot } }); } this.previousSignatures.set(signature.signature, signature); }); return alerts; } } -
交易分析
复制
interface TransactionAnalysis { total: number; successful: number; failed: number; statusDistribution: Record<string, number>; timeDistribution: { hourly: Record<number, number>; daily: Record<number, number>; }; metadata: { startTime: number; endTime: number; duration: number; }; } async function analyzeTransactions( address: PublicKey, limit: number = 1000 ): Promise<TransactionAnalysis> { const signatures = await connection.getSignaturesForAddress(address, { limit }); const statusDistribution: Record<string, number> = {}; const hourlyDistribution: Record<number, number> = {}; const dailyDistribution: Record<number, number> = {}; let successful = 0; let failed = 0; signatures.forEach(signature => { const status = signature.confirmationStatus || 'unknown'; statusDistribution[status] = (statusDistribution[status] || 0) + 1; if (signature.err) { failed++; } else { successful++; } if (signature.blockTime) { const date = new Date(signature.blockTime * 1000); const hour = date.getHours(); const day = date.getDay(); hourlyDistribution[hour] = (hourlyDistribution[hour] || 0) + 1; dailyDistribution[day] = (dailyDistribution[day] || 0) + 1; } }); return { total: signatures.length, successful, failed, statusDistribution, timeDistribution: { hourly: hourlyDistribution, daily: dailyDistribution }, metadata: { startTime: signatures[0]?.blockTime || 0, endTime: signatures[signatures.length - 1]?.blockTime || 0, duration: signatures.length > 1 ? (signatures[0]?.blockTime || 0) - (signatures[signatures.length - 1]?.blockTime || 0) : 0 } }; }