@morpho-dev/router 0.1.1 → 0.1.3
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 +11 -136
- package/dist/index.browser.d.ts +11 -136
- package/dist/index.browser.js +19 -238
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.mjs +21 -238
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.node.d.cts +12 -137
- package/dist/index.node.d.ts +12 -137
- package/dist/index.node.js +19 -238
- package/dist/index.node.js.map +1 -1
- package/dist/index.node.mjs +21 -238
- package/dist/index.node.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.browser.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Errors, LLTV, Offer, Format, Time, Maturity } from '@morpho-dev/mempool';
|
|
2
2
|
export * from '@morpho-dev/mempool';
|
|
3
|
-
import {
|
|
4
|
-
import { parseUnits, maxUint256, formatUnits, parseAbi } from 'viem';
|
|
3
|
+
import { parseUnits, maxUint256, formatUnits } from 'viem';
|
|
5
4
|
import { z } from 'zod/v4';
|
|
6
5
|
import { createDocument } from 'zod-openapi';
|
|
7
6
|
import { Base64 } from 'js-base64';
|
|
@@ -14,85 +13,6 @@ var __export = (target, all) => {
|
|
|
14
13
|
};
|
|
15
14
|
var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
|
|
16
15
|
|
|
17
|
-
// src/Chain.ts
|
|
18
|
-
var Chain_exports = {};
|
|
19
|
-
__export(Chain_exports, {
|
|
20
|
-
ChainId: () => ChainId,
|
|
21
|
-
chainIds: () => chainIds,
|
|
22
|
-
chainNames: () => chainNames,
|
|
23
|
-
chains: () => chains,
|
|
24
|
-
getChain: () => getChain,
|
|
25
|
-
getWhitelistedChains: () => getWhitelistedChains
|
|
26
|
-
});
|
|
27
|
-
var chainNames = ["ethereum", "base", "ethereum-virtual-testnet"];
|
|
28
|
-
var ChainId = {
|
|
29
|
-
ETHEREUM: BigInt(mainnet.id),
|
|
30
|
-
BASE: BigInt(base.id),
|
|
31
|
-
"ETHEREUM-VIRTUAL-TESTNET": 109111114n
|
|
32
|
-
};
|
|
33
|
-
var chainIds = new Set(Object.values(ChainId));
|
|
34
|
-
var chainNameLookup = new Map(Object.entries(ChainId).map(([key, value]) => [value, key]));
|
|
35
|
-
function getChain(chainId) {
|
|
36
|
-
const chainName = chainNameLookup.get(chainId)?.toLowerCase();
|
|
37
|
-
if (!chainName) {
|
|
38
|
-
return void 0;
|
|
39
|
-
}
|
|
40
|
-
return chains[chainName];
|
|
41
|
-
}
|
|
42
|
-
var getWhitelistedChains = () => {
|
|
43
|
-
return [chains.ethereum, chains.base, chains["ethereum-virtual-testnet"]];
|
|
44
|
-
};
|
|
45
|
-
var chains = {
|
|
46
|
-
ethereum: {
|
|
47
|
-
...mainnet,
|
|
48
|
-
id: ChainId.ETHEREUM,
|
|
49
|
-
name: "ethereum",
|
|
50
|
-
whitelistedAssets: new Set(
|
|
51
|
-
[
|
|
52
|
-
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
53
|
-
// USDC
|
|
54
|
-
"0x6B175474E89094C44Da98b954EedeAC495271d0F"
|
|
55
|
-
// DAI
|
|
56
|
-
].map((address) => address.toLowerCase())
|
|
57
|
-
),
|
|
58
|
-
morpho: "0x0000000000000000000000000000000000000000"
|
|
59
|
-
},
|
|
60
|
-
base: {
|
|
61
|
-
...base,
|
|
62
|
-
id: ChainId.BASE,
|
|
63
|
-
name: "base",
|
|
64
|
-
whitelistedAssets: new Set(
|
|
65
|
-
[
|
|
66
|
-
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
67
|
-
// USDC
|
|
68
|
-
"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb"
|
|
69
|
-
// DAI
|
|
70
|
-
].map((address) => address.toLowerCase())
|
|
71
|
-
),
|
|
72
|
-
morpho: "0x0000000000000000000000000000000000000000"
|
|
73
|
-
},
|
|
74
|
-
"ethereum-virtual-testnet": {
|
|
75
|
-
...mainnet,
|
|
76
|
-
id: 109111114n,
|
|
77
|
-
name: "ethereum-virtual-testnet",
|
|
78
|
-
whitelistedAssets: new Set(
|
|
79
|
-
[
|
|
80
|
-
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
81
|
-
// USDC
|
|
82
|
-
"0x6B175474E89094C44Da98b954EedeAC495271d0F"
|
|
83
|
-
// DAI
|
|
84
|
-
].map((address) => address.toLowerCase())
|
|
85
|
-
),
|
|
86
|
-
morpho: "0x11a002d45db720ed47a80d2f3489cba5b833eaf5",
|
|
87
|
-
// @TODO: This is mock Consumed contract, update with Terms once stable
|
|
88
|
-
mempool: {
|
|
89
|
-
address: "0x7be3164eeee8b35092f6128ec32c2e6ff8f6c890",
|
|
90
|
-
deploymentBlock: 23223727,
|
|
91
|
-
reindexBuffer: 10
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
|
|
96
16
|
// src/core/router/Client.ts
|
|
97
17
|
var Client_exports = {};
|
|
98
18
|
__export(Client_exports, {
|
|
@@ -1080,7 +1000,6 @@ function memory(parameters) {
|
|
|
1080
1000
|
const map = parameters.offers;
|
|
1081
1001
|
const filled = parameters.filled;
|
|
1082
1002
|
const consumedIds = /* @__PURE__ */ new Set();
|
|
1083
|
-
const indexingProgress = /* @__PURE__ */ new Map();
|
|
1084
1003
|
const create = async (parameters2) => {
|
|
1085
1004
|
if (map.has(parameters2.offer.hash.toLowerCase())) return parameters2.offer.hash;
|
|
1086
1005
|
map.set(parameters2.offer.hash.toLowerCase(), {
|
|
@@ -1151,7 +1070,7 @@ function memory(parameters) {
|
|
|
1151
1070
|
let {
|
|
1152
1071
|
creators,
|
|
1153
1072
|
side,
|
|
1154
|
-
chains
|
|
1073
|
+
chains,
|
|
1155
1074
|
loanTokens,
|
|
1156
1075
|
status = ["valid"],
|
|
1157
1076
|
callbackAddresses,
|
|
@@ -1222,7 +1141,7 @@ function memory(parameters) {
|
|
|
1222
1141
|
offers = offers.filter((o) => o.expiry >= now);
|
|
1223
1142
|
creators && (offers = offers.filter((o) => creators.includes(o.offering.toLowerCase())));
|
|
1224
1143
|
side && (offers = offers.filter((o) => o.buy === buy));
|
|
1225
|
-
|
|
1144
|
+
chains && (offers = offers.filter((o) => chains.includes(Number(o.chainId))));
|
|
1226
1145
|
loanTokens && (offers = offers.filter((o) => loanTokens.includes(o.loanToken.toLowerCase())));
|
|
1227
1146
|
status && (offers = offers.filter((o) => status.includes(o.status)));
|
|
1228
1147
|
callbackAddresses && (offers = offers.filter(
|
|
@@ -1428,31 +1347,10 @@ function memory(parameters) {
|
|
|
1428
1347
|
filledForOffering.set(nonce, current + parameters2.consumed);
|
|
1429
1348
|
filledForChain.set(address, filledForOffering);
|
|
1430
1349
|
filled.set(chainId, filledForChain);
|
|
1431
|
-
},
|
|
1432
|
-
saveLatestBlockNumberProcessed: async (parameters2) => {
|
|
1433
|
-
const key = `${parameters2.chainId.toString()}:${parameters2.eventType}`;
|
|
1434
|
-
indexingProgress.set(key, parameters2.latestBlockNumber);
|
|
1435
|
-
},
|
|
1436
|
-
getLatestBlockNumberProcessed: async (parameters2) => {
|
|
1437
|
-
const key = `${parameters2.chainId.toString()}:${parameters2.eventType}`;
|
|
1438
|
-
const value = indexingProgress.get(key);
|
|
1439
|
-
return value === void 0 ? null : { latestBlockNumber: value };
|
|
1440
1350
|
}
|
|
1441
1351
|
};
|
|
1442
1352
|
}
|
|
1443
1353
|
|
|
1444
|
-
// src/RouterEvent.ts
|
|
1445
|
-
var RouterEvent_exports = {};
|
|
1446
|
-
__export(RouterEvent_exports, {
|
|
1447
|
-
from: () => from2,
|
|
1448
|
-
types: () => types
|
|
1449
|
-
});
|
|
1450
|
-
var types = ["offer_created", "offer_consumed", "offer_validation"];
|
|
1451
|
-
function from2(base) {
|
|
1452
|
-
const id = base.type === "offer_consumed" ? `${base.type}:${base.offerConsumed.id}` : `${base.type}:${base.offer.hash.toLowerCase()}`;
|
|
1453
|
-
return { id, ...base };
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
1354
|
// src/Validation.ts
|
|
1457
1355
|
var Validation_exports = {};
|
|
1458
1356
|
__export(Validation_exports, {
|
|
@@ -1513,25 +1411,19 @@ function single(name, run2) {
|
|
|
1513
1411
|
function batch2(name, run2) {
|
|
1514
1412
|
return { kind: "batch", name, run: run2 };
|
|
1515
1413
|
}
|
|
1516
|
-
function morpho(
|
|
1517
|
-
const {
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
new Set(Array.from(chain.whitelistedAssets).map((a) => a.toLowerCase()))
|
|
1523
|
-
])
|
|
1524
|
-
);
|
|
1525
|
-
const morphoPerChain = new Map(
|
|
1526
|
-
whitelistedChains.map((chain) => [chain.id, chain.morpho.toLowerCase()])
|
|
1527
|
-
);
|
|
1528
|
-
const chainId = single("chain_id", (offer, _) => {
|
|
1529
|
-
if (!whitelistedChainIds.has(offer.chainId)) {
|
|
1530
|
-
return { message: `Chain ID ${offer.chainId} is not whitelisted` };
|
|
1414
|
+
function morpho() {
|
|
1415
|
+
const chainId = single("chain_id", (offer, { chain }) => {
|
|
1416
|
+
if (chain.id !== offer.chainId) {
|
|
1417
|
+
return {
|
|
1418
|
+
message: `Chain ID ${offer.chainId} is not the same as the chain ID in the context (${chain.id})`
|
|
1419
|
+
};
|
|
1531
1420
|
}
|
|
1532
1421
|
});
|
|
1533
|
-
const loanToken = single("loan_token", (offer,
|
|
1534
|
-
|
|
1422
|
+
const loanToken = single("loan_token", (offer, { chain }) => {
|
|
1423
|
+
const tokens = new Set(
|
|
1424
|
+
Array.from(chain.whitelistedAssets.values()).map((a) => a.toLowerCase())
|
|
1425
|
+
);
|
|
1426
|
+
if (!tokens.has(offer.loanToken.toLowerCase())) {
|
|
1535
1427
|
return {
|
|
1536
1428
|
message: `Loan token ${offer.loanToken} is not whitelisted on chain ${offer.chainId}`
|
|
1537
1429
|
};
|
|
@@ -1542,130 +1434,21 @@ function morpho(parameters) {
|
|
|
1542
1434
|
return { message: "Expiry mismatch" };
|
|
1543
1435
|
}
|
|
1544
1436
|
});
|
|
1545
|
-
const
|
|
1546
|
-
if (offer.callback.data !== "0x") {
|
|
1547
|
-
return { message: "Callback
|
|
1437
|
+
const callback = single("empty_callback", (offer, _) => {
|
|
1438
|
+
if (!offer.buy || offer.callback.data !== "0x") {
|
|
1439
|
+
return { message: "Callback not supported yet." };
|
|
1548
1440
|
}
|
|
1549
1441
|
});
|
|
1550
|
-
const sellOffersEmptyCallback = single(
|
|
1551
|
-
"sell_offers_empty_callback",
|
|
1552
|
-
(offer, _) => {
|
|
1553
|
-
if (!offer.buy && offer.callback.data === "0x") {
|
|
1554
|
-
return { message: "Sell offers with empty callback are not supported yet." };
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
);
|
|
1558
|
-
const buyOffersEmptyCallback = batch2(
|
|
1559
|
-
"buy_offers_empty_callback",
|
|
1560
|
-
async (offers, { publicClients }) => {
|
|
1561
|
-
const issues = /* @__PURE__ */ new Map();
|
|
1562
|
-
const hashToIndex = /* @__PURE__ */ new Map();
|
|
1563
|
-
for (let i = 0; i < offers.length; i++) {
|
|
1564
|
-
const offer = offers[i];
|
|
1565
|
-
hashToIndex.set(offer.hash, i);
|
|
1566
|
-
}
|
|
1567
|
-
const { buyOffers, sellOffers: _sellOffers } = offers.reduce(
|
|
1568
|
-
(acc, offer) => {
|
|
1569
|
-
offer.buy ? acc.buyOffers.push(offer) : issues.set(hashToIndex.get(offer.hash), {
|
|
1570
|
-
message: "Onchain callback for sell offers is not supported yet."
|
|
1571
|
-
});
|
|
1572
|
-
return acc;
|
|
1573
|
-
},
|
|
1574
|
-
{ buyOffers: [], sellOffers: [] }
|
|
1575
|
-
);
|
|
1576
|
-
const buyOffersPerLoanAsset = /* @__PURE__ */ new Map();
|
|
1577
|
-
for (const offer of buyOffers) {
|
|
1578
|
-
const chainName = getChain(offer.chainId)?.name;
|
|
1579
|
-
const loanTokens = buyOffersPerLoanAsset.get(chainName) ?? /* @__PURE__ */ new Map();
|
|
1580
|
-
const offers2 = loanTokens.get(offer.loanToken.toLowerCase()) ?? [];
|
|
1581
|
-
offers2.push(offer);
|
|
1582
|
-
loanTokens.set(offer.loanToken.toLowerCase(), offers2);
|
|
1583
|
-
buyOffersPerLoanAsset.set(chainName, loanTokens);
|
|
1584
|
-
}
|
|
1585
|
-
await Promise.all(
|
|
1586
|
-
Array.from(buyOffersPerLoanAsset.entries()).map(async ([name, loanTokens]) => {
|
|
1587
|
-
const chainName = name;
|
|
1588
|
-
const publicClient = publicClients[chainName];
|
|
1589
|
-
const morpho2 = morphoPerChain.get(chains[chainName].id);
|
|
1590
|
-
if (!publicClient) {
|
|
1591
|
-
const offers2 = Array.from(loanTokens.values()).flat();
|
|
1592
|
-
for (const offer of offers2) {
|
|
1593
|
-
issues.set(hashToIndex.get(offer.hash), {
|
|
1594
|
-
message: `Public client for chain "${chainName}" is not available`
|
|
1595
|
-
});
|
|
1596
|
-
}
|
|
1597
|
-
return;
|
|
1598
|
-
}
|
|
1599
|
-
const balances = /* @__PURE__ */ new Map();
|
|
1600
|
-
const allowances = /* @__PURE__ */ new Map();
|
|
1601
|
-
for (const [loanToken2, offers2] of loanTokens) {
|
|
1602
|
-
const data = await Promise.all(
|
|
1603
|
-
offers2.flatMap((offer) => [
|
|
1604
|
-
publicClient.readContract({
|
|
1605
|
-
address: loanToken2,
|
|
1606
|
-
abi: parseAbi([
|
|
1607
|
-
"function balanceOf(address owner) view returns (uint256 balance)"
|
|
1608
|
-
]),
|
|
1609
|
-
functionName: "balanceOf",
|
|
1610
|
-
args: [offer.offering]
|
|
1611
|
-
}),
|
|
1612
|
-
publicClient.readContract({
|
|
1613
|
-
address: loanToken2,
|
|
1614
|
-
abi: parseAbi([
|
|
1615
|
-
"function allowance(address owner, address spender) public view returns (uint256 remaining)"
|
|
1616
|
-
]),
|
|
1617
|
-
functionName: "allowance",
|
|
1618
|
-
args: [offer.offering, morpho2]
|
|
1619
|
-
})
|
|
1620
|
-
])
|
|
1621
|
-
);
|
|
1622
|
-
for (let i = 0; i < offers2.length; i++) {
|
|
1623
|
-
const user = offers2[i].offering.toLowerCase();
|
|
1624
|
-
const balance = data[i * 2] || 0n;
|
|
1625
|
-
const allowance = data[i * 2 + 1] || 0n;
|
|
1626
|
-
const userBalances = balances.get(user) ?? /* @__PURE__ */ new Map();
|
|
1627
|
-
userBalances.set(loanToken2.toLowerCase(), balance);
|
|
1628
|
-
const userAllowances = allowances.get(user) ?? /* @__PURE__ */ new Map();
|
|
1629
|
-
userAllowances.set(loanToken2.toLowerCase(), allowance);
|
|
1630
|
-
balances.set(user, userBalances);
|
|
1631
|
-
allowances.set(user, userAllowances);
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
for (const offer of Array.from(loanTokens.values()).flat()) {
|
|
1635
|
-
const user = offer.offering.toLowerCase();
|
|
1636
|
-
const userBalances = balances.get(user);
|
|
1637
|
-
const balance = userBalances?.get(offer.loanToken.toLowerCase());
|
|
1638
|
-
if (balance < offer.assets) {
|
|
1639
|
-
issues.set(hashToIndex.get(offer.hash), {
|
|
1640
|
-
message: `Insufficient balance for ${offer.loanToken} on chain ${offer.chainId} (${balance.toString()} < ${offer.assets.toString()})`
|
|
1641
|
-
});
|
|
1642
|
-
continue;
|
|
1643
|
-
}
|
|
1644
|
-
const userAllowances = allowances.get(user);
|
|
1645
|
-
const allowance = userAllowances?.get(offer.loanToken.toLowerCase());
|
|
1646
|
-
if (allowance < offer.assets) {
|
|
1647
|
-
issues.set(hashToIndex.get(offer.hash), {
|
|
1648
|
-
message: `Insufficient allowance for ${offer.loanToken} on chain ${offer.chainId} (${allowance.toString()} < ${offer.assets.toString()})`
|
|
1649
|
-
});
|
|
1650
|
-
}
|
|
1651
|
-
}
|
|
1652
|
-
})
|
|
1653
|
-
);
|
|
1654
|
-
return issues;
|
|
1655
|
-
}
|
|
1656
|
-
);
|
|
1657
1442
|
return [
|
|
1658
1443
|
chainId,
|
|
1659
1444
|
loanToken,
|
|
1660
1445
|
expiry,
|
|
1661
|
-
// note: callback
|
|
1662
|
-
// integrators should be able to
|
|
1663
|
-
|
|
1664
|
-
sellOffersEmptyCallback,
|
|
1665
|
-
buyOffersEmptyCallback
|
|
1446
|
+
// note: callback rule should be the last one, since it does not mean that the offer is forever invalid
|
|
1447
|
+
// integrators should be able to choose if they want to keep the offer or not
|
|
1448
|
+
callback
|
|
1666
1449
|
];
|
|
1667
1450
|
}
|
|
1668
1451
|
|
|
1669
|
-
export {
|
|
1452
|
+
export { OfferStore_exports as OfferStore, Client_exports as Router, RouterOffer_exports as RouterOffer, utils_exports as Utils, Validation_exports as Validation, ValidationRule_exports as ValidationRule };
|
|
1670
1453
|
//# sourceMappingURL=index.browser.mjs.map
|
|
1671
1454
|
//# sourceMappingURL=index.browser.mjs.map
|