@morpho-org/midnight-sdk 0.1.0 → 1.1.1

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