@continuumdao/ctm-mpc-defi 0.2.30 → 0.2.32

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.
Files changed (40) hide show
  1. package/dist/agent/catalog.cjs +1933 -56
  2. package/dist/agent/catalog.cjs.map +1 -1
  3. package/dist/agent/catalog.d.ts +3671 -661
  4. package/dist/agent/catalog.js +1896 -58
  5. package/dist/agent/catalog.js.map +1 -1
  6. package/dist/agent/skills/aerodrome/SKILL.md +93 -0
  7. package/dist/agent/skills/compound-v3/SKILL.md +132 -0
  8. package/dist/agent/skills/euler-v2/SKILL.md +1 -1
  9. package/dist/agent/skills/morpho/SKILL.md +16 -8
  10. package/dist/buildBatch-CngvebiD.d.ts +45 -0
  11. package/dist/chains/evm/index.d.ts +6 -44
  12. package/dist/core/index.cjs +2 -1
  13. package/dist/core/index.cjs.map +1 -1
  14. package/dist/core/index.js +2 -1
  15. package/dist/core/index.js.map +1 -1
  16. package/dist/index.cjs +119 -1
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.ts +4 -1
  19. package/dist/index.js +119 -2
  20. package/dist/index.js.map +1 -1
  21. package/dist/protocols/evm/aerodrome/index.cjs +3922 -0
  22. package/dist/protocols/evm/aerodrome/index.cjs.map +1 -0
  23. package/dist/protocols/evm/aerodrome/index.d.ts +792 -0
  24. package/dist/protocols/evm/aerodrome/index.js +3843 -0
  25. package/dist/protocols/evm/aerodrome/index.js.map +1 -0
  26. package/dist/protocols/evm/compound-v3/index.cjs +1542 -0
  27. package/dist/protocols/evm/compound-v3/index.cjs.map +1 -0
  28. package/dist/protocols/evm/compound-v3/index.d.ts +683 -0
  29. package/dist/protocols/evm/compound-v3/index.js +1488 -0
  30. package/dist/protocols/evm/compound-v3/index.js.map +1 -0
  31. package/dist/protocols/evm/euler-v2/index.cjs +17 -10
  32. package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
  33. package/dist/protocols/evm/euler-v2/index.js +17 -10
  34. package/dist/protocols/evm/euler-v2/index.js.map +1 -1
  35. package/dist/protocols/evm/morpho/index.cjs +746 -39
  36. package/dist/protocols/evm/morpho/index.cjs.map +1 -1
  37. package/dist/protocols/evm/morpho/index.d.ts +161 -14
  38. package/dist/protocols/evm/morpho/index.js +736 -42
  39. package/dist/protocols/evm/morpho/index.js.map +1 -1
  40. package/package.json +15 -1
@@ -47,17 +47,27 @@ var init_defiProxy = __esm({
47
47
  // src/protocols/evm/morpho/midnightConstants.ts
48
48
  var midnightConstants_exports = {};
49
49
  __export(midnightConstants_exports, {
50
+ MORPHO_BLUE_CANONICAL: () => exports.MORPHO_BLUE_CANONICAL,
50
51
  MORPHO_MIDNIGHT_ADDRESSES: () => exports.MORPHO_MIDNIGHT_ADDRESSES,
51
52
  MORPHO_MIDNIGHT_AUTHORIZE_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_AUTHORIZE_FALLBACK_GAS,
52
53
  MORPHO_MIDNIGHT_BASE_CHAIN_ID: () => exports.MORPHO_MIDNIGHT_BASE_CHAIN_ID,
54
+ MORPHO_MIDNIGHT_BLUE_SUPPLY_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_BLUE_SUPPLY_FALLBACK_GAS,
55
+ MORPHO_MIDNIGHT_BLUE_WITHDRAW_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_BLUE_WITHDRAW_FALLBACK_GAS,
53
56
  MORPHO_MIDNIGHT_BOOKS_MAX_LIMIT: () => exports.MORPHO_MIDNIGHT_BOOKS_MAX_LIMIT,
54
57
  MORPHO_MIDNIGHT_BORROW_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_BORROW_FALLBACK_GAS,
58
+ MORPHO_MIDNIGHT_CALLBACK_SALT: () => exports.MORPHO_MIDNIGHT_CALLBACK_SALT,
59
+ MORPHO_MIDNIGHT_CREATE_CALLBACK_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_CREATE_CALLBACK_FALLBACK_GAS,
55
60
  MORPHO_MIDNIGHT_DEFAULT_DEADLINE_SECONDS: () => exports.MORPHO_MIDNIGHT_DEFAULT_DEADLINE_SECONDS,
61
+ MORPHO_MIDNIGHT_DEFAULT_OFFER_TTL_SECONDS: () => exports.MORPHO_MIDNIGHT_DEFAULT_OFFER_TTL_SECONDS,
56
62
  MORPHO_MIDNIGHT_DEFAULT_SLIPPAGE_PCT: () => exports.MORPHO_MIDNIGHT_DEFAULT_SLIPPAGE_PCT,
57
63
  MORPHO_MIDNIGHT_ERC20_APPROVE_FALLBACK: () => exports.MORPHO_MIDNIGHT_ERC20_APPROVE_FALLBACK,
64
+ MORPHO_MIDNIGHT_ETHEREUM_CHAIN_ID: () => exports.MORPHO_MIDNIGHT_ETHEREUM_CHAIN_ID,
58
65
  MORPHO_MIDNIGHT_LEND_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_LEND_FALLBACK_GAS,
66
+ MORPHO_MIDNIGHT_MEMPOOL_PUBLISH_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_MEMPOOL_PUBLISH_FALLBACK_GAS,
59
67
  MORPHO_MIDNIGHT_REPAY_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_REPAY_FALLBACK_GAS,
60
68
  MORPHO_MIDNIGHT_REST_BASE: () => exports.MORPHO_MIDNIGHT_REST_BASE,
69
+ MORPHO_MIDNIGHT_SET_CONSUMED_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_SET_CONSUMED_FALLBACK_GAS,
70
+ MORPHO_MIDNIGHT_SET_ROOT_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_SET_ROOT_FALLBACK_GAS,
61
71
  MORPHO_MIDNIGHT_WETH_DEPOSIT_FALLBACK: () => exports.MORPHO_MIDNIGHT_WETH_DEPOSIT_FALLBACK,
62
72
  TOKEN_PERMIT_NONE: () => exports.TOKEN_PERMIT_NONE,
63
73
  morphoMidnightAddressesForChain: () => morphoMidnightAddressesForChain
@@ -65,18 +75,36 @@ __export(midnightConstants_exports, {
65
75
  function morphoMidnightAddressesForChain(chainId) {
66
76
  return exports.MORPHO_MIDNIGHT_ADDRESSES[chainId] ?? null;
67
77
  }
68
- exports.MORPHO_MIDNIGHT_REST_BASE = void 0; exports.MORPHO_MIDNIGHT_BOOKS_MAX_LIMIT = void 0; exports.MORPHO_MIDNIGHT_DEFAULT_SLIPPAGE_PCT = void 0; exports.MORPHO_MIDNIGHT_DEFAULT_DEADLINE_SECONDS = void 0; exports.MORPHO_MIDNIGHT_BASE_CHAIN_ID = void 0; exports.MORPHO_MIDNIGHT_ADDRESSES = void 0; exports.TOKEN_PERMIT_NONE = void 0; exports.MORPHO_MIDNIGHT_LEND_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_BORROW_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_REPAY_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_AUTHORIZE_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_ERC20_APPROVE_FALLBACK = void 0; exports.MORPHO_MIDNIGHT_WETH_DEPOSIT_FALLBACK = void 0;
78
+ exports.MORPHO_MIDNIGHT_REST_BASE = void 0; exports.MORPHO_MIDNIGHT_BOOKS_MAX_LIMIT = void 0; exports.MORPHO_MIDNIGHT_DEFAULT_SLIPPAGE_PCT = void 0; exports.MORPHO_MIDNIGHT_DEFAULT_DEADLINE_SECONDS = void 0; exports.MORPHO_MIDNIGHT_DEFAULT_OFFER_TTL_SECONDS = void 0; exports.MORPHO_MIDNIGHT_BASE_CHAIN_ID = void 0; exports.MORPHO_MIDNIGHT_ETHEREUM_CHAIN_ID = void 0; exports.MORPHO_BLUE_CANONICAL = void 0; exports.MORPHO_MIDNIGHT_CALLBACK_SALT = void 0; exports.MORPHO_MIDNIGHT_ADDRESSES = void 0; exports.TOKEN_PERMIT_NONE = void 0; exports.MORPHO_MIDNIGHT_LEND_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_BORROW_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_REPAY_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_AUTHORIZE_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_ERC20_APPROVE_FALLBACK = void 0; exports.MORPHO_MIDNIGHT_WETH_DEPOSIT_FALLBACK = void 0; exports.MORPHO_MIDNIGHT_CREATE_CALLBACK_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_BLUE_SUPPLY_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_BLUE_WITHDRAW_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_SET_ROOT_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_MEMPOOL_PUBLISH_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_SET_CONSUMED_FALLBACK_GAS = void 0;
69
79
  var init_midnightConstants = __esm({
70
80
  "src/protocols/evm/morpho/midnightConstants.ts"() {
71
81
  exports.MORPHO_MIDNIGHT_REST_BASE = "https://api.morpho.org/v0/midnight";
72
82
  exports.MORPHO_MIDNIGHT_BOOKS_MAX_LIMIT = 20;
73
83
  exports.MORPHO_MIDNIGHT_DEFAULT_SLIPPAGE_PCT = "0.5";
74
84
  exports.MORPHO_MIDNIGHT_DEFAULT_DEADLINE_SECONDS = 3600;
85
+ exports.MORPHO_MIDNIGHT_DEFAULT_OFFER_TTL_SECONDS = 7 * 24 * 3600;
75
86
  exports.MORPHO_MIDNIGHT_BASE_CHAIN_ID = 8453;
87
+ exports.MORPHO_MIDNIGHT_ETHEREUM_CHAIN_ID = 1;
88
+ exports.MORPHO_BLUE_CANONICAL = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb";
89
+ exports.MORPHO_MIDNIGHT_CALLBACK_SALT = viem.keccak256(viem.toBytes("continuum-midnight-lend-v1"));
76
90
  exports.MORPHO_MIDNIGHT_ADDRESSES = {
91
+ [exports.MORPHO_MIDNIGHT_ETHEREUM_CHAIN_ID]: {
92
+ midnight: "0x471686c42792F93528B000beF54bC10E3aa2045f",
93
+ bundles: "0x7c00dBB2b6b6b9B28745332e550dC8782Fcf77EC",
94
+ mempool: "0xde2d62449301a09A51EbF9326EA60d2e8BF4A8F7",
95
+ setterRatifier: "0xb72c416382c8A6399D0765CebfB032F040B00B3c",
96
+ ecrecoverRatifier: "0xAC439c81CAA6ef4C7B7E8F0110F8CE63A4b6D43e",
97
+ blueBuyCallbackFactory: "0x172d1FdC5f79bFe1ED46448f18541E591E5c93a7",
98
+ morphoBlue: exports.MORPHO_BLUE_CANONICAL
99
+ },
77
100
  [exports.MORPHO_MIDNIGHT_BASE_CHAIN_ID]: {
78
- midnight: "0xadedd8ab6de832766fedf0fac4992e5c4d3ea18a",
79
- bundles: "0x6688dEc8878f43905e11B3C6Bc025E098133144f"
101
+ midnight: "0xAdedD8ab6dE832766Fedf0FaC4992E5C4D3EA18A",
102
+ bundles: "0x091183d729BE9f808c212b475E387A12E67850A7",
103
+ mempool: "0xdD6DCE32e21f7b020898a8258dA37355b4017993",
104
+ setterRatifier: "0x800B5F12A61B8198a5a6EfD794Cac6699B294d63",
105
+ ecrecoverRatifier: "0xd6e70365C8E8DDa9a4ca662C07bbE663b017755E",
106
+ blueBuyCallbackFactory: "0x7337f119Eca028bD39E0e543cEf71631D2333425",
107
+ morphoBlue: exports.MORPHO_BLUE_CANONICAL
80
108
  }
81
109
  };
82
110
  exports.TOKEN_PERMIT_NONE = { kind: 0, data: "0x" };
@@ -86,6 +114,12 @@ var init_midnightConstants = __esm({
86
114
  exports.MORPHO_MIDNIGHT_AUTHORIZE_FALLBACK_GAS = 80000n;
87
115
  exports.MORPHO_MIDNIGHT_ERC20_APPROVE_FALLBACK = 100000n;
88
116
  exports.MORPHO_MIDNIGHT_WETH_DEPOSIT_FALLBACK = 120000n;
117
+ exports.MORPHO_MIDNIGHT_CREATE_CALLBACK_FALLBACK_GAS = 1200000n;
118
+ exports.MORPHO_MIDNIGHT_BLUE_SUPPLY_FALLBACK_GAS = 400000n;
119
+ exports.MORPHO_MIDNIGHT_BLUE_WITHDRAW_FALLBACK_GAS = 350000n;
120
+ exports.MORPHO_MIDNIGHT_SET_ROOT_FALLBACK_GAS = 80000n;
121
+ exports.MORPHO_MIDNIGHT_MEMPOOL_PUBLISH_FALLBACK_GAS = 250000n;
122
+ exports.MORPHO_MIDNIGHT_SET_CONSUMED_FALLBACK_GAS = 80000n;
89
123
  }
90
124
  });
91
125
 
@@ -95,6 +129,7 @@ __export(midnightApi_exports, {
95
129
  fetchMorphoMidnightBook: () => fetchMorphoMidnightBook,
96
130
  fetchMorphoMidnightBookQuote: () => fetchMorphoMidnightBookQuote,
97
131
  fetchMorphoMidnightBooks: () => fetchMorphoMidnightBooks,
132
+ fetchMorphoMidnightMakerOffers: () => fetchMorphoMidnightMakerOffers,
98
133
  fetchMorphoMidnightMarketById: () => fetchMorphoMidnightMarketById,
99
134
  fetchMorphoMidnightUserMarketPosition: () => fetchMorphoMidnightUserMarketPosition,
100
135
  fetchMorphoMidnightUserPositions: () => fetchMorphoMidnightUserPositions,
@@ -237,6 +272,39 @@ async function fetchMorphoMidnightUserPositions(args) {
237
272
  }
238
273
  return rows;
239
274
  }
275
+ async function fetchMorphoMidnightMakerOffers(args) {
276
+ const qs = new URLSearchParams();
277
+ qs.set("maker", viem.getAddress(args.maker));
278
+ if (args.chainId != null) qs.set("chain_ids", String(args.chainId));
279
+ const j = await midnightGetJson(`/takeable-offers?${qs}`);
280
+ const out = [];
281
+ for (const row of j.data ?? []) {
282
+ const o = row.offer;
283
+ if (!o?.maker || !viem.isAddress(o.maker) || !o.market?.loan_token || !viem.isAddress(o.market.loan_token)) continue;
284
+ if (!o.market.midnight || !viem.isAddress(o.market.midnight)) continue;
285
+ const group = (o.group ?? "").trim();
286
+ if (!group.startsWith("0x") || group.length !== 66) continue;
287
+ const callback = o.callback && viem.isAddress(o.callback) ? viem.getAddress(o.callback) : "0x0000000000000000000000000000000000000000";
288
+ out.push({
289
+ marketId: String(row.market_id ?? ""),
290
+ chainId: Number(o.market.chain_id ?? args.chainId ?? 0),
291
+ midnight: viem.getAddress(o.market.midnight),
292
+ loanToken: viem.getAddress(o.market.loan_token),
293
+ maker: viem.getAddress(o.maker),
294
+ buy: o.buy === true,
295
+ tick: String(o.tick ?? "0"),
296
+ maxAssets: String(o.max_assets ?? "0"),
297
+ maxUnits: String(o.max_units ?? "0"),
298
+ expiry: Number(o.expiry ?? 0),
299
+ group,
300
+ callback,
301
+ callbackData: o.callback_data ?? "0x",
302
+ units: String(row.units ?? "0"),
303
+ maturity: o.market.maturity != null ? Number(o.market.maturity) : null
304
+ });
305
+ }
306
+ return out;
307
+ }
240
308
  async function fetchMorphoMidnightUserMarketPosition(args) {
241
309
  const marketId = args.marketId.trim();
242
310
  const user = args.user.trim();
@@ -1463,18 +1531,43 @@ async function fetchMorphoMidnightIntents(_args) {
1463
1531
  // src/protocols/evm/morpho/index.ts
1464
1532
  init_midnightConstants();
1465
1533
  init_midnightApi();
1466
-
1467
- // src/protocols/evm/morpho/midnightMath.ts
1534
+ var WAD = 10n ** 18n;
1535
+ var SECONDS_PER_YEAR = 365 * 86400;
1536
+ function parseMorphoMidnightPriceWad(priceWad) {
1537
+ if (priceWad == null) return null;
1538
+ try {
1539
+ if (typeof priceWad === "bigint") return priceWad > 0n ? priceWad : null;
1540
+ if (typeof priceWad === "number") {
1541
+ if (!Number.isFinite(priceWad) || priceWad <= 0) return null;
1542
+ return BigInt(Math.round(priceWad));
1543
+ }
1544
+ const raw = BigInt(String(priceWad).split(".")[0] || "0");
1545
+ return raw > 0n ? raw : null;
1546
+ } catch {
1547
+ return null;
1548
+ }
1549
+ }
1468
1550
  function morphoMidnightAprFromPriceWad(priceWad, ttmSeconds) {
1469
- const raw = typeof priceWad === "bigint" ? priceWad : BigInt(priceWad.split(".")[0] || "0");
1470
- if (raw <= 0n || !Number.isFinite(ttmSeconds) || ttmSeconds <= 0) return null;
1551
+ const raw = parseMorphoMidnightPriceWad(priceWad);
1552
+ if (raw == null || !Number.isFinite(ttmSeconds) || ttmSeconds <= 0) return null;
1471
1553
  const p = Number(raw) / 1e18;
1472
1554
  if (!Number.isFinite(p) || p <= 0) return null;
1473
- const apr = (1 / p - 1) * (365 * 86400 / ttmSeconds);
1555
+ const apr = (1 / p - 1) * (SECONDS_PER_YEAR / ttmSeconds);
1474
1556
  return Number.isFinite(apr) ? apr : null;
1475
1557
  }
1476
- function formatMorphoMidnightAprPct(apr, digits = 2) {
1477
- if (apr == null || !Number.isFinite(apr)) return "\u2014";
1558
+ function morphoMidnightAprFromBookLevel(level, ttmSeconds) {
1559
+ if (!level || !Number.isFinite(ttmSeconds) || ttmSeconds <= 0) return null;
1560
+ if (level.tick != null && String(level.tick).trim() !== "") {
1561
+ try {
1562
+ const fromTick = morphoMidnightAprFromTick(BigInt(level.tick), ttmSeconds);
1563
+ if (fromTick != null) return fromTick;
1564
+ } catch {
1565
+ }
1566
+ }
1567
+ return level.price != null ? morphoMidnightAprFromPriceWad(level.price, ttmSeconds) : null;
1568
+ }
1569
+ function formatMorphoMidnightAprPct(apr, digits = 2, empty = "\u2014") {
1570
+ if (apr == null || !Number.isFinite(apr)) return empty;
1478
1571
  return `${(apr * 100).toFixed(digits)}%`;
1479
1572
  }
1480
1573
  function morphoMidnightTtmSeconds(maturityUnix, nowMs = Date.now()) {
@@ -1484,6 +1577,37 @@ function morphoMidnightUnitsFromAssets(targetAssets, priceWad) {
1484
1577
  if (priceWad <= 0n || targetAssets <= 0n) return 0n;
1485
1578
  return (targetAssets * 10n ** 18n + priceWad - 1n) / priceWad;
1486
1579
  }
1580
+ function parseMorphoMidnightAprInput(raw) {
1581
+ const t = raw.trim().replace(/%/g, "");
1582
+ if (!t || !/^\d*\.?\d+$/.test(t)) return null;
1583
+ const n = Number(t);
1584
+ if (!Number.isFinite(n) || n <= 0) return null;
1585
+ return n > 1 ? n / 100 : n;
1586
+ }
1587
+ function morphoMidnightPriceWadFromApr(apr, ttmSeconds) {
1588
+ if (!Number.isFinite(apr) || apr <= 0 || !Number.isFinite(ttmSeconds) || ttmSeconds <= 0) return null;
1589
+ const price = 1 / (1 + apr * (ttmSeconds / SECONDS_PER_YEAR));
1590
+ if (!Number.isFinite(price) || price <= 0 || price > 1) return null;
1591
+ return BigInt(Math.round(price * 1e18));
1592
+ }
1593
+ function morphoMidnightTickFromPriceWad(priceWad, spacing = midnightSdk.DEFAULT_TICK_SPACING) {
1594
+ return midnightSdk.TickLib.priceToTick(priceWad, spacing);
1595
+ }
1596
+ function morphoMidnightTickFromApr(apr, ttmSeconds, spacing = midnightSdk.DEFAULT_TICK_SPACING) {
1597
+ const priceWad = morphoMidnightPriceWadFromApr(apr, ttmSeconds);
1598
+ if (priceWad == null) return null;
1599
+ return morphoMidnightTickFromPriceWad(priceWad, spacing);
1600
+ }
1601
+ function morphoMidnightAprFromTick(tick, ttmSeconds) {
1602
+ if (ttmSeconds <= 0) return null;
1603
+ try {
1604
+ const aprWad = midnightSdk.TickLib.tickToApr(tick, BigInt(Math.floor(ttmSeconds)));
1605
+ const n = Number(aprWad) / Number(WAD);
1606
+ return Number.isFinite(n) ? n : null;
1607
+ } catch {
1608
+ return morphoMidnightAprFromPriceWad(midnightSdk.TickLib.tickToPrice(tick), ttmSeconds);
1609
+ }
1610
+ }
1487
1611
 
1488
1612
  // src/protocols/evm/morpho/midnightDiscovery.ts
1489
1613
  init_midnightApi();
@@ -1501,10 +1625,10 @@ function maturityIso(maturity) {
1501
1625
  }
1502
1626
  function morphoMidnightBookToDiscoveryRow(book) {
1503
1627
  const ttm = morphoMidnightTtmSeconds(book.maturity);
1504
- const bestAsk = book.asks[0];
1505
- const bestBid = book.bids[0];
1506
- const lendAprN = bestAsk ? morphoMidnightAprFromPriceWad(bestAsk.price, ttm) : null;
1507
- const borrowAprN = bestBid ? morphoMidnightAprFromPriceWad(bestBid.price, ttm) : null;
1628
+ const bestAsk = book.asks?.[0];
1629
+ const bestBid = book.bids?.[0];
1630
+ const lendAprN = morphoMidnightAprFromBookLevel(bestAsk, ttm);
1631
+ const borrowAprN = morphoMidnightAprFromBookLevel(bestBid, ttm);
1508
1632
  const loan = viem.getAddress(book.loanToken);
1509
1633
  const collaterals = book.collaterals.map((c) => viem.getAddress(c.token));
1510
1634
  const primary = book.collaterals[0];
@@ -1524,8 +1648,8 @@ function morphoMidnightBookToDiscoveryRow(book) {
1524
1648
  bestBidPriceWad: bestBid?.price ?? null,
1525
1649
  bestAskAssets: bestAsk?.assets ?? null,
1526
1650
  bestBidAssets: bestBid?.assets ?? null,
1527
- lendApr: formatMorphoMidnightAprPct(lendAprN),
1528
- borrowApr: formatMorphoMidnightAprPct(borrowAprN),
1651
+ lendApr: formatMorphoMidnightAprPct(lendAprN, 2, "No asks"),
1652
+ borrowApr: formatMorphoMidnightAprPct(borrowAprN, 2, "No bids"),
1529
1653
  lendAprNumeric: lendAprN,
1530
1654
  borrowAprNumeric: borrowAprN,
1531
1655
  marketLabel
@@ -1705,6 +1829,122 @@ async function morphoFetchMidnightPositionsSummary(args) {
1705
1829
  return { positions: rows.map(morphoMidnightPositionToDiscoveryRow) };
1706
1830
  }
1707
1831
 
1832
+ // src/protocols/evm/morpho/midnightOffers.ts
1833
+ init_midnightApi();
1834
+ function isoFromUnix(sec) {
1835
+ if (sec == null || sec <= 0) return "\u2014";
1836
+ try {
1837
+ return new Date(sec * 1e3).toISOString().slice(0, 10);
1838
+ } catch {
1839
+ return "\u2014";
1840
+ }
1841
+ }
1842
+ async function morphoFetchMidnightMakerOffersSummary(args) {
1843
+ if (!viem.isAddress(args.user)) {
1844
+ throw new Error("user must be a valid EVM address.");
1845
+ }
1846
+ const rows = await fetchMorphoMidnightMakerOffers({
1847
+ maker: viem.getAddress(args.user),
1848
+ chainId: args.chainId
1849
+ });
1850
+ const offers = [];
1851
+ for (const r of rows) {
1852
+ if (!r.buy) continue;
1853
+ const ttm = r.maturity != null ? morphoMidnightTtmSeconds(r.maturity) : 0;
1854
+ let tick = 0n;
1855
+ try {
1856
+ tick = BigInt(r.tick);
1857
+ } catch {
1858
+ tick = 0n;
1859
+ }
1860
+ const apr = ttm > 0 && tick > 0n ? morphoMidnightAprFromTick(tick, ttm) : null;
1861
+ offers.push({
1862
+ marketId: r.marketId,
1863
+ chainId: r.chainId,
1864
+ midnightAddress: r.midnight,
1865
+ loanTokenAddress: r.loanToken,
1866
+ maker: r.maker,
1867
+ group: r.group,
1868
+ callback: r.callback,
1869
+ callbackData: r.callbackData,
1870
+ tick: r.tick,
1871
+ maxAssets: r.maxAssets,
1872
+ remainingUnits: r.units,
1873
+ expiry: r.expiry,
1874
+ expiryIso: isoFromUnix(r.expiry),
1875
+ maturity: r.maturity,
1876
+ maturityIso: isoFromUnix(r.maturity),
1877
+ lendApr: formatMorphoMidnightAprPct(apr),
1878
+ lendAprNumeric: apr,
1879
+ marketLabel: `Offer \xB7 ${isoFromUnix(r.maturity)} \xB7 ${formatMorphoMidnightAprPct(apr)}`
1880
+ });
1881
+ }
1882
+ return { offers };
1883
+ }
1884
+ var BLUE_MARKET_PARAMS_ABI = [
1885
+ {
1886
+ type: "tuple",
1887
+ components: [
1888
+ { name: "loanToken", type: "address" },
1889
+ { name: "collateralToken", type: "address" },
1890
+ { name: "oracle", type: "address" },
1891
+ { name: "irm", type: "address" },
1892
+ { name: "lltv", type: "uint256" }
1893
+ ]
1894
+ }
1895
+ ];
1896
+ function encodeMorphoBlueMarketParamsCallbackData(params) {
1897
+ return viem.encodeAbiParameters(BLUE_MARKET_PARAMS_ABI, [
1898
+ {
1899
+ loanToken: params.loanToken,
1900
+ collateralToken: params.collateralToken,
1901
+ oracle: params.oracle,
1902
+ irm: params.irm,
1903
+ lltv: params.lltv
1904
+ }
1905
+ ]);
1906
+ }
1907
+ async function pickBestBlueSupplyMarketForLoan(args) {
1908
+ const loan = viem.getAddress(args.loanToken).toLowerCase();
1909
+ const d = await morphoGql(
1910
+ `
1911
+ query MorphoBlueParkMarkets($chainId: Int!) {
1912
+ markets(first: 200, where: { chainId_in: [$chainId] }, orderBy: SupplyAssetsUsd, orderDirection: Desc) {
1913
+ items {
1914
+ marketId
1915
+ loanAsset { address symbol decimals price { usd } }
1916
+ collateralAsset { address symbol decimals price { usd } }
1917
+ lltv
1918
+ oracle { address }
1919
+ irmAddress
1920
+ morphoBlue { address }
1921
+ state {
1922
+ supplyApy borrowApy netSupplyApy netBorrowApy
1923
+ supplyAssetsUsd borrowAssetsUsd collateralAssetsUsd utilization
1924
+ rewards { supplyApr borrowApr asset { address symbol } }
1925
+ }
1926
+ }
1927
+ }
1928
+ }
1929
+ `,
1930
+ { chainId: args.chainId }
1931
+ );
1932
+ for (const row of d.markets?.items ?? []) {
1933
+ const loanAddr = (row.loanAsset?.address ?? "").trim().toLowerCase();
1934
+ if (loanAddr !== loan || !row.morphoBlue?.address) continue;
1935
+ try {
1936
+ return {
1937
+ ...row,
1938
+ morphoBlueAddress: viem.getAddress(row.morphoBlue.address),
1939
+ marketParams: marketParamsFromApiRow(row)
1940
+ };
1941
+ } catch {
1942
+ continue;
1943
+ }
1944
+ }
1945
+ return null;
1946
+ }
1947
+
1708
1948
  // src/core/purpose.ts
1709
1949
  function mergePurposeText(purposeText, purposeSuffix) {
1710
1950
  const t = (purposeText ?? "").trim();
@@ -2401,6 +2641,458 @@ async function buildEvmMultisignBodyMorphoMidnightRepayBatch(args) {
2401
2641
  })
2402
2642
  });
2403
2643
  }
2644
+ init_midnightConstants();
2645
+ init_midnightApi();
2646
+ var wethDepositAbi2 = viem.parseAbi(["function deposit() payable"]);
2647
+ var erc20Abi2 = viem.parseAbi([
2648
+ "function allowance(address owner, address spender) view returns (uint256)",
2649
+ "function decimals() view returns (uint8)",
2650
+ "function approve(address spender, uint256 amount) returns (bool)"
2651
+ ]);
2652
+ var factoryAbi = viem.parseAbi([
2653
+ "function callbackOf(address owner, bytes32 salt) view returns (address)",
2654
+ "function createBlueBuyCallback(address owner, bytes32 salt) returns (address)"
2655
+ ]);
2656
+ var setterAbi = viem.parseAbi([
2657
+ "function isRootRatified(address maker, bytes32 root) view returns (bool)",
2658
+ "function setIsRootRatified(address maker, bytes32 root, bool newIsRatified)"
2659
+ ]);
2660
+ var morphoBlueAbi = viem.parseAbi([
2661
+ "function supply((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv), uint256 assets, uint256 shares, address onBehalf, bytes data)",
2662
+ "function withdraw((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv), uint256 assets, uint256 shares, address onBehalf, address receiver)",
2663
+ "function position(bytes32 id, address user) view returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral)"
2664
+ ]);
2665
+ var blueMarketParamsAbi = [
2666
+ {
2667
+ type: "tuple",
2668
+ components: [
2669
+ { name: "loanToken", type: "address" },
2670
+ { name: "collateralToken", type: "address" },
2671
+ { name: "oracle", type: "address" },
2672
+ { name: "irm", type: "address" },
2673
+ { name: "lltv", type: "uint256" }
2674
+ ]
2675
+ }
2676
+ ];
2677
+ function publicClientFor2(rpcUrl, chainId) {
2678
+ const ch = viem.defineChain({
2679
+ id: chainId,
2680
+ name: "MorphoMidnight",
2681
+ nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
2682
+ rpcUrls: { default: { http: [rpcUrl] } }
2683
+ });
2684
+ return viem.createPublicClient({ chain: ch, transport: viem.http(rpcUrl) });
2685
+ }
2686
+ async function readTokenDecimals2(args) {
2687
+ const publicClient = publicClientFor2(args.rpcUrl, args.chainId);
2688
+ const d = await publicClient.readContract({
2689
+ address: args.token,
2690
+ abi: erc20Abi2,
2691
+ functionName: "decimals"
2692
+ });
2693
+ const n = typeof d === "bigint" ? Number(d) : Number(d);
2694
+ return !Number.isFinite(n) || n < 0 || n > 36 ? 18 : n;
2695
+ }
2696
+ async function buildApproveSteps2(args) {
2697
+ const steps = [];
2698
+ let spendToken = args.token;
2699
+ if (args.isNativeIn && args.nativeWrapped) {
2700
+ const weth = viem.getAddress(args.nativeWrapped);
2701
+ if (spendToken.toLowerCase() !== weth.toLowerCase()) {
2702
+ throw new Error("Native path: token must match wrapped native.");
2703
+ }
2704
+ steps.push({
2705
+ kind: "weth_deposit",
2706
+ to: weth,
2707
+ data: viem.encodeFunctionData({ abi: wethDepositAbi2, functionName: "deposit" }),
2708
+ value: args.amountWei
2709
+ });
2710
+ spendToken = weth;
2711
+ }
2712
+ const publicClient = publicClientFor2(args.rpcUrl, args.chainId);
2713
+ const currentAllowance = await publicClient.readContract({
2714
+ address: spendToken,
2715
+ abi: erc20Abi2,
2716
+ functionName: "allowance",
2717
+ args: [args.executor, args.spender]
2718
+ });
2719
+ if (currentAllowance < args.amountWei) {
2720
+ if (currentAllowance > 0n) {
2721
+ steps.push({
2722
+ kind: "approve",
2723
+ to: spendToken,
2724
+ data: viem.encodeFunctionData({ abi: erc20Abi2, functionName: "approve", args: [args.spender, 0n] }),
2725
+ value: 0n
2726
+ });
2727
+ }
2728
+ steps.push({
2729
+ kind: "approve",
2730
+ to: spendToken,
2731
+ data: viem.encodeFunctionData({
2732
+ abi: erc20Abi2,
2733
+ functionName: "approve",
2734
+ args: [args.spender, args.amountWei]
2735
+ }),
2736
+ value: 0n
2737
+ });
2738
+ }
2739
+ return steps;
2740
+ }
2741
+ function approveStepsToEvm2(steps) {
2742
+ return steps.map((s) => ({
2743
+ to: s.to,
2744
+ data: s.data,
2745
+ value: s.value,
2746
+ fallbackGas: s.kind === "weth_deposit" ? exports.MORPHO_MIDNIGHT_WETH_DEPOSIT_FALLBACK : exports.MORPHO_MIDNIGHT_ERC20_APPROVE_FALLBACK
2747
+ }));
2748
+ }
2749
+ async function ensureAuthorizedSteps(args) {
2750
+ const publicClient = publicClientFor2(args.rpcUrl, args.chainId);
2751
+ const authorized = await publicClient.readContract({
2752
+ address: args.midnight,
2753
+ abi: midnightSdk.midnightAbi,
2754
+ functionName: "isAuthorized",
2755
+ args: [args.onBehalf, args.authorized]
2756
+ });
2757
+ if (authorized) return [];
2758
+ return [
2759
+ {
2760
+ to: args.midnight,
2761
+ data: viem.encodeFunctionData({
2762
+ abi: midnightSdk.midnightAbi,
2763
+ functionName: "setIsAuthorized",
2764
+ args: [args.authorized, true, args.onBehalf]
2765
+ }),
2766
+ value: 0n,
2767
+ fallbackGas: exports.MORPHO_MIDNIGHT_AUTHORIZE_FALLBACK_GAS
2768
+ }
2769
+ ];
2770
+ }
2771
+ function bookLevelTick(level) {
2772
+ if (!level) return null;
2773
+ if (level.tick != null && String(level.tick).trim() !== "") {
2774
+ try {
2775
+ return BigInt(level.tick);
2776
+ } catch {
2777
+ return null;
2778
+ }
2779
+ }
2780
+ if (!level.price) return null;
2781
+ try {
2782
+ return morphoMidnightTickFromPriceWad(BigInt(String(level.price).split(".")[0] || "0"));
2783
+ } catch {
2784
+ return null;
2785
+ }
2786
+ }
2787
+ function resolveOfferTick(args) {
2788
+ if (args.tick?.trim()) {
2789
+ try {
2790
+ const t = BigInt(args.tick.trim());
2791
+ if (t > 0n) return t;
2792
+ } catch {
2793
+ throw new Error(`Invalid Midnight offer tick: ${args.tick}`);
2794
+ }
2795
+ }
2796
+ const ttm = morphoMidnightTtmSeconds(args.book.maturity);
2797
+ if (args.lendAprPct?.trim()) {
2798
+ const apr = parseMorphoMidnightAprInput(args.lendAprPct);
2799
+ if (apr == null) throw new Error("lendAprPct must be a positive percent (e.g. 5.2).");
2800
+ const tick = morphoMidnightTickFromApr(apr, ttm);
2801
+ if (tick == null) throw new Error("Could not convert lendAprPct to a Midnight tick.");
2802
+ return tick;
2803
+ }
2804
+ const bidTick = bookLevelTick(args.book.bids?.[0]);
2805
+ if (bidTick != null && bidTick > 0n) return bidTick;
2806
+ const askTick = bookLevelTick(args.book.asks?.[0]);
2807
+ if (askTick != null && askTick > 0n) return askTick;
2808
+ throw new Error("No book tick available. Pass lendAprPct (e.g. 5.2) or tick.");
2809
+ }
2810
+ function offerExpiryUnix(maturity, ttlSeconds) {
2811
+ const now = Math.floor(Date.now() / 1e3);
2812
+ const ttl = ttlSeconds && ttlSeconds > 0 ? ttlSeconds : exports.MORPHO_MIDNIGHT_DEFAULT_OFFER_TTL_SECONDS;
2813
+ const byTtl = now + ttl;
2814
+ const byMaturity = maturity > 60 ? maturity - 60 : maturity;
2815
+ return BigInt(Math.max(now + 60, Math.min(byTtl, byMaturity)));
2816
+ }
2817
+ function decodeBlueMarketParams(data) {
2818
+ const [decoded] = viem.decodeAbiParameters(blueMarketParamsAbi, data);
2819
+ return {
2820
+ loanToken: viem.getAddress(decoded.loanToken),
2821
+ collateralToken: viem.getAddress(decoded.collateralToken),
2822
+ oracle: viem.getAddress(decoded.oracle),
2823
+ irm: viem.getAddress(decoded.irm),
2824
+ lltv: decoded.lltv
2825
+ };
2826
+ }
2827
+ async function buildEvmMultisignBodyMorphoMidnightLendOfferBatch(args) {
2828
+ const maker = viem.getAddress(args.maker);
2829
+ const executor = viem.getAddress(args.executorAddress);
2830
+ const known = morphoMidnightAddressesForChain(args.chainId);
2831
+ if (!known) {
2832
+ throw new Error(`Morpho Midnight addresses unknown for chain ${args.chainId}.`);
2833
+ }
2834
+ const book = await fetchMorphoMidnightBook(args.marketId);
2835
+ if (!book) throw new Error(`Midnight book not found: ${args.marketId}`);
2836
+ const marketParams = morphoMidnightBookToMarketParams(book);
2837
+ const midnight = args.midnight ? viem.getAddress(args.midnight) : viem.getAddress(book.midnight || known.midnight);
2838
+ const loanToken = args.loanToken ? viem.getAddress(args.loanToken) : viem.getAddress(marketParams.loanToken);
2839
+ if (loanToken.toLowerCase() !== marketParams.loanToken.toLowerCase()) {
2840
+ throw new Error("loanToken does not match Midnight market loan token.");
2841
+ }
2842
+ const dec = await readTokenDecimals2({ rpcUrl: args.rpcUrl, chainId: args.chainId, token: loanToken });
2843
+ const maxAssets = viem.parseUnits(args.amountHuman, dec);
2844
+ if (maxAssets === 0n) throw new Error("Lend offer amount is zero.");
2845
+ const blueRow = args.blueMarketId?.trim() ? await fetchMorphoMarketById({ chainId: args.chainId, marketId: args.blueMarketId.trim() }) : await pickBestBlueSupplyMarketForLoan({ chainId: args.chainId, loanToken });
2846
+ if (!blueRow) {
2847
+ throw new Error(
2848
+ `No Morpho Blue market found to park ${loanToken} while the Midnight offer waits. Pass blueMarketId.`
2849
+ );
2850
+ }
2851
+ if (blueRow.marketParams.loanToken.toLowerCase() !== loanToken.toLowerCase()) {
2852
+ throw new Error("blueMarketId loan token must match the Midnight loan token.");
2853
+ }
2854
+ const morphoBlue = viem.getAddress(blueRow.morphoBlueAddress);
2855
+ const callbackData = encodeMorphoBlueMarketParamsCallbackData(blueRow.marketParams);
2856
+ const tick = resolveOfferTick({ book, lendAprPct: args.lendAprPct, tick: args.tick });
2857
+ const expiry = offerExpiryUnix(book.maturity, args.expirySeconds);
2858
+ const publicClient = publicClientFor2(args.rpcUrl, args.chainId);
2859
+ let callback = await publicClient.readContract({
2860
+ address: known.blueBuyCallbackFactory,
2861
+ abi: factoryAbi,
2862
+ functionName: "callbackOf",
2863
+ args: [maker, exports.MORPHO_MIDNIGHT_CALLBACK_SALT]
2864
+ });
2865
+ const evmSteps = [];
2866
+ if (callback === viem.zeroAddress) {
2867
+ const sim = await publicClient.simulateContract({
2868
+ address: known.blueBuyCallbackFactory,
2869
+ abi: factoryAbi,
2870
+ functionName: "createBlueBuyCallback",
2871
+ args: [maker, exports.MORPHO_MIDNIGHT_CALLBACK_SALT],
2872
+ account: executor
2873
+ });
2874
+ callback = sim.result;
2875
+ evmSteps.push({
2876
+ to: known.blueBuyCallbackFactory,
2877
+ data: viem.encodeFunctionData({
2878
+ abi: factoryAbi,
2879
+ functionName: "createBlueBuyCallback",
2880
+ args: [maker, exports.MORPHO_MIDNIGHT_CALLBACK_SALT]
2881
+ }),
2882
+ value: 0n,
2883
+ fallbackGas: exports.MORPHO_MIDNIGHT_CREATE_CALLBACK_FALLBACK_GAS
2884
+ });
2885
+ }
2886
+ if (callback === viem.zeroAddress) {
2887
+ throw new Error("Could not resolve BlueBuyCallback address for this owner.");
2888
+ }
2889
+ const offer = midnightSdk.Offer.create({
2890
+ market: {
2891
+ chainId: args.chainId,
2892
+ midnight,
2893
+ loanToken,
2894
+ collateralParams: marketParams.collateralParams.map((c) => ({
2895
+ token: c.token,
2896
+ lltv: c.lltv,
2897
+ liquidationCursor: c.liquidationCursor,
2898
+ oracle: c.oracle
2899
+ })),
2900
+ maturity: marketParams.maturity,
2901
+ rcfThreshold: marketParams.rcfThreshold,
2902
+ enterGate: marketParams.enterGate,
2903
+ liquidatorGate: marketParams.liquidatorGate
2904
+ },
2905
+ buy: true,
2906
+ maker,
2907
+ tick,
2908
+ maxAssets,
2909
+ expiry,
2910
+ ratifier: known.setterRatifier,
2911
+ callback,
2912
+ callbackData
2913
+ });
2914
+ const tree = midnightSdk.Tree.create([offer]);
2915
+ await tree.mempoolValidate({ chainId: args.chainId, apiUrl: morphoMidnightApiBaseUrl() });
2916
+ const items = midnightSdk.SetterRatifierUtils.ratify({ tree });
2917
+ const payload = await midnightSdk.Payload.encode(items);
2918
+ evmSteps.push(
2919
+ ...approveStepsToEvm2(
2920
+ await buildApproveSteps2({
2921
+ rpcUrl: args.rpcUrl,
2922
+ chainId: args.chainId,
2923
+ token: loanToken,
2924
+ spender: morphoBlue,
2925
+ amountWei: maxAssets,
2926
+ executor,
2927
+ isNativeIn: args.isNativeIn,
2928
+ nativeWrapped: args.nativeWrapped
2929
+ })
2930
+ )
2931
+ );
2932
+ evmSteps.push({
2933
+ to: morphoBlue,
2934
+ data: viem.encodeFunctionData({
2935
+ abi: morphoBlueAbi,
2936
+ functionName: "supply",
2937
+ args: [blueRow.marketParams, maxAssets, 0n, callback, "0x"]
2938
+ }),
2939
+ value: 0n,
2940
+ fallbackGas: exports.MORPHO_MIDNIGHT_BLUE_SUPPLY_FALLBACK_GAS
2941
+ });
2942
+ evmSteps.push(
2943
+ ...await ensureAuthorizedSteps({
2944
+ rpcUrl: args.rpcUrl,
2945
+ chainId: args.chainId,
2946
+ midnight,
2947
+ authorized: known.setterRatifier,
2948
+ onBehalf: maker
2949
+ })
2950
+ );
2951
+ evmSteps.push({
2952
+ to: known.setterRatifier,
2953
+ data: viem.encodeFunctionData({
2954
+ abi: setterAbi,
2955
+ functionName: "setIsRootRatified",
2956
+ args: [maker, tree.root, true]
2957
+ }),
2958
+ value: 0n,
2959
+ fallbackGas: exports.MORPHO_MIDNIGHT_SET_ROOT_FALLBACK_GAS
2960
+ });
2961
+ evmSteps.push({
2962
+ to: known.mempool,
2963
+ data: payload,
2964
+ value: 0n,
2965
+ fallbackGas: exports.MORPHO_MIDNIGHT_MEMPOOL_PUBLISH_FALLBACK_GAS
2966
+ });
2967
+ const marketLabel = (args.marketLabel ?? "").trim() || `Midnight ${args.marketId.slice(0, 10)}\u2026`;
2968
+ return buildEvmMultisignBatch({
2969
+ context: {
2970
+ chainCategory: "evm",
2971
+ keyGen: args.keyGen,
2972
+ purposeText: args.purposeText,
2973
+ chainId: args.chainId,
2974
+ rpcUrl: args.rpcUrl,
2975
+ executorAddress: executor,
2976
+ chainDetail: args.chainDetail,
2977
+ useCustomGas: args.useCustomGas,
2978
+ customGasChainDetails: args.customGasChainDetails
2979
+ },
2980
+ steps: evmSteps,
2981
+ purposeSuffix: `Morpho Midnight: lend offer (${args.amountHuman}) on "${marketLabel}" (variable yield until filled).`,
2982
+ firstMsgRawNo0x: evmSteps[0].data.slice(2),
2983
+ destinationAddress: known.mempool,
2984
+ buildBatchMeta: ({ gasLimit }) => ({
2985
+ signatureText: JSON.stringify({
2986
+ kind: "MorphoMidnight",
2987
+ name: "lend_offer",
2988
+ marketLabel,
2989
+ amountHuman: args.amountHuman
2990
+ }),
2991
+ evm: { type: "morpho_midnight_lend_offer", version: 1, chainId: String(args.chainId) },
2992
+ morpho: {
2993
+ marketId: args.marketId,
2994
+ marketLabel,
2995
+ amountHuman: args.amountHuman,
2996
+ tick: tick.toString(),
2997
+ blueMarketId: blueRow.marketId,
2998
+ callback,
2999
+ treeRoot: tree.root,
3000
+ group: offer.group,
3001
+ gasBuild: { baseGasUnits: gasLimit.toString() }
3002
+ }
3003
+ })
3004
+ });
3005
+ }
3006
+ async function buildEvmMultisignBodyMorphoMidnightCancelLendOfferBatch(args) {
3007
+ const maker = viem.getAddress(args.maker);
3008
+ const executor = viem.getAddress(args.executorAddress);
3009
+ const known = morphoMidnightAddressesForChain(args.chainId);
3010
+ if (!known) {
3011
+ throw new Error(`Morpho Midnight addresses unknown for chain ${args.chainId}.`);
3012
+ }
3013
+ const midnight = args.midnight ? viem.getAddress(args.midnight) : known.midnight;
3014
+ const group = args.group.trim();
3015
+ if (!group.startsWith("0x") || group.length !== 66) {
3016
+ throw new Error("group must be a bytes32 hex id from ctm_morpho_fetch_midnight_offers.");
3017
+ }
3018
+ const evmSteps = [
3019
+ {
3020
+ to: midnight,
3021
+ data: viem.encodeFunctionData({
3022
+ abi: midnightSdk.midnightAbi,
3023
+ functionName: "setConsumed",
3024
+ args: [group, viem.maxUint256, maker]
3025
+ }),
3026
+ value: 0n,
3027
+ fallbackGas: exports.MORPHO_MIDNIGHT_SET_CONSUMED_FALLBACK_GAS
3028
+ }
3029
+ ];
3030
+ const withdrawRemaining = args.withdrawRemaining !== false;
3031
+ const callback = args.callback && args.callback !== viem.zeroAddress ? viem.getAddress(args.callback) : null;
3032
+ const callbackData = args.callbackData ?? "0x";
3033
+ if (withdrawRemaining && callback && callbackData !== "0x") {
3034
+ const params = decodeBlueMarketParams(callbackData);
3035
+ const publicClient = publicClientFor2(args.rpcUrl, args.chainId);
3036
+ const marketId = viem.keccak256(
3037
+ viem.encodeAbiParameters(
3038
+ [
3039
+ { type: "address" },
3040
+ { type: "address" },
3041
+ { type: "address" },
3042
+ { type: "address" },
3043
+ { type: "uint256" }
3044
+ ],
3045
+ [params.loanToken, params.collateralToken, params.oracle, params.irm, params.lltv]
3046
+ )
3047
+ );
3048
+ const pos = await publicClient.readContract({
3049
+ address: known.morphoBlue,
3050
+ abi: morphoBlueAbi,
3051
+ functionName: "position",
3052
+ args: [marketId, callback]
3053
+ });
3054
+ const supplyShares = pos[0];
3055
+ if (supplyShares > 0n) {
3056
+ evmSteps.push({
3057
+ to: known.morphoBlue,
3058
+ data: viem.encodeFunctionData({
3059
+ abi: morphoBlueAbi,
3060
+ functionName: "withdraw",
3061
+ args: [params, 0n, supplyShares, callback, maker]
3062
+ }),
3063
+ value: 0n,
3064
+ fallbackGas: exports.MORPHO_MIDNIGHT_BLUE_WITHDRAW_FALLBACK_GAS
3065
+ });
3066
+ }
3067
+ }
3068
+ const marketLabel = (args.marketLabel ?? "").trim() || "Midnight lend offer";
3069
+ return buildEvmMultisignBatch({
3070
+ context: {
3071
+ chainCategory: "evm",
3072
+ keyGen: args.keyGen,
3073
+ purposeText: args.purposeText,
3074
+ chainId: args.chainId,
3075
+ rpcUrl: args.rpcUrl,
3076
+ executorAddress: executor,
3077
+ chainDetail: args.chainDetail,
3078
+ useCustomGas: args.useCustomGas,
3079
+ customGasChainDetails: args.customGasChainDetails
3080
+ },
3081
+ steps: evmSteps,
3082
+ purposeSuffix: `Morpho Midnight: cancel lend offer on "${marketLabel}".`,
3083
+ firstMsgRawNo0x: evmSteps[0].data.slice(2),
3084
+ destinationAddress: midnight,
3085
+ buildBatchMeta: ({ gasLimit }) => ({
3086
+ signatureText: JSON.stringify({ kind: "MorphoMidnight", name: "cancel_lend_offer", marketLabel }),
3087
+ evm: { type: "morpho_midnight_cancel_lend_offer", version: 1, chainId: String(args.chainId) },
3088
+ morpho: {
3089
+ group,
3090
+ marketLabel,
3091
+ gasBuild: { baseGasUnits: gasLimit.toString() }
3092
+ }
3093
+ })
3094
+ });
3095
+ }
2404
3096
  var erc4626Abi = viem.parseAbi([
2405
3097
  "function asset() view returns (address)",
2406
3098
  "function decimals() view returns (uint8)",
@@ -2445,13 +3137,13 @@ async function fetchMorphoVaultMaxWithdrawWei(args) {
2445
3137
  args: [viem.getAddress(args.owner)]
2446
3138
  });
2447
3139
  }
2448
- var morphoBlueAbi = viem.parseAbi([
3140
+ var morphoBlueAbi2 = viem.parseAbi([
2449
3141
  "function position(bytes32 id, address user) view returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral)",
2450
3142
  "function market(bytes32 id) view returns (uint128 totalSupplyAssets, uint128 totalSupplyShares, uint128 totalBorrowAssets, uint128 totalBorrowShares, uint128 lastUpdate, uint128 fee)",
2451
3143
  "function idToMarketParams(bytes32 id) view returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv)"
2452
3144
  ]);
2453
3145
  var oracleAbi = viem.parseAbi(["function price() view returns (uint256)"]);
2454
- var WAD = 10n ** 18n;
3146
+ var WAD2 = 10n ** 18n;
2455
3147
  var ORACLE_PRICE_SCALE = 10n ** 36n;
2456
3148
  async function previewMorphoBlueHealthAfterCollateralWithdraw(args) {
2457
3149
  const ch = viem.defineChain({
@@ -2467,19 +3159,19 @@ async function previewMorphoBlueHealthAfterCollateralWithdraw(args) {
2467
3159
  const [pos, mkt, params] = await Promise.all([
2468
3160
  publicClient.readContract({
2469
3161
  address: morpho,
2470
- abi: morphoBlueAbi,
3162
+ abi: morphoBlueAbi2,
2471
3163
  functionName: "position",
2472
3164
  args: [id, user]
2473
3165
  }),
2474
3166
  publicClient.readContract({
2475
3167
  address: morpho,
2476
- abi: morphoBlueAbi,
3168
+ abi: morphoBlueAbi2,
2477
3169
  functionName: "market",
2478
3170
  args: [id]
2479
3171
  }),
2480
3172
  publicClient.readContract({
2481
3173
  address: morpho,
2482
- abi: morphoBlueAbi,
3174
+ abi: morphoBlueAbi2,
2483
3175
  functionName: "idToMarketParams",
2484
3176
  args: [id]
2485
3177
  })
@@ -2498,15 +3190,15 @@ async function previewMorphoBlueHealthAfterCollateralWithdraw(args) {
2498
3190
  const totalBorrowShares = BigInt(mkt[3]);
2499
3191
  if (totalBorrowShares === 0n) return { healthy: true, healthFactor: null };
2500
3192
  const borrowed = (borrowShares * totalBorrowAssets + totalBorrowShares - 1n) / totalBorrowShares;
2501
- const maxBorrow = collateral * price / ORACLE_PRICE_SCALE * lltv / WAD;
3193
+ const maxBorrow = collateral * price / ORACLE_PRICE_SCALE * lltv / WAD2;
2502
3194
  const healthy = maxBorrow >= borrowed;
2503
- const hf = borrowed === 0n ? null : Number(maxBorrow * WAD / borrowed) / Number(WAD);
3195
+ const hf = borrowed === 0n ? null : Number(maxBorrow * WAD2 / borrowed) / Number(WAD2);
2504
3196
  return { healthy, healthFactor: hf != null && Number.isFinite(hf) ? hf : null };
2505
3197
  }
2506
3198
  var MORPHO_VAULT_DEPOSIT_FALLBACK_GAS = 950000n;
2507
3199
  var MORPHO_ERC20_APPROVE_FALLBACK = 100000n;
2508
3200
  var MORPHO_WETH_DEPOSIT_FALLBACK = 120000n;
2509
- var wethDepositAbi2 = viem.parseAbi(["function deposit() payable"]);
3201
+ var wethDepositAbi3 = viem.parseAbi(["function deposit() payable"]);
2510
3202
  var erc20AllowanceAbi = viem.parseAbi([
2511
3203
  "function allowance(address owner, address spender) view returns (uint256)"
2512
3204
  ]);
@@ -2535,7 +3227,7 @@ async function buildEvmMultisignBodyMorphoVaultDepositBatch(args) {
2535
3227
  if (amountWei === 0n) throw new Error("Deposit amount is zero after converting with token decimals.");
2536
3228
  const steps = [];
2537
3229
  if (args.isNativeIn) {
2538
- const wethData = viem.encodeFunctionData({ abi: wethDepositAbi2, functionName: "deposit" });
3230
+ const wethData = viem.encodeFunctionData({ abi: wethDepositAbi3, functionName: "deposit" });
2539
3231
  steps.push({ kind: "weth_deposit", to: weth, data: wethData, value: amountWei });
2540
3232
  }
2541
3233
  const spendToken = args.isNativeIn ? weth : asset;
@@ -2687,13 +3379,13 @@ var MORPHO_BLUE_REPAY_FALLBACK_GAS = 1000000n;
2687
3379
  var MORPHO_BLUE_COLLATERAL_WITHDRAW_FALLBACK_GAS = 900000n;
2688
3380
  var MORPHO_ERC20_APPROVE_FALLBACK2 = 100000n;
2689
3381
  var MORPHO_WETH_DEPOSIT_FALLBACK2 = 120000n;
2690
- var wethDepositAbi3 = viem.parseAbi(["function deposit() payable"]);
3382
+ var wethDepositAbi4 = viem.parseAbi(["function deposit() payable"]);
2691
3383
  var erc20AllowanceAbi2 = viem.parseAbi([
2692
3384
  "function allowance(address owner, address spender) view returns (uint256)",
2693
3385
  "function decimals() view returns (uint8)"
2694
3386
  ]);
2695
3387
  var erc20ApproveAbi2 = viem.parseAbi(["function approve(address spender, uint256 amount) returns (bool)"]);
2696
- var morphoBlueAbi2 = viem.parseAbi([
3388
+ var morphoBlueAbi3 = viem.parseAbi([
2697
3389
  "function supplyCollateral((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv), uint256 assets, address onBehalf, bytes data)",
2698
3390
  "function borrow((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv), uint256 assets, uint256 shares, address onBehalf, address receiver)",
2699
3391
  "function repay((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv), uint256 assets, uint256 shares, address onBehalf, bytes data)",
@@ -2708,7 +3400,7 @@ function marketParamsTuple(p) {
2708
3400
  lltv: p.lltv
2709
3401
  };
2710
3402
  }
2711
- async function readTokenDecimals2(args) {
3403
+ async function readTokenDecimals3(args) {
2712
3404
  const ch = viem.defineChain({
2713
3405
  id: args.chainId,
2714
3406
  name: "MorphoToken",
@@ -2724,7 +3416,7 @@ async function readTokenDecimals2(args) {
2724
3416
  const n = typeof d === "bigint" ? Number(d) : Number(d);
2725
3417
  return !Number.isFinite(n) || n < 0 || n > 36 ? 18 : n;
2726
3418
  }
2727
- async function buildApproveSteps2(args) {
3419
+ async function buildApproveSteps3(args) {
2728
3420
  const steps = [];
2729
3421
  let spendToken = args.token;
2730
3422
  if (args.isNativeIn && args.nativeWrapped) {
@@ -2732,7 +3424,7 @@ async function buildApproveSteps2(args) {
2732
3424
  if (spendToken.toLowerCase() !== weth.toLowerCase()) {
2733
3425
  throw new Error("Native collateral path: token must match wrapped native.");
2734
3426
  }
2735
- const wethData = viem.encodeFunctionData({ abi: wethDepositAbi3, functionName: "deposit" });
3427
+ const wethData = viem.encodeFunctionData({ abi: wethDepositAbi4, functionName: "deposit" });
2736
3428
  steps.push({ kind: "weth_deposit", to: weth, data: wethData, value: args.amountWei });
2737
3429
  spendToken = weth;
2738
3430
  }
@@ -2783,10 +3475,10 @@ async function buildEvmMultisignBodyMorphoBlueSupplyCollateralBatch(args) {
2783
3475
  const onBehalf = viem.getAddress(args.onBehalf);
2784
3476
  const executor = viem.getAddress(args.executorAddress);
2785
3477
  const collateral = viem.getAddress(args.collateralToken);
2786
- const dec = await readTokenDecimals2({ rpcUrl: args.rpcUrl, chainId: args.chainId, token: collateral });
3478
+ const dec = await readTokenDecimals3({ rpcUrl: args.rpcUrl, chainId: args.chainId, token: collateral });
2787
3479
  const amountWei = viem.parseUnits(args.amountHuman, dec);
2788
3480
  if (amountWei === 0n) throw new Error("Collateral amount is zero.");
2789
- const approveSteps = await buildApproveSteps2({
3481
+ const approveSteps = await buildApproveSteps3({
2790
3482
  rpcUrl: args.rpcUrl,
2791
3483
  chainId: args.chainId,
2792
3484
  token: collateral,
@@ -2797,7 +3489,7 @@ async function buildEvmMultisignBodyMorphoBlueSupplyCollateralBatch(args) {
2797
3489
  nativeWrapped: args.nativeWrapped
2798
3490
  });
2799
3491
  const supplyData = viem.encodeFunctionData({
2800
- abi: morphoBlueAbi2,
3492
+ abi: morphoBlueAbi3,
2801
3493
  functionName: "supplyCollateral",
2802
3494
  args: [marketParamsTuple(args.marketParams), amountWei, onBehalf, "0x"]
2803
3495
  });
@@ -2837,11 +3529,11 @@ async function buildEvmMultisignBodyMorphoBlueBorrowBatch(args) {
2837
3529
  const receiver = viem.getAddress(args.receiver);
2838
3530
  const executor = viem.getAddress(args.executorAddress);
2839
3531
  const loan = viem.getAddress(args.loanToken);
2840
- const dec = await readTokenDecimals2({ rpcUrl: args.rpcUrl, chainId: args.chainId, token: loan });
3532
+ const dec = await readTokenDecimals3({ rpcUrl: args.rpcUrl, chainId: args.chainId, token: loan });
2841
3533
  const amountWei = viem.parseUnits(args.amountHuman, dec);
2842
3534
  if (amountWei === 0n) throw new Error("Borrow amount is zero.");
2843
3535
  const borrowData = viem.encodeFunctionData({
2844
- abi: morphoBlueAbi2,
3536
+ abi: morphoBlueAbi3,
2845
3537
  functionName: "borrow",
2846
3538
  args: [marketParamsTuple(args.marketParams), amountWei, 0n, onBehalf, receiver]
2847
3539
  });
@@ -2877,10 +3569,10 @@ async function buildEvmMultisignBodyMorphoBlueRepayBatch(args) {
2877
3569
  const onBehalf = viem.getAddress(args.onBehalf);
2878
3570
  const executor = viem.getAddress(args.executorAddress);
2879
3571
  const loan = viem.getAddress(args.loanToken);
2880
- const dec = await readTokenDecimals2({ rpcUrl: args.rpcUrl, chainId: args.chainId, token: loan });
3572
+ const dec = await readTokenDecimals3({ rpcUrl: args.rpcUrl, chainId: args.chainId, token: loan });
2881
3573
  const amountWei = viem.parseUnits(args.amountHuman, dec);
2882
3574
  if (amountWei === 0n) throw new Error("Repay amount is zero.");
2883
- const approveSteps = await buildApproveSteps2({
3575
+ const approveSteps = await buildApproveSteps3({
2884
3576
  rpcUrl: args.rpcUrl,
2885
3577
  chainId: args.chainId,
2886
3578
  token: loan,
@@ -2889,7 +3581,7 @@ async function buildEvmMultisignBodyMorphoBlueRepayBatch(args) {
2889
3581
  executor
2890
3582
  });
2891
3583
  const repayData = viem.encodeFunctionData({
2892
- abi: morphoBlueAbi2,
3584
+ abi: morphoBlueAbi3,
2893
3585
  functionName: "repay",
2894
3586
  args: [marketParamsTuple(args.marketParams), amountWei, 0n, onBehalf, "0x"]
2895
3587
  });
@@ -2931,7 +3623,7 @@ async function buildEvmMultisignBodyMorphoBlueWithdrawCollateralBatch(args) {
2931
3623
  const amountWei = viem.parseUnits(args.amountHuman, args.collateralDecimals);
2932
3624
  if (amountWei === 0n) throw new Error("Collateral withdraw amount is zero.");
2933
3625
  const withdrawData = viem.encodeFunctionData({
2934
- abi: morphoBlueAbi2,
3626
+ abi: morphoBlueAbi3,
2935
3627
  functionName: "withdrawCollateral",
2936
3628
  args: [marketParamsTuple(args.marketParams), amountWei, onBehalf, receiver]
2937
3629
  });
@@ -3020,6 +3712,8 @@ var morphoProtocolModule = {
3020
3712
  { id: "morpho.fetch-midnight-quote", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Quote Morpho Midnight lend/borrow fill", commonParams: [], params: {} },
3021
3713
  { id: "morpho.fetch-midnight-positions", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "List Morpho Midnight user positions", commonParams: [], params: {} },
3022
3714
  { id: "morpho.midnight-lend", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Morpho Midnight fixed-rate lend (take asks)", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3715
+ { id: "morpho.midnight-lend-offer", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Morpho Midnight lend limit offer parked in Blue until filled", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3716
+ { id: "morpho.midnight-cancel-lend-offer", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Cancel a Morpho Midnight lend offer and withdraw unused Blue park", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3023
3717
  { id: "morpho.midnight-borrow", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Morpho Midnight fixed-rate borrow (supply collateral + take bids)", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3024
3718
  { id: "morpho.midnight-repay", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Morpho Midnight repay debt and withdraw collateral", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
3025
3719
  ]
@@ -3047,11 +3741,14 @@ exports.buildEvmMultisignBodyMorphoBlueSupplyCollateralBatch = buildEvmMultisign
3047
3741
  exports.buildEvmMultisignBodyMorphoBlueWithdrawCollateralBatch = buildEvmMultisignBodyMorphoBlueWithdrawCollateralBatch;
3048
3742
  exports.buildEvmMultisignBodyMorphoMerklDistributorClaim = buildEvmMultisignBodyMorphoMerklDistributorClaim;
3049
3743
  exports.buildEvmMultisignBodyMorphoMidnightBorrowBatch = buildEvmMultisignBodyMorphoMidnightBorrowBatch;
3744
+ exports.buildEvmMultisignBodyMorphoMidnightCancelLendOfferBatch = buildEvmMultisignBodyMorphoMidnightCancelLendOfferBatch;
3050
3745
  exports.buildEvmMultisignBodyMorphoMidnightLendBatch = buildEvmMultisignBodyMorphoMidnightLendBatch;
3746
+ exports.buildEvmMultisignBodyMorphoMidnightLendOfferBatch = buildEvmMultisignBodyMorphoMidnightLendOfferBatch;
3051
3747
  exports.buildEvmMultisignBodyMorphoMidnightRepayBatch = buildEvmMultisignBodyMorphoMidnightRepayBatch;
3052
3748
  exports.buildEvmMultisignBodyMorphoVaultDepositBatch = buildEvmMultisignBodyMorphoVaultDepositBatch;
3053
3749
  exports.buildEvmMultisignBodyMorphoVaultWithdraw = buildEvmMultisignBodyMorphoVaultWithdraw;
3054
3750
  exports.emptyMorphoEarnVaultDetailFields = emptyMorphoEarnVaultDetailFields;
3751
+ exports.encodeMorphoBlueMarketParamsCallbackData = encodeMorphoBlueMarketParamsCallbackData;
3055
3752
  exports.enrichMorphoEarnOfferingRows = enrichMorphoEarnOfferingRows;
3056
3753
  exports.enrichMorphoEarnOfferingRowsForAgent = enrichMorphoEarnOfferingRowsForAgent;
3057
3754
  exports.ensureMorphoChainAssetCache = ensureMorphoChainAssetCache;
@@ -3067,6 +3764,7 @@ exports.fetchMorphoMidnightBookQuote = fetchMorphoMidnightBookQuote;
3067
3764
  exports.fetchMorphoMidnightBooks = fetchMorphoMidnightBooks;
3068
3765
  exports.fetchMorphoMidnightBooksForAsset = fetchMorphoMidnightBooksForAsset;
3069
3766
  exports.fetchMorphoMidnightIntents = fetchMorphoMidnightIntents;
3767
+ exports.fetchMorphoMidnightMakerOffers = fetchMorphoMidnightMakerOffers;
3070
3768
  exports.fetchMorphoMidnightMarketById = fetchMorphoMidnightMarketById;
3071
3769
  exports.fetchMorphoMidnightUserMarketPosition = fetchMorphoMidnightUserMarketPosition;
3072
3770
  exports.fetchMorphoMidnightUserPositions = fetchMorphoMidnightUserPositions;
@@ -3092,6 +3790,7 @@ exports.morphoEarnOfferingToDiscoveryRow = morphoEarnOfferingToDiscoveryRow;
3092
3790
  exports.morphoFetchBlueMarketsSummary = morphoFetchBlueMarketsSummary;
3093
3791
  exports.morphoFetchEarnVaultsSummary = morphoFetchEarnVaultsSummary;
3094
3792
  exports.morphoFetchMidnightBooksSummary = morphoFetchMidnightBooksSummary;
3793
+ exports.morphoFetchMidnightMakerOffersSummary = morphoFetchMidnightMakerOffersSummary;
3095
3794
  exports.morphoFetchMidnightPositionsSummary = morphoFetchMidnightPositionsSummary;
3096
3795
  exports.morphoFetchMidnightQuote = morphoFetchMidnightQuote;
3097
3796
  exports.morphoFetchMidnightQuoteSummary = morphoFetchMidnightQuoteSummary;
@@ -3100,15 +3799,23 @@ exports.morphoKeyForAssetRow = morphoKeyForAssetRow;
3100
3799
  exports.morphoMarketToBorrowRow = morphoMarketToBorrowRow;
3101
3800
  exports.morphoMidnightAddressesForChain = morphoMidnightAddressesForChain;
3102
3801
  exports.morphoMidnightApiBaseUrl = morphoMidnightApiBaseUrl;
3802
+ exports.morphoMidnightAprFromBookLevel = morphoMidnightAprFromBookLevel;
3103
3803
  exports.morphoMidnightAprFromPriceWad = morphoMidnightAprFromPriceWad;
3804
+ exports.morphoMidnightAprFromTick = morphoMidnightAprFromTick;
3104
3805
  exports.morphoMidnightBookToDiscoveryRow = morphoMidnightBookToDiscoveryRow;
3105
3806
  exports.morphoMidnightBookToMarketParams = morphoMidnightBookToMarketParams;
3106
3807
  exports.morphoMidnightMarketToParams = morphoMidnightMarketToParams;
3107
3808
  exports.morphoMidnightPositionToDiscoveryRow = morphoMidnightPositionToDiscoveryRow;
3809
+ exports.morphoMidnightPriceWadFromApr = morphoMidnightPriceWadFromApr;
3810
+ exports.morphoMidnightTickFromApr = morphoMidnightTickFromApr;
3811
+ exports.morphoMidnightTickFromPriceWad = morphoMidnightTickFromPriceWad;
3108
3812
  exports.morphoMidnightTtmSeconds = morphoMidnightTtmSeconds;
3109
3813
  exports.morphoMidnightUnitsFromAssets = morphoMidnightUnitsFromAssets;
3110
3814
  exports.morphoProtocolModule = morphoProtocolModule;
3111
3815
  exports.morphoResolveListedEarnVaultByAddress = morphoResolveListedEarnVaultByAddress;
3816
+ exports.parseMorphoMidnightAprInput = parseMorphoMidnightAprInput;
3817
+ exports.parseMorphoMidnightPriceWad = parseMorphoMidnightPriceWad;
3818
+ exports.pickBestBlueSupplyMarketForLoan = pickBestBlueSupplyMarketForLoan;
3112
3819
  exports.previewMorphoBlueHealthAfterCollateralWithdraw = previewMorphoBlueHealthAfterCollateralWithdraw;
3113
3820
  exports.resolveRobinhoodEarnFetchQuery = resolveRobinhoodEarnFetchQuery;
3114
3821
  exports.searchMorphoListedEarnVaults = searchMorphoListedEarnVaults;