@gearbox-protocol/sdk 9.12.1 → 9.12.3

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.
@@ -25,8 +25,8 @@ module.exports = __toCommonJS(RevolverTransport_exports);
25
25
  var import_viem = require("viem");
26
26
  var import_providers = require("./providers.js");
27
27
  class NoAvailableTransportsError extends import_viem.BaseError {
28
- constructor() {
29
- super("no available transports");
28
+ constructor(cause) {
29
+ super("no available transports", { cause });
30
30
  }
31
31
  }
32
32
  class RevolverTransport {
@@ -54,7 +54,10 @@ class RevolverTransport {
54
54
  };
55
55
  }
56
56
  constructor(config) {
57
- this.#config = { ...config };
57
+ this.#config = {
58
+ ...config,
59
+ shouldRetry: config.shouldRetry ?? defaultShouldRetry
60
+ };
58
61
  const rpcUrls = /* @__PURE__ */ new Map();
59
62
  const cooldowns = /* @__PURE__ */ new Map();
60
63
  for (const { provider, keys, cooldown } of config.providers) {
@@ -99,13 +102,22 @@ class RevolverTransport {
99
102
  if (this.#transports.length === 1) {
100
103
  return this.#transport({ ...this.overrides }).request(r);
101
104
  }
105
+ let error;
102
106
  do {
103
107
  try {
104
108
  this.#requests.set(r, this.currentTransportName());
105
- const resp = await this.#transport({ ...this.overrides }).request(r);
109
+ const resp = await (0, import_viem.withRetry)(
110
+ () => this.#transport({ ...this.overrides }).request(r),
111
+ {
112
+ delay: this.#config.retryDelay,
113
+ retryCount: this.#config.retryCount,
114
+ shouldRetry: this.#config.shouldRetry
115
+ }
116
+ );
106
117
  this.#requests.delete(r);
107
118
  return resp;
108
119
  } catch (e) {
120
+ error = error ?? e;
109
121
  if (e instanceof import_viem.RpcError || e instanceof import_viem.HttpRequestError) {
110
122
  const reqTransport = this.#requests.get(r);
111
123
  if (reqTransport === this.currentTransportName()) {
@@ -122,7 +134,7 @@ class RevolverTransport {
122
134
  }
123
135
  } while (this.#hasAvailableTransports);
124
136
  this.#requests.delete(r);
125
- throw new NoAvailableTransportsError();
137
+ throw new NoAvailableTransportsError(error);
126
138
  };
127
139
  get config() {
128
140
  return {
@@ -154,7 +166,6 @@ class RevolverTransport {
154
166
  {
155
167
  reason,
156
168
  current: this.currentTransportName,
157
- index: this.#index,
158
169
  total: this.#transports.length
159
170
  },
160
171
  "rotating transport"
@@ -168,7 +179,6 @@ class RevolverTransport {
168
179
  this.#logger?.info(
169
180
  {
170
181
  current: this.currentTransportName,
171
- index: this.#index,
172
182
  total: this.#transports.length
173
183
  },
174
184
  "switched to next transport"
@@ -187,7 +197,6 @@ class RevolverTransport {
187
197
  this.#logger?.warn(
188
198
  {
189
199
  current: this.currentTransportName,
190
- index: this.#index,
191
200
  total: this.#transports.length
192
201
  },
193
202
  "transport is still on cooldown"
@@ -222,6 +231,21 @@ class RevolverTransport {
222
231
  return this.#transports.some((t) => t.cooldown < now);
223
232
  }
224
233
  }
234
+ const retryCodes = /* @__PURE__ */ new Set([
235
+ import_viem.InvalidRequestRpcError.code,
236
+ import_viem.InvalidParamsRpcError.code,
237
+ import_viem.InvalidInputRpcError.code,
238
+ import_viem.ResourceNotFoundRpcError.code,
239
+ import_viem.ResourceUnavailableRpcError.code
240
+ ]);
241
+ const defaultShouldRetry = ({
242
+ error
243
+ }) => {
244
+ if ("code" in error && typeof error.code === "number") {
245
+ return retryCodes.has(error.code);
246
+ }
247
+ return false;
248
+ };
225
249
  // Annotate the CommonJS export names for ESM import in node:
226
250
  0 && (module.exports = {
227
251
  NoAvailableTransportsError,
@@ -2,14 +2,20 @@ import {
2
2
  BaseError,
3
3
  HttpRequestError,
4
4
  http,
5
- RpcError
5
+ InvalidInputRpcError,
6
+ InvalidParamsRpcError,
7
+ InvalidRequestRpcError,
8
+ ResourceNotFoundRpcError,
9
+ ResourceUnavailableRpcError,
10
+ RpcError,
11
+ withRetry
6
12
  } from "viem";
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 = { ...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 this.#transport({ ...this.overrides }).request(r);
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
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "9.12.1",
3
+ "version": "9.12.3",
4
4
  "description": "Gearbox SDK",
5
5
  "license": "MIT",
6
6
  "main": "./dist/cjs/sdk/index.js",
@@ -62,13 +62,13 @@
62
62
  "date-fns": "^4.1.0",
63
63
  "decimal.js-light": "^2.5.1",
64
64
  "viem": ">=2.23.15 <3.0.0",
65
- "zod": "^4.1.11"
65
+ "zod": "^4.1.12"
66
66
  },
67
67
  "devDependencies": {
68
- "@biomejs/biome": "^2.2.4",
68
+ "@biomejs/biome": "^2.2.5",
69
69
  "@commitlint/cli": "^20.1.0",
70
70
  "@commitlint/config-conventional": "^20.0.0",
71
- "@gearbox-protocol/biome-config": "^1.0.2",
71
+ "@gearbox-protocol/biome-config": "^1.0.4",
72
72
  "@types/cross-spawn": "^6.0.6",
73
73
  "axios": "^1.12.2",
74
74
  "cross-spawn": "^7.0.6",