@morpho-dev/router 0.10.0 → 0.12.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 (60) hide show
  1. package/README.md +20 -5
  2. package/dist/cli.js +14944 -8994
  3. package/dist/drizzle/migrations/0031_sell-takeable-reindex.sql +254 -0
  4. package/dist/drizzle/migrations/0032_callback-type.sql +3 -0
  5. package/dist/drizzle/migrations/0033_obligation-id-bytes20.sql +255 -0
  6. package/dist/drizzle/migrations/0034_chain-checkpoints.sql +1 -0
  7. package/dist/drizzle/migrations/0035_chain-tip-hash-cas.sql +1 -0
  8. package/dist/drizzle/migrations/0036_pending-links.sql +22 -0
  9. package/dist/drizzle/migrations/0037_chain-finalized-anchor.sql +2 -0
  10. package/dist/drizzle/migrations/0038_add-obligation-rcf-threshold.sql +2 -0
  11. package/dist/drizzle/migrations/0039_add-offers-composite-indexes.sql +2 -0
  12. package/dist/drizzle/migrations/0040_drop-redundant-offers-indexes.sql +2 -0
  13. package/dist/drizzle/migrations/0041_add-group-winner-expression-index.sql +10 -0
  14. package/dist/drizzle/migrations/0042_contract-sync-v1.14.sql +284 -0
  15. package/dist/drizzle/migrations/0043_add-obligation-side-tick-index.sql +1 -0
  16. package/dist/drizzle/migrations/0044_index-audit-cleanup.sql +27 -0
  17. package/dist/drizzle/migrations/0045_add-lots-offsets-availability-indexes.sql +5 -0
  18. package/dist/drizzle/migrations/0046_add-offers-active-tick-index.sql +1 -0
  19. package/dist/drizzle/migrations/0047_add-offers-book-winners-index.sql +1 -0
  20. package/dist/drizzle/migrations/0048_covering-indexes-for-winners-queries.sql +34 -0
  21. package/dist/drizzle/migrations/0049_contract-sync-v1.15.sql +305 -0
  22. package/dist/drizzle/migrations/meta/0031_snapshot.json +1652 -0
  23. package/dist/drizzle/migrations/meta/0033_snapshot.json +1658 -0
  24. package/dist/drizzle/migrations/meta/0036_snapshot.json +1864 -0
  25. package/dist/drizzle/migrations/meta/0037_snapshot.json +1876 -0
  26. package/dist/drizzle/migrations/meta/0038_snapshot.json +1882 -0
  27. package/dist/drizzle/migrations/meta/0039_snapshot.json +1960 -0
  28. package/dist/drizzle/migrations/meta/0040_snapshot.json +1912 -0
  29. package/dist/drizzle/migrations/meta/0041_snapshot.json +1912 -0
  30. package/dist/drizzle/migrations/meta/0042_snapshot.json +1882 -0
  31. package/dist/drizzle/migrations/meta/0043_snapshot.json +1909 -0
  32. package/dist/drizzle/migrations/meta/0044_snapshot.json +1853 -0
  33. package/dist/drizzle/migrations/meta/0045_snapshot.json +1921 -0
  34. package/dist/drizzle/migrations/meta/0046_snapshot.json +1966 -0
  35. package/dist/drizzle/migrations/meta/0047_snapshot.json +2005 -0
  36. package/dist/drizzle/migrations/meta/0048_snapshot.json +2035 -0
  37. package/dist/drizzle/migrations/meta/0049_snapshot.json +2035 -0
  38. package/dist/drizzle/migrations/meta/_journal.json +133 -0
  39. package/dist/evm/bytecode/morpho.txt +1 -1
  40. package/dist/index.browser.d.mts +784 -282
  41. package/dist/index.browser.d.mts.map +1 -1
  42. package/dist/index.browser.mjs +1516 -675
  43. package/dist/index.browser.mjs.map +1 -1
  44. package/dist/index.node.d.mts +1676 -602
  45. package/dist/index.node.d.mts.map +1 -1
  46. package/dist/index.node.mjs +10121 -5251
  47. package/dist/index.node.mjs.map +1 -1
  48. package/dist/register-otel-hook.js +7 -0
  49. package/dist/server-D4xxddev.js +9573 -0
  50. package/dist/server.js +9617 -0
  51. package/docs/integrator.md +14 -24
  52. package/package.json +36 -29
  53. package/dist/index.browser.d.ts +0 -5007
  54. package/dist/index.browser.d.ts.map +0 -1
  55. package/dist/index.browser.js +0 -5825
  56. package/dist/index.browser.js.map +0 -1
  57. package/dist/index.node.d.ts +0 -8263
  58. package/dist/index.node.d.ts.map +0 -1
  59. package/dist/index.node.js +0 -12566
  60. package/dist/index.node.js.map +0 -1
@@ -6,53 +6,14 @@ import { ApiBody, ApiOperation, ApiParam, ApiProperty, ApiQuery, ApiResponse, Ap
6
6
  import * as z$1 from "zod";
7
7
  import createOpenApiFetchClient from "openapi-fetch";
8
8
  import { bytesToHex, concatHex, decodeAbiParameters, encodeAbiParameters, getAddress, hashTypedData, hexToBytes, isAddress, isHex, keccak256, maxUint256, numberToHex, pad, parseAbi, publicActions, recoverAddress, zeroAddress } from "viem";
9
- import { getBlock, getLogs, multicall } from "viem/actions";
9
+ import { getBlockNumber, getLogs, multicall } from "viem/actions";
10
10
  import { anvil, base, mainnet } from "viem/chains";
11
- import { StandardMerkleTree } from "@openzeppelin/merkle-tree";
12
- import { gzip, ungzip } from "pako";
11
+ import { SimpleMerkleTree } from "@openzeppelin/merkle-tree";
12
+ import { Inflate, gzip } from "pako";
13
+ import { context, propagation } from "@opentelemetry/api";
14
+ import { sql } from "drizzle-orm";
15
+ import { bigint, boolean, foreignKey, index, integer, numeric, pgSchema, primaryKey, serial, text, timestamp, uniqueIndex, varchar } from "drizzle-orm/pg-core";
13
16
 
14
- //#region \0@oxc-project+runtime@0.110.0/helpers/typeof.js
15
- function _typeof(o) {
16
- "@babel/helpers - typeof";
17
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
18
- return typeof o;
19
- } : function(o) {
20
- return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
21
- }, _typeof(o);
22
- }
23
-
24
- //#endregion
25
- //#region \0@oxc-project+runtime@0.110.0/helpers/toPrimitive.js
26
- function toPrimitive(t, r) {
27
- if ("object" != _typeof(t) || !t) return t;
28
- var e = t[Symbol.toPrimitive];
29
- if (void 0 !== e) {
30
- var i = e.call(t, r || "default");
31
- if ("object" != _typeof(i)) return i;
32
- throw new TypeError("@@toPrimitive must return a primitive value.");
33
- }
34
- return ("string" === r ? String : Number)(t);
35
- }
36
-
37
- //#endregion
38
- //#region \0@oxc-project+runtime@0.110.0/helpers/toPropertyKey.js
39
- function toPropertyKey(t) {
40
- var i = toPrimitive(t, "string");
41
- return "symbol" == _typeof(i) ? i : i + "";
42
- }
43
-
44
- //#endregion
45
- //#region \0@oxc-project+runtime@0.110.0/helpers/defineProperty.js
46
- function _defineProperty(e, r, t) {
47
- return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
48
- value: t,
49
- enumerable: !0,
50
- configurable: !0,
51
- writable: !0
52
- }) : e[r] = t, e;
53
- }
54
-
55
- //#endregion
56
17
  //#region src/utils/Errors.ts
57
18
  var Errors_exports = /* @__PURE__ */ __exportAll({
58
19
  BaseError: () => BaseError,
@@ -68,6 +29,10 @@ var Errors_exports = /* @__PURE__ */ __exportAll({
68
29
  * ```
69
30
  */
70
31
  var BaseError = class BaseError extends Error {
32
+ details;
33
+ shortMessage;
34
+ cause;
35
+ name = "BaseError";
71
36
  constructor(shortMessage, options = {}) {
72
37
  const details = (() => {
73
38
  if (options.cause instanceof BaseError) {
@@ -84,10 +49,6 @@ var BaseError = class BaseError extends Error {
84
49
  ...details ? ["", details ? `Details: ${details}` : void 0] : []
85
50
  ].filter((x) => typeof x === "string").join("\n");
86
51
  super(message, options.cause ? { cause: options.cause } : void 0);
87
- _defineProperty(this, "details", void 0);
88
- _defineProperty(this, "shortMessage", void 0);
89
- _defineProperty(this, "cause", void 0);
90
- _defineProperty(this, "name", "BaseError");
91
52
  this.cause = options.cause;
92
53
  this.details = details;
93
54
  this.shortMessage = shortMessage;
@@ -103,9 +64,9 @@ function walk(err, fn) {
103
64
  return fn ? null : err;
104
65
  }
105
66
  var ReorgError = class extends BaseError {
67
+ name = "ReorgError";
106
68
  constructor(blockNumber) {
107
69
  super(`Reorg detected at block number ${blockNumber}`);
108
- _defineProperty(this, "name", "ReorgError");
109
70
  }
110
71
  };
111
72
 
@@ -116,6 +77,8 @@ var Tick_exports = /* @__PURE__ */ __exportAll({
116
77
  InvalidTickError: () => InvalidTickError,
117
78
  MAX_PRICE: () => MAX_PRICE,
118
79
  TICK_RANGE: () => TICK_RANGE,
80
+ assetsToObligationUnits: () => assetsToObligationUnits,
81
+ obligationUnitsToAssets: () => obligationUnitsToAssets,
119
82
  priceToTick: () => priceToTick,
120
83
  tickToPrice: () => tickToPrice
121
84
  });
@@ -175,16 +138,36 @@ function assertTick(tick) {
175
138
  function assertPrice(price) {
176
139
  if (price < 0n || price > MAX_PRICE) throw new InvalidPriceError(price);
177
140
  }
141
+ /**
142
+ * Converts obligation units to assets using the tick price (mulDivDown).
143
+ * @param obligationUnits - The obligation units to convert.
144
+ * @param tick - The offer tick.
145
+ * @returns The equivalent amount in assets.
146
+ */
147
+ function obligationUnitsToAssets(obligationUnits, tick) {
148
+ return obligationUnits * tickToPrice(tick) / WAD$1;
149
+ }
150
+ /**
151
+ * Converts assets to obligation units using the tick price (mulDivUp).
152
+ * @param assets - The asset amount to convert.
153
+ * @param tick - The offer tick.
154
+ * @returns The equivalent amount in obligation units.
155
+ */
156
+ function assetsToObligationUnits(assets, tick) {
157
+ const price = tickToPrice(tick);
158
+ if (price === 0n) return 0n;
159
+ return (assets * WAD$1 + price - 1n) / price;
160
+ }
178
161
  var InvalidTickError = class extends BaseError {
162
+ name = "Tick.InvalidTickError";
179
163
  constructor(tick) {
180
164
  super(`Invalid tick: ${tick}. Tick must be an integer between 0 and ${TICK_RANGE}.`);
181
- _defineProperty(this, "name", "Tick.InvalidTickError");
182
165
  }
183
166
  };
184
167
  var InvalidPriceError = class extends BaseError {
168
+ name = "Tick.InvalidPriceError";
185
169
  constructor(price) {
186
170
  super(`Invalid price: ${price}. Price must be between 0 and ${MAX_PRICE}.`);
187
- _defineProperty(this, "name", "Tick.InvalidPriceError");
188
171
  }
189
172
  };
190
173
 
@@ -196,7 +179,7 @@ function from$15(level) {
196
179
  return {
197
180
  tick: level.tick,
198
181
  price: price.toString(),
199
- assets: level.assets.toString(),
182
+ obligation_units: level.obligationUnits.toString(),
200
183
  count: level.count
201
184
  };
202
185
  }
@@ -254,9 +237,11 @@ function from$14(obligation, quote, chainId) {
254
237
  collaterals: obligation.collaterals.map((c) => ({
255
238
  token: c.asset,
256
239
  lltv: c.lltv.toString(),
240
+ max_lif: c.maxLif.toString(),
257
241
  oracle: c.oracle
258
242
  })),
259
243
  maturity: obligation.maturity,
244
+ rcf_threshold: obligation.rcfThreshold.toString(),
260
245
  ask: {
261
246
  tick: quote.ask.tick,
262
247
  price: quote.ask.price.toString()
@@ -297,15 +282,15 @@ function from$13(input) {
297
282
  collaterals: input.collaterals.map((c) => ({
298
283
  token: c.asset,
299
284
  lltv: c.lltv.toString(),
285
+ max_lif: c.maxLif.toString(),
300
286
  oracle: c.oracle
301
287
  })),
302
- maturity: input.maturity
288
+ maturity: input.maturity,
289
+ rcf_threshold: input.rcfThreshold.toString()
303
290
  },
304
291
  buy: input.buy,
305
292
  maker: input.maker,
306
- assets: input.assets.toString(),
307
293
  obligation_units: input.obligationUnits.toString(),
308
- obligation_shares: input.obligationShares.toString(),
309
294
  start: input.start,
310
295
  expiry: input.expiry,
311
296
  tick: input.tick,
@@ -313,7 +298,8 @@ function from$13(input) {
313
298
  session: input.session,
314
299
  callback: input.callback.address,
315
300
  callback_data: input.callback.data,
316
- receiver_if_maker_is_seller: input.receiverIfMakerIsSeller
301
+ receiver_if_maker_is_seller: input.receiverIfMakerIsSeller,
302
+ exit_only: input.exitOnly
317
303
  },
318
304
  offer_hash: input.hash,
319
305
  obligation_id: input.obligationId,
@@ -366,15 +352,15 @@ const offerExample = {
366
352
  collaterals: [{
367
353
  token: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
368
354
  lltv: "860000000000000000",
355
+ max_lif: "0",
369
356
  oracle: "0x45093658BE7f90B63D7c359e8f408e503c2D9401"
370
357
  }],
371
- maturity: 1761922799
358
+ maturity: 1761922799,
359
+ rcf_threshold: "0"
372
360
  },
373
361
  buy: false,
374
362
  maker: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
375
- assets: "369216000000000000000000",
376
- obligation_units: "0",
377
- obligation_shares: "0",
363
+ obligation_units: "369216000000000000000000",
378
364
  start: 1761922790,
379
365
  expiry: 1761922799,
380
366
  tick: 495,
@@ -382,10 +368,11 @@ const offerExample = {
382
368
  session: "0x0000000000000000000000000000000000000000000000000000000000000000",
383
369
  callback: "0x0000000000000000000000000000000000000000",
384
370
  callback_data: "0x",
385
- receiver_if_maker_is_seller: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401"
371
+ receiver_if_maker_is_seller: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
372
+ exit_only: false
386
373
  },
387
374
  offer_hash: "0xac4bd8318ec914f89f8af913f162230575b0ac0696a19256bc12138c5cfe1427",
388
- obligation_id: "0x25690ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9abc",
375
+ obligation_id: "0x25690ae1aee324a005be565f3bcdd16dbf8daf79",
389
376
  chain_id: 1,
390
377
  consumed: "0",
391
378
  takeable: "369216000000000000000000",
@@ -416,11 +403,10 @@ const missingCollectorExample = {
416
403
  };
417
404
  const validateOfferExample = {
418
405
  maker: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
419
- assets: "369216000000000000000000",
420
- obligation_units: "0",
421
- obligation_shares: "0",
406
+ obligation_units: "369216000000000000000000",
422
407
  tick: 495,
423
408
  maturity: 1761922799,
409
+ rcf_threshold: "0",
424
410
  expiry: 1761922799,
425
411
  start: 1761922790,
426
412
  group: "0x000000000000000000000000000000000000000000000000000000000008b8f4",
@@ -431,13 +417,15 @@ const validateOfferExample = {
431
417
  collaterals: [{
432
418
  asset: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
433
419
  oracle: "0x45093658BE7f90B63D7c359e8f408e503c2D9401",
434
- lltv: "860000000000000000"
420
+ lltv: "860000000000000000",
421
+ max_lif: "0"
435
422
  }],
436
423
  callback: {
437
424
  address: "0x0000000000000000000000000000000000000000",
438
425
  data: "0x"
439
426
  },
440
- receiver_if_maker_is_seller: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401"
427
+ receiver_if_maker_is_seller: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
428
+ exit_only: false
441
429
  };
442
430
  const routerStatusExample = {
443
431
  status: "live",
@@ -481,6 +469,10 @@ __decorate([ApiProperty({
481
469
  type: "string",
482
470
  example: "860000000000000000"
483
471
  })], CollateralResponse.prototype, "lltv", void 0);
472
+ __decorate([ApiProperty({
473
+ type: "string",
474
+ example: "0"
475
+ })], CollateralResponse.prototype, "max_lif", void 0);
484
476
  __decorate([ApiProperty({
485
477
  type: "string",
486
478
  example: "0x45093658BE7f90B63D7c359e8f408e503c2D9401"
@@ -498,6 +490,10 @@ __decorate([ApiProperty({
498
490
  type: "string",
499
491
  example: validateOfferExample.collaterals[0].lltv
500
492
  })], ValidateCollateralRequest.prototype, "lltv", void 0);
493
+ __decorate([ApiProperty({
494
+ type: "string",
495
+ example: validateOfferExample.collaterals[0].max_lif
496
+ })], ValidateCollateralRequest.prototype, "max_lif", void 0);
501
497
  var ValidateCallbackRequest = class {};
502
498
  __decorate([ApiProperty({
503
499
  type: "string",
@@ -542,6 +538,10 @@ __decorate([ApiProperty({
542
538
  type: "number",
543
539
  example: offerExample.offer.obligation.maturity
544
540
  })], ObligationOfferResponse.prototype, "maturity", void 0);
541
+ __decorate([ApiProperty({
542
+ type: "string",
543
+ example: offerExample.offer.obligation.rcf_threshold
544
+ })], ObligationOfferResponse.prototype, "rcf_threshold", void 0);
545
545
  var OfferDataResponse = class {};
546
546
  __decorate([ApiProperty({
547
547
  type: () => ObligationOfferResponse,
@@ -555,18 +555,10 @@ __decorate([ApiProperty({
555
555
  type: "string",
556
556
  example: offerExample.offer.maker
557
557
  })], OfferDataResponse.prototype, "maker", void 0);
558
- __decorate([ApiProperty({
559
- type: "string",
560
- example: offerExample.offer.assets
561
- })], OfferDataResponse.prototype, "assets", void 0);
562
558
  __decorate([ApiProperty({
563
559
  type: "string",
564
560
  example: offerExample.offer.obligation_units
565
561
  })], OfferDataResponse.prototype, "obligation_units", void 0);
566
- __decorate([ApiProperty({
567
- type: "string",
568
- example: offerExample.offer.obligation_shares
569
- })], OfferDataResponse.prototype, "obligation_shares", void 0);
570
562
  __decorate([ApiProperty({
571
563
  type: "number",
572
564
  example: offerExample.offer.start
@@ -601,6 +593,10 @@ __decorate([ApiProperty({
601
593
  type: "string",
602
594
  example: offerExample.offer.receiver_if_maker_is_seller
603
595
  })], OfferDataResponse.prototype, "receiver_if_maker_is_seller", void 0);
596
+ __decorate([ApiProperty({
597
+ type: "boolean",
598
+ example: offerExample.offer.exit_only
599
+ })], OfferDataResponse.prototype, "exit_only", void 0);
604
600
  var OfferListItemResponse = class {};
605
601
  __decorate([ApiProperty({
606
602
  type: () => OfferDataResponse,
@@ -663,6 +659,10 @@ __decorate([ApiProperty({
663
659
  type: "number",
664
660
  example: 1761922800
665
661
  })], ObligationResponse.prototype, "maturity", void 0);
662
+ __decorate([ApiProperty({
663
+ type: "string",
664
+ example: "0"
665
+ })], ObligationResponse.prototype, "rcf_threshold", void 0);
666
666
  __decorate([ApiProperty({ type: () => AskResponse })], ObligationResponse.prototype, "ask", void 0);
667
667
  __decorate([ApiProperty({ type: () => BidResponse })], ObligationResponse.prototype, "bid", void 0);
668
668
  var ObligationListResponse = class extends SuccessResponse {};
@@ -810,20 +810,11 @@ __decorate([ApiProperty({
810
810
  type: "string",
811
811
  example: validateOfferExample.maker
812
812
  })], ValidateOfferRequest.prototype, "maker", void 0);
813
- __decorate([ApiProperty({
814
- type: "string",
815
- example: validateOfferExample.assets
816
- })], ValidateOfferRequest.prototype, "assets", void 0);
817
813
  __decorate([ApiProperty({
818
814
  type: "string",
819
815
  example: validateOfferExample.obligation_units,
820
816
  required: false
821
817
  })], ValidateOfferRequest.prototype, "obligation_units", void 0);
822
- __decorate([ApiProperty({
823
- type: "string",
824
- example: validateOfferExample.obligation_shares,
825
- required: false
826
- })], ValidateOfferRequest.prototype, "obligation_shares", void 0);
827
818
  __decorate([ApiProperty({
828
819
  type: "number",
829
820
  example: validateOfferExample.tick,
@@ -834,6 +825,10 @@ __decorate([ApiProperty({
834
825
  type: "number",
835
826
  example: validateOfferExample.maturity
836
827
  })], ValidateOfferRequest.prototype, "maturity", void 0);
828
+ __decorate([ApiProperty({
829
+ type: "string",
830
+ example: validateOfferExample.rcf_threshold
831
+ })], ValidateOfferRequest.prototype, "rcf_threshold", void 0);
837
832
  __decorate([ApiProperty({
838
833
  type: "number",
839
834
  example: validateOfferExample.expiry
@@ -870,6 +865,11 @@ __decorate([ApiProperty({
870
865
  type: "string",
871
866
  example: validateOfferExample.receiver_if_maker_is_seller
872
867
  })], ValidateOfferRequest.prototype, "receiver_if_maker_is_seller", void 0);
868
+ __decorate([ApiProperty({
869
+ type: "boolean",
870
+ example: false,
871
+ required: false
872
+ })], ValidateOfferRequest.prototype, "exit_only", void 0);
873
873
  var ValidateOffersRequest = class {};
874
874
  __decorate([ApiProperty({
875
875
  type: "number",
@@ -948,7 +948,7 @@ __decorate([ApiProperty({
948
948
  __decorate([ApiProperty({
949
949
  type: "string",
950
950
  example: "369216000000000000000000"
951
- })], BookLevelResponse.prototype, "assets", void 0);
951
+ })], BookLevelResponse.prototype, "obligation_units", void 0);
952
952
  __decorate([ApiProperty({
953
953
  type: "number",
954
954
  example: 5
@@ -1572,7 +1572,7 @@ const OpenApi = async () => {
1572
1572
  info: {
1573
1573
  title: "Router API",
1574
1574
  version: "1.0.0",
1575
- description: "API for the Morpho Router"
1575
+ description: process.env.COMMIT_SHA ? `API for the Morpho Router — version: ${process.env.COMMIT_SHA.slice(0, 7)}` : "API for the Morpho Router"
1576
1576
  },
1577
1577
  servers: [{
1578
1578
  url: "https://router.morpho.dev",
@@ -1642,11 +1642,14 @@ function isValidBase64urlJson(val) {
1642
1642
  function isValidOfferHashCursor(val) {
1643
1643
  return /^0x[a-f0-9]{64}$/i.test(val);
1644
1644
  }
1645
+ function isValidObligationIdCursor(val) {
1646
+ return /^0x[a-f0-9]{64}$/i.test(val);
1647
+ }
1645
1648
  function isValidOfferCursor(val) {
1646
1649
  const [hash, obligationId, ...rest] = val.split(":");
1647
1650
  if (rest.length !== 0) return false;
1648
1651
  if (!hash || !obligationId) return false;
1649
- return isValidOfferHashCursor(hash) && isValidOfferHashCursor(obligationId);
1652
+ return isValidOfferHashCursor(hash) && isValidObligationIdCursor(obligationId);
1650
1653
  }
1651
1654
  const csvArray = (schema) => z$1.preprocess((value) => {
1652
1655
  if (value === void 0) return void 0;
@@ -1675,10 +1678,14 @@ const ConfigRuleTypes = z$1.enum([
1675
1678
  "callback",
1676
1679
  "loan_token",
1677
1680
  "collateral_token",
1678
- "oracle"
1681
+ "oracle",
1682
+ "group_consistency",
1683
+ "group_immutability",
1684
+ "max_collaterals",
1685
+ "min_duration"
1679
1686
  ]);
1680
1687
  const GetConfigRulesQueryParams = z$1.object({
1681
- cursor: z$1.string().regex(/^(maturity|callback|loan_token|collateral_token|oracle):[1-9]\d*:.+$/, { message: "Cursor must be in the format type:chain_id:<value>" }).optional().meta({
1688
+ cursor: z$1.string().regex(/^(maturity|callback|loan_token|collateral_token|oracle|group_consistency|group_immutability|max_collaterals|min_duration):[1-9]\d*:.+$/, { message: "Cursor must be in the format type:chain_id:<value>" }).optional().meta({
1682
1689
  description: "Pagination cursor in type:chain_id:<value> format",
1683
1690
  example: "maturity:1:1730415600:end_of_next_month"
1684
1691
  }),
@@ -1932,55 +1939,75 @@ const MetaMorphoFactory = parseAbi(["event CreateMetaMorpho(address indexed meta
1932
1939
  //#region src/core/Abi/MorphoV2.ts
1933
1940
  const MorphoV2 = parseAbi([
1934
1941
  "constructor()",
1935
- "function collateralOf(bytes32 id, address user, address collateralToken) view returns (uint256)",
1936
- "function consume(bytes32 group, uint256 amount)",
1942
+ "function activatedCollaterals(bytes32 id, address user) view returns (uint128)",
1943
+ "function collateralOf(bytes32 id, address user, uint256 index) view returns (uint128)",
1937
1944
  "function consumed(address user, bytes32 group) view returns (uint256)",
1945
+ "function creditAfterSlashing(bytes32 id, address user) view returns (uint256)",
1946
+ "function creditOf(bytes32 id, address user) view returns (uint256)",
1938
1947
  "function debtOf(bytes32 id, address user) view returns (uint256)",
1939
- "function defaultFees(address loanToken, uint256 index) view returns (uint16)",
1948
+ "function defaultFees(address loanToken, uint256) view returns (uint16)",
1940
1949
  "function feeSetter() view returns (address)",
1941
- "function fees(bytes32 id) view returns (uint16[6])",
1950
+ "function fees(bytes32 id) view returns (uint16[7])",
1942
1951
  "function flashLoan(address token, uint256 assets, address callback, bytes data)",
1943
- "function isHealthy((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, bytes32 id, address borrower) view returns (bool)",
1944
- "function liquidate((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, (uint256 collateralIndex, uint256 repaid, uint256 seized)[] seizures, address borrower, bytes data) returns ((uint256 collateralIndex, uint256 repaid, uint256 seized)[])",
1952
+ "function isAuthorized(address authorizer, address authorized) view returns (bool)",
1953
+ "function isHealthy((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, bytes32 id, address borrower) view returns (bool)",
1954
+ "function liquidate((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, uint256 collateralIndex, uint256 seizedAssets, uint256 repaidUnits, address borrower, bytes data) returns (uint256, uint256)",
1955
+ "function maxCollateralPerUser(address collateralToken) view returns (uint256)",
1956
+ "function maxLif(uint256 lltv, uint256 cursor) pure returns (uint256)",
1957
+ "function maxTakeableAssets(address loanToken) view returns (uint256)",
1958
+ "function maxTotalUnits(address loanToken) view returns (uint128)",
1959
+ "function maxTradingFee(uint256 index) pure returns (uint256)",
1945
1960
  "function multicall(bytes[] calls)",
1946
1961
  "function obligationCreated(bytes32 id) view returns (bool)",
1947
- "function obligationState(bytes32 id) view returns (uint128 totalUnits, uint128 totalShares, uint256 withdrawable, bool created)",
1962
+ "function obligationState(bytes32 id) view returns (uint128 totalUnits, uint256 withdrawable, uint128 lossIndex, bool created)",
1948
1963
  "function owner() view returns (address)",
1949
- "function repay((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, uint256 obligationUnits, address onBehalf)",
1964
+ "function repay((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, uint256 obligationUnits, address onBehalf)",
1950
1965
  "function session(address user) view returns (bytes32)",
1966
+ "function setConsumed(bytes32 group, uint256 amount, address onBehalf)",
1951
1967
  "function setDefaultTradingFee(address loanToken, uint256 index, uint256 newTradingFee)",
1952
1968
  "function setFeeSetter(address newFeeSetter)",
1969
+ "function setIsAuthorized(address onBehalf, address authorized, bool newIsAuthorized)",
1970
+ "function setMaxCollateralPerUser(address collateralToken, uint256 newMaxCollateralPerUser)",
1971
+ "function setMaxTakeableAssets(address loanToken, uint256 newMaxTakeableAssets)",
1972
+ "function setMaxTotalUnits(address loanToken, uint128 newMaxTotalUnits)",
1953
1973
  "function setObligationTradingFee(bytes32 id, uint256 index, uint256 newTradingFee)",
1954
1974
  "function setOwner(address newOwner)",
1955
1975
  "function setTradingFeeRecipient(address feeRecipient)",
1956
- "function sharesOf(bytes32 id, address user) view returns (uint256)",
1957
- "function shuffleSession()",
1958
- "function supplyCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, address collateral, uint256 assets, address onBehalf)",
1959
- "function take(uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, address taker, address takerCallback, bytes takerCallbackData, address receiverIfTakerIsSeller, ((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, bool buy, address maker, uint256 assets, uint256 obligationUnits, uint256 obligationShares, uint256 start, uint256 expiry, uint256 tick, bytes32 group, bytes32 session, address callback, bytes callbackData, address receiverIfMakerIsSeller) offer, (uint8 v, bytes32 r, bytes32 s) sig, bytes32 root, bytes32[] proof) returns (uint256, uint256, uint256, uint256)",
1960
- "function totalShares(bytes32 id) view returns (uint256)",
1976
+ "function shuffleSession(address onBehalf)",
1977
+ "function slash(bytes32 id, address user)",
1978
+ "function supplyCollateral((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, uint256 collateralIndex, uint256 assets, address onBehalf)",
1979
+ "function take(uint256 obligationUnits, address taker, address takerCallback, bytes takerCallbackData, address receiverIfTakerIsSeller, ((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, bool buy, address maker, uint256 obligationUnits, uint256 start, uint256 expiry, uint256 tick, bytes32 group, bytes32 session, address callback, bytes callbackData, address receiverIfMakerIsSeller, bool exitOnly) offer, (uint8 v, bytes32 r, bytes32 s) sig, bytes32 root, bytes32[] proof) returns (uint256, uint256, uint256)",
1980
+ "function toId((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation) view returns (bytes32)",
1981
+ "function toObligation(bytes32 id) view returns ((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold))",
1961
1982
  "function totalUnits(bytes32 id) view returns (uint256)",
1962
- "function touchObligation((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation) returns (bytes32)",
1983
+ "function touchObligation((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation) returns (bytes32)",
1963
1984
  "function tradingFee(bytes32 id, uint256 timeToMaturity) view returns (uint256)",
1964
1985
  "function tradingFeeRecipient() view returns (address)",
1965
- "function withdraw((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, uint256 obligationUnits, uint256 shares, address onBehalf, address receiver) returns (uint256, uint256)",
1966
- "function withdrawCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, address collateral, uint256 assets, address onBehalf, address receiver)",
1986
+ "function userLossIndex(bytes32 id, address user) view returns (uint128)",
1987
+ "function withdraw((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, uint256 obligationUnits, address onBehalf, address receiver)",
1988
+ "function withdrawCollateral((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, uint256 collateralIndex, uint256 assets, address onBehalf, address receiver)",
1967
1989
  "function withdrawable(bytes32 id) view returns (uint256)",
1968
1990
  "event Constructor(address indexed owner)",
1969
- "event Consume(address indexed user, bytes32 indexed group, uint256 amount)",
1970
1991
  "event FlashLoan(address indexed caller, address indexed token, uint256 assets)",
1971
- "event Liquidate(address indexed caller, bytes32 indexed id, (uint256 collateralIndex, uint256 repaid, uint256 seized)[] seizures, address indexed borrower, uint256 totalRepaid, uint256 badDebt)",
1972
- "event ObligationCreated(bytes32 indexed id, (address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation)",
1973
- "event Repay(address indexed caller, bytes32 indexed id, uint256 obligationUnits, address indexed onBehalf)",
1992
+ "event Liquidate(address indexed caller, bytes32 indexed id_, uint256 collateralIndex, uint256 seizedAssets, uint256 repaidUnits, address indexed borrower, uint256 badDebt, uint256 latestLossIndex)",
1993
+ "event ObligationCreated(bytes32 indexed id_, (address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation)",
1994
+ "event Repay(address indexed caller, bytes32 indexed id_, uint256 obligationUnits, address indexed onBehalf)",
1995
+ "event SetConsumed(address indexed caller, address indexed onBehalf, bytes32 indexed group, uint256 amount)",
1974
1996
  "event SetDefaultTradingFee(address indexed loanToken, uint256 indexed index, uint256 newTradingFee)",
1975
1997
  "event SetFeeSetter(address indexed feeSetter)",
1976
- "event SetObligationTradingFee(bytes32 indexed id, uint256 indexed index, uint256 newTradingFee)",
1998
+ "event SetIsAuthorized(address indexed caller, address indexed onBehalf, address indexed authorized, bool newIsAuthorized)",
1999
+ "event SetMaxCollateralPerUser(address indexed collateralToken, uint256 maxCollateralPerUser)",
2000
+ "event SetMaxTakeableAssets(address indexed loanToken, uint256 maxTakeableAssets)",
2001
+ "event SetMaxTotalUnits(address indexed loanToken, uint128 maxTotalUnits)",
2002
+ "event SetObligationTradingFee(bytes32 indexed id_, uint256 indexed index, uint256 newTradingFee)",
1977
2003
  "event SetOwner(address indexed owner)",
1978
2004
  "event SetTradingFeeRecipient(address indexed feeRecipient)",
1979
- "event ShuffleSession(address indexed user, bytes32 session)",
1980
- "event SupplyCollateral(address caller, bytes32 indexed id, address indexed collateral, uint256 assets, address indexed onBehalf)",
1981
- "event Take(address caller, bytes32 indexed id, address indexed maker, address indexed taker, bool offerIsBuy, uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, bool buyerIsLender, bool sellerIsBorrower, address sellerReceiver, bytes32 group, uint256 consumed)",
1982
- "event Withdraw(address caller, bytes32 indexed id, uint256 obligationUnits, uint256 shares, address indexed onBehalf, address indexed receiver)",
1983
- "event WithdrawCollateral(address caller, bytes32 indexed id, address indexed collateral, uint256 assets, address indexed onBehalf, address receiver)"
2005
+ "event ShuffleSession(address indexed caller, address indexed onBehalf, bytes32 session)",
2006
+ "event Slash(address caller, bytes32 indexed id_, address indexed user, uint256 credit, uint256 latestLossIndex)",
2007
+ "event SupplyCollateral(address caller, bytes32 indexed id_, address indexed collateral, uint256 assets, address indexed onBehalf)",
2008
+ "event Take(address caller, bytes32 indexed id_, address indexed maker, address indexed taker, bool offerIsBuy, uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, address sellerReceiver, bytes32 group, uint256 consumed, uint256 totalUnits)",
2009
+ "event Withdraw(address caller, bytes32 indexed id_, uint256 obligationUnits, address indexed onBehalf, address indexed receiver)",
2010
+ "event WithdrawCollateral(address caller, bytes32 indexed id_, address indexed collateral, uint256 assets, address indexed onBehalf, address receiver)"
1984
2011
  ]);
1985
2012
 
1986
2013
  //#endregion
@@ -2138,6 +2165,7 @@ const Morpho = [
2138
2165
  //#endregion
2139
2166
  //#region src/core/Callback.ts
2140
2167
  var Callback_exports = /* @__PURE__ */ __exportAll({
2168
+ CallbackType: () => CallbackType,
2141
2169
  Type: () => Type$1,
2142
2170
  isEmptyCallback: () => isEmptyCallback
2143
2171
  });
@@ -2146,30 +2174,12 @@ let Type$1 = /* @__PURE__ */ function(Type) {
2146
2174
  Type["SellWithEmptyCallback"] = "sell_with_empty_callback";
2147
2175
  return Type;
2148
2176
  }({});
2177
+ let CallbackType = /* @__PURE__ */ function(CallbackType) {
2178
+ CallbackType["Empty"] = "empty";
2179
+ return CallbackType;
2180
+ }({});
2149
2181
  const isEmptyCallback = (offer) => offer.callback.data === "0x";
2150
2182
 
2151
- //#endregion
2152
- //#region src/utils/BigMath.ts
2153
- function max$1(a, b) {
2154
- return a > b ? a : b;
2155
- }
2156
- function min(a, b) {
2157
- return a < b ? a : b;
2158
- }
2159
- /**
2160
- * Checks if at most one of the given values is non-zero.
2161
- * @param values - The bigint values to check.
2162
- * @returns True if zero or one value is non-zero, false if two or more are non-zero.
2163
- */
2164
- function atMostOneNonZero(...values) {
2165
- let nonZeroCount = 0;
2166
- for (const value of values) if (value !== 0n) {
2167
- nonZeroCount++;
2168
- if (nonZeroCount > 1) return false;
2169
- }
2170
- return true;
2171
- }
2172
-
2173
2183
  //#endregion
2174
2184
  //#region src/utils/batch.ts
2175
2185
  /**
@@ -2193,6 +2203,28 @@ function* batch$1(array, batchSize) {
2193
2203
  for (let i = 0; i < array.length; i += batchSize) yield array.slice(i, i + batchSize);
2194
2204
  }
2195
2205
 
2206
+ //#endregion
2207
+ //#region src/utils/BigMath.ts
2208
+ function max$1(a, b) {
2209
+ return a > b ? a : b;
2210
+ }
2211
+ function min(a, b) {
2212
+ return a < b ? a : b;
2213
+ }
2214
+ /**
2215
+ * Checks if at most one of the given values is non-zero.
2216
+ * @param values - The bigint values to check.
2217
+ * @returns True if zero or one value is non-zero, false if two or more are non-zero.
2218
+ */
2219
+ function atMostOneNonZero(...values) {
2220
+ let nonZeroCount = 0;
2221
+ for (const value of values) if (value !== 0n) {
2222
+ nonZeroCount++;
2223
+ if (nonZeroCount > 1) return false;
2224
+ }
2225
+ return true;
2226
+ }
2227
+
2196
2228
  //#endregion
2197
2229
  //#region src/core/Chain.ts
2198
2230
  var Chain_exports = /* @__PURE__ */ __exportAll({
@@ -2201,9 +2233,10 @@ var Chain_exports = /* @__PURE__ */ __exportAll({
2201
2233
  InvalidBlockRangeError: () => InvalidBlockRangeError,
2202
2234
  InvalidBlockWindowError: () => InvalidBlockWindowError,
2203
2235
  MissingBlockNumberError: () => MissingBlockNumberError,
2236
+ UnrecoverableLogsResponseSizeError: () => UnrecoverableLogsResponseSizeError,
2204
2237
  chainIds: () => chainIds,
2205
2238
  chainNames: () => chainNames,
2206
- chains: () => chains,
2239
+ chains: () => chains$1,
2207
2240
  getChain: () => getChain,
2208
2241
  getWhitelistedChains: () => getWhitelistedChains,
2209
2242
  streamLogs: () => streamLogs
@@ -2220,17 +2253,17 @@ const chainNameLookup = new Map(Object.entries(ChainId).map(([key, value]) => [v
2220
2253
  function getChain(chainId) {
2221
2254
  const chainName = chainNameLookup.get(chainId);
2222
2255
  if (!chainName) return void 0;
2223
- return chains[chainName];
2256
+ return chains$1[chainName];
2224
2257
  }
2225
2258
  const getWhitelistedChains = () => {
2226
2259
  return [
2227
- chains.ethereum,
2228
- chains.base,
2229
- chains["ethereum-virtual-testnet"],
2230
- chains.anvil
2260
+ chains$1.ethereum,
2261
+ chains$1.base,
2262
+ chains$1["ethereum-virtual-testnet"],
2263
+ chains$1.anvil
2231
2264
  ];
2232
2265
  };
2233
- const chains = {
2266
+ const chains$1 = {
2234
2267
  ethereum: {
2235
2268
  ...mainnet,
2236
2269
  id: ChainId.ETHEREUM,
@@ -2267,8 +2300,8 @@ const chains = {
2267
2300
  name: "base",
2268
2301
  custom: {
2269
2302
  morpho: {
2270
- address: "0x3F067BC9D8898F6ec02D6480c3fF1026E512BcBF",
2271
- blockCreated: 41799989
2303
+ address: "0xee437005ba0a3d0e9bc6510775c41f23ed2909e1",
2304
+ blockCreated: 43515847
2272
2305
  },
2273
2306
  morphoBlue: {
2274
2307
  address: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
@@ -2297,8 +2330,8 @@ const chains = {
2297
2330
  name: "ethereum-virtual-testnet",
2298
2331
  custom: {
2299
2332
  morpho: {
2300
- address: "0xc9f3c65996fc46b9500608b2c9a9152c01c540f7",
2301
- blockCreated: 23226871
2333
+ address: "0xc1c6e6fa308eeef18e96be420d8ccb218215a26c",
2334
+ blockCreated: 23244321
2302
2335
  },
2303
2336
  morphoBlue: {
2304
2337
  address: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
@@ -2325,9 +2358,13 @@ const chains = {
2325
2358
  ...anvil,
2326
2359
  id: ChainId.ANVIL,
2327
2360
  name: "anvil",
2361
+ contracts: { multicall3: {
2362
+ address: "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
2363
+ blockCreated: 0
2364
+ } },
2328
2365
  custom: {
2329
2366
  morpho: {
2330
- address: "0x23DFBc4B8B80C14CC5e25011B8491f268395BAd6",
2367
+ address: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
2331
2368
  blockCreated: 0
2332
2369
  },
2333
2370
  morphoBlue: {
@@ -2335,8 +2372,8 @@ const chains = {
2335
2372
  blockCreated: 0
2336
2373
  },
2337
2374
  mempool: {
2338
- address: "0xD946246695A9259F3B33a78629026F61B3Ab40aF",
2339
- blockCreated: 23223727
2375
+ address: "0x5FbDB2315678afecb367f032d93F642f64180aa3",
2376
+ blockCreated: 0
2340
2377
  },
2341
2378
  vaults: { factories: {
2342
2379
  v1_0: {
@@ -2356,33 +2393,72 @@ const MAX_BATCH_SIZE = 1e4;
2356
2393
  const DEFAULT_BATCH_SIZE$1 = 2500;
2357
2394
  const MAX_BLOCK_WINDOW = 1e4;
2358
2395
  const DEFAULT_BLOCK_WINDOW = 8e3;
2396
+ const MIN_BLOCK_WINDOW = 0n;
2397
+ const oversizedLogsErrorPatterns = [
2398
+ "cannot create a string longer than",
2399
+ "response is too big",
2400
+ "response size exceeded",
2401
+ "log response size exceeded",
2402
+ "query returned more than",
2403
+ "too many results"
2404
+ ];
2405
+ const getLatestBlockNumber = async (client) => {
2406
+ return await getBlockNumber(client, { cacheTime: 0 });
2407
+ };
2359
2408
  async function* streamLogs(parameters) {
2360
2409
  const { client, contractAddress, event, blockNumberGte, blockNumberLte, order = "desc", options: { maxBatchSize = DEFAULT_BATCH_SIZE$1, blockWindow = DEFAULT_BLOCK_WINDOW } = {} } = parameters;
2361
2410
  if (maxBatchSize > MAX_BATCH_SIZE) throw new InvalidBatchSizeError(maxBatchSize);
2362
2411
  if (blockWindow > MAX_BLOCK_WINDOW) throw new InvalidBlockWindowError(blockWindow);
2363
2412
  if (order === "asc" && blockNumberGte === void 0) throw new MissingBlockNumberError();
2364
- const latestBlock = (await getBlock(client, {
2365
- blockTag: "latest",
2366
- includeTransactions: false
2367
- })).number;
2413
+ const ascendingLowerBound = order === "asc" ? BigInt(blockNumberGte) : void 0;
2414
+ const latestBlock = await getLatestBlockNumber(client);
2415
+ let upperBound = blockNumberLte === void 0 ? latestBlock : min(BigInt(blockNumberLte), latestBlock);
2416
+ const lowerBound = BigInt(blockNumberGte || 0);
2417
+ const configuredBlockWindow = BigInt(blockWindow);
2418
+ let adaptiveBlockWindow = configuredBlockWindow;
2368
2419
  let toBlock = 0n;
2369
- if (order === "asc") toBlock = min(BigInt(blockNumberGte) + BigInt(blockWindow), blockNumberLte ? BigInt(blockNumberLte) : latestBlock);
2370
- if (order === "desc") toBlock = blockNumberLte === void 0 ? latestBlock : min(BigInt(blockNumberLte), latestBlock);
2420
+ if (order === "asc") toBlock = min(ascendingLowerBound + adaptiveBlockWindow, upperBound);
2421
+ if (order === "desc") toBlock = upperBound;
2371
2422
  let fromBlock = 0n;
2372
- if (order === "asc") fromBlock = min(BigInt(blockNumberGte), latestBlock);
2373
- if (order === "desc") fromBlock = max$1(BigInt(blockNumberGte || toBlock - BigInt(blockWindow)), 0n);
2374
- if (order === "asc") toBlock = min(toBlock, fromBlock + BigInt(blockWindow));
2375
- if (order === "desc") fromBlock = max$1(fromBlock, toBlock - BigInt(blockWindow));
2423
+ if (order === "asc") fromBlock = ascendingLowerBound;
2424
+ if (order === "desc") fromBlock = max$1(BigInt(blockNumberGte || toBlock - adaptiveBlockWindow), 0n);
2425
+ if (order === "asc") toBlock = min(toBlock, fromBlock + adaptiveBlockWindow);
2426
+ if (order === "desc") fromBlock = max$1(fromBlock, toBlock - adaptiveBlockWindow);
2376
2427
  if (fromBlock > toBlock) throw new InvalidBlockRangeError(fromBlock, toBlock);
2377
2428
  let streaming = true;
2378
2429
  while (streaming) {
2379
- const logs = await getLogs(client, {
2380
- address: contractAddress,
2381
- event,
2382
- fromBlock,
2383
- toBlock
2384
- });
2385
- streaming = order === "asc" ? toBlock < (blockNumberLte || latestBlock) : fromBlock > (blockNumberGte || 0n);
2430
+ let logs;
2431
+ try {
2432
+ logs = await getLogs(client, {
2433
+ address: contractAddress,
2434
+ event,
2435
+ fromBlock,
2436
+ toBlock
2437
+ });
2438
+ } catch (err) {
2439
+ if (order === "asc" && isBlockOutOfRangeError(err)) {
2440
+ const previousUpperBound = upperBound;
2441
+ const previousFromBlock = fromBlock;
2442
+ const previousToBlock = toBlock;
2443
+ const latestBlockOnRetry = await getLatestBlockNumber(client);
2444
+ upperBound = min(upperBound, latestBlockOnRetry);
2445
+ if (upperBound < ascendingLowerBound) throw new InvalidBlockRangeError(ascendingLowerBound, upperBound);
2446
+ toBlock = min(toBlock, upperBound);
2447
+ fromBlock = max$1(min(fromBlock, upperBound), ascendingLowerBound);
2448
+ if (fromBlock > toBlock) throw new InvalidBlockRangeError(fromBlock, toBlock);
2449
+ if (!(upperBound < previousUpperBound || fromBlock < previousFromBlock || toBlock < previousToBlock)) throw err;
2450
+ continue;
2451
+ }
2452
+ if (isOversizedLogsError(err)) {
2453
+ if (fromBlock === toBlock) throw new UnrecoverableLogsResponseSizeError(fromBlock, err);
2454
+ adaptiveBlockWindow = max$1((toBlock - fromBlock) / 2n, MIN_BLOCK_WINDOW);
2455
+ if (order === "asc") toBlock = min(fromBlock + adaptiveBlockWindow, upperBound);
2456
+ else fromBlock = max$1(toBlock - adaptiveBlockWindow, lowerBound);
2457
+ continue;
2458
+ }
2459
+ throw err;
2460
+ }
2461
+ streaming = order === "asc" ? toBlock < upperBound : fromBlock > lowerBound;
2386
2462
  if (logs.length === 0 && !streaming) break;
2387
2463
  if (logs.length === 0 && streaming) yield {
2388
2464
  logs: [],
@@ -2397,17 +2473,19 @@ async function* streamLogs(parameters) {
2397
2473
  logs: logBatch,
2398
2474
  blockNumber: logBatch.length === maxBatchSize ? Number(logBatch[logBatch.length - 1]?.blockNumber) : order === "asc" ? Number(toBlock) : Number(fromBlock)
2399
2475
  };
2476
+ if (adaptiveBlockWindow < configuredBlockWindow) {
2477
+ const expandedBlockWindow = adaptiveBlockWindow === 0n ? 1n : adaptiveBlockWindow * 2n;
2478
+ adaptiveBlockWindow = min(expandedBlockWindow, configuredBlockWindow);
2479
+ }
2400
2480
  if (order === "asc") {
2401
- const upperBound = BigInt(blockNumberLte || latestBlock);
2402
2481
  const nextFromBlock = min(BigInt(toBlock) + 1n, upperBound);
2403
- const nextToBlock = min(toBlock + BigInt(blockWindow) + 1n, upperBound);
2482
+ const nextToBlock = min(toBlock + adaptiveBlockWindow + 1n, upperBound);
2404
2483
  fromBlock = nextFromBlock;
2405
2484
  toBlock = nextToBlock;
2406
2485
  }
2407
2486
  if (order === "desc") {
2408
- const lowerBound = BigInt(blockNumberGte || 0);
2409
2487
  const nextToBlock = max$1(fromBlock - 1n, lowerBound);
2410
- const nextFromBlock = max$1(fromBlock - BigInt(blockWindow) - 1n, lowerBound);
2488
+ const nextFromBlock = max$1(fromBlock - adaptiveBlockWindow - 1n, lowerBound);
2411
2489
  toBlock = nextToBlock;
2412
2490
  fromBlock = nextFromBlock;
2413
2491
  }
@@ -2417,30 +2495,62 @@ async function* streamLogs(parameters) {
2417
2495
  blockNumber: order === "asc" ? Number(toBlock) : Number(fromBlock)
2418
2496
  };
2419
2497
  }
2498
+ const isBlockOutOfRangeError = (error) => {
2499
+ let cause = error;
2500
+ while (cause && typeof cause === "object") {
2501
+ const candidate = cause;
2502
+ if (typeof candidate.message === "string" && candidate.message.includes("BlockOutOfRangeError") || typeof candidate.details === "string" && candidate.details.includes("BlockOutOfRangeError")) return true;
2503
+ cause = candidate.cause;
2504
+ }
2505
+ return false;
2506
+ };
2420
2507
  var InvalidBlockRangeError = class extends BaseError {
2508
+ name = "Chain.InvalidBlockRangeError";
2509
+ fromBlock;
2510
+ toBlock;
2421
2511
  constructor(fromBlock, toBlock) {
2422
2512
  super(`Invalid block range while streaming data from chain. From block ${fromBlock} to block ${toBlock}.`);
2423
- _defineProperty(this, "name", "Chain.InvalidBlockRangeError");
2513
+ this.fromBlock = fromBlock;
2514
+ this.toBlock = toBlock;
2424
2515
  }
2425
2516
  };
2426
2517
  var InvalidBlockWindowError = class extends BaseError {
2518
+ name = "Chain.InvalidBlockWindowError";
2427
2519
  constructor(blockWindow) {
2428
2520
  super(`Invalid block window while streaming data from chain. Maximum is ${MAX_BLOCK_WINDOW}. Got ${blockWindow}.`);
2429
- _defineProperty(this, "name", "Chain.InvalidBlockWindowError");
2430
2521
  }
2431
2522
  };
2432
2523
  var InvalidBatchSizeError = class extends BaseError {
2524
+ name = "Chain.InvalidBatchSizeError";
2433
2525
  constructor(maxBatchSize) {
2434
2526
  super(`Invalid batch size while streaming data from chain. Maximum is ${MAX_BATCH_SIZE}. Got ${maxBatchSize}.`);
2435
- _defineProperty(this, "name", "Chain.InvalidBatchSizeError");
2436
2527
  }
2437
2528
  };
2438
2529
  var MissingBlockNumberError = class extends BaseError {
2530
+ name = "Chain.MissingBlockNumberError";
2439
2531
  constructor() {
2440
2532
  super("Missing block number when streaming data from chain in ascending order.");
2441
- _defineProperty(this, "name", "Chain.MissingBlockNumberError");
2442
2533
  }
2443
2534
  };
2535
+ var UnrecoverableLogsResponseSizeError = class extends BaseError {
2536
+ name = "Chain.UnrecoverableLogsResponseSizeError";
2537
+ constructor(blockNumber, cause) {
2538
+ const rootCause = cause instanceof Error ? cause : cause === void 0 ? void 0 : new Error(String(cause));
2539
+ super(`Failed to stream logs because even a single-block query exceeded the RPC response size limit at block ${blockNumber}.`, { cause: rootCause });
2540
+ }
2541
+ };
2542
+ function isOversizedLogsError(err) {
2543
+ return oversizedLogsErrorPatterns.some((pattern) => collectErrorMessages(err).includes(pattern));
2544
+ }
2545
+ function collectErrorMessages(err) {
2546
+ if (!(err instanceof Error)) return "";
2547
+ const fragments = [err.message];
2548
+ const candidate = err;
2549
+ if (typeof candidate.details === "string") fragments.push(candidate.details);
2550
+ if (typeof candidate.shortMessage === "string") fragments.push(candidate.shortMessage);
2551
+ if (candidate.cause instanceof Error) fragments.push(collectErrorMessages(candidate.cause));
2552
+ return fragments.join(" ").toLowerCase();
2553
+ }
2444
2554
 
2445
2555
  //#endregion
2446
2556
  //#region src/core/ChainRegistry.ts
@@ -2465,6 +2575,7 @@ var Random_exports = /* @__PURE__ */ __exportAll({
2465
2575
  address: () => address,
2466
2576
  bool: () => bool,
2467
2577
  bytes: () => bytes,
2578
+ createRng: () => createRng,
2468
2579
  float: () => float,
2469
2580
  hex: () => hex,
2470
2581
  int: () => int,
@@ -2482,7 +2593,19 @@ const hashSeed = (seed) => {
2482
2593
  }
2483
2594
  return hash >>> 0;
2484
2595
  };
2485
- const createSeededRng = (seed) => {
2596
+ /**
2597
+ * Creates an isolated seeded RNG instance — safe for concurrent use.
2598
+ * @param seed - Seed string used to derive the initial RNG state.
2599
+ */
2600
+ function createRng(seed) {
2601
+ const rng = createSeededRngFn(seed);
2602
+ return {
2603
+ float: () => rng(),
2604
+ int: (maxExclusive, min = 0) => Math.floor(rng() * (maxExclusive - min)) + min,
2605
+ bool: (probability = .5) => rng() < probability
2606
+ };
2607
+ }
2608
+ const createSeededRngFn = (seed) => {
2486
2609
  let state = hashSeed(seed);
2487
2610
  return () => {
2488
2611
  state += 1831565813;
@@ -2496,7 +2619,7 @@ const createSeededRng = (seed) => {
2496
2619
  */
2497
2620
  function withSeed(seed, fn) {
2498
2621
  const previous = currentRng;
2499
- currentRng = createSeededRng(seed);
2622
+ currentRng = createSeededRngFn(seed);
2500
2623
  try {
2501
2624
  return fn();
2502
2625
  } finally {
@@ -2507,7 +2630,7 @@ function withSeed(seed, fn) {
2507
2630
  * Seeds the global RNG for deterministic test runs.
2508
2631
  */
2509
2632
  function seed(seed) {
2510
- currentRng = createSeededRng(seed);
2633
+ currentRng = createSeededRngFn(seed);
2511
2634
  }
2512
2635
  /**
2513
2636
  * Returns a deterministic random float in [0, 1).
@@ -2663,15 +2786,15 @@ function from$11(lltv) {
2663
2786
  return BigInt(lltv * 10 ** 18);
2664
2787
  }
2665
2788
  var InvalidOptionError$1 = class extends BaseError {
2789
+ name = "LLTV.InvalidOptionError";
2666
2790
  constructor(input) {
2667
2791
  super(`Invalid LLTV option. Input: "${input}". Accepted values are: ${Options.map((option) => `"${option}"`).join(", ")}.`);
2668
- _defineProperty(this, "name", "LLTV.InvalidOptionError");
2669
2792
  }
2670
2793
  };
2671
2794
  var InvalidLLTVError = class extends BaseError {
2795
+ name = "LLTV.InvalidLLTVError";
2672
2796
  constructor(input) {
2673
2797
  super(`Invalid LLTV. Input: "${input}". Accepted values are: ${LLTV_SCALED.map((option) => `"${option}"`).join(", ")}.`);
2674
- _defineProperty(this, "name", "LLTV.InvalidLLTVError");
2675
2798
  }
2676
2799
  };
2677
2800
  const LLTVSchema = z$1.bigint({ coerce: true }).refine((lltv) => {
@@ -2703,6 +2826,10 @@ const abi$1 = [
2703
2826
  type: "uint256",
2704
2827
  name: "lltv"
2705
2828
  },
2829
+ {
2830
+ type: "uint256",
2831
+ name: "maxLif"
2832
+ },
2706
2833
  {
2707
2834
  type: "address",
2708
2835
  name: "oracle"
@@ -2711,7 +2838,8 @@ const abi$1 = [
2711
2838
  const CollateralSchema = z$1.object({
2712
2839
  asset: z$1.string().transform(transformAddress),
2713
2840
  oracle: z$1.string().transform(transformAddress),
2714
- lltv: LLTVSchema
2841
+ lltv: LLTVSchema,
2842
+ maxLif: z$1.bigint({ coerce: true }).min(0n).optional().default(0n)
2715
2843
  });
2716
2844
  const CollateralsSchema = z$1.array(CollateralSchema).min(1, { message: "At least one collateral is required" }).refine((collaterals) => {
2717
2845
  for (let i = 1; i < collaterals.length; i++) if (collaterals[i - 1].asset.toLowerCase() > collaterals[i].asset.toLowerCase()) return false;
@@ -2729,6 +2857,7 @@ const from$10 = (parameters) => {
2729
2857
  return {
2730
2858
  asset: parameters.asset.toLowerCase(),
2731
2859
  lltv: from$11(parameters.lltv),
2860
+ maxLif: parameters.maxLif ?? 0n,
2732
2861
  oracle: parameters.oracle.toLowerCase()
2733
2862
  };
2734
2863
  };
@@ -2745,7 +2874,8 @@ function random$3() {
2745
2874
  return from$10({
2746
2875
  asset: address(),
2747
2876
  oracle: address(),
2748
- lltv: .965
2877
+ lltv: .965,
2878
+ maxLif: 0n
2749
2879
  });
2750
2880
  }
2751
2881
 
@@ -2806,9 +2936,9 @@ function convertToShares(parameters) {
2806
2936
  return parameters.assets * (parameters.totalSupply + 10n ** BigInt(parameters.decimalsOffset)) / denominator;
2807
2937
  }
2808
2938
  var DenominatorIsZeroError = class extends BaseError {
2939
+ name = "ERC4626.DenominatorIsZeroError";
2809
2940
  constructor() {
2810
2941
  super("Denominator is 0.");
2811
- _defineProperty(this, "name", "ERC4626.DenominatorIsZeroError");
2812
2942
  }
2813
2943
  };
2814
2944
 
@@ -2876,9 +3006,9 @@ const MaturitySchema = z$1.number().int().refine((maturity) => {
2876
3006
  }
2877
3007
  }, { error: (issue) => {
2878
3008
  try {
2879
- return `The maturity is set to ${/* @__PURE__ */ new Date(issue.input * 1e3)}. It must fall on the allowed settlement cycles (Friday 15:00 UTC at the end of week/month/quarter).`;
3009
+ return `The maturity is set to ${/* @__PURE__ */ new Date(issue.input * 1e3)}. It must be at 15:00:00 UTC.`;
2880
3010
  } catch (_) {
2881
- return `The maturity is set to ${issue.input}. It must fall on the allowed settlement cycles (Friday 15:00 UTC at the end of week/month/quarter).`;
3011
+ return `The maturity is set to ${issue.input}. It must be at 15:00:00 UTC.`;
2882
3012
  }
2883
3013
  } }).transform((maturity) => maturity);
2884
3014
  let MaturityType = /* @__PURE__ */ function(MaturityType) {
@@ -2910,9 +3040,14 @@ function from$9(ts) {
2910
3040
  throw new InvalidOptionError(ts);
2911
3041
  }
2912
3042
  if (typeof ts === "number" && ts > 0xe8d4a51000) throw new InvalidFormatError();
2913
- if (!Object.values(MaturityOptions).some((option) => option() === ts)) throw new InvalidDateError(ts);
3043
+ if (!isAt15UTC(ts)) throw new InvalidDateError(ts);
2914
3044
  return ts;
2915
3045
  }
3046
+ /** Checks whether a timestamp (in seconds) falls at exactly 15:00:00 UTC. */
3047
+ function isAt15UTC(ts) {
3048
+ const date = /* @__PURE__ */ new Date(ts * 1e3);
3049
+ return date.getUTCHours() === 15 && date.getUTCMinutes() === 0 && date.getUTCSeconds() === 0 && date.getUTCMilliseconds() === 0;
3050
+ }
2916
3051
  /** Returns the end of the current week (friday at 15:00:00 UTC) */
2917
3052
  const endOfWeek = () => fridayOfWeek(0);
2918
3053
  /** Returns the end of the next week (friday at 15:00:00 UTC) */
@@ -2965,21 +3100,21 @@ const lastFridayOfQuarter = (quartersAhead = 0) => {
2965
3100
  return lastFridayOfMonth(now.getUTCFullYear() + Math.floor(quarterIndex / 4), quarterIndex % 4 * 3 + 2);
2966
3101
  };
2967
3102
  var InvalidFormatError = class extends BaseError {
3103
+ name = "Maturity.InvalidFormatError";
2968
3104
  constructor() {
2969
3105
  super("Invalid maturity format. Maturity should be expressed in seconds.");
2970
- _defineProperty(this, "name", "Maturity.InvalidFormatError");
2971
3106
  }
2972
3107
  };
2973
3108
  var InvalidDateError = class extends BaseError {
3109
+ name = "Maturity.InvalidDateError";
2974
3110
  constructor(input) {
2975
- super(`Invalid maturity date. Input: "${input}". Accepted values are: ${Object.values(MaturityOptions).map((option) => `"${option()}"`).join(", ")}.`);
2976
- _defineProperty(this, "name", "Maturity.InvalidDateError");
3111
+ super(`Invalid maturity date. Input: "${input}". Maturity must be at 15:00:00 UTC.`);
2977
3112
  }
2978
3113
  };
2979
3114
  var InvalidOptionError = class extends BaseError {
3115
+ name = "Maturity.InvalidOptionError";
2980
3116
  constructor(input) {
2981
3117
  super(`Invalid maturity option. Input: "${input}". Accepted values are: ${Object.keys(MaturityOptions).map((option) => `"${option}"`).join(", ")}.`);
2982
- _defineProperty(this, "name", "Maturity.InvalidOptionError");
2983
3118
  }
2984
3119
  };
2985
3120
 
@@ -3000,7 +3135,8 @@ var Obligation_exports = /* @__PURE__ */ __exportAll({
3000
3135
  const ObligationSchema = z$1.object({
3001
3136
  loanToken: z$1.string().transform(transformAddress),
3002
3137
  collaterals: CollateralsSchema,
3003
- maturity: MaturitySchema
3138
+ maturity: MaturitySchema,
3139
+ rcfThreshold: z$1.bigint({ coerce: true }).min(0n)
3004
3140
  });
3005
3141
  const abi = [
3006
3142
  {
@@ -3015,6 +3151,10 @@ const abi = [
3015
3151
  {
3016
3152
  type: "uint256",
3017
3153
  name: "maturity"
3154
+ },
3155
+ {
3156
+ type: "uint256",
3157
+ name: "rcfThreshold"
3018
3158
  }
3019
3159
  ];
3020
3160
  const tupleAbi = [{
@@ -3040,6 +3180,7 @@ const tupleAbi = [{
3040
3180
  * }),
3041
3181
  * ],
3042
3182
  * maturity: Maturity.from("end_of_next_quarter"),
3183
+ * rcfThreshold: 0n,
3043
3184
  * });
3044
3185
  * ```
3045
3186
  */
@@ -3052,7 +3193,8 @@ function from$8(parameters) {
3052
3193
  return {
3053
3194
  loanToken: parsedObligation.loanToken.toLowerCase(),
3054
3195
  collaterals: parsedObligation.collaterals.sort((a, b) => a.asset.localeCompare(b.asset)),
3055
- maturity: parsedObligation.maturity
3196
+ maturity: parsedObligation.maturity,
3197
+ rcfThreshold: parsedObligation.rcfThreshold
3056
3198
  };
3057
3199
  } catch (error) {
3058
3200
  throw new InvalidObligationError(error);
@@ -3069,7 +3211,7 @@ function fromSnakeCase$2(input) {
3069
3211
  }
3070
3212
  /**
3071
3213
  * Calculates a canonical key for an obligation payload.
3072
- * The key is computed as keccak256(abi.encode(loanToken, collaterals, maturity)).
3214
+ * The key is computed as keccak256(abi.encode(loanToken, collaterals, maturity, rcfThreshold)).
3073
3215
  * @throws If the collaterals are not sorted alphabetically by address. {@link CollateralsAreNotSortedError}
3074
3216
  * @param parameters - {@link key.Parameters}
3075
3217
  * @returns The obligation key as a 32-byte hex string. {@link key.ReturnType}
@@ -3093,9 +3235,11 @@ function key(parameters) {
3093
3235
  parameters.collaterals.map((c) => ({
3094
3236
  token: c.asset.toLowerCase(),
3095
3237
  lltv: c.lltv,
3238
+ maxLif: c.maxLif ?? 0n,
3096
3239
  oracle: c.oracle.toLowerCase()
3097
3240
  })),
3098
- BigInt(parameters.maturity)
3241
+ BigInt(parameters.maturity),
3242
+ parameters.rcfThreshold
3099
3243
  ]));
3100
3244
  }
3101
3245
  /**
@@ -3111,7 +3255,8 @@ function random$2() {
3111
3255
  return from$8({
3112
3256
  loanToken: address(),
3113
3257
  collaterals: [random$3()],
3114
- maturity: from$9("end_of_next_quarter")
3258
+ maturity: from$9("end_of_next_quarter"),
3259
+ rcfThreshold: 0n
3115
3260
  });
3116
3261
  }
3117
3262
  /**
@@ -3125,19 +3270,20 @@ function fromOffer$1(offer) {
3125
3270
  return from$8({
3126
3271
  loanToken: offer.loanToken,
3127
3272
  collaterals: offer.collaterals,
3128
- maturity: offer.maturity
3273
+ maturity: offer.maturity,
3274
+ rcfThreshold: offer.rcfThreshold
3129
3275
  });
3130
3276
  }
3131
3277
  var InvalidObligationError = class extends BaseError {
3278
+ name = "Obligation.InvalidObligationError";
3132
3279
  constructor(error) {
3133
3280
  super("Invalid obligation.", { cause: error });
3134
- _defineProperty(this, "name", "Obligation.InvalidObligationError");
3135
3281
  }
3136
3282
  };
3137
3283
  var CollateralsAreNotSortedError = class extends BaseError {
3284
+ name = "Obligation.CollateralsAreNotSortedError";
3138
3285
  constructor() {
3139
3286
  super("Collaterals are not sorted alphabetically by address.");
3140
- _defineProperty(this, "name", "Obligation.CollateralsAreNotSortedError");
3141
3287
  }
3142
3288
  };
3143
3289
 
@@ -3147,39 +3293,42 @@ var Id_exports = /* @__PURE__ */ __exportAll({
3147
3293
  creationCode: () => creationCode,
3148
3294
  toId: () => toId
3149
3295
  });
3150
- const CREATION_CODE_PREFIX = "0x603f380380603f5f395ff3";
3296
+ const CREATION_CODE_PREFIX = "0x600b380380600b5f395ff3";
3151
3297
  /**
3152
3298
  * Builds the same creation code as `IdLib.creationCode` in Solidity.
3153
3299
  *
3154
- * Layout: `prefix (11 bytes) + chainId (32 bytes) + morphoV2 (20 bytes) + abi.encode(obligation)`.
3300
+ * Layout: `prefix (11 bytes) + abi.encode(obligation)`.
3155
3301
  *
3156
3302
  * @param parameters - {@link creationCode.Parameters}
3157
3303
  * @returns The CREATE2 init code bytes. {@link creationCode.ReturnType}
3158
3304
  */
3159
3305
  function creationCode(parameters) {
3160
- const encodedObligation = encodeAbiParameters(tupleAbi, [{
3306
+ return concatHex([CREATION_CODE_PREFIX, encodeAbiParameters(tupleAbi, [{
3161
3307
  loanToken: parameters.obligation.loanToken.toLowerCase(),
3162
3308
  collaterals: parameters.obligation.collaterals.map((collateral) => ({
3163
3309
  token: collateral.asset.toLowerCase(),
3164
3310
  lltv: collateral.lltv,
3311
+ maxLif: collateral.maxLif ?? 0n,
3165
3312
  oracle: collateral.oracle.toLowerCase()
3166
3313
  })),
3167
- maturity: BigInt(parameters.obligation.maturity)
3168
- }]);
3169
- return concatHex([
3170
- CREATION_CODE_PREFIX,
3171
- numberToHex(BigInt(parameters.chainId), { size: 32 }),
3172
- parameters.morphoV2.toLowerCase(),
3173
- encodedObligation
3174
- ]);
3314
+ maturity: BigInt(parameters.obligation.maturity),
3315
+ rcfThreshold: parameters.obligation.rcfThreshold
3316
+ }])]);
3175
3317
  }
3176
3318
  /**
3177
- * Computes the same id as `IdLib.toId` in Solidity.
3319
+ * Computes the same id as `IdLib.toId` in Solidity using the CREATE2 preimage:
3320
+ * `keccak256(0xff ++ morphoV2 ++ chainId ++ keccak256(creationCode))`.
3321
+ *
3178
3322
  * @param parameters - {@link toId.Parameters}
3179
- * @returns The obligation id. {@link toId.ReturnType}
3323
+ * @returns The 32-byte obligation id. {@link toId.ReturnType}
3180
3324
  */
3181
3325
  function toId(parameters) {
3182
- return keccak256(creationCode(parameters));
3326
+ return keccak256(concatHex([
3327
+ "0xff",
3328
+ parameters.morphoV2.toLowerCase(),
3329
+ numberToHex(BigInt(parameters.chainId), { size: 32 }),
3330
+ keccak256(creationCode(parameters))
3331
+ ]));
3183
3332
  }
3184
3333
 
3185
3334
  //#endregion
@@ -3269,7 +3418,6 @@ var Offer_exports = /* @__PURE__ */ __exportAll({
3269
3418
  fromSnakeCase: () => fromSnakeCase$1,
3270
3419
  hash: () => hash,
3271
3420
  liquidateEvent: () => liquidateEvent,
3272
- obligationId: () => obligationId,
3273
3421
  random: () => random$1,
3274
3422
  repayEvent: () => repayEvent,
3275
3423
  serialize: () => serialize,
@@ -3288,11 +3436,10 @@ let Status = /* @__PURE__ */ function(Status) {
3288
3436
  const OfferSchema = () => {
3289
3437
  return z$1.object({
3290
3438
  maker: z$1.string().transform(transformAddress),
3291
- assets: z$1.bigint({ coerce: true }).min(0n).max(maxUint256),
3292
3439
  obligationUnits: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional().default(0n),
3293
- obligationShares: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional().default(0n),
3294
3440
  tick: z$1.coerce.number().int().min(0).max(990),
3295
3441
  maturity: MaturitySchema,
3442
+ rcfThreshold: z$1.bigint({ coerce: true }).min(0n).max(maxUint256),
3296
3443
  expiry: z$1.number().int().max(Number.MAX_SAFE_INTEGER),
3297
3444
  start: z$1.number().int().max(Number.MAX_SAFE_INTEGER),
3298
3445
  group: z$1.union([
@@ -3312,7 +3459,8 @@ const OfferSchema = () => {
3312
3459
  address: z$1.string().transform(transformAddress),
3313
3460
  data: z$1.string().transform(transformHex)
3314
3461
  }),
3315
- receiverIfMakerIsSeller: z$1.string().transform(transformAddress)
3462
+ receiverIfMakerIsSeller: z$1.string().transform(transformAddress),
3463
+ exitOnly: z$1.boolean().optional().default(false)
3316
3464
  }).refine((data) => data.start < data.expiry, {
3317
3465
  message: "start must be before expiry",
3318
3466
  path: ["start"]
@@ -3364,11 +3512,10 @@ function toSnakeCase(offer) {
3364
3512
  */
3365
3513
  const serialize = (offer) => ({
3366
3514
  maker: offer.maker,
3367
- assets: offer.assets.toString(),
3368
3515
  obligationUnits: offer.obligationUnits.toString(),
3369
- obligationShares: offer.obligationShares.toString(),
3370
3516
  tick: offer.tick,
3371
3517
  maturity: Number(offer.maturity),
3518
+ rcfThreshold: offer.rcfThreshold.toString(),
3372
3519
  expiry: Number(offer.expiry),
3373
3520
  start: Number(offer.start),
3374
3521
  group: offer.group,
@@ -3378,13 +3525,15 @@ const serialize = (offer) => ({
3378
3525
  collaterals: offer.collaterals.map((c) => ({
3379
3526
  asset: c.asset,
3380
3527
  oracle: c.oracle,
3381
- lltv: c.lltv.toString()
3528
+ lltv: c.lltv.toString(),
3529
+ maxLif: c.maxLif.toString()
3382
3530
  })),
3383
3531
  callback: {
3384
3532
  address: offer.callback.address,
3385
3533
  data: offer.callback.data
3386
3534
  },
3387
3535
  receiverIfMakerIsSeller: offer.receiverIfMakerIsSeller,
3536
+ exitOnly: offer.exitOnly,
3388
3537
  hash: hash(offer)
3389
3538
  });
3390
3539
  /**
@@ -3421,7 +3570,7 @@ function random$1(config) {
3421
3570
  const loanTokenDecimals = config?.assetsDecimals?.[loanToken] ?? 18;
3422
3571
  const unit = BigInt(10) ** BigInt(loanTokenDecimals);
3423
3572
  const amountBase = BigInt(100 + int(999901));
3424
- const assetsScaled = config?.assets ?? amountBase * unit;
3573
+ const obligationUnitsScaled = config?.obligationUnits ?? amountBase * unit;
3425
3574
  const emptyCallback = {
3426
3575
  address: zeroAddress,
3427
3576
  data: "0x"
@@ -3429,11 +3578,10 @@ function random$1(config) {
3429
3578
  const maker = config?.maker ?? address();
3430
3579
  return from$7({
3431
3580
  maker,
3432
- assets: assetsScaled,
3433
- obligationUnits: config?.obligationUnits ?? 0n,
3434
- obligationShares: config?.obligationShares ?? 0n,
3581
+ obligationUnits: obligationUnitsScaled,
3435
3582
  tick,
3436
3583
  maturity,
3584
+ rcfThreshold: config?.rcfThreshold ?? 0n,
3437
3585
  expiry: config?.expiry ?? maturity - 1,
3438
3586
  start: config?.start ?? maturity - 10,
3439
3587
  group: config?.group ?? hex(32),
@@ -3445,7 +3593,8 @@ function random$1(config) {
3445
3593
  lltv
3446
3594
  })).sort((a, b) => a.asset.localeCompare(b.asset)),
3447
3595
  callback: config?.callback ?? emptyCallback,
3448
- receiverIfMakerIsSeller: config?.receiverIfMakerIsSeller ?? maker
3596
+ receiverIfMakerIsSeller: config?.receiverIfMakerIsSeller ?? maker,
3597
+ exitOnly: config?.exitOnly ?? false
3449
3598
  });
3450
3599
  }
3451
3600
  const weightedChoice = (pairs) => {
@@ -3472,124 +3621,150 @@ function hash(offer) {
3472
3621
  return computed;
3473
3622
  }
3474
3623
  /**
3475
- * Calculates the onchain obligation id for an offer.
3476
- * The id is computed with {@link Id.toId}.
3477
- * @param offer - The offer to calculate the obligation id for.
3478
- * @param parameters - The chain context used by the onchain id function.
3479
- * @returns The obligation id as a 32-byte hex string.
3624
+ * ABI layout matching the Solidity `Offer` struct used by `abi.encode(offer)` in the contract.
3625
+ *
3626
+ * This is a **single top-level tuple** Solidity's `abi.encode(struct)` encodes the struct as one
3627
+ * tuple parameter, not as separate parameters per field. Field order and nesting must exactly
3628
+ * mirror `contracts/interfaces/IMidnight.sol`:
3629
+ *
3630
+ * ```
3631
+ * struct Offer {
3632
+ * Obligation obligation; // nested tuple
3633
+ * bool buy;
3634
+ * address maker;
3635
+ * uint256 obligationUnits;
3636
+ * uint256 start;
3637
+ * uint256 expiry;
3638
+ * uint256 tick;
3639
+ * bytes32 group;
3640
+ * bytes32 session;
3641
+ * address callback;
3642
+ * bytes callbackData;
3643
+ * address receiverIfMakerIsSeller;
3644
+ * bool exitOnly;
3645
+ * }
3646
+ * ```
3480
3647
  */
3481
- function obligationId(offer, parameters) {
3482
- return toId({
3483
- chainId: parameters.chainId,
3484
- morphoV2: parameters.morphoV2,
3485
- obligation: from$8({
3486
- loanToken: offer.loanToken,
3487
- collaterals: offer.collaterals,
3488
- maturity: offer.maturity
3489
- })
3490
- });
3491
- }
3492
- const OfferAbi = [
3493
- {
3494
- name: "maker",
3495
- type: "address"
3496
- },
3497
- {
3498
- name: "assets",
3499
- type: "uint256"
3500
- },
3501
- {
3502
- name: "obligationUnits",
3503
- type: "uint256"
3504
- },
3505
- {
3506
- name: "obligationShares",
3507
- type: "uint256"
3508
- },
3509
- {
3510
- name: "tick",
3511
- type: "uint256"
3512
- },
3513
- {
3514
- name: "maturity",
3515
- type: "uint256"
3516
- },
3517
- {
3518
- name: "expiry",
3519
- type: "uint256"
3520
- },
3521
- {
3522
- name: "group",
3523
- type: "bytes32"
3524
- },
3525
- {
3526
- name: "session",
3527
- type: "bytes32"
3528
- },
3529
- {
3530
- name: "buy",
3531
- type: "bool"
3532
- },
3533
- {
3534
- name: "loanToken",
3535
- type: "address"
3536
- },
3537
- {
3538
- name: "start",
3539
- type: "uint256"
3540
- },
3541
- {
3542
- name: "collaterals",
3543
- type: "tuple[]",
3544
- components: [
3545
- {
3546
- name: "asset",
3547
- type: "address"
3548
- },
3549
- {
3550
- name: "oracle",
3551
- type: "address"
3552
- },
3553
- {
3554
- name: "lltv",
3555
- type: "uint256"
3556
- }
3557
- ]
3558
- },
3559
- {
3560
- name: "callback",
3561
- type: "tuple",
3562
- components: [{
3563
- name: "address",
3648
+ const OfferAbi = [{
3649
+ name: "offer",
3650
+ type: "tuple",
3651
+ components: [
3652
+ {
3653
+ name: "obligation",
3654
+ type: "tuple",
3655
+ components: [
3656
+ {
3657
+ name: "loanToken",
3658
+ type: "address"
3659
+ },
3660
+ {
3661
+ name: "collaterals",
3662
+ type: "tuple[]",
3663
+ components: [
3664
+ {
3665
+ name: "token",
3666
+ type: "address"
3667
+ },
3668
+ {
3669
+ name: "lltv",
3670
+ type: "uint256"
3671
+ },
3672
+ {
3673
+ name: "maxLif",
3674
+ type: "uint256"
3675
+ },
3676
+ {
3677
+ name: "oracle",
3678
+ type: "address"
3679
+ }
3680
+ ]
3681
+ },
3682
+ {
3683
+ name: "maturity",
3684
+ type: "uint256"
3685
+ },
3686
+ {
3687
+ name: "rcfThreshold",
3688
+ type: "uint256"
3689
+ }
3690
+ ]
3691
+ },
3692
+ {
3693
+ name: "buy",
3694
+ type: "bool"
3695
+ },
3696
+ {
3697
+ name: "maker",
3564
3698
  type: "address"
3565
- }, {
3566
- name: "data",
3699
+ },
3700
+ {
3701
+ name: "obligationUnits",
3702
+ type: "uint256"
3703
+ },
3704
+ {
3705
+ name: "start",
3706
+ type: "uint256"
3707
+ },
3708
+ {
3709
+ name: "expiry",
3710
+ type: "uint256"
3711
+ },
3712
+ {
3713
+ name: "tick",
3714
+ type: "uint256"
3715
+ },
3716
+ {
3717
+ name: "group",
3718
+ type: "bytes32"
3719
+ },
3720
+ {
3721
+ name: "session",
3722
+ type: "bytes32"
3723
+ },
3724
+ {
3725
+ name: "callback",
3726
+ type: "address"
3727
+ },
3728
+ {
3729
+ name: "callbackData",
3567
3730
  type: "bytes"
3568
- }]
3569
- },
3570
- {
3571
- name: "receiverIfMakerIsSeller",
3572
- type: "address"
3573
- }
3574
- ];
3731
+ },
3732
+ {
3733
+ name: "receiverIfMakerIsSeller",
3734
+ type: "address"
3735
+ },
3736
+ {
3737
+ name: "exitOnly",
3738
+ type: "bool"
3739
+ }
3740
+ ]
3741
+ }];
3575
3742
  function encode$1(offer) {
3576
- return encodeAbiParameters(OfferAbi, [
3577
- offer.maker,
3578
- offer.assets,
3579
- offer.obligationUnits,
3580
- offer.obligationShares,
3581
- BigInt(offer.tick),
3582
- BigInt(offer.maturity),
3583
- BigInt(offer.expiry),
3584
- offer.group,
3585
- offer.session,
3586
- offer.buy,
3587
- offer.loanToken,
3588
- BigInt(offer.start),
3589
- offer.collaterals,
3590
- offer.callback,
3591
- offer.receiverIfMakerIsSeller
3592
- ]);
3743
+ return encodeAbiParameters(OfferAbi, [{
3744
+ obligation: {
3745
+ loanToken: offer.loanToken,
3746
+ collaterals: offer.collaterals.map((c) => ({
3747
+ token: c.asset,
3748
+ lltv: c.lltv,
3749
+ maxLif: c.maxLif ?? 0n,
3750
+ oracle: c.oracle
3751
+ })),
3752
+ maturity: BigInt(offer.maturity),
3753
+ rcfThreshold: offer.rcfThreshold
3754
+ },
3755
+ buy: offer.buy,
3756
+ maker: offer.maker,
3757
+ obligationUnits: offer.obligationUnits,
3758
+ start: BigInt(offer.start),
3759
+ expiry: BigInt(offer.expiry),
3760
+ tick: BigInt(offer.tick),
3761
+ group: offer.group,
3762
+ session: offer.session,
3763
+ callback: offer.callback.address,
3764
+ callbackData: offer.callback.data,
3765
+ receiverIfMakerIsSeller: offer.receiverIfMakerIsSeller,
3766
+ exitOnly: offer.exitOnly
3767
+ }]);
3593
3768
  }
3594
3769
  function decode$1(data) {
3595
3770
  let decoded;
@@ -3598,31 +3773,33 @@ function decode$1(data) {
3598
3773
  } catch (error) {
3599
3774
  throw new InvalidOfferError(error);
3600
3775
  }
3776
+ const s = decoded[0];
3601
3777
  return from$7({
3602
- maker: decoded[0],
3603
- assets: decoded[1],
3604
- obligationUnits: decoded[2],
3605
- obligationShares: decoded[3],
3606
- tick: Number(decoded[4]),
3607
- maturity: from$9(Number(decoded[5])),
3608
- expiry: Number(decoded[6]),
3609
- group: decoded[7],
3610
- session: decoded[8],
3611
- buy: decoded[9],
3612
- loanToken: decoded[10],
3613
- start: Number(decoded[11]),
3614
- collaterals: decoded[12].map((c) => {
3778
+ loanToken: s.obligation.loanToken,
3779
+ collaterals: s.obligation.collaterals.map((c) => {
3615
3780
  return from$10({
3616
- asset: c.asset,
3781
+ asset: c.token,
3617
3782
  oracle: c.oracle,
3618
- lltv: c.lltv
3783
+ lltv: c.lltv,
3784
+ maxLif: c.maxLif
3619
3785
  });
3620
3786
  }),
3787
+ maturity: from$9(Number(s.obligation.maturity)),
3788
+ rcfThreshold: s.obligation.rcfThreshold,
3789
+ buy: s.buy,
3790
+ maker: s.maker,
3791
+ obligationUnits: s.obligationUnits,
3792
+ start: Number(s.start),
3793
+ expiry: Number(s.expiry),
3794
+ tick: Number(s.tick),
3795
+ group: s.group,
3796
+ session: s.session,
3621
3797
  callback: {
3622
- address: decoded[13].address,
3623
- data: decoded[13].data
3798
+ address: s.callback,
3799
+ data: s.callbackData
3624
3800
  },
3625
- receiverIfMakerIsSeller: decoded[14]
3801
+ receiverIfMakerIsSeller: s.receiverIfMakerIsSeller,
3802
+ exitOnly: s.exitOnly
3626
3803
  });
3627
3804
  }
3628
3805
  /**
@@ -3639,7 +3816,7 @@ const takeEvent = {
3639
3816
  internalType: "address"
3640
3817
  },
3641
3818
  {
3642
- name: "id",
3819
+ name: "id_",
3643
3820
  type: "bytes32",
3644
3821
  indexed: true,
3645
3822
  internalType: "bytes32"
@@ -3680,24 +3857,6 @@ const takeEvent = {
3680
3857
  indexed: false,
3681
3858
  internalType: "uint256"
3682
3859
  },
3683
- {
3684
- name: "obligationShares",
3685
- type: "uint256",
3686
- indexed: false,
3687
- internalType: "uint256"
3688
- },
3689
- {
3690
- name: "buyerIsLender",
3691
- type: "bool",
3692
- indexed: false,
3693
- internalType: "bool"
3694
- },
3695
- {
3696
- name: "sellerIsBorrower",
3697
- type: "bool",
3698
- indexed: false,
3699
- internalType: "bool"
3700
- },
3701
3860
  {
3702
3861
  name: "sellerReceiver",
3703
3862
  type: "address",
@@ -3715,19 +3874,31 @@ const takeEvent = {
3715
3874
  type: "uint256",
3716
3875
  indexed: false,
3717
3876
  internalType: "uint256"
3718
- }
3719
- ],
3720
- anonymous: false
3877
+ },
3878
+ {
3879
+ name: "totalUnits",
3880
+ type: "uint256",
3881
+ indexed: false,
3882
+ internalType: "uint256"
3883
+ }
3884
+ ],
3885
+ anonymous: false
3721
3886
  };
3722
3887
  /**
3723
- * ABI for the Consume event emitted by the Obligation contract.
3888
+ * ABI for the SetConsumed event emitted by the Morpho V2 contract.
3724
3889
  */
3725
3890
  const consumedEvent = {
3726
3891
  type: "event",
3727
- name: "Consume",
3892
+ name: "SetConsumed",
3728
3893
  inputs: [
3729
3894
  {
3730
- name: "user",
3895
+ name: "caller",
3896
+ type: "address",
3897
+ indexed: true,
3898
+ internalType: "address"
3899
+ },
3900
+ {
3901
+ name: "onBehalf",
3731
3902
  type: "address",
3732
3903
  indexed: true,
3733
3904
  internalType: "address"
@@ -3761,7 +3932,7 @@ const repayEvent = {
3761
3932
  internalType: "address"
3762
3933
  },
3763
3934
  {
3764
- name: "id",
3935
+ name: "id_",
3765
3936
  type: "bytes32",
3766
3937
  indexed: true,
3767
3938
  internalType: "bytes32"
@@ -3795,33 +3966,28 @@ const liquidateEvent = {
3795
3966
  internalType: "address"
3796
3967
  },
3797
3968
  {
3798
- name: "id",
3969
+ name: "id_",
3799
3970
  type: "bytes32",
3800
3971
  indexed: true,
3801
3972
  internalType: "bytes32"
3802
3973
  },
3803
3974
  {
3804
- name: "seizures",
3805
- type: "tuple[]",
3975
+ name: "collateralIndex",
3976
+ type: "uint256",
3806
3977
  indexed: false,
3807
- internalType: "struct IMorphoV2.Seizure[]",
3808
- components: [
3809
- {
3810
- name: "collateralIndex",
3811
- type: "uint256",
3812
- internalType: "uint256"
3813
- },
3814
- {
3815
- name: "repaid",
3816
- type: "uint256",
3817
- internalType: "uint256"
3818
- },
3819
- {
3820
- name: "seized",
3821
- type: "uint256",
3822
- internalType: "uint256"
3823
- }
3824
- ]
3978
+ internalType: "uint256"
3979
+ },
3980
+ {
3981
+ name: "seizedAssets",
3982
+ type: "uint256",
3983
+ indexed: false,
3984
+ internalType: "uint256"
3985
+ },
3986
+ {
3987
+ name: "repaidUnits",
3988
+ type: "uint256",
3989
+ indexed: false,
3990
+ internalType: "uint256"
3825
3991
  },
3826
3992
  {
3827
3993
  name: "borrower",
@@ -3830,13 +3996,13 @@ const liquidateEvent = {
3830
3996
  internalType: "address"
3831
3997
  },
3832
3998
  {
3833
- name: "totalRepaid",
3999
+ name: "badDebt",
3834
4000
  type: "uint256",
3835
4001
  indexed: false,
3836
4002
  internalType: "uint256"
3837
4003
  },
3838
4004
  {
3839
- name: "badDebt",
4005
+ name: "latestLossIndex",
3840
4006
  type: "uint256",
3841
4007
  indexed: false,
3842
4008
  internalType: "uint256"
@@ -3858,7 +4024,7 @@ const supplyCollateralEvent = {
3858
4024
  internalType: "address"
3859
4025
  },
3860
4026
  {
3861
- name: "id",
4027
+ name: "id_",
3862
4028
  type: "bytes32",
3863
4029
  indexed: true,
3864
4030
  internalType: "bytes32"
@@ -3898,7 +4064,7 @@ const withdrawCollateralEvent = {
3898
4064
  internalType: "address"
3899
4065
  },
3900
4066
  {
3901
- name: "id",
4067
+ name: "id_",
3902
4068
  type: "bytes32",
3903
4069
  indexed: true,
3904
4070
  internalType: "bytes32"
@@ -3931,9 +4097,9 @@ const withdrawCollateralEvent = {
3931
4097
  anonymous: false
3932
4098
  };
3933
4099
  var InvalidOfferError = class InvalidOfferError extends BaseError {
4100
+ name = "Offer.InvalidOfferError";
3934
4101
  constructor(error) {
3935
4102
  super("Invalid offer.", { cause: error });
3936
- _defineProperty(this, "name", "Offer.InvalidOfferError");
3937
4103
  }
3938
4104
  /**
3939
4105
  * Formats ZodError issues into a human-readable string with line breaks.
@@ -4146,9 +4312,9 @@ function random() {
4146
4312
  });
4147
4313
  }
4148
4314
  var InvalidQuoteError = class extends BaseError {
4315
+ name = "Quote.InvalidQuoteError";
4149
4316
  constructor(error) {
4150
4317
  super("Invalid quote.", { cause: error });
4151
- _defineProperty(this, "name", "Quote.InvalidQuoteError");
4152
4318
  }
4153
4319
  };
4154
4320
  function sideFromTick(side) {
@@ -4174,7 +4340,7 @@ var TradingFee_exports = /* @__PURE__ */ __exportAll({
4174
4340
  });
4175
4341
  /**
4176
4342
  * Time breakpoints in seconds for piecewise linear fee interpolation.
4177
- * Matches on-chain constants: 0d, 1d, 7d, 30d, 90d, 180d.
4343
+ * Matches on-chain constants: 0d, 1d, 7d, 30d, 90d, 180d, 360d.
4178
4344
  */
4179
4345
  const BREAKPOINTS = [
4180
4346
  0n,
@@ -4182,21 +4348,22 @@ const BREAKPOINTS = [
4182
4348
  604800n,
4183
4349
  2592000n,
4184
4350
  7776000n,
4185
- 15552000n
4351
+ 15552000n,
4352
+ 31104000n
4186
4353
  ];
4187
4354
  /** WAD constant (1e18) for fee scaling. */
4188
4355
  const WAD = 10n ** 18n;
4189
4356
  /**
4190
- * Create a TradingFee from an activation flag and 6 fee values.
4357
+ * Create a TradingFee from an activation flag and 7 fee values.
4191
4358
  * @param activated - Whether the fee is active.
4192
- * @param fees - Tuple of 6 fee values in WAD (one per breakpoint: 0d, 1d, 7d, 30d, 90d, 180d).
4359
+ * @param fees - Tuple of 7 fee values in WAD (one per breakpoint: 0d, 1d, 7d, 30d, 90d, 180d, 360d).
4193
4360
  * @returns A new TradingFee instance.
4194
4361
  * @throws {@link InvalidFeeError} if any fee exceeds WAD (100%).
4195
- * @throws {@link InvalidFeesLengthError} if fees array doesn't have exactly 6 elements.
4362
+ * @throws {@link InvalidFeesLengthError} if fees array doesn't have exactly 7 elements.
4196
4363
  */
4197
4364
  function from$3(activated, fees) {
4198
- if (fees.length !== 6) throw new InvalidFeesLengthError(fees.length);
4199
- for (let i = 0; i < 6; i++) {
4365
+ if (fees.length !== 7) throw new InvalidFeesLengthError(fees.length);
4366
+ for (let i = 0; i < 7; i++) {
4200
4367
  const fee = fees[i];
4201
4368
  if (fee < 0n || fee > WAD) throw new InvalidFeeError(fee, i);
4202
4369
  }
@@ -4215,7 +4382,9 @@ function from$3(activated, fees) {
4215
4382
  function compute(tradingFee, timeToMaturity) {
4216
4383
  if (!tradingFee._activated) return 0n;
4217
4384
  const time = BigInt(Math.max(0, Math.floor(timeToMaturity)));
4218
- if (time >= BREAKPOINTS[5]) return tradingFee._fees[5];
4385
+ const maxBreakpoint = BREAKPOINTS[BREAKPOINTS.length - 1];
4386
+ const maxFee = tradingFee._fees[tradingFee._fees.length - 1];
4387
+ if (time >= maxBreakpoint) return maxFee;
4219
4388
  const { index, start, end } = getSegment(time);
4220
4389
  const feeLower = tradingFee._fees[index];
4221
4390
  const feeUpper = tradingFee._fees[index + 1];
@@ -4255,7 +4424,7 @@ function deactivate(tradingFee) {
4255
4424
  /**
4256
4425
  * Get the fee values at each breakpoint.
4257
4426
  * @param tradingFee - The TradingFee instance.
4258
- * @returns The tuple of 6 fee values.
4427
+ * @returns The tuple of 7 fee values.
4259
4428
  */
4260
4429
  function getFees(tradingFee) {
4261
4430
  return tradingFee._fees;
@@ -4266,44 +4435,35 @@ function getFees(tradingFee) {
4266
4435
  * @returns Object with index, start, and end of the segment.
4267
4436
  */
4268
4437
  function getSegment(timeToMaturity) {
4269
- if (timeToMaturity < BREAKPOINTS[1]) return {
4270
- index: 0,
4271
- start: BREAKPOINTS[0],
4272
- end: BREAKPOINTS[1]
4273
- };
4274
- if (timeToMaturity < BREAKPOINTS[2]) return {
4275
- index: 1,
4276
- start: BREAKPOINTS[1],
4277
- end: BREAKPOINTS[2]
4278
- };
4279
- if (timeToMaturity < BREAKPOINTS[3]) return {
4280
- index: 2,
4281
- start: BREAKPOINTS[2],
4282
- end: BREAKPOINTS[3]
4283
- };
4284
- if (timeToMaturity < BREAKPOINTS[4]) return {
4285
- index: 3,
4286
- start: BREAKPOINTS[3],
4287
- end: BREAKPOINTS[4]
4288
- };
4438
+ for (let segmentEndIndex = 1; segmentEndIndex < BREAKPOINTS.length; segmentEndIndex++) {
4439
+ const end = BREAKPOINTS[segmentEndIndex];
4440
+ if (timeToMaturity < end) {
4441
+ const index = segmentEndIndex - 1;
4442
+ return {
4443
+ index,
4444
+ start: BREAKPOINTS[index],
4445
+ end
4446
+ };
4447
+ }
4448
+ }
4289
4449
  return {
4290
- index: 4,
4291
- start: BREAKPOINTS[4],
4292
- end: BREAKPOINTS[5]
4450
+ index: BREAKPOINTS.length - 2,
4451
+ start: BREAKPOINTS[BREAKPOINTS.length - 2],
4452
+ end: BREAKPOINTS[BREAKPOINTS.length - 1]
4293
4453
  };
4294
4454
  }
4295
4455
  /** Error thrown when a fee value is invalid (negative or exceeds WAD). */
4296
4456
  var InvalidFeeError = class extends BaseError {
4457
+ name = "TradingFee.InvalidFeeError";
4297
4458
  constructor(fee, index) {
4298
4459
  super(`Invalid fee at index ${index}: ${fee}. Fee must be between 0 and ${WAD} (WAD).`);
4299
- _defineProperty(this, "name", "TradingFee.InvalidFeeError");
4300
4460
  }
4301
4461
  };
4302
- /** Error thrown when fees array doesn't have exactly 6 elements. */
4462
+ /** Error thrown when fees array doesn't have exactly 7 elements. */
4303
4463
  var InvalidFeesLengthError = class extends BaseError {
4464
+ name = "TradingFee.InvalidFeesLengthError";
4304
4465
  constructor(length) {
4305
- super(`Invalid fees length: ${length}. Expected exactly 6 fee values.`);
4306
- _defineProperty(this, "name", "TradingFee.InvalidFeesLengthError");
4466
+ super(`Invalid fees length: ${length}. Expected exactly 7 fee values.`);
4307
4467
  }
4308
4468
  };
4309
4469
 
@@ -4341,9 +4501,12 @@ function from$2(parameters) {
4341
4501
  var Tree_exports = /* @__PURE__ */ __exportAll({
4342
4502
  DecodeError: () => DecodeError,
4343
4503
  EncodeError: () => EncodeError,
4504
+ MAX_COMPRESSED_OFFERS_BYTES: () => MAX_COMPRESSED_OFFERS_BYTES,
4505
+ MAX_DECOMPRESSED_OFFERS_BYTES: () => MAX_DECOMPRESSED_OFFERS_BYTES,
4506
+ MAX_OFFERS_PER_TREE: () => MAX_OFFERS_PER_TREE,
4344
4507
  SignatureDomainError: () => SignatureDomainError,
4345
4508
  TreeError: () => TreeError,
4346
- VERSION: () => VERSION,
4509
+ VERSION: () => VERSION$1,
4347
4510
  decode: () => decode,
4348
4511
  encode: () => encode,
4349
4512
  encodeUnsigned: () => encodeUnsigned,
@@ -4352,7 +4515,16 @@ var Tree_exports = /* @__PURE__ */ __exportAll({
4352
4515
  signatureDomain: () => signatureDomain,
4353
4516
  signatureTypes: () => signatureTypes
4354
4517
  });
4355
- const VERSION = 1;
4518
+ const VERSION$1 = 2;
4519
+ const MAX_COMPRESSED_OFFERS_BYTES = 1e6;
4520
+ const MAX_DECOMPRESSED_OFFERS_BYTES = 4e6;
4521
+ const MAX_OFFERS_PER_TREE = 100;
4522
+ const ROOT_BYTES = 32;
4523
+ const SIGNATURE_BYTES = 65;
4524
+ const MIN_SIGNED_PAYLOAD_BYTES = 1 + ROOT_BYTES + SIGNATURE_BYTES;
4525
+ const INFLATE_INPUT_CHUNK_BYTES = 64 * 1024;
4526
+ const UTF8_ENCODER = new TextEncoder();
4527
+ const UTF8_DECODER = new TextDecoder();
4356
4528
  /**
4357
4529
  * EIP-712 types for signing the tree root (Root(bytes32 root)).
4358
4530
  */
@@ -4369,29 +4541,83 @@ const signatureTypes = {
4369
4541
  type: "bytes32"
4370
4542
  }]
4371
4543
  };
4372
- const normalizeHash = (hash) => hash.toLowerCase();
4544
+ const gzipOffersPayload = (payload, errorFactory) => {
4545
+ const payloadBytes = UTF8_ENCODER.encode(payload);
4546
+ if (payloadBytes.length > MAX_DECOMPRESSED_OFFERS_BYTES) throw errorFactory(`decompressed offers exceed ${MAX_DECOMPRESSED_OFFERS_BYTES} bytes`);
4547
+ try {
4548
+ const compressed = gzip(payloadBytes);
4549
+ if (compressed.length > MAX_COMPRESSED_OFFERS_BYTES) throw errorFactory(`compressed offers exceed ${MAX_COMPRESSED_OFFERS_BYTES} bytes`);
4550
+ return compressed;
4551
+ } catch (error) {
4552
+ if (error instanceof BaseError) throw error;
4553
+ throw errorFactory("compression failed");
4554
+ }
4555
+ };
4556
+ const gunzipOffersPayload = (compressed, errorFactory) => {
4557
+ if (compressed.length === 0) throw errorFactory("decompression failed");
4558
+ if (compressed.length > MAX_COMPRESSED_OFFERS_BYTES) throw errorFactory(`compressed offers exceed ${MAX_COMPRESSED_OFFERS_BYTES} bytes`);
4559
+ let totalLength = 0;
4560
+ const inflate = new Inflate();
4561
+ const defaultOnData = inflate.onData.bind(inflate);
4562
+ inflate.onData = (chunk) => {
4563
+ totalLength += chunk.length;
4564
+ if (totalLength > MAX_DECOMPRESSED_OFFERS_BYTES) throw errorFactory(`decompressed offers exceed ${MAX_DECOMPRESSED_OFFERS_BYTES} bytes`);
4565
+ defaultOnData(chunk);
4566
+ };
4567
+ try {
4568
+ for (let offset = 0; offset < compressed.length; offset += INFLATE_INPUT_CHUNK_BYTES) {
4569
+ const end = Math.min(offset + INFLATE_INPUT_CHUNK_BYTES, compressed.length);
4570
+ inflate.push(compressed.subarray(offset, end), end === compressed.length);
4571
+ }
4572
+ } catch (error) {
4573
+ if (error instanceof BaseError) throw error;
4574
+ throw errorFactory("decompression failed");
4575
+ }
4576
+ if (inflate.err !== 0) throw errorFactory(inflate.msg || "decompression failed");
4577
+ if (!(inflate.result instanceof Uint8Array)) throw errorFactory("decompression failed");
4578
+ return UTF8_DECODER.decode(inflate.result);
4579
+ };
4580
+ const parseRawOffersPayload = (decoded, errorFactory) => {
4581
+ let rawOffers;
4582
+ try {
4583
+ rawOffers = JSON.parse(decoded);
4584
+ } catch {
4585
+ throw errorFactory("JSON parse failed");
4586
+ }
4587
+ if (!Array.isArray(rawOffers)) throw errorFactory("offers payload must be a JSON array");
4588
+ if (rawOffers.length > MAX_OFFERS_PER_TREE) throw errorFactory(`offers payload exceeds ${MAX_OFFERS_PER_TREE} offers`);
4589
+ return rawOffers;
4590
+ };
4591
+ const assertUniqueOfferHashes = (offers, errorFactory) => {
4592
+ const seen = /* @__PURE__ */ new Set();
4593
+ for (const offer of offers) {
4594
+ const hash$1 = hash(offer);
4595
+ if (seen.has(hash$1)) throw errorFactory(`duplicate offer hash ${hash$1}`);
4596
+ seen.add(hash$1);
4597
+ }
4598
+ };
4373
4599
  /**
4374
4600
  * Builds a Merkle tree from a list of offers.
4375
4601
  *
4376
4602
  * Leaves are the offer `hash` values as `bytes32` and are deterministically
4377
- * ordered following the StandardMerkleTree leaf ordering so that the resulting
4378
- * root is stable regardless of the input order.
4603
+ * ordered so that the resulting root is stable regardless of the input order.
4379
4604
  *
4380
4605
  * @param offers - Offers to include in the tree.
4381
- * @returns A `StandardMerkleTree` of `bytes32` leaves representing the offers.
4606
+ * @returns A `SimpleMerkleTree` of offer hashes representing the offers.
4382
4607
  * @throws {TreeError} If tree building fails due to offer inconsistencies.
4383
4608
  */
4384
4609
  const from$1 = (offers) => {
4385
- const leaves = offers.map((offer) => [hash(offer)]);
4386
- const tree = StandardMerkleTree.of(leaves, ["bytes32"]);
4610
+ assertUniqueOfferHashes(offers, (reason) => new TreeError(reason));
4611
+ const leaves = offers.map((offer) => hash(offer));
4612
+ const tree = SimpleMerkleTree.of(leaves);
4387
4613
  const orderedOffers = orderOffers(tree, offers);
4388
4614
  return Object.assign(tree, { offers: orderedOffers });
4389
4615
  };
4390
4616
  const orderOffers = (tree, offers) => {
4391
4617
  const offerByHash = /* @__PURE__ */ new Map();
4392
- for (const offer of offers) offerByHash.set(normalizeHash(hash(offer)), offer);
4618
+ for (const offer of offers) offerByHash.set(hash(offer), offer);
4393
4619
  const entries = tree.dump().values.map((value) => {
4394
- const hash = normalizeHash(value.value[0]);
4620
+ const hash = value.value;
4395
4621
  const offer = offerByHash.get(hash);
4396
4622
  if (!offer) throw new TreeError(`missing offer for leaf ${hash}`);
4397
4623
  return {
@@ -4406,7 +4632,7 @@ const orderOffers = (tree, offers) => {
4406
4632
  * Generates merkle proofs for all offers in a tree.
4407
4633
  *
4408
4634
  * Each proof allows independent verification that an offer is included in the tree
4409
- * without requiring the full tree. Proofs are ordered by StandardMerkleTree leaf ordering.
4635
+ * without requiring the full tree.
4410
4636
  *
4411
4637
  * @param tree - The {@link Tree} to generate proofs for.
4412
4638
  * @returns Array of proofs - {@link Proof}
@@ -4415,7 +4641,7 @@ const proofs = (tree) => {
4415
4641
  return tree.offers.map((offer) => {
4416
4642
  return {
4417
4643
  offer,
4418
- path: tree.getProof([hash(offer)])
4644
+ path: tree.getProof(hash(offer))
4419
4645
  };
4420
4646
  });
4421
4647
  };
@@ -4546,16 +4772,17 @@ const encodeUnsigned = (tree) => {
4546
4772
  return bytesToHex(encodeUnsignedBytes(tree));
4547
4773
  };
4548
4774
  const validateTreeForEncoding = (tree) => {
4549
- if (VERSION > 255) throw new EncodeError(`version overflow: ${VERSION} exceeds 255`);
4775
+ if (VERSION$1 > 255) throw new EncodeError(`version overflow: ${VERSION$1} exceeds 255`);
4776
+ if (tree.offers.length > MAX_OFFERS_PER_TREE) throw new EncodeError(`offers payload exceeds ${MAX_OFFERS_PER_TREE} offers`);
4550
4777
  const computed = from$1(tree.offers);
4551
4778
  if (tree.root !== computed.root) throw new EncodeError(`root mismatch: expected ${computed.root}, got ${tree.root}`);
4552
4779
  };
4553
4780
  const encodeUnsignedBytes = (tree) => {
4554
4781
  const offersPayload = tree.offers.map(serialize);
4555
- const compressed = gzip(JSON.stringify(offersPayload));
4782
+ const compressed = gzipOffersPayload(JSON.stringify(offersPayload), (reason) => new EncodeError(reason));
4556
4783
  const rootBytes = hexToBytes(tree.root);
4557
- const encoded = new Uint8Array(1 + compressed.length + 32);
4558
- encoded[0] = VERSION;
4784
+ const encoded = new Uint8Array(1 + compressed.length + ROOT_BYTES);
4785
+ encoded[0] = VERSION$1;
4559
4786
  encoded.set(compressed, 1);
4560
4787
  encoded.set(rootBytes, 1 + compressed.length);
4561
4788
  return encoded;
@@ -4567,10 +4794,11 @@ const encodeUnsignedBytes = (tree) => {
4567
4794
  * Returns the tree with separately validated signature and recovered signer address.
4568
4795
  *
4569
4796
  * Validation order:
4570
- * 1. Version check
4797
+ * 1. Version and static size checks
4571
4798
  * 2. Signature verification (fail-fast, before decompression)
4572
- * 3. Decompression (only if signature valid)
4573
- * 4. Root verification (computed from offers vs embedded root)
4799
+ * 3. Streaming decompression with byte cap
4800
+ * 4. JSON array + offer count checks
4801
+ * 5. Root verification (computed from offers vs embedded root)
4574
4802
  *
4575
4803
  * @example
4576
4804
  * ```typescript
@@ -4587,33 +4815,20 @@ const decode = async (encoded, domain) => {
4587
4815
  const errorFactory = (reason) => new DecodeError(reason);
4588
4816
  const normalizedDomain = normalizeSignatureDomain(domain, errorFactory);
4589
4817
  const bytes = hexToBytes(encoded);
4590
- if (bytes.length < 98) throw new DecodeError("payload too short");
4818
+ if (bytes.length < MIN_SIGNED_PAYLOAD_BYTES) throw new DecodeError("payload too short");
4591
4819
  const version = bytes[0];
4592
- if (version !== (VERSION & 255)) throw new DecodeError(`invalid version: expected ${VERSION}, got ${version ?? 0}`);
4593
- const signature = bytesToHex(bytes.slice(-65));
4594
- const root = bytesToHex(bytes.slice(-97, -65));
4595
- assertHex(root, 32, "root");
4596
- assertHex(signature, 65, "signature");
4820
+ if (version !== (VERSION$1 & 255)) throw new DecodeError(`invalid version: expected ${VERSION$1}, got ${version ?? 0}`);
4821
+ const signature = bytesToHex(bytes.slice(-SIGNATURE_BYTES));
4822
+ const root = bytesToHex(bytes.slice(-(ROOT_BYTES + SIGNATURE_BYTES), -SIGNATURE_BYTES));
4823
+ assertHex(root, ROOT_BYTES, "root");
4824
+ assertHex(signature, SIGNATURE_BYTES, "signature");
4597
4825
  const signer = await verifySignatureAndRecoverAddress({
4598
4826
  root,
4599
4827
  signature,
4600
4828
  domain: normalizedDomain,
4601
4829
  errorFactory
4602
4830
  });
4603
- const compressed = bytes.slice(1, -97);
4604
- let decoded;
4605
- try {
4606
- decoded = ungzip(compressed, { to: "string" });
4607
- } catch {
4608
- throw new DecodeError("decompression failed");
4609
- }
4610
- let rawOffers;
4611
- try {
4612
- rawOffers = JSON.parse(decoded);
4613
- } catch {
4614
- throw new DecodeError("JSON parse failed");
4615
- }
4616
- const tree = from$1(rawOffers.map((o) => OfferSchema().parse(o)));
4831
+ const tree = from$1(parseRawOffersPayload(gunzipOffersPayload(bytes.slice(1, -(ROOT_BYTES + SIGNATURE_BYTES)), errorFactory), errorFactory).map((o) => OfferSchema().parse(o)));
4617
4832
  if (root !== tree.root) throw new DecodeError(`root mismatch: expected ${tree.root}, got ${root}`);
4618
4833
  return {
4619
4834
  tree,
@@ -4626,9 +4841,9 @@ const decode = async (encoded, domain) => {
4626
4841
  * Indicates structural issues with the tree (missing offers, inconsistent state).
4627
4842
  */
4628
4843
  var TreeError = class extends BaseError {
4844
+ name = "Tree.TreeError";
4629
4845
  constructor(reason) {
4630
4846
  super(`Tree error: ${reason}`);
4631
- _defineProperty(this, "name", "Tree.TreeError");
4632
4847
  }
4633
4848
  };
4634
4849
  /**
@@ -4636,9 +4851,9 @@ var TreeError = class extends BaseError {
4636
4851
  * Indicates validation failures (signature, root mismatch, mixed makers).
4637
4852
  */
4638
4853
  var EncodeError = class extends BaseError {
4854
+ name = "Tree.EncodeError";
4639
4855
  constructor(reason) {
4640
4856
  super(`Failed to encode tree: ${reason}`);
4641
- _defineProperty(this, "name", "Tree.EncodeError");
4642
4857
  }
4643
4858
  };
4644
4859
  /**
@@ -4646,18 +4861,18 @@ var EncodeError = class extends BaseError {
4646
4861
  * Indicates payload corruption, version mismatch, or validation failures.
4647
4862
  */
4648
4863
  var DecodeError = class extends BaseError {
4864
+ name = "Tree.DecodeError";
4649
4865
  constructor(reason) {
4650
4866
  super(`Failed to decode tree: ${reason}`);
4651
- _defineProperty(this, "name", "Tree.DecodeError");
4652
4867
  }
4653
4868
  };
4654
4869
  /**
4655
4870
  * Error thrown when an invalid signature domain is supplied.
4656
4871
  */
4657
4872
  var SignatureDomainError = class extends BaseError {
4873
+ name = "Tree.SignatureDomainError";
4658
4874
  constructor(reason) {
4659
4875
  super(`Invalid signature domain: ${reason}`);
4660
- _defineProperty(this, "name", "Tree.SignatureDomainError");
4661
4876
  }
4662
4877
  };
4663
4878
 
@@ -4732,11 +4947,10 @@ async function getOffers(apiClient, parameters) {
4732
4947
  return {
4733
4948
  ...fromSnakeCase$1({
4734
4949
  maker: offerData.maker,
4735
- assets: offerData.assets,
4736
4950
  obligation_units: offerData.obligation_units,
4737
- obligation_shares: offerData.obligation_shares,
4738
4951
  tick: offerData.tick,
4739
4952
  maturity: from$9(offerData.obligation.maturity),
4953
+ rcf_threshold: offerData.obligation.rcf_threshold,
4740
4954
  expiry: offerData.expiry,
4741
4955
  start: offerData.start,
4742
4956
  group: offerData.group,
@@ -4746,13 +4960,15 @@ async function getOffers(apiClient, parameters) {
4746
4960
  collaterals: offerData.obligation.collaterals.map((collateral) => ({
4747
4961
  asset: collateral.token,
4748
4962
  oracle: collateral.oracle,
4749
- lltv: collateral.lltv
4963
+ lltv: collateral.lltv,
4964
+ max_lif: collateral.max_lif
4750
4965
  })),
4751
4966
  callback: {
4752
4967
  address: offerData.callback,
4753
4968
  data: offerData.callback_data
4754
4969
  },
4755
- receiver_if_maker_is_seller: offerData.receiver_if_maker_is_seller
4970
+ receiver_if_maker_is_seller: offerData.receiver_if_maker_is_seller,
4971
+ exit_only: offerData.exit_only ?? false
4756
4972
  }),
4757
4973
  hash: item.offer_hash,
4758
4974
  consumed: BigInt(item.consumed),
@@ -4793,9 +5009,11 @@ async function getObligations(apiClient, parameters) {
4793
5009
  collaterals: item.collaterals.map((collateral) => ({
4794
5010
  asset: collateral.token,
4795
5011
  oracle: collateral.oracle,
4796
- lltv: collateral.lltv
5012
+ lltv: collateral.lltv,
5013
+ max_lif: collateral.max_lif
4797
5014
  })),
4798
- maturity: from$9(item.maturity)
5015
+ maturity: from$9(item.maturity),
5016
+ rcf_threshold: item.rcf_threshold
4799
5017
  });
4800
5018
  const { obligationId: _, ...quote } = from$4({
4801
5019
  obligationId: item.id,
@@ -4815,36 +5033,51 @@ async function getObligations(apiClient, parameters) {
4815
5033
  };
4816
5034
  }
4817
5035
  var InvalidUrlError = class extends BaseError {
5036
+ name = "Router.InvalidUrlError";
4818
5037
  constructor(url) {
4819
5038
  super(`URL "${url}" is not http/https.`);
4820
- _defineProperty(this, "name", "Router.InvalidUrlError");
4821
5039
  }
4822
5040
  };
4823
5041
  var HttpUnauthorizedError = class extends BaseError {
5042
+ name = "Router.HttpUnauthorizedError";
4824
5043
  constructor() {
4825
5044
  super("Unauthorized.", { metaMessages: ["Ensure that an API key is provided."] });
4826
- _defineProperty(this, "name", "Router.HttpUnauthorizedError");
4827
5045
  }
4828
5046
  };
4829
5047
  var HttpForbiddenError = class extends BaseError {
5048
+ name = "Router.HttpForbiddenError";
4830
5049
  constructor() {
4831
5050
  super("Forbidden.", { metaMessages: ["Ensure that the API key is valid."] });
4832
- _defineProperty(this, "name", "Router.HttpForbiddenError");
4833
5051
  }
4834
5052
  };
4835
5053
  var HttpRateLimitError = class extends BaseError {
5054
+ name = "Router.HttpRateLimitError";
4836
5055
  constructor() {
4837
5056
  super("Rate limit exceeded.", { metaMessages: ["The number of allowed requests has been exceeded. You must wait for the rate limit to reset."] });
4838
- _defineProperty(this, "name", "Router.HttpRateLimitError");
4839
5057
  }
4840
5058
  };
4841
5059
  var HttpGetApiFailedError = class extends BaseError {
5060
+ name = "Router.HttpGetApiFailedError";
4842
5061
  constructor(message, { details } = {}) {
4843
5062
  super(message, { metaMessages: [details] });
4844
- _defineProperty(this, "name", "Router.HttpGetApiFailedError");
4845
5063
  }
4846
5064
  };
4847
5065
 
5066
+ //#endregion
5067
+ //#region src/observability/TraceHeaders.ts
5068
+ /**
5069
+ * Inject active trace context headers into outgoing HTTP headers.
5070
+ * @param headers - Existing headers for the outgoing request.
5071
+ * @returns Headers enriched with active trace context.
5072
+ */
5073
+ function withActiveTraceHeaders(headers) {
5074
+ const enrichedHeaders = new Headers(headers);
5075
+ const carrier = {};
5076
+ propagation.inject(context.active(), carrier);
5077
+ for (const [key, value] of Object.entries(carrier)) enrichedHeaders.set(key, value);
5078
+ return enrichedHeaders;
5079
+ }
5080
+
4848
5081
  //#endregion
4849
5082
  //#region src/gatekeeper/Client.ts
4850
5083
  var Client_exports = /* @__PURE__ */ __exportAll({ createHttpClient: () => createHttpClient });
@@ -4865,7 +5098,7 @@ function createHttpClient(config) {
4865
5098
  try {
4866
5099
  return await fetchFn(`${baseUrl}${path}`, {
4867
5100
  ...init,
4868
- headers: mergeHeaders(baseHeaders, init.headers),
5101
+ headers: withActiveTraceHeaders(mergeHeaders(baseHeaders, init.headers)),
4869
5102
  signal: controller.signal
4870
5103
  });
4871
5104
  } finally {
@@ -5117,7 +5350,7 @@ const collateralAssets = {
5117
5350
  "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
5118
5351
  ]
5119
5352
  };
5120
- const oracles = {
5353
+ const oracles$1 = {
5121
5354
  [ChainId.ETHEREUM.toString()]: [
5122
5355
  "0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
5123
5356
  "0x9CB3f4276bcD149b3668e1a645a964bC12877b89",
@@ -5139,6 +5372,7 @@ const oracles = {
5139
5372
  ],
5140
5373
  [ChainId["ETHEREUM-VIRTUAL-TESTNET"].toString()]: [
5141
5374
  "0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
5375
+ "0xEeee770BADd886dF3864029e4B377B5F6a2B6b83",
5142
5376
  "0x9CB3f4276bcD149b3668e1a645a964bC12877b89",
5143
5377
  "0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2",
5144
5378
  "0x6Eb9F4128CeBc8B885A4d8562Db1Addf097f7348",
@@ -5147,6 +5381,7 @@ const oracles = {
5147
5381
  ],
5148
5382
  [ChainId.ANVIL.toString()]: [
5149
5383
  "0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
5384
+ "0xEeee770BADd886dF3864029e4B377B5F6a2B6b83",
5150
5385
  "0x9CB3f4276bcD149b3668e1a645a964bC12877b89",
5151
5386
  "0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2",
5152
5387
  "0x6Eb9F4128CeBc8B885A4d8562Db1Addf097f7348",
@@ -5157,30 +5392,698 @@ const oracles = {
5157
5392
  const configs = {
5158
5393
  ethereum: {
5159
5394
  callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
5160
- maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek]
5395
+ maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek],
5396
+ minDuration: 10
5161
5397
  },
5162
5398
  base: {
5163
5399
  callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
5164
- maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek]
5400
+ maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek],
5401
+ minDuration: 10
5165
5402
  },
5166
5403
  "ethereum-virtual-testnet": {
5167
5404
  callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
5168
- maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek]
5405
+ maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek],
5406
+ minDuration: 10
5169
5407
  },
5170
5408
  anvil: {
5171
5409
  callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
5172
- maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek]
5410
+ maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek],
5411
+ minDuration: 10
5412
+ }
5413
+ };
5414
+
5415
+ //#endregion
5416
+ //#region src/utils/retry.ts
5417
+ const retry = async (fn, attempts = 3, delayMs = 50) => {
5418
+ let lastErr;
5419
+ for (let i = 0; i < attempts; i++) try {
5420
+ return await fn();
5421
+ } catch (err) {
5422
+ lastErr = err;
5423
+ if (i < attempts - 1) await new Promise((r) => setTimeout(r, delayMs));
5424
+ }
5425
+ throw lastErr;
5426
+ };
5427
+
5428
+ //#endregion
5429
+ //#region src/utils/batchMulticall.ts
5430
+ /**
5431
+ * Helper function to execute multicall in batches with retry logic.
5432
+ * Abstracts the common pattern of batching calls, retrying, and collecting results.
5433
+ *
5434
+ * @param parameters - Configuration for batched multicall
5435
+ * @returns Promise resolving to flattened array of results
5436
+ */
5437
+ async function batchMulticall(parameters) {
5438
+ const { client, calls, batchSize, retryAttempts, retryDelayMs, blockNumber } = parameters;
5439
+ const results = [];
5440
+ for (const callsBatch of batch$1(calls, batchSize)) {
5441
+ const batchResults = await retry(() => multicall(client, {
5442
+ allowFailure: false,
5443
+ contracts: callsBatch,
5444
+ ...blockNumber ? { blockNumber } : {}
5445
+ }), retryAttempts, retryDelayMs);
5446
+ results.push(...batchResults);
5173
5447
  }
5448
+ return results;
5449
+ }
5450
+
5451
+ //#endregion
5452
+ //#region src/utils/Group.ts
5453
+ var Group_exports = /* @__PURE__ */ __exportAll({ fromNumber: () => fromNumber });
5454
+ /**
5455
+ * Creates a bytes32 group identifier from a number.
5456
+ * @param n - A non-negative integer.
5457
+ * @throws {Error} If n is negative or not an integer.
5458
+ */
5459
+ const fromNumber = (n) => {
5460
+ if (!Number.isInteger(n)) throw new Error(`Group.fromNumber: expected integer, got ${n}`);
5461
+ if (n < 0) throw new Error(`Group.fromNumber: expected non-negative, got ${n}`);
5462
+ return pad(`0x${n.toString(16)}`, { size: 32 });
5463
+ };
5464
+
5465
+ //#endregion
5466
+ //#region src/utils/lazy.ts
5467
+ /**
5468
+ * Transform a polling function into an async generator.
5469
+ * @param fn - The polling function to transform.
5470
+ * @returns An async generator.
5471
+ */
5472
+ function lazy(pollFn) {
5473
+ return () => (async function* () {
5474
+ let active = true;
5475
+ let resolveNext = null;
5476
+ const queue = [];
5477
+ const wait = () => new Promise((resolve) => {
5478
+ resolveNext = resolve;
5479
+ });
5480
+ const emit = (item) => {
5481
+ queue.push(item);
5482
+ resolveNext?.();
5483
+ resolveNext = null;
5484
+ };
5485
+ let unpoll = null;
5486
+ const stop = () => {
5487
+ active = false;
5488
+ unpoll?.();
5489
+ resolveNext?.();
5490
+ resolveNext = null;
5491
+ };
5492
+ unpoll = pollFn(emit, { stop });
5493
+ try {
5494
+ while (active) {
5495
+ if (queue.length === 0) await wait();
5496
+ while (queue.length > 0 && active) yield queue.shift();
5497
+ }
5498
+ } finally {
5499
+ stop();
5500
+ }
5501
+ })();
5502
+ }
5503
+
5504
+ //#endregion
5505
+ //#region src/utils/mapWithConcurrency.ts
5506
+ /**
5507
+ * Map values with a bounded number of concurrent async workers.
5508
+ *
5509
+ * Result ordering always matches the input order.
5510
+ * @param parameters - Input values, concurrency limit, and async mapper.
5511
+ * @returns Mapped results in input order.
5512
+ */
5513
+ async function mapWithConcurrency(parameters) {
5514
+ const { values, limit, run } = parameters;
5515
+ if (values.length === 0) return [];
5516
+ const normalizedLimit = Math.max(1, Math.floor(limit));
5517
+ const workerCount = Math.min(normalizedLimit, values.length);
5518
+ const results = new Array(values.length);
5519
+ let nextIndex = 0;
5520
+ const worker = async () => {
5521
+ while (true) {
5522
+ const index = nextIndex;
5523
+ if (index >= values.length) return;
5524
+ nextIndex += 1;
5525
+ results[index] = await run(values[index], index);
5526
+ }
5527
+ };
5528
+ await Promise.all(Array.from({ length: workerCount }, () => worker()));
5529
+ return results;
5530
+ }
5531
+
5532
+ //#endregion
5533
+ //#region src/utils/wait.ts
5534
+ async function wait(time) {
5535
+ return new Promise((res) => setTimeout(res, time));
5536
+ }
5537
+
5538
+ //#endregion
5539
+ //#region src/utils/poll.ts
5540
+ /**
5541
+ * Polls a function at a specified interval.
5542
+ * Inspired by https://github.com/wevm/viem/blob/845994d20275d08ff892018e237a4b599eeefb6a/src/utils/poll.ts
5543
+ */
5544
+ function poll(fn, { interval }) {
5545
+ let active = true;
5546
+ const unwatch = () => active = false;
5547
+ const watch = async () => {
5548
+ while (active) {
5549
+ const delay = await interval();
5550
+ if (!active) break;
5551
+ await wait(delay);
5552
+ if (!active) break;
5553
+ await fn({ unpoll: unwatch });
5554
+ }
5555
+ };
5556
+ watch();
5557
+ return unwatch;
5558
+ }
5559
+
5560
+ //#endregion
5561
+ //#region src/utils/time.ts
5562
+ var time_exports = /* @__PURE__ */ __exportAll({
5563
+ max: () => max,
5564
+ now: () => now
5565
+ });
5566
+ function now() {
5567
+ return Math.floor(Date.now() / 1e3);
5568
+ }
5569
+ function max() {
5570
+ return 0x77e772392b600000;
5571
+ }
5572
+
5573
+ //#endregion
5574
+ //#region src/utils/trim.ts
5575
+ /**
5576
+ * Keep the last `keep` entries from an array.
5577
+ * @param array - Source array.
5578
+ * @param keep - Number of entries to keep.
5579
+ * @returns Trimmed copy.
5580
+ */
5581
+ const trimTail = (array, keep) => {
5582
+ if (!Number.isInteger(keep) || keep < 0) throw new Error(`trimTail: expected non-negative integer keep, got ${keep}`);
5583
+ if (array.length <= keep) return array.slice();
5584
+ return array.slice(array.length - keep);
5174
5585
  };
5175
5586
 
5587
+ //#endregion
5588
+ //#region src/utils/index.ts
5589
+ var utils_exports = /* @__PURE__ */ __exportAll({
5590
+ BaseError: () => BaseError,
5591
+ Group: () => Group_exports,
5592
+ Random: () => Random_exports,
5593
+ ReorgError: () => ReorgError,
5594
+ Time: () => time_exports,
5595
+ atMostOneNonZero: () => atMostOneNonZero,
5596
+ batch: () => batch$1,
5597
+ batchMulticall: () => batchMulticall,
5598
+ fromSnakeCase: () => fromSnakeCase$3,
5599
+ lazy: () => lazy,
5600
+ mapWithConcurrency: () => mapWithConcurrency,
5601
+ max: () => max$1,
5602
+ min: () => min,
5603
+ poll: () => poll,
5604
+ retry: () => retry,
5605
+ stringifyBigint: () => stringifyBigint,
5606
+ toSnakeCase: () => toSnakeCase$1,
5607
+ trimTail: () => trimTail,
5608
+ wait: () => wait
5609
+ });
5610
+
5611
+ //#endregion
5612
+ //#region src/database/drizzle/VERSION.ts
5613
+ const VERSION = "router_v1.15";
5614
+
5615
+ //#endregion
5616
+ //#region src/database/drizzle/schema.ts
5617
+ const s = pgSchema(VERSION);
5618
+ var EnumTableName = /* @__PURE__ */ function(EnumTableName) {
5619
+ EnumTableName["OBLIGATIONS"] = "obligations";
5620
+ EnumTableName["OBLIGATION_ID_KEYS"] = "obligation_id_keys";
5621
+ EnumTableName["GROUPS"] = "groups";
5622
+ EnumTableName["CONSUMED_EVENTS"] = "consumed_events";
5623
+ EnumTableName["OBLIGATION_COLLATERALS_V2"] = "obligation_collaterals_v2";
5624
+ EnumTableName["ORACLES"] = "oracles";
5625
+ EnumTableName["OFFERS"] = "offers";
5626
+ EnumTableName["OFFERS_CALLBACKS"] = "offers_callbacks";
5627
+ EnumTableName["CALLBACKS"] = "callbacks";
5628
+ EnumTableName["POSITIONS"] = "positions";
5629
+ EnumTableName["TRANSFERS"] = "transfers";
5630
+ EnumTableName["VALIDATIONS"] = "validations";
5631
+ EnumTableName["COLLECTORS"] = "collectors";
5632
+ EnumTableName["CHAINS"] = "chains";
5633
+ EnumTableName["PENDING_LINKS"] = "pending_links";
5634
+ EnumTableName["LOTS"] = "lots";
5635
+ EnumTableName["LOTS_POSITIONS"] = "lots_positions";
5636
+ EnumTableName["OFFSETS"] = "offsets";
5637
+ EnumTableName["TREES"] = "trees";
5638
+ EnumTableName["MERKLE_PATHS"] = "merkle_paths";
5639
+ return EnumTableName;
5640
+ }(EnumTableName || {});
5641
+ const TABLE_NAMES = Object.values(EnumTableName);
5642
+ const VERSIONED_TABLE_NAMES = TABLE_NAMES.map((table) => `"${VERSION}"."${table}"`);
5643
+ const obligations = s.table(EnumTableName.OBLIGATIONS, {
5644
+ obligationKey: varchar("obligation_key", { length: 66 }).primaryKey(),
5645
+ loanToken: varchar("loan_token", { length: 42 }).notNull(),
5646
+ maturity: integer("maturity").notNull(),
5647
+ rcfThreshold: numeric("rcf_threshold", {
5648
+ precision: 78,
5649
+ scale: 0
5650
+ }).notNull()
5651
+ });
5652
+ const obligationIdKeys = s.table(EnumTableName.OBLIGATION_ID_KEYS, {
5653
+ obligationId: varchar("obligation_id", { length: 66 }).primaryKey(),
5654
+ obligationKey: varchar("obligation_key", { length: 66 }).notNull().references(() => obligations.obligationKey, { onDelete: "cascade" }),
5655
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5656
+ morphoV2: varchar("morpho_v2", { length: 42 }).notNull()
5657
+ }, (table) => [index("obligation_id_keys_obligation_key_idx").on(table.obligationKey), index("obligation_id_keys_chain_id_idx").on(table.chainId)]);
5658
+ const groups = s.table(EnumTableName.GROUPS, {
5659
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5660
+ maker: varchar("maker", { length: 42 }).notNull(),
5661
+ group: varchar("group", { length: 66 }).notNull(),
5662
+ consumed: numeric("consumed", {
5663
+ precision: 78,
5664
+ scale: 0
5665
+ }).notNull(),
5666
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5667
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5668
+ }, (table) => [primaryKey({
5669
+ columns: [
5670
+ table.chainId,
5671
+ table.maker,
5672
+ table.group
5673
+ ],
5674
+ name: "groups_pk"
5675
+ })]);
5676
+ const consumedEvents = s.table(EnumTableName.CONSUMED_EVENTS, {
5677
+ eventId: varchar("event_id", { length: 128 }).primaryKey(),
5678
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5679
+ maker: varchar("maker", { length: 42 }).notNull(),
5680
+ group: varchar("group", { length: 66 }).notNull(),
5681
+ amount: numeric("amount", {
5682
+ precision: 78,
5683
+ scale: 0
5684
+ }).notNull(),
5685
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5686
+ createdAt: timestamp("created_at").defaultNow().notNull()
5687
+ }, (t) => [
5688
+ foreignKey({
5689
+ columns: [
5690
+ t.chainId,
5691
+ t.maker,
5692
+ t.group
5693
+ ],
5694
+ foreignColumns: [
5695
+ groups.chainId,
5696
+ groups.maker,
5697
+ groups.group
5698
+ ],
5699
+ name: "consumed_events_groups_fk"
5700
+ }).onDelete("cascade"),
5701
+ index("consumed_events_group_idx").on(t.chainId, t.maker, t.group),
5702
+ index("consumed_events_block_number_idx").on(t.blockNumber)
5703
+ ]);
5704
+ const obligationCollateralsV2 = s.table(EnumTableName.OBLIGATION_COLLATERALS_V2, {
5705
+ obligationKey: varchar("obligation_key", { length: 66 }).notNull().references(() => obligations.obligationKey, { onDelete: "cascade" }),
5706
+ asset: varchar("asset", { length: 42 }).notNull(),
5707
+ oracleAddress: varchar("oracle_address", { length: 42 }).notNull(),
5708
+ lltv: bigint("lltv", { mode: "bigint" }).notNull(),
5709
+ maxLif: bigint("max_lif", { mode: "bigint" }).notNull(),
5710
+ collateralIndex: integer("collateral_index").notNull(),
5711
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5712
+ }, (table) => [primaryKey({
5713
+ columns: [table.obligationKey, table.asset],
5714
+ name: "obligation_collaterals_v2_pk"
5715
+ })]);
5716
+ const oracles = s.table(EnumTableName.ORACLES, {
5717
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5718
+ address: varchar("address", { length: 42 }).notNull(),
5719
+ price: numeric("price", {
5720
+ precision: 78,
5721
+ scale: 0
5722
+ }),
5723
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5724
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5725
+ }, (table) => [primaryKey({
5726
+ columns: [table.chainId, table.address],
5727
+ name: "oracles_pk"
5728
+ })]);
5729
+ const offers = s.table(EnumTableName.OFFERS, {
5730
+ hash: varchar("hash", { length: 66 }).notNull(),
5731
+ obligationId: varchar("obligation_id", { length: 66 }).notNull().references(() => obligationIdKeys.obligationId, { onDelete: "cascade" }),
5732
+ obligationUnits: numeric("obligation_units", {
5733
+ precision: 78,
5734
+ scale: 0
5735
+ }).notNull().default("0"),
5736
+ tick: integer("tick").notNull(),
5737
+ maturity: integer("maturity").notNull(),
5738
+ expiry: integer("expiry").notNull(),
5739
+ start: integer("start").notNull(),
5740
+ groupChainId: bigint("group_chain_id", { mode: "number" }).$type().notNull(),
5741
+ groupMaker: varchar("group_maker", { length: 42 }).notNull(),
5742
+ group: varchar("group_group", { length: 66 }).notNull(),
5743
+ session: varchar("session", { length: 66 }).notNull(),
5744
+ buy: boolean("buy").notNull(),
5745
+ callbackAddress: varchar("callback_address", { length: 42 }).notNull(),
5746
+ callbackData: text("callback_data").notNull(),
5747
+ receiverIfMakerIsSeller: varchar("receiver_if_maker_is_seller", { length: 42 }),
5748
+ exitOnly: boolean("exit_only").notNull().default(false),
5749
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5750
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5751
+ }, (table) => [
5752
+ primaryKey({
5753
+ columns: [table.hash, table.obligationId],
5754
+ name: "offers_pk"
5755
+ }),
5756
+ foreignKey({
5757
+ columns: [
5758
+ table.groupChainId,
5759
+ table.groupMaker,
5760
+ table.group
5761
+ ],
5762
+ foreignColumns: [
5763
+ groups.chainId,
5764
+ groups.maker,
5765
+ groups.group
5766
+ ],
5767
+ name: "offers_groups_fk"
5768
+ }).onDelete("cascade"),
5769
+ index("offers_group_and_hash_idx").on(table.groupChainId, table.groupMaker, table.group, table.hash),
5770
+ index("offers_obligation_side_tick_idx").on(table.obligationId, table.buy, table.tick),
5771
+ index("offers_obligation_active_tick_idx").on(table.obligationId, table.buy, table.expiry, table.maturity, table.start, table.tick),
5772
+ index("offers_group_maker_idx").on(table.groupMaker, table.hash, table.obligationId),
5773
+ index("offers_group_winner_expr_idx").on(table.groupChainId, table.groupMaker, table.group, table.obligationId, table.buy, sql`(CASE WHEN "buy" THEN -"tick" ELSE "tick" END)`, table.blockNumber, sql`"obligation_units" DESC`, table.hash),
5774
+ index("offers_book_winners_covering_idx").on(table.obligationId, table.buy, table.groupChainId, table.groupMaker, table.group, sql`(CASE WHEN "buy" THEN -"tick" ELSE "tick" END)`, table.blockNumber, sql`"obligation_units" DESC`, table.hash)
5775
+ ]);
5776
+ const offersCallbacks = s.table(EnumTableName.OFFERS_CALLBACKS, {
5777
+ offerHash: varchar("offer_hash", { length: 66 }).notNull(),
5778
+ obligationId: varchar("obligation_id", { length: 66 }).notNull(),
5779
+ callbackId: varchar("callback_id", { length: 66 })
5780
+ }, (table) => [foreignKey({
5781
+ columns: [table.offerHash, table.obligationId],
5782
+ foreignColumns: [offers.hash, offers.obligationId],
5783
+ name: "offers_callbacks_offer_fk"
5784
+ }).onDelete("cascade"), primaryKey({
5785
+ columns: [
5786
+ table.offerHash,
5787
+ table.obligationId,
5788
+ table.callbackId
5789
+ ],
5790
+ name: "offers_callbacks_pk"
5791
+ })]);
5792
+ const CallbackTypes = s.enum("callback_type", Object.values(CallbackType));
5793
+ const callbacks = s.table(EnumTableName.CALLBACKS, {
5794
+ id: varchar("id", { length: 66 }).primaryKey(),
5795
+ positionChainId: bigint("position_chain_id", { mode: "number" }).$type().notNull(),
5796
+ positionContract: varchar("position_contract", { length: 66 }).notNull(),
5797
+ positionUser: varchar("position_user", { length: 42 }).notNull(),
5798
+ positionTypeId: integer("position_type_id").notNull().references(() => positionTypes.id, { onDelete: "no action" }),
5799
+ type: CallbackTypes("type").notNull()
5800
+ });
5801
+ const lotsPositions = s.table(EnumTableName.LOTS_POSITIONS, {
5802
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5803
+ contract: varchar("contract", { length: 66 }).notNull(),
5804
+ user: varchar("user", { length: 42 }).notNull(),
5805
+ positionTypeId: integer("position_type_id").notNull().references(() => positionTypes.id, { onDelete: "no action" })
5806
+ }, (table) => [primaryKey({
5807
+ columns: [
5808
+ table.chainId,
5809
+ table.contract,
5810
+ table.user
5811
+ ],
5812
+ name: "lots_positions_pk"
5813
+ })]);
5814
+ const lots = s.table(EnumTableName.LOTS, {
5815
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5816
+ user: varchar("user", { length: 42 }).notNull(),
5817
+ contract: varchar("contract", { length: 66 }).notNull(),
5818
+ group: varchar("group", { length: 66 }).notNull(),
5819
+ obligationId: varchar("obligation_id", { length: 66 }).notNull(),
5820
+ lower: numeric("lower", {
5821
+ precision: 78,
5822
+ scale: 0
5823
+ }).notNull(),
5824
+ upper: numeric("upper", {
5825
+ precision: 78,
5826
+ scale: 0
5827
+ }).notNull()
5828
+ }, (table) => [
5829
+ primaryKey({
5830
+ columns: [
5831
+ table.chainId,
5832
+ table.user,
5833
+ table.contract,
5834
+ table.group,
5835
+ table.obligationId
5836
+ ],
5837
+ name: "lots_pk"
5838
+ }),
5839
+ foreignKey({
5840
+ columns: [
5841
+ table.chainId,
5842
+ table.contract,
5843
+ table.user
5844
+ ],
5845
+ foreignColumns: [
5846
+ lotsPositions.chainId,
5847
+ lotsPositions.contract,
5848
+ lotsPositions.user
5849
+ ],
5850
+ name: "lots_lots_positions_fk"
5851
+ }).onDelete("cascade"),
5852
+ foreignKey({
5853
+ columns: [
5854
+ table.chainId,
5855
+ table.user,
5856
+ table.group
5857
+ ],
5858
+ foreignColumns: [
5859
+ groups.chainId,
5860
+ groups.maker,
5861
+ groups.group
5862
+ ],
5863
+ name: "lots_groups_fk"
5864
+ }).onDelete("cascade"),
5865
+ index("lots_position_group_obligation_idx").on(table.chainId, table.user, table.group, table.obligationId)
5866
+ ]);
5867
+ const offsets = s.table(EnumTableName.OFFSETS, {
5868
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5869
+ user: varchar("user", { length: 42 }).notNull(),
5870
+ contract: varchar("contract", { length: 66 }).notNull(),
5871
+ group: varchar("group", { length: 66 }).notNull(),
5872
+ obligationId: varchar("obligation_id", { length: 66 }).notNull(),
5873
+ value: numeric("value", {
5874
+ precision: 78,
5875
+ scale: 0
5876
+ }).notNull()
5877
+ }, (table) => [
5878
+ primaryKey({
5879
+ columns: [
5880
+ table.chainId,
5881
+ table.user,
5882
+ table.contract,
5883
+ table.group,
5884
+ table.obligationId
5885
+ ],
5886
+ name: "offsets_pk"
5887
+ }),
5888
+ foreignKey({
5889
+ columns: [
5890
+ table.chainId,
5891
+ table.contract,
5892
+ table.user
5893
+ ],
5894
+ foreignColumns: [
5895
+ lotsPositions.chainId,
5896
+ lotsPositions.contract,
5897
+ lotsPositions.user
5898
+ ],
5899
+ name: "offsets_lots_positions_fk"
5900
+ }).onDelete("cascade"),
5901
+ index("offsets_position_obligation_idx").on(table.chainId, table.contract, table.user, table.obligationId)
5902
+ ]);
5903
+ const PositionTypes = s.enum("position_type", Object.values(Type));
5904
+ const positionTypes = s.table("position_types", {
5905
+ id: serial("id").primaryKey(),
5906
+ type: PositionTypes("type").notNull()
5907
+ });
5908
+ const positions = s.table(EnumTableName.POSITIONS, {
5909
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5910
+ contract: varchar("contract", { length: 66 }).notNull(),
5911
+ user: varchar("user", { length: 42 }).notNull(),
5912
+ positionTypeId: integer("position_type_id").notNull().references(() => positionTypes.id, { onDelete: "no action" }),
5913
+ balance: numeric("balance", {
5914
+ precision: 78,
5915
+ scale: 0
5916
+ }),
5917
+ asset: varchar("asset", { length: 42 }).notNull(),
5918
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5919
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5920
+ }, (table) => [primaryKey({
5921
+ columns: [
5922
+ table.chainId,
5923
+ table.contract,
5924
+ table.user,
5925
+ table.positionTypeId,
5926
+ table.asset
5927
+ ],
5928
+ name: "positions_pk"
5929
+ })]);
5930
+ const transfers = s.table(EnumTableName.TRANSFERS, {
5931
+ eventId: varchar("event_id", { length: 128 }).primaryKey(),
5932
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5933
+ contract: varchar("contract", { length: 66 }).notNull(),
5934
+ from: varchar("from", { length: 42 }).notNull(),
5935
+ to: varchar("to", { length: 42 }).notNull(),
5936
+ value: numeric("value", {
5937
+ precision: 78,
5938
+ scale: 0
5939
+ }).notNull(),
5940
+ positionTypeId: integer("position_type_id").notNull().references(() => positionTypes.id, { onDelete: "no action" }),
5941
+ asset: varchar("asset", { length: 42 }).notNull(),
5942
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5943
+ createdAt: timestamp("created_at").defaultNow().notNull()
5944
+ }, (table) => [
5945
+ foreignKey({
5946
+ columns: [
5947
+ table.chainId,
5948
+ table.contract,
5949
+ table.from,
5950
+ table.positionTypeId,
5951
+ table.asset
5952
+ ],
5953
+ foreignColumns: [
5954
+ positions.chainId,
5955
+ positions.contract,
5956
+ positions.user,
5957
+ positions.positionTypeId,
5958
+ positions.asset
5959
+ ],
5960
+ name: "transfers_positions_from_fk"
5961
+ }).onDelete("cascade"),
5962
+ foreignKey({
5963
+ columns: [
5964
+ table.chainId,
5965
+ table.contract,
5966
+ table.to,
5967
+ table.positionTypeId,
5968
+ table.asset
5969
+ ],
5970
+ foreignColumns: [
5971
+ positions.chainId,
5972
+ positions.contract,
5973
+ positions.user,
5974
+ positions.positionTypeId,
5975
+ positions.asset
5976
+ ],
5977
+ name: "transfers_positions_to_fk"
5978
+ }).onDelete("cascade"),
5979
+ index("transfers_chain_contract_user_idx").on(table.chainId, table.contract, table.from, table.to, table.blockNumber),
5980
+ index("transfers_chain_type_block_idx").on(table.chainId, table.positionTypeId, table.blockNumber)
5981
+ ]);
5982
+ const StatusCode = s.enum("status_code", Object.values(Status));
5983
+ const status = s.table("status", {
5984
+ id: serial("id").primaryKey(),
5985
+ code: StatusCode("code").unique()
5986
+ });
5987
+ const validations = s.table("validations", {
5988
+ offerHash: varchar("offer_hash", { length: 66 }).notNull(),
5989
+ obligationId: varchar("obligation_id", { length: 66 }).notNull(),
5990
+ statusId: integer("status_id").notNull().references(() => status.id, { onDelete: "no action" }),
5991
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5992
+ }, (table) => [primaryKey({
5993
+ columns: [table.offerHash, table.obligationId],
5994
+ name: "validations_pk"
5995
+ }), foreignKey({
5996
+ columns: [table.offerHash, table.obligationId],
5997
+ foreignColumns: [offers.hash, offers.obligationId],
5998
+ name: "validations_offer_fk"
5999
+ }).onDelete("cascade")]);
6000
+ const collectors = s.table(EnumTableName.COLLECTORS, {
6001
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull().references(() => chains.chainId, { onDelete: "no action" }),
6002
+ name: text("name").$type().notNull(),
6003
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
6004
+ epoch: numeric("epoch", {
6005
+ precision: 78,
6006
+ scale: 0
6007
+ }).default("0").notNull(),
6008
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
6009
+ }, (table) => [uniqueIndex("collectors_chain_name_idx").on(table.chainId, table.name)]);
6010
+ const chains = s.table(EnumTableName.CHAINS, {
6011
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
6012
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
6013
+ epoch: numeric("epoch", {
6014
+ precision: 78,
6015
+ scale: 0
6016
+ }).default("0").notNull(),
6017
+ checkpoints: text("checkpoints").default("[]").notNull(),
6018
+ tipHash: text("tip_hash"),
6019
+ finalizedBlockNumber: bigint("finalized_block_number", { mode: "number" }),
6020
+ finalizedBlockHash: text("finalized_block_hash"),
6021
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
6022
+ }, (table) => [uniqueIndex("chains_chain_id_idx").on(table.chainId)]);
6023
+ const pendingLinks = s.table(EnumTableName.PENDING_LINKS, {
6024
+ key: varchar("key", { length: 191 }).primaryKey(),
6025
+ type: text("type").notNull(),
6026
+ status: text("status").notNull(),
6027
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
6028
+ eventId: varchar("event_id", { length: 128 }).notNull(),
6029
+ obligationId: varchar("obligation_id", { length: 66 }).notNull(),
6030
+ collateralIndex: integer("collateral_index").notNull(),
6031
+ user: varchar("user", { length: 42 }).notNull(),
6032
+ amount: numeric("amount", {
6033
+ precision: 78,
6034
+ scale: 0
6035
+ }).notNull(),
6036
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
6037
+ firstSeenBlock: bigint("first_seen_block", { mode: "number" }).notNull(),
6038
+ lastTriedBlock: bigint("last_tried_block", { mode: "number" }),
6039
+ attempts: integer("attempts").notNull().default(0),
6040
+ ignoredReason: text("ignored_reason"),
6041
+ resolvedAt: timestamp("resolved_at"),
6042
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
6043
+ }, (table) => [index("pending_links_pending_scan_idx").on(table.chainId, table.type, table.status, table.firstSeenBlock), index("pending_links_event_id_idx").on(table.chainId, table.eventId)]);
6044
+ const trees = s.table(EnumTableName.TREES, {
6045
+ root: varchar("root", { length: 66 }).primaryKey(),
6046
+ rootSignature: varchar("root_signature", { length: 132 }).notNull(),
6047
+ createdAt: timestamp("created_at").defaultNow().notNull()
6048
+ });
6049
+ const merklePaths = s.table(EnumTableName.MERKLE_PATHS, {
6050
+ offerHash: varchar("offer_hash", { length: 66 }).notNull(),
6051
+ obligationId: varchar("obligation_id", { length: 66 }).notNull(),
6052
+ treeRoot: varchar("tree_root", { length: 66 }).notNull().references(() => trees.root, { onDelete: "cascade" }),
6053
+ proofNodes: text("proof_nodes").notNull(),
6054
+ createdAt: timestamp("created_at").defaultNow().notNull()
6055
+ }, (table) => [
6056
+ primaryKey({
6057
+ columns: [table.offerHash, table.obligationId],
6058
+ name: "merkle_paths_pk"
6059
+ }),
6060
+ foreignKey({
6061
+ columns: [table.offerHash, table.obligationId],
6062
+ foreignColumns: [offers.hash, offers.obligationId],
6063
+ name: "merkle_paths_offer_fk"
6064
+ }).onDelete("cascade"),
6065
+ index("merkle_paths_tree_root_idx").on(table.treeRoot)
6066
+ ]);
6067
+
6068
+ //#endregion
6069
+ //#region src/database/domains/Groups.ts
6070
+ /** Build composite key for a group. */
6071
+ function compositeKey(g) {
6072
+ return `${g.chainId}-${g.maker.toLowerCase()}-${g.group.toLowerCase()}`;
6073
+ }
6074
+
5176
6075
  //#endregion
5177
6076
  //#region src/gatekeeper/Rules.ts
5178
6077
  var Rules_exports = /* @__PURE__ */ __exportAll({
5179
- amountMutualExclusivity: () => amountMutualExclusivity,
6078
+ amountNonZero: () => amountNonZero,
5180
6079
  callback: () => callback,
5181
6080
  collateralToken: () => collateralToken,
6081
+ groupConsistency: () => groupConsistency,
6082
+ groupImmutability: () => groupImmutability,
5182
6083
  loanToken: () => loanToken,
5183
6084
  maturity: () => maturity,
6085
+ maxCollaterals: () => maxCollaterals,
6086
+ minDuration: () => minDuration,
5184
6087
  oracle: () => oracle,
5185
6088
  sameMaker: () => sameMaker
5186
6089
  });
@@ -5243,29 +6146,116 @@ const sameMaker = () => batch("mixed_maker", "Validates that all offers in a bat
5243
6146
  return issues;
5244
6147
  });
5245
6148
  /**
5246
- * A validation rule that ensures mutual exclusivity of offer amount fields.
5247
- * At most one of (assets, obligationUnits, obligationShares) can be non-zero.
5248
- * Matches contract requirement: `atMostOneNonZero(offer.assets, offer.obligationUnits, offer.obligationShares)`.
6149
+ * A validation rule that checks if the offer duration (expiry - start) meets a minimum threshold.
6150
+ * @param minSeconds - Minimum required duration in seconds.
6151
+ * @returns The issue that was found. If the offer is valid, this will be undefined.
6152
+ */
6153
+ const minDuration = ({ minSeconds }) => single("min_duration", `Validates that offer duration (expiry - start) is at least ${minSeconds}s`, (offer) => {
6154
+ const duration = offer.expiry - offer.start;
6155
+ if (duration < minSeconds) return { message: `Duration ${duration}s is below minimum ${minSeconds}s` };
6156
+ });
6157
+ /**
6158
+ * A validation rule that checks if an offer exceeds the maximum number of collaterals.
6159
+ * The contract enforces this limit; this rule rejects early to avoid on-chain reverts.
6160
+ * @param max - Maximum allowed collaterals per offer.
6161
+ * @returns The issue that was found. If the offer is valid, this will be undefined.
6162
+ */
6163
+ const maxCollaterals = ({ max }) => single("max_collaterals", `Validates that an offer has at most ${max} collaterals`, (offer) => {
6164
+ if (offer.collaterals.length > max) return { message: `Offer has ${offer.collaterals.length} collaterals, exceeding the maximum of ${max}` };
6165
+ });
6166
+ /**
6167
+ * A validation rule that checks if the offer's obligationUnits is non-zero.
6168
+ * The contract requires a positive amount; this rule rejects early.
6169
+ * @returns The issue that was found. If the offer is valid, this will be undefined.
6170
+ */
6171
+ const amountNonZero = () => single("amount_non_zero", "Validates that obligationUnits is non-zero", (offer) => {
6172
+ if (offer.obligationUnits === 0n) return { message: "obligationUnits must be non-zero" };
6173
+ });
6174
+ /**
6175
+ * A batch validation rule that ensures all offers within the same group are consistent.
6176
+ * All offers sharing the same group must have the same loan token, obligationUnits,
6177
+ * and side (buy/sell). The contract tracks consumed per group and requires these to match.
6178
+ */
6179
+ const groupConsistency = () => batch("group_consistency", "Validates that all offers in a group have the same loan token, obligation amounts, and side", (offers) => {
6180
+ const issues = /* @__PURE__ */ new Map();
6181
+ if (offers.length === 0) return issues;
6182
+ const groupMap = /* @__PURE__ */ new Map();
6183
+ for (let i = 0; i < offers.length; i++) {
6184
+ const key = offers[i].group.toLowerCase();
6185
+ const indices = groupMap.get(key);
6186
+ if (indices) indices.push(i);
6187
+ else groupMap.set(key, [i]);
6188
+ }
6189
+ for (const indices of groupMap.values()) {
6190
+ if (indices.length <= 1) continue;
6191
+ const reference = offers[indices[0]];
6192
+ const refLoanToken = reference.loanToken.toLowerCase();
6193
+ const refUnits = reference.obligationUnits;
6194
+ const refBuy = reference.buy;
6195
+ for (let j = 1; j < indices.length; j++) {
6196
+ const idx = indices[j];
6197
+ const offer = offers[idx];
6198
+ if (offer.loanToken.toLowerCase() !== refLoanToken) issues.set(idx, { message: `All offers in a group must have the same loan token. Expected ${reference.loanToken}, got ${offer.loanToken}` });
6199
+ else if (offer.obligationUnits !== refUnits) issues.set(idx, { message: `All offers in a group must have the same obligationUnits. Expected ${refUnits}, got ${offer.obligationUnits}` });
6200
+ else if (offer.buy !== refBuy) issues.set(idx, { message: `All offers in a group must be on the same side. Expected ${refBuy ? "buy" : "sell"}, got ${offer.buy ? "buy" : "sell"}` });
6201
+ }
6202
+ }
6203
+ return issues;
6204
+ });
6205
+ /**
6206
+ * A batch validation rule that prevents adding offers to groups that already exist in the database.
6207
+ * Groups are immutable after creation — new offers cannot be added to an existing group.
5249
6208
  */
5250
- const amountMutualExclusivity = () => single("amount_mutual_exclusivity", "Validates that at most one of (assets, obligationUnits, obligationShares) is non-zero", (offer) => {
5251
- if (!atMostOneNonZero(offer.assets, offer.obligationUnits, offer.obligationShares)) return { message: "Inconsistent offer input: at most one of (assets, obligationUnits, obligationShares) must be non-zero" };
6209
+ const groupImmutability = ({ db, chainId }) => batch("group_immutability", "Validates that offers do not target groups that already exist", async (offers) => {
6210
+ const issues = /* @__PURE__ */ new Map();
6211
+ if (offers.length === 0) return issues;
6212
+ const uniqueGroups = /* @__PURE__ */ new Map();
6213
+ for (const offer of offers) {
6214
+ const key = compositeKey({
6215
+ chainId,
6216
+ maker: offer.maker,
6217
+ group: offer.group
6218
+ });
6219
+ if (!uniqueGroups.has(key)) uniqueGroups.set(key, {
6220
+ chainId,
6221
+ maker: offer.maker,
6222
+ group: offer.group
6223
+ });
6224
+ }
6225
+ const existingKeys = await db.groups.exists(Array.from(uniqueGroups.values()));
6226
+ if (existingKeys.length === 0) return issues;
6227
+ const existingSet = new Set(existingKeys.map((k) => compositeKey(k)));
6228
+ for (let i = 0; i < offers.length; i++) {
6229
+ const offer = offers[i];
6230
+ const key = compositeKey({
6231
+ chainId,
6232
+ maker: offer.maker,
6233
+ group: offer.group
6234
+ });
6235
+ if (existingSet.has(key)) issues.set(i, { message: `Cannot add offers to existing group ${offer.group}` });
6236
+ }
6237
+ return issues;
5252
6238
  });
5253
6239
 
5254
6240
  //#endregion
5255
6241
  //#region src/gatekeeper/morphoRules.ts
5256
6242
  const morphoRules = (parameters) => {
5257
- const { chains, chainId } = parameters;
6243
+ const { chains, chainId, db } = parameters;
6244
+ const requestChain = chains.find((c) => c.id === chainId);
6245
+ const config = requestChain ? configs[requestChain.name] : void 0;
5258
6246
  const assetsByChainId = {};
5259
6247
  const collateralAssetsByChainId = {};
5260
6248
  const oraclesByChainId = {};
5261
6249
  for (const chain of chains) {
5262
6250
  assetsByChainId[chain.id] = assets[chain.id.toString()] ?? [];
5263
6251
  collateralAssetsByChainId[chain.id] = collateralAssets[chain.id.toString()] ?? [];
5264
- oraclesByChainId[chain.id] = oracles[chain.id.toString()] ?? [];
6252
+ oraclesByChainId[chain.id] = oracles$1[chain.id.toString()] ?? [];
5265
6253
  }
5266
- return [
6254
+ const rules = [
5267
6255
  sameMaker(),
5268
- amountMutualExclusivity(),
6256
+ amountNonZero(),
6257
+ groupConsistency(),
6258
+ ...config?.minDuration != null ? [minDuration({ minSeconds: config.minDuration })] : [],
5269
6259
  maturity({ maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek] }),
5270
6260
  callback({
5271
6261
  callbacks: [Type$1.BuyWithEmptyCallback, Type$1.SellWithEmptyCallback],
@@ -5275,6 +6265,7 @@ const morphoRules = (parameters) => {
5275
6265
  assetsByChainId,
5276
6266
  chainId
5277
6267
  }),
6268
+ maxCollaterals({ max: 128 }),
5278
6269
  collateralToken({
5279
6270
  collateralAssetsByChainId,
5280
6271
  chainId
@@ -5284,6 +6275,11 @@ const morphoRules = (parameters) => {
5284
6275
  chainId
5285
6276
  })
5286
6277
  ];
6278
+ if (db) rules.push(groupImmutability({
6279
+ db,
6280
+ chainId
6281
+ }));
6282
+ return rules;
5287
6283
  };
5288
6284
 
5289
6285
  //#endregion
@@ -5409,16 +6405,13 @@ async function* streamOffers(config, parameters) {
5409
6405
  };
5410
6406
  }
5411
6407
  var WalletAccountNotSetError = class extends BaseError {
6408
+ name = "Mempool.WalletAccountNotSetError";
5412
6409
  constructor() {
5413
6410
  super("Wallet account is not set.");
5414
- _defineProperty(this, "name", "Mempool.WalletAccountNotSetError");
5415
6411
  }
5416
6412
  };
5417
6413
  var ViemClientError = class extends BaseError {
5418
- constructor(..._args) {
5419
- super(..._args);
5420
- _defineProperty(this, "name", "Mempool.ViemClientError");
5421
- }
6414
+ name = "Mempool.ViemClientError";
5422
6415
  };
5423
6416
  const resolveSignatureDomain = (config, chainId) => {
5424
6417
  const chain = config.client.chain;
@@ -5430,9 +6423,9 @@ const resolveSignatureDomain = (config, chainId) => {
5430
6423
  };
5431
6424
  };
5432
6425
  var MissingMorphoAddressError = class extends BaseError {
6426
+ name = "Mempool.MissingMorphoAddressError";
5433
6427
  constructor() {
5434
6428
  super("Morpho address is required to verify root signatures (zero address is invalid).");
5435
- _defineProperty(this, "name", "Mempool.MissingMorphoAddressError");
5436
6429
  }
5437
6430
  };
5438
6431
 
@@ -5446,158 +6439,6 @@ function connect(parameters) {
5446
6439
  return from(parameters);
5447
6440
  }
5448
6441
 
5449
- //#endregion
5450
- //#region src/utils/retry.ts
5451
- const retry = async (fn, attempts = 3, delayMs = 50) => {
5452
- let lastErr;
5453
- for (let i = 0; i < attempts; i++) try {
5454
- return await fn();
5455
- } catch (err) {
5456
- lastErr = err;
5457
- if (i < attempts - 1) await new Promise((r) => setTimeout(r, delayMs));
5458
- }
5459
- throw lastErr;
5460
- };
5461
-
5462
- //#endregion
5463
- //#region src/utils/batchMulticall.ts
5464
- /**
5465
- * Helper function to execute multicall in batches with retry logic.
5466
- * Abstracts the common pattern of batching calls, retrying, and collecting results.
5467
- *
5468
- * @param parameters - Configuration for batched multicall
5469
- * @returns Promise resolving to flattened array of results
5470
- */
5471
- async function batchMulticall(parameters) {
5472
- const { client, calls, batchSize, retryAttempts, retryDelayMs, blockNumber } = parameters;
5473
- const results = [];
5474
- for (const callsBatch of batch$1(calls, batchSize)) {
5475
- const batchResults = await retry(() => multicall(client, {
5476
- allowFailure: false,
5477
- contracts: callsBatch,
5478
- ...blockNumber ? { blockNumber } : {}
5479
- }), retryAttempts, retryDelayMs);
5480
- results.push(...batchResults);
5481
- }
5482
- return results;
5483
- }
5484
-
5485
- //#endregion
5486
- //#region src/utils/Group.ts
5487
- var Group_exports = /* @__PURE__ */ __exportAll({ fromNumber: () => fromNumber });
5488
- /**
5489
- * Creates a bytes32 group identifier from a number.
5490
- * @param n - A non-negative integer.
5491
- * @throws {Error} If n is negative or not an integer.
5492
- */
5493
- const fromNumber = (n) => {
5494
- if (!Number.isInteger(n)) throw new Error(`Group.fromNumber: expected integer, got ${n}`);
5495
- if (n < 0) throw new Error(`Group.fromNumber: expected non-negative, got ${n}`);
5496
- return pad(`0x${n.toString(16)}`, { size: 32 });
5497
- };
5498
-
5499
- //#endregion
5500
- //#region src/utils/lazy.ts
5501
- /**
5502
- * Transform a polling function into an async generator.
5503
- * @param fn - The polling function to transform.
5504
- * @returns An async generator.
5505
- */
5506
- function lazy(pollFn) {
5507
- return () => (async function* () {
5508
- let active = true;
5509
- let resolveNext = null;
5510
- const queue = [];
5511
- const wait = () => new Promise((resolve) => {
5512
- resolveNext = resolve;
5513
- });
5514
- const emit = (item) => {
5515
- queue.push(item);
5516
- resolveNext?.();
5517
- resolveNext = null;
5518
- };
5519
- let unpoll = null;
5520
- const stop = () => {
5521
- active = false;
5522
- unpoll?.();
5523
- resolveNext?.();
5524
- resolveNext = null;
5525
- };
5526
- unpoll = pollFn(emit, { stop });
5527
- try {
5528
- while (active) {
5529
- if (queue.length === 0) await wait();
5530
- while (queue.length > 0 && active) yield queue.shift();
5531
- }
5532
- } finally {
5533
- stop();
5534
- }
5535
- })();
5536
- }
5537
-
5538
- //#endregion
5539
- //#region src/utils/wait.ts
5540
- async function wait(time) {
5541
- return new Promise((res) => setTimeout(res, time));
5542
- }
5543
-
5544
- //#endregion
5545
- //#region src/utils/poll.ts
5546
- /**
5547
- * Polls a function at a specified interval.
5548
- * Inspired by https://github.com/wevm/viem/blob/845994d20275d08ff892018e237a4b599eeefb6a/src/utils/poll.ts
5549
- */
5550
- function poll(fn, { interval }) {
5551
- let active = true;
5552
- const unwatch = () => active = false;
5553
- const watch = async () => {
5554
- while (active) {
5555
- const delay = await interval();
5556
- if (!active) break;
5557
- await wait(delay);
5558
- if (!active) break;
5559
- await fn({ unpoll: unwatch });
5560
- }
5561
- };
5562
- watch();
5563
- return unwatch;
5564
- }
5565
-
5566
- //#endregion
5567
- //#region src/utils/time.ts
5568
- var time_exports = /* @__PURE__ */ __exportAll({
5569
- max: () => max,
5570
- now: () => now
5571
- });
5572
- function now() {
5573
- return Math.floor(Date.now() / 1e3);
5574
- }
5575
- function max() {
5576
- return 0x77e772392b600000;
5577
- }
5578
-
5579
- //#endregion
5580
- //#region src/utils/index.ts
5581
- var utils_exports = /* @__PURE__ */ __exportAll({
5582
- BaseError: () => BaseError,
5583
- Group: () => Group_exports,
5584
- Random: () => Random_exports,
5585
- ReorgError: () => ReorgError,
5586
- Time: () => time_exports,
5587
- atMostOneNonZero: () => atMostOneNonZero,
5588
- batch: () => batch$1,
5589
- batchMulticall: () => batchMulticall,
5590
- fromSnakeCase: () => fromSnakeCase$3,
5591
- lazy: () => lazy,
5592
- max: () => max$1,
5593
- min: () => min,
5594
- poll: () => poll,
5595
- retry: () => retry,
5596
- stringifyBigint: () => stringifyBigint,
5597
- toSnakeCase: () => toSnakeCase$1,
5598
- wait: () => wait
5599
- });
5600
-
5601
6442
  //#endregion
5602
6443
  export { Abi_exports as Abi, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain, ChainRegistry_exports as ChainRegistry, Collateral_exports as Collateral, ERC4626_exports as ERC4626, Errors_exports as Errors, Format_exports as Format, Gatekeeper_exports as Gatekeeper, Client_exports as GatekeeperClient, Id_exports as Id, LLTV_exports as LLTV, Liquidity_exports as Liquidity, Maturity_exports as Maturity, MempoolClient_exports as Mempool, Obligation_exports as Obligation, Offer_exports as Offer, Oracle_exports as Oracle, Position_exports as Position, Quote_exports as Quote, Schema_exports as RouterApi, Client_exports$1 as RouterClient, Rules_exports as Rules, Tick_exports as Tick, time_exports as Time, TradingFee_exports as TradingFee, Transfer_exports as Transfer, Tree_exports as Tree, utils_exports as Utils, Gate_exports as Validation, morphoRules };
5603
6444
  //# sourceMappingURL=index.browser.mjs.map