@morpho-org/midnight-sdk 2.0.0 → 2.1.0-next.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.
@@ -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, or when its caps or buy-side receiver are not executable.
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 signed ABI-ready take caps mapped from the API response.
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, or when its caps or buy-side receiver are not executable.
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, or when its caps or buy-side receiver are not executable.
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 signed ABI-ready take caps mapped from the API response.
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, or when its caps or buy-side receiver are not executable.
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, or when its caps or buy-side receiver are not executable.
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 signed ABI-ready take caps mapped from the API response.
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
- if (averageWorstPrice != null) {
305
- const guard = BigInt(averageWorstPrice);
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, or when its caps or buy-side receiver are not executable.
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, or when its caps or buy-side receiver are not executable.
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 signed ABI-ready take caps mapped from the API response.
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, or when its caps or buy-side receiver are not executable.
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";
@@ -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;
@@ -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}".`);
@@ -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
- /** Effective weighted average-price guard for the returned instructions. */
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.0.0";
2
+ export declare const MIDNIGHT_SDK_VERSION = "2.1.0-next.0";
@@ -3,4 +3,4 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.MIDNIGHT_SDK_VERSION = void 0;
5
5
  /** @internal Installed Midnight SDK package version. */
6
- exports.MIDNIGHT_SDK_VERSION = "2.0.0";
6
+ exports.MIDNIGHT_SDK_VERSION = "2.1.0-next.0";
@@ -1,3 +1,4 @@
1
+ import { InvalidPositionAccrualStateError as SharedInvalidPositionAccrualStateError, InvalidPositionAccrualTimestampError as SharedInvalidPositionAccrualTimestampError, InvalidPositionLossFactorError as SharedInvalidPositionLossFactorError } from "@morpho-org/morpho-ts";
1
2
  import type { Address } from "viem";
2
3
  import type { MempoolPayloadValidationIssue } from "./api/types.js";
3
4
  /**
@@ -70,42 +71,27 @@ export declare class SettlementFeeExceedsPriceError extends Error {
70
71
  /**
71
72
  * Thrown when a local position accrual is requested for an impossible timestamp.
72
73
  *
73
- * @example
74
- * ```ts
75
- * import { InvalidPositionAccrualTimestampError } from "@morpho-org/midnight-sdk";
76
- *
77
- * throw new InvalidPositionAccrualTimestampError(1n, 2n);
78
- * ```
74
+ * @deprecated Import `InvalidPositionAccrualTimestampError` from `@morpho-org/morpho-ts`. Removed in the next major.
79
75
  */
80
- export declare class InvalidPositionAccrualTimestampError extends Error {
81
- constructor(timestamp: bigint, lastAccrual: bigint);
82
- }
76
+ export declare const InvalidPositionAccrualTimestampError: typeof SharedInvalidPositionAccrualTimestampError;
77
+ /** @deprecated Import `InvalidPositionAccrualTimestampError` from `@morpho-org/morpho-ts`. Removed in the next major. */
78
+ export type InvalidPositionAccrualTimestampError = SharedInvalidPositionAccrualTimestampError;
83
79
  /**
84
80
  * Thrown when a local position accrual sees a market loss factor older than the position.
85
81
  *
86
- * @example
87
- * ```ts
88
- * import { InvalidPositionLossFactorError } from "@morpho-org/midnight-sdk";
89
- *
90
- * throw new InvalidPositionLossFactorError(1n, 2n);
91
- * ```
82
+ * @deprecated Import `InvalidPositionLossFactorError` from `@morpho-org/morpho-ts`. Removed in the next major.
92
83
  */
93
- export declare class InvalidPositionLossFactorError extends Error {
94
- constructor(marketLossFactor: bigint, positionLossFactor: bigint);
95
- }
84
+ export declare const InvalidPositionLossFactorError: typeof SharedInvalidPositionLossFactorError;
85
+ /** @deprecated Import `InvalidPositionLossFactorError` from `@morpho-org/morpho-ts`. Removed in the next major. */
86
+ export type InvalidPositionLossFactorError = SharedInvalidPositionLossFactorError;
96
87
  /**
97
88
  * Thrown when local position accrual inputs violate Midnight accounting invariants.
98
89
  *
99
- * @example
100
- * ```ts
101
- * import { InvalidPositionAccrualStateError } from "@morpho-org/midnight-sdk";
102
- *
103
- * throw new InvalidPositionAccrualStateError("Pending fee exceeds credit.");
104
- * ```
90
+ * @deprecated Import `InvalidPositionAccrualStateError` from `@morpho-org/morpho-ts`. Removed in the next major.
105
91
  */
106
- export declare class InvalidPositionAccrualStateError extends Error {
107
- constructor(reason: string);
108
- }
92
+ export declare const InvalidPositionAccrualStateError: typeof SharedInvalidPositionAccrualStateError;
93
+ /** @deprecated Import `InvalidPositionAccrualStateError` from `@morpho-org/morpho-ts`. Removed in the next major. */
94
+ export type InvalidPositionAccrualStateError = SharedInvalidPositionAccrualStateError;
109
95
  /**
110
96
  * Thrown when a market parameter cannot satisfy Midnight protocol rules.
111
97
  *
package/lib/cjs/errors.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InvalidMidnightApiQuoteTargetError = exports.InvalidMidnightApiResponseError = exports.MidnightApiError = exports.InvalidEcrecoverSignatureVError = exports.InvalidTypedDataSignatureError = exports.MidnightMempoolValidationError = exports.ChainIdMismatchError = exports.RatifierV1TakerNotAllowedError = exports.InvalidRatifierV1AddressError = exports.InvalidRateRatifierV1TimeError = exports.InvalidRateRatifierV1TickError = exports.RateRatifierV1BoundOverflowError = exports.InvalidRateRatifierV1RateError = exports.InvalidTreeError = exports.InvalidTreeHeightError = exports.PayloadDecodeError = exports.InvalidOfferParameterError = exports.UnknownCollateralIndexError = exports.InvalidMarketParameterError = exports.InvalidPositionAccrualStateError = exports.InvalidPositionLossFactorError = exports.InvalidPositionAccrualTimestampError = exports.SettlementFeeExceedsPriceError = exports.InvalidTickSpacingError = exports.PriceGreaterThanOneError = exports.TickOutOfRangeError = exports.InvalidOfferGroupError = void 0;
4
+ const morpho_ts_1 = require("@morpho-org/morpho-ts");
4
5
  /**
5
6
  * Thrown when a Midnight offer group violates protocol-level group mechanics.
6
7
  *
@@ -89,57 +90,25 @@ class SettlementFeeExceedsPriceError extends Error {
89
90
  }
90
91
  }
91
92
  exports.SettlementFeeExceedsPriceError = SettlementFeeExceedsPriceError;
93
+ // Temporary compatibility exception for these shared morpho-ts errors.
92
94
  /**
93
95
  * Thrown when a local position accrual is requested for an impossible timestamp.
94
96
  *
95
- * @example
96
- * ```ts
97
- * import { InvalidPositionAccrualTimestampError } from "@morpho-org/midnight-sdk";
98
- *
99
- * throw new InvalidPositionAccrualTimestampError(1n, 2n);
100
- * ```
97
+ * @deprecated Import `InvalidPositionAccrualTimestampError` from `@morpho-org/morpho-ts`. Removed in the next major.
101
98
  */
102
- class InvalidPositionAccrualTimestampError extends Error {
103
- constructor(timestamp, lastAccrual) {
104
- super(`Position accrual timestamp "${timestamp}" is before last accrual "${lastAccrual}". Use a timestamp greater than or equal to last accrual.`);
105
- this.name = "InvalidPositionAccrualTimestampError";
106
- }
107
- }
108
- exports.InvalidPositionAccrualTimestampError = InvalidPositionAccrualTimestampError;
99
+ exports.InvalidPositionAccrualTimestampError = morpho_ts_1.InvalidPositionAccrualTimestampError;
109
100
  /**
110
101
  * Thrown when a local position accrual sees a market loss factor older than the position.
111
102
  *
112
- * @example
113
- * ```ts
114
- * import { InvalidPositionLossFactorError } from "@morpho-org/midnight-sdk";
115
- *
116
- * throw new InvalidPositionLossFactorError(1n, 2n);
117
- * ```
103
+ * @deprecated Import `InvalidPositionLossFactorError` from `@morpho-org/morpho-ts`. Removed in the next major.
118
104
  */
119
- class InvalidPositionLossFactorError extends Error {
120
- constructor(marketLossFactor, positionLossFactor) {
121
- super(`Market loss factor "${marketLossFactor}" is below position loss factor "${positionLossFactor}". Fetch a consistent market and position at the same block.`);
122
- this.name = "InvalidPositionLossFactorError";
123
- }
124
- }
125
- exports.InvalidPositionLossFactorError = InvalidPositionLossFactorError;
105
+ exports.InvalidPositionLossFactorError = morpho_ts_1.InvalidPositionLossFactorError;
126
106
  /**
127
107
  * Thrown when local position accrual inputs violate Midnight accounting invariants.
128
108
  *
129
- * @example
130
- * ```ts
131
- * import { InvalidPositionAccrualStateError } from "@morpho-org/midnight-sdk";
132
- *
133
- * throw new InvalidPositionAccrualStateError("Pending fee exceeds credit.");
134
- * ```
109
+ * @deprecated Import `InvalidPositionAccrualStateError` from `@morpho-org/morpho-ts`. Removed in the next major.
135
110
  */
136
- class InvalidPositionAccrualStateError extends Error {
137
- constructor(reason) {
138
- super(`Invalid Midnight position accrual state. ${reason}`);
139
- this.name = "InvalidPositionAccrualStateError";
140
- }
141
- }
142
- exports.InvalidPositionAccrualStateError = InvalidPositionAccrualStateError;
111
+ exports.InvalidPositionAccrualStateError = morpho_ts_1.InvalidPositionAccrualStateError;
143
112
  /**
144
113
  * Thrown when a market parameter cannot satisfy Midnight protocol rules.
145
114
  *
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PositionUtils = void 0;
4
4
  const morpho_ts_1 = require("@morpho-org/morpho-ts");
5
- const errors_js_1 = require("../errors.js");
6
5
  /**
7
6
  * Domain helpers for Midnight positions.
8
7
  *
@@ -135,40 +134,17 @@ var PositionUtils;
135
134
  */
136
135
  function accrueInterest(params) {
137
136
  const timestamp = BigInt(params.timestamp);
138
- const credit = BigInt(params.position.credit);
139
- const pendingFee = BigInt(params.position.pendingFee);
140
- const lastLossFactor = BigInt(params.position.lastLossFactor);
141
- const lastAccrual = BigInt(params.position.lastAccrual);
142
137
  const marketLossFactor = BigInt(params.market.lossFactor);
143
- if (timestamp < lastAccrual) {
144
- throw new errors_js_1.InvalidPositionAccrualTimestampError(timestamp, lastAccrual);
145
- }
146
- if (marketLossFactor < lastLossFactor) {
147
- throw new errors_js_1.InvalidPositionLossFactorError(marketLossFactor, lastLossFactor);
148
- }
149
- if (pendingFee > credit) {
150
- throw new errors_js_1.InvalidPositionAccrualStateError("Pending fee must be less than or equal to credit.");
151
- }
152
- const postSlashCredit = lastLossFactor < morpho_ts_1.MathLib.MAX_UINT_128
153
- ? morpho_ts_1.MathLib.mulDivDown(credit, morpho_ts_1.MathLib.MAX_UINT_128 - marketLossFactor, morpho_ts_1.MathLib.MAX_UINT_128 - lastLossFactor)
154
- : 0n;
155
- if (postSlashCredit > credit) {
156
- throw new errors_js_1.InvalidPositionAccrualStateError("Post-slash credit cannot exceed stored credit.");
157
- }
158
- const creditDecrease = credit - postSlashCredit;
159
- const pendingFeeDecrease = credit > 0n ? morpho_ts_1.MathLib.mulDivUp(pendingFee, creditDecrease, credit) : 0n;
160
- if (pendingFeeDecrease > pendingFee) {
161
- throw new errors_js_1.InvalidPositionAccrualStateError("Pending-fee decrease cannot exceed pending fee.");
162
- }
163
- const postSlashPendingFee = pendingFee - pendingFeeDecrease;
164
138
  const maturity = BigInt(params.market.params.maturity);
165
- const accrualEnd = timestamp < maturity ? timestamp : maturity;
166
- const accruedFee = lastAccrual < maturity
167
- ? morpho_ts_1.MathLib.mulDivDown(postSlashPendingFee, accrualEnd - lastAccrual, maturity - lastAccrual)
168
- : 0n;
169
- if (accruedFee > postSlashCredit || accruedFee > postSlashPendingFee) {
170
- throw new errors_js_1.InvalidPositionAccrualStateError("Accrued fee cannot exceed post-slash credit or pending fee.");
171
- }
139
+ const { credit, pendingFee, accruedFee } = morpho_ts_1.MidnightPositionLib.accrue({
140
+ credit: params.position.credit,
141
+ pendingFee: params.position.pendingFee,
142
+ lastLossFactor: params.position.lastLossFactor,
143
+ lastAccrual: params.position.lastAccrual,
144
+ marketLossFactor,
145
+ maturity,
146
+ timestamp,
147
+ });
172
148
  const collateral = params.position.collateral.map((assets) => BigInt(assets));
173
149
  const collateralParams = params.market.params.collateralParams.map((collateralParam) => ({
174
150
  token: collateralParam.token,
@@ -199,8 +175,8 @@ var PositionUtils;
199
175
  position: {
200
176
  user: params.position.user,
201
177
  marketId: params.position.marketId,
202
- credit: postSlashCredit - accruedFee,
203
- pendingFee: postSlashPendingFee - accruedFee,
178
+ credit,
179
+ pendingFee,
204
180
  lastLossFactor: marketLossFactor,
205
181
  lastAccrual: timestamp,
206
182
  debt: BigInt(params.position.debt),
@@ -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, or when its caps or buy-side receiver are not executable.
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 signed ABI-ready take caps mapped from the API response.
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, or when its caps or buy-side receiver are not executable.
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, or when its caps or buy-side receiver are not executable.
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 signed ABI-ready take caps mapped from the API response.
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, or when its caps or buy-side receiver are not executable.
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, or when its caps or buy-side receiver are not executable.
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 signed ABI-ready take caps mapped from the API response.
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
- if (averageWorstPrice != null) {
301
- const guard = BigInt(averageWorstPrice);
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, or when its caps or buy-side receiver are not executable.
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, or when its caps or buy-side receiver are not executable.
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 signed ABI-ready take caps mapped from the API response.
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, or when its caps or buy-side receiver are not executable.
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";
@@ -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;
@@ -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}".`);
@@ -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
- /** Effective weighted average-price guard for the returned instructions. */
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.0.0";
2
+ export declare const MIDNIGHT_SDK_VERSION = "2.1.0-next.0";
@@ -1,3 +1,3 @@
1
1
  // Generated by scripts/generate-midnight-package-version.ts. Do not edit.
2
2
  /** @internal Installed Midnight SDK package version. */
3
- export const MIDNIGHT_SDK_VERSION = "2.0.0";
3
+ export const MIDNIGHT_SDK_VERSION = "2.1.0-next.0";
@@ -1,3 +1,4 @@
1
+ import { InvalidPositionAccrualStateError as SharedInvalidPositionAccrualStateError, InvalidPositionAccrualTimestampError as SharedInvalidPositionAccrualTimestampError, InvalidPositionLossFactorError as SharedInvalidPositionLossFactorError } from "@morpho-org/morpho-ts";
1
2
  import type { Address } from "viem";
2
3
  import type { MempoolPayloadValidationIssue } from "./api/types.js";
3
4
  /**
@@ -70,42 +71,27 @@ export declare class SettlementFeeExceedsPriceError extends Error {
70
71
  /**
71
72
  * Thrown when a local position accrual is requested for an impossible timestamp.
72
73
  *
73
- * @example
74
- * ```ts
75
- * import { InvalidPositionAccrualTimestampError } from "@morpho-org/midnight-sdk";
76
- *
77
- * throw new InvalidPositionAccrualTimestampError(1n, 2n);
78
- * ```
74
+ * @deprecated Import `InvalidPositionAccrualTimestampError` from `@morpho-org/morpho-ts`. Removed in the next major.
79
75
  */
80
- export declare class InvalidPositionAccrualTimestampError extends Error {
81
- constructor(timestamp: bigint, lastAccrual: bigint);
82
- }
76
+ export declare const InvalidPositionAccrualTimestampError: typeof SharedInvalidPositionAccrualTimestampError;
77
+ /** @deprecated Import `InvalidPositionAccrualTimestampError` from `@morpho-org/morpho-ts`. Removed in the next major. */
78
+ export type InvalidPositionAccrualTimestampError = SharedInvalidPositionAccrualTimestampError;
83
79
  /**
84
80
  * Thrown when a local position accrual sees a market loss factor older than the position.
85
81
  *
86
- * @example
87
- * ```ts
88
- * import { InvalidPositionLossFactorError } from "@morpho-org/midnight-sdk";
89
- *
90
- * throw new InvalidPositionLossFactorError(1n, 2n);
91
- * ```
82
+ * @deprecated Import `InvalidPositionLossFactorError` from `@morpho-org/morpho-ts`. Removed in the next major.
92
83
  */
93
- export declare class InvalidPositionLossFactorError extends Error {
94
- constructor(marketLossFactor: bigint, positionLossFactor: bigint);
95
- }
84
+ export declare const InvalidPositionLossFactorError: typeof SharedInvalidPositionLossFactorError;
85
+ /** @deprecated Import `InvalidPositionLossFactorError` from `@morpho-org/morpho-ts`. Removed in the next major. */
86
+ export type InvalidPositionLossFactorError = SharedInvalidPositionLossFactorError;
96
87
  /**
97
88
  * Thrown when local position accrual inputs violate Midnight accounting invariants.
98
89
  *
99
- * @example
100
- * ```ts
101
- * import { InvalidPositionAccrualStateError } from "@morpho-org/midnight-sdk";
102
- *
103
- * throw new InvalidPositionAccrualStateError("Pending fee exceeds credit.");
104
- * ```
90
+ * @deprecated Import `InvalidPositionAccrualStateError` from `@morpho-org/morpho-ts`. Removed in the next major.
105
91
  */
106
- export declare class InvalidPositionAccrualStateError extends Error {
107
- constructor(reason: string);
108
- }
92
+ export declare const InvalidPositionAccrualStateError: typeof SharedInvalidPositionAccrualStateError;
93
+ /** @deprecated Import `InvalidPositionAccrualStateError` from `@morpho-org/morpho-ts`. Removed in the next major. */
94
+ export type InvalidPositionAccrualStateError = SharedInvalidPositionAccrualStateError;
109
95
  /**
110
96
  * Thrown when a market parameter cannot satisfy Midnight protocol rules.
111
97
  *
package/lib/esm/errors.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { InvalidPositionAccrualStateError as SharedInvalidPositionAccrualStateError, InvalidPositionAccrualTimestampError as SharedInvalidPositionAccrualTimestampError, InvalidPositionLossFactorError as SharedInvalidPositionLossFactorError, } from "@morpho-org/morpho-ts";
1
2
  /**
2
3
  * Thrown when a Midnight offer group violates protocol-level group mechanics.
3
4
  *
@@ -81,54 +82,25 @@ export class SettlementFeeExceedsPriceError extends Error {
81
82
  this.name = "SettlementFeeExceedsPriceError";
82
83
  }
83
84
  }
85
+ // Temporary compatibility exception for these shared morpho-ts errors.
84
86
  /**
85
87
  * Thrown when a local position accrual is requested for an impossible timestamp.
86
88
  *
87
- * @example
88
- * ```ts
89
- * import { InvalidPositionAccrualTimestampError } from "@morpho-org/midnight-sdk";
90
- *
91
- * throw new InvalidPositionAccrualTimestampError(1n, 2n);
92
- * ```
89
+ * @deprecated Import `InvalidPositionAccrualTimestampError` from `@morpho-org/morpho-ts`. Removed in the next major.
93
90
  */
94
- export class InvalidPositionAccrualTimestampError extends Error {
95
- constructor(timestamp, lastAccrual) {
96
- super(`Position accrual timestamp "${timestamp}" is before last accrual "${lastAccrual}". Use a timestamp greater than or equal to last accrual.`);
97
- this.name = "InvalidPositionAccrualTimestampError";
98
- }
99
- }
91
+ export const InvalidPositionAccrualTimestampError = SharedInvalidPositionAccrualTimestampError;
100
92
  /**
101
93
  * Thrown when a local position accrual sees a market loss factor older than the position.
102
94
  *
103
- * @example
104
- * ```ts
105
- * import { InvalidPositionLossFactorError } from "@morpho-org/midnight-sdk";
106
- *
107
- * throw new InvalidPositionLossFactorError(1n, 2n);
108
- * ```
95
+ * @deprecated Import `InvalidPositionLossFactorError` from `@morpho-org/morpho-ts`. Removed in the next major.
109
96
  */
110
- export class InvalidPositionLossFactorError extends Error {
111
- constructor(marketLossFactor, positionLossFactor) {
112
- super(`Market loss factor "${marketLossFactor}" is below position loss factor "${positionLossFactor}". Fetch a consistent market and position at the same block.`);
113
- this.name = "InvalidPositionLossFactorError";
114
- }
115
- }
97
+ export const InvalidPositionLossFactorError = SharedInvalidPositionLossFactorError;
116
98
  /**
117
99
  * Thrown when local position accrual inputs violate Midnight accounting invariants.
118
100
  *
119
- * @example
120
- * ```ts
121
- * import { InvalidPositionAccrualStateError } from "@morpho-org/midnight-sdk";
122
- *
123
- * throw new InvalidPositionAccrualStateError("Pending fee exceeds credit.");
124
- * ```
101
+ * @deprecated Import `InvalidPositionAccrualStateError` from `@morpho-org/morpho-ts`. Removed in the next major.
125
102
  */
126
- export class InvalidPositionAccrualStateError extends Error {
127
- constructor(reason) {
128
- super(`Invalid Midnight position accrual state. ${reason}`);
129
- this.name = "InvalidPositionAccrualStateError";
130
- }
131
- }
103
+ export const InvalidPositionAccrualStateError = SharedInvalidPositionAccrualStateError;
132
104
  /**
133
105
  * Thrown when a market parameter cannot satisfy Midnight protocol rules.
134
106
  *
@@ -1,5 +1,4 @@
1
- import { MathLib } from "@morpho-org/morpho-ts";
2
- import { InvalidPositionAccrualStateError, InvalidPositionAccrualTimestampError, InvalidPositionLossFactorError, } from "../errors.js";
1
+ import { MathLib, MidnightPositionLib, } from "@morpho-org/morpho-ts";
3
2
  /**
4
3
  * Domain helpers for Midnight positions.
5
4
  *
@@ -132,40 +131,17 @@ export var PositionUtils;
132
131
  */
133
132
  function accrueInterest(params) {
134
133
  const timestamp = BigInt(params.timestamp);
135
- const credit = BigInt(params.position.credit);
136
- const pendingFee = BigInt(params.position.pendingFee);
137
- const lastLossFactor = BigInt(params.position.lastLossFactor);
138
- const lastAccrual = BigInt(params.position.lastAccrual);
139
134
  const marketLossFactor = BigInt(params.market.lossFactor);
140
- if (timestamp < lastAccrual) {
141
- throw new InvalidPositionAccrualTimestampError(timestamp, lastAccrual);
142
- }
143
- if (marketLossFactor < lastLossFactor) {
144
- throw new InvalidPositionLossFactorError(marketLossFactor, lastLossFactor);
145
- }
146
- if (pendingFee > credit) {
147
- throw new InvalidPositionAccrualStateError("Pending fee must be less than or equal to credit.");
148
- }
149
- const postSlashCredit = lastLossFactor < MathLib.MAX_UINT_128
150
- ? MathLib.mulDivDown(credit, MathLib.MAX_UINT_128 - marketLossFactor, MathLib.MAX_UINT_128 - lastLossFactor)
151
- : 0n;
152
- if (postSlashCredit > credit) {
153
- throw new InvalidPositionAccrualStateError("Post-slash credit cannot exceed stored credit.");
154
- }
155
- const creditDecrease = credit - postSlashCredit;
156
- const pendingFeeDecrease = credit > 0n ? MathLib.mulDivUp(pendingFee, creditDecrease, credit) : 0n;
157
- if (pendingFeeDecrease > pendingFee) {
158
- throw new InvalidPositionAccrualStateError("Pending-fee decrease cannot exceed pending fee.");
159
- }
160
- const postSlashPendingFee = pendingFee - pendingFeeDecrease;
161
135
  const maturity = BigInt(params.market.params.maturity);
162
- const accrualEnd = timestamp < maturity ? timestamp : maturity;
163
- const accruedFee = lastAccrual < maturity
164
- ? MathLib.mulDivDown(postSlashPendingFee, accrualEnd - lastAccrual, maturity - lastAccrual)
165
- : 0n;
166
- if (accruedFee > postSlashCredit || accruedFee > postSlashPendingFee) {
167
- throw new InvalidPositionAccrualStateError("Accrued fee cannot exceed post-slash credit or pending fee.");
168
- }
136
+ const { credit, pendingFee, accruedFee } = MidnightPositionLib.accrue({
137
+ credit: params.position.credit,
138
+ pendingFee: params.position.pendingFee,
139
+ lastLossFactor: params.position.lastLossFactor,
140
+ lastAccrual: params.position.lastAccrual,
141
+ marketLossFactor,
142
+ maturity,
143
+ timestamp,
144
+ });
169
145
  const collateral = params.position.collateral.map((assets) => BigInt(assets));
170
146
  const collateralParams = params.market.params.collateralParams.map((collateralParam) => ({
171
147
  token: collateralParam.token,
@@ -196,8 +172,8 @@ export var PositionUtils;
196
172
  position: {
197
173
  user: params.position.user,
198
174
  marketId: params.position.marketId,
199
- credit: postSlashCredit - accruedFee,
200
- pendingFee: postSlashPendingFee - accruedFee,
175
+ credit,
176
+ pendingFee,
201
177
  lastLossFactor: marketLossFactor,
202
178
  lastAccrual: timestamp,
203
179
  debt: BigInt(params.position.debt),
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.0.0",
4
+ "version": "2.1.0-next.0",
5
5
  "author": "Morpho Association <contact@morpho.org>",
6
6
  "repository": {
7
7
  "type": "git",
@@ -41,12 +41,12 @@
41
41
  "MIGRATION-v1-to-v2.md"
42
42
  ],
43
43
  "peerDependencies": {
44
- "@morpho-org/morpho-ts": "^2.8.0 || ^3.0.0 || ^4.0.0",
44
+ "@morpho-org/morpho-ts": "^4.1.0-0",
45
45
  "viem": "^2.0.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@morpho-org/morpho-ts": "^4.0.0",
49
- "@morpho-org/test": "^2.10.1",
48
+ "@morpho-org/morpho-ts": "^4.1.0-next.0",
49
+ "@morpho-org/test": "^2.11.0-next.0",
50
50
  "fast-check": "^4.9.0",
51
51
  "typescript": "7.0.2",
52
52
  "viem": "^2.55.10",