@morpho-org/midnight-sdk 1.2.1 → 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 +6 -5
- package/lib/cjs/api/MidnightApi.js +9 -7
- package/lib/cjs/api/helpers.d.ts +12 -2
- package/lib/cjs/api/helpers.js +91 -2
- package/lib/cjs/api/types.d.ts +70 -2
- package/lib/cjs/api/types.js +41 -0
- 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 +6 -5
- package/lib/esm/api/MidnightApi.js +8 -7
- package/lib/esm/api/helpers.d.ts +12 -2
- package/lib/esm/api/helpers.js +90 -3
- package/lib/esm/api/types.d.ts +70 -2
- package/lib/esm/api/types.js +40 -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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FetchBookParams, FetchBookPriceLevelsParams, FetchBookQuoteParams, FetchBooksParams, FetchBookTakeableOffersParams, FetchTakeableOffersParams, MempoolPayloadValidationResult, MidnightApiBookPriceLevelsResult, MidnightApiBookResult, MidnightApiBooksResult, MidnightApiBookTakeableOffersResult, MidnightApiClientParams, MidnightApiConstructorConfig, MidnightApiQuoteResult, MidnightApiTakeableOffersResult, ValidateMempoolItemsParams, ValidateMempoolPayloadParams } from "./types.js";
|
|
2
|
-
export type { FetchBookParams, FetchBookPriceLevelsParams, FetchBookQuoteParams, FetchBooksParams, FetchBookTakeableOffersParams, FetchTakeableOffersParams, MempoolPayloadValidationIssue, MempoolPayloadValidationResult, MempoolPayloadValidationSuccess, MidnightApiBookMarket, MidnightApiBookPriceLevelsResult, MidnightApiBookResult, MidnightApiBookSide, MidnightApiBookSort, MidnightApiBookSortField, MidnightApiBookSortTerm, MidnightApiBooksResult, MidnightApiBookTakeableOffersResult, MidnightApiClientParams, MidnightApiCollateral, MidnightApiConfig, MidnightApiConstructorConfig, MidnightApiFetch, MidnightApiPriceLevel, MidnightApiQuote, MidnightApiQuoteAssetsTarget, MidnightApiQuoteAverageWorstPriceGuard, MidnightApiQuoteResult, MidnightApiQuoteSlippageGuard, MidnightApiQuoteUnitsTarget, MidnightApiQuoteWithoutGuard, MidnightApiRequestOptions, MidnightApiSlippage, MidnightApiTake, MidnightApiTakeableOffersResult, ValidateMempoolItemsParams, ValidateMempoolPayloadParams, } from "./types.js";
|
|
2
|
+
export type { FetchBookParams, FetchBookPriceLevelsParams, FetchBookQuoteParams, FetchBooksParams, FetchBookTakeableOffersParams, FetchTakeableOffersParams, MempoolPayloadValidationIssue, MempoolPayloadValidationIssueDetails, MempoolPayloadValidationResult, MempoolPayloadValidationSuccess, MidnightApiBookMarket, MidnightApiBookPriceLevelsResult, MidnightApiBookResult, MidnightApiBookSide, MidnightApiBookSort, MidnightApiBookSortField, MidnightApiBookSortTerm, MidnightApiBooksResult, MidnightApiBookTakeableOffersResult, MidnightApiClientParams, MidnightApiCollateral, MidnightApiConfig, MidnightApiConstructorConfig, MidnightApiFetch, MidnightApiPriceLevel, MidnightApiQuote, MidnightApiQuoteAssetsTarget, MidnightApiQuoteAverageWorstPriceGuard, MidnightApiQuoteResult, MidnightApiQuoteSlippageGuard, MidnightApiQuoteUnitsTarget, MidnightApiQuoteWithoutGuard, MidnightApiRequestOptions, MidnightApiSlippage, MidnightApiTake, MidnightApiTakeableOffersResult, ValidateMempoolItemsParams, ValidateMempoolPayloadParams, } from "./types.js";
|
|
3
|
+
export { MempoolPayloadValidationRule } from "./types.js";
|
|
3
4
|
/**
|
|
4
5
|
* Midnight API client and stateless helper surface for books and mempool data.
|
|
5
6
|
*
|
|
@@ -66,7 +67,7 @@ export declare class MidnightApi {
|
|
|
66
67
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
67
68
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
68
69
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
69
|
-
* @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.
|
|
70
71
|
* @example
|
|
71
72
|
* ```ts
|
|
72
73
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -91,7 +92,7 @@ export declare class MidnightApi {
|
|
|
91
92
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
92
93
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
93
94
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
94
|
-
* @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`.
|
|
95
96
|
* @example
|
|
96
97
|
* ```ts
|
|
97
98
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -319,7 +320,7 @@ export declare class MidnightApi {
|
|
|
319
320
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
320
321
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
321
322
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
322
|
-
* @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.
|
|
323
324
|
* @example
|
|
324
325
|
* ```ts
|
|
325
326
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -339,7 +340,7 @@ export declare class MidnightApi {
|
|
|
339
340
|
* @param params.depth - Optional maximum levels returned per side.
|
|
340
341
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
341
342
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
342
|
-
* @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`.
|
|
343
344
|
* @example
|
|
344
345
|
* ```ts
|
|
345
346
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MidnightApi = void 0;
|
|
3
|
+
exports.MidnightApi = exports.MempoolPayloadValidationRule = void 0;
|
|
4
4
|
const morpho_ts_1 = require("@morpho-org/morpho-ts");
|
|
5
5
|
const errors_js_1 = require("../errors.js");
|
|
6
6
|
const index_js_1 = require("../math/index.js");
|
|
7
7
|
const Payload_js_1 = require("../signatures/Payload.js");
|
|
8
8
|
const helpers_js_1 = require("./helpers.js");
|
|
9
|
+
var types_js_1 = require("./types.js");
|
|
10
|
+
Object.defineProperty(exports, "MempoolPayloadValidationRule", { enumerable: true, get: function () { return types_js_1.MempoolPayloadValidationRule; } });
|
|
9
11
|
/**
|
|
10
12
|
* Midnight API client and stateless helper surface for books and mempool data.
|
|
11
13
|
*
|
|
@@ -77,7 +79,7 @@ class MidnightApi {
|
|
|
77
79
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
78
80
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
79
81
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
80
|
-
* @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.
|
|
81
83
|
* @example
|
|
82
84
|
* ```ts
|
|
83
85
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -108,7 +110,7 @@ class MidnightApi {
|
|
|
108
110
|
});
|
|
109
111
|
return {
|
|
110
112
|
cursor: response.cursor,
|
|
111
|
-
data: response.data.
|
|
113
|
+
data: (0, helpers_js_1.mapBoundBooks)(response.data, input.marketIds),
|
|
112
114
|
};
|
|
113
115
|
}
|
|
114
116
|
/**
|
|
@@ -123,7 +125,7 @@ class MidnightApi {
|
|
|
123
125
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
124
126
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
125
127
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
126
|
-
* @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`.
|
|
127
129
|
* @example
|
|
128
130
|
* ```ts
|
|
129
131
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -145,7 +147,7 @@ class MidnightApi {
|
|
|
145
147
|
},
|
|
146
148
|
});
|
|
147
149
|
return {
|
|
148
|
-
data: (0, helpers_js_1.
|
|
150
|
+
data: (0, helpers_js_1.mapBoundBookMarket)(response.data, input.marketId),
|
|
149
151
|
};
|
|
150
152
|
}
|
|
151
153
|
/**
|
|
@@ -523,7 +525,7 @@ class MidnightApi {
|
|
|
523
525
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
524
526
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
525
527
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
526
|
-
* @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.
|
|
527
529
|
* @example
|
|
528
530
|
* ```ts
|
|
529
531
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -548,7 +550,7 @@ class MidnightApi {
|
|
|
548
550
|
* @param params.depth - Optional maximum levels returned per side.
|
|
549
551
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
550
552
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
551
|
-
* @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`.
|
|
552
554
|
* @example
|
|
553
555
|
* ```ts
|
|
554
556
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
package/lib/cjs/api/helpers.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Address, type Hash } from "viem";
|
|
2
|
-
import type
|
|
2
|
+
import { type ApiBookMarketResponse, type ApiCollateralResponse, type ApiPriceLevelResponse, type ApiRequestParams, type ApiTakeableOfferResponse, type MempoolPayloadValidationResult, type MidnightApiBookMarket, type MidnightApiBookSide, type MidnightApiCollateral, type MidnightApiPriceLevel, type MidnightApiTake } from "./types.js";
|
|
3
3
|
/** @internal Sends one Midnight API request and maps non-2xx responses to SDK errors. */
|
|
4
4
|
export declare function requestMidnightApi<Response = unknown>(params: ApiRequestParams): Promise<Response>;
|
|
5
5
|
/** @internal Builds a book endpoint path with encoded path segments. */
|
|
@@ -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;
|
|
@@ -12,8 +14,10 @@ const morpho_ts_1 = require("@morpho-org/morpho-ts");
|
|
|
12
14
|
const viem_1 = require("viem");
|
|
13
15
|
const errors_js_1 = require("../errors.js");
|
|
14
16
|
const index_js_1 = require("../market/index.js");
|
|
17
|
+
const types_js_1 = require("./types.js");
|
|
15
18
|
const version_generated_js_1 = require("./version.generated.js");
|
|
16
19
|
const DEFAULT_MIDNIGHT_API_URL = new URL("/v0/midnight", morpho_ts_1.BLUE_API_BASE_URL);
|
|
20
|
+
const MAX_UINT256_DECIMAL_LENGTH = viem_1.maxUint256.toString().length;
|
|
17
21
|
/** @internal Sends one Midnight API request and maps non-2xx responses to SDK errors. */
|
|
18
22
|
async function requestMidnightApi(params) {
|
|
19
23
|
const baseUrl = new URL(params.baseUrl ?? DEFAULT_MIDNIGHT_API_URL);
|
|
@@ -88,8 +92,42 @@ function buildBookPath(params) {
|
|
|
88
92
|
].filter((segment) => segment !== undefined);
|
|
89
93
|
return segments.map(encodeURIComponent).join("/");
|
|
90
94
|
}
|
|
91
|
-
/**
|
|
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
|
+
*/
|
|
92
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
|
+
}
|
|
93
131
|
return {
|
|
94
132
|
marketId: book.market_id,
|
|
95
133
|
chainId: book.chain_id,
|
|
@@ -104,6 +142,26 @@ function mapBookMarket(book) {
|
|
|
104
142
|
bids: book.bids.map(mapPriceLevel),
|
|
105
143
|
};
|
|
106
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
|
+
}
|
|
107
165
|
/** @internal Maps a collateral API payload to the SDK response shape. */
|
|
108
166
|
function mapCollateral(collateral) {
|
|
109
167
|
return {
|
|
@@ -220,7 +278,38 @@ function parseValidationResponse(response) {
|
|
|
220
278
|
if (typeof rule !== "string") {
|
|
221
279
|
throw new errors_js_1.InvalidMidnightApiResponseError('Midnight API validation issue is missing "rule".');
|
|
222
280
|
}
|
|
223
|
-
|
|
281
|
+
const details = record.details;
|
|
282
|
+
if (details == null)
|
|
283
|
+
return { rule };
|
|
284
|
+
if (rule === types_js_1.MempoolPayloadValidationRule.MinOfferAssetsUsd &&
|
|
285
|
+
isRecord(details)) {
|
|
286
|
+
const loanToken = details.loan_token;
|
|
287
|
+
const rawMinAssets = details.min_assets;
|
|
288
|
+
if (typeof loanToken === "string" &&
|
|
289
|
+
(0, viem_1.isAddress)(loanToken) &&
|
|
290
|
+
typeof rawMinAssets === "string" &&
|
|
291
|
+
rawMinAssets.length <= MAX_UINT256_DECIMAL_LENGTH &&
|
|
292
|
+
/^\d+$/.test(rawMinAssets)) {
|
|
293
|
+
const minAssets = BigInt(rawMinAssets);
|
|
294
|
+
if (minAssets <= viem_1.maxUint256) {
|
|
295
|
+
return {
|
|
296
|
+
rule,
|
|
297
|
+
details: {
|
|
298
|
+
type: "minOfferAssetsUsd",
|
|
299
|
+
loanToken,
|
|
300
|
+
minAssets,
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
rule,
|
|
308
|
+
details: {
|
|
309
|
+
type: "unknown",
|
|
310
|
+
raw: details,
|
|
311
|
+
},
|
|
312
|
+
};
|
|
224
313
|
});
|
|
225
314
|
return {
|
|
226
315
|
valid: issues.length === 0,
|
package/lib/cjs/api/types.d.ts
CHANGED
|
@@ -194,11 +194,79 @@ export interface FetchTakeableOffersParams extends MidnightApiConfig {
|
|
|
194
194
|
readonly cursor?: string;
|
|
195
195
|
}
|
|
196
196
|
/**
|
|
197
|
-
*
|
|
197
|
+
* `MempoolPayloadValidationRule` lists known Midnight mempool validation rules.
|
|
198
|
+
*/
|
|
199
|
+
export declare const MempoolPayloadValidationRule: {
|
|
200
|
+
readonly MinOfferAssetsUsd: "min_offer_assets_usd";
|
|
201
|
+
readonly PayloadVersion: "payload_version";
|
|
202
|
+
readonly PayloadFrame: "payload_frame";
|
|
203
|
+
readonly PayloadGzipLength: "payload_gzip_length";
|
|
204
|
+
readonly PayloadSuffixTooLarge: "payload_suffix_too_large";
|
|
205
|
+
readonly PayloadDecompression: "payload_decompression";
|
|
206
|
+
readonly PayloadAbiDecode: "payload_abi_decode";
|
|
207
|
+
readonly EmptyPayload: "empty_payload";
|
|
208
|
+
readonly MaxOffersPerTree: "max_offers_per_tree";
|
|
209
|
+
readonly DuplicateOfferHash: "duplicate_offer_hash";
|
|
210
|
+
readonly UnsupportedChain: "unsupported_chain";
|
|
211
|
+
readonly MarketChainMismatch: "market_chain_mismatch";
|
|
212
|
+
readonly Maturity: "maturity";
|
|
213
|
+
readonly LoanToken: "loan_token";
|
|
214
|
+
readonly CollateralToken: "collateral_token";
|
|
215
|
+
readonly Oracle: "oracle";
|
|
216
|
+
readonly MarketTriplet: "market_triplet";
|
|
217
|
+
readonly RcfThreshold: "rcf_threshold";
|
|
218
|
+
readonly CollateralLltv: "collateral_lltv";
|
|
219
|
+
readonly MaxLif: "max_lif";
|
|
220
|
+
readonly MaxCollaterals: "max_collaterals";
|
|
221
|
+
readonly AmountMissing: "amount_missing";
|
|
222
|
+
readonly AmountConflict: "amount_conflict";
|
|
223
|
+
readonly MinTick: "min_tick";
|
|
224
|
+
readonly MaxTick: "max_tick";
|
|
225
|
+
readonly TickSpacing: "tick_spacing";
|
|
226
|
+
readonly MinDuration: "min_duration";
|
|
227
|
+
readonly Ratifier: "ratifier";
|
|
228
|
+
readonly MixedMaker: "mixed_maker";
|
|
229
|
+
readonly MixedRatifier: "mixed_ratifier";
|
|
230
|
+
readonly GroupIdentity: "group_identity";
|
|
231
|
+
readonly GroupConsistency: "group_consistency";
|
|
232
|
+
readonly NonEmptyCallback: "non_empty_callback";
|
|
233
|
+
readonly BuyEmptyCallback: "buy_empty_callback";
|
|
234
|
+
readonly SellEmptyCallback: "sell_empty_callback";
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* `MempoolPayloadValidationRule` represents a rule returned by the API.
|
|
238
|
+
*
|
|
239
|
+
* Known values have autocomplete through the matching constant; the open
|
|
240
|
+
* string branch keeps newer API rules forward-compatible.
|
|
241
|
+
*/
|
|
242
|
+
export type MempoolPayloadValidationRule = (typeof MempoolPayloadValidationRule)[keyof typeof MempoolPayloadValidationRule] | (string & Record<never, never>);
|
|
243
|
+
/**
|
|
244
|
+
* `MempoolPayloadValidationIssueDetails` represents parsed issue details.
|
|
245
|
+
*
|
|
246
|
+
* Unrecognized non-null details are retained verbatim so API additions do not
|
|
247
|
+
* make older SDK clients reject the entire validation response.
|
|
248
|
+
*/
|
|
249
|
+
export type MempoolPayloadValidationIssueDetails = {
|
|
250
|
+
/** Identifies details for the `min_offer_assets_usd` rule. */
|
|
251
|
+
readonly type: "minOfferAssetsUsd";
|
|
252
|
+
/** Loan token of the first offer below its configured minimum. */
|
|
253
|
+
readonly loanToken: Address;
|
|
254
|
+
/** Configured minimum in raw loan-token assets. */
|
|
255
|
+
readonly minAssets: bigint;
|
|
256
|
+
} | {
|
|
257
|
+
/** Identifies details whose schema is not known by this SDK version. */
|
|
258
|
+
readonly type: "unknown";
|
|
259
|
+
/** Unmodified JSON value returned by the API. */
|
|
260
|
+
readonly raw: unknown;
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* `MempoolPayloadValidationIssue` represents one API validation issue.
|
|
198
264
|
*/
|
|
199
265
|
export interface MempoolPayloadValidationIssue {
|
|
200
266
|
/** API rule violated by the payload. */
|
|
201
|
-
readonly rule:
|
|
267
|
+
readonly rule: MempoolPayloadValidationRule;
|
|
268
|
+
/** Parsed non-null details, when the API provides them. */
|
|
269
|
+
readonly details?: MempoolPayloadValidationIssueDetails;
|
|
202
270
|
}
|
|
203
271
|
/**
|
|
204
272
|
* SDK-shaped result returned by Midnight mempool validation.
|
package/lib/cjs/api/types.js
CHANGED
|
@@ -1,2 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MempoolPayloadValidationRule = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* `MempoolPayloadValidationRule` lists known Midnight mempool validation rules.
|
|
6
|
+
*/
|
|
7
|
+
exports.MempoolPayloadValidationRule = {
|
|
8
|
+
MinOfferAssetsUsd: "min_offer_assets_usd",
|
|
9
|
+
PayloadVersion: "payload_version",
|
|
10
|
+
PayloadFrame: "payload_frame",
|
|
11
|
+
PayloadGzipLength: "payload_gzip_length",
|
|
12
|
+
PayloadSuffixTooLarge: "payload_suffix_too_large",
|
|
13
|
+
PayloadDecompression: "payload_decompression",
|
|
14
|
+
PayloadAbiDecode: "payload_abi_decode",
|
|
15
|
+
EmptyPayload: "empty_payload",
|
|
16
|
+
MaxOffersPerTree: "max_offers_per_tree",
|
|
17
|
+
DuplicateOfferHash: "duplicate_offer_hash",
|
|
18
|
+
UnsupportedChain: "unsupported_chain",
|
|
19
|
+
MarketChainMismatch: "market_chain_mismatch",
|
|
20
|
+
Maturity: "maturity",
|
|
21
|
+
LoanToken: "loan_token",
|
|
22
|
+
CollateralToken: "collateral_token",
|
|
23
|
+
Oracle: "oracle",
|
|
24
|
+
MarketTriplet: "market_triplet",
|
|
25
|
+
RcfThreshold: "rcf_threshold",
|
|
26
|
+
CollateralLltv: "collateral_lltv",
|
|
27
|
+
MaxLif: "max_lif",
|
|
28
|
+
MaxCollaterals: "max_collaterals",
|
|
29
|
+
AmountMissing: "amount_missing",
|
|
30
|
+
AmountConflict: "amount_conflict",
|
|
31
|
+
MinTick: "min_tick",
|
|
32
|
+
MaxTick: "max_tick",
|
|
33
|
+
TickSpacing: "tick_spacing",
|
|
34
|
+
MinDuration: "min_duration",
|
|
35
|
+
Ratifier: "ratifier",
|
|
36
|
+
MixedMaker: "mixed_maker",
|
|
37
|
+
MixedRatifier: "mixed_ratifier",
|
|
38
|
+
GroupIdentity: "group_identity",
|
|
39
|
+
GroupConsistency: "group_consistency",
|
|
40
|
+
NonEmptyCallback: "non_empty_callback",
|
|
41
|
+
BuyEmptyCallback: "buy_empty_callback",
|
|
42
|
+
SellEmptyCallback: "sell_empty_callback",
|
|
43
|
+
};
|
|
@@ -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.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
|
*
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FetchBookParams, FetchBookPriceLevelsParams, FetchBookQuoteParams, FetchBooksParams, FetchBookTakeableOffersParams, FetchTakeableOffersParams, MempoolPayloadValidationResult, MidnightApiBookPriceLevelsResult, MidnightApiBookResult, MidnightApiBooksResult, MidnightApiBookTakeableOffersResult, MidnightApiClientParams, MidnightApiConstructorConfig, MidnightApiQuoteResult, MidnightApiTakeableOffersResult, ValidateMempoolItemsParams, ValidateMempoolPayloadParams } from "./types.js";
|
|
2
|
-
export type { FetchBookParams, FetchBookPriceLevelsParams, FetchBookQuoteParams, FetchBooksParams, FetchBookTakeableOffersParams, FetchTakeableOffersParams, MempoolPayloadValidationIssue, MempoolPayloadValidationResult, MempoolPayloadValidationSuccess, MidnightApiBookMarket, MidnightApiBookPriceLevelsResult, MidnightApiBookResult, MidnightApiBookSide, MidnightApiBookSort, MidnightApiBookSortField, MidnightApiBookSortTerm, MidnightApiBooksResult, MidnightApiBookTakeableOffersResult, MidnightApiClientParams, MidnightApiCollateral, MidnightApiConfig, MidnightApiConstructorConfig, MidnightApiFetch, MidnightApiPriceLevel, MidnightApiQuote, MidnightApiQuoteAssetsTarget, MidnightApiQuoteAverageWorstPriceGuard, MidnightApiQuoteResult, MidnightApiQuoteSlippageGuard, MidnightApiQuoteUnitsTarget, MidnightApiQuoteWithoutGuard, MidnightApiRequestOptions, MidnightApiSlippage, MidnightApiTake, MidnightApiTakeableOffersResult, ValidateMempoolItemsParams, ValidateMempoolPayloadParams, } from "./types.js";
|
|
2
|
+
export type { FetchBookParams, FetchBookPriceLevelsParams, FetchBookQuoteParams, FetchBooksParams, FetchBookTakeableOffersParams, FetchTakeableOffersParams, MempoolPayloadValidationIssue, MempoolPayloadValidationIssueDetails, MempoolPayloadValidationResult, MempoolPayloadValidationSuccess, MidnightApiBookMarket, MidnightApiBookPriceLevelsResult, MidnightApiBookResult, MidnightApiBookSide, MidnightApiBookSort, MidnightApiBookSortField, MidnightApiBookSortTerm, MidnightApiBooksResult, MidnightApiBookTakeableOffersResult, MidnightApiClientParams, MidnightApiCollateral, MidnightApiConfig, MidnightApiConstructorConfig, MidnightApiFetch, MidnightApiPriceLevel, MidnightApiQuote, MidnightApiQuoteAssetsTarget, MidnightApiQuoteAverageWorstPriceGuard, MidnightApiQuoteResult, MidnightApiQuoteSlippageGuard, MidnightApiQuoteUnitsTarget, MidnightApiQuoteWithoutGuard, MidnightApiRequestOptions, MidnightApiSlippage, MidnightApiTake, MidnightApiTakeableOffersResult, ValidateMempoolItemsParams, ValidateMempoolPayloadParams, } from "./types.js";
|
|
3
|
+
export { MempoolPayloadValidationRule } from "./types.js";
|
|
3
4
|
/**
|
|
4
5
|
* Midnight API client and stateless helper surface for books and mempool data.
|
|
5
6
|
*
|
|
@@ -66,7 +67,7 @@ export declare class MidnightApi {
|
|
|
66
67
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
67
68
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
68
69
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
69
|
-
* @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.
|
|
70
71
|
* @example
|
|
71
72
|
* ```ts
|
|
72
73
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -91,7 +92,7 @@ export declare class MidnightApi {
|
|
|
91
92
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
92
93
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
93
94
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
94
|
-
* @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`.
|
|
95
96
|
* @example
|
|
96
97
|
* ```ts
|
|
97
98
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -319,7 +320,7 @@ export declare class MidnightApi {
|
|
|
319
320
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
320
321
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
321
322
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
322
|
-
* @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.
|
|
323
324
|
* @example
|
|
324
325
|
* ```ts
|
|
325
326
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -339,7 +340,7 @@ export declare class MidnightApi {
|
|
|
339
340
|
* @param params.depth - Optional maximum levels returned per side.
|
|
340
341
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
341
342
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
342
|
-
* @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`.
|
|
343
344
|
* @example
|
|
344
345
|
* ```ts
|
|
345
346
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -2,7 +2,8 @@ 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
|
+
export { MempoolPayloadValidationRule } from "./types.js";
|
|
6
7
|
/**
|
|
7
8
|
* Midnight API client and stateless helper surface for books and mempool data.
|
|
8
9
|
*
|
|
@@ -74,7 +75,7 @@ export class MidnightApi {
|
|
|
74
75
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
75
76
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
76
77
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
77
|
-
* @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.
|
|
78
79
|
* @example
|
|
79
80
|
* ```ts
|
|
80
81
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -105,7 +106,7 @@ export class MidnightApi {
|
|
|
105
106
|
});
|
|
106
107
|
return {
|
|
107
108
|
cursor: response.cursor,
|
|
108
|
-
data: response.data.
|
|
109
|
+
data: mapBoundBooks(response.data, input.marketIds),
|
|
109
110
|
};
|
|
110
111
|
}
|
|
111
112
|
/**
|
|
@@ -120,7 +121,7 @@ export class MidnightApi {
|
|
|
120
121
|
* @param params.request - Optional fetch options forwarded to this request.
|
|
121
122
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
122
123
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
123
|
-
* @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`.
|
|
124
125
|
* @example
|
|
125
126
|
* ```ts
|
|
126
127
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -142,7 +143,7 @@ export class MidnightApi {
|
|
|
142
143
|
},
|
|
143
144
|
});
|
|
144
145
|
return {
|
|
145
|
-
data:
|
|
146
|
+
data: mapBoundBookMarket(response.data, input.marketId),
|
|
146
147
|
};
|
|
147
148
|
}
|
|
148
149
|
/**
|
|
@@ -520,7 +521,7 @@ export class MidnightApi {
|
|
|
520
521
|
* @param params.cursor - Optional opaque pagination cursor from a previous response.
|
|
521
522
|
* @returns Paginated books mapped to SDK camelCase fields.
|
|
522
523
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
523
|
-
* @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.
|
|
524
525
|
* @example
|
|
525
526
|
* ```ts
|
|
526
527
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
|
@@ -545,7 +546,7 @@ export class MidnightApi {
|
|
|
545
546
|
* @param params.depth - Optional maximum levels returned per side.
|
|
546
547
|
* @returns Book snapshot mapped to SDK camelCase fields.
|
|
547
548
|
* @throws {MidnightApiError} when the API returns a non-2xx response.
|
|
548
|
-
* @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`.
|
|
549
550
|
* @example
|
|
550
551
|
* ```ts
|
|
551
552
|
* import { MidnightApi } from "@morpho-org/midnight-sdk/api";
|
package/lib/esm/api/helpers.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Address, type Hash } from "viem";
|
|
2
|
-
import type
|
|
2
|
+
import { type ApiBookMarketResponse, type ApiCollateralResponse, type ApiPriceLevelResponse, type ApiRequestParams, type ApiTakeableOfferResponse, type MempoolPayloadValidationResult, type MidnightApiBookMarket, type MidnightApiBookSide, type MidnightApiCollateral, type MidnightApiPriceLevel, type MidnightApiTake } from "./types.js";
|
|
3
3
|
/** @internal Sends one Midnight API request and maps non-2xx responses to SDK errors. */
|
|
4
4
|
export declare function requestMidnightApi<Response = unknown>(params: ApiRequestParams): Promise<Response>;
|
|
5
5
|
/** @internal Builds a book endpoint path with encoded path segments. */
|
|
@@ -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
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { BLUE_API_BASE_URL, isHexEqual } from "@morpho-org/morpho-ts";
|
|
2
|
-
import { isAddressEqual } from "viem";
|
|
2
|
+
import { isAddress, isAddressEqual, maxUint256, } from "viem";
|
|
3
3
|
import { InvalidMidnightApiResponseError, MidnightApiError, } from "../errors.js";
|
|
4
4
|
import { MarketUtils } from "../market/index.js";
|
|
5
|
+
import { MempoolPayloadValidationRule, } from "./types.js";
|
|
5
6
|
import { MIDNIGHT_SDK_VERSION } from "./version.generated.js";
|
|
6
7
|
const DEFAULT_MIDNIGHT_API_URL = new URL("/v0/midnight", BLUE_API_BASE_URL);
|
|
8
|
+
const MAX_UINT256_DECIMAL_LENGTH = maxUint256.toString().length;
|
|
7
9
|
/** @internal Sends one Midnight API request and maps non-2xx responses to SDK errors. */
|
|
8
10
|
export async function requestMidnightApi(params) {
|
|
9
11
|
const baseUrl = new URL(params.baseUrl ?? DEFAULT_MIDNIGHT_API_URL);
|
|
@@ -78,8 +80,42 @@ export function buildBookPath(params) {
|
|
|
78
80
|
].filter((segment) => segment !== undefined);
|
|
79
81
|
return segments.map(encodeURIComponent).join("/");
|
|
80
82
|
}
|
|
81
|
-
/**
|
|
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
|
+
*/
|
|
82
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
|
+
}
|
|
83
119
|
return {
|
|
84
120
|
marketId: book.market_id,
|
|
85
121
|
chainId: book.chain_id,
|
|
@@ -94,6 +130,26 @@ export function mapBookMarket(book) {
|
|
|
94
130
|
bids: book.bids.map(mapPriceLevel),
|
|
95
131
|
};
|
|
96
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
|
+
}
|
|
97
153
|
/** @internal Maps a collateral API payload to the SDK response shape. */
|
|
98
154
|
export function mapCollateral(collateral) {
|
|
99
155
|
return {
|
|
@@ -210,7 +266,38 @@ export function parseValidationResponse(response) {
|
|
|
210
266
|
if (typeof rule !== "string") {
|
|
211
267
|
throw new InvalidMidnightApiResponseError('Midnight API validation issue is missing "rule".');
|
|
212
268
|
}
|
|
213
|
-
|
|
269
|
+
const details = record.details;
|
|
270
|
+
if (details == null)
|
|
271
|
+
return { rule };
|
|
272
|
+
if (rule === MempoolPayloadValidationRule.MinOfferAssetsUsd &&
|
|
273
|
+
isRecord(details)) {
|
|
274
|
+
const loanToken = details.loan_token;
|
|
275
|
+
const rawMinAssets = details.min_assets;
|
|
276
|
+
if (typeof loanToken === "string" &&
|
|
277
|
+
isAddress(loanToken) &&
|
|
278
|
+
typeof rawMinAssets === "string" &&
|
|
279
|
+
rawMinAssets.length <= MAX_UINT256_DECIMAL_LENGTH &&
|
|
280
|
+
/^\d+$/.test(rawMinAssets)) {
|
|
281
|
+
const minAssets = BigInt(rawMinAssets);
|
|
282
|
+
if (minAssets <= maxUint256) {
|
|
283
|
+
return {
|
|
284
|
+
rule,
|
|
285
|
+
details: {
|
|
286
|
+
type: "minOfferAssetsUsd",
|
|
287
|
+
loanToken,
|
|
288
|
+
minAssets,
|
|
289
|
+
},
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
rule,
|
|
296
|
+
details: {
|
|
297
|
+
type: "unknown",
|
|
298
|
+
raw: details,
|
|
299
|
+
},
|
|
300
|
+
};
|
|
214
301
|
});
|
|
215
302
|
return {
|
|
216
303
|
valid: issues.length === 0,
|
package/lib/esm/api/types.d.ts
CHANGED
|
@@ -194,11 +194,79 @@ export interface FetchTakeableOffersParams extends MidnightApiConfig {
|
|
|
194
194
|
readonly cursor?: string;
|
|
195
195
|
}
|
|
196
196
|
/**
|
|
197
|
-
*
|
|
197
|
+
* `MempoolPayloadValidationRule` lists known Midnight mempool validation rules.
|
|
198
|
+
*/
|
|
199
|
+
export declare const MempoolPayloadValidationRule: {
|
|
200
|
+
readonly MinOfferAssetsUsd: "min_offer_assets_usd";
|
|
201
|
+
readonly PayloadVersion: "payload_version";
|
|
202
|
+
readonly PayloadFrame: "payload_frame";
|
|
203
|
+
readonly PayloadGzipLength: "payload_gzip_length";
|
|
204
|
+
readonly PayloadSuffixTooLarge: "payload_suffix_too_large";
|
|
205
|
+
readonly PayloadDecompression: "payload_decompression";
|
|
206
|
+
readonly PayloadAbiDecode: "payload_abi_decode";
|
|
207
|
+
readonly EmptyPayload: "empty_payload";
|
|
208
|
+
readonly MaxOffersPerTree: "max_offers_per_tree";
|
|
209
|
+
readonly DuplicateOfferHash: "duplicate_offer_hash";
|
|
210
|
+
readonly UnsupportedChain: "unsupported_chain";
|
|
211
|
+
readonly MarketChainMismatch: "market_chain_mismatch";
|
|
212
|
+
readonly Maturity: "maturity";
|
|
213
|
+
readonly LoanToken: "loan_token";
|
|
214
|
+
readonly CollateralToken: "collateral_token";
|
|
215
|
+
readonly Oracle: "oracle";
|
|
216
|
+
readonly MarketTriplet: "market_triplet";
|
|
217
|
+
readonly RcfThreshold: "rcf_threshold";
|
|
218
|
+
readonly CollateralLltv: "collateral_lltv";
|
|
219
|
+
readonly MaxLif: "max_lif";
|
|
220
|
+
readonly MaxCollaterals: "max_collaterals";
|
|
221
|
+
readonly AmountMissing: "amount_missing";
|
|
222
|
+
readonly AmountConflict: "amount_conflict";
|
|
223
|
+
readonly MinTick: "min_tick";
|
|
224
|
+
readonly MaxTick: "max_tick";
|
|
225
|
+
readonly TickSpacing: "tick_spacing";
|
|
226
|
+
readonly MinDuration: "min_duration";
|
|
227
|
+
readonly Ratifier: "ratifier";
|
|
228
|
+
readonly MixedMaker: "mixed_maker";
|
|
229
|
+
readonly MixedRatifier: "mixed_ratifier";
|
|
230
|
+
readonly GroupIdentity: "group_identity";
|
|
231
|
+
readonly GroupConsistency: "group_consistency";
|
|
232
|
+
readonly NonEmptyCallback: "non_empty_callback";
|
|
233
|
+
readonly BuyEmptyCallback: "buy_empty_callback";
|
|
234
|
+
readonly SellEmptyCallback: "sell_empty_callback";
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* `MempoolPayloadValidationRule` represents a rule returned by the API.
|
|
238
|
+
*
|
|
239
|
+
* Known values have autocomplete through the matching constant; the open
|
|
240
|
+
* string branch keeps newer API rules forward-compatible.
|
|
241
|
+
*/
|
|
242
|
+
export type MempoolPayloadValidationRule = (typeof MempoolPayloadValidationRule)[keyof typeof MempoolPayloadValidationRule] | (string & Record<never, never>);
|
|
243
|
+
/**
|
|
244
|
+
* `MempoolPayloadValidationIssueDetails` represents parsed issue details.
|
|
245
|
+
*
|
|
246
|
+
* Unrecognized non-null details are retained verbatim so API additions do not
|
|
247
|
+
* make older SDK clients reject the entire validation response.
|
|
248
|
+
*/
|
|
249
|
+
export type MempoolPayloadValidationIssueDetails = {
|
|
250
|
+
/** Identifies details for the `min_offer_assets_usd` rule. */
|
|
251
|
+
readonly type: "minOfferAssetsUsd";
|
|
252
|
+
/** Loan token of the first offer below its configured minimum. */
|
|
253
|
+
readonly loanToken: Address;
|
|
254
|
+
/** Configured minimum in raw loan-token assets. */
|
|
255
|
+
readonly minAssets: bigint;
|
|
256
|
+
} | {
|
|
257
|
+
/** Identifies details whose schema is not known by this SDK version. */
|
|
258
|
+
readonly type: "unknown";
|
|
259
|
+
/** Unmodified JSON value returned by the API. */
|
|
260
|
+
readonly raw: unknown;
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* `MempoolPayloadValidationIssue` represents one API validation issue.
|
|
198
264
|
*/
|
|
199
265
|
export interface MempoolPayloadValidationIssue {
|
|
200
266
|
/** API rule violated by the payload. */
|
|
201
|
-
readonly rule:
|
|
267
|
+
readonly rule: MempoolPayloadValidationRule;
|
|
268
|
+
/** Parsed non-null details, when the API provides them. */
|
|
269
|
+
readonly details?: MempoolPayloadValidationIssueDetails;
|
|
202
270
|
}
|
|
203
271
|
/**
|
|
204
272
|
* SDK-shaped result returned by Midnight mempool validation.
|
package/lib/esm/api/types.js
CHANGED
|
@@ -1 +1,40 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `MempoolPayloadValidationRule` lists known Midnight mempool validation rules.
|
|
3
|
+
*/
|
|
4
|
+
export const MempoolPayloadValidationRule = {
|
|
5
|
+
MinOfferAssetsUsd: "min_offer_assets_usd",
|
|
6
|
+
PayloadVersion: "payload_version",
|
|
7
|
+
PayloadFrame: "payload_frame",
|
|
8
|
+
PayloadGzipLength: "payload_gzip_length",
|
|
9
|
+
PayloadSuffixTooLarge: "payload_suffix_too_large",
|
|
10
|
+
PayloadDecompression: "payload_decompression",
|
|
11
|
+
PayloadAbiDecode: "payload_abi_decode",
|
|
12
|
+
EmptyPayload: "empty_payload",
|
|
13
|
+
MaxOffersPerTree: "max_offers_per_tree",
|
|
14
|
+
DuplicateOfferHash: "duplicate_offer_hash",
|
|
15
|
+
UnsupportedChain: "unsupported_chain",
|
|
16
|
+
MarketChainMismatch: "market_chain_mismatch",
|
|
17
|
+
Maturity: "maturity",
|
|
18
|
+
LoanToken: "loan_token",
|
|
19
|
+
CollateralToken: "collateral_token",
|
|
20
|
+
Oracle: "oracle",
|
|
21
|
+
MarketTriplet: "market_triplet",
|
|
22
|
+
RcfThreshold: "rcf_threshold",
|
|
23
|
+
CollateralLltv: "collateral_lltv",
|
|
24
|
+
MaxLif: "max_lif",
|
|
25
|
+
MaxCollaterals: "max_collaterals",
|
|
26
|
+
AmountMissing: "amount_missing",
|
|
27
|
+
AmountConflict: "amount_conflict",
|
|
28
|
+
MinTick: "min_tick",
|
|
29
|
+
MaxTick: "max_tick",
|
|
30
|
+
TickSpacing: "tick_spacing",
|
|
31
|
+
MinDuration: "min_duration",
|
|
32
|
+
Ratifier: "ratifier",
|
|
33
|
+
MixedMaker: "mixed_maker",
|
|
34
|
+
MixedRatifier: "mixed_ratifier",
|
|
35
|
+
GroupIdentity: "group_identity",
|
|
36
|
+
GroupConsistency: "group_consistency",
|
|
37
|
+
NonEmptyCallback: "non_empty_callback",
|
|
38
|
+
BuyEmptyCallback: "buy_empty_callback",
|
|
39
|
+
SellEmptyCallback: "sell_empty_callback",
|
|
40
|
+
};
|
|
@@ -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.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.
|
|
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
|
}
|