@morpho-dev/router 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +67 -71
  2. package/dist/cli.js +3209 -1252
  3. package/dist/drizzle/migrations/0017_dusty_the_hunter.sql +1 -0
  4. package/dist/drizzle/migrations/0018_add_chain_collector_constraints.sql +3 -0
  5. package/dist/drizzle/migrations/0019_add-obligation-units-shares.sql +2 -0
  6. package/dist/drizzle/migrations/0020_add-session.sql +1 -0
  7. package/dist/drizzle/migrations/0021_drop_chain_collector_epoch_indexes.sql +2 -0
  8. package/dist/drizzle/migrations/0021_migrate-rate-to-price.sql +15 -0
  9. package/dist/drizzle/migrations/0022_consolidate-price.sql +15 -0
  10. package/dist/drizzle/migrations/meta/0017_snapshot.json +1525 -0
  11. package/dist/drizzle/migrations/meta/0018_snapshot.json +1572 -0
  12. package/dist/drizzle/migrations/meta/0019_snapshot.json +1586 -0
  13. package/dist/drizzle/migrations/meta/_journal.json +42 -0
  14. package/dist/evm/bytecode/erc20.txt +1 -0
  15. package/dist/evm/bytecode/factory.txt +1 -0
  16. package/dist/evm/bytecode/mempool.txt +1 -0
  17. package/dist/evm/bytecode/morpho.txt +1 -0
  18. package/dist/evm/bytecode/multicall3.txt +1 -0
  19. package/dist/evm/bytecode/oracle.txt +1 -0
  20. package/dist/evm/bytecode/terms.txt +1 -0
  21. package/dist/evm/bytecode/vault.txt +1 -0
  22. package/dist/evm/bytecode/vaultV1.txt +1 -0
  23. package/dist/index.browser.d.mts +1327 -816
  24. package/dist/index.browser.d.mts.map +1 -1
  25. package/dist/index.browser.d.ts +1358 -847
  26. package/dist/index.browser.d.ts.map +1 -1
  27. package/dist/index.browser.js +2209 -1668
  28. package/dist/index.browser.js.map +1 -1
  29. package/dist/index.browser.mjs +2173 -1632
  30. package/dist/index.browser.mjs.map +1 -1
  31. package/dist/index.node.d.mts +1885 -1222
  32. package/dist/index.node.d.mts.map +1 -1
  33. package/dist/index.node.d.ts +1885 -1222
  34. package/dist/index.node.d.ts.map +1 -1
  35. package/dist/index.node.js +1984 -1016
  36. package/dist/index.node.js.map +1 -1
  37. package/dist/index.node.mjs +1963 -1014
  38. package/dist/index.node.mjs.map +1 -1
  39. package/docs/integrator.md +78 -0
  40. package/package.json +11 -5
@@ -1,22 +1,21 @@
1
1
  import { t as __export } from "./chunk-jass6xSI.mjs";
2
2
  import { z } from "zod/v4";
3
- import { bytesToHex, decodeAbiParameters, encodeAbiParameters, getAddress, hashMessage, hashTypedData, hexToBytes, isAddress, isHex, keccak256, maxUint256, parseAbi, publicActions, recoverAddress, zeroAddress } from "viem";
4
- import "reflect-metadata";
5
- import { generateDocument } from "openapi-metadata";
6
- import { ApiBody, ApiOperation, ApiProperty, ApiQuery, ApiResponse, ApiTags } from "openapi-metadata/decorators";
7
- import * as z$1 from "zod";
8
- import { Base64 } from "js-base64";
9
- import createOpenApiFetchClient from "openapi-fetch";
3
+ import { bytesToHex, decodeAbiParameters, encodeAbiParameters, getAddress, hashMessage, hashTypedData, hexToBytes, isAddress, isHex, keccak256, maxUint256, numberToHex, pad, parseAbi, publicActions, recoverAddress, zeroAddress } from "viem";
10
4
  import { getBlock, getLogs, multicall } from "viem/actions";
11
5
  import { anvil, base, mainnet } from "viem/chains";
6
+ import * as z$1 from "zod";
12
7
  import { StandardMerkleTree } from "@openzeppelin/merkle-tree";
13
8
  import { gzip, ungzip } from "pako";
9
+ import "reflect-metadata";
10
+ import { generateDocument } from "openapi-metadata";
11
+ import { ApiBody, ApiOperation, ApiParam, ApiProperty, ApiQuery, ApiResponse, ApiTags } from "openapi-metadata/decorators";
12
+ import createOpenApiFetchClient from "openapi-fetch";
14
13
 
15
14
  //#region src/api/Schema/BookResponse.ts
16
- var BookResponse_exports = /* @__PURE__ */ __export({ from: () => from$13 });
17
- function from$13(level) {
15
+ var BookResponse_exports = /* @__PURE__ */ __export({ from: () => from$14 });
16
+ function from$14(level) {
18
17
  return {
19
- rate: level.rate.toString(),
18
+ price: level.price.toString(),
20
19
  assets: level.assets.toString(),
21
20
  count: level.count
22
21
  };
@@ -34,1076 +33,127 @@ const CollectorHealth = z.object({
34
33
  "live",
35
34
  "lagging",
36
35
  "unknown"
37
- ])
36
+ ]),
37
+ initialized: z.boolean()
38
38
  });
39
39
  const CollectorsHealthResponse = z.array(CollectorHealth);
40
40
  const ChainHealth = z.object({
41
41
  chain_id: z.number(),
42
- local_block_number: z.number(),
42
+ local_block_number: z.number().nullable(),
43
43
  remote_block_number: z.number().nullable(),
44
- updated_at: z.string()
44
+ updated_at: z.string().nullable(),
45
+ initialized: z.boolean()
45
46
  });
46
47
  const ChainsHealthResponse = z.array(ChainHealth);
47
- const RouterStatusResponse = z.object({ status: z.enum(["live", "syncing"]) });
48
-
49
- //#endregion
50
- //#region src/utils/Format.ts
51
- var Format_exports = /* @__PURE__ */ __export({
52
- fromSnakeCase: () => fromSnakeCase$3,
53
- stringifyBigint: () => stringifyBigint,
54
- toSnakeCase: () => toSnakeCase$1
48
+ const RouterStatusResponse = z.object({
49
+ status: z.enum(["live", "syncing"]),
50
+ initialized: z.boolean(),
51
+ missing_chains: z.array(z.number()),
52
+ missing_collectors: z.array(z.object({
53
+ chain_id: z.number(),
54
+ name: z.string()
55
+ }))
55
56
  });
56
- /**
57
- * Formats object keys to snake case.
58
- * Preserves ethereum addresses as is.
59
- * Converts ethereum addresses to checksummed if used as values.
60
- * Stringifies bigint values to strings.
61
- */
62
- function toSnakeCase$1(obj) {
63
- return stringifyBigint(processObject(obj, (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`), (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? getAddress(value.toLowerCase()) : value));
64
- }
65
- /**
66
- * Formats a snake case object to its camel case type.
67
- * Preserves ethereum addresses as is.
68
- * Converts checksummed ethereum addresses to lowercase if used as values.
69
- * @warning Does not unstringify bigint values.
70
- */
71
- function fromSnakeCase$3(obj) {
72
- return processObject(obj, (s) => isAddress(s.toLowerCase()) ? s : s.replace(/_([a-z])/g, (_, c) => c.toUpperCase()), (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? value.toLowerCase() : value);
73
- }
74
- function processObject(obj, fnKey, fnValue) {
75
- if (typeof obj !== "object" || obj === null) return obj;
76
- if (Array.isArray(obj)) return obj.map((item) => processObject(item, fnKey, fnValue));
77
- return Object.entries(obj).reduce((acc, [key, value]) => {
78
- const newKey = fnKey(key);
79
- acc[newKey] = typeof value === "object" && value !== null ? processObject(value, fnKey, fnValue) : fnValue(value);
80
- return acc;
81
- }, {});
82
- }
83
- function stringifyBigint(value) {
84
- if (typeof value === "bigint") return value.toString();
85
- if (Array.isArray(value)) return value.map(stringifyBigint);
86
- if (value && typeof value === "object") {
87
- const out = {};
88
- for (const [k, v] of Object.entries(value)) out[k] = stringifyBigint(v);
89
- return out;
90
- }
91
- return value;
92
- }
93
57
 
94
58
  //#endregion
95
59
  //#region src/api/Schema/ObligationResponse.ts
96
- var ObligationResponse_exports = /* @__PURE__ */ __export({ from: () => from$12 });
60
+ var ObligationResponse_exports = /* @__PURE__ */ __export({ from: () => from$13 });
97
61
  /**
98
62
  * Creates an `ObligationResponse` from a `Obligation`.
99
63
  * @constructor
100
64
  * @param obligation - {@link Obligation}
101
65
  * @returns The created `ObligationResponse`. {@link ObligationResponse}
102
66
  */
103
- function from$12(obligation, quote) {
104
- return toSnakeCase$1({
105
- id: quote.obligationId,
106
- ...obligation,
107
- ask: quote.ask,
108
- bid: quote.bid
109
- });
110
- }
111
-
112
- //#endregion
113
- //#region src/api/Schema/OfferResponse.ts
114
- var OfferResponse_exports = /* @__PURE__ */ __export({ from: () => from$11 });
115
- /**
116
- * Creates an `OfferResponse` from an `Offer`.
117
- * @constructor
118
- * @param offer - {@link Offer}
119
- * @param attestation - {@link Attestation}
120
- * @returns The created `OfferResponse`. {@link OfferResponse}
121
- */
122
- function from$11(offer, attestation) {
123
- const { signature: _, ...rest } = toSnakeCase$1(offer);
67
+ function from$13(obligation, quote) {
124
68
  return {
125
- ...rest,
126
- root: attestation?.root.toLowerCase() ?? null,
127
- proof: attestation?.proof.map((p) => p.toLowerCase()) ?? null,
128
- signature: attestation?.signature.toLowerCase() ?? null
69
+ id: quote.obligationId,
70
+ chain_id: obligation.chainId,
71
+ loan_token: obligation.loanToken,
72
+ collaterals: obligation.collaterals.map((c) => ({
73
+ token: c.asset,
74
+ lltv: c.lltv.toString(),
75
+ oracle: c.oracle
76
+ })),
77
+ maturity: obligation.maturity,
78
+ ask: { price: quote.ask.price.toString() },
79
+ bid: { price: quote.bid.price.toString() }
129
80
  };
130
81
  }
131
82
 
132
83
  //#endregion
133
- //#region src/api/Controllers/Payload.ts
134
- const API_ERROR_CODES = [
135
- "VALIDATION_ERROR",
136
- "NOT_FOUND",
137
- "INTERNAL_SERVER_ERROR",
138
- "BAD_REQUEST"
139
- ];
84
+ //#region src/core/Abi/MetaMorpho.ts
85
+ const MetaMorpho = parseAbi([
86
+ "function balanceOf(address account) view returns (uint256)",
87
+ "function DECIMALS_OFFSET() view returns (uint8)",
88
+ "function totalAssets() view returns (uint256)",
89
+ "function totalSupply() view returns (uint256)",
90
+ "function maxWithdraw(address owner) view returns (uint256 assets)",
91
+ "function asset() view returns (address)",
92
+ "event Transfer(address indexed from, address indexed to, uint256 value)",
93
+ "function withdrawQueue(uint256 index) view returns (bytes32)",
94
+ "function withdrawQueueLength() view returns (uint256)"
95
+ ]);
140
96
 
141
97
  //#endregion
142
- //#region \0@oxc-project+runtime@0.97.0/helpers/decorate.js
143
- function __decorate(decorators, target, key, desc) {
144
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
145
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
146
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
147
- return c > 3 && r && Object.defineProperty(target, key, r), r;
148
- }
98
+ //#region src/core/Abi/MetaMorphoFactory.ts
99
+ const MetaMorphoFactory = parseAbi(["event CreateMetaMorpho(address indexed metaMorpho,address indexed caller,address initialOwner,uint256 initialTimelock,address indexed asset,string name,string symbol,bytes32 salt)", "function isMetaMorpho(address) view returns (bool)"]);
149
100
 
150
101
  //#endregion
151
- //#region src/api/Schema/openapi.ts
152
- const timestampExample = "2024-01-01T12:00:00.000Z";
153
- const offerCursorExample = "eyJvZmZzZXQiOjEwMH0";
154
- const obligationCursorExample = "0x25690ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9abc";
155
- const offerExample = {
156
- hash: "0xac4bd8318ec914f89f8af913f162230575b0ac0696a19256bc12138c5cfe1427",
157
- offering: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
158
- assets: "369216000000000000000000",
159
- rate: "2750000000000000000",
160
- maturity: 1761922799,
161
- expiry: 1761922799,
162
- start: 1761922790,
163
- nonce: "571380",
164
- buy: false,
165
- chain_id: 1,
166
- loan_token: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
167
- collaterals: [{
168
- asset: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
169
- oracle: "0x45093658BE7f90B63D7c359e8f408e503c2D9401",
170
- lltv: "860000000000000000"
102
+ //#region src/core/Abi/index.ts
103
+ var Abi_exports = /* @__PURE__ */ __export({
104
+ ERC4626: () => ERC4626,
105
+ MetaMorpho: () => MetaMorpho,
106
+ MetaMorphoFactory: () => MetaMorphoFactory,
107
+ Morpho: () => Morpho,
108
+ Oracle: () => Oracle
109
+ });
110
+ const Oracle = [{
111
+ type: "function",
112
+ name: "price",
113
+ inputs: [],
114
+ outputs: [{
115
+ name: "",
116
+ type: "uint256"
171
117
  }],
172
- callback: {
173
- address: "0x1111111111111111111111111111111111111111",
174
- data: "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000034cf890db685fc536e05652fb41f02090c3fb751000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000108e644e3ab01184155270aa92a00000000000",
175
- gas_limit: "500000"
176
- },
177
- consumed: "0",
178
- takeable: "369216000000000000000000",
179
- block_number: 0xa7495128adfb1,
180
- root: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
181
- proof: ["0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "0x9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba"],
182
- signature: "0x1234567890123456789012345678901234567890123456789012345678901234123456789012345678901234567890123456789012345678901234567890123400"
183
- };
184
- const collectorsHealthExample = {
185
- name: "offers",
186
- chain_id: 1,
187
- block_number: 21345678,
188
- updated_at: timestampExample,
189
- lag: 0,
190
- status: "live"
191
- };
192
- const chainsHealthExample = {
193
- chain_id: 1,
194
- local_block_number: 21345678,
195
- remote_block_number: 21345690,
196
- updated_at: timestampExample
197
- };
198
- const routerStatusExample = { status: "live" };
199
- var Meta = class {};
200
- __decorate([ApiProperty({
201
- type: "string",
202
- example: timestampExample
203
- })], Meta.prototype, "timestamp", void 0);
204
- var SuccessResponse = class {};
205
- __decorate([ApiProperty({ type: () => Meta })], SuccessResponse.prototype, "meta", void 0);
206
- var ErrorResponse = class {};
207
- __decorate([ApiProperty({
208
- type: "string",
209
- enum: API_ERROR_CODES,
210
- example: "VALIDATION_ERROR"
211
- })], ErrorResponse.prototype, "code", void 0);
212
- __decorate([ApiProperty({
213
- type: "string",
214
- example: "Limit must be greater than 0."
215
- })], ErrorResponse.prototype, "message", void 0);
216
- __decorate([ApiProperty({
217
- type: "object",
218
- example: [{
219
- field: "limit",
220
- issue: "Limit must be greater than 0."
221
- }]
222
- })], ErrorResponse.prototype, "details", void 0);
223
- var BadRequestResponse = class {};
224
- __decorate([ApiProperty({ type: () => ErrorResponse })], BadRequestResponse.prototype, "error", void 0);
225
- __decorate([ApiProperty({ type: () => Meta })], BadRequestResponse.prototype, "meta", void 0);
226
- var CollateralResponse = class {};
227
- __decorate([ApiProperty({
228
- type: "string",
229
- example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751"
230
- })], CollateralResponse.prototype, "asset", void 0);
231
- __decorate([ApiProperty({
232
- type: "string",
233
- example: "0x45093658BE7f90B63D7c359e8f408e503c2D9401"
234
- })], CollateralResponse.prototype, "oracle", void 0);
235
- __decorate([ApiProperty({
236
- type: "string",
237
- example: "860000000000000000"
238
- })], CollateralResponse.prototype, "lltv", void 0);
239
- var AskResponse = class {};
240
- __decorate([ApiProperty({
241
- type: "string",
242
- example: "1000000000000000000"
243
- })], AskResponse.prototype, "rate", void 0);
244
- var BidResponse = class {};
245
- __decorate([ApiProperty({
246
- type: "string",
247
- example: "1000000000000000000"
248
- })], BidResponse.prototype, "rate", void 0);
249
- var OfferCallbackResponse = class {};
250
- __decorate([ApiProperty({
251
- type: "string",
252
- example: offerExample.callback.address
253
- })], OfferCallbackResponse.prototype, "address", void 0);
254
- __decorate([ApiProperty({
255
- type: "string",
256
- example: offerExample.callback.data
257
- })], OfferCallbackResponse.prototype, "data", void 0);
258
- __decorate([ApiProperty({
259
- type: "string",
260
- example: offerExample.callback.gas_limit
261
- })], OfferCallbackResponse.prototype, "gas_limit", void 0);
262
- var OfferListItemResponse = class {};
263
- __decorate([ApiProperty({
264
- type: "string",
265
- example: offerExample.hash
266
- })], OfferListItemResponse.prototype, "hash", void 0);
267
- __decorate([ApiProperty({
268
- type: "string",
269
- example: offerExample.offering
270
- })], OfferListItemResponse.prototype, "offering", void 0);
271
- __decorate([ApiProperty({
272
- type: "string",
273
- example: offerExample.assets
274
- })], OfferListItemResponse.prototype, "assets", void 0);
275
- __decorate([ApiProperty({
276
- type: "string",
277
- example: offerExample.rate
278
- })], OfferListItemResponse.prototype, "rate", void 0);
279
- __decorate([ApiProperty({
280
- type: "number",
281
- example: offerExample.maturity
282
- })], OfferListItemResponse.prototype, "maturity", void 0);
283
- __decorate([ApiProperty({
284
- type: "number",
285
- example: offerExample.expiry
286
- })], OfferListItemResponse.prototype, "expiry", void 0);
287
- __decorate([ApiProperty({
288
- type: "number",
289
- example: offerExample.start
290
- })], OfferListItemResponse.prototype, "start", void 0);
291
- __decorate([ApiProperty({
292
- type: "string",
293
- example: offerExample.nonce
294
- })], OfferListItemResponse.prototype, "nonce", void 0);
295
- __decorate([ApiProperty({
296
- type: "boolean",
297
- example: offerExample.buy
298
- })], OfferListItemResponse.prototype, "buy", void 0);
299
- __decorate([ApiProperty({
300
- type: "number",
301
- example: offerExample.chain_id
302
- })], OfferListItemResponse.prototype, "chain_id", void 0);
303
- __decorate([ApiProperty({
304
- type: "string",
305
- example: offerExample.loan_token
306
- })], OfferListItemResponse.prototype, "loan_token", void 0);
307
- __decorate([ApiProperty({
308
- type: () => [CollateralResponse],
309
- example: offerExample.collaterals
310
- })], OfferListItemResponse.prototype, "collaterals", void 0);
311
- __decorate([ApiProperty({
312
- type: () => OfferCallbackResponse,
313
- example: offerExample.callback
314
- })], OfferListItemResponse.prototype, "callback", void 0);
315
- __decorate([ApiProperty({
316
- type: "string",
317
- example: offerExample.takeable
318
- })], OfferListItemResponse.prototype, "takeable", void 0);
319
- __decorate([ApiProperty({
320
- type: "string",
321
- example: offerExample.consumed
322
- })], OfferListItemResponse.prototype, "consumed", void 0);
323
- __decorate([ApiProperty({
324
- type: "number",
325
- example: offerExample.block_number
326
- })], OfferListItemResponse.prototype, "block_number", void 0);
327
- __decorate([ApiProperty({
328
- type: "string",
329
- nullable: true,
330
- example: offerExample.root
331
- })], OfferListItemResponse.prototype, "root", void 0);
332
- __decorate([ApiProperty({
333
- type: [String],
334
- nullable: true,
335
- example: offerExample.proof
336
- })], OfferListItemResponse.prototype, "proof", void 0);
337
- __decorate([ApiProperty({
338
- type: "string",
339
- nullable: true,
340
- example: offerExample.signature
341
- })], OfferListItemResponse.prototype, "signature", void 0);
342
- var ObligationResponse = class {};
343
- __decorate([ApiProperty({
344
- type: "string",
345
- example: "0x12590ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9f67"
346
- })], ObligationResponse.prototype, "id", void 0);
347
- __decorate([ApiProperty({
348
- type: "number",
349
- example: 1
350
- })], ObligationResponse.prototype, "chain_id", void 0);
351
- __decorate([ApiProperty({
352
- type: "string",
353
- example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078"
354
- })], ObligationResponse.prototype, "loan_token", void 0);
355
- __decorate([ApiProperty({ type: () => [CollateralResponse] })], ObligationResponse.prototype, "collaterals", void 0);
356
- __decorate([ApiProperty({
357
- type: "number",
358
- example: 1761922800
359
- })], ObligationResponse.prototype, "maturity", void 0);
360
- __decorate([ApiProperty({ type: () => AskResponse })], ObligationResponse.prototype, "ask", void 0);
361
- __decorate([ApiProperty({ type: () => BidResponse })], ObligationResponse.prototype, "bid", void 0);
362
- var ObligationListResponse = class extends SuccessResponse {};
363
- __decorate([ApiProperty({
364
- type: "string",
365
- nullable: true,
366
- example: obligationCursorExample
367
- })], ObligationListResponse.prototype, "cursor", void 0);
368
- __decorate([ApiProperty({
369
- type: () => [ObligationResponse],
370
- description: "List of obligations with takable offers."
371
- })], ObligationListResponse.prototype, "data", void 0);
372
- var ObligationSingleSuccessResponse = class extends SuccessResponse {};
373
- __decorate([ApiProperty({
374
- type: "string",
375
- nullable: true,
376
- example: null
377
- })], ObligationSingleSuccessResponse.prototype, "cursor", void 0);
378
- __decorate([ApiProperty({
379
- type: () => ObligationResponse,
380
- description: "Obligation details."
381
- })], ObligationSingleSuccessResponse.prototype, "data", void 0);
382
- var OfferListResponse = class extends SuccessResponse {};
383
- __decorate([ApiProperty({
384
- type: "string",
385
- nullable: true,
386
- example: offerCursorExample
387
- })], OfferListResponse.prototype, "cursor", void 0);
388
- __decorate([ApiProperty({
389
- type: () => [OfferListItemResponse],
390
- description: "Offers matching the provided filters.",
391
- example: [offerExample]
392
- })], OfferListResponse.prototype, "data", void 0);
393
- var RouterStatusDataResponse = class {};
394
- __decorate([ApiProperty({
395
- type: "string",
396
- enum: ["live", "syncing"],
397
- example: routerStatusExample.status
398
- })], RouterStatusDataResponse.prototype, "status", void 0);
399
- var RouterStatusSuccessResponse = class extends SuccessResponse {};
400
- __decorate([ApiProperty({
401
- type: () => RouterStatusDataResponse,
402
- description: "Aggregated router status.",
403
- example: routerStatusExample
404
- })], RouterStatusSuccessResponse.prototype, "data", void 0);
405
- var CollectorHealthResponse = class {};
406
- __decorate([ApiProperty({
407
- type: "string",
408
- example: collectorsHealthExample.name
409
- })], CollectorHealthResponse.prototype, "name", void 0);
410
- __decorate([ApiProperty({
411
- type: "number",
412
- example: collectorsHealthExample.chain_id
413
- })], CollectorHealthResponse.prototype, "chain_id", void 0);
414
- __decorate([ApiProperty({
415
- type: "number",
416
- nullable: true,
417
- example: collectorsHealthExample.block_number
418
- })], CollectorHealthResponse.prototype, "block_number", void 0);
419
- __decorate([ApiProperty({
420
- type: "string",
421
- nullable: true,
422
- example: collectorsHealthExample.updated_at
423
- })], CollectorHealthResponse.prototype, "updated_at", void 0);
424
- __decorate([ApiProperty({
425
- type: "number",
426
- nullable: true,
427
- example: collectorsHealthExample.lag
428
- })], CollectorHealthResponse.prototype, "lag", void 0);
429
- __decorate([ApiProperty({
430
- type: "string",
431
- enum: [
432
- "live",
433
- "lagging",
434
- "unknown"
435
- ],
436
- example: collectorsHealthExample.status
437
- })], CollectorHealthResponse.prototype, "status", void 0);
438
- var CollectorsHealthSuccessResponse = class extends SuccessResponse {};
439
- __decorate([ApiProperty({
440
- type: () => [CollectorHealthResponse],
441
- description: "Collectors health details and sync status.",
442
- example: [collectorsHealthExample]
443
- })], CollectorsHealthSuccessResponse.prototype, "data", void 0);
444
- var ChainHealthResponse = class {};
445
- __decorate([ApiProperty({
446
- type: "number",
447
- example: chainsHealthExample.chain_id
448
- })], ChainHealthResponse.prototype, "chain_id", void 0);
449
- __decorate([ApiProperty({
450
- type: "number",
451
- example: chainsHealthExample.local_block_number
452
- })], ChainHealthResponse.prototype, "local_block_number", void 0);
453
- __decorate([ApiProperty({
454
- type: "number",
455
- nullable: true,
456
- example: chainsHealthExample.remote_block_number
457
- })], ChainHealthResponse.prototype, "remote_block_number", void 0);
458
- __decorate([ApiProperty({
459
- type: "string",
460
- example: chainsHealthExample.updated_at
461
- })], ChainHealthResponse.prototype, "updated_at", void 0);
462
- var ChainsHealthSuccessResponse = class extends SuccessResponse {};
463
- __decorate([ApiProperty({
464
- type: () => [ChainHealthResponse],
465
- description: "Latest processed block per chain.",
466
- example: [chainsHealthExample]
467
- })], ChainsHealthSuccessResponse.prototype, "data", void 0);
468
- var ValidateOfferRequest = class {};
469
- __decorate([ApiProperty({
470
- type: "string",
471
- example: offerExample.offering
472
- })], ValidateOfferRequest.prototype, "offering", void 0);
473
- __decorate([ApiProperty({
474
- type: "string",
475
- example: offerExample.assets
476
- })], ValidateOfferRequest.prototype, "assets", void 0);
477
- __decorate([ApiProperty({
478
- type: "string",
479
- example: offerExample.rate
480
- })], ValidateOfferRequest.prototype, "rate", void 0);
481
- __decorate([ApiProperty({
482
- type: "number",
483
- example: offerExample.maturity
484
- })], ValidateOfferRequest.prototype, "maturity", void 0);
485
- __decorate([ApiProperty({
486
- type: "number",
487
- example: offerExample.expiry
488
- })], ValidateOfferRequest.prototype, "expiry", void 0);
489
- __decorate([ApiProperty({
490
- type: "number",
491
- example: offerExample.start
492
- })], ValidateOfferRequest.prototype, "start", void 0);
493
- __decorate([ApiProperty({
494
- type: "string",
495
- example: offerExample.nonce
496
- })], ValidateOfferRequest.prototype, "nonce", void 0);
497
- __decorate([ApiProperty({
498
- type: "boolean",
499
- example: offerExample.buy
500
- })], ValidateOfferRequest.prototype, "buy", void 0);
501
- __decorate([ApiProperty({
502
- type: "number",
503
- example: offerExample.chain_id
504
- })], ValidateOfferRequest.prototype, "chain_id", void 0);
505
- __decorate([ApiProperty({
506
- type: "string",
507
- example: offerExample.loan_token
508
- })], ValidateOfferRequest.prototype, "loan_token", void 0);
509
- __decorate([ApiProperty({
510
- type: () => [CollateralResponse],
511
- example: offerExample.collaterals
512
- })], ValidateOfferRequest.prototype, "collaterals", void 0);
513
- __decorate([ApiProperty({
514
- type: () => OfferCallbackResponse,
515
- example: offerExample.callback
516
- })], ValidateOfferRequest.prototype, "callback", void 0);
517
- var ValidateOffersRequest = class {};
518
- __decorate([ApiProperty({
519
- type: () => [ValidateOfferRequest],
520
- description: "Array of offers in snake_case format. Required, non-empty.",
521
- required: true
522
- })], ValidateOffersRequest.prototype, "offers", void 0);
523
- var ValidationSuccessDataResponse = class {};
524
- __decorate([ApiProperty({
525
- type: "string",
526
- description: "Unsigned payload: version (1B) + gzip(offers) + root (32B).",
527
- example: "0x01789c..."
528
- })], ValidationSuccessDataResponse.prototype, "payload", void 0);
529
- __decorate([ApiProperty({
530
- type: "string",
531
- description: "Merkle tree root to sign with EIP-191.",
532
- example: "0xac4bd8318ec914f89f8af913f162230575b0ac0696a19256bc12138c5cfe1427"
533
- })], ValidationSuccessDataResponse.prototype, "root", void 0);
534
- var ValidationSuccessResponse = class extends SuccessResponse {};
535
- __decorate([ApiProperty({
536
- type: "string",
537
- nullable: true,
538
- example: null
539
- })], ValidationSuccessResponse.prototype, "cursor", void 0);
540
- __decorate([ApiProperty({
541
- type: () => ValidationSuccessDataResponse,
542
- description: "Payload and root for client-side signing."
543
- })], ValidationSuccessResponse.prototype, "data", void 0);
544
- var ValidationIssueResponse = class {};
545
- __decorate([ApiProperty({
546
- type: "number",
547
- description: "0-indexed position of the failed offer in the request array.",
548
- example: 0
549
- })], ValidationIssueResponse.prototype, "index", void 0);
550
- __decorate([ApiProperty({
551
- type: "string",
552
- description: "Gatekeeper rule name that rejected the offer.",
553
- example: "no_buy"
554
- })], ValidationIssueResponse.prototype, "rule", void 0);
555
- __decorate([ApiProperty({
556
- type: "string",
557
- description: "Human-readable rejection reason.",
558
- example: "Buy offers are not supported"
559
- })], ValidationIssueResponse.prototype, "message", void 0);
560
- var ValidationFailureDataResponse = class {};
561
- __decorate([ApiProperty({
562
- type: () => [ValidationIssueResponse],
563
- description: "List of validation issues. Returned when any offer fails validation."
564
- })], ValidationFailureDataResponse.prototype, "issues", void 0);
565
- var ValidationFailureResponse = class extends SuccessResponse {};
566
- __decorate([ApiProperty({
567
- type: "string",
568
- nullable: true,
569
- example: null
570
- })], ValidationFailureResponse.prototype, "cursor", void 0);
571
- __decorate([ApiProperty({
572
- type: () => ValidationFailureDataResponse,
573
- description: "List of validation issues. Returned when any offer fails validation."
574
- })], ValidationFailureResponse.prototype, "data", void 0);
575
- var BookLevelResponse = class {};
576
- __decorate([ApiProperty({
577
- type: "string",
578
- example: "2750000000000000000"
579
- })], BookLevelResponse.prototype, "rate", void 0);
580
- __decorate([ApiProperty({
581
- type: "string",
582
- example: "369216000000000000000000"
583
- })], BookLevelResponse.prototype, "assets", void 0);
584
- __decorate([ApiProperty({
585
- type: "number",
586
- example: 5
587
- })], BookLevelResponse.prototype, "count", void 0);
588
- var BookListResponse = class extends SuccessResponse {};
589
- __decorate([ApiProperty({
590
- type: "string",
591
- nullable: true,
592
- example: offerCursorExample
593
- })], BookListResponse.prototype, "cursor", void 0);
594
- __decorate([ApiProperty({
595
- type: () => [BookLevelResponse],
596
- description: "Aggregated book levels grouped by rate."
597
- })], BookListResponse.prototype, "data", void 0);
598
- let BooksController = class BooksController$1 {
599
- async getBook() {}
600
- };
601
- __decorate([
602
- ApiOperation({
603
- methods: ["get"],
604
- path: "/v1/books/{obligationId}/{side}",
605
- summary: "Get aggregated book",
606
- description: "Returns aggregated book data for a given obligation and side. Offers are grouped by rate with summed takeable amounts. Book levels are sorted by rate (ascending for buy side, descending for sell side)."
607
- }),
608
- ApiQuery({
609
- name: "cursor",
610
- type: "string",
611
- example: offerCursorExample,
612
- description: "Pagination cursor in base64url-encoded format."
613
- }),
614
- ApiQuery({
615
- name: "limit",
616
- type: "number",
617
- example: 10,
618
- description: "Maximum number of rate levels to return."
619
- }),
620
- ApiResponse({
621
- status: 200,
622
- description: "Success",
623
- type: BookListResponse
624
- })
625
- ], BooksController.prototype, "getBook", null);
626
- BooksController = __decorate([ApiTags("Books"), ApiResponse({
627
- status: 400,
628
- description: "Bad Request",
629
- type: BadRequestResponse
630
- })], BooksController);
631
- let ValidateController = class ValidateController$1 {
632
- async validateOffers() {}
633
- };
634
- __decorate([
635
- ApiOperation({
636
- methods: ["post"],
637
- path: "/v1/validate",
638
- summary: "Validate offers",
639
- description: "Validates offers against router validation rules. Returns unsigned payload + root on success, or issues only on validation failure."
640
- }),
641
- ApiBody({ type: ValidateOffersRequest }),
642
- ApiResponse({
643
- status: 200,
644
- description: "Success",
645
- type: ValidationSuccessResponse
646
- }),
647
- ApiResponse({
648
- status: 200,
649
- description: "Validation issues",
650
- type: ValidationFailureResponse
651
- })
652
- ], ValidateController.prototype, "validateOffers", null);
653
- ValidateController = __decorate([ApiTags("Validate"), ApiResponse({
654
- status: 400,
655
- description: "Bad Request",
656
- type: BadRequestResponse
657
- })], ValidateController);
658
- let OffersController = class OffersController$1 {
659
- async getOffers() {}
660
- };
661
- __decorate([
662
- ApiOperation({
663
- methods: ["get"],
664
- path: "/v1/offers",
665
- summary: "List all offers",
666
- description: "Returns offers. Provide either `obligation_id` + `side` (order book) or `offering` (by maker)."
667
- }),
668
- ApiQuery({
669
- name: "side",
670
- type: "string",
671
- required: false,
672
- enum: ["buy", "sell"],
673
- example: "buy",
674
- description: "Side of the offer. Required when using obligation_id."
675
- }),
676
- ApiQuery({
677
- name: "obligation_id",
678
- type: "string",
679
- required: false,
680
- example: "0x1234567890123456789012345678901234567890123456789012345678901234",
681
- description: "Obligation id used to filter offers. Required when not using offering."
682
- }),
683
- ApiQuery({
684
- name: "offering",
685
- type: "string",
686
- required: false,
687
- example: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
688
- description: "Maker address to filter offers by. Alternative to obligation_id + side."
689
- }),
690
- ApiQuery({
691
- name: "cursor",
692
- type: "string",
693
- example: offerCursorExample,
694
- description: "Pagination cursor in base64url-encoded format."
695
- }),
696
- ApiQuery({
697
- name: "limit",
698
- type: "number",
699
- example: 10,
700
- description: "Maximum number of offers to return."
701
- }),
702
- ApiResponse({
703
- status: 200,
704
- description: "Success",
705
- type: OfferListResponse
706
- })
707
- ], OffersController.prototype, "getOffers", null);
708
- OffersController = __decorate([ApiTags("Offers"), ApiResponse({
709
- status: 400,
710
- description: "Bad Request",
711
- type: BadRequestResponse
712
- })], OffersController);
713
- let HealthController = class HealthController$1 {
714
- async getRouterStatus() {}
715
- async getCollectorsHealth() {}
716
- async getChainsHealth() {}
717
- };
718
- __decorate([ApiOperation({
719
- methods: ["get"],
720
- path: "/v1/health",
721
- summary: "Retrieve global health",
722
- description: "Returns the aggregated status of the router."
723
- }), ApiResponse({
724
- status: 200,
725
- description: "Success",
726
- type: RouterStatusSuccessResponse
727
- })], HealthController.prototype, "getRouterStatus", null);
728
- __decorate([ApiOperation({
729
- methods: ["get"],
730
- path: "/v1/health/collectors",
731
- summary: "Retrieve collectors health",
732
- description: "Returns the latest block numbers processed by collectors and their sync status."
733
- }), ApiResponse({
734
- status: 200,
735
- description: "Success",
736
- type: CollectorsHealthSuccessResponse
737
- })], HealthController.prototype, "getCollectorsHealth", null);
738
- __decorate([ApiOperation({
739
- methods: ["get"],
740
- path: "/v1/health/chains",
741
- summary: "Retrieve chains health",
742
- description: "Returns the latest block that can be processed by collectors for each chain."
743
- }), ApiResponse({
744
- status: 200,
745
- description: "Success",
746
- type: ChainsHealthSuccessResponse
747
- })], HealthController.prototype, "getChainsHealth", null);
748
- HealthController = __decorate([ApiTags("Health")], HealthController);
749
- let ObligationsController = class ObligationsController$1 {
750
- async getObligations() {}
751
- async getObligation() {}
752
- };
753
- __decorate([
754
- ApiOperation({
755
- methods: ["get"],
756
- path: "/v1/obligations",
757
- summary: "List all obligations",
758
- description: "Returns a list of obligations with their current best ask and bid. Obligations are sorted by their id in ascending order by default."
759
- }),
760
- ApiQuery({
761
- name: "cursor",
762
- type: "string",
763
- example: obligationCursorExample
764
- }),
765
- ApiQuery({
766
- name: "limit",
767
- type: "number",
768
- example: 10
769
- }),
770
- ApiResponse({
771
- status: 200,
772
- description: "Success",
773
- type: ObligationListResponse
774
- })
775
- ], ObligationsController.prototype, "getObligations", null);
776
- __decorate([ApiOperation({
777
- methods: ["get"],
778
- path: "/v1/obligations/{obligationId}",
779
- summary: "Get an obligation",
780
- description: "Returns an obligation by its id."
781
- }), ApiResponse({
782
- status: 200,
783
- description: "Success",
784
- type: ObligationSingleSuccessResponse
785
- })], ObligationsController.prototype, "getObligation", null);
786
- ObligationsController = __decorate([ApiTags("Obligations"), ApiResponse({
787
- status: 400,
788
- description: "Bad Request",
789
- type: BadRequestResponse
790
- })], ObligationsController);
791
- const OpenApi = async (options = {}) => {
792
- const document = await generateDocument({
793
- controllers: [
794
- BooksController,
795
- OffersController,
796
- ObligationsController,
797
- HealthController,
798
- ValidateController
799
- ],
800
- document: {
801
- openapi: "3.1.0",
802
- info: {
803
- title: "Router API",
804
- version: "1.0.0",
805
- description: "API for the Morpho Router"
806
- },
807
- servers: [{
808
- url: "https://router.morpho.dev",
809
- description: "Production server"
810
- }, {
811
- url: "http://localhost:7891",
812
- description: "Local development server"
813
- }]
814
- }
815
- });
816
- if (options.rules && options.rules.length > 0) {
817
- const rulesDescription = options.rules.map((rule) => `- **${rule.name}**: ${rule.description}`).join("\n");
818
- const validatePath = document.paths?.["/v1/validate"];
819
- if (validatePath && "post" in validatePath && validatePath.post) validatePath.post.description = `Validates offers against router validation rules. Returns unsigned payload + root on success, or issues only on validation failure.\n\n**Available validation rules:**\n${rulesDescription}`;
820
- }
821
- return document;
822
- };
823
-
824
- //#endregion
825
- //#region src/database/utils/Cursor.ts
826
- var Cursor_exports = /* @__PURE__ */ __export({
827
- decode: () => decode$3,
828
- encode: () => encode$3,
829
- validate: () => validate
830
- });
831
- const isSort = (value) => {
832
- return [
833
- "rate",
834
- "maturity",
835
- "expiry",
836
- "amount"
837
- ].includes(value);
838
- };
839
- function validate(cursor) {
840
- if (!cursor || typeof cursor !== "object") throw new Error("Cursor must be an object");
841
- const c = cursor;
842
- const sort = c.sort;
843
- const dir = c.dir;
844
- const hash$1 = c.hash;
845
- if (typeof sort !== "string" || !isSort(sort)) throw new Error(`Invalid sort field: ${String(sort)}. Must be one of: rate, maturity, expiry, amount`);
846
- if (typeof dir !== "string" || !["asc", "desc"].includes(dir)) throw new Error(`Invalid direction: ${String(dir)}. Must be one of: asc, desc`);
847
- if (typeof hash$1 !== "string" || !/^0x[a-fA-F0-9]{64}$/.test(hash$1)) throw new Error(`Invalid hash format: ${String(hash$1)}. Must be a 64-character hex string starting with 0x`);
848
- const validation = {
849
- rate: {
850
- field: "rate",
851
- type: "string",
852
- pattern: /^\d+$/,
853
- error: "numeric string"
854
- },
855
- amount: {
856
- field: "assets",
857
- type: "string",
858
- pattern: /^\d+$/,
859
- error: "numeric string"
860
- },
861
- maturity: {
862
- field: "maturity",
863
- type: "number",
864
- min: 1,
865
- error: "positive number"
866
- },
867
- expiry: {
868
- field: "expiry",
869
- type: "number",
870
- min: 1,
871
- error: "positive number"
872
- }
873
- }[sort];
874
- if (!validation) throw new Error(`Invalid sort field: ${sort}`);
875
- const fieldValue = c[validation.field];
876
- if (fieldValue === void 0 || fieldValue === null) throw new Error(`${sort} sort requires '${validation.field}' field to be present`);
877
- if (validation.type === "string") {
878
- if (typeof fieldValue !== "string") throw new Error(`${sort} sort requires '${validation.field}' field of type ${validation.type}`);
879
- if (!validation.pattern.test(fieldValue)) throw new Error(`Invalid ${validation.field} format: ${fieldValue}. Must be a ${validation.error}`);
880
- }
881
- if (validation.type === "number") {
882
- if (typeof fieldValue !== "number") throw new Error(`${sort} sort requires '${validation.field}' field of type ${validation.type}`);
883
- if (fieldValue < validation.min) throw new Error(`Invalid ${validation.field} value: ${fieldValue}. Must be a ${validation.error}`);
884
- }
885
- const page = c.page;
886
- if (page !== void 0) {
887
- if (typeof page !== "number" || !Number.isInteger(page) || page < 1) throw new Error("Invalid page: must be a positive integer");
888
- }
889
- return true;
890
- }
891
- function encode$3(c) {
892
- return Base64.encodeURL(JSON.stringify(c));
893
- }
894
- function decode$3(token$1) {
895
- if (!token$1) return null;
896
- const decoded = JSON.parse(Base64.decode(token$1));
897
- validate(decoded);
898
- return decoded;
899
- }
900
-
901
- //#endregion
902
- //#region src/api/Schema/requests.ts
903
- const MAX_LIMIT = 100;
904
- const DEFAULT_LIMIT = 20;
905
- const PaginationQueryParams = z$1.object({
906
- cursor: z$1.string().optional().refine((val) => {
907
- if (!val) return true;
908
- try {
909
- return decode$3(val) !== null;
910
- } catch (_error) {
911
- return false;
912
- }
913
- }, { message: "Invalid cursor format. Must be a valid base64url-encoded cursor object" }).meta({
914
- description: "Pagination cursor in base64url-encoded format",
915
- example: "eyJzb3J0IjoicHJpY2UiLCJkaXIiOiJkZXNjIiwicHJpY2UiOiIxMDAwMDAwMDAwMDAwMDAwMDAwIiwiaGFzaCI6IjB4ZGRmZDY4NTllM2UwODJkMTkzODlhMWFlYzFiZGFkN2U4ZDkyZDk2YjFhYTc5NDBkYTkxYTMxMjVkMzFlM2JlNWIifQ"
916
- }),
917
- limit: z$1.string().regex(/^[1-9]\d*$/, { message: "Limit must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).pipe(z$1.number().max(MAX_LIMIT, { message: `Limit cannot exceed ${MAX_LIMIT}` })).optional().default(DEFAULT_LIMIT).meta({
918
- description: `Limit maximum: ${MAX_LIMIT}. Default: ${DEFAULT_LIMIT}`,
919
- example: 10
920
- })
921
- });
922
- const GetOffersQueryParams = z$1.object({
923
- ...PaginationQueryParams.shape,
924
- side: z$1.enum(["buy", "sell"]).optional().meta({
925
- description: "Side of the offer. Required when using obligation_id.",
926
- example: "buy"
927
- }),
928
- obligation_id: z$1.string().regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).optional().meta({
929
- description: "Offers obligation id. Required when not using offering.",
930
- example: "0x1234567890123456789012345678901234567890123456789012345678901234"
931
- }),
932
- offering: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Offering must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).optional().meta({
933
- description: "Maker address to filter offers by. Alternative to obligation_id + side.",
934
- example: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401"
935
- })
936
- }).superRefine((val, ctx) => {
937
- const hasObligation = val.obligation_id !== void 0;
938
- const hasSide = val.side !== void 0;
939
- const hasOffering = val.offering !== void 0;
940
- if (hasOffering && (hasObligation || hasSide)) {
941
- ctx.addIssue({
942
- code: "custom",
943
- message: "Cannot use both offering and obligation_id/side parameters"
944
- });
945
- return;
946
- }
947
- if (hasOffering) return;
948
- if (!hasObligation || !hasSide) ctx.addIssue({
949
- code: "custom",
950
- message: "Must provide either offering or both obligation_id and side"
951
- });
952
- });
953
- const GetObligationsQueryParams = z$1.object({
954
- ...PaginationQueryParams.shape,
955
- cursor: z$1.string().optional().meta({
956
- description: "Obligation id cursor",
957
- example: "0x1234567890123456789012345678901234567890123456789012345678901234"
958
- })
959
- });
960
- const GetObligationParams = z$1.object({ obligation_id: z$1.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({
961
- description: "Obligation id",
962
- example: "0x1234567890123456789012345678901234567890123456789012345678901234"
963
- }) });
964
- /** Validate a book cursor format: {side, lastRate, offersCursor} */
965
- function isValidBookCursor(cursorString) {
966
- const isNumericString = (value) => typeof value === "string" && /^-?\d+$/.test(value);
967
- try {
968
- const v = JSON.parse(Buffer.from(cursorString, "base64url").toString("utf8"));
969
- return (v?.side === "buy" || v?.side === "sell") && isNumericString(v?.lastRate) && (v?.offersCursor === null || typeof v?.offersCursor === "string");
970
- } catch {
971
- return false;
972
- }
973
- }
974
- const BookPaginationQueryParams = z$1.object({
975
- cursor: z$1.string().optional().refine((value) => {
976
- if (!value) return true;
977
- return isValidBookCursor(value);
978
- }, { message: "Invalid cursor format. Must be a valid base64url-encoded book cursor object" }).meta({
979
- description: "Pagination cursor in base64url-encoded format for book levels",
980
- example: "eyJzaWRlIjoiYnV5IiwibGFzdFJhdGUiOiIxMDAwMDAwMDAwMDAwMDAwMDAwIiwib2ZmZXJzQ3Vyc29yIjpudWxsfQ"
981
- }),
982
- limit: z$1.string().regex(/^[1-9]\d*$/, { message: "Limit must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).pipe(z$1.number().max(MAX_LIMIT, { message: `Limit cannot exceed ${MAX_LIMIT}` })).optional().default(DEFAULT_LIMIT).meta({
983
- description: `Limit maximum: ${MAX_LIMIT}. Default: ${DEFAULT_LIMIT}`,
984
- example: 10
985
- })
986
- });
987
- const GetBookParams = z$1.object({
988
- ...BookPaginationQueryParams.shape,
989
- obligation_id: z$1.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({
990
- description: "Obligation id",
991
- example: "0x1234567890123456789012345678901234567890123456789012345678901234"
992
- }),
993
- side: z$1.enum(["buy", "sell"]).meta({
994
- description: "Side of the book (buy or sell).",
995
- example: "buy"
996
- })
997
- });
998
- const schemas = {
999
- get_offers: GetOffersQueryParams,
1000
- get_obligations: GetObligationsQueryParams,
1001
- get_obligation: GetObligationParams,
1002
- get_book: GetBookParams,
1003
- validate_offers: z$1.object({ offers: z$1.array(z$1.unknown()).min(1, { message: "'offers' must contain at least 1 offer" }) }).strict()
1004
- };
1005
- function parse(action, query) {
1006
- return schemas[action].parse(query);
1007
- }
1008
- function safeParse(action, query, error) {
1009
- return schemas[action].safeParse(query, { error });
1010
- }
1011
-
1012
- //#endregion
1013
- //#region src/api/Schema/index.ts
1014
- var Schema_exports = /* @__PURE__ */ __export({
1015
- BookResponse: () => BookResponse_exports,
1016
- BooksController: () => BooksController,
1017
- ChainHealth: () => ChainHealth,
1018
- ChainsHealthResponse: () => ChainsHealthResponse,
1019
- CollectorHealth: () => CollectorHealth,
1020
- CollectorsHealthResponse: () => CollectorsHealthResponse,
1021
- HealthController: () => HealthController,
1022
- ObligationResponse: () => ObligationResponse_exports,
1023
- ObligationsController: () => ObligationsController,
1024
- OfferResponse: () => OfferResponse_exports,
1025
- OffersController: () => OffersController,
1026
- OpenApi: () => OpenApi,
1027
- RouterStatusResponse: () => RouterStatusResponse,
1028
- ValidateController: () => ValidateController,
1029
- parse: () => parse,
1030
- safeParse: () => safeParse
1031
- });
1032
-
1033
- //#endregion
1034
- //#region src/core/Abi/MetaMorpho.ts
1035
- const MetaMorpho = parseAbi([
1036
- "function balanceOf(address account) view returns (uint256)",
1037
- "function DECIMALS_OFFSET() view returns (uint8)",
1038
- "function totalAssets() view returns (uint256)",
1039
- "function totalSupply() view returns (uint256)",
1040
- "function maxWithdraw(address owner) view returns (uint256 assets)",
1041
- "function asset() view returns (address)",
1042
- "event Transfer(address indexed from, address indexed to, uint256 value)",
1043
- "function withdrawQueue(uint256 index) view returns (bytes32)",
1044
- "function withdrawQueueLength() view returns (uint256)"
1045
- ]);
1046
-
1047
- //#endregion
1048
- //#region src/core/Abi/MetaMorphoFactory.ts
1049
- const MetaMorphoFactory = parseAbi(["event CreateMetaMorpho(address indexed metaMorpho,address indexed caller,address initialOwner,uint256 initialTimelock,address indexed asset,string name,string symbol,bytes32 salt)", "function isMetaMorpho(address) view returns (bool)"]);
1050
-
1051
- //#endregion
1052
- //#region src/core/Abi/index.ts
1053
- var Abi_exports = /* @__PURE__ */ __export({
1054
- ERC4626: () => ERC4626,
1055
- MetaMorpho: () => MetaMorpho,
1056
- MetaMorphoFactory: () => MetaMorphoFactory,
1057
- Morpho: () => Morpho,
1058
- Oracle: () => Oracle
1059
- });
1060
- const Oracle = [{
1061
- type: "function",
1062
- name: "price",
1063
- inputs: [],
1064
- outputs: [{
1065
- name: "",
1066
- type: "uint256"
1067
- }],
1068
- stateMutability: "view"
1069
- }];
1070
- const ERC4626 = [{
1071
- type: "function",
1072
- name: "asset",
1073
- inputs: [],
1074
- outputs: [{
1075
- name: "",
1076
- type: "address"
1077
- }],
1078
- stateMutability: "view"
1079
- }];
1080
- const Morpho = [
1081
- {
1082
- type: "function",
1083
- name: "collateralOf",
1084
- inputs: [
1085
- {
1086
- name: "",
1087
- type: "address",
1088
- internalType: "address"
1089
- },
1090
- {
1091
- name: "",
1092
- type: "bytes32",
1093
- internalType: "bytes32"
1094
- },
1095
- {
1096
- name: "",
1097
- type: "address",
1098
- internalType: "address"
1099
- }
1100
- ],
1101
- outputs: [{
1102
- name: "",
1103
- type: "uint256",
1104
- internalType: "uint256"
1105
- }],
1106
- stateMutability: "view"
118
+ stateMutability: "view"
119
+ }];
120
+ const ERC4626 = [{
121
+ type: "function",
122
+ name: "asset",
123
+ inputs: [],
124
+ outputs: [{
125
+ name: "",
126
+ type: "address"
127
+ }],
128
+ stateMutability: "view"
129
+ }];
130
+ const Morpho = [
131
+ {
132
+ type: "function",
133
+ name: "collateralOf",
134
+ inputs: [
135
+ {
136
+ name: "",
137
+ type: "address",
138
+ internalType: "address"
139
+ },
140
+ {
141
+ name: "",
142
+ type: "bytes32",
143
+ internalType: "bytes32"
144
+ },
145
+ {
146
+ name: "",
147
+ type: "address",
148
+ internalType: "address"
149
+ }
150
+ ],
151
+ outputs: [{
152
+ name: "",
153
+ type: "uint256",
154
+ internalType: "uint256"
155
+ }],
156
+ stateMutability: "view"
1107
157
  },
1108
158
  {
1109
159
  type: "function",
@@ -1277,6 +327,19 @@ function max$1(a, b) {
1277
327
  function min(a, b) {
1278
328
  return a < b ? a : b;
1279
329
  }
330
+ /**
331
+ * Checks if at most one of the given values is non-zero.
332
+ * @param values - The bigint values to check.
333
+ * @returns True if zero or one value is non-zero, false if two or more are non-zero.
334
+ */
335
+ function atMostOneNonZero(...values) {
336
+ let nonZeroCount = 0;
337
+ for (const value of values) if (value !== 0n) {
338
+ nonZeroCount++;
339
+ if (nonZeroCount > 1) return false;
340
+ }
341
+ return true;
342
+ }
1280
343
 
1281
344
  //#endregion
1282
345
  //#region src/utils/batch.ts
@@ -1645,6 +708,18 @@ var MissingBlockNumberError = class extends BaseError {
1645
708
  }
1646
709
  };
1647
710
 
711
+ //#endregion
712
+ //#region src/core/ChainRegistry.ts
713
+ var ChainRegistry_exports = /* @__PURE__ */ __export({ create: () => create$1 });
714
+ function create$1(chains$2) {
715
+ const byId = /* @__PURE__ */ new Map();
716
+ for (const chain of chains$2) byId.set(chain.id, chain);
717
+ return {
718
+ getById: (chainId) => byId.get(chainId),
719
+ list: () => Array.from(byId.values())
720
+ };
721
+ }
722
+
1648
723
  //#endregion
1649
724
  //#region src/utils/Random.ts
1650
725
  var Random_exports = /* @__PURE__ */ __export({
@@ -1737,23 +812,81 @@ function address() {
1737
812
 
1738
813
  //#endregion
1739
814
  //#region src/utils/zod.ts
815
+ /**
816
+ * Converts a hex string to a padded bytes32.
817
+ * Returns null if the value is not a valid hex string.
818
+ */
819
+ const hexToBytes32 = (val) => {
820
+ if (!isHex(val)) return null;
821
+ return pad(val, { size: 32 });
822
+ };
823
+ /**
824
+ * Converts a numeric string to a padded bytes32.
825
+ * @throws {Error} If parsing fails or value is negative.
826
+ */
827
+ const numericStringToBytes32 = (val) => {
828
+ const num = BigInt(val);
829
+ if (num < 0n) throw new Error("expected bigint to be >=0");
830
+ return pad(numberToHex(num), { size: 32 });
831
+ };
832
+ /**
833
+ * Converts a number or bigint to a padded bytes32.
834
+ * @throws {Error} If value is negative.
835
+ */
836
+ const numericToBytes32 = (val) => {
837
+ const num = BigInt(val);
838
+ if (num < 0n) throw new Error("expected bigint to be >=0");
839
+ return pad(numberToHex(num), { size: 32 });
840
+ };
841
+ /**
842
+ * Transforms a value to a bytes32 hex string.
843
+ * Accepts:
844
+ * - Hex strings (0x...) - pads to 32 bytes if needed
845
+ * - Numeric strings - converts to padded hex
846
+ * - Numbers/bigints - converts to padded hex (must be non-negative)
847
+ */
848
+ const transformBytes32 = (val, ctx) => {
849
+ if (typeof val === "string") {
850
+ const hexResult = hexToBytes32(val);
851
+ if (hexResult !== null) return hexResult;
852
+ try {
853
+ return numericStringToBytes32(val);
854
+ } catch (error) {
855
+ ctx.addIssue({
856
+ code: z$1.ZodIssueCode.custom,
857
+ message: `Not a valid bytes32 value: ${error instanceof Error ? error.message : String(error)}`
858
+ });
859
+ return z$1.NEVER;
860
+ }
861
+ }
862
+ if (typeof val === "number" || typeof val === "bigint") try {
863
+ return numericToBytes32(val);
864
+ } catch (error) {
865
+ ctx.addIssue({
866
+ code: z$1.ZodIssueCode.custom,
867
+ message: `Too small: ${error instanceof Error ? error.message : String(error)}`
868
+ });
869
+ return z$1.NEVER;
870
+ }
871
+ ctx.addIssue({
872
+ code: z$1.ZodIssueCode.custom,
873
+ message: "Not a valid bytes32 value"
874
+ });
875
+ return z$1.NEVER;
876
+ };
1740
877
  const transformHex = (val, ctx) => {
1741
878
  if (isHex(val)) return val;
1742
879
  ctx.addIssue({
1743
- code: "invalid_format",
1744
- input: val,
1745
- format: "hex",
1746
- error: "not a hex"
880
+ code: z$1.ZodIssueCode.custom,
881
+ message: "Invalid hex"
1747
882
  });
1748
883
  return z$1.NEVER;
1749
884
  };
1750
885
  const transformAddress = (val, ctx) => {
1751
886
  if (isAddress(val.toLowerCase())) return val.toLowerCase();
1752
887
  ctx.addIssue({
1753
- code: "invalid_format",
1754
- input: val,
1755
- format: "address",
1756
- error: "not a valid address"
888
+ code: z$1.ZodIssueCode.custom,
889
+ message: "Invalid address"
1757
890
  });
1758
891
  return z$1.NEVER;
1759
892
  };
@@ -1765,7 +898,7 @@ var LLTV_exports = /* @__PURE__ */ __export({
1765
898
  InvalidOptionError: () => InvalidOptionError$1,
1766
899
  LLTVSchema: () => LLTVSchema,
1767
900
  Options: () => Options,
1768
- from: () => from$10
901
+ from: () => from$12
1769
902
  });
1770
903
  const Options = [
1771
904
  .385,
@@ -1784,7 +917,7 @@ const LLTV_SCALED = Options.map((lltv) => BigInt(lltv * 10 ** 18));
1784
917
  * @param lltv - The LLTV option or the scaled LLTV.
1785
918
  * @returns The LLTV.
1786
919
  */
1787
- function from$10(lltv) {
920
+ function from$12(lltv) {
1788
921
  if (typeof lltv === "bigint" && !LLTV_SCALED.includes(lltv)) throw new InvalidLLTVError(lltv);
1789
922
  if (typeof lltv === "bigint") return lltv;
1790
923
  if (typeof lltv === "number" && !Options.includes(lltv)) throw new InvalidOptionError$1(lltv);
@@ -1804,21 +937,21 @@ var InvalidLLTVError = class extends BaseError {
1804
937
  };
1805
938
  const LLTVSchema = z$1.bigint({ coerce: true }).refine((lltv) => {
1806
939
  try {
1807
- from$10(lltv);
940
+ from$12(lltv);
1808
941
  return true;
1809
942
  } catch (_) {
1810
943
  return false;
1811
944
  }
1812
945
  }, { error: () => {
1813
946
  return "Invalid LLTV: must be one of 0.385, 0.625, 0.77, 0.86, 0.915, 0.945, 0.965 or 0.98 (scaled by 1e18)";
1814
- } }).transform((lltv) => from$10(lltv));
947
+ } }).transform((lltv) => from$12(lltv));
1815
948
 
1816
949
  //#endregion
1817
950
  //#region src/core/Collateral.ts
1818
951
  var Collateral_exports = /* @__PURE__ */ __export({
1819
952
  CollateralSchema: () => CollateralSchema,
1820
953
  CollateralsSchema: () => CollateralsSchema,
1821
- from: () => from$9,
954
+ from: () => from$11,
1822
955
  random: () => random$3
1823
956
  });
1824
957
  const CollateralSchema = z$1.object({
@@ -1838,10 +971,10 @@ const CollateralsSchema = z$1.array(CollateralSchema).min(1, { message: "At leas
1838
971
  }
1839
972
  return true;
1840
973
  }, { message: "Collaterals must not contain duplicate assets" });
1841
- const from$9 = (parameters) => {
974
+ const from$11 = (parameters) => {
1842
975
  return {
1843
976
  asset: parameters.asset.toLowerCase(),
1844
- lltv: from$10(parameters.lltv),
977
+ lltv: from$12(parameters.lltv),
1845
978
  oracle: parameters.oracle.toLowerCase()
1846
979
  };
1847
980
  };
@@ -1855,7 +988,7 @@ const from$9 = (parameters) => {
1855
988
  * ```
1856
989
  */
1857
990
  function random$3() {
1858
- return from$9({
991
+ return from$11({
1859
992
  asset: address(),
1860
993
  oracle: address(),
1861
994
  lltv: .965
@@ -2024,11 +1157,11 @@ var Maturity_exports = /* @__PURE__ */ __export({
2024
1157
  InvalidOptionError: () => InvalidOptionError,
2025
1158
  MaturitySchema: () => MaturitySchema,
2026
1159
  MaturityType: () => MaturityType,
2027
- from: () => from$8
1160
+ from: () => from$10
2028
1161
  });
2029
1162
  const MaturitySchema = z$1.number().int().refine((maturity$1) => {
2030
1163
  try {
2031
- from$8(maturity$1);
1164
+ from$10(maturity$1);
2032
1165
  return true;
2033
1166
  } catch (_e) {
2034
1167
  return false;
@@ -2063,7 +1196,7 @@ const MaturityOptions = {
2063
1196
  * @throws {InvalidDateError} If the maturity is in seconds but not a valid date.
2064
1197
  * @throws {InvalidOptionError} If the maturity is not a valid option.
2065
1198
  */
2066
- function from$8(ts) {
1199
+ function from$10(ts) {
2067
1200
  if (typeof ts === "string") {
2068
1201
  if (ts in MaturityOptions) return MaturityOptions[ts]();
2069
1202
  throw new InvalidOptionError(ts);
@@ -2142,13 +1275,58 @@ var InvalidOptionError = class extends BaseError {
2142
1275
  }
2143
1276
  };
2144
1277
 
1278
+ //#endregion
1279
+ //#region src/utils/Format.ts
1280
+ var Format_exports = /* @__PURE__ */ __export({
1281
+ fromSnakeCase: () => fromSnakeCase$3,
1282
+ stringifyBigint: () => stringifyBigint,
1283
+ toSnakeCase: () => toSnakeCase$1
1284
+ });
1285
+ /**
1286
+ * Formats object keys to snake case.
1287
+ * Preserves ethereum addresses as is.
1288
+ * Converts ethereum addresses to checksummed if used as values.
1289
+ * Stringifies bigint values to strings.
1290
+ */
1291
+ function toSnakeCase$1(obj) {
1292
+ return stringifyBigint(processObject(obj, (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`), (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? getAddress(value.toLowerCase()) : value));
1293
+ }
1294
+ /**
1295
+ * Formats a snake case object to its camel case type.
1296
+ * Preserves ethereum addresses as is.
1297
+ * Converts checksummed ethereum addresses to lowercase if used as values.
1298
+ * @warning Does not unstringify bigint values.
1299
+ */
1300
+ function fromSnakeCase$3(obj) {
1301
+ return processObject(obj, (s) => isAddress(s.toLowerCase()) ? s : s.replace(/_([a-z])/g, (_, c) => c.toUpperCase()), (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? value.toLowerCase() : value);
1302
+ }
1303
+ function processObject(obj, fnKey, fnValue) {
1304
+ if (typeof obj !== "object" || obj === null) return obj;
1305
+ if (Array.isArray(obj)) return obj.map((item) => processObject(item, fnKey, fnValue));
1306
+ return Object.entries(obj).reduce((acc, [key, value]) => {
1307
+ const newKey = fnKey(key);
1308
+ acc[newKey] = typeof value === "object" && value !== null ? processObject(value, fnKey, fnValue) : fnValue(value);
1309
+ return acc;
1310
+ }, {});
1311
+ }
1312
+ function stringifyBigint(value) {
1313
+ if (typeof value === "bigint") return value.toString();
1314
+ if (Array.isArray(value)) return value.map(stringifyBigint);
1315
+ if (value && typeof value === "object") {
1316
+ const out = {};
1317
+ for (const [k, v] of Object.entries(value)) out[k] = stringifyBigint(v);
1318
+ return out;
1319
+ }
1320
+ return value;
1321
+ }
1322
+
2145
1323
  //#endregion
2146
1324
  //#region src/core/Obligation.ts
2147
1325
  var Obligation_exports = /* @__PURE__ */ __export({
2148
1326
  CollateralsAreNotSortedError: () => CollateralsAreNotSortedError,
2149
1327
  InvalidObligationError: () => InvalidObligationError,
2150
1328
  ObligationSchema: () => ObligationSchema,
2151
- from: () => from$7,
1329
+ from: () => from$9,
2152
1330
  fromSnakeCase: () => fromSnakeCase$2,
2153
1331
  id: () => id,
2154
1332
  random: () => random$2
@@ -2182,11 +1360,11 @@ const ObligationSchema = z$1.object({
2182
1360
  * });
2183
1361
  * ```
2184
1362
  */
2185
- function from$7(parameters) {
1363
+ function from$9(parameters) {
2186
1364
  try {
2187
1365
  const parsedObligation = ObligationSchema.parse({
2188
1366
  ...parameters,
2189
- maturity: from$8(parameters.maturity)
1367
+ maturity: from$10(parameters.maturity)
2190
1368
  });
2191
1369
  return {
2192
1370
  chainId: parsedObligation.chainId,
@@ -2205,13 +1383,13 @@ function from$7(parameters) {
2205
1383
  * @returns The created obligation. {@link fromSnakeCase.ReturnType}
2206
1384
  */
2207
1385
  function fromSnakeCase$2(input) {
2208
- return from$7(fromSnakeCase$3(input));
1386
+ return from$9(fromSnakeCase$3(input));
2209
1387
  }
2210
1388
  /**
2211
1389
  * Calculates the obligation id based on the smart contract's Obligation struct.
2212
1390
  * The id is computed as keccak256(abi.encode(chainId, loanToken, collaterals, maturity)).
2213
1391
  * @throws If the collaterals are not sorted alphabetically by address. {@link CollateralsAreNotSortedError}
2214
- * @param obligation - {@link id.Parameters}
1392
+ * @param parameters - {@link id.Parameters}
2215
1393
  * @returns The obligation id as a 32-byte hex string. {@link id.ReturnType}
2216
1394
  *
2217
1395
  * @example
@@ -2221,9 +1399,9 @@ function fromSnakeCase$2(input) {
2221
1399
  * console.log(id); // 0x1234567890123456789012345678901234567890123456789012345678901234
2222
1400
  * ```
2223
1401
  */
2224
- function id(obligation) {
1402
+ function id(parameters) {
2225
1403
  let lastAsset = "";
2226
- for (const collateral of obligation.collaterals) {
1404
+ for (const collateral of parameters.collaterals) {
2227
1405
  const newAsset = collateral.asset.toLowerCase();
2228
1406
  if (newAsset.localeCompare(lastAsset) < 0) throw new CollateralsAreNotSortedError();
2229
1407
  lastAsset = newAsset;
@@ -2250,14 +1428,14 @@ function id(obligation) {
2250
1428
  },
2251
1429
  { type: "uint256" }
2252
1430
  ], [
2253
- BigInt(obligation.chainId),
2254
- obligation.loanToken.toLowerCase(),
2255
- obligation.collaterals.map((c) => ({
1431
+ BigInt(parameters.chainId),
1432
+ parameters.loanToken.toLowerCase(),
1433
+ parameters.collaterals.map((c) => ({
2256
1434
  token: c.asset.toLowerCase(),
2257
1435
  lltv: c.lltv,
2258
1436
  oracle: c.oracle.toLowerCase()
2259
1437
  })),
2260
- BigInt(obligation.maturity)
1438
+ BigInt(parameters.maturity)
2261
1439
  ]));
2262
1440
  }
2263
1441
  /**
@@ -2270,11 +1448,11 @@ function id(obligation) {
2270
1448
  * ```
2271
1449
  */
2272
1450
  function random$2() {
2273
- return from$7({
1451
+ return from$9({
2274
1452
  chainId: 1,
2275
1453
  loanToken: address(),
2276
1454
  collaterals: [random$3()],
2277
- maturity: from$8("end_of_next_quarter")
1455
+ maturity: from$10("end_of_next_quarter")
2278
1456
  });
2279
1457
  }
2280
1458
  var InvalidObligationError = class extends BaseError {
@@ -2300,7 +1478,7 @@ var Tree_exports = /* @__PURE__ */ __export({
2300
1478
  decode: () => decode$1,
2301
1479
  encode: () => encode$1,
2302
1480
  encodeUnsigned: () => encodeUnsigned,
2303
- from: () => from$6,
1481
+ from: () => from$8,
2304
1482
  proofs: () => proofs
2305
1483
  });
2306
1484
  const VERSION = 1;
@@ -2316,15 +1494,15 @@ const normalizeHash = (hash$1) => hash$1.toLowerCase();
2316
1494
  * @returns A `StandardMerkleTree` of `bytes32` leaves representing the offers.
2317
1495
  * @throws {TreeError} If tree building fails due to offer inconsistencies.
2318
1496
  */
2319
- const from$6 = (offers) => {
2320
- const leaves = offers.map((offer) => [offer.hash]);
1497
+ const from$8 = (offers) => {
1498
+ const leaves = offers.map((offer) => [hash(offer)]);
2321
1499
  const tree = StandardMerkleTree.of(leaves, ["bytes32"]);
2322
1500
  const orderedOffers = orderOffers(tree, offers);
2323
1501
  return Object.assign(tree, { offers: orderedOffers });
2324
1502
  };
2325
1503
  const orderOffers = (tree, offers) => {
2326
1504
  const offerByHash = /* @__PURE__ */ new Map();
2327
- for (const offer of offers) offerByHash.set(normalizeHash(offer.hash), offer);
1505
+ for (const offer of offers) offerByHash.set(normalizeHash(hash(offer)), offer);
2328
1506
  const entries = tree.dump().values.map((value) => {
2329
1507
  const hash$1 = normalizeHash(value.value[0]);
2330
1508
  const offer = offerByHash.get(hash$1);
@@ -2350,7 +1528,7 @@ const proofs = (tree) => {
2350
1528
  return tree.offers.map((offer) => {
2351
1529
  return {
2352
1530
  offer,
2353
- path: tree.getProof([offer.hash])
1531
+ path: tree.getProof([hash(offer)])
2354
1532
  };
2355
1533
  });
2356
1534
  };
@@ -2438,7 +1616,7 @@ const encodeUnsigned = (tree) => {
2438
1616
  };
2439
1617
  const validateTreeForEncoding = (tree) => {
2440
1618
  if (VERSION > 255) throw new EncodeError(`version overflow: ${VERSION} exceeds 255`);
2441
- const computed = from$6(tree.offers);
1619
+ const computed = from$8(tree.offers);
2442
1620
  if (tree.root !== computed.root) throw new EncodeError(`root mismatch: expected ${computed.root}, got ${tree.root}`);
2443
1621
  };
2444
1622
  const encodeUnsignedBytes = (tree) => {
@@ -2499,7 +1677,7 @@ const decode$1 = async (encoded) => {
2499
1677
  } catch {
2500
1678
  throw new DecodeError("JSON parse failed");
2501
1679
  }
2502
- const tree = from$6(rawOffers.map((o) => OfferSchema().parse(o)));
1680
+ const tree = from$8(rawOffers.map((o) => OfferSchema().parse(o)));
2503
1681
  if (root !== tree.root) throw new DecodeError(`root mismatch: expected ${tree.root}, got ${root}`);
2504
1682
  return {
2505
1683
  tree,
@@ -2543,14 +1721,13 @@ var DecodeError = class extends BaseError {
2543
1721
  var Offer_exports = /* @__PURE__ */ __export({
2544
1722
  AccountNotSetError: () => AccountNotSetError,
2545
1723
  InvalidOfferError: () => InvalidOfferError,
2546
- OfferHashSchema: () => OfferHashSchema,
2547
1724
  OfferSchema: () => OfferSchema,
2548
1725
  Status: () => Status,
2549
1726
  consumedEvent: () => consumedEvent,
2550
1727
  decode: () => decode,
2551
1728
  domain: () => domain,
2552
1729
  encode: () => encode,
2553
- from: () => from$5,
1730
+ from: () => from$7,
2554
1731
  fromSnakeCase: () => fromSnakeCase$1,
2555
1732
  hash: () => hash,
2556
1733
  obligationId: () => obligationId,
@@ -2561,42 +1738,46 @@ var Offer_exports = /* @__PURE__ */ __export({
2561
1738
  toSnakeCase: () => toSnakeCase,
2562
1739
  types: () => types
2563
1740
  });
1741
+ /** Internal symbol for caching the computed hash. */
1742
+ const HASH_CACHE = Symbol("offer.hash");
2564
1743
  let Status = /* @__PURE__ */ function(Status$1) {
2565
1744
  Status$1["VALID"] = "VALID";
2566
1745
  Status$1["SIMULATION_ERROR"] = "SIMULATION_ERROR";
2567
1746
  return Status$1;
2568
1747
  }({});
2569
- const OfferHashSchema = z$1.string().regex(/^0x[0-9a-fA-F]{64}$/, { message: "Hash must be a valid 32-byte hex string" }).transform(transformHex);
2570
- const OfferSchema = (parameters) => {
2571
- const { omitHash = false } = parameters || {};
2572
- let base$1 = z$1.object({
2573
- offering: z$1.string().transform(transformAddress),
1748
+ const OfferSchema = () => {
1749
+ return z$1.object({
1750
+ maker: z$1.string().transform(transformAddress),
2574
1751
  assets: z$1.bigint({ coerce: true }).min(0n).max(maxUint256),
2575
- rate: z$1.bigint({ coerce: true }).min(0n).max(maxUint256),
1752
+ obligationUnits: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional().default(0n),
1753
+ obligationShares: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional().default(0n),
1754
+ price: z$1.bigint({ coerce: true }).min(0n).max(maxUint256),
2576
1755
  maturity: MaturitySchema,
2577
1756
  expiry: z$1.number().int().max(Number.MAX_SAFE_INTEGER),
2578
1757
  start: z$1.number().int().max(Number.MAX_SAFE_INTEGER),
2579
- nonce: z$1.bigint({ coerce: true }).min(0n).max(maxUint256),
1758
+ group: z$1.union([
1759
+ z$1.string(),
1760
+ z$1.number(),
1761
+ z$1.bigint()
1762
+ ]).transform(transformBytes32),
1763
+ session: z$1.union([
1764
+ z$1.string(),
1765
+ z$1.number(),
1766
+ z$1.bigint()
1767
+ ]).optional().default("0x0000000000000000000000000000000000000000000000000000000000000000").transform(transformBytes32),
2580
1768
  buy: z$1.boolean(),
2581
1769
  chainId: z$1.number().min(0).max(Number.MAX_SAFE_INTEGER),
2582
1770
  loanToken: z$1.string().transform(transformAddress),
2583
1771
  collaterals: CollateralsSchema,
2584
1772
  callback: z$1.object({
2585
1773
  address: z$1.string().transform(transformAddress),
2586
- data: z$1.string().transform(transformHex),
2587
- gasLimit: z$1.bigint({ coerce: true }).min(0n).max(maxUint256)
2588
- }),
2589
- signature: z$1.string().regex(/^0x[0-9a-fA-F]{130}$/, { message: "Signature must be a valid 65-byte hex string" }).transform(transformHex).optional(),
2590
- consumed: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional(),
2591
- takeable: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional(),
2592
- blockNumber: z$1.number().int().max(Number.MAX_SAFE_INTEGER).optional()
2593
- });
2594
- if (!omitHash) base$1 = base$1.extend({ hash: OfferHashSchema });
2595
- return base$1.refine((data) => data.start < data.expiry, {
2596
- message: "Start must be before expiry",
1774
+ data: z$1.string().transform(transformHex)
1775
+ })
1776
+ }).refine((data) => data.start < data.expiry, {
1777
+ message: "start must be before expiry",
2597
1778
  path: ["start"]
2598
1779
  }).refine((data) => data.expiry <= data.maturity, {
2599
- message: "Expiry cannot be after maturity",
1780
+ message: "expiry must be before or equal to maturity",
2600
1781
  path: ["expiry"]
2601
1782
  });
2602
1783
  };
@@ -2604,16 +1785,11 @@ const OfferSchema = (parameters) => {
2604
1785
  * Creates an offer from a plain object.
2605
1786
  * @throws {InvalidOfferError} If the offer is invalid.
2606
1787
  * @param input - The offer to create.
2607
- * @returns The created offer with its hash.
1788
+ * @returns The created offer.
2608
1789
  */
2609
- function from$5(input) {
1790
+ function from$7(input) {
2610
1791
  try {
2611
- const parsedOffer = OfferSchema({ omitHash: true }).parse(input);
2612
- const parsedHash = OfferHashSchema.parse(hash(parsedOffer));
2613
- return {
2614
- ...parsedOffer,
2615
- hash: parsedHash
2616
- };
1792
+ return OfferSchema().parse(input);
2617
1793
  } catch (error) {
2618
1794
  throw new InvalidOfferError(error);
2619
1795
  }
@@ -2622,10 +1798,10 @@ function from$5(input) {
2622
1798
  * Creates an offer from a snake case object.
2623
1799
  * @throws {InvalidOfferError} If the offer is invalid.
2624
1800
  * @param input - The offer to create.
2625
- * @returns The created offer with its hash.
1801
+ * @returns The created offer.
2626
1802
  */
2627
1803
  function fromSnakeCase$1(input) {
2628
- return from$5(fromSnakeCase$3(input));
1804
+ return from$7(fromSnakeCase$3(input));
2629
1805
  }
2630
1806
  /**
2631
1807
  * Converts an offer to a snake case object.
@@ -2643,13 +1819,16 @@ function toSnakeCase(offer) {
2643
1819
  * @returns JSON-serializable offer object
2644
1820
  */
2645
1821
  const serialize = (offer) => ({
2646
- offering: offer.offering,
1822
+ maker: offer.maker,
2647
1823
  assets: offer.assets.toString(),
2648
- rate: offer.rate.toString(),
1824
+ obligationUnits: offer.obligationUnits.toString(),
1825
+ obligationShares: offer.obligationShares.toString(),
1826
+ price: offer.price.toString(),
2649
1827
  maturity: Number(offer.maturity),
2650
1828
  expiry: Number(offer.expiry),
2651
1829
  start: Number(offer.start),
2652
- nonce: offer.nonce.toString(),
1830
+ group: offer.group,
1831
+ session: offer.session,
2653
1832
  buy: offer.buy,
2654
1833
  chainId: offer.chainId,
2655
1834
  loanToken: offer.loanToken,
@@ -2660,11 +1839,9 @@ const serialize = (offer) => ({
2660
1839
  })),
2661
1840
  callback: {
2662
1841
  address: offer.callback.address,
2663
- data: offer.callback.data,
2664
- gasLimit: offer.callback.gasLimit.toString()
1842
+ data: offer.callback.data
2665
1843
  },
2666
- signature: offer.signature,
2667
- hash: offer.hash
1844
+ hash: hash(offer)
2668
1845
  });
2669
1846
  /**
2670
1847
  * Generates a random Offer.
@@ -2678,8 +1855,8 @@ function random$1(config) {
2678
1855
  const collateralCandidates = config?.collateralTokens ? config.collateralTokens.filter((a) => a !== loanToken) : [address()];
2679
1856
  const collateralAsset = collateralCandidates[int(collateralCandidates.length)];
2680
1857
  const maturityOption = weightedChoice([["end_of_month", 1], ["end_of_next_month", 1]]);
2681
- const maturity$1 = config?.maturity ?? from$8(maturityOption);
2682
- const lltv = from$10(weightedChoice([
1858
+ const maturity$1 = config?.maturity ?? from$10(maturityOption);
1859
+ const lltv = from$12(weightedChoice([
2683
1860
  [.385, 1],
2684
1861
  [.5, 1],
2685
1862
  [.625, 2],
@@ -2694,21 +1871,19 @@ function random$1(config) {
2694
1871
  const ONE = 1000000000000000000n;
2695
1872
  const qMin = buy ? 16 : 4;
2696
1873
  const len = (buy ? 32 : 16) - qMin + 1;
2697
- const ratePairs = Array.from({ length: len }, (_, idx) => {
1874
+ const pricePairs = Array.from({ length: len }, (_, idx) => {
2698
1875
  const q = qMin + idx;
2699
1876
  return [BigInt(q) * (ONE / 4n), buy ? 1 + idx : 1 + (len - 1 - idx)];
2700
1877
  });
2701
- const rate = config?.rate ?? weightedChoice(ratePairs);
1878
+ const price = config?.price ?? weightedChoice(pricePairs);
2702
1879
  const loanTokenDecimals = config?.assetsDecimals?.[loanToken] ?? 18;
2703
1880
  const unit = BigInt(10) ** BigInt(loanTokenDecimals);
2704
1881
  const amountBase = BigInt(100 + int(999901));
2705
1882
  const assetsScaled = config?.assets ?? amountBase * unit;
2706
- const consumed = config?.consumed !== void 0 ? config.consumed : float() < .8 ? 0n : assetsScaled * BigInt(1 + int(900)) / 1000n;
2707
1883
  const callbackBySide = (() => {
2708
1884
  if (buy) return {
2709
1885
  address: zeroAddress,
2710
- data: "0x",
2711
- gasLimit: 0n
1886
+ data: "0x"
2712
1887
  };
2713
1888
  const sellCallbackAddress = "0x3333333333333333333333333333333333333333";
2714
1889
  const amount = assetsScaled * 1000000000000000000000n;
@@ -2717,18 +1892,20 @@ function random$1(config) {
2717
1892
  data: encodeSellERC20Callback({
2718
1893
  collaterals: [collateralAsset],
2719
1894
  amounts: [amount]
2720
- }),
2721
- gasLimit: 0n
1895
+ })
2722
1896
  };
2723
1897
  })();
2724
- return from$5({
2725
- offering: config?.offering ?? address(),
1898
+ return from$7({
1899
+ maker: config?.maker ?? address(),
2726
1900
  assets: assetsScaled,
2727
- rate,
1901
+ obligationUnits: config?.obligationUnits ?? 0n,
1902
+ obligationShares: config?.obligationShares ?? 0n,
1903
+ price,
2728
1904
  maturity: maturity$1,
2729
1905
  expiry: config?.expiry ?? maturity$1 - 1,
2730
1906
  start: config?.start ?? maturity$1 - 10,
2731
- nonce: BigInt(int(1e6)),
1907
+ group: config?.group ?? hex(32),
1908
+ session: config?.session ?? hex(32),
2732
1909
  buy,
2733
1910
  chainId: chain.id,
2734
1911
  loanToken,
@@ -2736,10 +1913,7 @@ function random$1(config) {
2736
1913
  ...random$3(),
2737
1914
  lltv
2738
1915
  })).sort((a, b) => a.asset.localeCompare(b.asset)),
2739
- callback: config?.callback ?? callbackBySide,
2740
- consumed,
2741
- takeable: config?.takeable ?? assetsScaled - consumed,
2742
- blockNumber: config?.blockNumber ?? int(Number.MAX_SAFE_INTEGER)
1916
+ callback: config?.callback ?? callbackBySide
2743
1917
  });
2744
1918
  }
2745
1919
  const weightedChoice = (pairs) => {
@@ -2769,490 +1943,1814 @@ const types = {
2769
1943
  EIP712Domain: [{
2770
1944
  name: "chainId",
2771
1945
  type: "uint256"
2772
- }, {
2773
- name: "verifyingContract",
1946
+ }, {
1947
+ name: "verifyingContract",
1948
+ type: "address"
1949
+ }],
1950
+ Offer: [
1951
+ {
1952
+ name: "maker",
1953
+ type: "address"
1954
+ },
1955
+ {
1956
+ name: "assets",
1957
+ type: "uint256"
1958
+ },
1959
+ {
1960
+ name: "obligationUnits",
1961
+ type: "uint256"
1962
+ },
1963
+ {
1964
+ name: "obligationShares",
1965
+ type: "uint256"
1966
+ },
1967
+ {
1968
+ name: "price",
1969
+ type: "uint256"
1970
+ },
1971
+ {
1972
+ name: "maturity",
1973
+ type: "uint256"
1974
+ },
1975
+ {
1976
+ name: "expiry",
1977
+ type: "uint256"
1978
+ },
1979
+ {
1980
+ name: "group",
1981
+ type: "bytes32"
1982
+ },
1983
+ {
1984
+ name: "session",
1985
+ type: "bytes32"
1986
+ },
1987
+ {
1988
+ name: "buy",
1989
+ type: "bool"
1990
+ },
1991
+ {
1992
+ name: "loanToken",
1993
+ type: "address"
1994
+ },
1995
+ {
1996
+ name: "collaterals",
1997
+ type: "Collateral[]"
1998
+ },
1999
+ {
2000
+ name: "callback",
2001
+ type: "Callback"
2002
+ }
2003
+ ],
2004
+ Collateral: [
2005
+ {
2006
+ name: "asset",
2007
+ type: "address"
2008
+ },
2009
+ {
2010
+ name: "oracle",
2011
+ type: "address"
2012
+ },
2013
+ {
2014
+ name: "lltv",
2015
+ type: "uint256"
2016
+ }
2017
+ ],
2018
+ Callback: [{
2019
+ name: "address",
2020
+ type: "address"
2021
+ }, {
2022
+ name: "data",
2023
+ type: "bytes"
2024
+ }]
2025
+ };
2026
+ /**
2027
+ * Signs an array of offers.
2028
+ * @throws {Error} If the wallet account is not set.
2029
+ * @param offers - The offers to sign.
2030
+ * @param wallet - The wallet to sign the offers with.
2031
+ * @returns The signed offers.
2032
+ */
2033
+ async function sign(offers, wallet) {
2034
+ if (!wallet.account) throw new AccountNotSetError();
2035
+ return wallet.signMessage({
2036
+ account: wallet.account,
2037
+ message: { raw: signatureMsg(offers) }
2038
+ });
2039
+ }
2040
+ function signatureMsg(offers) {
2041
+ return from$8(offers).root;
2042
+ }
2043
+ function hash(offer) {
2044
+ const cached = offer[HASH_CACHE];
2045
+ if (cached) return cached;
2046
+ const computed = hashTypedData({
2047
+ domain: domain(offer.chainId),
2048
+ message: {
2049
+ maker: offer.maker.toLowerCase(),
2050
+ assets: offer.assets,
2051
+ obligationUnits: offer.obligationUnits,
2052
+ obligationShares: offer.obligationShares,
2053
+ price: offer.price,
2054
+ maturity: BigInt(offer.maturity),
2055
+ expiry: BigInt(offer.expiry),
2056
+ group: offer.group,
2057
+ session: offer.session,
2058
+ buy: offer.buy,
2059
+ loanToken: offer.loanToken.toLowerCase(),
2060
+ collaterals: offer.collaterals,
2061
+ callback: {
2062
+ address: offer.callback.address.toLowerCase(),
2063
+ data: offer.callback.data
2064
+ }
2065
+ },
2066
+ primaryType: "Offer",
2067
+ types
2068
+ });
2069
+ offer[HASH_CACHE] = computed;
2070
+ return computed;
2071
+ }
2072
+ /**
2073
+ * Calculates the obligation id for an offer based on the smart contract's Obligation struct.
2074
+ * The id is computed as keccak256(abi.encode(chainId, loanToken, collaterals (sorted by token address), maturity)).
2075
+ * @param offer - The offer to calculate the obligation id for.
2076
+ * @returns The obligation id as a 32-byte hex string.
2077
+ */
2078
+ function obligationId(offer) {
2079
+ return id(from$9({
2080
+ chainId: offer.chainId,
2081
+ loanToken: offer.loanToken,
2082
+ collaterals: offer.collaterals,
2083
+ maturity: offer.maturity
2084
+ }));
2085
+ }
2086
+ const OfferAbi = [
2087
+ {
2088
+ name: "maker",
2089
+ type: "address"
2090
+ },
2091
+ {
2092
+ name: "assets",
2093
+ type: "uint256"
2094
+ },
2095
+ {
2096
+ name: "obligationUnits",
2097
+ type: "uint256"
2098
+ },
2099
+ {
2100
+ name: "obligationShares",
2101
+ type: "uint256"
2102
+ },
2103
+ {
2104
+ name: "price",
2105
+ type: "uint256"
2106
+ },
2107
+ {
2108
+ name: "maturity",
2109
+ type: "uint256"
2110
+ },
2111
+ {
2112
+ name: "expiry",
2113
+ type: "uint256"
2114
+ },
2115
+ {
2116
+ name: "group",
2117
+ type: "bytes32"
2118
+ },
2119
+ {
2120
+ name: "session",
2121
+ type: "bytes32"
2122
+ },
2123
+ {
2124
+ name: "buy",
2125
+ type: "bool"
2126
+ },
2127
+ {
2128
+ name: "chainId",
2129
+ type: "uint256"
2130
+ },
2131
+ {
2132
+ name: "loanToken",
2774
2133
  type: "address"
2775
- }],
2776
- Offer: [
2777
- {
2778
- name: "offering",
2779
- type: "address"
2780
- },
2781
- {
2782
- name: "assets",
2783
- type: "uint256"
2784
- },
2785
- {
2786
- name: "rate",
2787
- type: "uint256"
2788
- },
2789
- {
2790
- name: "maturity",
2791
- type: "uint256"
2792
- },
2793
- {
2794
- name: "expiry",
2795
- type: "uint256"
2796
- },
2797
- {
2798
- name: "nonce",
2799
- type: "uint256"
2800
- },
2801
- {
2802
- name: "buy",
2803
- type: "bool"
2804
- },
2805
- {
2806
- name: "loanToken",
2134
+ },
2135
+ {
2136
+ name: "start",
2137
+ type: "uint256"
2138
+ },
2139
+ {
2140
+ name: "collaterals",
2141
+ type: "tuple[]",
2142
+ components: [
2143
+ {
2144
+ name: "asset",
2145
+ type: "address"
2146
+ },
2147
+ {
2148
+ name: "oracle",
2149
+ type: "address"
2150
+ },
2151
+ {
2152
+ name: "lltv",
2153
+ type: "uint256"
2154
+ }
2155
+ ]
2156
+ },
2157
+ {
2158
+ name: "callback",
2159
+ type: "tuple",
2160
+ components: [{
2161
+ name: "address",
2807
2162
  type: "address"
2808
- },
2809
- {
2810
- name: "collaterals",
2811
- type: "Collateral[]"
2812
- },
2813
- {
2814
- name: "callback",
2815
- type: "Callback"
2163
+ }, {
2164
+ name: "data",
2165
+ type: "bytes"
2166
+ }]
2167
+ }
2168
+ ];
2169
+ function encode(offer) {
2170
+ return encodeAbiParameters(OfferAbi, [
2171
+ offer.maker,
2172
+ offer.assets,
2173
+ offer.obligationUnits,
2174
+ offer.obligationShares,
2175
+ offer.price,
2176
+ BigInt(offer.maturity),
2177
+ BigInt(offer.expiry),
2178
+ offer.group,
2179
+ offer.session,
2180
+ offer.buy,
2181
+ BigInt(offer.chainId),
2182
+ offer.loanToken,
2183
+ BigInt(offer.start),
2184
+ offer.collaterals,
2185
+ offer.callback
2186
+ ]);
2187
+ }
2188
+ function decode(data) {
2189
+ let decoded;
2190
+ try {
2191
+ decoded = decodeAbiParameters(OfferAbi, data);
2192
+ } catch (error) {
2193
+ throw new InvalidOfferError(error);
2194
+ }
2195
+ return from$7({
2196
+ maker: decoded[0],
2197
+ assets: decoded[1],
2198
+ obligationUnits: decoded[2],
2199
+ obligationShares: decoded[3],
2200
+ price: decoded[4],
2201
+ maturity: from$10(Number(decoded[5])),
2202
+ expiry: Number(decoded[6]),
2203
+ group: decoded[7],
2204
+ session: decoded[8],
2205
+ buy: decoded[9],
2206
+ chainId: Number(decoded[10]),
2207
+ loanToken: decoded[11],
2208
+ start: Number(decoded[12]),
2209
+ collaterals: decoded[13].map((c) => {
2210
+ return from$11({
2211
+ asset: c.asset,
2212
+ oracle: c.oracle,
2213
+ lltv: c.lltv
2214
+ });
2215
+ }),
2216
+ callback: {
2217
+ address: decoded[14].address,
2218
+ data: decoded[14].data
2816
2219
  }
2817
- ],
2818
- Collateral: [
2220
+ });
2221
+ }
2222
+ /**
2223
+ * ABI for the Consume event emitted by the Obligation contract.
2224
+ */
2225
+ const consumedEvent = {
2226
+ type: "event",
2227
+ name: "Consume",
2228
+ inputs: [
2819
2229
  {
2820
- name: "asset",
2821
- type: "address"
2230
+ name: "user",
2231
+ type: "address",
2232
+ indexed: true,
2233
+ internalType: "address"
2822
2234
  },
2823
2235
  {
2824
- name: "oracle",
2825
- type: "address"
2236
+ name: "group",
2237
+ type: "bytes32",
2238
+ indexed: true,
2239
+ internalType: "bytes32"
2826
2240
  },
2827
2241
  {
2828
- name: "lltv",
2829
- type: "uint256"
2242
+ name: "amount",
2243
+ type: "uint256",
2244
+ indexed: false,
2245
+ internalType: "uint256"
2830
2246
  }
2831
2247
  ],
2832
- Callback: [
2833
- {
2834
- name: "address",
2835
- type: "address"
2836
- },
2837
- {
2838
- name: "data",
2839
- type: "bytes"
2840
- },
2841
- {
2842
- name: "gasLimit",
2843
- type: "uint256"
2844
- }
2845
- ]
2248
+ anonymous: false
2249
+ };
2250
+ var InvalidOfferError = class InvalidOfferError extends BaseError {
2251
+ constructor(error) {
2252
+ super("Invalid offer.", { cause: error });
2253
+ _defineProperty(this, "name", "Offer.InvalidOfferError");
2254
+ }
2255
+ /**
2256
+ * Formats ZodError issues into a human-readable string with line breaks.
2257
+ * @example
2258
+ * "- 'assets': too small, expected >= 0
2259
+ * - 'start': must be before expiry"
2260
+ */
2261
+ static formatDetails(error) {
2262
+ if (!(error instanceof z$1.ZodError)) return error.message;
2263
+ return error.issues.map((issue) => {
2264
+ return `'${issue.path.join(".")}': ${issue.message.trim().toLowerCase()}`;
2265
+ }).join(". ");
2266
+ }
2267
+ /**
2268
+ * Returns the formatted human-readable message.
2269
+ */
2270
+ get formattedMessage() {
2271
+ return `Invalid offer. ${InvalidOfferError.formatDetails(this.cause)}`;
2272
+ }
2273
+ };
2274
+ var AccountNotSetError = class extends BaseError {
2275
+ constructor() {
2276
+ super("Account not set.");
2277
+ _defineProperty(this, "name", "Offer.AccountNotSetError");
2278
+ }
2846
2279
  };
2280
+
2281
+ //#endregion
2282
+ //#region src/core/Oracle.ts
2283
+ var Oracle_exports = /* @__PURE__ */ __export({
2284
+ Conversion: () => Conversion,
2285
+ from: () => from$6
2286
+ });
2847
2287
  /**
2848
- * Signs an array of offers.
2849
- * @throws {Error} If the wallet account is not set.
2850
- * @param offers - The offers to sign.
2851
- * @param wallet - The wallet to sign the offers with.
2852
- * @returns The signed offers.
2288
+ * Create an Oracle from a plain object.
2289
+ * @param data - The data to create the oracle from.
2290
+ * @returns The created oracle.
2291
+ */
2292
+ function from$6(data) {
2293
+ return {
2294
+ chainId: data.chainId,
2295
+ address: data.address.toLowerCase(),
2296
+ price: data.price ? BigInt(data.price) : null,
2297
+ blockNumber: data.blockNumber
2298
+ };
2299
+ }
2300
+ let Conversion;
2301
+ (function(_Conversion) {
2302
+ function collateralToLoan(amount, params) {
2303
+ return amount * params.price / 10n ** 36n * params.lltv / 10n ** 18n;
2304
+ }
2305
+ _Conversion.collateralToLoan = collateralToLoan;
2306
+ function loanToCollateral(amount, params) {
2307
+ if (params.price === 0n || params.lltv === 0n) return 0n;
2308
+ return amount * 10n ** 36n / params.price * 10n ** 18n / params.lltv;
2309
+ }
2310
+ _Conversion.loanToCollateral = loanToCollateral;
2311
+ })(Conversion || (Conversion = {}));
2312
+
2313
+ //#endregion
2314
+ //#region src/core/Position.ts
2315
+ var Position_exports = /* @__PURE__ */ __export({
2316
+ Type: () => Type,
2317
+ from: () => from$5
2318
+ });
2319
+ let Type = /* @__PURE__ */ function(Type$1) {
2320
+ Type$1["ERC20"] = "erc20";
2321
+ Type$1["VAULT_V1"] = "vault_v1";
2322
+ return Type$1;
2323
+ }({});
2324
+ /**
2325
+ * @constructor
2326
+ * Creates a Position.
2327
+ * @param parameters - {@link from.Parameters}
2328
+ * @returns The created Position. {@link from.ReturnType}
2329
+ */
2330
+ function from$5(parameters) {
2331
+ return {
2332
+ chainId: parameters.chainId,
2333
+ contract: parameters.contract.toLowerCase(),
2334
+ user: parameters.user.toLowerCase(),
2335
+ type: parameters.type,
2336
+ balance: parameters.balance,
2337
+ ...parameters.asset !== void 0 ? { asset: parameters.asset.toLowerCase() } : {},
2338
+ blockNumber: parameters.blockNumber
2339
+ };
2340
+ }
2341
+
2342
+ //#endregion
2343
+ //#region src/core/Quote.ts
2344
+ var Quote_exports = /* @__PURE__ */ __export({
2345
+ InvalidQuoteError: () => InvalidQuoteError,
2346
+ QuoteSchema: () => QuoteSchema,
2347
+ from: () => from$4,
2348
+ fromSnakeCase: () => fromSnakeCase,
2349
+ random: () => random
2350
+ });
2351
+ const QuoteSchema = z$1.object({
2352
+ obligationId: z$1.string().transform(transformHex),
2353
+ ask: z$1.object({ price: z$1.bigint({ coerce: true }).min(0n).max(maxUint256) }),
2354
+ bid: z$1.object({ price: z$1.bigint({ coerce: true }).min(0n).max(maxUint256) })
2355
+ });
2356
+ /**
2357
+ * Creates a quote for a given obligation.
2358
+ * @constructor
2359
+ * @param parameters - {@link from.Parameters}
2360
+ * @returns The created quote. {@link Quote}
2361
+ * @throws If the quote is invalid. {@link InvalidQuoteError}
2362
+ *
2363
+ * @example
2364
+ * ```ts
2365
+ * const quote = Quote.from({ obligationId: "0x123", ask: { price: 100n }, bid: { price: 100n } });
2366
+ * ```
2853
2367
  */
2854
- async function sign(offers, wallet) {
2855
- if (!wallet.account) throw new AccountNotSetError();
2856
- return wallet.signMessage({
2857
- account: wallet.account,
2858
- message: { raw: signatureMsg(offers) }
2859
- });
2368
+ function from$4(parameters) {
2369
+ try {
2370
+ const parsedQuote = QuoteSchema.parse(parameters);
2371
+ return {
2372
+ obligationId: parsedQuote.obligationId,
2373
+ ask: parsedQuote.ask,
2374
+ bid: parsedQuote.bid
2375
+ };
2376
+ } catch (error) {
2377
+ throw new InvalidQuoteError(error);
2378
+ }
2860
2379
  }
2861
- function signatureMsg(offers) {
2862
- return from$6(offers).root;
2380
+ /**
2381
+ * Creates a quote from a snake case object.
2382
+ * @throws If the quote is invalid. {@link InvalidQuoteError}
2383
+ * @param snake - {@link fromSnakeCase.Parameters}
2384
+ * @returns The created quote. {@link fromSnakeCase.ReturnType}
2385
+ */
2386
+ function fromSnakeCase(snake) {
2387
+ return from$4(fromSnakeCase$3(snake));
2863
2388
  }
2864
- function hash(offer) {
2865
- return hashTypedData({
2866
- domain: domain(offer.chainId),
2867
- message: {
2868
- offering: offer.offering.toLowerCase(),
2869
- assets: offer.assets,
2870
- rate: offer.rate,
2871
- maturity: BigInt(offer.maturity),
2872
- expiry: BigInt(offer.expiry),
2873
- nonce: offer.nonce,
2874
- buy: offer.buy,
2875
- loanToken: offer.loanToken.toLowerCase(),
2876
- collaterals: offer.collaterals,
2877
- callback: {
2878
- address: offer.callback.address.toLowerCase(),
2879
- data: offer.callback.data,
2880
- gasLimit: offer.callback.gasLimit
2881
- }
2882
- },
2883
- primaryType: "Offer",
2884
- types
2389
+ /**
2390
+ * Generates a random quote.
2391
+ * @returns A randomly generated quote. {@link random.ReturnType}
2392
+ *
2393
+ * @example
2394
+ * ```ts
2395
+ * const quote = Quote.random();
2396
+ * ```
2397
+ */
2398
+ function random() {
2399
+ return from$4({
2400
+ obligationId: id(random$2()),
2401
+ ask: { price: BigInt(int(1e6)) },
2402
+ bid: { price: BigInt(int(1e6)) }
2885
2403
  });
2886
2404
  }
2405
+ var InvalidQuoteError = class extends BaseError {
2406
+ constructor(error) {
2407
+ super("Invalid quote.", { cause: error });
2408
+ _defineProperty(this, "name", "Quote.InvalidQuoteError");
2409
+ }
2410
+ };
2411
+
2412
+ //#endregion
2413
+ //#region src/core/Transfer.ts
2414
+ var Transfer_exports = /* @__PURE__ */ __export({ from: () => from$3 });
2887
2415
  /**
2888
- * Calculates the obligation id for an offer based on the smart contract's Obligation struct.
2889
- * The id is computed as keccak256(abi.encode(chainId, loanToken, collaterals (sorted by token address), maturity)).
2890
- * @param offer - The offer to calculate the obligation id for.
2891
- * @returns The obligation id as a 32-byte hex string.
2416
+ * @constructor
2417
+ *
2418
+ * Creates a {@link Transfer}.
2419
+ * @param parameters - {@link from.Parameters}
2420
+ * @returns The created Transfer. {@link from.ReturnType}
2421
+ *
2422
+ * @example
2423
+ * ```ts
2424
+ * const transfer = Transfer.from({ id: "1", chainId: 1, contract: "0x123", from: "0x456", to: "0x789", value: 100n, blockNumber: 100n });
2425
+ * ```
2892
2426
  */
2893
- function obligationId(offer) {
2894
- return id(from$7({
2895
- chainId: offer.chainId,
2896
- loanToken: offer.loanToken,
2897
- collaterals: offer.collaterals,
2898
- maturity: offer.maturity
2899
- }));
2427
+ function from$3(parameters) {
2428
+ return {
2429
+ id: parameters.id,
2430
+ chainId: parameters.chainId,
2431
+ contract: parameters.contract.toLowerCase(),
2432
+ from: parameters.from.toLowerCase(),
2433
+ to: parameters.to.toLowerCase(),
2434
+ value: parameters.value,
2435
+ blockNumber: parameters.blockNumber
2436
+ };
2900
2437
  }
2901
- const OfferAbi = [
2902
- {
2903
- name: "offering",
2904
- type: "address"
2905
- },
2906
- {
2907
- name: "assets",
2908
- type: "uint256"
2909
- },
2910
- {
2911
- name: "rate",
2912
- type: "uint256"
2913
- },
2914
- {
2915
- name: "maturity",
2916
- type: "uint256"
2917
- },
2918
- {
2919
- name: "expiry",
2920
- type: "uint256"
2921
- },
2922
- {
2923
- name: "nonce",
2924
- type: "uint256"
2925
- },
2926
- {
2927
- name: "buy",
2928
- type: "bool"
2929
- },
2930
- {
2931
- name: "chainId",
2932
- type: "uint256"
2933
- },
2934
- {
2935
- name: "loanToken",
2936
- type: "address"
2937
- },
2938
- {
2939
- name: "start",
2940
- type: "uint256"
2941
- },
2942
- {
2943
- name: "collaterals",
2944
- type: "tuple[]",
2945
- components: [
2946
- {
2947
- name: "asset",
2948
- type: "address"
2949
- },
2950
- {
2951
- name: "oracle",
2952
- type: "address"
2953
- },
2954
- {
2955
- name: "lltv",
2956
- type: "uint256"
2957
- }
2958
- ]
2959
- },
2960
- {
2961
- name: "callback",
2962
- type: "tuple",
2963
- components: [
2964
- {
2965
- name: "address",
2966
- type: "address"
2967
- },
2968
- {
2969
- name: "data",
2970
- type: "bytes"
2438
+
2439
+ //#endregion
2440
+ //#region src/core/types.ts
2441
+ const BrandTypeId = Symbol.for("mempool/Brand");
2442
+
2443
+ //#endregion
2444
+ //#region src/api/Schema/OfferResponse.ts
2445
+ var OfferResponse_exports = /* @__PURE__ */ __export({ from: () => from$2 });
2446
+ /**
2447
+ * Creates an `OfferResponse` matching the Solidity Offer struct layout.
2448
+ * @constructor
2449
+ * @param input - {@link Input}
2450
+ * @returns The created `OfferResponse`. {@link OfferResponse}
2451
+ */
2452
+ function from$2(input) {
2453
+ const base$1 = {
2454
+ offer: {
2455
+ obligation: {
2456
+ loan_token: input.loanToken,
2457
+ collaterals: input.collaterals.map((c) => ({
2458
+ token: c.asset,
2459
+ lltv: c.lltv.toString(),
2460
+ oracle: c.oracle
2461
+ })),
2462
+ maturity: input.maturity
2971
2463
  },
2972
- {
2973
- name: "gasLimit",
2974
- type: "uint256"
2975
- }
2976
- ]
2977
- },
2978
- {
2979
- name: "signature",
2980
- type: "bytes"
2981
- }
2464
+ buy: input.buy,
2465
+ maker: input.maker,
2466
+ assets: input.assets.toString(),
2467
+ obligation_units: input.obligationUnits.toString(),
2468
+ obligation_shares: input.obligationShares.toString(),
2469
+ start: input.start,
2470
+ expiry: input.expiry,
2471
+ price: input.price.toString(),
2472
+ group: input.group,
2473
+ session: input.session,
2474
+ callback: input.callback.address,
2475
+ callback_data: input.callback.data
2476
+ },
2477
+ offer_hash: input.hash,
2478
+ obligation_id: id({
2479
+ chainId: input.chainId,
2480
+ loanToken: input.loanToken,
2481
+ collaterals: [...input.collaterals],
2482
+ maturity: input.maturity
2483
+ }),
2484
+ chain_id: input.chainId,
2485
+ consumed: input.consumed.toString(),
2486
+ takeable: input.takeable.toString(),
2487
+ block_number: input.blockNumber
2488
+ };
2489
+ if (!input.proof || !input.root || !input.signature) return {
2490
+ ...base$1,
2491
+ root: null,
2492
+ proof: null,
2493
+ signature: null
2494
+ };
2495
+ return {
2496
+ ...base$1,
2497
+ root: input.root.toLowerCase(),
2498
+ proof: input.proof.map((p) => p.toLowerCase()),
2499
+ signature: input.signature.toLowerCase()
2500
+ };
2501
+ }
2502
+
2503
+ //#endregion
2504
+ //#region src/api/Controllers/Payload.ts
2505
+ const API_ERROR_CODES = [
2506
+ "VALIDATION_ERROR",
2507
+ "NOT_FOUND",
2508
+ "INTERNAL_SERVER_ERROR",
2509
+ "BAD_REQUEST"
2982
2510
  ];
2983
- function encode(offer) {
2984
- return encodeAbiParameters(OfferAbi, [
2985
- offer.offering,
2986
- offer.assets,
2987
- offer.rate,
2988
- BigInt(offer.maturity),
2989
- BigInt(offer.expiry),
2990
- offer.nonce,
2991
- offer.buy,
2992
- BigInt(offer.chainId),
2993
- offer.loanToken,
2994
- BigInt(offer.start),
2995
- offer.collaterals,
2996
- offer.callback,
2997
- offer.signature ?? "0x"
2998
- ]);
2511
+
2512
+ //#endregion
2513
+ //#region \0@oxc-project+runtime@0.97.0/helpers/decorate.js
2514
+ function __decorate(decorators, target, key, desc) {
2515
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2516
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2517
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2518
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2999
2519
  }
3000
- function decode(data, blockNumber) {
3001
- let decoded;
3002
- try {
3003
- decoded = decodeAbiParameters(OfferAbi, data);
3004
- } catch (error) {
3005
- throw new InvalidOfferError(error);
2520
+
2521
+ //#endregion
2522
+ //#region src/api/Schema/openapi.ts
2523
+ const timestampExample = "2024-01-01T12:00:00.000Z";
2524
+ const offerCursorExample = "eyJvZmZzZXQiOjEwMH0";
2525
+ const obligationCursorExample = "0x25690ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9abc";
2526
+ const offerExample = {
2527
+ offer: {
2528
+ obligation: {
2529
+ loan_token: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
2530
+ collaterals: [{
2531
+ token: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
2532
+ lltv: "860000000000000000",
2533
+ oracle: "0x45093658BE7f90B63D7c359e8f408e503c2D9401"
2534
+ }],
2535
+ maturity: 1761922799
2536
+ },
2537
+ buy: false,
2538
+ maker: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
2539
+ assets: "369216000000000000000000",
2540
+ obligation_units: "0",
2541
+ obligation_shares: "0",
2542
+ start: 1761922790,
2543
+ expiry: 1761922799,
2544
+ price: "2750000000000000000",
2545
+ group: "0x000000000000000000000000000000000000000000000000000000000008b8f4",
2546
+ session: "0x0000000000000000000000000000000000000000000000000000000000000000",
2547
+ callback: "0x1111111111111111111111111111111111111111",
2548
+ callback_data: "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000034cf890db685fc536e05652fb41f02090c3fb751000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000108e644e3ab01184155270aa92a00000000000"
2549
+ },
2550
+ offer_hash: "0xac4bd8318ec914f89f8af913f162230575b0ac0696a19256bc12138c5cfe1427",
2551
+ obligation_id: "0x25690ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9abc",
2552
+ chain_id: 1,
2553
+ consumed: "0",
2554
+ takeable: "369216000000000000000000",
2555
+ block_number: 0xa7495128adfb1,
2556
+ root: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
2557
+ proof: ["0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "0x9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba"],
2558
+ signature: "0x1234567890123456789012345678901234567890123456789012345678901234123456789012345678901234567890123456789012345678901234567890123400"
2559
+ };
2560
+ const collectorsHealthExample = {
2561
+ name: "offers",
2562
+ chain_id: 1,
2563
+ block_number: 21345678,
2564
+ updated_at: timestampExample,
2565
+ lag: 0,
2566
+ status: "live",
2567
+ initialized: true
2568
+ };
2569
+ const chainsHealthExample = {
2570
+ chain_id: 1,
2571
+ local_block_number: 21345678,
2572
+ remote_block_number: 21345690,
2573
+ updated_at: timestampExample,
2574
+ initialized: true
2575
+ };
2576
+ const missingCollectorExample = {
2577
+ chain_id: 1,
2578
+ name: "offers"
2579
+ };
2580
+ const validateOfferExample = {
2581
+ maker: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
2582
+ assets: "369216000000000000000000",
2583
+ obligation_units: "0",
2584
+ obligation_shares: "0",
2585
+ price: "2750000000000000000",
2586
+ maturity: 1761922799,
2587
+ expiry: 1761922799,
2588
+ start: 1761922790,
2589
+ group: "0x000000000000000000000000000000000000000000000000000000000008b8f4",
2590
+ session: "0x0000000000000000000000000000000000000000000000000000000000000000",
2591
+ buy: false,
2592
+ chain_id: 1,
2593
+ loan_token: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
2594
+ collaterals: [{
2595
+ asset: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
2596
+ oracle: "0x45093658BE7f90B63D7c359e8f408e503c2D9401",
2597
+ lltv: "860000000000000000"
2598
+ }],
2599
+ callback: {
2600
+ address: "0x1111111111111111111111111111111111111111",
2601
+ data: "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000034cf890db685fc536e05652fb41f02090c3fb751000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000108e644e3ab01184155270aa92a00000000000"
3006
2602
  }
3007
- return from$5({
3008
- offering: decoded[0],
3009
- assets: decoded[1],
3010
- rate: decoded[2],
3011
- maturity: from$8(Number(decoded[3])),
3012
- expiry: Number(decoded[4]),
3013
- nonce: decoded[5],
3014
- buy: decoded[6],
3015
- chainId: Number(decoded[7]),
3016
- loanToken: decoded[8],
3017
- start: Number(decoded[9]),
3018
- collaterals: decoded[10].map((c) => {
3019
- return from$9({
3020
- asset: c.asset,
3021
- oracle: c.oracle,
3022
- lltv: c.lltv
3023
- });
3024
- }),
3025
- callback: {
3026
- address: decoded[11].address,
3027
- data: decoded[11].data,
3028
- gasLimit: decoded[11].gasLimit
3029
- },
3030
- consumed: 0n,
3031
- blockNumber: Number(blockNumber),
3032
- takeable: decoded[1],
3033
- ...decoded[12] === "0x" ? {} : { signature: decoded[12] }
3034
- });
3035
- }
3036
- /**
3037
- * ABI for the Consumed event emitted by the Obligation contract.
3038
- */
3039
- const consumedEvent = {
3040
- type: "event",
3041
- name: "Consumed",
3042
- inputs: [
3043
- {
3044
- name: "user",
3045
- type: "address",
3046
- indexed: true,
3047
- internalType: "address"
3048
- },
3049
- {
3050
- name: "nonce",
3051
- type: "uint256",
3052
- indexed: true,
3053
- internalType: "uint256"
3054
- },
3055
- {
3056
- name: "amount",
3057
- type: "uint256",
3058
- indexed: false,
3059
- internalType: "uint256"
3060
- }
2603
+ };
2604
+ const routerStatusExample = {
2605
+ status: "live",
2606
+ initialized: true,
2607
+ missing_chains: [],
2608
+ missing_collectors: []
2609
+ };
2610
+ var Meta = class {};
2611
+ __decorate([ApiProperty({
2612
+ type: "string",
2613
+ example: timestampExample
2614
+ })], Meta.prototype, "timestamp", void 0);
2615
+ var SuccessResponse = class {};
2616
+ __decorate([ApiProperty({ type: () => Meta })], SuccessResponse.prototype, "meta", void 0);
2617
+ var ErrorResponse = class {};
2618
+ __decorate([ApiProperty({
2619
+ type: "string",
2620
+ enum: API_ERROR_CODES,
2621
+ example: "VALIDATION_ERROR"
2622
+ })], ErrorResponse.prototype, "code", void 0);
2623
+ __decorate([ApiProperty({
2624
+ type: "string",
2625
+ example: "Limit must be greater than 0."
2626
+ })], ErrorResponse.prototype, "message", void 0);
2627
+ __decorate([ApiProperty({
2628
+ type: "object",
2629
+ example: [{
2630
+ field: "limit",
2631
+ issue: "Limit must be greater than 0."
2632
+ }]
2633
+ })], ErrorResponse.prototype, "details", void 0);
2634
+ var BadRequestResponse = class {};
2635
+ __decorate([ApiProperty({ type: () => ErrorResponse })], BadRequestResponse.prototype, "error", void 0);
2636
+ __decorate([ApiProperty({ type: () => Meta })], BadRequestResponse.prototype, "meta", void 0);
2637
+ var CollateralResponse = class {};
2638
+ __decorate([ApiProperty({
2639
+ type: "string",
2640
+ example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751"
2641
+ })], CollateralResponse.prototype, "token", void 0);
2642
+ __decorate([ApiProperty({
2643
+ type: "string",
2644
+ example: "860000000000000000"
2645
+ })], CollateralResponse.prototype, "lltv", void 0);
2646
+ __decorate([ApiProperty({
2647
+ type: "string",
2648
+ example: "0x45093658BE7f90B63D7c359e8f408e503c2D9401"
2649
+ })], CollateralResponse.prototype, "oracle", void 0);
2650
+ var ValidateCollateralRequest = class {};
2651
+ __decorate([ApiProperty({
2652
+ type: "string",
2653
+ example: validateOfferExample.collaterals[0].asset
2654
+ })], ValidateCollateralRequest.prototype, "asset", void 0);
2655
+ __decorate([ApiProperty({
2656
+ type: "string",
2657
+ example: validateOfferExample.collaterals[0].oracle
2658
+ })], ValidateCollateralRequest.prototype, "oracle", void 0);
2659
+ __decorate([ApiProperty({
2660
+ type: "string",
2661
+ example: validateOfferExample.collaterals[0].lltv
2662
+ })], ValidateCollateralRequest.prototype, "lltv", void 0);
2663
+ var ValidateCallbackRequest = class {};
2664
+ __decorate([ApiProperty({
2665
+ type: "string",
2666
+ example: validateOfferExample.callback.address
2667
+ })], ValidateCallbackRequest.prototype, "address", void 0);
2668
+ __decorate([ApiProperty({
2669
+ type: "string",
2670
+ example: validateOfferExample.callback.data
2671
+ })], ValidateCallbackRequest.prototype, "data", void 0);
2672
+ var AskResponse = class {};
2673
+ __decorate([ApiProperty({
2674
+ type: "string",
2675
+ example: "1000000000000000000"
2676
+ })], AskResponse.prototype, "price", void 0);
2677
+ var BidResponse = class {};
2678
+ __decorate([ApiProperty({
2679
+ type: "string",
2680
+ example: "1000000000000000000"
2681
+ })], BidResponse.prototype, "price", void 0);
2682
+ var ObligationOfferResponse = class {};
2683
+ __decorate([ApiProperty({
2684
+ type: "string",
2685
+ example: offerExample.offer.obligation.loan_token
2686
+ })], ObligationOfferResponse.prototype, "loan_token", void 0);
2687
+ __decorate([ApiProperty({
2688
+ type: () => [CollateralResponse],
2689
+ example: offerExample.offer.obligation.collaterals
2690
+ })], ObligationOfferResponse.prototype, "collaterals", void 0);
2691
+ __decorate([ApiProperty({
2692
+ type: "number",
2693
+ example: offerExample.offer.obligation.maturity
2694
+ })], ObligationOfferResponse.prototype, "maturity", void 0);
2695
+ var OfferDataResponse = class {};
2696
+ __decorate([ApiProperty({
2697
+ type: () => ObligationOfferResponse,
2698
+ example: offerExample.offer.obligation
2699
+ })], OfferDataResponse.prototype, "obligation", void 0);
2700
+ __decorate([ApiProperty({
2701
+ type: "boolean",
2702
+ example: offerExample.offer.buy
2703
+ })], OfferDataResponse.prototype, "buy", void 0);
2704
+ __decorate([ApiProperty({
2705
+ type: "string",
2706
+ example: offerExample.offer.maker
2707
+ })], OfferDataResponse.prototype, "maker", void 0);
2708
+ __decorate([ApiProperty({
2709
+ type: "string",
2710
+ example: offerExample.offer.assets
2711
+ })], OfferDataResponse.prototype, "assets", void 0);
2712
+ __decorate([ApiProperty({
2713
+ type: "string",
2714
+ example: offerExample.offer.obligation_units
2715
+ })], OfferDataResponse.prototype, "obligation_units", void 0);
2716
+ __decorate([ApiProperty({
2717
+ type: "string",
2718
+ example: offerExample.offer.obligation_shares
2719
+ })], OfferDataResponse.prototype, "obligation_shares", void 0);
2720
+ __decorate([ApiProperty({
2721
+ type: "number",
2722
+ example: offerExample.offer.start
2723
+ })], OfferDataResponse.prototype, "start", void 0);
2724
+ __decorate([ApiProperty({
2725
+ type: "number",
2726
+ example: offerExample.offer.expiry
2727
+ })], OfferDataResponse.prototype, "expiry", void 0);
2728
+ __decorate([ApiProperty({
2729
+ type: "string",
2730
+ example: offerExample.offer.price
2731
+ })], OfferDataResponse.prototype, "price", void 0);
2732
+ __decorate([ApiProperty({
2733
+ type: "string",
2734
+ example: offerExample.offer.group
2735
+ })], OfferDataResponse.prototype, "group", void 0);
2736
+ __decorate([ApiProperty({
2737
+ type: "string",
2738
+ example: offerExample.offer.session
2739
+ })], OfferDataResponse.prototype, "session", void 0);
2740
+ __decorate([ApiProperty({
2741
+ type: "string",
2742
+ example: offerExample.offer.callback
2743
+ })], OfferDataResponse.prototype, "callback", void 0);
2744
+ __decorate([ApiProperty({
2745
+ type: "string",
2746
+ example: offerExample.offer.callback_data
2747
+ })], OfferDataResponse.prototype, "callback_data", void 0);
2748
+ var OfferListItemResponse = class {};
2749
+ __decorate([ApiProperty({
2750
+ type: () => OfferDataResponse,
2751
+ example: offerExample.offer
2752
+ })], OfferListItemResponse.prototype, "offer", void 0);
2753
+ __decorate([ApiProperty({
2754
+ type: "string",
2755
+ example: offerExample.offer_hash
2756
+ })], OfferListItemResponse.prototype, "offer_hash", void 0);
2757
+ __decorate([ApiProperty({
2758
+ type: "string",
2759
+ example: offerExample.obligation_id
2760
+ })], OfferListItemResponse.prototype, "obligation_id", void 0);
2761
+ __decorate([ApiProperty({
2762
+ type: "number",
2763
+ example: offerExample.chain_id
2764
+ })], OfferListItemResponse.prototype, "chain_id", void 0);
2765
+ __decorate([ApiProperty({
2766
+ type: "string",
2767
+ example: offerExample.consumed
2768
+ })], OfferListItemResponse.prototype, "consumed", void 0);
2769
+ __decorate([ApiProperty({
2770
+ type: "string",
2771
+ example: offerExample.takeable
2772
+ })], OfferListItemResponse.prototype, "takeable", void 0);
2773
+ __decorate([ApiProperty({
2774
+ type: "number",
2775
+ example: offerExample.block_number
2776
+ })], OfferListItemResponse.prototype, "block_number", void 0);
2777
+ __decorate([ApiProperty({
2778
+ type: "string",
2779
+ nullable: true,
2780
+ example: offerExample.root
2781
+ })], OfferListItemResponse.prototype, "root", void 0);
2782
+ __decorate([ApiProperty({
2783
+ type: [String],
2784
+ nullable: true,
2785
+ example: offerExample.proof
2786
+ })], OfferListItemResponse.prototype, "proof", void 0);
2787
+ __decorate([ApiProperty({
2788
+ type: "string",
2789
+ nullable: true,
2790
+ example: offerExample.signature
2791
+ })], OfferListItemResponse.prototype, "signature", void 0);
2792
+ var ObligationResponse = class {};
2793
+ __decorate([ApiProperty({
2794
+ type: "string",
2795
+ example: "0x12590ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9f67"
2796
+ })], ObligationResponse.prototype, "id", void 0);
2797
+ __decorate([ApiProperty({
2798
+ type: "number",
2799
+ example: 1
2800
+ })], ObligationResponse.prototype, "chain_id", void 0);
2801
+ __decorate([ApiProperty({
2802
+ type: "string",
2803
+ example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078"
2804
+ })], ObligationResponse.prototype, "loan_token", void 0);
2805
+ __decorate([ApiProperty({ type: () => [CollateralResponse] })], ObligationResponse.prototype, "collaterals", void 0);
2806
+ __decorate([ApiProperty({
2807
+ type: "number",
2808
+ example: 1761922800
2809
+ })], ObligationResponse.prototype, "maturity", void 0);
2810
+ __decorate([ApiProperty({ type: () => AskResponse })], ObligationResponse.prototype, "ask", void 0);
2811
+ __decorate([ApiProperty({ type: () => BidResponse })], ObligationResponse.prototype, "bid", void 0);
2812
+ var ObligationListResponse = class extends SuccessResponse {};
2813
+ __decorate([ApiProperty({
2814
+ type: "string",
2815
+ nullable: true,
2816
+ example: obligationCursorExample
2817
+ })], ObligationListResponse.prototype, "cursor", void 0);
2818
+ __decorate([ApiProperty({
2819
+ type: () => [ObligationResponse],
2820
+ description: "List of obligations with takable offers."
2821
+ })], ObligationListResponse.prototype, "data", void 0);
2822
+ var ObligationSingleSuccessResponse = class extends SuccessResponse {};
2823
+ __decorate([ApiProperty({
2824
+ type: "string",
2825
+ nullable: true,
2826
+ example: null
2827
+ })], ObligationSingleSuccessResponse.prototype, "cursor", void 0);
2828
+ __decorate([ApiProperty({
2829
+ type: () => ObligationResponse,
2830
+ description: "Obligation details."
2831
+ })], ObligationSingleSuccessResponse.prototype, "data", void 0);
2832
+ var OfferListResponse = class extends SuccessResponse {};
2833
+ __decorate([ApiProperty({
2834
+ type: "string",
2835
+ nullable: true,
2836
+ example: offerCursorExample
2837
+ })], OfferListResponse.prototype, "cursor", void 0);
2838
+ __decorate([ApiProperty({
2839
+ type: () => [OfferListItemResponse],
2840
+ description: "Offers matching the provided filters.",
2841
+ example: [offerExample]
2842
+ })], OfferListResponse.prototype, "data", void 0);
2843
+ var MissingCollectorResponse = class {};
2844
+ __decorate([ApiProperty({
2845
+ type: "number",
2846
+ example: missingCollectorExample.chain_id
2847
+ })], MissingCollectorResponse.prototype, "chain_id", void 0);
2848
+ __decorate([ApiProperty({
2849
+ type: "string",
2850
+ example: missingCollectorExample.name
2851
+ })], MissingCollectorResponse.prototype, "name", void 0);
2852
+ var RouterStatusDataResponse = class {};
2853
+ __decorate([ApiProperty({
2854
+ type: "string",
2855
+ enum: ["live", "syncing"],
2856
+ example: routerStatusExample.status
2857
+ })], RouterStatusDataResponse.prototype, "status", void 0);
2858
+ __decorate([ApiProperty({
2859
+ type: "boolean",
2860
+ example: routerStatusExample.initialized
2861
+ })], RouterStatusDataResponse.prototype, "initialized", void 0);
2862
+ __decorate([ApiProperty({
2863
+ type: () => [Number],
2864
+ example: routerStatusExample.missing_chains,
2865
+ description: "Configured chain ids missing initialization rows."
2866
+ })], RouterStatusDataResponse.prototype, "missing_chains", void 0);
2867
+ __decorate([ApiProperty({
2868
+ type: () => [MissingCollectorResponse],
2869
+ example: routerStatusExample.missing_collectors,
2870
+ description: "Collectors missing initialization rows."
2871
+ })], RouterStatusDataResponse.prototype, "missing_collectors", void 0);
2872
+ var RouterStatusSuccessResponse = class extends SuccessResponse {};
2873
+ __decorate([ApiProperty({
2874
+ type: () => RouterStatusDataResponse,
2875
+ description: "Aggregated router status.",
2876
+ example: routerStatusExample
2877
+ })], RouterStatusSuccessResponse.prototype, "data", void 0);
2878
+ var CollectorHealthResponse = class {};
2879
+ __decorate([ApiProperty({
2880
+ type: "string",
2881
+ example: collectorsHealthExample.name
2882
+ })], CollectorHealthResponse.prototype, "name", void 0);
2883
+ __decorate([ApiProperty({
2884
+ type: "number",
2885
+ example: collectorsHealthExample.chain_id
2886
+ })], CollectorHealthResponse.prototype, "chain_id", void 0);
2887
+ __decorate([ApiProperty({
2888
+ type: "number",
2889
+ nullable: true,
2890
+ example: collectorsHealthExample.block_number
2891
+ })], CollectorHealthResponse.prototype, "block_number", void 0);
2892
+ __decorate([ApiProperty({
2893
+ type: "string",
2894
+ nullable: true,
2895
+ example: collectorsHealthExample.updated_at
2896
+ })], CollectorHealthResponse.prototype, "updated_at", void 0);
2897
+ __decorate([ApiProperty({
2898
+ type: "number",
2899
+ nullable: true,
2900
+ example: collectorsHealthExample.lag
2901
+ })], CollectorHealthResponse.prototype, "lag", void 0);
2902
+ __decorate([ApiProperty({
2903
+ type: "string",
2904
+ enum: [
2905
+ "live",
2906
+ "lagging",
2907
+ "unknown"
3061
2908
  ],
3062
- anonymous: false
2909
+ example: collectorsHealthExample.status
2910
+ })], CollectorHealthResponse.prototype, "status", void 0);
2911
+ __decorate([ApiProperty({
2912
+ type: "boolean",
2913
+ example: collectorsHealthExample.initialized
2914
+ })], CollectorHealthResponse.prototype, "initialized", void 0);
2915
+ var CollectorsHealthSuccessResponse = class extends SuccessResponse {};
2916
+ __decorate([ApiProperty({
2917
+ type: () => [CollectorHealthResponse],
2918
+ description: "Collectors health details and sync status.",
2919
+ example: [collectorsHealthExample]
2920
+ })], CollectorsHealthSuccessResponse.prototype, "data", void 0);
2921
+ var ChainHealthResponse = class {};
2922
+ __decorate([ApiProperty({
2923
+ type: "number",
2924
+ example: chainsHealthExample.chain_id
2925
+ })], ChainHealthResponse.prototype, "chain_id", void 0);
2926
+ __decorate([ApiProperty({
2927
+ type: "number",
2928
+ nullable: true,
2929
+ example: chainsHealthExample.local_block_number
2930
+ })], ChainHealthResponse.prototype, "local_block_number", void 0);
2931
+ __decorate([ApiProperty({
2932
+ type: "number",
2933
+ nullable: true,
2934
+ example: chainsHealthExample.remote_block_number
2935
+ })], ChainHealthResponse.prototype, "remote_block_number", void 0);
2936
+ __decorate([ApiProperty({
2937
+ type: "string",
2938
+ nullable: true,
2939
+ example: chainsHealthExample.updated_at
2940
+ })], ChainHealthResponse.prototype, "updated_at", void 0);
2941
+ __decorate([ApiProperty({
2942
+ type: "boolean",
2943
+ example: chainsHealthExample.initialized
2944
+ })], ChainHealthResponse.prototype, "initialized", void 0);
2945
+ var ChainsHealthSuccessResponse = class extends SuccessResponse {};
2946
+ __decorate([ApiProperty({
2947
+ type: () => [ChainHealthResponse],
2948
+ description: "Latest processed block per chain.",
2949
+ example: [chainsHealthExample]
2950
+ })], ChainsHealthSuccessResponse.prototype, "data", void 0);
2951
+ var ValidateOfferRequest = class {};
2952
+ __decorate([ApiProperty({
2953
+ type: "string",
2954
+ example: validateOfferExample.maker
2955
+ })], ValidateOfferRequest.prototype, "maker", void 0);
2956
+ __decorate([ApiProperty({
2957
+ type: "string",
2958
+ example: validateOfferExample.assets
2959
+ })], ValidateOfferRequest.prototype, "assets", void 0);
2960
+ __decorate([ApiProperty({
2961
+ type: "string",
2962
+ example: validateOfferExample.obligation_units,
2963
+ required: false
2964
+ })], ValidateOfferRequest.prototype, "obligation_units", void 0);
2965
+ __decorate([ApiProperty({
2966
+ type: "string",
2967
+ example: validateOfferExample.obligation_shares,
2968
+ required: false
2969
+ })], ValidateOfferRequest.prototype, "obligation_shares", void 0);
2970
+ __decorate([ApiProperty({
2971
+ type: "string",
2972
+ example: validateOfferExample.price
2973
+ })], ValidateOfferRequest.prototype, "price", void 0);
2974
+ __decorate([ApiProperty({
2975
+ type: "number",
2976
+ example: validateOfferExample.maturity
2977
+ })], ValidateOfferRequest.prototype, "maturity", void 0);
2978
+ __decorate([ApiProperty({
2979
+ type: "number",
2980
+ example: validateOfferExample.expiry
2981
+ })], ValidateOfferRequest.prototype, "expiry", void 0);
2982
+ __decorate([ApiProperty({
2983
+ type: "number",
2984
+ example: validateOfferExample.start
2985
+ })], ValidateOfferRequest.prototype, "start", void 0);
2986
+ __decorate([ApiProperty({
2987
+ type: "string",
2988
+ example: validateOfferExample.group
2989
+ })], ValidateOfferRequest.prototype, "group", void 0);
2990
+ __decorate([ApiProperty({
2991
+ type: "string",
2992
+ example: validateOfferExample.session
2993
+ })], ValidateOfferRequest.prototype, "session", void 0);
2994
+ __decorate([ApiProperty({
2995
+ type: "boolean",
2996
+ example: validateOfferExample.buy
2997
+ })], ValidateOfferRequest.prototype, "buy", void 0);
2998
+ __decorate([ApiProperty({
2999
+ type: "number",
3000
+ example: validateOfferExample.chain_id
3001
+ })], ValidateOfferRequest.prototype, "chain_id", void 0);
3002
+ __decorate([ApiProperty({
3003
+ type: "string",
3004
+ example: validateOfferExample.loan_token
3005
+ })], ValidateOfferRequest.prototype, "loan_token", void 0);
3006
+ __decorate([ApiProperty({
3007
+ type: () => [ValidateCollateralRequest],
3008
+ example: validateOfferExample.collaterals
3009
+ })], ValidateOfferRequest.prototype, "collaterals", void 0);
3010
+ __decorate([ApiProperty({
3011
+ type: () => ValidateCallbackRequest,
3012
+ example: validateOfferExample.callback
3013
+ })], ValidateOfferRequest.prototype, "callback", void 0);
3014
+ var ValidateOffersRequest = class {};
3015
+ __decorate([ApiProperty({
3016
+ type: () => [ValidateOfferRequest],
3017
+ description: "Array of offers in snake_case format. Required, non-empty.",
3018
+ required: true
3019
+ })], ValidateOffersRequest.prototype, "offers", void 0);
3020
+ var ValidationSuccessDataResponse = class {};
3021
+ __decorate([ApiProperty({
3022
+ type: "string",
3023
+ description: "Unsigned payload: version (1B) + gzip(offers) + root (32B).",
3024
+ example: "0x01789c..."
3025
+ })], ValidationSuccessDataResponse.prototype, "payload", void 0);
3026
+ __decorate([ApiProperty({
3027
+ type: "string",
3028
+ description: "Merkle tree root to sign with EIP-191.",
3029
+ example: "0xac4bd8318ec914f89f8af913f162230575b0ac0696a19256bc12138c5cfe1427"
3030
+ })], ValidationSuccessDataResponse.prototype, "root", void 0);
3031
+ var ValidationSuccessResponse = class extends SuccessResponse {};
3032
+ __decorate([ApiProperty({
3033
+ type: "string",
3034
+ nullable: true,
3035
+ example: null
3036
+ })], ValidationSuccessResponse.prototype, "cursor", void 0);
3037
+ __decorate([ApiProperty({
3038
+ type: () => ValidationSuccessDataResponse,
3039
+ description: "Payload and root for client-side signing."
3040
+ })], ValidationSuccessResponse.prototype, "data", void 0);
3041
+ var ValidationIssueResponse = class {};
3042
+ __decorate([ApiProperty({
3043
+ type: "number",
3044
+ description: "0-indexed position of the failed offer in the request array.",
3045
+ example: 0
3046
+ })], ValidationIssueResponse.prototype, "index", void 0);
3047
+ __decorate([ApiProperty({
3048
+ type: "string",
3049
+ description: "Gatekeeper rule name that rejected the offer.",
3050
+ example: "no_buy"
3051
+ })], ValidationIssueResponse.prototype, "rule", void 0);
3052
+ __decorate([ApiProperty({
3053
+ type: "string",
3054
+ description: "Human-readable rejection reason.",
3055
+ example: "Buy offers are not supported"
3056
+ })], ValidationIssueResponse.prototype, "message", void 0);
3057
+ var ValidationFailureDataResponse = class {};
3058
+ __decorate([ApiProperty({
3059
+ type: () => [ValidationIssueResponse],
3060
+ description: "List of validation issues. Returned when any offer fails validation."
3061
+ })], ValidationFailureDataResponse.prototype, "issues", void 0);
3062
+ var ValidationFailureResponse = class extends SuccessResponse {};
3063
+ __decorate([ApiProperty({
3064
+ type: "string",
3065
+ nullable: true,
3066
+ example: null
3067
+ })], ValidationFailureResponse.prototype, "cursor", void 0);
3068
+ __decorate([ApiProperty({
3069
+ type: () => ValidationFailureDataResponse,
3070
+ description: "List of validation issues. Returned when any offer fails validation."
3071
+ })], ValidationFailureResponse.prototype, "data", void 0);
3072
+ var BookLevelResponse = class {};
3073
+ __decorate([ApiProperty({
3074
+ type: "string",
3075
+ example: "2750000000000000000"
3076
+ })], BookLevelResponse.prototype, "price", void 0);
3077
+ __decorate([ApiProperty({
3078
+ type: "string",
3079
+ example: "369216000000000000000000"
3080
+ })], BookLevelResponse.prototype, "assets", void 0);
3081
+ __decorate([ApiProperty({
3082
+ type: "number",
3083
+ example: 5
3084
+ })], BookLevelResponse.prototype, "count", void 0);
3085
+ const positionExample = {
3086
+ chain_id: 1,
3087
+ contract: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
3088
+ user: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
3089
+ reserved: "200000000000000000000",
3090
+ block_number: 21345678
3091
+ };
3092
+ var PositionListItemResponse = class {};
3093
+ __decorate([ApiProperty({
3094
+ type: "number",
3095
+ example: positionExample.chain_id
3096
+ })], PositionListItemResponse.prototype, "chain_id", void 0);
3097
+ __decorate([ApiProperty({
3098
+ type: "string",
3099
+ example: positionExample.contract
3100
+ })], PositionListItemResponse.prototype, "contract", void 0);
3101
+ __decorate([ApiProperty({
3102
+ type: "string",
3103
+ example: positionExample.user
3104
+ })], PositionListItemResponse.prototype, "user", void 0);
3105
+ __decorate([ApiProperty({
3106
+ type: "string",
3107
+ example: positionExample.reserved
3108
+ })], PositionListItemResponse.prototype, "reserved", void 0);
3109
+ __decorate([ApiProperty({
3110
+ type: "number",
3111
+ example: positionExample.block_number
3112
+ })], PositionListItemResponse.prototype, "block_number", void 0);
3113
+ var PositionListResponse = class extends SuccessResponse {};
3114
+ __decorate([ApiProperty({
3115
+ type: "string",
3116
+ nullable: true,
3117
+ example: offerCursorExample
3118
+ })], PositionListResponse.prototype, "cursor", void 0);
3119
+ __decorate([ApiProperty({
3120
+ type: () => [PositionListItemResponse],
3121
+ description: "User positions with reserved balances from active offers.",
3122
+ example: [positionExample]
3123
+ })], PositionListResponse.prototype, "data", void 0);
3124
+ var BookListResponse = class extends SuccessResponse {};
3125
+ __decorate([ApiProperty({
3126
+ type: "string",
3127
+ nullable: true,
3128
+ example: offerCursorExample
3129
+ })], BookListResponse.prototype, "cursor", void 0);
3130
+ __decorate([ApiProperty({
3131
+ type: () => [BookLevelResponse],
3132
+ description: "Aggregated book levels grouped by computed price."
3133
+ })], BookListResponse.prototype, "data", void 0);
3134
+ let BooksController = class BooksController$1 {
3135
+ async getBook() {}
3136
+ };
3137
+ __decorate([
3138
+ ApiOperation({
3139
+ methods: ["get"],
3140
+ path: "/v1/books/{obligationId}/{side}",
3141
+ summary: "Get aggregated book",
3142
+ description: "Returns aggregated book data for a given obligation and side. Offers are grouped by computed price with summed takeable amounts. Book levels are sorted by price (ascending for buy side, descending for sell side)."
3143
+ }),
3144
+ ApiParam({
3145
+ name: "obligationId",
3146
+ type: "string",
3147
+ example: "0x12590ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9f67",
3148
+ description: "Obligation id."
3149
+ }),
3150
+ ApiParam({
3151
+ name: "side",
3152
+ type: "string",
3153
+ enum: ["buy", "sell"],
3154
+ example: "buy",
3155
+ description: "Book side (buy or sell)."
3156
+ }),
3157
+ ApiQuery({
3158
+ name: "cursor",
3159
+ type: "string",
3160
+ example: offerCursorExample,
3161
+ description: "Pagination cursor in base64url-encoded format."
3162
+ }),
3163
+ ApiQuery({
3164
+ name: "limit",
3165
+ type: "number",
3166
+ example: 10,
3167
+ description: "Maximum number of price levels to return."
3168
+ }),
3169
+ ApiResponse({
3170
+ status: 200,
3171
+ description: "Success",
3172
+ type: BookListResponse
3173
+ })
3174
+ ], BooksController.prototype, "getBook", null);
3175
+ BooksController = __decorate([ApiTags("Markets"), ApiResponse({
3176
+ status: 400,
3177
+ description: "Bad Request",
3178
+ type: BadRequestResponse
3179
+ })], BooksController);
3180
+ let ValidateController = class ValidateController$1 {
3181
+ async validateOffers() {}
3182
+ };
3183
+ __decorate([
3184
+ ApiOperation({
3185
+ methods: ["post"],
3186
+ path: "/v1/validate",
3187
+ summary: "Validate offers",
3188
+ description: "Validates offers against router validation rules. Returns unsigned payload + root on success, or issues only on validation failure."
3189
+ }),
3190
+ ApiBody({ type: ValidateOffersRequest }),
3191
+ ApiResponse({
3192
+ status: 200,
3193
+ description: "Success",
3194
+ type: ValidationSuccessResponse
3195
+ }),
3196
+ ApiResponse({
3197
+ status: 200,
3198
+ description: "Validation issues",
3199
+ type: ValidationFailureResponse
3200
+ })
3201
+ ], ValidateController.prototype, "validateOffers", null);
3202
+ ValidateController = __decorate([ApiTags("Make"), ApiResponse({
3203
+ status: 400,
3204
+ description: "Bad Request",
3205
+ type: BadRequestResponse
3206
+ })], ValidateController);
3207
+ let OffersController = class OffersController$1 {
3208
+ async getOffers() {}
3209
+ };
3210
+ __decorate([
3211
+ ApiOperation({
3212
+ methods: ["get"],
3213
+ path: "/v1/offers",
3214
+ summary: "List all offers",
3215
+ description: "Returns offers. Provide either `obligation_id` + `side` (order book) or `maker` (by maker address)."
3216
+ }),
3217
+ ApiQuery({
3218
+ name: "side",
3219
+ type: "string",
3220
+ required: false,
3221
+ enum: ["buy", "sell"],
3222
+ example: "buy",
3223
+ description: "Side of the offer. Required when using obligation_id."
3224
+ }),
3225
+ ApiQuery({
3226
+ name: "obligation_id",
3227
+ type: "string",
3228
+ required: false,
3229
+ example: "0x1234567890123456789012345678901234567890123456789012345678901234",
3230
+ description: "Obligation id used to filter offers. Required when not using maker."
3231
+ }),
3232
+ ApiQuery({
3233
+ name: "maker",
3234
+ type: "string",
3235
+ required: false,
3236
+ example: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
3237
+ description: "Maker address to filter offers by. Alternative to obligation_id + side."
3238
+ }),
3239
+ ApiQuery({
3240
+ name: "cursor",
3241
+ type: "string",
3242
+ example: offerCursorExample,
3243
+ description: "Pagination cursor in base64url-encoded format."
3244
+ }),
3245
+ ApiQuery({
3246
+ name: "limit",
3247
+ type: "number",
3248
+ example: 10,
3249
+ description: "Maximum number of offers to return."
3250
+ }),
3251
+ ApiResponse({
3252
+ status: 200,
3253
+ description: "Success",
3254
+ type: OfferListResponse
3255
+ })
3256
+ ], OffersController.prototype, "getOffers", null);
3257
+ OffersController = __decorate([ApiTags("Markets"), ApiResponse({
3258
+ status: 400,
3259
+ description: "Bad Request",
3260
+ type: BadRequestResponse
3261
+ })], OffersController);
3262
+ let HealthController = class HealthController$1 {
3263
+ async getRouterStatus() {}
3264
+ async getCollectorsHealth() {}
3265
+ async getChainsHealth() {}
3063
3266
  };
3064
- var InvalidOfferError = class InvalidOfferError extends BaseError {
3065
- constructor(error) {
3066
- super("Invalid offer.", { cause: error });
3067
- _defineProperty(this, "name", "Offer.InvalidOfferError");
3068
- }
3069
- /**
3070
- * Formats ZodError issues into a human-readable string with line breaks.
3071
- * @example
3072
- * "- 'assets': too small, expected >= 0
3073
- * - 'start': must be before expiry"
3074
- */
3075
- static formatDetails(error) {
3076
- if (!(error instanceof z$1.ZodError)) return error.message;
3077
- return error.issues.map((issue) => {
3078
- return `'${issue.path.join(".")}': ${(issue.message.includes(":") ? issue.message.split(":")[1].trim() : issue.message.trim()).toLowerCase()}`;
3079
- }).join(". ");
3080
- }
3081
- /**
3082
- * Returns the formatted human-readable message.
3083
- */
3084
- get formattedMessage() {
3085
- return `Invalid offer. ${InvalidOfferError.formatDetails(this.cause)}`;
3086
- }
3267
+ __decorate([
3268
+ ApiOperation({
3269
+ methods: ["get"],
3270
+ path: "/v1/health",
3271
+ summary: "Retrieve global health",
3272
+ description: "Returns the aggregated status of the router."
3273
+ }),
3274
+ ApiQuery({
3275
+ name: "strict",
3276
+ type: "boolean",
3277
+ required: false,
3278
+ example: true,
3279
+ description: "Fail the request if initialization is incomplete."
3280
+ }),
3281
+ ApiResponse({
3282
+ status: 200,
3283
+ description: "Success",
3284
+ type: RouterStatusSuccessResponse
3285
+ })
3286
+ ], HealthController.prototype, "getRouterStatus", null);
3287
+ __decorate([
3288
+ ApiOperation({
3289
+ methods: ["get"],
3290
+ path: "/v1/health/collectors",
3291
+ summary: "Retrieve collectors health",
3292
+ description: "Returns the latest block numbers processed by collectors and their sync status."
3293
+ }),
3294
+ ApiQuery({
3295
+ name: "strict",
3296
+ type: "boolean",
3297
+ required: false,
3298
+ example: true,
3299
+ description: "Fail the request if initialization is incomplete."
3300
+ }),
3301
+ ApiResponse({
3302
+ status: 200,
3303
+ description: "Success",
3304
+ type: CollectorsHealthSuccessResponse
3305
+ })
3306
+ ], HealthController.prototype, "getCollectorsHealth", null);
3307
+ __decorate([
3308
+ ApiOperation({
3309
+ methods: ["get"],
3310
+ path: "/v1/health/chains",
3311
+ summary: "Retrieve chains health",
3312
+ description: "Returns the latest block that can be processed by collectors for each chain."
3313
+ }),
3314
+ ApiQuery({
3315
+ name: "strict",
3316
+ type: "boolean",
3317
+ required: false,
3318
+ example: true,
3319
+ description: "Fail the request if initialization is incomplete."
3320
+ }),
3321
+ ApiResponse({
3322
+ status: 200,
3323
+ description: "Success",
3324
+ type: ChainsHealthSuccessResponse
3325
+ })
3326
+ ], HealthController.prototype, "getChainsHealth", null);
3327
+ HealthController = __decorate([ApiTags("System")], HealthController);
3328
+ const maturitiesExample = {
3329
+ end_of_month: 1738335600,
3330
+ end_of_next_month: 1740754800
3087
3331
  };
3088
- var AccountNotSetError = class extends BaseError {
3089
- constructor() {
3090
- super("Account not set.");
3091
- _defineProperty(this, "name", "Offer.AccountNotSetError");
3092
- }
3332
+ const chainConfigExample = {
3333
+ chain_id: 505050505,
3334
+ contracts: { mempool: "0xD946246695A9259F3B33a78629026F61B3Ab40aF" },
3335
+ maturities: maturitiesExample
3093
3336
  };
3094
-
3095
- //#endregion
3096
- //#region src/core/Oracle.ts
3097
- var Oracle_exports = /* @__PURE__ */ __export({
3098
- Conversion: () => Conversion,
3099
- from: () => from$4
3100
- });
3101
- /**
3102
- * Create an Oracle from a plain object.
3103
- * @param data - The data to create the oracle from.
3104
- * @returns The created oracle.
3105
- */
3106
- function from$4(data) {
3107
- return {
3108
- chainId: data.chainId,
3109
- address: data.address.toLowerCase(),
3110
- price: data.price ? BigInt(data.price) : null,
3111
- blockNumber: data.blockNumber
3112
- };
3113
- }
3114
- let Conversion;
3115
- (function(_Conversion) {
3116
- function collateralToLoan(amount, params) {
3117
- return amount * params.price / 10n ** 36n * params.lltv / 10n ** 18n;
3118
- }
3119
- _Conversion.collateralToLoan = collateralToLoan;
3120
- function loanToCollateral(amount, params) {
3121
- if (params.price === 0n || params.lltv === 0n) return 0n;
3122
- return amount * 10n ** 36n / params.price * 10n ** 18n / params.lltv;
3337
+ var ConfigContractsResponse = class {};
3338
+ __decorate([ApiProperty({
3339
+ type: "string",
3340
+ example: chainConfigExample.contracts.mempool
3341
+ })], ConfigContractsResponse.prototype, "mempool", void 0);
3342
+ var MaturitiesResponse = class {};
3343
+ __decorate([ApiProperty({
3344
+ type: "number",
3345
+ description: "Unix timestamp for end of current month maturity (last Friday 15:00 UTC).",
3346
+ example: maturitiesExample.end_of_month
3347
+ })], MaturitiesResponse.prototype, "end_of_month", void 0);
3348
+ __decorate([ApiProperty({
3349
+ type: "number",
3350
+ description: "Unix timestamp for end of next month maturity (last Friday 15:00 UTC).",
3351
+ example: maturitiesExample.end_of_next_month
3352
+ })], MaturitiesResponse.prototype, "end_of_next_month", void 0);
3353
+ var ConfigDataResponse = class {};
3354
+ __decorate([ApiProperty({
3355
+ type: "number",
3356
+ example: chainConfigExample.chain_id
3357
+ })], ConfigDataResponse.prototype, "chain_id", void 0);
3358
+ __decorate([ApiProperty({ type: () => ConfigContractsResponse })], ConfigDataResponse.prototype, "contracts", void 0);
3359
+ __decorate([ApiProperty({
3360
+ type: () => MaturitiesResponse,
3361
+ description: "Supported maturity timestamps. Offers must use one of these values.",
3362
+ example: chainConfigExample.maturities
3363
+ })], ConfigDataResponse.prototype, "maturities", void 0);
3364
+ var ConfigSuccessResponse = class extends SuccessResponse {};
3365
+ __decorate([ApiProperty({
3366
+ type: "string",
3367
+ nullable: true,
3368
+ example: null
3369
+ })], ConfigSuccessResponse.prototype, "cursor", void 0);
3370
+ __decorate([ApiProperty({
3371
+ type: () => [ConfigDataResponse],
3372
+ description: "Array of chain configurations for all indexed chains.",
3373
+ example: [chainConfigExample]
3374
+ })], ConfigSuccessResponse.prototype, "data", void 0);
3375
+ let ConfigController = class ConfigController$1 {
3376
+ async getConfig() {}
3377
+ };
3378
+ __decorate([ApiOperation({
3379
+ methods: ["get"],
3380
+ path: "/v1/config",
3381
+ summary: "Get router configuration",
3382
+ description: "Returns chain configurations including contract addresses and supported maturity timestamps."
3383
+ }), ApiResponse({
3384
+ status: 200,
3385
+ description: "Success",
3386
+ type: ConfigSuccessResponse
3387
+ })], ConfigController.prototype, "getConfig", null);
3388
+ ConfigController = __decorate([ApiTags("System")], ConfigController);
3389
+ let ObligationsController = class ObligationsController$1 {
3390
+ async getObligations() {}
3391
+ async getObligation() {}
3392
+ };
3393
+ __decorate([
3394
+ ApiOperation({
3395
+ methods: ["get"],
3396
+ path: "/v1/obligations",
3397
+ summary: "List all obligations",
3398
+ description: "Returns a list of obligations with their current best ask and bid. Obligations are sorted by their id in ascending order by default."
3399
+ }),
3400
+ ApiQuery({
3401
+ name: "cursor",
3402
+ type: "string",
3403
+ example: obligationCursorExample,
3404
+ description: "Obligation id cursor for pagination."
3405
+ }),
3406
+ ApiQuery({
3407
+ name: "limit",
3408
+ type: "number",
3409
+ example: 10,
3410
+ description: "Maximum number of obligations to return."
3411
+ }),
3412
+ ApiQuery({
3413
+ name: "chain",
3414
+ type: "number",
3415
+ required: false,
3416
+ example: 1,
3417
+ description: "Filter by chain ID."
3418
+ }),
3419
+ ApiQuery({
3420
+ name: "loan_token",
3421
+ type: "string",
3422
+ required: false,
3423
+ example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
3424
+ description: "Filter by loan token address."
3425
+ }),
3426
+ ApiQuery({
3427
+ name: "collateral_token",
3428
+ type: "string",
3429
+ required: false,
3430
+ example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
3431
+ description: "Filter by collateral token (matches any collateral in the obligation)."
3432
+ }),
3433
+ ApiQuery({
3434
+ name: "maturity",
3435
+ type: "number",
3436
+ required: false,
3437
+ example: 1761922800,
3438
+ description: "Filter by exact maturity timestamp (unix seconds)."
3439
+ }),
3440
+ ApiResponse({
3441
+ status: 200,
3442
+ description: "Success",
3443
+ type: ObligationListResponse
3444
+ })
3445
+ ], ObligationsController.prototype, "getObligations", null);
3446
+ __decorate([
3447
+ ApiOperation({
3448
+ methods: ["get"],
3449
+ path: "/v1/obligations/{obligationId}",
3450
+ summary: "Get an obligation",
3451
+ description: "Returns an obligation by its id."
3452
+ }),
3453
+ ApiParam({
3454
+ name: "obligationId",
3455
+ type: "string",
3456
+ example: "0x12590ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9f67",
3457
+ description: "Obligation id."
3458
+ }),
3459
+ ApiResponse({
3460
+ status: 200,
3461
+ description: "Success",
3462
+ type: ObligationSingleSuccessResponse
3463
+ })
3464
+ ], ObligationsController.prototype, "getObligation", null);
3465
+ ObligationsController = __decorate([ApiTags("Markets"), ApiResponse({
3466
+ status: 400,
3467
+ description: "Bad Request",
3468
+ type: BadRequestResponse
3469
+ })], ObligationsController);
3470
+ let UsersController = class UsersController$1 {
3471
+ async getUserPositions() {}
3472
+ };
3473
+ __decorate([
3474
+ ApiOperation({
3475
+ methods: ["get"],
3476
+ path: "/v1/users/{userAddress}/positions",
3477
+ summary: "Get user positions",
3478
+ description: "Returns positions for a user with reserved balance. The reserved balance is the amount locked by active offers (max lot upper - offset - consumed)."
3479
+ }),
3480
+ ApiParam({
3481
+ name: "userAddress",
3482
+ type: "string",
3483
+ example: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
3484
+ description: "User address to get positions for."
3485
+ }),
3486
+ ApiQuery({
3487
+ name: "cursor",
3488
+ type: "string",
3489
+ example: offerCursorExample,
3490
+ description: "Pagination cursor in base64url-encoded format."
3491
+ }),
3492
+ ApiQuery({
3493
+ name: "limit",
3494
+ type: "number",
3495
+ example: 10,
3496
+ description: "Maximum number of positions to return."
3497
+ }),
3498
+ ApiResponse({
3499
+ status: 200,
3500
+ description: "Success",
3501
+ type: PositionListResponse
3502
+ })
3503
+ ], UsersController.prototype, "getUserPositions", null);
3504
+ UsersController = __decorate([ApiTags("Make"), ApiResponse({
3505
+ status: 400,
3506
+ description: "Bad Request",
3507
+ type: BadRequestResponse
3508
+ })], UsersController);
3509
+ const OpenApi = async (options = {}) => {
3510
+ const document = await generateDocument({
3511
+ controllers: [
3512
+ BooksController,
3513
+ ConfigController,
3514
+ OffersController,
3515
+ ObligationsController,
3516
+ HealthController,
3517
+ UsersController,
3518
+ ValidateController
3519
+ ],
3520
+ document: {
3521
+ openapi: "3.1.0",
3522
+ info: {
3523
+ title: "Router API",
3524
+ version: "1.0.0",
3525
+ description: "API for the Morpho Router"
3526
+ },
3527
+ servers: [{
3528
+ url: "https://router.morpho.dev",
3529
+ description: "Production server"
3530
+ }, {
3531
+ url: "http://localhost:7891",
3532
+ description: "Local development server"
3533
+ }],
3534
+ tags: [
3535
+ {
3536
+ name: "Markets",
3537
+ description: "Read-only endpoints to discover markets, order books and fetch current offers."
3538
+ },
3539
+ {
3540
+ name: "Make",
3541
+ description: "Utilities to ease making offers."
3542
+ },
3543
+ {
3544
+ name: "System",
3545
+ description: "Router configuration and health monitoring."
3546
+ }
3547
+ ]
3548
+ }
3549
+ });
3550
+ if (options.rules && options.rules.length > 0) {
3551
+ const rulesDescription = options.rules.map((rule) => `- **${rule.name}**: ${rule.description}`).join("\n");
3552
+ const validatePath = document.paths?.["/v1/validate"];
3553
+ if (validatePath && "post" in validatePath && validatePath.post) validatePath.post.description = `Validates offers against router validation rules. Returns unsigned payload + root on success, or issues only on validation failure.\n\n**Available validation rules:**\n${rulesDescription}`;
3123
3554
  }
3124
- _Conversion.loanToCollateral = loanToCollateral;
3125
- })(Conversion || (Conversion = {}));
3555
+ return document;
3556
+ };
3126
3557
 
3127
3558
  //#endregion
3128
- //#region src/core/Position.ts
3129
- var Position_exports = /* @__PURE__ */ __export({
3130
- Type: () => Type,
3131
- from: () => from$3
3132
- });
3133
- let Type = /* @__PURE__ */ function(Type$1) {
3134
- Type$1["ERC20"] = "erc20";
3135
- Type$1["VAULT_V1"] = "vault_v1";
3136
- return Type$1;
3137
- }({});
3559
+ //#region src/api/Schema/PositionResponse.ts
3560
+ var PositionResponse_exports = /* @__PURE__ */ __export({ from: () => from$1 });
3138
3561
  /**
3139
- * @constructor
3140
- * Creates a Position.
3141
- * @param parameters - {@link from.Parameters}
3142
- * @returns The created Position. {@link from.ReturnType}
3562
+ * Creates a `PositionResponse` from a `PositionWithReserved`.
3563
+ * @param position - {@link PositionWithReserved}
3564
+ * @returns The created `PositionResponse`. {@link PositionResponse}
3143
3565
  */
3144
- function from$3(parameters) {
3566
+ function from$1(position) {
3145
3567
  return {
3146
- chainId: parameters.chainId,
3147
- contract: parameters.contract.toLowerCase(),
3148
- user: parameters.user.toLowerCase(),
3149
- type: parameters.type,
3150
- balance: parameters.balance,
3151
- ...parameters.asset !== void 0 ? { asset: parameters.asset.toLowerCase() } : {},
3152
- blockNumber: parameters.blockNumber
3568
+ chain_id: position.chainId,
3569
+ contract: position.contract,
3570
+ user: position.user,
3571
+ reserved: position.reserved.toString(),
3572
+ block_number: position.blockNumber
3153
3573
  };
3154
3574
  }
3155
3575
 
3156
3576
  //#endregion
3157
- //#region src/core/Quote.ts
3158
- var Quote_exports = /* @__PURE__ */ __export({
3159
- InvalidQuoteError: () => InvalidQuoteError,
3160
- QuoteSchema: () => QuoteSchema,
3161
- from: () => from$2,
3162
- fromSnakeCase: () => fromSnakeCase,
3163
- random: () => random
3164
- });
3165
- const QuoteSchema = z$1.object({
3166
- obligationId: z$1.string().transform(transformHex),
3167
- ask: z$1.object({ rate: z$1.bigint({ coerce: true }).min(0n).max(maxUint256) }),
3168
- bid: z$1.object({ rate: z$1.bigint({ coerce: true }).min(0n).max(maxUint256) })
3169
- });
3170
- /**
3171
- * Creates a quote for a given obligation.
3172
- * @constructor
3173
- * @param parameters - {@link from.Parameters}
3174
- * @returns The created quote. {@link Quote}
3175
- * @throws If the quote is invalid. {@link InvalidQuoteError}
3176
- *
3177
- * @example
3178
- * ```ts
3179
- * const quote = Quote.from({ obligationId: "0x123", ask: { assets: 100n, rate: 100n }, bid: { assets: 100n, rate: 100n } });
3180
- * ```
3181
- */
3182
- function from$2(parameters) {
3577
+ //#region src/api/Schema/requests.ts
3578
+ const MAX_LIMIT = 100;
3579
+ const DEFAULT_LIMIT = 20;
3580
+ /** Validate cursor is a valid base64url-encoded JSON object.
3581
+ * Domain layer handles semantic validation of cursor fields. */
3582
+ function isValidBase64urlJson(val) {
3183
3583
  try {
3184
- const parsedQuote = QuoteSchema.parse(parameters);
3185
- return {
3186
- obligationId: parsedQuote.obligationId,
3187
- ask: parsedQuote.ask,
3188
- bid: parsedQuote.bid
3189
- };
3190
- } catch (error) {
3191
- throw new InvalidQuoteError(error);
3584
+ const decoded = Buffer.from(val, "base64url").toString("utf8");
3585
+ JSON.parse(decoded);
3586
+ return true;
3587
+ } catch {
3588
+ return false;
3192
3589
  }
3193
3590
  }
3194
- /**
3195
- * Creates a quote from a snake case object.
3196
- * @throws If the quote is invalid. {@link InvalidQuoteError}
3197
- * @param snake - {@link fromSnakeCase.Parameters}
3198
- * @returns The created quote. {@link fromSnakeCase.ReturnType}
3199
- */
3200
- function fromSnakeCase(snake) {
3201
- return from$2(fromSnakeCase$3(snake));
3202
- }
3203
- /**
3204
- * Generates a random quote.
3205
- * @returns A randomly generated quote. {@link random.ReturnType}
3206
- *
3207
- * @example
3208
- * ```ts
3209
- * const quote = Quote.random();
3210
- * ```
3211
- */
3212
- function random() {
3213
- return from$2({
3214
- obligationId: id(random$2()),
3215
- ask: { rate: BigInt(int(1e6)) },
3216
- bid: { rate: BigInt(int(1e6)) }
3591
+ const PaginationQueryParams = z$1.object({
3592
+ cursor: z$1.string().optional().refine((val) => {
3593
+ if (!val) return true;
3594
+ return isValidBase64urlJson(val);
3595
+ }, { message: "Invalid cursor format. Must be a valid base64url-encoded cursor object" }).meta({
3596
+ description: "Pagination cursor in base64url-encoded format",
3597
+ example: "eyJzaWRlIjoic2VsbCIsImN1cnJlbnRQcmljZSI6IjEwMDAwMDAwMDAwMDAwMDAwMDAiLCJibG9ja051bWJlciI6MSwiYXNzZXRzIjoiMTAwMDAwMDAwMDAwMDAwMDAwMCIsImhhc2giOiIweGRmZDY4NTllM2UwODJkMTkzODlhMWFlYzFiZGFkN2U4ZDkyZDk2YjFhYTc5NDBkYTkxYTMxMjVkMzFlM2JlNWIiLCJ0b3RhbFJldHVybmVkIjoxMCwibm93IjoxNjAwMDAwMDAwfQ"
3598
+ }),
3599
+ limit: z$1.string().regex(/^[1-9]\d*$/, { message: "Limit must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).pipe(z$1.number().max(MAX_LIMIT, { message: `Limit cannot exceed ${MAX_LIMIT}` })).optional().default(DEFAULT_LIMIT).meta({
3600
+ description: `Limit maximum: ${MAX_LIMIT}. Default: ${DEFAULT_LIMIT}`,
3601
+ example: 10
3602
+ })
3603
+ });
3604
+ const GetOffersQueryParams = z$1.object({
3605
+ ...PaginationQueryParams.shape,
3606
+ side: z$1.enum(["buy", "sell"]).optional().meta({
3607
+ description: "Side of the offer. Required when using obligation_id.",
3608
+ example: "buy"
3609
+ }),
3610
+ obligation_id: z$1.string().regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).optional().meta({
3611
+ description: "Offers obligation id. Required when not using maker.",
3612
+ example: "0x1234567890123456789012345678901234567890123456789012345678901234"
3613
+ }),
3614
+ maker: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Maker must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).optional().meta({
3615
+ description: "Maker address to filter offers by. Alternative to obligation_id + side.",
3616
+ example: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401"
3617
+ })
3618
+ }).superRefine((val, ctx) => {
3619
+ const hasObligation = val.obligation_id !== void 0;
3620
+ const hasSide = val.side !== void 0;
3621
+ const hasMaker = val.maker !== void 0;
3622
+ if (hasMaker && (hasObligation || hasSide)) {
3623
+ ctx.addIssue({
3624
+ code: "custom",
3625
+ message: "Cannot use both maker and obligation_id/side parameters"
3626
+ });
3627
+ return;
3628
+ }
3629
+ if (hasMaker) return;
3630
+ if (!hasObligation || !hasSide) ctx.addIssue({
3631
+ code: "custom",
3632
+ message: "Must provide either maker or both obligation_id and side"
3217
3633
  });
3218
- }
3219
- var InvalidQuoteError = class extends BaseError {
3220
- constructor(error) {
3221
- super("Invalid quote.", { cause: error });
3222
- _defineProperty(this, "name", "Quote.InvalidQuoteError");
3634
+ });
3635
+ const GetObligationsQueryParams = z$1.object({
3636
+ ...PaginationQueryParams.shape,
3637
+ cursor: z$1.string().optional().meta({
3638
+ description: "Obligation id cursor",
3639
+ example: "0x1234567890123456789012345678901234567890123456789012345678901234"
3640
+ }),
3641
+ chain: z$1.string().regex(/^[1-9]\d*$/, { message: "Chain must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).optional().meta({
3642
+ description: "Filter by chain ID",
3643
+ example: "1"
3644
+ }),
3645
+ loan_token: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Loan token must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).optional().meta({
3646
+ description: "Filter by loan token address",
3647
+ example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078"
3648
+ }),
3649
+ collateral_token: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Collateral token must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).optional().meta({
3650
+ description: "Filter by collateral token (matches any collateral in the obligation)",
3651
+ example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751"
3652
+ }),
3653
+ maturity: z$1.string().regex(/^[1-9]\d*$/, { message: "Maturity must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).optional().meta({
3654
+ description: "Filter by exact maturity timestamp (unix seconds)",
3655
+ example: "1761922800"
3656
+ })
3657
+ });
3658
+ const GetObligationParams = z$1.object({ obligation_id: z$1.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({
3659
+ description: "Obligation id",
3660
+ example: "0x1234567890123456789012345678901234567890123456789012345678901234"
3661
+ }) });
3662
+ /** Validate a book cursor format: {side, lastPrice, offersCursor} */
3663
+ function isValidBookCursor(cursorString) {
3664
+ const isNumericString = (value) => typeof value === "string" && /^-?\d+$/.test(value);
3665
+ try {
3666
+ const v = JSON.parse(Buffer.from(cursorString, "base64url").toString("utf8"));
3667
+ return (v?.side === "buy" || v?.side === "sell") && isNumericString(v?.lastPrice) && (v?.offersCursor === null || typeof v?.offersCursor === "string");
3668
+ } catch {
3669
+ return false;
3223
3670
  }
3671
+ }
3672
+ const BookPaginationQueryParams = z$1.object({
3673
+ cursor: z$1.string().optional().refine((value) => {
3674
+ if (!value) return true;
3675
+ return isValidBookCursor(value);
3676
+ }, { message: "Invalid cursor format. Must be a valid base64url-encoded book cursor object" }).meta({
3677
+ description: "Pagination cursor in base64url-encoded format for book levels",
3678
+ example: "eyJzaWRlIjoiYnV5IiwibGFzdFJhdGUiOiIxMDAwMDAwMDAwMDAwMDAwMDAwIiwib2ZmZXJzQ3Vyc29yIjpudWxsfQ"
3679
+ }),
3680
+ limit: z$1.string().regex(/^[1-9]\d*$/, { message: "Limit must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).pipe(z$1.number().max(MAX_LIMIT, { message: `Limit cannot exceed ${MAX_LIMIT}` })).optional().default(DEFAULT_LIMIT).meta({
3681
+ description: `Limit maximum: ${MAX_LIMIT}. Default: ${DEFAULT_LIMIT}`,
3682
+ example: 10
3683
+ })
3684
+ });
3685
+ const HealthQueryParams = z$1.object({ strict: z$1.enum([
3686
+ "true",
3687
+ "false",
3688
+ "1",
3689
+ "0"
3690
+ ]).transform((value) => value === "true" || value === "1").optional().meta({
3691
+ description: "Enable strict mode to fail health checks when initialization is incomplete.",
3692
+ example: "true"
3693
+ }) });
3694
+ const GetBookParams = z$1.object({
3695
+ ...BookPaginationQueryParams.shape,
3696
+ obligation_id: z$1.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({
3697
+ description: "Obligation id",
3698
+ example: "0x1234567890123456789012345678901234567890123456789012345678901234"
3699
+ }),
3700
+ side: z$1.enum(["buy", "sell"]).meta({
3701
+ description: "Side of the book (buy or sell).",
3702
+ example: "buy"
3703
+ })
3704
+ });
3705
+ const ValidateOffersBody = z$1.object({ offers: z$1.array(z$1.unknown()).min(1, { message: "'offers' must contain at least 1 offer" }) }).strict();
3706
+ const GetUserPositionsParams = z$1.object({
3707
+ ...PaginationQueryParams.shape,
3708
+ user_address: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "User address must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).meta({
3709
+ description: "User address to get positions for",
3710
+ example: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401"
3711
+ })
3712
+ });
3713
+ const schemas = {
3714
+ get_health: HealthQueryParams,
3715
+ get_health_collectors: HealthQueryParams,
3716
+ get_health_chains: HealthQueryParams,
3717
+ get_offers: GetOffersQueryParams,
3718
+ get_obligations: GetObligationsQueryParams,
3719
+ get_obligation: GetObligationParams,
3720
+ get_book: GetBookParams,
3721
+ validate_offers: ValidateOffersBody,
3722
+ get_user_positions: GetUserPositionsParams
3224
3723
  };
3225
-
3226
- //#endregion
3227
- //#region src/core/Transfer.ts
3228
- var Transfer_exports = /* @__PURE__ */ __export({ from: () => from$1 });
3229
- /**
3230
- * @constructor
3231
- *
3232
- * Creates a {@link Transfer}.
3233
- * @param parameters - {@link from.Parameters}
3234
- * @returns The created Transfer. {@link from.ReturnType}
3235
- *
3236
- * @example
3237
- * ```ts
3238
- * const transfer = Transfer.from({ id: "1", chainId: 1, contract: "0x123", from: "0x456", to: "0x789", value: 100n, blockNumber: 100n });
3239
- * ```
3240
- */
3241
- function from$1(parameters) {
3242
- return {
3243
- id: parameters.id,
3244
- chainId: parameters.chainId,
3245
- contract: parameters.contract.toLowerCase(),
3246
- from: parameters.from.toLowerCase(),
3247
- to: parameters.to.toLowerCase(),
3248
- value: parameters.value,
3249
- blockNumber: parameters.blockNumber
3250
- };
3724
+ function parse(action, query) {
3725
+ return schemas[action].parse(query);
3726
+ }
3727
+ function safeParse(action, query, error) {
3728
+ return schemas[action].safeParse(query, { error });
3251
3729
  }
3252
3730
 
3253
3731
  //#endregion
3254
- //#region src/core/types.ts
3255
- const BrandTypeId = Symbol.for("mempool/Brand");
3732
+ //#region src/api/Schema/index.ts
3733
+ var Schema_exports = /* @__PURE__ */ __export({
3734
+ BookResponse: () => BookResponse_exports,
3735
+ BooksController: () => BooksController,
3736
+ ChainHealth: () => ChainHealth,
3737
+ ChainsHealthResponse: () => ChainsHealthResponse,
3738
+ CollectorHealth: () => CollectorHealth,
3739
+ CollectorsHealthResponse: () => CollectorsHealthResponse,
3740
+ ConfigController: () => ConfigController,
3741
+ HealthController: () => HealthController,
3742
+ ObligationResponse: () => ObligationResponse_exports,
3743
+ ObligationsController: () => ObligationsController,
3744
+ OfferResponse: () => OfferResponse_exports,
3745
+ OffersController: () => OffersController,
3746
+ OpenApi: () => OpenApi,
3747
+ PositionResponse: () => PositionResponse_exports,
3748
+ RouterStatusResponse: () => RouterStatusResponse,
3749
+ UsersController: () => UsersController,
3750
+ ValidateController: () => ValidateController,
3751
+ parse: () => parse,
3752
+ safeParse: () => safeParse
3753
+ });
3256
3754
 
3257
3755
  //#endregion
3258
3756
  //#region src/client/Client.ts
@@ -3313,27 +3811,39 @@ async function getOffers(apiClient, parameters) {
3313
3811
  throw new HttpGetApiFailedError(`GET request returned ${response.status}`, { details: JSON.stringify(error) });
3314
3812
  }
3315
3813
  const offers = data?.data.map((item) => {
3316
- const { root, proof, signature, ...rest } = item;
3814
+ const { root, proof, signature, offer: offerData } = item;
3317
3815
  return {
3318
3816
  ...fromSnakeCase$1({
3319
- ...rest,
3320
- offering: item.offering,
3321
- maturity: from$8(item.maturity),
3322
- loan_token: item.loan_token,
3323
- collaterals: item.collaterals.map((collateral) => ({
3324
- asset: collateral.asset,
3817
+ maker: offerData.maker,
3818
+ assets: offerData.assets,
3819
+ obligation_units: offerData.obligation_units,
3820
+ obligation_shares: offerData.obligation_shares,
3821
+ price: offerData.price,
3822
+ maturity: from$10(offerData.obligation.maturity),
3823
+ expiry: offerData.expiry,
3824
+ start: offerData.start,
3825
+ group: offerData.group,
3826
+ session: offerData.session,
3827
+ buy: offerData.buy,
3828
+ chain_id: item.chain_id,
3829
+ loan_token: offerData.obligation.loan_token,
3830
+ collaterals: offerData.obligation.collaterals.map((collateral) => ({
3831
+ asset: collateral.token,
3325
3832
  oracle: collateral.oracle,
3326
3833
  lltv: collateral.lltv
3327
3834
  })),
3328
3835
  callback: {
3329
- ...item.callback,
3330
- address: item.callback.address,
3331
- data: item.callback.data
3332
- },
3333
- signature: signature?.toLowerCase()
3836
+ address: offerData.callback,
3837
+ data: offerData.callback_data
3838
+ }
3334
3839
  }),
3335
- root: root?.toLowerCase() || void 0,
3336
- proof: proof?.map((p) => p.toLowerCase()) || void 0
3840
+ hash: item.offer_hash,
3841
+ consumed: BigInt(item.consumed),
3842
+ takeable: BigInt(item.takeable),
3843
+ blockNumber: Number(item.block_number),
3844
+ root: root || void 0,
3845
+ proof: proof || void 0,
3846
+ signature: signature ? signature : void 0
3337
3847
  };
3338
3848
  }) ?? [];
3339
3849
  return {
@@ -3344,7 +3854,11 @@ async function getOffers(apiClient, parameters) {
3344
3854
  async function getObligations(apiClient, parameters) {
3345
3855
  const { data, error, response } = await apiClient.GET("/v1/obligations", { params: { query: {
3346
3856
  cursor: parameters?.cursor,
3347
- limit: parameters?.limit
3857
+ limit: parameters?.limit,
3858
+ chain: parameters?.chainId,
3859
+ loan_token: parameters?.loanToken,
3860
+ collateral_token: parameters?.collateralToken,
3861
+ maturity: parameters?.maturity
3348
3862
  } } });
3349
3863
  if (error !== void 0) {
3350
3864
  switch (response.status) {
@@ -3359,11 +3873,11 @@ async function getObligations(apiClient, parameters) {
3359
3873
  chain_id: item.chain_id,
3360
3874
  loan_token: item.loan_token,
3361
3875
  collaterals: item.collaterals.map((collateral) => ({
3362
- asset: collateral.asset,
3876
+ asset: collateral.token,
3363
3877
  oracle: collateral.oracle,
3364
3878
  lltv: collateral.lltv
3365
3879
  })),
3366
- maturity: from$8(item.maturity)
3880
+ maturity: from$10(item.maturity)
3367
3881
  });
3368
3882
  const { obligationId: _, ...returned } = {
3369
3883
  id: () => id(obligation),
@@ -3656,6 +4170,7 @@ function create(parameters) {
3656
4170
  //#endregion
3657
4171
  //#region src/gatekeeper/Rules.ts
3658
4172
  var Rules_exports = /* @__PURE__ */ __export({
4173
+ amountMutualExclusivity: () => amountMutualExclusivity,
3659
4174
  callback: () => callback,
3660
4175
  chains: () => chains,
3661
4176
  maturity: () => maturity,
@@ -3775,7 +4290,7 @@ const chains = ({ chains: chains$2 }) => single("chain_ids", `Validates that off
3775
4290
  if (!allowedChainIds.some((id$1) => id$1 === offer.chainId)) return { message: `Chain ID ${offer.chainId} is not in the allowed chains (${allowedChainIds.join(", ")})` };
3776
4291
  });
3777
4292
  const maturity = ({ maturities }) => single("maturity", `Validates that offer maturity is one of: [${maturities.join(", ")}]`, (offer) => {
3778
- const allowedMaturities = maturities.map((m) => from$8(m));
4293
+ const allowedMaturities = maturities.map((m) => from$10(m));
3779
4294
  if (!allowedMaturities.includes(offer.maturity)) return { message: `Maturity must be end of current month (${allowedMaturities[0]}) or end of next month (${allowedMaturities[1]}). Got: ${offer.maturity}` };
3780
4295
  });
3781
4296
  const callback = ({ callbacks, allowedAddresses }) => single("callback", `Validates callbacks: buy empty callback is ${callbacks.includes(CallbackType.BuyWithEmptyCallback) ? "allowed" : "not allowed"}; sell offers must use a non-empty callback; non-empty callbacks must target one of [${allowedAddresses.map((a) => a.toLowerCase()).join(", ")}]`, (offer) => {
@@ -3786,51 +4301,64 @@ const callback = ({ callbacks, allowedAddresses }) => single("callback", `Valida
3786
4301
  }
3787
4302
  });
3788
4303
  /**
3789
- * A validation rule that checks if the offer's token is allowed.
3790
- * @param offer - The offer to validate.
4304
+ * A validation rule that checks if the offer's tokens are allowed for its chain.
4305
+ * @param assetsByChainId - Allowed assets indexed by chain id.
3791
4306
  * @returns The issue that was found. If the offer is valid, this will be undefined.
3792
4307
  */
3793
- const token = ({ assets: assets$1 }) => single("token", "Validates that offer loan token and collateral tokens are in the allowed assets list", (offer) => {
3794
- const allowedAssets = assets$1?.map((asset) => asset.toLowerCase());
3795
- if (!allowedAssets || allowedAssets.length === 0) return { message: "No allowed assets" };
4308
+ const token = ({ assetsByChainId }) => single("token", "Validates that offer loan token and collateral tokens are in the allowed assets list for the offer chain", (offer) => {
4309
+ const allowedAssets = assetsByChainId[offer.chainId]?.map((asset) => asset.toLowerCase());
4310
+ if (!allowedAssets || allowedAssets.length === 0) return { message: `No allowed assets for chain ${offer.chainId}` };
3796
4311
  if (!allowedAssets.includes(offer.loanToken.toLowerCase())) return { message: "Loan token is not allowed" };
3797
4312
  if (offer.collaterals.some((collateral) => !allowedAssets.includes(collateral.asset.toLowerCase()))) return { message: "Collateral is not allowed" };
3798
4313
  });
3799
4314
  /**
3800
- * A batch validation rule that ensures all offers in a tree have the same maker (offering address).
4315
+ * A batch validation rule that ensures all offers in a tree have the same maker address.
3801
4316
  * Returns an issue only for the first non-conforming offer.
3802
4317
  * This rule is signing-agnostic; signer verification is handled at the collector level.
3803
4318
  */
3804
- const sameMaker = () => batch$1("mixed_maker", "Validates that all offers in a batch have the same maker (offering address)", (offers) => {
4319
+ const sameMaker = () => batch$1("mixed_maker", "Validates that all offers in a batch have the same maker address", (offers) => {
3805
4320
  const issues = /* @__PURE__ */ new Map();
3806
4321
  if (offers.length === 0) return issues;
3807
- const firstMaker = offers[0].offering.toLowerCase();
4322
+ const firstMaker = offers[0].maker.toLowerCase();
3808
4323
  for (let i = 1; i < offers.length; i++) {
3809
4324
  const offer = offers[i];
3810
- if (offer.offering.toLowerCase() !== firstMaker) {
3811
- issues.set(i, { message: `Offer has different maker ${offer.offering} than first offer ${offers[0].offering}` });
4325
+ if (offer.maker.toLowerCase() !== firstMaker) {
4326
+ issues.set(i, { message: `Offer has different maker ${offer.maker} than first offer ${offers[0].maker}` });
3812
4327
  return issues;
3813
4328
  }
3814
4329
  }
3815
4330
  return issues;
3816
4331
  });
4332
+ /**
4333
+ * A validation rule that ensures mutual exclusivity of offer amount fields.
4334
+ * At most one of (assets, obligationUnits, obligationShares) can be non-zero.
4335
+ * Matches contract requirement: `atMostOneNonZero(offer.assets, offer.obligationUnits, offer.obligationShares)`.
4336
+ */
4337
+ const amountMutualExclusivity = () => single("amount_mutual_exclusivity", "Validates that at most one of (assets, obligationUnits, obligationShares) is non-zero", (offer) => {
4338
+ if (!atMostOneNonZero(offer.assets, offer.obligationUnits, offer.obligationShares)) return { message: "Inconsistent offer input: at most one of (assets, obligationUnits, obligationShares) must be non-zero" };
4339
+ });
3817
4340
 
3818
4341
  //#endregion
3819
4342
  //#region src/gatekeeper/morphoRules.ts
3820
- const morphoRules = (chains$2) => [
3821
- sameMaker(),
3822
- chains({ chains: chains$2 }),
3823
- maturity({ maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth] }),
3824
- callback({
3825
- callbacks: [
3826
- CallbackType.BuyWithEmptyCallback,
3827
- CallbackType.BuyVaultV1Callback,
3828
- CallbackType.SellERC20Callback
3829
- ],
3830
- allowedAddresses: chains$2.flatMap((c) => getCallbackAddresses(c.name))
3831
- }),
3832
- token({ assets: chains$2.flatMap((c) => assets[c.id.toString()] ?? []) })
3833
- ];
4343
+ const morphoRules = (chains$2) => {
4344
+ const assetsByChainId = {};
4345
+ for (const chain of chains$2) assetsByChainId[chain.id] = assets[chain.id.toString()] ?? [];
4346
+ return [
4347
+ sameMaker(),
4348
+ amountMutualExclusivity(),
4349
+ chains({ chains: chains$2 }),
4350
+ maturity({ maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth] }),
4351
+ callback({
4352
+ callbacks: [
4353
+ CallbackType.BuyWithEmptyCallback,
4354
+ CallbackType.BuyVaultV1Callback,
4355
+ CallbackType.SellERC20Callback
4356
+ ],
4357
+ allowedAddresses: chains$2.flatMap((c) => getCallbackAddresses(c.name))
4358
+ }),
4359
+ token({ assetsByChainId })
4360
+ ];
4361
+ };
3834
4362
 
3835
4363
  //#endregion
3836
4364
  //#region src/mempool/MempoolEVMClient.ts
@@ -3856,7 +4384,7 @@ function from(parameters) {
3856
4384
  */
3857
4385
  async function add(config, offers) {
3858
4386
  if (!config.client.account) throw new WalletAccountNotSetError();
3859
- const tree = from$6(offers.map((o) => from$5(o)));
4387
+ const tree = from$8(offers.map((o) => from$7(o)));
3860
4388
  const chainId = await getChainId(config.client);
3861
4389
  for (const offer of tree.offers) if (chainId !== offer.chainId) throw new ChainIdMismatchError(offer.chainId, chainId);
3862
4390
  const signature = await sign(tree.offers, config.client);
@@ -3933,10 +4461,7 @@ async function* streamOffers(config, parameters) {
3933
4461
  const { tree } = await decode$1(payload);
3934
4462
  for (const offer of tree.offers) {
3935
4463
  if (loanToken && offer.loanToken.toLowerCase() !== loanToken.toLowerCase()) continue;
3936
- offers.push({
3937
- ...offer,
3938
- blockNumber: Number(log.blockNumber)
3939
- });
4464
+ offers.push(offer);
3940
4465
  }
3941
4466
  } catch (_) {}
3942
4467
  }
@@ -4015,6 +4540,20 @@ async function batchMulticall(parameters) {
4015
4540
  return results;
4016
4541
  }
4017
4542
 
4543
+ //#endregion
4544
+ //#region src/utils/Group.ts
4545
+ var Group_exports = /* @__PURE__ */ __export({ fromNumber: () => fromNumber });
4546
+ /**
4547
+ * Creates a bytes32 group identifier from a number.
4548
+ * @param n - A non-negative integer.
4549
+ * @throws {Error} If n is negative or not an integer.
4550
+ */
4551
+ const fromNumber = (n) => {
4552
+ if (!Number.isInteger(n)) throw new Error(`Group.fromNumber: expected integer, got ${n}`);
4553
+ if (n < 0) throw new Error(`Group.fromNumber: expected non-negative, got ${n}`);
4554
+ return pad(`0x${n.toString(16)}`, { size: 32 });
4555
+ };
4556
+
4018
4557
  //#endregion
4019
4558
  //#region src/utils/lazy.ts
4020
4559
  /**
@@ -4099,9 +4638,11 @@ function max() {
4099
4638
  //#region src/utils/index.ts
4100
4639
  var utils_exports = /* @__PURE__ */ __export({
4101
4640
  BaseError: () => BaseError,
4641
+ Group: () => Group_exports,
4102
4642
  Random: () => Random_exports,
4103
4643
  ReorgError: () => ReorgError,
4104
4644
  Time: () => time_exports,
4645
+ atMostOneNonZero: () => atMostOneNonZero,
4105
4646
  batch: () => batch,
4106
4647
  batchMulticall: () => batchMulticall,
4107
4648
  fromSnakeCase: () => fromSnakeCase$3,
@@ -4116,5 +4657,5 @@ var utils_exports = /* @__PURE__ */ __export({
4116
4657
  });
4117
4658
 
4118
4659
  //#endregion
4119
- export { Abi_exports as Abi, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain, Collateral_exports as Collateral, Cursor_exports as Cursor, ERC4626_exports as ERC4626, 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, Oracle_exports as Oracle, Position_exports as Position, Quote_exports as Quote, Schema_exports as RouterApi, Client_exports as RouterClient, Rules_exports as Rules, time_exports as Time, Transfer_exports as Transfer, Tree_exports as Tree, utils_exports as Utils, Gate_exports as Validation, morphoRules };
4660
+ export { Abi_exports as Abi, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain, ChainRegistry_exports as ChainRegistry, Collateral_exports as Collateral, ERC4626_exports as ERC4626, 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, Oracle_exports as Oracle, Position_exports as Position, Quote_exports as Quote, Schema_exports as RouterApi, Client_exports as RouterClient, Rules_exports as Rules, time_exports as Time, Transfer_exports as Transfer, Tree_exports as Tree, utils_exports as Utils, Gate_exports as Validation, morphoRules };
4120
4661
  //# sourceMappingURL=index.browser.mjs.map