@morpho-dev/router 0.1.6 → 0.1.7

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.
@@ -1,4 +1,4 @@
1
- import { Errors, LLTV, Offer, Format, Utils, Time, Maturity } from '@morpho-dev/mempool';
1
+ import { Errors, LLTV, Offer, Format, Utils } from '@morpho-dev/mempool';
2
2
  export * from '@morpho-dev/mempool';
3
3
  import { Base64 } from 'js-base64';
4
4
  import { parseUnits, maxUint256, formatUnits, erc20Abi } from 'viem';
@@ -1121,415 +1121,6 @@ function serialize(liquidity) {
1121
1121
  return JSON.stringify(normalized);
1122
1122
  }
1123
1123
 
1124
- // src/OfferStore/index.ts
1125
- var OfferStore_exports = {};
1126
- __export(OfferStore_exports, {
1127
- memory: () => memory
1128
- });
1129
- function memory(parameters) {
1130
- const map = parameters.offers;
1131
- const filled = parameters.filled;
1132
- const consumedIds = /* @__PURE__ */ new Set();
1133
- const create = async (parameters2) => {
1134
- if (map.has(parameters2.offer.hash.toLowerCase())) return parameters2.offer.hash;
1135
- const callbackId = getCallbackIdForOffer(parameters2.offer);
1136
- map.set(parameters2.offer.hash.toLowerCase(), {
1137
- ...parameters2.offer,
1138
- ...callbackId ? { callbackId } : {},
1139
- status: parameters2.status,
1140
- metadata: parameters2.metadata
1141
- });
1142
- const chainId = parameters2.offer.chainId;
1143
- const address = parameters2.offer.offering.toLowerCase();
1144
- const nonce = parameters2.offer.nonce;
1145
- const filledForChain = filled.get(chainId) || /* @__PURE__ */ new Map();
1146
- const filledForOffering = filledForChain.get(address) || /* @__PURE__ */ new Map();
1147
- if (!filledForOffering.has(nonce)) filledForOffering.set(nonce, 0n);
1148
- filledForChain.set(address, filledForOffering);
1149
- filled.set(chainId, filledForChain);
1150
- return Promise.resolve(parameters2.offer.hash);
1151
- };
1152
- const sort = (sortBy, sortOrder, a, b) => {
1153
- sortBy = sortBy || "expiry";
1154
- sortOrder = sortOrder || "desc";
1155
- const sortKey = sortBy === "amount" ? "assets" : sortBy;
1156
- if (a[sortKey] === b[sortKey]) {
1157
- if (a.hash === b.hash) return 0;
1158
- return sortOrder === "asc" ? a.hash > b.hash ? 1 : -1 : b.hash > a.hash ? 1 : -1;
1159
- }
1160
- switch (sortBy) {
1161
- case "rate":
1162
- if (a.rate === b.rate) {
1163
- if (a.hash === b.hash) return 0;
1164
- return sortOrder === "asc" ? a.hash > b.hash ? 1 : -1 : a.hash > b.hash ? -1 : 1;
1165
- }
1166
- return sortOrder === "asc" ? a.rate > b.rate ? 1 : -1 : b.rate > a.rate ? 1 : -1;
1167
- case "maturity":
1168
- if (a.maturity === b.maturity) {
1169
- if (a.hash === b.hash) return 0;
1170
- return sortOrder === "asc" ? a.hash > b.hash ? 1 : -1 : a.hash > b.hash ? -1 : 1;
1171
- }
1172
- return sortOrder === "asc" ? a.maturity > b.maturity ? 1 : -1 : b.maturity > a.maturity ? 1 : -1;
1173
- case "expiry":
1174
- if (a.expiry === b.expiry) {
1175
- if (a.hash === b.hash) return 0;
1176
- return sortOrder === "asc" ? a.hash > b.hash ? 1 : -1 : a.hash > b.hash ? -1 : 1;
1177
- }
1178
- return sortOrder === "asc" ? a.expiry > b.expiry ? 1 : -1 : b.expiry > a.expiry ? 1 : -1;
1179
- case "amount":
1180
- if (a.assets === b.assets) {
1181
- if (a.hash === b.hash) return 0;
1182
- return sortOrder === "asc" ? a.hash > b.hash ? 1 : -1 : a.hash > b.hash ? -1 : 1;
1183
- }
1184
- return sortOrder === "asc" ? a.assets > b.assets ? 1 : -1 : b.assets > a.assets ? 1 : -1;
1185
- default:
1186
- if (a.expiry === b.expiry) {
1187
- if (a.hash === b.hash) return 0;
1188
- return sortOrder === "asc" ? a.hash > b.hash ? 1 : -1 : a.hash > b.hash ? -1 : 1;
1189
- }
1190
- return sortOrder === "asc" ? a.expiry > b.expiry ? 1 : -1 : b.expiry > a.expiry ? 1 : -1;
1191
- }
1192
- };
1193
- return {
1194
- create,
1195
- createMany: async (parameters2) => {
1196
- return Promise.all(
1197
- parameters2.map((p) => create({ offer: p.offer, status: p.status, metadata: p.metadata }))
1198
- );
1199
- },
1200
- getAll: async (params) => {
1201
- const { query } = params || {};
1202
- let {
1203
- creators,
1204
- side,
1205
- chains,
1206
- loanTokens,
1207
- status = ["valid"],
1208
- callbackAddresses,
1209
- minAmount,
1210
- maxAmount,
1211
- minRate,
1212
- maxRate,
1213
- minMaturity,
1214
- maxMaturity,
1215
- minExpiry,
1216
- maxExpiry,
1217
- collateralAssets,
1218
- collateralOracles,
1219
- collateralTuple,
1220
- minLltv,
1221
- maxLltv,
1222
- sortBy = "expiry",
1223
- sortOrder = "desc",
1224
- cursor: queryCursor,
1225
- limit = 20
1226
- } = query || {};
1227
- const now = Time.now();
1228
- const buy = side === "buy";
1229
- let offers = Array.from(map.values()).map((o) => ({
1230
- ...o,
1231
- consumed: filled.get(o.chainId)?.get(o.offering.toLowerCase())?.get(o.nonce) || 0n
1232
- })).filter((o) => o.consumed < o.assets);
1233
- const cursor = decode(queryCursor);
1234
- if (cursor) {
1235
- if (cursor.sort !== sortBy || cursor.dir !== sortOrder) {
1236
- throw new Error("Cursor does not match the current sort parameters");
1237
- }
1238
- switch (cursor.sort) {
1239
- case "rate":
1240
- offers = offers.filter(
1241
- (o) => (sortOrder === "asc" ? o.rate >= BigInt(cursor.rate) : o.rate <= BigInt(cursor.rate)) && (o.rate !== BigInt(cursor.rate) || (sortOrder === "asc" ? o.hash > cursor.hash : o.hash < cursor.hash))
1242
- );
1243
- break;
1244
- case "maturity":
1245
- offers = offers.filter(
1246
- (o) => (sortOrder === "asc" ? o.maturity >= BigInt(cursor.maturity) : o.maturity <= BigInt(cursor.maturity)) && (o.maturity !== Maturity.from(cursor.maturity) || (sortOrder === "asc" ? o.hash > cursor.hash : o.hash < cursor.hash))
1247
- );
1248
- break;
1249
- case "expiry":
1250
- offers = offers.filter(
1251
- (o) => (sortOrder === "asc" ? o.expiry >= cursor.expiry : o.expiry <= cursor.expiry) && (o.expiry !== cursor.expiry || (sortOrder === "asc" ? o.hash > cursor.hash : o.hash < cursor.hash))
1252
- );
1253
- break;
1254
- case "amount":
1255
- offers = offers.filter(
1256
- (o) => (sortOrder === "asc" ? o.assets >= BigInt(cursor.assets) : o.assets <= BigInt(cursor.assets)) && (o.assets !== BigInt(cursor.assets) || (sortOrder === "asc" ? o.hash > cursor.hash : o.hash < cursor.hash))
1257
- );
1258
- break;
1259
- default:
1260
- throw new Error("Invalid sort parameter");
1261
- }
1262
- offers = offers.filter((o) => o.hash !== cursor.hash);
1263
- }
1264
- creators && (creators = creators.map((c) => c.toLowerCase()));
1265
- loanTokens && (loanTokens = loanTokens.map((lt) => lt.toLowerCase()));
1266
- callbackAddresses && (callbackAddresses = callbackAddresses.map((ca) => ca.toLowerCase()));
1267
- collateralAssets && (collateralAssets = collateralAssets.map((ca) => ca.toLowerCase()));
1268
- collateralOracles && (collateralOracles = collateralOracles.map((co) => co.toLowerCase()));
1269
- collateralTuple && (collateralTuple = collateralTuple.map((ct) => ({
1270
- asset: ct.asset.toLowerCase(),
1271
- oracle: ct.oracle?.toLowerCase()
1272
- })));
1273
- offers = offers.filter((o) => o.expiry >= now);
1274
- creators && (offers = offers.filter((o) => creators.includes(o.offering.toLowerCase())));
1275
- side && (offers = offers.filter((o) => o.buy === buy));
1276
- chains && (offers = offers.filter((o) => chains.includes(Number(o.chainId))));
1277
- loanTokens && (offers = offers.filter((o) => loanTokens.includes(o.loanToken.toLowerCase())));
1278
- status && (offers = offers.filter((o) => status.includes(o.status)));
1279
- callbackAddresses && (offers = offers.filter(
1280
- (o) => callbackAddresses.includes(o.callback.address.toLowerCase())
1281
- ));
1282
- minAmount && (offers = offers.filter((o) => o.assets >= minAmount));
1283
- maxAmount && (offers = offers.filter((o) => o.assets <= maxAmount));
1284
- minRate && (offers = offers.filter((o) => o.rate >= minRate));
1285
- maxRate && (offers = offers.filter((o) => o.rate <= maxRate));
1286
- minMaturity && (offers = offers.filter((o) => o.maturity >= minMaturity));
1287
- maxMaturity && (offers = offers.filter((o) => o.maturity <= maxMaturity));
1288
- minExpiry && (offers = offers.filter((o) => o.expiry >= minExpiry));
1289
- maxExpiry && (offers = offers.filter((o) => o.expiry <= maxExpiry));
1290
- collateralAssets && (offers = offers.filter(
1291
- (o) => o.collaterals.some((c) => collateralAssets.includes(c.asset.toLowerCase()))
1292
- ));
1293
- collateralOracles && (offers = offers.filter(
1294
- (o) => o.collaterals.some((c) => collateralOracles.includes(c.oracle.toLowerCase()))
1295
- ));
1296
- collateralTuple && (offers = offers.filter(
1297
- (o) => o.collaterals.some(
1298
- (c) => collateralTuple.some(
1299
- (ct) => c.asset.toLowerCase() === ct.asset.toLowerCase() && (ct.oracle ? c.oracle.toLowerCase() === ct.oracle.toLowerCase() : true) && (ct.lltv ? c.lltv === LLTV.from(BigInt(ct.lltv)) : true)
1300
- )
1301
- )
1302
- ));
1303
- minLltv && (offers = offers.filter(
1304
- (o) => o.collaterals.every((c) => c.lltv >= parseUnits(minLltv.toString(), 16))
1305
- ));
1306
- maxLltv && (offers = offers.filter(
1307
- (o) => o.collaterals.every((c) => c.lltv <= parseUnits(maxLltv.toString(), 16))
1308
- ));
1309
- offers = offers.sort((a, b) => sort(sortBy, sortOrder, a, b));
1310
- let nextCursor = null;
1311
- if (offers.length > limit) {
1312
- const last = offers[limit - 1];
1313
- const base = {
1314
- sort: sortBy,
1315
- dir: sortOrder,
1316
- hash: last.hash
1317
- };
1318
- switch (sortBy) {
1319
- case "rate":
1320
- base.rate = last.rate.toString();
1321
- break;
1322
- case "amount":
1323
- base.assets = last.assets.toString();
1324
- break;
1325
- case "maturity":
1326
- base.maturity = last.maturity;
1327
- break;
1328
- default:
1329
- base.expiry = last.expiry;
1330
- }
1331
- nextCursor = encode(base);
1332
- }
1333
- offers = offers.slice(0, limit);
1334
- const data = offers.map((o) => ({
1335
- ...Offer.from({
1336
- offering: o.offering,
1337
- assets: o.assets,
1338
- rate: o.rate,
1339
- maturity: Maturity.from(o.maturity),
1340
- expiry: o.expiry,
1341
- start: o.start,
1342
- nonce: o.nonce,
1343
- buy: o.buy,
1344
- chainId: o.chainId,
1345
- loanToken: o.loanToken,
1346
- collaterals: o.collaterals.map((c) => ({ asset: c.asset, oracle: c.oracle, lltv: c.lltv })).sort((a, b) => a.asset.toLowerCase().localeCompare(b.asset.toLowerCase())),
1347
- callback: {
1348
- address: o.callback.address,
1349
- data: o.callback.data,
1350
- gasLimit: o.callback.gasLimit
1351
- },
1352
- ...o.signature !== null && o.signature !== void 0 ? { signature: o.signature } : {}
1353
- }),
1354
- consumed: o.consumed,
1355
- status: o.status,
1356
- ...o.metadata ? { metadata: o.metadata } : {}
1357
- }));
1358
- return {
1359
- offers: data,
1360
- nextCursor
1361
- };
1362
- },
1363
- findMatchingOffers: async (params) => {
1364
- const {
1365
- side,
1366
- chainId,
1367
- rate,
1368
- collaterals = [],
1369
- maturity,
1370
- minMaturity,
1371
- maxMaturity,
1372
- loanToken,
1373
- creator,
1374
- cursor: queryCursor,
1375
- limit = 20
1376
- } = params;
1377
- const now = Time.now();
1378
- const isBuying = side === "buy";
1379
- const sortOrder = isBuying ? "desc" : "asc";
1380
- let offers = Array.from(map.values()).map((o) => ({
1381
- ...o,
1382
- consumed: filled.get(o.chainId)?.get(o.offering.toLowerCase())?.get(o.nonce) || 0n
1383
- })).filter((o) => o.consumed < o.assets);
1384
- const cursor = decode(queryCursor);
1385
- if (cursor) {
1386
- if (cursor.sort !== "rate" || cursor.dir !== sortOrder) {
1387
- throw new Error("Cursor does not match the current sort parameters");
1388
- }
1389
- offers = offers.filter(
1390
- (o) => sortOrder === "asc" ? o.rate >= BigInt(cursor.rate) : o.rate <= BigInt(cursor.rate)
1391
- );
1392
- }
1393
- offers = offers.filter((o) => o.buy === !isBuying);
1394
- offers = offers.filter((o) => o.chainId === BigInt(chainId));
1395
- offers = offers.filter((o) => o.expiry >= now);
1396
- rate && (offers = offers.filter((o) => isBuying ? o.rate >= rate : o.rate <= rate));
1397
- collaterals.length > 0 && (offers = offers.filter(
1398
- (o) => isBuying ? (
1399
- // when wanting to buy, sell offer collaterals ⊆ user buy collaterals
1400
- o.collaterals.every((oc) => {
1401
- return collaterals.some(
1402
- (c) => oc.asset.toLowerCase() === c.asset.toLowerCase() && oc.oracle.toLowerCase() === c.oracle.toLowerCase() && oc.lltv === c.lltv
1403
- );
1404
- })
1405
- ) : (
1406
- // when wanting to sell, user sell collaterals ⊆ buy offer collaterals
1407
- collaterals.every((c) => {
1408
- return o.collaterals.some(
1409
- (oc) => oc.asset.toLowerCase() === c.asset.toLowerCase() && oc.oracle.toLowerCase() === c.oracle.toLowerCase() && oc.lltv === c.lltv
1410
- );
1411
- })
1412
- )
1413
- ));
1414
- maturity && (offers = offers.filter((o) => o.maturity === maturity));
1415
- minMaturity && (offers = offers.filter((o) => o.maturity >= minMaturity));
1416
- maxMaturity && (offers = offers.filter((o) => o.maturity <= maxMaturity));
1417
- loanToken && (offers = offers.filter((o) => o.loanToken.toLowerCase() === loanToken.toLowerCase()));
1418
- creator && (offers = offers.filter((o) => o.offering.toLowerCase() === creator.toLowerCase()));
1419
- offers = offers.filter((o) => ["valid"].includes(o.status));
1420
- const byGroup = /* @__PURE__ */ new Map();
1421
- for (const offer of offers) {
1422
- const groupKey = `${offer.chainId}-${offer.offering.toLowerCase()}-${offer.nonce}-${offer.buy}`;
1423
- const current = byGroup.get(groupKey);
1424
- if (!current) {
1425
- byGroup.set(groupKey, offer);
1426
- continue;
1427
- }
1428
- const remainingCandidate = offer.assets - offer.consumed;
1429
- const remainingCurrent = current.assets - current.consumed;
1430
- let candidateIsBetter = false;
1431
- if (offer.buy) {
1432
- if (offer.rate !== current.rate) candidateIsBetter = offer.rate < current.rate;
1433
- else if (remainingCandidate !== remainingCurrent)
1434
- candidateIsBetter = remainingCandidate > remainingCurrent;
1435
- else if (offer.maturity !== current.maturity)
1436
- candidateIsBetter = offer.maturity > current.maturity;
1437
- else candidateIsBetter = offer.hash < current.hash;
1438
- } else {
1439
- if (offer.rate !== current.rate) candidateIsBetter = offer.rate > current.rate;
1440
- else if (remainingCandidate !== remainingCurrent)
1441
- candidateIsBetter = remainingCandidate > remainingCurrent;
1442
- else if (offer.maturity !== current.maturity)
1443
- candidateIsBetter = offer.maturity > current.maturity;
1444
- else candidateIsBetter = offer.hash < current.hash;
1445
- }
1446
- if (candidateIsBetter) byGroup.set(groupKey, offer);
1447
- }
1448
- offers = Array.from(byGroup.values());
1449
- offers = offers.sort((a, b) => sort("rate", sortOrder, a, b));
1450
- cursor && (offers = offers.filter((o) => o.hash !== cursor.hash));
1451
- let nextCursor = null;
1452
- if (offers.length > limit) {
1453
- const last = offers[limit - 1];
1454
- nextCursor = encode({
1455
- sort: "rate",
1456
- dir: sortOrder,
1457
- hash: last.hash,
1458
- rate: last.rate.toString()
1459
- });
1460
- }
1461
- offers = offers.slice(0, limit);
1462
- const data = offers.map((o) => ({
1463
- ...Offer.from({
1464
- offering: o.offering,
1465
- assets: o.assets,
1466
- rate: o.rate,
1467
- maturity: Maturity.from(o.maturity),
1468
- expiry: o.expiry,
1469
- start: o.start,
1470
- nonce: o.nonce,
1471
- buy: o.buy,
1472
- chainId: o.chainId,
1473
- loanToken: o.loanToken,
1474
- collaterals: o.collaterals.map((c) => ({ asset: c.asset, oracle: c.oracle, lltv: c.lltv })).sort((a, b) => a.asset.toLowerCase().localeCompare(b.asset.toLowerCase())),
1475
- callback: {
1476
- address: o.callback.address,
1477
- data: o.callback.data,
1478
- gasLimit: o.callback.gasLimit
1479
- },
1480
- ...o.signature !== null && o.signature !== void 0 ? { signature: o.signature } : {}
1481
- }),
1482
- consumed: o.consumed,
1483
- status: o.status,
1484
- ...o.metadata ? { metadata: o.metadata } : {}
1485
- }));
1486
- return {
1487
- offers: data,
1488
- nextCursor
1489
- };
1490
- },
1491
- delete: async (hash) => {
1492
- if (!map.has(hash.toLowerCase())) return false;
1493
- map.delete(hash.toLowerCase());
1494
- return true;
1495
- },
1496
- deleteMany: async (hashes) => {
1497
- let deleted = 0;
1498
- for (const hash of hashes) {
1499
- if (map.has(hash.toLowerCase())) {
1500
- map.delete(hash.toLowerCase());
1501
- deleted++;
1502
- }
1503
- }
1504
- return deleted;
1505
- },
1506
- updateStatus: async (parameters2) => {
1507
- const key = parameters2.offerHash.toLowerCase();
1508
- const existing = map.get(key);
1509
- if (!existing) return;
1510
- if (existing.status === parameters2.status) return;
1511
- map.set(key, {
1512
- ...existing,
1513
- status: parameters2.status,
1514
- metadata: parameters2.metadata
1515
- });
1516
- },
1517
- updateConsumedAmount: async (parameters2) => {
1518
- if (consumedIds.has(parameters2.id)) return;
1519
- consumedIds.add(parameters2.id);
1520
- const chainId = parameters2.chainId;
1521
- const address = parameters2.offering.toLowerCase();
1522
- const nonce = parameters2.nonce;
1523
- const filledForChain = filled.get(chainId) || /* @__PURE__ */ new Map();
1524
- const filledForOffering = filledForChain.get(address) || /* @__PURE__ */ new Map();
1525
- const current = filledForOffering.get(nonce) || 0n;
1526
- filledForOffering.set(nonce, current + parameters2.consumed);
1527
- filledForChain.set(address, filledForOffering);
1528
- filled.set(chainId, filledForChain);
1529
- }
1530
- };
1531
- }
1532
-
1533
1124
  // src/Validation.ts
1534
1125
  var Validation_exports = {};
1535
1126
  __export(Validation_exports, {
@@ -1628,6 +1219,6 @@ function morpho() {
1628
1219
  ];
1629
1220
  }
1630
1221
 
1631
- export { Callback_exports as Callback, Cursor_exports as Cursor, Liquidity_exports as Liquidity, OfferStore_exports as OfferStore, Client_exports as Router, RouterOffer_exports as RouterOffer, Validation_exports as Validation, ValidationRule_exports as ValidationRule };
1222
+ export { Callback_exports as Callback, Cursor_exports as Cursor, Liquidity_exports as Liquidity, Client_exports as Router, RouterOffer_exports as RouterOffer, Validation_exports as Validation, ValidationRule_exports as ValidationRule };
1632
1223
  //# sourceMappingURL=index.browser.mjs.map
1633
1224
  //# sourceMappingURL=index.browser.mjs.map