@morpho-dev/router 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +191 -39
- package/dist/index.browser.d.mts +44 -8
- package/dist/index.browser.d.mts.map +1 -1
- package/dist/index.browser.d.ts +44 -8
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +103 -13
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.mjs +103 -13
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.node.d.mts +51 -15
- package/dist/index.node.d.mts.map +1 -1
- package/dist/index.node.d.ts +51 -15
- package/dist/index.node.d.ts.map +1 -1
- package/dist/index.node.js +130 -25
- package/dist/index.node.js.map +1 -1
- package/dist/index.node.mjs +130 -25
- package/dist/index.node.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.node.mjs
CHANGED
|
@@ -5256,7 +5256,8 @@ var OfferListResponse = class extends SuccessResponse {};
|
|
|
5256
5256
|
__decorate([ApiProperty({
|
|
5257
5257
|
type: "string",
|
|
5258
5258
|
nullable: true,
|
|
5259
|
-
example: offerCursorExample
|
|
5259
|
+
example: offerCursorExample,
|
|
5260
|
+
description: "Pagination cursor. Offer hash (0x...) for maker queries; base64url-encoded cursor for obligation queries."
|
|
5260
5261
|
})], OfferListResponse.prototype, "cursor", void 0);
|
|
5261
5262
|
__decorate([ApiProperty({
|
|
5262
5263
|
type: () => [OfferListItemResponse],
|
|
@@ -5809,11 +5810,17 @@ const configRulesLoanTokenExample = {
|
|
|
5809
5810
|
chain_id: 1,
|
|
5810
5811
|
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
|
|
5811
5812
|
};
|
|
5813
|
+
const configRulesOracleExample = {
|
|
5814
|
+
type: "oracle",
|
|
5815
|
+
chain_id: 1,
|
|
5816
|
+
address: "0xDddd770BADd886dF3864029e4B377B5F6a2B6b83"
|
|
5817
|
+
};
|
|
5812
5818
|
const configRulesChecksumExample = "f1d2d2f924e986ac86fdf7b36c94bcdf";
|
|
5813
5819
|
const configRulesPayloadExample = [
|
|
5814
5820
|
configRulesMaturityExample,
|
|
5815
5821
|
configRulesCallbackExample,
|
|
5816
|
-
configRulesLoanTokenExample
|
|
5822
|
+
configRulesLoanTokenExample,
|
|
5823
|
+
configRulesOracleExample
|
|
5817
5824
|
];
|
|
5818
5825
|
const configContractNames = [
|
|
5819
5826
|
"mempool",
|
|
@@ -5964,7 +5971,7 @@ __decorate([
|
|
|
5964
5971
|
name: "types",
|
|
5965
5972
|
type: ["string"],
|
|
5966
5973
|
required: false,
|
|
5967
|
-
example: "maturity,loan_token",
|
|
5974
|
+
example: "maturity,loan_token,oracle",
|
|
5968
5975
|
description: "Filter by rule types (comma-separated).",
|
|
5969
5976
|
style: "form",
|
|
5970
5977
|
explode: false
|
|
@@ -6195,6 +6202,9 @@ function isValidBase64urlJson(val) {
|
|
|
6195
6202
|
return false;
|
|
6196
6203
|
}
|
|
6197
6204
|
}
|
|
6205
|
+
function isValidOfferHashCursor(val) {
|
|
6206
|
+
return /^0x[a-f0-9]{64}$/i.test(val);
|
|
6207
|
+
}
|
|
6198
6208
|
const csvArray = (schema) => z$1.preprocess((value) => {
|
|
6199
6209
|
if (value === void 0) return void 0;
|
|
6200
6210
|
if (Array.isArray(value)) {
|
|
@@ -6220,10 +6230,11 @@ const PaginationQueryParams = z$1.object({
|
|
|
6220
6230
|
const ConfigRuleTypes = z$1.enum([
|
|
6221
6231
|
"maturity",
|
|
6222
6232
|
"callback",
|
|
6223
|
-
"loan_token"
|
|
6233
|
+
"loan_token",
|
|
6234
|
+
"oracle"
|
|
6224
6235
|
]);
|
|
6225
6236
|
const GetConfigRulesQueryParams = z$1.object({
|
|
6226
|
-
cursor: z$1.string().regex(/^(maturity|callback|loan_token):[1-9]\d*:.+$/, { message: "Cursor must be in the format type:chain_id:<value>" }).optional().meta({
|
|
6237
|
+
cursor: z$1.string().regex(/^(maturity|callback|loan_token|oracle):[1-9]\d*:.+$/, { message: "Cursor must be in the format type:chain_id:<value>" }).optional().meta({
|
|
6227
6238
|
description: "Pagination cursor in type:chain_id:<value> format",
|
|
6228
6239
|
example: "maturity:1:1730415600:end_of_next_month"
|
|
6229
6240
|
}),
|
|
@@ -6233,7 +6244,7 @@ const GetConfigRulesQueryParams = z$1.object({
|
|
|
6233
6244
|
}),
|
|
6234
6245
|
types: csvArray(ConfigRuleTypes).meta({
|
|
6235
6246
|
description: "Filter by rule types (comma-separated).",
|
|
6236
|
-
example: "maturity,loan_token"
|
|
6247
|
+
example: "maturity,loan_token,oracle"
|
|
6237
6248
|
}),
|
|
6238
6249
|
chains: csvArray(z$1.string().regex(/^[1-9]\d*$/, { message: "Chain must be a positive integer" }).transform((val) => Number.parseInt(val, 10))).meta({
|
|
6239
6250
|
description: "Filter by chain IDs (comma-separated).",
|
|
@@ -6254,8 +6265,11 @@ const GetConfigContractsQueryParams = z$1.object({
|
|
|
6254
6265
|
example: "1,8453"
|
|
6255
6266
|
})
|
|
6256
6267
|
});
|
|
6257
|
-
const GetOffersQueryParams =
|
|
6258
|
-
|
|
6268
|
+
const GetOffersQueryParams = PaginationQueryParams.omit({ cursor: true }).extend({
|
|
6269
|
+
cursor: z$1.string().optional().meta({
|
|
6270
|
+
description: "Pagination cursor. Use offer hash (0x...) for maker queries, base64url for obligation queries.",
|
|
6271
|
+
example: "eyJzaWRlIjoic2VsbCIsImN1cnJlbnRQcmljZSI6IjEwMDAwMDAwMDAwMDAwMDAwMDAiLCJibG9ja051bWJlciI6MSwiYXNzZXRzIjoiMTAwMDAwMDAwMDAwMDAwMDAwMCIsImhhc2giOiIweGRmZDY4NTllM2UwODJkMTkzODlhMWFlYzFiZGFkN2U4ZDkyZDk2YjFhYTc5NDBkYTkxYTMxMjVkMzFlM2JlNWIiLCJ0b3RhbFJldHVybmVkIjoxMCwibm93IjoxNjAwMDAwMDAwfQ"
|
|
6272
|
+
}),
|
|
6259
6273
|
side: z$1.enum(["buy", "sell"]).optional().meta({
|
|
6260
6274
|
description: "Side of the offer. Required when using obligation_id.",
|
|
6261
6275
|
example: "buy"
|
|
@@ -6279,11 +6293,29 @@ const GetOffersQueryParams = z$1.object({
|
|
|
6279
6293
|
});
|
|
6280
6294
|
return;
|
|
6281
6295
|
}
|
|
6282
|
-
if (hasMaker)
|
|
6296
|
+
if (hasMaker) {
|
|
6297
|
+
if (val.cursor !== void 0 && !isValidOfferHashCursor(val.cursor)) ctx.addIssue({
|
|
6298
|
+
code: "custom",
|
|
6299
|
+
path: ["cursor"],
|
|
6300
|
+
message: "Cursor must be a 32-byte hex offer hash when filtering by maker"
|
|
6301
|
+
});
|
|
6302
|
+
return;
|
|
6303
|
+
}
|
|
6283
6304
|
if (!hasObligation || !hasSide) ctx.addIssue({
|
|
6284
6305
|
code: "custom",
|
|
6285
6306
|
message: "Must provide either maker or both obligation_id and side"
|
|
6286
6307
|
});
|
|
6308
|
+
if (val.cursor !== void 0 && !isValidBase64urlJson(val.cursor)) ctx.addIssue({
|
|
6309
|
+
code: "custom",
|
|
6310
|
+
path: ["cursor"],
|
|
6311
|
+
message: "Invalid cursor format. Must be a valid base64url-encoded cursor object"
|
|
6312
|
+
});
|
|
6313
|
+
}).transform((val) => {
|
|
6314
|
+
if (val.maker && val.cursor) return {
|
|
6315
|
+
...val,
|
|
6316
|
+
cursor: val.cursor.toLowerCase()
|
|
6317
|
+
};
|
|
6318
|
+
return val;
|
|
6287
6319
|
});
|
|
6288
6320
|
const GetObligationsQueryParams = z$1.object({
|
|
6289
6321
|
...PaginationQueryParams.shape,
|
|
@@ -6559,13 +6591,18 @@ const assets = {
|
|
|
6559
6591
|
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
6560
6592
|
"0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
6561
6593
|
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
6562
|
-
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
|
|
6594
|
+
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
|
|
6595
|
+
"0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",
|
|
6596
|
+
"0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
|
|
6563
6597
|
],
|
|
6564
6598
|
[ChainId.BASE.toString()]: [
|
|
6565
6599
|
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
6566
6600
|
"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
|
6567
6601
|
"0x4200000000000000000000000000000000000006",
|
|
6568
|
-
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
|
|
6602
|
+
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
|
|
6603
|
+
"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf",
|
|
6604
|
+
"0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452",
|
|
6605
|
+
"0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42"
|
|
6569
6606
|
],
|
|
6570
6607
|
[ChainId["ETHEREUM-VIRTUAL-TESTNET"].toString()]: [
|
|
6571
6608
|
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
@@ -6581,6 +6618,43 @@ const assets = {
|
|
|
6581
6618
|
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
|
|
6582
6619
|
]
|
|
6583
6620
|
};
|
|
6621
|
+
const oracles$1 = {
|
|
6622
|
+
[ChainId.ETHEREUM.toString()]: [
|
|
6623
|
+
"0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
|
|
6624
|
+
"0x9CB3f4276bcD149b3668e1a645a964bC12877b89",
|
|
6625
|
+
"0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2",
|
|
6626
|
+
"0x6Eb9F4128CeBc8B885A4d8562Db1Addf097f7348",
|
|
6627
|
+
"0xbD60A6770b27E084E8617335ddE769241B0e71D8",
|
|
6628
|
+
"0xAe12416c1F21B0698c27fe042D9309C83baC6597"
|
|
6629
|
+
],
|
|
6630
|
+
[ChainId.BASE.toString()]: [
|
|
6631
|
+
"0xD09048c8B568Dbf5f189302beA26c9edABFC4858",
|
|
6632
|
+
"0xFEa2D58cEfCb9fcb597723c6bAE66fFE4193aFE4",
|
|
6633
|
+
"0x05D2618404668D725B66c0f32B39e4EC15B393dC",
|
|
6634
|
+
"0xE1bb8E5b4930eC9FeC7f7943FCF6227649F14B37",
|
|
6635
|
+
"0x663BECd10daE6C4A3Dcd89F1d76c1174199639B9",
|
|
6636
|
+
"0x10b95702a0ce895972C91e432C4f7E19811D320E",
|
|
6637
|
+
"0x8C87DbD7A0c647A4291592Bc2994dbF95880fE2F",
|
|
6638
|
+
"0x4A11590e5326138B514E08A9B52202D42077Ca65",
|
|
6639
|
+
"0xa54122f0E0766258377Ffe732e454A3248f454F4"
|
|
6640
|
+
],
|
|
6641
|
+
[ChainId["ETHEREUM-VIRTUAL-TESTNET"].toString()]: [
|
|
6642
|
+
"0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
|
|
6643
|
+
"0x9CB3f4276bcD149b3668e1a645a964bC12877b89",
|
|
6644
|
+
"0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2",
|
|
6645
|
+
"0x6Eb9F4128CeBc8B885A4d8562Db1Addf097f7348",
|
|
6646
|
+
"0xbD60A6770b27E084E8617335ddE769241B0e71D8",
|
|
6647
|
+
"0xAe12416c1F21B0698c27fe042D9309C83baC6597"
|
|
6648
|
+
],
|
|
6649
|
+
[ChainId.ANVIL.toString()]: [
|
|
6650
|
+
"0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
|
|
6651
|
+
"0x9CB3f4276bcD149b3668e1a645a964bC12877b89",
|
|
6652
|
+
"0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2",
|
|
6653
|
+
"0x6Eb9F4128CeBc8B885A4d8562Db1Addf097f7348",
|
|
6654
|
+
"0xbD60A6770b27E084E8617335ddE769241B0e71D8",
|
|
6655
|
+
"0xAe12416c1F21B0698c27fe042D9309C83baC6597"
|
|
6656
|
+
]
|
|
6657
|
+
};
|
|
6584
6658
|
const configs = {
|
|
6585
6659
|
ethereum: {
|
|
6586
6660
|
callbacks: [
|
|
@@ -6647,7 +6721,7 @@ const configs = {
|
|
|
6647
6721
|
//#endregion
|
|
6648
6722
|
//#region src/gatekeeper/ConfigRules.ts
|
|
6649
6723
|
/**
|
|
6650
|
-
* Build the configured rules (maturities + callback addresses + loan tokens) for the provided chains.
|
|
6724
|
+
* Build the configured rules (maturities + callback addresses + loan tokens + oracles) for the provided chains.
|
|
6651
6725
|
* @param chains - Chains to include in the configured rules.
|
|
6652
6726
|
* @returns Sorted list of config rules.
|
|
6653
6727
|
*/
|
|
@@ -6679,6 +6753,12 @@ function buildConfigRules(chains) {
|
|
|
6679
6753
|
chain_id: chain.id,
|
|
6680
6754
|
address: normalizeAddress(address)
|
|
6681
6755
|
});
|
|
6756
|
+
const oracles = oracles$1[chain.id.toString()] ?? [];
|
|
6757
|
+
for (const address of oracles) rules.push({
|
|
6758
|
+
type: "oracle",
|
|
6759
|
+
chain_id: chain.id,
|
|
6760
|
+
address: normalizeAddress(address)
|
|
6761
|
+
});
|
|
6682
6762
|
}
|
|
6683
6763
|
rules.sort(compareConfigRules);
|
|
6684
6764
|
return rules;
|
|
@@ -6700,6 +6780,10 @@ function buildConfigRulesChecksum(rules) {
|
|
|
6700
6780
|
hash.update(`callback:${rule.chain_id}:${rule.callback_type}:${rule.address}\n`);
|
|
6701
6781
|
continue;
|
|
6702
6782
|
}
|
|
6783
|
+
if (rule.type === "oracle") {
|
|
6784
|
+
hash.update(`oracle:${rule.chain_id}:${rule.address}\n`);
|
|
6785
|
+
continue;
|
|
6786
|
+
}
|
|
6703
6787
|
hash.update(`loan_token:${rule.chain_id}:${rule.address}\n`);
|
|
6704
6788
|
}
|
|
6705
6789
|
return hash.digest("hex");
|
|
@@ -6716,6 +6800,7 @@ function compareConfigRules(left, right) {
|
|
|
6716
6800
|
return left.address.localeCompare(right.address);
|
|
6717
6801
|
}
|
|
6718
6802
|
if (left.type === "loan_token" && right.type === "loan_token") return left.address.localeCompare(right.address);
|
|
6803
|
+
if (left.type === "oracle" && right.type === "oracle") return left.address.localeCompare(right.address);
|
|
6719
6804
|
return 0;
|
|
6720
6805
|
}
|
|
6721
6806
|
|
|
@@ -6760,6 +6845,7 @@ async function getConfigRules(query, chains) {
|
|
|
6760
6845
|
function formatCursor(rule) {
|
|
6761
6846
|
if (rule.type === "maturity") return `maturity:${rule.chain_id}:${rule.timestamp}:${rule.name}`;
|
|
6762
6847
|
if (rule.type === "callback") return `callback:${rule.chain_id}:${rule.callback_type}:${rule.address.toLowerCase()}`;
|
|
6848
|
+
if (rule.type === "oracle") return `oracle:${rule.chain_id}:${rule.address.toLowerCase()}`;
|
|
6763
6849
|
return `loan_token:${rule.chain_id}:${rule.address.toLowerCase()}`;
|
|
6764
6850
|
}
|
|
6765
6851
|
function parseCursor(cursor) {
|
|
@@ -6792,13 +6878,16 @@ function parseCursor(cursor) {
|
|
|
6792
6878
|
address: parseAddress(addressValue, "Cursor address")
|
|
6793
6879
|
};
|
|
6794
6880
|
}
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6881
|
+
if (type === "loan_token" || type === "oracle") {
|
|
6882
|
+
const addressValue = rest.join(":");
|
|
6883
|
+
if (!addressValue) throw new BadRequestError(`Cursor must be in the format ${type}:chain_id:address`);
|
|
6884
|
+
return {
|
|
6885
|
+
type,
|
|
6886
|
+
chain_id,
|
|
6887
|
+
address: parseAddress(addressValue, "Cursor address")
|
|
6888
|
+
};
|
|
6889
|
+
}
|
|
6890
|
+
throw new BadRequestError("Cursor has an invalid rule type");
|
|
6802
6891
|
}
|
|
6803
6892
|
function findStartIndex(rules, cursor) {
|
|
6804
6893
|
let low = 0;
|
|
@@ -6816,7 +6905,7 @@ function parseAddress(address, label) {
|
|
|
6816
6905
|
return address.toLowerCase();
|
|
6817
6906
|
}
|
|
6818
6907
|
function isConfigRuleType(value) {
|
|
6819
|
-
return value === "maturity" || value === "callback" || value === "loan_token";
|
|
6908
|
+
return value === "maturity" || value === "callback" || value === "loan_token" || value === "oracle";
|
|
6820
6909
|
}
|
|
6821
6910
|
function isMaturityType(value) {
|
|
6822
6911
|
return Object.values(MaturityType).includes(value);
|
|
@@ -9280,9 +9369,9 @@ function create$5(db) {
|
|
|
9280
9369
|
blockNumber: r.blockNumber
|
|
9281
9370
|
}));
|
|
9282
9371
|
},
|
|
9283
|
-
upsert: async (oracles$
|
|
9284
|
-
if (oracles$
|
|
9285
|
-
const rows = oracles$
|
|
9372
|
+
upsert: async (oracles$2) => {
|
|
9373
|
+
if (oracles$2.length === 0) return;
|
|
9374
|
+
const rows = oracles$2.map((o) => ({
|
|
9286
9375
|
chainId: o.chainId,
|
|
9287
9376
|
address: o.address.toLowerCase(),
|
|
9288
9377
|
price: o.price !== null ? o.price.toString() : null,
|
|
@@ -10478,6 +10567,7 @@ var Rules_exports = /* @__PURE__ */ __exportAll({
|
|
|
10478
10567
|
callback: () => callback,
|
|
10479
10568
|
chains: () => chains,
|
|
10480
10569
|
maturity: () => maturity,
|
|
10570
|
+
oracle: () => oracle,
|
|
10481
10571
|
sameMaker: () => sameMaker,
|
|
10482
10572
|
token: () => token,
|
|
10483
10573
|
validity: () => validity
|
|
@@ -10616,6 +10706,16 @@ const token = ({ assetsByChainId }) => single("token", "Validates that offer loa
|
|
|
10616
10706
|
if (offer.collaterals.some((collateral) => !allowedAssets.includes(collateral.asset.toLowerCase()))) return { message: "Collateral is not allowed" };
|
|
10617
10707
|
});
|
|
10618
10708
|
/**
|
|
10709
|
+
* A validation rule that checks if the offer's oracle addresses are allowed for its chain.
|
|
10710
|
+
* @param oraclesByChainId - Allowed oracles indexed by chain id.
|
|
10711
|
+
* @returns The issue that was found. If the offer is valid, this will be undefined.
|
|
10712
|
+
*/
|
|
10713
|
+
const oracle = ({ oraclesByChainId }) => single("oracle", "Validates that offer collateral oracles are in the allowed oracle list for the offer chain", (offer) => {
|
|
10714
|
+
const allowedOracles = oraclesByChainId[offer.chainId]?.map((oracle) => oracle.toLowerCase());
|
|
10715
|
+
if (!allowedOracles || allowedOracles.length === 0) return { message: `No allowed oracles for chain ${offer.chainId}` };
|
|
10716
|
+
if (offer.collaterals.some((collateral) => !allowedOracles.includes(collateral.oracle.toLowerCase()))) return { message: "Oracle is not allowed" };
|
|
10717
|
+
});
|
|
10718
|
+
/**
|
|
10619
10719
|
* A batch validation rule that ensures all offers in a tree have the same maker address.
|
|
10620
10720
|
* Returns an issue only for the first non-conforming offer.
|
|
10621
10721
|
* This rule is signing-agnostic; signer verification is handled at the collector level.
|
|
@@ -10646,7 +10746,11 @@ const amountMutualExclusivity = () => single("amount_mutual_exclusivity", "Valid
|
|
|
10646
10746
|
//#region src/gatekeeper/morphoRules.ts
|
|
10647
10747
|
const morphoRules = (chains$3) => {
|
|
10648
10748
|
const assetsByChainId = {};
|
|
10649
|
-
|
|
10749
|
+
const oraclesByChainId = {};
|
|
10750
|
+
for (const chain of chains$3) {
|
|
10751
|
+
assetsByChainId[chain.id] = assets[chain.id.toString()] ?? [];
|
|
10752
|
+
oraclesByChainId[chain.id] = oracles$1[chain.id.toString()] ?? [];
|
|
10753
|
+
}
|
|
10650
10754
|
return [
|
|
10651
10755
|
sameMaker(),
|
|
10652
10756
|
amountMutualExclusivity(),
|
|
@@ -10660,7 +10764,8 @@ const morphoRules = (chains$3) => {
|
|
|
10660
10764
|
],
|
|
10661
10765
|
allowedAddresses: chains$3.flatMap((c) => getCallbackAddresses(c.name))
|
|
10662
10766
|
}),
|
|
10663
|
-
token({ assetsByChainId })
|
|
10767
|
+
token({ assetsByChainId }),
|
|
10768
|
+
oracle({ oraclesByChainId })
|
|
10664
10769
|
];
|
|
10665
10770
|
};
|
|
10666
10771
|
|