@morpho-org/midnight-sdk 1.5.1-next.0 → 1.7.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.
- 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.js +1 -1
- 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/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.js +1 -1
- 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/package.json +3 -6
|
@@ -65,9 +65,9 @@ export declare class MidnightApi {
|
|
|
65
65
|
* @param params.baseUrl - Optional Midnight API base URL override.
|
|
66
66
|
* @param params.fetch - Optional fetch implementation override.
|
|
67
67
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
68
|
-
* @returns Paginated books mapped to SDK camelCase fields.
|
|
68
|
+
* @returns Paginated books mapped to SDK camelCase fields, with each book's price levels sorted best first (asks ascending tick, bids descending tick).
|
|
69
69
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
70
|
-
* @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`
|
|
70
|
+
* @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.
|
|
71
71
|
* @example
|
|
72
72
|
* ```ts
|
|
73
73
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -90,7 +90,7 @@ export declare class MidnightApi {
|
|
|
90
90
|
* @param params.baseUrl - Optional Midnight API base URL override.
|
|
91
91
|
* @param params.fetch - Optional fetch implementation override.
|
|
92
92
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
93
|
-
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
93
|
+
* @returns Book snapshot mapped to SDK camelCase fields, with price levels sorted best first (asks ascending tick, bids descending tick).
|
|
94
94
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
95
95
|
* @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`.
|
|
96
96
|
* @example
|
|
@@ -115,7 +115,7 @@ export declare class MidnightApi {
|
|
|
115
115
|
* @param params.baseUrl - Optional Midnight API base URL override.
|
|
116
116
|
* @param params.fetch - Optional fetch implementation override.
|
|
117
117
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
118
|
-
* @returns Price levels mapped to SDK camelCase fields.
|
|
118
|
+
* @returns Price levels mapped to SDK camelCase fields, sorted best first (asks ascending tick, bids descending tick).
|
|
119
119
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
120
120
|
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
121
121
|
* @example
|
|
@@ -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.
|
|
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.
|
|
146
146
|
* @example
|
|
147
147
|
* ```ts
|
|
148
148
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -171,9 +171,10 @@ export declare class MidnightApi {
|
|
|
171
171
|
* @param params.fetch - Optional fetch implementation override.
|
|
172
172
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
173
173
|
* @returns Quote and signed ABI-ready take caps mapped from the API response.
|
|
174
|
+
* @throws {InvalidMidnightApiQuoteTargetError} when the runtime input does not set exactly one of `units` or `assets`.
|
|
174
175
|
* @throws {NegativeValueError} when `settlementFee` is negative.
|
|
175
176
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
176
|
-
* @throws {InvalidMidnightApiResponseError} when the API
|
|
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.
|
|
177
178
|
* @throws {SettlementFeeExceedsPriceError} when a bid's settlement fee exceeds its offer price.
|
|
178
179
|
* @example
|
|
179
180
|
* ```ts
|
|
@@ -204,7 +205,7 @@ export declare class MidnightApi {
|
|
|
204
205
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
205
206
|
* @returns Paginated ABI-ready take objects mapped from the API response.
|
|
206
207
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
207
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
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.
|
|
208
209
|
* @example
|
|
209
210
|
* ```ts
|
|
210
211
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -321,9 +322,9 @@ export declare class MidnightApi {
|
|
|
321
322
|
* @param params.marketIds - Optional market id filters.
|
|
322
323
|
* @param params.limit - Optional maximum number of books to return.
|
|
323
324
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
324
|
-
* @returns Paginated books mapped to SDK camelCase fields.
|
|
325
|
+
* @returns Paginated books mapped to SDK camelCase fields, with each book's price levels sorted best first (asks ascending tick, bids descending tick).
|
|
325
326
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
326
|
-
* @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`
|
|
327
|
+
* @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.
|
|
327
328
|
* @example
|
|
328
329
|
* ```ts
|
|
329
330
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -341,7 +342,7 @@ export declare class MidnightApi {
|
|
|
341
342
|
*
|
|
342
343
|
* @param params.marketId - Market id whose book to read.
|
|
343
344
|
* @param params.depth - Optional maximum levels returned per side.
|
|
344
|
-
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
345
|
+
* @returns Book snapshot mapped to SDK camelCase fields, with price levels sorted best first (asks ascending tick, bids descending tick).
|
|
345
346
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
346
347
|
* @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`.
|
|
347
348
|
* @example
|
|
@@ -364,7 +365,7 @@ export declare class MidnightApi {
|
|
|
364
365
|
* @param params.marketId - Market id whose book side to read.
|
|
365
366
|
* @param params.side - Book side to query.
|
|
366
367
|
* @param params.depth - Optional maximum levels returned.
|
|
367
|
-
* @returns Price levels mapped to SDK camelCase fields.
|
|
368
|
+
* @returns Price levels mapped to SDK camelCase fields, sorted best first (asks ascending tick, bids descending tick).
|
|
368
369
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
369
370
|
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
370
371
|
* @example
|
|
@@ -389,7 +390,7 @@ export declare class MidnightApi {
|
|
|
389
390
|
* @param params.side - Book side to query.
|
|
390
391
|
* @returns ABI-ready take objects mapped from the API response.
|
|
391
392
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
392
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
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.
|
|
393
394
|
* @example
|
|
394
395
|
* ```ts
|
|
395
396
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -416,9 +417,10 @@ export declare class MidnightApi {
|
|
|
416
417
|
* @param params.slippage - Optional slippage percentage used to derive the guard. Mutually exclusive with `params.averageWorstPrice`.
|
|
417
418
|
* @param params.settlementFee - Optional current WAD-scaled settlement fee used for local guard validation. Defaults to zero.
|
|
418
419
|
* @returns Quote and signed ABI-ready take caps mapped from the API response.
|
|
420
|
+
* @throws {InvalidMidnightApiQuoteTargetError} when the runtime input does not set exactly one of `units` or `assets`.
|
|
419
421
|
* @throws {NegativeValueError} when `settlementFee` is negative.
|
|
420
422
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
421
|
-
* @throws {InvalidMidnightApiResponseError} when the API
|
|
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.
|
|
422
424
|
* @throws {SettlementFeeExceedsPriceError} when a bid's settlement fee exceeds its offer price.
|
|
423
425
|
* @example
|
|
424
426
|
* ```ts
|
|
@@ -446,7 +448,7 @@ export declare class MidnightApi {
|
|
|
446
448
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
447
449
|
* @returns Paginated ABI-ready take objects mapped from the API response.
|
|
448
450
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
449
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
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.
|
|
450
452
|
* @example
|
|
451
453
|
* ```ts
|
|
452
454
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -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-next.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
|
+
}
|
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;
|
|
@@ -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.
|
package/lib/esm/offers/Offer.js
CHANGED
|
@@ -476,7 +476,7 @@ export class Offer {
|
|
|
476
476
|
* @param params.tickSpacing - Optional market tick spacing; defaults to `DEFAULT_TICK_SPACING`.
|
|
477
477
|
* @param params.maxUnits - Optional unit cap; defaults to zero.
|
|
478
478
|
* @param params.maxAssets - Optional buyer or seller asset cap; defaults to zero.
|
|
479
|
-
* @param params.continuousFeeCap - Optional maximum market continuous fee accepted by this offer; defaults to `
|
|
479
|
+
* @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).
|
|
480
480
|
* @param params.start - Optional offer start timestamp; defaults to zero.
|
|
481
481
|
* @param params.expiry - Offer expiry timestamp.
|
|
482
482
|
* @param params.callback - Optional callback address; defaults to the zero address.
|