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