@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.browser.js
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
var mempool = require('@morpho-dev/mempool');
|
|
4
4
|
var chains$1 = require('viem/chains');
|
|
5
|
+
var viem = require('viem');
|
|
5
6
|
var v4 = require('zod/v4');
|
|
6
7
|
var zodOpenapi = require('zod-openapi');
|
|
7
|
-
var
|
|
8
|
+
var jsBase64 = require('js-base64');
|
|
8
9
|
|
|
9
10
|
var __defProp = Object.defineProperty;
|
|
10
11
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -157,8 +158,6 @@ function* batch(array, batchSize) {
|
|
|
157
158
|
yield array.slice(i, i + batchSize);
|
|
158
159
|
}
|
|
159
160
|
}
|
|
160
|
-
|
|
161
|
-
// src/utils/cursor.ts
|
|
162
161
|
function validateCursor(cursor) {
|
|
163
162
|
if (!cursor || typeof cursor !== "object") {
|
|
164
163
|
throw new Error("Cursor must be an object");
|
|
@@ -229,11 +228,11 @@ function validateCursor(cursor) {
|
|
|
229
228
|
return true;
|
|
230
229
|
}
|
|
231
230
|
function encodeCursor(c) {
|
|
232
|
-
return
|
|
231
|
+
return jsBase64.Base64.encodeURL(JSON.stringify(c));
|
|
233
232
|
}
|
|
234
233
|
function decodeCursor(token) {
|
|
235
234
|
if (!token) return null;
|
|
236
|
-
const decoded = JSON.parse(
|
|
235
|
+
const decoded = JSON.parse(jsBase64.Base64.decode(token));
|
|
237
236
|
validateCursor(decoded);
|
|
238
237
|
return decoded;
|
|
239
238
|
}
|
|
@@ -345,19 +344,33 @@ var GetOffersQueryParams = v4.z.object({
|
|
|
345
344
|
example: "1500000000000000000"
|
|
346
345
|
}),
|
|
347
346
|
// Time range
|
|
348
|
-
min_maturity: v4.z.
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
347
|
+
min_maturity: v4.z.coerce.number().int().positive().transform((maturity, ctx) => {
|
|
348
|
+
try {
|
|
349
|
+
return mempool.Maturity.from(maturity);
|
|
350
|
+
} catch (e) {
|
|
351
|
+
ctx.addIssue({
|
|
352
|
+
code: "custom",
|
|
353
|
+
message: e.message
|
|
354
|
+
});
|
|
355
|
+
return v4.z.NEVER;
|
|
356
|
+
}
|
|
357
|
+
}).optional(),
|
|
358
|
+
max_maturity: v4.z.coerce.number().int().positive().transform((maturity, ctx) => {
|
|
359
|
+
try {
|
|
360
|
+
return mempool.Maturity.from(maturity);
|
|
361
|
+
} catch (e) {
|
|
362
|
+
ctx.addIssue({
|
|
363
|
+
code: "custom",
|
|
364
|
+
message: e.message
|
|
365
|
+
});
|
|
366
|
+
return v4.z.NEVER;
|
|
367
|
+
}
|
|
368
|
+
}).optional(),
|
|
369
|
+
min_expiry: v4.z.coerce.number().int().optional().meta({
|
|
357
370
|
description: "Minimum expiry timestamp (Unix timestamp in seconds)",
|
|
358
371
|
example: "1700000000"
|
|
359
372
|
}),
|
|
360
|
-
max_expiry: v4.z.
|
|
373
|
+
max_expiry: v4.z.coerce.number().int().optional().meta({
|
|
361
374
|
description: "Maximum expiry timestamp (Unix timestamp in seconds)",
|
|
362
375
|
example: "1800000000"
|
|
363
376
|
}),
|
|
@@ -379,51 +392,81 @@ var GetOffersQueryParams = v4.z.object({
|
|
|
379
392
|
{
|
|
380
393
|
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)."
|
|
381
394
|
}
|
|
382
|
-
).transform((val) => {
|
|
395
|
+
).transform((val, ctx) => {
|
|
383
396
|
return val.split("#").map((tuple) => {
|
|
384
397
|
const parts = tuple.split(":");
|
|
385
398
|
if (parts.length === 0 || !parts[0]) {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
]);
|
|
399
|
+
ctx.addIssue({
|
|
400
|
+
code: "custom",
|
|
401
|
+
message: "Asset address is required for each collateral tuple",
|
|
402
|
+
path: ["asset"],
|
|
403
|
+
input: val
|
|
404
|
+
});
|
|
405
|
+
return v4.z.NEVER;
|
|
394
406
|
}
|
|
395
407
|
const asset = parts[0]?.toLowerCase();
|
|
396
408
|
const oracle = parts[1]?.toLowerCase();
|
|
397
409
|
const lltv = parts[2] ? parseFloat(parts[2]) : void 0;
|
|
398
410
|
if (lltv !== void 0 && (lltv < MIN_LLTV || lltv > MAX_LLTV)) {
|
|
399
|
-
|
|
400
|
-
|
|
411
|
+
ctx.addIssue({
|
|
412
|
+
code: "custom",
|
|
413
|
+
message: `LLTV must be between ${MIN_LLTV} and ${MAX_LLTV} (0-100%)`,
|
|
414
|
+
path: ["lltv"],
|
|
415
|
+
input: val
|
|
416
|
+
});
|
|
417
|
+
return v4.z.NEVER;
|
|
418
|
+
}
|
|
419
|
+
let lltvValue;
|
|
420
|
+
if (lltv !== void 0) {
|
|
421
|
+
try {
|
|
422
|
+
lltvValue = mempool.LLTV.from(viem.parseUnits(lltv.toString(), 16));
|
|
423
|
+
} catch (e) {
|
|
424
|
+
ctx.issues.push({
|
|
401
425
|
code: "custom",
|
|
402
|
-
message:
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
406
|
-
|
|
426
|
+
message: e instanceof mempool.LLTV.InvalidLLTVError || e instanceof mempool.LLTV.InvalidOptionError ? e.message : "Invalid LLTV.",
|
|
427
|
+
input: lltv,
|
|
428
|
+
path: ["lltv"]
|
|
429
|
+
});
|
|
430
|
+
return v4.z.NEVER;
|
|
431
|
+
}
|
|
407
432
|
}
|
|
408
433
|
return {
|
|
409
434
|
asset,
|
|
410
435
|
oracle,
|
|
411
|
-
lltv
|
|
436
|
+
lltv: lltvValue
|
|
412
437
|
};
|
|
413
438
|
});
|
|
414
439
|
}).optional().meta({
|
|
415
440
|
description: "Filter by collateral combinations in format: asset:oracle:lltv#asset2:oracle2:lltv2. Oracle and lltv are optional. Use # to separate multiple combinations.",
|
|
416
|
-
example: "0x1234567890123456789012345678901234567890:0xabcdefabcdefabcdefabcdefabcdefabcdefabcd:
|
|
441
|
+
example: "0x1234567890123456789012345678901234567890:0xabcdefabcdefabcdefabcdefabcdefabcdefabcd:86#0x9876543210987654321098765432109876543210:94.5"
|
|
417
442
|
}),
|
|
418
|
-
min_lltv: v4.z.
|
|
419
|
-
|
|
420
|
-
|
|
443
|
+
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) => {
|
|
444
|
+
try {
|
|
445
|
+
return mempool.LLTV.from(viem.parseUnits(lltv.toString(), 16));
|
|
446
|
+
} catch (e) {
|
|
447
|
+
ctx.addIssue({
|
|
448
|
+
code: "custom",
|
|
449
|
+
message: e.message,
|
|
450
|
+
input: lltv
|
|
451
|
+
});
|
|
452
|
+
return v4.z.NEVER;
|
|
453
|
+
}
|
|
454
|
+
}).optional().meta({
|
|
421
455
|
description: "Minimum Loan-to-Value ratio (LLTV) for collateral (percentage as decimal, e.g., 80.5 = 80.5%)",
|
|
422
456
|
example: "80.5"
|
|
423
457
|
}),
|
|
424
|
-
max_lltv: v4.z.
|
|
425
|
-
|
|
426
|
-
|
|
458
|
+
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) => {
|
|
459
|
+
try {
|
|
460
|
+
return mempool.LLTV.from(viem.parseUnits(lltv.toString(), 16));
|
|
461
|
+
} catch (e) {
|
|
462
|
+
ctx.addIssue({
|
|
463
|
+
code: "custom",
|
|
464
|
+
message: e.message,
|
|
465
|
+
input: lltv
|
|
466
|
+
});
|
|
467
|
+
return v4.z.NEVER;
|
|
468
|
+
}
|
|
469
|
+
}).optional().meta({
|
|
427
470
|
description: "Maximum Loan-to-Value ratio (LLTV) for collateral (percentage as decimal, e.g., 95.5 = 95.5%)",
|
|
428
471
|
example: "95.5"
|
|
429
472
|
}),
|
|
@@ -516,68 +559,89 @@ var MatchOffersQueryParams = v4.z.object({
|
|
|
516
559
|
}),
|
|
517
560
|
// Collateral filtering
|
|
518
561
|
collaterals: v4.z.string().regex(
|
|
519
|
-
/^(0x[a-fA-F0-9]{40}:0x[a-fA-F0-9]{40}
|
|
562
|
+
/^(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]+)?)*$/,
|
|
520
563
|
{
|
|
521
564
|
message: "Collaterals must be in format: asset:oracle:lltv#asset2:oracle2:lltv2. All fields are required for each collateral."
|
|
522
565
|
}
|
|
523
|
-
).transform((val) => {
|
|
566
|
+
).transform((val, ctx) => {
|
|
524
567
|
return val.split("#").map((collateral) => {
|
|
525
568
|
const parts = collateral.split(":");
|
|
526
569
|
if (parts.length !== 3) {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
]);
|
|
570
|
+
ctx.addIssue({
|
|
571
|
+
code: "custom",
|
|
572
|
+
message: "Each collateral must have exactly 3 parts: asset:oracle:lltv",
|
|
573
|
+
path: ["collaterals"],
|
|
574
|
+
input: val
|
|
575
|
+
});
|
|
576
|
+
return v4.z.NEVER;
|
|
535
577
|
}
|
|
536
578
|
const [asset, oracle, lltvStr] = parts;
|
|
537
579
|
if (!asset || !oracle || !lltvStr) {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
}
|
|
545
|
-
]);
|
|
580
|
+
ctx.addIssue({
|
|
581
|
+
code: "custom",
|
|
582
|
+
message: "Asset, oracle, and lltv are all required for each collateral",
|
|
583
|
+
path: ["collaterals"],
|
|
584
|
+
input: val
|
|
585
|
+
});
|
|
546
586
|
}
|
|
547
|
-
|
|
548
|
-
if (
|
|
549
|
-
|
|
550
|
-
|
|
587
|
+
let lltvValue;
|
|
588
|
+
if (lltvStr !== void 0) {
|
|
589
|
+
try {
|
|
590
|
+
lltvValue = mempool.LLTV.from(viem.parseUnits(lltvStr, 16));
|
|
591
|
+
} catch (e) {
|
|
592
|
+
ctx.issues.push({
|
|
551
593
|
code: "custom",
|
|
552
|
-
message:
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
556
|
-
|
|
594
|
+
message: e instanceof mempool.LLTV.InvalidLLTVError || e instanceof mempool.LLTV.InvalidOptionError ? e.message : "Invalid LLTV.",
|
|
595
|
+
input: lltvStr,
|
|
596
|
+
path: ["lltv"]
|
|
597
|
+
});
|
|
598
|
+
return v4.z.NEVER;
|
|
599
|
+
}
|
|
557
600
|
}
|
|
558
601
|
return {
|
|
559
602
|
asset: asset.toLowerCase(),
|
|
560
603
|
oracle: oracle.toLowerCase(),
|
|
561
|
-
lltv
|
|
604
|
+
lltv: lltvValue
|
|
562
605
|
};
|
|
563
606
|
});
|
|
564
607
|
}).optional().meta({
|
|
565
608
|
description: "Collateral requirements in format: asset:oracle:lltv#asset2:oracle2:lltv2. Use # to separate multiple collaterals.",
|
|
566
|
-
example: "0x1234567890123456789012345678901234567890:0xabcdefabcdefabcdefabcdefabcdefabcdefabcd:
|
|
609
|
+
example: "0x1234567890123456789012345678901234567890:0xabcdefabcdefabcdefabcdefabcdefabcdefabcd:86#0x9876543210987654321098765432109876543210:0xfedcbafedcbafedcbafedcbafedcbafedcbafedc:94.5"
|
|
567
610
|
}),
|
|
568
611
|
// Maturity filtering
|
|
569
|
-
maturity: v4.z.
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
612
|
+
maturity: v4.z.coerce.number().int().positive().transform((maturity, ctx) => {
|
|
613
|
+
try {
|
|
614
|
+
return mempool.Maturity.from(maturity);
|
|
615
|
+
} catch (e) {
|
|
616
|
+
ctx.addIssue({
|
|
617
|
+
code: "custom",
|
|
618
|
+
message: e.message
|
|
619
|
+
});
|
|
620
|
+
return v4.z.NEVER;
|
|
621
|
+
}
|
|
622
|
+
}).optional(),
|
|
623
|
+
min_maturity: v4.z.coerce.number().int().positive().transform((maturity, ctx) => {
|
|
624
|
+
try {
|
|
625
|
+
return mempool.Maturity.from(maturity);
|
|
626
|
+
} catch (e) {
|
|
627
|
+
ctx.addIssue({
|
|
628
|
+
code: "custom",
|
|
629
|
+
message: e.message
|
|
630
|
+
});
|
|
631
|
+
return v4.z.NEVER;
|
|
632
|
+
}
|
|
633
|
+
}).optional(),
|
|
634
|
+
max_maturity: v4.z.coerce.number().int().positive().transform((maturity, ctx) => {
|
|
635
|
+
try {
|
|
636
|
+
return mempool.Maturity.from(maturity);
|
|
637
|
+
} catch (e) {
|
|
638
|
+
ctx.addIssue({
|
|
639
|
+
code: "custom",
|
|
640
|
+
message: e.message
|
|
641
|
+
});
|
|
642
|
+
return v4.z.NEVER;
|
|
643
|
+
}
|
|
644
|
+
}).optional(),
|
|
581
645
|
// Asset and creator filtering
|
|
582
646
|
loan_token: v4.z.string().regex(/^0x[a-fA-F0-9]{40}$/, {
|
|
583
647
|
message: "Loan asset must be a valid Ethereum address"
|
|
@@ -639,8 +703,10 @@ var schemas = {
|
|
|
639
703
|
get_offers: GetOffersQueryParams,
|
|
640
704
|
match_offers: MatchOffersQueryParams
|
|
641
705
|
};
|
|
642
|
-
function safeParse(action, query) {
|
|
643
|
-
return schemas[action].safeParse(query
|
|
706
|
+
function safeParse(action, query, error) {
|
|
707
|
+
return schemas[action].safeParse(query, {
|
|
708
|
+
error
|
|
709
|
+
});
|
|
644
710
|
}
|
|
645
711
|
|
|
646
712
|
// src/core/apiSchema/openapi.ts
|
|
@@ -692,7 +758,7 @@ var paths = {
|
|
|
692
758
|
}
|
|
693
759
|
}
|
|
694
760
|
},
|
|
695
|
-
"/v1/match
|
|
761
|
+
"/v1/offers/match": {
|
|
696
762
|
get: {
|
|
697
763
|
summary: "Match offers",
|
|
698
764
|
description: "Find offers that match specific criteria",
|
|
@@ -843,16 +909,16 @@ async function get(config, parameters) {
|
|
|
843
909
|
} else if (lltv !== void 0) {
|
|
844
910
|
result += `:`;
|
|
845
911
|
}
|
|
846
|
-
if (lltv !== void 0) result += `:${lltv}`;
|
|
912
|
+
if (lltv !== void 0) result += `:${viem.formatUnits(lltv, 16)}`;
|
|
847
913
|
return result;
|
|
848
914
|
}).join("#");
|
|
849
915
|
url.searchParams.set("collateral_tuple", tupleStr);
|
|
850
916
|
}
|
|
851
917
|
if (parameters.minLltv !== void 0) {
|
|
852
|
-
url.searchParams.set("min_lltv", parameters.minLltv
|
|
918
|
+
url.searchParams.set("min_lltv", viem.formatUnits(parameters.minLltv, 16));
|
|
853
919
|
}
|
|
854
920
|
if (parameters.maxLltv !== void 0) {
|
|
855
|
-
url.searchParams.set("max_lltv", parameters.maxLltv
|
|
921
|
+
url.searchParams.set("max_lltv", viem.formatUnits(parameters.maxLltv, 16));
|
|
856
922
|
}
|
|
857
923
|
if (parameters.sortBy) {
|
|
858
924
|
url.searchParams.set("sort_by", parameters.sortBy);
|
|
@@ -874,14 +940,14 @@ async function get(config, parameters) {
|
|
|
874
940
|
};
|
|
875
941
|
}
|
|
876
942
|
async function match(config, parameters) {
|
|
877
|
-
const url = new URL(`${config.url.toString()}v1/match
|
|
943
|
+
const url = new URL(`${config.url.toString()}v1/offers/match`);
|
|
878
944
|
url.searchParams.set("side", parameters.side);
|
|
879
945
|
url.searchParams.set("chain_id", parameters.chainId.toString());
|
|
880
946
|
if (parameters.rate !== void 0) {
|
|
881
947
|
url.searchParams.set("rate", parameters.rate.toString());
|
|
882
948
|
}
|
|
883
949
|
if (parameters.collaterals?.length) {
|
|
884
|
-
const collateralsStr = parameters.collaterals.map(({ asset, oracle, lltv }) => `${asset}:${oracle}:${lltv}`).join("#");
|
|
950
|
+
const collateralsStr = parameters.collaterals.map(({ asset, oracle, lltv }) => `${asset}:${oracle}:${viem.formatUnits(lltv, 16)}`).join("#");
|
|
885
951
|
url.searchParams.set("collaterals", collateralsStr);
|
|
886
952
|
}
|
|
887
953
|
if (parameters.maturity !== void 0) {
|
|
@@ -919,12 +985,12 @@ async function getApi(config, url) {
|
|
|
919
985
|
const pathname = url.pathname;
|
|
920
986
|
let action;
|
|
921
987
|
switch (true) {
|
|
988
|
+
case pathname.includes("/v1/offers/match"):
|
|
989
|
+
action = "match_offers";
|
|
990
|
+
break;
|
|
922
991
|
case pathname.includes("/v1/offers"):
|
|
923
992
|
action = "get_offers";
|
|
924
993
|
break;
|
|
925
|
-
case pathname.includes("/v1/match-offers"):
|
|
926
|
-
action = "match_offers";
|
|
927
|
-
break;
|
|
928
994
|
default:
|
|
929
995
|
throw new HttpGetOffersFailedError("Unknown endpoint", {
|
|
930
996
|
details: `Unsupported path: ${pathname}`
|
|
@@ -1135,6 +1201,7 @@ function memory(parameters) {
|
|
|
1135
1201
|
}
|
|
1136
1202
|
creators && (creators = creators.map((c) => c.toLowerCase()));
|
|
1137
1203
|
loanTokens && (loanTokens = loanTokens.map((lt) => lt.toLowerCase()));
|
|
1204
|
+
callbackAddresses && (callbackAddresses = callbackAddresses.map((ca) => ca.toLowerCase()));
|
|
1138
1205
|
collateralAssets && (collateralAssets = collateralAssets.map((ca) => ca.toLowerCase()));
|
|
1139
1206
|
collateralOracles && (collateralOracles = collateralOracles.map((co) => co.toLowerCase()));
|
|
1140
1207
|
collateralTuple && (collateralTuple = collateralTuple.map((ct) => ({
|
|
@@ -1171,12 +1238,8 @@ function memory(parameters) {
|
|
|
1171
1238
|
)
|
|
1172
1239
|
)
|
|
1173
1240
|
));
|
|
1174
|
-
minLltv && (offers = offers.filter(
|
|
1175
|
-
|
|
1176
|
-
));
|
|
1177
|
-
maxLltv && (offers = offers.filter(
|
|
1178
|
-
(o) => o.collaterals.every((c) => c.lltv <= mempool.LLTV.from(viem.parseUnits(maxLltv.toString(), 16)))
|
|
1179
|
-
));
|
|
1241
|
+
minLltv && (offers = offers.filter((o) => o.collaterals.every((c) => c.lltv >= minLltv)));
|
|
1242
|
+
maxLltv && (offers = offers.filter((o) => o.collaterals.every((c) => c.lltv <= maxLltv)));
|
|
1180
1243
|
offers = offers.sort((a, b) => sort(sortBy, sortOrder, a, b));
|
|
1181
1244
|
let nextCursor = null;
|
|
1182
1245
|
if (offers.length > limit) {
|
|
@@ -1223,8 +1286,8 @@ function memory(parameters) {
|
|
|
1223
1286
|
limit = 20
|
|
1224
1287
|
} = params;
|
|
1225
1288
|
const now = mempool.Time.now();
|
|
1226
|
-
const
|
|
1227
|
-
const sortOrder =
|
|
1289
|
+
const isBuying = side === "buy";
|
|
1290
|
+
const sortOrder = isBuying ? "desc" : "asc";
|
|
1228
1291
|
let offers = Array.from(map.values()).map((o) => ({
|
|
1229
1292
|
...o,
|
|
1230
1293
|
consumed: filled.get(o.chainId)?.get(o.offering.toLowerCase())?.get(o.nonce) || 0n
|
|
@@ -1237,22 +1300,27 @@ function memory(parameters) {
|
|
|
1237
1300
|
offers = offers.filter(
|
|
1238
1301
|
(o) => sortOrder === "asc" ? o.rate >= BigInt(cursor.rate) : o.rate <= BigInt(cursor.rate)
|
|
1239
1302
|
);
|
|
1240
|
-
offers = offers.filter((o) => o.hash !== cursor.hash);
|
|
1241
1303
|
}
|
|
1242
|
-
offers = offers.filter((o) => o.buy ===
|
|
1304
|
+
offers = offers.filter((o) => o.buy === !isBuying);
|
|
1243
1305
|
offers = offers.filter((o) => o.chainId === BigInt(chainId));
|
|
1244
1306
|
offers = offers.filter((o) => o.expiry >= now);
|
|
1245
|
-
rate && (offers = offers.filter((o) =>
|
|
1307
|
+
rate && (offers = offers.filter((o) => isBuying ? o.rate >= rate : o.rate <= rate));
|
|
1246
1308
|
collaterals.length > 0 && (offers = offers.filter(
|
|
1247
|
-
(o) =>
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1309
|
+
(o) => isBuying ? (
|
|
1310
|
+
// when wanting to buy, sell offer collaterals ⊆ user buy collaterals
|
|
1311
|
+
o.collaterals.every((oc) => {
|
|
1312
|
+
return collaterals.some(
|
|
1313
|
+
(c) => oc.asset.toLowerCase() === c.asset.toLowerCase() && oc.oracle.toLowerCase() === c.oracle.toLowerCase() && oc.lltv === c.lltv
|
|
1314
|
+
);
|
|
1315
|
+
})
|
|
1316
|
+
) : (
|
|
1317
|
+
// when wanting to sell, user sell collaterals ⊆ buy offer collaterals
|
|
1318
|
+
collaterals.every((c) => {
|
|
1319
|
+
return o.collaterals.some(
|
|
1320
|
+
(oc) => oc.asset.toLowerCase() === c.asset.toLowerCase() && oc.oracle.toLowerCase() === c.oracle.toLowerCase() && oc.lltv === c.lltv
|
|
1321
|
+
);
|
|
1322
|
+
})
|
|
1323
|
+
)
|
|
1256
1324
|
));
|
|
1257
1325
|
maturity && (offers = offers.filter((o) => o.maturity === maturity));
|
|
1258
1326
|
minMaturity && (offers = offers.filter((o) => o.maturity >= minMaturity));
|
|
@@ -1290,6 +1358,7 @@ function memory(parameters) {
|
|
|
1290
1358
|
}
|
|
1291
1359
|
offers = Array.from(byGroup.values());
|
|
1292
1360
|
offers = offers.sort((a, b) => sort("rate", sortOrder, a, b));
|
|
1361
|
+
cursor && (offers = offers.filter((o) => o.hash !== cursor.hash));
|
|
1293
1362
|
let nextCursor = null;
|
|
1294
1363
|
if (offers.length > limit) {
|
|
1295
1364
|
const last = offers[limit - 1];
|
|
@@ -1322,9 +1391,12 @@ function memory(parameters) {
|
|
|
1322
1391
|
return deleted;
|
|
1323
1392
|
},
|
|
1324
1393
|
updateStatus: async (parameters2) => {
|
|
1325
|
-
|
|
1326
|
-
map.
|
|
1327
|
-
|
|
1394
|
+
const key = parameters2.offerHash.toLowerCase();
|
|
1395
|
+
const existing = map.get(key);
|
|
1396
|
+
if (!existing) return;
|
|
1397
|
+
if (existing.status === parameters2.status) return;
|
|
1398
|
+
map.set(key, {
|
|
1399
|
+
...existing,
|
|
1328
1400
|
status: parameters2.status,
|
|
1329
1401
|
metadata: parameters2.metadata
|
|
1330
1402
|
});
|