@w3lib/solana-batch-call 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/README.md +16 -8
- package/dist/accountReader.d.ts +57 -0
- package/dist/accountReader.d.ts.map +1 -0
- package/dist/accountReader.js +149 -0
- package/dist/accountReader.js.map +1 -0
- package/dist/address.d.ts +9 -0
- package/dist/address.d.ts.map +1 -1
- package/dist/address.js +36 -6
- package/dist/address.js.map +1 -1
- package/dist/approvals.d.ts +5 -3
- package/dist/approvals.d.ts.map +1 -1
- package/dist/approvals.js +25 -36
- package/dist/approvals.js.map +1 -1
- package/dist/balances.d.ts +178 -0
- package/dist/balances.d.ts.map +1 -0
- package/dist/balances.js +524 -0
- package/dist/balances.js.map +1 -0
- package/dist/batchPlan.d.ts +2 -2
- package/dist/batchPlan.d.ts.map +1 -1
- package/dist/batchPlan.js +5 -26
- package/dist/batchPlan.js.map +1 -1
- package/dist/bytes.d.ts +31 -0
- package/dist/bytes.d.ts.map +1 -0
- package/dist/bytes.js +74 -0
- package/dist/bytes.js.map +1 -0
- package/dist/claim.d.ts +5 -3
- package/dist/claim.d.ts.map +1 -1
- package/dist/claim.js +10 -10
- package/dist/claim.js.map +1 -1
- package/dist/client.d.ts +26 -41
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +41 -986
- package/dist/client.js.map +1 -1
- package/dist/clientConfig.d.ts +11 -0
- package/dist/clientConfig.d.ts.map +1 -0
- package/dist/clientConfig.js +3 -0
- package/dist/clientConfig.js.map +1 -0
- package/dist/decode.d.ts.map +1 -1
- package/dist/decode.js +2 -29
- package/dist/decode.js.map +1 -1
- package/dist/fees.d.ts.map +1 -1
- package/dist/fees.js +2 -12
- package/dist/fees.js.map +1 -1
- package/dist/history.d.ts.map +1 -1
- package/dist/history.js +4 -15
- package/dist/history.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/layout.d.ts +21 -0
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +50 -69
- package/dist/layout.js.map +1 -1
- package/dist/liquidity/common.js +2 -2
- package/dist/liquidity/common.js.map +1 -1
- package/dist/lp.d.ts +9 -13
- package/dist/lp.d.ts.map +1 -1
- package/dist/lp.js +67 -55
- package/dist/lp.js.map +1 -1
- package/dist/portfolio.d.ts.map +1 -1
- package/dist/portfolio.js +3 -8
- package/dist/portfolio.js.map +1 -1
- package/dist/reclaim.d.ts +4 -2
- package/dist/reclaim.d.ts.map +1 -1
- package/dist/reclaim.js +16 -16
- package/dist/reclaim.js.map +1 -1
- package/dist/risk.js +2 -2
- package/dist/risk.js.map +1 -1
- package/dist/rpc.d.ts +30 -7
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +400 -109
- package/dist/rpc.js.map +1 -1
- package/dist/simulate.d.ts.map +1 -1
- package/dist/simulate.js +3 -26
- package/dist/simulate.js.map +1 -1
- package/dist/source.d.ts +8 -4
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +11 -4
- package/dist/source.js.map +1 -1
- package/dist/subpaths/approvals.d.ts +3 -3
- package/dist/subpaths/approvals.d.ts.map +1 -1
- package/dist/subpaths/approvals.js.map +1 -1
- package/dist/subpaths/claim.d.ts +3 -3
- package/dist/subpaths/claim.d.ts.map +1 -1
- package/dist/subpaths/claim.js.map +1 -1
- package/dist/subpaths/reclaim.d.ts +3 -3
- package/dist/subpaths/reclaim.d.ts.map +1 -1
- package/dist/subpaths/reclaim.js.map +1 -1
- package/dist/swap/index.js +3 -3
- package/dist/swap/index.js.map +1 -1
- package/dist/tokenDetails.d.ts +12 -0
- package/dist/tokenDetails.d.ts.map +1 -0
- package/dist/tokenDetails.js +196 -0
- package/dist/tokenDetails.js.map +1 -0
- package/dist/tokenMeta.d.ts +63 -0
- package/dist/tokenMeta.d.ts.map +1 -0
- package/dist/tokenMeta.js +226 -0
- package/dist/tokenMeta.js.map +1 -0
- package/dist/tradeCheck.js +3 -3
- package/dist/tradeCheck.js.map +1 -1
- package/dist/util.d.ts +22 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +107 -0
- package/dist/util.js.map +1 -0
- package/dist/write/chain.d.ts +51 -0
- package/dist/write/chain.d.ts.map +1 -0
- package/dist/write/chain.js +184 -0
- package/dist/write/chain.js.map +1 -0
- package/dist/write/collect.js +2 -2
- package/dist/write/collect.js.map +1 -1
- package/dist/write/errors.d.ts +10 -0
- package/dist/write/errors.d.ts.map +1 -0
- package/dist/write/errors.js +77 -0
- package/dist/write/errors.js.map +1 -0
- package/dist/write/pack.d.ts +28 -0
- package/dist/write/pack.d.ts.map +1 -0
- package/dist/write/pack.js +125 -0
- package/dist/write/pack.js.map +1 -0
- package/dist/write/send.d.ts +23 -9
- package/dist/write/send.d.ts.map +1 -1
- package/dist/write/send.js +53 -351
- package/dist/write/send.js.map +1 -1
- package/dist/write/tracker.d.ts +24 -0
- package/dist/write/tracker.d.ts.map +1 -0
- package/dist/write/tracker.js +129 -0
- package/dist/write/tracker.js.map +1 -0
- package/package.json +1 -1
- package/src/accountReader.ts +187 -0
- package/src/address.ts +41 -6
- package/src/approvals.ts +36 -44
- package/src/balances.ts +678 -0
- package/src/batchPlan.ts +6 -26
- package/src/bytes.ts +89 -0
- package/src/claim.ts +15 -11
- package/src/client.ts +59 -1239
- package/src/clientConfig.ts +12 -0
- package/src/decode.ts +4 -30
- package/src/fees.ts +2 -9
- package/src/history.ts +4 -15
- package/src/index.ts +13 -1
- package/src/layout.ts +63 -82
- package/src/liquidity/common.ts +2 -2
- package/src/lp.ts +86 -60
- package/src/portfolio.ts +8 -11
- package/src/reclaim.ts +20 -17
- package/src/risk.ts +2 -2
- package/src/rpc.ts +472 -116
- package/src/simulate.ts +3 -21
- package/src/source.ts +14 -5
- package/src/subpaths/approvals.ts +3 -2
- package/src/subpaths/claim.ts +3 -2
- package/src/subpaths/reclaim.ts +3 -2
- package/src/swap/index.ts +3 -3
- package/src/tokenDetails.ts +240 -0
- package/src/tokenMeta.ts +270 -0
- package/src/tradeCheck.ts +3 -3
- package/src/util.ts +110 -0
- package/src/write/chain.ts +218 -0
- package/src/write/collect.ts +2 -2
- package/src/write/errors.ts +82 -0
- package/src/write/pack.ts +142 -0
- package/src/write/send.ts +74 -407
- package/src/write/tracker.ts +152 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### 改进(读取链路,无破坏性变更)
|
|
6
|
+
|
|
7
|
+
- 取消传到底层:`RpcTransport.request` 新增可选的第三个参数 `{ signal }`(新增类型 `RpcRequestOptions`,自定义传输不处理也照常工作)。各查询的 `signal` 传给传输层:`HttpRpc` 合并超时与 signal 交给 `fetch`,还在排队的调用取消时直接移出队列,已发出的批量请求在所有成员都取消后才中止;`FallbackRpc` 取消后不再换节点,也不把节点记为故障;取消时 reject 的仍是 `signal.reason`
|
|
8
|
+
- publicnode 的已知限制预置:单次 `getMultipleAccounts` 最多 10 个账户、一个批量里最多 1 个,首次请求就按它拆分,不再先等 3 秒多的 403
|
|
9
|
+
- `HttpRpc` 新增 `maxConcurrency`(默认 4):同一节点地址同时在途的 HTTP 请求数上限(按 URL 在所有连接间共享),超出的排队:排队最多等 `timeout`(等不到按超时处理、多节点时换节点),发出后重新计时。之前大批量读取在 publicnode 上同时有二十多个请求
|
|
10
|
+
- 拆分后的 `getMultipleAccounts` 子请求、客户端分组读取改用并发池(不再整波等最慢的;出错后不再发后面的请求)
|
|
11
|
+
- 429 退避加 ±25% 随机抖动,有 `Retry-After` 头时按它等(超过 10 秒不等,直接报错交给上层换节点);413 / “Batch of more than N” 缩小的批量 10 分钟后恢复(之前永久缩小);学到的节点限制表有条目上限
|
|
12
|
+
- 去重:`HttpRpc` 同一批里 method 和 params 完全相同的只读调用只发一次(新增选项 `dedupe`,默认 true);补读代币 decimals / 元数据时,同一 mint 正在被别的查询读取就共用那次读取
|
|
13
|
+
- `/lp`:LP mint → 池子地址找到后缓存(最多 1 万条),之后不再 `getProgramAccounts`;按 LP mint 找池子同时最多 4 个
|
|
14
|
+
- 内部:并发池 `mapPool`、`sleep` 挪到公共的 `util.ts`
|
|
15
|
+
|
|
16
|
+
### 新功能 / 改进(第二阶段,公开 API 只新增)
|
|
17
|
+
|
|
18
|
+
- 写操作 `SendOptions` 新增 `sendRpc`(发送交易用的节点,按 client 的网络和节点选项解析,网络不一致时报 `NetworkMismatchError`;模拟和查确认状态仍用 client)和 `broadcast: 'first' | 'all'`(默认 `'first'`;`'all'` 同时发给所有节点,第一个接受就返回,其余在后台完成)
|
|
19
|
+
- 有优先费用时少一次模拟:第一次模拟顺带取付款方模拟后的余额(和当前余额同一个批量请求),付完优先费用后仍不低于免租下限就不再按真实费用模拟第二次。取舍:第二次模拟和第一次只隔几百毫秒、基于几乎同一个状态,按收紧后的计算单元上限复核几乎不会失败,挡不住发送时的状态变化;新增 `SendOptions.computeUnitMargin`(默认 `{ ratio: 1.1, extra: 1000 }`),消耗会波动的调用可以调大余量
|
|
20
|
+
- 内部的并发池(`mapPool`)一项出错后不再执行后面的项(/lp 找池子的 `getProgramAccounts`、/history 的 `getTransaction` 等)
|
|
21
|
+
- 等待确认时不再每轮都查 `getEpochInfo`:记下上次的(区块高度, slot),用状态查询返回的 slot 估算高度上限,可能过期时才查
|
|
22
|
+
- `priorityFee: 'auto'` 去掉 0 再取 75 分位:不活跃账户的最近费用大多是 0(2026-10 主网实测 USDC mint 150 个 slot 里 135 个为 0),之前几乎总是算出 0
|
|
23
|
+
- 打包合一:`batchCall` 等的发送和 `/reclaim`、`/claim` 的批量计划共用 `packUnits`,按累计的账户集合和指令字节增量估算交易大小(之前每加一个调用就完整编译整条消息),每笔最后完整编译校验一次;分组结果与之前相同
|
|
24
|
+
- `client.balances(owner, { mints, ...options })` 新写法(新类型 `BalancesQueryOptions`),旧写法 `balances(owner, mints, options)` 照常可用
|
|
25
|
+
- 地址非法时抛 `InvalidAddressError`(继承 `Error`,message 不变,带 `code: 'INVALID_ADDRESS'` 和 `address`),主入口导出
|
|
26
|
+
- `/approvals`、`/reclaim`、`/claim` 的查询参数类型改名为 `ApprovalsOptions`、`ReclaimableOptions`、`ClaimableOptions`(与其他查询的 options 统一),旧名 `ApprovalsQuery`、`ReclaimQuery`、`ClaimQuery` 保留为别名(@deprecated)
|
|
27
|
+
- 去重:同一批里相同的只读调用,第二个起的调用方拿到结果的副本(调用方修改结果不会影响别人)
|
|
28
|
+
- PDA 缓存的键改用种子的十六进制(不再每次 base58 编码),满了按 LRU 淘汰最久没用的(之前整表清空)
|
|
29
|
+
|
|
30
|
+
### 内部重构(导出路径和名字不变)
|
|
31
|
+
|
|
32
|
+
- `client.ts` 拆成 `tokenMeta.ts`(代币信息缓存)、`accountReader.ts`(账户读取管线)、`balances.ts`(三种余额查法、持仓列表)、`tokenDetails.ts`(代币详情 / NFT),`SolanaClient` 只保留薄的公开方法
|
|
33
|
+
- `write/send.ts` 拆出 `errors.ts`(交易错误文案)、`chain.ts`(blockhash / 优先费用 / 模拟 / 广播)、`tracker.ts`(确认轮询)、`pack.ts`(打包)
|
|
34
|
+
- 二进制读取器合一(`bytes.ts`,原 layout 的 Reader、lp 的 Bytes、decode 的 Data);代币账户完整布局的解析统一到 `layout.parseTokenAccountState`(/approvals、/simulate 共用);计算预算指令的上限 / 单价解码合一(`computeBudgetOf`,/simulate、/fees 共用);`history.ts` 的并发池改用公共的 `mapPool`;“方法不可用时说明怎么绕过”的报错包装抽成 `withMethodHint`(/lp、/approvals、资产总值共用)
|
|
35
|
+
|
|
3
36
|
## 0.6.0
|
|
4
37
|
|
|
5
38
|
### 新功能
|
package/README.md
CHANGED
|
@@ -123,7 +123,7 @@ await getLpPositions(owner, { provider, prices: true })
|
|
|
123
123
|
| 选项 | 说明 |
|
|
124
124
|
| --- | --- |
|
|
125
125
|
| `mints` | 只看这些代币(仓位 NFT 的 mint、LP 代币的 mint),按 ATA 读余额,免费节点也能用。不传时扫描全部代币账户(需要支持 `getTokenAccountsByOwner` 的节点) |
|
|
126
|
-
| `pools` | Raydium AMM v4 / CPMM 的池子地址。LP 代币要找到对应的池子:不在这里的按 LP mint 用 `getProgramAccounts`
|
|
126
|
+
| `pools` | Raydium AMM v4 / CPMM 的池子地址。LP 代币要找到对应的池子:不在这里的按 LP mint 用 `getProgramAccounts` 查找(同时最多 4 个;找到的池子地址会缓存,之后只读池子账户核对;免费公共节点大多不支持,这时报错并提示传 `pools`,或用 `protocols` 只查 CLMM / Whirlpool);不是 AMM v4 / CPMM 池子的地址会报错;不持有 Raydium 的 LP 代币时不会用到 |
|
|
127
127
|
| `protocols` | 只查某些协议:`'raydium-clmm'`、`'orca-whirlpool'`、`'raydium-amm'`、`'raydium-cpmm'`,默认全部 |
|
|
128
128
|
| `includeClosed` | 返回已清空的仓位(流动性为 0、手续费也领完,NFT 还在),默认 false |
|
|
129
129
|
| `prices` | `true` 用 DefiLlama,也可以传自己的 `SolanaPriceSource`;默认不查。价格源出错时照样返回仓位,只是 `valueUsd` / `feesUsd` 为 null |
|
|
@@ -330,7 +330,7 @@ await getCostEstimate({ feePayer: owner, instructions: [ix1, ix2] })
|
|
|
330
330
|
await getCostEstimate({ transaction: base64Tx }) // 构建好的交易(如聚合器 API 返回的),按交易自带的计算预算算
|
|
331
331
|
```
|
|
332
332
|
|
|
333
|
-
- **费用建议**:`getRecentPrioritizationFees` 返回最近 150 个 slot 里(会写 `accounts` 的)落块交易的**最低**单价,三档取第 50 / 75 / 90 百分位(`percentiles`),`normal`
|
|
333
|
+
- **费用建议**:`getRecentPrioritizationFees` 返回最近 150 个 slot 里(会写 `accounts` 的)落块交易的**最低**单价,三档取第 50 / 75 / 90 百分位(`percentiles`),`normal` 是包含 0 的 75 分位(`/write` 的 `priorityFee: 'auto'` 去掉 0 再取 75 分位,并受 `maxPriorityFee` 限制)。不传 `accounts` 时看全网,大多是 0(每个区块总有不加优先费的交易);估某笔交易时传它的可写账户(`estimateCost` 自动这样做)
|
|
334
334
|
- **一笔交易**:模拟一次(`sigVerify: false`、`replaceRecentBlockhash`,不需要签名、不会发送),模拟失败时抛出(带程序日志里的原因)。传指令时按 `/write` 的发送方式算:去掉自带的计算预算指令,计算单元上限 = 模拟消耗 × 1.1 + 1000,单价按这一档(`level`,或 `priorityFee` 直接指定,或传查好的 `fees` 共用);传构建好的交易时按它自带的 SetComputeUnitLimit / SetComputeUnitPrice(没有单价时优先费为 0,没有上限时按每条指令 20 万),v0 交易会读地址查找表找可写账户
|
|
335
335
|
- **手续费** = 每个签名 5000 lamports + 单价 × 上限(向上取整)。**押金**:交易前不存在、模拟后存在、有数据或不归 System Program 的可写账户(新建的代币账户、仓位等),按 `getMinimumBalanceForRentExemption` 算(不写死:2026-10 主网 165 字节是 1,488,440 lamports),关闭账户时退回;普通转账给新地址不算押金
|
|
336
336
|
- 只支持 legacy 和 v0 交易:主网已经有 v1 格式的交易(2026-10 约三成),它们的布局不同,传入时报错(改传指令)
|
|
@@ -544,6 +544,8 @@ await getHistory(address, { source: [heliusHistory({ apiKey }), rpcHistory()] })
|
|
|
544
544
|
|
|
545
545
|
## 余额的三种模式
|
|
546
546
|
|
|
547
|
+
`client.balances(owner, mints, options)` 也可以写成 `client.balances(owner, { mints, ...options })`(两种写法等价)。
|
|
548
|
+
|
|
547
549
|
| | 指定 mints(默认,`accounts: 'ata'`) | 指定 mints + `accounts: 'all'` | 扫描(不传 mints,或 `scan: true`) |
|
|
548
550
|
| --- | --- | --- | --- |
|
|
549
551
|
| 实现 | 本地推导 ATA + 一次 `getMultipleAccounts` | 每个代币一次按 mint 过滤的 `getTokenAccountsByOwner`(同一 tick 发出,合并成批量请求) | `getTokenAccountsByOwner`(Token / Token-2022 各一次) |
|
|
@@ -565,7 +567,7 @@ await getBalances(owner, [USDC, PYUSD], { provider: 'https://my-rpc.example', ac
|
|
|
565
567
|
- **缓存**:decimals、所属程序永久缓存;name、symbol 来自可修改的元数据,缓存 1 小时(确认没有元数据的代币同样缓存,不会每次重查)。按网络共享(各函数共用);自定义节点且没指定 `cluster` 时只在该客户端内缓存。最多 5 万个代币,超出淘汰最早的
|
|
566
568
|
- **大数**:lamports 等 u64 超过 2⁵³ 时不会丢精度
|
|
567
569
|
- **失败**:mint 不存在、地址非法等只让该项 `success: false`,并带 `error` 说明原因;节点不可用等整个请求失败时才抛错(多个节点都失败时是 `AllNodesFailedError`,`err.errors` 里有每个节点的名称和原因)
|
|
568
|
-
- **取消**:所有查询都可以传 `signal`(`AbortSignal`)。已取消时直接 reject、不发请求;中途取消时立即 reject
|
|
570
|
+
- **取消**:所有查询都可以传 `signal`(`AbortSignal`)。已取消时直接 reject、不发请求;中途取消时立即 reject(reason 为 `signal.reason`)。signal 会传到底层:还在排队的请求不再发出,已经发出的 HTTP 请求在合并在一起的所有调用方都取消后中止,取消后也不再换节点。自定义传输的 `request(method, params, options?)` 可以从第三个参数拿到 `{ signal }`,不处理也照常工作
|
|
569
571
|
- **最低 slot**:`getBalances` / `getMultiBalances` / `getSolBalances` / `getOwnerTokens` / `accounts` 可以传 `minContextSlot`:节点高度不够时换下一个节点,都不够时每 500ms 重试,最多约 10 秒;`withSlot: true`(或传了 `minContextSlot`)时结果项带读取时的 `slot`(一次查询发了多个请求时取最小的)
|
|
570
572
|
|
|
571
573
|
## 轮询余额
|
|
@@ -617,6 +619,8 @@ token.transferFee
|
|
|
617
619
|
| `no-holder` | 没有持有人(供应量为 0 或已销毁) | `getNftOwners` |
|
|
618
620
|
| `missing-field` | 代币存在,但请求的字段读不到;`errorField` 是第一个读不到的字段(如没有元数据时的 `name`) | `getTokens` |
|
|
619
621
|
|
|
622
|
+
owner 等参数本身非法时(不是单项失败)抛 `InvalidAddressError`(继承 `Error`,message 不变,带 `code: 'INVALID_ADDRESS'` 和 `address`)。
|
|
623
|
+
|
|
620
624
|
```ts
|
|
621
625
|
const [item] = await getBalances(owner, [mint])
|
|
622
626
|
if (item.error === 'invalid-address') throw new Error('bad mint') // 参数错误
|
|
@@ -648,9 +652,11 @@ await getBalances(owner, mints, { provider: 'https://my-rpc.example', cluster: '
|
|
|
648
652
|
|
|
649
653
|
**传输层行为**(`HttpRpc`):
|
|
650
654
|
|
|
651
|
-
- 收集窗口(`batchWait`,默认 0 即同一 tick)内的调用合并成一个批量请求,最多 `maxBatchSize`(默认 20
|
|
652
|
-
-
|
|
653
|
-
-
|
|
655
|
+
- 收集窗口(`batchWait`,默认 0 即同一 tick)内的调用合并成一个批量请求,最多 `maxBatchSize`(默认 20)条;同一批里 method 和 params 完全相同的只读调用只发一次,结果分给各调用方(`dedupe: false` 关闭)
|
|
656
|
+
- 同一节点地址同时在途的 HTTP 请求最多 `maxConcurrency`(默认 4,按 URL 在所有连接间共享;`0` 不限制),超出的排队;排队最多等 `timeout`(等不到按超时处理、换节点),发出后重新计时
|
|
657
|
+
- publicnode 的已知限制(单次 `getMultipleAccounts` 最多 10 个账户、一个批量里最多 1 个 `getMultipleAccounts`)是预置的,第一次请求就按它拆分,不用先等 3 秒多的 403;其他节点的限制从报错里学到后按节点地址记住
|
|
658
|
+
- 节点不支持批量请求时自动改为逐条并发;返回 “Batch of more than N” 时按 N 缩小批量;请求体过大(413)时批量减半(这两种缩小 10 分钟后恢复原来的大小)。批量请求被限频或拒绝访问时不会降级(降级只会让限频更严重)
|
|
659
|
+
- HTTP 429 和 JSON-RPC 错误码 429 都会退避重试(`retries`,默认 2;传入多个自定义节点时为 0,直接换节点;内置节点保留重试),退避带随机抖动,有 `Retry-After` 头时按它等(超过 10 秒不等,直接报错换节点);批量里只重试被限频的那几条
|
|
654
660
|
- 单次请求超时 `timeout`,默认 10 秒
|
|
655
661
|
|
|
656
662
|
**故障切换**(多节点时):网络错误、超时、限频、403、需要 API Key、请求被拦截、高度不到 `minContextSlot` 等节点问题换下一个节点;参数错误等确定性错误直接抛出(`RpcError`,`isNodeFault(err)` 可判断)。
|
|
@@ -686,6 +692,8 @@ new SolanaClient(provider?, {
|
|
|
686
692
|
batchWait: 0,
|
|
687
693
|
batch: true, // false:不合并成批量请求
|
|
688
694
|
retries: 2,
|
|
695
|
+
maxConcurrency: 4, // 同一节点地址同时在途的 HTTP 请求数
|
|
696
|
+
dedupe: true, // 同一批里相同的只读调用只发一次
|
|
689
697
|
cooldown: 30_000,
|
|
690
698
|
headers: { 'x-api-key': '…' },
|
|
691
699
|
fetch: customFetch, // 需要代理等场景
|
|
@@ -751,7 +759,7 @@ await batchCall(client, [{ from: signer, instructions }])
|
|
|
751
759
|
**打包与发送**:
|
|
752
760
|
- 同一手续费支付者的相邻调用打包进同一笔交易(`mode: 'pack'`,默认;`'tx'` 每个调用一笔)。Solana 一笔交易本来就能放多条指令,不需要 EVM 上 Disperse 那样的合约
|
|
753
761
|
- 每笔先模拟:失败的调用(余额不足、账户冻结、SOL 转给新地址但低于免租下限等)单独标记 `failed`,其余重新模拟后照常发送;模拟失败且同一支付者还有未确认的交易时,先等它们确认再模拟一次(后一笔依赖前一笔的结果时自动正确处理)。节点暂时的问题(限频、高度落后)会重试,不当成调用失败
|
|
754
|
-
- 计算单元上限按模拟结果设置(× 1.1 + 1000),优先费用默认 `'auto'
|
|
762
|
+
- 计算单元上限按模拟结果设置(× 1.1 + 1000),优先费用默认 `'auto'`:按这笔交易可写账户的最近费用去掉 0 后取 75 分位(不活跃的账户大多数 slot 是 0,带上 0 几乎总是 0),不超过 `maxPriorityFee`(默认 1,000,000 micro-lamports / CU)。有优先费用时,第一次模拟顺带取付款方模拟后的余额(和当前余额一起读,同一个批量请求),付完优先费用后仍不低于免租下限就不再模拟第二次,否则照旧按真实费用再模拟一次。调用里自带的 SetComputeUnitLimit / SetComputeUnitPrice 指令会被去掉(和库加的重复会让交易失败),优先费用用 `priorityFee` 指定
|
|
755
763
|
- 交易发出后不等确认就发下一笔;等待期间每两次轮询重发一次原交易,一次 `getSignatureStatuses` 查所有交易。blockhash 过期仍没上链时换新 blockhash 重新模拟、重发,最多 `retries` 次(默认 2)。判断过期时,再查一次历史的那个节点的数据必须不早于看到过期的那个 slot(多节点 / 负载均衡时落后的节点可能还没看到已上链的交易),否则这一轮先不判断,避免重复执行
|
|
756
764
|
- Token-2022:有转账手续费的代币,`amount` 是转出的数量,收款方实际收到的更少;带 transfer hook 的代币,TransferChecked 需要额外的账户,本库不支持(模拟会失败,这一项 `failed`)
|
|
757
765
|
- 同一笔交易上链后才失败时一起回滚,里面的调用都是 `reverted`
|
|
@@ -768,7 +776,7 @@ await batchCall(client, [{ from: signer, instructions }])
|
|
|
768
776
|
|
|
769
777
|
**归集流程**(`batchCollect`):一次读出所有钱包的余额 → 归集地址没有该代币的 ATA 时创建(传了 `feePayer` 时随第一批转账创建;不传时先由第一个有这种代币的钱包单独创建,其他钱包只需付得起手续费)→ 打包发送代币转账(`closeAccounts` 时随后关闭代币账户)→ 包含 SOL 时等代币归集确认,按最新余额扫空 SOL:传了 `feePayer` 时整个余额转走,否则扣掉这笔的手续费后转走(余额归零)。代币没有全部归集成功的钱包不扫 SOL;余额为 0、低于 `minAmount`、钱包就是归集地址或 `feePayer` 的项为 `skipped`。Solana 上不需要先给子钱包补 gas,传 `feePayer` 即可;不传时没有 SOL 的钱包对应的项失败。`dryRun` 时代币转账照常模拟,扫 SOL 的金额要等归集之后才知道,只标记 `simulated`、不做模拟。
|
|
770
778
|
|
|
771
|
-
**共同选项**(`SendOptions`):`feePayer`、`priorityFee` / `maxPriorityFee`、`wait`(默认 true)、`timeout`(默认 120 秒)、`pollInterval`(默认 2 秒)、`retries`(默认 2)、`commitment`(`'confirmed'` / `'finalized'`)、`concurrency`(不同手续费支付者并发数,默认 8)、`dryRun`、`signal`、`onUpdate
|
|
779
|
+
**共同选项**(`SendOptions`):`feePayer`、`priorityFee` / `maxPriorityFee`、`wait`(默认 true)、`timeout`(默认 120 秒)、`pollInterval`(默认 2 秒)、`retries`(默认 2)、`commitment`(`'confirmed'` / `'finalized'`)、`concurrency`(不同手续费支付者并发数,默认 8)、`dryRun`、`signal`、`onUpdate`、`sendRpc`(发送交易用的节点,如专门的发送服务;模拟和查状态仍用 client)、`broadcast`(`'first'` 默认只发给第一个可用节点;`'all'` 同时发给所有节点,第一个接受就返回,更容易上链但请求数成倍增加)、`computeUnitMargin`(计算单元上限 = 模拟消耗 × `ratio` + `extra`,默认 1.1 和 1000;消耗会随状态波动的调用可以调大)。`sendRpc` 按 client 的网络和节点选项(headers、fetch、timeout 等)解析,和 client 不在同一个网络时报 `NetworkMismatchError`。等待确认时只在交易可能快过期时才查区块高度(按状态查询返回的 slot 估算),不再每轮都查。
|
|
772
780
|
|
|
773
781
|
**指令工具**:`systemTransfer`、`transferChecked`、`createAssociatedTokenAccountIdempotent`、`closeAccount`、`revoke`、`harvestWithheldTokensToMint`、`setComputeUnitLimit`、`setComputeUnitPrice`,生成本库格式的指令,可直接放进 `batchCall`。
|
|
774
782
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { RequestOptions, SlotOptions } from './client.js';
|
|
2
|
+
import type { AccountInfo } from './layout.js';
|
|
3
|
+
import { type RpcTransport } from './rpc.js';
|
|
4
|
+
import type { Commitment } from './types.js';
|
|
5
|
+
/** 一次查询的上下文:取消、最低 slot,以及读到的 slot(各请求 context.slot 的最小值) */
|
|
6
|
+
export interface QueryContext {
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
minContextSlot?: number;
|
|
9
|
+
slot?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare const MAX_ACCOUNTS_PER_REQUEST = 100;
|
|
12
|
+
/** fetchAccounts 里没能读到(节点问题)的账户 */
|
|
13
|
+
export declare const FAILED: unique symbol;
|
|
14
|
+
/** 可以降级处理的错误:网络 / HTTP 错误、节点限制(限频、需要 Key 等)、节点不在期望的网络上、所有节点都失败;其他(参数错误、程序 bug)照常抛出 */
|
|
15
|
+
export declare function isRecoverable(err: unknown): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* 账户读取管线:getMultipleAccounts 按 100 个一组、去重、并发池(最多同时 3 个),节点高度不够时等待重试,
|
|
18
|
+
* 记录读到的 slot;tolerant 时节点问题只标记失败。SolanaClient 和余额 / 代币详情模块共用
|
|
19
|
+
*/
|
|
20
|
+
export declare class AccountReader {
|
|
21
|
+
readonly transport: RpcTransport;
|
|
22
|
+
readonly commitment: Commitment;
|
|
23
|
+
constructor(transport: RpcTransport, commitment: Commitment);
|
|
24
|
+
/** 发给传输层:有 signal 时作为第三个参数传下去(没有时只传两个参数,自定义传输不受影响) */
|
|
25
|
+
send<T>(method: string, params: readonly unknown[] | undefined, signal: AbortSignal | undefined): Promise<T>;
|
|
26
|
+
/**
|
|
27
|
+
* 发一个读账户类的请求:params 最后一项是配置对象,传了 minContextSlot 时带上;
|
|
28
|
+
* 节点高度不够(所有节点都落后)时每 500ms 重试,最多约 10 秒;记录返回的 context.slot(取最小值)
|
|
29
|
+
*/
|
|
30
|
+
call<T>(ctx: QueryContext, method: string, params: unknown[]): Promise<T>;
|
|
31
|
+
accounts(addresses: readonly string[], ctx: QueryContext): Promise<(AccountInfo | null)[]>;
|
|
32
|
+
/**
|
|
33
|
+
* 只读 lamports(主币余额):getMultipleAccounts 带 dataSlice { offset: 0, length: 0 },不读回账户数据——
|
|
34
|
+
* 钱包可能是数据很大的程序账户(上百 KB),整份读回会拖慢甚至超时。结果与 addresses 一一对应,账户不存在或地址非法时为 null
|
|
35
|
+
*/
|
|
36
|
+
lamports(addresses: readonly string[], ctx: QueryContext): Promise<(bigint | null)[]>;
|
|
37
|
+
/** getMultipleAccounts(读账户数据):见 fetchGroups */
|
|
38
|
+
fetchAccounts(addresses: readonly string[], tolerant: boolean, ctx: QueryContext, failure?: {
|
|
39
|
+
error?: unknown;
|
|
40
|
+
}): Promise<Map<string, AccountInfo | null | typeof FAILED>>;
|
|
41
|
+
/**
|
|
42
|
+
* getMultipleAccounts:每组去重、按 100 个一组拆分,所有组的请求放进并发池,最多同时 3 个(一个结束就发下一个,不必等同一波里最慢的)。
|
|
43
|
+
* lamportsOnly 的组带 dataSlice(长度 0,对同一请求里的所有账户生效,所以只要 lamports 的账户要单独成组)。
|
|
44
|
+
* tolerant 为 true 时,某个请求因节点问题(网络、限频等)失败不抛错:该请求的账户标记为 FAILED,并且不再发后面的请求(节点已经在限频了),
|
|
45
|
+
* 第一个这样的错误记在 failure.error;否则第一个错误抛出,后面的请求也不再发。结果按组返回
|
|
46
|
+
*/
|
|
47
|
+
fetchGroups(groups: ReadonlyArray<{
|
|
48
|
+
addresses: readonly string[];
|
|
49
|
+
lamportsOnly: boolean;
|
|
50
|
+
}>, tolerant: boolean, ctx: QueryContext, failure?: {
|
|
51
|
+
error?: unknown;
|
|
52
|
+
}): Promise<Array<Map<string, AccountInfo | null | typeof FAILED>>>;
|
|
53
|
+
}
|
|
54
|
+
/** 结果项带上 slot(传了 withSlot / minContextSlot,且这次查询发了请求时) */
|
|
55
|
+
export declare function attachSlot<T extends object>(items: T[], ctx: QueryContext, options: SlotOptions): T[];
|
|
56
|
+
export declare function queryContext(options: RequestOptions & SlotOptions): QueryContext;
|
|
57
|
+
//# sourceMappingURL=accountReader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accountReader.d.ts","sourceRoot":"","sources":["../src/accountReader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAsD,KAAK,YAAY,EAAE,MAAM,UAAU,CAAA;AAEhG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAG5C,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAMD,eAAO,MAAM,wBAAwB,MAAM,CAAA;AAG3C,mCAAmC;AACnC,eAAO,MAAM,MAAM,eAAmB,CAAA;AAEtC,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAEnD;AAuBD;;;GAGG;AACH,qBAAa,aAAa;IAEtB,QAAQ,CAAC,SAAS,EAAE,YAAY;IAChC,QAAQ,CAAC,UAAU,EAAE,UAAU;gBADtB,SAAS,EAAE,YAAY,EACvB,UAAU,EAAE,UAAU;IAGjC,sDAAsD;IACtD,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC;IAI5G;;;OAGG;IACG,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IAsBzE,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC;IAKhG;;;OAGG;IACG,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAK3F,+CAA+C;IACzC,aAAa,CACjB,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,QAAQ,EAAE,OAAO,EACjB,GAAG,EAAE,YAAY,EACjB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,MAAM,CAAC,CAAC;IAK3D;;;;;OAKG;IACG,WAAW,CACf,MAAM,EAAE,aAAa,CAAC;QAAE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC,EAC9E,QAAQ,EAAE,OAAO,EACjB,GAAG,EAAE,YAAY,EACjB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAC5B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,MAAM,CAAC,CAAC,CAAC;CAyCnE;AAED,0DAA0D;AAC1D,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,GAAG,CAAC,EAAE,CAMrG;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,GAAG,YAAY,CAEhF"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// 账户读取管线(getMultipleAccounts 分组 / 并发 / 重试)和查询上下文
|
|
2
|
+
import { base64 } from '@scure/base';
|
|
3
|
+
import { isAddress } from './address.js';
|
|
4
|
+
import { AllNodesFailedError, HttpError, RpcError, isBehind } from './rpc.js';
|
|
5
|
+
import { NetworkMismatchError } from './source.js';
|
|
6
|
+
import { mapPool, sleep } from './util.js';
|
|
7
|
+
/** 节点高度不够时的重试间隔与总时长 */
|
|
8
|
+
const BEHIND_RETRY_INTERVAL = 500;
|
|
9
|
+
const BEHIND_RETRY_TIMEOUT = 10_000;
|
|
10
|
+
export const MAX_ACCOUNTS_PER_REQUEST = 100;
|
|
11
|
+
/** 同时进行的 getMultipleAccounts 请求数上限 */
|
|
12
|
+
const MAX_PARALLEL_ACCOUNT_REQUESTS = 3;
|
|
13
|
+
/** fetchAccounts 里没能读到(节点问题)的账户 */
|
|
14
|
+
export const FAILED = Symbol('failed');
|
|
15
|
+
/** 可以降级处理的错误:网络 / HTTP 错误、节点限制(限频、需要 Key 等)、节点不在期望的网络上、所有节点都失败;其他(参数错误、程序 bug)照常抛出 */
|
|
16
|
+
export function isRecoverable(err) {
|
|
17
|
+
return err instanceof HttpError || (err instanceof RpcError && err.nodeFault) || err instanceof NetworkMismatchError || err instanceof AllNodesFailedError;
|
|
18
|
+
}
|
|
19
|
+
function toAccountInfo(address, raw) {
|
|
20
|
+
if (!raw) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const encoded = Array.isArray(raw.data) ? raw.data[0] : raw.data;
|
|
24
|
+
return {
|
|
25
|
+
address,
|
|
26
|
+
lamports: BigInt(raw.lamports),
|
|
27
|
+
owner: raw.owner,
|
|
28
|
+
data: base64.decode(encoded),
|
|
29
|
+
executable: raw.executable,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 账户读取管线:getMultipleAccounts 按 100 个一组、去重、并发池(最多同时 3 个),节点高度不够时等待重试,
|
|
34
|
+
* 记录读到的 slot;tolerant 时节点问题只标记失败。SolanaClient 和余额 / 代币详情模块共用
|
|
35
|
+
*/
|
|
36
|
+
export class AccountReader {
|
|
37
|
+
transport;
|
|
38
|
+
commitment;
|
|
39
|
+
constructor(transport, commitment) {
|
|
40
|
+
this.transport = transport;
|
|
41
|
+
this.commitment = commitment;
|
|
42
|
+
}
|
|
43
|
+
/** 发给传输层:有 signal 时作为第三个参数传下去(没有时只传两个参数,自定义传输不受影响) */
|
|
44
|
+
send(method, params, signal) {
|
|
45
|
+
return signal ? this.transport.request(method, params, { signal }) : this.transport.request(method, params);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 发一个读账户类的请求:params 最后一项是配置对象,传了 minContextSlot 时带上;
|
|
49
|
+
* 节点高度不够(所有节点都落后)时每 500ms 重试,最多约 10 秒;记录返回的 context.slot(取最小值)
|
|
50
|
+
*/
|
|
51
|
+
async call(ctx, method, params) {
|
|
52
|
+
const last = params[params.length - 1];
|
|
53
|
+
const sent = ctx.minContextSlot === undefined ? params : [...params.slice(0, -1), { ...last, minContextSlot: ctx.minContextSlot }];
|
|
54
|
+
const started = Date.now();
|
|
55
|
+
for (;;) {
|
|
56
|
+
try {
|
|
57
|
+
const res = await this.send(method, sent, ctx.signal);
|
|
58
|
+
const slot = res?.context?.slot;
|
|
59
|
+
if (typeof slot === 'number') {
|
|
60
|
+
ctx.slot = ctx.slot === undefined ? slot : Math.min(ctx.slot, slot);
|
|
61
|
+
}
|
|
62
|
+
return res;
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
if (ctx.minContextSlot === undefined || !isBehind(err) || Date.now() - started + BEHIND_RETRY_INTERVAL > BEHIND_RETRY_TIMEOUT) {
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
await sleep(BEHIND_RETRY_INTERVAL, ctx.signal);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async accounts(addresses, ctx) {
|
|
73
|
+
const fetched = await this.fetchAccounts(addresses, false, ctx);
|
|
74
|
+
return addresses.map((address) => fetched.get(address) ?? null);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 只读 lamports(主币余额):getMultipleAccounts 带 dataSlice { offset: 0, length: 0 },不读回账户数据——
|
|
78
|
+
* 钱包可能是数据很大的程序账户(上百 KB),整份读回会拖慢甚至超时。结果与 addresses 一一对应,账户不存在或地址非法时为 null
|
|
79
|
+
*/
|
|
80
|
+
async lamports(addresses, ctx) {
|
|
81
|
+
const [fetched] = await this.fetchGroups([{ addresses, lamportsOnly: true }], false, ctx);
|
|
82
|
+
return addresses.map((address) => fetched?.get(address)?.lamports ?? null);
|
|
83
|
+
}
|
|
84
|
+
/** getMultipleAccounts(读账户数据):见 fetchGroups */
|
|
85
|
+
async fetchAccounts(addresses, tolerant, ctx, failure) {
|
|
86
|
+
const [fetched] = await this.fetchGroups([{ addresses, lamportsOnly: false }], tolerant, ctx, failure);
|
|
87
|
+
return fetched;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* getMultipleAccounts:每组去重、按 100 个一组拆分,所有组的请求放进并发池,最多同时 3 个(一个结束就发下一个,不必等同一波里最慢的)。
|
|
91
|
+
* lamportsOnly 的组带 dataSlice(长度 0,对同一请求里的所有账户生效,所以只要 lamports 的账户要单独成组)。
|
|
92
|
+
* tolerant 为 true 时,某个请求因节点问题(网络、限频等)失败不抛错:该请求的账户标记为 FAILED,并且不再发后面的请求(节点已经在限频了),
|
|
93
|
+
* 第一个这样的错误记在 failure.error;否则第一个错误抛出,后面的请求也不再发。结果按组返回
|
|
94
|
+
*/
|
|
95
|
+
async fetchGroups(groups, tolerant, ctx, failure) {
|
|
96
|
+
const chunks = [];
|
|
97
|
+
groups.forEach(({ addresses, lamportsOnly }, group) => {
|
|
98
|
+
const unique = [...new Set(addresses.filter((a) => isAddress(a)))];
|
|
99
|
+
for (let i = 0; i < unique.length; i += MAX_ACCOUNTS_PER_REQUEST) {
|
|
100
|
+
chunks.push({ group, addresses: unique.slice(i, i + MAX_ACCOUNTS_PER_REQUEST), lamportsOnly });
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
const results = groups.map(() => new Map());
|
|
104
|
+
// 出错后不再发后面的请求
|
|
105
|
+
let stopped = false;
|
|
106
|
+
// 并发池最先发出的几个请求在同一 tick(合并成一个 JSON-RPC 批量请求)
|
|
107
|
+
await mapPool(chunks, MAX_PARALLEL_ACCOUNT_REQUESTS, async (chunk) => {
|
|
108
|
+
const result = results[chunk.group];
|
|
109
|
+
if (stopped) {
|
|
110
|
+
chunk.addresses.forEach((address) => result.set(address, FAILED));
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
// 已取消的查询不再发后面的请求
|
|
114
|
+
if (ctx.signal?.aborted) {
|
|
115
|
+
throw ctx.signal.reason;
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
const res = await this.call(ctx, 'getMultipleAccounts', [
|
|
119
|
+
chunk.addresses,
|
|
120
|
+
{ encoding: 'base64', commitment: this.commitment, ...(chunk.lamportsOnly ? { dataSlice: { offset: 0, length: 0 } } : {}) },
|
|
121
|
+
]);
|
|
122
|
+
chunk.addresses.forEach((address, j) => result.set(address, toAccountInfo(address, res?.value?.[j] ?? null)));
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
stopped = true;
|
|
126
|
+
if (!tolerant || !isRecoverable(err)) {
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
129
|
+
if (failure && !('error' in failure)) {
|
|
130
|
+
failure.error = err;
|
|
131
|
+
}
|
|
132
|
+
chunk.addresses.forEach((address) => result.set(address, FAILED));
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
return results;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/** 结果项带上 slot(传了 withSlot / minContextSlot,且这次查询发了请求时) */
|
|
139
|
+
export function attachSlot(items, ctx, options) {
|
|
140
|
+
if ((!options.withSlot && options.minContextSlot === undefined) || ctx.slot === undefined) {
|
|
141
|
+
return items;
|
|
142
|
+
}
|
|
143
|
+
const slot = ctx.slot;
|
|
144
|
+
return items.map((item) => ({ ...item, slot }));
|
|
145
|
+
}
|
|
146
|
+
export function queryContext(options) {
|
|
147
|
+
return { signal: options.signal, minContextSlot: options.minContextSlot };
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=accountReader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accountReader.js","sourceRoot":"","sources":["../src/accountReader.ts"],"names":[],"mappings":"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"}
|
package/dist/address.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export declare function encodeAddress(bytes: Uint8Array): string;
|
|
|
8
8
|
* y ≥ p、x = 0 但符号位为 1 都算不在曲线上。只需判断 x² = (y² - 1) / (d·y² + 1) 有没有解,不必真的开方
|
|
9
9
|
*/
|
|
10
10
|
export declare function isOnCurve(bytes: Uint8Array): boolean;
|
|
11
|
+
/** 测试用:这组种子的 PDA 是否在缓存里 */
|
|
12
|
+
export declare function isPdaCached(seeds: readonly Uint8Array[], programId: string): boolean;
|
|
11
13
|
/**
|
|
12
14
|
* 推导 PDA(与 web3.js PublicKey.findProgramAddressSync 相同),返回地址。
|
|
13
15
|
* seeds 每项不超过 32 字节、最多 15 个(加上 bump 共 16 个,链上上限),超出时抛错。
|
|
@@ -19,4 +21,11 @@ export declare function createProgramAddress(seeds: Uint8Array[], programId: str
|
|
|
19
21
|
export declare function getAssociatedTokenAddress(owner: string, mint: string, tokenProgram: string): string;
|
|
20
22
|
/** Metaplex Token Metadata 账户地址 */
|
|
21
23
|
export declare function getMetadataAddress(mint: string): string;
|
|
24
|
+
/** 地址不合法时抛出(继承 Error,message 与之前的普通 Error 相同;用 code / address 判断) */
|
|
25
|
+
export declare class InvalidAddressError extends Error {
|
|
26
|
+
readonly code = "INVALID_ADDRESS";
|
|
27
|
+
/** 不合法的那个值 */
|
|
28
|
+
readonly address: string;
|
|
29
|
+
constructor(message: string, address: string);
|
|
30
|
+
}
|
|
22
31
|
//# sourceMappingURL=address.d.ts.map
|
package/dist/address.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"AAKA,qCAAqC;AACrC,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CASzD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAMzD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEvD;AA4BD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAoBpD;
|
|
1
|
+
{"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"AAKA,qCAAqC;AACrC,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CASzD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAMzD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEvD;AA4BD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAoBpD;AAmCD,2BAA2B;AAC3B,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEpF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CA4BjF;AAED,iHAAiH;AACjH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAMnF;AAED,oBAAoB;AACpB,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEnG;AAED,mCAAmC;AACnC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED,qEAAqE;AACrE,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,qBAAoB;IACjC,cAAc;IACd,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK7C"}
|
package/dist/address.js
CHANGED
|
@@ -16,7 +16,7 @@ export function isAddress(value) {
|
|
|
16
16
|
export function decodeAddress(address) {
|
|
17
17
|
const bytes = base58.decode(address);
|
|
18
18
|
if (bytes.length !== 32) {
|
|
19
|
-
throw new
|
|
19
|
+
throw new InvalidAddressError(`Invalid Solana address: ${address}`, address);
|
|
20
20
|
}
|
|
21
21
|
return bytes;
|
|
22
22
|
}
|
|
@@ -85,8 +85,25 @@ function concat(parts) {
|
|
|
85
85
|
}
|
|
86
86
|
const MAX_SEED_LENGTH = 32;
|
|
87
87
|
const MAX_SEEDS = 16;
|
|
88
|
-
// PDA 推导是纯计算但要做多次 sha256 +
|
|
88
|
+
// PDA 推导是纯计算但要做多次 sha256 + 曲线判断,结果缓存(LRU:命中时移到最后,满了删最久没用的)
|
|
89
89
|
const pdaCache = new Map();
|
|
90
|
+
const MAX_PDA_CACHE = 10_000;
|
|
91
|
+
const HEX = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
|
92
|
+
/** 缓存键:程序地址 + 各种子的十六进制(比 base58 编码快得多;用 ',' 分隔,不同的种子划分不会撞键) */
|
|
93
|
+
function pdaKey(seeds, programId) {
|
|
94
|
+
let key = programId;
|
|
95
|
+
for (const seed of seeds) {
|
|
96
|
+
key += ',';
|
|
97
|
+
for (let i = 0; i < seed.length; i++) {
|
|
98
|
+
key += HEX[seed[i]];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return key;
|
|
102
|
+
}
|
|
103
|
+
/** 测试用:这组种子的 PDA 是否在缓存里 */
|
|
104
|
+
export function isPdaCached(seeds, programId) {
|
|
105
|
+
return pdaCache.has(pdaKey(seeds, programId));
|
|
106
|
+
}
|
|
90
107
|
/**
|
|
91
108
|
* 推导 PDA(与 web3.js PublicKey.findProgramAddressSync 相同),返回地址。
|
|
92
109
|
* seeds 每项不超过 32 字节、最多 15 个(加上 bump 共 16 个,链上上限),超出时抛错。
|
|
@@ -99,9 +116,11 @@ export function findProgramAddress(seeds, programId) {
|
|
|
99
116
|
if (seeds.length + 1 > MAX_SEEDS) {
|
|
100
117
|
throw new TypeError('Max seeds exceeded');
|
|
101
118
|
}
|
|
102
|
-
const key =
|
|
119
|
+
const key = pdaKey(seeds, programId);
|
|
103
120
|
const cached = pdaCache.get(key);
|
|
104
121
|
if (cached) {
|
|
122
|
+
pdaCache.delete(key);
|
|
123
|
+
pdaCache.set(key, cached);
|
|
105
124
|
return cached;
|
|
106
125
|
}
|
|
107
126
|
const program = decodeAddress(programId);
|
|
@@ -109,10 +128,10 @@ export function findProgramAddress(seeds, programId) {
|
|
|
109
128
|
const hash = sha256(concat([...seeds, new Uint8Array([bump]), program, PDA_MARKER]));
|
|
110
129
|
if (!isOnCurve(hash)) {
|
|
111
130
|
const address = encodeAddress(hash);
|
|
112
|
-
if (pdaCache.size > 10_000) {
|
|
113
|
-
pdaCache.clear();
|
|
114
|
-
}
|
|
115
131
|
pdaCache.set(key, address);
|
|
132
|
+
if (pdaCache.size > MAX_PDA_CACHE) {
|
|
133
|
+
pdaCache.delete(pdaCache.keys().next().value);
|
|
134
|
+
}
|
|
116
135
|
return address;
|
|
117
136
|
}
|
|
118
137
|
}
|
|
@@ -134,4 +153,15 @@ export function getAssociatedTokenAddress(owner, mint, tokenProgram) {
|
|
|
134
153
|
export function getMetadataAddress(mint) {
|
|
135
154
|
return findProgramAddress([new TextEncoder().encode('metadata'), decodeAddress(METADATA_PROGRAM_ID), decodeAddress(mint)], METADATA_PROGRAM_ID);
|
|
136
155
|
}
|
|
156
|
+
/** 地址不合法时抛出(继承 Error,message 与之前的普通 Error 相同;用 code / address 判断) */
|
|
157
|
+
export class InvalidAddressError extends Error {
|
|
158
|
+
code = 'INVALID_ADDRESS';
|
|
159
|
+
/** 不合法的那个值 */
|
|
160
|
+
address;
|
|
161
|
+
constructor(message, address) {
|
|
162
|
+
super(message);
|
|
163
|
+
this.name = 'InvalidAddressError';
|
|
164
|
+
this.address = address;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
137
167
|
//# sourceMappingURL=address.js.map
|
package/dist/address.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address.js","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,OAAO,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEjF,qCAAqC;AACrC,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACxE,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,EAAE,CAAA;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACpC,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"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"}
|
package/dist/approvals.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { BatchCallOptions } from './write/batch.js';
|
|
|
3
3
|
import type { WriteResult } from './write/send.js';
|
|
4
4
|
import type { SignerInput } from './write/signer.js';
|
|
5
5
|
import type { Instruction } from './write/transaction.js';
|
|
6
|
-
export interface
|
|
6
|
+
export interface ApprovalsOptions extends RequestOptions {
|
|
7
7
|
/**
|
|
8
8
|
* 要检查的代币 mint:读这些代币的关联代币账户(ATA,SPL Token 和 Token-2022 都看),免费公共节点也能用;非 ATA 的代币账户查不到。
|
|
9
9
|
* 不传时列出地址的全部代币账户(getTokenAccountsByOwner),需要支持它的节点
|
|
@@ -12,6 +12,8 @@ export interface ApprovalsQuery extends RequestOptions {
|
|
|
12
12
|
/** 返回全部代币账户(含没有授权、有余额的),默认 false:只返回有授权(delegate / 别人的关闭权限)的账户和余额为 0 的账户 */
|
|
13
13
|
all?: boolean;
|
|
14
14
|
}
|
|
15
|
+
/** @deprecated 改名为 ApprovalsOptions(与其他查询的 options 命名统一),旧名保留 */
|
|
16
|
+
export type ApprovalsQuery = ApprovalsOptions;
|
|
15
17
|
/** 关不掉的原因:balance 有余额(Wrapped SOL 除外);close-authority 关闭权限是别的地址;confidential-balance Token-2022 机密余额不为 0 */
|
|
16
18
|
export type CloseBlocker = 'balance' | 'close-authority' | 'confidential-balance';
|
|
17
19
|
/** 一个代币账户的授权状态,字段都是字符串 / 数字 / 布尔 / null,可以直接 JSON.stringify */
|
|
@@ -64,7 +66,7 @@ interface ParsedAccount {
|
|
|
64
66
|
withheldAmount: bigint;
|
|
65
67
|
confidentialBalance: boolean;
|
|
66
68
|
}
|
|
67
|
-
/**
|
|
69
|
+
/** 解析代币账户(基础布局用 layout 的 parseTokenAccountState)及关闭相关的 Token-2022 扩展;不是已初始化的代币账户时为 null */
|
|
68
70
|
export declare function parseTokenAccountState(data: Uint8Array): ParsedAccount | null;
|
|
69
71
|
/**
|
|
70
72
|
* 查一个地址的代币账户给出的授权,和可以关闭回收租金的空账户(结果按账户,同一账户的授权和关闭状态在一起)。
|
|
@@ -76,7 +78,7 @@ export declare function parseTokenAccountState(data: Uint8Array): ParsedAccount
|
|
|
76
78
|
* await approvals(new SolanaClient('https://my-rpc…'), owner) // 全部代币账户
|
|
77
79
|
* ```
|
|
78
80
|
*/
|
|
79
|
-
export declare function approvals(client: SolanaClient, owner: string,
|
|
81
|
+
export declare function approvals(client: SolanaClient, owner: string, options?: ApprovalsOptions): Promise<TokenAccountApproval[]>;
|
|
80
82
|
/** 一个账户要执行的指令(作为 batchCall 的一个调用,原子执行) */
|
|
81
83
|
export interface ApprovalCall {
|
|
82
84
|
/** revoke:撤销 delegate;close:关闭账户(有暂存的转账手续费时先收到 mint 上) */
|
package/dist/approvals.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"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"}
|