@gearbox-protocol/sdk 14.0.0-next.6 → 14.0.0-next.8

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.
@@ -43,7 +43,9 @@ const RANGE_ERROR_PATTERNS = [
43
43
  /eth_getLogs is limited to/i,
44
44
  /eth_getLogs requests with up to/i,
45
45
  /range is too large/i,
46
- /exceeded max allowed range/i
46
+ /exceeded max allowed range/i,
47
+ // Encountered on DRPC: "query exceeds max results 20000, retry with the range …"
48
+ /exceeds max results/i
47
49
  ];
48
50
  function isRangeError(error) {
49
51
  const msg = errorMessage(error);
@@ -51,10 +53,17 @@ function isRangeError(error) {
51
53
  }
52
54
  const GENERIC_BLOCKS_RE = /(\d+)\s*block/i;
53
55
  const ALCHEMY_RANGE_RE = /this block range should work: \[(0x[0-9a-fA-F]+),\s*(0x[0-9a-fA-F]+)\]/;
56
+ const DRPC_RANGE_RE = /retry with the range (\d+)-(\d+)/;
54
57
  function parsePageSizeHint(error) {
55
58
  const alchemy = tryAlchemyHint(error);
56
59
  if (alchemy != null) return alchemy;
57
60
  const msg = errorMessage(error);
61
+ const drpc = msg.match(DRPC_RANGE_RE);
62
+ if (drpc) {
63
+ const from = Number(drpc[1]);
64
+ const to = Number(drpc[2]);
65
+ return to - from + 1;
66
+ }
58
67
  const m = msg.match(GENERIC_BLOCKS_RE);
59
68
  return m ? Number(m[1]) : null;
60
69
  }
@@ -32,7 +32,8 @@ __export(formatter_exports, {
32
32
  shortAddress: () => shortAddress,
33
33
  shortHash: () => shortHash,
34
34
  toBN: () => toBN,
35
- toBigInt: () => toBigInt
35
+ toBigInt: () => toBigInt,
36
+ toSignificant: () => toSignificant
36
37
  });
37
38
  module.exports = __toCommonJS(formatter_exports);
38
39
  var import_date_fns = require("date-fns");
@@ -168,6 +169,91 @@ function formatPercentage(healthFactor, decimals = 2) {
168
169
  function formatLeverage(leverage, decimals = 2) {
169
170
  return (leverage / Number(import_constants.LEVERAGE_DECIMALS)).toFixed(decimals);
170
171
  }
172
+ function formatDecimalJsLikeToString(digits, base10exp) {
173
+ const len = digits.length;
174
+ const isExp = base10exp <= -7 || base10exp >= 21;
175
+ if (isExp) {
176
+ let coeff = digits;
177
+ if (len > 1) {
178
+ coeff = `${digits[0]}.${digits.slice(1)}`;
179
+ }
180
+ const exp = base10exp;
181
+ const expStr = exp < 0 ? `e${exp}` : `e+${exp}`;
182
+ return `${coeff}${expStr}`;
183
+ }
184
+ if (base10exp < 0) {
185
+ return `0.${"0".repeat(-base10exp - 1)}${digits}`;
186
+ }
187
+ if (base10exp >= len) {
188
+ return `${digits}${"0".repeat(base10exp + 1 - len)}`;
189
+ }
190
+ const k = base10exp + 1;
191
+ if (k === len) return digits;
192
+ return `${digits.slice(0, k)}.${digits.slice(k)}`;
193
+ }
194
+ function roundToSignificantDigitsHalfUp(digits, base10exp, precision) {
195
+ if (precision < 1) {
196
+ throw new Error(`Invalid precision: ${precision}`);
197
+ }
198
+ if (digits === "0") return { digits: "0", base10exp: 0 };
199
+ let norm = digits;
200
+ while (norm.length > 1 && norm.endsWith("0")) {
201
+ norm = norm.slice(0, -1);
202
+ }
203
+ digits = norm;
204
+ if (digits.length <= precision) {
205
+ return { digits, base10exp };
206
+ }
207
+ const cut = digits.slice(0, precision).split("");
208
+ const next = digits.charCodeAt(precision) - 48;
209
+ if (next >= 5) {
210
+ let i = cut.length - 1;
211
+ while (i >= 0) {
212
+ const cur = cut[i];
213
+ if (cur === void 0) {
214
+ throw new Error("roundToSignificantDigitsHalfUp: invalid state");
215
+ }
216
+ const d = cur.charCodeAt(0) - 48;
217
+ if (d !== 9) {
218
+ cut[i] = String.fromCharCode(48 + d + 1);
219
+ break;
220
+ }
221
+ cut[i] = "0";
222
+ i -= 1;
223
+ }
224
+ if (i < 0) {
225
+ cut.unshift("1");
226
+ base10exp += 1;
227
+ }
228
+ }
229
+ let rounded = cut.join("");
230
+ let tz = 0;
231
+ for (let i = rounded.length - 1; i >= 0 && rounded[i] === "0"; i -= 1) {
232
+ tz += 1;
233
+ }
234
+ if (tz > 0) {
235
+ rounded = rounded.slice(0, -tz);
236
+ }
237
+ if (rounded === "") {
238
+ return { digits: "0", base10exp: 0 };
239
+ }
240
+ return { digits: rounded, base10exp };
241
+ }
242
+ function toSignificant(num, decimals, precision = 6) {
243
+ if (num === 1n) return "0";
244
+ if (num === 0n) return "0";
245
+ const negative = num < 0n;
246
+ const abs = negative ? -num : num;
247
+ const rawDigits = abs.toString();
248
+ const base10exp = rawDigits.length - decimals - 1;
249
+ const rounded = roundToSignificantDigitsHalfUp(
250
+ rawDigits,
251
+ base10exp,
252
+ precision
253
+ );
254
+ const body = formatDecimalJsLikeToString(rounded.digits, rounded.base10exp);
255
+ return negative ? `-${body}` : body;
256
+ }
171
257
  // Annotate the CommonJS export names for ESM import in node:
172
258
  0 && (module.exports = {
173
259
  fmtBinaryMask,
@@ -184,5 +270,6 @@ function formatLeverage(leverage, decimals = 2) {
184
270
  shortAddress,
185
271
  shortHash,
186
272
  toBN,
187
- toBigInt
273
+ toBigInt,
274
+ toSignificant
188
275
  });
@@ -21,7 +21,9 @@ const RANGE_ERROR_PATTERNS = [
21
21
  /eth_getLogs is limited to/i,
22
22
  /eth_getLogs requests with up to/i,
23
23
  /range is too large/i,
24
- /exceeded max allowed range/i
24
+ /exceeded max allowed range/i,
25
+ // Encountered on DRPC: "query exceeds max results 20000, retry with the range …"
26
+ /exceeds max results/i
25
27
  ];
26
28
  function isRangeError(error) {
27
29
  const msg = errorMessage(error);
@@ -29,10 +31,17 @@ function isRangeError(error) {
29
31
  }
30
32
  const GENERIC_BLOCKS_RE = /(\d+)\s*block/i;
31
33
  const ALCHEMY_RANGE_RE = /this block range should work: \[(0x[0-9a-fA-F]+),\s*(0x[0-9a-fA-F]+)\]/;
34
+ const DRPC_RANGE_RE = /retry with the range (\d+)-(\d+)/;
32
35
  function parsePageSizeHint(error) {
33
36
  const alchemy = tryAlchemyHint(error);
34
37
  if (alchemy != null) return alchemy;
35
38
  const msg = errorMessage(error);
39
+ const drpc = msg.match(DRPC_RANGE_RE);
40
+ if (drpc) {
41
+ const from = Number(drpc[1]);
42
+ const to = Number(drpc[2]);
43
+ return to - from + 1;
44
+ }
36
45
  const m = msg.match(GENERIC_BLOCKS_RE);
37
46
  return m ? Number(m[1]) : null;
38
47
  }
@@ -131,6 +131,91 @@ function formatPercentage(healthFactor, decimals = 2) {
131
131
  function formatLeverage(leverage, decimals = 2) {
132
132
  return (leverage / Number(LEVERAGE_DECIMALS)).toFixed(decimals);
133
133
  }
134
+ function formatDecimalJsLikeToString(digits, base10exp) {
135
+ const len = digits.length;
136
+ const isExp = base10exp <= -7 || base10exp >= 21;
137
+ if (isExp) {
138
+ let coeff = digits;
139
+ if (len > 1) {
140
+ coeff = `${digits[0]}.${digits.slice(1)}`;
141
+ }
142
+ const exp = base10exp;
143
+ const expStr = exp < 0 ? `e${exp}` : `e+${exp}`;
144
+ return `${coeff}${expStr}`;
145
+ }
146
+ if (base10exp < 0) {
147
+ return `0.${"0".repeat(-base10exp - 1)}${digits}`;
148
+ }
149
+ if (base10exp >= len) {
150
+ return `${digits}${"0".repeat(base10exp + 1 - len)}`;
151
+ }
152
+ const k = base10exp + 1;
153
+ if (k === len) return digits;
154
+ return `${digits.slice(0, k)}.${digits.slice(k)}`;
155
+ }
156
+ function roundToSignificantDigitsHalfUp(digits, base10exp, precision) {
157
+ if (precision < 1) {
158
+ throw new Error(`Invalid precision: ${precision}`);
159
+ }
160
+ if (digits === "0") return { digits: "0", base10exp: 0 };
161
+ let norm = digits;
162
+ while (norm.length > 1 && norm.endsWith("0")) {
163
+ norm = norm.slice(0, -1);
164
+ }
165
+ digits = norm;
166
+ if (digits.length <= precision) {
167
+ return { digits, base10exp };
168
+ }
169
+ const cut = digits.slice(0, precision).split("");
170
+ const next = digits.charCodeAt(precision) - 48;
171
+ if (next >= 5) {
172
+ let i = cut.length - 1;
173
+ while (i >= 0) {
174
+ const cur = cut[i];
175
+ if (cur === void 0) {
176
+ throw new Error("roundToSignificantDigitsHalfUp: invalid state");
177
+ }
178
+ const d = cur.charCodeAt(0) - 48;
179
+ if (d !== 9) {
180
+ cut[i] = String.fromCharCode(48 + d + 1);
181
+ break;
182
+ }
183
+ cut[i] = "0";
184
+ i -= 1;
185
+ }
186
+ if (i < 0) {
187
+ cut.unshift("1");
188
+ base10exp += 1;
189
+ }
190
+ }
191
+ let rounded = cut.join("");
192
+ let tz = 0;
193
+ for (let i = rounded.length - 1; i >= 0 && rounded[i] === "0"; i -= 1) {
194
+ tz += 1;
195
+ }
196
+ if (tz > 0) {
197
+ rounded = rounded.slice(0, -tz);
198
+ }
199
+ if (rounded === "") {
200
+ return { digits: "0", base10exp: 0 };
201
+ }
202
+ return { digits: rounded, base10exp };
203
+ }
204
+ function toSignificant(num, decimals, precision = 6) {
205
+ if (num === 1n) return "0";
206
+ if (num === 0n) return "0";
207
+ const negative = num < 0n;
208
+ const abs = negative ? -num : num;
209
+ const rawDigits = abs.toString();
210
+ const base10exp = rawDigits.length - decimals - 1;
211
+ const rounded = roundToSignificantDigitsHalfUp(
212
+ rawDigits,
213
+ base10exp,
214
+ precision
215
+ );
216
+ const body = formatDecimalJsLikeToString(rounded.digits, rounded.base10exp);
217
+ return negative ? `-${body}` : body;
218
+ }
134
219
  export {
135
220
  fmtBinaryMask,
136
221
  formatBN,
@@ -146,5 +231,6 @@ export {
146
231
  shortAddress,
147
232
  shortHash,
148
233
  toBN,
149
- toBigInt
234
+ toBigInt,
235
+ toSignificant
150
236
  };
@@ -56,7 +56,9 @@ export declare function isRangeError(error: unknown): boolean;
56
56
  * 1. **Alchemy JSON details** — parses the `details` field of a
57
57
  * {@link HttpRequestError} for a suggested `[fromHex, toHex]` range and
58
58
  * computes the span as `toHex - fromHex + 1`.
59
- * 2. **Generic N-blocks pattern** — matches `/<number> block(s)/i` in the
59
+ * 2. **DRPC decimal range** — matches `retry with the range <from>-<to>` and
60
+ * computes the span as `to - from + 1`.
61
+ * 3. **Generic N-blocks pattern** — matches `/<number> block(s)/i` in the
60
62
  * error message.
61
63
  *
62
64
  * @param error - Any thrown value.
@@ -17,4 +17,5 @@ export declare function shortAddress(address?: string): string;
17
17
  export declare function shortHash(address?: string): string;
18
18
  export declare function formatPercentage(healthFactor: number, decimals?: number): string;
19
19
  export declare function formatLeverage(leverage: number, decimals?: number): string;
20
+ export declare function toSignificant(num: bigint, decimals: number, precision?: number): string;
20
21
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "14.0.0-next.6",
3
+ "version": "14.0.0-next.8",
4
4
  "description": "Gearbox SDK",
5
5
  "license": "MIT",
6
6
  "main": "./dist/cjs/sdk/index.js",