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