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