@1delta/providers 0.0.41 → 0.0.43
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/{_esm-NMEXBKYZ.mjs → _esm-BLSSJTMS.mjs} +33 -33
- package/dist/{ccip-3Y4YD27I.mjs → ccip-P6QKYDYG.mjs} +1 -1
- package/dist/{chunk-7BYOX3YW.mjs → chunk-GGVKF6RL.mjs} +175 -129
- package/dist/index.d.mts +582 -160
- package/dist/index.d.ts +582 -160
- package/dist/index.js +1424 -1193
- package/dist/index.mjs +815 -640
- package/package.json +5 -6
- package/src/chains/chainMapping.ts +314 -0
- package/src/chains/customChains.ts +202 -0
- package/src/client/client.ts +110 -0
- package/src/evm.ts +7 -1067
- package/src/multicall/multicall.ts +250 -0
- package/src/rpc/rpcOverrides.ts +248 -0
- package/src/transport/transport.ts +17 -0
- package/src/utils/utils.ts +55 -0
- package/test/contract.ts +204 -0
- package/test/multicallRetry.test.ts +808 -0
- package/test/multicallRetry.testUtils.ts +181 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseError,
|
|
3
|
+
ContractFunctionExecutionError,
|
|
4
|
+
ContractFunctionRevertedError,
|
|
5
|
+
} from 'viem'
|
|
6
|
+
import { LIST_OVERRIDES } from '../rpc/rpcOverrides'
|
|
7
|
+
import { getEvmClientWithCustomRpcsUniversal } from '../client/client'
|
|
8
|
+
import { DEFAULT_BATCH_SIZE, deepCompare, isArray } from '../utils/utils'
|
|
9
|
+
|
|
10
|
+
/** Return true if it is a revert case */
|
|
11
|
+
function isContractRevert(e: unknown): boolean {
|
|
12
|
+
if (!(e instanceof BaseError)) return false
|
|
13
|
+
|
|
14
|
+
// Walk the cause chain
|
|
15
|
+
let err: BaseError | null = e
|
|
16
|
+
while (err) {
|
|
17
|
+
// Strong signal
|
|
18
|
+
if (err instanceof ContractFunctionRevertedError) return true
|
|
19
|
+
|
|
20
|
+
// Weaker but common signal
|
|
21
|
+
if (
|
|
22
|
+
err.name === 'ContractFunctionRevertedError' ||
|
|
23
|
+
err.message?.toLowerCase().includes('execution reverted')
|
|
24
|
+
) {
|
|
25
|
+
return true
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
err = err.cause instanceof BaseError ? err.cause : null
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface MulticallRetryParams {
|
|
35
|
+
chain: string
|
|
36
|
+
calls: any[]
|
|
37
|
+
abi: any
|
|
38
|
+
batchSize?: number
|
|
39
|
+
maxRetries?: number
|
|
40
|
+
providerId?: number
|
|
41
|
+
allowFailure?: boolean
|
|
42
|
+
overrdies?: Record<string, string[]>
|
|
43
|
+
logErrors?: boolean
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function createMulticallRetry(
|
|
47
|
+
customRpcs: Record<string, string[]> = LIST_OVERRIDES,
|
|
48
|
+
) {
|
|
49
|
+
return async function multicallRetry(
|
|
50
|
+
chain: string,
|
|
51
|
+
calls: any[],
|
|
52
|
+
abi: any,
|
|
53
|
+
batchSize = DEFAULT_BATCH_SIZE,
|
|
54
|
+
maxRetries = 3,
|
|
55
|
+
providerId = 0,
|
|
56
|
+
allowFailure = true,
|
|
57
|
+
logErrors = false,
|
|
58
|
+
revertedIndices: Set<number> = new Set(),
|
|
59
|
+
): Promise<any[]> {
|
|
60
|
+
const abiIsArray = isArray(abi[0])
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const nonRevertedIndices = calls
|
|
64
|
+
.map((_, i) => i)
|
|
65
|
+
.filter((i) => !revertedIndices.has(i))
|
|
66
|
+
|
|
67
|
+
const filteredCalls = nonRevertedIndices.map((i) => calls[i])
|
|
68
|
+
const filteredAbi = abiIsArray
|
|
69
|
+
? nonRevertedIndices.map((i) => abi[i])
|
|
70
|
+
: abi
|
|
71
|
+
|
|
72
|
+
const provider = getEvmClientWithCustomRpcsUniversal({
|
|
73
|
+
chain,
|
|
74
|
+
rpcId: providerId,
|
|
75
|
+
customRpcs,
|
|
76
|
+
})
|
|
77
|
+
const data = await provider.multicall({
|
|
78
|
+
batchSize,
|
|
79
|
+
contracts: filteredCalls.map((call, i) => ({
|
|
80
|
+
abi: abiIsArray ? filteredAbi[i] : filteredAbi,
|
|
81
|
+
address: call.address as any,
|
|
82
|
+
functionName: call.name,
|
|
83
|
+
args: call.args ?? call.params ?? [],
|
|
84
|
+
})),
|
|
85
|
+
allowFailure: false,
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
if (revertedIndices.size > 0) {
|
|
89
|
+
const finalResults: any[] = []
|
|
90
|
+
let filteredIndex = 0
|
|
91
|
+
|
|
92
|
+
for (let i = 0; i < calls.length; i++) {
|
|
93
|
+
if (revertedIndices.has(i)) {
|
|
94
|
+
finalResults.push('0x')
|
|
95
|
+
} else {
|
|
96
|
+
finalResults.push(data[filteredIndex++])
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return finalResults
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return data
|
|
103
|
+
} catch (e) {
|
|
104
|
+
if (isContractRevert(e)) {
|
|
105
|
+
const error = e as ContractFunctionExecutionError
|
|
106
|
+
const errorAddress = (error as any).contractAddress?.toLowerCase()
|
|
107
|
+
const errorFunctionName = error.functionName
|
|
108
|
+
const errorArgs = (error as any).args
|
|
109
|
+
|
|
110
|
+
const nonRevertedIndices = calls
|
|
111
|
+
.map((_, i) => i)
|
|
112
|
+
.filter((i) => !revertedIndices.has(i))
|
|
113
|
+
|
|
114
|
+
const matchingIndices: number[] = []
|
|
115
|
+
for (let i = 0; i < nonRevertedIndices.length; i++) {
|
|
116
|
+
const originalIndex = nonRevertedIndices[i]
|
|
117
|
+
const call = calls[originalIndex]
|
|
118
|
+
const callAddress = call.address?.toLowerCase()
|
|
119
|
+
const callFunctionName = call.name
|
|
120
|
+
const callArgs = call.args ?? call.params ?? []
|
|
121
|
+
|
|
122
|
+
const addressMatch = errorAddress && callAddress === errorAddress
|
|
123
|
+
const functionMatch = errorFunctionName === callFunctionName
|
|
124
|
+
const argsMatch = deepCompare(errorArgs, callArgs)
|
|
125
|
+
|
|
126
|
+
if (addressMatch && functionMatch && argsMatch) {
|
|
127
|
+
matchingIndices.push(originalIndex)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (matchingIndices.length > 0) {
|
|
132
|
+
const newRevertedIndices = new Set(revertedIndices)
|
|
133
|
+
matchingIndices.forEach((idx) => newRevertedIndices.add(idx))
|
|
134
|
+
|
|
135
|
+
if (newRevertedIndices.size === calls.length) {
|
|
136
|
+
return Array(calls.length).fill('0x')
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return await multicallRetry(
|
|
140
|
+
chain,
|
|
141
|
+
calls,
|
|
142
|
+
abi,
|
|
143
|
+
batchSize,
|
|
144
|
+
maxRetries,
|
|
145
|
+
providerId,
|
|
146
|
+
allowFailure,
|
|
147
|
+
logErrors,
|
|
148
|
+
newRevertedIndices,
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (maxRetries === 0) {
|
|
154
|
+
if (!allowFailure) throw e
|
|
155
|
+
if (logErrors) console.debug(e)
|
|
156
|
+
return Array(calls.length).fill('0x')
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (logErrors) console.debug(e)
|
|
160
|
+
|
|
161
|
+
return await multicallRetry(
|
|
162
|
+
chain,
|
|
163
|
+
calls,
|
|
164
|
+
abi,
|
|
165
|
+
batchSize,
|
|
166
|
+
maxRetries - 1,
|
|
167
|
+
providerId + 1,
|
|
168
|
+
allowFailure,
|
|
169
|
+
logErrors,
|
|
170
|
+
revertedIndices,
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async function multicallRetryInternal(
|
|
177
|
+
chain: string,
|
|
178
|
+
calls: any[],
|
|
179
|
+
abi: any,
|
|
180
|
+
batchSize = DEFAULT_BATCH_SIZE,
|
|
181
|
+
maxRetries = 5,
|
|
182
|
+
providerId = 0,
|
|
183
|
+
allowFailure = false,
|
|
184
|
+
overrdies: Record<string, string[]> = LIST_OVERRIDES,
|
|
185
|
+
logErrors = false,
|
|
186
|
+
) {
|
|
187
|
+
const defaultMulticallRetry = createMulticallRetry(overrdies)
|
|
188
|
+
return defaultMulticallRetry(
|
|
189
|
+
chain,
|
|
190
|
+
calls,
|
|
191
|
+
abi,
|
|
192
|
+
batchSize,
|
|
193
|
+
maxRetries,
|
|
194
|
+
providerId,
|
|
195
|
+
allowFailure,
|
|
196
|
+
logErrors,
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* @deprecated use multicallRetryUniversal instead
|
|
202
|
+
* @see multicallRetryUniversal
|
|
203
|
+
*/
|
|
204
|
+
export async function multicallRetry(
|
|
205
|
+
chain: string,
|
|
206
|
+
calls: any[],
|
|
207
|
+
abi: any,
|
|
208
|
+
batchSize = DEFAULT_BATCH_SIZE,
|
|
209
|
+
maxRetries = 5,
|
|
210
|
+
providerId = 0,
|
|
211
|
+
allowFailure = false,
|
|
212
|
+
overrdies: Record<string, string[]> = LIST_OVERRIDES,
|
|
213
|
+
logErrors = false,
|
|
214
|
+
) {
|
|
215
|
+
return multicallRetryInternal(
|
|
216
|
+
chain,
|
|
217
|
+
calls,
|
|
218
|
+
abi,
|
|
219
|
+
batchSize,
|
|
220
|
+
maxRetries,
|
|
221
|
+
providerId,
|
|
222
|
+
allowFailure,
|
|
223
|
+
overrdies,
|
|
224
|
+
logErrors,
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export async function multicallRetryUniversal({
|
|
229
|
+
chain,
|
|
230
|
+
calls,
|
|
231
|
+
abi,
|
|
232
|
+
batchSize = DEFAULT_BATCH_SIZE,
|
|
233
|
+
maxRetries = 5,
|
|
234
|
+
providerId = 0,
|
|
235
|
+
allowFailure = false,
|
|
236
|
+
overrdies = LIST_OVERRIDES,
|
|
237
|
+
logErrors = false,
|
|
238
|
+
}: MulticallRetryParams) {
|
|
239
|
+
return multicallRetryInternal(
|
|
240
|
+
chain,
|
|
241
|
+
calls,
|
|
242
|
+
abi,
|
|
243
|
+
batchSize,
|
|
244
|
+
maxRetries,
|
|
245
|
+
providerId,
|
|
246
|
+
allowFailure,
|
|
247
|
+
overrdies,
|
|
248
|
+
logErrors,
|
|
249
|
+
)
|
|
250
|
+
}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { Chain } from '@1delta/chain-registry'
|
|
2
|
+
|
|
3
|
+
export const LIST_OVERRIDES: Record<string, string[]> = {
|
|
4
|
+
[Chain.BASE]: [
|
|
5
|
+
'https://base-rpc.publicnode.com',
|
|
6
|
+
'https://base.llamarpc.com',
|
|
7
|
+
'https://base.public.blockpi.network/v1/rpc/public',
|
|
8
|
+
'https://1rpc.io/base',
|
|
9
|
+
'https://base-pokt.nodies.app',
|
|
10
|
+
'https://base.meowrpc.com',
|
|
11
|
+
'https://developer-access-mainnet.base.org',
|
|
12
|
+
'https://base.drpc.org',
|
|
13
|
+
'https://base.api.onfinality.io/public',
|
|
14
|
+
'https://base.rpc.subquery.network/public',
|
|
15
|
+
'https://api.zan.top/base-mainnet',
|
|
16
|
+
'https://endpoints.omniatech.io/v1/base/mainnet/public',
|
|
17
|
+
'https://base.lava.build',
|
|
18
|
+
'https://0xrpc.io/base',
|
|
19
|
+
'https://base.therpc.io',
|
|
20
|
+
],
|
|
21
|
+
[Chain.POLYGON_MAINNET]: [
|
|
22
|
+
'https://polygon-bor-rpc.publicnode.com',
|
|
23
|
+
'https://polygon.lava.build',
|
|
24
|
+
'https://polygon.drpc.org',
|
|
25
|
+
'https://gateway.tenderly.co/public/polygon',
|
|
26
|
+
'https://endpoints.omniatech.io/v1/matic/mainnet/public',
|
|
27
|
+
'https://polygon.therpc.io',
|
|
28
|
+
'https://rpc-mainnet.matic.quiknode.pro',
|
|
29
|
+
'https://polygon-pokt.nodies.app',
|
|
30
|
+
'https://polygon.gateway.tenderly.co',
|
|
31
|
+
'https://polygon-rpc.com',
|
|
32
|
+
'https://polygon.api.onfinality.io/public',
|
|
33
|
+
'https://api.zan.top/polygon-mainnet',
|
|
34
|
+
'https://polygon.rpc.subquery.network/public',
|
|
35
|
+
'https://polygon-mainnet.nodereal.io/v1/f510fc4d083b49d1ab383d25246cc7de',
|
|
36
|
+
'wss://polygon-mainnet.nodereal.io/ws/v1/f510fc4d083b49d1ab383d25246cc7de',
|
|
37
|
+
],
|
|
38
|
+
[Chain.HEMI_NETWORK]: ['https://rpc.hemi.network/rpc'],
|
|
39
|
+
[Chain.MANTLE]: [
|
|
40
|
+
'https://rpc.mantle.xyz',
|
|
41
|
+
'https://1rpc.io/mantle',
|
|
42
|
+
'https://api.zan.top/mantle-mainnet',
|
|
43
|
+
'https://mantle-public.nodies.app',
|
|
44
|
+
'https://mantle.drpc.org',
|
|
45
|
+
],
|
|
46
|
+
[Chain.XDC_NETWORK]: [
|
|
47
|
+
'https://rpc.ankr.com/xdc',
|
|
48
|
+
'https://earpc.xinfin.network',
|
|
49
|
+
'https://rpc.xinfin.network',
|
|
50
|
+
'https://rpc.xdc.org',
|
|
51
|
+
'https://rpc.xdc.network',
|
|
52
|
+
'https://erpc.xdcrpc.com',
|
|
53
|
+
],
|
|
54
|
+
[Chain.ETHEREUM_MAINNET]: [
|
|
55
|
+
'https://eth.llamarpc.com',
|
|
56
|
+
'https://api.zan.top/eth-mainnet',
|
|
57
|
+
'https://rpc.flashbots.net/fast',
|
|
58
|
+
'https://rpc.owlracle.info/eth/70d38ce1826c4a60bb2a8e05a6c8b20f',
|
|
59
|
+
'https://eth.merkle.io',
|
|
60
|
+
'https://eth-mainnet.nodereal.io/v1/1659dfb40aa24bbb8153a677b98064d7',
|
|
61
|
+
'wss://eth-mainnet.nodereal.io/ws/v1/1659dfb40aa24bbb8153a677b98064d7',
|
|
62
|
+
'https://rpc.payload.de',
|
|
63
|
+
'https://ethereum-rpc.publicnode.com',
|
|
64
|
+
'https://eth-mainnet.g.alchemy.com/v2/demo',
|
|
65
|
+
'https://go.getblock.io/aefd01aa907c4805ba3c00a9e5b48c6b',
|
|
66
|
+
'https://rpc.flashbots.net',
|
|
67
|
+
'https://public-eth.nownodes.io',
|
|
68
|
+
'https://ethereum-json-rpc.stakely.io',
|
|
69
|
+
'https://eth.blockrazor.xyz',
|
|
70
|
+
'https://eth.drpc.org',
|
|
71
|
+
'https://ethereum.public.blockpi.network/v1/rpc/public',
|
|
72
|
+
'https://ethereum-public.nodies.app',
|
|
73
|
+
'https://0xrpc.io/eth',
|
|
74
|
+
],
|
|
75
|
+
[Chain.PLASMA_MAINNET]: ['https://rpc.plasma.to', 'https://plasma.drpc.org'],
|
|
76
|
+
[Chain.SCROLL]: [
|
|
77
|
+
'https://rpc.scroll.io',
|
|
78
|
+
'https://1rpc.io/scroll',
|
|
79
|
+
'https://scroll.drpc.org',
|
|
80
|
+
'https://scroll.api.onfinality.io/public',
|
|
81
|
+
'https://endpoints.omniatech.io/v1/scroll/mainnet/public',
|
|
82
|
+
'https://scroll-rpc.publicnode.com',
|
|
83
|
+
'https://scroll.therpc.io',
|
|
84
|
+
],
|
|
85
|
+
[Chain.SONIC_MAINNET]: [
|
|
86
|
+
'https://sonic.api.onfinality.io/public',
|
|
87
|
+
'https://sonic-rpc.publicnode.com',
|
|
88
|
+
'https://rpc.soniclabs.com',
|
|
89
|
+
'https://sonic.therpc.io',
|
|
90
|
+
'https://sonic.drpc.org',
|
|
91
|
+
'https://sonic-json-rpc.stakely.io',
|
|
92
|
+
],
|
|
93
|
+
[Chain.KAIA_MAINNET]: [
|
|
94
|
+
'https://public-en.node.kaia.io',
|
|
95
|
+
'https://klaytn.api.onfinality.io/public',
|
|
96
|
+
'https://kaia-mainnet.gateway.tatum.io',
|
|
97
|
+
'https://kaia-public.nodies.app',
|
|
98
|
+
'https://kaia.blockpi.network/v1/rpc/public',
|
|
99
|
+
'https://rpc.ankr.com/kaia',
|
|
100
|
+
'https://klaytn.drpc.org',
|
|
101
|
+
'https://1rpc.io/klay',
|
|
102
|
+
],
|
|
103
|
+
[Chain.MOONBEAM]: [
|
|
104
|
+
'https://moonbeam.unitedbloc.com',
|
|
105
|
+
'https://1rpc.io/glmr',
|
|
106
|
+
'https://moonbeam-rpc.dwellir.com',
|
|
107
|
+
'https://moonbeam-rpc.publicnode.com',
|
|
108
|
+
'https://moonbeam.drpc.org',
|
|
109
|
+
'https://endpoints.omniatech.io/v1/moonbeam/mainnet/public',
|
|
110
|
+
'https://rpc.api.moonbeam.network',
|
|
111
|
+
'https://rpc.poolz.finance/moonbeam',
|
|
112
|
+
'https://moonbeam.rpc.grove.city/v1/01fdb492',
|
|
113
|
+
'https://moonbeam.api.onfinality.io/public',
|
|
114
|
+
],
|
|
115
|
+
[Chain.OP_MAINNET]: [
|
|
116
|
+
'https://optimism.public.blockpi.network/v1/rpc/public',
|
|
117
|
+
'https://optimism-rpc.publicnode.com',
|
|
118
|
+
'https://optimism.drpc.org',
|
|
119
|
+
'https://0xrpc.io/op',
|
|
120
|
+
'https://1rpc.io/op',
|
|
121
|
+
'wss://optimism-rpc.publicnode.com',
|
|
122
|
+
'wss://0xrpc.io/op',
|
|
123
|
+
'wss://optimism.drpc.org',
|
|
124
|
+
'https://optimism.api.onfinality.io/public',
|
|
125
|
+
'https://api.zan.top/opt-mainnet',
|
|
126
|
+
],
|
|
127
|
+
[Chain.BNB_SMART_CHAIN_MAINNET]: [
|
|
128
|
+
'https://bsc-dataseed.bnbchain.org',
|
|
129
|
+
'https://binance.nodereal.io',
|
|
130
|
+
'https://bsc-mainnet.nodereal.io/v1/64a9df0874fb4a93b9d0a3849de012d3',
|
|
131
|
+
'wss://bsc-mainnet.nodereal.io/ws/v1/64a9df0874fb4a93b9d0a3849de012d3',
|
|
132
|
+
'https://bsc-dataseed.binance.org',
|
|
133
|
+
'https://bsc-dataseed1.binance.org',
|
|
134
|
+
'https://bsc-dataseed1.defibit.io',
|
|
135
|
+
'https://bsc-dataseed2.defibit.io',
|
|
136
|
+
'https://bsc-dataseed3.defibit.io',
|
|
137
|
+
'https://bsc-dataseed4.defibit.io',
|
|
138
|
+
'https://1rpc.io/bnb',
|
|
139
|
+
'https://bsc-rpc.publicnode.com',
|
|
140
|
+
'https://bsc.drpc.org',
|
|
141
|
+
'https://bsc.api.onfinality.io/public',
|
|
142
|
+
],
|
|
143
|
+
[Chain.ARBITRUM_ONE]: [
|
|
144
|
+
'https://arb1.lava.build',
|
|
145
|
+
'https://arb1.arbitrum.io/rpc',
|
|
146
|
+
'https://arbitrum-one-rpc.publicnode.com',
|
|
147
|
+
'https://arbitrum.drpc.org',
|
|
148
|
+
'https://arbitrum.public.blockpi.network/v1/rpc/public',
|
|
149
|
+
'https://1rpc.io/arb',
|
|
150
|
+
'https://arbitrum.api.onfinality.io/public',
|
|
151
|
+
'https://0xrpc.io/arb',
|
|
152
|
+
'https://arbitrum.therpc.io',
|
|
153
|
+
],
|
|
154
|
+
[Chain.LINEA]: [
|
|
155
|
+
'https://rpc.linea.build',
|
|
156
|
+
'https://1rpc.io/linea',
|
|
157
|
+
'https://linea.drpc.org',
|
|
158
|
+
'https://linea-rpc.publicnode.com',
|
|
159
|
+
'https://linea.decubate.com',
|
|
160
|
+
'https://linea.api.onfinality.io/public',
|
|
161
|
+
],
|
|
162
|
+
[Chain.AVALANCHE_C_CHAIN]: [
|
|
163
|
+
'https://avalanche.drpc.org',
|
|
164
|
+
'https://1rpc.io/avax/c',
|
|
165
|
+
'https://avalanche-c-chain-rpc.publicnode.com',
|
|
166
|
+
'https://avalanche.api.onfinality.io/public/ext/bc/C/rpc',
|
|
167
|
+
'https://api.avax.network/ext/bc/C/rpc',
|
|
168
|
+
'https://avalanche.public-rpc.com',
|
|
169
|
+
'https://avax-rpc.gateway.pokt.network',
|
|
170
|
+
],
|
|
171
|
+
[Chain.CELO_MAINNET]: [
|
|
172
|
+
'https://forno.celo.org',
|
|
173
|
+
'https://1rpc.io/celo',
|
|
174
|
+
'https://celo.drpc.org',
|
|
175
|
+
'https://celo-rpc.publicnode.com',
|
|
176
|
+
],
|
|
177
|
+
[Chain.BLAST]: [
|
|
178
|
+
'https://rpc.blast.io',
|
|
179
|
+
'https://blast.drpc.org',
|
|
180
|
+
'https://blast-rpc.publicnode.com',
|
|
181
|
+
],
|
|
182
|
+
[Chain.TAIKO_ALETHIA]: [
|
|
183
|
+
'https://rpc.taiko.xyz',
|
|
184
|
+
'https://rpc.ankr.com/taiko',
|
|
185
|
+
'https://rpc.mainnet.taiko.xyz',
|
|
186
|
+
'https://taiko-rpc.publicnode.com',
|
|
187
|
+
],
|
|
188
|
+
[Chain.GNOSIS]: [
|
|
189
|
+
'https://gnosis.oat.farm',
|
|
190
|
+
'https://rpc.gnosischain.com',
|
|
191
|
+
'https://gnosis.drpc.org',
|
|
192
|
+
'https://gnosis-rpc.publicnode.com',
|
|
193
|
+
'https://1rpc.io/gnosis',
|
|
194
|
+
],
|
|
195
|
+
[Chain.CORE_BLOCKCHAIN_MAINNET]: [
|
|
196
|
+
'https://rpc.coredao.org',
|
|
197
|
+
'https://core.drpc.org',
|
|
198
|
+
'https://core-rpc.publicnode.com',
|
|
199
|
+
],
|
|
200
|
+
[Chain.MODE]: [
|
|
201
|
+
'https://mainnet.mode.network',
|
|
202
|
+
'https://mode.drpc.org',
|
|
203
|
+
'https://mode-rpc.publicnode.com',
|
|
204
|
+
],
|
|
205
|
+
[Chain.METIS_ANDROMEDA_MAINNET]: [
|
|
206
|
+
'https://andromeda.metis.io/?owner=1088',
|
|
207
|
+
'https://metis.drpc.org',
|
|
208
|
+
'https://metis-rpc.publicnode.com',
|
|
209
|
+
'https://metis.api.onfinality.io/public',
|
|
210
|
+
],
|
|
211
|
+
[Chain.FANTOM_OPERA]: [
|
|
212
|
+
'https://rpc.fantom.network',
|
|
213
|
+
'https://fantom.drpc.org',
|
|
214
|
+
'https://fantom-rpc.publicnode.com',
|
|
215
|
+
'https://1rpc.io/ftm',
|
|
216
|
+
'https://fantom.api.onfinality.io/public',
|
|
217
|
+
],
|
|
218
|
+
[Chain.OPBNB_MAINNET]: [
|
|
219
|
+
'https://opbnb-mainnet.nodereal.io/v1/64a9df0874fb4a93b9d0a3849de012d3',
|
|
220
|
+
'wss://opbnb-mainnet.nodereal.io/ws/v1/64a9df0874fb4a93b9d0a3849de012d3',
|
|
221
|
+
],
|
|
222
|
+
[Chain.X_LAYER_MAINNET]: ['https://xlayerrpc.okx.com'],
|
|
223
|
+
[Chain.MANTA_PACIFIC_MAINNET]: [
|
|
224
|
+
'https://manta.nirvanalabs.xyz/mantapublic',
|
|
225
|
+
'https://manta-pacific-gascap.calderachain.xyz/http',
|
|
226
|
+
'https://manta-pacific.calderachain.xyz/http',
|
|
227
|
+
'https://pacific-rpc.manta.network/http',
|
|
228
|
+
'https://r1.pacific.manta.systems/http',
|
|
229
|
+
'wss://manta-pacific.calderachain.xyz/ws',
|
|
230
|
+
'https://1rpc.io/manta',
|
|
231
|
+
],
|
|
232
|
+
[Chain.SEI_NETWORK]: [
|
|
233
|
+
'https://evm-rpc.sei-apis.com',
|
|
234
|
+
'https://sei.drpc.org',
|
|
235
|
+
'https://sei-evm-rpc.stakeme.pro',
|
|
236
|
+
'https://sei-public.nodies.app',
|
|
237
|
+
'wss://sei.drpc.org',
|
|
238
|
+
'wss://evm-ws.sei-apis.com',
|
|
239
|
+
],
|
|
240
|
+
[Chain.MONAD_MAINNET]: [
|
|
241
|
+
'https://rpc-mainnet.monadinfra.com',
|
|
242
|
+
'https://rpc.monad.xyz',
|
|
243
|
+
'https://rpc1.monad.xyz',
|
|
244
|
+
'https://rpc2.monad.xyz',
|
|
245
|
+
'https://rpc3.monad.xyz',
|
|
246
|
+
'https://rpc4.monad.xyz',
|
|
247
|
+
],
|
|
248
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { http, webSocket } from 'viem'
|
|
2
|
+
|
|
3
|
+
export function createTransport(url: string, config?: any) {
|
|
4
|
+
if (!url) throw new Error('URL is required for transport')
|
|
5
|
+
const retryConfig = {
|
|
6
|
+
...config,
|
|
7
|
+
retryCount: config?.retryCount ?? 0, // this is critical, especially for multicall failures where the reason for failure is rpc realted issues
|
|
8
|
+
}
|
|
9
|
+
if (url.startsWith('wss://')) {
|
|
10
|
+
return webSocket(url, retryConfig)
|
|
11
|
+
}
|
|
12
|
+
return http(url, retryConfig)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getTransport(url: string) {
|
|
16
|
+
return createTransport(url)
|
|
17
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export const DEFAULT_BATCH_SIZE = 4096
|
|
2
|
+
|
|
3
|
+
export function trimTrailingSlash(url?: string) {
|
|
4
|
+
if (!url) return undefined
|
|
5
|
+
return url.endsWith('/') ? url.slice(0, -1) : url
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function deepCompare(a: any, b: any): boolean {
|
|
9
|
+
if (a === b) return true
|
|
10
|
+
|
|
11
|
+
if (a == null || b == null) return false
|
|
12
|
+
|
|
13
|
+
const typeA = typeof a
|
|
14
|
+
const typeB = typeof b
|
|
15
|
+
|
|
16
|
+
if (typeA !== typeB) return false
|
|
17
|
+
|
|
18
|
+
if (typeA === 'bigint') return false
|
|
19
|
+
|
|
20
|
+
if (typeA !== 'object') return false
|
|
21
|
+
|
|
22
|
+
const isArrayA = Array.isArray(a)
|
|
23
|
+
const isArrayB = Array.isArray(b)
|
|
24
|
+
|
|
25
|
+
if (isArrayA !== isArrayB) return false
|
|
26
|
+
|
|
27
|
+
if (isArrayA) {
|
|
28
|
+
if (a.length !== b.length) return false
|
|
29
|
+
for (let i = 0; i < a.length; i++) {
|
|
30
|
+
if (!deepCompare(a[i], b[i])) return false
|
|
31
|
+
}
|
|
32
|
+
return true
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const keysA = Object.keys(a)
|
|
36
|
+
const keysB = Object.keys(b)
|
|
37
|
+
|
|
38
|
+
if (keysA.length !== keysB.length) return false
|
|
39
|
+
|
|
40
|
+
for (let i = 0; i < keysA.length; i++) {
|
|
41
|
+
const key = keysA[i]
|
|
42
|
+
if (!Object.prototype.hasOwnProperty.call(b, key)) return false
|
|
43
|
+
if (!deepCompare(a[key], b[key])) return false
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return true
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function uniq<T>(array: T[]): T[] {
|
|
50
|
+
return [...new Set(array)]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function isArray(value: any): boolean {
|
|
54
|
+
return Array.isArray(value)
|
|
55
|
+
}
|