@w3lib/evm-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.
Files changed (110) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +161 -2
  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/lp.d.ts +2 -1
  23. package/dist/lp.d.ts.map +1 -1
  24. package/dist/lp.js +2 -1
  25. package/dist/lp.js.map +1 -1
  26. package/dist/multicall.d.ts.map +1 -1
  27. package/dist/multicall.js +3 -0
  28. package/dist/multicall.js.map +1 -1
  29. package/dist/names.d.ts +55 -0
  30. package/dist/names.d.ts.map +1 -0
  31. package/dist/names.js +93 -0
  32. package/dist/names.js.map +1 -0
  33. package/dist/owner.d.ts +4 -26
  34. package/dist/owner.d.ts.map +1 -1
  35. package/dist/owner.js +7 -112
  36. package/dist/owner.js.map +1 -1
  37. package/dist/portfolio.d.ts +54 -0
  38. package/dist/portfolio.d.ts.map +1 -0
  39. package/dist/portfolio.js +49 -0
  40. package/dist/portfolio.js.map +1 -0
  41. package/dist/price.d.ts +95 -0
  42. package/dist/price.d.ts.map +1 -0
  43. package/dist/price.js +329 -0
  44. package/dist/price.js.map +1 -0
  45. package/dist/risk.d.ts +42 -0
  46. package/dist/risk.d.ts.map +1 -0
  47. package/dist/risk.js +134 -0
  48. package/dist/risk.js.map +1 -0
  49. package/dist/rpcNodes.d.ts.map +1 -1
  50. package/dist/rpcNodes.js +18 -0
  51. package/dist/rpcNodes.js.map +1 -1
  52. package/dist/subpaths/approvals.d.ts +26 -0
  53. package/dist/subpaths/approvals.d.ts.map +1 -0
  54. package/dist/subpaths/approvals.js +27 -0
  55. package/dist/subpaths/approvals.js.map +1 -0
  56. package/dist/subpaths/fees.d.ts +23 -0
  57. package/dist/subpaths/fees.d.ts.map +1 -0
  58. package/dist/subpaths/fees.js +25 -0
  59. package/dist/subpaths/fees.js.map +1 -0
  60. package/dist/subpaths/names.d.ts +35 -0
  61. package/dist/subpaths/names.d.ts.map +1 -0
  62. package/dist/subpaths/names.js +39 -0
  63. package/dist/subpaths/names.js.map +1 -0
  64. package/dist/subpaths/price.d.ts +38 -0
  65. package/dist/subpaths/price.d.ts.map +1 -0
  66. package/dist/subpaths/price.js +40 -0
  67. package/dist/subpaths/price.js.map +1 -0
  68. package/dist/subpaths/risk.d.ts +19 -0
  69. package/dist/subpaths/risk.d.ts.map +1 -0
  70. package/dist/subpaths/risk.js +20 -0
  71. package/dist/subpaths/risk.js.map +1 -0
  72. package/dist/subpaths/swap.d.ts +19 -0
  73. package/dist/subpaths/swap.d.ts.map +1 -0
  74. package/dist/subpaths/swap.js +20 -0
  75. package/dist/subpaths/swap.js.map +1 -0
  76. package/dist/swap.d.ts +128 -0
  77. package/dist/swap.d.ts.map +1 -0
  78. package/dist/swap.js +291 -0
  79. package/dist/swap.js.map +1 -0
  80. package/dist/tokenProbe.d.ts +3 -0
  81. package/dist/tokenProbe.d.ts.map +1 -0
  82. package/dist/tokenProbe.js +4 -0
  83. package/dist/tokenProbe.js.map +1 -0
  84. package/dist/write/tron.d.ts +25 -0
  85. package/dist/write/tron.d.ts.map +1 -1
  86. package/dist/write/tron.js +26 -0
  87. package/dist/write/tron.js.map +1 -1
  88. package/package.json +39 -16
  89. package/src/aggregate.ts +110 -3
  90. package/src/approvals.ts +462 -0
  91. package/src/chains.ts +4 -0
  92. package/src/fees.ts +201 -0
  93. package/src/http.ts +34 -0
  94. package/src/lp.ts +3 -1
  95. package/src/multicall.ts +3 -0
  96. package/src/names.ts +141 -0
  97. package/src/owner.ts +7 -138
  98. package/src/portfolio.ts +91 -0
  99. package/src/price.ts +415 -0
  100. package/src/risk.ts +166 -0
  101. package/src/rpcNodes.ts +18 -0
  102. package/src/subpaths/approvals.ts +48 -0
  103. package/src/subpaths/fees.ts +43 -0
  104. package/src/subpaths/names.ts +43 -0
  105. package/src/subpaths/price.ts +60 -0
  106. package/src/subpaths/risk.ts +23 -0
  107. package/src/subpaths/swap.ts +36 -0
  108. package/src/swap.ts +413 -0
  109. package/src/tokenProbe.ts +5 -0
  110. package/src/write/tron.ts +43 -0
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"}
package/dist/risk.js ADDED
@@ -0,0 +1,134 @@
1
+ /**
2
+ * 代币风险检查(子路径 `@w3lib/evm-batch-call/risk`):在 eth_call 里模拟“买入 → 转账 → 卖出”(deployless 的探测合约,不部署、不发交易),
3
+ * 算出买入税、转账税、卖出税,判断能不能卖(貔貅盘);另外看合约是不是可升级的代理、owner 有没有放弃。
4
+ * 只能检查在内置 V2 协议里有 代币 / 包装主币 池子的代币;Tron 不支持
5
+ */
6
+ import { AbiCoder, Interface, concat } from 'ethers';
7
+ import { LP_PROTOCOLS, LP_QUOTE_TOKENS } from './lp.js';
8
+ import { TOKEN_PROBE_BYTECODE } from './tokenProbe.js';
9
+ import { isExecutionError } from './errors.js';
10
+ import { isTronChain } from './tron.js';
11
+ const coder = AbiCoder.defaultAbiCoder();
12
+ const factoryInterface = new Interface(['function getPair(address tokenA, address tokenB) view returns (address)']);
13
+ const pairInterface = new Interface(['function token0() view returns (address)', 'function getReserves() view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast)']);
14
+ const ownerInterface = new Interface(['function owner() view returns (address)']);
15
+ /** EIP-1967 的实现合约槽位:bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) */
16
+ const IMPLEMENTATION_SLOT = '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc';
17
+ const STAGES = ['ok', 'buy-failed', 'transfer-failed', 'approve-failed', 'sell-failed'];
18
+ const ZERO = '0x0000000000000000000000000000000000000000';
19
+ /**
20
+ * 检查代币的风险(每个代币一次模拟的 eth_call,加上一次 multicall 找池子、读 owner)。
21
+ *
22
+ * ```ts
23
+ * const [risk] = await tokenRisks(provider, [token])
24
+ * // { stage: 'ok', honeypot: false, buyTax: 0.05, sellTax: 0.05, transferTax: 0, flags: ['has-tax', 'owned'], … }
25
+ * ```
26
+ */
27
+ export async function tokenRisks(provider, tokens, options = {}) {
28
+ const chainId = await provider.getChainId();
29
+ if (isTronChain(chainId))
30
+ throw new Error('tokenRisks is not supported on Tron');
31
+ const wrapped = LP_QUOTE_TOKENS[chainId]?.[0];
32
+ const protocols = (options.protocols ?? LP_PROTOCOLS.filter((p) => p.chainId === chainId)).filter((p) => p.version === 'v2' && p.router && p.factory);
33
+ if (!wrapped || !protocols.length)
34
+ throw new Error(`No V2 protocol with a router on chain ${chainId}`);
35
+ // 1. 每个代币在每个 V2 协议里和包装主币的池子,以及 owner()
36
+ const pairCalls = tokens.flatMap((t) => protocols.map((p) => provider.contract(p.factory, factoryInterface).getPair(t, wrapped)));
37
+ const ownerCalls = tokens.map((t) => provider.contract(t, ownerInterface).owner());
38
+ const first = await provider.tryAll([...pairCalls, ...ownerCalls]);
39
+ const pairs = first.slice(0, pairCalls.length);
40
+ const owners = first.slice(pairCalls.length);
41
+ const found = pairs.flatMap((pair, i) => (pair && pair.toLowerCase() !== ZERO ? [{ i, pair }] : []));
42
+ const reserves = found.length
43
+ ? await provider.tryAll(found.flatMap(({ pair }) => [provider.contract(pair, pairInterface).token0(), provider.contract(pair, pairInterface).getReserves()]))
44
+ : [];
45
+ // 每个代币:包装主币一侧最深的池子
46
+ const best = tokens.map(() => null);
47
+ found.forEach(({ i, pair }, k) => {
48
+ const token0 = reserves[k * 2];
49
+ const r = reserves[k * 2 + 1];
50
+ if (!token0 || !r)
51
+ return;
52
+ const wrappedReserve = token0.toLowerCase() === wrapped.toLowerCase() ? r[0] : r[1];
53
+ const t = Math.floor(i / protocols.length);
54
+ const current = best[t];
55
+ if (wrappedReserve > 0n && (!current || wrappedReserve > current.wrappedReserve))
56
+ best[t] = { protocol: protocols[i % protocols.length], pair, wrappedReserve };
57
+ });
58
+ const { runOnNodes } = await import('./write/rpc.js');
59
+ const node = (method, fn, isFinal) => runOnNodes(provider.rpc, method, (n) => fn(n), isFinal);
60
+ const ONE = 10n ** 18n;
61
+ return Promise.all(tokens.map(async (token, t) => {
62
+ const pick = best[t];
63
+ const owner = owners[t] ?? null;
64
+ const implementation = await node('getStorage', (n) => (n.getStorage ? n.getStorage(token, IMPLEMENTATION_SLOT) : Promise.resolve('0x')))
65
+ .then((slot) => (slot && BigInt(slot) !== 0n ? `0x${slot.slice(-40)}` : null))
66
+ .catch(() => null);
67
+ const base = { token, implementation, owner, buyTax: null, sellTax: null, transferTax: null, buyGas: null, sellGas: null };
68
+ if (!pick)
69
+ return { ...base, protocol: null, pool: null, stage: null, honeypot: null, flags: flagsOf({ ...base, stage: null, honeypot: null }, true) };
70
+ const amount = options.amount ?? min(pick.wrappedReserve / 1000n, ONE);
71
+ // deployless:没有 to 的 eth_call 执行构造函数;从包装主币合约发起(它持有大量主币,eth_call 不需要签名)
72
+ const data = concat([TOKEN_PROBE_BYTECODE, coder.encode(['address', 'address', 'address'], [pick.protocol.router, token, pick.pair])]);
73
+ let decoded = null;
74
+ try {
75
+ // 探测合约自己不会 revert(每一步都 try);执行出错(如买入时代币合约把调用方拒之门外导致整体 revert)算买不进,
76
+ // 节点、网络、限频的错误照常抛出,不当成代币的风险
77
+ const out = await node('call', (n) => n.call({ from: wrapped, data, value: amount }), isExecutionError);
78
+ decoded = coder.decode(new Array(11).fill('uint256'), out).toArray();
79
+ }
80
+ catch (err) {
81
+ if (!isExecutionError(err))
82
+ throw err;
83
+ decoded = null;
84
+ }
85
+ if (!decoded) {
86
+ const failed = { ...base, protocol: pick.protocol.id, pool: pick.pair, stage: 'buy-failed', honeypot: null };
87
+ return { ...failed, flags: flagsOf(failed, false) };
88
+ }
89
+ const [stageIndex, buyQuote, bought, transferSent, transferReceived, sellAmount, sellQuote, sold, buyGas, sellGas, pairReceived] = decoded;
90
+ const stage = STAGES[Number(stageIndex)] ?? 'buy-failed';
91
+ const tax = (actual, expected) => (expected > 0n ? Math.max(0, 1 - Number((actual * 1000000n) / expected) / 1_000_000) : null);
92
+ const result = {
93
+ ...base,
94
+ protocol: pick.protocol.id,
95
+ pool: pick.pair,
96
+ stage,
97
+ buyTax: stage === 'buy-failed' ? null : tax(bought, buyQuote),
98
+ transferTax: stage === 'ok' || stage === 'approve-failed' || stage === 'sell-failed' ? tax(transferReceived, transferSent) : null,
99
+ // 卖出税:池子实际收到的代币(转账时扣的税,精确),和实际换回的主币比报价少多少(有的代币卖出时顺便把收来的税也卖进同一个池子,
100
+ // 池子那边看不出来),取较大的
101
+ sellTax: stage === 'ok' ? Math.max(tax(pairReceived, sellAmount) ?? 0, tax(sold, sellQuote) ?? 0) : null,
102
+ buyGas: stage === 'buy-failed' ? null : Number(buyGas),
103
+ sellGas: stage === 'ok' ? Number(sellGas) : null,
104
+ honeypot: stage === 'sell-failed' || stage === 'transfer-failed' || stage === 'approve-failed' ? true : stage === 'ok' ? (tax(sold, sellQuote) ?? 0) >= 0.9 : null,
105
+ };
106
+ return { ...result, flags: flagsOf(result, false) };
107
+ }));
108
+ }
109
+ const min = (a, b) => (a < b ? a : b);
110
+ function flagsOf(r, noPool) {
111
+ const flags = [];
112
+ if (noPool)
113
+ flags.push('no-pool');
114
+ if (r.honeypot)
115
+ flags.push('honeypot');
116
+ if (r.stage === 'buy-failed')
117
+ flags.push('cannot-buy');
118
+ for (const [name, value] of [
119
+ ['buy', r.buyTax],
120
+ ['sell', r.sellTax],
121
+ ['transfer', r.transferTax],
122
+ ]) {
123
+ if (value !== null && value > 0.1)
124
+ flags.push(`high-${name}-tax`);
125
+ }
126
+ if ([r.buyTax, r.sellTax, r.transferTax].some((v) => v !== null && v > 0.005))
127
+ flags.push('has-tax');
128
+ if (r.implementation)
129
+ flags.push('proxy');
130
+ if (r.owner && r.owner.toLowerCase() !== ZERO)
131
+ flags.push('owned');
132
+ return flags;
133
+ }
134
+ //# sourceMappingURL=risk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"risk.js","sourceRoot":"","sources":["../src/risk.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"rpcNodes.d.ts","sourceRoot":"","sources":["../src/rpcNodes.ts"],"names":[],"mappings":"AAGA,gCAAgC;AAChC,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAqLxE,CAAA;AAED,6CAA6C;AAC7C,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAK/C,CAAA"}
1
+ {"version":3,"file":"rpcNodes.d.ts","sourceRoot":"","sources":["../src/rpcNodes.ts"],"names":[],"mappings":"AAGA,gCAAgC;AAChC,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAuMxE,CAAA;AAED,6CAA6C;AAC7C,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAK/C,CAAA"}
package/dist/rpcNodes.js CHANGED
@@ -182,6 +182,24 @@ export const DEFAULT_RPC_URLS = {
182
182
  'https://rpc-qnd.inkonchain.com',
183
183
  'https://ink.api.pocket.network',
184
184
  ],
185
+ // 星空链(Starry)
186
+ 202308: [
187
+ 'https://rpc.starryscan.com',
188
+ ],
189
+ // conflux
190
+ 1030: [
191
+ 'https://evm.confluxrpc.com',
192
+ ],
193
+ // injective
194
+ 1776: [
195
+ 'https://sentry.evm-rpc.injective.network',
196
+ 'https://injectiveevm-rpc.polkachu.com',
197
+ ],
198
+ // pharos
199
+ 1672: [
200
+ 'https://rpc.pharos.xyz',
201
+ 'https://infra.originstake.com/pharos/evm',
202
+ ],
185
203
  };
186
204
  /** Tron 主网全节点 HTTP API(均支持跨域与 deployless) */
187
205
  export const DEFAULT_TRON_HOSTS = [
@@ -1 +1 @@
1
- {"version":3,"file":"rpcNodes.js","sourceRoot":"","sources":["../src/rpcNodes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rpcNodes.js","sourceRoot":"","sources":["../src/rpcNodes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * 授权管理(子路径 `@w3lib/evm-batch-call/approvals`):批量查地址给出的授权(ERC20、Permit2、NFT 的 setApprovalForAll),
3
+ * 按 Approval 事件发现授权过的代币,批量撤销。不放在主入口,不用时打包不会带上这部分代码;发送的代码按需加载。
4
+ *
5
+ * ```ts
6
+ * import { getApprovals, revokeApprovals } from '@w3lib/evm-batch-call/approvals'
7
+ *
8
+ * const list = await getApprovals(user, { chainId: 56, tokens: [USDT, CAKE] })
9
+ * await revokeApprovals(provider, key, list.filter((a) => a.type !== 'nft' && a.unlimited))
10
+ * ```
11
+ */
12
+ import { type Approval, type ApprovalsQuery } from '../approvals.js';
13
+ import { type ShortcutProviderOptions } from '../shortcuts.js';
14
+ export { PERMIT2_ADDRESS, approvals, buildRevokes, knownSpenders, revokeApprovals, scanApprovals, type Approval, type ApprovalScanOptions, type ApprovalScanProgress, type ApprovalScanResult, type ApprovalsQuery, type Erc20Approval, type KnownSpender, type NftApproval, type Permit2Approval, type RevokeResult, type RevokeTx, } from '../approvals.js';
15
+ export interface GetApprovalsOptions extends ApprovalsQuery, ShortcutProviderOptions {
16
+ }
17
+ /**
18
+ * 查地址给出的授权,节点参数与 getBalances 相同。默认检查已知的 Router / 聚合器 / NFT 市场。
19
+ *
20
+ * ```ts
21
+ * await getApprovals(user, { chainId: 56, tokens: [USDT, CAKE] })
22
+ * // [{ type: 'erc20', token: USDT, symbol: 'USDT', spender: '0x1111…', spenderName: '1inch Router v6', amount: '…', unlimited: true }, …]
23
+ * ```
24
+ */
25
+ export declare function getApprovals(owner: string, options: GetApprovalsOptions): Promise<Approval[]>;
26
+ //# sourceMappingURL=approvals.d.ts.map