@gearbox-protocol/sdk 9.12.1 → 9.12.2
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.
|
@@ -23,10 +23,11 @@ __export(RevolverTransport_exports, {
|
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(RevolverTransport_exports);
|
|
25
25
|
var import_viem = require("viem");
|
|
26
|
+
var import_rpc = require("../../node_modules/viem/errors/rpc");
|
|
26
27
|
var import_providers = require("./providers.js");
|
|
27
28
|
class NoAvailableTransportsError extends import_viem.BaseError {
|
|
28
|
-
constructor() {
|
|
29
|
-
super("no available transports");
|
|
29
|
+
constructor(cause) {
|
|
30
|
+
super("no available transports", { cause });
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
class RevolverTransport {
|
|
@@ -54,7 +55,10 @@ class RevolverTransport {
|
|
|
54
55
|
};
|
|
55
56
|
}
|
|
56
57
|
constructor(config) {
|
|
57
|
-
this.#config = {
|
|
58
|
+
this.#config = {
|
|
59
|
+
...config,
|
|
60
|
+
shouldRetry: config.shouldRetry ?? defaultShouldRetry
|
|
61
|
+
};
|
|
58
62
|
const rpcUrls = /* @__PURE__ */ new Map();
|
|
59
63
|
const cooldowns = /* @__PURE__ */ new Map();
|
|
60
64
|
for (const { provider, keys, cooldown } of config.providers) {
|
|
@@ -99,13 +103,22 @@ class RevolverTransport {
|
|
|
99
103
|
if (this.#transports.length === 1) {
|
|
100
104
|
return this.#transport({ ...this.overrides }).request(r);
|
|
101
105
|
}
|
|
106
|
+
let error;
|
|
102
107
|
do {
|
|
103
108
|
try {
|
|
104
109
|
this.#requests.set(r, this.currentTransportName());
|
|
105
|
-
const resp = await
|
|
110
|
+
const resp = await (0, import_viem.withRetry)(
|
|
111
|
+
() => this.#transport({ ...this.overrides }).request(r),
|
|
112
|
+
{
|
|
113
|
+
delay: this.#config.retryDelay,
|
|
114
|
+
retryCount: this.#config.retryCount,
|
|
115
|
+
shouldRetry: this.#config.shouldRetry
|
|
116
|
+
}
|
|
117
|
+
);
|
|
106
118
|
this.#requests.delete(r);
|
|
107
119
|
return resp;
|
|
108
120
|
} catch (e) {
|
|
121
|
+
error = error ?? e;
|
|
109
122
|
if (e instanceof import_viem.RpcError || e instanceof import_viem.HttpRequestError) {
|
|
110
123
|
const reqTransport = this.#requests.get(r);
|
|
111
124
|
if (reqTransport === this.currentTransportName()) {
|
|
@@ -122,7 +135,7 @@ class RevolverTransport {
|
|
|
122
135
|
}
|
|
123
136
|
} while (this.#hasAvailableTransports);
|
|
124
137
|
this.#requests.delete(r);
|
|
125
|
-
throw new NoAvailableTransportsError();
|
|
138
|
+
throw new NoAvailableTransportsError(error);
|
|
126
139
|
};
|
|
127
140
|
get config() {
|
|
128
141
|
return {
|
|
@@ -154,7 +167,6 @@ class RevolverTransport {
|
|
|
154
167
|
{
|
|
155
168
|
reason,
|
|
156
169
|
current: this.currentTransportName,
|
|
157
|
-
index: this.#index,
|
|
158
170
|
total: this.#transports.length
|
|
159
171
|
},
|
|
160
172
|
"rotating transport"
|
|
@@ -168,7 +180,6 @@ class RevolverTransport {
|
|
|
168
180
|
this.#logger?.info(
|
|
169
181
|
{
|
|
170
182
|
current: this.currentTransportName,
|
|
171
|
-
index: this.#index,
|
|
172
183
|
total: this.#transports.length
|
|
173
184
|
},
|
|
174
185
|
"switched to next transport"
|
|
@@ -187,7 +198,6 @@ class RevolverTransport {
|
|
|
187
198
|
this.#logger?.warn(
|
|
188
199
|
{
|
|
189
200
|
current: this.currentTransportName,
|
|
190
|
-
index: this.#index,
|
|
191
201
|
total: this.#transports.length
|
|
192
202
|
},
|
|
193
203
|
"transport is still on cooldown"
|
|
@@ -222,6 +232,21 @@ class RevolverTransport {
|
|
|
222
232
|
return this.#transports.some((t) => t.cooldown < now);
|
|
223
233
|
}
|
|
224
234
|
}
|
|
235
|
+
const retryCodes = /* @__PURE__ */ new Set([
|
|
236
|
+
import_viem.InvalidRequestRpcError.code,
|
|
237
|
+
import_viem.InvalidParamsRpcError.code,
|
|
238
|
+
import_viem.InvalidInputRpcError.code,
|
|
239
|
+
import_rpc.ResourceNotFoundRpcError.code,
|
|
240
|
+
import_viem.ResourceUnavailableRpcError.code
|
|
241
|
+
]);
|
|
242
|
+
const defaultShouldRetry = ({
|
|
243
|
+
error
|
|
244
|
+
}) => {
|
|
245
|
+
if ("code" in error && typeof error.code === "number") {
|
|
246
|
+
return retryCodes.has(error.code);
|
|
247
|
+
}
|
|
248
|
+
return false;
|
|
249
|
+
};
|
|
225
250
|
// Annotate the CommonJS export names for ESM import in node:
|
|
226
251
|
0 && (module.exports = {
|
|
227
252
|
NoAvailableTransportsError,
|
|
@@ -2,14 +2,20 @@ import {
|
|
|
2
2
|
BaseError,
|
|
3
3
|
HttpRequestError,
|
|
4
4
|
http,
|
|
5
|
-
|
|
5
|
+
InvalidInputRpcError,
|
|
6
|
+
InvalidParamsRpcError,
|
|
7
|
+
InvalidRequestRpcError,
|
|
8
|
+
ResourceUnavailableRpcError,
|
|
9
|
+
RpcError,
|
|
10
|
+
withRetry
|
|
6
11
|
} from "viem";
|
|
12
|
+
import { ResourceNotFoundRpcError } from "../../node_modules/viem/errors/rpc";
|
|
7
13
|
import {
|
|
8
14
|
getProviderUrl
|
|
9
15
|
} from "./providers.js";
|
|
10
16
|
class NoAvailableTransportsError extends BaseError {
|
|
11
|
-
constructor() {
|
|
12
|
-
super("no available transports");
|
|
17
|
+
constructor(cause) {
|
|
18
|
+
super("no available transports", { cause });
|
|
13
19
|
}
|
|
14
20
|
}
|
|
15
21
|
class RevolverTransport {
|
|
@@ -37,7 +43,10 @@ class RevolverTransport {
|
|
|
37
43
|
};
|
|
38
44
|
}
|
|
39
45
|
constructor(config) {
|
|
40
|
-
this.#config = {
|
|
46
|
+
this.#config = {
|
|
47
|
+
...config,
|
|
48
|
+
shouldRetry: config.shouldRetry ?? defaultShouldRetry
|
|
49
|
+
};
|
|
41
50
|
const rpcUrls = /* @__PURE__ */ new Map();
|
|
42
51
|
const cooldowns = /* @__PURE__ */ new Map();
|
|
43
52
|
for (const { provider, keys, cooldown } of config.providers) {
|
|
@@ -82,13 +91,22 @@ class RevolverTransport {
|
|
|
82
91
|
if (this.#transports.length === 1) {
|
|
83
92
|
return this.#transport({ ...this.overrides }).request(r);
|
|
84
93
|
}
|
|
94
|
+
let error;
|
|
85
95
|
do {
|
|
86
96
|
try {
|
|
87
97
|
this.#requests.set(r, this.currentTransportName());
|
|
88
|
-
const resp = await
|
|
98
|
+
const resp = await withRetry(
|
|
99
|
+
() => this.#transport({ ...this.overrides }).request(r),
|
|
100
|
+
{
|
|
101
|
+
delay: this.#config.retryDelay,
|
|
102
|
+
retryCount: this.#config.retryCount,
|
|
103
|
+
shouldRetry: this.#config.shouldRetry
|
|
104
|
+
}
|
|
105
|
+
);
|
|
89
106
|
this.#requests.delete(r);
|
|
90
107
|
return resp;
|
|
91
108
|
} catch (e) {
|
|
109
|
+
error = error ?? e;
|
|
92
110
|
if (e instanceof RpcError || e instanceof HttpRequestError) {
|
|
93
111
|
const reqTransport = this.#requests.get(r);
|
|
94
112
|
if (reqTransport === this.currentTransportName()) {
|
|
@@ -105,7 +123,7 @@ class RevolverTransport {
|
|
|
105
123
|
}
|
|
106
124
|
} while (this.#hasAvailableTransports);
|
|
107
125
|
this.#requests.delete(r);
|
|
108
|
-
throw new NoAvailableTransportsError();
|
|
126
|
+
throw new NoAvailableTransportsError(error);
|
|
109
127
|
};
|
|
110
128
|
get config() {
|
|
111
129
|
return {
|
|
@@ -137,7 +155,6 @@ class RevolverTransport {
|
|
|
137
155
|
{
|
|
138
156
|
reason,
|
|
139
157
|
current: this.currentTransportName,
|
|
140
|
-
index: this.#index,
|
|
141
158
|
total: this.#transports.length
|
|
142
159
|
},
|
|
143
160
|
"rotating transport"
|
|
@@ -151,7 +168,6 @@ class RevolverTransport {
|
|
|
151
168
|
this.#logger?.info(
|
|
152
169
|
{
|
|
153
170
|
current: this.currentTransportName,
|
|
154
|
-
index: this.#index,
|
|
155
171
|
total: this.#transports.length
|
|
156
172
|
},
|
|
157
173
|
"switched to next transport"
|
|
@@ -170,7 +186,6 @@ class RevolverTransport {
|
|
|
170
186
|
this.#logger?.warn(
|
|
171
187
|
{
|
|
172
188
|
current: this.currentTransportName,
|
|
173
|
-
index: this.#index,
|
|
174
189
|
total: this.#transports.length
|
|
175
190
|
},
|
|
176
191
|
"transport is still on cooldown"
|
|
@@ -205,6 +220,21 @@ class RevolverTransport {
|
|
|
205
220
|
return this.#transports.some((t) => t.cooldown < now);
|
|
206
221
|
}
|
|
207
222
|
}
|
|
223
|
+
const retryCodes = /* @__PURE__ */ new Set([
|
|
224
|
+
InvalidRequestRpcError.code,
|
|
225
|
+
InvalidParamsRpcError.code,
|
|
226
|
+
InvalidInputRpcError.code,
|
|
227
|
+
ResourceNotFoundRpcError.code,
|
|
228
|
+
ResourceUnavailableRpcError.code
|
|
229
|
+
]);
|
|
230
|
+
const defaultShouldRetry = ({
|
|
231
|
+
error
|
|
232
|
+
}) => {
|
|
233
|
+
if ("code" in error && typeof error.code === "number") {
|
|
234
|
+
return retryCodes.has(error.code);
|
|
235
|
+
}
|
|
236
|
+
return false;
|
|
237
|
+
};
|
|
208
238
|
export {
|
|
209
239
|
NoAvailableTransportsError,
|
|
210
240
|
RevolverTransport
|
|
@@ -18,6 +18,19 @@ export interface RevolverTransportConfig {
|
|
|
18
18
|
retryCount?: TransportConfig["retryCount"] | undefined;
|
|
19
19
|
retryDelay?: TransportConfig["retryDelay"] | undefined;
|
|
20
20
|
timeout?: TransportConfig["timeout"] | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* When single http transport should retry?
|
|
23
|
+
* Defaults to some less strict criteria, so it'll retry "blockNumber from the future" errors
|
|
24
|
+
*
|
|
25
|
+
* By viem's default, simple http transport retries LimitExceededRpcError.code, InternalRpcError.code and HTTP errors
|
|
26
|
+
* so for things like ResourceNotFoundRpcError (eth_call with block number from other rps, which is yet in the future for current rpc)
|
|
27
|
+
* it'll fail and not retry
|
|
28
|
+
* https://github.com/wevm/viem/blob/3bc5e6f3c4a317441063342dd9ec2aaa7eb56b01/src/utils/buildRequest.ts#L269
|
|
29
|
+
*/
|
|
30
|
+
shouldRetry?: ((iter: {
|
|
31
|
+
count: number;
|
|
32
|
+
error: Error;
|
|
33
|
+
}) => Promise<boolean> | boolean) | undefined;
|
|
21
34
|
/**
|
|
22
35
|
* Allow batching of json-rpc requests
|
|
23
36
|
*/
|
|
@@ -44,7 +57,7 @@ export interface RevolverTransportConfig {
|
|
|
44
57
|
cooldown?: number | undefined;
|
|
45
58
|
}
|
|
46
59
|
export declare class NoAvailableTransportsError extends BaseError {
|
|
47
|
-
constructor();
|
|
60
|
+
constructor(cause?: Error);
|
|
48
61
|
}
|
|
49
62
|
export interface RevolverTransportValue {
|
|
50
63
|
/**
|