@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.
- package/dist/cjs/model/filters.schema.js +2 -0
- package/dist/cjs/model/index.js +3 -0
- package/dist/cjs/model/opportunities.schema.js +45 -0
- package/dist/cjs/offchain/AbstractOffchainNamespace.js +132 -0
- package/dist/cjs/offchain/index.js +5 -0
- package/dist/cjs/offchain/opportunities/OffchainOpportunities.js +34 -56
- package/dist/cjs/offchain/positions/OffchainPositions.js +5 -24
- package/dist/cjs/offchain/types.js +58 -0
- package/dist/esm/dev/AccountOpener.js +1 -1
- package/dist/esm/dev/withdrawalUtils.js +1 -1
- package/dist/esm/model/filters.schema.js +2 -1
- package/dist/esm/model/index.js +3 -3
- package/dist/esm/model/opportunities.schema.js +45 -2
- package/dist/esm/offchain/AbstractOffchainNamespace.js +131 -0
- package/dist/esm/offchain/index.js +3 -2
- package/dist/esm/offchain/opportunities/OffchainOpportunities.js +34 -56
- package/dist/esm/offchain/positions/OffchainPositions.js +5 -24
- package/dist/esm/offchain/types.js +56 -1
- package/dist/esm/plugins/adapters/contracts/ERC4626AdapterContract.js +1 -1
- package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
- package/dist/esm/preview/trace/extractTransfers.js +1 -1
- package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +2 -2
- package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +1 -1
- package/dist/esm/sdk/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
- package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
- package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
- package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
- package/dist/esm/sdk/base/TokensMeta.js +2 -2
- package/dist/esm/sdk/chain/detectNetwork.js +1 -1
- package/dist/esm/sdk/core/createAddressProvider.js +1 -1
- package/dist/esm/sdk/market/credit/CreditFacadeV310BaseContract.js +1 -1
- package/dist/esm/sdk/market/pool/PoolV310Contract.js +1 -1
- package/dist/esm/sdk/market/zapper/IETHZapperContract.js +1 -1
- package/dist/esm/sdk/market/zapper/ZapperContract.js +1 -1
- package/dist/esm/sdk/pools/PoolService.js +1 -1
- package/dist/esm/sdk/utils/viem/simulateWithPriceUpdates.js +1 -1
- package/dist/types/model/filters.schema.d.ts +5 -1
- package/dist/types/model/index.d.ts +3 -3
- package/dist/types/model/opportunities.schema.d.ts +49 -1
- package/dist/types/offchain/AbstractOffchainNamespace.d.ts +87 -0
- package/dist/types/offchain/index.d.ts +3 -2
- package/dist/types/offchain/opportunities/OffchainOpportunities.d.ts +3 -33
- package/dist/types/offchain/positions/OffchainPositions.d.ts +2 -17
- package/dist/types/offchain/types.d.ts +49 -1
- 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;
|
package/dist/cjs/model/index.js
CHANGED
|
@@ -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
|
|
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
|
-
#
|
|
20
|
-
#logger;
|
|
9
|
+
var OffchainOpportunities = class extends require_offchain_AbstractOffchainNamespace.AbstractOffchainNamespace {
|
|
10
|
+
#root = "/v2/opportunities";
|
|
21
11
|
constructor(options) {
|
|
22
|
-
|
|
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
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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 };
|
package/dist/esm/model/index.js
CHANGED
|
@@ -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 {
|
|
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 };
|