@morpho-dev/router 0.3.0 → 0.4.0

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