@morpho-dev/router 0.1.17 → 0.2.0
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/README.md +34 -24
- package/dist/cli.js +3140 -2143
- package/dist/cli.js.map +1 -1
- package/dist/drizzle/VERSION.ts +3 -0
- package/dist/drizzle/drizzle.config.ts +18 -0
- package/dist/drizzle/index.ts +2 -0
- package/dist/drizzle/{router_v1.4/0000_add_obligation_id.sql → router_v1.5/0000_add_block_number_to_liquidity_graph_and_offer_liquidity_pools_relation.sql} +49 -39
- package/dist/drizzle/router_v1.5/0001_create_new_relations_to_prepare_new_liquidity_model.sql +55 -0
- package/dist/drizzle/router_v1.5/0002_add_new_offer_status_relation.sql +9 -0
- package/dist/drizzle/router_v1.5/0003_insert-status-code.sql +1 -0
- package/dist/drizzle/router_v1.5/0004_add_index_for_fast_book_lookup.sql +3 -0
- package/dist/drizzle/router_v1.5/0005_add_group_consumed_events_table.sql +12 -0
- package/dist/drizzle/router_v1.5/0006_add-trigger-for-consumed-events.sql +58 -0
- package/dist/drizzle/router_v1.5/0007_update_index_for_fast_book_lookup.sql +5 -0
- package/dist/drizzle/router_v1.5/0008_rename_consumed_events_table.sql +8 -0
- package/dist/drizzle/{router_v1.4 → router_v1.5}/meta/0000_snapshot.json +83 -27
- package/dist/drizzle/{router_v1.4 → router_v1.5}/meta/0001_snapshot.json +459 -27
- package/dist/drizzle/router_v1.5/meta/0002_snapshot.json +1463 -0
- package/dist/drizzle/router_v1.5/meta/0003_snapshot.json +1463 -0
- package/dist/drizzle/router_v1.5/meta/0004_snapshot.json +1569 -0
- package/dist/drizzle/router_v1.5/meta/0005_snapshot.json +1664 -0
- package/dist/drizzle/router_v1.5/meta/0006_snapshot.json +1664 -0
- package/dist/drizzle/router_v1.5/meta/0007_snapshot.json +1752 -0
- package/dist/drizzle/router_v1.5/meta/0008_snapshot.json +1752 -0
- package/dist/drizzle/router_v1.5/meta/_journal.json +69 -0
- package/dist/drizzle/schema.ts +363 -0
- package/dist/index.browser.d.cts +909 -159
- package/dist/index.browser.d.ts +909 -159
- package/dist/index.browser.js +1529 -1037
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.mjs +1522 -1036
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.node.d.cts +2718 -912
- package/dist/index.node.d.ts +2718 -912
- package/dist/index.node.js +6827 -5521
- package/dist/index.node.js.map +1 -1
- package/dist/index.node.mjs +6816 -5515
- package/dist/index.node.mjs.map +1 -1
- package/package.json +21 -17
- package/dist/drizzle/router_v1.4/0001_update-primary-key-on-link.sql +0 -3
- package/dist/drizzle/router_v1.4/meta/_journal.json +0 -20
package/dist/index.browser.js
CHANGED
|
@@ -2,12 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
var v4 = require('zod/v4');
|
|
4
4
|
var viem = require('viem');
|
|
5
|
-
|
|
5
|
+
require('reflect-metadata');
|
|
6
|
+
var openapiMetadata = require('openapi-metadata');
|
|
7
|
+
var decorators = require('openapi-metadata/decorators');
|
|
8
|
+
var z9 = require('zod');
|
|
9
|
+
var jsBase64 = require('js-base64');
|
|
10
|
+
var createOpenApiFetchClient = require('openapi-fetch');
|
|
6
11
|
var actions = require('viem/actions');
|
|
7
12
|
var chains$1 = require('viem/chains');
|
|
8
|
-
var z7 = require('zod');
|
|
9
13
|
var accounts = require('viem/accounts');
|
|
10
|
-
var
|
|
14
|
+
var merkleTree = require('@openzeppelin/merkle-tree');
|
|
15
|
+
var pako = require('pako');
|
|
16
|
+
|
|
17
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
18
|
|
|
12
19
|
function _interopNamespace(e) {
|
|
13
20
|
if (e && e.__esModule) return e;
|
|
@@ -27,14 +34,24 @@ function _interopNamespace(e) {
|
|
|
27
34
|
return Object.freeze(n);
|
|
28
35
|
}
|
|
29
36
|
|
|
30
|
-
var
|
|
37
|
+
var z9__namespace = /*#__PURE__*/_interopNamespace(z9);
|
|
38
|
+
var createOpenApiFetchClient__default = /*#__PURE__*/_interopDefault(createOpenApiFetchClient);
|
|
31
39
|
|
|
32
40
|
var __defProp = Object.defineProperty;
|
|
41
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
33
42
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
34
43
|
var __export = (target, all) => {
|
|
35
44
|
for (var name in all)
|
|
36
45
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
37
46
|
};
|
|
47
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
48
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
49
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
50
|
+
if (decorator = decorators[i])
|
|
51
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
52
|
+
if (kind && result) __defProp(target, key, result);
|
|
53
|
+
return result;
|
|
54
|
+
};
|
|
38
55
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
39
56
|
|
|
40
57
|
// src/api/Schema/index.ts
|
|
@@ -44,8 +61,11 @@ __export(Schema_exports, {
|
|
|
44
61
|
ChainsHealthResponse: () => ChainsHealthResponse,
|
|
45
62
|
CollectorHealth: () => CollectorHealth,
|
|
46
63
|
CollectorsHealthResponse: () => CollectorsHealthResponse,
|
|
64
|
+
HealthController: () => HealthController,
|
|
47
65
|
ObligationResponse: () => ObligationResponse_exports,
|
|
66
|
+
ObligationsController: () => ObligationsController,
|
|
48
67
|
OfferResponse: () => OfferResponse_exports,
|
|
68
|
+
OffersController: () => OffersController,
|
|
49
69
|
OpenApi: () => OpenApi,
|
|
50
70
|
RouterStatusResponse: () => RouterStatusResponse,
|
|
51
71
|
parse: () => parse,
|
|
@@ -80,6 +100,7 @@ __export(ObligationResponse_exports, {
|
|
|
80
100
|
var Format_exports = {};
|
|
81
101
|
__export(Format_exports, {
|
|
82
102
|
fromSnakeCase: () => fromSnakeCase,
|
|
103
|
+
stringifyBigint: () => stringifyBigint,
|
|
83
104
|
toSnakeCase: () => toSnakeCase
|
|
84
105
|
});
|
|
85
106
|
function toSnakeCase(obj) {
|
|
@@ -139,9 +160,621 @@ __export(OfferResponse_exports, {
|
|
|
139
160
|
from: () => from2
|
|
140
161
|
});
|
|
141
162
|
function from2(offer) {
|
|
142
|
-
|
|
163
|
+
const result = toSnakeCase(offer);
|
|
164
|
+
return { ...result, signature: result.signature ?? null };
|
|
165
|
+
}
|
|
166
|
+
var API_ERROR_CODES = [
|
|
167
|
+
"VALIDATION_ERROR",
|
|
168
|
+
"NOT_FOUND",
|
|
169
|
+
"INTERNAL_SERVER_ERROR",
|
|
170
|
+
"BAD_REQUEST"
|
|
171
|
+
];
|
|
172
|
+
|
|
173
|
+
// src/api/Schema/openapi.ts
|
|
174
|
+
var timestampExample = "2024-01-01T12:00:00.000Z";
|
|
175
|
+
var offerCursorExample = "eyJvZmZzZXQiOjEwMH0";
|
|
176
|
+
var obligationCursorExample = "0x25690ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9abc";
|
|
177
|
+
var offerExample = {
|
|
178
|
+
hash: "0xac4bd8318ec914f89f8af913f162230575b0ac0696a19256bc12138c5cfe1427",
|
|
179
|
+
offering: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
180
|
+
assets: "369216000000000000000000",
|
|
181
|
+
rate: "2750000000000000000",
|
|
182
|
+
maturity: 1761922799,
|
|
183
|
+
expiry: 1761922799,
|
|
184
|
+
start: 1761922790,
|
|
185
|
+
nonce: "571380",
|
|
186
|
+
buy: false,
|
|
187
|
+
chain_id: "1",
|
|
188
|
+
loan_token: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
|
|
189
|
+
collaterals: [
|
|
190
|
+
{
|
|
191
|
+
asset: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
|
|
192
|
+
oracle: "0x45093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
193
|
+
lltv: "860000000000000000"
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
callback: {
|
|
197
|
+
address: "0x1111111111111111111111111111111111111111",
|
|
198
|
+
data: "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000034cf890db685fc536e05652fb41f02090c3fb751000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000108e644e3ab01184155270aa92a00000000000",
|
|
199
|
+
gas_limit: "500000"
|
|
200
|
+
},
|
|
201
|
+
signature: "0x1234567890123456789012345678901234567890123456789012345678901234123456789012345678901234567890123456789012345678901234567890123400",
|
|
202
|
+
consumed: "0",
|
|
203
|
+
block_number: 2942933377146801
|
|
204
|
+
};
|
|
205
|
+
var collectorsHealthExample = {
|
|
206
|
+
name: "mempool_offers",
|
|
207
|
+
chain_id: "1",
|
|
208
|
+
block_number: 21345678,
|
|
209
|
+
updated_at: timestampExample,
|
|
210
|
+
lag: 0,
|
|
211
|
+
status: "live"
|
|
212
|
+
};
|
|
213
|
+
var chainsHealthExample = {
|
|
214
|
+
chain_id: "1",
|
|
215
|
+
block_number: 21345678,
|
|
216
|
+
updated_at: timestampExample
|
|
217
|
+
};
|
|
218
|
+
var routerStatusExample = {
|
|
219
|
+
status: "live"
|
|
220
|
+
};
|
|
221
|
+
var Meta = class {
|
|
222
|
+
};
|
|
223
|
+
__decorateClass([
|
|
224
|
+
decorators.ApiProperty({ type: "string", example: timestampExample })
|
|
225
|
+
], Meta.prototype, "timestamp", 2);
|
|
226
|
+
var SuccessResponse = class {
|
|
227
|
+
};
|
|
228
|
+
__decorateClass([
|
|
229
|
+
decorators.ApiProperty({ type: "string", enum: ["success"] })
|
|
230
|
+
], SuccessResponse.prototype, "status", 2);
|
|
231
|
+
__decorateClass([
|
|
232
|
+
decorators.ApiProperty({ type: () => Meta })
|
|
233
|
+
], SuccessResponse.prototype, "meta", 2);
|
|
234
|
+
var ErrorResponse = class {
|
|
235
|
+
};
|
|
236
|
+
__decorateClass([
|
|
237
|
+
decorators.ApiProperty({ type: "string", enum: API_ERROR_CODES, example: "VALIDATION_ERROR" })
|
|
238
|
+
], ErrorResponse.prototype, "code", 2);
|
|
239
|
+
__decorateClass([
|
|
240
|
+
decorators.ApiProperty({
|
|
241
|
+
type: "string",
|
|
242
|
+
example: "Limit must be greater than 0."
|
|
243
|
+
})
|
|
244
|
+
], ErrorResponse.prototype, "message", 2);
|
|
245
|
+
__decorateClass([
|
|
246
|
+
decorators.ApiProperty({
|
|
247
|
+
type: "object",
|
|
248
|
+
example: [
|
|
249
|
+
{
|
|
250
|
+
field: "limit",
|
|
251
|
+
issue: "Limit must be greater than 0."
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
})
|
|
255
|
+
], ErrorResponse.prototype, "details", 2);
|
|
256
|
+
var BadRequestResponse = class {
|
|
257
|
+
};
|
|
258
|
+
__decorateClass([
|
|
259
|
+
decorators.ApiProperty({ type: "string", enum: ["error"] })
|
|
260
|
+
], BadRequestResponse.prototype, "status", 2);
|
|
261
|
+
__decorateClass([
|
|
262
|
+
decorators.ApiProperty({ type: () => ErrorResponse })
|
|
263
|
+
], BadRequestResponse.prototype, "error", 2);
|
|
264
|
+
__decorateClass([
|
|
265
|
+
decorators.ApiProperty({ type: () => Meta })
|
|
266
|
+
], BadRequestResponse.prototype, "meta", 2);
|
|
267
|
+
var CollateralResponse = class {
|
|
268
|
+
};
|
|
269
|
+
__decorateClass([
|
|
270
|
+
decorators.ApiProperty({ type: "string", example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751" })
|
|
271
|
+
], CollateralResponse.prototype, "asset", 2);
|
|
272
|
+
__decorateClass([
|
|
273
|
+
decorators.ApiProperty({ type: "string", example: "0x45093658BE7f90B63D7c359e8f408e503c2D9401" })
|
|
274
|
+
], CollateralResponse.prototype, "oracle", 2);
|
|
275
|
+
__decorateClass([
|
|
276
|
+
decorators.ApiProperty({ type: "string", example: "860000000000000000" })
|
|
277
|
+
], CollateralResponse.prototype, "lltv", 2);
|
|
278
|
+
var AskResponse = class {
|
|
279
|
+
};
|
|
280
|
+
__decorateClass([
|
|
281
|
+
decorators.ApiProperty({ type: "string", example: "1000000000000000000" })
|
|
282
|
+
], AskResponse.prototype, "rate", 2);
|
|
283
|
+
var BidResponse = class {
|
|
284
|
+
};
|
|
285
|
+
__decorateClass([
|
|
286
|
+
decorators.ApiProperty({ type: "string", example: "1000000000000000000" })
|
|
287
|
+
], BidResponse.prototype, "rate", 2);
|
|
288
|
+
var OfferCallbackResponse = class {
|
|
289
|
+
};
|
|
290
|
+
__decorateClass([
|
|
291
|
+
decorators.ApiProperty({ type: "string", example: offerExample.callback.address })
|
|
292
|
+
], OfferCallbackResponse.prototype, "address", 2);
|
|
293
|
+
__decorateClass([
|
|
294
|
+
decorators.ApiProperty({ type: "string", example: offerExample.callback.data })
|
|
295
|
+
], OfferCallbackResponse.prototype, "data", 2);
|
|
296
|
+
__decorateClass([
|
|
297
|
+
decorators.ApiProperty({ type: "string", example: offerExample.callback.gas_limit })
|
|
298
|
+
], OfferCallbackResponse.prototype, "gas_limit", 2);
|
|
299
|
+
var OfferListItemResponse = class {
|
|
300
|
+
};
|
|
301
|
+
__decorateClass([
|
|
302
|
+
decorators.ApiProperty({ type: "string", example: offerExample.hash })
|
|
303
|
+
], OfferListItemResponse.prototype, "hash", 2);
|
|
304
|
+
__decorateClass([
|
|
305
|
+
decorators.ApiProperty({ type: "string", example: offerExample.offering })
|
|
306
|
+
], OfferListItemResponse.prototype, "offering", 2);
|
|
307
|
+
__decorateClass([
|
|
308
|
+
decorators.ApiProperty({ type: "string", example: offerExample.assets })
|
|
309
|
+
], OfferListItemResponse.prototype, "assets", 2);
|
|
310
|
+
__decorateClass([
|
|
311
|
+
decorators.ApiProperty({ type: "string", example: offerExample.rate })
|
|
312
|
+
], OfferListItemResponse.prototype, "rate", 2);
|
|
313
|
+
__decorateClass([
|
|
314
|
+
decorators.ApiProperty({ type: "number", example: offerExample.maturity })
|
|
315
|
+
], OfferListItemResponse.prototype, "maturity", 2);
|
|
316
|
+
__decorateClass([
|
|
317
|
+
decorators.ApiProperty({ type: "number", example: offerExample.expiry })
|
|
318
|
+
], OfferListItemResponse.prototype, "expiry", 2);
|
|
319
|
+
__decorateClass([
|
|
320
|
+
decorators.ApiProperty({ type: "number", example: offerExample.start })
|
|
321
|
+
], OfferListItemResponse.prototype, "start", 2);
|
|
322
|
+
__decorateClass([
|
|
323
|
+
decorators.ApiProperty({ type: "string", example: offerExample.nonce })
|
|
324
|
+
], OfferListItemResponse.prototype, "nonce", 2);
|
|
325
|
+
__decorateClass([
|
|
326
|
+
decorators.ApiProperty({ type: "boolean", example: offerExample.buy })
|
|
327
|
+
], OfferListItemResponse.prototype, "buy", 2);
|
|
328
|
+
__decorateClass([
|
|
329
|
+
decorators.ApiProperty({ type: "string", example: offerExample.chain_id })
|
|
330
|
+
], OfferListItemResponse.prototype, "chain_id", 2);
|
|
331
|
+
__decorateClass([
|
|
332
|
+
decorators.ApiProperty({ type: "string", example: offerExample.loan_token })
|
|
333
|
+
], OfferListItemResponse.prototype, "loan_token", 2);
|
|
334
|
+
__decorateClass([
|
|
335
|
+
decorators.ApiProperty({ type: () => [CollateralResponse], example: offerExample.collaterals })
|
|
336
|
+
], OfferListItemResponse.prototype, "collaterals", 2);
|
|
337
|
+
__decorateClass([
|
|
338
|
+
decorators.ApiProperty({ type: () => OfferCallbackResponse, example: offerExample.callback })
|
|
339
|
+
], OfferListItemResponse.prototype, "callback", 2);
|
|
340
|
+
__decorateClass([
|
|
341
|
+
decorators.ApiProperty({ type: "string", example: offerExample.consumed })
|
|
342
|
+
], OfferListItemResponse.prototype, "consumed", 2);
|
|
343
|
+
__decorateClass([
|
|
344
|
+
decorators.ApiProperty({ type: "number", example: offerExample.block_number })
|
|
345
|
+
], OfferListItemResponse.prototype, "block_number", 2);
|
|
346
|
+
__decorateClass([
|
|
347
|
+
decorators.ApiProperty({ type: "string", nullable: true, example: offerExample.signature })
|
|
348
|
+
], OfferListItemResponse.prototype, "signature", 2);
|
|
349
|
+
var ObligationResponse = class {
|
|
350
|
+
};
|
|
351
|
+
__decorateClass([
|
|
352
|
+
decorators.ApiProperty({
|
|
353
|
+
type: "string",
|
|
354
|
+
example: "0x12590ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9f67"
|
|
355
|
+
})
|
|
356
|
+
], ObligationResponse.prototype, "id", 2);
|
|
357
|
+
__decorateClass([
|
|
358
|
+
decorators.ApiProperty({ type: "string", example: "1" })
|
|
359
|
+
], ObligationResponse.prototype, "chain_id", 2);
|
|
360
|
+
__decorateClass([
|
|
361
|
+
decorators.ApiProperty({ type: "string", example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078" })
|
|
362
|
+
], ObligationResponse.prototype, "loan_token", 2);
|
|
363
|
+
__decorateClass([
|
|
364
|
+
decorators.ApiProperty({ type: () => [CollateralResponse] })
|
|
365
|
+
], ObligationResponse.prototype, "collaterals", 2);
|
|
366
|
+
__decorateClass([
|
|
367
|
+
decorators.ApiProperty({ type: "number", example: 1761922800 })
|
|
368
|
+
], ObligationResponse.prototype, "maturity", 2);
|
|
369
|
+
__decorateClass([
|
|
370
|
+
decorators.ApiProperty({ type: () => AskResponse })
|
|
371
|
+
], ObligationResponse.prototype, "ask", 2);
|
|
372
|
+
__decorateClass([
|
|
373
|
+
decorators.ApiProperty({ type: () => BidResponse })
|
|
374
|
+
], ObligationResponse.prototype, "bid", 2);
|
|
375
|
+
var ObligationListResponse = class extends SuccessResponse {
|
|
376
|
+
};
|
|
377
|
+
__decorateClass([
|
|
378
|
+
decorators.ApiProperty({ type: "string", nullable: true, example: obligationCursorExample })
|
|
379
|
+
], ObligationListResponse.prototype, "cursor", 2);
|
|
380
|
+
__decorateClass([
|
|
381
|
+
decorators.ApiProperty({
|
|
382
|
+
type: () => [ObligationResponse],
|
|
383
|
+
description: "List of obligations with takable offers."
|
|
384
|
+
})
|
|
385
|
+
], ObligationListResponse.prototype, "data", 2);
|
|
386
|
+
var ObligationSingleSuccessResponse = class extends SuccessResponse {
|
|
387
|
+
};
|
|
388
|
+
__decorateClass([
|
|
389
|
+
decorators.ApiProperty({ type: "string", nullable: true, example: null })
|
|
390
|
+
], ObligationSingleSuccessResponse.prototype, "cursor", 2);
|
|
391
|
+
__decorateClass([
|
|
392
|
+
decorators.ApiProperty({ type: () => ObligationResponse, description: "Obligation details." })
|
|
393
|
+
], ObligationSingleSuccessResponse.prototype, "data", 2);
|
|
394
|
+
var OfferListResponse = class extends SuccessResponse {
|
|
395
|
+
};
|
|
396
|
+
__decorateClass([
|
|
397
|
+
decorators.ApiProperty({ type: "string", nullable: true, example: offerCursorExample })
|
|
398
|
+
], OfferListResponse.prototype, "cursor", 2);
|
|
399
|
+
__decorateClass([
|
|
400
|
+
decorators.ApiProperty({
|
|
401
|
+
type: () => [OfferListItemResponse],
|
|
402
|
+
description: "Offers matching the provided filters.",
|
|
403
|
+
example: [offerExample]
|
|
404
|
+
})
|
|
405
|
+
], OfferListResponse.prototype, "data", 2);
|
|
406
|
+
var RouterStatusDataResponse = class {
|
|
407
|
+
};
|
|
408
|
+
__decorateClass([
|
|
409
|
+
decorators.ApiProperty({ type: "string", enum: ["live", "syncing"], example: routerStatusExample.status })
|
|
410
|
+
], RouterStatusDataResponse.prototype, "status", 2);
|
|
411
|
+
var RouterStatusSuccessResponse = class extends SuccessResponse {
|
|
412
|
+
};
|
|
413
|
+
__decorateClass([
|
|
414
|
+
decorators.ApiProperty({
|
|
415
|
+
type: () => RouterStatusDataResponse,
|
|
416
|
+
description: "Aggregated router status.",
|
|
417
|
+
example: routerStatusExample
|
|
418
|
+
})
|
|
419
|
+
], RouterStatusSuccessResponse.prototype, "data", 2);
|
|
420
|
+
var CollectorHealthResponse = class {
|
|
421
|
+
};
|
|
422
|
+
__decorateClass([
|
|
423
|
+
decorators.ApiProperty({ type: "string", example: collectorsHealthExample.name })
|
|
424
|
+
], CollectorHealthResponse.prototype, "name", 2);
|
|
425
|
+
__decorateClass([
|
|
426
|
+
decorators.ApiProperty({ type: "string", example: collectorsHealthExample.chain_id })
|
|
427
|
+
], CollectorHealthResponse.prototype, "chain_id", 2);
|
|
428
|
+
__decorateClass([
|
|
429
|
+
decorators.ApiProperty({ type: "number", nullable: true, example: collectorsHealthExample.block_number })
|
|
430
|
+
], CollectorHealthResponse.prototype, "block_number", 2);
|
|
431
|
+
__decorateClass([
|
|
432
|
+
decorators.ApiProperty({ type: "string", nullable: true, example: collectorsHealthExample.updated_at })
|
|
433
|
+
], CollectorHealthResponse.prototype, "updated_at", 2);
|
|
434
|
+
__decorateClass([
|
|
435
|
+
decorators.ApiProperty({ type: "number", nullable: true, example: collectorsHealthExample.lag })
|
|
436
|
+
], CollectorHealthResponse.prototype, "lag", 2);
|
|
437
|
+
__decorateClass([
|
|
438
|
+
decorators.ApiProperty({
|
|
439
|
+
type: "string",
|
|
440
|
+
enum: ["live", "lagging", "unknown"],
|
|
441
|
+
example: collectorsHealthExample.status
|
|
442
|
+
})
|
|
443
|
+
], CollectorHealthResponse.prototype, "status", 2);
|
|
444
|
+
var CollectorsHealthSuccessResponse = class extends SuccessResponse {
|
|
445
|
+
};
|
|
446
|
+
__decorateClass([
|
|
447
|
+
decorators.ApiProperty({
|
|
448
|
+
type: () => [CollectorHealthResponse],
|
|
449
|
+
description: "Collectors health details and sync status.",
|
|
450
|
+
example: [collectorsHealthExample]
|
|
451
|
+
})
|
|
452
|
+
], CollectorsHealthSuccessResponse.prototype, "data", 2);
|
|
453
|
+
var ChainHealthResponse = class {
|
|
454
|
+
};
|
|
455
|
+
__decorateClass([
|
|
456
|
+
decorators.ApiProperty({ type: "string", example: chainsHealthExample.chain_id })
|
|
457
|
+
], ChainHealthResponse.prototype, "chain_id", 2);
|
|
458
|
+
__decorateClass([
|
|
459
|
+
decorators.ApiProperty({ type: "number", example: chainsHealthExample.block_number })
|
|
460
|
+
], ChainHealthResponse.prototype, "block_number", 2);
|
|
461
|
+
__decorateClass([
|
|
462
|
+
decorators.ApiProperty({ type: "string", example: chainsHealthExample.updated_at })
|
|
463
|
+
], ChainHealthResponse.prototype, "updated_at", 2);
|
|
464
|
+
var ChainsHealthSuccessResponse = class extends SuccessResponse {
|
|
465
|
+
};
|
|
466
|
+
__decorateClass([
|
|
467
|
+
decorators.ApiProperty({
|
|
468
|
+
type: () => [ChainHealthResponse],
|
|
469
|
+
description: "Latest processed block per chain.",
|
|
470
|
+
example: [chainsHealthExample]
|
|
471
|
+
})
|
|
472
|
+
], ChainsHealthSuccessResponse.prototype, "data", 2);
|
|
473
|
+
var OffersController = class {
|
|
474
|
+
async getOffers() {
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
__decorateClass([
|
|
478
|
+
decorators.ApiOperation({
|
|
479
|
+
methods: ["get"],
|
|
480
|
+
path: "/v1/offers",
|
|
481
|
+
summary: "List all offers",
|
|
482
|
+
description: "Returns a list of offers for a given obligation and side. Offers are sorted by the best rate (depending on the side), their block number (older offers first) and their assets (bigger offers first)."
|
|
483
|
+
}),
|
|
484
|
+
decorators.ApiQuery({ name: "side", type: "string", required: true, enum: ["buy", "sell"], example: "buy" }),
|
|
485
|
+
decorators.ApiQuery({
|
|
486
|
+
name: "obligation_id",
|
|
487
|
+
type: "string",
|
|
488
|
+
required: true,
|
|
489
|
+
example: "0x1234567890123456789012345678901234567890123456789012345678901234",
|
|
490
|
+
description: "Obligation id used to filter offers."
|
|
491
|
+
}),
|
|
492
|
+
decorators.ApiQuery({
|
|
493
|
+
name: "cursor",
|
|
494
|
+
type: "string",
|
|
495
|
+
example: offerCursorExample,
|
|
496
|
+
description: "Pagination cursor in base64url-encoded format."
|
|
497
|
+
}),
|
|
498
|
+
decorators.ApiQuery({
|
|
499
|
+
name: "limit",
|
|
500
|
+
type: "number",
|
|
501
|
+
example: 10,
|
|
502
|
+
description: "Maximum number of offers to return."
|
|
503
|
+
}),
|
|
504
|
+
decorators.ApiResponse({ status: 200, description: "Success", type: OfferListResponse })
|
|
505
|
+
], OffersController.prototype, "getOffers", 1);
|
|
506
|
+
OffersController = __decorateClass([
|
|
507
|
+
decorators.ApiTags("Offers"),
|
|
508
|
+
decorators.ApiResponse({ status: 400, description: "Bad Request", type: BadRequestResponse })
|
|
509
|
+
], OffersController);
|
|
510
|
+
var HealthController = class {
|
|
511
|
+
async getRouterStatus() {
|
|
512
|
+
}
|
|
513
|
+
async getCollectorsHealth() {
|
|
514
|
+
}
|
|
515
|
+
async getChainsHealth() {
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
__decorateClass([
|
|
519
|
+
decorators.ApiOperation({
|
|
520
|
+
methods: ["get"],
|
|
521
|
+
path: "/v1/health",
|
|
522
|
+
summary: "Retrieve global health",
|
|
523
|
+
description: "Returns the aggregated status of the router."
|
|
524
|
+
}),
|
|
525
|
+
decorators.ApiResponse({ status: 200, description: "Success", type: RouterStatusSuccessResponse })
|
|
526
|
+
], HealthController.prototype, "getRouterStatus", 1);
|
|
527
|
+
__decorateClass([
|
|
528
|
+
decorators.ApiOperation({
|
|
529
|
+
methods: ["get"],
|
|
530
|
+
path: "/v1/health/collectors",
|
|
531
|
+
summary: "Retrieve collectors health",
|
|
532
|
+
description: "Returns the latest block numbers processed by collectors and their sync status."
|
|
533
|
+
}),
|
|
534
|
+
decorators.ApiResponse({ status: 200, description: "Success", type: CollectorsHealthSuccessResponse })
|
|
535
|
+
], HealthController.prototype, "getCollectorsHealth", 1);
|
|
536
|
+
__decorateClass([
|
|
537
|
+
decorators.ApiOperation({
|
|
538
|
+
methods: ["get"],
|
|
539
|
+
path: "/v1/health/chains",
|
|
540
|
+
summary: "Retrieve chains health",
|
|
541
|
+
description: "Returns the latest block that can be processed by collectors for each chain."
|
|
542
|
+
}),
|
|
543
|
+
decorators.ApiResponse({ status: 200, description: "Success", type: ChainsHealthSuccessResponse })
|
|
544
|
+
], HealthController.prototype, "getChainsHealth", 1);
|
|
545
|
+
HealthController = __decorateClass([
|
|
546
|
+
decorators.ApiTags("Health")
|
|
547
|
+
], HealthController);
|
|
548
|
+
var ObligationsController = class {
|
|
549
|
+
async getObligations() {
|
|
550
|
+
}
|
|
551
|
+
async getObligation() {
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
__decorateClass([
|
|
555
|
+
decorators.ApiOperation({
|
|
556
|
+
methods: ["get"],
|
|
557
|
+
path: "/v1/obligations",
|
|
558
|
+
summary: "List all obligations",
|
|
559
|
+
description: "Returns a list of obligations with their current best ask and bid. Obligations are sorted by their id in ascending order by default."
|
|
560
|
+
}),
|
|
561
|
+
decorators.ApiQuery({
|
|
562
|
+
name: "cursor",
|
|
563
|
+
type: "string",
|
|
564
|
+
example: obligationCursorExample
|
|
565
|
+
}),
|
|
566
|
+
decorators.ApiQuery({ name: "limit", type: "number", example: 10 }),
|
|
567
|
+
decorators.ApiResponse({ status: 200, description: "Success", type: ObligationListResponse })
|
|
568
|
+
], ObligationsController.prototype, "getObligations", 1);
|
|
569
|
+
__decorateClass([
|
|
570
|
+
decorators.ApiOperation({
|
|
571
|
+
methods: ["get"],
|
|
572
|
+
path: "/v1/obligations/{obligationId}",
|
|
573
|
+
summary: "Get an obligation",
|
|
574
|
+
description: "Returns an obligation by its id."
|
|
575
|
+
}),
|
|
576
|
+
decorators.ApiResponse({ status: 200, description: "Success", type: ObligationSingleSuccessResponse })
|
|
577
|
+
], ObligationsController.prototype, "getObligation", 1);
|
|
578
|
+
ObligationsController = __decorateClass([
|
|
579
|
+
decorators.ApiTags("Obligations"),
|
|
580
|
+
decorators.ApiResponse({ status: 400, description: "Bad Request", type: BadRequestResponse })
|
|
581
|
+
], ObligationsController);
|
|
582
|
+
var OpenApi = async () => await openapiMetadata.generateDocument({
|
|
583
|
+
controllers: [OffersController, ObligationsController, HealthController],
|
|
584
|
+
document: {
|
|
585
|
+
openapi: "3.1.0",
|
|
586
|
+
info: {
|
|
587
|
+
title: "Router API",
|
|
588
|
+
version: "1.0.0",
|
|
589
|
+
description: "API for the Morpho Router"
|
|
590
|
+
},
|
|
591
|
+
servers: [
|
|
592
|
+
{
|
|
593
|
+
url: "https://router.morpho.dev",
|
|
594
|
+
description: "Production server"
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
url: "http://localhost:7891",
|
|
598
|
+
description: "Local development server"
|
|
599
|
+
}
|
|
600
|
+
]
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
// src/database/utils/Cursor.ts
|
|
605
|
+
var Cursor_exports = {};
|
|
606
|
+
__export(Cursor_exports, {
|
|
607
|
+
decode: () => decode,
|
|
608
|
+
encode: () => encode,
|
|
609
|
+
validate: () => validate
|
|
610
|
+
});
|
|
611
|
+
function validate(cursor) {
|
|
612
|
+
if (!cursor || typeof cursor !== "object") {
|
|
613
|
+
throw new Error("Cursor must be an object");
|
|
614
|
+
}
|
|
615
|
+
const c = cursor;
|
|
616
|
+
if (!["rate", "maturity", "expiry", "amount"].includes(c.sort)) {
|
|
617
|
+
throw new Error(
|
|
618
|
+
`Invalid sort field: ${c.sort}. Must be one of: rate, maturity, expiry, amount`
|
|
619
|
+
);
|
|
620
|
+
}
|
|
621
|
+
if (!["asc", "desc"].includes(c.dir)) {
|
|
622
|
+
throw new Error(`Invalid direction: ${c.dir}. Must be one of: asc, desc`);
|
|
623
|
+
}
|
|
624
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(c.hash)) {
|
|
625
|
+
throw new Error(
|
|
626
|
+
`Invalid hash format: ${c.hash}. Must be a 64-character hex string starting with 0x`
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
const validations = {
|
|
630
|
+
rate: {
|
|
631
|
+
field: "rate",
|
|
632
|
+
type: "string",
|
|
633
|
+
pattern: /^\d+$/,
|
|
634
|
+
error: "numeric string"
|
|
635
|
+
},
|
|
636
|
+
amount: {
|
|
637
|
+
field: "assets",
|
|
638
|
+
type: "string",
|
|
639
|
+
pattern: /^\d+$/,
|
|
640
|
+
error: "numeric string"
|
|
641
|
+
},
|
|
642
|
+
maturity: {
|
|
643
|
+
field: "maturity",
|
|
644
|
+
type: "number",
|
|
645
|
+
validator: (val) => val > 0,
|
|
646
|
+
error: "positive number"
|
|
647
|
+
},
|
|
648
|
+
expiry: {
|
|
649
|
+
field: "expiry",
|
|
650
|
+
type: "number",
|
|
651
|
+
validator: (val) => val > 0,
|
|
652
|
+
error: "positive number"
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
const validation = validations[c.sort];
|
|
656
|
+
if (!validation) {
|
|
657
|
+
throw new Error(`Invalid sort field: ${c.sort}`);
|
|
658
|
+
}
|
|
659
|
+
const fieldValue = c[validation.field];
|
|
660
|
+
if (!fieldValue) {
|
|
661
|
+
throw new Error(`${c.sort} sort requires '${validation.field}' field to be present`);
|
|
662
|
+
}
|
|
663
|
+
if (typeof fieldValue !== validation.type) {
|
|
664
|
+
throw new Error(
|
|
665
|
+
`${c.sort} sort requires '${validation.field}' field of type ${validation.type}`
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
if (validation.pattern && !validation.pattern.test(fieldValue)) {
|
|
669
|
+
throw new Error(
|
|
670
|
+
`Invalid ${validation.field} format: ${fieldValue}. Must be a ${validation.error}`
|
|
671
|
+
);
|
|
672
|
+
}
|
|
673
|
+
if (validation.validator && !validation.validator(fieldValue)) {
|
|
674
|
+
throw new Error(
|
|
675
|
+
`Invalid ${validation.field} value: ${fieldValue}. Must be a ${validation.error}`
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
if (c.page !== void 0) {
|
|
679
|
+
if (typeof c.page !== "number" || !Number.isInteger(c.page) || c.page < 1) {
|
|
680
|
+
throw new Error("Invalid page: must be a positive integer");
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
return true;
|
|
684
|
+
}
|
|
685
|
+
function encode(c) {
|
|
686
|
+
return jsBase64.Base64.encodeURL(JSON.stringify(c));
|
|
687
|
+
}
|
|
688
|
+
function decode(token2) {
|
|
689
|
+
if (!token2) return null;
|
|
690
|
+
const decoded = JSON.parse(jsBase64.Base64.decode(token2));
|
|
691
|
+
validate(decoded);
|
|
692
|
+
return decoded;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// src/api/Schema/requests.ts
|
|
696
|
+
var MAX_LIMIT = 100;
|
|
697
|
+
var DEFAULT_LIMIT = 20;
|
|
698
|
+
var PaginationQueryParams = z9__namespace.object({
|
|
699
|
+
cursor: z9__namespace.string().optional().refine(
|
|
700
|
+
(val) => {
|
|
701
|
+
if (!val) return true;
|
|
702
|
+
try {
|
|
703
|
+
const decoded = Cursor_exports.decode(val);
|
|
704
|
+
return decoded !== null;
|
|
705
|
+
} catch (_error) {
|
|
706
|
+
return false;
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
message: "Invalid cursor format. Must be a valid base64url-encoded cursor object"
|
|
711
|
+
}
|
|
712
|
+
).meta({
|
|
713
|
+
description: "Pagination cursor in base64url-encoded format",
|
|
714
|
+
example: "eyJzb3J0IjoicHJpY2UiLCJkaXIiOiJkZXNjIiwicHJpY2UiOiIxMDAwMDAwMDAwMDAwMDAwMDAwIiwiaGFzaCI6IjB4ZGRmZDY4NTllM2UwODJkMTkzODlhMWFlYzFiZGFkN2U4ZDkyZDk2YjFhYTc5NDBkYTkxYTMxMjVkMzFlM2JlNWIifQ"
|
|
715
|
+
}),
|
|
716
|
+
limit: z9__namespace.string().regex(/^[1-9]\d*$/, {
|
|
717
|
+
message: "Limit must be a positive integer"
|
|
718
|
+
}).transform((val) => Number.parseInt(val, 10)).pipe(
|
|
719
|
+
z9__namespace.number().max(MAX_LIMIT, {
|
|
720
|
+
message: `Limit cannot exceed ${MAX_LIMIT}`
|
|
721
|
+
})
|
|
722
|
+
).optional().default(DEFAULT_LIMIT).meta({
|
|
723
|
+
description: `Limit maximum: ${MAX_LIMIT}. Default: ${DEFAULT_LIMIT}`,
|
|
724
|
+
example: 10
|
|
725
|
+
})
|
|
726
|
+
});
|
|
727
|
+
var GetOffersQueryParams = z9__namespace.object({
|
|
728
|
+
...PaginationQueryParams.shape,
|
|
729
|
+
side: z9__namespace.enum(["buy", "sell"]).meta({
|
|
730
|
+
description: "Side of the offer.",
|
|
731
|
+
example: "buy"
|
|
732
|
+
}),
|
|
733
|
+
obligation_id: z9__namespace.string({ error: "Obligation id is required and must be a valid 32-byte hex string" }).regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).meta({
|
|
734
|
+
description: "Offers obligation id",
|
|
735
|
+
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
736
|
+
})
|
|
737
|
+
});
|
|
738
|
+
var GetObligationsQueryParams = z9__namespace.object({
|
|
739
|
+
...PaginationQueryParams.shape,
|
|
740
|
+
cursor: z9__namespace.string().optional().meta({
|
|
741
|
+
description: "Obligation id cursor",
|
|
742
|
+
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
743
|
+
})
|
|
744
|
+
});
|
|
745
|
+
var GetObligationParams = z9__namespace.object({
|
|
746
|
+
obligation_id: z9__namespace.string({ error: "Obligation id is required and must be a valid 32-byte hex string" }).regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).meta({
|
|
747
|
+
description: "Obligation id",
|
|
748
|
+
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
749
|
+
})
|
|
750
|
+
});
|
|
751
|
+
var schemas = {
|
|
752
|
+
get_offers: GetOffersQueryParams,
|
|
753
|
+
get_obligations: GetObligationsQueryParams,
|
|
754
|
+
get_obligation: GetObligationParams
|
|
755
|
+
};
|
|
756
|
+
function parse(action, query) {
|
|
757
|
+
return schemas[action].parse(query);
|
|
758
|
+
}
|
|
759
|
+
function safeParse(action, query, error) {
|
|
760
|
+
return schemas[action].safeParse(query, {
|
|
761
|
+
error
|
|
762
|
+
});
|
|
143
763
|
}
|
|
144
764
|
|
|
765
|
+
// src/client/Client.ts
|
|
766
|
+
var Client_exports = {};
|
|
767
|
+
__export(Client_exports, {
|
|
768
|
+
HttpForbiddenError: () => HttpForbiddenError,
|
|
769
|
+
HttpGetApiFailedError: () => HttpGetApiFailedError,
|
|
770
|
+
HttpRateLimitError: () => HttpRateLimitError,
|
|
771
|
+
HttpUnauthorizedError: () => HttpUnauthorizedError,
|
|
772
|
+
InvalidUrlError: () => InvalidUrlError,
|
|
773
|
+
connect: () => connect,
|
|
774
|
+
getObligations: () => getObligations,
|
|
775
|
+
getOffers: () => getOffers
|
|
776
|
+
});
|
|
777
|
+
|
|
145
778
|
// src/core/Abi.ts
|
|
146
779
|
var Abi_exports = {};
|
|
147
780
|
__export(Abi_exports, {
|
|
@@ -339,11 +972,13 @@ var Morpho = [
|
|
|
339
972
|
var Callback_exports = {};
|
|
340
973
|
__export(Callback_exports, {
|
|
341
974
|
CallbackType: () => CallbackType,
|
|
342
|
-
|
|
975
|
+
decode: () => decode2,
|
|
343
976
|
decodeBuyVaultV1Callback: () => decodeBuyVaultV1Callback,
|
|
344
977
|
decodeSellERC20Callback: () => decodeSellERC20Callback,
|
|
978
|
+
encode: () => encode2,
|
|
345
979
|
encodeBuyVaultV1Callback: () => encodeBuyVaultV1Callback,
|
|
346
|
-
encodeSellERC20Callback: () => encodeSellERC20Callback
|
|
980
|
+
encodeSellERC20Callback: () => encodeSellERC20Callback,
|
|
981
|
+
isEmptyCallback: () => isEmptyCallback
|
|
347
982
|
});
|
|
348
983
|
var CallbackType = /* @__PURE__ */ ((CallbackType2) => {
|
|
349
984
|
CallbackType2["BuyWithEmptyCallback"] = "buy_with_empty_callback";
|
|
@@ -351,19 +986,27 @@ var CallbackType = /* @__PURE__ */ ((CallbackType2) => {
|
|
|
351
986
|
CallbackType2["SellERC20Callback"] = "sell_erc20_callback";
|
|
352
987
|
return CallbackType2;
|
|
353
988
|
})(CallbackType || {});
|
|
354
|
-
var
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
"
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
989
|
+
var isEmptyCallback = (offer) => offer.callback.data === "0x";
|
|
990
|
+
function decode2(type, data) {
|
|
991
|
+
switch (type) {
|
|
992
|
+
case "buy_vault_v1_callback" /* BuyVaultV1Callback */:
|
|
993
|
+
return decodeBuyVaultV1Callback(data);
|
|
994
|
+
case "sell_erc20_callback" /* SellERC20Callback */:
|
|
995
|
+
return decodeSellERC20Callback(data);
|
|
996
|
+
default:
|
|
997
|
+
throw new Error("Invalid callback type");
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
function encode2(type, data) {
|
|
1001
|
+
switch (type) {
|
|
1002
|
+
case "buy_vault_v1_callback" /* BuyVaultV1Callback */:
|
|
1003
|
+
return encodeBuyVaultV1Callback(data);
|
|
1004
|
+
case "sell_erc20_callback" /* SellERC20Callback */:
|
|
1005
|
+
return encodeSellERC20Callback(data);
|
|
1006
|
+
default:
|
|
1007
|
+
throw new Error("Invalid callback type");
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
367
1010
|
function decodeBuyVaultV1Callback(data) {
|
|
368
1011
|
if (!data || data === "0x") throw new Error("Empty callback data");
|
|
369
1012
|
try {
|
|
@@ -505,62 +1148,30 @@ var chains = {
|
|
|
505
1148
|
...chains$1.mainnet,
|
|
506
1149
|
id: ChainId.ETHEREUM,
|
|
507
1150
|
name: "ethereum",
|
|
508
|
-
whitelistedAssets: new Set(
|
|
509
|
-
[
|
|
510
|
-
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
511
|
-
// USDC
|
|
512
|
-
"0x6B175474E89094C44Da98b954EedeAC495271d0F"
|
|
513
|
-
// DAI
|
|
514
|
-
].map((address) => address.toLowerCase())
|
|
515
|
-
),
|
|
516
1151
|
morpho: "0x0000000000000000000000000000000000000000",
|
|
517
1152
|
morphoBlue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
|
|
518
1153
|
mempool: {
|
|
519
1154
|
address: "0x0000000000000000000000000000000000000000",
|
|
520
1155
|
deploymentBlock: 23347674,
|
|
521
1156
|
reindexBuffer: 10
|
|
522
|
-
},
|
|
523
|
-
vaultV1Factory: {
|
|
524
|
-
"v1.0": "0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101",
|
|
525
|
-
"v1.1": "0x1897A8997241C1cD4bD0698647e4EB7213535c24"
|
|
526
1157
|
}
|
|
527
1158
|
},
|
|
528
1159
|
base: {
|
|
529
1160
|
...chains$1.base,
|
|
530
1161
|
id: ChainId.BASE,
|
|
531
1162
|
name: "base",
|
|
532
|
-
whitelistedAssets: new Set(
|
|
533
|
-
[
|
|
534
|
-
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
535
|
-
// USDC
|
|
536
|
-
"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb"
|
|
537
|
-
// DAI
|
|
538
|
-
].map((address) => address.toLowerCase())
|
|
539
|
-
),
|
|
540
1163
|
morpho: "0x0000000000000000000000000000000000000000",
|
|
541
1164
|
morphoBlue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
|
|
542
1165
|
mempool: {
|
|
543
1166
|
address: "0x0000000000000000000000000000000000000000",
|
|
544
1167
|
deploymentBlock: 35449942,
|
|
545
1168
|
reindexBuffer: 10
|
|
546
|
-
},
|
|
547
|
-
vaultV1Factory: {
|
|
548
|
-
"v1.0": "0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101",
|
|
549
|
-
"v1.1": "0xFf62A7c278C62eD665133147129245053Bbf5918"
|
|
550
1169
|
}
|
|
551
1170
|
},
|
|
552
1171
|
"ethereum-virtual-testnet": {
|
|
553
1172
|
...chains$1.mainnet,
|
|
554
1173
|
id: ChainId["ETHEREUM-VIRTUAL-TESTNET"],
|
|
555
1174
|
name: "ethereum-virtual-testnet",
|
|
556
|
-
whitelistedAssets: new Set(
|
|
557
|
-
[
|
|
558
|
-
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
559
|
-
// USDC
|
|
560
|
-
"0x6B175474E89094C44Da98b954EedeAC495271d0F"
|
|
561
|
-
// DAI
|
|
562
|
-
].map((address) => address.toLowerCase())
|
|
563
|
-
),
|
|
564
1175
|
morpho: "0x11a002d45db720ed47a80d2f3489cba5b833eaf5",
|
|
565
1176
|
// @TODO: This is mock Consumed contract, update with Terms once stable
|
|
566
1177
|
morphoBlue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
|
|
@@ -568,24 +1179,12 @@ var chains = {
|
|
|
568
1179
|
address: "0x5b06224f736a57635b5bcb50b8ef178b189107cb",
|
|
569
1180
|
deploymentBlock: 23224302,
|
|
570
1181
|
reindexBuffer: 10
|
|
571
|
-
},
|
|
572
|
-
vaultV1Factory: {
|
|
573
|
-
"v1.0": "0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101",
|
|
574
|
-
"v1.1": "0x1897A8997241C1cD4bD0698647e4EB7213535c24"
|
|
575
1182
|
}
|
|
576
1183
|
},
|
|
577
1184
|
anvil: {
|
|
578
1185
|
...chains$1.anvil,
|
|
579
1186
|
id: ChainId.ANVIL,
|
|
580
1187
|
name: "anvil",
|
|
581
|
-
whitelistedAssets: new Set(
|
|
582
|
-
[
|
|
583
|
-
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
584
|
-
// USDC
|
|
585
|
-
"0x6B175474E89094C44Da98b954EedeAC495271d0F"
|
|
586
|
-
// DAI
|
|
587
|
-
].map((address) => address.toLowerCase())
|
|
588
|
-
),
|
|
589
1188
|
morpho: "0x23DFBc4B8B80C14CC5e25011B8491f268395BAd6",
|
|
590
1189
|
morphoBlue: "0x0000000000000000000000000000000000000000",
|
|
591
1190
|
// Set dynamically in tests
|
|
@@ -593,10 +1192,6 @@ var chains = {
|
|
|
593
1192
|
address: "0xD946246695A9259F3B33a78629026F61B3Ab40aF",
|
|
594
1193
|
deploymentBlock: 23223727,
|
|
595
1194
|
reindexBuffer: 10
|
|
596
|
-
},
|
|
597
|
-
vaultV1Factory: {
|
|
598
|
-
"v1.0": "0x0000000000000000000000000000000000000000",
|
|
599
|
-
"v1.1": "0x0000000000000000000000000000000000000000"
|
|
600
1195
|
}
|
|
601
1196
|
}
|
|
602
1197
|
};
|
|
@@ -611,24 +1206,24 @@ async function* streamLogs(parameters) {
|
|
|
611
1206
|
event,
|
|
612
1207
|
blockNumberGte,
|
|
613
1208
|
blockNumberLte,
|
|
614
|
-
order = "desc",
|
|
1209
|
+
order: order2 = "desc",
|
|
615
1210
|
options: { maxBatchSize = DEFAULT_BATCH_SIZE, blockWindow = DEFAULT_BLOCK_WINDOW } = {}
|
|
616
1211
|
} = parameters;
|
|
617
1212
|
if (maxBatchSize > MAX_BATCH_SIZE) throw new InvalidBatchSizeError(maxBatchSize);
|
|
618
1213
|
if (blockWindow > MAX_BLOCK_WINDOW) throw new InvalidBlockWindowError(blockWindow);
|
|
619
|
-
if (
|
|
1214
|
+
if (order2 === "asc" && blockNumberGte === void 0) throw new MissingBlockNumberError();
|
|
620
1215
|
const latestBlock = (await actions.getBlock(client, { blockTag: "latest", includeTransactions: false })).number;
|
|
621
1216
|
let toBlock = 0n;
|
|
622
|
-
if (
|
|
1217
|
+
if (order2 === "asc")
|
|
623
1218
|
toBlock = min(BigInt(blockNumberGte) + BigInt(blockWindow), latestBlock);
|
|
624
|
-
if (
|
|
1219
|
+
if (order2 === "desc")
|
|
625
1220
|
toBlock = blockNumberLte === void 0 ? latestBlock : min(BigInt(blockNumberLte), latestBlock);
|
|
626
1221
|
let fromBlock = 0n;
|
|
627
|
-
if (
|
|
628
|
-
if (
|
|
1222
|
+
if (order2 === "asc") fromBlock = min(BigInt(blockNumberGte), latestBlock);
|
|
1223
|
+
if (order2 === "desc")
|
|
629
1224
|
fromBlock = max(BigInt(blockNumberGte || toBlock - BigInt(blockWindow)), 0n);
|
|
630
|
-
if (
|
|
631
|
-
if (
|
|
1225
|
+
if (order2 === "asc") toBlock = min(toBlock, fromBlock + BigInt(blockWindow));
|
|
1226
|
+
if (order2 === "desc") fromBlock = max(fromBlock, toBlock - BigInt(blockWindow));
|
|
632
1227
|
if (fromBlock > toBlock) throw new InvalidBlockRangeError(fromBlock, toBlock);
|
|
633
1228
|
let streaming = true;
|
|
634
1229
|
while (streaming) {
|
|
@@ -640,10 +1235,10 @@ async function* streamLogs(parameters) {
|
|
|
640
1235
|
});
|
|
641
1236
|
logs.sort((a, b) => {
|
|
642
1237
|
if (a.blockNumber !== b.blockNumber)
|
|
643
|
-
return
|
|
1238
|
+
return order2 === "asc" ? Number(a.blockNumber - b.blockNumber) : Number(b.blockNumber - a.blockNumber);
|
|
644
1239
|
if (a.transactionIndex !== b.transactionIndex)
|
|
645
|
-
return
|
|
646
|
-
return
|
|
1240
|
+
return order2 === "asc" ? a.transactionIndex - b.transactionIndex : b.transactionIndex - a.transactionIndex;
|
|
1241
|
+
return order2 === "asc" ? a.logIndex - b.logIndex : b.logIndex - a.logIndex;
|
|
647
1242
|
});
|
|
648
1243
|
for (const logBatch of batch(logs, maxBatchSize)) {
|
|
649
1244
|
if (logBatch.length === 0) break;
|
|
@@ -654,16 +1249,16 @@ async function* streamLogs(parameters) {
|
|
|
654
1249
|
Number(logBatch[logBatch.length - 1]?.blockNumber)
|
|
655
1250
|
) : (
|
|
656
1251
|
// if the batch is not full, return `toBlock` or `fromBlock` to indicate until which block the logs were fetched
|
|
657
|
-
|
|
1252
|
+
order2 === "asc" ? Number(toBlock) : Number(fromBlock)
|
|
658
1253
|
)
|
|
659
1254
|
};
|
|
660
1255
|
}
|
|
661
|
-
streaming =
|
|
662
|
-
if (
|
|
1256
|
+
streaming = order2 === "asc" ? toBlock < (blockNumberLte || latestBlock) : fromBlock > (blockNumberGte || 0n);
|
|
1257
|
+
if (order2 === "asc") {
|
|
663
1258
|
fromBlock = min(BigInt(toBlock) + 1n, latestBlock);
|
|
664
1259
|
toBlock = min(fromBlock + BigInt(blockWindow), latestBlock);
|
|
665
1260
|
}
|
|
666
|
-
if (
|
|
1261
|
+
if (order2 === "desc") {
|
|
667
1262
|
const lowerBound = BigInt(blockNumberGte || 0);
|
|
668
1263
|
const windowSize = BigInt(blockWindow);
|
|
669
1264
|
const nextToBlock = max(fromBlock - 1n, lowerBound);
|
|
@@ -672,7 +1267,7 @@ async function* streamLogs(parameters) {
|
|
|
672
1267
|
fromBlock = nextFromBlock;
|
|
673
1268
|
}
|
|
674
1269
|
}
|
|
675
|
-
yield { logs: [], blockNumber:
|
|
1270
|
+
yield { logs: [], blockNumber: order2 === "asc" ? Number(toBlock) : Number(fromBlock) };
|
|
676
1271
|
return;
|
|
677
1272
|
}
|
|
678
1273
|
var InvalidBlockRangeError = class extends BaseError {
|
|
@@ -711,7 +1306,8 @@ var Collateral_exports = {};
|
|
|
711
1306
|
__export(Collateral_exports, {
|
|
712
1307
|
CollateralSchema: () => CollateralSchema,
|
|
713
1308
|
CollateralsSchema: () => CollateralsSchema,
|
|
714
|
-
from: () => from4
|
|
1309
|
+
from: () => from4,
|
|
1310
|
+
random: () => random
|
|
715
1311
|
});
|
|
716
1312
|
var transformHex = (val, ctx) => {
|
|
717
1313
|
if (viem.isHex(val)) return val;
|
|
@@ -721,7 +1317,7 @@ var transformHex = (val, ctx) => {
|
|
|
721
1317
|
format: "hex",
|
|
722
1318
|
error: "not a hex"
|
|
723
1319
|
});
|
|
724
|
-
return
|
|
1320
|
+
return z9__namespace.NEVER;
|
|
725
1321
|
};
|
|
726
1322
|
var transformAddress = (val, ctx) => {
|
|
727
1323
|
if (viem.isAddress(val.toLowerCase())) return val.toLowerCase();
|
|
@@ -731,7 +1327,7 @@ var transformAddress = (val, ctx) => {
|
|
|
731
1327
|
format: "address",
|
|
732
1328
|
error: "not a valid address"
|
|
733
1329
|
});
|
|
734
|
-
return
|
|
1330
|
+
return z9__namespace.NEVER;
|
|
735
1331
|
};
|
|
736
1332
|
|
|
737
1333
|
// src/core/LLTV.ts
|
|
@@ -771,7 +1367,7 @@ var InvalidLLTVError = class extends BaseError {
|
|
|
771
1367
|
__publicField(this, "name", "LLTV.InvalidLLTVError");
|
|
772
1368
|
}
|
|
773
1369
|
};
|
|
774
|
-
var LLTVSchema =
|
|
1370
|
+
var LLTVSchema = z9__namespace.bigint({ coerce: true }).refine(
|
|
775
1371
|
(lltv) => {
|
|
776
1372
|
try {
|
|
777
1373
|
from3(lltv);
|
|
@@ -788,12 +1384,12 @@ var LLTVSchema = z7__namespace.bigint({ coerce: true }).refine(
|
|
|
788
1384
|
).transform((lltv) => from3(lltv));
|
|
789
1385
|
|
|
790
1386
|
// src/core/Collateral.ts
|
|
791
|
-
var CollateralSchema =
|
|
792
|
-
asset:
|
|
793
|
-
oracle:
|
|
1387
|
+
var CollateralSchema = z9__namespace.object({
|
|
1388
|
+
asset: z9__namespace.string().transform(transformAddress),
|
|
1389
|
+
oracle: z9__namespace.string().transform(transformAddress),
|
|
794
1390
|
lltv: LLTVSchema
|
|
795
1391
|
});
|
|
796
|
-
var CollateralsSchema =
|
|
1392
|
+
var CollateralsSchema = z9__namespace.array(CollateralSchema).min(1, { message: "At least one collateral is required" }).refine(
|
|
797
1393
|
(collaterals) => {
|
|
798
1394
|
for (let i = 1; i < collaterals.length; i++) {
|
|
799
1395
|
if (collaterals[i - 1].asset.toLowerCase() > collaterals[i].asset.toLowerCase()) {
|
|
@@ -828,6 +1424,13 @@ var from4 = (parameters) => {
|
|
|
828
1424
|
oracle: parameters.oracle.toLowerCase()
|
|
829
1425
|
};
|
|
830
1426
|
};
|
|
1427
|
+
function random() {
|
|
1428
|
+
return from4({
|
|
1429
|
+
asset: accounts.privateKeyToAccount(accounts.generatePrivateKey()).address,
|
|
1430
|
+
oracle: accounts.privateKeyToAccount(accounts.generatePrivateKey()).address,
|
|
1431
|
+
lltv: 0.965
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
831
1434
|
|
|
832
1435
|
// src/core/Liquidity.ts
|
|
833
1436
|
var Liquidity_exports = {};
|
|
@@ -851,20 +1454,20 @@ function calculateMaxDebt(amount, oraclePrice, lltv) {
|
|
|
851
1454
|
return maxDebt;
|
|
852
1455
|
}
|
|
853
1456
|
function generateBalancePoolId(parameters) {
|
|
854
|
-
const { user, chainId, token } = parameters;
|
|
855
|
-
return `${user}-${chainId.toString()}-${
|
|
1457
|
+
const { user, chainId, token: token2 } = parameters;
|
|
1458
|
+
return `${user}-${chainId.toString()}-${token2}-balance`.toLowerCase();
|
|
856
1459
|
}
|
|
857
1460
|
function generateAllowancePoolId(parameters) {
|
|
858
|
-
const { user, chainId, token } = parameters;
|
|
859
|
-
return `${user}-${chainId.toString()}-${
|
|
1461
|
+
const { user, chainId, token: token2 } = parameters;
|
|
1462
|
+
return `${user}-${chainId.toString()}-${token2}-allowance`.toLowerCase();
|
|
860
1463
|
}
|
|
861
1464
|
function generateSellERC20CallbackPoolId(parameters) {
|
|
862
|
-
const { user, chainId, obligationId: obligationId2, token, offerHash } = parameters;
|
|
863
|
-
return `${user}-${chainId.toString()}-${obligationId2}-${
|
|
1465
|
+
const { user, chainId, obligationId: obligationId2, token: token2, offerHash } = parameters;
|
|
1466
|
+
return `${user}-${chainId.toString()}-${obligationId2}-${token2}-${offerHash}-sell_erc20_callback`.toLowerCase();
|
|
864
1467
|
}
|
|
865
1468
|
function generateObligationCollateralPoolId(parameters) {
|
|
866
|
-
const { user, chainId, obligationId: obligationId2, token } = parameters;
|
|
867
|
-
return `${user}-${chainId.toString()}-${obligationId2}-${
|
|
1469
|
+
const { user, chainId, obligationId: obligationId2, token: token2 } = parameters;
|
|
1470
|
+
return `${user}-${chainId.toString()}-${obligationId2}-${token2}-obligation-collateral`.toLowerCase();
|
|
868
1471
|
}
|
|
869
1472
|
function generateBuyVaultCallbackPoolId(parameters) {
|
|
870
1473
|
const { user, chainId, vault, offerHash } = parameters;
|
|
@@ -894,12 +1497,13 @@ __export(Maturity_exports, {
|
|
|
894
1497
|
InvalidFormatError: () => InvalidFormatError,
|
|
895
1498
|
InvalidOptionError: () => InvalidOptionError2,
|
|
896
1499
|
MaturitySchema: () => MaturitySchema,
|
|
1500
|
+
MaturityType: () => MaturityType,
|
|
897
1501
|
from: () => from5
|
|
898
1502
|
});
|
|
899
|
-
var MaturitySchema =
|
|
900
|
-
(
|
|
1503
|
+
var MaturitySchema = z9__namespace.number().int().refine(
|
|
1504
|
+
(maturity2) => {
|
|
901
1505
|
try {
|
|
902
|
-
from5(
|
|
1506
|
+
from5(maturity2);
|
|
903
1507
|
return true;
|
|
904
1508
|
} catch (_e) {
|
|
905
1509
|
return false;
|
|
@@ -915,7 +1519,16 @@ var MaturitySchema = z7__namespace.number().int().refine(
|
|
|
915
1519
|
}
|
|
916
1520
|
}
|
|
917
1521
|
}
|
|
918
|
-
).transform((
|
|
1522
|
+
).transform((maturity2) => maturity2);
|
|
1523
|
+
var MaturityType = /* @__PURE__ */ ((MaturityType2) => {
|
|
1524
|
+
MaturityType2["EndOfWeek"] = "end_of_week";
|
|
1525
|
+
MaturityType2["EndOfNextWeek"] = "end_of_next_week";
|
|
1526
|
+
MaturityType2["EndOfMonth"] = "end_of_month";
|
|
1527
|
+
MaturityType2["EndOfNextMonth"] = "end_of_next_month";
|
|
1528
|
+
MaturityType2["EndOfQuarter"] = "end_of_quarter";
|
|
1529
|
+
MaturityType2["EndOfNextQuarter"] = "end_of_next_quarter";
|
|
1530
|
+
return MaturityType2;
|
|
1531
|
+
})(MaturityType || {});
|
|
919
1532
|
var MaturityOptions = {
|
|
920
1533
|
end_of_week: () => endOfWeek(),
|
|
921
1534
|
end_of_next_week: () => endOfNextWeek(),
|
|
@@ -936,8 +1549,26 @@ function from5(ts) {
|
|
|
936
1549
|
}
|
|
937
1550
|
var endOfWeek = () => fridayOfWeek(0);
|
|
938
1551
|
var endOfNextWeek = () => fridayOfWeek(1);
|
|
939
|
-
var endOfMonth = () =>
|
|
940
|
-
|
|
1552
|
+
var endOfMonth = () => {
|
|
1553
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
1554
|
+
const year = now2.getUTCFullYear();
|
|
1555
|
+
const month = now2.getUTCMonth();
|
|
1556
|
+
const endOfMonth2 = lastFridayOfMonth(year, month);
|
|
1557
|
+
if (now2.getTime() > endOfMonth2 * 1e3) {
|
|
1558
|
+
return lastFridayOfMonth(year, month + 1);
|
|
1559
|
+
}
|
|
1560
|
+
return endOfMonth2;
|
|
1561
|
+
};
|
|
1562
|
+
var endOfNextMonth = () => {
|
|
1563
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
1564
|
+
const year = now2.getUTCFullYear();
|
|
1565
|
+
const month = now2.getUTCMonth();
|
|
1566
|
+
const endOfMonth2 = lastFridayOfMonth(year, month);
|
|
1567
|
+
if (now2.getTime() > endOfMonth2 * 1e3) {
|
|
1568
|
+
return lastFridayOfMonth(year, month + 2);
|
|
1569
|
+
}
|
|
1570
|
+
return lastFridayOfMonth(year, month + 1);
|
|
1571
|
+
};
|
|
941
1572
|
var endOfQuarter = () => lastFridayOfQuarter(0);
|
|
942
1573
|
var endOfNextQuarter = () => lastFridayOfQuarter(1);
|
|
943
1574
|
var fridayOfWeek = (weeksAhead = 0) => {
|
|
@@ -958,8 +1589,8 @@ var lastFridayOfMonth = (year, month) => {
|
|
|
958
1589
|
while (lastDayOfMonth15H.getUTCDay() !== 5) {
|
|
959
1590
|
lastDayOfMonth15H.setUTCDate(lastDayOfMonth15H.getUTCDate() - 1);
|
|
960
1591
|
}
|
|
961
|
-
const
|
|
962
|
-
return
|
|
1592
|
+
const maturity2 = lastDayOfMonth15H.setUTCDate(lastDayOfMonth15H.getUTCDate()) / 1e3;
|
|
1593
|
+
return maturity2;
|
|
963
1594
|
};
|
|
964
1595
|
var lastFridayOfQuarter = (quartersAhead = 0) => {
|
|
965
1596
|
const now2 = /* @__PURE__ */ new Date();
|
|
@@ -1005,11 +1636,11 @@ __export(Obligation_exports, {
|
|
|
1005
1636
|
from: () => from6,
|
|
1006
1637
|
fromSnakeCase: () => fromSnakeCase2,
|
|
1007
1638
|
id: () => id,
|
|
1008
|
-
random: () =>
|
|
1639
|
+
random: () => random2
|
|
1009
1640
|
});
|
|
1010
|
-
var ObligationSchema =
|
|
1011
|
-
chainId:
|
|
1012
|
-
loanToken:
|
|
1641
|
+
var ObligationSchema = z9__namespace.object({
|
|
1642
|
+
chainId: z9__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256),
|
|
1643
|
+
loanToken: z9__namespace.string().transform(transformAddress),
|
|
1013
1644
|
collaterals: CollateralsSchema,
|
|
1014
1645
|
maturity: MaturitySchema
|
|
1015
1646
|
});
|
|
@@ -1067,7 +1698,7 @@ function id(obligation) {
|
|
|
1067
1698
|
)
|
|
1068
1699
|
);
|
|
1069
1700
|
}
|
|
1070
|
-
function
|
|
1701
|
+
function random2() {
|
|
1071
1702
|
return from6({
|
|
1072
1703
|
chainId: 1n,
|
|
1073
1704
|
loanToken: accounts.privateKeyToAccount(accounts.generatePrivateKey()).address,
|
|
@@ -1101,170 +1732,138 @@ __export(Offer_exports, {
|
|
|
1101
1732
|
InvalidOfferError: () => InvalidOfferError,
|
|
1102
1733
|
OfferHashSchema: () => OfferHashSchema,
|
|
1103
1734
|
OfferSchema: () => OfferSchema,
|
|
1735
|
+
StatusCode: () => StatusCode,
|
|
1104
1736
|
consumedEvent: () => consumedEvent,
|
|
1105
|
-
decode: () =>
|
|
1737
|
+
decode: () => decode4,
|
|
1106
1738
|
domain: () => domain,
|
|
1107
|
-
encode: () =>
|
|
1108
|
-
from: () =>
|
|
1739
|
+
encode: () => encode4,
|
|
1740
|
+
from: () => from8,
|
|
1109
1741
|
fromConsumedLog: () => fromConsumedLog,
|
|
1110
1742
|
fromSnakeCase: () => fromSnakeCase3,
|
|
1111
1743
|
hash: () => hash,
|
|
1112
1744
|
obligationId: () => obligationId,
|
|
1113
|
-
random: () =>
|
|
1745
|
+
random: () => random3,
|
|
1114
1746
|
sign: () => sign,
|
|
1747
|
+
signatureMsg: () => signatureMsg,
|
|
1115
1748
|
toSnakeCase: () => toSnakeCase2,
|
|
1116
1749
|
types: () => types
|
|
1117
1750
|
});
|
|
1118
1751
|
|
|
1119
|
-
// src/
|
|
1120
|
-
var
|
|
1121
|
-
__export(
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
fromSnakeCase: () => fromSnakeCase,
|
|
1127
|
-
lazy: () => lazy,
|
|
1128
|
-
max: () => max,
|
|
1129
|
-
min: () => min,
|
|
1130
|
-
poll: () => poll,
|
|
1131
|
-
retry: () => retry,
|
|
1132
|
-
toSnakeCase: () => toSnakeCase,
|
|
1133
|
-
wait: () => wait
|
|
1752
|
+
// src/core/Tree.ts
|
|
1753
|
+
var Tree_exports = {};
|
|
1754
|
+
__export(Tree_exports, {
|
|
1755
|
+
VERSION: () => VERSION,
|
|
1756
|
+
decode: () => decode3,
|
|
1757
|
+
encode: () => encode3,
|
|
1758
|
+
from: () => from7
|
|
1134
1759
|
});
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
} catch (err) {
|
|
1143
|
-
lastErr = err;
|
|
1144
|
-
if (i < attempts - 1) await new Promise((r) => setTimeout(r, delayMs));
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
throw lastErr;
|
|
1760
|
+
var VERSION = 1;
|
|
1761
|
+
var from7 = (offers) => {
|
|
1762
|
+
const leaves = order(offers).map((offer) => {
|
|
1763
|
+
return [offer.hash];
|
|
1764
|
+
});
|
|
1765
|
+
const tree = merkleTree.StandardMerkleTree.of(leaves, ["bytes32"]);
|
|
1766
|
+
return Object.assign(tree, { offers });
|
|
1148
1767
|
};
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1768
|
+
var byHashAsc = (a, b) => a.localeCompare(b);
|
|
1769
|
+
var order = (offers) => {
|
|
1770
|
+
return offers.sort((a, b) => byHashAsc(a.hash, b.hash));
|
|
1771
|
+
};
|
|
1772
|
+
var encode3 = (tree) => {
|
|
1773
|
+
assertRoot(tree.root, tree.offers);
|
|
1774
|
+
const offersPayload = tree.offers.map((offer) => ({
|
|
1775
|
+
offering: offer.offering,
|
|
1776
|
+
assets: offer.assets.toString(),
|
|
1777
|
+
rate: offer.rate.toString(),
|
|
1778
|
+
maturity: Number(offer.maturity),
|
|
1779
|
+
expiry: Number(offer.expiry),
|
|
1780
|
+
start: Number(offer.start),
|
|
1781
|
+
nonce: offer.nonce.toString(),
|
|
1782
|
+
buy: offer.buy,
|
|
1783
|
+
chainId: offer.chainId.toString(),
|
|
1784
|
+
loanToken: offer.loanToken,
|
|
1785
|
+
collaterals: offer.collaterals.map((c) => ({
|
|
1786
|
+
asset: c.asset,
|
|
1787
|
+
oracle: c.oracle,
|
|
1788
|
+
lltv: c.lltv.toString()
|
|
1789
|
+
})),
|
|
1790
|
+
callback: {
|
|
1791
|
+
address: offer.callback.address,
|
|
1792
|
+
data: offer.callback.data,
|
|
1793
|
+
gasLimit: offer.callback.gasLimit.toString()
|
|
1794
|
+
},
|
|
1795
|
+
signature: offer.signature,
|
|
1796
|
+
hash: offer.hash
|
|
1797
|
+
}));
|
|
1798
|
+
const compressed = pako.gzip(JSON.stringify([tree.root, ...offersPayload]));
|
|
1799
|
+
const encoded = new Uint8Array(1 + compressed.length);
|
|
1800
|
+
encoded[0] = VERSION;
|
|
1801
|
+
encoded.set(compressed, 1);
|
|
1802
|
+
return viem.bytesToHex(encoded);
|
|
1803
|
+
};
|
|
1804
|
+
var assertRoot = (root, offers) => {
|
|
1805
|
+
const tree = from7(offers);
|
|
1806
|
+
if (root !== tree.root) {
|
|
1807
|
+
throw new Error(`Invalid root: expected ${tree.root}, got ${root}`);
|
|
1165
1808
|
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
resolveNext?.();
|
|
1188
|
-
resolveNext = null;
|
|
1189
|
-
};
|
|
1190
|
-
unpoll = pollFn(emit, { stop });
|
|
1191
|
-
try {
|
|
1192
|
-
while (active) {
|
|
1193
|
-
if (queue.length === 0) await wait2();
|
|
1194
|
-
while (queue.length > 0 && active) yield queue.shift();
|
|
1195
|
-
}
|
|
1196
|
-
} finally {
|
|
1197
|
-
stop();
|
|
1198
|
-
}
|
|
1199
|
-
}();
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
|
-
// src/utils/wait.ts
|
|
1203
|
-
async function wait(time) {
|
|
1204
|
-
return new Promise((res) => setTimeout(res, time));
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
// src/utils/poll.ts
|
|
1208
|
-
function poll(fn, { interval }) {
|
|
1209
|
-
let active = true;
|
|
1210
|
-
const unwatch = () => active = false;
|
|
1211
|
-
const watch2 = async () => {
|
|
1212
|
-
await wait(interval);
|
|
1213
|
-
const poll2 = async () => {
|
|
1214
|
-
if (!active) return;
|
|
1215
|
-
await fn({ unpoll: unwatch });
|
|
1216
|
-
await wait(interval);
|
|
1217
|
-
poll2();
|
|
1218
|
-
};
|
|
1219
|
-
poll2();
|
|
1220
|
-
};
|
|
1221
|
-
watch2();
|
|
1222
|
-
return unwatch;
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
// src/utils/time.ts
|
|
1226
|
-
var time_exports = {};
|
|
1227
|
-
__export(time_exports, {
|
|
1228
|
-
max: () => max2,
|
|
1229
|
-
now: () => now
|
|
1230
|
-
});
|
|
1231
|
-
function now() {
|
|
1232
|
-
return Math.floor(Date.now() / 1e3);
|
|
1233
|
-
}
|
|
1234
|
-
function max2() {
|
|
1235
|
-
return 864e16;
|
|
1236
|
-
}
|
|
1809
|
+
};
|
|
1810
|
+
var decode3 = (encoded) => {
|
|
1811
|
+
const bytes = viem.hexToBytes(encoded);
|
|
1812
|
+
if (bytes.length < 2) {
|
|
1813
|
+
throw new Error("Invalid payload: too short");
|
|
1814
|
+
}
|
|
1815
|
+
const version = bytes[0];
|
|
1816
|
+
if (version !== (VERSION & 255)) {
|
|
1817
|
+
throw new Error(`Invalid version: expected ${VERSION}, got ${version}`);
|
|
1818
|
+
}
|
|
1819
|
+
const payload = bytes.slice(1);
|
|
1820
|
+
const decoded = pako.ungzip(payload, { to: "string" });
|
|
1821
|
+
const data = JSON.parse(decoded);
|
|
1822
|
+
const root = data[0];
|
|
1823
|
+
const offers = data.slice(1).map((o) => OfferSchema({ omitConsumed: true, omitBlockNumber: true }).parse(o));
|
|
1824
|
+
const tree = from7(offers);
|
|
1825
|
+
if (root !== tree.root) {
|
|
1826
|
+
throw new Error(`Invalid root: expected ${tree.root}, got ${root}`);
|
|
1827
|
+
}
|
|
1828
|
+
return tree;
|
|
1829
|
+
};
|
|
1237
1830
|
|
|
1238
1831
|
// src/core/Offer.ts
|
|
1239
|
-
var
|
|
1832
|
+
var StatusCode = /* @__PURE__ */ ((StatusCode2) => {
|
|
1833
|
+
StatusCode2["VALID"] = "VALID";
|
|
1834
|
+
StatusCode2["NOT_ENOUGH_LIQUIDITY"] = "NOT_ENOUGH_LIQUIDITY";
|
|
1835
|
+
return StatusCode2;
|
|
1836
|
+
})(StatusCode || {});
|
|
1837
|
+
var OfferHashSchema = z9__namespace.string().regex(/^0x[0-9a-fA-F]{64}$/, {
|
|
1240
1838
|
message: "Hash must be a valid 32-byte hex string"
|
|
1241
1839
|
}).transform(transformHex);
|
|
1242
1840
|
var OfferSchema = (parameters) => {
|
|
1243
|
-
const { omitHash = false } = parameters || {};
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
rate: z7__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256),
|
|
1841
|
+
const { omitHash = false, omitConsumed = false, omitBlockNumber = false } = parameters || {};
|
|
1842
|
+
let base = z9__namespace.object({
|
|
1843
|
+
offering: z9__namespace.string().transform(transformAddress),
|
|
1844
|
+
assets: z9__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256),
|
|
1845
|
+
rate: z9__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256),
|
|
1249
1846
|
maturity: MaturitySchema,
|
|
1250
|
-
expiry:
|
|
1251
|
-
start:
|
|
1252
|
-
nonce:
|
|
1253
|
-
buy:
|
|
1254
|
-
chainId:
|
|
1255
|
-
loanToken:
|
|
1847
|
+
expiry: z9__namespace.number().int().max(Number.MAX_SAFE_INTEGER),
|
|
1848
|
+
start: z9__namespace.number().int().max(Number.MAX_SAFE_INTEGER),
|
|
1849
|
+
nonce: z9__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256),
|
|
1850
|
+
buy: z9__namespace.boolean(),
|
|
1851
|
+
chainId: z9__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256),
|
|
1852
|
+
loanToken: z9__namespace.string().transform(transformAddress),
|
|
1256
1853
|
collaterals: CollateralsSchema,
|
|
1257
|
-
callback:
|
|
1258
|
-
address:
|
|
1259
|
-
data:
|
|
1260
|
-
gasLimit:
|
|
1854
|
+
callback: z9__namespace.object({
|
|
1855
|
+
address: z9__namespace.string().transform(transformAddress),
|
|
1856
|
+
data: z9__namespace.string().transform(transformHex),
|
|
1857
|
+
gasLimit: z9__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256)
|
|
1261
1858
|
}),
|
|
1262
|
-
|
|
1263
|
-
blockNumber: z7__namespace.number().int().max(Number.MAX_SAFE_INTEGER),
|
|
1264
|
-
signature: z7__namespace.string().regex(/^0x[0-9a-fA-F]{130}$/, {
|
|
1859
|
+
signature: z9__namespace.string().regex(/^0x[0-9a-fA-F]{130}$/, {
|
|
1265
1860
|
message: "Signature must be a valid 65-byte hex string"
|
|
1266
1861
|
}).transform(transformHex).optional()
|
|
1267
1862
|
});
|
|
1863
|
+
if (!omitConsumed)
|
|
1864
|
+
base = base.extend({ consumed: z9__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256) });
|
|
1865
|
+
if (!omitBlockNumber)
|
|
1866
|
+
base = base.extend({ blockNumber: z9__namespace.number().int().max(Number.MAX_SAFE_INTEGER) });
|
|
1268
1867
|
if (!omitHash) base = base.extend({ hash: OfferHashSchema });
|
|
1269
1868
|
return base.refine((data) => data.start < data.expiry, {
|
|
1270
1869
|
message: "Start must be before expiry",
|
|
@@ -1274,7 +1873,7 @@ var OfferSchema = (parameters) => {
|
|
|
1274
1873
|
path: ["expiry"]
|
|
1275
1874
|
});
|
|
1276
1875
|
};
|
|
1277
|
-
function
|
|
1876
|
+
function from8(input) {
|
|
1278
1877
|
try {
|
|
1279
1878
|
const parsedOffer = OfferSchema({ omitHash: true }).parse(input);
|
|
1280
1879
|
const parsedHash = OfferHashSchema.parse(hash(parsedOffer));
|
|
@@ -1287,44 +1886,94 @@ function from7(input) {
|
|
|
1287
1886
|
}
|
|
1288
1887
|
}
|
|
1289
1888
|
function fromSnakeCase3(input) {
|
|
1290
|
-
return
|
|
1889
|
+
return from8(fromSnakeCase(input));
|
|
1291
1890
|
}
|
|
1292
1891
|
function toSnakeCase2(offer) {
|
|
1293
1892
|
return toSnakeCase(offer);
|
|
1294
1893
|
}
|
|
1295
|
-
function
|
|
1296
|
-
const
|
|
1297
|
-
const
|
|
1298
|
-
const
|
|
1299
|
-
const
|
|
1300
|
-
const
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1894
|
+
function random3(config) {
|
|
1895
|
+
const chain2 = config?.chains ? config.chains[Math.floor(Math.random() * config.chains.length)] : chains.ethereum;
|
|
1896
|
+
const loanToken = config?.loanTokens ? config.loanTokens[Math.floor(Math.random() * config.loanTokens.length)] : accounts.privateKeyToAccount(accounts.generatePrivateKey()).address;
|
|
1897
|
+
const collateralCandidates = config?.collateralTokens ? config.collateralTokens.filter((a) => a !== loanToken) : [accounts.privateKeyToAccount(accounts.generatePrivateKey()).address];
|
|
1898
|
+
const collateralAsset = collateralCandidates[Math.floor(Math.random() * collateralCandidates.length)];
|
|
1899
|
+
const maturityOption = weightedChoice([
|
|
1900
|
+
["end_of_month", 1],
|
|
1901
|
+
["end_of_next_month", 1]
|
|
1902
|
+
]);
|
|
1903
|
+
const maturity2 = config?.maturity ?? from5(maturityOption);
|
|
1904
|
+
const lltv = from3(
|
|
1905
|
+
weightedChoice([
|
|
1906
|
+
[0.385, 1],
|
|
1907
|
+
[0.5, 1],
|
|
1908
|
+
[0.625, 2],
|
|
1909
|
+
[0.77, 8],
|
|
1910
|
+
[0.86, 10],
|
|
1911
|
+
[0.915, 8],
|
|
1912
|
+
[0.945, 6],
|
|
1913
|
+
[0.965, 4],
|
|
1914
|
+
[0.98, 2]
|
|
1915
|
+
])
|
|
1916
|
+
);
|
|
1917
|
+
const buy = config?.buy !== void 0 ? config.buy : Math.random() > 0.5;
|
|
1918
|
+
const ONE = 1000000000000000000n;
|
|
1919
|
+
const qMin = buy ? 16 : 4;
|
|
1920
|
+
const qMax = buy ? 32 : 16;
|
|
1921
|
+
const len = qMax - qMin + 1;
|
|
1922
|
+
const ratePairs = Array.from(
|
|
1923
|
+
{ length: len },
|
|
1924
|
+
(_, idx) => {
|
|
1925
|
+
const q = qMin + idx;
|
|
1926
|
+
const scaledRate = BigInt(q) * (ONE / 4n);
|
|
1927
|
+
const weight = buy ? 1 + idx : 1 + (len - 1 - idx);
|
|
1928
|
+
return [scaledRate, weight];
|
|
1929
|
+
}
|
|
1930
|
+
);
|
|
1931
|
+
const rate = config?.rate ?? weightedChoice(ratePairs);
|
|
1932
|
+
const loanTokenDecimals = config?.assetsDecimals?.[loanToken] ?? 18;
|
|
1933
|
+
const unit = BigInt(10) ** BigInt(loanTokenDecimals);
|
|
1934
|
+
const amountBase = BigInt(100 + Math.floor(Math.random() * (1e6 - 100 + 1)));
|
|
1935
|
+
const assetsScaled = config?.assets ?? amountBase * unit;
|
|
1936
|
+
const consumed = config?.consumed !== void 0 ? config.consumed : Math.random() < 0.8 ? 0n : assetsScaled * BigInt(1 + Math.floor(Math.random() * 900)) / 1000n;
|
|
1937
|
+
const callbackBySide = (() => {
|
|
1938
|
+
if (buy) return { address: viem.zeroAddress, data: "0x", gasLimit: 0n };
|
|
1939
|
+
const sellCallbackAddress = "0x3333333333333333333333333333333333333333";
|
|
1940
|
+
const amount = assetsScaled * 1000000000000000000000n;
|
|
1941
|
+
const data = encodeSellERC20Callback({
|
|
1942
|
+
collaterals: [collateralAsset],
|
|
1943
|
+
amounts: [amount]
|
|
1944
|
+
});
|
|
1945
|
+
return { address: sellCallbackAddress, data, gasLimit: 0n };
|
|
1946
|
+
})();
|
|
1947
|
+
const offer = from8({
|
|
1948
|
+
offering: config?.offering ?? accounts.privateKeyToAccount(accounts.generatePrivateKey()).address,
|
|
1949
|
+
assets: assetsScaled,
|
|
1950
|
+
rate,
|
|
1951
|
+
maturity: maturity2,
|
|
1952
|
+
expiry: config?.expiry ?? maturity2 - 1,
|
|
1953
|
+
start: config?.start ?? maturity2 - 10,
|
|
1307
1954
|
nonce: BigInt(Math.floor(Math.random() * 1e6)),
|
|
1308
|
-
buy
|
|
1309
|
-
chainId:
|
|
1955
|
+
buy,
|
|
1956
|
+
chainId: chain2.id,
|
|
1310
1957
|
loanToken,
|
|
1311
|
-
collaterals:
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
],
|
|
1318
|
-
callback: {
|
|
1319
|
-
address: viem.zeroAddress,
|
|
1320
|
-
data: "0x",
|
|
1321
|
-
gasLimit: 0n
|
|
1322
|
-
},
|
|
1323
|
-
consumed: 0n,
|
|
1958
|
+
collaterals: config?.collaterals ?? Array.from({ length: Math.floor(Math.random() * 3) + 1 }, () => ({
|
|
1959
|
+
...random(),
|
|
1960
|
+
lltv
|
|
1961
|
+
})).sort((a, b) => a.asset.localeCompare(b.asset)),
|
|
1962
|
+
callback: config?.callback ?? callbackBySide,
|
|
1963
|
+
consumed,
|
|
1324
1964
|
blockNumber: Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)
|
|
1325
1965
|
});
|
|
1326
1966
|
return offer;
|
|
1327
1967
|
}
|
|
1968
|
+
var weightedChoice = (pairs) => {
|
|
1969
|
+
const total = pairs.reduce((sum, [, weight]) => sum + weight, 0);
|
|
1970
|
+
let roll = Math.random() * total;
|
|
1971
|
+
for (const [value, weight] of pairs) {
|
|
1972
|
+
roll -= weight;
|
|
1973
|
+
if (roll < 0) return value;
|
|
1974
|
+
}
|
|
1975
|
+
return pairs[0][0];
|
|
1976
|
+
};
|
|
1328
1977
|
var domain = (chainId) => ({
|
|
1329
1978
|
chainId,
|
|
1330
1979
|
verifyingContract: viem.zeroAddress
|
|
@@ -1357,31 +2006,16 @@ var types = {
|
|
|
1357
2006
|
{ name: "gasLimit", type: "uint256" }
|
|
1358
2007
|
]
|
|
1359
2008
|
};
|
|
1360
|
-
function sign(
|
|
2009
|
+
async function sign(offers, wallet) {
|
|
1361
2010
|
if (!wallet.account) throw new AccountNotSetError();
|
|
1362
|
-
return wallet.
|
|
2011
|
+
return wallet.signMessage({
|
|
1363
2012
|
account: wallet.account,
|
|
1364
|
-
|
|
1365
|
-
types,
|
|
1366
|
-
primaryType: "Offer",
|
|
1367
|
-
message: {
|
|
1368
|
-
offering: offer.offering.toLowerCase(),
|
|
1369
|
-
assets: offer.assets,
|
|
1370
|
-
rate: offer.rate,
|
|
1371
|
-
maturity: BigInt(offer.maturity),
|
|
1372
|
-
expiry: BigInt(offer.expiry),
|
|
1373
|
-
nonce: offer.nonce,
|
|
1374
|
-
buy: offer.buy,
|
|
1375
|
-
loanToken: offer.loanToken.toLowerCase(),
|
|
1376
|
-
collaterals: offer.collaterals,
|
|
1377
|
-
callback: {
|
|
1378
|
-
address: offer.callback.address.toLowerCase(),
|
|
1379
|
-
data: offer.callback.data,
|
|
1380
|
-
gasLimit: offer.callback.gasLimit
|
|
1381
|
-
}
|
|
1382
|
-
}
|
|
2013
|
+
message: { raw: signatureMsg(offers) }
|
|
1383
2014
|
});
|
|
1384
2015
|
}
|
|
2016
|
+
function signatureMsg(offers) {
|
|
2017
|
+
return from7(offers).root;
|
|
2018
|
+
}
|
|
1385
2019
|
function hash(offer) {
|
|
1386
2020
|
return viem.hashTypedData({
|
|
1387
2021
|
domain: domain(offer.chainId),
|
|
@@ -1446,7 +2080,7 @@ var OfferAbi = [
|
|
|
1446
2080
|
},
|
|
1447
2081
|
{ name: "signature", type: "bytes" }
|
|
1448
2082
|
];
|
|
1449
|
-
function
|
|
2083
|
+
function encode4(offer) {
|
|
1450
2084
|
return viem.encodeAbiParameters(OfferAbi, [
|
|
1451
2085
|
offer.offering,
|
|
1452
2086
|
offer.assets,
|
|
@@ -1463,14 +2097,14 @@ function encode(offer) {
|
|
|
1463
2097
|
offer.signature ?? "0x"
|
|
1464
2098
|
]);
|
|
1465
2099
|
}
|
|
1466
|
-
function
|
|
2100
|
+
function decode4(data, blockNumber) {
|
|
1467
2101
|
let decoded;
|
|
1468
2102
|
try {
|
|
1469
2103
|
decoded = viem.decodeAbiParameters(OfferAbi, data);
|
|
1470
2104
|
} catch (error) {
|
|
1471
2105
|
throw new InvalidOfferError(error);
|
|
1472
2106
|
}
|
|
1473
|
-
const offer =
|
|
2107
|
+
const offer = from8({
|
|
1474
2108
|
offering: decoded[0],
|
|
1475
2109
|
assets: decoded[1],
|
|
1476
2110
|
rate: decoded[2],
|
|
@@ -1538,20 +2172,20 @@ var Quote_exports = {};
|
|
|
1538
2172
|
__export(Quote_exports, {
|
|
1539
2173
|
InvalidQuoteError: () => InvalidQuoteError,
|
|
1540
2174
|
QuoteSchema: () => QuoteSchema,
|
|
1541
|
-
from: () =>
|
|
2175
|
+
from: () => from9,
|
|
1542
2176
|
fromSnakeCase: () => fromSnakeCase4,
|
|
1543
|
-
random: () =>
|
|
2177
|
+
random: () => random4
|
|
1544
2178
|
});
|
|
1545
|
-
var QuoteSchema =
|
|
1546
|
-
obligationId:
|
|
1547
|
-
ask:
|
|
1548
|
-
rate:
|
|
2179
|
+
var QuoteSchema = z9__namespace.object({
|
|
2180
|
+
obligationId: z9__namespace.string().transform(transformHex),
|
|
2181
|
+
ask: z9__namespace.object({
|
|
2182
|
+
rate: z9__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256)
|
|
1549
2183
|
}),
|
|
1550
|
-
bid:
|
|
1551
|
-
rate:
|
|
2184
|
+
bid: z9__namespace.object({
|
|
2185
|
+
rate: z9__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256)
|
|
1552
2186
|
})
|
|
1553
2187
|
});
|
|
1554
|
-
function
|
|
2188
|
+
function from9(parameters) {
|
|
1555
2189
|
try {
|
|
1556
2190
|
const parsedQuote = QuoteSchema.parse(parameters);
|
|
1557
2191
|
return {
|
|
@@ -1564,10 +2198,10 @@ function from8(parameters) {
|
|
|
1564
2198
|
}
|
|
1565
2199
|
}
|
|
1566
2200
|
function fromSnakeCase4(snake) {
|
|
1567
|
-
return
|
|
2201
|
+
return from9(fromSnakeCase(snake));
|
|
1568
2202
|
}
|
|
1569
|
-
function
|
|
1570
|
-
return
|
|
2203
|
+
function random4() {
|
|
2204
|
+
return from9({
|
|
1571
2205
|
obligationId: Obligation_exports.id(Obligation_exports.random()),
|
|
1572
2206
|
ask: {
|
|
1573
2207
|
rate: BigInt(Math.floor(Math.random() * 1e6))
|
|
@@ -1587,520 +2221,130 @@ var InvalidQuoteError = class extends BaseError {
|
|
|
1587
2221
|
// src/core/types.ts
|
|
1588
2222
|
var BrandTypeId = Symbol.for("mempool/Brand");
|
|
1589
2223
|
|
|
1590
|
-
// src/
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
2224
|
+
// src/client/Client.ts
|
|
2225
|
+
function connect(parameters) {
|
|
2226
|
+
const u = new URL(parameters?.url || "https://router.morpho.dev");
|
|
2227
|
+
if (u.protocol !== "http:" && u.protocol !== "https:") throw new InvalidUrlError(u.toString());
|
|
2228
|
+
const headers = parameters?.headers ?? new Headers();
|
|
2229
|
+
headers.set("Content-Type", "application/json");
|
|
2230
|
+
parameters?.apiKey !== void 0 ? headers.set("X-API-Key", parameters.apiKey) : null;
|
|
2231
|
+
const config = { url: u, headers };
|
|
2232
|
+
const apiClient = createOpenApiFetchClient__default.default({
|
|
2233
|
+
baseUrl: config.url.toString(),
|
|
2234
|
+
headers: config.headers
|
|
2235
|
+
});
|
|
2236
|
+
return {
|
|
2237
|
+
...config,
|
|
2238
|
+
getOffers: (parameters2) => getOffers(apiClient, parameters2),
|
|
2239
|
+
getObligations: (parameters2) => getObligations(apiClient, parameters2)
|
|
2240
|
+
};
|
|
2241
|
+
}
|
|
2242
|
+
async function getOffers(apiClient, parameters) {
|
|
2243
|
+
const { data, error, response } = await apiClient.GET("/v1/offers", {
|
|
2244
|
+
params: {
|
|
2245
|
+
query: {
|
|
2246
|
+
side: parameters.side,
|
|
2247
|
+
obligation_id: parameters.obligationId,
|
|
2248
|
+
cursor: parameters.cursor,
|
|
2249
|
+
limit: parameters.limit
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
});
|
|
2253
|
+
if (error !== void 0) {
|
|
2254
|
+
switch (response.status) {
|
|
2255
|
+
case 401:
|
|
2256
|
+
throw new HttpUnauthorizedError();
|
|
2257
|
+
case 403:
|
|
2258
|
+
throw new HttpForbiddenError();
|
|
2259
|
+
case 429:
|
|
2260
|
+
throw new HttpRateLimitError();
|
|
2261
|
+
}
|
|
2262
|
+
throw new HttpGetApiFailedError(`GET request returned ${response.status}`, {
|
|
2263
|
+
details: JSON.stringify(error)
|
|
2264
|
+
});
|
|
1600
2265
|
}
|
|
1601
|
-
const
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
2266
|
+
const offers = data?.data.map((item) => {
|
|
2267
|
+
const { signature, ...rest } = item;
|
|
2268
|
+
return Offer_exports.fromSnakeCase({
|
|
2269
|
+
...rest,
|
|
2270
|
+
offering: item.offering,
|
|
2271
|
+
maturity: Maturity_exports.from(item.maturity),
|
|
2272
|
+
loan_token: item.loan_token,
|
|
2273
|
+
collaterals: item.collaterals.map((collateral) => ({
|
|
2274
|
+
asset: collateral.asset,
|
|
2275
|
+
oracle: collateral.oracle,
|
|
2276
|
+
lltv: collateral.lltv
|
|
2277
|
+
})),
|
|
2278
|
+
callback: {
|
|
2279
|
+
...item.callback,
|
|
2280
|
+
address: item.callback.address,
|
|
2281
|
+
data: item.callback.data
|
|
2282
|
+
},
|
|
2283
|
+
...signature !== null ? { signature: item.signature } : void 0
|
|
2284
|
+
});
|
|
2285
|
+
}) ?? [];
|
|
2286
|
+
return {
|
|
2287
|
+
cursor: data?.cursor ?? null,
|
|
2288
|
+
offers
|
|
2289
|
+
};
|
|
2290
|
+
}
|
|
2291
|
+
async function getObligations(apiClient, parameters) {
|
|
2292
|
+
const { data, error, response } = await apiClient.GET("/v1/obligations", {
|
|
2293
|
+
params: {
|
|
2294
|
+
query: {
|
|
2295
|
+
cursor: parameters?.cursor,
|
|
2296
|
+
limit: parameters?.limit
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
});
|
|
2300
|
+
if (error !== void 0) {
|
|
2301
|
+
switch (response.status) {
|
|
2302
|
+
case 401:
|
|
2303
|
+
throw new HttpUnauthorizedError();
|
|
2304
|
+
case 403:
|
|
2305
|
+
throw new HttpForbiddenError();
|
|
2306
|
+
case 429:
|
|
2307
|
+
throw new HttpRateLimitError();
|
|
2308
|
+
}
|
|
2309
|
+
throw new HttpGetApiFailedError(`GET request returned ${response.status}`, {
|
|
2310
|
+
details: JSON.stringify(error)
|
|
2311
|
+
});
|
|
1606
2312
|
}
|
|
1607
|
-
|
|
1608
|
-
|
|
2313
|
+
const obligations = data?.data.map((item) => {
|
|
2314
|
+
const obligation = Obligation_exports.fromSnakeCase({
|
|
2315
|
+
chain_id: item.chain_id,
|
|
2316
|
+
loan_token: item.loan_token,
|
|
2317
|
+
collaterals: item.collaterals.map((collateral) => ({
|
|
2318
|
+
asset: collateral.asset,
|
|
2319
|
+
oracle: collateral.oracle,
|
|
2320
|
+
lltv: collateral.lltv
|
|
2321
|
+
})),
|
|
2322
|
+
maturity: Maturity_exports.from(item.maturity)
|
|
2323
|
+
});
|
|
2324
|
+
const { obligationId: _, ...returned } = {
|
|
2325
|
+
id: () => Obligation_exports.id(obligation),
|
|
2326
|
+
...obligation,
|
|
2327
|
+
...Quote_exports.fromSnakeCase({ obligation_id: item.id, ask: item.ask, bid: item.bid })
|
|
2328
|
+
};
|
|
2329
|
+
return returned;
|
|
2330
|
+
}) ?? [];
|
|
2331
|
+
return {
|
|
2332
|
+
cursor: data?.cursor ?? null,
|
|
2333
|
+
obligations
|
|
2334
|
+
};
|
|
2335
|
+
}
|
|
2336
|
+
var InvalidUrlError = class extends BaseError {
|
|
2337
|
+
constructor(url) {
|
|
2338
|
+
super(`URL "${url}" is not http/https.`);
|
|
2339
|
+
__publicField(this, "name", "Router.InvalidUrlError");
|
|
1609
2340
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
field: "rate",
|
|
1618
|
-
type: "string",
|
|
1619
|
-
pattern: /^\d+$/,
|
|
1620
|
-
error: "numeric string"
|
|
1621
|
-
},
|
|
1622
|
-
amount: {
|
|
1623
|
-
field: "assets",
|
|
1624
|
-
type: "string",
|
|
1625
|
-
pattern: /^\d+$/,
|
|
1626
|
-
error: "numeric string"
|
|
1627
|
-
},
|
|
1628
|
-
maturity: {
|
|
1629
|
-
field: "maturity",
|
|
1630
|
-
type: "number",
|
|
1631
|
-
validator: (val) => val > 0,
|
|
1632
|
-
error: "positive number"
|
|
1633
|
-
},
|
|
1634
|
-
expiry: {
|
|
1635
|
-
field: "expiry",
|
|
1636
|
-
type: "number",
|
|
1637
|
-
validator: (val) => val > 0,
|
|
1638
|
-
error: "positive number"
|
|
1639
|
-
}
|
|
1640
|
-
};
|
|
1641
|
-
const validation = validations[c.sort];
|
|
1642
|
-
if (!validation) {
|
|
1643
|
-
throw new Error(`Invalid sort field: ${c.sort}`);
|
|
1644
|
-
}
|
|
1645
|
-
const fieldValue = c[validation.field];
|
|
1646
|
-
if (!fieldValue) {
|
|
1647
|
-
throw new Error(`${c.sort} sort requires '${validation.field}' field to be present`);
|
|
1648
|
-
}
|
|
1649
|
-
if (typeof fieldValue !== validation.type) {
|
|
1650
|
-
throw new Error(
|
|
1651
|
-
`${c.sort} sort requires '${validation.field}' field of type ${validation.type}`
|
|
1652
|
-
);
|
|
1653
|
-
}
|
|
1654
|
-
if (validation.pattern && !validation.pattern.test(fieldValue)) {
|
|
1655
|
-
throw new Error(
|
|
1656
|
-
`Invalid ${validation.field} format: ${fieldValue}. Must be a ${validation.error}`
|
|
1657
|
-
);
|
|
1658
|
-
}
|
|
1659
|
-
if (validation.validator && !validation.validator(fieldValue)) {
|
|
1660
|
-
throw new Error(
|
|
1661
|
-
`Invalid ${validation.field} value: ${fieldValue}. Must be a ${validation.error}`
|
|
1662
|
-
);
|
|
1663
|
-
}
|
|
1664
|
-
if (c.page !== void 0) {
|
|
1665
|
-
if (typeof c.page !== "number" || !Number.isInteger(c.page) || c.page < 1) {
|
|
1666
|
-
throw new Error("Invalid page: must be a positive integer");
|
|
1667
|
-
}
|
|
1668
|
-
}
|
|
1669
|
-
return true;
|
|
1670
|
-
}
|
|
1671
|
-
function encode2(c) {
|
|
1672
|
-
return jsBase64.Base64.encodeURL(JSON.stringify(c));
|
|
1673
|
-
}
|
|
1674
|
-
function decode2(token) {
|
|
1675
|
-
if (!token) return null;
|
|
1676
|
-
const decoded = JSON.parse(jsBase64.Base64.decode(token));
|
|
1677
|
-
validate(decoded);
|
|
1678
|
-
return decoded;
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
// src/api/Schema/requests.ts
|
|
1682
|
-
var MAX_LIMIT = 100;
|
|
1683
|
-
var DEFAULT_LIMIT = 20;
|
|
1684
|
-
var PaginationQueryParams = z7__namespace.object({
|
|
1685
|
-
cursor: z7__namespace.string().optional().refine(
|
|
1686
|
-
(val) => {
|
|
1687
|
-
if (!val) return true;
|
|
1688
|
-
try {
|
|
1689
|
-
const decoded = Cursor_exports.decode(val);
|
|
1690
|
-
return decoded !== null;
|
|
1691
|
-
} catch (_error) {
|
|
1692
|
-
return false;
|
|
1693
|
-
}
|
|
1694
|
-
},
|
|
1695
|
-
{
|
|
1696
|
-
message: "Invalid cursor format. Must be a valid base64url-encoded cursor object"
|
|
1697
|
-
}
|
|
1698
|
-
).meta({
|
|
1699
|
-
description: "Pagination cursor in base64url-encoded format",
|
|
1700
|
-
example: "eyJzb3J0IjoicHJpY2UiLCJkaXIiOiJkZXNjIiwicHJpY2UiOiIxMDAwMDAwMDAwMDAwMDAwMDAwIiwiaGFzaCI6IjB4ZGRmZDY4NTllM2UwODJkMTkzODlhMWFlYzFiZGFkN2U4ZDkyZDk2YjFhYTc5NDBkYTkxYTMxMjVkMzFlM2JlNWIifQ"
|
|
1701
|
-
}),
|
|
1702
|
-
limit: z7__namespace.string().regex(/^[1-9]\d*$/, {
|
|
1703
|
-
message: "Limit must be a positive integer"
|
|
1704
|
-
}).transform((val) => Number.parseInt(val, 10)).pipe(
|
|
1705
|
-
z7__namespace.number().max(MAX_LIMIT, {
|
|
1706
|
-
message: `Limit cannot exceed ${MAX_LIMIT}`
|
|
1707
|
-
})
|
|
1708
|
-
).optional().default(DEFAULT_LIMIT).meta({
|
|
1709
|
-
description: `Limit maximum: ${MAX_LIMIT}. Default: ${DEFAULT_LIMIT}`,
|
|
1710
|
-
example: 10
|
|
1711
|
-
})
|
|
1712
|
-
});
|
|
1713
|
-
var GetOffersQueryParams = z7__namespace.object({
|
|
1714
|
-
...PaginationQueryParams.shape,
|
|
1715
|
-
side: z7__namespace.enum(["buy", "sell"]).meta({
|
|
1716
|
-
description: "Side of the offer.",
|
|
1717
|
-
example: "buy"
|
|
1718
|
-
}),
|
|
1719
|
-
obligation_id: z7__namespace.string({ error: "Obligation id is required and must be a valid 32-byte hex string" }).regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).meta({
|
|
1720
|
-
description: "Offers obligation id",
|
|
1721
|
-
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
1722
|
-
})
|
|
1723
|
-
});
|
|
1724
|
-
var GetObligationsQueryParams = z7__namespace.object({
|
|
1725
|
-
...PaginationQueryParams.shape,
|
|
1726
|
-
cursor: z7__namespace.string().optional().meta({
|
|
1727
|
-
description: "Obligation id cursor",
|
|
1728
|
-
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
1729
|
-
})
|
|
1730
|
-
});
|
|
1731
|
-
var schemas = {
|
|
1732
|
-
get_offers: GetOffersQueryParams,
|
|
1733
|
-
get_obligations: GetObligationsQueryParams
|
|
1734
|
-
};
|
|
1735
|
-
function parse(action, query) {
|
|
1736
|
-
return schemas[action].parse(query);
|
|
1737
|
-
}
|
|
1738
|
-
function safeParse(action, query, error) {
|
|
1739
|
-
return schemas[action].safeParse(query, {
|
|
1740
|
-
error
|
|
1741
|
-
});
|
|
1742
|
-
}
|
|
1743
|
-
|
|
1744
|
-
// src/api/Schema/openapi.ts
|
|
1745
|
-
var timestampExample = "2024-01-01T12:00:00.000Z";
|
|
1746
|
-
var cursorExample = "eyJvZmZzZXQiOjEwMH0";
|
|
1747
|
-
function makeSuccessResponse(parameters) {
|
|
1748
|
-
const { dataSchema, dataDescription, dataExample, cursor } = parameters;
|
|
1749
|
-
const withDataMeta = dataDescription ? dataSchema.meta({ description: dataDescription }) : dataSchema;
|
|
1750
|
-
return v4.z.object({
|
|
1751
|
-
status: v4.z.literal("success"),
|
|
1752
|
-
cursor: v4.z.string().nullable(),
|
|
1753
|
-
data: v4.z.any(),
|
|
1754
|
-
meta: v4.z.object({
|
|
1755
|
-
timestamp: v4.z.string()
|
|
1756
|
-
})
|
|
1757
|
-
}).extend({
|
|
1758
|
-
data: withDataMeta
|
|
1759
|
-
}).meta({
|
|
1760
|
-
example: {
|
|
1761
|
-
status: "success",
|
|
1762
|
-
cursor,
|
|
1763
|
-
data: dataExample,
|
|
1764
|
-
meta: { timestamp: timestampExample }
|
|
1765
|
-
}
|
|
1766
|
-
});
|
|
1767
|
-
}
|
|
1768
|
-
var OffersSuccessResponseSchema = makeSuccessResponse({
|
|
1769
|
-
dataSchema: v4.z.array(v4.z.any()),
|
|
1770
|
-
dataDescription: "Offers matching the provided filters.",
|
|
1771
|
-
dataExample: [toSnakeCase(Offer_exports.random())],
|
|
1772
|
-
cursor: cursorExample
|
|
1773
|
-
});
|
|
1774
|
-
var ObligationsSuccessResponseSchema = makeSuccessResponse({
|
|
1775
|
-
dataSchema: v4.z.array(v4.z.any()),
|
|
1776
|
-
dataDescription: "Obligations known to the router.",
|
|
1777
|
-
dataExample: [toSnakeCase(Obligation_exports.random())],
|
|
1778
|
-
cursor: cursorExample
|
|
1779
|
-
});
|
|
1780
|
-
var RouterStatusSuccessResponseSchema = makeSuccessResponse({
|
|
1781
|
-
dataSchema: RouterStatusResponse,
|
|
1782
|
-
dataDescription: "Aggregated router status.",
|
|
1783
|
-
dataExample: { status: "live" },
|
|
1784
|
-
cursor: null
|
|
1785
|
-
});
|
|
1786
|
-
var CollectorsHealthSuccessResponseSchema = makeSuccessResponse({
|
|
1787
|
-
dataSchema: CollectorsHealthResponse,
|
|
1788
|
-
dataDescription: "Collectors health details and sync status.",
|
|
1789
|
-
dataExample: [
|
|
1790
|
-
{
|
|
1791
|
-
name: "mempool_offers",
|
|
1792
|
-
chain_id: "1",
|
|
1793
|
-
block_number: 21345678,
|
|
1794
|
-
updated_at: "2024-01-01T12:00:00.000Z",
|
|
1795
|
-
lag: 0,
|
|
1796
|
-
status: "live"
|
|
1797
|
-
}
|
|
1798
|
-
],
|
|
1799
|
-
cursor: null
|
|
1800
|
-
});
|
|
1801
|
-
var ChainsHealthSuccessResponseSchema = makeSuccessResponse({
|
|
1802
|
-
dataSchema: ChainsHealthResponse,
|
|
1803
|
-
dataDescription: "Latest processed block per chain.",
|
|
1804
|
-
dataExample: [
|
|
1805
|
-
{
|
|
1806
|
-
chain_id: "1",
|
|
1807
|
-
block_number: 21345678,
|
|
1808
|
-
updated_at: "2024-01-01T12:00:00.000Z"
|
|
1809
|
-
}
|
|
1810
|
-
],
|
|
1811
|
-
cursor: null
|
|
1812
|
-
});
|
|
1813
|
-
var errorResponseSchema = v4.z.object({
|
|
1814
|
-
status: v4.z.literal("error"),
|
|
1815
|
-
error: v4.z.object({
|
|
1816
|
-
code: v4.z.string(),
|
|
1817
|
-
message: v4.z.string(),
|
|
1818
|
-
details: v4.z.any().optional()
|
|
1819
|
-
}),
|
|
1820
|
-
meta: v4.z.object({
|
|
1821
|
-
timestamp: v4.z.string()
|
|
1822
|
-
})
|
|
1823
|
-
}).meta({
|
|
1824
|
-
description: "Error response wrapper.",
|
|
1825
|
-
example: {
|
|
1826
|
-
status: "error",
|
|
1827
|
-
error: {
|
|
1828
|
-
code: "VALIDATION_ERROR",
|
|
1829
|
-
message: "Invalid cursor format. Must be a valid base64url-encoded cursor object",
|
|
1830
|
-
details: [
|
|
1831
|
-
{
|
|
1832
|
-
field: "cursor",
|
|
1833
|
-
issue: "Invalid cursor format. Must be a valid base64url-encoded cursor object"
|
|
1834
|
-
}
|
|
1835
|
-
]
|
|
1836
|
-
},
|
|
1837
|
-
meta: {
|
|
1838
|
-
timestamp: timestampExample
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
});
|
|
1842
|
-
var paths = {
|
|
1843
|
-
"/v1/offers": {
|
|
1844
|
-
get: {
|
|
1845
|
-
summary: "Offers",
|
|
1846
|
-
description: "Find offers that match specific criteria",
|
|
1847
|
-
tags: ["Offers"],
|
|
1848
|
-
requestParams: {
|
|
1849
|
-
query: GetOffersQueryParams
|
|
1850
|
-
},
|
|
1851
|
-
responses: {
|
|
1852
|
-
200: {
|
|
1853
|
-
description: "Success",
|
|
1854
|
-
content: {
|
|
1855
|
-
"application/json": {
|
|
1856
|
-
schema: OffersSuccessResponseSchema
|
|
1857
|
-
}
|
|
1858
|
-
}
|
|
1859
|
-
},
|
|
1860
|
-
400: {
|
|
1861
|
-
description: "Bad Request",
|
|
1862
|
-
content: {
|
|
1863
|
-
"application/json": {
|
|
1864
|
-
schema: errorResponseSchema
|
|
1865
|
-
}
|
|
1866
|
-
}
|
|
1867
|
-
}
|
|
1868
|
-
}
|
|
1869
|
-
}
|
|
1870
|
-
},
|
|
1871
|
-
"/v1/obligations": {
|
|
1872
|
-
get: {
|
|
1873
|
-
summary: "Obligations",
|
|
1874
|
-
description: "List obligations with pagination support",
|
|
1875
|
-
tags: ["Obligations"],
|
|
1876
|
-
requestParams: {
|
|
1877
|
-
query: GetObligationsQueryParams
|
|
1878
|
-
},
|
|
1879
|
-
responses: {
|
|
1880
|
-
200: {
|
|
1881
|
-
description: "Success",
|
|
1882
|
-
content: {
|
|
1883
|
-
"application/json": {
|
|
1884
|
-
schema: ObligationsSuccessResponseSchema
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
|
-
},
|
|
1888
|
-
400: {
|
|
1889
|
-
description: "Bad Request",
|
|
1890
|
-
content: {
|
|
1891
|
-
"application/json": {
|
|
1892
|
-
schema: errorResponseSchema
|
|
1893
|
-
}
|
|
1894
|
-
}
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1897
|
-
}
|
|
1898
|
-
},
|
|
1899
|
-
"/v1/health": {
|
|
1900
|
-
get: {
|
|
1901
|
-
summary: "Router status",
|
|
1902
|
-
description: "Retrieve the aggregated status of the router.",
|
|
1903
|
-
tags: ["Health"],
|
|
1904
|
-
responses: {
|
|
1905
|
-
200: {
|
|
1906
|
-
description: "Success",
|
|
1907
|
-
content: {
|
|
1908
|
-
"application/json": {
|
|
1909
|
-
schema: RouterStatusSuccessResponseSchema
|
|
1910
|
-
}
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
1913
|
-
}
|
|
1914
|
-
}
|
|
1915
|
-
},
|
|
1916
|
-
"/v1/health/collectors": {
|
|
1917
|
-
get: {
|
|
1918
|
-
summary: "Collectors health",
|
|
1919
|
-
description: "Retrieve the block numbers processed by collectors and their sync status.",
|
|
1920
|
-
tags: ["Health"],
|
|
1921
|
-
responses: {
|
|
1922
|
-
200: {
|
|
1923
|
-
description: "Success",
|
|
1924
|
-
content: {
|
|
1925
|
-
"application/json": {
|
|
1926
|
-
schema: CollectorsHealthSuccessResponseSchema
|
|
1927
|
-
}
|
|
1928
|
-
}
|
|
1929
|
-
}
|
|
1930
|
-
}
|
|
1931
|
-
}
|
|
1932
|
-
},
|
|
1933
|
-
"/v1/health/chains": {
|
|
1934
|
-
get: {
|
|
1935
|
-
summary: "Chains health",
|
|
1936
|
-
description: "Retrieve the latest block processed for each chain.",
|
|
1937
|
-
tags: ["Health"],
|
|
1938
|
-
responses: {
|
|
1939
|
-
200: {
|
|
1940
|
-
description: "Success",
|
|
1941
|
-
content: {
|
|
1942
|
-
"application/json": {
|
|
1943
|
-
schema: ChainsHealthSuccessResponseSchema
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1946
|
-
}
|
|
1947
|
-
}
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
};
|
|
1951
|
-
var OpenApi = zodOpenapi.createDocument({
|
|
1952
|
-
openapi: "3.1.0",
|
|
1953
|
-
info: {
|
|
1954
|
-
title: "Router API",
|
|
1955
|
-
version: "1.0.0",
|
|
1956
|
-
description: "API for the Morpho Router"
|
|
1957
|
-
},
|
|
1958
|
-
tags: [
|
|
1959
|
-
{
|
|
1960
|
-
name: "Offers"
|
|
1961
|
-
},
|
|
1962
|
-
{
|
|
1963
|
-
name: "Obligations"
|
|
1964
|
-
},
|
|
1965
|
-
{
|
|
1966
|
-
name: "Health"
|
|
1967
|
-
}
|
|
1968
|
-
],
|
|
1969
|
-
servers: [
|
|
1970
|
-
{
|
|
1971
|
-
url: "https://router.morpho.dev",
|
|
1972
|
-
description: "Production server"
|
|
1973
|
-
},
|
|
1974
|
-
{
|
|
1975
|
-
url: "http://localhost:7891",
|
|
1976
|
-
description: "Local development server"
|
|
1977
|
-
}
|
|
1978
|
-
],
|
|
1979
|
-
paths
|
|
1980
|
-
});
|
|
1981
|
-
|
|
1982
|
-
// src/client/Client.ts
|
|
1983
|
-
var Client_exports = {};
|
|
1984
|
-
__export(Client_exports, {
|
|
1985
|
-
HttpForbiddenError: () => HttpForbiddenError,
|
|
1986
|
-
HttpGetApiFailedError: () => HttpGetApiFailedError,
|
|
1987
|
-
HttpRateLimitError: () => HttpRateLimitError,
|
|
1988
|
-
HttpUnauthorizedError: () => HttpUnauthorizedError,
|
|
1989
|
-
InvalidUrlError: () => InvalidUrlError,
|
|
1990
|
-
connect: () => connect,
|
|
1991
|
-
getObligations: () => getObligations,
|
|
1992
|
-
getOffers: () => getOffers
|
|
1993
|
-
});
|
|
1994
|
-
function connect(options) {
|
|
1995
|
-
const u = new URL(options?.url || "https://router.morpho.dev");
|
|
1996
|
-
if (u.protocol !== "http:" && u.protocol !== "https:") {
|
|
1997
|
-
throw new InvalidUrlError(u.toString());
|
|
1998
|
-
}
|
|
1999
|
-
const headers = options?.headers ?? new Headers();
|
|
2000
|
-
headers.set("Content-Type", "application/json");
|
|
2001
|
-
options?.apiKey !== void 0 ? headers.set("X-API-Key", options.apiKey) : null;
|
|
2002
|
-
const config = {
|
|
2003
|
-
url: u,
|
|
2004
|
-
headers
|
|
2005
|
-
};
|
|
2006
|
-
return {
|
|
2007
|
-
...config,
|
|
2008
|
-
getOffers: (parameters) => getOffers(config, parameters),
|
|
2009
|
-
getObligations: (parameters) => getObligations(config, parameters)
|
|
2010
|
-
};
|
|
2011
|
-
}
|
|
2012
|
-
async function getOffers(config, parameters) {
|
|
2013
|
-
const url = new URL(`${config.url.toString()}v1/offers`);
|
|
2014
|
-
url.searchParams.set("side", parameters.side);
|
|
2015
|
-
url.searchParams.set("obligation_id", parameters.obligationId.toString());
|
|
2016
|
-
if (parameters.cursor) {
|
|
2017
|
-
url.searchParams.set("cursor", parameters.cursor);
|
|
2018
|
-
}
|
|
2019
|
-
if (parameters.limit !== void 0) {
|
|
2020
|
-
url.searchParams.set("limit", parameters.limit.toString());
|
|
2021
|
-
}
|
|
2022
|
-
const { cursor: returnedCursor, data: offers } = await getApi(config, url);
|
|
2023
|
-
const routerOffers = offers.map(Offer_exports.fromSnakeCase);
|
|
2024
|
-
return {
|
|
2025
|
-
cursor: returnedCursor,
|
|
2026
|
-
offers: routerOffers
|
|
2027
|
-
};
|
|
2028
|
-
}
|
|
2029
|
-
async function getObligations(config, parameters) {
|
|
2030
|
-
const url = new URL(`${config.url.toString()}v1/obligations`);
|
|
2031
|
-
if (parameters?.cursor !== void 0) {
|
|
2032
|
-
url.searchParams.set("cursor", parameters.cursor);
|
|
2033
|
-
}
|
|
2034
|
-
if (parameters?.limit !== void 0) {
|
|
2035
|
-
url.searchParams.set("limit", parameters.limit.toString());
|
|
2036
|
-
}
|
|
2037
|
-
const { cursor: returnedCursor, data: items } = await getApi(config, url);
|
|
2038
|
-
const obligations = items.map((item) => {
|
|
2039
|
-
const obligation = Obligation_exports.fromSnakeCase(item);
|
|
2040
|
-
const { obligationId: _, ...returned } = {
|
|
2041
|
-
id: () => Obligation_exports.id(obligation),
|
|
2042
|
-
...obligation,
|
|
2043
|
-
...Quote_exports.fromSnakeCase({ obligation_id: item.id, ask: item.ask, bid: item.bid })
|
|
2044
|
-
};
|
|
2045
|
-
return returned;
|
|
2046
|
-
});
|
|
2047
|
-
return {
|
|
2048
|
-
cursor: returnedCursor,
|
|
2049
|
-
obligations
|
|
2050
|
-
};
|
|
2051
|
-
}
|
|
2052
|
-
async function getApi(config, url) {
|
|
2053
|
-
const pathname = url.pathname;
|
|
2054
|
-
let action;
|
|
2055
|
-
switch (true) {
|
|
2056
|
-
case pathname.includes("/v1/offers"):
|
|
2057
|
-
action = "get_offers";
|
|
2058
|
-
break;
|
|
2059
|
-
case pathname.includes("/v1/obligations"):
|
|
2060
|
-
action = "get_obligations";
|
|
2061
|
-
break;
|
|
2062
|
-
default:
|
|
2063
|
-
throw new HttpGetApiFailedError("Unknown endpoint", {
|
|
2064
|
-
details: `Unsupported path: ${pathname}`
|
|
2065
|
-
});
|
|
2066
|
-
}
|
|
2067
|
-
const schemaParseResult = safeParse(action, Object.fromEntries(url.searchParams));
|
|
2068
|
-
if (!schemaParseResult.success) {
|
|
2069
|
-
throw new HttpGetApiFailedError(`Invalid URL parameters`, {
|
|
2070
|
-
details: schemaParseResult.error.issues[0]?.message
|
|
2071
|
-
});
|
|
2072
|
-
}
|
|
2073
|
-
const response = await fetch(url.toString(), {
|
|
2074
|
-
method: "GET",
|
|
2075
|
-
headers: config.headers
|
|
2076
|
-
});
|
|
2077
|
-
if (!response.ok) {
|
|
2078
|
-
switch (response.status) {
|
|
2079
|
-
case 401:
|
|
2080
|
-
throw new HttpUnauthorizedError();
|
|
2081
|
-
case 403:
|
|
2082
|
-
throw new HttpForbiddenError();
|
|
2083
|
-
case 429:
|
|
2084
|
-
throw new HttpRateLimitError();
|
|
2085
|
-
}
|
|
2086
|
-
throw new HttpGetApiFailedError(`GET request returned ${response.status}`, {
|
|
2087
|
-
details: await response.text()
|
|
2088
|
-
});
|
|
2089
|
-
}
|
|
2090
|
-
return response.json();
|
|
2091
|
-
}
|
|
2092
|
-
var InvalidUrlError = class extends BaseError {
|
|
2093
|
-
constructor(url) {
|
|
2094
|
-
super(`URL "${url}" is not http/https.`);
|
|
2095
|
-
__publicField(this, "name", "Router.InvalidUrlError");
|
|
2096
|
-
}
|
|
2097
|
-
};
|
|
2098
|
-
var HttpUnauthorizedError = class extends BaseError {
|
|
2099
|
-
constructor() {
|
|
2100
|
-
super("Unauthorized.", {
|
|
2101
|
-
metaMessages: ["Ensure that an API key is provided."]
|
|
2102
|
-
});
|
|
2103
|
-
__publicField(this, "name", "Router.HttpUnauthorizedError");
|
|
2341
|
+
};
|
|
2342
|
+
var HttpUnauthorizedError = class extends BaseError {
|
|
2343
|
+
constructor() {
|
|
2344
|
+
super("Unauthorized.", {
|
|
2345
|
+
metaMessages: ["Ensure that an API key is provided."]
|
|
2346
|
+
});
|
|
2347
|
+
__publicField(this, "name", "Router.HttpUnauthorizedError");
|
|
2104
2348
|
}
|
|
2105
2349
|
};
|
|
2106
2350
|
var HttpForbiddenError = class extends BaseError {
|
|
@@ -2130,13 +2374,21 @@ var HttpGetApiFailedError = class extends BaseError {
|
|
|
2130
2374
|
}
|
|
2131
2375
|
};
|
|
2132
2376
|
|
|
2133
|
-
// src/
|
|
2134
|
-
var
|
|
2135
|
-
__export(
|
|
2136
|
-
|
|
2377
|
+
// src/gatekeeper/Gate.ts
|
|
2378
|
+
var Gate_exports = {};
|
|
2379
|
+
__export(Gate_exports, {
|
|
2380
|
+
batch: () => batch2,
|
|
2381
|
+
run: () => run,
|
|
2382
|
+
single: () => single
|
|
2137
2383
|
});
|
|
2384
|
+
function single(name, run2) {
|
|
2385
|
+
return { kind: "single", name, run: run2 };
|
|
2386
|
+
}
|
|
2387
|
+
function batch2(name, run2) {
|
|
2388
|
+
return { kind: "batch", name, run: run2 };
|
|
2389
|
+
}
|
|
2138
2390
|
async function run(parameters) {
|
|
2139
|
-
const { items, rules,
|
|
2391
|
+
const { items, rules, chunkSize } = parameters;
|
|
2140
2392
|
const issues = [];
|
|
2141
2393
|
let validItems = items.slice();
|
|
2142
2394
|
for (const rule of rules) {
|
|
@@ -2145,7 +2397,7 @@ async function run(parameters) {
|
|
|
2145
2397
|
if (rule.kind === "single") {
|
|
2146
2398
|
for (let i = 0; i < validItems.length; i++) {
|
|
2147
2399
|
const item = validItems[i];
|
|
2148
|
-
const issue = await rule.run(item
|
|
2400
|
+
const issue = await rule.run(item);
|
|
2149
2401
|
if (issue) {
|
|
2150
2402
|
issues.push({ ...issue, ruleName: rule.name, item });
|
|
2151
2403
|
indicesToRemove.add(i);
|
|
@@ -2153,7 +2405,7 @@ async function run(parameters) {
|
|
|
2153
2405
|
}
|
|
2154
2406
|
} else if (rule.kind === "batch") {
|
|
2155
2407
|
const exec = async (slice, offset) => {
|
|
2156
|
-
const map = await rule.run(slice
|
|
2408
|
+
const map = await rule.run(slice);
|
|
2157
2409
|
for (let i = 0; i < slice.length; i++) {
|
|
2158
2410
|
const issue = map.get(i);
|
|
2159
2411
|
if (issue !== void 0) {
|
|
@@ -2177,157 +2429,265 @@ async function run(parameters) {
|
|
|
2177
2429
|
};
|
|
2178
2430
|
}
|
|
2179
2431
|
|
|
2180
|
-
// src/
|
|
2181
|
-
var
|
|
2182
|
-
__export(
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2432
|
+
// src/gatekeeper/GateConfig.ts
|
|
2433
|
+
var GateConfig_exports = {};
|
|
2434
|
+
__export(GateConfig_exports, {
|
|
2435
|
+
assets: () => assets,
|
|
2436
|
+
configs: () => configs,
|
|
2437
|
+
getCallback: () => getCallback,
|
|
2438
|
+
getCallbackAddresses: () => getCallbackAddresses,
|
|
2439
|
+
getCallbackType: () => getCallbackType,
|
|
2440
|
+
getCallbackTypeAddresses: () => getCallbackTypeAddresses
|
|
2186
2441
|
});
|
|
2187
|
-
function
|
|
2188
|
-
return
|
|
2442
|
+
function getCallback(chain2, type) {
|
|
2443
|
+
return configs[chain2].callbacks?.find((c) => c.type === type);
|
|
2189
2444
|
}
|
|
2190
|
-
function
|
|
2191
|
-
return
|
|
2445
|
+
function getCallbackType(chain2, address) {
|
|
2446
|
+
return configs[chain2].callbacks?.find(
|
|
2447
|
+
(c) => c.type !== "buy_with_empty_callback" /* BuyWithEmptyCallback */ && c.addresses.includes(address?.toLowerCase())
|
|
2448
|
+
)?.type;
|
|
2192
2449
|
}
|
|
2193
|
-
function
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
"
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
"
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2450
|
+
function getCallbackTypeAddresses(chain2, type) {
|
|
2451
|
+
if (type === "buy_with_empty_callback" /* BuyWithEmptyCallback */) {
|
|
2452
|
+
return [];
|
|
2453
|
+
}
|
|
2454
|
+
const match = configs[chain2].callbacks?.find((c) => c.type === type);
|
|
2455
|
+
return match && "addresses" in match ? match.addresses : [];
|
|
2456
|
+
}
|
|
2457
|
+
var getCallbackAddresses = (chain2) => {
|
|
2458
|
+
return configs[chain2].callbacks?.filter((c) => c.type !== "buy_with_empty_callback" /* BuyWithEmptyCallback */).flatMap((c) => c.addresses) ?? [];
|
|
2459
|
+
};
|
|
2460
|
+
var assets = {
|
|
2461
|
+
[ChainId.ETHEREUM.toString()]: [
|
|
2462
|
+
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
2463
|
+
// USDC
|
|
2464
|
+
"0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
2465
|
+
// DAI
|
|
2466
|
+
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
2467
|
+
// WETH
|
|
2468
|
+
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
|
|
2469
|
+
// WBTC
|
|
2470
|
+
],
|
|
2471
|
+
[ChainId.BASE.toString()]: [
|
|
2472
|
+
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
2473
|
+
// USDC
|
|
2474
|
+
"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
|
2475
|
+
// DAI
|
|
2476
|
+
"0x4200000000000000000000000000000000000006",
|
|
2477
|
+
// WETH
|
|
2478
|
+
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
|
|
2479
|
+
// WBTC
|
|
2480
|
+
],
|
|
2481
|
+
[ChainId["ETHEREUM-VIRTUAL-TESTNET"].toString()]: [
|
|
2482
|
+
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
2483
|
+
// USDC
|
|
2484
|
+
"0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
2485
|
+
// DAI
|
|
2486
|
+
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
2487
|
+
// WETH
|
|
2488
|
+
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
|
|
2489
|
+
// WBTC
|
|
2490
|
+
],
|
|
2491
|
+
[ChainId.ANVIL.toString()]: [
|
|
2492
|
+
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
2493
|
+
// USDC
|
|
2494
|
+
"0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
2495
|
+
// DAI
|
|
2496
|
+
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
2497
|
+
// WETH
|
|
2498
|
+
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
|
|
2499
|
+
// WBTC
|
|
2500
|
+
]
|
|
2501
|
+
};
|
|
2502
|
+
var configs = {
|
|
2503
|
+
ethereum: {
|
|
2504
|
+
callbacks: [
|
|
2505
|
+
{
|
|
2506
|
+
type: "buy_vault_v1_callback" /* BuyVaultV1Callback */,
|
|
2507
|
+
addresses: [
|
|
2508
|
+
"0x3333333333333333333333333333333333333333",
|
|
2509
|
+
"0x4444444444444444444444444444444444444444"
|
|
2510
|
+
],
|
|
2511
|
+
vaultFactories: [
|
|
2512
|
+
"0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101",
|
|
2513
|
+
//v1.0
|
|
2514
|
+
"0x1897A8997241C1cD4bD0698647e4EB7213535c24"
|
|
2515
|
+
//v1.1
|
|
2516
|
+
]
|
|
2517
|
+
},
|
|
2518
|
+
{
|
|
2519
|
+
type: "sell_erc20_callback" /* SellERC20Callback */,
|
|
2520
|
+
addresses: [
|
|
2521
|
+
"0x1111111111111111111111111111111111111111",
|
|
2522
|
+
"0x2222222222222222222222222222222222222222"
|
|
2523
|
+
]
|
|
2524
|
+
},
|
|
2525
|
+
{ type: "buy_with_empty_callback" /* BuyWithEmptyCallback */ }
|
|
2526
|
+
],
|
|
2527
|
+
maturities: ["end_of_month" /* EndOfMonth */, "end_of_next_month" /* EndOfNextMonth */]
|
|
2528
|
+
},
|
|
2529
|
+
base: {
|
|
2530
|
+
callbacks: [
|
|
2531
|
+
{
|
|
2532
|
+
type: "buy_vault_v1_callback" /* BuyVaultV1Callback */,
|
|
2533
|
+
addresses: [
|
|
2534
|
+
"0x3333333333333333333333333333333333333333",
|
|
2535
|
+
"0x4444444444444444444444444444444444444444"
|
|
2536
|
+
],
|
|
2537
|
+
vaultFactories: [
|
|
2538
|
+
"0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101",
|
|
2539
|
+
//v1.0
|
|
2540
|
+
"0xFf62A7c278C62eD665133147129245053Bbf5918"
|
|
2541
|
+
//v1.1
|
|
2542
|
+
]
|
|
2543
|
+
},
|
|
2544
|
+
{
|
|
2545
|
+
type: "sell_erc20_callback" /* SellERC20Callback */,
|
|
2546
|
+
addresses: [
|
|
2547
|
+
"0x1111111111111111111111111111111111111111",
|
|
2548
|
+
"0x2222222222222222222222222222222222222222"
|
|
2549
|
+
]
|
|
2550
|
+
},
|
|
2551
|
+
{ type: "buy_with_empty_callback" /* BuyWithEmptyCallback */ }
|
|
2552
|
+
],
|
|
2553
|
+
maturities: ["end_of_month" /* EndOfMonth */, "end_of_next_month" /* EndOfNextMonth */]
|
|
2554
|
+
},
|
|
2555
|
+
"ethereum-virtual-testnet": {
|
|
2556
|
+
callbacks: [
|
|
2557
|
+
{
|
|
2558
|
+
type: "buy_vault_v1_callback" /* BuyVaultV1Callback */,
|
|
2559
|
+
addresses: [
|
|
2560
|
+
"0x3333333333333333333333333333333333333333",
|
|
2561
|
+
"0x4444444444444444444444444444444444444444"
|
|
2562
|
+
],
|
|
2563
|
+
vaultFactories: [
|
|
2564
|
+
"0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101",
|
|
2565
|
+
//v1.0
|
|
2566
|
+
"0x1897A8997241C1cD4bD0698647e4EB7213535c24"
|
|
2567
|
+
//v1.1
|
|
2568
|
+
]
|
|
2569
|
+
},
|
|
2570
|
+
{
|
|
2571
|
+
type: "sell_erc20_callback" /* SellERC20Callback */,
|
|
2572
|
+
addresses: [
|
|
2573
|
+
"0x1111111111111111111111111111111111111111",
|
|
2574
|
+
"0x2222222222222222222222222222222222222222"
|
|
2575
|
+
]
|
|
2576
|
+
},
|
|
2577
|
+
{ type: "buy_with_empty_callback" /* BuyWithEmptyCallback */ }
|
|
2578
|
+
],
|
|
2579
|
+
maturities: ["end_of_month" /* EndOfMonth */, "end_of_next_month" /* EndOfNextMonth */]
|
|
2580
|
+
},
|
|
2581
|
+
anvil: {
|
|
2582
|
+
callbacks: [
|
|
2583
|
+
{
|
|
2584
|
+
type: "buy_vault_v1_callback" /* BuyVaultV1Callback */,
|
|
2585
|
+
addresses: [
|
|
2586
|
+
"0x3333333333333333333333333333333333333333",
|
|
2587
|
+
"0x4444444444444444444444444444444444444444"
|
|
2588
|
+
],
|
|
2589
|
+
vaultFactories: [
|
|
2590
|
+
"0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101",
|
|
2591
|
+
//v1.0
|
|
2592
|
+
"0x1897A8997241C1cD4bD0698647e4EB7213535c24"
|
|
2593
|
+
//v1.1
|
|
2594
|
+
]
|
|
2595
|
+
},
|
|
2596
|
+
{
|
|
2597
|
+
type: "sell_erc20_callback" /* SellERC20Callback */,
|
|
2598
|
+
addresses: [
|
|
2599
|
+
"0x1111111111111111111111111111111111111111",
|
|
2600
|
+
"0x2222222222222222222222222222222222222222"
|
|
2601
|
+
]
|
|
2602
|
+
},
|
|
2603
|
+
{ type: "buy_with_empty_callback" /* BuyWithEmptyCallback */ }
|
|
2604
|
+
],
|
|
2605
|
+
maturities: ["end_of_month" /* EndOfMonth */, "end_of_next_month" /* EndOfNextMonth */]
|
|
2606
|
+
}
|
|
2607
|
+
};
|
|
2608
|
+
|
|
2609
|
+
// src/gatekeeper/Gatekeeper.ts
|
|
2610
|
+
var Gatekeeper_exports = {};
|
|
2611
|
+
__export(Gatekeeper_exports, {
|
|
2612
|
+
create: () => create
|
|
2613
|
+
});
|
|
2614
|
+
function create(parameters) {
|
|
2615
|
+
return {
|
|
2616
|
+
isAllowed: async (offers) => {
|
|
2617
|
+
return await run({
|
|
2618
|
+
items: offers,
|
|
2619
|
+
rules: parameters.rules
|
|
2620
|
+
});
|
|
2240
2621
|
}
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2622
|
+
};
|
|
2623
|
+
}
|
|
2624
|
+
|
|
2625
|
+
// src/gatekeeper/Rules.ts
|
|
2626
|
+
var Rules_exports = {};
|
|
2627
|
+
__export(Rules_exports, {
|
|
2628
|
+
callback: () => callback,
|
|
2629
|
+
chain: () => chain,
|
|
2630
|
+
maturity: () => maturity,
|
|
2631
|
+
token: () => token,
|
|
2632
|
+
validity: () => validity
|
|
2633
|
+
});
|
|
2634
|
+
function validity(parameters) {
|
|
2635
|
+
const { chain: chain2, client } = parameters;
|
|
2636
|
+
const sellErc20CallbackInvalid = single("sell_erc20_callback_invalid", (offer) => {
|
|
2637
|
+
const callbackType = getCallbackType(chain2.name, offer.callback.address);
|
|
2638
|
+
if (callbackType !== Callback_exports.CallbackType.SellERC20Callback) {
|
|
2639
|
+
return;
|
|
2256
2640
|
}
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
(offer, _) => {
|
|
2261
|
-
if (!offer.buy && offer.callback.data !== "0x") {
|
|
2262
|
-
try {
|
|
2263
|
-
const decoded = Callback_exports.decodeSellERC20Callback(offer.callback.data);
|
|
2264
|
-
if (decoded.length === 0) {
|
|
2265
|
-
return { message: "Sell offer callback data must include at least one collateral." };
|
|
2266
|
-
}
|
|
2267
|
-
} catch (_2) {
|
|
2268
|
-
return { message: "Sell offer callback data cannot be decoded." };
|
|
2269
|
-
}
|
|
2270
|
-
}
|
|
2641
|
+
const decoded = Callback_exports.decode(callbackType, offer.callback.data);
|
|
2642
|
+
if (decoded.length === 0) {
|
|
2643
|
+
return { message: "Callback data cannot be decoded or is empty." };
|
|
2271
2644
|
}
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
if (
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
offer.collaterals.map((c) => c.asset.toLowerCase())
|
|
2281
|
-
);
|
|
2282
|
-
for (const { collateral } of decoded) {
|
|
2283
|
-
if (!offerCollaterals.has(collateral.toLowerCase())) {
|
|
2284
|
-
return { message: "Sell callback collateral is not part of offer collaterals." };
|
|
2285
|
-
}
|
|
2286
|
-
}
|
|
2287
|
-
} catch (_2) {
|
|
2288
|
-
}
|
|
2645
|
+
if (callbackType === Callback_exports.CallbackType.SellERC20Callback) {
|
|
2646
|
+
const offerCollaterals = new Set(
|
|
2647
|
+
offer.collaterals.map((c) => c.asset.toLowerCase())
|
|
2648
|
+
);
|
|
2649
|
+
if (decoded.length !== offer.collaterals.length) {
|
|
2650
|
+
return {
|
|
2651
|
+
message: `Sell callback collateral length mismatch. Expected ${offer.collaterals.length}, got ${decoded.length}.`
|
|
2652
|
+
};
|
|
2289
2653
|
}
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
"buy_offers_callback_data_invalid",
|
|
2294
|
-
(offer, _) => {
|
|
2295
|
-
if (offer.buy && offer.callback.data !== "0x") {
|
|
2296
|
-
try {
|
|
2297
|
-
const decoded = Callback_exports.decodeBuyVaultV1Callback(offer.callback.data);
|
|
2298
|
-
if (decoded.length === 0) {
|
|
2299
|
-
return { message: "Buy offer callback data must include at least one vault." };
|
|
2300
|
-
}
|
|
2301
|
-
} catch (_2) {
|
|
2302
|
-
return { message: "Buy offer callback data cannot be decoded." };
|
|
2654
|
+
for (const { collateral } of decoded) {
|
|
2655
|
+
if (!offerCollaterals.has(collateral.toLowerCase())) {
|
|
2656
|
+
return { message: "Sell callback collateral is not part of offer collaterals." };
|
|
2303
2657
|
}
|
|
2304
2658
|
}
|
|
2305
2659
|
}
|
|
2306
|
-
);
|
|
2660
|
+
});
|
|
2307
2661
|
const buyCallbackVaultInvalid = batch2(
|
|
2308
2662
|
"buy_offers_callback_vault_invalid",
|
|
2309
|
-
async (offers
|
|
2663
|
+
async (offers) => {
|
|
2310
2664
|
const validationIssues = /* @__PURE__ */ new Map();
|
|
2311
2665
|
const offersByVaultAddress = /* @__PURE__ */ new Map();
|
|
2312
2666
|
for (let i = 0; i < offers.length; i++) {
|
|
2313
2667
|
const offer = offers[i];
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2668
|
+
const callbackType = getCallbackType(chain2.name, offer.callback.address);
|
|
2669
|
+
if (callbackType !== Callback_exports.CallbackType.BuyVaultV1Callback) {
|
|
2670
|
+
continue;
|
|
2671
|
+
}
|
|
2672
|
+
try {
|
|
2673
|
+
const callbackVaults = Callback_exports.decodeBuyVaultV1Callback(offer.callback.data);
|
|
2674
|
+
for (const { vault } of callbackVaults) {
|
|
2675
|
+
const normalizedVaultAddress = vault.toLowerCase();
|
|
2676
|
+
if (!offersByVaultAddress.has(normalizedVaultAddress)) {
|
|
2677
|
+
offersByVaultAddress.set(normalizedVaultAddress, []);
|
|
2323
2678
|
}
|
|
2324
|
-
|
|
2679
|
+
offersByVaultAddress.get(normalizedVaultAddress).push({ index: i, offer });
|
|
2325
2680
|
}
|
|
2681
|
+
} catch (_) {
|
|
2326
2682
|
}
|
|
2327
2683
|
}
|
|
2328
2684
|
const uniqueVaultAddresses = Array.from(offersByVaultAddress.keys());
|
|
2329
2685
|
if (uniqueVaultAddresses.length === 0) return validationIssues;
|
|
2330
|
-
const
|
|
2686
|
+
const allowedFactories = getCallback(
|
|
2687
|
+
chain2.name,
|
|
2688
|
+
Callback_exports.CallbackType.BuyVaultV1Callback
|
|
2689
|
+
)?.vaultFactories.map((f) => f.toLowerCase());
|
|
2690
|
+
if (!allowedFactories) return validationIssues;
|
|
2331
2691
|
const multicallContracts = [];
|
|
2332
2692
|
for (const vaultAddress of uniqueVaultAddresses) {
|
|
2333
2693
|
multicallContracts.push({
|
|
@@ -2335,7 +2695,7 @@ function morpho() {
|
|
|
2335
2695
|
abi: Abi_exports.ERC4626,
|
|
2336
2696
|
functionName: "asset"
|
|
2337
2697
|
});
|
|
2338
|
-
for (const factoryAddress of
|
|
2698
|
+
for (const factoryAddress of allowedFactories) {
|
|
2339
2699
|
multicallContracts.push({
|
|
2340
2700
|
address: factoryAddress,
|
|
2341
2701
|
abi: Abi_exports.MetaMorphoFactory,
|
|
@@ -2350,7 +2710,7 @@ function morpho() {
|
|
|
2350
2710
|
});
|
|
2351
2711
|
const vaultAssetByAddress = /* @__PURE__ */ new Map();
|
|
2352
2712
|
const registeredVaults = /* @__PURE__ */ new Set();
|
|
2353
|
-
const numberOfFactories =
|
|
2713
|
+
const numberOfFactories = allowedFactories.length;
|
|
2354
2714
|
let resultIndex = 0;
|
|
2355
2715
|
for (const vaultAddress of uniqueVaultAddresses) {
|
|
2356
2716
|
const assetCallResult = multicallResults[resultIndex++];
|
|
@@ -2409,30 +2769,61 @@ function morpho() {
|
|
|
2409
2769
|
return validationIssues;
|
|
2410
2770
|
}
|
|
2411
2771
|
);
|
|
2412
|
-
const
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
return {
|
|
2416
|
-
message: `Maturity must be end of current month (${allowedMaturities[0]}) or end of next month (${allowedMaturities[1]}). Got: ${offer.maturity}`
|
|
2417
|
-
};
|
|
2772
|
+
const expiry = single("expiry", (offer) => {
|
|
2773
|
+
if (offer.expiry < Math.floor(Date.now() / 1e3)) {
|
|
2774
|
+
return { message: "Expiry mismatch" };
|
|
2418
2775
|
}
|
|
2419
2776
|
});
|
|
2420
|
-
return [
|
|
2421
|
-
chainId,
|
|
2422
|
-
loanToken,
|
|
2423
|
-
expiry,
|
|
2424
|
-
maturity,
|
|
2425
|
-
// note: callback rules should be the last ones, since they do not mean that the offer is forever invalid
|
|
2426
|
-
// integrators should be able to choose if they want to keep the offer or not
|
|
2427
|
-
sellEmptyCallback,
|
|
2428
|
-
buyNonEmptyCallback,
|
|
2429
|
-
sellNonWhitelistedCallback,
|
|
2430
|
-
sellCallbackDataInvalid,
|
|
2431
|
-
sellCallbackCollateralInvalid,
|
|
2432
|
-
buyCallbackDataInvalid,
|
|
2433
|
-
buyCallbackVaultInvalid
|
|
2434
|
-
];
|
|
2777
|
+
return [expiry, sellErc20CallbackInvalid, buyCallbackVaultInvalid];
|
|
2435
2778
|
}
|
|
2779
|
+
var chain = ({ chain: chain2 }) => single("chain_id", (offer) => {
|
|
2780
|
+
if (chain2.id !== offer.chainId) {
|
|
2781
|
+
return {
|
|
2782
|
+
message: `Chain ID ${offer.chainId} is not the same as the chain ID in the context (${chain2.id})`
|
|
2783
|
+
};
|
|
2784
|
+
}
|
|
2785
|
+
});
|
|
2786
|
+
var maturity = ({ maturities }) => single("maturity", (offer) => {
|
|
2787
|
+
const allowedMaturities = maturities.map((m) => Maturity_exports.from(m));
|
|
2788
|
+
if (!allowedMaturities.includes(offer.maturity)) {
|
|
2789
|
+
return {
|
|
2790
|
+
message: `Maturity must be end of current month (${allowedMaturities[0]}) or end of next month (${allowedMaturities[1]}). Got: ${offer.maturity}`
|
|
2791
|
+
};
|
|
2792
|
+
}
|
|
2793
|
+
});
|
|
2794
|
+
var callback = ({
|
|
2795
|
+
callbacks,
|
|
2796
|
+
allowedAddresses
|
|
2797
|
+
}) => single("callback", (offer) => {
|
|
2798
|
+
if (Callback_exports.isEmptyCallback(offer) && offer.buy && !callbacks?.find((c) => c === Callback_exports.CallbackType.BuyWithEmptyCallback)) {
|
|
2799
|
+
return {
|
|
2800
|
+
message: "Buy offers with empty callback not allowed."
|
|
2801
|
+
};
|
|
2802
|
+
}
|
|
2803
|
+
if (Callback_exports.isEmptyCallback(offer) && !offer.buy) {
|
|
2804
|
+
return {
|
|
2805
|
+
message: "Sell offers require a non-empty callback."
|
|
2806
|
+
};
|
|
2807
|
+
}
|
|
2808
|
+
if (!Callback_exports.isEmptyCallback(offer)) {
|
|
2809
|
+
if (!allowedAddresses.includes(offer.callback.address?.toLowerCase())) {
|
|
2810
|
+
return {
|
|
2811
|
+
message: `Callback address ${offer.callback.address} is not allowed.`
|
|
2812
|
+
};
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
});
|
|
2816
|
+
var token = ({ assets: assets2 }) => single("token", (offer) => {
|
|
2817
|
+
const allowedAssets = assets2?.map((asset) => asset.toLowerCase());
|
|
2818
|
+
if (!allowedAssets || allowedAssets.length === 0) return { message: "No allowed assets" };
|
|
2819
|
+
if (!allowedAssets.includes(offer.loanToken.toLowerCase()))
|
|
2820
|
+
return { message: "Loan token is not allowed" };
|
|
2821
|
+
if (offer.collaterals.some(
|
|
2822
|
+
(collateral) => !allowedAssets.includes(collateral.asset.toLowerCase())
|
|
2823
|
+
))
|
|
2824
|
+
return { message: "Collateral is not allowed" };
|
|
2825
|
+
return void 0;
|
|
2826
|
+
});
|
|
2436
2827
|
|
|
2437
2828
|
// src/mempool/MempoolClient.ts
|
|
2438
2829
|
var MempoolClient_exports = {};
|
|
@@ -2441,7 +2832,7 @@ __export(MempoolClient_exports, {
|
|
|
2441
2832
|
});
|
|
2442
2833
|
var DEFAULT_BATCH_SIZE2 = 100;
|
|
2443
2834
|
var DEFAULT_BLOCK_WINDOW2 = 100;
|
|
2444
|
-
function
|
|
2835
|
+
function from10(parameters) {
|
|
2445
2836
|
const config = {
|
|
2446
2837
|
client: parameters.client,
|
|
2447
2838
|
mempoolAddress: parameters.mempoolAddress,
|
|
@@ -2450,24 +2841,24 @@ function from9(parameters) {
|
|
|
2450
2841
|
return {
|
|
2451
2842
|
add: (parameters2) => add(config, parameters2),
|
|
2452
2843
|
get: (parameters2) => get(config, parameters2),
|
|
2453
|
-
watch: (parameters2) => watch(config, parameters2),
|
|
2454
2844
|
stream: (parameters2) => streamOffers(config, parameters2)
|
|
2455
2845
|
};
|
|
2456
2846
|
}
|
|
2457
|
-
async function add(config,
|
|
2458
|
-
const offer = Offer_exports.from(parameters.offer);
|
|
2847
|
+
async function add(config, offers) {
|
|
2459
2848
|
if (!config.client.account) throw new WalletAccountNotSetError();
|
|
2849
|
+
const tree = Tree_exports.from(offers.map((o) => Offer_exports.from(o)));
|
|
2460
2850
|
const chainId = await getChainId(config.client);
|
|
2461
|
-
|
|
2462
|
-
|
|
2851
|
+
for (const offer of tree.offers) {
|
|
2852
|
+
if (BigInt(chainId) !== offer.chainId)
|
|
2853
|
+
throw new ChainIdMismatchError(offer.chainId, BigInt(chainId));
|
|
2854
|
+
}
|
|
2463
2855
|
try {
|
|
2464
|
-
|
|
2856
|
+
return await config.client.sendTransaction({
|
|
2465
2857
|
chain: config.client.chain,
|
|
2466
2858
|
account: config.client.account,
|
|
2467
2859
|
to: config.mempoolAddress,
|
|
2468
|
-
data:
|
|
2860
|
+
data: Tree_exports.encode(tree)
|
|
2469
2861
|
});
|
|
2470
|
-
return { offer, txHash: tx };
|
|
2471
2862
|
} catch (error) {
|
|
2472
2863
|
throw new ViemClientError(error instanceof Error ? error.message : "Unknown error");
|
|
2473
2864
|
}
|
|
@@ -2477,40 +2868,17 @@ async function* get(config, parameters) {
|
|
|
2477
2868
|
loanToken,
|
|
2478
2869
|
blockNumberGte,
|
|
2479
2870
|
blockNumberLte,
|
|
2480
|
-
order = "desc",
|
|
2871
|
+
order: order2 = "desc",
|
|
2481
2872
|
options: { maxBatchSize = DEFAULT_BATCH_SIZE2 } = {}
|
|
2482
2873
|
} = parameters || {};
|
|
2483
2874
|
yield* streamOffers(config, {
|
|
2484
2875
|
loanToken,
|
|
2485
|
-
order,
|
|
2876
|
+
order: order2,
|
|
2486
2877
|
blockNumberGte,
|
|
2487
2878
|
blockNumberLte,
|
|
2488
2879
|
options: { maxBatchSize, blockWindow: config.blockWindow }
|
|
2489
2880
|
});
|
|
2490
2881
|
}
|
|
2491
|
-
function watch(config, parameters) {
|
|
2492
|
-
const {
|
|
2493
|
-
loanToken,
|
|
2494
|
-
lastSyncedBlock,
|
|
2495
|
-
polling: { interval = 3e4, maxBatchSize = DEFAULT_BATCH_SIZE2 } = {},
|
|
2496
|
-
onOffers
|
|
2497
|
-
} = parameters;
|
|
2498
|
-
return poll(
|
|
2499
|
-
async () => {
|
|
2500
|
-
const blockNumberGte = await lastSyncedBlock();
|
|
2501
|
-
const stream = streamOffers(config, {
|
|
2502
|
-
loanToken,
|
|
2503
|
-
order: "asc",
|
|
2504
|
-
blockNumberGte,
|
|
2505
|
-
options: { maxBatchSize, blockWindow: config.blockWindow }
|
|
2506
|
-
});
|
|
2507
|
-
for await (const { offers, blockNumber } of stream) {
|
|
2508
|
-
await onOffers(offers, blockNumber);
|
|
2509
|
-
}
|
|
2510
|
-
},
|
|
2511
|
-
{ interval }
|
|
2512
|
-
);
|
|
2513
|
-
}
|
|
2514
2882
|
var chainIdCache = /* @__PURE__ */ new Map();
|
|
2515
2883
|
var getChainId = async (client) => {
|
|
2516
2884
|
if (chainIdCache.has(client.uid)) return chainIdCache.get(client.uid);
|
|
@@ -2523,7 +2891,7 @@ async function* streamOffers(config, parameters) {
|
|
|
2523
2891
|
loanToken,
|
|
2524
2892
|
blockNumberGte,
|
|
2525
2893
|
blockNumberLte,
|
|
2526
|
-
order = "desc",
|
|
2894
|
+
order: order2 = "desc",
|
|
2527
2895
|
options: { maxBatchSize = DEFAULT_BATCH_SIZE2, blockWindow = config.blockWindow } = {}
|
|
2528
2896
|
} = parameters;
|
|
2529
2897
|
const stream = Chain_exports.streamLogs({
|
|
@@ -2537,28 +2905,29 @@ async function* streamOffers(config, parameters) {
|
|
|
2537
2905
|
},
|
|
2538
2906
|
blockNumberGte,
|
|
2539
2907
|
blockNumberLte,
|
|
2540
|
-
order,
|
|
2908
|
+
order: order2,
|
|
2541
2909
|
options: { maxBatchSize, blockWindow }
|
|
2542
2910
|
});
|
|
2543
|
-
let blockNumber =
|
|
2911
|
+
let blockNumber = order2 === "asc" ? blockNumberGte : blockNumberLte;
|
|
2544
2912
|
for await (const { logs, blockNumber: newBlockNumber } of stream) {
|
|
2545
2913
|
blockNumber = newBlockNumber;
|
|
2546
2914
|
if (logs.length === 0) break;
|
|
2547
|
-
|
|
2915
|
+
const offers = [];
|
|
2916
|
+
for (const log of logs) {
|
|
2917
|
+
if (!log) continue;
|
|
2548
2918
|
const [payload] = viem.decodeAbiParameters([{ type: "bytes" }], log.data);
|
|
2549
2919
|
try {
|
|
2550
|
-
|
|
2920
|
+
const tree = Tree_exports.decode(payload);
|
|
2921
|
+
for (const offer of tree.offers) {
|
|
2922
|
+
if (loanToken && offer.loanToken.toLowerCase() !== loanToken.toLowerCase()) continue;
|
|
2923
|
+
offers.push({ ...offer, blockNumber: Number(log.blockNumber) });
|
|
2924
|
+
}
|
|
2551
2925
|
} catch (_) {
|
|
2552
|
-
return null;
|
|
2553
2926
|
}
|
|
2554
|
-
}
|
|
2555
|
-
if (
|
|
2556
|
-
offersAndBlockNumbers = offersAndBlockNumbers.filter(
|
|
2557
|
-
(o) => o.offer.loanToken.toLowerCase() === loanToken.toLowerCase()
|
|
2558
|
-
);
|
|
2559
|
-
if (offersAndBlockNumbers.length === 0) continue;
|
|
2927
|
+
}
|
|
2928
|
+
if (offers.length === 0) continue;
|
|
2560
2929
|
yield {
|
|
2561
|
-
offers
|
|
2930
|
+
offers,
|
|
2562
2931
|
blockNumber
|
|
2563
2932
|
};
|
|
2564
2933
|
}
|
|
@@ -2586,7 +2955,127 @@ var ChainIdMismatchError = class extends BaseError {
|
|
|
2586
2955
|
|
|
2587
2956
|
// src/mempool/MempoolClient.ts
|
|
2588
2957
|
function connect2(parameters) {
|
|
2589
|
-
return
|
|
2958
|
+
return from10(parameters);
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
// src/utils/index.ts
|
|
2962
|
+
var utils_exports = {};
|
|
2963
|
+
__export(utils_exports, {
|
|
2964
|
+
BaseError: () => BaseError,
|
|
2965
|
+
Time: () => time_exports,
|
|
2966
|
+
batch: () => batch,
|
|
2967
|
+
batchMulticall: () => batchMulticall,
|
|
2968
|
+
fromSnakeCase: () => fromSnakeCase,
|
|
2969
|
+
lazy: () => lazy,
|
|
2970
|
+
max: () => max,
|
|
2971
|
+
min: () => min,
|
|
2972
|
+
poll: () => poll,
|
|
2973
|
+
retry: () => retry,
|
|
2974
|
+
stringifyBigint: () => stringifyBigint,
|
|
2975
|
+
toSnakeCase: () => toSnakeCase,
|
|
2976
|
+
wait: () => wait
|
|
2977
|
+
});
|
|
2978
|
+
|
|
2979
|
+
// src/utils/retry.ts
|
|
2980
|
+
var retry = async (fn, attempts = 3, delayMs = 50) => {
|
|
2981
|
+
let lastErr;
|
|
2982
|
+
for (let i = 0; i < attempts; i++) {
|
|
2983
|
+
try {
|
|
2984
|
+
return await fn();
|
|
2985
|
+
} catch (err) {
|
|
2986
|
+
lastErr = err;
|
|
2987
|
+
if (i < attempts - 1) await new Promise((r) => setTimeout(r, delayMs));
|
|
2988
|
+
}
|
|
2989
|
+
}
|
|
2990
|
+
throw lastErr;
|
|
2991
|
+
};
|
|
2992
|
+
|
|
2993
|
+
// src/utils/batchMulticall.ts
|
|
2994
|
+
async function batchMulticall(parameters) {
|
|
2995
|
+
const { client, calls, batchSize, retryAttempts, retryDelayMs, blockNumber } = parameters;
|
|
2996
|
+
const results = [];
|
|
2997
|
+
for (const callsBatch of batch(calls, batchSize)) {
|
|
2998
|
+
const batchResults = await retry(
|
|
2999
|
+
() => client.multicall({
|
|
3000
|
+
allowFailure: false,
|
|
3001
|
+
contracts: callsBatch,
|
|
3002
|
+
...blockNumber ? { blockNumber } : {}
|
|
3003
|
+
}),
|
|
3004
|
+
retryAttempts,
|
|
3005
|
+
retryDelayMs
|
|
3006
|
+
);
|
|
3007
|
+
results.push(...batchResults);
|
|
3008
|
+
}
|
|
3009
|
+
return results;
|
|
3010
|
+
}
|
|
3011
|
+
|
|
3012
|
+
// src/utils/lazy.ts
|
|
3013
|
+
function lazy(pollFn) {
|
|
3014
|
+
return () => async function* () {
|
|
3015
|
+
let active = true;
|
|
3016
|
+
let resolveNext = null;
|
|
3017
|
+
const queue = [];
|
|
3018
|
+
const wait2 = () => new Promise((resolve) => {
|
|
3019
|
+
resolveNext = resolve;
|
|
3020
|
+
});
|
|
3021
|
+
const emit = (item) => {
|
|
3022
|
+
queue.push(item);
|
|
3023
|
+
resolveNext?.();
|
|
3024
|
+
resolveNext = null;
|
|
3025
|
+
};
|
|
3026
|
+
let unpoll = null;
|
|
3027
|
+
const stop = () => {
|
|
3028
|
+
active = false;
|
|
3029
|
+
unpoll?.();
|
|
3030
|
+
resolveNext?.();
|
|
3031
|
+
resolveNext = null;
|
|
3032
|
+
};
|
|
3033
|
+
unpoll = pollFn(emit, { stop });
|
|
3034
|
+
try {
|
|
3035
|
+
while (active) {
|
|
3036
|
+
if (queue.length === 0) await wait2();
|
|
3037
|
+
while (queue.length > 0 && active) yield queue.shift();
|
|
3038
|
+
}
|
|
3039
|
+
} finally {
|
|
3040
|
+
stop();
|
|
3041
|
+
}
|
|
3042
|
+
}();
|
|
3043
|
+
}
|
|
3044
|
+
|
|
3045
|
+
// src/utils/wait.ts
|
|
3046
|
+
async function wait(time) {
|
|
3047
|
+
return new Promise((res) => setTimeout(res, time));
|
|
3048
|
+
}
|
|
3049
|
+
|
|
3050
|
+
// src/utils/poll.ts
|
|
3051
|
+
function poll(fn, { interval }) {
|
|
3052
|
+
let active = true;
|
|
3053
|
+
const unwatch = () => active = false;
|
|
3054
|
+
const watch = async () => {
|
|
3055
|
+
await wait(interval);
|
|
3056
|
+
const poll2 = async () => {
|
|
3057
|
+
if (!active) return;
|
|
3058
|
+
await fn({ unpoll: unwatch });
|
|
3059
|
+
await wait(interval);
|
|
3060
|
+
poll2();
|
|
3061
|
+
};
|
|
3062
|
+
poll2();
|
|
3063
|
+
};
|
|
3064
|
+
watch();
|
|
3065
|
+
return unwatch;
|
|
3066
|
+
}
|
|
3067
|
+
|
|
3068
|
+
// src/utils/time.ts
|
|
3069
|
+
var time_exports = {};
|
|
3070
|
+
__export(time_exports, {
|
|
3071
|
+
max: () => max2,
|
|
3072
|
+
now: () => now
|
|
3073
|
+
});
|
|
3074
|
+
function now() {
|
|
3075
|
+
return Math.floor(Date.now() / 1e3);
|
|
3076
|
+
}
|
|
3077
|
+
function max2() {
|
|
3078
|
+
return 864e16;
|
|
2590
3079
|
}
|
|
2591
3080
|
|
|
2592
3081
|
exports.Abi = Abi_exports;
|
|
@@ -2597,6 +3086,8 @@ exports.Collateral = Collateral_exports;
|
|
|
2597
3086
|
exports.Cursor = Cursor_exports;
|
|
2598
3087
|
exports.Errors = Errors_exports;
|
|
2599
3088
|
exports.Format = Format_exports;
|
|
3089
|
+
exports.GateConfig = GateConfig_exports;
|
|
3090
|
+
exports.Gatekeeper = Gatekeeper_exports;
|
|
2600
3091
|
exports.LLTV = LLTV_exports;
|
|
2601
3092
|
exports.Liquidity = Liquidity_exports;
|
|
2602
3093
|
exports.Maturity = Maturity_exports;
|
|
@@ -2606,9 +3097,10 @@ exports.Offer = Offer_exports;
|
|
|
2606
3097
|
exports.Quote = Quote_exports;
|
|
2607
3098
|
exports.RouterApi = Schema_exports;
|
|
2608
3099
|
exports.RouterClient = Client_exports;
|
|
3100
|
+
exports.Rules = Rules_exports;
|
|
2609
3101
|
exports.Time = time_exports;
|
|
3102
|
+
exports.Tree = Tree_exports;
|
|
2610
3103
|
exports.Utils = utils_exports;
|
|
2611
|
-
exports.Validation =
|
|
2612
|
-
exports.ValidationRule = ValidationRule_exports;
|
|
3104
|
+
exports.Validation = Gate_exports;
|
|
2613
3105
|
//# sourceMappingURL=index.browser.js.map
|
|
2614
3106
|
//# sourceMappingURL=index.browser.js.map
|