@w3lib/evm-batch-call 0.5.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.
Files changed (160) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +240 -4
  3. package/contracts/TokenProbe.sol +103 -0
  4. package/dist/aggregate.d.ts.map +1 -1
  5. package/dist/aggregate.js +114 -3
  6. package/dist/aggregate.js.map +1 -1
  7. package/dist/approvals.d.ts +169 -0
  8. package/dist/approvals.d.ts.map +1 -0
  9. package/dist/approvals.js +310 -0
  10. package/dist/approvals.js.map +1 -0
  11. package/dist/chains.d.ts.map +1 -1
  12. package/dist/chains.js +4 -0
  13. package/dist/chains.js.map +1 -1
  14. package/dist/fees.d.ts +97 -0
  15. package/dist/fees.d.ts.map +1 -0
  16. package/dist/fees.js +115 -0
  17. package/dist/fees.js.map +1 -0
  18. package/dist/http.d.ts +10 -0
  19. package/dist/http.d.ts.map +1 -0
  20. package/dist/http.js +30 -0
  21. package/dist/http.js.map +1 -0
  22. package/dist/liquidity/common.d.ts +72 -0
  23. package/dist/liquidity/common.d.ts.map +1 -0
  24. package/dist/liquidity/common.js +271 -0
  25. package/dist/liquidity/common.js.map +1 -0
  26. package/dist/liquidity/concentrated.d.ts +19 -0
  27. package/dist/liquidity/concentrated.d.ts.map +1 -0
  28. package/dist/liquidity/concentrated.js +106 -0
  29. package/dist/liquidity/concentrated.js.map +1 -0
  30. package/dist/liquidity/index.d.ts +42 -0
  31. package/dist/liquidity/index.d.ts.map +1 -0
  32. package/dist/liquidity/index.js +143 -0
  33. package/dist/liquidity/index.js.map +1 -0
  34. package/dist/liquidity/types.d.ts +182 -0
  35. package/dist/liquidity/types.d.ts.map +1 -0
  36. package/dist/liquidity/types.js +2 -0
  37. package/dist/liquidity/types.js.map +1 -0
  38. package/dist/liquidity/v2.d.ts +5 -0
  39. package/dist/liquidity/v2.d.ts.map +1 -0
  40. package/dist/liquidity/v2.js +342 -0
  41. package/dist/liquidity/v2.js.map +1 -0
  42. package/dist/liquidity/v3.d.ts +6 -0
  43. package/dist/liquidity/v3.d.ts.map +1 -0
  44. package/dist/liquidity/v3.js +310 -0
  45. package/dist/liquidity/v3.js.map +1 -0
  46. package/dist/liquidity/v4.d.ts +5 -0
  47. package/dist/liquidity/v4.d.ts.map +1 -0
  48. package/dist/liquidity/v4.js +279 -0
  49. package/dist/liquidity/v4.js.map +1 -0
  50. package/dist/lp.d.ts +10 -2
  51. package/dist/lp.d.ts.map +1 -1
  52. package/dist/lp.js +31 -19
  53. package/dist/lp.js.map +1 -1
  54. package/dist/lpMath.d.ts +55 -0
  55. package/dist/lpMath.d.ts.map +1 -1
  56. package/dist/lpMath.js +209 -0
  57. package/dist/lpMath.js.map +1 -1
  58. package/dist/multicall.d.ts.map +1 -1
  59. package/dist/multicall.js +3 -0
  60. package/dist/multicall.js.map +1 -1
  61. package/dist/names.d.ts +55 -0
  62. package/dist/names.d.ts.map +1 -0
  63. package/dist/names.js +93 -0
  64. package/dist/names.js.map +1 -0
  65. package/dist/owner.d.ts +4 -26
  66. package/dist/owner.d.ts.map +1 -1
  67. package/dist/owner.js +7 -112
  68. package/dist/owner.js.map +1 -1
  69. package/dist/portfolio.d.ts +54 -0
  70. package/dist/portfolio.d.ts.map +1 -0
  71. package/dist/portfolio.js +49 -0
  72. package/dist/portfolio.js.map +1 -0
  73. package/dist/price.d.ts +95 -0
  74. package/dist/price.d.ts.map +1 -0
  75. package/dist/price.js +329 -0
  76. package/dist/price.js.map +1 -0
  77. package/dist/risk.d.ts +42 -0
  78. package/dist/risk.d.ts.map +1 -0
  79. package/dist/risk.js +134 -0
  80. package/dist/risk.js.map +1 -0
  81. package/dist/rpcNodes.d.ts.map +1 -1
  82. package/dist/rpcNodes.js +18 -0
  83. package/dist/rpcNodes.js.map +1 -1
  84. package/dist/subpaths/approvals.d.ts +26 -0
  85. package/dist/subpaths/approvals.d.ts.map +1 -0
  86. package/dist/subpaths/approvals.js +27 -0
  87. package/dist/subpaths/approvals.js.map +1 -0
  88. package/dist/subpaths/fees.d.ts +23 -0
  89. package/dist/subpaths/fees.d.ts.map +1 -0
  90. package/dist/subpaths/fees.js +25 -0
  91. package/dist/subpaths/fees.js.map +1 -0
  92. package/dist/subpaths/liquidity.d.ts +24 -0
  93. package/dist/subpaths/liquidity.d.ts.map +1 -0
  94. package/dist/subpaths/liquidity.js +21 -0
  95. package/dist/subpaths/liquidity.js.map +1 -0
  96. package/dist/subpaths/lp.d.ts +1 -1
  97. package/dist/subpaths/lp.d.ts.map +1 -1
  98. package/dist/subpaths/lp.js +1 -1
  99. package/dist/subpaths/lp.js.map +1 -1
  100. package/dist/subpaths/names.d.ts +35 -0
  101. package/dist/subpaths/names.d.ts.map +1 -0
  102. package/dist/subpaths/names.js +39 -0
  103. package/dist/subpaths/names.js.map +1 -0
  104. package/dist/subpaths/price.d.ts +38 -0
  105. package/dist/subpaths/price.d.ts.map +1 -0
  106. package/dist/subpaths/price.js +40 -0
  107. package/dist/subpaths/price.js.map +1 -0
  108. package/dist/subpaths/risk.d.ts +19 -0
  109. package/dist/subpaths/risk.d.ts.map +1 -0
  110. package/dist/subpaths/risk.js +20 -0
  111. package/dist/subpaths/risk.js.map +1 -0
  112. package/dist/subpaths/swap.d.ts +19 -0
  113. package/dist/subpaths/swap.d.ts.map +1 -0
  114. package/dist/subpaths/swap.js +20 -0
  115. package/dist/subpaths/swap.js.map +1 -0
  116. package/dist/swap.d.ts +128 -0
  117. package/dist/swap.d.ts.map +1 -0
  118. package/dist/swap.js +291 -0
  119. package/dist/swap.js.map +1 -0
  120. package/dist/tokenProbe.d.ts +3 -0
  121. package/dist/tokenProbe.d.ts.map +1 -0
  122. package/dist/tokenProbe.js +4 -0
  123. package/dist/tokenProbe.js.map +1 -0
  124. package/dist/write/tron.d.ts +27 -0
  125. package/dist/write/tron.d.ts.map +1 -1
  126. package/dist/write/tron.js +30 -0
  127. package/dist/write/tron.js.map +1 -1
  128. package/package.json +32 -1
  129. package/src/aggregate.ts +110 -3
  130. package/src/approvals.ts +462 -0
  131. package/src/chains.ts +4 -0
  132. package/src/fees.ts +201 -0
  133. package/src/http.ts +34 -0
  134. package/src/liquidity/common.ts +314 -0
  135. package/src/liquidity/concentrated.ts +121 -0
  136. package/src/liquidity/index.ts +171 -0
  137. package/src/liquidity/types.ts +194 -0
  138. package/src/liquidity/v2.ts +371 -0
  139. package/src/liquidity/v3.ts +382 -0
  140. package/src/liquidity/v4.ts +348 -0
  141. package/src/lp.ts +39 -19
  142. package/src/lpMath.ts +223 -0
  143. package/src/multicall.ts +3 -0
  144. package/src/names.ts +141 -0
  145. package/src/owner.ts +7 -138
  146. package/src/portfolio.ts +91 -0
  147. package/src/price.ts +415 -0
  148. package/src/risk.ts +166 -0
  149. package/src/rpcNodes.ts +18 -0
  150. package/src/subpaths/approvals.ts +48 -0
  151. package/src/subpaths/fees.ts +43 -0
  152. package/src/subpaths/liquidity.ts +52 -0
  153. package/src/subpaths/lp.ts +20 -1
  154. package/src/subpaths/names.ts +43 -0
  155. package/src/subpaths/price.ts +60 -0
  156. package/src/subpaths/risk.ts +23 -0
  157. package/src/subpaths/swap.ts +36 -0
  158. package/src/swap.ts +413 -0
  159. package/src/tokenProbe.ts +5 -0
  160. package/src/write/tron.ts +48 -0
@@ -0,0 +1,49 @@
1
+ /**
2
+ * 资产总值(子路径 `@w3lib/evm-batch-call/price`):已知代币的余额 × 价格,可选加上 LP 仓位的价值
3
+ */
4
+ import { lpPositions } from './lp.js';
5
+ import { combinePrices, defillamaPrices, onchainPrices, tokenPrices } from './price.js';
6
+ /**
7
+ * 一个地址的资产总值:代币余额(只看传入的代币,EVM 不能只靠节点列出持仓)× 价格,可选加上 LP 仓位。
8
+ *
9
+ * ```ts
10
+ * const p = await portfolio(provider, user, { tokens: [NATIVE_TOKEN, USDT, USDC], lp: true })
11
+ * p.totalUsd // 1234.5
12
+ * ```
13
+ */
14
+ export async function portfolio(provider, owner, options) {
15
+ const { tokens, sources = [defillamaPrices(), onchainPrices()], lp, minUsd = 0, onPriceError, fetch: fetchFn } = options;
16
+ const onError = onPriceError ? (_, err) => onPriceError(err) : undefined;
17
+ const [balances, positions] = await Promise.all([
18
+ tokens.length ? provider.balances(owner, tokens, { symbol: true }) : Promise.resolve([]),
19
+ lp ? lpPositions(provider, owner, { ...(lp === true ? {} : lp), prices: combinePrices(sources, { onError }), ...(fetchFn ? { fetch: fetchFn } : {}), ...(onPriceError ? { onPriceError } : {}) }) : Promise.resolve([]),
20
+ ]);
21
+ const held = balances.filter((b) => b.success && BigInt(b.balance) > 0n);
22
+ const prices = held.length ? await tokenPrices(provider, held.map((b) => b.token), { sources, ...(onError ? { onError } : {}), ...(fetchFn ? { fetch: fetchFn } : {}) }) : [];
23
+ const list = held.map((b, i) => {
24
+ const p = prices[i];
25
+ const price = p?.price ?? null;
26
+ return {
27
+ token: b.token,
28
+ native: b.native,
29
+ symbol: b.symbol ?? null,
30
+ balance: b.balance,
31
+ decimals: b.decimals,
32
+ formatted: b.formatted,
33
+ price,
34
+ value: price === null ? null : Number(b.formatted) * price,
35
+ priceSource: p?.source ?? null,
36
+ };
37
+ });
38
+ const tokensUsd = list.reduce((sum, t) => sum + (t.value ?? 0), 0);
39
+ const lpUsd = positions.reduce((sum, p) => sum + (p.valueUsd ?? 0), 0);
40
+ return {
41
+ totalUsd: tokensUsd + lpUsd,
42
+ tokensUsd,
43
+ lpUsd,
44
+ tokens: list.filter((t) => (t.value ?? 0) >= minUsd || (minUsd === 0 && t.value === null)).sort((a, b) => (b.value ?? -1) - (a.value ?? -1)),
45
+ lp: positions,
46
+ unpriced: list.filter((t) => t.price === null).length + positions.filter((p) => p.valueUsd === null).length,
47
+ };
48
+ }
49
+ //# 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,95 @@
1
+ import { type LpProtocol } from './lp.js';
2
+ import type { Provider } from './provider.js';
3
+ export interface PriceSourceContext {
4
+ chainId: number;
5
+ /** 代币地址(不含主币) */
6
+ tokens: readonly string[];
7
+ /** 主币 symbol(需要主币价格时);不需要时为 null */
8
+ nativeSymbol: string | null;
9
+ fetch: typeof fetch;
10
+ /** 查询用的 Provider(链上价格源 onchainPrices 用它读池子) */
11
+ provider?: Provider;
12
+ }
13
+ export interface PriceSource {
14
+ readonly name: string;
15
+ /** 返回 去重键 → 美元价格:EVM 是小写 0x 地址;Tron 是 T 开头的 base58 地址(区分大小写);主币用键 'native'。没有价格的不返回 */
16
+ prices(ctx: PriceSourceContext): Promise<Map<string, number>>;
17
+ }
18
+ /** DefiLlama 的链标识:chainId → slug(2026-10 实测可用) */
19
+ export declare const DEFILLAMA_CHAINS: Readonly<Record<number, string>>;
20
+ export interface DefillamaPriceOptions {
21
+ /** 置信度下限(0~1),DefiLlama 给出的置信度低于它视为没有价格,默认 0.9 */
22
+ minConfidence?: number;
23
+ /** 历史价格:这个时间点(unix 秒或 Date)附近的价格;不传为当前价格 */
24
+ at?: number | Date;
25
+ }
26
+ /**
27
+ * DefiLlama 价格(免费、不需要 Key)。
28
+ * 注意:流动性很差的代币价格可能虚高,展示总资产时建议配合 minUsd 或自己的价格源。
29
+ *
30
+ * ```ts
31
+ * defillamaPrices() // 当前价格
32
+ * defillamaPrices({ at: new Date('2026-01-01') }) // 历史价格
33
+ * ```
34
+ */
35
+ export declare function defillamaPrices(options?: DefillamaPriceOptions): PriceSource;
36
+ /**
37
+ * 依次使用多个价格源:前面的源没给出价格的代币(和主币)交给下一个源。某个源出错时跳过它(错误交给 onError)。
38
+ *
39
+ * ```ts
40
+ * combinePrices([defillamaPrices(), onchainPrices()])
41
+ * ```
42
+ */
43
+ export declare function combinePrices(sources: readonly PriceSource[], options?: {
44
+ onError?: (source: PriceSource, err: unknown) => void;
45
+ }): PriceSource;
46
+ /** 价格结果里的键:EVM 小写 0x 地址;Tron 是 T 开头的 base58 地址;主币为 'native' */
47
+ export declare function priceKeyOf(chainId: number, token: string): string;
48
+ /** 按 1 美元计的稳定币(链上价格的计价锚点之一;另一个是包装主币) */
49
+ export declare const STABLECOINS: Readonly<Record<number, readonly string[]>>;
50
+ export interface OnchainPriceOptions {
51
+ /** 池子里计价币一侧的价值(美元)下限,低于它的池子不用(防止小池子的价格被操纵),默认 10000 */
52
+ minLiquidityUsd?: number;
53
+ /** 包装主币(计价锚点,主币的价格也按它),默认 LP_QUOTE_TOKENS 里这条链的第一个 */
54
+ wrappedNative?: string;
55
+ /** 按 1 美元计的稳定币,默认 STABLECOINS 里这条链的 */
56
+ stablecoins?: readonly string[];
57
+ /** 用哪些协议的池子,默认 LP_PROTOCOLS 里这条链的 V2 和 V3 */
58
+ protocols?: readonly LpProtocol[];
59
+ /** V3 池子的手续费档位,默认 [100, 500, 2500, 3000, 10000] */
60
+ fees?: readonly number[];
61
+ }
62
+ /**
63
+ * 链上价格:在 V2 / V3 池子里找代币对包装主币、稳定币的池子,用计价币一侧最深的池子的价格。
64
+ * 稳定币按 1 美元;包装主币(和主币)按它对稳定币最深的池子。读取全部用 multicall 合并。
65
+ * 适合 DefiLlama 没有收录的新币;价格是池子当前的价格,可能被单个区块内的交易影响,只用于展示
66
+ */
67
+ export declare function onchainPrices(options?: OnchainPriceOptions): PriceSource;
68
+ export interface TokenPricesOptions {
69
+ /** 价格源,依次使用(前面没有价格的交给后面的),默认 [defillamaPrices(), onchainPrices()] */
70
+ sources?: readonly PriceSource[];
71
+ /** 某个价格源出错时调用(继续用下一个源) */
72
+ onError?: (source: PriceSource, err: unknown) => void;
73
+ /** 自定义 fetch(代理等场景);默认全局 fetch */
74
+ fetch?: typeof fetch;
75
+ }
76
+ export interface TokenPrice {
77
+ /** 传入的代币地址(原样) */
78
+ token: string;
79
+ native: boolean;
80
+ /** 美元价格;所有价格源都没有时为 null */
81
+ price: number | null;
82
+ /** 给出价格的价格源(如 'defillama'、'onchain') */
83
+ source: string | null;
84
+ }
85
+ /**
86
+ * 查代币的美元价格(主币用 NATIVE_TOKEN 或零地址)。默认先查 DefiLlama,没有收录的再从链上池子算。
87
+ *
88
+ * ```ts
89
+ * await tokenPrices(provider, [NATIVE_TOKEN, USDT, newToken])
90
+ * // [{ token: '0xEeee…', native: true, price: 612.3, source: 'defillama' }, …, { token: newToken, price: 0.0012, source: 'onchain' }]
91
+ * await tokenPrices(provider, tokens, { sources: [defillamaPrices({ at: new Date('2026-01-01') })] }) // 历史价格
92
+ * ```
93
+ */
94
+ export declare function tokenPrices(provider: Provider, tokens: readonly string[], options?: TokenPricesOptions): Promise<TokenPrice[]>;
95
+ //# sourceMappingURL=price.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"price.d.ts","sourceRoot":"","sources":["../src/price.ts"],"names":[],"mappings":"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"}
package/dist/price.js ADDED
@@ -0,0 +1,329 @@
1
+ import { formatUnits } from './erc20.js';
2
+ import { fetchJson } from './http.js';
3
+ import { LP_PROTOCOLS, LP_QUOTE_TOKENS } from './lp.js';
4
+ import { sqrtPriceToPrice } from './lpMath.js';
5
+ import { getNativeCurrency } from './chains.js';
6
+ import { TRON_CHAIN_ID, isTronChain, toTronAddress } from './tron.js';
7
+ /** DefiLlama 的链标识:chainId → slug(2026-10 实测可用) */
8
+ export const DEFILLAMA_CHAINS = {
9
+ 1: 'ethereum',
10
+ 10: 'optimism',
11
+ 56: 'bsc',
12
+ 130: 'unichain',
13
+ 137: 'polygon',
14
+ 143: 'monad',
15
+ 196: 'xlayer',
16
+ 204: 'op_bnb',
17
+ 324: 'era',
18
+ 999: 'hyperliquid',
19
+ 1116: 'core',
20
+ 2818: 'morph',
21
+ 5000: 'mantle',
22
+ 8453: 'base',
23
+ 9745: 'plasma',
24
+ 34443: 'mode',
25
+ 42161: 'arbitrum',
26
+ 43114: 'avax',
27
+ 57073: 'ink',
28
+ 59144: 'linea',
29
+ 80094: 'berachain',
30
+ 81457: 'blast',
31
+ 534352: 'scroll',
32
+ [TRON_CHAIN_ID.mainnet]: 'tron',
33
+ };
34
+ /** 主币价格:按主币 symbol 对应 CoinGecko 的币种 id(DefiLlama 用 coingecko:<id> 查) */
35
+ const NATIVE_PRICE_IDS = {
36
+ ETH: 'ethereum',
37
+ BNB: 'binancecoin',
38
+ POL: 'polygon-ecosystem-token',
39
+ AVAX: 'avalanche-2',
40
+ MNT: 'mantle',
41
+ OKB: 'okb',
42
+ HYPE: 'hyperliquid',
43
+ BERA: 'berachain-bera',
44
+ CORE: 'coredaoorg',
45
+ MON: 'monad',
46
+ XPL: 'plasma',
47
+ TRX: 'tron',
48
+ };
49
+ /**
50
+ * DefiLlama 价格(免费、不需要 Key)。
51
+ * 注意:流动性很差的代币价格可能虚高,展示总资产时建议配合 minUsd 或自己的价格源。
52
+ *
53
+ * ```ts
54
+ * defillamaPrices() // 当前价格
55
+ * defillamaPrices({ at: new Date('2026-01-01') }) // 历史价格
56
+ * ```
57
+ */
58
+ export function defillamaPrices(options = {}) {
59
+ const minConfidence = options.minConfidence ?? 0.9;
60
+ const at = options.at instanceof Date ? Math.floor(options.at.getTime() / 1000) : options.at;
61
+ const endpoint = at === undefined ? 'https://coins.llama.fi/prices/current' : `https://coins.llama.fi/prices/historical/${Math.floor(at)}`;
62
+ return {
63
+ name: at === undefined ? 'defillama' : `defillama@${Math.floor(at)}`,
64
+ async prices({ chainId, tokens, nativeSymbol, fetch: fetchFn }) {
65
+ const result = new Map();
66
+ const slug = DEFILLAMA_CHAINS[chainId];
67
+ const nativeId = nativeSymbol ? NATIVE_PRICE_IDS[nativeSymbol.toUpperCase()] : undefined;
68
+ // 查询键 → 结果里用的去重键:EVM 地址小写;Tron 地址区分大小写,DefiLlama 要用原样的 base58(T…)地址
69
+ const resultKey = new Map();
70
+ const tokenKeys = slug
71
+ ? tokens.map((t) => {
72
+ const tron = slug === 'tron';
73
+ const query = `${slug}:${tron ? toTronAddress(t) : t.toLowerCase()}`;
74
+ resultKey.set(query.toLowerCase(), tron ? toTronAddress(t) : t.toLowerCase());
75
+ return query;
76
+ })
77
+ : [];
78
+ const keys = [...(nativeId ? [`coingecko:${nativeId}`] : []), ...tokenKeys];
79
+ const batches = [];
80
+ for (let i = 0; i < keys.length; i += 100) {
81
+ batches.push(keys.slice(i, i + 100));
82
+ }
83
+ const responses = await Promise.all(batches.map((batch) => fetchJson(fetchFn, `${endpoint}/${batch.join(',')}`)));
84
+ for (const res of responses) {
85
+ for (const [key, coin] of Object.entries(res.coins ?? {})) {
86
+ if (typeof coin.price !== 'number' || !Number.isFinite(coin.price) || (coin.confidence !== undefined && coin.confidence < minConfidence)) {
87
+ continue;
88
+ }
89
+ result.set(key.startsWith('coingecko:') ? 'native' : (resultKey.get(key.toLowerCase()) ?? key.slice(key.indexOf(':') + 1).toLowerCase()), coin.price);
90
+ }
91
+ }
92
+ return result;
93
+ },
94
+ };
95
+ }
96
+ // ---------------------------------------------------------------------------
97
+ // 组合
98
+ // ---------------------------------------------------------------------------
99
+ /**
100
+ * 依次使用多个价格源:前面的源没给出价格的代币(和主币)交给下一个源。某个源出错时跳过它(错误交给 onError)。
101
+ *
102
+ * ```ts
103
+ * combinePrices([defillamaPrices(), onchainPrices()])
104
+ * ```
105
+ */
106
+ export function combinePrices(sources, options = {}) {
107
+ return {
108
+ name: sources.map((s) => s.name).join('+'),
109
+ async prices(ctx) {
110
+ const found = await runSources(sources, ctx, options.onError);
111
+ return new Map([...found].map(([k, v]) => [k, v.price]));
112
+ },
113
+ };
114
+ }
115
+ /** 依次查询,记下每个价格来自哪个源 */
116
+ async function runSources(sources, ctx, onError) {
117
+ const result = new Map();
118
+ let tokens = [...ctx.tokens];
119
+ let nativeSymbol = ctx.nativeSymbol;
120
+ for (const source of sources) {
121
+ if (!tokens.length && !nativeSymbol)
122
+ break;
123
+ let found;
124
+ try {
125
+ found = await source.prices({ ...ctx, tokens, nativeSymbol });
126
+ }
127
+ catch (err) {
128
+ onError?.(source, err);
129
+ continue;
130
+ }
131
+ for (const [key, price] of found)
132
+ if (!result.has(key) && Number.isFinite(price) && price > 0)
133
+ result.set(key, { price, source: source.name });
134
+ tokens = tokens.filter((t) => !result.has(priceKeyOf(ctx.chainId, t)));
135
+ if (result.has('native'))
136
+ nativeSymbol = null;
137
+ }
138
+ return result;
139
+ }
140
+ /** 价格结果里的键:EVM 小写 0x 地址;Tron 是 T 开头的 base58 地址;主币为 'native' */
141
+ export function priceKeyOf(chainId, token) {
142
+ return isTronChain(chainId) ? toTronAddress(token) : token.toLowerCase();
143
+ }
144
+ // ---------------------------------------------------------------------------
145
+ // 链上价格
146
+ // ---------------------------------------------------------------------------
147
+ /** 按 1 美元计的稳定币(链上价格的计价锚点之一;另一个是包装主币) */
148
+ export const STABLECOINS = {
149
+ 1: ['0xdAC17F958D2ee523a2206206994597C13D831ec7', '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', '0x6B175474E89094C44Da98b954EedeAC495271d0F'],
150
+ 56: ['0x55d398326f99059fF775485246999027B3197955', '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d'],
151
+ 8453: ['0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'],
152
+ 42161: ['0xaf88d065e77c8cC2239327C5EDb3A432268e5831', '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9'],
153
+ 10: ['0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58'],
154
+ 137: ['0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', '0xc2132D05D31c914a87C6611C10748AEb04B58e8F'],
155
+ 43114: ['0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E'],
156
+ [TRON_CHAIN_ID.mainnet]: ['TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'],
157
+ };
158
+ const ERC20_ABI = ['function decimals() view returns (uint8)', 'function balanceOf(address owner) view returns (uint256)'];
159
+ const V2_FACTORY_ABI = ['function getPair(address tokenA, address tokenB) view returns (address)'];
160
+ const V2_PAIR_ABI = ['function token0() view returns (address)', 'function getReserves() view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast)'];
161
+ const V3_FACTORY_ABI = ['function getPool(address tokenA, address tokenB, uint24 fee) view returns (address)'];
162
+ const V3_POOL_ABI = ['function token0() view returns (address)', 'function slot0() view returns (uint160 sqrtPriceX96, int24 tick)', 'function liquidity() view returns (uint128)'];
163
+ const ZERO = '0x0000000000000000000000000000000000000000';
164
+ /**
165
+ * 链上价格:在 V2 / V3 池子里找代币对包装主币、稳定币的池子,用计价币一侧最深的池子的价格。
166
+ * 稳定币按 1 美元;包装主币(和主币)按它对稳定币最深的池子。读取全部用 multicall 合并。
167
+ * 适合 DefiLlama 没有收录的新币;价格是池子当前的价格,可能被单个区块内的交易影响,只用于展示
168
+ */
169
+ export function onchainPrices(options = {}) {
170
+ return {
171
+ name: 'onchain',
172
+ async prices({ chainId, tokens, nativeSymbol, provider }) {
173
+ if (!provider)
174
+ throw new Error('onchainPrices needs a Provider (ctx.provider)');
175
+ const key = (t) => priceKeyOf(chainId, t);
176
+ const wrapped = options.wrappedNative ?? LP_QUOTE_TOKENS[chainId]?.[0];
177
+ const stables = options.stablecoins ?? STABLECOINS[chainId] ?? [];
178
+ const protocols = (options.protocols ?? LP_PROTOCOLS.filter((p) => p.chainId === chainId)).filter((p) => (p.version === 'v2' || p.version === 'v3') && p.factory);
179
+ const minLiquidity = options.minLiquidityUsd ?? 10_000;
180
+ const result = new Map();
181
+ const stableKeys = new Set(stables.map(key));
182
+ for (const t of tokens)
183
+ if (stableKeys.has(key(t)))
184
+ result.set(key(t), 1);
185
+ if (!stables.length || !protocols.length)
186
+ return result;
187
+ // 包装主币先对稳定币定价,其他代币再对包装主币和稳定币定价(两轮都用一次 multicall 找池子 + 一次读池子)
188
+ const anchorsUsd = new Map(stables.map((s) => [key(s), 1]));
189
+ const needWrapped = wrapped && (nativeSymbol || tokens.some((t) => key(t) === key(wrapped)) || tokens.some((t) => !stableKeys.has(key(t))));
190
+ if (wrapped && needWrapped) {
191
+ const [quote] = await bestQuotes(provider, [wrapped], stables, anchorsUsd, protocols, options.fees, minLiquidity);
192
+ if (quote) {
193
+ anchorsUsd.set(key(wrapped), quote);
194
+ if (tokens.some((t) => key(t) === key(wrapped)))
195
+ result.set(key(wrapped), quote);
196
+ if (nativeSymbol)
197
+ result.set('native', quote);
198
+ }
199
+ }
200
+ const rest = [...new Set(tokens.map(key))].filter((k) => !result.has(k)).map((k) => tokens.find((t) => key(t) === k));
201
+ if (!rest.length)
202
+ return result;
203
+ const anchors = [...(wrapped && anchorsUsd.has(key(wrapped)) ? [wrapped] : []), ...stables];
204
+ const quotes = await bestQuotes(provider, rest, anchors, anchorsUsd, protocols, options.fees, minLiquidity);
205
+ rest.forEach((t, i) => {
206
+ const q = quotes[i];
207
+ if (q !== null && q !== undefined)
208
+ result.set(key(t), q);
209
+ });
210
+ return result;
211
+ },
212
+ };
213
+ }
214
+ /** 每个代币在 anchors 上最深的池子给出的美元价格(池子深度不够时为 null) */
215
+ async function bestQuotes(provider, tokens, anchors, anchorsUsd, protocols, fees = [100, 500, 2500, 3000, 10000], minLiquidityUsd, overrides) {
216
+ const chainId = await provider.getChainId();
217
+ const key = (t) => priceKeyOf(chainId, t);
218
+ // 1. 找池子:代币 × 计价币 × (V3 的每个手续费档位 + V2)
219
+ const lookups = [];
220
+ const calls = [];
221
+ tokens.forEach((token, i) => {
222
+ for (const anchor of anchors) {
223
+ if (key(anchor) === key(token))
224
+ continue;
225
+ for (const p of protocols) {
226
+ const factory = p.factory;
227
+ if (p.version === 'v2') {
228
+ lookups.push({ token: i, anchor, v3: false });
229
+ calls.push(provider.contract(factory, V2_FACTORY_ABI).getPair(token, anchor));
230
+ }
231
+ else {
232
+ for (const fee of fees) {
233
+ lookups.push({ token: i, anchor, v3: true });
234
+ calls.push(provider.contract(factory, V3_FACTORY_ABI).getPool(token, anchor, fee));
235
+ }
236
+ }
237
+ }
238
+ }
239
+ });
240
+ const addresses = await provider.tryAll(calls, overrides);
241
+ const pools = lookups.flatMap((l, i) => {
242
+ const address = addresses[i];
243
+ return address && address.toLowerCase() !== ZERO ? [{ ...l, address }] : [];
244
+ });
245
+ if (!pools.length)
246
+ return tokens.map(() => null);
247
+ // 2. 读池子(token0 和价格 / 储备、计价币在池子里的余额)和精度
248
+ const decimalsOf = [...new Set([...tokens, ...anchors].map(key))];
249
+ const original = new Map([...tokens, ...anchors].map((t) => [key(t), t]));
250
+ const state = await provider.tryAll([
251
+ ...decimalsOf.map((k) => provider.contract(original.get(k), ERC20_ABI).decimals()),
252
+ ...pools.flatMap((p) => p.v3
253
+ ? [
254
+ provider.contract(p.address, V3_POOL_ABI).token0(),
255
+ provider.contract(p.address, V3_POOL_ABI).slot0(),
256
+ provider.contract(p.anchor, ERC20_ABI).balanceOf(p.address),
257
+ provider.contract(p.address, V3_POOL_ABI).liquidity(),
258
+ ]
259
+ : [provider.contract(p.address, V2_PAIR_ABI).token0(), provider.contract(p.address, V2_PAIR_ABI).getReserves()]),
260
+ ], overrides);
261
+ const decimals = new Map(decimalsOf.map((k, i) => [k, state[i] === null || state[i] === undefined ? null : Number(state[i])]));
262
+ const best = tokens.map(() => null);
263
+ let offset = decimalsOf.length;
264
+ for (const p of pools) {
265
+ const size = p.v3 ? 4 : 2;
266
+ const [token0, second, third, liquidity] = state.slice(offset, offset + size);
267
+ offset += size;
268
+ const token = tokens[p.token];
269
+ const dt = decimals.get(key(token));
270
+ const da = decimals.get(key(p.anchor));
271
+ const anchorUsd = anchorsUsd.get(key(p.anchor));
272
+ if (!token0 || !second || dt === null || dt === undefined || da === null || da === undefined || anchorUsd === undefined)
273
+ continue;
274
+ const tokenIs0 = key(token0) === key(token);
275
+ const q = p.v3 ? v3Quote(second[0], third, liquidity ?? null, tokenIs0, dt, da) : v2Quote(second[0], second[1], tokenIs0, dt, da);
276
+ if (!q || !Number.isFinite(q.price) || q.price <= 0)
277
+ continue;
278
+ const depthUsd = q.depth * anchorUsd;
279
+ const current = best[p.token];
280
+ if (depthUsd >= minLiquidityUsd && (!current || depthUsd > current.depthUsd))
281
+ best[p.token] = { usd: q.price * anchorUsd, depthUsd };
282
+ }
283
+ return best.map((b) => (b ? b.usd : null));
284
+ }
285
+ /**
286
+ * V3 的深度:池子里计价币的余额和当前价格附近的流动性折算的计价币数量(虚拟储备:计价币是 token1 时 L·√P,是 token0 时 L / √P)取较小的。
287
+ * 只看余额的话,在远离当前价格的区间放一笔计价币、再把价格推过没有流动性的区间,就能用很少的成本让池子“看起来很深”
288
+ */
289
+ function v3Quote(sqrtPriceX96, anchorBalance, liquidity, tokenIs0, dt, da) {
290
+ if (sqrtPriceX96 === 0n || anchorBalance === null || liquidity === null)
291
+ return null;
292
+ // price = token1 / token0(按精度换算)
293
+ const price1Per0 = tokenIs0 ? sqrtPriceToPrice(sqrtPriceX96, dt, da) : sqrtPriceToPrice(sqrtPriceX96, da, dt);
294
+ const sqrtP = Number(sqrtPriceX96) / 2 ** 96;
295
+ const virtual = (tokenIs0 ? Number(liquidity) * sqrtP : Number(liquidity) / sqrtP) / 10 ** da;
296
+ return { price: tokenIs0 ? price1Per0 : 1 / price1Per0, depth: Math.min(Number(formatUnits(anchorBalance, da)), virtual) };
297
+ }
298
+ function v2Quote(reserve0, reserve1, tokenIs0, dt, da) {
299
+ const [rt, ra] = tokenIs0 ? [reserve0, reserve1] : [reserve1, reserve0];
300
+ if (rt === 0n || ra === 0n)
301
+ return null;
302
+ const anchor = Number(formatUnits(ra, da));
303
+ return { price: anchor / Number(formatUnits(rt, dt)), depth: anchor };
304
+ }
305
+ /**
306
+ * 查代币的美元价格(主币用 NATIVE_TOKEN 或零地址)。默认先查 DefiLlama,没有收录的再从链上池子算。
307
+ *
308
+ * ```ts
309
+ * await tokenPrices(provider, [NATIVE_TOKEN, USDT, newToken])
310
+ * // [{ token: '0xEeee…', native: true, price: 612.3, source: 'defillama' }, …, { token: newToken, price: 0.0012, source: 'onchain' }]
311
+ * await tokenPrices(provider, tokens, { sources: [defillamaPrices({ at: new Date('2026-01-01') })] }) // 历史价格
312
+ * ```
313
+ */
314
+ export async function tokenPrices(provider, tokens, options = {}) {
315
+ const { sources = [defillamaPrices(), onchainPrices()], onError, fetch: fetchOption } = options;
316
+ const chainId = await provider.getChainId();
317
+ const fetchFn = fetchOption ?? ((...args) => fetch(...args));
318
+ const native = tokens.map((t) => provider.isNativeToken(t));
319
+ const erc20 = [...new Set(tokens.filter((_, i) => !native[i]).map((t) => (isTronChain(chainId) ? toTronAddress(t) : t)))];
320
+ // 主币 symbol:内置链信息表,或 Provider 的 nativeSymbol 配置(不在表里的链)
321
+ const nativeIndex = native.indexOf(true);
322
+ const nativeSymbol = nativeIndex < 0 ? null : (getNativeCurrency(chainId)?.symbol ?? (await provider.tokens([tokens[nativeIndex]], { fields: ['symbol'] }))[0]?.symbol ?? null);
323
+ const found = await runSources(sources, { chainId, tokens: erc20, nativeSymbol, fetch: fetchFn, provider }, onError);
324
+ return tokens.map((token, i) => {
325
+ const hit = found.get(native[i] ? 'native' : priceKeyOf(chainId, token));
326
+ return { token, native: native[i], price: hit?.price ?? null, source: hit?.source ?? null };
327
+ });
328
+ }
329
+ //# sourceMappingURL=price.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"price.js","sourceRoot":"","sources":["../src/price.ts"],"names":[],"mappings":"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"}
package/dist/risk.d.ts ADDED
@@ -0,0 +1,42 @@
1
+ import { type LpProtocol } from './lp.js';
2
+ import type { Provider } from './provider.js';
3
+ export type ProbeStage = 'ok' | 'buy-failed' | 'transfer-failed' | 'approve-failed' | 'sell-failed';
4
+ export interface TokenRisk {
5
+ token: string;
6
+ /** 模拟用的 V2 协议和池子(代币 / 包装主币里包装主币一侧最深的);没有池子时为 null */
7
+ protocol: string | null;
8
+ pool: string | null;
9
+ /** 模拟到哪一步:ok 全部成功;buy-failed 买不进(可能还没开放交易、限制了合约地址);sell-failed 卖不出(貔貅盘) */
10
+ stage: ProbeStage | null;
11
+ /** 卖不出,或卖出税 ≥ 90% */
12
+ honeypot: boolean | null;
13
+ /** 税率(0~1):实际数量比 Router 报价少多少;对应的步骤没跑到时为 null */
14
+ buyTax: number | null;
15
+ sellTax: number | null;
16
+ transferTax: number | null;
17
+ /** 买入 / 卖出消耗的 gas(异常高可能有额外逻辑) */
18
+ buyGas: number | null;
19
+ sellGas: number | null;
20
+ /** EIP-1967 代理的实现合约(可升级:规则以后可以改);不是代理时为 null */
21
+ implementation: string | null;
22
+ /** owner():没有这个方法时为 null;零地址表示已放弃 */
23
+ owner: string | null;
24
+ /** 汇总的风险标记:honeypot、cannot-buy、high-buy-tax / high-sell-tax / high-transfer-tax(> 10%)、has-tax(> 0.5%)、proxy、owned、no-pool */
25
+ flags: string[];
26
+ }
27
+ export interface TokenRiskOptions {
28
+ /** 模拟买入用的主币数量(最小单位),默认包装主币储备的 1 / 1000,最多 1 个主币 */
29
+ amount?: bigint;
30
+ /** 用哪些 V2 协议的池子,默认这条链内置表里有 Router 的 V2 协议 */
31
+ protocols?: readonly LpProtocol[];
32
+ }
33
+ /**
34
+ * 检查代币的风险(每个代币一次模拟的 eth_call,加上一次 multicall 找池子、读 owner)。
35
+ *
36
+ * ```ts
37
+ * const [risk] = await tokenRisks(provider, [token])
38
+ * // { stage: 'ok', honeypot: false, buyTax: 0.05, sellTax: 0.05, transferTax: 0, flags: ['has-tax', 'owned'], … }
39
+ * ```
40
+ */
41
+ export declare function tokenRisks(provider: Provider, tokens: readonly string[], options?: TokenRiskOptions): Promise<TokenRisk[]>;
42
+ //# sourceMappingURL=risk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"risk.d.ts","sourceRoot":"","sources":["../src/risk.ts"],"names":[],"mappings":"AAOA,OAAO,EAAiC,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAK7C,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,YAAY,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,aAAa,CAAA;AAEnG,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,qDAAqD;IACrD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,2EAA2E;IAC3E,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IACxB,qBAAqB;IACrB,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAA;IACxB,iDAAiD;IACjD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,iCAAiC;IACjC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,gDAAgD;IAChD,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,qCAAqC;IACrC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,8HAA8H;IAC9H,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6CAA6C;IAC7C,SAAS,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;CAClC;AAaD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAgFpI"}