@morpho-org/midnight-sdk 0.1.0 → 1.0.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 (118) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +56 -46
  3. package/lib/cjs/abis.d.ts +1185 -996
  4. package/lib/cjs/abis.js +1445 -1211
  5. package/lib/cjs/api/MidnightApi.d.ts +22 -16
  6. package/lib/cjs/api/MidnightApi.js +22 -16
  7. package/lib/cjs/api/helpers.js +6 -3
  8. package/lib/cjs/api/types.d.ts +35 -9
  9. package/lib/cjs/constants.d.ts +12 -11
  10. package/lib/cjs/constants.js +14 -12
  11. package/lib/cjs/errors.d.ts +74 -1
  12. package/lib/cjs/errors.js +94 -3
  13. package/lib/cjs/fetch/Market.js +0 -1
  14. package/lib/cjs/fetch/index.d.ts +0 -1
  15. package/lib/cjs/fetch/index.js +0 -1
  16. package/lib/cjs/index.d.ts +1 -1
  17. package/lib/cjs/index.js +2 -23
  18. package/lib/cjs/market/Market.d.ts +99 -33
  19. package/lib/cjs/market/Market.js +137 -28
  20. package/lib/cjs/market/MarketUtils.d.ts +61 -41
  21. package/lib/cjs/market/MarketUtils.js +108 -48
  22. package/lib/cjs/market/Position.d.ts +16 -11
  23. package/lib/cjs/market/Position.js +18 -12
  24. package/lib/cjs/market/PositionUtils.d.ts +6 -4
  25. package/lib/cjs/market/PositionUtils.js +9 -6
  26. package/lib/cjs/math/TickLib.d.ts +22 -0
  27. package/lib/cjs/math/TickLib.js +30 -0
  28. package/lib/cjs/math/index.d.ts +0 -1
  29. package/lib/cjs/math/index.js +0 -1
  30. package/lib/cjs/offers/Offer.d.ts +217 -11
  31. package/lib/cjs/offers/Offer.js +215 -7
  32. package/lib/cjs/offers/OfferUtils.d.ts +245 -139
  33. package/lib/cjs/offers/OfferUtils.js +304 -36
  34. package/lib/cjs/queries/GetPosition.d.ts +1 -1
  35. package/lib/cjs/queries/GetPosition.js +1 -1
  36. package/lib/cjs/signatures/EcrecoverRatifierUtils.d.ts +66 -38
  37. package/lib/cjs/signatures/EcrecoverRatifierUtils.js +147 -79
  38. package/lib/cjs/signatures/Group.d.ts +12 -4
  39. package/lib/cjs/signatures/Group.js +12 -4
  40. package/lib/cjs/signatures/GroupUtils.d.ts +12 -4
  41. package/lib/cjs/signatures/GroupUtils.js +6 -2
  42. package/lib/cjs/signatures/Payload.d.ts +277 -277
  43. package/lib/cjs/signatures/Payload.js +517 -534
  44. package/lib/cjs/signatures/RatifierUtils.d.ts +57 -0
  45. package/lib/cjs/signatures/RatifierUtils.js +94 -0
  46. package/lib/cjs/signatures/SetterRatifierUtils.d.ts +21 -13
  47. package/lib/cjs/signatures/SetterRatifierUtils.js +25 -20
  48. package/lib/cjs/signatures/Tree.d.ts +28 -16
  49. package/lib/cjs/signatures/Tree.js +25 -13
  50. package/lib/cjs/signatures/TreeUtils.d.ts +181 -62
  51. package/lib/cjs/signatures/TreeUtils.js +73 -76
  52. package/lib/cjs/signatures/index.d.ts +1 -0
  53. package/lib/cjs/signatures/index.js +3 -0
  54. package/lib/cjs/signatures/offerStructInternal.d.ts +14 -0
  55. package/lib/cjs/signatures/offerStructInternal.js +72 -0
  56. package/lib/esm/abis.d.ts +1185 -996
  57. package/lib/esm/abis.js +1445 -1211
  58. package/lib/esm/api/MidnightApi.d.ts +22 -16
  59. package/lib/esm/api/MidnightApi.js +23 -17
  60. package/lib/esm/api/helpers.js +6 -3
  61. package/lib/esm/api/types.d.ts +35 -9
  62. package/lib/esm/constants.d.ts +12 -11
  63. package/lib/esm/constants.js +13 -11
  64. package/lib/esm/errors.d.ts +74 -1
  65. package/lib/esm/errors.js +89 -2
  66. package/lib/esm/fetch/Market.js +0 -1
  67. package/lib/esm/fetch/index.d.ts +0 -1
  68. package/lib/esm/fetch/index.js +0 -1
  69. package/lib/esm/index.d.ts +1 -1
  70. package/lib/esm/index.js +1 -1
  71. package/lib/esm/market/Market.d.ts +99 -33
  72. package/lib/esm/market/Market.js +137 -28
  73. package/lib/esm/market/MarketUtils.d.ts +61 -41
  74. package/lib/esm/market/MarketUtils.js +109 -49
  75. package/lib/esm/market/Position.d.ts +16 -11
  76. package/lib/esm/market/Position.js +19 -13
  77. package/lib/esm/market/PositionUtils.d.ts +6 -4
  78. package/lib/esm/market/PositionUtils.js +9 -6
  79. package/lib/esm/math/TickLib.d.ts +22 -0
  80. package/lib/esm/math/TickLib.js +31 -1
  81. package/lib/esm/math/index.d.ts +0 -1
  82. package/lib/esm/math/index.js +0 -1
  83. package/lib/esm/offers/Offer.d.ts +217 -11
  84. package/lib/esm/offers/Offer.js +216 -8
  85. package/lib/esm/offers/OfferUtils.d.ts +245 -139
  86. package/lib/esm/offers/OfferUtils.js +306 -38
  87. package/lib/esm/queries/GetPosition.d.ts +1 -1
  88. package/lib/esm/queries/GetPosition.js +1 -1
  89. package/lib/esm/signatures/EcrecoverRatifierUtils.d.ts +66 -38
  90. package/lib/esm/signatures/EcrecoverRatifierUtils.js +149 -81
  91. package/lib/esm/signatures/Group.d.ts +12 -4
  92. package/lib/esm/signatures/Group.js +12 -4
  93. package/lib/esm/signatures/GroupUtils.d.ts +12 -4
  94. package/lib/esm/signatures/GroupUtils.js +6 -2
  95. package/lib/esm/signatures/Payload.d.ts +277 -277
  96. package/lib/esm/signatures/Payload.js +517 -531
  97. package/lib/esm/signatures/RatifierUtils.d.ts +57 -0
  98. package/lib/esm/signatures/RatifierUtils.js +94 -0
  99. package/lib/esm/signatures/SetterRatifierUtils.d.ts +21 -13
  100. package/lib/esm/signatures/SetterRatifierUtils.js +25 -20
  101. package/lib/esm/signatures/Tree.d.ts +28 -16
  102. package/lib/esm/signatures/Tree.js +25 -13
  103. package/lib/esm/signatures/TreeUtils.d.ts +181 -62
  104. package/lib/esm/signatures/TreeUtils.js +75 -78
  105. package/lib/esm/signatures/index.d.ts +1 -0
  106. package/lib/esm/signatures/index.js +1 -0
  107. package/lib/esm/signatures/offerStructInternal.d.ts +14 -0
  108. package/lib/esm/signatures/offerStructInternal.js +67 -0
  109. package/package.json +28 -32
  110. package/src/index.ts +1 -1
  111. package/lib/cjs/fetch/Offer.d.ts +0 -74
  112. package/lib/cjs/fetch/Offer.js +0 -119
  113. package/lib/cjs/math/ConsumableUnitsLib.d.ts +0 -57
  114. package/lib/cjs/math/ConsumableUnitsLib.js +0 -77
  115. package/lib/esm/fetch/Offer.d.ts +0 -74
  116. package/lib/esm/fetch/Offer.js +0 -116
  117. package/lib/esm/math/ConsumableUnitsLib.d.ts +0 -57
  118. package/lib/esm/math/ConsumableUnitsLib.js +0 -74
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OfferUtils = void 0;
4
+ const morpho_ts_1 = require("@morpho-org/morpho-ts");
4
5
  const viem_1 = require("viem");
5
6
  const constants_js_1 = require("../constants.js");
6
7
  const errors_js_1 = require("../errors.js");
7
8
  const index_js_1 = require("../market/index.js");
9
+ const index_js_2 = require("../math/index.js");
8
10
  const Offer_js_1 = require("./Offer.js");
9
11
  const comparableHex = (value) => value.toLowerCase();
10
12
  const offerHashParams = [
@@ -21,8 +23,8 @@ const offerHashParams = [
21
23
  { name: "receiverIfMakerIsSeller", type: "address" },
22
24
  { name: "ratifier", type: "address" },
23
25
  { name: "reduceOnly", type: "bool" },
24
- { name: "maxUnits", type: "uint256" },
25
- { name: "maxAssets", type: "uint256" },
26
+ { name: "maxUnits", type: "uint128" },
27
+ { name: "maxAssets", type: "uint128" },
26
28
  { name: "continuousFeeCap", type: "uint256" },
27
29
  ];
28
30
  /**
@@ -59,12 +61,14 @@ var OfferUtils;
59
61
  *
60
62
  * const offer = Offer.create({
61
63
  * market: {
64
+ * chainId: 8453,
65
+ * midnight: "0x0000000000000000000000000000000000001000",
62
66
  * loanToken: "0x0000000000000000000000000000000000006000",
63
67
  * collateralParams: [
64
68
  * {
65
69
  * token: "0x0000000000000000000000000000000000007000",
66
70
  * lltv: 770000000000000000n,
67
- * maxLif: 1061007957559681697n,
71
+ * liquidationCursor: 250000000000000000n,
68
72
  * oracle: "0x0000000000000000000000000000000000008000",
69
73
  * },
70
74
  * ],
@@ -123,12 +127,14 @@ var OfferUtils;
123
127
  *
124
128
  * const offer = Offer.create({
125
129
  * market: {
130
+ * chainId: 8453,
131
+ * midnight: "0x0000000000000000000000000000000000001000",
126
132
  * loanToken: "0x0000000000000000000000000000000000006000",
127
133
  * collateralParams: [
128
134
  * {
129
135
  * token: "0x0000000000000000000000000000000000007000",
130
136
  * lltv: 770000000000000000n,
131
- * maxLif: 1061007957559681697n,
137
+ * liquidationCursor: 250000000000000000n,
132
138
  * oracle: "0x0000000000000000000000000000000000008000",
133
139
  * },
134
140
  * ],
@@ -186,12 +192,14 @@ var OfferUtils;
186
192
  *
187
193
  * const offer = Offer.create({
188
194
  * market: {
195
+ * chainId: 8453,
196
+ * midnight: "0x0000000000000000000000000000000000001000",
189
197
  * loanToken: "0x0000000000000000000000000000000000006000",
190
198
  * collateralParams: [
191
199
  * {
192
200
  * token: "0x0000000000000000000000000000000000007000",
193
201
  * lltv: 770000000000000000n,
194
- * maxLif: 1061007957559681697n,
202
+ * liquidationCursor: 250000000000000000n,
195
203
  * oracle: "0x0000000000000000000000000000000000008000",
196
204
  * },
197
205
  * ],
@@ -232,12 +240,14 @@ var OfferUtils;
232
240
  *
233
241
  * const offer = Offer.create({
234
242
  * market: {
243
+ * chainId: 8453,
244
+ * midnight: "0x0000000000000000000000000000000000001000",
235
245
  * loanToken: "0x0000000000000000000000000000000000006000",
236
246
  * collateralParams: [
237
247
  * {
238
248
  * token: "0x0000000000000000000000000000000000007000",
239
249
  * lltv: 770000000000000000n,
240
- * maxLif: 1061007957559681697n,
250
+ * liquidationCursor: 250000000000000000n,
241
251
  * oracle: "0x0000000000000000000000000000000000008000",
242
252
  * },
243
253
  * ],
@@ -315,7 +325,7 @@ var OfferUtils;
315
325
  * @param params.start - Optional offer start timestamp; defaults to zero.
316
326
  * @param params.expiry - Offer expiry timestamp.
317
327
  * @returns Normalized start and expiry timestamps.
318
- * @throws {InvalidOfferParameterError} when the range is negative or not strictly increasing.
328
+ * @throws {InvalidOfferParameterError} when the range is negative or expiry is before start.
319
329
  * @example
320
330
  * ```ts
321
331
  * import { OfferUtils } from "@morpho-org/midnight-sdk";
@@ -334,11 +344,11 @@ var OfferUtils;
334
344
  instruction: "Use a non-negative timestamp.",
335
345
  });
336
346
  }
337
- if (expiry < 0n || expiry <= start) {
347
+ if (expiry < 0n || expiry < start) {
338
348
  throw new errors_js_1.InvalidOfferParameterError({
339
349
  parameter: "expiry",
340
350
  value: expiry,
341
- instruction: `Use an expiry greater than start "${start}".`,
351
+ instruction: `Use an expiry greater than or equal to start "${start}".`,
342
352
  });
343
353
  }
344
354
  return { start, expiry };
@@ -379,6 +389,20 @@ var OfferUtils;
379
389
  instruction: "Use a non-negative cap.",
380
390
  });
381
391
  }
392
+ if (maxUnits > constants_js_1.MAX_OFFER_CAP) {
393
+ throw new errors_js_1.InvalidOfferParameterError({
394
+ parameter: "maxUnits",
395
+ value: maxUnits,
396
+ instruction: `Use a cap less than or equal to "${constants_js_1.MAX_OFFER_CAP}".`,
397
+ });
398
+ }
399
+ if (maxAssets > constants_js_1.MAX_OFFER_CAP) {
400
+ throw new errors_js_1.InvalidOfferParameterError({
401
+ parameter: "maxAssets",
402
+ value: maxAssets,
403
+ instruction: `Use a cap less than or equal to "${constants_js_1.MAX_OFFER_CAP}".`,
404
+ });
405
+ }
382
406
  if ((maxAssets === 0n) === (maxUnits === 0n)) {
383
407
  throw new errors_js_1.InvalidOfferParameterError({
384
408
  parameter: "maxUnits/maxAssets",
@@ -461,22 +485,16 @@ var OfferUtils;
461
485
  * instantiating an `Offer`. `Offer.create` uses the same validation and then
462
486
  * constructs the class instance for grouping and trees.
463
487
  *
464
- * @param params.market - Market params or hydrated market this offer trades.
465
488
  * @param params.buy - Whether the maker buys loan assets.
466
489
  * @param params.maker - Maker address.
467
490
  * @param params.tick - Offer tick.
468
- * @param params.group - Optional consumption group id for already-grouped offers.
469
491
  * @param params.tickSpacing - Optional market tick spacing; defaults to `DEFAULT_TICK_SPACING`.
470
492
  * @param params.maxUnits - Optional unit cap; defaults to zero.
471
493
  * @param params.maxAssets - Optional buyer or seller asset cap; defaults to zero.
472
494
  * @param params.continuousFeeCap - Optional maximum market continuous fee accepted by this offer; defaults to `MAX_CONTINUOUS_FEE`.
473
495
  * @param params.start - Optional offer start timestamp; defaults to zero.
474
496
  * @param params.expiry - Offer expiry timestamp.
475
- * @param params.callback - Optional callback address; defaults to the zero address.
476
- * @param params.callbackData - Optional callback payload; defaults to `0x`.
477
497
  * @param params.receiverIfMakerIsSeller - Optional receiver used when maker is seller.
478
- * @param params.ratifier - Ratifier contract address.
479
- * @param params.reduceOnly - Optional flag restricting the offer to exposure-reducing execution.
480
498
  * @returns Normalized deterministic offer parameters.
481
499
  * @throws {InvalidOfferParameterError} when a deterministic offer parameter cannot satisfy protocol rules.
482
500
  * @example
@@ -484,26 +502,10 @@ var OfferUtils;
484
502
  * import { OfferUtils } from "@morpho-org/midnight-sdk";
485
503
  *
486
504
  * const params = OfferUtils.validateOfferParams({
487
- * market: {
488
- * loanToken: "0x0000000000000000000000000000000000006000",
489
- * collateralParams: [
490
- * {
491
- * token: "0x0000000000000000000000000000000000007000",
492
- * lltv: 770000000000000000n,
493
- * maxLif: 1061007957559681697n,
494
- * oracle: "0x0000000000000000000000000000000000008000",
495
- * },
496
- * ],
497
- * maturity: 54_000n,
498
- * rcfThreshold: 0n,
499
- * enterGate: "0x0000000000000000000000000000000000000000",
500
- * liquidatorGate: "0x0000000000000000000000000000000000000000",
501
- * },
502
505
  * buy: true,
503
506
  * maker: "0x0000000000000000000000000000000000009000",
504
507
  * tick: 5_000n,
505
508
  * expiry: 3_600n,
506
- * ratifier: "0x0000000000000000000000000000000000004000",
507
509
  * maxUnits: 100n,
508
510
  * });
509
511
  * console.log(params.maxAssets);
@@ -546,12 +548,14 @@ var OfferUtils;
546
548
  *
547
549
  * const offer = Offer.create({
548
550
  * market: {
551
+ * chainId: 8453,
552
+ * midnight: "0x0000000000000000000000000000000000001000",
549
553
  * loanToken: "0x0000000000000000000000000000000000006000",
550
554
  * collateralParams: [
551
555
  * {
552
556
  * token: "0x0000000000000000000000000000000000007000",
553
557
  * lltv: 770000000000000000n,
554
- * maxLif: 1061007957559681697n,
558
+ * liquidationCursor: 250000000000000000n,
555
559
  * oracle: "0x0000000000000000000000000000000000008000",
556
560
  * },
557
561
  * ],
@@ -580,7 +584,7 @@ var OfferUtils;
580
584
  const first = offers[0];
581
585
  const expectedMaker = comparableHex(first.maker);
582
586
  const expectedBuy = first.buy;
583
- const expectedLoanToken = comparableHex(first.market.loanToken);
587
+ const expectedLoanToken = comparableHex(index_js_1.MarketParams.from(first.market).loanToken);
584
588
  const expectedMaxUnits = first.maxUnits;
585
589
  const expectedMaxAssets = first.maxAssets;
586
590
  for (const offer of offers) {
@@ -591,11 +595,14 @@ var OfferUtils;
591
595
  throw new errors_js_1.InvalidOfferGroupError("All offers in a group must use the same maker side.");
592
596
  }
593
597
  if (offer.maxUnits < 0n ||
598
+ offer.maxUnits > constants_js_1.MAX_OFFER_CAP ||
594
599
  offer.maxAssets < 0n ||
600
+ offer.maxAssets > constants_js_1.MAX_OFFER_CAP ||
595
601
  (offer.maxAssets === 0n) === (offer.maxUnits === 0n)) {
596
- throw new errors_js_1.InvalidOfferGroupError("Every offer must set exactly one non-zero non-negative cap.");
602
+ throw new errors_js_1.InvalidOfferGroupError("Every offer must set exactly one non-zero uint128 cap.");
597
603
  }
598
- if (comparableHex(offer.market.loanToken) !== expectedLoanToken) {
604
+ if (comparableHex(index_js_1.MarketParams.from(offer.market).loanToken) !==
605
+ expectedLoanToken) {
599
606
  throw new errors_js_1.InvalidOfferGroupError("All offers in a group must use the same loan token.");
600
607
  }
601
608
  if (offer.maxUnits !== expectedMaxUnits ||
@@ -611,6 +618,265 @@ var OfferUtils;
611
618
  return [...offers];
612
619
  }
613
620
  OfferUtils.validateOfferGroup = validateOfferGroup;
621
+ /**
622
+ * Converts an offer tick into its WAD zero-coupon price.
623
+ *
624
+ * Use for display or local quote checks when accepting any plain object
625
+ * matching `IOffer` or an `Offer` instance.
626
+ *
627
+ * @param offer - Offer to inspect.
628
+ * @returns WAD price rounded to the protocol price quantum.
629
+ * @throws {NegativeValueError} when `offer.tick` is negative.
630
+ * @throws {TickOutOfRangeError} when `offer.tick` exceeds `MAX_TICK`.
631
+ * @example
632
+ * ```ts
633
+ * import { OfferUtils } from "@morpho-org/midnight-sdk";
634
+ *
635
+ * const price = OfferUtils.getPrice({ tick: 5_000n });
636
+ * console.log(price);
637
+ * ```
638
+ */
639
+ function getPrice(offer) {
640
+ return index_js_2.TickLib.tickToPrice(offer.tick);
641
+ }
642
+ OfferUtils.getPrice = getPrice;
643
+ /**
644
+ * Converts an offer tick into a WAD per-second simple rate at a timestamp.
645
+ *
646
+ * The rate is the offer's fixed period rate divided by the market's remaining
647
+ * time to maturity at `timestamp`, rounded up.
648
+ *
649
+ * @param params.offer - Offer to inspect.
650
+ * @param params.timestamp - Timestamp at which the rate is calculated.
651
+ * @returns WAD per-second simple rate rounded up.
652
+ * @throws {NegativeValueError} when `market.maturity`, `timestamp`, or `tick` is negative.
653
+ * @throws {TickOutOfRangeError} when `tick` exceeds `MAX_TICK`.
654
+ * @throws {DivisionByZeroError} when the tick price is zero or `timestamp` is at or after maturity.
655
+ * @example
656
+ * ```ts
657
+ * import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
658
+ *
659
+ * const offer = Offer.from({
660
+ * market: {
661
+ * loanToken: "0x0000000000000000000000000000000000006000",
662
+ * collateralParams: [
663
+ * {
664
+ * token: "0x0000000000000000000000000000000000007000",
665
+ * lltv: 770000000000000000n,
666
+ * liquidationCursor: 250000000000000000n,
667
+ * oracle: "0x0000000000000000000000000000000000008000",
668
+ * },
669
+ * ],
670
+ * maturity: 54_000n,
671
+ * rcfThreshold: 0n,
672
+ * enterGate: "0x0000000000000000000000000000000000000000",
673
+ * liquidatorGate: "0x0000000000000000000000000000000000000000",
674
+ * },
675
+ * buy: true,
676
+ * maker: "0x0000000000000000000000000000000000009000",
677
+ * start: 0n,
678
+ * expiry: 3_600n,
679
+ * tick: 5_000n,
680
+ * callback: "0x0000000000000000000000000000000000000000",
681
+ * callbackData: "0x",
682
+ * receiverIfMakerIsSeller: "0x0000000000000000000000000000000000000000",
683
+ * ratifier: "0x0000000000000000000000000000000000004000",
684
+ * reduceOnly: false,
685
+ * maxUnits: 100n,
686
+ * maxAssets: 0n,
687
+ * continuousFeeCap: 317097919n,
688
+ * });
689
+ * const rate = OfferUtils.getRate({ offer, timestamp: 1_000n });
690
+ * console.log(rate);
691
+ * ```
692
+ */
693
+ function getRate(params) {
694
+ const market = index_js_1.MarketParams.from(params.offer.market);
695
+ const timestamp = BigInt(params.timestamp);
696
+ (0, morpho_ts_1.assertNonNegative)("market.maturity", market.maturity);
697
+ (0, morpho_ts_1.assertNonNegative)("timestamp", timestamp);
698
+ const timeToMaturity = morpho_ts_1.MathLib.zeroFloorSub(market.maturity, timestamp);
699
+ if (timeToMaturity === 0n) {
700
+ throw new morpho_ts_1.DivisionByZeroError("timeToMaturity");
701
+ }
702
+ return morpho_ts_1.MathLib.mulDiv(index_js_2.TickLib.tickToRate(params.offer.tick), 1n, timeToMaturity, "Up");
703
+ }
704
+ OfferUtils.getRate = getRate;
705
+ /**
706
+ * Converts an offer tick into a WAD simple annual percentage rate at a timestamp.
707
+ *
708
+ * It computes time to maturity from the offer market and delegates the final
709
+ * tick annualization to `TickLib.tickToApr`.
710
+ *
711
+ * @param params.offer - Offer to inspect.
712
+ * @param params.timestamp - Timestamp at which the APR is calculated.
713
+ * @returns WAD simple APR rounded up.
714
+ * @throws {NegativeValueError} when `market.maturity`, `timestamp`, or `tick` is negative.
715
+ * @throws {TickOutOfRangeError} when `tick` exceeds `MAX_TICK`.
716
+ * @throws {DivisionByZeroError} when the tick price is zero or `timestamp` is at or after maturity.
717
+ * @example
718
+ * ```ts
719
+ * import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
720
+ *
721
+ * const offer = Offer.from({
722
+ * market: {
723
+ * loanToken: "0x0000000000000000000000000000000000006000",
724
+ * collateralParams: [
725
+ * {
726
+ * token: "0x0000000000000000000000000000000000007000",
727
+ * lltv: 770000000000000000n,
728
+ * liquidationCursor: 250000000000000000n,
729
+ * oracle: "0x0000000000000000000000000000000000008000",
730
+ * },
731
+ * ],
732
+ * maturity: 54_000n,
733
+ * rcfThreshold: 0n,
734
+ * enterGate: "0x0000000000000000000000000000000000000000",
735
+ * liquidatorGate: "0x0000000000000000000000000000000000000000",
736
+ * },
737
+ * buy: true,
738
+ * maker: "0x0000000000000000000000000000000000009000",
739
+ * start: 0n,
740
+ * expiry: 3_600n,
741
+ * tick: 5_000n,
742
+ * callback: "0x0000000000000000000000000000000000000000",
743
+ * callbackData: "0x",
744
+ * receiverIfMakerIsSeller: "0x0000000000000000000000000000000000000000",
745
+ * ratifier: "0x0000000000000000000000000000000000004000",
746
+ * reduceOnly: false,
747
+ * maxUnits: 100n,
748
+ * maxAssets: 0n,
749
+ * continuousFeeCap: 317097919n,
750
+ * });
751
+ * const apr = OfferUtils.getApr({ offer, timestamp: 1_000n });
752
+ * console.log(apr);
753
+ * ```
754
+ */
755
+ function getApr(params) {
756
+ const market = index_js_1.MarketParams.from(params.offer.market);
757
+ const timestamp = BigInt(params.timestamp);
758
+ (0, morpho_ts_1.assertNonNegative)("market.maturity", market.maturity);
759
+ (0, morpho_ts_1.assertNonNegative)("timestamp", timestamp);
760
+ return index_js_2.TickLib.tickToApr(params.offer.tick, morpho_ts_1.MathLib.zeroFloorSub(market.maturity, timestamp));
761
+ }
762
+ OfferUtils.getApr = getApr;
763
+ /**
764
+ * Returns remaining units accepted by an offer's cap at a timestamp.
765
+ *
766
+ * The offer must carry a hydrated {@link Market} so the current market
767
+ * continuous fee and settlement-fee buckets are available locally. Fetch the
768
+ * current `consumed(maker, group)` value separately and pass it as input.
769
+ *
770
+ * @param params.offer - Offer to inspect. Its market must be hydrated.
771
+ * @param params.consumed - Amount already consumed from the offer group.
772
+ * @param params.timestamp - Timestamp used to compute market time to maturity.
773
+ * @returns Remaining consumable units accepted by Midnight `take`.
774
+ * @throws {InvalidOfferParameterError} when the offer does not carry hydrated market state or has invalid caps.
775
+ * @throws {NegativeValueError} when `consumed`, `timestamp`, offer limits, or delegated math inputs are negative.
776
+ * @throws {TickOutOfRangeError} when `tick` exceeds `MAX_TICK`.
777
+ * @throws {SettlementFeeExceedsPriceError} when settlement fee exceeds a buy-offer price.
778
+ * @example
779
+ * ```ts
780
+ * import { OfferUtils, midnightAbi } from "@morpho-org/midnight-sdk";
781
+ * import { createPublicClient, http } from "viem";
782
+ * import { base } from "viem/chains";
783
+ * import { readContract } from "viem/actions";
784
+ *
785
+ * const client = createPublicClient({ chain: base, transport: http() });
786
+ * const offer = {
787
+ * market: {
788
+ * params: {
789
+ * chainId: 8453,
790
+ * midnight: "0x0000000000000000000000000000000000001000",
791
+ * loanToken: "0x0000000000000000000000000000000000006000",
792
+ * collateralParams: [
793
+ * {
794
+ * token: "0x0000000000000000000000000000000000007000",
795
+ * lltv: 770000000000000000n,
796
+ * liquidationCursor: 250000000000000000n,
797
+ * oracle: "0x0000000000000000000000000000000000008000",
798
+ * },
799
+ * ],
800
+ * maturity: 54_000n,
801
+ * rcfThreshold: 0n,
802
+ * enterGate: "0x0000000000000000000000000000000000000000",
803
+ * liquidatorGate: "0x0000000000000000000000000000000000000000",
804
+ * },
805
+ * totalUnits: 1_000n,
806
+ * lossFactor: 0n,
807
+ * withdrawable: 500n,
808
+ * continuousFeeCredit: 0n,
809
+ * settlementFeeCbps: [1, 2, 3, 4, 5, 6, 7],
810
+ * continuousFee: 10,
811
+ * tickSpacing: 4,
812
+ * },
813
+ * buy: true,
814
+ * maker: "0x0000000000000000000000000000000000009000",
815
+ * start: 0n,
816
+ * expiry: 3_600n,
817
+ * tick: 5_000n,
818
+ * callback: "0x0000000000000000000000000000000000000000",
819
+ * callbackData: "0x",
820
+ * receiverIfMakerIsSeller: "0x0000000000000000000000000000000000000000",
821
+ * ratifier: "0x0000000000000000000000000000000000004000",
822
+ * reduceOnly: false,
823
+ * maxUnits: 100n,
824
+ * maxAssets: 0n,
825
+ * continuousFeeCap: 317097919n,
826
+ * } as const;
827
+ * const consumed = await readContract(client, {
828
+ * address: "0x0000000000000000000000000000000000001000",
829
+ * abi: midnightAbi,
830
+ * functionName: "consumed",
831
+ * args: [offer.maker, "0x1111111111111111111111111111111111111111111111111111111111111111"],
832
+ * });
833
+ * const units = OfferUtils.getConsumableUnits({ offer, consumed, timestamp: 1_000n });
834
+ * console.log(units);
835
+ * ```
836
+ */
837
+ function getConsumableUnits(params) {
838
+ const offer = params.offer;
839
+ const consumed = BigInt(params.consumed);
840
+ const maxUnits = BigInt(offer.maxUnits);
841
+ const maxAssets = BigInt(offer.maxAssets);
842
+ const continuousFeeCap = BigInt(offer.continuousFeeCap);
843
+ (0, morpho_ts_1.assertNonNegative)("consumed", consumed);
844
+ (0, morpho_ts_1.assertNonNegative)("offer.maxUnits", maxUnits);
845
+ (0, morpho_ts_1.assertNonNegative)("offer.maxAssets", maxAssets);
846
+ (0, morpho_ts_1.assertNonNegative)("offer.continuousFeeCap", continuousFeeCap);
847
+ validateOfferCaps({ maxUnits, maxAssets });
848
+ if (!("params" in offer.market)) {
849
+ throw new errors_js_1.InvalidOfferParameterError({
850
+ parameter: "market",
851
+ value: offer.market,
852
+ instruction: "Provide a hydrated Market with continuous fee and settlement fee buckets.",
853
+ });
854
+ }
855
+ const market = index_js_1.Market.from(offer.market);
856
+ if (continuousFeeCap < BigInt(market.continuousFee))
857
+ return 0n;
858
+ if (maxUnits > 0n)
859
+ return morpho_ts_1.MathLib.zeroFloorSub(maxUnits, consumed);
860
+ const remainingAssets = morpho_ts_1.MathLib.zeroFloorSub(maxAssets, consumed);
861
+ const settlementFee = market.getSettlementFee(market.timeToMaturity(params.timestamp));
862
+ if (!offer.buy) {
863
+ const { sellerPrice } = index_js_2.TakeAmountsLib.prices({
864
+ offer,
865
+ settlementFee,
866
+ });
867
+ if (sellerPrice === 0n)
868
+ return morpho_ts_1.MathLib.MAX_UINT_256;
869
+ return morpho_ts_1.MathLib.mulDivDown(remainingAssets, morpho_ts_1.MathLib.WAD, sellerPrice);
870
+ }
871
+ const { buyerPrice } = index_js_2.TakeAmountsLib.prices({
872
+ offer,
873
+ settlementFee,
874
+ });
875
+ if (buyerPrice === 0n)
876
+ return morpho_ts_1.MathLib.MAX_UINT_256;
877
+ return ((remainingAssets + 1n) * morpho_ts_1.MathLib.WAD - 1n) / buyerPrice;
878
+ }
879
+ OfferUtils.getConsumableUnits = getConsumableUnits;
614
880
  /**
615
881
  * Returns an offer expiry timestamp.
616
882
  *
@@ -627,12 +893,14 @@ var OfferUtils;
627
893
  *
628
894
  * const offer = Offer.create({
629
895
  * market: {
896
+ * chainId: 8453,
897
+ * midnight: "0x0000000000000000000000000000000000001000",
630
898
  * loanToken: "0x0000000000000000000000000000000000006000",
631
899
  * collateralParams: [
632
900
  * {
633
901
  * token: "0x0000000000000000000000000000000000007000",
634
902
  * lltv: 770000000000000000n,
635
- * maxLif: 1061007957559681697n,
903
+ * liquidationCursor: 250000000000000000n,
636
904
  * oracle: "0x0000000000000000000000000000000000008000",
637
905
  * },
638
906
  * ],
@@ -52,4 +52,4 @@ export declare const abi: readonly [{
52
52
  readonly type: "function";
53
53
  }];
54
54
  /** @internal Deployless `GetPosition` query bytecode. */
55
- export declare const code = "0x60808060405234601557610362908161001a8239f35b5f80fdfe6080806040526004361015610012575f80fd5b5f3560e01c63d8f172c414610025575f80fd5b346101b85760603660031901126101b8576004356001600160a01b03811691908290036101b857602435906044356001600160a01b038116908190036101b85760e0820182811067ffffffffffffffff8211176102e2576040525f825260208201925f845260408301925f8452606081015f8152608082015f815260a08301915f835260c0840196611000604051906100be81836102f6565b36823788526040516349e2903160e11b8152600481018790526024810188905260c0816044818e5afa9081156101c4575f905f925f91885f925f925f91610243575b506001600160801b039081169091529081168852908116865290811684529182168b521685525f5b60808110156101cf5760405163ecdcc72d60e01b8152600481018890526024810189905260448101829052906020826064818f5afa80156101c4575f90610187575b600192506001600160801b038b519116908260051b015201610128565b506020823d82116101bc575b816101a0602093836102f6565b810103126101b8576101b3600192610318565b61016a565b5f80fd5b3d9150610193565b6040513d5f823e3d90fd5b506001600160801b039283899593818094818e816040519c51168c52511660208b0152511660408901525116606087015251166080850152511660a08301525160c082015f905b60808210610224576110c084f35b6020806001926001600160801b03865116815201930191019091610216565b965050505050505060c0813d60c0116102da575b8161026460c093836102f6565b810103126101b857806001600160801b0361027f8193610318565b918161028d60208301610318565b938161029b60408501610318565b93816102a960608301610318565b938d826102c460a06102bd60808801610318565b9601610318565b929a989694929550509497509450509396610100565b3d9150610257565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff8211176102e257604052565b51906001600160801b03821682036101b85756fea264697066735822122047b31034ba6d0d5a88fb953996f2d97fa501664a716d124ff2e42e0782119d9164736f6c63430008230033";
55
+ export declare const code = "0x60808060405234601557610362908161001a8239f35b5f80fdfe6080806040526004361015610012575f80fd5b5f3560e01c63d8f172c414610025575f80fd5b346101b85760603660031901126101b8576004356001600160a01b03811691908290036101b857602435906044356001600160a01b038116908190036101b85760e0820182811067ffffffffffffffff8211176102e2576040525f825260208201925f845260408301925f8452606081015f8152608082015f815260a08301915f835260c0840196611000604051906100be81836102f6565b36823788526040516349e2903160e11b8152600481018790526024810188905260c0816044818e5afa9081156101c4575f905f925f91885f925f925f91610243575b506001600160801b039081169091529081168852908116865290811684529182168b521685525f5b60808110156101cf5760405163ecdcc72d60e01b8152600481018890526024810189905260448101829052906020826064818f5afa80156101c4575f90610187575b600192506001600160801b038b519116908260051b015201610128565b506020823d82116101bc575b816101a0602093836102f6565b810103126101b8576101b3600192610318565b61016a565b5f80fd5b3d9150610193565b6040513d5f823e3d90fd5b506001600160801b039283899593818094818e816040519c51168c52511660208b0152511660408901525116606087015251166080850152511660a08301525160c082015f905b60808210610224576110c084f35b6020806001926001600160801b03865116815201930191019091610216565b965050505050505060c0813d60c0116102da575b8161026460c093836102f6565b810103126101b857806001600160801b0361027f8193610318565b918161028d60208301610318565b938161029b60408501610318565b93816102a960608301610318565b938d826102c460a06102bd60808801610318565b9601610318565b929a989694929550509497509450509396610100565b3d9150610257565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff8211176102e257604052565b51906001600160801b03821682036101b85756fea264697066735822122048ab3e1a986178f7e3c65d73416611318a31ef34d18800cb6a1f1ba4dad746b364736f6c63430008230033";
@@ -71,4 +71,4 @@ exports.abi = [
71
71
  },
72
72
  ];
73
73
  /** @internal Deployless `GetPosition` query bytecode. */
74
- exports.code = "0x60808060405234601557610362908161001a8239f35b5f80fdfe6080806040526004361015610012575f80fd5b5f3560e01c63d8f172c414610025575f80fd5b346101b85760603660031901126101b8576004356001600160a01b03811691908290036101b857602435906044356001600160a01b038116908190036101b85760e0820182811067ffffffffffffffff8211176102e2576040525f825260208201925f845260408301925f8452606081015f8152608082015f815260a08301915f835260c0840196611000604051906100be81836102f6565b36823788526040516349e2903160e11b8152600481018790526024810188905260c0816044818e5afa9081156101c4575f905f925f91885f925f925f91610243575b506001600160801b039081169091529081168852908116865290811684529182168b521685525f5b60808110156101cf5760405163ecdcc72d60e01b8152600481018890526024810189905260448101829052906020826064818f5afa80156101c4575f90610187575b600192506001600160801b038b519116908260051b015201610128565b506020823d82116101bc575b816101a0602093836102f6565b810103126101b8576101b3600192610318565b61016a565b5f80fd5b3d9150610193565b6040513d5f823e3d90fd5b506001600160801b039283899593818094818e816040519c51168c52511660208b0152511660408901525116606087015251166080850152511660a08301525160c082015f905b60808210610224576110c084f35b6020806001926001600160801b03865116815201930191019091610216565b965050505050505060c0813d60c0116102da575b8161026460c093836102f6565b810103126101b857806001600160801b0361027f8193610318565b918161028d60208301610318565b938161029b60408501610318565b93816102a960608301610318565b938d826102c460a06102bd60808801610318565b9601610318565b929a989694929550509497509450509396610100565b3d9150610257565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff8211176102e257604052565b51906001600160801b03821682036101b85756fea264697066735822122047b31034ba6d0d5a88fb953996f2d97fa501664a716d124ff2e42e0782119d9164736f6c63430008230033";
74
+ exports.code = "0x60808060405234601557610362908161001a8239f35b5f80fdfe6080806040526004361015610012575f80fd5b5f3560e01c63d8f172c414610025575f80fd5b346101b85760603660031901126101b8576004356001600160a01b03811691908290036101b857602435906044356001600160a01b038116908190036101b85760e0820182811067ffffffffffffffff8211176102e2576040525f825260208201925f845260408301925f8452606081015f8152608082015f815260a08301915f835260c0840196611000604051906100be81836102f6565b36823788526040516349e2903160e11b8152600481018790526024810188905260c0816044818e5afa9081156101c4575f905f925f91885f925f925f91610243575b506001600160801b039081169091529081168852908116865290811684529182168b521685525f5b60808110156101cf5760405163ecdcc72d60e01b8152600481018890526024810189905260448101829052906020826064818f5afa80156101c4575f90610187575b600192506001600160801b038b519116908260051b015201610128565b506020823d82116101bc575b816101a0602093836102f6565b810103126101b8576101b3600192610318565b61016a565b5f80fd5b3d9150610193565b6040513d5f823e3d90fd5b506001600160801b039283899593818094818e816040519c51168c52511660208b0152511660408901525116606087015251166080850152511660a08301525160c082015f905b60808210610224576110c084f35b6020806001926001600160801b03865116815201930191019091610216565b965050505050505060c0813d60c0116102da575b8161026460c093836102f6565b810103126101b857806001600160801b0361027f8193610318565b918161028d60208301610318565b938161029b60408501610318565b93816102a960608301610318565b938d826102c460a06102bd60808801610318565b9601610318565b929a989694929550509497509450509396610100565b3d9150610257565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff8211176102e257604052565b51906001600160801b03821682036101b85756fea264697066735822122048ab3e1a986178f7e3c65d73416611318a31ef34d18800cb6a1f1ba4dad746b364736f6c63430008230033";