@1delta/providers 0.0.1
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.
- package/dist/evm.d.ts +115 -0
- package/dist/evm.d.ts.map +1 -0
- package/dist/evm.js +363 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/package.json +23 -0
- package/src/evm.ts +460 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +25 -0
package/dist/evm.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { PublicClient } from "viem";
|
|
2
|
+
export declare const crossfi: {
|
|
3
|
+
blockExplorers: {
|
|
4
|
+
readonly default: {
|
|
5
|
+
readonly name: "Explorer";
|
|
6
|
+
readonly url: "https://xfiscan.com/";
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
blockTime?: number | undefined | undefined;
|
|
10
|
+
contracts?: {
|
|
11
|
+
[x: string]: import("viem").ChainContract | {
|
|
12
|
+
[sourceId: number]: import("viem").ChainContract | undefined;
|
|
13
|
+
} | undefined;
|
|
14
|
+
ensRegistry?: import("viem").ChainContract | undefined;
|
|
15
|
+
ensUniversalResolver?: import("viem").ChainContract | undefined;
|
|
16
|
+
multicall3?: import("viem").ChainContract | undefined;
|
|
17
|
+
universalSignatureVerifier?: import("viem").ChainContract | undefined;
|
|
18
|
+
} | undefined;
|
|
19
|
+
ensTlds?: readonly string[] | undefined;
|
|
20
|
+
id: 4158;
|
|
21
|
+
name: "CrossFi Mainet";
|
|
22
|
+
nativeCurrency: {
|
|
23
|
+
readonly decimals: 18;
|
|
24
|
+
readonly name: "XFI";
|
|
25
|
+
readonly symbol: "XFI";
|
|
26
|
+
};
|
|
27
|
+
rpcUrls: {
|
|
28
|
+
readonly default: {
|
|
29
|
+
readonly http: readonly ["https://rpc.mainnet.ms/"];
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
sourceId?: number | undefined | undefined;
|
|
33
|
+
testnet?: boolean | undefined | undefined;
|
|
34
|
+
custom?: Record<string, unknown> | undefined;
|
|
35
|
+
fees?: import("viem").ChainFees<undefined> | undefined;
|
|
36
|
+
formatters?: undefined;
|
|
37
|
+
serializers?: import("viem").ChainSerializers<undefined, import("viem").TransactionSerializable> | undefined;
|
|
38
|
+
};
|
|
39
|
+
export declare const botanix: {
|
|
40
|
+
blockExplorers: {
|
|
41
|
+
readonly default: {
|
|
42
|
+
readonly name: "Explorer";
|
|
43
|
+
readonly url: "https://botanixscan.io/";
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
blockTime?: number | undefined | undefined;
|
|
47
|
+
contracts: {
|
|
48
|
+
readonly multicall3: {
|
|
49
|
+
readonly address: "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
50
|
+
readonly blockCreated: 1;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
ensTlds?: readonly string[] | undefined;
|
|
54
|
+
id: 3637;
|
|
55
|
+
name: "Botanix";
|
|
56
|
+
nativeCurrency: {
|
|
57
|
+
readonly decimals: 18;
|
|
58
|
+
readonly name: "BTC";
|
|
59
|
+
readonly symbol: "BTC";
|
|
60
|
+
};
|
|
61
|
+
rpcUrls: {
|
|
62
|
+
readonly default: {
|
|
63
|
+
readonly http: readonly ["https://rpc.ankr.com/botanix_mainnet", "https://rpc.botanixlabs.com"];
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
sourceId?: number | undefined | undefined;
|
|
67
|
+
testnet?: boolean | undefined | undefined;
|
|
68
|
+
custom?: Record<string, unknown> | undefined;
|
|
69
|
+
fees?: import("viem").ChainFees<undefined> | undefined;
|
|
70
|
+
formatters?: undefined;
|
|
71
|
+
serializers?: import("viem").ChainSerializers<undefined, import("viem").TransactionSerializable> | undefined;
|
|
72
|
+
};
|
|
73
|
+
export declare const GraphLinq: {
|
|
74
|
+
blockExplorers: {
|
|
75
|
+
readonly default: {
|
|
76
|
+
readonly name: "Explorer";
|
|
77
|
+
readonly url: "https://explorer.graphlinq.io";
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
blockTime?: number | undefined | undefined;
|
|
81
|
+
contracts?: {
|
|
82
|
+
[x: string]: import("viem").ChainContract | {
|
|
83
|
+
[sourceId: number]: import("viem").ChainContract | undefined;
|
|
84
|
+
} | undefined;
|
|
85
|
+
ensRegistry?: import("viem").ChainContract | undefined;
|
|
86
|
+
ensUniversalResolver?: import("viem").ChainContract | undefined;
|
|
87
|
+
multicall3?: import("viem").ChainContract | undefined;
|
|
88
|
+
universalSignatureVerifier?: import("viem").ChainContract | undefined;
|
|
89
|
+
} | undefined;
|
|
90
|
+
ensTlds?: readonly string[] | undefined;
|
|
91
|
+
id: 614;
|
|
92
|
+
name: "GraphLinq Chain";
|
|
93
|
+
nativeCurrency: {
|
|
94
|
+
readonly decimals: 18;
|
|
95
|
+
readonly name: "GLQ";
|
|
96
|
+
readonly symbol: "GLQ";
|
|
97
|
+
};
|
|
98
|
+
rpcUrls: {
|
|
99
|
+
readonly default: {
|
|
100
|
+
readonly http: readonly ["https://glq-dataseed.graphlinq.io"];
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
sourceId?: number | undefined | undefined;
|
|
104
|
+
testnet?: boolean | undefined | undefined;
|
|
105
|
+
custom?: Record<string, unknown> | undefined;
|
|
106
|
+
fees?: import("viem").ChainFees<undefined> | undefined;
|
|
107
|
+
formatters?: undefined;
|
|
108
|
+
serializers?: import("viem").ChainSerializers<undefined, import("viem").TransactionSerializable> | undefined;
|
|
109
|
+
};
|
|
110
|
+
export declare function getEvmClient(chain: string, rpcId?: number): PublicClient;
|
|
111
|
+
export declare function createMulticallRetry(customRpcs?: {
|
|
112
|
+
[chainId: string]: string[];
|
|
113
|
+
}): (chain: string, calls: any[], abi: any, batchSize?: number, maxRetries?: number, providerId?: number, allowFailure?: boolean) => Promise<any[]>;
|
|
114
|
+
export declare function multicallRetry(chain: string, calls: any[], abi: any, batchSize?: number, maxRetries?: number, providerId?: number): Promise<any[]>;
|
|
115
|
+
//# sourceMappingURL=evm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evm.d.ts","sourceRoot":"","sources":["../src/evm.ts"],"names":[],"mappings":"AAEA,OAAO,EAAyC,YAAY,EAAE,MAAM,MAAM,CAAA;AAkE1E,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsBlB,CAAC;AAEH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwBlB,CAAC;AAGH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsBpB,CAAC;AA8MH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,YAAY,CAmBnE;AAID,wBAAgB,oBAAoB,CAAC,UAAU,CAAC,EAAE;IAAE,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,IAEzE,OAAO,MAAM,EACb,OAAO,GAAG,EAAE,EACZ,KAAK,GAAG,EACR,kBAA8B,EAC9B,mBAAc,EACd,mBAAc,EACd,sBAAmB,oBA6B1B;AA0CD,wBAAsB,cAAc,CAChC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,GAAG,EAAE,EACZ,GAAG,EAAE,GAAG,EACR,SAAS,SAAqB,EAC9B,UAAU,SAAI,EACd,UAAU,SAAI,kBAIjB"}
|
package/dist/evm.js
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import { Chain, CHAIN_INFO } from "@1delta/asset-registry";
|
|
2
|
+
import { isArray, uniq } from "lodash";
|
|
3
|
+
import { createPublicClient, defineChain, http } from "viem";
|
|
4
|
+
import { mantle, mainnet, optimism, arbitrum, bsc, avalanche, taiko, metis, polygon, zksync, scroll, gnosis, base, blast, kaia, opBNB, fantom, sonic, linea, hemi, neonMainnet, degen, gravity, lightlinkPhoenix, plume, abstract, peaq, flowMainnet, soneium, goat, berachain, rootstock, ink, vanar, fuse, superposition, story, apeChain, telos, flare, aurora, kava, iota, coreDao, unichain, mode, xLayer, zircuit, corn, bob, manta, harmonyOne, celo, bitlayer, merlin, sei, iotex, bsquared, zetachain, ronin, inEVM, } from "viem/chains";
|
|
5
|
+
export const crossfi = defineChain({
|
|
6
|
+
id: 4158,
|
|
7
|
+
name: 'CrossFi Mainet',
|
|
8
|
+
nativeCurrency: {
|
|
9
|
+
decimals: 18,
|
|
10
|
+
name: 'XFI',
|
|
11
|
+
symbol: 'XFI',
|
|
12
|
+
},
|
|
13
|
+
rpcUrls: {
|
|
14
|
+
default: {
|
|
15
|
+
http: ['https://rpc.mainnet.ms/'],
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
blockExplorers: {
|
|
19
|
+
default: { name: 'Explorer', url: 'https://xfiscan.com/' },
|
|
20
|
+
},
|
|
21
|
+
// contracts: {
|
|
22
|
+
// multicall3: {
|
|
23
|
+
// address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
24
|
+
// blockCreated: 1,
|
|
25
|
+
// }
|
|
26
|
+
// }
|
|
27
|
+
});
|
|
28
|
+
export const botanix = defineChain({
|
|
29
|
+
id: 3637,
|
|
30
|
+
name: 'Botanix',
|
|
31
|
+
nativeCurrency: {
|
|
32
|
+
decimals: 18,
|
|
33
|
+
name: 'BTC',
|
|
34
|
+
symbol: 'BTC',
|
|
35
|
+
},
|
|
36
|
+
rpcUrls: {
|
|
37
|
+
default: {
|
|
38
|
+
http: [
|
|
39
|
+
"https://rpc.ankr.com/botanix_mainnet",
|
|
40
|
+
"https://rpc.botanixlabs.com"
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
blockExplorers: {
|
|
45
|
+
default: { name: 'Explorer', url: 'https://botanixscan.io/' },
|
|
46
|
+
},
|
|
47
|
+
contracts: {
|
|
48
|
+
multicall3: {
|
|
49
|
+
address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
50
|
+
blockCreated: 1,
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
export const GraphLinq = defineChain({
|
|
55
|
+
id: 614,
|
|
56
|
+
name: 'GraphLinq Chain',
|
|
57
|
+
nativeCurrency: {
|
|
58
|
+
decimals: 18,
|
|
59
|
+
name: 'GLQ',
|
|
60
|
+
symbol: 'GLQ',
|
|
61
|
+
},
|
|
62
|
+
rpcUrls: {
|
|
63
|
+
default: {
|
|
64
|
+
http: ["https://glq-dataseed.graphlinq.io"],
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
blockExplorers: {
|
|
68
|
+
default: { name: 'Explorer', "url": "https://explorer.graphlinq.io", },
|
|
69
|
+
},
|
|
70
|
+
// contracts: {
|
|
71
|
+
// multicall3: {
|
|
72
|
+
// address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
73
|
+
// blockCreated: 1,
|
|
74
|
+
// }
|
|
75
|
+
// }
|
|
76
|
+
});
|
|
77
|
+
function getEvmChain(chain) {
|
|
78
|
+
switch (chain) {
|
|
79
|
+
case Chain.ARBITRUM_ONE:
|
|
80
|
+
return arbitrum;
|
|
81
|
+
case Chain.ETHEREUM_MAINNET:
|
|
82
|
+
return mainnet;
|
|
83
|
+
case Chain.MANTLE:
|
|
84
|
+
return mantle;
|
|
85
|
+
case Chain.BNB_SMART_CHAIN_MAINNET:
|
|
86
|
+
return bsc;
|
|
87
|
+
case Chain.OPBNB_MAINNET:
|
|
88
|
+
return opBNB;
|
|
89
|
+
case Chain.TAIKO_ALETHIA:
|
|
90
|
+
return taiko;
|
|
91
|
+
case Chain.AVALANCHE_C_CHAIN:
|
|
92
|
+
return avalanche;
|
|
93
|
+
case Chain.OP_MAINNET:
|
|
94
|
+
return optimism;
|
|
95
|
+
case Chain.METIS_ANDROMEDA_MAINNET:
|
|
96
|
+
return metis;
|
|
97
|
+
case Chain.POLYGON_MAINNET:
|
|
98
|
+
return polygon;
|
|
99
|
+
case Chain.ZKSYNC_MAINNET:
|
|
100
|
+
return zksync;
|
|
101
|
+
case Chain.SCROLL:
|
|
102
|
+
return scroll;
|
|
103
|
+
case Chain.GNOSIS:
|
|
104
|
+
return gnosis;
|
|
105
|
+
case Chain.BASE:
|
|
106
|
+
return base;
|
|
107
|
+
case Chain.BLAST:
|
|
108
|
+
return blast;
|
|
109
|
+
case Chain.KAIA_MAINNET:
|
|
110
|
+
return kaia;
|
|
111
|
+
case Chain.FANTOM_OPERA:
|
|
112
|
+
return fantom;
|
|
113
|
+
case Chain.SONIC_MAINNET:
|
|
114
|
+
return sonic;
|
|
115
|
+
case Chain.LINEA:
|
|
116
|
+
return linea;
|
|
117
|
+
case Chain.HEMI_NETWORK:
|
|
118
|
+
return {
|
|
119
|
+
...hemi,
|
|
120
|
+
contracts: {
|
|
121
|
+
multicall3: {
|
|
122
|
+
address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
123
|
+
blockCreated: 1,
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
case Chain.NEON_EVM_MAINNET:
|
|
128
|
+
return neonMainnet;
|
|
129
|
+
case Chain.DEGEN_CHAIN:
|
|
130
|
+
return {
|
|
131
|
+
...degen,
|
|
132
|
+
contracts: {
|
|
133
|
+
multicall3: {
|
|
134
|
+
address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
135
|
+
blockCreated: 1,
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
case Chain.GRAVITY_ALPHA_MAINNET:
|
|
140
|
+
return gravity;
|
|
141
|
+
case Chain.LIGHTLINK_PHOENIX_MAINNET:
|
|
142
|
+
return lightlinkPhoenix;
|
|
143
|
+
case Chain.PLUME_MAINNET:
|
|
144
|
+
return plume;
|
|
145
|
+
case Chain.ABSTRACT:
|
|
146
|
+
return abstract;
|
|
147
|
+
case Chain.PEAQ:
|
|
148
|
+
return peaq;
|
|
149
|
+
case Chain.EVM_ON_FLOW:
|
|
150
|
+
return flowMainnet;
|
|
151
|
+
case Chain.SONEIUM:
|
|
152
|
+
return soneium;
|
|
153
|
+
case Chain.GOAT_NETWORK:
|
|
154
|
+
return goat;
|
|
155
|
+
case Chain.BERACHAIN:
|
|
156
|
+
return berachain;
|
|
157
|
+
case Chain.ROOTSTOCK_MAINNET:
|
|
158
|
+
return rootstock;
|
|
159
|
+
case Chain.VANAR_MAINNET:
|
|
160
|
+
return vanar;
|
|
161
|
+
case Chain.INK:
|
|
162
|
+
return {
|
|
163
|
+
...ink,
|
|
164
|
+
contracts: {
|
|
165
|
+
multicall3: {
|
|
166
|
+
address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
167
|
+
blockCreated: 1,
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
case Chain.FUSE_MAINNET:
|
|
172
|
+
return fuse;
|
|
173
|
+
case Chain.SUPERPOSITION:
|
|
174
|
+
return superposition;
|
|
175
|
+
case Chain.STORY:
|
|
176
|
+
return {
|
|
177
|
+
...story,
|
|
178
|
+
contracts: {
|
|
179
|
+
multicall3: {
|
|
180
|
+
address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
181
|
+
blockCreated: 1,
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
case Chain.APECHAIN:
|
|
186
|
+
return apeChain;
|
|
187
|
+
case Chain.IOTEX_NETWORK_MAINNET:
|
|
188
|
+
return iotex;
|
|
189
|
+
case Chain.TELOS_EVM_MAINNET:
|
|
190
|
+
return telos;
|
|
191
|
+
case Chain.FLARE_MAINNET:
|
|
192
|
+
return flare;
|
|
193
|
+
case Chain.AURA_MAINNET:
|
|
194
|
+
return aurora;
|
|
195
|
+
case Chain.KAVA:
|
|
196
|
+
return kava;
|
|
197
|
+
case Chain.IOTA_EVM:
|
|
198
|
+
return iota;
|
|
199
|
+
case Chain.AURORA_MAINNET:
|
|
200
|
+
return aurora;
|
|
201
|
+
case Chain.UNICHAIN:
|
|
202
|
+
return unichain;
|
|
203
|
+
case Chain.CORE_BLOCKCHAIN_MAINNET:
|
|
204
|
+
return coreDao;
|
|
205
|
+
case Chain.MODE:
|
|
206
|
+
return mode;
|
|
207
|
+
case Chain.CORN:
|
|
208
|
+
return corn;
|
|
209
|
+
case Chain.BOB:
|
|
210
|
+
return bob;
|
|
211
|
+
case Chain.RONIN_MAINNET:
|
|
212
|
+
return ronin;
|
|
213
|
+
case Chain.MANTA_PACIFIC_MAINNET:
|
|
214
|
+
return manta;
|
|
215
|
+
case Chain.ZIRCUIT_MAINNET:
|
|
216
|
+
return zircuit;
|
|
217
|
+
case Chain.GRAPHLINQ_BLOCKCHAIN_MAINNET:
|
|
218
|
+
return GraphLinq;
|
|
219
|
+
case Chain.ZETACHAIN_MAINNET:
|
|
220
|
+
return zetachain;
|
|
221
|
+
case Chain.BITLAYER_MAINNET:
|
|
222
|
+
return bitlayer;
|
|
223
|
+
case Chain.CROSSFI_MAINNET:
|
|
224
|
+
return crossfi;
|
|
225
|
+
case Chain.INEVM_MAINNET:
|
|
226
|
+
return inEVM;
|
|
227
|
+
case Chain.B2_MAINNET:
|
|
228
|
+
return {
|
|
229
|
+
...bsquared,
|
|
230
|
+
contracts: {
|
|
231
|
+
multicall3: {
|
|
232
|
+
address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
233
|
+
blockCreated: 1,
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
case Chain.SEI_NETWORK:
|
|
238
|
+
return sei;
|
|
239
|
+
case Chain.MERLIN_MAINNET:
|
|
240
|
+
return {
|
|
241
|
+
...merlin,
|
|
242
|
+
contracts: {
|
|
243
|
+
multicall3: {
|
|
244
|
+
address: "0x46063722c010AF39E465d286B84936A12aFb81F0",
|
|
245
|
+
blockCreated: 1,
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
case Chain.X_LAYER_MAINNET:
|
|
250
|
+
return xLayer;
|
|
251
|
+
case Chain.CELO_MAINNET:
|
|
252
|
+
return celo;
|
|
253
|
+
case Chain.BOTANIX_MAINNET:
|
|
254
|
+
return botanix;
|
|
255
|
+
case Chain.HARMONY_MAINNET_SHARD_0:
|
|
256
|
+
return harmonyOne;
|
|
257
|
+
// case Chain.VANA:
|
|
258
|
+
// return vana
|
|
259
|
+
// case Chain.RARI_CHAIN_MAINNET:
|
|
260
|
+
// return rariChain
|
|
261
|
+
// case Chain.GLUE_MAINNET:
|
|
262
|
+
// return glue
|
|
263
|
+
default: throw new Error("Not in VIEM: " + chain);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const RPC_OVERRIDES = {
|
|
267
|
+
[Chain.FANTOM_OPERA]: "https://rpc.fantom.network",
|
|
268
|
+
[Chain.BNB_SMART_CHAIN_MAINNET]: "https://bsc-dataseed2.ninicoin.io",
|
|
269
|
+
[Chain.METIS_ANDROMEDA_MAINNET]: "https://andromeda.metis.io/?owner=1088",
|
|
270
|
+
[Chain.X_LAYER_MAINNET]: "https://xlayerrpc.okx.com",
|
|
271
|
+
};
|
|
272
|
+
function trimTrailingSlash(url) {
|
|
273
|
+
if (!url)
|
|
274
|
+
return undefined;
|
|
275
|
+
return url.endsWith('/') ? url.slice(0, -1) : url;
|
|
276
|
+
}
|
|
277
|
+
export function getEvmClient(chain, rpcId = 0) {
|
|
278
|
+
const chainInfo = getEvmChain(chain);
|
|
279
|
+
let rpc;
|
|
280
|
+
if (rpcId === 0)
|
|
281
|
+
rpc = chainInfo.rpcUrls.default.http[0];
|
|
282
|
+
else {
|
|
283
|
+
const rpcsChain = CHAIN_INFO[chain].rpc?.filter(a => !a.includes("wss://"));
|
|
284
|
+
const rpcs = chainInfo.rpcUrls.default.http.map(a => trimTrailingSlash(a));
|
|
285
|
+
const rpcsAdded = rpcsChain.map(a => trimTrailingSlash(a));
|
|
286
|
+
const allRpcs = uniq([...rpcs, ...rpcsAdded]);
|
|
287
|
+
rpc = allRpcs[rpcId];
|
|
288
|
+
}
|
|
289
|
+
return createPublicClient({
|
|
290
|
+
chain: chainInfo,
|
|
291
|
+
transport: http(RPC_OVERRIDES[chain] ??
|
|
292
|
+
rpc)
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
const DEFAULT_BATCH_SIZE = 4096;
|
|
296
|
+
export function createMulticallRetry(customRpcs) {
|
|
297
|
+
return async function multicallRetry(chain, calls, abi, batchSize = DEFAULT_BATCH_SIZE, maxRetries = 3, providerId = 0, allowFailure = true) {
|
|
298
|
+
try {
|
|
299
|
+
const provider = getEvmClientWithCustomRpcs(chain, providerId, customRpcs);
|
|
300
|
+
const abiIsArray = isArray(abi[0]);
|
|
301
|
+
const data = await provider.multicall({
|
|
302
|
+
batchSize: DEFAULT_BATCH_SIZE,
|
|
303
|
+
contracts: calls.map((call, i) => ({
|
|
304
|
+
abi: abiIsArray ? abi?.[i] : abi,
|
|
305
|
+
address: call.address,
|
|
306
|
+
functionName: call.name,
|
|
307
|
+
// @ts-ignore
|
|
308
|
+
args: call.args ?? call.params ?? [],
|
|
309
|
+
})),
|
|
310
|
+
allowFailure,
|
|
311
|
+
});
|
|
312
|
+
if (allowFailure) {
|
|
313
|
+
return data.map(({ result, status }) => status !== "success" ? '0x' : result);
|
|
314
|
+
}
|
|
315
|
+
return data;
|
|
316
|
+
}
|
|
317
|
+
catch (e) {
|
|
318
|
+
// error if max retries achieved
|
|
319
|
+
if (maxRetries === 0)
|
|
320
|
+
throw e;
|
|
321
|
+
console.log(e);
|
|
322
|
+
return await multicallRetry(chain, calls, abi, batchSize, maxRetries - 1, providerId + 1);
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function getEvmClientWithCustomRpcs(chain, rpcId = 0, customRpcs) {
|
|
327
|
+
const chainInfo = getEvmChain(chain);
|
|
328
|
+
let rpc;
|
|
329
|
+
if (customRpcs && customRpcs[chain]) {
|
|
330
|
+
// Use custom RPC list if any (make sure that they are unique and valid)
|
|
331
|
+
const customRpcList = uniq(customRpcs[chain]
|
|
332
|
+
.filter(Boolean) // Remove empty ones
|
|
333
|
+
.filter(a => !a.includes("wss://")) // filter websocket ones (like the default impl)
|
|
334
|
+
.map(url => trimTrailingSlash(url))
|
|
335
|
+
.filter((url) => Boolean(url)) // Type-safe filter for defined URLs
|
|
336
|
+
);
|
|
337
|
+
if (customRpcList.length === 0) {
|
|
338
|
+
throw new Error(`No valid custom RPCs provided for chain ${chain}`);
|
|
339
|
+
}
|
|
340
|
+
rpc = customRpcList[rpcId % customRpcList.length];
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
// Fallback to existing logic
|
|
344
|
+
if (rpcId === 0)
|
|
345
|
+
rpc = chainInfo.rpcUrls.default.http[0];
|
|
346
|
+
else {
|
|
347
|
+
const rpcsChain = CHAIN_INFO[chain].rpc?.filter(a => !a.includes("wss://"));
|
|
348
|
+
const rpcs = chainInfo.rpcUrls.default.http.map(a => trimTrailingSlash(a));
|
|
349
|
+
const rpcsAdded = rpcsChain.map(a => trimTrailingSlash(a));
|
|
350
|
+
const allRpcs = uniq([...rpcs, ...rpcsAdded]);
|
|
351
|
+
rpc = allRpcs[rpcId];
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return createPublicClient({
|
|
355
|
+
chain: chainInfo,
|
|
356
|
+
transport: http(RPC_OVERRIDES[chain] ??
|
|
357
|
+
rpc)
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
export async function multicallRetry(chain, calls, abi, batchSize = DEFAULT_BATCH_SIZE, maxRetries = 3, providerId = 0) {
|
|
361
|
+
const defaultMulticallRetry = createMulticallRetry();
|
|
362
|
+
return defaultMulticallRetry(chain, calls, abi, batchSize, maxRetries, providerId);
|
|
363
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./evm";
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@1delta/providers",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"keywords": [],
|
|
14
|
+
"author": "",
|
|
15
|
+
"license": "ISC",
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"typescript": "^5.8.3"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"test": "vitest"
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/evm.ts
ADDED
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
import { Chain, CHAIN_INFO } from "@1delta/asset-registry"
|
|
2
|
+
import { isArray, uniq } from "lodash";
|
|
3
|
+
import { createPublicClient, defineChain, http, PublicClient } from "viem"
|
|
4
|
+
import {
|
|
5
|
+
mantle,
|
|
6
|
+
mainnet,
|
|
7
|
+
optimism,
|
|
8
|
+
arbitrum,
|
|
9
|
+
bsc,
|
|
10
|
+
avalanche,
|
|
11
|
+
taiko,
|
|
12
|
+
metis,
|
|
13
|
+
polygon,
|
|
14
|
+
zksync,
|
|
15
|
+
scroll,
|
|
16
|
+
gnosis,
|
|
17
|
+
base,
|
|
18
|
+
blast,
|
|
19
|
+
kaia,
|
|
20
|
+
opBNB,
|
|
21
|
+
fantom,
|
|
22
|
+
sonic,
|
|
23
|
+
linea,
|
|
24
|
+
hemi,
|
|
25
|
+
neonMainnet,
|
|
26
|
+
degen,
|
|
27
|
+
gravity,
|
|
28
|
+
lightlinkPhoenix,
|
|
29
|
+
plume,
|
|
30
|
+
abstract,
|
|
31
|
+
peaq,
|
|
32
|
+
flowMainnet,
|
|
33
|
+
soneium,
|
|
34
|
+
goat,
|
|
35
|
+
berachain,
|
|
36
|
+
rootstock,
|
|
37
|
+
ink,
|
|
38
|
+
vanar,
|
|
39
|
+
fuse,
|
|
40
|
+
superposition,
|
|
41
|
+
story,
|
|
42
|
+
apeChain,
|
|
43
|
+
telos,
|
|
44
|
+
flare,
|
|
45
|
+
aurora,
|
|
46
|
+
kava,
|
|
47
|
+
iota,
|
|
48
|
+
coreDao,
|
|
49
|
+
unichain,
|
|
50
|
+
mode,
|
|
51
|
+
xLayer,
|
|
52
|
+
zircuit,
|
|
53
|
+
corn,
|
|
54
|
+
bob,
|
|
55
|
+
manta,
|
|
56
|
+
harmonyOne,
|
|
57
|
+
celo,
|
|
58
|
+
bitlayer,
|
|
59
|
+
merlin,
|
|
60
|
+
sei,
|
|
61
|
+
iotex,
|
|
62
|
+
bsquared,
|
|
63
|
+
zetachain,
|
|
64
|
+
ronin,
|
|
65
|
+
inEVM,
|
|
66
|
+
} from "viem/chains"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
export const crossfi = defineChain({
|
|
70
|
+
id: 4158,
|
|
71
|
+
name: 'CrossFi Mainet',
|
|
72
|
+
nativeCurrency: {
|
|
73
|
+
decimals: 18,
|
|
74
|
+
name: 'XFI',
|
|
75
|
+
symbol: 'XFI',
|
|
76
|
+
},
|
|
77
|
+
rpcUrls: {
|
|
78
|
+
default: {
|
|
79
|
+
http: ['https://rpc.mainnet.ms/'],
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
blockExplorers: {
|
|
83
|
+
default: { name: 'Explorer', url: 'https://xfiscan.com/' },
|
|
84
|
+
},
|
|
85
|
+
// contracts: {
|
|
86
|
+
// multicall3: {
|
|
87
|
+
// address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
88
|
+
// blockCreated: 1,
|
|
89
|
+
// }
|
|
90
|
+
// }
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
export const botanix = defineChain({
|
|
94
|
+
id: 3637,
|
|
95
|
+
name: 'Botanix',
|
|
96
|
+
nativeCurrency: {
|
|
97
|
+
decimals: 18,
|
|
98
|
+
name: 'BTC',
|
|
99
|
+
symbol: 'BTC',
|
|
100
|
+
},
|
|
101
|
+
rpcUrls: {
|
|
102
|
+
default: {
|
|
103
|
+
http: [
|
|
104
|
+
"https://rpc.ankr.com/botanix_mainnet",
|
|
105
|
+
"https://rpc.botanixlabs.com"],
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
blockExplorers: {
|
|
109
|
+
default: { name: 'Explorer', url: 'https://botanixscan.io/' },
|
|
110
|
+
},
|
|
111
|
+
contracts: {
|
|
112
|
+
multicall3: {
|
|
113
|
+
address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
114
|
+
blockCreated: 1,
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
export const GraphLinq = defineChain({
|
|
121
|
+
id: 614,
|
|
122
|
+
name: 'GraphLinq Chain',
|
|
123
|
+
nativeCurrency: {
|
|
124
|
+
decimals: 18,
|
|
125
|
+
name: 'GLQ',
|
|
126
|
+
symbol: 'GLQ',
|
|
127
|
+
},
|
|
128
|
+
rpcUrls: {
|
|
129
|
+
default: {
|
|
130
|
+
http: ["https://glq-dataseed.graphlinq.io"],
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
blockExplorers: {
|
|
134
|
+
default: { name: 'Explorer', "url": "https://explorer.graphlinq.io", },
|
|
135
|
+
},
|
|
136
|
+
// contracts: {
|
|
137
|
+
// multicall3: {
|
|
138
|
+
// address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
139
|
+
// blockCreated: 1,
|
|
140
|
+
// }
|
|
141
|
+
// }
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
function getEvmChain(chain: string) {
|
|
147
|
+
switch (chain) {
|
|
148
|
+
case Chain.ARBITRUM_ONE:
|
|
149
|
+
return arbitrum
|
|
150
|
+
case Chain.ETHEREUM_MAINNET:
|
|
151
|
+
return mainnet
|
|
152
|
+
case Chain.MANTLE:
|
|
153
|
+
return mantle
|
|
154
|
+
case Chain.BNB_SMART_CHAIN_MAINNET:
|
|
155
|
+
return bsc
|
|
156
|
+
case Chain.OPBNB_MAINNET:
|
|
157
|
+
return opBNB
|
|
158
|
+
case Chain.TAIKO_ALETHIA:
|
|
159
|
+
return taiko
|
|
160
|
+
case Chain.AVALANCHE_C_CHAIN:
|
|
161
|
+
return avalanche
|
|
162
|
+
case Chain.OP_MAINNET:
|
|
163
|
+
return optimism
|
|
164
|
+
case Chain.METIS_ANDROMEDA_MAINNET:
|
|
165
|
+
return metis
|
|
166
|
+
case Chain.POLYGON_MAINNET:
|
|
167
|
+
return polygon
|
|
168
|
+
case Chain.ZKSYNC_MAINNET:
|
|
169
|
+
return zksync
|
|
170
|
+
case Chain.SCROLL:
|
|
171
|
+
return scroll
|
|
172
|
+
case Chain.GNOSIS:
|
|
173
|
+
return gnosis
|
|
174
|
+
case Chain.BASE:
|
|
175
|
+
return base
|
|
176
|
+
case Chain.BLAST:
|
|
177
|
+
return blast
|
|
178
|
+
case Chain.KAIA_MAINNET:
|
|
179
|
+
return kaia
|
|
180
|
+
case Chain.FANTOM_OPERA:
|
|
181
|
+
return fantom
|
|
182
|
+
case Chain.SONIC_MAINNET:
|
|
183
|
+
return sonic
|
|
184
|
+
case Chain.LINEA:
|
|
185
|
+
return linea
|
|
186
|
+
case Chain.HEMI_NETWORK:
|
|
187
|
+
return {
|
|
188
|
+
...hemi,
|
|
189
|
+
contracts: {
|
|
190
|
+
multicall3: {
|
|
191
|
+
address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
192
|
+
blockCreated: 1,
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
case Chain.NEON_EVM_MAINNET:
|
|
197
|
+
return neonMainnet
|
|
198
|
+
case Chain.DEGEN_CHAIN:
|
|
199
|
+
return {
|
|
200
|
+
...degen,
|
|
201
|
+
contracts: {
|
|
202
|
+
multicall3: {
|
|
203
|
+
address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
204
|
+
blockCreated: 1,
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
case Chain.GRAVITY_ALPHA_MAINNET:
|
|
209
|
+
return gravity
|
|
210
|
+
case Chain.LIGHTLINK_PHOENIX_MAINNET:
|
|
211
|
+
return lightlinkPhoenix
|
|
212
|
+
case Chain.PLUME_MAINNET:
|
|
213
|
+
return plume
|
|
214
|
+
case Chain.ABSTRACT:
|
|
215
|
+
return abstract
|
|
216
|
+
case Chain.PEAQ:
|
|
217
|
+
return peaq
|
|
218
|
+
case Chain.EVM_ON_FLOW:
|
|
219
|
+
return flowMainnet
|
|
220
|
+
case Chain.SONEIUM:
|
|
221
|
+
return soneium
|
|
222
|
+
case Chain.GOAT_NETWORK:
|
|
223
|
+
return goat
|
|
224
|
+
case Chain.BERACHAIN:
|
|
225
|
+
return berachain
|
|
226
|
+
case Chain.ROOTSTOCK_MAINNET:
|
|
227
|
+
return rootstock
|
|
228
|
+
case Chain.VANAR_MAINNET:
|
|
229
|
+
return vanar
|
|
230
|
+
case Chain.INK:
|
|
231
|
+
return {
|
|
232
|
+
...ink,
|
|
233
|
+
contracts: {
|
|
234
|
+
multicall3: {
|
|
235
|
+
address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
236
|
+
blockCreated: 1,
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
case Chain.FUSE_MAINNET:
|
|
241
|
+
return fuse
|
|
242
|
+
case Chain.SUPERPOSITION:
|
|
243
|
+
return superposition
|
|
244
|
+
case Chain.STORY:
|
|
245
|
+
return {
|
|
246
|
+
...story,
|
|
247
|
+
contracts: {
|
|
248
|
+
multicall3: {
|
|
249
|
+
address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
250
|
+
blockCreated: 1,
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
case Chain.APECHAIN:
|
|
255
|
+
return apeChain
|
|
256
|
+
case Chain.IOTEX_NETWORK_MAINNET:
|
|
257
|
+
return iotex
|
|
258
|
+
case Chain.TELOS_EVM_MAINNET:
|
|
259
|
+
return telos
|
|
260
|
+
case Chain.FLARE_MAINNET:
|
|
261
|
+
return flare
|
|
262
|
+
case Chain.AURA_MAINNET:
|
|
263
|
+
return aurora
|
|
264
|
+
case Chain.KAVA:
|
|
265
|
+
return kava
|
|
266
|
+
case Chain.IOTA_EVM:
|
|
267
|
+
return iota
|
|
268
|
+
case Chain.AURORA_MAINNET:
|
|
269
|
+
return aurora
|
|
270
|
+
case Chain.UNICHAIN:
|
|
271
|
+
return unichain
|
|
272
|
+
case Chain.CORE_BLOCKCHAIN_MAINNET:
|
|
273
|
+
return coreDao
|
|
274
|
+
case Chain.MODE:
|
|
275
|
+
return mode
|
|
276
|
+
case Chain.CORN:
|
|
277
|
+
return corn
|
|
278
|
+
case Chain.BOB:
|
|
279
|
+
return bob
|
|
280
|
+
case Chain.RONIN_MAINNET:
|
|
281
|
+
return ronin
|
|
282
|
+
case Chain.MANTA_PACIFIC_MAINNET:
|
|
283
|
+
return manta
|
|
284
|
+
case Chain.ZIRCUIT_MAINNET:
|
|
285
|
+
return zircuit
|
|
286
|
+
case Chain.GRAPHLINQ_BLOCKCHAIN_MAINNET:
|
|
287
|
+
return GraphLinq
|
|
288
|
+
case Chain.ZETACHAIN_MAINNET:
|
|
289
|
+
return zetachain
|
|
290
|
+
case Chain.BITLAYER_MAINNET:
|
|
291
|
+
return bitlayer
|
|
292
|
+
case Chain.CROSSFI_MAINNET:
|
|
293
|
+
return crossfi
|
|
294
|
+
case Chain.INEVM_MAINNET:
|
|
295
|
+
return inEVM
|
|
296
|
+
case Chain.B2_MAINNET:
|
|
297
|
+
return {
|
|
298
|
+
...bsquared,
|
|
299
|
+
contracts: {
|
|
300
|
+
multicall3: {
|
|
301
|
+
address: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
302
|
+
blockCreated: 1,
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
case Chain.SEI_NETWORK:
|
|
307
|
+
return sei
|
|
308
|
+
case Chain.MERLIN_MAINNET:
|
|
309
|
+
return {
|
|
310
|
+
...merlin,
|
|
311
|
+
contracts: {
|
|
312
|
+
multicall3: {
|
|
313
|
+
address: "0x46063722c010AF39E465d286B84936A12aFb81F0",
|
|
314
|
+
blockCreated: 1,
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
case Chain.X_LAYER_MAINNET:
|
|
319
|
+
return xLayer
|
|
320
|
+
case Chain.CELO_MAINNET:
|
|
321
|
+
return celo
|
|
322
|
+
case Chain.BOTANIX_MAINNET:
|
|
323
|
+
return botanix
|
|
324
|
+
case Chain.HARMONY_MAINNET_SHARD_0:
|
|
325
|
+
return harmonyOne
|
|
326
|
+
// case Chain.VANA:
|
|
327
|
+
// return vana
|
|
328
|
+
// case Chain.RARI_CHAIN_MAINNET:
|
|
329
|
+
// return rariChain
|
|
330
|
+
// case Chain.GLUE_MAINNET:
|
|
331
|
+
// return glue
|
|
332
|
+
default: throw new Error("Not in VIEM: " + chain)
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const RPC_OVERRIDES: any = {
|
|
337
|
+
[Chain.FANTOM_OPERA]: "https://rpc.fantom.network",
|
|
338
|
+
[Chain.BNB_SMART_CHAIN_MAINNET]: "https://bsc-dataseed2.ninicoin.io",
|
|
339
|
+
[Chain.METIS_ANDROMEDA_MAINNET]: "https://andromeda.metis.io/?owner=1088",
|
|
340
|
+
[Chain.X_LAYER_MAINNET]: "https://xlayerrpc.okx.com",
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function trimTrailingSlash(url?: string) {
|
|
344
|
+
if (!url) return undefined
|
|
345
|
+
return url.endsWith('/') ? url.slice(0, -1) : url;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
export function getEvmClient(chain: string, rpcId = 0): PublicClient {
|
|
349
|
+
const chainInfo = getEvmChain(chain)
|
|
350
|
+
let rpc: string
|
|
351
|
+
if (rpcId === 0) rpc = chainInfo.rpcUrls.default.http[0]
|
|
352
|
+
else {
|
|
353
|
+
const rpcsChain = CHAIN_INFO[chain].rpc?.filter(a => !a.includes("wss://"))
|
|
354
|
+
const rpcs = chainInfo.rpcUrls.default.http.map(a => trimTrailingSlash(a))
|
|
355
|
+
const rpcsAdded = rpcsChain.map(a => trimTrailingSlash(a))
|
|
356
|
+
const allRpcs = uniq([...rpcs, ...rpcsAdded])
|
|
357
|
+
rpc = allRpcs[rpcId] as any
|
|
358
|
+
}
|
|
359
|
+
return createPublicClient({
|
|
360
|
+
chain: chainInfo as any,
|
|
361
|
+
transport: http(
|
|
362
|
+
RPC_OVERRIDES[chain] ??
|
|
363
|
+
rpc
|
|
364
|
+
)
|
|
365
|
+
}) as any
|
|
366
|
+
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const DEFAULT_BATCH_SIZE = 4096;
|
|
370
|
+
|
|
371
|
+
export function createMulticallRetry(customRpcs?: { [chainId: string]: string[] }) {
|
|
372
|
+
return async function multicallRetry(
|
|
373
|
+
chain: string,
|
|
374
|
+
calls: any[],
|
|
375
|
+
abi: any,
|
|
376
|
+
batchSize = DEFAULT_BATCH_SIZE,
|
|
377
|
+
maxRetries = 3,
|
|
378
|
+
providerId = 0,
|
|
379
|
+
allowFailure = true,
|
|
380
|
+
) {
|
|
381
|
+
try {
|
|
382
|
+
const provider = getEvmClientWithCustomRpcs(chain, providerId, customRpcs)
|
|
383
|
+
const abiIsArray = isArray(abi[0])
|
|
384
|
+
const data = await provider.multicall({
|
|
385
|
+
batchSize: DEFAULT_BATCH_SIZE,
|
|
386
|
+
contracts: calls.map((call, i) => ({
|
|
387
|
+
abi: abiIsArray ? abi?.[i] : abi,
|
|
388
|
+
address: call.address as any,
|
|
389
|
+
functionName: call.name,
|
|
390
|
+
// @ts-ignore
|
|
391
|
+
args: call.args ?? call.params ?? [],
|
|
392
|
+
})),
|
|
393
|
+
allowFailure,
|
|
394
|
+
})
|
|
395
|
+
if (allowFailure) {
|
|
396
|
+
return (data as any[]).map(
|
|
397
|
+
({ result, status }: any) => status !== "success" ? '0x' : result
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
return data
|
|
401
|
+
} catch (e) {
|
|
402
|
+
// error if max retries achieved
|
|
403
|
+
if (maxRetries === 0) throw e
|
|
404
|
+
console.log(e)
|
|
405
|
+
return await multicallRetry(chain, calls, abi, batchSize, maxRetries - 1, providerId + 1)
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function getEvmClientWithCustomRpcs(chain: string, rpcId = 0, customRpcs?: { [chainId: string]: string[] }): PublicClient {
|
|
411
|
+
const chainInfo = getEvmChain(chain)
|
|
412
|
+
let rpc: string
|
|
413
|
+
|
|
414
|
+
if (customRpcs && customRpcs[chain]) {
|
|
415
|
+
// Use custom RPC list if any (make sure that they are unique and valid)
|
|
416
|
+
const customRpcList = uniq(
|
|
417
|
+
customRpcs[chain]
|
|
418
|
+
.filter(Boolean) // Remove empty ones
|
|
419
|
+
.filter(a => !a.includes("wss://")) // filter websocket ones (like the default impl)
|
|
420
|
+
.map(url => trimTrailingSlash(url))
|
|
421
|
+
.filter((url): url is string => Boolean(url)) // Type-safe filter for defined URLs
|
|
422
|
+
)
|
|
423
|
+
|
|
424
|
+
if (customRpcList.length === 0) {
|
|
425
|
+
throw new Error(`No valid custom RPCs provided for chain ${chain}`)
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
rpc = customRpcList[rpcId % customRpcList.length]
|
|
429
|
+
} else {
|
|
430
|
+
// Fallback to existing logic
|
|
431
|
+
if (rpcId === 0) rpc = chainInfo.rpcUrls.default.http[0]
|
|
432
|
+
else {
|
|
433
|
+
const rpcsChain = CHAIN_INFO[chain].rpc?.filter(a => !a.includes("wss://"))
|
|
434
|
+
const rpcs = chainInfo.rpcUrls.default.http.map(a => trimTrailingSlash(a))
|
|
435
|
+
const rpcsAdded = rpcsChain.map(a => trimTrailingSlash(a))
|
|
436
|
+
const allRpcs = uniq([...rpcs, ...rpcsAdded])
|
|
437
|
+
rpc = allRpcs[rpcId] as any
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return createPublicClient({
|
|
442
|
+
chain: chainInfo as any,
|
|
443
|
+
transport: http(
|
|
444
|
+
RPC_OVERRIDES[chain] ??
|
|
445
|
+
rpc
|
|
446
|
+
)
|
|
447
|
+
}) as any
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
export async function multicallRetry(
|
|
451
|
+
chain: string,
|
|
452
|
+
calls: any[],
|
|
453
|
+
abi: any,
|
|
454
|
+
batchSize = DEFAULT_BATCH_SIZE,
|
|
455
|
+
maxRetries = 3,
|
|
456
|
+
providerId = 0,
|
|
457
|
+
) {
|
|
458
|
+
const defaultMulticallRetry = createMulticallRetry()
|
|
459
|
+
return defaultMulticallRetry(chain, calls, abi, batchSize, maxRetries, providerId)
|
|
460
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./evm"
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "ESNext", // Ensure ESM (ES Modules) output
|
|
5
|
+
"target": "ESNext", // Output code that targets the latest ES features
|
|
6
|
+
"moduleResolution": "node", // Use Node.js module resolution
|
|
7
|
+
"esModuleInterop": true, // For compatibility with commonjs
|
|
8
|
+
"outDir": "dist", // Specify output directory
|
|
9
|
+
"rootDir": "src", // Specify output directory
|
|
10
|
+
"declaration": true, // Generate .d.ts files
|
|
11
|
+
"declarationMap": true, // Generate declaration map files
|
|
12
|
+
"allowJs": true, // Allow JavaScript files to be included
|
|
13
|
+
"resolveJsonModule": true, // Allow importing JSON files
|
|
14
|
+
"skipLibCheck": true, // Skip type checking of all declaration files
|
|
15
|
+
"strict": true, // Enable strict type checking
|
|
16
|
+
"isolatedModules": true // Allow isolated module builds
|
|
17
|
+
},
|
|
18
|
+
"include": [
|
|
19
|
+
"src/*"
|
|
20
|
+
], // Include all the TypeScript files in src/
|
|
21
|
+
"exclude": [
|
|
22
|
+
"node_modules",
|
|
23
|
+
"dist"
|
|
24
|
+
] // Exclude node_modules and dist from being compiled
|
|
25
|
+
}
|