@morpho-org/midnight-sdk 2.0.0 → 2.1.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.
- package/lib/cjs/api/MidnightApi.d.ts +10 -8
- package/lib/cjs/api/MidnightApi.js +13 -11
- package/lib/cjs/api/helpers.d.ts +1 -1
- package/lib/cjs/api/helpers.js +4 -1
- package/lib/cjs/api/types.d.ts +1 -1
- package/lib/cjs/api/version.generated.d.ts +1 -1
- package/lib/cjs/api/version.generated.js +1 -1
- package/lib/cjs/offers/Offer.d.ts +50 -0
- package/lib/cjs/offers/Offer.js +53 -0
- package/lib/cjs/offers/OfferUtils.d.ts +108 -0
- package/lib/cjs/offers/OfferUtils.js +116 -0
- package/lib/esm/api/MidnightApi.d.ts +10 -8
- package/lib/esm/api/MidnightApi.js +13 -11
- package/lib/esm/api/helpers.d.ts +1 -1
- package/lib/esm/api/helpers.js +4 -1
- package/lib/esm/api/types.d.ts +1 -1
- package/lib/esm/api/version.generated.d.ts +1 -1
- package/lib/esm/api/version.generated.js +1 -1
- package/lib/esm/offers/Offer.d.ts +50 -0
- package/lib/esm/offers/Offer.js +53 -0
- package/lib/esm/offers/OfferUtils.d.ts +108 -0
- package/lib/esm/offers/OfferUtils.js +117 -1
- package/package.json +3 -3
|
@@ -142,7 +142,7 @@ export declare class MidnightApi {
|
|
|
142
142
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
143
143
|
* @returns ABI-ready take objects mapped from the API response.
|
|
144
144
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
145
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
145
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
146
146
|
* @example
|
|
147
147
|
* ```ts
|
|
148
148
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -170,11 +170,12 @@ export declare class MidnightApi {
|
|
|
170
170
|
* @param params.baseUrl - Optional Midnight API base URL override.
|
|
171
171
|
* @param params.fetch - Optional fetch implementation override.
|
|
172
172
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
173
|
-
* @returns Quote and
|
|
173
|
+
* @returns Quote and ABI-ready take caps. `averageWorstPrice` equals the caller's guard when provided,
|
|
174
|
+
* otherwise the API's guard.
|
|
174
175
|
* @throws {InvalidMidnightApiQuoteTargetError} when the runtime input does not set exactly one of `units` or `assets`.
|
|
175
176
|
* @throws {NegativeValueError} when `settlementFee` is negative.
|
|
176
177
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
177
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
178
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, when its units exceed its offer `maxUnits`, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
178
179
|
* @throws {SettlementFeeExceedsPriceError} when a bid's settlement fee exceeds its offer price.
|
|
179
180
|
* @example
|
|
180
181
|
* ```ts
|
|
@@ -205,7 +206,7 @@ export declare class MidnightApi {
|
|
|
205
206
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
206
207
|
* @returns Paginated ABI-ready take objects mapped from the API response.
|
|
207
208
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
208
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
209
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
209
210
|
* @example
|
|
210
211
|
* ```ts
|
|
211
212
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -390,7 +391,7 @@ export declare class MidnightApi {
|
|
|
390
391
|
* @param params.side - Book side to query.
|
|
391
392
|
* @returns ABI-ready take objects mapped from the API response.
|
|
392
393
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
393
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
394
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
394
395
|
* @example
|
|
395
396
|
* ```ts
|
|
396
397
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -416,11 +417,12 @@ export declare class MidnightApi {
|
|
|
416
417
|
* @param params.averageWorstPrice - Optional WAD-scaled average worst price guard. Mutually exclusive with `params.slippage`.
|
|
417
418
|
* @param params.slippage - Optional slippage percentage used to derive the guard. Mutually exclusive with `params.averageWorstPrice`.
|
|
418
419
|
* @param params.settlementFee - Optional current WAD-scaled settlement fee used for local guard validation. Defaults to zero.
|
|
419
|
-
* @returns Quote and
|
|
420
|
+
* @returns Quote and ABI-ready take caps. `averageWorstPrice` equals the caller's guard when provided,
|
|
421
|
+
* otherwise the API's guard.
|
|
420
422
|
* @throws {InvalidMidnightApiQuoteTargetError} when the runtime input does not set exactly one of `units` or `assets`.
|
|
421
423
|
* @throws {NegativeValueError} when `settlementFee` is negative.
|
|
422
424
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
423
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
425
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, when its units exceed its offer `maxUnits`, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
424
426
|
* @throws {SettlementFeeExceedsPriceError} when a bid's settlement fee exceeds its offer price.
|
|
425
427
|
* @example
|
|
426
428
|
* ```ts
|
|
@@ -448,7 +450,7 @@ export declare class MidnightApi {
|
|
|
448
450
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
449
451
|
* @returns Paginated ABI-ready take objects mapped from the API response.
|
|
450
452
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
451
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
453
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
452
454
|
* @example
|
|
453
455
|
* ```ts
|
|
454
456
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -207,7 +207,7 @@ class MidnightApi {
|
|
|
207
207
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
208
208
|
* @returns ABI-ready take objects mapped from the API response.
|
|
209
209
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
210
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
210
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
211
211
|
* @example
|
|
212
212
|
* ```ts
|
|
213
213
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -252,11 +252,12 @@ class MidnightApi {
|
|
|
252
252
|
* @param params.baseUrl - Optional Midnight API base URL override.
|
|
253
253
|
* @param params.fetch - Optional fetch implementation override.
|
|
254
254
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
255
|
-
* @returns Quote and
|
|
255
|
+
* @returns Quote and ABI-ready take caps. `averageWorstPrice` equals the caller's guard when provided,
|
|
256
|
+
* otherwise the API's guard.
|
|
256
257
|
* @throws {InvalidMidnightApiQuoteTargetError} when the runtime input does not set exactly one of `units` or `assets`.
|
|
257
258
|
* @throws {NegativeValueError} when `settlementFee` is negative.
|
|
258
259
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
259
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
260
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, when its units exceed its offer `maxUnits`, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
260
261
|
* @throws {SettlementFeeExceedsPriceError} when a bid's settlement fee exceeds its offer price.
|
|
261
262
|
* @example
|
|
262
263
|
* ```ts
|
|
@@ -301,8 +302,8 @@ class MidnightApi {
|
|
|
301
302
|
: "slippage" in input && input.slippage != null
|
|
302
303
|
? response.data.average_worst_price
|
|
303
304
|
: undefined;
|
|
304
|
-
|
|
305
|
-
|
|
305
|
+
const guard = averageWorstPrice == null ? undefined : BigInt(averageWorstPrice);
|
|
306
|
+
if (guard != null) {
|
|
306
307
|
let filledUnits = 0n;
|
|
307
308
|
let filledAssets = 0n;
|
|
308
309
|
if ("units" in input && input.units != null) {
|
|
@@ -359,7 +360,7 @@ class MidnightApi {
|
|
|
359
360
|
return {
|
|
360
361
|
data: {
|
|
361
362
|
averageBestPrice: response.data.average_best_price,
|
|
362
|
-
averageWorstPrice: response.data.average_worst_price,
|
|
363
|
+
averageWorstPrice: guard?.toString() ?? response.data.average_worst_price,
|
|
363
364
|
availableAssets: response.data.available_assets,
|
|
364
365
|
availableUnits: response.data.available_units,
|
|
365
366
|
takeableOffers,
|
|
@@ -381,7 +382,7 @@ class MidnightApi {
|
|
|
381
382
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
382
383
|
* @returns Paginated ABI-ready take objects mapped from the API response.
|
|
383
384
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
384
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
385
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
385
386
|
* @example
|
|
386
387
|
* ```ts
|
|
387
388
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -629,7 +630,7 @@ class MidnightApi {
|
|
|
629
630
|
* @param params.side - Book side to query.
|
|
630
631
|
* @returns ABI-ready take objects mapped from the API response.
|
|
631
632
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
632
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
633
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
633
634
|
* @example
|
|
634
635
|
* ```ts
|
|
635
636
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -660,11 +661,12 @@ class MidnightApi {
|
|
|
660
661
|
* @param params.averageWorstPrice - Optional WAD-scaled average worst price guard. Mutually exclusive with `params.slippage`.
|
|
661
662
|
* @param params.slippage - Optional slippage percentage used to derive the guard. Mutually exclusive with `params.averageWorstPrice`.
|
|
662
663
|
* @param params.settlementFee - Optional current WAD-scaled settlement fee used for local guard validation. Defaults to zero.
|
|
663
|
-
* @returns Quote and
|
|
664
|
+
* @returns Quote and ABI-ready take caps. `averageWorstPrice` equals the caller's guard when provided,
|
|
665
|
+
* otherwise the API's guard.
|
|
664
666
|
* @throws {InvalidMidnightApiQuoteTargetError} when the runtime input does not set exactly one of `units` or `assets`.
|
|
665
667
|
* @throws {NegativeValueError} when `settlementFee` is negative.
|
|
666
668
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
667
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
669
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, when its units exceed its offer `maxUnits`, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
668
670
|
* @throws {SettlementFeeExceedsPriceError} when a bid's settlement fee exceeds its offer price.
|
|
669
671
|
* @example
|
|
670
672
|
* ```ts
|
|
@@ -697,7 +699,7 @@ class MidnightApi {
|
|
|
697
699
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
698
700
|
* @returns Paginated ABI-ready take objects mapped from the API response.
|
|
699
701
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
700
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
702
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
701
703
|
* @example
|
|
702
704
|
* ```ts
|
|
703
705
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
package/lib/cjs/api/helpers.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export interface TakeableOfferContext {
|
|
|
30
30
|
readonly marketIds?: readonly Hash[];
|
|
31
31
|
readonly groups?: readonly Hash[];
|
|
32
32
|
}
|
|
33
|
-
/** @internal Maps, validates, and best-price-sorts API takeable offers. */
|
|
33
|
+
/** @internal Maps, validates offer caps and units, and best-price-sorts API takeable offers. */
|
|
34
34
|
export declare function mapBoundTakeableOffers(takeableOffers: readonly ApiTakeableOfferResponse[], context: TakeableOfferContext): MidnightApiTake[];
|
|
35
35
|
/** @internal Parses the mempool validation response envelope. */
|
|
36
36
|
export declare function parseValidationResponse(response: unknown): MempoolPayloadValidationResult;
|
package/lib/cjs/api/helpers.js
CHANGED
|
@@ -250,7 +250,7 @@ function mapTakeableOffer(takeableOffer) {
|
|
|
250
250
|
ratifierData: takeableOffer.ratifier_data,
|
|
251
251
|
};
|
|
252
252
|
}
|
|
253
|
-
/** @internal Maps, validates, and best-price-sorts API takeable offers. */
|
|
253
|
+
/** @internal Maps, validates offer caps and units, and best-price-sorts API takeable offers. */
|
|
254
254
|
function mapBoundTakeableOffers(takeableOffers, context) {
|
|
255
255
|
const mapped = takeableOffers.map((takeableOffer) => {
|
|
256
256
|
let take;
|
|
@@ -285,6 +285,9 @@ function mapBoundTakeableOffers(takeableOffers, context) {
|
|
|
285
285
|
throw cause;
|
|
286
286
|
throw new errors_js_1.InvalidMidnightApiResponseError(`Midnight API takeable offer for market_id "${take.marketId}" is not executable: ${cause.message}`, { cause });
|
|
287
287
|
}
|
|
288
|
+
if (maxUnits > 0n && take.units > maxUnits) {
|
|
289
|
+
throw new errors_js_1.InvalidMidnightApiResponseError(`Midnight API takeable offer for market_id "${take.marketId}" reports units "${take.units}" above offer maxUnits "${maxUnits}".`);
|
|
290
|
+
}
|
|
288
291
|
if (context.marketId != null &&
|
|
289
292
|
!(0, morpho_ts_1.isHexEqual)(take.marketId, context.marketId)) {
|
|
290
293
|
throw new errors_js_1.InvalidMidnightApiResponseError(`Midnight API takeable offer market_id "${take.marketId}" does not match requested market "${context.marketId}".`);
|
package/lib/cjs/api/types.d.ts
CHANGED
|
@@ -409,7 +409,7 @@ export interface MidnightApiBookPriceLevelsResult {
|
|
|
409
409
|
export interface MidnightApiQuote {
|
|
410
410
|
/** Weighted average price for the requested size before any guard. */
|
|
411
411
|
readonly averageBestPrice: string;
|
|
412
|
-
/**
|
|
412
|
+
/** Equals the caller's `averageWorstPrice` when provided, otherwise the API's guard. */
|
|
413
413
|
readonly averageWorstPrice: string;
|
|
414
414
|
/** Maximum assets available from the returned take caps. */
|
|
415
415
|
readonly availableAssets: string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal Installed Midnight SDK package version. */
|
|
2
|
-
export declare const MIDNIGHT_SDK_VERSION = "2.
|
|
2
|
+
export declare const MIDNIGHT_SDK_VERSION = "2.1.0";
|
|
@@ -150,6 +150,7 @@ export declare class Offer {
|
|
|
150
150
|
readonly tick: bigint;
|
|
151
151
|
private cachedGroup;
|
|
152
152
|
private cachedHash;
|
|
153
|
+
private cachedOnchainHash;
|
|
153
154
|
/**
|
|
154
155
|
* Whether the group id was supplied at construction rather than derived.
|
|
155
156
|
*
|
|
@@ -329,6 +330,55 @@ export declare class Offer {
|
|
|
329
330
|
* ```
|
|
330
331
|
*/
|
|
331
332
|
get hash(): Hash;
|
|
333
|
+
/**
|
|
334
|
+
* Returns the on-chain offer identifier emitted by Midnight's `Take` event.
|
|
335
|
+
*
|
|
336
|
+
* This `keccak256(abi.encode(offer))` hash identifies offers on-chain and is
|
|
337
|
+
* distinct from `hash`, the typehash-prefixed ratifier hash.
|
|
338
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
339
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
340
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
341
|
+
* `Group.create` group.
|
|
342
|
+
*
|
|
343
|
+
* @returns The cached on-chain offer hash.
|
|
344
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
345
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* import { Offer } from "@morpho-org/midnight-sdk";
|
|
349
|
+
* import { zeroAddress } from "viem";
|
|
350
|
+
*
|
|
351
|
+
* const offer = Offer.create({
|
|
352
|
+
* market: {
|
|
353
|
+
* chainId: 8453,
|
|
354
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
355
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
356
|
+
* collateralParams: [
|
|
357
|
+
* {
|
|
358
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
359
|
+
* lltv: 770000000000000000n,
|
|
360
|
+
* liquidationCursor: 250000000000000000n,
|
|
361
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
362
|
+
* },
|
|
363
|
+
* ],
|
|
364
|
+
* maturity: 54_000n,
|
|
365
|
+
* rcfThreshold: 0n,
|
|
366
|
+
* enterGate: zeroAddress,
|
|
367
|
+
* liquidatorGate: zeroAddress,
|
|
368
|
+
* },
|
|
369
|
+
* buy: true,
|
|
370
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
371
|
+
* tick: 5_000n,
|
|
372
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
373
|
+
* expiry: 3_600n,
|
|
374
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
375
|
+
* maxUnits: 100n,
|
|
376
|
+
* });
|
|
377
|
+
* const offerHash = offer.onchainHash;
|
|
378
|
+
* console.log(offerHash);
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
get onchainHash(): Hash;
|
|
332
382
|
/**
|
|
333
383
|
* WAD zero-coupon price at this offer's tick.
|
|
334
384
|
*
|
package/lib/cjs/offers/Offer.js
CHANGED
|
@@ -71,6 +71,7 @@ class Offer {
|
|
|
71
71
|
tick;
|
|
72
72
|
cachedGroup;
|
|
73
73
|
cachedHash;
|
|
74
|
+
cachedOnchainHash;
|
|
74
75
|
/**
|
|
75
76
|
* Whether the group id was supplied at construction rather than derived.
|
|
76
77
|
*
|
|
@@ -281,6 +282,58 @@ class Offer {
|
|
|
281
282
|
this.cachedHash ??= OfferUtils_js_1.OfferUtils.hash(this);
|
|
282
283
|
return this.cachedHash;
|
|
283
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Returns the on-chain offer identifier emitted by Midnight's `Take` event.
|
|
287
|
+
*
|
|
288
|
+
* This `keccak256(abi.encode(offer))` hash identifies offers on-chain and is
|
|
289
|
+
* distinct from `hash`, the typehash-prefixed ratifier hash.
|
|
290
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
291
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
292
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
293
|
+
* `Group.create` group.
|
|
294
|
+
*
|
|
295
|
+
* @returns The cached on-chain offer hash.
|
|
296
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
297
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
298
|
+
* @example
|
|
299
|
+
* ```ts
|
|
300
|
+
* import { Offer } from "@morpho-org/midnight-sdk";
|
|
301
|
+
* import { zeroAddress } from "viem";
|
|
302
|
+
*
|
|
303
|
+
* const offer = Offer.create({
|
|
304
|
+
* market: {
|
|
305
|
+
* chainId: 8453,
|
|
306
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
307
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
308
|
+
* collateralParams: [
|
|
309
|
+
* {
|
|
310
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
311
|
+
* lltv: 770000000000000000n,
|
|
312
|
+
* liquidationCursor: 250000000000000000n,
|
|
313
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
314
|
+
* },
|
|
315
|
+
* ],
|
|
316
|
+
* maturity: 54_000n,
|
|
317
|
+
* rcfThreshold: 0n,
|
|
318
|
+
* enterGate: zeroAddress,
|
|
319
|
+
* liquidatorGate: zeroAddress,
|
|
320
|
+
* },
|
|
321
|
+
* buy: true,
|
|
322
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
323
|
+
* tick: 5_000n,
|
|
324
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
325
|
+
* expiry: 3_600n,
|
|
326
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
327
|
+
* maxUnits: 100n,
|
|
328
|
+
* });
|
|
329
|
+
* const offerHash = offer.onchainHash;
|
|
330
|
+
* console.log(offerHash);
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
get onchainHash() {
|
|
334
|
+
this.cachedOnchainHash ??= OfferUtils_js_1.OfferUtils.onchainHash(this);
|
|
335
|
+
return this.cachedOnchainHash;
|
|
336
|
+
}
|
|
284
337
|
/**
|
|
285
338
|
* WAD zero-coupon price at this offer's tick.
|
|
286
339
|
*
|
|
@@ -160,6 +160,114 @@ export declare namespace OfferUtils {
|
|
|
160
160
|
* ```
|
|
161
161
|
*/
|
|
162
162
|
function hash(offer: IOffer & Required<Pick<IOffer, "group">>): Hash;
|
|
163
|
+
/**
|
|
164
|
+
* Computes the on-chain offer identifier from the supplied offer struct.
|
|
165
|
+
*
|
|
166
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
167
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
168
|
+
* `hashStruct` and `hash`, which produce the typehash-prefixed ratifier hash.
|
|
169
|
+
* Collaterals are hashed in the supplied order; Midnight rejects unsorted
|
|
170
|
+
* collateral params with `CollateralParamsNotSorted`, so pass a sorted struct,
|
|
171
|
+
* for example one returned by `toStruct`.
|
|
172
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
173
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
174
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
175
|
+
* `Group.create` group.
|
|
176
|
+
*
|
|
177
|
+
* @param offerStruct - ABI-compatible offer to hash without normalization.
|
|
178
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
179
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
180
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
184
|
+
* import { zeroAddress } from "viem";
|
|
185
|
+
*
|
|
186
|
+
* const offer = Offer.create({
|
|
187
|
+
* market: {
|
|
188
|
+
* chainId: 8453,
|
|
189
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
190
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
191
|
+
* collateralParams: [
|
|
192
|
+
* {
|
|
193
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
194
|
+
* lltv: 770000000000000000n,
|
|
195
|
+
* liquidationCursor: 250000000000000000n,
|
|
196
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
197
|
+
* },
|
|
198
|
+
* ],
|
|
199
|
+
* maturity: 54_000n,
|
|
200
|
+
* rcfThreshold: 0n,
|
|
201
|
+
* enterGate: zeroAddress,
|
|
202
|
+
* liquidatorGate: zeroAddress,
|
|
203
|
+
* },
|
|
204
|
+
* buy: true,
|
|
205
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
206
|
+
* tick: 5_000n,
|
|
207
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
208
|
+
* expiry: 3_600n,
|
|
209
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
210
|
+
* maxUnits: 100n,
|
|
211
|
+
* });
|
|
212
|
+
* const offerHash = OfferUtils.onchainHashStruct(
|
|
213
|
+
* OfferUtils.toStruct({ offer }),
|
|
214
|
+
* );
|
|
215
|
+
* console.log(offerHash);
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
function onchainHashStruct(offerStruct: OfferStruct): Hash;
|
|
219
|
+
/**
|
|
220
|
+
* Computes the on-chain offer identifier from an offer with a group id.
|
|
221
|
+
*
|
|
222
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
223
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
224
|
+
* `hash`, which returns the typehash-prefixed ratifier hash. `toStruct`
|
|
225
|
+
* normalizes the offer and sorts collateral params as required by Midnight.
|
|
226
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
227
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
228
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
229
|
+
* `Group.create` group.
|
|
230
|
+
*
|
|
231
|
+
* @param offer - Offer with the protocol group id encoded in its struct.
|
|
232
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
233
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
234
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
235
|
+
* @example
|
|
236
|
+
* ```ts
|
|
237
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
238
|
+
* import { zeroAddress } from "viem";
|
|
239
|
+
*
|
|
240
|
+
* const offer = Offer.create({
|
|
241
|
+
* market: {
|
|
242
|
+
* chainId: 8453,
|
|
243
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
244
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
245
|
+
* collateralParams: [
|
|
246
|
+
* {
|
|
247
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
248
|
+
* lltv: 770000000000000000n,
|
|
249
|
+
* liquidationCursor: 250000000000000000n,
|
|
250
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
251
|
+
* },
|
|
252
|
+
* ],
|
|
253
|
+
* maturity: 54_000n,
|
|
254
|
+
* rcfThreshold: 0n,
|
|
255
|
+
* enterGate: zeroAddress,
|
|
256
|
+
* liquidatorGate: zeroAddress,
|
|
257
|
+
* },
|
|
258
|
+
* buy: true,
|
|
259
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
260
|
+
* tick: 5_000n,
|
|
261
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
262
|
+
* expiry: 3_600n,
|
|
263
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
264
|
+
* maxUnits: 100n,
|
|
265
|
+
* });
|
|
266
|
+
* const offerHash = OfferUtils.onchainHash(offer);
|
|
267
|
+
* console.log(offerHash);
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
function onchainHash(offer: IOffer & Required<Pick<IOffer, "group">>): Hash;
|
|
163
271
|
/**
|
|
164
272
|
* Computes the offer hash used to derive a content-addressed group id.
|
|
165
273
|
*
|
|
@@ -3,11 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.OfferUtils = void 0;
|
|
4
4
|
const morpho_ts_1 = require("@morpho-org/morpho-ts");
|
|
5
5
|
const viem_1 = require("viem");
|
|
6
|
+
const abis_js_1 = require("../abis.js");
|
|
6
7
|
const constants_js_1 = require("../constants.js");
|
|
7
8
|
const errors_js_1 = require("../errors.js");
|
|
8
9
|
const index_js_1 = require("../market/index.js");
|
|
9
10
|
const index_js_2 = require("../math/index.js");
|
|
10
11
|
const Offer_js_1 = require("./Offer.js");
|
|
12
|
+
const takeOfferParam = (0, viem_1.getAbiItem)({ abi: abis_js_1.midnightAbi, name: "take" }).inputs[0];
|
|
11
13
|
const offerHashParams = [
|
|
12
14
|
{ name: "typehash", type: "bytes32" },
|
|
13
15
|
{ name: "marketHash", type: "bytes32" },
|
|
@@ -226,6 +228,120 @@ var OfferUtils;
|
|
|
226
228
|
return hashStruct(toStruct({ offer }));
|
|
227
229
|
}
|
|
228
230
|
OfferUtils.hash = hash;
|
|
231
|
+
/**
|
|
232
|
+
* Computes the on-chain offer identifier from the supplied offer struct.
|
|
233
|
+
*
|
|
234
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
235
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
236
|
+
* `hashStruct` and `hash`, which produce the typehash-prefixed ratifier hash.
|
|
237
|
+
* Collaterals are hashed in the supplied order; Midnight rejects unsorted
|
|
238
|
+
* collateral params with `CollateralParamsNotSorted`, so pass a sorted struct,
|
|
239
|
+
* for example one returned by `toStruct`.
|
|
240
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
241
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
242
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
243
|
+
* `Group.create` group.
|
|
244
|
+
*
|
|
245
|
+
* @param offerStruct - ABI-compatible offer to hash without normalization.
|
|
246
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
247
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
248
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
249
|
+
* @example
|
|
250
|
+
* ```ts
|
|
251
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
252
|
+
* import { zeroAddress } from "viem";
|
|
253
|
+
*
|
|
254
|
+
* const offer = Offer.create({
|
|
255
|
+
* market: {
|
|
256
|
+
* chainId: 8453,
|
|
257
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
258
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
259
|
+
* collateralParams: [
|
|
260
|
+
* {
|
|
261
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
262
|
+
* lltv: 770000000000000000n,
|
|
263
|
+
* liquidationCursor: 250000000000000000n,
|
|
264
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
265
|
+
* },
|
|
266
|
+
* ],
|
|
267
|
+
* maturity: 54_000n,
|
|
268
|
+
* rcfThreshold: 0n,
|
|
269
|
+
* enterGate: zeroAddress,
|
|
270
|
+
* liquidatorGate: zeroAddress,
|
|
271
|
+
* },
|
|
272
|
+
* buy: true,
|
|
273
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
274
|
+
* tick: 5_000n,
|
|
275
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
276
|
+
* expiry: 3_600n,
|
|
277
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
278
|
+
* maxUnits: 100n,
|
|
279
|
+
* });
|
|
280
|
+
* const offerHash = OfferUtils.onchainHashStruct(
|
|
281
|
+
* OfferUtils.toStruct({ offer }),
|
|
282
|
+
* );
|
|
283
|
+
* console.log(offerHash);
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
function onchainHashStruct(offerStruct) {
|
|
287
|
+
return (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([takeOfferParam], [offerStruct]));
|
|
288
|
+
}
|
|
289
|
+
OfferUtils.onchainHashStruct = onchainHashStruct;
|
|
290
|
+
/**
|
|
291
|
+
* Computes the on-chain offer identifier from an offer with a group id.
|
|
292
|
+
*
|
|
293
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
294
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
295
|
+
* `hash`, which returns the typehash-prefixed ratifier hash. `toStruct`
|
|
296
|
+
* normalizes the offer and sorts collateral params as required by Midnight.
|
|
297
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
298
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
299
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
300
|
+
* `Group.create` group.
|
|
301
|
+
*
|
|
302
|
+
* @param offer - Offer with the protocol group id encoded in its struct.
|
|
303
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
304
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
305
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
306
|
+
* @example
|
|
307
|
+
* ```ts
|
|
308
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
309
|
+
* import { zeroAddress } from "viem";
|
|
310
|
+
*
|
|
311
|
+
* const offer = Offer.create({
|
|
312
|
+
* market: {
|
|
313
|
+
* chainId: 8453,
|
|
314
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
315
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
316
|
+
* collateralParams: [
|
|
317
|
+
* {
|
|
318
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
319
|
+
* lltv: 770000000000000000n,
|
|
320
|
+
* liquidationCursor: 250000000000000000n,
|
|
321
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
322
|
+
* },
|
|
323
|
+
* ],
|
|
324
|
+
* maturity: 54_000n,
|
|
325
|
+
* rcfThreshold: 0n,
|
|
326
|
+
* enterGate: zeroAddress,
|
|
327
|
+
* liquidatorGate: zeroAddress,
|
|
328
|
+
* },
|
|
329
|
+
* buy: true,
|
|
330
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
331
|
+
* tick: 5_000n,
|
|
332
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
333
|
+
* expiry: 3_600n,
|
|
334
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
335
|
+
* maxUnits: 100n,
|
|
336
|
+
* });
|
|
337
|
+
* const offerHash = OfferUtils.onchainHash(offer);
|
|
338
|
+
* console.log(offerHash);
|
|
339
|
+
* ```
|
|
340
|
+
*/
|
|
341
|
+
function onchainHash(offer) {
|
|
342
|
+
return onchainHashStruct(toStruct({ offer }));
|
|
343
|
+
}
|
|
344
|
+
OfferUtils.onchainHash = onchainHash;
|
|
229
345
|
/**
|
|
230
346
|
* Computes the offer hash used to derive a content-addressed group id.
|
|
231
347
|
*
|
|
@@ -142,7 +142,7 @@ export declare class MidnightApi {
|
|
|
142
142
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
143
143
|
* @returns ABI-ready take objects mapped from the API response.
|
|
144
144
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
145
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
145
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
146
146
|
* @example
|
|
147
147
|
* ```ts
|
|
148
148
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -170,11 +170,12 @@ export declare class MidnightApi {
|
|
|
170
170
|
* @param params.baseUrl - Optional Midnight API base URL override.
|
|
171
171
|
* @param params.fetch - Optional fetch implementation override.
|
|
172
172
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
173
|
-
* @returns Quote and
|
|
173
|
+
* @returns Quote and ABI-ready take caps. `averageWorstPrice` equals the caller's guard when provided,
|
|
174
|
+
* otherwise the API's guard.
|
|
174
175
|
* @throws {InvalidMidnightApiQuoteTargetError} when the runtime input does not set exactly one of `units` or `assets`.
|
|
175
176
|
* @throws {NegativeValueError} when `settlementFee` is negative.
|
|
176
177
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
177
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
178
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, when its units exceed its offer `maxUnits`, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
178
179
|
* @throws {SettlementFeeExceedsPriceError} when a bid's settlement fee exceeds its offer price.
|
|
179
180
|
* @example
|
|
180
181
|
* ```ts
|
|
@@ -205,7 +206,7 @@ export declare class MidnightApi {
|
|
|
205
206
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
206
207
|
* @returns Paginated ABI-ready take objects mapped from the API response.
|
|
207
208
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
208
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
209
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
209
210
|
* @example
|
|
210
211
|
* ```ts
|
|
211
212
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -390,7 +391,7 @@ export declare class MidnightApi {
|
|
|
390
391
|
* @param params.side - Book side to query.
|
|
391
392
|
* @returns ABI-ready take objects mapped from the API response.
|
|
392
393
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
393
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
394
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
394
395
|
* @example
|
|
395
396
|
* ```ts
|
|
396
397
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -416,11 +417,12 @@ export declare class MidnightApi {
|
|
|
416
417
|
* @param params.averageWorstPrice - Optional WAD-scaled average worst price guard. Mutually exclusive with `params.slippage`.
|
|
417
418
|
* @param params.slippage - Optional slippage percentage used to derive the guard. Mutually exclusive with `params.averageWorstPrice`.
|
|
418
419
|
* @param params.settlementFee - Optional current WAD-scaled settlement fee used for local guard validation. Defaults to zero.
|
|
419
|
-
* @returns Quote and
|
|
420
|
+
* @returns Quote and ABI-ready take caps. `averageWorstPrice` equals the caller's guard when provided,
|
|
421
|
+
* otherwise the API's guard.
|
|
420
422
|
* @throws {InvalidMidnightApiQuoteTargetError} when the runtime input does not set exactly one of `units` or `assets`.
|
|
421
423
|
* @throws {NegativeValueError} when `settlementFee` is negative.
|
|
422
424
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
423
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
425
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, when its units exceed its offer `maxUnits`, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
424
426
|
* @throws {SettlementFeeExceedsPriceError} when a bid's settlement fee exceeds its offer price.
|
|
425
427
|
* @example
|
|
426
428
|
* ```ts
|
|
@@ -448,7 +450,7 @@ export declare class MidnightApi {
|
|
|
448
450
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
449
451
|
* @returns Paginated ABI-ready take objects mapped from the API response.
|
|
450
452
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
451
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
453
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
452
454
|
* @example
|
|
453
455
|
* ```ts
|
|
454
456
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -203,7 +203,7 @@ export class MidnightApi {
|
|
|
203
203
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
204
204
|
* @returns ABI-ready take objects mapped from the API response.
|
|
205
205
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
206
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
206
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
207
207
|
* @example
|
|
208
208
|
* ```ts
|
|
209
209
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -248,11 +248,12 @@ export class MidnightApi {
|
|
|
248
248
|
* @param params.baseUrl - Optional Midnight API base URL override.
|
|
249
249
|
* @param params.fetch - Optional fetch implementation override.
|
|
250
250
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
251
|
-
* @returns Quote and
|
|
251
|
+
* @returns Quote and ABI-ready take caps. `averageWorstPrice` equals the caller's guard when provided,
|
|
252
|
+
* otherwise the API's guard.
|
|
252
253
|
* @throws {InvalidMidnightApiQuoteTargetError} when the runtime input does not set exactly one of `units` or `assets`.
|
|
253
254
|
* @throws {NegativeValueError} when `settlementFee` is negative.
|
|
254
255
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
255
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
256
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, when its units exceed its offer `maxUnits`, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
256
257
|
* @throws {SettlementFeeExceedsPriceError} when a bid's settlement fee exceeds its offer price.
|
|
257
258
|
* @example
|
|
258
259
|
* ```ts
|
|
@@ -297,8 +298,8 @@ export class MidnightApi {
|
|
|
297
298
|
: "slippage" in input && input.slippage != null
|
|
298
299
|
? response.data.average_worst_price
|
|
299
300
|
: undefined;
|
|
300
|
-
|
|
301
|
-
|
|
301
|
+
const guard = averageWorstPrice == null ? undefined : BigInt(averageWorstPrice);
|
|
302
|
+
if (guard != null) {
|
|
302
303
|
let filledUnits = 0n;
|
|
303
304
|
let filledAssets = 0n;
|
|
304
305
|
if ("units" in input && input.units != null) {
|
|
@@ -355,7 +356,7 @@ export class MidnightApi {
|
|
|
355
356
|
return {
|
|
356
357
|
data: {
|
|
357
358
|
averageBestPrice: response.data.average_best_price,
|
|
358
|
-
averageWorstPrice: response.data.average_worst_price,
|
|
359
|
+
averageWorstPrice: guard?.toString() ?? response.data.average_worst_price,
|
|
359
360
|
availableAssets: response.data.available_assets,
|
|
360
361
|
availableUnits: response.data.available_units,
|
|
361
362
|
takeableOffers,
|
|
@@ -377,7 +378,7 @@ export class MidnightApi {
|
|
|
377
378
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
378
379
|
* @returns Paginated ABI-ready take objects mapped from the API response.
|
|
379
380
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
380
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
381
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
381
382
|
* @example
|
|
382
383
|
* ```ts
|
|
383
384
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -625,7 +626,7 @@ export class MidnightApi {
|
|
|
625
626
|
* @param params.side - Book side to query.
|
|
626
627
|
* @returns ABI-ready take objects mapped from the API response.
|
|
627
628
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
628
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
629
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
629
630
|
* @example
|
|
630
631
|
* ```ts
|
|
631
632
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -656,11 +657,12 @@ export class MidnightApi {
|
|
|
656
657
|
* @param params.averageWorstPrice - Optional WAD-scaled average worst price guard. Mutually exclusive with `params.slippage`.
|
|
657
658
|
* @param params.slippage - Optional slippage percentage used to derive the guard. Mutually exclusive with `params.averageWorstPrice`.
|
|
658
659
|
* @param params.settlementFee - Optional current WAD-scaled settlement fee used for local guard validation. Defaults to zero.
|
|
659
|
-
* @returns Quote and
|
|
660
|
+
* @returns Quote and ABI-ready take caps. `averageWorstPrice` equals the caller's guard when provided,
|
|
661
|
+
* otherwise the API's guard.
|
|
660
662
|
* @throws {InvalidMidnightApiQuoteTargetError} when the runtime input does not set exactly one of `units` or `assets`.
|
|
661
663
|
* @throws {NegativeValueError} when `settlementFee` is negative.
|
|
662
664
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
663
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
665
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, when its units exceed its offer `maxUnits`, or when the returned offers imply a rounded aggregate settlement price outside the effective average-worst-price guard.
|
|
664
666
|
* @throws {SettlementFeeExceedsPriceError} when a bid's settlement fee exceeds its offer price.
|
|
665
667
|
* @example
|
|
666
668
|
* ```ts
|
|
@@ -693,7 +695,7 @@ export class MidnightApi {
|
|
|
693
695
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
694
696
|
* @returns Paginated ABI-ready take objects mapped from the API response.
|
|
695
697
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
696
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address,
|
|
698
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned offer cannot be mapped (malformed numeric or hex fields), when its `market_id` does not match, or cannot be derived from, its embedded market, when it falls outside the requested filters, when its `receiverIfMakerIsSeller` is not a well-formed address, when its caps or buy-side receiver are not executable, or when its units exceed its offer `maxUnits`.
|
|
697
699
|
* @example
|
|
698
700
|
* ```ts
|
|
699
701
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
package/lib/esm/api/helpers.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export interface TakeableOfferContext {
|
|
|
30
30
|
readonly marketIds?: readonly Hash[];
|
|
31
31
|
readonly groups?: readonly Hash[];
|
|
32
32
|
}
|
|
33
|
-
/** @internal Maps, validates, and best-price-sorts API takeable offers. */
|
|
33
|
+
/** @internal Maps, validates offer caps and units, and best-price-sorts API takeable offers. */
|
|
34
34
|
export declare function mapBoundTakeableOffers(takeableOffers: readonly ApiTakeableOfferResponse[], context: TakeableOfferContext): MidnightApiTake[];
|
|
35
35
|
/** @internal Parses the mempool validation response envelope. */
|
|
36
36
|
export declare function parseValidationResponse(response: unknown): MempoolPayloadValidationResult;
|
package/lib/esm/api/helpers.js
CHANGED
|
@@ -241,7 +241,7 @@ function mapTakeableOffer(takeableOffer) {
|
|
|
241
241
|
ratifierData: takeableOffer.ratifier_data,
|
|
242
242
|
};
|
|
243
243
|
}
|
|
244
|
-
/** @internal Maps, validates, and best-price-sorts API takeable offers. */
|
|
244
|
+
/** @internal Maps, validates offer caps and units, and best-price-sorts API takeable offers. */
|
|
245
245
|
export function mapBoundTakeableOffers(takeableOffers, context) {
|
|
246
246
|
const mapped = takeableOffers.map((takeableOffer) => {
|
|
247
247
|
let take;
|
|
@@ -276,6 +276,9 @@ export function mapBoundTakeableOffers(takeableOffers, context) {
|
|
|
276
276
|
throw cause;
|
|
277
277
|
throw new InvalidMidnightApiResponseError(`Midnight API takeable offer for market_id "${take.marketId}" is not executable: ${cause.message}`, { cause });
|
|
278
278
|
}
|
|
279
|
+
if (maxUnits > 0n && take.units > maxUnits) {
|
|
280
|
+
throw new InvalidMidnightApiResponseError(`Midnight API takeable offer for market_id "${take.marketId}" reports units "${take.units}" above offer maxUnits "${maxUnits}".`);
|
|
281
|
+
}
|
|
279
282
|
if (context.marketId != null &&
|
|
280
283
|
!isHexEqual(take.marketId, context.marketId)) {
|
|
281
284
|
throw new InvalidMidnightApiResponseError(`Midnight API takeable offer market_id "${take.marketId}" does not match requested market "${context.marketId}".`);
|
package/lib/esm/api/types.d.ts
CHANGED
|
@@ -409,7 +409,7 @@ export interface MidnightApiBookPriceLevelsResult {
|
|
|
409
409
|
export interface MidnightApiQuote {
|
|
410
410
|
/** Weighted average price for the requested size before any guard. */
|
|
411
411
|
readonly averageBestPrice: string;
|
|
412
|
-
/**
|
|
412
|
+
/** Equals the caller's `averageWorstPrice` when provided, otherwise the API's guard. */
|
|
413
413
|
readonly averageWorstPrice: string;
|
|
414
414
|
/** Maximum assets available from the returned take caps. */
|
|
415
415
|
readonly availableAssets: string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal Installed Midnight SDK package version. */
|
|
2
|
-
export declare const MIDNIGHT_SDK_VERSION = "2.
|
|
2
|
+
export declare const MIDNIGHT_SDK_VERSION = "2.1.0";
|
|
@@ -150,6 +150,7 @@ export declare class Offer {
|
|
|
150
150
|
readonly tick: bigint;
|
|
151
151
|
private cachedGroup;
|
|
152
152
|
private cachedHash;
|
|
153
|
+
private cachedOnchainHash;
|
|
153
154
|
/**
|
|
154
155
|
* Whether the group id was supplied at construction rather than derived.
|
|
155
156
|
*
|
|
@@ -329,6 +330,55 @@ export declare class Offer {
|
|
|
329
330
|
* ```
|
|
330
331
|
*/
|
|
331
332
|
get hash(): Hash;
|
|
333
|
+
/**
|
|
334
|
+
* Returns the on-chain offer identifier emitted by Midnight's `Take` event.
|
|
335
|
+
*
|
|
336
|
+
* This `keccak256(abi.encode(offer))` hash identifies offers on-chain and is
|
|
337
|
+
* distinct from `hash`, the typehash-prefixed ratifier hash.
|
|
338
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
339
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
340
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
341
|
+
* `Group.create` group.
|
|
342
|
+
*
|
|
343
|
+
* @returns The cached on-chain offer hash.
|
|
344
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
345
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* import { Offer } from "@morpho-org/midnight-sdk";
|
|
349
|
+
* import { zeroAddress } from "viem";
|
|
350
|
+
*
|
|
351
|
+
* const offer = Offer.create({
|
|
352
|
+
* market: {
|
|
353
|
+
* chainId: 8453,
|
|
354
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
355
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
356
|
+
* collateralParams: [
|
|
357
|
+
* {
|
|
358
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
359
|
+
* lltv: 770000000000000000n,
|
|
360
|
+
* liquidationCursor: 250000000000000000n,
|
|
361
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
362
|
+
* },
|
|
363
|
+
* ],
|
|
364
|
+
* maturity: 54_000n,
|
|
365
|
+
* rcfThreshold: 0n,
|
|
366
|
+
* enterGate: zeroAddress,
|
|
367
|
+
* liquidatorGate: zeroAddress,
|
|
368
|
+
* },
|
|
369
|
+
* buy: true,
|
|
370
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
371
|
+
* tick: 5_000n,
|
|
372
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
373
|
+
* expiry: 3_600n,
|
|
374
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
375
|
+
* maxUnits: 100n,
|
|
376
|
+
* });
|
|
377
|
+
* const offerHash = offer.onchainHash;
|
|
378
|
+
* console.log(offerHash);
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
get onchainHash(): Hash;
|
|
332
382
|
/**
|
|
333
383
|
* WAD zero-coupon price at this offer's tick.
|
|
334
384
|
*
|
package/lib/esm/offers/Offer.js
CHANGED
|
@@ -68,6 +68,7 @@ export class Offer {
|
|
|
68
68
|
tick;
|
|
69
69
|
cachedGroup;
|
|
70
70
|
cachedHash;
|
|
71
|
+
cachedOnchainHash;
|
|
71
72
|
/**
|
|
72
73
|
* Whether the group id was supplied at construction rather than derived.
|
|
73
74
|
*
|
|
@@ -278,6 +279,58 @@ export class Offer {
|
|
|
278
279
|
this.cachedHash ??= OfferUtils.hash(this);
|
|
279
280
|
return this.cachedHash;
|
|
280
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* Returns the on-chain offer identifier emitted by Midnight's `Take` event.
|
|
284
|
+
*
|
|
285
|
+
* This `keccak256(abi.encode(offer))` hash identifies offers on-chain and is
|
|
286
|
+
* distinct from `hash`, the typehash-prefixed ratifier hash.
|
|
287
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
288
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
289
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
290
|
+
* `Group.create` group.
|
|
291
|
+
*
|
|
292
|
+
* @returns The cached on-chain offer hash.
|
|
293
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
294
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
295
|
+
* @example
|
|
296
|
+
* ```ts
|
|
297
|
+
* import { Offer } from "@morpho-org/midnight-sdk";
|
|
298
|
+
* import { zeroAddress } from "viem";
|
|
299
|
+
*
|
|
300
|
+
* const offer = Offer.create({
|
|
301
|
+
* market: {
|
|
302
|
+
* chainId: 8453,
|
|
303
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
304
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
305
|
+
* collateralParams: [
|
|
306
|
+
* {
|
|
307
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
308
|
+
* lltv: 770000000000000000n,
|
|
309
|
+
* liquidationCursor: 250000000000000000n,
|
|
310
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
311
|
+
* },
|
|
312
|
+
* ],
|
|
313
|
+
* maturity: 54_000n,
|
|
314
|
+
* rcfThreshold: 0n,
|
|
315
|
+
* enterGate: zeroAddress,
|
|
316
|
+
* liquidatorGate: zeroAddress,
|
|
317
|
+
* },
|
|
318
|
+
* buy: true,
|
|
319
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
320
|
+
* tick: 5_000n,
|
|
321
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
322
|
+
* expiry: 3_600n,
|
|
323
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
324
|
+
* maxUnits: 100n,
|
|
325
|
+
* });
|
|
326
|
+
* const offerHash = offer.onchainHash;
|
|
327
|
+
* console.log(offerHash);
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
get onchainHash() {
|
|
331
|
+
this.cachedOnchainHash ??= OfferUtils.onchainHash(this);
|
|
332
|
+
return this.cachedOnchainHash;
|
|
333
|
+
}
|
|
281
334
|
/**
|
|
282
335
|
* WAD zero-coupon price at this offer's tick.
|
|
283
336
|
*
|
|
@@ -160,6 +160,114 @@ export declare namespace OfferUtils {
|
|
|
160
160
|
* ```
|
|
161
161
|
*/
|
|
162
162
|
function hash(offer: IOffer & Required<Pick<IOffer, "group">>): Hash;
|
|
163
|
+
/**
|
|
164
|
+
* Computes the on-chain offer identifier from the supplied offer struct.
|
|
165
|
+
*
|
|
166
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
167
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
168
|
+
* `hashStruct` and `hash`, which produce the typehash-prefixed ratifier hash.
|
|
169
|
+
* Collaterals are hashed in the supplied order; Midnight rejects unsorted
|
|
170
|
+
* collateral params with `CollateralParamsNotSorted`, so pass a sorted struct,
|
|
171
|
+
* for example one returned by `toStruct`.
|
|
172
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
173
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
174
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
175
|
+
* `Group.create` group.
|
|
176
|
+
*
|
|
177
|
+
* @param offerStruct - ABI-compatible offer to hash without normalization.
|
|
178
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
179
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
180
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
184
|
+
* import { zeroAddress } from "viem";
|
|
185
|
+
*
|
|
186
|
+
* const offer = Offer.create({
|
|
187
|
+
* market: {
|
|
188
|
+
* chainId: 8453,
|
|
189
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
190
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
191
|
+
* collateralParams: [
|
|
192
|
+
* {
|
|
193
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
194
|
+
* lltv: 770000000000000000n,
|
|
195
|
+
* liquidationCursor: 250000000000000000n,
|
|
196
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
197
|
+
* },
|
|
198
|
+
* ],
|
|
199
|
+
* maturity: 54_000n,
|
|
200
|
+
* rcfThreshold: 0n,
|
|
201
|
+
* enterGate: zeroAddress,
|
|
202
|
+
* liquidatorGate: zeroAddress,
|
|
203
|
+
* },
|
|
204
|
+
* buy: true,
|
|
205
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
206
|
+
* tick: 5_000n,
|
|
207
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
208
|
+
* expiry: 3_600n,
|
|
209
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
210
|
+
* maxUnits: 100n,
|
|
211
|
+
* });
|
|
212
|
+
* const offerHash = OfferUtils.onchainHashStruct(
|
|
213
|
+
* OfferUtils.toStruct({ offer }),
|
|
214
|
+
* );
|
|
215
|
+
* console.log(offerHash);
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
function onchainHashStruct(offerStruct: OfferStruct): Hash;
|
|
219
|
+
/**
|
|
220
|
+
* Computes the on-chain offer identifier from an offer with a group id.
|
|
221
|
+
*
|
|
222
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
223
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
224
|
+
* `hash`, which returns the typehash-prefixed ratifier hash. `toStruct`
|
|
225
|
+
* normalizes the offer and sorts collateral params as required by Midnight.
|
|
226
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
227
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
228
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
229
|
+
* `Group.create` group.
|
|
230
|
+
*
|
|
231
|
+
* @param offer - Offer with the protocol group id encoded in its struct.
|
|
232
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
233
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
234
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
235
|
+
* @example
|
|
236
|
+
* ```ts
|
|
237
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
238
|
+
* import { zeroAddress } from "viem";
|
|
239
|
+
*
|
|
240
|
+
* const offer = Offer.create({
|
|
241
|
+
* market: {
|
|
242
|
+
* chainId: 8453,
|
|
243
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
244
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
245
|
+
* collateralParams: [
|
|
246
|
+
* {
|
|
247
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
248
|
+
* lltv: 770000000000000000n,
|
|
249
|
+
* liquidationCursor: 250000000000000000n,
|
|
250
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
251
|
+
* },
|
|
252
|
+
* ],
|
|
253
|
+
* maturity: 54_000n,
|
|
254
|
+
* rcfThreshold: 0n,
|
|
255
|
+
* enterGate: zeroAddress,
|
|
256
|
+
* liquidatorGate: zeroAddress,
|
|
257
|
+
* },
|
|
258
|
+
* buy: true,
|
|
259
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
260
|
+
* tick: 5_000n,
|
|
261
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
262
|
+
* expiry: 3_600n,
|
|
263
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
264
|
+
* maxUnits: 100n,
|
|
265
|
+
* });
|
|
266
|
+
* const offerHash = OfferUtils.onchainHash(offer);
|
|
267
|
+
* console.log(offerHash);
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
function onchainHash(offer: IOffer & Required<Pick<IOffer, "group">>): Hash;
|
|
163
271
|
/**
|
|
164
272
|
* Computes the offer hash used to derive a content-addressed group id.
|
|
165
273
|
*
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { assertNonNegative, DivisionByZeroError, MathLib, } from "@morpho-org/morpho-ts";
|
|
2
|
-
import { encodeAbiParameters, isAddressEqual, keccak256, zeroAddress, zeroHash, } from "viem";
|
|
2
|
+
import { encodeAbiParameters, getAbiItem, isAddressEqual, keccak256, zeroAddress, zeroHash, } from "viem";
|
|
3
|
+
import { midnightAbi } from "../abis.js";
|
|
3
4
|
import { DEFAULT_TICK_SPACING, MAX_OFFER_CAP, MAX_TICK, OFFER_TYPEHASH, } from "../constants.js";
|
|
4
5
|
import { InvalidOfferGroupError, InvalidOfferParameterError, } from "../errors.js";
|
|
5
6
|
import { Market, MarketParams, MarketUtils } from "../market/index.js";
|
|
6
7
|
import { TakeAmountsLib, TickLib } from "../math/index.js";
|
|
7
8
|
import { Offer, } from "./Offer.js";
|
|
9
|
+
const takeOfferParam = getAbiItem({ abi: midnightAbi, name: "take" }).inputs[0];
|
|
8
10
|
const offerHashParams = [
|
|
9
11
|
{ name: "typehash", type: "bytes32" },
|
|
10
12
|
{ name: "marketHash", type: "bytes32" },
|
|
@@ -223,6 +225,120 @@ export var OfferUtils;
|
|
|
223
225
|
return hashStruct(toStruct({ offer }));
|
|
224
226
|
}
|
|
225
227
|
OfferUtils.hash = hash;
|
|
228
|
+
/**
|
|
229
|
+
* Computes the on-chain offer identifier from the supplied offer struct.
|
|
230
|
+
*
|
|
231
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
232
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
233
|
+
* `hashStruct` and `hash`, which produce the typehash-prefixed ratifier hash.
|
|
234
|
+
* Collaterals are hashed in the supplied order; Midnight rejects unsorted
|
|
235
|
+
* collateral params with `CollateralParamsNotSorted`, so pass a sorted struct,
|
|
236
|
+
* for example one returned by `toStruct`.
|
|
237
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
238
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
239
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
240
|
+
* `Group.create` group.
|
|
241
|
+
*
|
|
242
|
+
* @param offerStruct - ABI-compatible offer to hash without normalization.
|
|
243
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
244
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
245
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
246
|
+
* @example
|
|
247
|
+
* ```ts
|
|
248
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
249
|
+
* import { zeroAddress } from "viem";
|
|
250
|
+
*
|
|
251
|
+
* const offer = Offer.create({
|
|
252
|
+
* market: {
|
|
253
|
+
* chainId: 8453,
|
|
254
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
255
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
256
|
+
* collateralParams: [
|
|
257
|
+
* {
|
|
258
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
259
|
+
* lltv: 770000000000000000n,
|
|
260
|
+
* liquidationCursor: 250000000000000000n,
|
|
261
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
262
|
+
* },
|
|
263
|
+
* ],
|
|
264
|
+
* maturity: 54_000n,
|
|
265
|
+
* rcfThreshold: 0n,
|
|
266
|
+
* enterGate: zeroAddress,
|
|
267
|
+
* liquidatorGate: zeroAddress,
|
|
268
|
+
* },
|
|
269
|
+
* buy: true,
|
|
270
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
271
|
+
* tick: 5_000n,
|
|
272
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
273
|
+
* expiry: 3_600n,
|
|
274
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
275
|
+
* maxUnits: 100n,
|
|
276
|
+
* });
|
|
277
|
+
* const offerHash = OfferUtils.onchainHashStruct(
|
|
278
|
+
* OfferUtils.toStruct({ offer }),
|
|
279
|
+
* );
|
|
280
|
+
* console.log(offerHash);
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
function onchainHashStruct(offerStruct) {
|
|
284
|
+
return keccak256(encodeAbiParameters([takeOfferParam], [offerStruct]));
|
|
285
|
+
}
|
|
286
|
+
OfferUtils.onchainHashStruct = onchainHashStruct;
|
|
287
|
+
/**
|
|
288
|
+
* Computes the on-chain offer identifier from an offer with a group id.
|
|
289
|
+
*
|
|
290
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
291
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
292
|
+
* `hash`, which returns the typehash-prefixed ratifier hash. `toStruct`
|
|
293
|
+
* normalizes the offer and sorts collateral params as required by Midnight.
|
|
294
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
295
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
296
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
297
|
+
* `Group.create` group.
|
|
298
|
+
*
|
|
299
|
+
* @param offer - Offer with the protocol group id encoded in its struct.
|
|
300
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
301
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
302
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
303
|
+
* @example
|
|
304
|
+
* ```ts
|
|
305
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
306
|
+
* import { zeroAddress } from "viem";
|
|
307
|
+
*
|
|
308
|
+
* const offer = Offer.create({
|
|
309
|
+
* market: {
|
|
310
|
+
* chainId: 8453,
|
|
311
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
312
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
313
|
+
* collateralParams: [
|
|
314
|
+
* {
|
|
315
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
316
|
+
* lltv: 770000000000000000n,
|
|
317
|
+
* liquidationCursor: 250000000000000000n,
|
|
318
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
319
|
+
* },
|
|
320
|
+
* ],
|
|
321
|
+
* maturity: 54_000n,
|
|
322
|
+
* rcfThreshold: 0n,
|
|
323
|
+
* enterGate: zeroAddress,
|
|
324
|
+
* liquidatorGate: zeroAddress,
|
|
325
|
+
* },
|
|
326
|
+
* buy: true,
|
|
327
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
328
|
+
* tick: 5_000n,
|
|
329
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
330
|
+
* expiry: 3_600n,
|
|
331
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
332
|
+
* maxUnits: 100n,
|
|
333
|
+
* });
|
|
334
|
+
* const offerHash = OfferUtils.onchainHash(offer);
|
|
335
|
+
* console.log(offerHash);
|
|
336
|
+
* ```
|
|
337
|
+
*/
|
|
338
|
+
function onchainHash(offer) {
|
|
339
|
+
return onchainHashStruct(toStruct({ offer }));
|
|
340
|
+
}
|
|
341
|
+
OfferUtils.onchainHash = onchainHash;
|
|
226
342
|
/**
|
|
227
343
|
* Computes the offer hash used to derive a content-addressed group id.
|
|
228
344
|
*
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morpho-org/midnight-sdk",
|
|
3
3
|
"description": "Viem-based package for Morpho Midnight that exports protocol utilities, fetch helpers, and Midnight API utilities under a dedicated API subpath.",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.1.0",
|
|
5
5
|
"author": "Morpho Association <contact@morpho.org>",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"viem": "^2.0.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@morpho-org/morpho-ts": "^4.0.
|
|
49
|
-
"@morpho-org/test": "^2.
|
|
48
|
+
"@morpho-org/morpho-ts": "^4.0.1",
|
|
49
|
+
"@morpho-org/test": "^2.11.0",
|
|
50
50
|
"fast-check": "^4.9.0",
|
|
51
51
|
"typescript": "7.0.2",
|
|
52
52
|
"viem": "^2.55.10",
|