@w3lib/evm-batch-call 0.1.0 → 0.3.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 (77) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +194 -12
  3. package/dist/aggregate.d.ts +5 -2
  4. package/dist/aggregate.d.ts.map +1 -1
  5. package/dist/aggregate.js.map +1 -1
  6. package/dist/call.d.ts +8 -2
  7. package/dist/call.d.ts.map +1 -1
  8. package/dist/call.js +25 -1
  9. package/dist/call.js.map +1 -1
  10. package/dist/chains.d.ts +13 -0
  11. package/dist/chains.d.ts.map +1 -0
  12. package/dist/chains.js +35 -0
  13. package/dist/chains.js.map +1 -0
  14. package/dist/detect.d.ts +23 -0
  15. package/dist/detect.d.ts.map +1 -0
  16. package/dist/detect.js +178 -0
  17. package/dist/detect.js.map +1 -0
  18. package/dist/erc20.d.ts +83 -7
  19. package/dist/erc20.d.ts.map +1 -1
  20. package/dist/erc20.js +36 -5
  21. package/dist/erc20.js.map +1 -1
  22. package/dist/fallback.d.ts +25 -0
  23. package/dist/fallback.d.ts.map +1 -1
  24. package/dist/fallback.js +123 -21
  25. package/dist/fallback.js.map +1 -1
  26. package/dist/index.d.ts +10 -3
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +9 -2
  29. package/dist/index.js.map +1 -1
  30. package/dist/nft.d.ts +71 -0
  31. package/dist/nft.d.ts.map +1 -0
  32. package/dist/nft.js +194 -0
  33. package/dist/nft.js.map +1 -0
  34. package/dist/owner.d.ts +136 -0
  35. package/dist/owner.d.ts.map +1 -0
  36. package/dist/owner.js +501 -0
  37. package/dist/owner.js.map +1 -0
  38. package/dist/provider.d.ts +112 -12
  39. package/dist/provider.d.ts.map +1 -1
  40. package/dist/provider.js +343 -48
  41. package/dist/provider.js.map +1 -1
  42. package/dist/scan.d.ts +59 -0
  43. package/dist/scan.d.ts.map +1 -0
  44. package/dist/scan.js +245 -0
  45. package/dist/scan.js.map +1 -0
  46. package/dist/shortcuts.d.ts +113 -0
  47. package/dist/shortcuts.d.ts.map +1 -0
  48. package/dist/shortcuts.js +193 -0
  49. package/dist/shortcuts.js.map +1 -0
  50. package/dist/source.d.ts +23 -1
  51. package/dist/source.d.ts.map +1 -1
  52. package/dist/source.js +110 -3
  53. package/dist/source.js.map +1 -1
  54. package/dist/tron.d.ts +6 -0
  55. package/dist/tron.d.ts.map +1 -1
  56. package/dist/tron.js +16 -1
  57. package/dist/tron.js.map +1 -1
  58. package/dist/util.d.ts +6 -0
  59. package/dist/util.d.ts.map +1 -0
  60. package/dist/util.js +20 -0
  61. package/dist/util.js.map +1 -0
  62. package/package.json +3 -2
  63. package/src/aggregate.ts +5 -2
  64. package/src/call.ts +32 -3
  65. package/src/chains.ts +46 -0
  66. package/src/detect.ts +193 -0
  67. package/src/erc20.ts +111 -9
  68. package/src/fallback.ts +127 -23
  69. package/src/index.ts +90 -4
  70. package/src/nft.ts +298 -0
  71. package/src/owner.ts +651 -0
  72. package/src/provider.ts +458 -54
  73. package/src/scan.ts +293 -0
  74. package/src/shortcuts.ts +278 -0
  75. package/src/source.ts +118 -3
  76. package/src/tron.ts +21 -2
  77. package/src/util.ts +20 -0
package/dist/detect.js ADDED
@@ -0,0 +1,178 @@
1
+ import { BrowserProvider, FetchRequest } from 'ethers';
2
+ import { TronProvider } from './tron.js';
3
+ import { withTimeout } from './util.js';
4
+ // 识别结果缓存,避免每次都请求。缓存的是 Promise:同时发起的识别共用一个请求;失败(含超时)时删除,下次重试。
5
+ // 只缓存“链不会悄悄变”或“变了能感知到”的来源:
6
+ // - URL:同一个地址的链不会变,按 URL 缓存
7
+ // - tronWeb:TronLink 切网络时换的是 fullNode.host,按 host 缓存
8
+ // - EIP-1193 钱包:有 on() 的监听 chainChanged,切链时清掉;没有 on() 的不缓存(无法感知切链)
9
+ // - ethers BrowserProvider:底下是钱包,可能切链,不缓存(getNetwork 只问本地钱包,开销很小)
10
+ // - 其他 ethers Provider / TronProvider 等对象:按对象缓存
11
+ const keyedCache = new Map();
12
+ let objectCache = new WeakMap();
13
+ const watched = new WeakSet();
14
+ function cacheSlot(source) {
15
+ if (typeof source === 'string') {
16
+ return { kind: 'key', key: `url:${source}` };
17
+ }
18
+ const value = source;
19
+ if (source instanceof BrowserProvider) {
20
+ return null;
21
+ }
22
+ if (typeof value.call === 'function') {
23
+ return { kind: 'object', key: source };
24
+ }
25
+ if (value.fullNode && typeof value.fullNode.request === 'function') {
26
+ return typeof value.fullNode.host === 'string' ? { kind: 'key', key: `tronweb:${value.fullNode.host}` } : null;
27
+ }
28
+ if (typeof value.request === 'function') {
29
+ return watchChainChanged(source) ? { kind: 'object', key: source } : null;
30
+ }
31
+ return null;
32
+ }
33
+ /**
34
+ * 按来源缓存地执行一次识别(与 detectChainId 共用缓存)。
35
+ * 链校验用它通过已配置好的节点连接识别(带 apiKey / 限流等),而不是重新创建连接。
36
+ */
37
+ export function detectChainIdCached(source, detect, timeout = 10_000) {
38
+ return cached(source, () => withTimeout(detect(), timeout));
39
+ }
40
+ function cached(source, detect) {
41
+ const slot = cacheSlot(source);
42
+ if (!slot) {
43
+ return detect();
44
+ }
45
+ const hit = slot.kind === 'key' ? keyedCache.get(slot.key) : objectCache.get(slot.key);
46
+ if (hit) {
47
+ return hit;
48
+ }
49
+ const promise = detect();
50
+ if (slot.kind === 'key') {
51
+ keyedCache.set(slot.key, promise);
52
+ }
53
+ else {
54
+ objectCache.set(slot.key, promise);
55
+ }
56
+ promise.catch(() => {
57
+ if (slot.kind === 'key') {
58
+ if (keyedCache.get(slot.key) === promise)
59
+ keyedCache.delete(slot.key);
60
+ }
61
+ else if (objectCache.get(slot.key) === promise) {
62
+ objectCache.delete(slot.key);
63
+ }
64
+ });
65
+ return promise;
66
+ }
67
+ /** EIP-1193 钱包切链时会触发 chainChanged,清掉该钱包的缓存。返回是否成功监听 */
68
+ function watchChainChanged(wallet) {
69
+ if (watched.has(wallet)) {
70
+ return true;
71
+ }
72
+ if (typeof wallet.on !== 'function') {
73
+ return false;
74
+ }
75
+ try {
76
+ const result = wallet.on('chainChanged', () => objectCache.delete(wallet));
77
+ result?.catch?.(() => { });
78
+ watched.add(wallet);
79
+ return true;
80
+ }
81
+ catch {
82
+ return false;
83
+ }
84
+ }
85
+ /** 清空 chainId 识别缓存 */
86
+ export function clearChainIdCache() {
87
+ keyedCache.clear();
88
+ objectCache = new WeakMap();
89
+ }
90
+ /**
91
+ * 从节点识别 chainId(不传 chainId 时使用),结果会缓存。数组按顺序探测,第一个成功的为准:
92
+ * - RPC URL:先按 EVM 节点发 eth_chainId,失败再按 Tron 全节点读创世区块
93
+ * - 浏览器插件钱包(EIP-1193):eth_chainId;tronWeb:Tron 创世区块
94
+ * - ethers Provider:getNetwork();TronProvider / FallbackRpc:getChainId()
95
+ *
96
+ * @param timeout 单个节点的超时(毫秒);URL 的 EVM / Tron 两次尝试各自计时
97
+ */
98
+ export async function detectChainId(source, timeout = 10_000) {
99
+ const list = Array.isArray(source) ? source : [source];
100
+ let lastError = new Error('Provider list is empty');
101
+ for (const item of list) {
102
+ try {
103
+ // 超时包在缓存里面:挂住的识别超时后会从缓存删除,不会让后续调用一直等
104
+ return await cached(item, () => (typeof item === 'string' ? detectUrl(item, timeout) : withTimeout(detectOne(item), timeout)));
105
+ }
106
+ catch (err) {
107
+ lastError = err;
108
+ }
109
+ }
110
+ throw lastError;
111
+ }
112
+ /** 能否从这个来源识别 chainId(不能的来源跳过链校验,见 source.ts) */
113
+ export function canDetectChainId(source) {
114
+ if (typeof source === 'string') {
115
+ return true;
116
+ }
117
+ const value = source;
118
+ if (typeof value.call === 'function') {
119
+ return typeof value.getChainId === 'function' || typeof value.getNetwork === 'function';
120
+ }
121
+ return typeof value.fullNode?.request === 'function' || typeof value.request === 'function';
122
+ }
123
+ /** 已创建的连接对象上识别 chainId */
124
+ export async function detectChainIdOf(node) {
125
+ const value = node;
126
+ if (typeof value.getChainId === 'function') {
127
+ return Number(await value.getChainId());
128
+ }
129
+ // ethers JsonRpcProvider / BrowserProvider:直接问节点。getNetwork 在 staticNetwork 或 'any' 网络下
130
+ // 返回的是配置 / 首次识别的值,节点(钱包)切链后不会变
131
+ if (typeof value.send === 'function') {
132
+ return Number(await value.send('eth_chainId', []));
133
+ }
134
+ if (typeof value.getNetwork === 'function') {
135
+ return Number((await value.getNetwork()).chainId);
136
+ }
137
+ throw new Error('Unable to detect chainId from this provider, please pass chainId explicitly');
138
+ }
139
+ async function detectOne(source) {
140
+ const value = source;
141
+ if (typeof value.call === 'function') {
142
+ return detectChainIdOf(source);
143
+ }
144
+ if (value.fullNode && typeof value.fullNode.request === 'function') {
145
+ return TronProvider.fromTronWeb(source).getChainId();
146
+ }
147
+ if (typeof value.request === 'function') {
148
+ return Number(await value.request({ method: 'eth_chainId' }));
149
+ }
150
+ throw new Error('Unsupported provider: expected an RPC URL, an ethers Provider, an EIP-1193 provider or a tronWeb instance');
151
+ }
152
+ async function detectUrl(url, timeout) {
153
+ try {
154
+ const request = new FetchRequest(url);
155
+ if (timeout > 0 && Number.isFinite(timeout)) {
156
+ request.timeout = timeout;
157
+ }
158
+ request.setHeader('content-type', 'application/json');
159
+ request.body = JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_chainId', params: [] });
160
+ const response = await request.send();
161
+ response.assertOk();
162
+ const json = response.bodyJson;
163
+ if (!json?.result) {
164
+ throw new Error(`eth_chainId failed: ${json?.error?.message ?? 'empty result'}`);
165
+ }
166
+ return Number(json.result);
167
+ }
168
+ catch (evmError) {
169
+ // 不是 EVM 节点:按 Tron 全节点 HTTP API 再试一次(单独计时)
170
+ try {
171
+ return await new TronProvider({ fullHost: url, retries: 0, timeout }).getChainId();
172
+ }
173
+ catch {
174
+ throw evmError;
175
+ }
176
+ }
177
+ }
178
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"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"}
package/dist/erc20.d.ts CHANGED
@@ -14,14 +14,90 @@ export interface Erc20Contract extends Contract {
14
14
  transfer: Method<[to: string, amount: bigint | string | number], boolean>;
15
15
  transferFrom: Method<[from: string, to: string, amount: bigint | string | number], boolean>;
16
16
  }
17
- export interface TokenInfo {
18
- address: string;
19
- /** 读取失败(如 symbol 是 bytes32 的老代币)时为 null */
20
- symbol: string | null;
21
- name: string | null;
17
+ /** allowances() / getAllowances() 的单项结果 */
18
+ export interface TokenAllowance {
19
+ token: string;
20
+ spender: string;
21
+ /** 主币不需要授权,视为无限额度 */
22
+ native: boolean;
23
+ /** 授权额度(最小单位的十进制字符串) */
24
+ allowance: string;
22
25
  decimals: number;
26
+ /** 按 decimals 换算后的额度 */
27
+ formatted: string;
28
+ /** 额度 ≥ uint96 最大值时为 true(覆盖 MaxUint256,以及 UNI / COMP 等把额度截断为 uint96 的代币) */
29
+ unlimited: boolean;
30
+ success: boolean;
31
+ }
32
+ /** unlimited 的判定阈值:uint96 最大值 */
33
+ export declare const UNLIMITED_ALLOWANCE_THRESHOLD: bigint;
34
+ declare const MAX_UINT256: bigint;
35
+ export { MAX_UINT256 };
36
+ /** tokens() / getTokens() 可选的字段 */
37
+ export type TokenField = 'name' | 'symbol' | 'decimals' | 'totalSupply';
38
+ /** 不指定 fields 时返回的字段 */
39
+ export declare const DEFAULT_TOKEN_FIELDS: readonly ["name", "symbol", "decimals"];
40
+ export type DefaultTokenField = (typeof DEFAULT_TOKEN_FIELDS)[number];
41
+ interface TokenFieldTypes {
42
+ name: string | null;
43
+ symbol: string | null;
44
+ decimals: number | null;
45
+ /** 最小单位的十进制字符串 */
46
+ totalSupply: string | null;
23
47
  }
24
- /** 常见的主币占位地址:多数聚合器用 0xeeee…eeee,部分协议用零地址 */
48
+ /**
49
+ * tokens() / getTokens() 的单项结果,只包含请求的字段(读取失败的字段为 null)。
50
+ * 请求 totalSupply 时额外带 totalSupplyFormatted(按 decimals 换算)。
51
+ */
52
+ export type TokenDetails<F extends TokenField = DefaultTokenField> = {
53
+ address: string;
54
+ /** 是否是主币占位地址(信息来自内置链信息表 / nativeSymbol 等配置) */
55
+ native: boolean;
56
+ /** 请求的字段都读到时为 true(主币没有 totalSupply,不计入) */
57
+ success: boolean;
58
+ } & {
59
+ [K in F]: TokenFieldTypes[K];
60
+ } & ('totalSupply' extends F ? {
61
+ totalSupplyFormatted: string | null;
62
+ } : unknown);
63
+ /** 主币占位地址(多数聚合器、钱包的约定),传给 balances() 时按主币处理 */
64
+ export declare const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
65
+ /** balances() 默认视为主币的地址:0xeeee…eeee 和零地址 */
25
66
  export declare const DEFAULT_NATIVE_TOKENS: readonly string[];
26
- export {};
67
+ /** balances() 的代币参数:地址,或带已知 decimals 的对象(跳过 decimals 查询) */
68
+ export type BalanceToken = string | {
69
+ address: string;
70
+ decimals?: number;
71
+ };
72
+ export interface TokenBalance {
73
+ /** 传入的代币地址(原样) */
74
+ token: string;
75
+ /** 是否按主币查询 */
76
+ native: boolean;
77
+ /** 原始余额(最小单位)的十进制字符串,如 "1234500000";需要计算时用 BigInt(balance) */
78
+ balance: string;
79
+ decimals: number;
80
+ /** 按 decimals 换算后的十进制字符串,如 "1234.5";整数不带小数点 */
81
+ formatted: string;
82
+ /** 仅在 symbol: true 时返回;读取失败或主币 symbol 未知时为 null */
83
+ symbol?: string | null;
84
+ /** 余额和 decimals 都查到时为 true;失败时 balance、formatted 都为 "0" */
85
+ success: boolean;
86
+ }
87
+ /**
88
+ * 按精度格式化:formatAmount(1234500000n, 6) === '1234.5',formatAmount(10n ** 18n, 18) === '1'。
89
+ * 不做四舍五入,保留全部有效小数位。
90
+ */
91
+ export declare function formatAmount(value: bigint, decimals: number): string;
92
+ interface TokenMeta {
93
+ decimals?: number;
94
+ symbol?: string;
95
+ name?: string;
96
+ /** NFT 集合标准(nftCollections 识别后缓存);null 表示确认不是 ERC721 / ERC1155 */
97
+ standard?: 'ERC721' | 'ERC1155' | null;
98
+ }
99
+ export declare function getCachedTokenMeta(chainId: number, token: string): TokenMeta;
100
+ export declare function setCachedTokenMeta(chainId: number, token: string, meta: TokenMeta): void;
101
+ /** 测试用:清空 decimals / symbol 缓存 */
102
+ export declare function resetDecimalsCache(): void;
27
103
  //# sourceMappingURL=erc20.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"erc20.d.ts","sourceRoot":"","sources":["../src/erc20.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE1D,eAAO,MAAM,SAAS,2hBAUZ,CAAA;AAEV,KAAK,MAAM,CAAC,IAAI,SAAS,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAA;AAEjH,+CAA+C;AAC/C,MAAM,WAAW,aAAc,SAAQ,QAAQ;IAC7C,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACxB,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAC1B,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAC/B,SAAS,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAA;IAC1C,SAAS,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAA;IAC3D,OAAO,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,EAAE,OAAO,CAAC,CAAA;IAC7E,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,EAAE,OAAO,CAAC,CAAA;IACzE,YAAY,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,EAAE,OAAO,CAAC,CAAA;CAC5F;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,2CAA2C;IAC3C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,4CAA4C;AAC5C,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAGlD,CAAA"}
1
+ {"version":3,"file":"erc20.d.ts","sourceRoot":"","sources":["../src/erc20.ts"],"names":[],"mappings":"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"}
package/dist/erc20.js CHANGED
@@ -9,9 +9,40 @@ export const ERC20_ABI = [
9
9
  'function transfer(address to, uint256 amount) returns (bool)',
10
10
  'function transferFrom(address from, address to, uint256 amount) returns (bool)',
11
11
  ];
12
- /** 常见的主币占位地址:多数聚合器用 0xeeee…eeee,部分协议用零地址 */
13
- export const DEFAULT_NATIVE_TOKENS = [
14
- '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
15
- '0x0000000000000000000000000000000000000000',
16
- ];
12
+ /** unlimited 的判定阈值:uint96 最大值 */
13
+ export const UNLIMITED_ALLOWANCE_THRESHOLD = 2n ** 96n - 1n;
14
+ const MAX_UINT256 = 2n ** 256n - 1n;
15
+ export { MAX_UINT256 };
16
+ /** 不指定 fields 时返回的字段 */
17
+ export const DEFAULT_TOKEN_FIELDS = ['name', 'symbol', 'decimals'];
18
+ /** 主币占位地址(多数聚合器、钱包的约定),传给 balances() 时按主币处理 */
19
+ export const NATIVE_TOKEN = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
20
+ /** balances() 默认视为主币的地址:0xeeee…eeee 和零地址 */
21
+ export const DEFAULT_NATIVE_TOKENS = [NATIVE_TOKEN, '0x0000000000000000000000000000000000000000'];
22
+ /**
23
+ * 按精度格式化:formatAmount(1234500000n, 6) === '1234.5',formatAmount(10n ** 18n, 18) === '1'。
24
+ * 不做四舍五入,保留全部有效小数位。
25
+ */
26
+ export function formatAmount(value, decimals) {
27
+ const negative = value < 0n;
28
+ const digits = (negative ? -value : value).toString().padStart(decimals + 1, '0');
29
+ const whole = digits.slice(0, digits.length - decimals);
30
+ const fraction = digits.slice(digits.length - decimals).replace(/0+$/, '');
31
+ return `${negative ? '-' : ''}${whole}${fraction ? `.${fraction}` : ''}`;
32
+ }
33
+ const tokenMetaCache = new Map();
34
+ export function getCachedTokenMeta(chainId, token) {
35
+ return tokenMetaCache.get(`${chainId}:${token.toLowerCase()}`) ?? {};
36
+ }
37
+ export function setCachedTokenMeta(chainId, token, meta) {
38
+ if (Object.keys(meta).length === 0) {
39
+ return; // 没有新数据(如查询失败)时不写入空条目
40
+ }
41
+ const key = `${chainId}:${token.toLowerCase()}`;
42
+ tokenMetaCache.set(key, { ...tokenMetaCache.get(key), ...meta });
43
+ }
44
+ /** 测试用:清空 decimals / symbol 缓存 */
45
+ export function resetDecimalsCache() {
46
+ tokenMetaCache.clear();
47
+ }
17
48
  //# sourceMappingURL=erc20.js.map
package/dist/erc20.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"erc20.js","sourceRoot":"","sources":["../src/erc20.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,uCAAuC;IACvC,yCAAyC;IACzC,0CAA0C;IAC1C,+CAA+C;IAC/C,0DAA0D;IAC1D,2EAA2E;IAC3E,kEAAkE;IAClE,8DAA8D;IAC9D,gFAAgF;CACxE,CAAA;AAyBV,4CAA4C;AAC5C,MAAM,CAAC,MAAM,qBAAqB,GAAsB;IACtD,4CAA4C;IAC5C,4CAA4C;CAC7C,CAAA"}
1
+ {"version":3,"file":"erc20.js","sourceRoot":"","sources":["../src/erc20.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,uCAAuC;IACvC,yCAAyC;IACzC,0CAA0C;IAC1C,+CAA+C;IAC/C,0DAA0D;IAC1D,2EAA2E;IAC3E,kEAAkE;IAClE,8DAA8D;IAC9D,gFAAgF;CACxE,CAAA;AAiCV,iCAAiC;AACjC,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,CAAA;AAE3D,MAAM,WAAW,GAAG,EAAE,IAAI,IAAI,GAAG,EAAE,CAAA;AAEnC,OAAO,EAAE,WAAW,EAAE,CAAA;AAKtB,wBAAwB;AACxB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,CAA0C,CAAA;AAwB3G,+CAA+C;AAC/C,MAAM,CAAC,MAAM,YAAY,GAAG,4CAA4C,CAAA;AAExE,4CAA4C;AAC5C,MAAM,CAAC,MAAM,qBAAqB,GAAsB,CAAC,YAAY,EAAE,4CAA4C,CAAC,CAAA;AAqBpH;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,QAAgB;IAC1D,MAAM,QAAQ,GAAG,KAAK,GAAG,EAAE,CAAA;IAC3B,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,QAAQ,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IACjF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAA;IACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAC1E,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;AAC1E,CAAC;AAWD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAqB,CAAA;AAEnD,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,KAAa;IAC/D,OAAO,cAAc,CAAC,GAAG,CAAC,GAAG,OAAO,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;AACtE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,KAAa,EAAE,IAAe;IAChF,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAM,CAAC,sBAAsB;IAC/B,CAAC;IACD,MAAM,GAAG,GAAG,GAAG,OAAO,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAA;IAC/C,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAA;AAClE,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,kBAAkB;IAChC,cAAc,CAAC,KAAK,EAAE,CAAA;AACxB,CAAC"}
@@ -19,5 +19,30 @@ export declare class FallbackRpc implements EthersLikeProvider {
19
19
  get nodes(): readonly EthersLikeProvider[];
20
20
  call(tx: TransactionRequest): Promise<string>;
21
21
  getBalance(address: Parameters<EthersLikeProvider['getBalance']>[0], blockTag?: Parameters<EthersLikeProvider['getBalance']>[1]): Promise<bigint>;
22
+ /** 按节点顺序探测 chainId(节点需实现 getChainId,见 detect.ts) */
23
+ getChainId(): Promise<number>;
24
+ /**
25
+ * 当前区块号。优先问上次 getLogs 成功的节点(增量扫描时区块号和日志来自同一个节点,不会因节点间的高度差漏扫);
26
+ * 不支持 getBlockNumber 的节点跳过,失败也不让节点进入冷却(不影响 call / getBalance)
27
+ */
28
+ getBlockNumber(): Promise<number>;
29
+ /**
30
+ * 依次尝试支持 getLogs 的节点。与其他请求不同:
31
+ * - getLogs 失败多半是“区块范围超限 / 节点不开放这个方法”,不代表节点故障,所以不影响 call / getBalance 的节点顺序;
32
+ * 超时 / 连不上的节点只在 getLogs 里排到后面(冷却期内),上次成功的节点排在最前
33
+ * - 在用的节点被限频时直接抛出(连续 3 次后才换节点),其他情况全部失败时抛出;GetLogsError 带上每个节点的错误
34
+ */
35
+ getLogs(filter: Parameters<NonNullable<EthersLikeProvider['getLogs']>>[0]): Promise<Awaited<ReturnType<NonNullable<EthersLikeProvider['getLogs']>>>>;
22
36
  }
37
+ /**
38
+ * getLogs 失败时抛出(所有节点都失败,或在用的节点被限频),errors 是各节点的错误;
39
+ * preferred 是上次成功的节点这次返回的错误(它最能说明问题:其他节点可能一直就不能用)
40
+ */
41
+ export declare class GetLogsError extends Error {
42
+ readonly errors: readonly unknown[];
43
+ readonly preferred?: unknown | undefined;
44
+ constructor(errors: readonly unknown[], preferred?: unknown | undefined);
45
+ }
46
+ /** 取出错误里节点返回的原始信息(ethers 会把它放在 error.message 里,外层是 “could not coalesce error”) */
47
+ export declare function errorText(err: unknown): string;
23
48
  //# sourceMappingURL=fallback.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fallback.d.ts","sourceRoot":"","sources":["../src/fallback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAGxD,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;GAMG;AACH,qBAAa,WAAY,YAAW,kBAAkB;;gBAMxC,KAAK,EAAE,kBAAkB,EAAE,EAAE,OAAO,GAAE,eAAoB;IAUtE,IAAI,KAAK,IAAI,SAAS,kBAAkB,EAAE,CAEzC;IAED,IAAI,CAAC,EAAE,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAI7C,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,UAAU,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;CA+BlJ"}
1
+ {"version":3,"file":"fallback.d.ts","sourceRoot":"","sources":["../src/fallback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAKxD,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;GAMG;AACH,qBAAa,WAAY,YAAW,kBAAkB;;gBAYxC,KAAK,EAAE,kBAAkB,EAAE,EAAE,OAAO,GAAE,eAAoB;IAWtE,IAAI,KAAK,IAAI,SAAS,kBAAkB,EAAE,CAEzC;IAED,IAAI,CAAC,EAAE,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAI7C,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,UAAU,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAIjJ,oDAAoD;IACpD,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAgBvC;;;;;OAKG;IACG,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;CAgF3J;AAED;;;GAGG;AACH,qBAAa,YAAa,SAAQ,KAAK;IAEnC,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO;gBADnB,MAAM,EAAE,SAAS,OAAO,EAAE,EAC1B,SAAS,CAAC,EAAE,OAAO,YAAA;CAK/B;AAED,kFAAkF;AAClF,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAI9C"}
package/dist/fallback.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { isError } from 'ethers';
2
+ import { detectChainIdOf } from './detect.js';
2
3
  import { isExecutionError } from './errors.js';
4
+ import { withTimeout } from './util.js';
3
5
  /**
4
6
  * 多节点故障切换:按顺序使用节点,出错或超时换下一个;出错的节点在 cooldown 内排到最后。
5
7
  *
@@ -12,6 +14,12 @@ export class FallbackRpc {
12
14
  #timeout;
13
15
  #cooldown;
14
16
  #failedAt;
17
+ /** 上次 getLogs 成功的节点 */
18
+ #logsNode = -1;
19
+ /** 上次成功的节点连续被限频的次数 */
20
+ #logsThrottled = 0;
21
+ /** getLogs 超时 / 连不上的时间,只影响 getLogs 的节点顺序 */
22
+ #logsFailedAt;
15
23
  constructor(nodes, options = {}) {
16
24
  if (!nodes.length) {
17
25
  throw new Error('FallbackRpc requires at least one node');
@@ -20,6 +28,7 @@ export class FallbackRpc {
20
28
  this.#timeout = options.timeout ?? 10_000;
21
29
  this.#cooldown = options.cooldown ?? 30_000;
22
30
  this.#failedAt = nodes.map(() => 0);
31
+ this.#logsFailedAt = nodes.map(() => 0);
23
32
  }
24
33
  get nodes() {
25
34
  return this.#nodes;
@@ -30,6 +39,80 @@ export class FallbackRpc {
30
39
  getBalance(address, blockTag) {
31
40
  return this.#run((node) => node.getBalance(address, blockTag));
32
41
  }
42
+ /** 按节点顺序探测 chainId(节点需实现 getChainId,见 detect.ts) */
43
+ getChainId() {
44
+ return this.#run((node) => detectChainIdOf(node));
45
+ }
46
+ /**
47
+ * 当前区块号。优先问上次 getLogs 成功的节点(增量扫描时区块号和日志来自同一个节点,不会因节点间的高度差漏扫);
48
+ * 不支持 getBlockNumber 的节点跳过,失败也不让节点进入冷却(不影响 call / getBalance)
49
+ */
50
+ async getBlockNumber() {
51
+ let lastError = new Error('No node supports getBlockNumber');
52
+ for (const index of this.#preferLogsNode(this.#order())) {
53
+ const node = this.#nodes[index];
54
+ if (!node.getBlockNumber) {
55
+ continue;
56
+ }
57
+ try {
58
+ return await withTimeout(node.getBlockNumber(), this.#timeout);
59
+ }
60
+ catch (err) {
61
+ lastError = err;
62
+ }
63
+ }
64
+ throw lastError;
65
+ }
66
+ /**
67
+ * 依次尝试支持 getLogs 的节点。与其他请求不同:
68
+ * - getLogs 失败多半是“区块范围超限 / 节点不开放这个方法”,不代表节点故障,所以不影响 call / getBalance 的节点顺序;
69
+ * 超时 / 连不上的节点只在 getLogs 里排到后面(冷却期内),上次成功的节点排在最前
70
+ * - 在用的节点被限频时直接抛出(连续 3 次后才换节点),其他情况全部失败时抛出;GetLogsError 带上每个节点的错误
71
+ */
72
+ async getLogs(filter) {
73
+ const errors = [];
74
+ let preferred;
75
+ const sticky = this.#logsNode;
76
+ for (const index of this.#preferLogsNode(this.#order(this.#logsFailedAt))) {
77
+ const node = this.#nodes[index];
78
+ if (!node.getLogs) {
79
+ continue;
80
+ }
81
+ try {
82
+ const logs = await withTimeout(node.getLogs(filter), this.#timeout);
83
+ this.#logsNode = index;
84
+ this.#logsFailedAt[index] = 0;
85
+ this.#logsThrottled = 0;
86
+ return logs;
87
+ }
88
+ catch (err) {
89
+ if (isError(err, 'INVALID_ARGUMENT')) {
90
+ throw err;
91
+ }
92
+ if (!isAlive(err)) {
93
+ // 超时 / 连不上:排到后面;如果是上次成功的节点,不再优先用它
94
+ this.#logsFailedAt[index] = Date.now();
95
+ if (index === this.#logsNode) {
96
+ this.#logsNode = -1;
97
+ }
98
+ }
99
+ else if (index === sticky) {
100
+ preferred = err;
101
+ if (isRateLimited(err)) {
102
+ // 在用的节点只是限频:直接抛出让调用方退避重试(其他节点多半本来就不能用,逐个试只会更慢);
103
+ // 连续 3 次就不再优先用它,试其他节点
104
+ if (++this.#logsThrottled < 3) {
105
+ throw new GetLogsError([err], err);
106
+ }
107
+ this.#logsThrottled = 0;
108
+ this.#logsNode = -1;
109
+ }
110
+ }
111
+ errors.push(err);
112
+ }
113
+ }
114
+ throw new GetLogsError(errors, preferred);
115
+ }
33
116
  async #run(fn) {
34
117
  let lastError;
35
118
  for (const index of this.#order()) {
@@ -49,14 +132,51 @@ export class FallbackRpc {
49
132
  throw lastError;
50
133
  }
51
134
  /** 健康的节点按原顺序在前,冷却中的按出错时间先后排在后面(全挂时也都会再试一次) */
52
- #order() {
135
+ #order(failedAt = this.#failedAt) {
53
136
  const now = Date.now();
54
137
  const healthy = [];
55
138
  const cooling = [];
56
- this.#failedAt.forEach((at, i) => (at && now - at < this.#cooldown ? cooling : healthy).push(i));
57
- cooling.sort((a, b) => this.#failedAt[a] - this.#failedAt[b]);
139
+ failedAt.forEach((at, i) => (at && now - at < this.#cooldown ? cooling : healthy).push(i));
140
+ cooling.sort((a, b) => failedAt[a] - failedAt[b]);
58
141
  return [...healthy, ...cooling];
59
142
  }
143
+ /** 上次 getLogs 成功的节点(不在 getLogs 冷却中时)排到最前 */
144
+ #preferLogsNode(order) {
145
+ const index = this.#logsNode;
146
+ const at = this.#logsFailedAt[index];
147
+ if (index < 0 || (at && Date.now() - at < this.#cooldown)) {
148
+ return order;
149
+ }
150
+ return [index, ...order.filter((i) => i !== index)];
151
+ }
152
+ }
153
+ /**
154
+ * getLogs 失败时抛出(所有节点都失败,或在用的节点被限频),errors 是各节点的错误;
155
+ * preferred 是上次成功的节点这次返回的错误(它最能说明问题:其他节点可能一直就不能用)
156
+ */
157
+ export class GetLogsError extends Error {
158
+ errors;
159
+ preferred;
160
+ constructor(errors, preferred) {
161
+ super(errors.length ? `getLogs failed: ${errors.map(errorText).join(' | ')}` : 'No node supports getLogs');
162
+ this.errors = errors;
163
+ this.preferred = preferred;
164
+ this.name = 'GetLogsError';
165
+ }
166
+ }
167
+ /** 取出错误里节点返回的原始信息(ethers 会把它放在 error.message 里,外层是 “could not coalesce error”) */
168
+ export function errorText(err) {
169
+ const e = err;
170
+ const parts = [e?.error?.message, e?.info?.error?.message, e?.shortMessage ?? e?.message].filter((p) => typeof p === 'string');
171
+ return parts.length ? parts.join('; ') : String(err);
172
+ }
173
+ /** 节点正常返回了 JSON-RPC 错误(ethers 把它放在 error / info.error 里)或只是限频,说明节点本身可用 */
174
+ function isAlive(err) {
175
+ const e = err;
176
+ return typeof (e?.error?.message ?? e?.info?.error?.message) === 'string' || isRateLimited(err);
177
+ }
178
+ function isRateLimited(err) {
179
+ return /too many requests|rate.?limit|\b429\b/i.test(errorText(err));
60
180
  }
61
181
  /** 换节点也不会变的错误:合约执行结果、参数错误、用户拒绝等 */
62
182
  function isDeterministic(err) {
@@ -65,22 +185,4 @@ function isDeterministic(err) {
65
185
  isError(err, 'ACTION_REJECTED') ||
66
186
  isError(err, 'NUMERIC_FAULT'));
67
187
  }
68
- class TimeoutError extends Error {
69
- constructor(ms) {
70
- super(`RPC request timed out after ${ms}ms`);
71
- this.name = 'TimeoutError';
72
- }
73
- }
74
- function withTimeout(promise, ms) {
75
- if (!Number.isFinite(ms) || ms <= 0) {
76
- return promise;
77
- }
78
- let timer;
79
- return Promise.race([
80
- promise,
81
- new Promise((_, reject) => {
82
- timer = setTimeout(() => reject(new TimeoutError(ms)), ms);
83
- }),
84
- ]).finally(() => clearTimeout(timer));
85
- }
86
188
  //# sourceMappingURL=fallback.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fallback.js","sourceRoot":"","sources":["../src/fallback.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fallback.js","sourceRoot":"","sources":["../src/fallback.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,17 @@
1
1
  export { Contract, bindCall, type BoundMethod, type ContractAbi, type ContractRunner } from './contract.js';
2
- export { DEFAULT_NATIVE_TOKENS, ERC20_ABI, type Erc20Contract, type TokenInfo } from './erc20.js';
3
- export { Provider, type ProviderConfig, type CallInput, type CallResults, type ProviderSource, type TryCallResults, type StaticCallItem, type StaticCallOverrides, type StaticCallResult, } from './provider.js';
2
+ export { getTransferScanState, keyValueScanStorage, memoryScanStorage, transferScan, type TransferScanOptions, type TransferScanState, type TransferScanStorage, } from './scan.js';
3
+ export { GetLogsError } from './fallback.js';
4
+ export { ALCHEMY_NETWORKS, COINGECKO_PLATFORMS, DEFILLAMA_CHAINS, alchemy, clearTokenListCache, coingeckoTokenList, combine, defaultTokenSource, defillamaPrices, firstAvailable, metamaskTokenList, nodereal, staticTokens, tokenList, type DiscoveredToken, type OwnedToken, type OwnerTokensOptions, type PriceSource, type PriceSourceContext, type TokenSource, type TokenSourceContext, } from './owner.js';
5
+ export { getAllowances, getBalances, getErc1155Balances, getNftBalances, getNftCollections, getNftOwners, getNftTokenUris, getOwnerTokens, getTokens, type GetBalancesOptions, type GetNftCollectionsOptions, type GetNftTokenUrisOptions, type GetOwnerTokensOptions, type GetTokensOptions, type ShortcutOptions, type ShortcutProviderOptions, } from './shortcuts.js';
6
+ export { DEFAULT_NFT_COLLECTION_FIELDS, ERC1155_ABI, ERC721_ABI, type DefaultNftCollectionField, type Erc1155Balance, type NftBalance, type NftCollection, type NftCollectionField, type NftCollectionsOptions, type NftItem, type NftOwner, type NftStandard, type NftTokenUri, type NftTokenUriOptions, } from './nft.js';
7
+ export { NATIVE_CURRENCIES, getNativeCurrency, type NativeCurrency } from './chains.js';
8
+ export { clearChainIdCache, detectChainId } from './detect.js';
9
+ export { DEFAULT_NATIVE_TOKENS, ERC20_ABI, NATIVE_TOKEN, formatAmount, type BalanceToken, type Erc20Contract, type TokenBalance, type TokenAllowance, MAX_UINT256, UNLIMITED_ALLOWANCE_THRESHOLD, DEFAULT_TOKEN_FIELDS, type DefaultTokenField, type TokenDetails, type TokenField, } from './erc20.js';
10
+ export { Provider, type BalancesOptions, type CallInput, type CallResults, type ProviderConfig, type ProviderSource, type StaticCallItem, type StaticCallOverrides, type StaticCallResult, type TokensOptions, type TryCallResults, } from './provider.js';
4
11
  export { TRON_CHAIN_ID, TronProvider, isTronAddress, toEvmAddress, toTronAddress, type TronProviderOptions, type TronRequest, type TronWebLike, } from './tron.js';
5
12
  export { CallFailedError, decodeRevertReason, isExecutionError } from './errors.js';
6
13
  export { FallbackRpc, type FallbackOptions } from './fallback.js';
7
- export { getDefaultRpcUrls, isTronChain, type SourceOptions } from './source.js';
14
+ export { ChainCheckedProvider, getDefaultRpcUrls, isTronChain, type SourceOptions } from './source.js';
8
15
  export { DEFAULT_RPC_URLS, DEFAULT_TRON_HOSTS } from './rpcNodes.js';
9
16
  export { MULTICALL3_ADDRESS, getMulticall3, type Multicall } from './multicall.js';
10
17
  export type { BlockTag, CallOverrides, EthersLikeProvider } from './aggregate.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AAC3G,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AACjG,OAAO,EACL,QAAQ,EACR,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,aAAa,EACb,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnF,OAAO,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AACjE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA;AAChF,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAClF,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACjF,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAChD,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}