@w3lib/evm-batch-call 0.3.0 → 0.4.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 (103) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +98 -35
  3. package/contracts/DeploylessMulticall3.sol +5 -0
  4. package/dist/aggregate.d.ts +20 -1
  5. package/dist/aggregate.d.ts.map +1 -1
  6. package/dist/aggregate.js +143 -5
  7. package/dist/aggregate.js.map +1 -1
  8. package/dist/batcher.d.ts +6 -1
  9. package/dist/batcher.d.ts.map +1 -1
  10. package/dist/batcher.js +59 -9
  11. package/dist/batcher.js.map +1 -1
  12. package/dist/call.d.ts +27 -2
  13. package/dist/call.d.ts.map +1 -1
  14. package/dist/call.js +22 -0
  15. package/dist/call.js.map +1 -1
  16. package/dist/chains.d.ts +7 -0
  17. package/dist/chains.d.ts.map +1 -1
  18. package/dist/chains.js +11 -0
  19. package/dist/chains.js.map +1 -1
  20. package/dist/deployless.d.ts +1 -1
  21. package/dist/deployless.d.ts.map +1 -1
  22. package/dist/deployless.js +1 -1
  23. package/dist/deployless.js.map +1 -1
  24. package/dist/erc20.d.ts +70 -4
  25. package/dist/erc20.d.ts.map +1 -1
  26. package/dist/erc20.js +121 -5
  27. package/dist/erc20.js.map +1 -1
  28. package/dist/events.d.ts +25 -0
  29. package/dist/events.d.ts.map +1 -0
  30. package/dist/events.js +25 -0
  31. package/dist/events.js.map +1 -0
  32. package/dist/fallback.d.ts +31 -3
  33. package/dist/fallback.d.ts.map +1 -1
  34. package/dist/fallback.js +165 -27
  35. package/dist/fallback.js.map +1 -1
  36. package/dist/index.d.ts +9 -10
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +6 -7
  39. package/dist/index.js.map +1 -1
  40. package/dist/multicall.d.ts.map +1 -1
  41. package/dist/multicall.js +33 -2
  42. package/dist/multicall.js.map +1 -1
  43. package/dist/nft.d.ts +5 -0
  44. package/dist/nft.d.ts.map +1 -1
  45. package/dist/nft.js +5 -0
  46. package/dist/nft.js.map +1 -1
  47. package/dist/owner.d.ts +9 -0
  48. package/dist/owner.d.ts.map +1 -1
  49. package/dist/owner.js +11 -2
  50. package/dist/owner.js.map +1 -1
  51. package/dist/provider.d.ts +55 -29
  52. package/dist/provider.d.ts.map +1 -1
  53. package/dist/provider.js +140 -111
  54. package/dist/provider.js.map +1 -1
  55. package/dist/shortcuts.d.ts +34 -53
  56. package/dist/shortcuts.d.ts.map +1 -1
  57. package/dist/shortcuts.js +41 -91
  58. package/dist/shortcuts.js.map +1 -1
  59. package/dist/source.d.ts +4 -2
  60. package/dist/source.d.ts.map +1 -1
  61. package/dist/source.js +35 -6
  62. package/dist/source.js.map +1 -1
  63. package/dist/subpaths/nft.d.ts +46 -0
  64. package/dist/subpaths/nft.d.ts.map +1 -0
  65. package/dist/subpaths/nft.js +55 -0
  66. package/dist/subpaths/nft.js.map +1 -0
  67. package/dist/subpaths/owner.d.ts +33 -0
  68. package/dist/subpaths/owner.d.ts.map +1 -0
  69. package/dist/subpaths/owner.js +34 -0
  70. package/dist/subpaths/owner.js.map +1 -0
  71. package/dist/tron.d.ts +2 -0
  72. package/dist/tron.d.ts.map +1 -1
  73. package/dist/tron.js +5 -0
  74. package/dist/tron.js.map +1 -1
  75. package/dist/util.d.ts +5 -0
  76. package/dist/util.d.ts.map +1 -1
  77. package/dist/util.js +23 -0
  78. package/dist/util.js.map +1 -1
  79. package/dist/watch.d.ts +25 -0
  80. package/dist/watch.d.ts.map +1 -0
  81. package/dist/watch.js +105 -0
  82. package/dist/watch.js.map +1 -0
  83. package/package.json +19 -10
  84. package/src/aggregate.ts +172 -7
  85. package/src/batcher.ts +69 -9
  86. package/src/call.ts +42 -2
  87. package/src/chains.ts +15 -0
  88. package/src/deployless.ts +1 -1
  89. package/src/erc20.ts +171 -8
  90. package/src/events.ts +42 -0
  91. package/src/fallback.ts +193 -26
  92. package/src/index.ts +19 -61
  93. package/src/multicall.ts +34 -2
  94. package/src/nft.ts +5 -0
  95. package/src/owner.ts +11 -2
  96. package/src/provider.ts +225 -124
  97. package/src/shortcuts.ts +76 -110
  98. package/src/source.ts +35 -8
  99. package/src/subpaths/nft.ts +107 -0
  100. package/src/subpaths/owner.ts +69 -0
  101. package/src/tron.ts +7 -0
  102. package/src/util.ts +27 -0
  103. package/src/watch.ts +149 -0
package/dist/erc20.js CHANGED
@@ -20,29 +20,145 @@ export const NATIVE_TOKEN = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
20
20
  /** balances() 默认视为主币的地址:0xeeee…eeee 和零地址 */
21
21
  export const DEFAULT_NATIVE_TOKENS = [NATIVE_TOKEN, '0x0000000000000000000000000000000000000000'];
22
22
  /**
23
- * 按精度格式化:formatAmount(1234500000n, 6) === '1234.5',formatAmount(10n ** 18n, 18) === '1'。
24
- * 不做四舍五入,保留全部有效小数位。
23
+ * 按精度格式化(与 ethers 的 formatUnits 同名同义):formatUnits(1234500000n, 6) === '1234.5',formatUnits(10n ** 18n, 18) === '1'。
24
+ * 不做四舍五入,保留全部有效小数位,整数不带小数点(与 ethers 不同:ethers 会返回 '1.0')。
25
25
  */
26
- export function formatAmount(value, decimals) {
26
+ export function formatUnits(value, decimals) {
27
27
  const negative = value < 0n;
28
28
  const digits = (negative ? -value : value).toString().padStart(decimals + 1, '0');
29
29
  const whole = digits.slice(0, digits.length - decimals);
30
30
  const fraction = digits.slice(digits.length - decimals).replace(/0+$/, '');
31
31
  return `${negative ? '-' : ''}${whole}${fraction ? `.${fraction}` : ''}`;
32
32
  }
33
+ /** @deprecated 改用 formatUnits(同一个函数;formatAmount 容易与项目里的数字展示函数撞名) */
34
+ export const formatAmount = formatUnits;
35
+ const NAME_TTL = 60 * 60 * 1000;
36
+ const MAX_CACHED_TOKENS = 50_000;
33
37
  const tokenMetaCache = new Map();
38
+ const cacheListeners = new Set();
34
39
  export function getCachedTokenMeta(chainId, token) {
35
- return tokenMetaCache.get(`${chainId}:${token.toLowerCase()}`) ?? {};
40
+ const cached = tokenMetaCache.get(`${chainId}:${token.toLowerCase()}`);
41
+ if (!cached) {
42
+ return {};
43
+ }
44
+ const { nameAt, symbolAt, ...meta } = cached;
45
+ const now = Date.now();
46
+ if (nameAt === undefined || now - nameAt > NAME_TTL) {
47
+ delete meta.name;
48
+ }
49
+ if (symbolAt === undefined || now - symbolAt > NAME_TTL) {
50
+ delete meta.symbol;
51
+ }
52
+ return meta;
36
53
  }
37
54
  export function setCachedTokenMeta(chainId, token, meta) {
38
55
  if (Object.keys(meta).length === 0) {
39
56
  return; // 没有新数据(如查询失败)时不写入空条目
40
57
  }
58
+ const defined = { ...meta };
59
+ if ('name' in meta) {
60
+ defined.nameAt = Date.now();
61
+ }
62
+ if ('symbol' in meta) {
63
+ defined.symbolAt = Date.now();
64
+ }
41
65
  const key = `${chainId}:${token.toLowerCase()}`;
42
- tokenMetaCache.set(key, { ...tokenMetaCache.get(key), ...meta });
66
+ const merged = { ...tokenMetaCache.get(key), ...defined };
67
+ tokenMetaCache.delete(key); // 重新插入,保持“最近写入在后”的顺序
68
+ tokenMetaCache.set(key, merged);
69
+ if (tokenMetaCache.size > MAX_CACHED_TOKENS) {
70
+ tokenMetaCache.delete(tokenMetaCache.keys().next().value);
71
+ }
72
+ cacheListeners.forEach((listener) => listener());
43
73
  }
44
74
  /** 测试用:清空 decimals / symbol 缓存 */
45
75
  export function resetDecimalsCache() {
46
76
  tokenMetaCache.clear();
47
77
  }
78
+ /**
79
+ * 导出代币信息缓存(decimals / symbol / name / NFT 标准),可存到任意地方,下次用 importTokenMetaCache 导入,
80
+ * 页面刷新后不必重查精度。name / symbol 带写入时间,导入后仍按 1 小时过期。
81
+ *
82
+ * @param maxEntries 最多导出多少条(最近写入的优先),默认全部
83
+ */
84
+ export function exportTokenMetaCache(maxEntries = Number.POSITIVE_INFINITY) {
85
+ const entries = [...tokenMetaCache];
86
+ return { version: 1, entries: entries.slice(Math.max(0, entries.length - maxEntries)) };
87
+ }
88
+ /** 导入 exportTokenMetaCache 的结果;格式不对的数据忽略。已有的条目以缓存里的为准(更新) */
89
+ export function importTokenMetaCache(snapshot) {
90
+ const entries = snapshot?.entries;
91
+ if (snapshot?.version !== 1 || !Array.isArray(entries)) {
92
+ return;
93
+ }
94
+ for (const entry of entries) {
95
+ if (!Array.isArray(entry) || typeof entry[0] !== 'string' || !/^\d+:\S+$/.test(entry[0]) || !entry[1] || typeof entry[1] !== 'object') {
96
+ continue;
97
+ }
98
+ const [rawKey, value] = entry;
99
+ // 与 getCachedTokenMeta 的 key 一致:地址部分小写
100
+ const separator = rawKey.indexOf(':');
101
+ const key = `${rawKey.slice(0, separator)}:${rawKey.slice(separator + 1).toLowerCase()}`;
102
+ const meta = {};
103
+ if (Number.isInteger(value.decimals) && value.decimals >= 0 && value.decimals <= 255)
104
+ meta.decimals = value.decimals;
105
+ if (typeof value.name === 'string' && typeof value.nameAt === 'number') {
106
+ meta.name = value.name;
107
+ meta.nameAt = value.nameAt;
108
+ }
109
+ if (typeof value.symbol === 'string' && typeof value.symbolAt === 'number') {
110
+ meta.symbol = value.symbol;
111
+ meta.symbolAt = value.symbolAt;
112
+ }
113
+ if (value.standard === 'ERC721' || value.standard === 'ERC1155' || value.standard === null)
114
+ meta.standard = value.standard;
115
+ if (Object.keys(meta).length && !tokenMetaCache.has(key)) {
116
+ tokenMetaCache.set(key, meta);
117
+ }
118
+ }
119
+ while (tokenMetaCache.size > MAX_CACHED_TOKENS) {
120
+ tokenMetaCache.delete(tokenMetaCache.keys().next().value);
121
+ }
122
+ }
123
+ /**
124
+ * 把代币信息缓存持久化到同步的键值存储(如 localStorage):调用时先读入,之后缓存有更新就防抖(1 秒)整体写回。
125
+ * 返回停止持久化的函数。存储读写出错(如超出配额)时忽略。
126
+ *
127
+ * ```ts
128
+ * persistTokenMetaCache(localStorage) // 刷新页面后不必重查 decimals
129
+ * ```
130
+ */
131
+ export function persistTokenMetaCache(store, options = {}) {
132
+ const { key = 'w3lib:evm-token-meta', maxEntries = 5000 } = options;
133
+ try {
134
+ const raw = store.getItem(key);
135
+ if (raw) {
136
+ importTokenMetaCache(JSON.parse(raw));
137
+ }
138
+ }
139
+ catch {
140
+ // 数据损坏:忽略,之后会被覆盖
141
+ }
142
+ let timer;
143
+ const save = () => {
144
+ timer = undefined;
145
+ try {
146
+ store.setItem(key, JSON.stringify(exportTokenMetaCache(maxEntries)));
147
+ }
148
+ catch {
149
+ // 超出配额等:忽略
150
+ }
151
+ };
152
+ const listener = () => {
153
+ timer ??= setTimeout(save, 1000);
154
+ };
155
+ cacheListeners.add(listener);
156
+ return () => {
157
+ cacheListeners.delete(listener);
158
+ if (timer !== undefined) {
159
+ clearTimeout(timer);
160
+ save();
161
+ }
162
+ };
163
+ }
48
164
  //# 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;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"}
1
+ {"version":3,"file":"erc20.js","sourceRoot":"","sources":["../src/erc20.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /** 一次对某个节点的请求(onRequest 的事件) */
2
+ export interface RequestEvent {
3
+ /** 节点标识:URL 节点只取 host(不含 path / query,避免泄露 API Key);钱包为 'wallet',tronWeb 为 'tronWeb',其他对象为 'provider' */
4
+ node: string;
5
+ /** 'call' | 'getBalance' | 'getChainId' | 'getBlockNumber' | 'getLogs' */
6
+ method: string;
7
+ /** 耗时(毫秒) */
8
+ ms: number;
9
+ ok: boolean;
10
+ /** 失败时的错误 */
11
+ error?: unknown;
12
+ /** 本次请求按故障切换顺序的第几个节点(0 起);大于 0 表示换过节点 */
13
+ attempt: number;
14
+ }
15
+ export type RequestListener = (event: RequestEvent) => void;
16
+ /**
17
+ * 订阅所有节点请求(全局,对所有 Provider 生效),用于观察哪个节点返回、换过几次节点、每次耗时。返回取消订阅的函数。
18
+ *
19
+ * ```ts
20
+ * const off = onRequest((e) => console.log(e.node, e.method, e.ms, e.ok, e.attempt))
21
+ * ```
22
+ */
23
+ export declare function onRequest(listener: RequestListener): () => void;
24
+ export declare function emitRequest(event: RequestEvent): void;
25
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,MAAM,WAAW,YAAY;IAC3B,yGAAyG;IACzG,IAAI,EAAE,MAAM,CAAA;IACZ,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAA;IACd,aAAa;IACb,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,OAAO,CAAA;IACX,aAAa;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;AAI3D;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI,CAK/D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAQrD"}
package/dist/events.js ADDED
@@ -0,0 +1,25 @@
1
+ const listeners = new Set();
2
+ /**
3
+ * 订阅所有节点请求(全局,对所有 Provider 生效),用于观察哪个节点返回、换过几次节点、每次耗时。返回取消订阅的函数。
4
+ *
5
+ * ```ts
6
+ * const off = onRequest((e) => console.log(e.node, e.method, e.ms, e.ok, e.attempt))
7
+ * ```
8
+ */
9
+ export function onRequest(listener) {
10
+ listeners.add(listener);
11
+ return () => {
12
+ listeners.delete(listener);
13
+ };
14
+ }
15
+ export function emitRequest(event) {
16
+ for (const listener of listeners) {
17
+ try {
18
+ listener(event);
19
+ }
20
+ catch {
21
+ // 监听函数出错不影响请求
22
+ }
23
+ }
24
+ }
25
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAiBA,MAAM,SAAS,GAAG,IAAI,GAAG,EAAmB,CAAA;AAE5C;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,QAAyB;IACjD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACvB,OAAO,GAAG,EAAE;QACV,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC5B,CAAC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAmB;IAC7C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,QAAQ,CAAC,KAAK,CAAC,CAAA;QACjB,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -3,11 +3,39 @@ import type { EthersLikeProvider } from './aggregate.js';
3
3
  export interface FallbackOptions {
4
4
  /** 单个节点单次请求超时(毫秒),超时视为该节点故障并换下一个。默认 10000;<= 0 表示不限制 */
5
5
  timeout?: number;
6
- /** 节点出错后跳过它的时长(毫秒),期间优先用其他节点。默认 30000 */
6
+ /**
7
+ * 节点迟迟不返回时,过多久(毫秒)同时请求下一个节点:原来的请求不取消,谁先成功用谁(与 ethers FallbackProvider 的 stallTimeout 相同)。
8
+ * 适合正常但偶尔较慢的节点:不必把 timeout 设得很短(正常的慢请求会被判成超时)。
9
+ * 默认 0(不提前请求,只在出错 / 超时后换节点);只影响 call / getBalance,不影响 getLogs / getBlockNumber
10
+ */
11
+ stallTimeout?: number;
12
+ /** 节点出错后跳过它的时长(毫秒),期间优先用其他节点。默认 30000。超时不算出错,同一节点连续 3 次超时才冷却 */
7
13
  cooldown?: number;
8
14
  }
15
+ /** FallbackRpc 每个节点的标识(resolveSource 传入;直接 new FallbackRpc 时可省略) */
16
+ export interface FallbackNodeInfo {
17
+ /** 用于错误信息和 onRequest 事件的节点标识 */
18
+ label: string;
19
+ /** 健康状态的 key:URL 字符串或节点对象。相同 key 的节点在所有 FallbackRpc 之间共享冷却状态 */
20
+ key: string | object;
21
+ }
22
+ /** 测试用:清空全局的节点健康状态 */
23
+ export declare function resetNodeHealth(): void;
24
+ /** 所有节点都失败(多节点时):errors 是每个节点的标识和失败原因,按尝试顺序 */
25
+ export declare class AllNodesFailedError extends Error {
26
+ readonly errors: ReadonlyArray<{
27
+ node: string;
28
+ error: unknown;
29
+ }>;
30
+ constructor(errors: ReadonlyArray<{
31
+ node: string;
32
+ error: unknown;
33
+ }>);
34
+ }
9
35
  /**
10
- * 多节点故障切换:按顺序使用节点,出错或超时换下一个;出错的节点在 cooldown 内排到最后。
36
+ * 多节点故障切换:按顺序使用节点,出错或超时换下一个;出错的节点在 cooldown 内排到最后(超时只换节点,连续 3 次才冷却)。
37
+ * 设置了 stallTimeout 时,节点迟迟不返回就同时请求下一个,谁先成功用谁。所有节点都失败时抛 AllNodesFailedError(单节点时抛原始错误)。
38
+ * 冷却状态按节点全局共享,每次请求都会触发 onRequest 事件。
11
39
  *
12
40
  * 与 ethers FallbackProvider 相比:
13
41
  * - 没有首次请求前对所有节点的 getBlockNumber 同步,一个卡住的节点不会拖住第一次查询
@@ -15,7 +43,7 @@ export interface FallbackOptions {
15
43
  */
16
44
  export declare class FallbackRpc implements EthersLikeProvider {
17
45
  #private;
18
- constructor(nodes: EthersLikeProvider[], options?: FallbackOptions);
46
+ constructor(nodes: EthersLikeProvider[], options?: FallbackOptions, info?: readonly FallbackNodeInfo[]);
19
47
  get nodes(): readonly EthersLikeProvider[];
20
48
  call(tx: TransactionRequest): Promise<string>;
21
49
  getBalance(address: Parameters<EthersLikeProvider['getBalance']>[0], blockTag?: Parameters<EthersLikeProvider['getBalance']>[1]): Promise<bigint>;
@@ -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;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"}
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;AAMxD,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,gEAAgE;IAChE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CACrB;AAmCD,sBAAsB;AACtB,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED,+CAA+C;AAC/C,qBAAa,mBAAoB,SAAQ,KAAK;IAChC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;gBAAvD,MAAM,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;CAI7E;AAED;;;;;;;;GAQG;AACH,qBAAa,WAAY,YAAW,kBAAkB;;gBAexC,KAAK,EAAE,kBAAkB,EAAE,EAAE,OAAO,GAAE,eAAoB,EAAE,IAAI,CAAC,EAAE,SAAS,gBAAgB,EAAE;IAa1G,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;IAsB7B;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAwBvC;;;;;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;CAkJ3J;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,9 +1,49 @@
1
1
  import { isError } from 'ethers';
2
2
  import { detectChainIdOf } from './detect.js';
3
3
  import { isExecutionError } from './errors.js';
4
- import { withTimeout } from './util.js';
4
+ import { emitRequest } from './events.js';
5
+ import { TimeoutError, withTimeout } from './util.js';
6
+ /** 连续超时多少次后才冷却(偶尔慢不算坏节点) */
7
+ const TIMEOUTS_BEFORE_COOLDOWN = 3;
8
+ const MAX_TRACKED_URLS = 1000;
9
+ const healthByUrl = new Map();
10
+ const healthByObject = new WeakMap();
11
+ function healthOf(key) {
12
+ if (typeof key === 'string') {
13
+ let health = healthByUrl.get(key);
14
+ if (!health) {
15
+ health = { failedAt: 0, timeouts: 0 };
16
+ healthByUrl.set(key, health);
17
+ if (healthByUrl.size > MAX_TRACKED_URLS) {
18
+ healthByUrl.delete(healthByUrl.keys().next().value);
19
+ }
20
+ }
21
+ return health;
22
+ }
23
+ let health = healthByObject.get(key);
24
+ if (!health) {
25
+ health = { failedAt: 0, timeouts: 0 };
26
+ healthByObject.set(key, health);
27
+ }
28
+ return health;
29
+ }
30
+ /** 测试用:清空全局的节点健康状态 */
31
+ export function resetNodeHealth() {
32
+ healthByUrl.clear();
33
+ }
34
+ /** 所有节点都失败(多节点时):errors 是每个节点的标识和失败原因,按尝试顺序 */
35
+ export class AllNodesFailedError extends Error {
36
+ errors;
37
+ constructor(errors) {
38
+ super(`All RPC nodes failed: ${errors.map((e) => `${e.node}: ${errorText(e.error)}`).join(' | ')}`, { cause: errors[errors.length - 1]?.error });
39
+ this.errors = errors;
40
+ this.name = 'AllNodesFailedError';
41
+ }
42
+ }
5
43
  /**
6
- * 多节点故障切换:按顺序使用节点,出错或超时换下一个;出错的节点在 cooldown 内排到最后。
44
+ * 多节点故障切换:按顺序使用节点,出错或超时换下一个;出错的节点在 cooldown 内排到最后(超时只换节点,连续 3 次才冷却)。
45
+ * 设置了 stallTimeout 时,节点迟迟不返回就同时请求下一个,谁先成功用谁。所有节点都失败时抛 AllNodesFailedError(单节点时抛原始错误)。
46
+ * 冷却状态按节点全局共享,每次请求都会触发 onRequest 事件。
7
47
  *
8
48
  * 与 ethers FallbackProvider 相比:
9
49
  * - 没有首次请求前对所有节点的 getBlockNumber 同步,一个卡住的节点不会拖住第一次查询
@@ -12,50 +52,80 @@ import { withTimeout } from './util.js';
12
52
  export class FallbackRpc {
13
53
  #nodes;
14
54
  #timeout;
55
+ #stallTimeout;
15
56
  #cooldown;
16
- #failedAt;
57
+ #labels;
58
+ /** 健康状态的 key;每次用时再从全局表里取(表淘汰条目后,各实例仍取到同一个对象) */
59
+ #healthKeys;
17
60
  /** 上次 getLogs 成功的节点 */
18
61
  #logsNode = -1;
19
62
  /** 上次成功的节点连续被限频的次数 */
20
63
  #logsThrottled = 0;
21
64
  /** getLogs 超时 / 连不上的时间,只影响 getLogs 的节点顺序 */
22
65
  #logsFailedAt;
23
- constructor(nodes, options = {}) {
66
+ constructor(nodes, options = {}, info) {
24
67
  if (!nodes.length) {
25
68
  throw new Error('FallbackRpc requires at least one node');
26
69
  }
27
70
  this.#nodes = nodes;
28
71
  this.#timeout = options.timeout ?? 10_000;
72
+ this.#stallTimeout = options.stallTimeout ?? 0;
29
73
  this.#cooldown = options.cooldown ?? 30_000;
30
- this.#failedAt = nodes.map(() => 0);
74
+ this.#labels = nodes.map((_, i) => info?.[i]?.label ?? `node${i}`);
75
+ this.#healthKeys = nodes.map((node, i) => info?.[i]?.key ?? node);
31
76
  this.#logsFailedAt = nodes.map(() => 0);
32
77
  }
33
78
  get nodes() {
34
79
  return this.#nodes;
35
80
  }
36
81
  call(tx) {
37
- return this.#run((node) => node.call(tx));
82
+ return this.#run('call', (node) => node.call(tx));
38
83
  }
39
84
  getBalance(address, blockTag) {
40
- return this.#run((node) => node.getBalance(address, blockTag));
85
+ return this.#run('getBalance', (node) => node.getBalance(address, blockTag));
41
86
  }
42
87
  /** 按节点顺序探测 chainId(节点需实现 getChainId,见 detect.ts) */
43
88
  getChainId() {
44
- return this.#run((node) => detectChainIdOf(node));
89
+ return this.#run('getChainId', (node) => detectChainIdOf(node));
90
+ }
91
+ /** 对第 index 个节点发一次请求(带超时),并触发 onRequest 事件 */
92
+ async #attempt(method, index, attempt, fn, timeout = this.#timeout) {
93
+ const started = Date.now();
94
+ try {
95
+ const result = await withTimeout(Promise.resolve().then(() => fn(this.#nodes[index])), timeout);
96
+ emitRequest({ node: this.#labels[index], method, ms: Date.now() - started, ok: true, attempt });
97
+ return result;
98
+ }
99
+ catch (err) {
100
+ emitRequest({ node: this.#labels[index], method, ms: Date.now() - started, ok: false, error: err, attempt });
101
+ throw err;
102
+ }
103
+ }
104
+ /** 单节点:直接请求(getLogs / getBlockNumber 不走多节点的特殊逻辑),抛原始错误 */
105
+ #single(method, fn) {
106
+ return this.#attempt(method, 0, 0, fn);
45
107
  }
46
108
  /**
47
109
  * 当前区块号。优先问上次 getLogs 成功的节点(增量扫描时区块号和日志来自同一个节点,不会因节点间的高度差漏扫);
48
110
  * 不支持 getBlockNumber 的节点跳过,失败也不让节点进入冷却(不影响 call / getBalance)
49
111
  */
50
112
  async getBlockNumber() {
113
+ if (this.#nodes.length === 1) {
114
+ const node = this.#nodes[0];
115
+ if (!node.getBlockNumber) {
116
+ throw new Error('getBlockNumber is not supported by this provider');
117
+ }
118
+ return this.#single('getBlockNumber', (n) => n.getBlockNumber());
119
+ }
51
120
  let lastError = new Error('No node supports getBlockNumber');
121
+ let attempt = 0;
52
122
  for (const index of this.#preferLogsNode(this.#order())) {
53
123
  const node = this.#nodes[index];
54
124
  if (!node.getBlockNumber) {
55
125
  continue;
56
126
  }
57
127
  try {
58
- return await withTimeout(node.getBlockNumber(), this.#timeout);
128
+ return await this.#attempt('getBlockNumber', index, attempt++, (n) => n.getBlockNumber());
59
129
  }
60
130
  catch (err) {
61
131
  lastError = err;
@@ -70,16 +140,24 @@ export class FallbackRpc {
70
140
  * - 在用的节点被限频时直接抛出(连续 3 次后才换节点),其他情况全部失败时抛出;GetLogsError 带上每个节点的错误
71
141
  */
72
142
  async getLogs(filter) {
143
+ if (this.#nodes.length === 1) {
144
+ // 单节点:原样请求、抛原始错误(与不经过 FallbackRpc 时一致)
145
+ if (!this.#nodes[0]?.getLogs) {
146
+ throw new Error('getLogs is not supported by this provider');
147
+ }
148
+ return this.#single('getLogs', (n) => n.getLogs(filter));
149
+ }
73
150
  const errors = [];
74
151
  let preferred;
75
152
  const sticky = this.#logsNode;
153
+ let attempt = 0;
76
154
  for (const index of this.#preferLogsNode(this.#order(this.#logsFailedAt))) {
77
155
  const node = this.#nodes[index];
78
156
  if (!node.getLogs) {
79
157
  continue;
80
158
  }
81
159
  try {
82
- const logs = await withTimeout(node.getLogs(filter), this.#timeout);
160
+ const logs = await this.#attempt('getLogs', index, attempt++, (n) => n.getLogs(filter));
83
161
  this.#logsNode = index;
84
162
  this.#logsFailedAt[index] = 0;
85
163
  this.#logsThrottled = 0;
@@ -113,26 +191,80 @@ export class FallbackRpc {
113
191
  }
114
192
  throw new GetLogsError(errors, preferred);
115
193
  }
116
- async #run(fn) {
117
- let lastError;
118
- for (const index of this.#order()) {
119
- try {
120
- const result = await withTimeout(fn(this.#nodes[index]), this.#timeout);
121
- this.#failedAt[index] = 0;
122
- return result;
123
- }
124
- catch (err) {
125
- if (isDeterministic(err)) {
126
- throw err;
194
+ /**
195
+ * 按顺序请求节点:出错(非确定性错误)或超时立即换下一个;设置了 stallTimeout 时,
196
+ * 当前节点超过 stallTimeout 还没返回也会同时请求下一个(已发出的请求不取消),第一个成功的结果胜出。
197
+ * 出错的节点进入冷却;超时只换节点,同一节点连续 3 次超时才冷却(冷启动的大批量查询偶尔慢,不应把健康的节点踢到后面);
198
+ * 节点还没有请求的区块(minBlock 重查时落后的节点)也只换节点、不冷却。
199
+ * 确定性错误(revert、参数错误等)直接抛出;所有节点都失败时抛 AllNodesFailedError(单节点时抛原始错误)。
200
+ */
201
+ #run(method, fn) {
202
+ const order = this.#order();
203
+ return new Promise((resolve, reject) => {
204
+ let next = 0;
205
+ let running = 0;
206
+ let settled = false;
207
+ const errors = [];
208
+ let stallTimer;
209
+ const finish = (done) => {
210
+ settled = true;
211
+ clearTimeout(stallTimer);
212
+ done();
213
+ };
214
+ const fail = () => {
215
+ const only = errors.length === 1 && this.#nodes.length === 1;
216
+ finish(() => reject(only ? errors[0]?.error : new AllNodesFailedError(errors)));
217
+ };
218
+ const launch = () => {
219
+ if (settled || next >= order.length) {
220
+ return false;
127
221
  }
128
- this.#failedAt[index] = Date.now();
129
- lastError = err;
130
- }
131
- }
132
- throw lastError;
222
+ const attempt = next++;
223
+ const index = order[attempt];
224
+ const health = healthOf(this.#healthKeys[index]);
225
+ running++;
226
+ clearTimeout(stallTimer);
227
+ if (this.#stallTimeout > 0 && next < order.length) {
228
+ stallTimer = setTimeout(launch, this.#stallTimeout);
229
+ }
230
+ this.#attempt(method, index, attempt, fn).then((result) => {
231
+ running--;
232
+ health.failedAt = 0;
233
+ health.timeouts = 0;
234
+ if (!settled) {
235
+ finish(() => resolve(result));
236
+ }
237
+ }, (err) => {
238
+ running--;
239
+ const deterministic = isDeterministic(err);
240
+ if (err instanceof TimeoutError) {
241
+ if (++health.timeouts >= TIMEOUTS_BEFORE_COOLDOWN) {
242
+ health.failedAt = Date.now();
243
+ health.timeouts = 0;
244
+ }
245
+ }
246
+ else if (!deterministic && !isBehind(err)) {
247
+ health.failedAt = Date.now();
248
+ }
249
+ if (settled) {
250
+ return;
251
+ }
252
+ if (deterministic) {
253
+ finish(() => reject(err));
254
+ return;
255
+ }
256
+ errors.push({ node: this.#labels[index], error: err });
257
+ if (!launch() && running === 0) {
258
+ fail();
259
+ }
260
+ });
261
+ return true;
262
+ };
263
+ launch();
264
+ });
133
265
  }
134
266
  /** 健康的节点按原顺序在前,冷却中的按出错时间先后排在后面(全挂时也都会再试一次) */
135
- #order(failedAt = this.#failedAt) {
267
+ #order(failedAt = this.#healthKeys.map((key) => healthOf(key).failedAt)) {
136
268
  const now = Date.now();
137
269
  const healthy = [];
138
270
  const cooling = [];
@@ -178,6 +310,12 @@ function isAlive(err) {
178
310
  function isRateLimited(err) {
179
311
  return /too many requests|rate.?limit|\b429\b/i.test(errorText(err));
180
312
  }
313
+ /**
314
+ * 节点还没有请求的区块(minBlock 按指定区块重查时,落后的节点会这样报错):只换节点、不冷却——节点本身是健康的,只是慢一两个块
315
+ */
316
+ function isBehind(err) {
317
+ return /header not found|unknown block|block not found|block .*not (yet )?(available|found)|requested block .*(ahead|future)|after last accepted block/i.test(errorText(err));
318
+ }
181
319
  /** 换节点也不会变的错误:合约执行结果、参数错误、用户拒绝等 */
182
320
  function isDeterministic(err) {
183
321
  return (isExecutionError(err) ||
@@ -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,20 +1,19 @@
1
1
  export { Contract, bindCall, type BoundMethod, type ContractAbi, type ContractRunner } from './contract.js';
2
- export { getTransferScanState, keyValueScanStorage, memoryScanStorage, transferScan, type TransferScanOptions, type TransferScanState, type TransferScanStorage, } from './scan.js';
3
2
  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';
3
+ export { getAllowances, getBalances, getMultiBalances, getTokens, type GetAllowancesOptions, type GetBalancesOptions, type GetTokensOptions, type ShortcutOptions, type ShortcutProviderOptions, } from './shortcuts.js';
4
+ export { NATIVE_BALANCE_MODES, NATIVE_CURRENCIES, getNativeBalanceMode, getNativeCurrency, type NativeCurrency } from './chains.js';
8
5
  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';
6
+ export { DEFAULT_NATIVE_TOKENS, ERC20_ABI, NATIVE_TOKEN, exportTokenMetaCache, formatAmount, formatUnits, importTokenMetaCache, persistTokenMetaCache, type TokenMetaSnapshot, type TokenMetaStore, type BalanceToken, type Erc20Contract, type RawTokenAllowance, type RawTokenBalance, type TokenBalance, type TokenAllowance, MAX_UINT256, UNLIMITED_ALLOWANCE_THRESHOLD, DEFAULT_TOKEN_FIELDS, type DefaultTokenField, type TokenDetails, type TokenField, } from './erc20.js';
7
+ export { Provider, type AllowancesOptions, type BalancesOptions, type BalancesQuery, type BlockOptions, type CallInput, type CallResults, type ProviderConfig, type ProviderSource, type StaticCallItem, type StaticCallOverrides, type StaticCallResult, type TokensOptions, type TryCallResults, } from './provider.js';
11
8
  export { TRON_CHAIN_ID, TronProvider, isTronAddress, toEvmAddress, toTronAddress, type TronProviderOptions, type TronRequest, type TronWebLike, } from './tron.js';
12
9
  export { CallFailedError, decodeRevertReason, isExecutionError } from './errors.js';
13
- export { FallbackRpc, type FallbackOptions } from './fallback.js';
10
+ export { AllNodesFailedError, FallbackRpc, type FallbackNodeInfo, type FallbackOptions } from './fallback.js';
11
+ export { onRequest, type RequestEvent, type RequestListener } from './events.js';
12
+ export { watchBalances, type WatchBalancesOptions } from './watch.js';
14
13
  export { ChainCheckedProvider, getDefaultRpcUrls, isTronChain, type SourceOptions } from './source.js';
15
14
  export { DEFAULT_RPC_URLS, DEFAULT_TRON_HOSTS } from './rpcNodes.js';
16
15
  export { MULTICALL3_ADDRESS, getMulticall3, type Multicall } from './multicall.js';
17
- export type { BlockTag, CallOverrides, EthersLikeProvider } from './aggregate.js';
16
+ export type { BlockTag, CallOverrides, EthersLikeProvider, NativeBalanceMode } from './aggregate.js';
18
17
  export type { BatchOptions } from './batcher.js';
19
- export type { BoundCall, Call, FailableCall, Params, RawResult } from './call.js';
18
+ export type { BoundCall, Call, FailableCall, FailureReason, Params, RawResult, Settled } from './call.js';
20
19
  //# sourceMappingURL=index.d.ts.map