@morpho-org/midnight-sdk 1.7.0-next.0 → 1.8.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 (92) hide show
  1. package/README.md +61 -61
  2. package/lib/cjs/abis.d.ts +794 -0
  3. package/lib/cjs/abis.js +502 -1
  4. package/lib/cjs/api/version.generated.d.ts +1 -1
  5. package/lib/cjs/api/version.generated.js +2 -2
  6. package/lib/cjs/constants.d.ts +34 -0
  7. package/lib/cjs/constants.js +35 -1
  8. package/lib/cjs/errors.d.ts +107 -0
  9. package/lib/cjs/errors.js +139 -1
  10. package/lib/cjs/fetch/Ratifier.d.ts +4 -3
  11. package/lib/cjs/fetch/Ratifier.js +5 -4
  12. package/lib/cjs/index.d.ts +7 -0
  13. package/lib/cjs/index.js +16 -1
  14. package/lib/cjs/offers/Offer.d.ts +10 -0
  15. package/lib/cjs/offers/Offer.js +15 -1
  16. package/lib/cjs/offers/OfferUtils.d.ts +3 -0
  17. package/lib/cjs/offers/OfferUtils.js +3 -0
  18. package/lib/cjs/signatures/{EcrecoverRatifierUtils.d.ts → EcrecoverRatifier.d.ts} +118 -2
  19. package/lib/cjs/signatures/{EcrecoverRatifierUtils.js → EcrecoverRatifier.js} +146 -9
  20. package/lib/cjs/signatures/GroupUtils.d.ts +55 -2
  21. package/lib/cjs/signatures/GroupUtils.js +64 -5
  22. package/lib/cjs/signatures/Payload.d.ts +3 -3
  23. package/lib/cjs/signatures/PriceRatifierV1.d.ts +472 -0
  24. package/lib/cjs/signatures/PriceRatifierV1.js +521 -0
  25. package/lib/cjs/signatures/RateRatifierV1.d.ts +581 -0
  26. package/lib/cjs/signatures/RateRatifierV1.js +696 -0
  27. package/lib/{esm/signatures/RatifierUtils.d.ts → cjs/signatures/Ratifier.d.ts} +14 -12
  28. package/lib/cjs/signatures/{RatifierUtils.js → Ratifier.js} +29 -29
  29. package/lib/cjs/signatures/{SetterRatifierUtils.d.ts → SetterRatifier.d.ts} +50 -3
  30. package/lib/cjs/signatures/{SetterRatifierUtils.js → SetterRatifier.js} +65 -7
  31. package/lib/cjs/signatures/Tree.d.ts +94 -17
  32. package/lib/cjs/signatures/Tree.js +146 -111
  33. package/lib/cjs/signatures/TreeUtils.d.ts +191 -21
  34. package/lib/cjs/signatures/TreeUtils.js +320 -134
  35. package/lib/cjs/signatures/index.d.ts +7 -3
  36. package/lib/cjs/signatures/index.js +5 -3
  37. package/lib/cjs/signatures/ratifierRequests.d.ts +55 -0
  38. package/lib/cjs/signatures/ratifierRequests.js +2 -0
  39. package/lib/cjs/signatures/ratifierV1Internal.d.ts +57 -0
  40. package/lib/cjs/signatures/ratifierV1Internal.js +183 -0
  41. package/lib/cjs/signatures/standardRatifierInternal.d.ts +4 -0
  42. package/lib/cjs/signatures/standardRatifierInternal.js +12 -0
  43. package/lib/cjs/signatures/treeMathInternal.d.ts +4 -0
  44. package/lib/cjs/signatures/treeMathInternal.js +12 -0
  45. package/lib/cjs/signatures/treeTypes.d.ts +109 -0
  46. package/lib/cjs/signatures/treeTypes.js +2 -0
  47. package/lib/esm/abis.d.ts +794 -0
  48. package/lib/esm/abis.js +501 -0
  49. package/lib/esm/api/version.generated.d.ts +1 -1
  50. package/lib/esm/api/version.generated.js +2 -2
  51. package/lib/esm/constants.d.ts +34 -0
  52. package/lib/esm/constants.js +34 -0
  53. package/lib/esm/errors.d.ts +107 -0
  54. package/lib/esm/errors.js +132 -0
  55. package/lib/esm/fetch/Ratifier.d.ts +4 -3
  56. package/lib/esm/fetch/Ratifier.js +5 -4
  57. package/lib/esm/index.d.ts +7 -0
  58. package/lib/esm/index.js +5 -0
  59. package/lib/esm/offers/Offer.d.ts +10 -0
  60. package/lib/esm/offers/Offer.js +15 -1
  61. package/lib/esm/offers/OfferUtils.d.ts +3 -0
  62. package/lib/esm/offers/OfferUtils.js +3 -0
  63. package/lib/esm/signatures/{EcrecoverRatifierUtils.d.ts → EcrecoverRatifier.d.ts} +118 -2
  64. package/lib/esm/signatures/{EcrecoverRatifierUtils.js → EcrecoverRatifier.js} +146 -9
  65. package/lib/esm/signatures/GroupUtils.d.ts +55 -2
  66. package/lib/esm/signatures/GroupUtils.js +64 -5
  67. package/lib/esm/signatures/Payload.d.ts +3 -3
  68. package/lib/esm/signatures/PriceRatifierV1.d.ts +472 -0
  69. package/lib/esm/signatures/PriceRatifierV1.js +520 -0
  70. package/lib/esm/signatures/RateRatifierV1.d.ts +581 -0
  71. package/lib/esm/signatures/RateRatifierV1.js +695 -0
  72. package/lib/{cjs/signatures/RatifierUtils.d.ts → esm/signatures/Ratifier.d.ts} +14 -12
  73. package/lib/esm/signatures/{RatifierUtils.js → Ratifier.js} +31 -29
  74. package/lib/esm/signatures/{SetterRatifierUtils.d.ts → SetterRatifier.d.ts} +50 -3
  75. package/lib/esm/signatures/{SetterRatifierUtils.js → SetterRatifier.js} +65 -7
  76. package/lib/esm/signatures/Tree.d.ts +94 -17
  77. package/lib/esm/signatures/Tree.js +147 -112
  78. package/lib/esm/signatures/TreeUtils.d.ts +191 -21
  79. package/lib/esm/signatures/TreeUtils.js +318 -132
  80. package/lib/esm/signatures/index.d.ts +7 -3
  81. package/lib/esm/signatures/index.js +5 -3
  82. package/lib/esm/signatures/ratifierRequests.d.ts +55 -0
  83. package/lib/esm/signatures/ratifierRequests.js +1 -0
  84. package/lib/esm/signatures/ratifierV1Internal.d.ts +57 -0
  85. package/lib/esm/signatures/ratifierV1Internal.js +176 -0
  86. package/lib/esm/signatures/standardRatifierInternal.d.ts +4 -0
  87. package/lib/esm/signatures/standardRatifierInternal.js +9 -0
  88. package/lib/esm/signatures/treeMathInternal.d.ts +4 -0
  89. package/lib/esm/signatures/treeMathInternal.js +8 -0
  90. package/lib/esm/signatures/treeTypes.d.ts +109 -0
  91. package/lib/esm/signatures/treeTypes.js +1 -0
  92. package/package.json +4 -4
package/README.md CHANGED
@@ -150,93 +150,93 @@ The take-side starts from API book, quote, or maker takeable-offer responses. `M
150
150
  router response into ABI-ready take objects: each item has `offer`, `ratifierData`, and `units` for
151
151
  `IMidnight.take`, plus `marketId` metadata from the API. Book `asks` are maker sell offers, while
152
152
  book `bids` are maker buy offers.
153
- For a quote that spans several offers, execute the returned takes in order with `Midnight.take` and
154
- clamp each take to the remaining target instead of submitting every returned cap blindly.
153
+ The quote's `averageWorstPrice` is an **aggregate** guard over the requested target: a favorable
154
+ offer can compensate for a worse one, and the worse offer does not satisfy the guard on its own.
155
+ That guard only holds if every returned offer settles together, so execute a quote through
156
+ `MidnightBundlesV1` in a single transaction. The bundle skips offers that became stale since the
157
+ quote, reverts unless the exact target is reached, and enforces one aggregate consideration bound
158
+ (`maxBuyerAssets` for asks, `minSellerAssets` for bids). Never split a quote into independent
159
+ `Midnight.take` transactions: a stale first leg reverts but still consumes its nonce, so the
160
+ remaining legs settle at a price the quote never authorized. The high-level
161
+ `@morpho-org/morpho-sdk` `client.morpho.midnight(chainId)` flows already route through the bundle
162
+ and resolve approvals for you; the recipe below shows the same route with this package's raw ABI.
155
163
 
156
164
  ```ts
157
- import { addresses } from "@morpho-org/morpho-ts";
158
- import {
159
- MidnightApi,
160
- type MidnightApiTake,
161
- } from "@morpho-org/midnight-sdk/api";
162
- import { midnightAbi } from "@morpho-org/midnight-sdk";
165
+ import { getChainAddress, MathLib } from "@morpho-org/morpho-ts";
166
+ import { MidnightApi } from "@morpho-org/midnight-sdk/api";
167
+ import { midnightBundlesAbi } from "@morpho-org/midnight-sdk";
163
168
  import {
169
+ maxUint256,
164
170
  parseUnits,
165
171
  zeroAddress,
166
172
  type Address,
167
173
  type Hash,
168
174
  type WalletClient,
169
175
  } from "viem";
176
+ import { base } from "viem/chains";
170
177
 
171
- const chainId = 8453;
172
- const midnight = addresses[chainId].midnight!;
178
+ const chainId = base.id;
179
+ const midnightBundles = getChainAddress(chainId, "midnightBundles");
173
180
 
174
- async function buildAskQuoteTakes(marketId: Hash, targetUnits: bigint) {
181
+ export async function takeAskQuoteAtomically(params: {
182
+ readonly walletClient: WalletClient;
183
+ readonly taker: Address;
184
+ readonly marketId: Hash;
185
+ readonly deadline: bigint;
186
+ }) {
187
+ const targetUnits = parseUnits("50", 18);
175
188
  const quote = await MidnightApi.fetchBookQuote({
176
- marketId,
189
+ marketId: params.marketId,
177
190
  side: "asks",
178
191
  units: targetUnits,
179
192
  slippage: "0.5",
180
193
  });
181
194
 
182
- return quote.data;
183
- }
184
-
185
- export async function takeOneOffer(params: {
186
- readonly walletClient: WalletClient;
187
- readonly taker: Address;
188
- readonly receiverIfTakerIsSeller: Address;
189
- readonly take: MidnightApiTake;
190
- }) {
195
+ // Keep the caller's target and the quote's aggregate guard as two independent inputs.
196
+ // Do not substitute `quote.data.availableUnits` for the target: it is fallback capacity,
197
+ // not what the caller asked for.
198
+ const maxBuyerAssets = MathLib.wMulUp(targetUnits, quote.data.averageWorstPrice);
199
+
200
+ // Two confirmed prerequisites before this call: the taker has approved `midnightBundles`
201
+ // to spend `maxBuyerAssets` of the loan token (or passes an ERC-2612/Permit2 payload as
202
+ // `loanTokenPermit`), and has authorized the bundle on Midnight via
203
+ // `Midnight.setIsAuthorized(midnightBundles, true, taker)` so it can act on the taker's
204
+ // behalf (`@morpho-org/morpho-sdk`'s `getMidnightAuthorizationRequirement` resolves this
205
+ // for you).
191
206
  return params.walletClient.writeContract({
192
207
  account: params.taker,
193
- address: midnight,
194
- abi: midnightAbi,
195
- functionName: "take",
208
+ chain: base,
209
+ address: midnightBundles,
210
+ abi: midnightBundlesAbi,
211
+ functionName: "midnightBundlesV1BuyWithUnitsTargetAndWithdrawCollateral",
196
212
  args: [
197
- params.take.offer,
198
- params.take.ratifierData,
199
- params.take.units,
213
+ targetUnits,
214
+ maxBuyerAssets,
200
215
  params.taker,
201
- params.receiverIfTakerIsSeller,
202
- zeroAddress,
203
- "0x",
216
+ false, // reduceOnly
217
+ { kind: 0, data: "0x" }, // loanTokenPermit: none
218
+ quote.data.takeableOffers, // { offer, units, ratifierData }[] straight from the quote
219
+ [], // collateralWithdrawals
220
+ zeroAddress, // collateralReceiver
221
+ 0n, // referralFeePct
222
+ zeroAddress, // referralFeeRecipient
223
+ maxUint256, // maxContinuousFee: bound this to the fee the caller accepts
224
+ params.deadline,
204
225
  ],
205
226
  });
206
227
  }
207
-
208
- export async function takeAskQuoteSequentially(params: {
209
- readonly walletClient: WalletClient;
210
- readonly taker: Address;
211
- readonly receiverIfTakerIsSeller: Address;
212
- readonly marketId: Hash;
213
- }) {
214
- const targetUnits = parseUnits("50", 18);
215
- const quote = await buildAskQuoteTakes(params.marketId, targetUnits);
216
- const transactionHashes: Hash[] = [];
217
- let remainingUnits = targetUnits;
218
-
219
- for (const take of quote.takeableOffers) {
220
- if (remainingUnits === 0n) break;
221
-
222
- const units = take.units < remainingUnits ? take.units : remainingUnits;
223
- if (units === 0n) continue;
224
-
225
- transactionHashes.push(
226
- await takeOneOffer({
227
- walletClient: params.walletClient,
228
- taker: params.taker,
229
- receiverIfTakerIsSeller: params.receiverIfTakerIsSeller,
230
- take: { ...take, units },
231
- }),
232
- );
233
- remainingUnits -= units;
234
- }
235
-
236
- return { remainingUnits, transactionHashes };
237
- }
238
228
  ```
239
229
 
230
+ Bids mirror this with `midnightBundlesV1SupplyCollateralAndSellWithUnitsTarget` and a
231
+ `minSellerAssets` floor derived from the same `averageWorstPrice`. Prefer the `*WithAssetsTarget*`
232
+ variants when the caller fixes the asset amount instead of the unit amount.
233
+
234
+ If you must submit `Midnight.take` directly (for example from a contract that performs its own
235
+ atomic price check), treat each transaction as an independent fill: await and validate its receipt
236
+ before reducing the remaining target, stop on any revert, refresh offer consumption, and re-quote
237
+ the remaining target so a fresh aggregate guard covers what is left. An aggregate guard for the
238
+ full quote does not apply to any subset of it.
239
+
240
240
  ## Midnight API
241
241
 
242
242
  Instantiate `MidnightApi` when an integration makes more than one Midnight API call or needs shared