@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.
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  var mempool = require('@morpho-dev/mempool');
4
- var chains$1 = require('viem/chains');
5
4
  var v4 = require('zod/v4');
6
5
  var zodOpenapi = require('zod-openapi');
7
6
  var viem = require('viem');
@@ -16,85 +15,6 @@ var __export = (target, all) => {
16
15
  __defProp(target, name, { get: all[name], enumerable: true });
17
16
  };
18
17
 
19
- // src/Chain.ts
20
- var Chain_exports = {};
21
- __export(Chain_exports, {
22
- ChainId: () => ChainId,
23
- chainIds: () => chainIds,
24
- chainNames: () => chainNames,
25
- chains: () => chains,
26
- getChain: () => getChain,
27
- getWhitelistedChains: () => getWhitelistedChains
28
- });
29
- var chainNames = ["ethereum", "base", "ethereum-virtual-testnet"];
30
- var ChainId = {
31
- ETHEREUM: BigInt(chains$1.mainnet.id),
32
- BASE: BigInt(chains$1.base.id),
33
- "ETHEREUM-VIRTUAL-TESTNET": 109111114n
34
- };
35
- var chainIds = new Set(Object.values(ChainId));
36
- var chainNameLookup = new Map(Object.entries(ChainId).map(([key, value]) => [value, key]));
37
- function getChain(chainId) {
38
- const chainName = chainNameLookup.get(chainId)?.toLowerCase();
39
- if (!chainName) {
40
- return void 0;
41
- }
42
- return chains[chainName];
43
- }
44
- var getWhitelistedChains = () => {
45
- return [chains.ethereum, chains.base, chains["ethereum-virtual-testnet"]];
46
- };
47
- var chains = {
48
- ethereum: {
49
- ...chains$1.mainnet,
50
- id: ChainId.ETHEREUM,
51
- name: "ethereum",
52
- whitelistedAssets: new Set(
53
- [
54
- "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
55
- // USDC
56
- "0x6B175474E89094C44Da98b954EedeAC495271d0F"
57
- // DAI
58
- ].map((address) => address.toLowerCase())
59
- ),
60
- morpho: "0x0000000000000000000000000000000000000000"
61
- },
62
- base: {
63
- ...chains$1.base,
64
- id: ChainId.BASE,
65
- name: "base",
66
- whitelistedAssets: new Set(
67
- [
68
- "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
69
- // USDC
70
- "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb"
71
- // DAI
72
- ].map((address) => address.toLowerCase())
73
- ),
74
- morpho: "0x0000000000000000000000000000000000000000"
75
- },
76
- "ethereum-virtual-testnet": {
77
- ...chains$1.mainnet,
78
- id: 109111114n,
79
- name: "ethereum-virtual-testnet",
80
- whitelistedAssets: new Set(
81
- [
82
- "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
83
- // USDC
84
- "0x6B175474E89094C44Da98b954EedeAC495271d0F"
85
- // DAI
86
- ].map((address) => address.toLowerCase())
87
- ),
88
- morpho: "0x11a002d45db720ed47a80d2f3489cba5b833eaf5",
89
- // @TODO: This is mock Consumed contract, update with Terms once stable
90
- mempool: {
91
- address: "0x7be3164eeee8b35092f6128ec32c2e6ff8f6c890",
92
- deploymentBlock: 23223727,
93
- reindexBuffer: 10
94
- }
95
- }
96
- };
97
-
98
18
  // src/core/apiSchema/index.ts
99
19
  var apiSchema_exports = {};
100
20
  __export(apiSchema_exports, {
@@ -1102,7 +1022,6 @@ function memory(parameters) {
1102
1022
  const map = parameters.offers;
1103
1023
  const filled = parameters.filled;
1104
1024
  const consumedIds = /* @__PURE__ */ new Set();
1105
- const indexingProgress = /* @__PURE__ */ new Map();
1106
1025
  const create = async (parameters2) => {
1107
1026
  if (map.has(parameters2.offer.hash.toLowerCase())) return parameters2.offer.hash;
1108
1027
  map.set(parameters2.offer.hash.toLowerCase(), {
@@ -1173,7 +1092,7 @@ function memory(parameters) {
1173
1092
  let {
1174
1093
  creators,
1175
1094
  side,
1176
- chains: chains2,
1095
+ chains,
1177
1096
  loanTokens,
1178
1097
  status = ["valid"],
1179
1098
  callbackAddresses,
@@ -1244,7 +1163,7 @@ function memory(parameters) {
1244
1163
  offers = offers.filter((o) => o.expiry >= now);
1245
1164
  creators && (offers = offers.filter((o) => creators.includes(o.offering.toLowerCase())));
1246
1165
  side && (offers = offers.filter((o) => o.buy === buy));
1247
- chains2 && (offers = offers.filter((o) => chains2.includes(Number(o.chainId))));
1166
+ chains && (offers = offers.filter((o) => chains.includes(Number(o.chainId))));
1248
1167
  loanTokens && (offers = offers.filter((o) => loanTokens.includes(o.loanToken.toLowerCase())));
1249
1168
  status && (offers = offers.filter((o) => status.includes(o.status)));
1250
1169
  callbackAddresses && (offers = offers.filter(
@@ -1450,15 +1369,6 @@ function memory(parameters) {
1450
1369
  filledForOffering.set(nonce, current + parameters2.consumed);
1451
1370
  filledForChain.set(address, filledForOffering);
1452
1371
  filled.set(chainId, filledForChain);
1453
- },
1454
- saveLatestBlockNumberProcessed: async (parameters2) => {
1455
- const key = `${parameters2.chainId.toString()}:${parameters2.eventType}`;
1456
- indexingProgress.set(key, parameters2.latestBlockNumber);
1457
- },
1458
- getLatestBlockNumberProcessed: async (parameters2) => {
1459
- const key = `${parameters2.chainId.toString()}:${parameters2.eventType}`;
1460
- const value = indexingProgress.get(key);
1461
- return value === void 0 ? null : { latestBlockNumber: value };
1462
1372
  }
1463
1373
  };
1464
1374
  }
@@ -1712,18 +1622,6 @@ function getLogger() {
1712
1622
  return loggerContext.getStore() ?? defaultLogger();
1713
1623
  }
1714
1624
 
1715
- // src/RouterEvent.ts
1716
- var RouterEvent_exports = {};
1717
- __export(RouterEvent_exports, {
1718
- from: () => from2,
1719
- types: () => types
1720
- });
1721
- var types = ["offer_created", "offer_consumed", "offer_validation"];
1722
- function from2(base) {
1723
- const id = base.type === "offer_consumed" ? `${base.type}:${base.offerConsumed.id}` : `${base.type}:${base.offer.hash.toLowerCase()}`;
1724
- return { id, ...base };
1725
- }
1726
-
1727
1625
  // src/Validation.ts
1728
1626
  var Validation_exports = {};
1729
1627
  __export(Validation_exports, {
@@ -1784,25 +1682,19 @@ function single(name, run2) {
1784
1682
  function batch2(name, run2) {
1785
1683
  return { kind: "batch", name, run: run2 };
1786
1684
  }
1787
- function morpho(parameters) {
1788
- const { whitelistedChains } = parameters;
1789
- const whitelistedChainIds = new Set(whitelistedChains.map((chain) => chain.id));
1790
- const whitelistedLoanTokensPerChain = new Map(
1791
- whitelistedChains.map((chain) => [
1792
- chain.id,
1793
- new Set(Array.from(chain.whitelistedAssets).map((a) => a.toLowerCase()))
1794
- ])
1795
- );
1796
- const morphoPerChain = new Map(
1797
- whitelistedChains.map((chain) => [chain.id, chain.morpho.toLowerCase()])
1798
- );
1799
- const chainId = single("chain_id", (offer, _) => {
1800
- if (!whitelistedChainIds.has(offer.chainId)) {
1801
- return { message: `Chain ID ${offer.chainId} is not whitelisted` };
1685
+ function morpho() {
1686
+ const chainId = single("chain_id", (offer, { chain }) => {
1687
+ if (chain.id !== offer.chainId) {
1688
+ return {
1689
+ message: `Chain ID ${offer.chainId} is not the same as the chain ID in the context (${chain.id})`
1690
+ };
1802
1691
  }
1803
1692
  });
1804
- const loanToken = single("loan_token", (offer, _) => {
1805
- if (!whitelistedLoanTokensPerChain.get(offer.chainId)?.has(offer.loanToken.toLowerCase())) {
1693
+ const loanToken = single("loan_token", (offer, { chain }) => {
1694
+ const tokens = new Set(
1695
+ Array.from(chain.whitelistedAssets.values()).map((a) => a.toLowerCase())
1696
+ );
1697
+ if (!tokens.has(offer.loanToken.toLowerCase())) {
1806
1698
  return {
1807
1699
  message: `Loan token ${offer.loanToken} is not whitelisted on chain ${offer.chainId}`
1808
1700
  };
@@ -1813,136 +1705,25 @@ function morpho(parameters) {
1813
1705
  return { message: "Expiry mismatch" };
1814
1706
  }
1815
1707
  });
1816
- const emptyCallback = single("empty_callback", (offer, _) => {
1817
- if (offer.callback.data !== "0x") {
1818
- return { message: "Callback data is not empty. Not supported yet." };
1708
+ const callback = single("empty_callback", (offer, _) => {
1709
+ if (!offer.buy || offer.callback.data !== "0x") {
1710
+ return { message: "Callback not supported yet." };
1819
1711
  }
1820
1712
  });
1821
- const sellOffersEmptyCallback = single(
1822
- "sell_offers_empty_callback",
1823
- (offer, _) => {
1824
- if (!offer.buy && offer.callback.data === "0x") {
1825
- return { message: "Sell offers with empty callback are not supported yet." };
1826
- }
1827
- }
1828
- );
1829
- const buyOffersEmptyCallback = batch2(
1830
- "buy_offers_empty_callback",
1831
- async (offers, { publicClients }) => {
1832
- const issues = /* @__PURE__ */ new Map();
1833
- const hashToIndex = /* @__PURE__ */ new Map();
1834
- for (let i = 0; i < offers.length; i++) {
1835
- const offer = offers[i];
1836
- hashToIndex.set(offer.hash, i);
1837
- }
1838
- const { buyOffers, sellOffers: _sellOffers } = offers.reduce(
1839
- (acc, offer) => {
1840
- offer.buy ? acc.buyOffers.push(offer) : issues.set(hashToIndex.get(offer.hash), {
1841
- message: "Onchain callback for sell offers is not supported yet."
1842
- });
1843
- return acc;
1844
- },
1845
- { buyOffers: [], sellOffers: [] }
1846
- );
1847
- const buyOffersPerLoanAsset = /* @__PURE__ */ new Map();
1848
- for (const offer of buyOffers) {
1849
- const chainName = getChain(offer.chainId)?.name;
1850
- const loanTokens = buyOffersPerLoanAsset.get(chainName) ?? /* @__PURE__ */ new Map();
1851
- const offers2 = loanTokens.get(offer.loanToken.toLowerCase()) ?? [];
1852
- offers2.push(offer);
1853
- loanTokens.set(offer.loanToken.toLowerCase(), offers2);
1854
- buyOffersPerLoanAsset.set(chainName, loanTokens);
1855
- }
1856
- await Promise.all(
1857
- Array.from(buyOffersPerLoanAsset.entries()).map(async ([name, loanTokens]) => {
1858
- const chainName = name;
1859
- const publicClient = publicClients[chainName];
1860
- const morpho2 = morphoPerChain.get(chains[chainName].id);
1861
- if (!publicClient) {
1862
- const offers2 = Array.from(loanTokens.values()).flat();
1863
- for (const offer of offers2) {
1864
- issues.set(hashToIndex.get(offer.hash), {
1865
- message: `Public client for chain "${chainName}" is not available`
1866
- });
1867
- }
1868
- return;
1869
- }
1870
- const balances = /* @__PURE__ */ new Map();
1871
- const allowances = /* @__PURE__ */ new Map();
1872
- for (const [loanToken2, offers2] of loanTokens) {
1873
- const data = await Promise.all(
1874
- offers2.flatMap((offer) => [
1875
- publicClient.readContract({
1876
- address: loanToken2,
1877
- abi: viem.parseAbi([
1878
- "function balanceOf(address owner) view returns (uint256 balance)"
1879
- ]),
1880
- functionName: "balanceOf",
1881
- args: [offer.offering]
1882
- }),
1883
- publicClient.readContract({
1884
- address: loanToken2,
1885
- abi: viem.parseAbi([
1886
- "function allowance(address owner, address spender) public view returns (uint256 remaining)"
1887
- ]),
1888
- functionName: "allowance",
1889
- args: [offer.offering, morpho2]
1890
- })
1891
- ])
1892
- );
1893
- for (let i = 0; i < offers2.length; i++) {
1894
- const user = offers2[i].offering.toLowerCase();
1895
- const balance = data[i * 2] || 0n;
1896
- const allowance = data[i * 2 + 1] || 0n;
1897
- const userBalances = balances.get(user) ?? /* @__PURE__ */ new Map();
1898
- userBalances.set(loanToken2.toLowerCase(), balance);
1899
- const userAllowances = allowances.get(user) ?? /* @__PURE__ */ new Map();
1900
- userAllowances.set(loanToken2.toLowerCase(), allowance);
1901
- balances.set(user, userBalances);
1902
- allowances.set(user, userAllowances);
1903
- }
1904
- }
1905
- for (const offer of Array.from(loanTokens.values()).flat()) {
1906
- const user = offer.offering.toLowerCase();
1907
- const userBalances = balances.get(user);
1908
- const balance = userBalances?.get(offer.loanToken.toLowerCase());
1909
- if (balance < offer.assets) {
1910
- issues.set(hashToIndex.get(offer.hash), {
1911
- message: `Insufficient balance for ${offer.loanToken} on chain ${offer.chainId} (${balance.toString()} < ${offer.assets.toString()})`
1912
- });
1913
- continue;
1914
- }
1915
- const userAllowances = allowances.get(user);
1916
- const allowance = userAllowances?.get(offer.loanToken.toLowerCase());
1917
- if (allowance < offer.assets) {
1918
- issues.set(hashToIndex.get(offer.hash), {
1919
- message: `Insufficient allowance for ${offer.loanToken} on chain ${offer.chainId} (${allowance.toString()} < ${offer.assets.toString()})`
1920
- });
1921
- }
1922
- }
1923
- })
1924
- );
1925
- return issues;
1926
- }
1927
- );
1928
1713
  return [
1929
1714
  chainId,
1930
1715
  loanToken,
1931
1716
  expiry,
1932
- // note: callback onchain check should be done last since it does not mean that the offer is forever invalid
1933
- // integrators should be able to keep the offers that have an invalid callback onchain and be sure that is the only check that is not valid
1934
- emptyCallback,
1935
- sellOffersEmptyCallback,
1936
- buyOffersEmptyCallback
1717
+ // note: callback rule should be the last one, since it does not mean that the offer is forever invalid
1718
+ // integrators should be able to choose if they want to keep the offer or not
1719
+ callback
1937
1720
  ];
1938
1721
  }
1939
1722
 
1940
1723
  exports.ApiSchema = apiSchema_exports;
1941
- exports.Chain = Chain_exports;
1942
1724
  exports.Logger = Logger_exports;
1943
1725
  exports.OfferStore = OfferStore_exports;
1944
1726
  exports.Router = router_exports;
1945
- exports.RouterEvent = RouterEvent_exports;
1946
1727
  exports.RouterOffer = RouterOffer_exports;
1947
1728
  exports.Utils = utils_exports;
1948
1729
  exports.Validation = Validation_exports;