@morpho-org/midnight-sdk 1.7.0 → 2.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 (103) hide show
  1. package/MIGRATION-v1-to-v2.md +6 -0
  2. package/README.md +63 -61
  3. package/lib/cjs/abis.d.ts +1962 -759
  4. package/lib/cjs/abis.js +2021 -995
  5. package/lib/cjs/api/helpers.d.ts +1 -17
  6. package/lib/cjs/api/helpers.js +0 -4
  7. package/lib/cjs/api/types.d.ts +5 -4
  8. package/lib/cjs/api/version.generated.d.ts +1 -1
  9. package/lib/cjs/api/version.generated.js +2 -2
  10. package/lib/cjs/bundlesV2.d.ts +15 -0
  11. package/lib/cjs/bundlesV2.js +2 -0
  12. package/lib/cjs/constants.d.ts +34 -0
  13. package/lib/cjs/constants.js +35 -1
  14. package/lib/cjs/errors.d.ts +107 -0
  15. package/lib/cjs/errors.js +139 -1
  16. package/lib/cjs/fetch/Ratifier.d.ts +4 -3
  17. package/lib/cjs/fetch/Ratifier.js +6 -4
  18. package/lib/cjs/index.d.ts +8 -0
  19. package/lib/cjs/index.js +16 -1
  20. package/lib/cjs/offers/Offer.d.ts +10 -0
  21. package/lib/cjs/offers/Offer.js +15 -1
  22. package/lib/cjs/offers/OfferUtils.d.ts +3 -0
  23. package/lib/cjs/offers/OfferUtils.js +3 -0
  24. package/lib/cjs/signatures/{EcrecoverRatifierUtils.d.ts → EcrecoverRatifier.d.ts} +118 -2
  25. package/lib/cjs/signatures/{EcrecoverRatifierUtils.js → EcrecoverRatifier.js} +146 -9
  26. package/lib/cjs/signatures/GroupUtils.d.ts +55 -2
  27. package/lib/cjs/signatures/GroupUtils.js +64 -5
  28. package/lib/cjs/signatures/Payload.d.ts +3 -3
  29. package/lib/cjs/signatures/PriceRatifierV1.d.ts +472 -0
  30. package/lib/cjs/signatures/PriceRatifierV1.js +521 -0
  31. package/lib/cjs/signatures/RateRatifierV1.d.ts +581 -0
  32. package/lib/cjs/signatures/RateRatifierV1.js +696 -0
  33. package/lib/{esm/signatures/RatifierUtils.d.ts → cjs/signatures/Ratifier.d.ts} +14 -12
  34. package/lib/cjs/signatures/{RatifierUtils.js → Ratifier.js} +29 -29
  35. package/lib/cjs/signatures/{SetterRatifierUtils.d.ts → SetterRatifier.d.ts} +50 -3
  36. package/lib/cjs/signatures/{SetterRatifierUtils.js → SetterRatifier.js} +65 -7
  37. package/lib/cjs/signatures/Tree.d.ts +94 -17
  38. package/lib/cjs/signatures/Tree.js +146 -111
  39. package/lib/cjs/signatures/TreeUtils.d.ts +191 -21
  40. package/lib/cjs/signatures/TreeUtils.js +320 -134
  41. package/lib/cjs/signatures/index.d.ts +7 -3
  42. package/lib/cjs/signatures/index.js +5 -3
  43. package/lib/cjs/signatures/ratifierRequests.d.ts +55 -0
  44. package/lib/cjs/signatures/ratifierRequests.js +2 -0
  45. package/lib/cjs/signatures/ratifierV1Internal.d.ts +57 -0
  46. package/lib/cjs/signatures/ratifierV1Internal.js +183 -0
  47. package/lib/cjs/signatures/standardRatifierInternal.d.ts +4 -0
  48. package/lib/cjs/signatures/standardRatifierInternal.js +12 -0
  49. package/lib/cjs/signatures/treeMathInternal.d.ts +4 -0
  50. package/lib/cjs/signatures/treeMathInternal.js +12 -0
  51. package/lib/cjs/signatures/treeTypes.d.ts +109 -0
  52. package/lib/cjs/signatures/treeTypes.js +2 -0
  53. package/lib/esm/abis.d.ts +1962 -759
  54. package/lib/esm/abis.js +2020 -994
  55. package/lib/esm/api/helpers.d.ts +1 -17
  56. package/lib/esm/api/helpers.js +4 -4
  57. package/lib/esm/api/types.d.ts +5 -4
  58. package/lib/esm/api/version.generated.d.ts +1 -1
  59. package/lib/esm/api/version.generated.js +2 -2
  60. package/lib/esm/bundlesV2.d.ts +15 -0
  61. package/lib/esm/bundlesV2.js +1 -0
  62. package/lib/esm/constants.d.ts +34 -0
  63. package/lib/esm/constants.js +34 -0
  64. package/lib/esm/errors.d.ts +107 -0
  65. package/lib/esm/errors.js +132 -0
  66. package/lib/esm/fetch/Ratifier.d.ts +4 -3
  67. package/lib/esm/fetch/Ratifier.js +6 -4
  68. package/lib/esm/index.d.ts +8 -0
  69. package/lib/esm/index.js +5 -0
  70. package/lib/esm/offers/Offer.d.ts +10 -0
  71. package/lib/esm/offers/Offer.js +15 -1
  72. package/lib/esm/offers/OfferUtils.d.ts +3 -0
  73. package/lib/esm/offers/OfferUtils.js +3 -0
  74. package/lib/esm/signatures/{EcrecoverRatifierUtils.d.ts → EcrecoverRatifier.d.ts} +118 -2
  75. package/lib/esm/signatures/{EcrecoverRatifierUtils.js → EcrecoverRatifier.js} +146 -9
  76. package/lib/esm/signatures/GroupUtils.d.ts +55 -2
  77. package/lib/esm/signatures/GroupUtils.js +64 -5
  78. package/lib/esm/signatures/Payload.d.ts +3 -3
  79. package/lib/esm/signatures/PriceRatifierV1.d.ts +472 -0
  80. package/lib/esm/signatures/PriceRatifierV1.js +520 -0
  81. package/lib/esm/signatures/RateRatifierV1.d.ts +581 -0
  82. package/lib/esm/signatures/RateRatifierV1.js +695 -0
  83. package/lib/{cjs/signatures/RatifierUtils.d.ts → esm/signatures/Ratifier.d.ts} +14 -12
  84. package/lib/esm/signatures/{RatifierUtils.js → Ratifier.js} +31 -29
  85. package/lib/esm/signatures/{SetterRatifierUtils.d.ts → SetterRatifier.d.ts} +50 -3
  86. package/lib/esm/signatures/{SetterRatifierUtils.js → SetterRatifier.js} +65 -7
  87. package/lib/esm/signatures/Tree.d.ts +94 -17
  88. package/lib/esm/signatures/Tree.js +147 -112
  89. package/lib/esm/signatures/TreeUtils.d.ts +191 -21
  90. package/lib/esm/signatures/TreeUtils.js +318 -132
  91. package/lib/esm/signatures/index.d.ts +7 -3
  92. package/lib/esm/signatures/index.js +5 -3
  93. package/lib/esm/signatures/ratifierRequests.d.ts +55 -0
  94. package/lib/esm/signatures/ratifierRequests.js +1 -0
  95. package/lib/esm/signatures/ratifierV1Internal.d.ts +57 -0
  96. package/lib/esm/signatures/ratifierV1Internal.js +176 -0
  97. package/lib/esm/signatures/standardRatifierInternal.d.ts +4 -0
  98. package/lib/esm/signatures/standardRatifierInternal.js +9 -0
  99. package/lib/esm/signatures/treeMathInternal.d.ts +4 -0
  100. package/lib/esm/signatures/treeMathInternal.js +8 -0
  101. package/lib/esm/signatures/treeTypes.d.ts +109 -0
  102. package/lib/esm/signatures/treeTypes.js +1 -0
  103. package/package.json +9 -8
@@ -0,0 +1,6 @@
1
+ # Migrating from midnight-sdk v1 to v2
2
+
3
+ midnight-sdk v2 removes `midnightBundlesAbi` (MidnightBundles V1). Use `midnightBundlesV2Abi`
4
+ against the `midnightBundlesV2` address. V2 acts for `msg.sender` (no `taker` argument), takes no
5
+ inline token permits, and takes the `Market` struct as its first argument; the README's atomic-take
6
+ recipe shows the V2 call. Integrations that still call V1 must pin midnight-sdk v1.
package/README.md CHANGED
@@ -150,93 +150,95 @@ 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
+ `MidnightBundlesV2` 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 { midnightBundlesV2Abi, type MarketParams } 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
+ // Throws `UnknownAddressError` until the chain's `midnightBundlesV2` is pinned in morpho-ts or
180
+ // registered with `registerCustomAddresses`.
181
+ const midnightBundlesV2 = getChainAddress(chainId, "midnightBundlesV2");
173
182
 
174
- async function buildAskQuoteTakes(marketId: Hash, targetUnits: bigint) {
183
+ export async function takeAskQuoteAtomically(params: {
184
+ readonly walletClient: WalletClient;
185
+ readonly taker: Address;
186
+ readonly market: MarketParams;
187
+ readonly marketId: Hash;
188
+ readonly deadline: bigint;
189
+ }) {
190
+ const targetUnits = parseUnits("50", 18);
175
191
  const quote = await MidnightApi.fetchBookQuote({
176
- marketId,
192
+ marketId: params.marketId,
177
193
  side: "asks",
178
194
  units: targetUnits,
179
195
  slippage: "0.5",
180
196
  });
181
197
 
182
- return quote.data;
183
- }
198
+ // Keep the caller's target and the quote's aggregate guard as two independent inputs.
199
+ // Do not substitute `quote.data.availableUnits` for the target: it is fallback capacity,
200
+ // not what the caller asked for.
201
+ const maxBuyerAssets = MathLib.wMulUp(targetUnits, quote.data.averageWorstPrice);
184
202
 
185
- export async function takeOneOffer(params: {
186
- readonly walletClient: WalletClient;
187
- readonly taker: Address;
188
- readonly receiverIfTakerIsSeller: Address;
189
- readonly take: MidnightApiTake;
190
- }) {
203
+ // Two confirmed prerequisites before this call: the taker has approved `midnightBundlesV2`
204
+ // to spend `maxBuyerAssets` of the loan token, and has authorized the bundle on Midnight via
205
+ // `Midnight.setIsAuthorized(midnightBundlesV2, true, taker)`. V2 acts for `msg.sender`, so the
206
+ // taker sends the transaction (`@morpho-org/morpho-sdk`'s entity `getRequirements()` resolves both).
191
207
  return params.walletClient.writeContract({
192
208
  account: params.taker,
193
- address: midnight,
194
- abi: midnightAbi,
195
- functionName: "take",
209
+ chain: base,
210
+ address: midnightBundlesV2,
211
+ abi: midnightBundlesV2Abi,
212
+ functionName: "midnightBundlesV2BuyWithUnitsTargetAndWithdrawCollateral",
196
213
  args: [
197
- params.take.offer,
198
- params.take.ratifierData,
199
- params.take.units,
200
- params.taker,
201
- params.receiverIfTakerIsSeller,
202
- zeroAddress,
203
- "0x",
214
+ params.market,
215
+ targetUnits,
216
+ maxBuyerAssets,
217
+ false, // reduceOnly
218
+ false, // repayEnabled
219
+ quote.data.takeableOffers, // { offer, units, ratifierData }[] straight from the quote
220
+ [], // collateralWithdrawals
221
+ zeroAddress, // collateralReceiver
222
+ 0n, // referralFeePct
223
+ zeroAddress, // referralFeeRecipient
224
+ maxUint256, // maxContinuousFee: bound this to the fee the caller accepts
225
+ params.deadline,
226
+ zeroAddress, // wrappedNative
204
227
  ],
205
228
  });
206
229
  }
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
230
  ```
239
231
 
232
+ Bids mirror this with `midnightBundlesV2SupplyCollateralAndSellWithUnitsTarget` and a
233
+ `minSellerAssets` floor derived from the same `averageWorstPrice`. Prefer the `*WithAssetsTarget*`
234
+ variants when the caller fixes the asset amount instead of the unit amount.
235
+
236
+ If you must submit `Midnight.take` directly (for example from a contract that performs its own
237
+ atomic price check), treat each transaction as an independent fill: await and validate its receipt
238
+ before reducing the remaining target, stop on any revert, refresh offer consumption, and re-quote
239
+ the remaining target so a fresh aggregate guard covers what is left. An aggregate guard for the
240
+ full quote does not apply to any subset of it.
241
+
240
242
  ## Midnight API
241
243
 
242
244
  Instantiate `MidnightApi` when an integration makes more than one Midnight API call or needs shared