@morpho-org/midnight-sdk 1.3.0 → 1.3.1
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 +4 -4
- package/lib/cjs/api/MidnightApi.js +6 -6
- package/lib/cjs/api/helpers.d.ts +11 -1
- package/lib/cjs/api/helpers.js +57 -1
- package/lib/cjs/api/version.generated.d.ts +1 -1
- package/lib/cjs/api/version.generated.js +1 -1
- package/lib/cjs/fetch/utils.d.ts +1 -1
- package/lib/cjs/signatures/EcrecoverRatifierUtils.d.ts +1 -1
- package/lib/esm/api/MidnightApi.d.ts +4 -4
- package/lib/esm/api/MidnightApi.js +7 -7
- package/lib/esm/api/helpers.d.ts +11 -1
- package/lib/esm/api/helpers.js +55 -1
- package/lib/esm/api/version.generated.d.ts +1 -1
- package/lib/esm/api/version.generated.js +1 -1
- package/lib/esm/fetch/utils.d.ts +1 -1
- package/lib/esm/signatures/EcrecoverRatifierUtils.d.ts +1 -1
- package/package.json +8 -8
|
@@ -67,7 +67,7 @@ export declare class MidnightApi {
|
|
|
67
67
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
68
68
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
69
69
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
70
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
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` filter.
|
|
71
71
|
* @example
|
|
72
72
|
* ```ts
|
|
73
73
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -92,7 +92,7 @@ export declare class MidnightApi {
|
|
|
92
92
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
93
93
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
94
94
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
95
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON
|
|
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
|
|
97
97
|
* ```ts
|
|
98
98
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -320,7 +320,7 @@ export declare class MidnightApi {
|
|
|
320
320
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
321
321
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
322
322
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
323
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
323
|
+
* @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` filter.
|
|
324
324
|
* @example
|
|
325
325
|
* ```ts
|
|
326
326
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -340,7 +340,7 @@ export declare class MidnightApi {
|
|
|
340
340
|
* @param params.depth - Optional maximum levels returned per side.
|
|
341
341
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
342
342
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
343
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON
|
|
343
|
+
* @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`.
|
|
344
344
|
* @example
|
|
345
345
|
* ```ts
|
|
346
346
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -79,7 +79,7 @@ class MidnightApi {
|
|
|
79
79
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
80
80
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
81
81
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
82
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
82
|
+
* @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` filter.
|
|
83
83
|
* @example
|
|
84
84
|
* ```ts
|
|
85
85
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -110,7 +110,7 @@ class MidnightApi {
|
|
|
110
110
|
});
|
|
111
111
|
return {
|
|
112
112
|
cursor: response.cursor,
|
|
113
|
-
data: response.data.
|
|
113
|
+
data: (0, helpers_js_1.mapBoundBooks)(response.data, input.marketIds),
|
|
114
114
|
};
|
|
115
115
|
}
|
|
116
116
|
/**
|
|
@@ -125,7 +125,7 @@ class MidnightApi {
|
|
|
125
125
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
126
126
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
127
127
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
128
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON
|
|
128
|
+
* @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`.
|
|
129
129
|
* @example
|
|
130
130
|
* ```ts
|
|
131
131
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -147,7 +147,7 @@ class MidnightApi {
|
|
|
147
147
|
},
|
|
148
148
|
});
|
|
149
149
|
return {
|
|
150
|
-
data: (0, helpers_js_1.
|
|
150
|
+
data: (0, helpers_js_1.mapBoundBookMarket)(response.data, input.marketId),
|
|
151
151
|
};
|
|
152
152
|
}
|
|
153
153
|
/**
|
|
@@ -525,7 +525,7 @@ class MidnightApi {
|
|
|
525
525
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
526
526
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
527
527
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
528
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
528
|
+
* @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` filter.
|
|
529
529
|
* @example
|
|
530
530
|
* ```ts
|
|
531
531
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -550,7 +550,7 @@ class MidnightApi {
|
|
|
550
550
|
* @param params.depth - Optional maximum levels returned per side.
|
|
551
551
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
552
552
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
553
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON
|
|
553
|
+
* @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`.
|
|
554
554
|
* @example
|
|
555
555
|
* ```ts
|
|
556
556
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
package/lib/cjs/api/helpers.d.ts
CHANGED
|
@@ -8,8 +8,18 @@ export declare function buildBookPath(params: {
|
|
|
8
8
|
readonly side?: MidnightApiBookSide;
|
|
9
9
|
readonly suffix?: "quote" | "takeable-offers";
|
|
10
10
|
}): string;
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* @internal Maps a book market API payload to the SDK response shape, rejecting any
|
|
13
|
+
* response whose advertised `market_id` cannot be derived from — or does not match —
|
|
14
|
+
* its own market params. Recomputing the id with `MarketUtils.toId` (mirroring the
|
|
15
|
+
* takeable-offers path) stops a hostile API from pairing a trusted id with foreign
|
|
16
|
+
* metadata; every book flows through here, so both bound paths reject the same substitution.
|
|
17
|
+
*/
|
|
12
18
|
export declare function mapBookMarket(book: ApiBookMarketResponse): MidnightApiBookMarket;
|
|
19
|
+
/** @internal Maps a book market, binding its verified id to the requested market. */
|
|
20
|
+
export declare function mapBoundBookMarket(book: ApiBookMarketResponse, requestedMarketId: Hash): MidnightApiBookMarket;
|
|
21
|
+
/** @internal Maps listed book markets, binding each verified id to the requested market_ids filter when present. */
|
|
22
|
+
export declare function mapBoundBooks(books: readonly ApiBookMarketResponse[], marketIds?: readonly Hash[]): MidnightApiBookMarket[];
|
|
13
23
|
/** @internal Maps a collateral API payload to the SDK response shape. */
|
|
14
24
|
export declare function mapCollateral(collateral: ApiCollateralResponse): MidnightApiCollateral;
|
|
15
25
|
/** @internal Maps a price-level API payload to the SDK response shape. */
|
package/lib/cjs/api/helpers.js
CHANGED
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.requestMidnightApi = requestMidnightApi;
|
|
4
4
|
exports.buildBookPath = buildBookPath;
|
|
5
5
|
exports.mapBookMarket = mapBookMarket;
|
|
6
|
+
exports.mapBoundBookMarket = mapBoundBookMarket;
|
|
7
|
+
exports.mapBoundBooks = mapBoundBooks;
|
|
6
8
|
exports.mapCollateral = mapCollateral;
|
|
7
9
|
exports.mapPriceLevel = mapPriceLevel;
|
|
8
10
|
exports.mapTakeableOffer = mapTakeableOffer;
|
|
@@ -90,8 +92,42 @@ function buildBookPath(params) {
|
|
|
90
92
|
].filter((segment) => segment !== undefined);
|
|
91
93
|
return segments.map(encodeURIComponent).join("/");
|
|
92
94
|
}
|
|
93
|
-
/**
|
|
95
|
+
/**
|
|
96
|
+
* @internal Maps a book market API payload to the SDK response shape, rejecting any
|
|
97
|
+
* response whose advertised `market_id` cannot be derived from — or does not match —
|
|
98
|
+
* its own market params. Recomputing the id with `MarketUtils.toId` (mirroring the
|
|
99
|
+
* takeable-offers path) stops a hostile API from pairing a trusted id with foreign
|
|
100
|
+
* metadata; every book flows through here, so both bound paths reject the same substitution.
|
|
101
|
+
*/
|
|
94
102
|
function mapBookMarket(book) {
|
|
103
|
+
let derivedMarketId;
|
|
104
|
+
let matchesAdvertisedId;
|
|
105
|
+
try {
|
|
106
|
+
derivedMarketId = index_js_1.MarketUtils.toId({
|
|
107
|
+
chainId: book.chain_id,
|
|
108
|
+
midnight: book.midnight,
|
|
109
|
+
loanToken: book.loan_token,
|
|
110
|
+
collateralParams: book.collaterals.map((collateral) => ({
|
|
111
|
+
token: collateral.token,
|
|
112
|
+
lltv: collateral.lltv,
|
|
113
|
+
liquidationCursor: collateral.liquidation_cursor,
|
|
114
|
+
oracle: collateral.oracle,
|
|
115
|
+
})),
|
|
116
|
+
maturity: book.maturity,
|
|
117
|
+
rcfThreshold: book.rcf_threshold,
|
|
118
|
+
enterGate: book.enter_gate,
|
|
119
|
+
liquidatorGate: book.liquidator_gate,
|
|
120
|
+
});
|
|
121
|
+
// Comparison stays inside the try so a malformed advertised `market_id`
|
|
122
|
+
// (non-hex value) surfaces as a wrapped response error, not a raw TypeError.
|
|
123
|
+
matchesAdvertisedId = (0, morpho_ts_1.isHexEqual)(derivedMarketId, book.market_id);
|
|
124
|
+
}
|
|
125
|
+
catch (cause) {
|
|
126
|
+
throw new errors_js_1.InvalidMidnightApiResponseError(`Midnight API book market_id "${book.market_id}" could not be validated against its market params.`, { cause });
|
|
127
|
+
}
|
|
128
|
+
if (!matchesAdvertisedId) {
|
|
129
|
+
throw new errors_js_1.InvalidMidnightApiResponseError(`Midnight API book market_id "${book.market_id}" does not match the id "${derivedMarketId}" derived from its market params.`);
|
|
130
|
+
}
|
|
95
131
|
return {
|
|
96
132
|
marketId: book.market_id,
|
|
97
133
|
chainId: book.chain_id,
|
|
@@ -106,6 +142,26 @@ function mapBookMarket(book) {
|
|
|
106
142
|
bids: book.bids.map(mapPriceLevel),
|
|
107
143
|
};
|
|
108
144
|
}
|
|
145
|
+
/** @internal Maps a book market, binding its verified id to the requested market. */
|
|
146
|
+
function mapBoundBookMarket(book, requestedMarketId) {
|
|
147
|
+
const market = mapBookMarket(book);
|
|
148
|
+
if (!(0, morpho_ts_1.isHexEqual)(market.marketId, requestedMarketId)) {
|
|
149
|
+
throw new errors_js_1.InvalidMidnightApiResponseError(`Midnight API book market_id "${market.marketId}" does not match requested market "${requestedMarketId}".`);
|
|
150
|
+
}
|
|
151
|
+
return market;
|
|
152
|
+
}
|
|
153
|
+
/** @internal Maps listed book markets, binding each verified id to the requested market_ids filter when present. */
|
|
154
|
+
function mapBoundBooks(books, marketIds) {
|
|
155
|
+
return books.map((book) => {
|
|
156
|
+
const market = mapBookMarket(book);
|
|
157
|
+
if (marketIds != null &&
|
|
158
|
+
marketIds.length > 0 &&
|
|
159
|
+
!marketIds.some((marketId) => (0, morpho_ts_1.isHexEqual)(marketId, market.marketId))) {
|
|
160
|
+
throw new errors_js_1.InvalidMidnightApiResponseError(`Midnight API book market_id "${market.marketId}" is outside the requested market_ids filter.`);
|
|
161
|
+
}
|
|
162
|
+
return market;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
109
165
|
/** @internal Maps a collateral API payload to the SDK response shape. */
|
|
110
166
|
function mapCollateral(collateral) {
|
|
111
167
|
return {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal Installed Midnight SDK package version. */
|
|
2
|
-
export declare const MIDNIGHT_SDK_VERSION = "1.3.
|
|
2
|
+
export declare const MIDNIGHT_SDK_VERSION = "1.3.1";
|
package/lib/cjs/fetch/utils.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ import type { DeploylessFetchParameters, MidnightCallParameters } from "./types.
|
|
|
3
3
|
/** @internal Extracts viem call parameters from Midnight fetch inputs. */
|
|
4
4
|
export declare const callParameters: (params: MidnightCallParameters) => MidnightCallParameters;
|
|
5
5
|
/** @internal Returns the configured deployless mode, defaulting to enabled. */
|
|
6
|
-
export declare const shouldUseDeployless: (params: DeploylessFetchParameters) =>
|
|
6
|
+
export declare const shouldUseDeployless: (params: DeploylessFetchParameters) => "force" | boolean;
|
|
7
7
|
/** @internal Returns the RPC chain id and rejects configured-chain drift. */
|
|
8
8
|
export declare const resolveChainId: (client: Client) => Promise<number>;
|
|
@@ -434,7 +434,7 @@ export declare namespace EcrecoverRatifierUtils {
|
|
|
434
434
|
* console.log(EcrecoverRatifierUtils.treeTypeHash(0));
|
|
435
435
|
* ```
|
|
436
436
|
*/
|
|
437
|
-
function treeTypeHash(height: number): "
|
|
437
|
+
function treeTypeHash(height: number): "0x0754209b60d99d0822b3ecd5a970f9db09df9c8998a8441e24b81f06d6c76fee" | "0x15bd6e2aa1a7a61614187ac16d2cbf8610c8f2f3c3d9eaa380ae7a501ee3cf06" | "0x1608d5eb56943c667c34b413f9f8a1c24a84ddfe1301a9c25487e638de1f5822" | "0x270da1ebafc0f24637af3612fb8c3a1d828fcb56d3637c24e86dd006b12ca7f9" | "0x3a677100d2e855c24a62d1e9c365bff90d02287f066a07064843ca1ee70ea113" | "0x4fa4f16f09f0c36c7670449a4032073380d28a60071e12ee8874bb3e5a8318fc" | "0x5400a5d43d39e6bfe910af8cb84ac77bf501d310413769dffd62ccecda8b00c6" | "0x5801c07a6c7df039ce00a7a2b8bd92aa1cf333c30b0bc3d78768590b6063d09e" | "0x817bbaac8bb863670f488b454cdd5d0990d9d81871a68e9df381c3c13d3f2ba2" | "0x828b9cdf8326a1cf234328e4d5229546a98fb72ef73624f5b6b31538e555b96c" | "0xa47534c85ac57c583568465d40fd46683d2d558d8129fe1aca01e93023afca92" | "0xb1e841691fb54f4ef85e2ed9de45d610e57f49e1e6eb2510ceead16e447dd519" | "0xb726cb7fab1a24c28213cbd482fa5a301f127fb25feb01da341919983a72711a" | "0xc447f06079bddf4b011523c4bce119e9e90fdf937de4ee88f48010406560e9c1" | "0xc9da7190eaf4b14c7cb1c14f9898256c0adb6b1dc303afe79594dea64fe199c0" | "0xcc97cb1955496a5269b5a7afca62ba694edcab26ba838a1adbd257931249de92" | "0xcea9cd557c6f821868ea287304199d0e0554af630bfa8fe36c64eb3bbacca418" | "0xda3feb08db360ad9e09540132ff04d2b6a596fdaa4747892217aaa4c7c9bcc31" | "0xf5d561d88647c3b38ed6636709d3166819fc66f8ed52a0daf4ae186387b4646c" | "0xf7dbde8234e8e345cec8fc0a8ac5909ee336b214882751ecd51e7b37df4f6cdd" | "0xfcb7a3ca4094246b8185620c4cf025c93032b6f0384805aa3f22afe04290e982";
|
|
438
438
|
/**
|
|
439
439
|
* Builds EcrecoverRatifier typed data for a tree-like input.
|
|
440
440
|
*
|
|
@@ -67,7 +67,7 @@ export declare class MidnightApi {
|
|
|
67
67
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
68
68
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
69
69
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
70
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
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` filter.
|
|
71
71
|
* @example
|
|
72
72
|
* ```ts
|
|
73
73
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -92,7 +92,7 @@ export declare class MidnightApi {
|
|
|
92
92
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
93
93
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
94
94
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
95
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON
|
|
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
|
|
97
97
|
* ```ts
|
|
98
98
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -320,7 +320,7 @@ export declare class MidnightApi {
|
|
|
320
320
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
321
321
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
322
322
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
323
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
323
|
+
* @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` filter.
|
|
324
324
|
* @example
|
|
325
325
|
* ```ts
|
|
326
326
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -340,7 +340,7 @@ export declare class MidnightApi {
|
|
|
340
340
|
* @param params.depth - Optional maximum levels returned per side.
|
|
341
341
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
342
342
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
343
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON
|
|
343
|
+
* @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`.
|
|
344
344
|
* @example
|
|
345
345
|
* ```ts
|
|
346
346
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -2,7 +2,7 @@ import { MathLib } from "@morpho-org/morpho-ts";
|
|
|
2
2
|
import { InvalidMidnightApiResponseError } from "../errors.js";
|
|
3
3
|
import { TickLib } from "../math/index.js";
|
|
4
4
|
import { Payload } from "../signatures/Payload.js";
|
|
5
|
-
import { buildBookPath,
|
|
5
|
+
import { buildBookPath, mapBoundBookMarket, mapBoundBooks, mapBoundTakeableOffers, mapPriceLevel, 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.
|
|
@@ -75,7 +75,7 @@ export class MidnightApi {
|
|
|
75
75
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
76
76
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
77
77
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
78
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
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` filter.
|
|
79
79
|
* @example
|
|
80
80
|
* ```ts
|
|
81
81
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -106,7 +106,7 @@ export class MidnightApi {
|
|
|
106
106
|
});
|
|
107
107
|
return {
|
|
108
108
|
cursor: response.cursor,
|
|
109
|
-
data: response.data.
|
|
109
|
+
data: mapBoundBooks(response.data, input.marketIds),
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
@@ -121,7 +121,7 @@ export class MidnightApi {
|
|
|
121
121
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
122
122
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
123
123
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
124
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON
|
|
124
|
+
* @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
125
|
* @example
|
|
126
126
|
* ```ts
|
|
127
127
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -143,7 +143,7 @@ export class MidnightApi {
|
|
|
143
143
|
},
|
|
144
144
|
});
|
|
145
145
|
return {
|
|
146
|
-
data:
|
|
146
|
+
data: mapBoundBookMarket(response.data, input.marketId),
|
|
147
147
|
};
|
|
148
148
|
}
|
|
149
149
|
/**
|
|
@@ -521,7 +521,7 @@ export class MidnightApi {
|
|
|
521
521
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
522
522
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
523
523
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
524
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON.
|
|
524
|
+
* @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` filter.
|
|
525
525
|
* @example
|
|
526
526
|
* ```ts
|
|
527
527
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -546,7 +546,7 @@ export class MidnightApi {
|
|
|
546
546
|
* @param params.depth - Optional maximum levels returned per side.
|
|
547
547
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
548
548
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
549
|
-
* @throws {InvalidMidnightApiResponseError} when the API success response is not JSON
|
|
549
|
+
* @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`.
|
|
550
550
|
* @example
|
|
551
551
|
* ```ts
|
|
552
552
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
package/lib/esm/api/helpers.d.ts
CHANGED
|
@@ -8,8 +8,18 @@ export declare function buildBookPath(params: {
|
|
|
8
8
|
readonly side?: MidnightApiBookSide;
|
|
9
9
|
readonly suffix?: "quote" | "takeable-offers";
|
|
10
10
|
}): string;
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* @internal Maps a book market API payload to the SDK response shape, rejecting any
|
|
13
|
+
* response whose advertised `market_id` cannot be derived from — or does not match —
|
|
14
|
+
* its own market params. Recomputing the id with `MarketUtils.toId` (mirroring the
|
|
15
|
+
* takeable-offers path) stops a hostile API from pairing a trusted id with foreign
|
|
16
|
+
* metadata; every book flows through here, so both bound paths reject the same substitution.
|
|
17
|
+
*/
|
|
12
18
|
export declare function mapBookMarket(book: ApiBookMarketResponse): MidnightApiBookMarket;
|
|
19
|
+
/** @internal Maps a book market, binding its verified id to the requested market. */
|
|
20
|
+
export declare function mapBoundBookMarket(book: ApiBookMarketResponse, requestedMarketId: Hash): MidnightApiBookMarket;
|
|
21
|
+
/** @internal Maps listed book markets, binding each verified id to the requested market_ids filter when present. */
|
|
22
|
+
export declare function mapBoundBooks(books: readonly ApiBookMarketResponse[], marketIds?: readonly Hash[]): MidnightApiBookMarket[];
|
|
13
23
|
/** @internal Maps a collateral API payload to the SDK response shape. */
|
|
14
24
|
export declare function mapCollateral(collateral: ApiCollateralResponse): MidnightApiCollateral;
|
|
15
25
|
/** @internal Maps a price-level API payload to the SDK response shape. */
|
package/lib/esm/api/helpers.js
CHANGED
|
@@ -80,8 +80,42 @@ export function buildBookPath(params) {
|
|
|
80
80
|
].filter((segment) => segment !== undefined);
|
|
81
81
|
return segments.map(encodeURIComponent).join("/");
|
|
82
82
|
}
|
|
83
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* @internal Maps a book market API payload to the SDK response shape, rejecting any
|
|
85
|
+
* response whose advertised `market_id` cannot be derived from — or does not match —
|
|
86
|
+
* its own market params. Recomputing the id with `MarketUtils.toId` (mirroring the
|
|
87
|
+
* takeable-offers path) stops a hostile API from pairing a trusted id with foreign
|
|
88
|
+
* metadata; every book flows through here, so both bound paths reject the same substitution.
|
|
89
|
+
*/
|
|
84
90
|
export function mapBookMarket(book) {
|
|
91
|
+
let derivedMarketId;
|
|
92
|
+
let matchesAdvertisedId;
|
|
93
|
+
try {
|
|
94
|
+
derivedMarketId = MarketUtils.toId({
|
|
95
|
+
chainId: book.chain_id,
|
|
96
|
+
midnight: book.midnight,
|
|
97
|
+
loanToken: book.loan_token,
|
|
98
|
+
collateralParams: book.collaterals.map((collateral) => ({
|
|
99
|
+
token: collateral.token,
|
|
100
|
+
lltv: collateral.lltv,
|
|
101
|
+
liquidationCursor: collateral.liquidation_cursor,
|
|
102
|
+
oracle: collateral.oracle,
|
|
103
|
+
})),
|
|
104
|
+
maturity: book.maturity,
|
|
105
|
+
rcfThreshold: book.rcf_threshold,
|
|
106
|
+
enterGate: book.enter_gate,
|
|
107
|
+
liquidatorGate: book.liquidator_gate,
|
|
108
|
+
});
|
|
109
|
+
// Comparison stays inside the try so a malformed advertised `market_id`
|
|
110
|
+
// (non-hex value) surfaces as a wrapped response error, not a raw TypeError.
|
|
111
|
+
matchesAdvertisedId = isHexEqual(derivedMarketId, book.market_id);
|
|
112
|
+
}
|
|
113
|
+
catch (cause) {
|
|
114
|
+
throw new InvalidMidnightApiResponseError(`Midnight API book market_id "${book.market_id}" could not be validated against its market params.`, { cause });
|
|
115
|
+
}
|
|
116
|
+
if (!matchesAdvertisedId) {
|
|
117
|
+
throw new InvalidMidnightApiResponseError(`Midnight API book market_id "${book.market_id}" does not match the id "${derivedMarketId}" derived from its market params.`);
|
|
118
|
+
}
|
|
85
119
|
return {
|
|
86
120
|
marketId: book.market_id,
|
|
87
121
|
chainId: book.chain_id,
|
|
@@ -96,6 +130,26 @@ export function mapBookMarket(book) {
|
|
|
96
130
|
bids: book.bids.map(mapPriceLevel),
|
|
97
131
|
};
|
|
98
132
|
}
|
|
133
|
+
/** @internal Maps a book market, binding its verified id to the requested market. */
|
|
134
|
+
export function mapBoundBookMarket(book, requestedMarketId) {
|
|
135
|
+
const market = mapBookMarket(book);
|
|
136
|
+
if (!isHexEqual(market.marketId, requestedMarketId)) {
|
|
137
|
+
throw new InvalidMidnightApiResponseError(`Midnight API book market_id "${market.marketId}" does not match requested market "${requestedMarketId}".`);
|
|
138
|
+
}
|
|
139
|
+
return market;
|
|
140
|
+
}
|
|
141
|
+
/** @internal Maps listed book markets, binding each verified id to the requested market_ids filter when present. */
|
|
142
|
+
export function mapBoundBooks(books, marketIds) {
|
|
143
|
+
return books.map((book) => {
|
|
144
|
+
const market = mapBookMarket(book);
|
|
145
|
+
if (marketIds != null &&
|
|
146
|
+
marketIds.length > 0 &&
|
|
147
|
+
!marketIds.some((marketId) => isHexEqual(marketId, market.marketId))) {
|
|
148
|
+
throw new InvalidMidnightApiResponseError(`Midnight API book market_id "${market.marketId}" is outside the requested market_ids filter.`);
|
|
149
|
+
}
|
|
150
|
+
return market;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
99
153
|
/** @internal Maps a collateral API payload to the SDK response shape. */
|
|
100
154
|
export function mapCollateral(collateral) {
|
|
101
155
|
return {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal Installed Midnight SDK package version. */
|
|
2
|
-
export declare const MIDNIGHT_SDK_VERSION = "1.3.
|
|
2
|
+
export declare const MIDNIGHT_SDK_VERSION = "1.3.1";
|
package/lib/esm/fetch/utils.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ import type { DeploylessFetchParameters, MidnightCallParameters } from "./types.
|
|
|
3
3
|
/** @internal Extracts viem call parameters from Midnight fetch inputs. */
|
|
4
4
|
export declare const callParameters: (params: MidnightCallParameters) => MidnightCallParameters;
|
|
5
5
|
/** @internal Returns the configured deployless mode, defaulting to enabled. */
|
|
6
|
-
export declare const shouldUseDeployless: (params: DeploylessFetchParameters) =>
|
|
6
|
+
export declare const shouldUseDeployless: (params: DeploylessFetchParameters) => "force" | boolean;
|
|
7
7
|
/** @internal Returns the RPC chain id and rejects configured-chain drift. */
|
|
8
8
|
export declare const resolveChainId: (client: Client) => Promise<number>;
|
|
@@ -434,7 +434,7 @@ export declare namespace EcrecoverRatifierUtils {
|
|
|
434
434
|
* console.log(EcrecoverRatifierUtils.treeTypeHash(0));
|
|
435
435
|
* ```
|
|
436
436
|
*/
|
|
437
|
-
function treeTypeHash(height: number): "
|
|
437
|
+
function treeTypeHash(height: number): "0x0754209b60d99d0822b3ecd5a970f9db09df9c8998a8441e24b81f06d6c76fee" | "0x15bd6e2aa1a7a61614187ac16d2cbf8610c8f2f3c3d9eaa380ae7a501ee3cf06" | "0x1608d5eb56943c667c34b413f9f8a1c24a84ddfe1301a9c25487e638de1f5822" | "0x270da1ebafc0f24637af3612fb8c3a1d828fcb56d3637c24e86dd006b12ca7f9" | "0x3a677100d2e855c24a62d1e9c365bff90d02287f066a07064843ca1ee70ea113" | "0x4fa4f16f09f0c36c7670449a4032073380d28a60071e12ee8874bb3e5a8318fc" | "0x5400a5d43d39e6bfe910af8cb84ac77bf501d310413769dffd62ccecda8b00c6" | "0x5801c07a6c7df039ce00a7a2b8bd92aa1cf333c30b0bc3d78768590b6063d09e" | "0x817bbaac8bb863670f488b454cdd5d0990d9d81871a68e9df381c3c13d3f2ba2" | "0x828b9cdf8326a1cf234328e4d5229546a98fb72ef73624f5b6b31538e555b96c" | "0xa47534c85ac57c583568465d40fd46683d2d558d8129fe1aca01e93023afca92" | "0xb1e841691fb54f4ef85e2ed9de45d610e57f49e1e6eb2510ceead16e447dd519" | "0xb726cb7fab1a24c28213cbd482fa5a301f127fb25feb01da341919983a72711a" | "0xc447f06079bddf4b011523c4bce119e9e90fdf937de4ee88f48010406560e9c1" | "0xc9da7190eaf4b14c7cb1c14f9898256c0adb6b1dc303afe79594dea64fe199c0" | "0xcc97cb1955496a5269b5a7afca62ba694edcab26ba838a1adbd257931249de92" | "0xcea9cd557c6f821868ea287304199d0e0554af630bfa8fe36c64eb3bbacca418" | "0xda3feb08db360ad9e09540132ff04d2b6a596fdaa4747892217aaa4c7c9bcc31" | "0xf5d561d88647c3b38ed6636709d3166819fc66f8ed52a0daf4ae186387b4646c" | "0xf7dbde8234e8e345cec8fc0a8ac5909ee336b214882751ecd51e7b37df4f6cdd" | "0xfcb7a3ca4094246b8185620c4cf025c93032b6f0384805aa3f22afe04290e982";
|
|
438
438
|
/**
|
|
439
439
|
* Builds EcrecoverRatifier typed data for a tree-like input.
|
|
440
440
|
*
|
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": "1.3.
|
|
4
|
+
"version": "1.3.1",
|
|
5
5
|
"author": "Morpho Association <contact@morpho.org>",
|
|
6
6
|
"contributors": [
|
|
7
7
|
"Rubilmax <rmilon@gmail.com>"
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"viem": "^2.0.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"fast-check": "^4.
|
|
51
|
-
"typescript": "^
|
|
52
|
-
"viem": "^2.
|
|
53
|
-
"vitest": "^4.1.
|
|
54
|
-
"@morpho-org/morpho-ts": "^2.
|
|
55
|
-
"@morpho-org/test": "^2.
|
|
50
|
+
"fast-check": "^4.9.0",
|
|
51
|
+
"typescript": "^7.0.2",
|
|
52
|
+
"viem": "^2.55.10",
|
|
53
|
+
"vitest": "^4.1.10",
|
|
54
|
+
"@morpho-org/morpho-ts": "^2.11.1",
|
|
55
|
+
"@morpho-org/test": "^2.10.0"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"prepublish": "$npm_execpath build",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"build:cjs": "tsc --build tsconfig.build.cjs.json && echo '{\"type\":\"commonjs\"}' > lib/cjs/package.json",
|
|
62
62
|
"build:esm": "tsc --build tsconfig.build.esm.json && echo '{\"type\":\"module\"}' > lib/esm/package.json",
|
|
63
63
|
"generate:version": "node ../../scripts/release/generate-midnight-package-version.mjs",
|
|
64
|
-
"test": "vitest --root ../.. --project midnight-sdk"
|
|
64
|
+
"test": "vitest --root ../.. --project midnight-sdk --project midnight-sdk-fork"
|
|
65
65
|
},
|
|
66
66
|
"types": "./lib/esm/index.d.ts"
|
|
67
67
|
}
|