@w3lib/solana-batch-call 0.4.0 → 0.6.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.
Files changed (223) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +343 -3
  3. package/dist/approvals.d.ts +129 -0
  4. package/dist/approvals.d.ts.map +1 -0
  5. package/dist/approvals.js +221 -0
  6. package/dist/approvals.js.map +1 -0
  7. package/dist/batchPlan.d.ts +52 -0
  8. package/dist/batchPlan.d.ts.map +1 -0
  9. package/dist/batchPlan.js +85 -0
  10. package/dist/batchPlan.js.map +1 -0
  11. package/dist/claim.d.ts +161 -0
  12. package/dist/claim.d.ts.map +1 -0
  13. package/dist/claim.js +197 -0
  14. package/dist/claim.js.map +1 -0
  15. package/dist/decode.d.ts +22 -0
  16. package/dist/decode.d.ts.map +1 -0
  17. package/dist/decode.js +187 -0
  18. package/dist/decode.js.map +1 -0
  19. package/dist/describe.d.ts +26 -0
  20. package/dist/describe.d.ts.map +1 -0
  21. package/dist/describe.js +58 -0
  22. package/dist/describe.js.map +1 -0
  23. package/dist/fees.d.ts +89 -0
  24. package/dist/fees.d.ts.map +1 -0
  25. package/dist/fees.js +166 -0
  26. package/dist/fees.js.map +1 -0
  27. package/dist/history.d.ts +125 -0
  28. package/dist/history.d.ts.map +1 -0
  29. package/dist/history.js +231 -0
  30. package/dist/history.js.map +1 -0
  31. package/dist/historyHelius.d.ts +52 -0
  32. package/dist/historyHelius.d.ts.map +1 -0
  33. package/dist/historyHelius.js +125 -0
  34. package/dist/historyHelius.js.map +1 -0
  35. package/dist/layout.d.ts +2 -0
  36. package/dist/layout.d.ts.map +1 -1
  37. package/dist/layout.js +2 -2
  38. package/dist/layout.js.map +1 -1
  39. package/dist/liquidity/orca.d.ts +6 -0
  40. package/dist/liquidity/orca.d.ts.map +1 -1
  41. package/dist/liquidity/orca.js +14 -3
  42. package/dist/liquidity/orca.js.map +1 -1
  43. package/dist/liquidity/raydiumClmm.d.ts +6 -0
  44. package/dist/liquidity/raydiumClmm.d.ts.map +1 -1
  45. package/dist/liquidity/raydiumClmm.js +12 -5
  46. package/dist/liquidity/raydiumClmm.js.map +1 -1
  47. package/dist/lp.d.ts +55 -15
  48. package/dist/lp.d.ts.map +1 -1
  49. package/dist/lp.js +98 -46
  50. package/dist/lp.js.map +1 -1
  51. package/dist/lpMath.d.ts +22 -0
  52. package/dist/lpMath.d.ts.map +1 -1
  53. package/dist/lpMath.js +21 -0
  54. package/dist/lpMath.js.map +1 -1
  55. package/dist/names.d.ts +68 -0
  56. package/dist/names.d.ts.map +1 -0
  57. package/dist/names.js +257 -0
  58. package/dist/names.js.map +1 -0
  59. package/dist/pools.d.ts +9 -0
  60. package/dist/pools.d.ts.map +1 -0
  61. package/dist/pools.js +45 -0
  62. package/dist/pools.js.map +1 -0
  63. package/dist/portfolio.d.ts +64 -0
  64. package/dist/portfolio.d.ts.map +1 -0
  65. package/dist/portfolio.js +57 -0
  66. package/dist/portfolio.js.map +1 -0
  67. package/dist/price.d.ts +90 -0
  68. package/dist/price.d.ts.map +1 -0
  69. package/dist/price.js +287 -0
  70. package/dist/price.js.map +1 -0
  71. package/dist/programs.d.ts +19 -0
  72. package/dist/programs.d.ts.map +1 -0
  73. package/dist/programs.js +175 -0
  74. package/dist/programs.js.map +1 -0
  75. package/dist/reclaim.d.ts +190 -0
  76. package/dist/reclaim.d.ts.map +1 -0
  77. package/dist/reclaim.js +399 -0
  78. package/dist/reclaim.js.map +1 -0
  79. package/dist/risk.d.ts +84 -0
  80. package/dist/risk.d.ts.map +1 -0
  81. package/dist/risk.js +211 -0
  82. package/dist/risk.js.map +1 -0
  83. package/dist/rpc.d.ts +2 -0
  84. package/dist/rpc.d.ts.map +1 -1
  85. package/dist/rpc.js +36 -10
  86. package/dist/rpc.js.map +1 -1
  87. package/dist/simulate.d.ts +106 -0
  88. package/dist/simulate.d.ts.map +1 -0
  89. package/dist/simulate.js +418 -0
  90. package/dist/simulate.js.map +1 -0
  91. package/dist/subpaths/approvals.d.ts +29 -0
  92. package/dist/subpaths/approvals.d.ts.map +1 -0
  93. package/dist/subpaths/approvals.js +30 -0
  94. package/dist/subpaths/approvals.js.map +1 -0
  95. package/dist/subpaths/claim.d.ts +31 -0
  96. package/dist/subpaths/claim.d.ts.map +1 -0
  97. package/dist/subpaths/claim.js +31 -0
  98. package/dist/subpaths/claim.js.map +1 -0
  99. package/dist/subpaths/fees.d.ts +23 -0
  100. package/dist/subpaths/fees.d.ts.map +1 -0
  101. package/dist/subpaths/fees.js +25 -0
  102. package/dist/subpaths/fees.js.map +1 -0
  103. package/dist/subpaths/history.d.ts +21 -0
  104. package/dist/subpaths/history.d.ts.map +1 -0
  105. package/dist/subpaths/history.js +22 -0
  106. package/dist/subpaths/history.js.map +1 -0
  107. package/dist/subpaths/lp.d.ts +2 -2
  108. package/dist/subpaths/lp.d.ts.map +1 -1
  109. package/dist/subpaths/lp.js +2 -2
  110. package/dist/subpaths/lp.js.map +1 -1
  111. package/dist/subpaths/names.d.ts +37 -0
  112. package/dist/subpaths/names.d.ts.map +1 -0
  113. package/dist/subpaths/names.js +27 -0
  114. package/dist/subpaths/names.js.map +1 -0
  115. package/dist/subpaths/price.d.ts +40 -0
  116. package/dist/subpaths/price.d.ts.map +1 -0
  117. package/dist/subpaths/price.js +43 -0
  118. package/dist/subpaths/price.js.map +1 -0
  119. package/dist/subpaths/reclaim.d.ts +34 -0
  120. package/dist/subpaths/reclaim.d.ts.map +1 -0
  121. package/dist/subpaths/reclaim.js +34 -0
  122. package/dist/subpaths/reclaim.js.map +1 -0
  123. package/dist/subpaths/risk.d.ts +28 -0
  124. package/dist/subpaths/risk.d.ts.map +1 -0
  125. package/dist/subpaths/risk.js +30 -0
  126. package/dist/subpaths/risk.js.map +1 -0
  127. package/dist/subpaths/simulate.d.ts +22 -0
  128. package/dist/subpaths/simulate.d.ts.map +1 -0
  129. package/dist/subpaths/simulate.js +23 -0
  130. package/dist/subpaths/simulate.js.map +1 -0
  131. package/dist/subpaths/swap.d.ts +22 -0
  132. package/dist/subpaths/swap.d.ts.map +1 -0
  133. package/dist/subpaths/swap.js +21 -0
  134. package/dist/subpaths/swap.js.map +1 -0
  135. package/dist/subpaths/write.d.ts +1 -1
  136. package/dist/subpaths/write.d.ts.map +1 -1
  137. package/dist/subpaths/write.js +1 -1
  138. package/dist/subpaths/write.js.map +1 -1
  139. package/dist/swap/amm.d.ts +20 -0
  140. package/dist/swap/amm.d.ts.map +1 -0
  141. package/dist/swap/amm.js +77 -0
  142. package/dist/swap/amm.js.map +1 -0
  143. package/dist/swap/clmmMath.d.ts +24 -0
  144. package/dist/swap/clmmMath.d.ts.map +1 -0
  145. package/dist/swap/clmmMath.js +82 -0
  146. package/dist/swap/clmmMath.js.map +1 -0
  147. package/dist/swap/common.d.ts +68 -0
  148. package/dist/swap/common.d.ts.map +1 -0
  149. package/dist/swap/common.js +65 -0
  150. package/dist/swap/common.js.map +1 -0
  151. package/dist/swap/cpmm.d.ts +28 -0
  152. package/dist/swap/cpmm.d.ts.map +1 -0
  153. package/dist/swap/cpmm.js +113 -0
  154. package/dist/swap/cpmm.js.map +1 -0
  155. package/dist/swap/index.d.ts +145 -0
  156. package/dist/swap/index.d.ts.map +1 -0
  157. package/dist/swap/index.js +349 -0
  158. package/dist/swap/index.js.map +1 -0
  159. package/dist/swap/orca.d.ts +50 -0
  160. package/dist/swap/orca.d.ts.map +1 -0
  161. package/dist/swap/orca.js +382 -0
  162. package/dist/swap/orca.js.map +1 -0
  163. package/dist/swap/raydiumClmm.d.ts +62 -0
  164. package/dist/swap/raydiumClmm.d.ts.map +1 -0
  165. package/dist/swap/raydiumClmm.js +447 -0
  166. package/dist/swap/raydiumClmm.js.map +1 -0
  167. package/dist/tradeCheck.d.ts +45 -0
  168. package/dist/tradeCheck.d.ts.map +1 -0
  169. package/dist/tradeCheck.js +131 -0
  170. package/dist/tradeCheck.js.map +1 -0
  171. package/dist/write/instructions.d.ts +9 -0
  172. package/dist/write/instructions.d.ts.map +1 -1
  173. package/dist/write/instructions.js +40 -1
  174. package/dist/write/instructions.js.map +1 -1
  175. package/dist/write/transaction.d.ts +23 -0
  176. package/dist/write/transaction.d.ts.map +1 -1
  177. package/dist/write/transaction.js +50 -0
  178. package/dist/write/transaction.js.map +1 -1
  179. package/package.json +66 -14
  180. package/src/approvals.ts +358 -0
  181. package/src/batchPlan.ts +137 -0
  182. package/src/claim.ts +323 -0
  183. package/src/decode.ts +202 -0
  184. package/src/describe.ts +77 -0
  185. package/src/fees.ts +259 -0
  186. package/src/history.ts +336 -0
  187. package/src/historyHelius.ts +136 -0
  188. package/src/layout.ts +2 -2
  189. package/src/liquidity/orca.ts +15 -5
  190. package/src/liquidity/raydiumClmm.ts +13 -5
  191. package/src/lp.ts +148 -59
  192. package/src/lpMath.ts +38 -0
  193. package/src/names.ts +329 -0
  194. package/src/pools.ts +43 -0
  195. package/src/portfolio.ts +124 -0
  196. package/src/price.ts +366 -0
  197. package/src/programs.ts +216 -0
  198. package/src/reclaim.ts +547 -0
  199. package/src/risk.ts +243 -0
  200. package/src/rpc.ts +39 -10
  201. package/src/simulate.ts +535 -0
  202. package/src/subpaths/approvals.ts +47 -0
  203. package/src/subpaths/claim.ts +53 -0
  204. package/src/subpaths/fees.ts +41 -0
  205. package/src/subpaths/history.ts +38 -0
  206. package/src/subpaths/lp.ts +5 -1
  207. package/src/subpaths/names.ts +45 -0
  208. package/src/subpaths/price.ts +62 -0
  209. package/src/subpaths/reclaim.ts +57 -0
  210. package/src/subpaths/risk.ts +36 -0
  211. package/src/subpaths/simulate.ts +37 -0
  212. package/src/subpaths/swap.ts +41 -0
  213. package/src/subpaths/write.ts +2 -0
  214. package/src/swap/amm.ts +88 -0
  215. package/src/swap/clmmMath.ts +96 -0
  216. package/src/swap/common.ts +113 -0
  217. package/src/swap/cpmm.ts +132 -0
  218. package/src/swap/index.ts +467 -0
  219. package/src/swap/orca.ts +397 -0
  220. package/src/swap/raydiumClmm.ts +464 -0
  221. package/src/tradeCheck.ts +166 -0
  222. package/src/write/instructions.ts +43 -1
  223. package/src/write/transaction.ts +62 -0
@@ -0,0 +1,57 @@
1
+ import { lpPositions, methodUnavailable } from './lp.js';
2
+ import { combinePrices, defillamaPrices, onchainPrices, tokenPrices } from './price.js';
3
+ /**
4
+ * 一个地址的资产总值:代币余额 × 价格,可选加上 LP 仓位。
5
+ *
6
+ * ```ts
7
+ * const p = await portfolio(client, owner, { tokens: [NATIVE_MINT, USDC, JUP] }) // 指定代币:免费公共节点也能用
8
+ * const all = await portfolio(new SolanaClient('https://my-rpc…'), owner, { lp: true }) // 全部持仓 + LP:需要支持 getTokenAccountsByOwner 的节点
9
+ * p.totalUsd // 1234.5
10
+ * ```
11
+ */
12
+ export async function portfolio(client, owner, options = {}) {
13
+ const { tokens, sources = [defillamaPrices(), onchainPrices()], lp, minUsd = 0, onPriceError, fetch: fetchFn, signal } = options;
14
+ // 回调本身出错由 combinePrices / lpPositions 忽略
15
+ const onError = onPriceError ? (_, err) => onPriceError(err) : undefined;
16
+ const [balances, positions] = await Promise.all([
17
+ holdings(client, owner, tokens, signal),
18
+ lp
19
+ ? lpPositions(client, owner, { ...(lp === true ? {} : lp), prices: combinePrices(sources, { onError }), fetch: fetchFn, onPriceError, signal })
20
+ : Promise.resolve([]),
21
+ ]);
22
+ // 列出全部持仓时,LP 代币已经按仓位计入,不再作为代币重复计算
23
+ const lpMints = new Set(positions.flatMap((p) => (p.type === 'amm' ? [p.lpMint] : [])));
24
+ const held = balances.filter((b) => BigInt(b.balance) > 0n && !(tokens === undefined && lpMints.has(b.token)));
25
+ const prices = held.length ? await tokenPrices(client, held.map((b) => b.token), { sources, onError, fetch: fetchFn, signal }) : [];
26
+ const list = held.map((b, i) => {
27
+ const p = prices[i];
28
+ const price = p?.price ?? null;
29
+ return { ...b, price, value: price === null ? null : Number(b.formatted) * price, priceSource: p?.source ?? null };
30
+ });
31
+ const tokensUsd = list.reduce((sum, t) => sum + (t.value ?? 0), 0);
32
+ const lpUsd = positions.reduce((sum, p) => sum + (p.valueUsd ?? 0), 0);
33
+ return {
34
+ totalUsd: tokensUsd + lpUsd,
35
+ tokensUsd,
36
+ lpUsd,
37
+ tokens: list.filter((t) => (t.value ?? 0) >= minUsd || (minUsd === 0 && t.value === null)).sort((a, b) => (b.value ?? -1) - (a.value ?? -1)),
38
+ lp: positions,
39
+ unpriced: list.filter((t) => t.price === null).length + positions.filter((p) => p.valueUsd === null).length,
40
+ };
41
+ }
42
+ /** 余额:传 tokens 时读这些代币的 ATA,否则列出全部持仓 */
43
+ async function holdings(client, owner, tokens, signal) {
44
+ if (tokens) {
45
+ const balances = tokens.length ? await client.balances(owner, tokens, { symbol: true, signal }) : [];
46
+ return balances.filter((b) => b.success).map((b) => ({ token: b.token, native: b.native, symbol: b.symbol ?? null, balance: b.balance, decimals: b.decimals, formatted: b.formatted }));
47
+ }
48
+ const owned = await client.ownerTokens(owner, { signal }).catch((err) => {
49
+ if (signal?.aborted || !methodUnavailable(err)) {
50
+ throw err; // 取消、限频、超时等原样抛出(保留错误类型)
51
+ }
52
+ throw new Error(`Listing the tokens of ${owner} failed (${err instanceof Error ? err.message : String(err)}). ` +
53
+ 'Listing needs getTokenAccountsByOwner (most free public nodes do not support it): pass the mints in `tokens`, or use a node that supports it', { cause: err });
54
+ });
55
+ return owned.map((t) => ({ token: t.token, native: t.native, symbol: t.symbol ?? null, balance: t.balance, decimals: t.decimals, formatted: t.formatted }));
56
+ }
57
+ //# sourceMappingURL=portfolio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portfolio.js","sourceRoot":"","sources":["../src/portfolio.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import type { RequestOptions, SolanaClient } from './client.js';
2
+ import { type PdaPoolProtocol } from './pools.js';
3
+ export interface SolanaPriceSourceContext {
4
+ /** 代币 mint(原生 SOL 用 NATIVE_MINT So111…112 查) */
5
+ mints: readonly string[];
6
+ fetch: typeof fetch;
7
+ signal?: AbortSignal;
8
+ /** 查询用的客户端(链上价格源 onchainPrices 用它读池子) */
9
+ client?: SolanaClient;
10
+ }
11
+ export interface SolanaPriceSource {
12
+ readonly name: string;
13
+ /** 返回 mint → 美元价格;没有价格的不返回 */
14
+ prices(ctx: SolanaPriceSourceContext): Promise<Map<string, number>>;
15
+ }
16
+ export interface DefillamaPriceOptions {
17
+ /** 置信度下限(0~1),DefiLlama 给出的置信度低于它视为没有价格,默认 0.9 */
18
+ minConfidence?: number;
19
+ /** 历史价格:这个时间点(unix 秒或 Date)附近的价格;不传为当前价格 */
20
+ at?: number | Date;
21
+ }
22
+ /**
23
+ * DefiLlama 价格(免费、不需要 Key,按 100 个一批查询)。
24
+ * 注意:流动性很差的代币价格可能虚高,展示总资产时建议配合 minUsd 或自己的价格源。
25
+ *
26
+ * ```ts
27
+ * defillamaPrices() // 当前价格
28
+ * defillamaPrices({ at: new Date('2026-01-01') }) // 历史价格
29
+ * ```
30
+ */
31
+ export declare function defillamaPrices(options?: DefillamaPriceOptions): SolanaPriceSource;
32
+ /**
33
+ * 依次使用多个价格源:前面的源没给出价格的代币交给下一个源。某个源出错时跳过它(错误交给 onError;取消查询时照常 reject)。
34
+ *
35
+ * ```ts
36
+ * combinePrices([defillamaPrices(), onchainPrices()])
37
+ * ```
38
+ */
39
+ export declare function combinePrices(sources: readonly SolanaPriceSource[], options?: {
40
+ onError?: (source: SolanaPriceSource, err: unknown) => void;
41
+ }): SolanaPriceSource;
42
+ /** 按 1 美元计的稳定币(链上价格的计价锚点之一;另一个是 Wrapped SOL):USDC、USDT */
43
+ export declare const STABLECOINS: readonly string[];
44
+ export type OnchainPriceProtocol = PdaPoolProtocol;
45
+ export interface OnchainPriceOptions {
46
+ /** 池子里计价币一侧的价值(美元)下限,低于它的池子不用(防止小池子的价格被操纵),默认 10000 */
47
+ minLiquidityUsd?: number;
48
+ /** 按 1 美元计的稳定币,默认 STABLECOINS(USDC、USDT) */
49
+ stablecoins?: readonly string[];
50
+ /** 用哪些协议的池子,默认全部:'raydium-clmm'、'orca-whirlpool'、'raydium-cpmm' */
51
+ protocols?: readonly OnchainPriceProtocol[];
52
+ }
53
+ /**
54
+ * 链上价格:按 PDA 推导代币对 Wrapped SOL、稳定币的池子(Raydium CLMM 的每个 AmmConfig、Orca 的每个费率档位、Raydium CPMM 的每个 AmmConfig),
55
+ * 用计价币一侧最深的池子的价格。稳定币按 1 美元;Wrapped SOL(和原生 SOL)按它对稳定币最深的池子。
56
+ * 不需要 getProgramAccounts(免费公共节点大多不支持);每个代币约推导 190 个地址,读取用 getMultipleAccounts 合并(一共两轮:池子和 mint、金库)。
57
+ * 深度:CPMM 是金库余额;集中流动性取金库余额和当前活跃流动性折算的储备中较小的(流动性都在区间外的池子价格不可信,不会被选中)。
58
+ * 适合 DefiLlama 没有收录的新币;价格是池子当前的价格,可能被单个区块内的交易影响,只用于展示。
59
+ * Raydium AMM v4、Meteora、PumpSwap 等池子地址不能只靠两个 mint 推导,不在查找范围内
60
+ */
61
+ export declare function onchainPrices(options?: OnchainPriceOptions): SolanaPriceSource;
62
+ export interface TokenPricesOptions extends RequestOptions {
63
+ /** 价格源,依次使用(前面没有价格的交给后面的),默认 [defillamaPrices(), onchainPrices()] */
64
+ sources?: readonly SolanaPriceSource[];
65
+ /** 某个价格源出错时调用(继续用下一个源);回调本身出错会被忽略 */
66
+ onError?: (source: SolanaPriceSource, err: unknown) => void;
67
+ /** 查价格用的 fetch(代理等场景),默认全局 fetch */
68
+ fetch?: typeof fetch;
69
+ }
70
+ export interface TokenPrice {
71
+ /** 传入的 mint(原样) */
72
+ token: string;
73
+ /** 按原生 SOL 处理(客户端的 nativeMints,默认 So111…112 和 11111…1),价格就是 SOL 的价格 */
74
+ native: boolean;
75
+ /** 美元价格;所有价格源都没有时为 null */
76
+ price: number | null;
77
+ /** 给出价格的价格源(如 'defillama'、'onchain') */
78
+ source: string | null;
79
+ }
80
+ /**
81
+ * 查代币的美元价格(SOL 用 NATIVE_MINT)。默认先查 DefiLlama,没有收录的再从链上池子算。
82
+ *
83
+ * ```ts
84
+ * await tokenPrices(client, [NATIVE_MINT, USDC, newToken])
85
+ * // [{ token: 'So111…112', native: true, price: 187.4, source: 'defillama' }, …, { token: newToken, price: 0.0012, source: 'onchain' }]
86
+ * await tokenPrices(client, mints, { sources: [defillamaPrices({ at: new Date('2026-01-01') })] }) // 历史价格
87
+ * ```
88
+ */
89
+ export declare function tokenPrices(client: SolanaClient, mints: readonly string[], options?: TokenPricesOptions): Promise<TokenPrice[]>;
90
+ //# sourceMappingURL=price.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"price.d.ts","sourceRoot":"","sources":["../src/price.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK/D,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAA;AAEhE,MAAM,WAAW,wBAAwB;IACvC,gDAAgD;IAChD,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,KAAK,EAAE,OAAO,KAAK,CAAA;IACnB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,yCAAyC;IACzC,MAAM,CAAC,EAAE,YAAY,CAAA;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,8BAA8B;IAC9B,MAAM,CAAC,GAAG,EAAE,wBAAwB,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACpE;AAED,MAAM,WAAW,qBAAqB;IACpC,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,4CAA4C;IAC5C,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,qBAA0B,GAAG,iBAAiB,CA6BtF;AAMD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,EAAE,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;CAAO,GAAG,iBAAiB,CAQrK;AAsCD,0DAA0D;AAC1D,eAAO,MAAM,WAAW,EAAE,SAAS,MAAM,EAAqG,CAAA;AAE9I,MAAM,MAAM,oBAAoB,GAAG,eAAe,CAAA;AAElD,MAAM,WAAW,mBAAmB;IAClC,uDAAuD;IACvD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC/B,mEAAmE;IACnE,SAAS,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAA;CAC5C;AAmDD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,mBAAwB,GAAG,iBAAiB,CA2ElF;AA+CD,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD,qEAAqE;IACrE,OAAO,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAA;IACtC,qCAAqC;IACrC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;IAC3D,oCAAoC;IACpC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,uEAAuE;IACvE,MAAM,EAAE,OAAO,CAAA;IACf,2BAA2B;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,wCAAwC;IACxC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAYzI"}
package/dist/price.js ADDED
@@ -0,0 +1,287 @@
1
+ /**
2
+ * 价格(子路径 `@w3lib/solana-batch-call/price`):DefiLlama(当前 / 历史)、链上池子价格(Raydium CLMM / CPMM、Orca Whirlpool,按 PDA 推导池子地址,
3
+ * 不需要 getProgramAccounts)、组合多个价格源。价格只用于展示和估值,不要用来计算交易的最小数量
4
+ */
5
+ import { isAddress } from './address.js';
6
+ import { NATIVE_MINT } from './constants.js';
7
+ import { formatUnits, parseMint, parseTokenAccount } from './layout.js';
8
+ import { Bytes, ORCA_WHIRLPOOL_PROGRAM_ID, RAYDIUM_CLMM_PROGRAM_ID, parseAmmPool } from './lp.js';
9
+ import { sqrtPriceToPrice } from './lpMath.js';
10
+ import { poolAddresses } from './pools.js';
11
+ /**
12
+ * DefiLlama 价格(免费、不需要 Key,按 100 个一批查询)。
13
+ * 注意:流动性很差的代币价格可能虚高,展示总资产时建议配合 minUsd 或自己的价格源。
14
+ *
15
+ * ```ts
16
+ * defillamaPrices() // 当前价格
17
+ * defillamaPrices({ at: new Date('2026-01-01') }) // 历史价格
18
+ * ```
19
+ */
20
+ export function defillamaPrices(options = {}) {
21
+ const minConfidence = options.minConfidence ?? 0.9;
22
+ const at = options.at instanceof Date ? Math.floor(options.at.getTime() / 1000) : options.at === undefined ? undefined : Math.floor(options.at);
23
+ const endpoint = at === undefined ? 'https://coins.llama.fi/prices/current' : `https://coins.llama.fi/prices/historical/${at}`;
24
+ return {
25
+ name: at === undefined ? 'defillama' : `defillama@${at}`,
26
+ async prices({ mints, fetch: fetchFn, signal }) {
27
+ const result = new Map();
28
+ const batches = [];
29
+ for (let i = 0; i < mints.length; i += 100) {
30
+ batches.push(mints.slice(i, i + 100));
31
+ }
32
+ await Promise.all(batches.map(async (batch) => {
33
+ const res = await fetchFn(`${endpoint}/${batch.map((m) => `solana:${m}`).join(',')}`, { signal });
34
+ if (!res.ok) {
35
+ throw new Error(`DefiLlama prices: HTTP ${res.status}`);
36
+ }
37
+ const body = (await res.json());
38
+ for (const [key, coin] of Object.entries(body.coins ?? {})) {
39
+ if (typeof coin.price === 'number' && Number.isFinite(coin.price) && (coin.confidence === undefined || coin.confidence >= minConfidence)) {
40
+ result.set(key.slice(key.indexOf(':') + 1), coin.price);
41
+ }
42
+ }
43
+ }));
44
+ return result;
45
+ },
46
+ };
47
+ }
48
+ // ---------------------------------------------------------------------------
49
+ // 组合
50
+ // ---------------------------------------------------------------------------
51
+ /**
52
+ * 依次使用多个价格源:前面的源没给出价格的代币交给下一个源。某个源出错时跳过它(错误交给 onError;取消查询时照常 reject)。
53
+ *
54
+ * ```ts
55
+ * combinePrices([defillamaPrices(), onchainPrices()])
56
+ * ```
57
+ */
58
+ export function combinePrices(sources, options = {}) {
59
+ return {
60
+ name: sources.map((s) => s.name).join('+'),
61
+ async prices(ctx) {
62
+ const found = await runSources(sources, ctx, options.onError);
63
+ return new Map([...found].map(([k, v]) => [k, v.price]));
64
+ },
65
+ };
66
+ }
67
+ /** 依次查询,记下每个价格来自哪个源 */
68
+ async function runSources(sources, ctx, onError) {
69
+ const result = new Map();
70
+ let mints = [...ctx.mints];
71
+ for (const source of sources) {
72
+ if (!mints.length)
73
+ break;
74
+ let found;
75
+ try {
76
+ found = await source.prices({ ...ctx, mints });
77
+ }
78
+ catch (err) {
79
+ if (ctx.signal?.aborted) {
80
+ throw err;
81
+ }
82
+ try {
83
+ onError?.(source, err);
84
+ }
85
+ catch {
86
+ // 回调出错不影响查询结果
87
+ }
88
+ continue;
89
+ }
90
+ for (const [mint, price] of found) {
91
+ if (!result.has(mint) && Number.isFinite(price))
92
+ result.set(mint, { price, source: source.name });
93
+ }
94
+ mints = mints.filter((m) => !result.has(m));
95
+ }
96
+ return result;
97
+ }
98
+ // ---------------------------------------------------------------------------
99
+ // 链上价格
100
+ // ---------------------------------------------------------------------------
101
+ /** 按 1 美元计的稳定币(链上价格的计价锚点之一;另一个是 Wrapped SOL):USDC、USDT */
102
+ export const STABLECOINS = ['EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'];
103
+ /** 账户至少要读到的长度(Raydium PoolState 1544 字节,Orca Whirlpool 653 字节) */
104
+ const RAYDIUM_POOL_SIZE = 1544;
105
+ const ORCA_POOL_SIZE = 653;
106
+ /** 两个 mint 在所有协议里可能的池子地址 */
107
+ function candidates(token, anchor, protocols) {
108
+ return poolAddresses(token, anchor, protocols).map((p) => ({ ...p, token, anchor }));
109
+ }
110
+ function readPool(c, account) {
111
+ const b = new Bytes(account.data);
112
+ if (c.protocol === 'raydium-clmm' && account.owner === RAYDIUM_CLMM_PROGRAM_ID && account.data.length >= RAYDIUM_POOL_SIZE) {
113
+ // PoolState:mint 73 / 105、vault 137 / 169、liquidity 237、sqrt_price 253
114
+ return { kind: 'clmm', mint0: b.key(73), mint1: b.key(105), vault0: b.key(137), vault1: b.key(169), liquidity: b.u128(237), sqrtPrice: b.u128(253) };
115
+ }
116
+ if (c.protocol === 'orca-whirlpool' && account.owner === ORCA_WHIRLPOOL_PROGRAM_ID && account.data.length >= ORCA_POOL_SIZE) {
117
+ // Whirlpool:liquidity 49、sqrt_price 65、mint_a 101、vault_a 133、mint_b 181、vault_b 213
118
+ return { kind: 'clmm', mint0: b.key(101), mint1: b.key(181), vault0: b.key(133), vault1: b.key(213), liquidity: b.u128(49), sqrtPrice: b.u128(65) };
119
+ }
120
+ if (c.protocol === 'raydium-cpmm') {
121
+ const pool = parseAmmPool(account);
122
+ return pool?.protocol === 'raydium-cpmm'
123
+ ? { kind: 'cpmm', mint0: pool.mint0, mint1: pool.mint1, vault0: pool.vault0, vault1: pool.vault1, reserved0: pool.reserved0, reserved1: pool.reserved1 }
124
+ : null;
125
+ }
126
+ return null;
127
+ }
128
+ /**
129
+ * 链上价格:按 PDA 推导代币对 Wrapped SOL、稳定币的池子(Raydium CLMM 的每个 AmmConfig、Orca 的每个费率档位、Raydium CPMM 的每个 AmmConfig),
130
+ * 用计价币一侧最深的池子的价格。稳定币按 1 美元;Wrapped SOL(和原生 SOL)按它对稳定币最深的池子。
131
+ * 不需要 getProgramAccounts(免费公共节点大多不支持);每个代币约推导 190 个地址,读取用 getMultipleAccounts 合并(一共两轮:池子和 mint、金库)。
132
+ * 深度:CPMM 是金库余额;集中流动性取金库余额和当前活跃流动性折算的储备中较小的(流动性都在区间外的池子价格不可信,不会被选中)。
133
+ * 适合 DefiLlama 没有收录的新币;价格是池子当前的价格,可能被单个区块内的交易影响,只用于展示。
134
+ * Raydium AMM v4、Meteora、PumpSwap 等池子地址不能只靠两个 mint 推导,不在查找范围内
135
+ */
136
+ export function onchainPrices(options = {}) {
137
+ return {
138
+ name: 'onchain',
139
+ async prices({ mints, client, signal }) {
140
+ if (!client)
141
+ throw new Error('onchainPrices needs a SolanaClient (ctx.client)');
142
+ const stables = options.stablecoins ?? STABLECOINS;
143
+ const protocols = new Set(options.protocols ?? ['raydium-clmm', 'orca-whirlpool', 'raydium-cpmm']);
144
+ const minLiquidity = options.minLiquidityUsd ?? 10_000;
145
+ const result = new Map();
146
+ const stableSet = new Set(stables);
147
+ for (const m of mints)
148
+ if (stableSet.has(m))
149
+ result.set(m, 1);
150
+ const rest = [...new Set(mints)].filter((m) => !stableSet.has(m) && m !== NATIVE_MINT && isAddress(m));
151
+ const wantSol = mints.includes(NATIVE_MINT);
152
+ if (!stables.length || !protocols.size || (!rest.length && !wantSol))
153
+ return result;
154
+ // 1. 一次读:Wrapped SOL 对稳定币、其他代币对 Wrapped SOL 和稳定币的候选池子,以及这些代币的 mint(精度)
155
+ const list = [
156
+ ...stables.flatMap((s) => candidates(NATIVE_MINT, s, protocols)),
157
+ ...rest.flatMap((t) => [NATIVE_MINT, ...stables].flatMap((anchor) => candidates(t, anchor, protocols))),
158
+ ];
159
+ const mintList = [...new Set([NATIVE_MINT, ...stables, ...rest])];
160
+ const first = await client.accounts([...list.map((c) => c.address), ...mintList], { signal });
161
+ const decimals = new Map();
162
+ mintList.forEach((m, i) => {
163
+ const account = first[list.length + i];
164
+ try {
165
+ if (account)
166
+ decimals.set(m, parseMint(account.data).decimals);
167
+ }
168
+ catch {
169
+ // 不是代币 mint
170
+ }
171
+ });
172
+ const pools = list.flatMap((c, i) => {
173
+ const account = first[i];
174
+ const pool = account ? readPool(c, account) : null;
175
+ // 池子里的两个 mint 要和推导时的一致(PDA 上可能是别的账户)
176
+ const ok = pool && ((pool.mint0 === c.token && pool.mint1 === c.anchor) || (pool.mint1 === c.token && pool.mint0 === c.anchor));
177
+ return ok ? [{ ...c, pool }] : [];
178
+ });
179
+ if (!pools.length)
180
+ return result;
181
+ // 2. 一次读:金库(集中流动性只读计价币一侧,CPMM 两侧都读)
182
+ const vaultsOf = (p) => {
183
+ const anchorIs0 = p.pool.mint0 === p.anchor;
184
+ return p.pool.kind === 'cpmm' ? [p.pool.vault0, p.pool.vault1] : [anchorIs0 ? p.pool.vault0 : p.pool.vault1];
185
+ };
186
+ const vaultAddresses = [...new Set(pools.flatMap(vaultsOf))];
187
+ const vaultAccounts = await client.accounts(vaultAddresses, { signal });
188
+ const balances = new Map();
189
+ vaultAddresses.forEach((address, i) => {
190
+ const account = vaultAccounts[i];
191
+ try {
192
+ if (account)
193
+ balances.set(address, parseTokenAccount(account.data).amount);
194
+ }
195
+ catch {
196
+ // 不是代币账户
197
+ }
198
+ });
199
+ const quotes = pools.flatMap((p) => {
200
+ const q = quote(p.pool, p.token, p.anchor, decimals, balances);
201
+ return q && Number.isFinite(q.price) && q.price > 0 && Number.isFinite(q.depth) ? [q] : [];
202
+ });
203
+ // 3. 先算 Wrapped SOL(对稳定币),再按 SOL 和稳定币的美元价格算其他代币
204
+ const anchorsUsd = new Map(stables.map((s) => [s, 1]));
205
+ const sol = best(quotes.filter((q) => q.token === NATIVE_MINT), anchorsUsd, minLiquidity);
206
+ if (sol !== null) {
207
+ anchorsUsd.set(NATIVE_MINT, sol);
208
+ if (wantSol)
209
+ result.set(NATIVE_MINT, sol);
210
+ }
211
+ for (const t of rest) {
212
+ const usd = best(quotes.filter((q) => q.token === t), anchorsUsd, minLiquidity);
213
+ if (usd !== null)
214
+ result.set(t, usd);
215
+ }
216
+ return result;
217
+ },
218
+ };
219
+ }
220
+ /** 一个池子给出的价格(计价币 / 代币)和计价币一侧的深度;缺精度、金库时为 null */
221
+ function quote(pool, token, anchor, decimals, balances) {
222
+ const d0 = decimals.get(pool.mint0);
223
+ const d1 = decimals.get(pool.mint1);
224
+ if (d0 === undefined || d1 === undefined)
225
+ return null;
226
+ const tokenIs0 = pool.mint0 === token;
227
+ const da = tokenIs0 ? d1 : d0;
228
+ if (pool.kind === 'cpmm') {
229
+ const v0 = balances.get(pool.vault0);
230
+ const v1 = balances.get(pool.vault1);
231
+ if (v0 === undefined || v1 === undefined)
232
+ return null;
233
+ // 与程序一致:金库余额扣掉协议 / 基金 / 创建者手续费才是储备
234
+ const r0 = v0 > pool.reserved0 ? v0 - pool.reserved0 : 0n;
235
+ const r1 = v1 > pool.reserved1 ? v1 - pool.reserved1 : 0n;
236
+ if (r0 === 0n || r1 === 0n)
237
+ return null;
238
+ const [rt, ra, dt] = tokenIs0 ? [r0, r1, d0] : [r1, r0, d1];
239
+ const depth = Number(formatUnits(ra, da));
240
+ return { token, anchor, price: depth / Number(formatUnits(rt, dt)), depth };
241
+ }
242
+ const vault = balances.get(tokenIs0 ? pool.vault1 : pool.vault0);
243
+ if (vault === undefined || pool.sqrtPrice === 0n)
244
+ return null;
245
+ // price = token1 / token0(按精度换算)
246
+ const price1Per0 = sqrtPriceToPrice(pool.sqrtPrice, d0, d1);
247
+ // 当前活跃流动性折算的计价币储备(最小单位):token1 = L × √P,token0 = L / √P(√P = sqrtPrice / 2^64)
248
+ const sqrt = Number(pool.sqrtPrice) / 2 ** 64;
249
+ const virtual = (tokenIs0 ? Number(pool.liquidity) * sqrt : Number(pool.liquidity) / sqrt) / 10 ** da;
250
+ return { token, anchor, price: tokenIs0 ? price1Per0 : 1 / price1Per0, depth: Math.min(Number(formatUnits(vault, da)), virtual) };
251
+ }
252
+ /** 深度(美元)达到下限的池子里最深的一个给出的美元价格;没有时为 null */
253
+ function best(quotes, anchorsUsd, minLiquidityUsd) {
254
+ let found = null;
255
+ for (const q of quotes) {
256
+ const anchorUsd = anchorsUsd.get(q.anchor);
257
+ if (anchorUsd === undefined)
258
+ continue;
259
+ const depthUsd = q.depth * anchorUsd;
260
+ if (depthUsd >= minLiquidityUsd && (!found || depthUsd > found.depthUsd))
261
+ found = { usd: q.price * anchorUsd, depthUsd };
262
+ }
263
+ return found ? found.usd : null;
264
+ }
265
+ /**
266
+ * 查代币的美元价格(SOL 用 NATIVE_MINT)。默认先查 DefiLlama,没有收录的再从链上池子算。
267
+ *
268
+ * ```ts
269
+ * await tokenPrices(client, [NATIVE_MINT, USDC, newToken])
270
+ * // [{ token: 'So111…112', native: true, price: 187.4, source: 'defillama' }, …, { token: newToken, price: 0.0012, source: 'onchain' }]
271
+ * await tokenPrices(client, mints, { sources: [defillamaPrices({ at: new Date('2026-01-01') })] }) // 历史价格
272
+ * ```
273
+ */
274
+ export async function tokenPrices(client, mints, options = {}) {
275
+ const { sources = [defillamaPrices(), onchainPrices()], onError, fetch: fetchOption, signal } = options;
276
+ const fetchFn = fetchOption ?? ((...args) => fetch(...args));
277
+ const native = mints.map((m) => client.isNativeMint(m));
278
+ // 原生 SOL 按 Wrapped SOL 的 mint 查;不是合法地址的不查
279
+ const keys = mints.map((m, i) => (native[i] ? NATIVE_MINT : m));
280
+ const query = [...new Set(keys.filter((k) => isAddress(k)))];
281
+ const found = await runSources(sources, { mints: query, fetch: fetchFn, signal, client }, onError);
282
+ return mints.map((token, i) => {
283
+ const hit = found.get(keys[i]);
284
+ return { token, native: native[i], price: hit?.price ?? null, source: hit?.source ?? null };
285
+ });
286
+ }
287
+ //# sourceMappingURL=price.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"price.js","sourceRoot":"","sources":["../src/price.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export declare const COMPUTE_BUDGET = "ComputeBudget111111111111111111111111111111";
2
+ export declare const MEMO_V2 = "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr";
3
+ export declare const MEMO_V1 = "Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo";
4
+ export declare const BPF_LOADER_UPGRADEABLE = "BPFLoaderUpgradeab1e11111111111111111111111";
5
+ /** 指令的大类:交易的类型由它们和余额变化一起决定 */
6
+ export type IxType = 'transfer' | 'swap' | 'approve' | 'liquidity' | 'mint' | 'burn' | 'close' | 'setup' | 'budget' | 'memo' | 'contract' | 'unknown';
7
+ export interface ProgramInfo {
8
+ name: string;
9
+ /** 内置程序(系统、代币、ATA、计算预算、备忘录等):不算“不认识的程序” */
10
+ builtin?: boolean;
11
+ /** 协议名(DEX / 借贷等),内置程序没有 */
12
+ protocol?: string;
13
+ }
14
+ export declare const PROGRAMS: Readonly<Record<string, ProgramInfo>>;
15
+ /** 认得的程序指令:返回指令名和大类;不认识的指令(程序认得)返回 null */
16
+ export declare function knownMethod(programId: string, data: Uint8Array): [method: string, type: IxType] | null;
17
+ /** 自定义错误码的名字:先看这个程序自己的表,再看 Anchor 框架的;认不出时返回 undefined */
18
+ export declare function programErrorName(programId: string | undefined, code: number): string | undefined;
19
+ //# sourceMappingURL=programs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"programs.d.ts","sourceRoot":"","sources":["../src/programs.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,cAAc,gDAAgD,CAAA;AAC3E,eAAO,MAAM,OAAO,gDAAgD,CAAA;AACpE,eAAO,MAAM,OAAO,gDAAgD,CAAA;AACpE,eAAO,MAAM,sBAAsB,gDAAgD,CAAA;AAEnF,8BAA8B;AAC9B,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;AAErJ,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,2CAA2C;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAKD,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAiD1D,CAAA;AA6ED,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,IAAI,CAatG;AAkCD,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEhG"}