@morpho-org/midnight-sdk 1.6.0 → 1.7.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 +16 -14
- package/lib/cjs/api/MidnightApi.js +26 -16
- package/lib/cjs/api/helpers.d.ts +14 -2
- package/lib/cjs/api/helpers.js +71 -11
- package/lib/cjs/api/index.d.ts +1 -1
- package/lib/cjs/api/index.js +2 -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/errors.d.ts +13 -0
- package/lib/cjs/errors.js +18 -1
- package/lib/cjs/market/Market.d.ts +6 -30
- package/lib/cjs/market/Market.js +7 -31
- package/lib/cjs/market/MarketUtils.d.ts +14 -0
- package/lib/cjs/market/MarketUtils.js +17 -1
- package/lib/cjs/offers/Offer.d.ts +1 -1
- package/lib/cjs/offers/Offer.js +1 -1
- package/lib/cjs/offers/OfferChainUtils.d.ts +6 -2
- package/lib/cjs/offers/OfferChainUtils.js +6 -2
- package/lib/cjs/position/Position.d.ts +5 -25
- package/lib/cjs/position/Position.js +5 -25
- package/lib/esm/api/MidnightApi.d.ts +16 -14
- package/lib/esm/api/MidnightApi.js +28 -18
- package/lib/esm/api/helpers.d.ts +14 -2
- package/lib/esm/api/helpers.js +71 -12
- package/lib/esm/api/index.d.ts +1 -1
- package/lib/esm/api/index.js +1 -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/errors.d.ts +13 -0
- package/lib/esm/errors.js +16 -0
- package/lib/esm/market/Market.d.ts +6 -30
- package/lib/esm/market/Market.js +7 -31
- package/lib/esm/market/MarketUtils.d.ts +14 -0
- package/lib/esm/market/MarketUtils.js +18 -2
- package/lib/esm/offers/Offer.d.ts +1 -1
- package/lib/esm/offers/Offer.js +1 -1
- package/lib/esm/offers/OfferChainUtils.d.ts +6 -2
- package/lib/esm/offers/OfferChainUtils.js +6 -2
- package/lib/esm/position/Position.d.ts +5 -25
- package/lib/esm/position/Position.js +5 -25
- package/package.json +3 -6
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { assertNonNegative, MathLib } from "@morpho-org/morpho-ts";
|
|
2
|
-
import { InvalidMidnightApiResponseError } from "../errors.js";
|
|
2
|
+
import { InvalidMidnightApiQuoteTargetError, InvalidMidnightApiResponseError, } from "../errors.js";
|
|
3
3
|
import { TakeAmountsLib } from "../math/index.js";
|
|
4
4
|
import { Payload } from "../signatures/Payload.js";
|
|
5
|
-
import { buildBookPath, mapBoundBookMarket, mapBoundBooks, mapBoundTakeableOffers,
|
|
5
|
+
import { buildBookPath, mapBoundBookMarket, mapBoundBooks, mapBoundTakeableOffers, mapPriceLevels, parseValidationResponse, requestMidnightApi, } from "./helpers.js";
|
|
6
6
|
export { MempoolPayloadValidationRule } from "./types.js";
|
|
7
7
|
/**
|
|
8
8
|
* Midnight API client and stateless helper surface for books and mempool data.
|
|
@@ -73,9 +73,9 @@ export class MidnightApi {
|
|
|
73
73
|
* @param params.baseUrl - Optional Midnight API base URL override.
|
|
74
74
|
* @param params.fetch - Optional fetch implementation override.
|
|
75
75
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
76
|
-
* @returns Paginated books mapped to SDK camelCase fields.
|
|
76
|
+
* @returns Paginated books mapped to SDK camelCase fields, with each book's price levels sorted best first (asks ascending tick, bids descending tick).
|
|
77
77
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
78
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned book's `market_id` does not match, or cannot be derived from, its own market params, or when a returned book falls outside the supplied `marketIds`
|
|
78
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned book's `market_id` does not match, or cannot be derived from, its own market params, or when a returned book falls outside the supplied `marketIds`, `chainIds`, `loanTokens`, `collateralTokens`, or `maturities` filters.
|
|
79
79
|
* @example
|
|
80
80
|
* ```ts
|
|
81
81
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -106,7 +106,13 @@ export class MidnightApi {
|
|
|
106
106
|
});
|
|
107
107
|
return {
|
|
108
108
|
cursor: response.cursor,
|
|
109
|
-
data: mapBoundBooks(response.data,
|
|
109
|
+
data: mapBoundBooks(response.data, {
|
|
110
|
+
marketIds: input.marketIds,
|
|
111
|
+
chainIds: input.chainIds,
|
|
112
|
+
loanTokens: input.loanTokens,
|
|
113
|
+
collateralTokens: input.collateralTokens,
|
|
114
|
+
maturities: input.maturities,
|
|
115
|
+
}),
|
|
110
116
|
};
|
|
111
117
|
}
|
|
112
118
|
/**
|
|
@@ -119,7 +125,7 @@ export class MidnightApi {
|
|
|
119
125
|
* @param params.baseUrl - Optional Midnight API base URL override.
|
|
120
126
|
* @param params.fetch - Optional fetch implementation override.
|
|
121
127
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
122
|
-
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
128
|
+
* @returns Book snapshot mapped to SDK camelCase fields, with price levels sorted best first (asks ascending tick, bids descending tick).
|
|
123
129
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
124
130
|
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when the returned book's `market_id` does not match, or cannot be derived from, its own market params, or when it differs from the requested `marketId`.
|
|
125
131
|
* @example
|
|
@@ -157,7 +163,7 @@ export class MidnightApi {
|
|
|
157
163
|
* @param params.baseUrl - Optional Midnight API base URL override.
|
|
158
164
|
* @param params.fetch - Optional fetch implementation override.
|
|
159
165
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
160
|
-
* @returns Price levels mapped to SDK camelCase fields.
|
|
166
|
+
* @returns Price levels mapped to SDK camelCase fields, sorted best first (asks ascending tick, bids descending tick).
|
|
161
167
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
162
168
|
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
163
169
|
* @example
|
|
@@ -182,7 +188,7 @@ export class MidnightApi {
|
|
|
182
188
|
},
|
|
183
189
|
});
|
|
184
190
|
return {
|
|
185
|
-
data: response.data.
|
|
191
|
+
data: mapPriceLevels(response.data, input.side),
|
|
186
192
|
};
|
|
187
193
|
}
|
|
188
194
|
/**
|
|
@@ -197,7 +203,7 @@ export class MidnightApi {
|
|
|
197
203
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
198
204
|
* @returns ABI-ready take objects mapped from the API response.
|
|
199
205
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
200
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
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.
|
|
201
207
|
* @example
|
|
202
208
|
* ```ts
|
|
203
209
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -243,9 +249,10 @@ export class MidnightApi {
|
|
|
243
249
|
* @param params.fetch - Optional fetch implementation override.
|
|
244
250
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
245
251
|
* @returns Quote and signed ABI-ready take caps mapped from the API response.
|
|
252
|
+
* @throws {InvalidMidnightApiQuoteTargetError} when the runtime input does not set exactly one of `units` or `assets`.
|
|
246
253
|
* @throws {NegativeValueError} when `settlementFee` is negative.
|
|
247
254
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
248
|
-
* @throws {InvalidMidnightApiResponseError} when the API
|
|
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.
|
|
249
256
|
* @throws {SettlementFeeExceedsPriceError} when a bid's settlement fee exceeds its offer price.
|
|
250
257
|
* @example
|
|
251
258
|
* ```ts
|
|
@@ -262,6 +269,8 @@ export class MidnightApi {
|
|
|
262
269
|
*/
|
|
263
270
|
static async fetchBookQuote(params) {
|
|
264
271
|
const input = params;
|
|
272
|
+
if ((input.units == null) === (input.assets == null))
|
|
273
|
+
throw new InvalidMidnightApiQuoteTargetError();
|
|
265
274
|
const settlementFee = BigInt(input.settlementFee ?? 0n);
|
|
266
275
|
assertNonNegative("settlementFee", settlementFee);
|
|
267
276
|
const response = await requestMidnightApi({
|
|
@@ -368,7 +377,7 @@ export class MidnightApi {
|
|
|
368
377
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
369
378
|
* @returns Paginated ABI-ready take objects mapped from the API response.
|
|
370
379
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
371
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
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.
|
|
372
381
|
* @example
|
|
373
382
|
* ```ts
|
|
374
383
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -533,9 +542,9 @@ export class MidnightApi {
|
|
|
533
542
|
* @param params.marketIds - Optional market id filters.
|
|
534
543
|
* @param params.limit - Optional maximum number of books to return.
|
|
535
544
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
536
|
-
* @returns Paginated books mapped to SDK camelCase fields.
|
|
545
|
+
* @returns Paginated books mapped to SDK camelCase fields, with each book's price levels sorted best first (asks ascending tick, bids descending tick).
|
|
537
546
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
538
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned book's `market_id` does not match, or cannot be derived from, its own market params, or when a returned book falls outside the supplied `marketIds`
|
|
547
|
+
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when a returned book's `market_id` does not match, or cannot be derived from, its own market params, or when a returned book falls outside the supplied `marketIds`, `chainIds`, `loanTokens`, `collateralTokens`, or `maturities` filters.
|
|
539
548
|
* @example
|
|
540
549
|
* ```ts
|
|
541
550
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -558,7 +567,7 @@ export class MidnightApi {
|
|
|
558
567
|
*
|
|
559
568
|
* @param params.marketId - Market id whose book to read.
|
|
560
569
|
* @param params.depth - Optional maximum levels returned per side.
|
|
561
|
-
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
570
|
+
* @returns Book snapshot mapped to SDK camelCase fields, with price levels sorted best first (asks ascending tick, bids descending tick).
|
|
562
571
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
563
572
|
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON, when the returned book's `market_id` does not match, or cannot be derived from, its own market params, or when it differs from the requested `marketId`.
|
|
564
573
|
* @example
|
|
@@ -586,7 +595,7 @@ export class MidnightApi {
|
|
|
586
595
|
* @param params.marketId - Market id whose book side to read.
|
|
587
596
|
* @param params.side - Book side to query.
|
|
588
597
|
* @param params.depth - Optional maximum levels returned.
|
|
589
|
-
* @returns Price levels mapped to SDK camelCase fields.
|
|
598
|
+
* @returns Price levels mapped to SDK camelCase fields, sorted best first (asks ascending tick, bids descending tick).
|
|
590
599
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
591
600
|
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
592
601
|
* @example
|
|
@@ -616,7 +625,7 @@ export class MidnightApi {
|
|
|
616
625
|
* @param params.side - Book side to query.
|
|
617
626
|
* @returns ABI-ready take objects mapped from the API response.
|
|
618
627
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
619
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
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.
|
|
620
629
|
* @example
|
|
621
630
|
* ```ts
|
|
622
631
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -648,9 +657,10 @@ export class MidnightApi {
|
|
|
648
657
|
* @param params.slippage - Optional slippage percentage used to derive the guard. Mutually exclusive with `params.averageWorstPrice`.
|
|
649
658
|
* @param params.settlementFee - Optional current WAD-scaled settlement fee used for local guard validation. Defaults to zero.
|
|
650
659
|
* @returns Quote and signed ABI-ready take caps mapped from the API response.
|
|
660
|
+
* @throws {InvalidMidnightApiQuoteTargetError} when the runtime input does not set exactly one of `units` or `assets`.
|
|
651
661
|
* @throws {NegativeValueError} when `settlementFee` is negative.
|
|
652
662
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
653
|
-
* @throws {InvalidMidnightApiResponseError} when the API
|
|
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.
|
|
654
664
|
* @throws {SettlementFeeExceedsPriceError} when a bid's settlement fee exceeds its offer price.
|
|
655
665
|
* @example
|
|
656
666
|
* ```ts
|
|
@@ -683,7 +693,7 @@ export class MidnightApi {
|
|
|
683
693
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
684
694
|
* @returns Paginated ABI-ready take objects mapped from the API response.
|
|
685
695
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
686
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
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.
|
|
687
697
|
* @example
|
|
688
698
|
* ```ts
|
|
689
699
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
package/lib/esm/api/helpers.d.ts
CHANGED
|
@@ -14,16 +14,28 @@ export declare function buildBookPath(params: {
|
|
|
14
14
|
* its own market params. Recomputing the id with `MarketUtils.toId` (mirroring the
|
|
15
15
|
* takeable-offers path) stops a hostile API from pairing a trusted id with foreign
|
|
16
16
|
* metadata; every book flows through here, so both bound paths reject the same substitution.
|
|
17
|
+
* Collaterals are returned in the protocol's canonical order so their array index matches
|
|
18
|
+
* the onchain `collateralIndex`.
|
|
17
19
|
*/
|
|
18
20
|
export declare function mapBookMarket(book: ApiBookMarketResponse): MidnightApiBookMarket;
|
|
19
21
|
/** @internal Maps a book market, binding its verified id to the requested market. */
|
|
20
22
|
export declare function mapBoundBookMarket(book: ApiBookMarketResponse, requestedMarketId: Hash): MidnightApiBookMarket;
|
|
21
|
-
/** @internal
|
|
22
|
-
export
|
|
23
|
+
/** @internal Requested `fetchBooks` filters that every returned book must satisfy. */
|
|
24
|
+
export interface BookFilterContext {
|
|
25
|
+
readonly marketIds?: readonly Hash[];
|
|
26
|
+
readonly chainIds?: readonly number[];
|
|
27
|
+
readonly loanTokens?: readonly Address[];
|
|
28
|
+
readonly collateralTokens?: readonly Address[];
|
|
29
|
+
readonly maturities?: readonly number[];
|
|
30
|
+
}
|
|
31
|
+
/** @internal Maps listed book markets, binding each verified id to requested filters when present. */
|
|
32
|
+
export declare function mapBoundBooks(books: readonly ApiBookMarketResponse[], context?: BookFilterContext): MidnightApiBookMarket[];
|
|
23
33
|
/** @internal Maps a collateral API payload to the SDK response shape. */
|
|
24
34
|
export declare function mapCollateral(collateral: ApiCollateralResponse): MidnightApiCollateral;
|
|
25
35
|
/** @internal Maps a price-level API payload to the SDK response shape. */
|
|
26
36
|
export declare function mapPriceLevel(level: ApiPriceLevelResponse): MidnightApiPriceLevel;
|
|
37
|
+
/** @internal Maps API price levels and sorts them best first: asks by ascending tick, bids by descending tick. */
|
|
38
|
+
export declare function mapPriceLevels(levels: readonly ApiPriceLevelResponse[], side: MidnightApiBookSide): MidnightApiPriceLevel[];
|
|
27
39
|
/** @internal Maps a takeable-offer API payload to the SDK response shape. */
|
|
28
40
|
export declare function mapTakeableOffer(takeableOffer: ApiTakeableOfferResponse): MidnightApiTake;
|
|
29
41
|
/** @internal API response context required for a takeable offer to be executable for the caller's request. */
|
package/lib/esm/api/helpers.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BLUE_API_BASE_URL, isHexEqual } from "@morpho-org/morpho-ts";
|
|
2
2
|
import { isAddress, isAddressEqual, maxUint256, } from "viem";
|
|
3
|
-
import { InvalidMidnightApiResponseError, MidnightApiError, } from "../errors.js";
|
|
3
|
+
import { InvalidMidnightApiResponseError, InvalidOfferParameterError, MidnightApiError, } from "../errors.js";
|
|
4
4
|
import { MarketUtils } from "../market/index.js";
|
|
5
|
+
import { OfferUtils } from "../offers/index.js";
|
|
5
6
|
import { MempoolPayloadValidationRule, } from "./types.js";
|
|
6
7
|
import { MIDNIGHT_SDK_VERSION } from "./version.generated.js";
|
|
7
8
|
const DEFAULT_MIDNIGHT_API_URL = new URL("/v0/midnight", BLUE_API_BASE_URL);
|
|
@@ -86,6 +87,8 @@ export function buildBookPath(params) {
|
|
|
86
87
|
* its own market params. Recomputing the id with `MarketUtils.toId` (mirroring the
|
|
87
88
|
* takeable-offers path) stops a hostile API from pairing a trusted id with foreign
|
|
88
89
|
* metadata; every book flows through here, so both bound paths reject the same substitution.
|
|
90
|
+
* Collaterals are returned in the protocol's canonical order so their array index matches
|
|
91
|
+
* the onchain `collateralIndex`.
|
|
89
92
|
*/
|
|
90
93
|
export function mapBookMarket(book) {
|
|
91
94
|
let derivedMarketId;
|
|
@@ -121,13 +124,15 @@ export function mapBookMarket(book) {
|
|
|
121
124
|
chainId: book.chain_id,
|
|
122
125
|
midnight: book.midnight,
|
|
123
126
|
loanToken: book.loan_token,
|
|
124
|
-
collaterals: book.collaterals
|
|
127
|
+
collaterals: [...book.collaterals]
|
|
128
|
+
.sort(MarketUtils.compareCollateralTokens)
|
|
129
|
+
.map(mapCollateral),
|
|
125
130
|
maturity: book.maturity,
|
|
126
131
|
rcfThreshold: book.rcf_threshold,
|
|
127
132
|
enterGate: book.enter_gate,
|
|
128
133
|
liquidatorGate: book.liquidator_gate,
|
|
129
|
-
asks: book.asks
|
|
130
|
-
bids: book.bids
|
|
134
|
+
asks: mapPriceLevels(book.asks, "asks"),
|
|
135
|
+
bids: mapPriceLevels(book.bids, "bids"),
|
|
131
136
|
};
|
|
132
137
|
}
|
|
133
138
|
/** @internal Maps a book market, binding its verified id to the requested market. */
|
|
@@ -138,15 +143,36 @@ export function mapBoundBookMarket(book, requestedMarketId) {
|
|
|
138
143
|
}
|
|
139
144
|
return market;
|
|
140
145
|
}
|
|
141
|
-
/** @internal Maps listed book markets, binding each verified id to
|
|
142
|
-
export function mapBoundBooks(books,
|
|
146
|
+
/** @internal Maps listed book markets, binding each verified id to requested filters when present. */
|
|
147
|
+
export function mapBoundBooks(books, context = {}) {
|
|
143
148
|
return books.map((book) => {
|
|
144
149
|
const market = mapBookMarket(book);
|
|
145
|
-
if (marketIds != null &&
|
|
146
|
-
marketIds.length > 0 &&
|
|
147
|
-
!marketIds.some((marketId) => isHexEqual(marketId, market.marketId))) {
|
|
150
|
+
if (context.marketIds != null &&
|
|
151
|
+
context.marketIds.length > 0 &&
|
|
152
|
+
!context.marketIds.some((marketId) => isHexEqual(marketId, market.marketId))) {
|
|
148
153
|
throw new InvalidMidnightApiResponseError(`Midnight API book market_id "${market.marketId}" is outside the requested market_ids filter.`);
|
|
149
154
|
}
|
|
155
|
+
if (context.chainIds != null &&
|
|
156
|
+
context.chainIds.length > 0 &&
|
|
157
|
+
!context.chainIds.includes(market.chainId)) {
|
|
158
|
+
throw new InvalidMidnightApiResponseError(`Midnight API book market_id "${market.marketId}" is outside the requested chain_ids filter.`);
|
|
159
|
+
}
|
|
160
|
+
if (context.loanTokens != null &&
|
|
161
|
+
context.loanTokens.length > 0 &&
|
|
162
|
+
!context.loanTokens.some((token) => isAddressEqual(token, market.loanToken))) {
|
|
163
|
+
throw new InvalidMidnightApiResponseError(`Midnight API book market_id "${market.marketId}" is outside the requested loan_tokens filter.`);
|
|
164
|
+
}
|
|
165
|
+
const { collateralTokens } = context;
|
|
166
|
+
if (collateralTokens != null &&
|
|
167
|
+
collateralTokens.length > 0 &&
|
|
168
|
+
!market.collaterals.some((collateral) => collateralTokens.some((token) => isAddressEqual(token, collateral.token)))) {
|
|
169
|
+
throw new InvalidMidnightApiResponseError(`Midnight API book market_id "${market.marketId}" is outside the requested collateral_tokens filter.`);
|
|
170
|
+
}
|
|
171
|
+
if (context.maturities != null &&
|
|
172
|
+
context.maturities.length > 0 &&
|
|
173
|
+
!context.maturities.includes(market.maturity)) {
|
|
174
|
+
throw new InvalidMidnightApiResponseError(`Midnight API book market_id "${market.marketId}" is outside the requested maturities filter.`);
|
|
175
|
+
}
|
|
150
176
|
return market;
|
|
151
177
|
});
|
|
152
178
|
}
|
|
@@ -169,6 +195,12 @@ export function mapPriceLevel(level) {
|
|
|
169
195
|
count: level.count,
|
|
170
196
|
};
|
|
171
197
|
}
|
|
198
|
+
/** @internal Maps API price levels and sorts them best first: asks by ascending tick, bids by descending tick. */
|
|
199
|
+
export function mapPriceLevels(levels, side) {
|
|
200
|
+
return levels
|
|
201
|
+
.map(mapPriceLevel)
|
|
202
|
+
.sort((a, b) => (side === "asks" ? a.tick - b.tick : b.tick - a.tick));
|
|
203
|
+
}
|
|
172
204
|
/** @internal Maps a takeable-offer API payload to the SDK response shape. */
|
|
173
205
|
export function mapTakeableOffer(takeableOffer) {
|
|
174
206
|
const offer = takeableOffer.offer;
|
|
@@ -212,11 +244,38 @@ export function mapTakeableOffer(takeableOffer) {
|
|
|
212
244
|
/** @internal Maps, validates, and best-price-sorts API takeable offers. */
|
|
213
245
|
export function mapBoundTakeableOffers(takeableOffers, context) {
|
|
214
246
|
const mapped = takeableOffers.map((takeableOffer) => {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
247
|
+
let take;
|
|
248
|
+
let matchesAdvertisedId;
|
|
249
|
+
let embeddedMarketId;
|
|
250
|
+
try {
|
|
251
|
+
take = mapTakeableOffer(takeableOffer);
|
|
252
|
+
embeddedMarketId = MarketUtils.toId(take.offer.market);
|
|
253
|
+
matchesAdvertisedId = isHexEqual(embeddedMarketId, take.marketId);
|
|
254
|
+
}
|
|
255
|
+
catch (cause) {
|
|
256
|
+
throw new InvalidMidnightApiResponseError(`Midnight API takeable offer market_id "${takeableOffer.market_id}" could not be mapped or validated against its embedded offer market.`, { cause });
|
|
257
|
+
}
|
|
258
|
+
if (!matchesAdvertisedId) {
|
|
218
259
|
throw new InvalidMidnightApiResponseError(`Midnight API takeable offer market_id "${take.marketId}" does not match embedded offer market "${embeddedMarketId}".`);
|
|
219
260
|
}
|
|
261
|
+
const { maxUnits, maxAssets, buy, maker, receiverIfMakerIsSeller } = take.offer;
|
|
262
|
+
if (!isAddress(receiverIfMakerIsSeller)) {
|
|
263
|
+
throw new InvalidMidnightApiResponseError(`Midnight API takeable offer receiverIfMakerIsSeller "${receiverIfMakerIsSeller}" is not an address.`);
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
// Return values unused: called only to enforce the cap-shape and buy-receiver invariants.
|
|
267
|
+
OfferUtils.validateOfferCaps({ maxUnits, maxAssets });
|
|
268
|
+
OfferUtils.resolveReceiverIfMakerIsSeller({
|
|
269
|
+
buy,
|
|
270
|
+
maker,
|
|
271
|
+
receiverIfMakerIsSeller,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
catch (cause) {
|
|
275
|
+
if (!(cause instanceof InvalidOfferParameterError))
|
|
276
|
+
throw cause;
|
|
277
|
+
throw new InvalidMidnightApiResponseError(`Midnight API takeable offer for market_id "${take.marketId}" is not executable: ${cause.message}`, { cause });
|
|
278
|
+
}
|
|
220
279
|
if (context.marketId != null &&
|
|
221
280
|
!isHexEqual(take.marketId, context.marketId)) {
|
|
222
281
|
throw new InvalidMidnightApiResponseError(`Midnight API takeable offer market_id "${take.marketId}" does not match requested market "${context.marketId}".`);
|
package/lib/esm/api/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { InvalidMidnightApiResponseError, MidnightApiError, } from "../errors.js";
|
|
1
|
+
export { InvalidMidnightApiQuoteTargetError, InvalidMidnightApiResponseError, MidnightApiError, } from "../errors.js";
|
|
2
2
|
export * from "./MidnightApi.js";
|
package/lib/esm/api/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { InvalidMidnightApiResponseError, MidnightApiError, } from "../errors.js";
|
|
1
|
+
export { InvalidMidnightApiQuoteTargetError, InvalidMidnightApiResponseError, MidnightApiError, } from "../errors.js";
|
|
2
2
|
export * from "./MidnightApi.js";
|
package/lib/esm/api/types.d.ts
CHANGED
|
@@ -341,7 +341,7 @@ export interface MidnightApiBookMarket {
|
|
|
341
341
|
readonly midnight: Address;
|
|
342
342
|
/** Loan token address. */
|
|
343
343
|
readonly loanToken: Address;
|
|
344
|
-
/** Collateral definitions for the market. */
|
|
344
|
+
/** Collateral definitions for the market, in canonical `collateralIndex` order. */
|
|
345
345
|
readonly collaterals: readonly MidnightApiCollateral[];
|
|
346
346
|
/** Market maturity timestamp in unix seconds. */
|
|
347
347
|
readonly maturity: number;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal Installed Midnight SDK package version. */
|
|
2
|
-
export declare const MIDNIGHT_SDK_VERSION = "1.
|
|
2
|
+
export declare const MIDNIGHT_SDK_VERSION = "1.7.0";
|
package/lib/esm/errors.d.ts
CHANGED
|
@@ -339,3 +339,16 @@ export declare class MidnightApiError extends Error {
|
|
|
339
339
|
export declare class InvalidMidnightApiResponseError extends Error {
|
|
340
340
|
constructor(message: string, options?: ErrorOptions);
|
|
341
341
|
}
|
|
342
|
+
/**
|
|
343
|
+
* Thrown when a Midnight API quote request does not target exactly one of `units` or `assets`.
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```ts
|
|
347
|
+
* import { InvalidMidnightApiQuoteTargetError } from "@morpho-org/midnight-sdk/api";
|
|
348
|
+
*
|
|
349
|
+
* throw new InvalidMidnightApiQuoteTargetError();
|
|
350
|
+
* ```
|
|
351
|
+
*/
|
|
352
|
+
export declare class InvalidMidnightApiQuoteTargetError extends Error {
|
|
353
|
+
constructor(options?: ErrorOptions);
|
|
354
|
+
}
|
package/lib/esm/errors.js
CHANGED
|
@@ -395,3 +395,19 @@ export class InvalidMidnightApiResponseError extends Error {
|
|
|
395
395
|
this.name = "InvalidMidnightApiResponseError";
|
|
396
396
|
}
|
|
397
397
|
}
|
|
398
|
+
/**
|
|
399
|
+
* Thrown when a Midnight API quote request does not target exactly one of `units` or `assets`.
|
|
400
|
+
*
|
|
401
|
+
* @example
|
|
402
|
+
* ```ts
|
|
403
|
+
* import { InvalidMidnightApiQuoteTargetError } from "@morpho-org/midnight-sdk/api";
|
|
404
|
+
*
|
|
405
|
+
* throw new InvalidMidnightApiQuoteTargetError();
|
|
406
|
+
* ```
|
|
407
|
+
*/
|
|
408
|
+
export class InvalidMidnightApiQuoteTargetError extends Error {
|
|
409
|
+
constructor(options) {
|
|
410
|
+
super("Midnight API quote requires exactly one of `units` or `assets`. Provide a single target amount.", options);
|
|
411
|
+
this.name = "InvalidMidnightApiQuoteTargetError";
|
|
412
|
+
}
|
|
413
|
+
}
|
|
@@ -292,11 +292,7 @@ export type MarketInput = IMarketParams | IMarket;
|
|
|
292
292
|
* registerCustomAddresses({
|
|
293
293
|
* addresses: {
|
|
294
294
|
* 31337: {
|
|
295
|
-
*
|
|
296
|
-
* bundler3: {
|
|
297
|
-
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
298
|
-
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
299
|
-
* },
|
|
295
|
+
* blue: "0x0000000000000000000000000000000000000001",
|
|
300
296
|
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
301
297
|
* midnight: "0x0000000000000000000000000000000000001000",
|
|
302
298
|
* },
|
|
@@ -412,11 +408,7 @@ export declare class Market {
|
|
|
412
408
|
* registerCustomAddresses({
|
|
413
409
|
* addresses: {
|
|
414
410
|
* 31337: {
|
|
415
|
-
*
|
|
416
|
-
* bundler3: {
|
|
417
|
-
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
418
|
-
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
419
|
-
* },
|
|
411
|
+
* blue: "0x0000000000000000000000000000000000000001",
|
|
420
412
|
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
421
413
|
* midnight: "0x0000000000000000000000000000000000001000",
|
|
422
414
|
* },
|
|
@@ -467,11 +459,7 @@ export declare class Market {
|
|
|
467
459
|
* registerCustomAddresses({
|
|
468
460
|
* addresses: {
|
|
469
461
|
* 31337: {
|
|
470
|
-
*
|
|
471
|
-
* bundler3: {
|
|
472
|
-
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
473
|
-
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
474
|
-
* },
|
|
462
|
+
* blue: "0x0000000000000000000000000000000000000001",
|
|
475
463
|
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
476
464
|
* midnight: "0x0000000000000000000000000000000000001000",
|
|
477
465
|
* },
|
|
@@ -522,11 +510,7 @@ export declare class Market {
|
|
|
522
510
|
* registerCustomAddresses({
|
|
523
511
|
* addresses: {
|
|
524
512
|
* 31337: {
|
|
525
|
-
*
|
|
526
|
-
* bundler3: {
|
|
527
|
-
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
528
|
-
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
529
|
-
* },
|
|
513
|
+
* blue: "0x0000000000000000000000000000000000000001",
|
|
530
514
|
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
531
515
|
* midnight: "0x0000000000000000000000000000000000001000",
|
|
532
516
|
* },
|
|
@@ -577,11 +561,7 @@ export declare class Market {
|
|
|
577
561
|
* registerCustomAddresses({
|
|
578
562
|
* addresses: {
|
|
579
563
|
* 31337: {
|
|
580
|
-
*
|
|
581
|
-
* bundler3: {
|
|
582
|
-
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
583
|
-
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
584
|
-
* },
|
|
564
|
+
* blue: "0x0000000000000000000000000000000000000001",
|
|
585
565
|
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
586
566
|
* midnight: "0x0000000000000000000000000000000000001000",
|
|
587
567
|
* },
|
|
@@ -633,11 +613,7 @@ export declare class Market {
|
|
|
633
613
|
* registerCustomAddresses({
|
|
634
614
|
* addresses: {
|
|
635
615
|
* 31337: {
|
|
636
|
-
*
|
|
637
|
-
* bundler3: {
|
|
638
|
-
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
639
|
-
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
640
|
-
* },
|
|
616
|
+
* blue: "0x0000000000000000000000000000000000000001",
|
|
641
617
|
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
642
618
|
* midnight: "0x0000000000000000000000000000000000001000",
|
|
643
619
|
* },
|
package/lib/esm/market/Market.js
CHANGED
|
@@ -132,7 +132,7 @@ export class MarketParams {
|
|
|
132
132
|
}
|
|
133
133
|
seenCollateralTokens.add(token);
|
|
134
134
|
}
|
|
135
|
-
this.collateralParams = collateralParams.sort(
|
|
135
|
+
this.collateralParams = collateralParams.sort(MarketUtils.compareCollateralTokens);
|
|
136
136
|
this.maturity = BigInt(params.maturity);
|
|
137
137
|
this.rcfThreshold = BigInt(params.rcfThreshold);
|
|
138
138
|
this.enterGate = params.enterGate;
|
|
@@ -187,11 +187,7 @@ export class MarketParams {
|
|
|
187
187
|
* registerCustomAddresses({
|
|
188
188
|
* addresses: {
|
|
189
189
|
* 31337: {
|
|
190
|
-
*
|
|
191
|
-
* bundler3: {
|
|
192
|
-
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
193
|
-
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
194
|
-
* },
|
|
190
|
+
* blue: "0x0000000000000000000000000000000000000001",
|
|
195
191
|
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
196
192
|
* midnight: "0x0000000000000000000000000000000000001000",
|
|
197
193
|
* },
|
|
@@ -320,11 +316,7 @@ export class Market {
|
|
|
320
316
|
* registerCustomAddresses({
|
|
321
317
|
* addresses: {
|
|
322
318
|
* 31337: {
|
|
323
|
-
*
|
|
324
|
-
* bundler3: {
|
|
325
|
-
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
326
|
-
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
327
|
-
* },
|
|
319
|
+
* blue: "0x0000000000000000000000000000000000000001",
|
|
328
320
|
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
329
321
|
* midnight: "0x0000000000000000000000000000000000001000",
|
|
330
322
|
* },
|
|
@@ -381,11 +373,7 @@ export class Market {
|
|
|
381
373
|
* registerCustomAddresses({
|
|
382
374
|
* addresses: {
|
|
383
375
|
* 31337: {
|
|
384
|
-
*
|
|
385
|
-
* bundler3: {
|
|
386
|
-
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
387
|
-
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
388
|
-
* },
|
|
376
|
+
* blue: "0x0000000000000000000000000000000000000001",
|
|
389
377
|
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
390
378
|
* midnight: "0x0000000000000000000000000000000000001000",
|
|
391
379
|
* },
|
|
@@ -441,11 +429,7 @@ export class Market {
|
|
|
441
429
|
* registerCustomAddresses({
|
|
442
430
|
* addresses: {
|
|
443
431
|
* 31337: {
|
|
444
|
-
*
|
|
445
|
-
* bundler3: {
|
|
446
|
-
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
447
|
-
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
448
|
-
* },
|
|
432
|
+
* blue: "0x0000000000000000000000000000000000000001",
|
|
449
433
|
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
450
434
|
* midnight: "0x0000000000000000000000000000000000001000",
|
|
451
435
|
* },
|
|
@@ -498,11 +482,7 @@ export class Market {
|
|
|
498
482
|
* registerCustomAddresses({
|
|
499
483
|
* addresses: {
|
|
500
484
|
* 31337: {
|
|
501
|
-
*
|
|
502
|
-
* bundler3: {
|
|
503
|
-
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
504
|
-
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
505
|
-
* },
|
|
485
|
+
* blue: "0x0000000000000000000000000000000000000001",
|
|
506
486
|
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
507
487
|
* midnight: "0x0000000000000000000000000000000000001000",
|
|
508
488
|
* },
|
|
@@ -558,11 +538,7 @@ export class Market {
|
|
|
558
538
|
* registerCustomAddresses({
|
|
559
539
|
* addresses: {
|
|
560
540
|
* 31337: {
|
|
561
|
-
*
|
|
562
|
-
* bundler3: {
|
|
563
|
-
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
564
|
-
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
565
|
-
* },
|
|
541
|
+
* blue: "0x0000000000000000000000000000000000000001",
|
|
566
542
|
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
567
543
|
* midnight: "0x0000000000000000000000000000000000001000",
|
|
568
544
|
* },
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type BigIntish } from "@morpho-org/morpho-ts";
|
|
2
|
+
import { type Address } from "viem";
|
|
2
3
|
import { type CollateralParams, type ICollateralParams, type MarketInput, MarketParams, type SettlementFeeCbps } from "./Market.js";
|
|
3
4
|
type CollateralParamsInput = ICollateralParams | CollateralParams;
|
|
4
5
|
/**
|
|
@@ -12,6 +13,19 @@ type CollateralParamsInput = ICollateralParams | CollateralParams;
|
|
|
12
13
|
* ```
|
|
13
14
|
*/
|
|
14
15
|
export declare namespace MarketUtils {
|
|
16
|
+
/**
|
|
17
|
+
* @internal Orders collaterals by token address, case-insensitively, matching the protocol's
|
|
18
|
+
* canonical `collateralIndex` order used by `MarketParams` and `MarketUtils.hash`.
|
|
19
|
+
*
|
|
20
|
+
* @param a - First collateral.
|
|
21
|
+
* @param b - Second collateral.
|
|
22
|
+
* @returns Negative when `a` sorts before `b`, positive when after, `0` when tokens are equal.
|
|
23
|
+
*/
|
|
24
|
+
function compareCollateralTokens(a: {
|
|
25
|
+
readonly token: Address;
|
|
26
|
+
}, b: {
|
|
27
|
+
readonly token: Address;
|
|
28
|
+
}): -1 | 0 | 1;
|
|
15
29
|
/**
|
|
16
30
|
* Converts collateral params from a plain input or ABI tuple.
|
|
17
31
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assertNonNegative, MathLib, } from "@morpho-org/morpho-ts";
|
|
2
|
-
import { concat, encodeAbiParameters, encodePacked, keccak256 } from "viem";
|
|
2
|
+
import { concat, encodeAbiParameters, encodePacked, keccak256, } from "viem";
|
|
3
3
|
import { CBP, COLLATERAL_PARAMS_TYPEHASH, MARKET_TYPEHASH, SETTLEMENT_FEE_BREAKPOINTS, } from "../constants.js";
|
|
4
4
|
import { InvalidMarketParameterError, UnknownCollateralIndexError, } from "../errors.js";
|
|
5
5
|
import { MarketParams, } from "./Market.js";
|
|
@@ -56,6 +56,22 @@ const marketParamsAbiParameter = {
|
|
|
56
56
|
*/
|
|
57
57
|
export var MarketUtils;
|
|
58
58
|
(function (MarketUtils) {
|
|
59
|
+
/**
|
|
60
|
+
* @internal Orders collaterals by token address, case-insensitively, matching the protocol's
|
|
61
|
+
* canonical `collateralIndex` order used by `MarketParams` and `MarketUtils.hash`.
|
|
62
|
+
*
|
|
63
|
+
* @param a - First collateral.
|
|
64
|
+
* @param b - Second collateral.
|
|
65
|
+
* @returns Negative when `a` sorts before `b`, positive when after, `0` when tokens are equal.
|
|
66
|
+
*/
|
|
67
|
+
function compareCollateralTokens(a, b) {
|
|
68
|
+
const tokenA = a.token.toLowerCase();
|
|
69
|
+
const tokenB = b.token.toLowerCase();
|
|
70
|
+
if (tokenA === tokenB)
|
|
71
|
+
return 0;
|
|
72
|
+
return tokenA < tokenB ? -1 : 1;
|
|
73
|
+
}
|
|
74
|
+
MarketUtils.compareCollateralTokens = compareCollateralTokens;
|
|
59
75
|
/**
|
|
60
76
|
* Converts collateral params from a plain input or ABI tuple.
|
|
61
77
|
*
|
|
@@ -299,7 +315,7 @@ export var MarketUtils;
|
|
|
299
315
|
const marketParams = "params" in market ? market.params : market;
|
|
300
316
|
const collateralParams = marketParams.collateralParams.length === 0
|
|
301
317
|
? marketParams.collateralParams
|
|
302
|
-
: [...marketParams.collateralParams].sort(
|
|
318
|
+
: [...marketParams.collateralParams].sort(compareCollateralTokens);
|
|
303
319
|
const collateralParamHashes = collateralParams.map((params) => keccak256(encodeAbiParameters(collateralParamsHashParams, [
|
|
304
320
|
COLLATERAL_PARAMS_TYPEHASH,
|
|
305
321
|
params.token,
|
|
@@ -526,7 +526,7 @@ export declare class Offer {
|
|
|
526
526
|
* @param params.tickSpacing - Optional market tick spacing; defaults to `DEFAULT_TICK_SPACING`.
|
|
527
527
|
* @param params.maxUnits - Optional unit cap; defaults to zero.
|
|
528
528
|
* @param params.maxAssets - Optional buyer or seller asset cap; defaults to zero.
|
|
529
|
-
* @param params.continuousFeeCap - Optional maximum market continuous fee accepted by this offer; defaults to `
|
|
529
|
+
* @param params.continuousFeeCap - Optional maximum market continuous fee accepted by this offer; defaults to `0n` (fail-closed: no market continuous fee accepted unless set explicitly).
|
|
530
530
|
* @param params.start - Optional offer start timestamp; defaults to zero.
|
|
531
531
|
* @param params.expiry - Offer expiry timestamp.
|
|
532
532
|
* @param params.callback - Optional callback address; defaults to the zero address.
|