参数
程序公钥(base-58 编码)
显示 config fields
显示 config fields
响应
代码示例
基本请求
复制
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": "getProgramAccounts",
"params": [
"PROGRAM_ID"
]
}'
带过滤器的请求
复制
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": "getProgramAccounts",
"params": [
"PROGRAM_ID",
{
"filters": [
{
"dataSize": 165
},
{
"memcmp": {
"offset": 0,
"bytes": "BASE58_ENCODED_BYTES"
}
}
]
}
]
}'
使用 web3.js
复制
import { Connection, PublicKey } from '@solana/web3.js';
const connection = new Connection('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY');
// Get all program accounts
const accounts = await connection.getProgramAccounts(
new PublicKey('PROGRAM_ID')
);
console.log('Accounts:', accounts);
// Get filtered program accounts
async function getFilteredProgramAccounts(
programId: PublicKey,
filters: any[]
) {
const accounts = await connection.getProgramAccounts(programId, {
filters
});
return accounts.map(({ pubkey, account }) => ({
pubkey: pubkey.toBase58(),
data: account.data,
lamports: account.lamports,
owner: account.owner.toBase58(),
executable: account.executable
}));
}
注意事项
- 返回特定程序拥有的所有账户
- 可以应用过滤器缩小结果范围
- 可以对账户数据进行切片以减少响应大小
- 响应是即时的,因为它从当前状态读取
- 可以为账户数据指定不同的编码格式
最佳实践
- 使用过滤器高效查询特定账户
- 考虑使用 dataSlice 减少响应大小
- 在适当时缓存结果以减少 RPC 负载
- 使用分页处理大型结果集
- 根据需求使用适当的编码格式
常见错误
| 错误码 | 消息 | 解决方案 |
|---|---|---|
| -32601 | Method not found | 验证是否连接到 Solana RPC 节点 |
| -32602 | Invalid params | 检查 programId 和配置参数 |
| -32007 | Account information unavailable | 节点可能正在启动或同步中 |
用例
-
程序账户分析
复制
interface ProgramAccountAnalysis { pubkey: string; dataSize: number; dataHash: string; lamports: number; metadata: { timestamp: number; }; } async function analyzeProgramAccounts( programId: PublicKey, filters?: any[] ): Promise<ProgramAccountAnalysis[]> { const accounts = await connection.getProgramAccounts(programId, { filters, encoding: 'base64' }); return accounts.map(({ pubkey, account }) => { const data = account.data[0]; const dataSize = Buffer.from(data, 'base64').length; return { pubkey: pubkey.toBase58(), dataSize, dataHash: require('crypto') .createHash('sha256') .update(data) .digest('hex'), lamports: account.lamports, metadata: { timestamp: Date.now() } }; }); } -
程序账户监控
复制
interface ProgramAccountChange { pubkey: string; type: 'created' | 'deleted' | 'modified'; previous: any; current: any; difference: number; } class ProgramAccountMonitor { private previousAccounts: Map<string, any> = new Map(); async monitorProgramAccounts( programId: PublicKey, filters?: any[], interval: number = 5000 ): Promise<ProgramAccountChange[]> { const accounts = await connection.getProgramAccounts(programId, { filters }); const changes: ProgramAccountChange[] = []; accounts.forEach(({ pubkey, account }) => { const address = pubkey.toBase58(); const current = account; const previous = this.previousAccounts.get(address); if (!previous && current) { changes.push({ pubkey: address, type: 'created', previous: null, current, difference: current.lamports }); } else if (previous && !current) { changes.push({ pubkey: address, type: 'deleted', previous, current: null, difference: -previous.lamports }); } else if (previous && current) { const difference = current.lamports - previous.lamports; if (difference !== 0 || current.data[0] !== previous.data[0]) { changes.push({ pubkey: address, type: 'modified', previous, current, difference }); } } this.previousAccounts.set(address, current); }); return changes; } } -
程序账户分页
复制
interface ProgramAccountPage { accounts: Array<{ pubkey: string; data: any; lamports: number; }>; total: number; page: number; pageSize: number; metadata: { timestamp: number; }; } async function getProgramAccountPage( programId: PublicKey, page: number = 1, pageSize: number = 100, filters?: any[] ): Promise<ProgramAccountPage> { const accounts = await connection.getProgramAccounts(programId, { filters, encoding: 'base64' }); const start = (page - 1) * pageSize; const end = start + pageSize; const pageAccounts = accounts.slice(start, end); return { accounts: pageAccounts.map(({ pubkey, account }) => ({ pubkey: pubkey.toBase58(), data: account.data[0], lamports: account.lamports })), total: accounts.length, page, pageSize, metadata: { timestamp: Date.now() } }; }