Solana JSON-RPC API 有几十个方法。大多数文档全列、不分主次。实践里,~10 个方法覆盖 95% 生产代码做的事。知道用哪个、怎么用好,比记完整面更有用。
这是你实际会用的 JSON-RPC 方法参考、每个带生产模式。
高频方法
生产代码反复调用的方法。
getAccountInfo
读单个账户状态。
const account = await connection.getAccountInfo(pubkey, "confirmed");
什么时候用:你需要一个账户的数据。
性能提示:
- 一次调用要多账户用
getMultipleAccountsInfo - 缓存变化慢的数据(代币元数据、程序所有权)
getMultipleAccountsInfo
一次调用读多个账户。
const accounts = await connection.getMultipleAccountsInfo(
[key1, key2, key3],
"confirmed"
);
什么时候用:要 2 个以上账户。永远偏好这个、不要循环 getAccountInfo。
限制:每次调用 ~100 账户。批量更大集合。
getProgramAccounts
读程序拥有的所有账户。
const accounts = await connection.getProgramAccounts(programId, {
filters: [
{ dataSize: 165 },
{ memcmp: { offset: 0, bytes: ownerKey.toBase58() } },
],
});
什么时候用:枚举匹配具体条件的账户。
永远用 filter。 不带 filter 会拉几 MB 数据。
一些 RPC 服务商出于成本理由限 getProgramAccounts。查你服务商策略。
getLatestBlockhash
拿最近 blockhash 给交易签名用。
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
什么时候用:你要构建签名交易。
大多数情况用 "confirmed" commitment。别缓存;每笔交易拿新的。
sendTransaction / sendRawTransaction
提交签名交易。
const signature = await connection.sendTransaction(tx, signers, {
skipPreflight: true,
maxRetries: 0,
});
// 或预序列化:
const signature = await connection.sendRawTransaction(tx.serialize(), {
skipPreflight: true,
maxRetries: 0,
});
什么时候用:提交交易给打包。
生产模式:skipPreflight: true, maxRetries: 0。看 sendTransaction 最佳实践。
confirmTransaction
等交易上链。
const result = await connection.confirmTransaction(
{ signature, blockhash, lastValidBlockHeight },
"confirmed"
);
if (result.value.err) {
// 交易执行期间失败
}
什么时候用:发送后,你要知道是不是上链了。
新的"签名带 blockhash"形式比老的"只签名"形式更可靠。
simulateTransaction
不提交跑一遍交易。
const sim = await connection.simulateTransaction(tx);
console.log("用 CU:", sim.value.unitsConsumed);
console.log("日志:", sim.value.logs);
什么时候用:开发期测试、profile CU 用量、debug。
生产里偏好 skipPreflight: true 跳模拟。模拟只给诊断。
getBalance
拿钱包 SOL 余额。
const balance = await connection.getBalance(pubkey, "confirmed");
console.log(balance); // Lamports
什么时候用:检查钱包资金、给用户显示余额。
getTokenAccountBalance
拿 SPL 代币账户余额。
const balance = await connection.getTokenAccountBalance(tokenAccountKey, "confirmed");
console.log(balance.value.uiAmount);
什么时候用:检查代币持仓。
要查钱包持有的所有代币,用 getTokenAccountsByOwner。
getSignaturesForAddress
拿地址最近的交易签名。
const sigs = await connection.getSignaturesForAddress(pubkey, { limit: 100 });
什么时候用:搭交易历史视图、监控活动。
生产级索引,专门索引方案比这方法好。
getTransaction
取具体交易详情。
const tx = await connection.getTransaction(signature, {
commitment: "confirmed",
maxSupportedTransactionVersion: 0,
});
什么时候用:查具体交易结果、debug。
maxSupportedTransactionVersion: 0 给版本化交易(大多数现代交易)需要。
订阅方法(WebSocket)
要实时更新而不是轮询。
onAccountChange
账户状态变化时被通知。
const subId = connection.onAccountChange(
pubkey,
(accountInfo, context) => {
handleChange(accountInfo, context.slot);
},
"confirmed"
);
// 清理:
await connection.removeAccountChangeListener(subId);
onLogs
被通知程序日志发出。
const subId = connection.onLogs(
programId,
(logs, context) => {
if (logs.err === null) {
// 解析事件
}
},
"confirmed"
);
onSignature
具体交易确认时被通知。
const subId = connection.onSignature(
signature,
(result, context) => {
if (result.err === null) {
// 已确认
}
},
"confirmed"
);
反应式应用用这些替代轮询。
不那么常见但有用的方法
getRecentPrioritizationFees
拿最近 priority fee 数据,给 tip 策略用。
const fees = await connection.getRecentPrioritizationFees();
// 最近 slot 的 slot/fee 对数组
什么时候用:实现动态 priority fee 策略。
getSlot
当前 slot 号。
const slot = await connection.getSlot("processed");
什么时候用:定时决策、新鲜度检查、健康监控。
getEpochInfo
当前 epoch 状态。
const epoch = await connection.getEpochInfo("confirmed");
什么时候用:监控 epoch 边界、staking 相关逻辑。
getTokenAccountsByOwner
钱包拥有的所有代币账户。
const accounts = await connection.getTokenAccountsByOwner(
ownerKey,
{ programId: TOKEN_PROGRAM_ID }
);
什么时候用:钱包 UI 显示所有代币、组合分析。
getInflationRate
当前通胀率。
const rate = await connection.getInflationRate();
什么时候用:staking 计算、validator 经济学。
生产里避免的方法
一些方法值得避免高频用:
不带 filter 的 getProgramAccounts。 拉所有的;贵。
getBlock。 返完整块数据;大响应。只在你要块级详情时用。
getConfirmedTransaction(废弃)。 用 getTransaction 替代。
getRecentBlockhash(废弃)。 用 getLatestBlockhash 替代。
Commitment 等级
大多数读方法接受三个 commitment 等级:
"processed"。 最新可用状态。能被短分叉 reorg。最快。
"confirmed"。 三分之二的 validator 已投票。实际上稳定,适合做默认。
"finalized"。 完全终结。最慢但不可反驳。
大多数生产代码 "confirmed" 对。"processed" 只在延迟重要且能处理 reorg 时用。"finalized" 给高价值不可撤销决定。
常见模式
批量读: 永远用 getMultipleAccountsInfo 而不是循环 getAccountInfo。
过滤查询: getProgramAccounts 永远用 filter。
订阅胜过轮询: 反应式 app,订阅在性能和新鲜度上都赢轮询。
发送后确认: 永远确认你发的交易。别信签名返回意味着上链。
缓存变化慢的数据: 代币元数据、程序所有权等。激进缓存。
这周可以做什么
审你的 RPC 用法:
- 数你方法调用。 你最用什么方法?
- 审批量读。 该用
getMultipleAccountsInfo时用了吗? - 审 filter 用法。
getProgramAccounts调用永远带 filter? - 审订阅 vs 轮询。 反应式用例,偏好订阅。
- 审 commitment 等级。 每个用例用对的吗?
- Profile 每方法延迟。 一些方法重;高频在重方法上是问题。
试一下 BoltTx
具体到 sendTransaction:
import { Connection } from "@solana/web3.js";
const connection = new Connection(
"https://bolttx.io/?api-key=YOUR_API_KEY",
"processed"
);
const signature = await connection.sendTransaction(tx, signers, {
skipPreflight: true,
maxRetries: 0,
});
免费档注册。读流量配你认为合适的任何读服务商。
常见问题
规范参考在哪? Solana 官方 JSON-RPC API 文档。这篇覆盖实际用的子集。
RPC 方法跨服务商标准化吗? 方法名和参数标准。行为和限流看服务商变。
能在一个 HTTP 请求里批多个 JSON-RPC 调用吗? JSON-RPC 2.0 协议层支持批量;服务商支持参差。大多数情况批量没显著加速。
每方法延迟成本是什么? 变化。读典型几十到几百毫秒;写有额外确认延迟。
该用废弃的方法名吗? 不。可能未来版本停工作。用当前名字。