@gearbox-protocol/sdk 14.12.0-next.79 → 14.12.0-next.80

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.
Files changed (45) hide show
  1. package/dist/cjs/model/filters.schema.js +2 -0
  2. package/dist/cjs/model/index.js +3 -0
  3. package/dist/cjs/model/opportunities.schema.js +45 -0
  4. package/dist/cjs/offchain/AbstractOffchainNamespace.js +132 -0
  5. package/dist/cjs/offchain/index.js +5 -0
  6. package/dist/cjs/offchain/opportunities/OffchainOpportunities.js +34 -56
  7. package/dist/cjs/offchain/positions/OffchainPositions.js +5 -24
  8. package/dist/cjs/offchain/types.js +58 -0
  9. package/dist/esm/dev/AccountOpener.js +1 -1
  10. package/dist/esm/dev/withdrawalUtils.js +1 -1
  11. package/dist/esm/model/filters.schema.js +2 -1
  12. package/dist/esm/model/index.js +3 -3
  13. package/dist/esm/model/opportunities.schema.js +45 -2
  14. package/dist/esm/offchain/AbstractOffchainNamespace.js +131 -0
  15. package/dist/esm/offchain/index.js +3 -2
  16. package/dist/esm/offchain/opportunities/OffchainOpportunities.js +34 -56
  17. package/dist/esm/offchain/positions/OffchainPositions.js +5 -24
  18. package/dist/esm/offchain/types.js +56 -1
  19. package/dist/esm/plugins/adapters/contracts/ERC4626AdapterContract.js +1 -1
  20. package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
  21. package/dist/esm/preview/trace/extractTransfers.js +1 -1
  22. package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +2 -2
  23. package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +1 -1
  24. package/dist/esm/sdk/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
  25. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
  26. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
  27. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
  28. package/dist/esm/sdk/base/TokensMeta.js +2 -2
  29. package/dist/esm/sdk/chain/detectNetwork.js +1 -1
  30. package/dist/esm/sdk/core/createAddressProvider.js +1 -1
  31. package/dist/esm/sdk/market/credit/CreditFacadeV310BaseContract.js +1 -1
  32. package/dist/esm/sdk/market/pool/PoolV310Contract.js +1 -1
  33. package/dist/esm/sdk/market/zapper/IETHZapperContract.js +1 -1
  34. package/dist/esm/sdk/market/zapper/ZapperContract.js +1 -1
  35. package/dist/esm/sdk/pools/PoolService.js +1 -1
  36. package/dist/esm/sdk/utils/viem/simulateWithPriceUpdates.js +1 -1
  37. package/dist/types/model/filters.schema.d.ts +5 -1
  38. package/dist/types/model/index.d.ts +3 -3
  39. package/dist/types/model/opportunities.schema.d.ts +49 -1
  40. package/dist/types/offchain/AbstractOffchainNamespace.d.ts +87 -0
  41. package/dist/types/offchain/index.d.ts +3 -2
  42. package/dist/types/offchain/opportunities/OffchainOpportunities.d.ts +3 -33
  43. package/dist/types/offchain/positions/OffchainPositions.d.ts +2 -17
  44. package/dist/types/offchain/types.d.ts +49 -1
  45. package/package.json +2 -1
@@ -16,6 +16,8 @@ const filterAllSchema = zod_v4.z.literal("all");
16
16
  function filterable(schema) {
17
17
  return zod_v4.z.union([schema, filterAllSchema]);
18
18
  }
19
+ const booleanParamSchema = zod_v4.z.enum(["true", "false"]);
19
20
  //#endregion
21
+ exports.booleanParamSchema = booleanParamSchema;
20
22
  exports.filterAllSchema = filterAllSchema;
21
23
  exports.filterable = filterable;
@@ -21,6 +21,7 @@ exports.STRATEGY_POSITION_HISTORY_METRICS = require_model_history.STRATEGY_POSIT
21
21
  exports.amountSchema = require_model_primitives_schema.amountSchema;
22
22
  exports.apyBreakdownSchema = require_model_opportunities_schema.apyBreakdownSchema;
23
23
  exports.assetTypeSchema = require_model_primitives_schema.assetTypeSchema;
24
+ exports.booleanParamSchema = require_model_filters_schema.booleanParamSchema;
24
25
  exports.bpsSchema = require_model_primitives_schema.bpsSchema;
25
26
  exports.chainIdSchema = require_model_primitives_schema.chainIdSchema;
26
27
  exports.curatorNameSchema = require_model_curators_schema.curatorNameSchema;
@@ -47,6 +48,8 @@ exports.matchesOpportunityFilter = require_model_opportunities.matchesOpportunit
47
48
  exports.matchesPositionFilter = require_model_positions.matchesPositionFilter;
48
49
  exports.opportunityBaseSchema = require_model_opportunities_schema.opportunityBaseSchema;
49
50
  exports.opportunityDetailSchema = require_model_opportunities_schema.opportunityDetailSchema;
51
+ exports.opportunityFilterQueryParamsSchema = require_model_opportunities_schema.opportunityFilterQueryParamsSchema;
52
+ exports.opportunityFilterQuerySchema = require_model_opportunities_schema.opportunityFilterQuerySchema;
50
53
  exports.opportunityFilterSchema = require_model_opportunities_schema.opportunityFilterSchema;
51
54
  exports.opportunityHistoryQuerySchema = require_model_history_schema.opportunityHistoryQuerySchema;
52
55
  exports.opportunityId = require_model_opportunities.opportunityId;
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_sdk_utils_zod = require("../sdk/utils/zod.js");
3
3
  const require_model_curators_schema = require("./curators.schema.js");
4
+ const require_model_filters = require("./filters.js");
4
5
  const require_model_filters_schema = require("./filters.schema.js");
5
6
  const require_model_primitives_schema = require("./primitives.schema.js");
6
7
  let zod_v4 = require("zod/v4");
@@ -112,6 +113,48 @@ const opportunityFilterSchema = zod_v4.z.object({
112
113
  rwa: require_model_filters_schema.filterable(zod_v4.z.boolean()).optional()
113
114
  });
114
115
  /**
116
+ * {@link OpportunityFilter} as a URL can carry it: every condition is a string,
117
+ * and a condition that does not narrow is absent rather than empty.
118
+ **/
119
+ const opportunityFilterQueryParamsSchema = zod_v4.z.object({
120
+ kind: opportunityKindSchema.optional(),
121
+ chainIds: zod_v4.z.string().regex(/^$|^\d+(,\d+)*$/).optional(),
122
+ underlyingType: require_model_primitives_schema.assetTypeSchema.optional(),
123
+ paused: require_model_filters_schema.booleanParamSchema.optional(),
124
+ sunset: require_model_filters_schema.booleanParamSchema.optional(),
125
+ rwa: require_model_filters_schema.booleanParamSchema.optional()
126
+ });
127
+ /**
128
+ * Code for {@link OpportunityFilter} to encode/decode to/from url query parameters.
129
+ **/
130
+ const opportunityFilterQuerySchema = zod_v4.z.codec(opportunityFilterQueryParamsSchema, opportunityFilterSchema, {
131
+ decode: (params) => {
132
+ const filter = {};
133
+ if (params.kind !== void 0) filter.kind = params.kind;
134
+ if (params.chainIds !== void 0) filter.chainIds = decodeChainIds(params.chainIds);
135
+ if (params.underlyingType !== void 0) filter.underlyingType = params.underlyingType;
136
+ if (params.paused !== void 0) filter.paused = params.paused === "true";
137
+ if (params.sunset !== void 0) filter.sunset = params.sunset === "true";
138
+ if (params.rwa !== void 0) filter.rwa = params.rwa === "true";
139
+ return filter;
140
+ },
141
+ encode: (filter) => ({
142
+ kind: require_model_filters.isFilterSet(filter.kind) ? filter.kind : void 0,
143
+ chainIds: require_model_filters.isFilterSet(filter.chainIds) ? filter.chainIds.join(",") : void 0,
144
+ underlyingType: require_model_filters.isFilterSet(filter.underlyingType) ? filter.underlyingType : void 0,
145
+ paused: encodeFlag(filter.paused),
146
+ sunset: encodeFlag(filter.sunset),
147
+ rwa: encodeFlag(filter.rwa)
148
+ })
149
+ });
150
+ function decodeChainIds(param) {
151
+ return param === "" ? [] : param.split(",").map(Number);
152
+ }
153
+ function encodeFlag(condition) {
154
+ if (!require_model_filters.isFilterSet(condition)) return;
155
+ return condition ? "true" : "false";
156
+ }
157
+ /**
115
158
  * {@link RateCurvePoint}
116
159
  **/
117
160
  const rateCurvePointSchema = zod_v4.z.object({
@@ -205,6 +248,8 @@ const opportunityKeySchema = zod_v4.z.discriminatedUnion("kind", [zod_v4.z.objec
205
248
  exports.apyBreakdownSchema = apyBreakdownSchema;
206
249
  exports.opportunityBaseSchema = opportunityBaseSchema;
207
250
  exports.opportunityDetailSchema = opportunityDetailSchema;
251
+ exports.opportunityFilterQueryParamsSchema = opportunityFilterQueryParamsSchema;
252
+ exports.opportunityFilterQuerySchema = opportunityFilterQuerySchema;
208
253
  exports.opportunityFilterSchema = opportunityFilterSchema;
209
254
  exports.opportunityKeySchema = opportunityKeySchema;
210
255
  exports.opportunityKindSchema = opportunityKindSchema;
@@ -0,0 +1,132 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_model_history_schema = require("../model/history.schema.js");
3
+ const require_offchain_types = require("./types.js");
4
+ let zod_v4 = require("zod/v4");
5
+ //#region src/offchain/AbstractOffchainNamespace.ts
6
+ const DEFAULT_TIMEOUT = 3e4;
7
+ /**
8
+ * Common logic of every {@link GearboxAPI} namespace.
9
+ *
10
+ * A namespace is a set of routes: it knows which path answers which read and
11
+ * which schema describes the payload. Everything under that — where the
12
+ * backend is, how long a request may take, how a failure is reported and how a
13
+ * response becomes read model values — lives here, so a namespace holds
14
+ * nothing but its routes.
15
+ **/
16
+ var AbstractOffchainNamespace = class {
17
+ logger;
18
+ #baseUrl;
19
+ #timeout;
20
+ constructor(name, options) {
21
+ this.#baseUrl = options?.baseUrl?.replace(/\/+$/, "");
22
+ this.#timeout = options?.timeout ?? DEFAULT_TIMEOUT;
23
+ this.logger = options?.logger?.child?.({ name }) ?? options?.logger;
24
+ }
25
+ /**
26
+ * Base URL every read of this namespace is issued against.
27
+ **/
28
+ get baseUrl() {
29
+ return this.#baseUrl;
30
+ }
31
+ /**
32
+ * Reads one endpoint and decodes its payload.
33
+ *
34
+ * The envelope is built here rather than by the caller: the status is
35
+ * `"success"` whenever this returns at all, because anything else has
36
+ * already thrown.
37
+ **/
38
+ async get(request) {
39
+ const url = this.#url(request.path, request.query);
40
+ this.logger?.debug(`reading ${url}`);
41
+ const payload = await this.#fetchJson(url);
42
+ const parsed = request.schema.safeParse(payload);
43
+ if (!parsed.success) {
44
+ this.logger?.error({
45
+ url,
46
+ issues: parsed.error.issues
47
+ }, "offchain response does not match the read model");
48
+ throw new require_offchain_types.OffchainValidationError(url, parsed.error.issues);
49
+ }
50
+ return {
51
+ result: parsed.data,
52
+ meta: { status: "success" }
53
+ };
54
+ }
55
+ /**
56
+ * Reads one historical series.
57
+ *
58
+ * The requested metric is pinned in the schema, which is what upholds the
59
+ * `HistorySeries<M>` a caller gets back: a response carrying a different
60
+ * metric is version skew and fails validation like any other mismatch,
61
+ * rather than being cast into the requested shape.
62
+ **/
63
+ async readHistory(request) {
64
+ return this.get({
65
+ path: request.path,
66
+ query: { range: request.range },
67
+ schema: require_model_history_schema.historySeriesSchema.extend({ metric: zod_v4.z.literal(request.metric) })
68
+ });
69
+ }
70
+ /**
71
+ * Full URL of a read, with the conditions that do not narrow left out.
72
+ **/
73
+ #url(path, query) {
74
+ if (!this.#baseUrl) throw new require_offchain_types.OffchainNotConfiguredError(path);
75
+ const url = new URL(`${this.#baseUrl}${path}`);
76
+ for (const [key, value] of Object.entries(query ?? {})) if (value !== void 0) url.searchParams.set(key, value);
77
+ return url.toString();
78
+ }
79
+ /**
80
+ * Body of a successful read, still undecoded.
81
+ **/
82
+ async #fetchJson(url) {
83
+ let response;
84
+ try {
85
+ response = await fetch(url, {
86
+ headers: { accept: "application/json" },
87
+ signal: AbortSignal.timeout(this.#timeout)
88
+ });
89
+ } catch (error) {
90
+ throw new require_offchain_types.OffchainTransportError(url, describe(error));
91
+ }
92
+ if (!response.ok) throw new require_offchain_types.OffchainTransportError(url, await failureReason(response), response.status);
93
+ try {
94
+ return await response.json();
95
+ } catch (error) {
96
+ throw new require_offchain_types.OffchainTransportError(url, `the body is not JSON (${describe(error)})`, response.status);
97
+ }
98
+ }
99
+ };
100
+ /**
101
+ * Why a non-2xx response failed, in the backend's own words when it said.
102
+ **/
103
+ async function failureReason(response) {
104
+ const status = `the backend answered ${response.status}`;
105
+ let body;
106
+ try {
107
+ body = await response.text();
108
+ } catch {
109
+ return status;
110
+ }
111
+ const message = backendMessage(body) ?? body.trim();
112
+ return message ? `${status}: ${truncate(message)}` : status;
113
+ }
114
+ /**
115
+ * The `message` of a Gearbox backend error body, or nothing when the body is
116
+ * not one.
117
+ **/
118
+ function backendMessage(body) {
119
+ try {
120
+ const parsed = JSON.parse(body);
121
+ if (typeof parsed === "object" && parsed !== null && "message" in parsed && typeof parsed.message === "string") return parsed.message;
122
+ } catch {}
123
+ }
124
+ function describe(error) {
125
+ if (error instanceof Error) return error.name === "TimeoutError" ? "the request timed out" : error.message;
126
+ return String(error);
127
+ }
128
+ function truncate(text) {
129
+ return text.length > 200 ? `${text.slice(0, 200)}…` : text;
130
+ }
131
+ //#endregion
132
+ exports.AbstractOffchainNamespace = AbstractOffchainNamespace;
@@ -1,11 +1,16 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_offchain_types = require("./types.js");
3
+ const require_offchain_AbstractOffchainNamespace = require("./AbstractOffchainNamespace.js");
3
4
  const require_offchain_opportunities_OffchainOpportunities = require("./opportunities/OffchainOpportunities.js");
4
5
  require("./opportunities/index.js");
5
6
  const require_offchain_positions_OffchainPositions = require("./positions/OffchainPositions.js");
6
7
  require("./positions/index.js");
7
8
  const require_offchain_GearboxAPI = require("./GearboxAPI.js");
9
+ exports.AbstractOffchainNamespace = require_offchain_AbstractOffchainNamespace.AbstractOffchainNamespace;
8
10
  exports.GearboxAPI = require_offchain_GearboxAPI.GearboxAPI;
11
+ exports.OffchainNotConfiguredError = require_offchain_types.OffchainNotConfiguredError;
9
12
  exports.OffchainNotImplementedError = require_offchain_types.OffchainNotImplementedError;
10
13
  exports.OffchainOpportunities = require_offchain_opportunities_OffchainOpportunities.OffchainOpportunities;
11
14
  exports.OffchainPositions = require_offchain_positions_OffchainPositions.OffchainPositions;
15
+ exports.OffchainTransportError = require_offchain_types.OffchainTransportError;
16
+ exports.OffchainValidationError = require_offchain_types.OffchainValidationError;
@@ -1,85 +1,63 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_offchain_types = require("../types.js");
2
+ const require_model_opportunities_schema = require("../../model/opportunities.schema.js");
3
+ const require_offchain_AbstractOffchainNamespace = require("../AbstractOffchainNamespace.js");
4
+ let zod_v4 = require("zod/v4");
3
5
  //#region src/offchain/opportunities/OffchainOpportunities.ts
4
6
  /**
5
7
  * Backend counterpart of the `opportunities` namespace.
6
- *
7
- * This is a stub: the HTTP client is not written yet, so list reads answer with
8
- * an empty list and detail reads throw. Every signature is already the final
9
- * one, because the backend returns the read model types directly — there is no
10
- * wire DTO and no mapper between the two.
11
- *
12
- * When the transport lands, each method will validate the response against the
13
- * matching schema from `src/model` before returning it. A validation failure is
14
- * a version-skew error and is handled exactly like a transport error: the
15
- * combined SDK drops the backend's contribution in `both` mode and rethrows in
16
- * `offchain` mode.
17
8
  **/
18
- var OffchainOpportunities = class {
19
- #baseUrl;
20
- #logger;
9
+ var OffchainOpportunities = class extends require_offchain_AbstractOffchainNamespace.AbstractOffchainNamespace {
10
+ #root = "/v2/opportunities";
21
11
  constructor(options) {
22
- this.#baseUrl = options?.baseUrl;
23
- this.#logger = options?.logger?.child?.({ name: "OffchainOpportunities" });
24
- }
25
- /**
26
- * Base URL the client will call once the transport is implemented.
27
- **/
28
- get baseUrl() {
29
- return this.#baseUrl;
12
+ super("OffchainOpportunities", options);
30
13
  }
31
14
  /**
32
15
  * All opportunities the backend knows about, optionally narrowed by
33
16
  * {@link OpportunityFilter}.
34
- *
35
- * @returns An empty list until the backend client is implemented.
36
17
  **/
37
18
  async list(filter) {
38
- this.#logger?.debug({ filter }, "offchain opportunities list is not implemented, serving empty list");
39
- return {
40
- result: [],
41
- meta: { status: "success" }
42
- };
19
+ return this.get({
20
+ path: this.#root,
21
+ query: filter ? zod_v4.z.encode(require_model_opportunities_schema.opportunityFilterQuerySchema, filter) : void 0,
22
+ schema: zod_v4.z.array(require_model_opportunities_schema.opportunitySchema)
23
+ });
43
24
  }
44
25
  /**
45
26
  * Detailed view of one pool opportunity.
46
- *
47
- * @throws {@link OffchainNotImplementedError} until the backend client is
48
- * implemented.
49
27
  **/
50
28
  async getPool(key) {
51
- throw new require_offchain_types.OffchainNotImplementedError("opportunities.getPool");
29
+ return this.get({
30
+ path: this.#poolPath(key),
31
+ schema: require_model_opportunities_schema.poolOpportunityDetailSchema
32
+ });
52
33
  }
53
34
  /**
54
35
  * Detailed view of one strategy opportunity.
55
- *
56
- * @throws {@link OffchainNotImplementedError} until the backend client is
57
- * implemented.
58
36
  **/
59
37
  async getStrategy(key) {
60
- throw new require_offchain_types.OffchainNotImplementedError("opportunities.getStrategy");
38
+ return this.get({
39
+ path: this.#strategyPath(key),
40
+ schema: require_model_opportunities_schema.strategyOpportunityDetailSchema
41
+ });
61
42
  }
62
43
  /**
63
- * One historical series of one opportunity. History exists only here:
64
- * rebuilding it from the chain would mean an archive read per point.
65
- *
66
- * The requested metric types the response, so a caller asking for one metric
67
- * does not have to narrow the union back down. When the transport lands,
68
- * validation is what upholds it: a response carrying a different metric than
69
- * the one asked for is a version-skew error like any other.
70
- *
71
- * @returns An empty series until the backend client is implemented.
44
+ * One historical series of one opportunity
72
45
  **/
73
46
  async getHistory(query) {
74
- this.#logger?.debug({ query }, "offchain opportunities history is not implemented, serving empty series");
75
- return {
76
- result: {
77
- metric: query.metric,
78
- points: [],
79
- metadata: {}
80
- },
81
- meta: { status: "success" }
82
- };
47
+ return this.readHistory({
48
+ path: `${this.#historyRoot(query.opportunity)}/history/${query.metric}`,
49
+ metric: query.metric,
50
+ range: query.range
51
+ });
52
+ }
53
+ #poolPath(key) {
54
+ return `${this.#root}/pools/${key.chainId}/${key.pool}`;
55
+ }
56
+ #strategyPath(key) {
57
+ return `${this.#root}/strategies/${key.chainId}/${key.creditManager}/${key.targetCollateral}`;
58
+ }
59
+ #historyRoot(key) {
60
+ return key.kind === "pool" ? this.#poolPath(key) : this.#strategyPath(key);
83
61
  }
84
62
  };
85
63
  //#endregion
@@ -1,31 +1,12 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_offchain_AbstractOffchainNamespace = require("../AbstractOffchainNamespace.js");
2
3
  //#region src/offchain/positions/OffchainPositions.ts
3
4
  /**
4
5
  * Backend counterpart of the `positions` namespace.
5
- *
6
- * This is a stub: the HTTP client is not written yet, so reads answer with an
7
- * empty payload. Every signature is already the final one, because the backend
8
- * returns the read model types directly — there is no wire DTO and no mapper
9
- * between the two.
10
- *
11
- * When the transport lands, each method will validate the response against the
12
- * matching schema from `src/model` before returning it. A validation failure is
13
- * a version-skew error and is handled exactly like a transport error: the
14
- * combined SDK drops the backend's contribution in `both` mode and rethrows in
15
- * `offchain` mode.
16
6
  **/
17
- var OffchainPositions = class {
18
- #baseUrl;
19
- #logger;
7
+ var OffchainPositions = class extends require_offchain_AbstractOffchainNamespace.AbstractOffchainNamespace {
20
8
  constructor(options) {
21
- this.#baseUrl = options?.baseUrl;
22
- this.#logger = options?.logger?.child?.({ name: "OffchainPositions" });
23
- }
24
- /**
25
- * Base URL the client will call once the transport is implemented.
26
- **/
27
- get baseUrl() {
28
- return this.#baseUrl;
9
+ super("OffchainPositions", options);
29
10
  }
30
11
  /**
31
12
  * Everything a wallet holds, optionally narrowed by {@link PositionFilter}.
@@ -33,7 +14,7 @@ var OffchainPositions = class {
33
14
  * @returns An empty list until the backend client is implemented.
34
15
  **/
35
16
  async list(wallet, filter) {
36
- this.#logger?.debug({
17
+ this.logger?.debug({
37
18
  wallet,
38
19
  filter
39
20
  }, "offchain positions list is not implemented, serving empty list");
@@ -54,7 +35,7 @@ var OffchainPositions = class {
54
35
  * @returns An empty series until the backend client is implemented.
55
36
  **/
56
37
  async getHistory(query) {
57
- this.#logger?.debug({ query }, "offchain positions history is not implemented, serving empty series");
38
+ this.logger?.debug({ query }, "offchain positions history is not implemented, serving empty series");
58
39
  return {
59
40
  result: {
60
41
  metric: query.metric,
@@ -14,5 +14,63 @@ var OffchainNotImplementedError = class extends Error {
14
14
  this.name = "OffchainNotImplementedError";
15
15
  }
16
16
  };
17
+ /**
18
+ * Thrown when a read is issued against a client that was never told where the
19
+ * backend is.
20
+ **/
21
+ var OffchainNotConfiguredError = class extends Error {
22
+ constructor(path) {
23
+ super(`GearboxAPI: cannot read ${path}, no baseUrl was configured`);
24
+ this.name = "OffchainNotConfiguredError";
25
+ }
26
+ };
27
+ /**
28
+ * Thrown when the backend could not be reached, or answered with a status
29
+ * outside the 2xx range.
30
+ **/
31
+ var OffchainTransportError = class extends Error {
32
+ /**
33
+ * URL that was requested, query included.
34
+ **/
35
+ url;
36
+ /**
37
+ * Status the backend answered with, absent when the request never completed.
38
+ **/
39
+ status;
40
+ constructor(url, reason, status) {
41
+ super(`GearboxAPI: request to ${url} failed, ${reason}`);
42
+ this.name = "OffchainTransportError";
43
+ this.url = url;
44
+ this.status = status;
45
+ }
46
+ };
47
+ /**
48
+ * Thrown when the backend answered, but with a payload the read model does not
49
+ * describe.
50
+ *
51
+ * This is version skew rather than a bad request, and it is deliberately
52
+ * handled like a transport error: the combined SDK drops the backend's
53
+ * contribution in `both` mode and fails the read in `offchain` mode.
54
+ **/
55
+ var OffchainValidationError = class extends Error {
56
+ /**
57
+ * URL whose payload failed to validate.
58
+ **/
59
+ url;
60
+ /**
61
+ * What did not match, in the order zod reported it.
62
+ **/
63
+ issues;
64
+ constructor(url, issues) {
65
+ const summary = issues.map((issue) => `${issue.path.join(".") || "<root>"}: ${issue.message}`).join("; ");
66
+ super(`GearboxAPI: response from ${url} does not match the model, ${summary}`);
67
+ this.name = "OffchainValidationError";
68
+ this.url = url;
69
+ this.issues = issues;
70
+ }
71
+ };
17
72
  //#endregion
73
+ exports.OffchainNotConfiguredError = OffchainNotConfiguredError;
18
74
  exports.OffchainNotImplementedError = OffchainNotImplementedError;
75
+ exports.OffchainTransportError = OffchainTransportError;
76
+ exports.OffchainValidationError = OffchainValidationError;
@@ -1,9 +1,9 @@
1
+ import { ierc20Abi } from "../abi/iERC20.js";
1
2
  import { iCreditFacadeV310Abi } from "../abi/310/generated.js";
2
3
  import { AddressMap } from "../sdk/utils/AddressMap.js";
3
4
  import { AddressSet } from "../sdk/utils/AddressSet.js";
4
5
  import { AssetsMap } from "../sdk/utils/AssetsMap.js";
5
6
  import { childLogger } from "../sdk/utils/childLogger.js";
6
- import { ierc20Abi } from "../abi/iERC20.js";
7
7
  import "../sdk/constants/addresses.js";
8
8
  import { MAX_UINT256, PERCENTAGE_FACTOR } from "../sdk/constants/math.js";
9
9
  import { SDKConstruct } from "../sdk/base/SDKConstruct.js";
@@ -1,6 +1,6 @@
1
+ import { iWithdrawalCompressorV313Abi } from "../abi/IWithdrawalCompressorV313.js";
1
2
  import { getNetworkType } from "../sdk/chain/chains.js";
2
3
  import { getWithdrawalCompressorAddress } from "../sdk/accounts/withdrawal-compressor/addresses.js";
3
- import { iWithdrawalCompressorV313Abi } from "../abi/IWithdrawalCompressorV313.js";
4
4
  import "../sdk/index.js";
5
5
  import { iMidasDataFeedAbi, iMidasRedemptionVaultAbi, midasGatewayAbi, midasRedeemerAbi, midasRedemptionVaultPhantomTokenAbi, securitizeRedeemerAbi, securitizeRedemptionGatewayAbi, securitizeRedemptionPhantomTokenAbi } from "./withdrawalAbi.js";
6
6
  import { erc20Abi, hexToString, parseAbi, parseEther } from "viem";
@@ -15,5 +15,6 @@ const filterAllSchema = z.literal("all");
15
15
  function filterable(schema) {
16
16
  return z.union([schema, filterAllSchema]);
17
17
  }
18
+ const booleanParamSchema = z.enum(["true", "false"]);
18
19
  //#endregion
19
- export { filterAllSchema, filterable };
20
+ export { booleanParamSchema, filterAllSchema, filterable };
@@ -1,10 +1,10 @@
1
1
  import "./curators.js";
2
2
  import { curatorNameSchema, curatorSchema } from "./curators.schema.js";
3
3
  import { FILTER_ALL, isFilterSet } from "./filters.js";
4
- import { filterAllSchema, filterable } from "./filters.schema.js";
4
+ import { booleanParamSchema, filterAllSchema, filterable } from "./filters.schema.js";
5
5
  import { POOL_HISTORY_METRICS, POOL_POSITION_HISTORY_METRICS, STRATEGY_HISTORY_METRICS, STRATEGY_POSITION_HISTORY_METRICS } from "./history.js";
6
6
  import { amountSchema, assetTypeSchema, bpsSchema, chainIdSchema, leverageSchema, timestampSchema, tokenAmountSchema, tokenSchema, txCallSchema } from "./primitives.schema.js";
7
- import { apyBreakdownSchema, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterSchema, opportunityKeySchema, opportunityKindSchema, opportunitySchema, pointRewardsSchema, pointsProgramSchema, poolOpportunityDetailSchema, poolOpportunityKeySchema, poolOpportunitySchema, priceFeedDataSchema, priceFeedSummarySchema, quotaAssetSchema, rateCurvePointSchema, rateCurveSchema, rewardsSchema, strategyOpportunityDetailSchema, strategyOpportunityKeySchema, strategyOpportunitySchema, tokenRewardsSchema } from "./opportunities.schema.js";
7
+ import { apyBreakdownSchema, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterQueryParamsSchema, opportunityFilterQuerySchema, opportunityFilterSchema, opportunityKeySchema, opportunityKindSchema, opportunitySchema, pointRewardsSchema, pointsProgramSchema, poolOpportunityDetailSchema, poolOpportunityKeySchema, poolOpportunitySchema, priceFeedDataSchema, priceFeedSummarySchema, quotaAssetSchema, rateCurvePointSchema, rateCurveSchema, rewardsSchema, strategyOpportunityDetailSchema, strategyOpportunityKeySchema, strategyOpportunitySchema, tokenRewardsSchema } from "./opportunities.schema.js";
8
8
  import { delayedReceivedAssetSchema, instantReceivedAssetSchema, liquidatableAccountFilterSchema, liquidatableAccountSchema, liquidationApprovalSchema, liquidationDetailsSchema, liquidationPositionSchema, receivedAssetSchema } from "./liquidations.schema.js";
9
9
  import { pnlBreakdownSchema, pointsProgramPnLSchema, pointsRewardsPnLSchema, poolPositionKeySchema, poolPositionSchema, positionCollateralSchema, positionFilterSchema, positionKeySchema, positionKindSchema, positionSchema, rewardsPnLSchema, strategyPositionKeySchema, strategyPositionSchema, tokenRewardsPnLSchema } from "./positions.schema.js";
10
10
  import { historyChartMetadataSchema, historyMetricSchema, historyPointSchema, historyRangeSchema, historySeriesSchema, opportunityHistoryQuerySchema, poolHistoryMetricSchema, poolPositionHistoryMetricSchema, positionHistoryMetricSchema, positionHistoryQuerySchema, strategyHistoryMetricSchema, strategyPositionHistoryMetricSchema } from "./history.schema.js";
@@ -12,4 +12,4 @@ import { matchesLiquidatableAccountFilter } from "./liquidations.js";
12
12
  import { matchesOpportunityFilter, opportunityId, poolOpportunityId, strategyOpportunityId } from "./opportunities.js";
13
13
  import { liquidationPositionId, matchesPositionFilter, poolPositionId, positionId, strategyPositionId } from "./positions.js";
14
14
  import "./primitives.js";
15
- export { FILTER_ALL, POOL_HISTORY_METRICS, POOL_POSITION_HISTORY_METRICS, STRATEGY_HISTORY_METRICS, STRATEGY_POSITION_HISTORY_METRICS, amountSchema, apyBreakdownSchema, assetTypeSchema, bpsSchema, chainIdSchema, curatorNameSchema, curatorSchema, delayedReceivedAssetSchema, filterAllSchema, filterable, historyChartMetadataSchema, historyMetricSchema, historyPointSchema, historyRangeSchema, historySeriesSchema, instantReceivedAssetSchema, isFilterSet, leverageSchema, liquidatableAccountFilterSchema, liquidatableAccountSchema, liquidationApprovalSchema, liquidationDetailsSchema, liquidationPositionId, liquidationPositionSchema, matchesLiquidatableAccountFilter, matchesOpportunityFilter, matchesPositionFilter, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterSchema, opportunityHistoryQuerySchema, opportunityId, opportunityKeySchema, opportunityKindSchema, opportunitySchema, pnlBreakdownSchema, pointRewardsSchema, pointsProgramPnLSchema, pointsProgramSchema, pointsRewardsPnLSchema, poolHistoryMetricSchema, poolOpportunityDetailSchema, poolOpportunityId, poolOpportunityKeySchema, poolOpportunitySchema, poolPositionHistoryMetricSchema, poolPositionId, poolPositionKeySchema, poolPositionSchema, positionCollateralSchema, positionFilterSchema, positionHistoryMetricSchema, positionHistoryQuerySchema, positionId, positionKeySchema, positionKindSchema, positionSchema, priceFeedDataSchema, priceFeedSummarySchema, quotaAssetSchema, rateCurvePointSchema, rateCurveSchema, receivedAssetSchema, rewardsPnLSchema, rewardsSchema, strategyHistoryMetricSchema, strategyOpportunityDetailSchema, strategyOpportunityId, strategyOpportunityKeySchema, strategyOpportunitySchema, strategyPositionHistoryMetricSchema, strategyPositionId, strategyPositionKeySchema, strategyPositionSchema, timestampSchema, tokenAmountSchema, tokenRewardsPnLSchema, tokenRewardsSchema, tokenSchema, txCallSchema };
15
+ export { FILTER_ALL, POOL_HISTORY_METRICS, POOL_POSITION_HISTORY_METRICS, STRATEGY_HISTORY_METRICS, STRATEGY_POSITION_HISTORY_METRICS, amountSchema, apyBreakdownSchema, assetTypeSchema, booleanParamSchema, bpsSchema, chainIdSchema, curatorNameSchema, curatorSchema, delayedReceivedAssetSchema, filterAllSchema, filterable, historyChartMetadataSchema, historyMetricSchema, historyPointSchema, historyRangeSchema, historySeriesSchema, instantReceivedAssetSchema, isFilterSet, leverageSchema, liquidatableAccountFilterSchema, liquidatableAccountSchema, liquidationApprovalSchema, liquidationDetailsSchema, liquidationPositionId, liquidationPositionSchema, matchesLiquidatableAccountFilter, matchesOpportunityFilter, matchesPositionFilter, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterQueryParamsSchema, opportunityFilterQuerySchema, opportunityFilterSchema, opportunityHistoryQuerySchema, opportunityId, opportunityKeySchema, opportunityKindSchema, opportunitySchema, pnlBreakdownSchema, pointRewardsSchema, pointsProgramPnLSchema, pointsProgramSchema, pointsRewardsPnLSchema, poolHistoryMetricSchema, poolOpportunityDetailSchema, poolOpportunityId, poolOpportunityKeySchema, poolOpportunitySchema, poolPositionHistoryMetricSchema, poolPositionId, poolPositionKeySchema, poolPositionSchema, positionCollateralSchema, positionFilterSchema, positionHistoryMetricSchema, positionHistoryQuerySchema, positionId, positionKeySchema, positionKindSchema, positionSchema, priceFeedDataSchema, priceFeedSummarySchema, quotaAssetSchema, rateCurvePointSchema, rateCurveSchema, receivedAssetSchema, rewardsPnLSchema, rewardsSchema, strategyHistoryMetricSchema, strategyOpportunityDetailSchema, strategyOpportunityId, strategyOpportunityKeySchema, strategyOpportunitySchema, strategyPositionHistoryMetricSchema, strategyPositionId, strategyPositionKeySchema, strategyPositionSchema, timestampSchema, tokenAmountSchema, tokenRewardsPnLSchema, tokenRewardsSchema, tokenSchema, txCallSchema };
@@ -1,6 +1,7 @@
1
1
  import { ZodAddress } from "../sdk/utils/zod.js";
2
2
  import { curatorSchema } from "./curators.schema.js";
3
- import { filterable } from "./filters.schema.js";
3
+ import { isFilterSet } from "./filters.js";
4
+ import { booleanParamSchema, filterable } from "./filters.schema.js";
4
5
  import { amountSchema, assetTypeSchema, bpsSchema, chainIdSchema, leverageSchema, timestampSchema, tokenSchema } from "./primitives.schema.js";
5
6
  import { z } from "zod/v4";
6
7
  //#region src/model/opportunities.schema.ts
@@ -111,6 +112,48 @@ const opportunityFilterSchema = z.object({
111
112
  rwa: filterable(z.boolean()).optional()
112
113
  });
113
114
  /**
115
+ * {@link OpportunityFilter} as a URL can carry it: every condition is a string,
116
+ * and a condition that does not narrow is absent rather than empty.
117
+ **/
118
+ const opportunityFilterQueryParamsSchema = z.object({
119
+ kind: opportunityKindSchema.optional(),
120
+ chainIds: z.string().regex(/^$|^\d+(,\d+)*$/).optional(),
121
+ underlyingType: assetTypeSchema.optional(),
122
+ paused: booleanParamSchema.optional(),
123
+ sunset: booleanParamSchema.optional(),
124
+ rwa: booleanParamSchema.optional()
125
+ });
126
+ /**
127
+ * Code for {@link OpportunityFilter} to encode/decode to/from url query parameters.
128
+ **/
129
+ const opportunityFilterQuerySchema = z.codec(opportunityFilterQueryParamsSchema, opportunityFilterSchema, {
130
+ decode: (params) => {
131
+ const filter = {};
132
+ if (params.kind !== void 0) filter.kind = params.kind;
133
+ if (params.chainIds !== void 0) filter.chainIds = decodeChainIds(params.chainIds);
134
+ if (params.underlyingType !== void 0) filter.underlyingType = params.underlyingType;
135
+ if (params.paused !== void 0) filter.paused = params.paused === "true";
136
+ if (params.sunset !== void 0) filter.sunset = params.sunset === "true";
137
+ if (params.rwa !== void 0) filter.rwa = params.rwa === "true";
138
+ return filter;
139
+ },
140
+ encode: (filter) => ({
141
+ kind: isFilterSet(filter.kind) ? filter.kind : void 0,
142
+ chainIds: isFilterSet(filter.chainIds) ? filter.chainIds.join(",") : void 0,
143
+ underlyingType: isFilterSet(filter.underlyingType) ? filter.underlyingType : void 0,
144
+ paused: encodeFlag(filter.paused),
145
+ sunset: encodeFlag(filter.sunset),
146
+ rwa: encodeFlag(filter.rwa)
147
+ })
148
+ });
149
+ function decodeChainIds(param) {
150
+ return param === "" ? [] : param.split(",").map(Number);
151
+ }
152
+ function encodeFlag(condition) {
153
+ if (!isFilterSet(condition)) return;
154
+ return condition ? "true" : "false";
155
+ }
156
+ /**
114
157
  * {@link RateCurvePoint}
115
158
  **/
116
159
  const rateCurvePointSchema = z.object({
@@ -201,4 +244,4 @@ const opportunityKeySchema = z.discriminatedUnion("kind", [z.object({
201
244
  ...strategyOpportunityKeySchema.shape
202
245
  })]);
203
246
  //#endregion
204
- export { apyBreakdownSchema, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterSchema, opportunityKeySchema, opportunityKindSchema, opportunitySchema, pointRewardsSchema, pointsProgramSchema, poolOpportunityDetailSchema, poolOpportunityKeySchema, poolOpportunitySchema, priceFeedDataSchema, priceFeedSummarySchema, quotaAssetSchema, rateCurvePointSchema, rateCurveSchema, rewardsSchema, strategyOpportunityDetailSchema, strategyOpportunityKeySchema, strategyOpportunitySchema, tokenRewardsSchema };
247
+ export { apyBreakdownSchema, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterQueryParamsSchema, opportunityFilterQuerySchema, opportunityFilterSchema, opportunityKeySchema, opportunityKindSchema, opportunitySchema, pointRewardsSchema, pointsProgramSchema, poolOpportunityDetailSchema, poolOpportunityKeySchema, poolOpportunitySchema, priceFeedDataSchema, priceFeedSummarySchema, quotaAssetSchema, rateCurvePointSchema, rateCurveSchema, rewardsSchema, strategyOpportunityDetailSchema, strategyOpportunityKeySchema, strategyOpportunitySchema, tokenRewardsSchema };