@morpho-dev/router 0.0.18 → 0.0.20
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/index.browser.d.cts +19 -19
- package/dist/index.browser.d.ts +19 -19
- package/dist/index.browser.js +186 -114
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.mjs +187 -115
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.node.d.cts +31 -31
- package/dist/index.node.d.ts +31 -31
- package/dist/index.node.js +186 -114
- package/dist/index.node.js.map +1 -1
- package/dist/index.node.mjs +188 -116
- package/dist/index.node.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.node.js
CHANGED
|
@@ -5,6 +5,7 @@ var chains$1 = require('viem/chains');
|
|
|
5
5
|
var v4 = require('zod/v4');
|
|
6
6
|
var zodOpenapi = require('zod-openapi');
|
|
7
7
|
var viem = require('viem');
|
|
8
|
+
var jsBase64 = require('js-base64');
|
|
8
9
|
var nodeServer = require('@hono/node-server');
|
|
9
10
|
var hono = require('hono');
|
|
10
11
|
var fs = require('fs');
|
|
@@ -8256,8 +8257,6 @@ function* batch(array, batchSize) {
|
|
|
8256
8257
|
yield array.slice(i, i + batchSize);
|
|
8257
8258
|
}
|
|
8258
8259
|
}
|
|
8259
|
-
|
|
8260
|
-
// src/utils/cursor.ts
|
|
8261
8260
|
function validateCursor(cursor) {
|
|
8262
8261
|
if (!cursor || typeof cursor !== "object") {
|
|
8263
8262
|
throw new Error("Cursor must be an object");
|
|
@@ -8328,11 +8327,11 @@ function validateCursor(cursor) {
|
|
|
8328
8327
|
return true;
|
|
8329
8328
|
}
|
|
8330
8329
|
function encodeCursor(c) {
|
|
8331
|
-
return
|
|
8330
|
+
return jsBase64.Base64.encodeURL(JSON.stringify(c));
|
|
8332
8331
|
}
|
|
8333
8332
|
function decodeCursor(token) {
|
|
8334
8333
|
if (!token) return null;
|
|
8335
|
-
const decoded = JSON.parse(
|
|
8334
|
+
const decoded = JSON.parse(jsBase64.Base64.decode(token));
|
|
8336
8335
|
validateCursor(decoded);
|
|
8337
8336
|
return decoded;
|
|
8338
8337
|
}
|
|
@@ -8444,19 +8443,33 @@ var GetOffersQueryParams = v4.z.object({
|
|
|
8444
8443
|
example: "1500000000000000000"
|
|
8445
8444
|
}),
|
|
8446
8445
|
// Time range
|
|
8447
|
-
min_maturity: v4.z.
|
|
8448
|
-
|
|
8449
|
-
|
|
8450
|
-
|
|
8451
|
-
|
|
8452
|
-
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
|
|
8446
|
+
min_maturity: v4.z.coerce.number().int().positive().transform((maturity, ctx) => {
|
|
8447
|
+
try {
|
|
8448
|
+
return mempool.Maturity.from(maturity);
|
|
8449
|
+
} catch (e) {
|
|
8450
|
+
ctx.addIssue({
|
|
8451
|
+
code: "custom",
|
|
8452
|
+
message: e.message
|
|
8453
|
+
});
|
|
8454
|
+
return v4.z.NEVER;
|
|
8455
|
+
}
|
|
8456
|
+
}).optional(),
|
|
8457
|
+
max_maturity: v4.z.coerce.number().int().positive().transform((maturity, ctx) => {
|
|
8458
|
+
try {
|
|
8459
|
+
return mempool.Maturity.from(maturity);
|
|
8460
|
+
} catch (e) {
|
|
8461
|
+
ctx.addIssue({
|
|
8462
|
+
code: "custom",
|
|
8463
|
+
message: e.message
|
|
8464
|
+
});
|
|
8465
|
+
return v4.z.NEVER;
|
|
8466
|
+
}
|
|
8467
|
+
}).optional(),
|
|
8468
|
+
min_expiry: v4.z.coerce.number().int().optional().meta({
|
|
8456
8469
|
description: "Minimum expiry timestamp (Unix timestamp in seconds)",
|
|
8457
8470
|
example: "1700000000"
|
|
8458
8471
|
}),
|
|
8459
|
-
max_expiry: v4.z.
|
|
8472
|
+
max_expiry: v4.z.coerce.number().int().optional().meta({
|
|
8460
8473
|
description: "Maximum expiry timestamp (Unix timestamp in seconds)",
|
|
8461
8474
|
example: "1800000000"
|
|
8462
8475
|
}),
|
|
@@ -8478,51 +8491,81 @@ var GetOffersQueryParams = v4.z.object({
|
|
|
8478
8491
|
{
|
|
8479
8492
|
message: "Collateral tuple must be in format: asset:oracle:lltv#asset2:oracle2:lltv2. Oracle and lltv are optional. Asset must be 0x + 40 hex chars, oracle must be 0x + 40 hex chars, lltv must be a number (e.g., 80.5)."
|
|
8480
8493
|
}
|
|
8481
|
-
).transform((val) => {
|
|
8494
|
+
).transform((val, ctx) => {
|
|
8482
8495
|
return val.split("#").map((tuple) => {
|
|
8483
8496
|
const parts = tuple.split(":");
|
|
8484
8497
|
if (parts.length === 0 || !parts[0]) {
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
]);
|
|
8498
|
+
ctx.addIssue({
|
|
8499
|
+
code: "custom",
|
|
8500
|
+
message: "Asset address is required for each collateral tuple",
|
|
8501
|
+
path: ["asset"],
|
|
8502
|
+
input: val
|
|
8503
|
+
});
|
|
8504
|
+
return v4.z.NEVER;
|
|
8493
8505
|
}
|
|
8494
8506
|
const asset = parts[0]?.toLowerCase();
|
|
8495
8507
|
const oracle = parts[1]?.toLowerCase();
|
|
8496
8508
|
const lltv = parts[2] ? parseFloat(parts[2]) : void 0;
|
|
8497
8509
|
if (lltv !== void 0 && (lltv < MIN_LLTV || lltv > MAX_LLTV)) {
|
|
8498
|
-
|
|
8499
|
-
|
|
8510
|
+
ctx.addIssue({
|
|
8511
|
+
code: "custom",
|
|
8512
|
+
message: `LLTV must be between ${MIN_LLTV} and ${MAX_LLTV} (0-100%)`,
|
|
8513
|
+
path: ["lltv"],
|
|
8514
|
+
input: val
|
|
8515
|
+
});
|
|
8516
|
+
return v4.z.NEVER;
|
|
8517
|
+
}
|
|
8518
|
+
let lltvValue;
|
|
8519
|
+
if (lltv !== void 0) {
|
|
8520
|
+
try {
|
|
8521
|
+
lltvValue = mempool.LLTV.from(viem.parseUnits(lltv.toString(), 16));
|
|
8522
|
+
} catch (e) {
|
|
8523
|
+
ctx.issues.push({
|
|
8500
8524
|
code: "custom",
|
|
8501
|
-
message:
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
}
|
|
8505
|
-
|
|
8525
|
+
message: e instanceof mempool.LLTV.InvalidLLTVError || e instanceof mempool.LLTV.InvalidOptionError ? e.message : "Invalid LLTV.",
|
|
8526
|
+
input: lltv,
|
|
8527
|
+
path: ["lltv"]
|
|
8528
|
+
});
|
|
8529
|
+
return v4.z.NEVER;
|
|
8530
|
+
}
|
|
8506
8531
|
}
|
|
8507
8532
|
return {
|
|
8508
8533
|
asset,
|
|
8509
8534
|
oracle,
|
|
8510
|
-
lltv
|
|
8535
|
+
lltv: lltvValue
|
|
8511
8536
|
};
|
|
8512
8537
|
});
|
|
8513
8538
|
}).optional().meta({
|
|
8514
8539
|
description: "Filter by collateral combinations in format: asset:oracle:lltv#asset2:oracle2:lltv2. Oracle and lltv are optional. Use # to separate multiple combinations.",
|
|
8515
|
-
example: "0x1234567890123456789012345678901234567890:0xabcdefabcdefabcdefabcdefabcdefabcdefabcd:
|
|
8540
|
+
example: "0x1234567890123456789012345678901234567890:0xabcdefabcdefabcdefabcdefabcdefabcdefabcd:86#0x9876543210987654321098765432109876543210:94.5"
|
|
8516
8541
|
}),
|
|
8517
|
-
min_lltv: v4.z.
|
|
8518
|
-
|
|
8519
|
-
|
|
8542
|
+
min_lltv: v4.z.coerce.number().min(0, { message: "LLTV must be above 0" }).max(100, { message: "LLTV must be below 100" }).transform((lltv, ctx) => {
|
|
8543
|
+
try {
|
|
8544
|
+
return mempool.LLTV.from(viem.parseUnits(lltv.toString(), 16));
|
|
8545
|
+
} catch (e) {
|
|
8546
|
+
ctx.addIssue({
|
|
8547
|
+
code: "custom",
|
|
8548
|
+
message: e.message,
|
|
8549
|
+
input: lltv
|
|
8550
|
+
});
|
|
8551
|
+
return v4.z.NEVER;
|
|
8552
|
+
}
|
|
8553
|
+
}).optional().meta({
|
|
8520
8554
|
description: "Minimum Loan-to-Value ratio (LLTV) for collateral (percentage as decimal, e.g., 80.5 = 80.5%)",
|
|
8521
8555
|
example: "80.5"
|
|
8522
8556
|
}),
|
|
8523
|
-
max_lltv: v4.z.
|
|
8524
|
-
|
|
8525
|
-
|
|
8557
|
+
max_lltv: v4.z.coerce.number().min(0, { message: "LLTV must be above 0" }).max(100, { message: "LLTV must be below 100" }).transform((lltv, ctx) => {
|
|
8558
|
+
try {
|
|
8559
|
+
return mempool.LLTV.from(viem.parseUnits(lltv.toString(), 16));
|
|
8560
|
+
} catch (e) {
|
|
8561
|
+
ctx.addIssue({
|
|
8562
|
+
code: "custom",
|
|
8563
|
+
message: e.message,
|
|
8564
|
+
input: lltv
|
|
8565
|
+
});
|
|
8566
|
+
return v4.z.NEVER;
|
|
8567
|
+
}
|
|
8568
|
+
}).optional().meta({
|
|
8526
8569
|
description: "Maximum Loan-to-Value ratio (LLTV) for collateral (percentage as decimal, e.g., 95.5 = 95.5%)",
|
|
8527
8570
|
example: "95.5"
|
|
8528
8571
|
}),
|
|
@@ -8615,68 +8658,89 @@ var MatchOffersQueryParams = v4.z.object({
|
|
|
8615
8658
|
}),
|
|
8616
8659
|
// Collateral filtering
|
|
8617
8660
|
collaterals: v4.z.string().regex(
|
|
8618
|
-
/^(0x[a-fA-F0-9]{40}:0x[a-fA-F0-9]{40}
|
|
8661
|
+
/^(0x[a-fA-F0-9]{40}:0x[a-fA-F0-9]{40}:[0-9]+(\.[0-9]+)?)(#0x[a-fA-F0-9]{40}:0x[a-fA-F0-9]{40}:[0-9]+(\.[0-9]+)?)*$/,
|
|
8619
8662
|
{
|
|
8620
8663
|
message: "Collaterals must be in format: asset:oracle:lltv#asset2:oracle2:lltv2. All fields are required for each collateral."
|
|
8621
8664
|
}
|
|
8622
|
-
).transform((val) => {
|
|
8665
|
+
).transform((val, ctx) => {
|
|
8623
8666
|
return val.split("#").map((collateral) => {
|
|
8624
8667
|
const parts = collateral.split(":");
|
|
8625
8668
|
if (parts.length !== 3) {
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
]);
|
|
8669
|
+
ctx.addIssue({
|
|
8670
|
+
code: "custom",
|
|
8671
|
+
message: "Each collateral must have exactly 3 parts: asset:oracle:lltv",
|
|
8672
|
+
path: ["collaterals"],
|
|
8673
|
+
input: val
|
|
8674
|
+
});
|
|
8675
|
+
return v4.z.NEVER;
|
|
8634
8676
|
}
|
|
8635
8677
|
const [asset, oracle, lltvStr] = parts;
|
|
8636
8678
|
if (!asset || !oracle || !lltvStr) {
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
|
|
8640
|
-
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
}
|
|
8644
|
-
]);
|
|
8679
|
+
ctx.addIssue({
|
|
8680
|
+
code: "custom",
|
|
8681
|
+
message: "Asset, oracle, and lltv are all required for each collateral",
|
|
8682
|
+
path: ["collaterals"],
|
|
8683
|
+
input: val
|
|
8684
|
+
});
|
|
8645
8685
|
}
|
|
8646
|
-
|
|
8647
|
-
if (
|
|
8648
|
-
|
|
8649
|
-
|
|
8686
|
+
let lltvValue;
|
|
8687
|
+
if (lltvStr !== void 0) {
|
|
8688
|
+
try {
|
|
8689
|
+
lltvValue = mempool.LLTV.from(viem.parseUnits(lltvStr, 16));
|
|
8690
|
+
} catch (e) {
|
|
8691
|
+
ctx.issues.push({
|
|
8650
8692
|
code: "custom",
|
|
8651
|
-
message:
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
}
|
|
8655
|
-
|
|
8693
|
+
message: e instanceof mempool.LLTV.InvalidLLTVError || e instanceof mempool.LLTV.InvalidOptionError ? e.message : "Invalid LLTV.",
|
|
8694
|
+
input: lltvStr,
|
|
8695
|
+
path: ["lltv"]
|
|
8696
|
+
});
|
|
8697
|
+
return v4.z.NEVER;
|
|
8698
|
+
}
|
|
8656
8699
|
}
|
|
8657
8700
|
return {
|
|
8658
8701
|
asset: asset.toLowerCase(),
|
|
8659
8702
|
oracle: oracle.toLowerCase(),
|
|
8660
|
-
lltv
|
|
8703
|
+
lltv: lltvValue
|
|
8661
8704
|
};
|
|
8662
8705
|
});
|
|
8663
8706
|
}).optional().meta({
|
|
8664
8707
|
description: "Collateral requirements in format: asset:oracle:lltv#asset2:oracle2:lltv2. Use # to separate multiple collaterals.",
|
|
8665
|
-
example: "0x1234567890123456789012345678901234567890:0xabcdefabcdefabcdefabcdefabcdefabcdefabcd:
|
|
8708
|
+
example: "0x1234567890123456789012345678901234567890:0xabcdefabcdefabcdefabcdefabcdefabcdefabcd:86#0x9876543210987654321098765432109876543210:0xfedcbafedcbafedcbafedcbafedcbafedcbafedc:94.5"
|
|
8666
8709
|
}),
|
|
8667
8710
|
// Maturity filtering
|
|
8668
|
-
maturity: v4.z.
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
|
|
8673
|
-
|
|
8674
|
-
|
|
8675
|
-
|
|
8676
|
-
|
|
8677
|
-
|
|
8678
|
-
|
|
8679
|
-
|
|
8711
|
+
maturity: v4.z.coerce.number().int().positive().transform((maturity, ctx) => {
|
|
8712
|
+
try {
|
|
8713
|
+
return mempool.Maturity.from(maturity);
|
|
8714
|
+
} catch (e) {
|
|
8715
|
+
ctx.addIssue({
|
|
8716
|
+
code: "custom",
|
|
8717
|
+
message: e.message
|
|
8718
|
+
});
|
|
8719
|
+
return v4.z.NEVER;
|
|
8720
|
+
}
|
|
8721
|
+
}).optional(),
|
|
8722
|
+
min_maturity: v4.z.coerce.number().int().positive().transform((maturity, ctx) => {
|
|
8723
|
+
try {
|
|
8724
|
+
return mempool.Maturity.from(maturity);
|
|
8725
|
+
} catch (e) {
|
|
8726
|
+
ctx.addIssue({
|
|
8727
|
+
code: "custom",
|
|
8728
|
+
message: e.message
|
|
8729
|
+
});
|
|
8730
|
+
return v4.z.NEVER;
|
|
8731
|
+
}
|
|
8732
|
+
}).optional(),
|
|
8733
|
+
max_maturity: v4.z.coerce.number().int().positive().transform((maturity, ctx) => {
|
|
8734
|
+
try {
|
|
8735
|
+
return mempool.Maturity.from(maturity);
|
|
8736
|
+
} catch (e) {
|
|
8737
|
+
ctx.addIssue({
|
|
8738
|
+
code: "custom",
|
|
8739
|
+
message: e.message
|
|
8740
|
+
});
|
|
8741
|
+
return v4.z.NEVER;
|
|
8742
|
+
}
|
|
8743
|
+
}).optional(),
|
|
8680
8744
|
// Asset and creator filtering
|
|
8681
8745
|
loan_token: v4.z.string().regex(/^0x[a-fA-F0-9]{40}$/, {
|
|
8682
8746
|
message: "Loan asset must be a valid Ethereum address"
|
|
@@ -8741,8 +8805,10 @@ var schemas = {
|
|
|
8741
8805
|
function parse(action, query) {
|
|
8742
8806
|
return schemas[action].parse(query);
|
|
8743
8807
|
}
|
|
8744
|
-
function safeParse(action, query) {
|
|
8745
|
-
return schemas[action].safeParse(query
|
|
8808
|
+
function safeParse(action, query, error) {
|
|
8809
|
+
return schemas[action].safeParse(query, {
|
|
8810
|
+
error
|
|
8811
|
+
});
|
|
8746
8812
|
}
|
|
8747
8813
|
|
|
8748
8814
|
// src/core/apiSchema/openapi.ts
|
|
@@ -8794,7 +8860,7 @@ var paths = {
|
|
|
8794
8860
|
}
|
|
8795
8861
|
}
|
|
8796
8862
|
},
|
|
8797
|
-
"/v1/match
|
|
8863
|
+
"/v1/offers/match": {
|
|
8798
8864
|
get: {
|
|
8799
8865
|
summary: "Match offers",
|
|
8800
8866
|
description: "Find offers that match specific criteria",
|
|
@@ -8957,16 +9023,16 @@ async function get(config, parameters) {
|
|
|
8957
9023
|
} else if (lltv !== void 0) {
|
|
8958
9024
|
result += `:`;
|
|
8959
9025
|
}
|
|
8960
|
-
if (lltv !== void 0) result += `:${lltv}`;
|
|
9026
|
+
if (lltv !== void 0) result += `:${viem.formatUnits(lltv, 16)}`;
|
|
8961
9027
|
return result;
|
|
8962
9028
|
}).join("#");
|
|
8963
9029
|
url.searchParams.set("collateral_tuple", tupleStr);
|
|
8964
9030
|
}
|
|
8965
9031
|
if (parameters.minLltv !== void 0) {
|
|
8966
|
-
url.searchParams.set("min_lltv", parameters.minLltv
|
|
9032
|
+
url.searchParams.set("min_lltv", viem.formatUnits(parameters.minLltv, 16));
|
|
8967
9033
|
}
|
|
8968
9034
|
if (parameters.maxLltv !== void 0) {
|
|
8969
|
-
url.searchParams.set("max_lltv", parameters.maxLltv
|
|
9035
|
+
url.searchParams.set("max_lltv", viem.formatUnits(parameters.maxLltv, 16));
|
|
8970
9036
|
}
|
|
8971
9037
|
if (parameters.sortBy) {
|
|
8972
9038
|
url.searchParams.set("sort_by", parameters.sortBy);
|
|
@@ -8988,14 +9054,14 @@ async function get(config, parameters) {
|
|
|
8988
9054
|
};
|
|
8989
9055
|
}
|
|
8990
9056
|
async function match(config, parameters) {
|
|
8991
|
-
const url = new URL(`${config.url.toString()}v1/match
|
|
9057
|
+
const url = new URL(`${config.url.toString()}v1/offers/match`);
|
|
8992
9058
|
url.searchParams.set("side", parameters.side);
|
|
8993
9059
|
url.searchParams.set("chain_id", parameters.chainId.toString());
|
|
8994
9060
|
if (parameters.rate !== void 0) {
|
|
8995
9061
|
url.searchParams.set("rate", parameters.rate.toString());
|
|
8996
9062
|
}
|
|
8997
9063
|
if (parameters.collaterals?.length) {
|
|
8998
|
-
const collateralsStr = parameters.collaterals.map(({ asset, oracle, lltv }) => `${asset}:${oracle}:${lltv}`).join("#");
|
|
9064
|
+
const collateralsStr = parameters.collaterals.map(({ asset, oracle, lltv }) => `${asset}:${oracle}:${viem.formatUnits(lltv, 16)}`).join("#");
|
|
8999
9065
|
url.searchParams.set("collaterals", collateralsStr);
|
|
9000
9066
|
}
|
|
9001
9067
|
if (parameters.maturity !== void 0) {
|
|
@@ -9033,12 +9099,12 @@ async function getApi(config, url) {
|
|
|
9033
9099
|
const pathname = url.pathname;
|
|
9034
9100
|
let action;
|
|
9035
9101
|
switch (true) {
|
|
9102
|
+
case pathname.includes("/v1/offers/match"):
|
|
9103
|
+
action = "match_offers";
|
|
9104
|
+
break;
|
|
9036
9105
|
case pathname.includes("/v1/offers"):
|
|
9037
9106
|
action = "get_offers";
|
|
9038
9107
|
break;
|
|
9039
|
-
case pathname.includes("/v1/match-offers"):
|
|
9040
|
-
action = "match_offers";
|
|
9041
|
-
break;
|
|
9042
9108
|
default:
|
|
9043
9109
|
throw new HttpGetOffersFailedError("Unknown endpoint", {
|
|
9044
9110
|
details: `Unsupported path: ${pathname}`
|
|
@@ -9249,6 +9315,7 @@ function memory(parameters) {
|
|
|
9249
9315
|
}
|
|
9250
9316
|
creators && (creators = creators.map((c) => c.toLowerCase()));
|
|
9251
9317
|
loanTokens && (loanTokens = loanTokens.map((lt) => lt.toLowerCase()));
|
|
9318
|
+
callbackAddresses && (callbackAddresses = callbackAddresses.map((ca) => ca.toLowerCase()));
|
|
9252
9319
|
collateralAssets && (collateralAssets = collateralAssets.map((ca) => ca.toLowerCase()));
|
|
9253
9320
|
collateralOracles && (collateralOracles = collateralOracles.map((co) => co.toLowerCase()));
|
|
9254
9321
|
collateralTuple && (collateralTuple = collateralTuple.map((ct) => ({
|
|
@@ -9285,12 +9352,8 @@ function memory(parameters) {
|
|
|
9285
9352
|
)
|
|
9286
9353
|
)
|
|
9287
9354
|
));
|
|
9288
|
-
minLltv && (offers = offers.filter(
|
|
9289
|
-
|
|
9290
|
-
));
|
|
9291
|
-
maxLltv && (offers = offers.filter(
|
|
9292
|
-
(o) => o.collaterals.every((c) => c.lltv <= mempool.LLTV.from(viem.parseUnits(maxLltv.toString(), 16)))
|
|
9293
|
-
));
|
|
9355
|
+
minLltv && (offers = offers.filter((o) => o.collaterals.every((c) => c.lltv >= minLltv)));
|
|
9356
|
+
maxLltv && (offers = offers.filter((o) => o.collaterals.every((c) => c.lltv <= maxLltv)));
|
|
9294
9357
|
offers = offers.sort((a, b) => sort(sortBy, sortOrder, a, b));
|
|
9295
9358
|
let nextCursor = null;
|
|
9296
9359
|
if (offers.length > limit) {
|
|
@@ -9337,8 +9400,8 @@ function memory(parameters) {
|
|
|
9337
9400
|
limit = 20
|
|
9338
9401
|
} = params;
|
|
9339
9402
|
const now = mempool.Time.now();
|
|
9340
|
-
const
|
|
9341
|
-
const sortOrder =
|
|
9403
|
+
const isBuying = side === "buy";
|
|
9404
|
+
const sortOrder = isBuying ? "desc" : "asc";
|
|
9342
9405
|
let offers = Array.from(map.values()).map((o) => ({
|
|
9343
9406
|
...o,
|
|
9344
9407
|
consumed: filled.get(o.chainId)?.get(o.offering.toLowerCase())?.get(o.nonce) || 0n
|
|
@@ -9351,22 +9414,27 @@ function memory(parameters) {
|
|
|
9351
9414
|
offers = offers.filter(
|
|
9352
9415
|
(o) => sortOrder === "asc" ? o.rate >= BigInt(cursor.rate) : o.rate <= BigInt(cursor.rate)
|
|
9353
9416
|
);
|
|
9354
|
-
offers = offers.filter((o) => o.hash !== cursor.hash);
|
|
9355
9417
|
}
|
|
9356
|
-
offers = offers.filter((o) => o.buy ===
|
|
9418
|
+
offers = offers.filter((o) => o.buy === !isBuying);
|
|
9357
9419
|
offers = offers.filter((o) => o.chainId === BigInt(chainId));
|
|
9358
9420
|
offers = offers.filter((o) => o.expiry >= now);
|
|
9359
|
-
rate && (offers = offers.filter((o) =>
|
|
9421
|
+
rate && (offers = offers.filter((o) => isBuying ? o.rate >= rate : o.rate <= rate));
|
|
9360
9422
|
collaterals.length > 0 && (offers = offers.filter(
|
|
9361
|
-
(o) =>
|
|
9362
|
-
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
9366
|
-
|
|
9367
|
-
|
|
9368
|
-
|
|
9369
|
-
|
|
9423
|
+
(o) => isBuying ? (
|
|
9424
|
+
// when wanting to buy, sell offer collaterals ⊆ user buy collaterals
|
|
9425
|
+
o.collaterals.every((oc) => {
|
|
9426
|
+
return collaterals.some(
|
|
9427
|
+
(c) => oc.asset.toLowerCase() === c.asset.toLowerCase() && oc.oracle.toLowerCase() === c.oracle.toLowerCase() && oc.lltv === c.lltv
|
|
9428
|
+
);
|
|
9429
|
+
})
|
|
9430
|
+
) : (
|
|
9431
|
+
// when wanting to sell, user sell collaterals ⊆ buy offer collaterals
|
|
9432
|
+
collaterals.every((c) => {
|
|
9433
|
+
return o.collaterals.some(
|
|
9434
|
+
(oc) => oc.asset.toLowerCase() === c.asset.toLowerCase() && oc.oracle.toLowerCase() === c.oracle.toLowerCase() && oc.lltv === c.lltv
|
|
9435
|
+
);
|
|
9436
|
+
})
|
|
9437
|
+
)
|
|
9370
9438
|
));
|
|
9371
9439
|
maturity && (offers = offers.filter((o) => o.maturity === maturity));
|
|
9372
9440
|
minMaturity && (offers = offers.filter((o) => o.maturity >= minMaturity));
|
|
@@ -9404,6 +9472,7 @@ function memory(parameters) {
|
|
|
9404
9472
|
}
|
|
9405
9473
|
offers = Array.from(byGroup.values());
|
|
9406
9474
|
offers = offers.sort((a, b) => sort("rate", sortOrder, a, b));
|
|
9475
|
+
cursor && (offers = offers.filter((o) => o.hash !== cursor.hash));
|
|
9407
9476
|
let nextCursor = null;
|
|
9408
9477
|
if (offers.length > limit) {
|
|
9409
9478
|
const last = offers[limit - 1];
|
|
@@ -9436,9 +9505,12 @@ function memory(parameters) {
|
|
|
9436
9505
|
return deleted;
|
|
9437
9506
|
},
|
|
9438
9507
|
updateStatus: async (parameters2) => {
|
|
9439
|
-
|
|
9440
|
-
map.
|
|
9441
|
-
|
|
9508
|
+
const key = parameters2.offerHash.toLowerCase();
|
|
9509
|
+
const existing = map.get(key);
|
|
9510
|
+
if (!existing) return;
|
|
9511
|
+
if (existing.status === parameters2.status) return;
|
|
9512
|
+
map.set(key, {
|
|
9513
|
+
...existing,
|
|
9442
9514
|
status: parameters2.status,
|
|
9443
9515
|
metadata: parameters2.metadata
|
|
9444
9516
|
});
|
|
@@ -9504,7 +9576,7 @@ async function serve(parameters) {
|
|
|
9504
9576
|
return mempool.Mempool.error(err, c);
|
|
9505
9577
|
}
|
|
9506
9578
|
});
|
|
9507
|
-
app.get("/v1/match
|
|
9579
|
+
app.get("/v1/offers/match", async (c) => {
|
|
9508
9580
|
try {
|
|
9509
9581
|
const params = parse("match_offers", c.req.query());
|
|
9510
9582
|
const offers = await store.findMatchingOffers({
|