@0xtorch/evm 0.0.122 → 0.0.124
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/_cjs/chain/definitions/arbitrumOne.js +0 -10
- package/_cjs/chain/definitions/arbitrumOne.js.map +1 -1
- package/_cjs/chain/definitions/avalancheC.js +0 -5
- package/_cjs/chain/definitions/avalancheC.js.map +1 -1
- package/_cjs/chain/definitions/base.js +0 -5
- package/_cjs/chain/definitions/base.js.map +1 -1
- package/_cjs/chain/definitions/blast.js +0 -10
- package/_cjs/chain/definitions/blast.js.map +1 -1
- package/_cjs/chain/definitions/bsc.js +8 -13
- package/_cjs/chain/definitions/bsc.js.map +1 -1
- package/_cjs/chain/definitions/ethereum.js +1 -6
- package/_cjs/chain/definitions/ethereum.js.map +1 -1
- package/_cjs/chain/definitions/fantom.js +0 -10
- package/_cjs/chain/definitions/fantom.js.map +1 -1
- package/_cjs/chain/definitions/linea.js +0 -5
- package/_cjs/chain/definitions/linea.js.map +1 -1
- package/_cjs/chain/definitions/mantaPacific.js +0 -5
- package/_cjs/chain/definitions/mantaPacific.js.map +1 -1
- package/_cjs/chain/definitions/opBnb.js +2 -2
- package/_cjs/chain/definitions/opBnb.js.map +1 -1
- package/_cjs/chain/definitions/optimism.js +2 -22
- package/_cjs/chain/definitions/optimism.js.map +1 -1
- package/_cjs/chain/definitions/polygonPos.js +2 -7
- package/_cjs/chain/definitions/polygonPos.js.map +1 -1
- package/_cjs/chain/definitions/polygonZkEvm.js +0 -5
- package/_cjs/chain/definitions/polygonZkEvm.js.map +1 -1
- package/_cjs/chain/definitions/ronin.js +0 -10
- package/_cjs/chain/definitions/ronin.js.map +1 -1
- package/_cjs/chain/definitions/scroll.js +2 -7
- package/_cjs/chain/definitions/scroll.js.map +1 -1
- package/_cjs/chain/definitions/zkSyncEra.js +0 -10
- package/_cjs/chain/definitions/zkSyncEra.js.map +1 -1
- package/_cjs/client/create.js +120 -67
- package/_cjs/client/create.js.map +1 -1
- package/_esm/chain/definitions/arbitrumOne.js +12 -10
- package/_esm/chain/definitions/arbitrumOne.js.map +1 -1
- package/_esm/chain/definitions/avalancheC.js +6 -5
- package/_esm/chain/definitions/avalancheC.js.map +1 -1
- package/_esm/chain/definitions/base.js +6 -5
- package/_esm/chain/definitions/base.js.map +1 -1
- package/_esm/chain/definitions/blast.js +12 -10
- package/_esm/chain/definitions/blast.js.map +1 -1
- package/_esm/chain/definitions/bsc.js +14 -13
- package/_esm/chain/definitions/bsc.js.map +1 -1
- package/_esm/chain/definitions/ethereum.js +8 -7
- package/_esm/chain/definitions/ethereum.js.map +1 -1
- package/_esm/chain/definitions/fantom.js +12 -10
- package/_esm/chain/definitions/fantom.js.map +1 -1
- package/_esm/chain/definitions/linea.js +6 -5
- package/_esm/chain/definitions/linea.js.map +1 -1
- package/_esm/chain/definitions/mantaPacific.js +6 -5
- package/_esm/chain/definitions/mantaPacific.js.map +1 -1
- package/_esm/chain/definitions/opBnb.js +2 -2
- package/_esm/chain/definitions/opBnb.js.map +1 -1
- package/_esm/chain/definitions/optimism.js +26 -22
- package/_esm/chain/definitions/optimism.js.map +1 -1
- package/_esm/chain/definitions/polygonPos.js +8 -7
- package/_esm/chain/definitions/polygonPos.js.map +1 -1
- package/_esm/chain/definitions/polygonZkEvm.js +6 -5
- package/_esm/chain/definitions/polygonZkEvm.js.map +1 -1
- package/_esm/chain/definitions/ronin.js +12 -10
- package/_esm/chain/definitions/ronin.js.map +1 -1
- package/_esm/chain/definitions/scroll.js +8 -7
- package/_esm/chain/definitions/scroll.js.map +1 -1
- package/_esm/chain/definitions/zkSyncEra.js +12 -10
- package/_esm/chain/definitions/zkSyncEra.js.map +1 -1
- package/_esm/client/create.js +121 -67
- package/_esm/client/create.js.map +1 -1
- package/_types/chain/definitions/arbitrumOne.d.ts.map +1 -1
- package/_types/chain/definitions/avalancheC.d.ts.map +1 -1
- package/_types/chain/definitions/base.d.ts.map +1 -1
- package/_types/chain/definitions/blast.d.ts.map +1 -1
- package/_types/chain/definitions/bsc.d.ts.map +1 -1
- package/_types/chain/definitions/ethereum.d.ts.map +1 -1
- package/_types/chain/definitions/fantom.d.ts.map +1 -1
- package/_types/chain/definitions/linea.d.ts.map +1 -1
- package/_types/chain/definitions/mantaPacific.d.ts.map +1 -1
- package/_types/chain/definitions/optimism.d.ts.map +1 -1
- package/_types/chain/definitions/polygonPos.d.ts.map +1 -1
- package/_types/chain/definitions/polygonZkEvm.d.ts.map +1 -1
- package/_types/chain/definitions/ronin.d.ts.map +1 -1
- package/_types/chain/definitions/scroll.d.ts.map +1 -1
- package/_types/chain/definitions/zkSyncEra.d.ts.map +1 -1
- package/_types/client/create.d.ts.map +1 -1
- package/chain/definitions/arbitrumOne.ts +12 -10
- package/chain/definitions/avalancheC.ts +6 -5
- package/chain/definitions/base.ts +6 -5
- package/chain/definitions/blast.ts +12 -10
- package/chain/definitions/bsc.ts +14 -13
- package/chain/definitions/ethereum.ts +8 -7
- package/chain/definitions/fantom.ts +12 -10
- package/chain/definitions/linea.ts +6 -5
- package/chain/definitions/mantaPacific.ts +6 -5
- package/chain/definitions/opBnb.ts +2 -2
- package/chain/definitions/optimism.ts +26 -22
- package/chain/definitions/polygonPos.ts +8 -7
- package/chain/definitions/polygonZkEvm.ts +6 -5
- package/chain/definitions/ronin.ts +12 -10
- package/chain/definitions/scroll.ts +8 -7
- package/chain/definitions/zkSyncEra.ts +12 -10
- package/client/create.ts +161 -76
- package/package.json +1 -1
- package/_cjs/client/rpcManager.js +0 -94
- package/_cjs/client/rpcManager.js.map +0 -1
- package/_esm/client/rpcManager.js +0 -90
- package/_esm/client/rpcManager.js.map +0 -1
- package/_types/client/rpcManager.d.ts +0 -20
- package/_types/client/rpcManager.d.ts.map +0 -1
- package/client/rpcManager.ts +0 -135
|
@@ -59,11 +59,12 @@ export const createFantomChainCustom = ({
|
|
|
59
59
|
})
|
|
60
60
|
|
|
61
61
|
export const fantomHttpRpcs: HttpRpc[] = [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
// Endpoint is not working
|
|
63
|
+
// {
|
|
64
|
+
// url: 'https://rpc.ankr.com/fantom/',
|
|
65
|
+
// getLogsIsUsable: true,
|
|
66
|
+
// getLogsMaxBlockRange: 3000n,
|
|
67
|
+
// },
|
|
67
68
|
{
|
|
68
69
|
url: 'https://rpcapi.fantom.network',
|
|
69
70
|
getLogsIsUsable: true,
|
|
@@ -84,11 +85,12 @@ export const fantomHttpRpcs: HttpRpc[] = [
|
|
|
84
85
|
getLogsIsUsable: true,
|
|
85
86
|
getLogsMaxBlockRange: 40_000n,
|
|
86
87
|
},
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
88
|
+
// Endpoint is not working
|
|
89
|
+
// {
|
|
90
|
+
// url: 'https://fantom.blockpi.network/v1/rpc/public',
|
|
91
|
+
// getLogsIsUsable: true,
|
|
92
|
+
// getLogsMaxBlockRange: 1024n,
|
|
93
|
+
// },
|
|
92
94
|
{
|
|
93
95
|
url: 'https://fantom.drpc.org/',
|
|
94
96
|
getLogsIsUsable: true,
|
|
@@ -59,11 +59,12 @@ export const createLineaChainCustom = ({
|
|
|
59
59
|
})
|
|
60
60
|
|
|
61
61
|
export const lineaHttpRpcs: HttpRpc[] = [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
// Endpoint is not working
|
|
63
|
+
// {
|
|
64
|
+
// url: 'https://linea.blockpi.network/v1/rpc/public',
|
|
65
|
+
// getLogsIsUsable: true,
|
|
66
|
+
// getLogsMaxBlockRange: 1024n,
|
|
67
|
+
// },
|
|
67
68
|
{
|
|
68
69
|
url: 'https://1rpc.io/linea',
|
|
69
70
|
getLogsIsUsable: true,
|
|
@@ -68,11 +68,12 @@ export const mantaPacificHttpRpcs: HttpRpc[] = [
|
|
|
68
68
|
getLogsIsUsable: true,
|
|
69
69
|
getLogsMaxBlockRange: 20_000n,
|
|
70
70
|
},
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
// Endpoint is not working
|
|
72
|
+
// {
|
|
73
|
+
// url: 'https://www.tencentcloud-rpc.com/v2/manta/manta-rpc',
|
|
74
|
+
// getLogsIsUsable: false,
|
|
75
|
+
// getLogsMaxBlockRange: 0n,
|
|
76
|
+
// },
|
|
76
77
|
{
|
|
77
78
|
url: 'https://r1.pacific.manta.systems/http',
|
|
78
79
|
getLogsIsUsable: true,
|
|
@@ -81,8 +81,8 @@ export const opBnbHttpRpcs: HttpRpc[] = [
|
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
url: 'https://opbnb-mainnet.4everland.org/v1/37fa9972c1b1cd5fab542c7bdd4cde2f',
|
|
84
|
-
getLogsIsUsable:
|
|
85
|
-
getLogsMaxBlockRange:
|
|
84
|
+
getLogsIsUsable: false,
|
|
85
|
+
getLogsMaxBlockRange: 0n,
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
88
|
url: 'https://opbnb-mainnet.nodereal.io/v1/64a9df0874fb4a93b9d0a3849de012d3',
|
|
@@ -95,11 +95,12 @@ export const optimismHttpRpcs: HttpRpc[] = [
|
|
|
95
95
|
getLogsIsUsable: true,
|
|
96
96
|
getLogsMaxBlockRange: 1024n,
|
|
97
97
|
},
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
// Not archiving receipts
|
|
99
|
+
// {
|
|
100
|
+
// url: 'https://endpoints.omniatech.io/v1/op/mainnet/public',
|
|
101
|
+
// getLogsIsUsable: true,
|
|
102
|
+
// getLogsMaxBlockRange: 3000n,
|
|
103
|
+
// },
|
|
103
104
|
{
|
|
104
105
|
url: 'https://optimism.api.onfinality.io/public',
|
|
105
106
|
getLogsIsUsable: true,
|
|
@@ -111,11 +112,12 @@ export const optimismHttpRpcs: HttpRpc[] = [
|
|
|
111
112
|
// getLogsIsUsable: true,
|
|
112
113
|
// getLogsMaxBlockRange: 4000n,
|
|
113
114
|
// },
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
// Not archiving receipts
|
|
116
|
+
// {
|
|
117
|
+
// url: 'https://optimism-rpc.publicnode.com',
|
|
118
|
+
// getLogsIsUsable: true,
|
|
119
|
+
// getLogsMaxBlockRange: 10_000n,
|
|
120
|
+
// },
|
|
119
121
|
// Not archiving receipts
|
|
120
122
|
// {
|
|
121
123
|
// url: 'https://optimism.meowrpc.com',
|
|
@@ -128,11 +130,12 @@ export const optimismHttpRpcs: HttpRpc[] = [
|
|
|
128
130
|
// getLogsIsUsable: true,
|
|
129
131
|
// getLogsMaxBlockRange: 10_000n,
|
|
130
132
|
// },
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
// Not archiving receipts
|
|
134
|
+
// {
|
|
135
|
+
// url: 'https://optimism.publicnode.com',
|
|
136
|
+
// getLogsIsUsable: true,
|
|
137
|
+
// getLogsMaxBlockRange: 10_000n,
|
|
138
|
+
// },
|
|
136
139
|
// Not archiving receipts
|
|
137
140
|
// {
|
|
138
141
|
// url: 'https://optimism.meowrpc.com',
|
|
@@ -174,14 +177,15 @@ export const optimismHttpRpcs: HttpRpc[] = [
|
|
|
174
177
|
// },
|
|
175
178
|
{
|
|
176
179
|
url: 'https://opt-mainnet.4everland.org/v1/37fa9972c1b1cd5fab542c7bdd4cde2f',
|
|
177
|
-
getLogsIsUsable:
|
|
178
|
-
getLogsMaxBlockRange:
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
url: 'https://optimism.rpc.subquery.network/public',
|
|
182
|
-
getLogsIsUsable: true,
|
|
183
|
-
getLogsMaxBlockRange: 10_000n,
|
|
180
|
+
getLogsIsUsable: false,
|
|
181
|
+
getLogsMaxBlockRange: 0n,
|
|
184
182
|
},
|
|
183
|
+
// Not archiving receipts
|
|
184
|
+
// {
|
|
185
|
+
// url: 'https://optimism.rpc.subquery.network/public',
|
|
186
|
+
// getLogsIsUsable: true,
|
|
187
|
+
// getLogsMaxBlockRange: 10_000n,
|
|
188
|
+
// },
|
|
185
189
|
]
|
|
186
190
|
|
|
187
191
|
export const optimismWebsocketRpcUrls: readonly string[] = [
|
|
@@ -59,11 +59,12 @@ export const createPolygonPosChainCustom = ({
|
|
|
59
59
|
})
|
|
60
60
|
|
|
61
61
|
export const polygonPosHttpRpcs: HttpRpc[] = [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
// Not archiving receipts
|
|
63
|
+
// {
|
|
64
|
+
// url: 'https://endpoints.omniatech.io/v1/matic/mainnet/public',
|
|
65
|
+
// getLogsIsUsable: false,
|
|
66
|
+
// getLogsMaxBlockRange: 0n,
|
|
67
|
+
// },
|
|
67
68
|
{
|
|
68
69
|
url: 'https://polygon-rpc.com',
|
|
69
70
|
getLogsIsUsable: true,
|
|
@@ -175,8 +176,8 @@ export const polygonPosHttpRpcs: HttpRpc[] = [
|
|
|
175
176
|
},
|
|
176
177
|
{
|
|
177
178
|
url: 'https://polygon-mainnet.4everland.org/v1/37fa9972c1b1cd5fab542c7bdd4cde2f',
|
|
178
|
-
getLogsIsUsable:
|
|
179
|
-
getLogsMaxBlockRange:
|
|
179
|
+
getLogsIsUsable: false,
|
|
180
|
+
getLogsMaxBlockRange: 0n,
|
|
180
181
|
},
|
|
181
182
|
]
|
|
182
183
|
|
|
@@ -75,11 +75,12 @@ export const polygonZkEvmHttpRpcs: HttpRpc[] = [
|
|
|
75
75
|
// getLogsIsUsable: true,
|
|
76
76
|
// getLogsMaxBlockRange: 10_000n,
|
|
77
77
|
// },
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
// Endpoint is not working
|
|
79
|
+
// {
|
|
80
|
+
// url: 'https://polygon-zkevm.blockpi.network/v1/rpc/public',
|
|
81
|
+
// getLogsIsUsable: true,
|
|
82
|
+
// getLogsMaxBlockRange: 10_000n,
|
|
83
|
+
// },
|
|
83
84
|
{
|
|
84
85
|
url: 'https://polygon-zkevm-mainnet.public.blastapi.io',
|
|
85
86
|
getLogsIsUsable: false,
|
|
@@ -66,16 +66,18 @@ export const roninHttpRpcs: HttpRpc[] = [
|
|
|
66
66
|
// getLogsIsUsable: true,
|
|
67
67
|
// getLogsMaxBlockRange: 20_000n,
|
|
68
68
|
// },
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
69
|
+
// Endpoint is not working
|
|
70
|
+
// {
|
|
71
|
+
// url: 'https://api-gateway.skymavis.com/rpc?apikey=9aqYLBbxSC6LROynQJBvKkEIsioqwHmr',
|
|
72
|
+
// getLogsIsUsable: true,
|
|
73
|
+
// getLogsMaxBlockRange: 500n,
|
|
74
|
+
// },
|
|
75
|
+
// Not archiving receipts
|
|
76
|
+
// {
|
|
77
|
+
// url: 'https://ronin.drpc.org',
|
|
78
|
+
// getLogsIsUsable: true,
|
|
79
|
+
// getLogsMaxBlockRange: 10_000n,
|
|
80
|
+
// },
|
|
79
81
|
]
|
|
80
82
|
|
|
81
83
|
export const roninWebsocketRpcUrls: readonly string[] = []
|
|
@@ -80,15 +80,16 @@ export const scrollHttpRpcs: HttpRpc[] = [
|
|
|
80
80
|
getLogsIsUsable: true,
|
|
81
81
|
getLogsMaxBlockRange: 10_000n,
|
|
82
82
|
},
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
// Endpoint is not working
|
|
84
|
+
// {
|
|
85
|
+
// url: 'https://scroll.blockpi.network/v1/rpc/public',
|
|
86
|
+
// getLogsIsUsable: true,
|
|
87
|
+
// getLogsMaxBlockRange: 1024n,
|
|
88
|
+
// },
|
|
88
89
|
{
|
|
89
90
|
url: 'https://1rpc.io/scroll',
|
|
90
|
-
getLogsIsUsable:
|
|
91
|
-
getLogsMaxBlockRange:
|
|
91
|
+
getLogsIsUsable: false,
|
|
92
|
+
getLogsMaxBlockRange: 0n,
|
|
92
93
|
},
|
|
93
94
|
{
|
|
94
95
|
url: 'https://scroll.drpc.org',
|
|
@@ -64,11 +64,12 @@ export const zksyncEraHttpRpcs: HttpRpc[] = [
|
|
|
64
64
|
getLogsIsUsable: true,
|
|
65
65
|
getLogsMaxBlockRange: 10_000n,
|
|
66
66
|
},
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
// Endpoint is not working
|
|
68
|
+
// {
|
|
69
|
+
// url: 'https://zksync-era.blockpi.network/v1/rpc/public',
|
|
70
|
+
// getLogsIsUsable: true,
|
|
71
|
+
// getLogsMaxBlockRange: 1024n,
|
|
72
|
+
// },
|
|
72
73
|
// Not archiving receipts
|
|
73
74
|
// {
|
|
74
75
|
// url: 'https://go.getblock.io/f76c09905def4618a34946bf71851542',
|
|
@@ -92,11 +93,12 @@ export const zksyncEraHttpRpcs: HttpRpc[] = [
|
|
|
92
93
|
getLogsIsUsable: true,
|
|
93
94
|
getLogsMaxBlockRange: 1000n,
|
|
94
95
|
},
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
// Endpoint is not working
|
|
97
|
+
// {
|
|
98
|
+
// url: 'https://endpoints.omniatech.io/v1/zksync-era/mainnet/public',
|
|
99
|
+
// getLogsIsUsable: true,
|
|
100
|
+
// getLogsMaxBlockRange: 10_000n,
|
|
101
|
+
// },
|
|
100
102
|
// Not archiving receipts
|
|
101
103
|
// {
|
|
102
104
|
// url: 'https://api.zan.top/zksync-mainnet',
|
package/client/create.ts
CHANGED
|
@@ -10,7 +10,9 @@ import {
|
|
|
10
10
|
InvalidInputRpcError,
|
|
11
11
|
JsonRpcVersionUnsupportedError,
|
|
12
12
|
type MulticallParameters,
|
|
13
|
+
type MulticallReturnType,
|
|
13
14
|
type PublicClient,
|
|
15
|
+
type ReadContractParameters,
|
|
14
16
|
RpcRequestError,
|
|
15
17
|
TransactionNotFoundError,
|
|
16
18
|
TransactionReceiptNotFoundError,
|
|
@@ -21,6 +23,68 @@ import type { LowerHex } from '../types'
|
|
|
21
23
|
import { bigIntMin } from '../utils'
|
|
22
24
|
import type { Client } from './types'
|
|
23
25
|
|
|
26
|
+
class Semaphore {
|
|
27
|
+
#endpoints: readonly string[]
|
|
28
|
+
#usingIndexSet = new Set<number>()
|
|
29
|
+
#queue: Array<{
|
|
30
|
+
call: () => void
|
|
31
|
+
timeoutId: ReturnType<typeof setTimeout>
|
|
32
|
+
}> = []
|
|
33
|
+
|
|
34
|
+
constructor(endpoints: readonly string[]) {
|
|
35
|
+
this.#endpoints = endpoints
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async acquire(timeout: number): Promise<string> {
|
|
39
|
+
if (this.#usingIndexSet.size < this.#endpoints.length) {
|
|
40
|
+
const index = this.#endpoints.findIndex(
|
|
41
|
+
(_, index) => !this.#usingIndexSet.has(index),
|
|
42
|
+
)
|
|
43
|
+
this.#usingIndexSet.add(index)
|
|
44
|
+
const endpoint = this.#endpoints[index]
|
|
45
|
+
return Promise.resolve(endpoint)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return new Promise<string>((resolve, reject) => {
|
|
49
|
+
const timeoutId = setTimeout(() => {
|
|
50
|
+
const index = this.#queue.findIndex(
|
|
51
|
+
(item) => item.timeoutId === timeoutId,
|
|
52
|
+
)
|
|
53
|
+
if (index !== -1) {
|
|
54
|
+
this.#queue.splice(index, 1)
|
|
55
|
+
reject(new Error('Timeout while waiting for semaphore'))
|
|
56
|
+
}
|
|
57
|
+
}, timeout)
|
|
58
|
+
|
|
59
|
+
this.#queue.push({
|
|
60
|
+
call: () => {
|
|
61
|
+
const index = this.#endpoints.findIndex(
|
|
62
|
+
(_, index) => !this.#usingIndexSet.has(index),
|
|
63
|
+
)
|
|
64
|
+
this.#usingIndexSet.add(index)
|
|
65
|
+
const endpoint = this.#endpoints[index]
|
|
66
|
+
resolve(endpoint)
|
|
67
|
+
},
|
|
68
|
+
timeoutId,
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async release(endpoint: string, cooldown?: number): Promise<void> {
|
|
74
|
+
if (cooldown !== undefined) {
|
|
75
|
+
await new Promise((resolve) => setTimeout(resolve, cooldown))
|
|
76
|
+
}
|
|
77
|
+
const index = this.#endpoints.indexOf(endpoint)
|
|
78
|
+
this.#usingIndexSet.delete(index)
|
|
79
|
+
const next = this.#queue.shift()
|
|
80
|
+
if (next !== undefined) {
|
|
81
|
+
const { call, timeoutId } = next
|
|
82
|
+
clearTimeout(timeoutId)
|
|
83
|
+
call()
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
24
88
|
type CreateClientParameters = {
|
|
25
89
|
chain: Chain
|
|
26
90
|
httpRpcs: HttpRpc[]
|
|
@@ -31,6 +95,7 @@ export const createClient = ({
|
|
|
31
95
|
httpRpcs,
|
|
32
96
|
}: CreateClientParameters): Client => {
|
|
33
97
|
const endpoints = httpRpcs.map((httpRpc) => httpRpc.url)
|
|
98
|
+
const semaphore = new Semaphore(endpoints)
|
|
34
99
|
const getLogsIsUsableEndpoints = new Set<string>()
|
|
35
100
|
const endpointGetLogsMaxBlockRanges = new Map<string, bigint>()
|
|
36
101
|
for (const httpRpc of httpRpcs) {
|
|
@@ -87,7 +152,8 @@ export const createClient = ({
|
|
|
87
152
|
timeout?: number
|
|
88
153
|
}): Promise<T> => {
|
|
89
154
|
const start = Date.now()
|
|
90
|
-
const endpoint = await
|
|
155
|
+
const endpoint = await semaphore.acquire(timeout)
|
|
156
|
+
let cooldown: number | undefined
|
|
91
157
|
console.debug(`Call ${callName ?? ''} on ${endpoint}`)
|
|
92
158
|
try {
|
|
93
159
|
const client = createPublicClient({
|
|
@@ -104,27 +170,19 @@ export const createClient = ({
|
|
|
104
170
|
])
|
|
105
171
|
} catch (error) {
|
|
106
172
|
if (
|
|
107
|
-
(error
|
|
108
|
-
(error.status === 429 || error.status === 503)) ||
|
|
109
|
-
(error instanceof ContractFunctionExecutionError &&
|
|
110
|
-
(error.message.includes('Status: 429') ||
|
|
111
|
-
error.message.includes('Status: 503'))) ||
|
|
112
|
-
(error instanceof CallExecutionError &&
|
|
113
|
-
(error.message.includes('429') || error.message.includes('503'))) ||
|
|
114
|
-
error instanceof RpcRequestError ||
|
|
115
|
-
error instanceof JsonRpcVersionUnsupportedError ||
|
|
116
|
-
error instanceof InternalRpcError ||
|
|
173
|
+
isRequestError(error) ||
|
|
117
174
|
(error instanceof Error &&
|
|
118
175
|
(error.message.includes('The request timed out.') ||
|
|
119
176
|
error.message.includes('Timeout')))
|
|
120
177
|
) {
|
|
121
178
|
console.debug(error)
|
|
122
|
-
|
|
179
|
+
cooldown = 60_000
|
|
123
180
|
return await call({
|
|
124
181
|
clientCall,
|
|
125
182
|
timeout: timeout - (Date.now() - start),
|
|
126
183
|
})
|
|
127
184
|
}
|
|
185
|
+
|
|
128
186
|
if (
|
|
129
187
|
error instanceof TransactionNotFoundError ||
|
|
130
188
|
error instanceof TransactionReceiptNotFoundError ||
|
|
@@ -132,26 +190,16 @@ export const createClient = ({
|
|
|
132
190
|
error instanceof InvalidInputRpcError
|
|
133
191
|
) {
|
|
134
192
|
console.debug(error)
|
|
135
|
-
|
|
136
|
-
return await call({
|
|
137
|
-
clientCall,
|
|
138
|
-
timeout: timeout - (Date.now() - start),
|
|
139
|
-
})
|
|
140
|
-
}
|
|
141
|
-
if (
|
|
142
|
-
error instanceof RpcRequestError &&
|
|
143
|
-
error.details.includes('Unparsable response type')
|
|
144
|
-
) {
|
|
145
|
-
console.debug(error)
|
|
146
|
-
cooldownEndpoint(endpoint, 1000 * 60 * 60)
|
|
193
|
+
cooldown = 5000
|
|
147
194
|
return await call({
|
|
148
195
|
clientCall,
|
|
149
196
|
timeout: timeout - (Date.now() - start),
|
|
150
197
|
})
|
|
151
198
|
}
|
|
199
|
+
|
|
152
200
|
throw error
|
|
153
201
|
} finally {
|
|
154
|
-
|
|
202
|
+
semaphore.release(endpoint, cooldown)
|
|
155
203
|
}
|
|
156
204
|
}
|
|
157
205
|
|
|
@@ -206,16 +254,7 @@ export const createClient = ({
|
|
|
206
254
|
currentFromBlock = currentToBlock + 1n
|
|
207
255
|
} catch (error) {
|
|
208
256
|
if (
|
|
209
|
-
(error
|
|
210
|
-
(error.status === 429 || error.status === 503)) ||
|
|
211
|
-
(error instanceof ContractFunctionExecutionError &&
|
|
212
|
-
(error.message.includes('Status: 429') ||
|
|
213
|
-
error.message.includes('Status: 503'))) ||
|
|
214
|
-
(error instanceof CallExecutionError &&
|
|
215
|
-
(error.message.includes('429') || error.message.includes('503'))) ||
|
|
216
|
-
error instanceof RpcRequestError ||
|
|
217
|
-
error instanceof JsonRpcVersionUnsupportedError ||
|
|
218
|
-
error instanceof InternalRpcError ||
|
|
257
|
+
isRequestError(error) ||
|
|
219
258
|
(error instanceof Error &&
|
|
220
259
|
(error.message.includes('The request timed out.') ||
|
|
221
260
|
error.message.includes('Timeout')))
|
|
@@ -224,6 +263,7 @@ export const createClient = ({
|
|
|
224
263
|
cooldownEndpoint(endpoint)
|
|
225
264
|
continue
|
|
226
265
|
}
|
|
266
|
+
|
|
227
267
|
if (
|
|
228
268
|
error instanceof TransactionNotFoundError ||
|
|
229
269
|
error instanceof TransactionReceiptNotFoundError ||
|
|
@@ -234,14 +274,7 @@ export const createClient = ({
|
|
|
234
274
|
cooldownEndpoint(endpoint, 5000)
|
|
235
275
|
continue
|
|
236
276
|
}
|
|
237
|
-
|
|
238
|
-
error instanceof RpcRequestError &&
|
|
239
|
-
error.details.includes('Unparsable response type')
|
|
240
|
-
) {
|
|
241
|
-
console.debug(error)
|
|
242
|
-
cooldownEndpoint(endpoint, 1000 * 60 * 60)
|
|
243
|
-
continue
|
|
244
|
-
}
|
|
277
|
+
|
|
245
278
|
throw error
|
|
246
279
|
} finally {
|
|
247
280
|
busyEndpoints.delete(endpoint)
|
|
@@ -256,10 +289,47 @@ export const createClient = ({
|
|
|
256
289
|
}: {
|
|
257
290
|
args: MulticallParameters<T>
|
|
258
291
|
timeout?: number
|
|
259
|
-
}) => {
|
|
292
|
+
}): Promise<MulticallReturnType<T>> => {
|
|
260
293
|
const start = Date.now()
|
|
261
|
-
|
|
262
|
-
|
|
294
|
+
|
|
295
|
+
if (chain.contracts?.multicall3?.address === undefined) {
|
|
296
|
+
// multicall を使用しないで並列実行
|
|
297
|
+
if (args.contracts.length === 0) {
|
|
298
|
+
return [] as unknown as MulticallReturnType<T>
|
|
299
|
+
}
|
|
300
|
+
const results = await Promise.all(
|
|
301
|
+
args.contracts.map((contract) =>
|
|
302
|
+
(async () => {
|
|
303
|
+
try {
|
|
304
|
+
const result = await call({
|
|
305
|
+
clientCall: (client) =>
|
|
306
|
+
client.readContract(contract as ReadContractParameters),
|
|
307
|
+
timeout,
|
|
308
|
+
})
|
|
309
|
+
return {
|
|
310
|
+
result,
|
|
311
|
+
status: 'success',
|
|
312
|
+
}
|
|
313
|
+
} catch (error) {
|
|
314
|
+
if (
|
|
315
|
+
error instanceof Error &&
|
|
316
|
+
error.message === 'Timeout while waiting for semaphore'
|
|
317
|
+
) {
|
|
318
|
+
throw error
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
error,
|
|
322
|
+
status: 'failure',
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
})(),
|
|
326
|
+
),
|
|
327
|
+
)
|
|
328
|
+
return results as MulticallReturnType<T>
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const endpoint = await semaphore.acquire(timeout)
|
|
332
|
+
let cooldown: number | undefined
|
|
263
333
|
try {
|
|
264
334
|
const client = createPublicClient({
|
|
265
335
|
chain,
|
|
@@ -281,40 +351,17 @@ export const createClient = ({
|
|
|
281
351
|
return results
|
|
282
352
|
}
|
|
283
353
|
const { error } = result0
|
|
284
|
-
if (error
|
|
354
|
+
if (isRequestError(error)) {
|
|
285
355
|
throw error
|
|
286
356
|
}
|
|
287
357
|
return results
|
|
288
358
|
} catch (error) {
|
|
289
|
-
if (
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
error.message.includes('The request timed out.') ||
|
|
294
|
-
error.message.includes('RPC Request failed')
|
|
295
|
-
) {
|
|
296
|
-
console.debug(error)
|
|
297
|
-
cooldownEndpoint(endpoint)
|
|
298
|
-
return await multicall({
|
|
299
|
-
args,
|
|
300
|
-
timeout: timeout - (Date.now() - start),
|
|
301
|
-
})
|
|
302
|
-
}
|
|
303
|
-
if (
|
|
304
|
-
error.message.includes('Status: 404') ||
|
|
305
|
-
error.message.includes('HTTP request failed')
|
|
306
|
-
) {
|
|
307
|
-
console.debug(error)
|
|
308
|
-
cooldownEndpoint(endpoint, 5000)
|
|
309
|
-
return await multicall({
|
|
310
|
-
args,
|
|
311
|
-
timeout: timeout - (Date.now() - start),
|
|
312
|
-
})
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
if (error instanceof Error && error.message.includes('Timeout')) {
|
|
359
|
+
if (
|
|
360
|
+
isRequestError(error) ||
|
|
361
|
+
(error instanceof Error && error.message.includes('Timeout'))
|
|
362
|
+
) {
|
|
316
363
|
console.debug(error)
|
|
317
|
-
|
|
364
|
+
cooldown = 60_000
|
|
318
365
|
return await multicall({
|
|
319
366
|
args,
|
|
320
367
|
timeout: timeout - (Date.now() - start),
|
|
@@ -322,7 +369,7 @@ export const createClient = ({
|
|
|
322
369
|
}
|
|
323
370
|
throw error
|
|
324
371
|
} finally {
|
|
325
|
-
|
|
372
|
+
semaphore.release(endpoint, cooldown)
|
|
326
373
|
}
|
|
327
374
|
}
|
|
328
375
|
|
|
@@ -333,3 +380,41 @@ export const createClient = ({
|
|
|
333
380
|
multicall,
|
|
334
381
|
}
|
|
335
382
|
}
|
|
383
|
+
|
|
384
|
+
const requestErrorMessages: readonly string[] = [
|
|
385
|
+
'Failed to fetch',
|
|
386
|
+
'HTTP request failed',
|
|
387
|
+
'RPC Request failed',
|
|
388
|
+
'Status: 404',
|
|
389
|
+
'Status: 429',
|
|
390
|
+
'Status: 503',
|
|
391
|
+
'The request timed out.',
|
|
392
|
+
'Unparsable response type',
|
|
393
|
+
]
|
|
394
|
+
|
|
395
|
+
const isRequestError = (error: unknown): boolean => {
|
|
396
|
+
if (
|
|
397
|
+
error instanceof HttpRequestError ||
|
|
398
|
+
error instanceof RpcRequestError ||
|
|
399
|
+
error instanceof JsonRpcVersionUnsupportedError ||
|
|
400
|
+
error instanceof InternalRpcError
|
|
401
|
+
) {
|
|
402
|
+
return true
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (error instanceof ContractFunctionExecutionError) {
|
|
406
|
+
for (const message of requestErrorMessages) {
|
|
407
|
+
if (error.message.includes(message)) {
|
|
408
|
+
return true
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (
|
|
414
|
+
error instanceof CallExecutionError &&
|
|
415
|
+
(error.message.includes('429') || error.message.includes('503'))
|
|
416
|
+
) {
|
|
417
|
+
return true
|
|
418
|
+
}
|
|
419
|
+
return false
|
|
420
|
+
}
|