@continuumdao/ctm-mpc-defi 0.2.1 → 0.2.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.
Files changed (57) hide show
  1. package/dist/agent/catalog.cjs +96 -25
  2. package/dist/agent/catalog.cjs.map +1 -1
  3. package/dist/agent/catalog.d.ts +27 -1
  4. package/dist/agent/catalog.js +95 -26
  5. package/dist/agent/catalog.js.map +1 -1
  6. package/dist/agent/skills/curve-dao/SKILL.md +2 -1
  7. package/dist/chains/evm/index.cjs +54 -0
  8. package/dist/chains/evm/index.cjs.map +1 -1
  9. package/dist/chains/evm/index.d.ts +13 -1
  10. package/dist/chains/evm/index.js +52 -2
  11. package/dist/chains/evm/index.js.map +1 -1
  12. package/dist/core/index.cjs +64 -0
  13. package/dist/core/index.cjs.map +1 -1
  14. package/dist/core/index.d.ts +20 -1
  15. package/dist/core/index.js +56 -1
  16. package/dist/core/index.js.map +1 -1
  17. package/dist/index.cjs +165 -14
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.js +154 -16
  21. package/dist/index.js.map +1 -1
  22. package/dist/protocols/evm/aave-v4/index.cjs +766 -6
  23. package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
  24. package/dist/protocols/evm/aave-v4/index.d.ts +417 -1
  25. package/dist/protocols/evm/aave-v4/index.js +741 -8
  26. package/dist/protocols/evm/aave-v4/index.js.map +1 -1
  27. package/dist/protocols/evm/curve-dao/index.cjs +268 -21
  28. package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
  29. package/dist/protocols/evm/curve-dao/index.d.ts +74 -9
  30. package/dist/protocols/evm/curve-dao/index.js +262 -23
  31. package/dist/protocols/evm/curve-dao/index.js.map +1 -1
  32. package/dist/protocols/evm/ethena/index.cjs +104 -0
  33. package/dist/protocols/evm/ethena/index.cjs.map +1 -1
  34. package/dist/protocols/evm/ethena/index.d.ts +46 -1
  35. package/dist/protocols/evm/ethena/index.js +99 -1
  36. package/dist/protocols/evm/ethena/index.js.map +1 -1
  37. package/dist/protocols/evm/euler-v2/index.cjs +2334 -37
  38. package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
  39. package/dist/protocols/evm/euler-v2/index.d.ts +464 -1
  40. package/dist/protocols/evm/euler-v2/index.js +2286 -39
  41. package/dist/protocols/evm/euler-v2/index.js.map +1 -1
  42. package/dist/protocols/evm/lido/index.cjs +110 -0
  43. package/dist/protocols/evm/lido/index.cjs.map +1 -1
  44. package/dist/protocols/evm/lido/index.d.ts +33 -2
  45. package/dist/protocols/evm/lido/index.js +107 -2
  46. package/dist/protocols/evm/lido/index.js.map +1 -1
  47. package/dist/protocols/evm/maple/index.cjs +83 -0
  48. package/dist/protocols/evm/maple/index.cjs.map +1 -1
  49. package/dist/protocols/evm/maple/index.d.ts +22 -1
  50. package/dist/protocols/evm/maple/index.js +82 -1
  51. package/dist/protocols/evm/maple/index.js.map +1 -1
  52. package/dist/protocols/evm/sky/index.cjs +217 -0
  53. package/dist/protocols/evm/sky/index.cjs.map +1 -1
  54. package/dist/protocols/evm/sky/index.d.ts +56 -1
  55. package/dist/protocols/evm/sky/index.js +210 -2
  56. package/dist/protocols/evm/sky/index.js.map +1 -1
  57. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- import { parseAbi, isAddress, getAddress, defineChain, createPublicClient, http, parseUnits, encodeFunctionData, parseGwei, serializeTransaction, keccak256 } from 'viem';
1
+ import { parseAbi, isAddress, getAddress, defineChain, createPublicClient, http, parseUnits, encodeFunctionData, formatUnits, zeroAddress, parseGwei, serializeTransaction, keccak256 } from 'viem';
2
2
  import { isValidRpcUrl, fetchChainFeeParams, gasLimitFromEstimateAndChainConfig, gweiToDecimalString, proposalTxParamsToFeeSnapshot, alignEip1559FeesWithLatestBase, getClientIdFromKeyGenResult } from '@continuumdao/continuum-node-sdk';
3
3
 
4
4
  // src/core/registry.ts
@@ -11,18 +11,26 @@ function registerProtocolModule(mod) {
11
11
  modules.push(mod);
12
12
  }
13
13
  }
14
- var AAVE_V4_GRAPHQL_URL = "https://api.v4.aave.com/graphql";
15
- async function aaveV4Gql(query, variables) {
16
- const r = await fetch(AAVE_V4_GRAPHQL_URL, {
14
+ async function postJsonViaOptionalProxy(args) {
15
+ const r = await fetch(args.directUrl, {
17
16
  method: "POST",
18
17
  headers: { "content-type": "application/json" },
19
- body: JSON.stringify({ query, variables: variables ?? {} })
18
+ body: JSON.stringify(args.body)
20
19
  });
21
20
  if (!r.ok) {
22
21
  const t = await r.text().catch(() => "");
23
- throw new Error(t ? `Aave V4 API HTTP ${r.status}: ${t.slice(0, 200)}` : `Aave V4 API HTTP ${r.status}`);
22
+ throw new Error(t ? `HTTP ${r.status}: ${t.slice(0, 200)}` : `HTTP ${r.status}`);
24
23
  }
25
- const j = await r.json();
24
+ return await r.json();
25
+ }
26
+
27
+ // src/protocols/evm/aave-v4/api.ts
28
+ var AAVE_V4_GRAPHQL_URL = "https://api.v4.aave.com/graphql";
29
+ async function aaveV4Gql(query, variables) {
30
+ const body = { query, variables: variables ?? {} };
31
+ const j = await postJsonViaOptionalProxy({
32
+ directUrl: AAVE_V4_GRAPHQL_URL,
33
+ body});
26
34
  if (j.errors?.length) {
27
35
  const msg = j.errors.map((e) => e.message ?? "Unknown").join("; ");
28
36
  throw new Error(msg);
@@ -1640,6 +1648,731 @@ function resolveAaveV4DepositGasUnitsFromSignRequest(detail, batchIndex) {
1640
1648
  }
1641
1649
  return null;
1642
1650
  }
1651
+ var POSITIONS_LIST = `
1652
+ query AaveUserPositions($r: UserPositionsRequest!, $currency: Currency! = USD, $w: TimeWindow! = LAST_DAY) {
1653
+ userPositions(request: $r) {
1654
+ id
1655
+ user
1656
+ createdAt
1657
+ spoke {
1658
+ id
1659
+ name
1660
+ address
1661
+ chain {
1662
+ chainId
1663
+ name
1664
+ }
1665
+ liquidationConfig {
1666
+ targetHealthFactor
1667
+ healthFactorForMaxBonus
1668
+ }
1669
+ }
1670
+ totalSupplied(currency: $currency) {
1671
+ current { value name symbol }
1672
+ }
1673
+ totalDebt(currency: $currency) {
1674
+ current { value name symbol }
1675
+ }
1676
+ netBalance(currency: $currency) {
1677
+ current { value name symbol }
1678
+ }
1679
+ healthFactor {
1680
+ current
1681
+ change(window: $w) {
1682
+ normalized
1683
+ value
1684
+ }
1685
+ }
1686
+ netApy {
1687
+ normalized
1688
+ value
1689
+ }
1690
+ }
1691
+ }
1692
+ `;
1693
+ var POSITION_DETAIL = `
1694
+ query AaveUserPosition(
1695
+ $r: UserPositionRequest!
1696
+ $currency: Currency! = USD
1697
+ $w: TimeWindow! = LAST_DAY
1698
+ ) {
1699
+ userPosition(request: $r) {
1700
+ id
1701
+ user
1702
+ createdAt
1703
+ spoke {
1704
+ id
1705
+ name
1706
+ address
1707
+ chain {
1708
+ chainId
1709
+ name
1710
+ }
1711
+ liquidationConfig {
1712
+ targetHealthFactor
1713
+ healthFactorForMaxBonus
1714
+ }
1715
+ }
1716
+ totalSupplied(currency: $currency) {
1717
+ current { value name symbol }
1718
+ change { normalized value }
1719
+ }
1720
+ totalCollateral(currency: $currency) {
1721
+ current { value name symbol }
1722
+ change { normalized value }
1723
+ }
1724
+ totalDebt(currency: $currency) {
1725
+ current { value name symbol }
1726
+ change { normalized value }
1727
+ }
1728
+ netBalance(currency: $currency) {
1729
+ current { value name symbol }
1730
+ change { normalized value }
1731
+ }
1732
+ netCollateral(currency: $currency) {
1733
+ current { value name symbol }
1734
+ change { normalized value }
1735
+ }
1736
+ netApy {
1737
+ normalized
1738
+ value
1739
+ }
1740
+ netSupplyApy {
1741
+ current {
1742
+ normalized
1743
+ }
1744
+ }
1745
+ netBorrowApy {
1746
+ current {
1747
+ normalized
1748
+ }
1749
+ }
1750
+ netAccruedInterest(currency: $currency) {
1751
+ value
1752
+ name
1753
+ symbol
1754
+ }
1755
+ healthFactor {
1756
+ current
1757
+ change(window: $w) {
1758
+ normalized
1759
+ value
1760
+ }
1761
+ }
1762
+ maxBorrowingPower(currency: $currency) {
1763
+ value
1764
+ name
1765
+ symbol
1766
+ }
1767
+ remainingBorrowingPower(currency: $currency) {
1768
+ value
1769
+ name
1770
+ symbol
1771
+ }
1772
+ averageCollateralFactor {
1773
+ normalized
1774
+ }
1775
+ liquidationPrice(currency: $currency) {
1776
+ value
1777
+ name
1778
+ symbol
1779
+ }
1780
+ canUpdateDynamicConfig
1781
+ netBalancePercentChange(window: $w) {
1782
+ normalized
1783
+ }
1784
+ }
1785
+ }
1786
+ `;
1787
+ var USER_SUPPLIES = `
1788
+ query AaveUserSupplies($r: UserSuppliesRequest!) {
1789
+ userSupplies(request: $r) {
1790
+ id
1791
+ isCollateral
1792
+ principal {
1793
+ amount {
1794
+ value
1795
+ }
1796
+ token {
1797
+ address
1798
+ info {
1799
+ symbol
1800
+ name
1801
+ icon
1802
+ }
1803
+ }
1804
+ }
1805
+ balance {
1806
+ amount {
1807
+ value
1808
+ }
1809
+ token {
1810
+ address
1811
+ info {
1812
+ symbol
1813
+ name
1814
+ }
1815
+ }
1816
+ }
1817
+ withdrawable {
1818
+ amount {
1819
+ value
1820
+ }
1821
+ token {
1822
+ address
1823
+ info {
1824
+ symbol
1825
+ }
1826
+ }
1827
+ }
1828
+ interest {
1829
+ amount {
1830
+ value
1831
+ }
1832
+ token {
1833
+ address
1834
+ info {
1835
+ symbol
1836
+ }
1837
+ }
1838
+ }
1839
+ reserve {
1840
+ id
1841
+ onChainId
1842
+ summary {
1843
+ supplyApy {
1844
+ normalized
1845
+ value
1846
+ }
1847
+ }
1848
+ asset {
1849
+ underlying {
1850
+ address
1851
+ info {
1852
+ symbol
1853
+ name
1854
+ icon
1855
+ }
1856
+ }
1857
+ }
1858
+ }
1859
+ }
1860
+ }
1861
+ `;
1862
+ var DEFAULT_CURRENCY = "USD";
1863
+ var DEFAULT_TIME_WINDOW = "LAST_DAY";
1864
+ function formatAaveV4ExchangeLabel(ex) {
1865
+ if (ex == null) return "\u2014";
1866
+ const sym = (ex.symbol ?? "").trim();
1867
+ const name = (ex.name ?? "").trim();
1868
+ if (sym === "$" && name) return name;
1869
+ if (name && sym && name.toUpperCase() !== sym) return name;
1870
+ return sym || name || "\u2014";
1871
+ }
1872
+ function formatAaveV4PositionPercent(normalized, value) {
1873
+ const n = (normalized ?? "").trim();
1874
+ const v = (value ?? "").trim();
1875
+ if (n === "0" && (v === "0" || v === "")) return "0%";
1876
+ const out = formatAaveV4PercentDisplay(normalized, value);
1877
+ return out;
1878
+ }
1879
+ function formatAaveV4PositionHealthFactor(raw) {
1880
+ if (raw == null || String(raw).trim() === "") return "\u221E";
1881
+ return formatAaveV4HealthFactorInner(raw);
1882
+ }
1883
+ function formatAaveV4HealthFactorInner(raw) {
1884
+ const n = Number(raw);
1885
+ if (!Number.isFinite(n)) return String(raw);
1886
+ if (n >= 1e12) return "\u221E";
1887
+ return n >= 10 ? n.toFixed(1) : n.toFixed(2);
1888
+ }
1889
+ function buildUserPositionsRequest(user, filter) {
1890
+ return {
1891
+ user,
1892
+ filter,
1893
+ orderBy: { balance: "DESC" }
1894
+ };
1895
+ }
1896
+ async function fetchAaveV4UserPositionsForChain(args) {
1897
+ const u = (args.user ?? "").trim();
1898
+ if (!u || !isAddress(u)) return [];
1899
+ const user = getAddress(u);
1900
+ const d = await aaveV4Gql(POSITIONS_LIST, {
1901
+ r: buildUserPositionsRequest(user, { chainIds: [args.chainId] }),
1902
+ currency: DEFAULT_CURRENCY,
1903
+ w: DEFAULT_TIME_WINDOW
1904
+ });
1905
+ return d.userPositions ?? [];
1906
+ }
1907
+ async function fetchAaveV4UserPositionsByAssetOnChain(args) {
1908
+ const u = (args.user ?? "").trim();
1909
+ if (!u || !isAddress(u)) {
1910
+ return { forAsset: [], other: [], filterUnderlying: null };
1911
+ }
1912
+ const user = getAddress(u);
1913
+ const c = args.chainId;
1914
+ const f = args.filterUnderlying;
1915
+ if (f == null) {
1916
+ const all2 = await fetchAaveV4UserPositionsForChain({ user: u, chainId: c });
1917
+ return { forAsset: all2, other: [], filterUnderlying: null };
1918
+ }
1919
+ const token = getAddress(f);
1920
+ const [allRes, withTokenRes] = await Promise.all([
1921
+ aaveV4Gql(POSITIONS_LIST, {
1922
+ r: buildUserPositionsRequest(user, { chainIds: [c] }),
1923
+ currency: DEFAULT_CURRENCY,
1924
+ w: DEFAULT_TIME_WINDOW
1925
+ }),
1926
+ aaveV4Gql(POSITIONS_LIST, {
1927
+ r: buildUserPositionsRequest(user, { tokens: [{ address: token, chainId: c }] }),
1928
+ currency: DEFAULT_CURRENCY,
1929
+ w: DEFAULT_TIME_WINDOW
1930
+ })
1931
+ ]);
1932
+ const all = allRes.userPositions ?? [];
1933
+ const forAsset = withTokenRes.userPositions ?? [];
1934
+ const want = new Set(forAsset.map((p) => p.id));
1935
+ const other = all.filter((p) => !want.has(p.id));
1936
+ return { forAsset, other, filterUnderlying: token };
1937
+ }
1938
+ async function fetchAaveV4UserPositionById(positionId) {
1939
+ const id = (positionId ?? "").trim();
1940
+ if (!id) return null;
1941
+ const d = await aaveV4Gql(POSITION_DETAIL, {
1942
+ r: { id },
1943
+ currency: DEFAULT_CURRENCY,
1944
+ w: DEFAULT_TIME_WINDOW
1945
+ });
1946
+ return d.userPosition ?? null;
1947
+ }
1948
+ async function fetchAaveV4UserSuppliesForPosition(userPositionId) {
1949
+ const pid = (userPositionId ?? "").trim();
1950
+ if (!pid) return [];
1951
+ const d = await aaveV4Gql(USER_SUPPLIES, {
1952
+ r: {
1953
+ query: { userPositionId: pid },
1954
+ orderBy: { amount: "DESC" },
1955
+ includeZeroBalances: false
1956
+ }
1957
+ });
1958
+ return d.userSupplies ?? [];
1959
+ }
1960
+ async function aaveV4UserHasAvailableBorrowCollateralForContextOnSpoke(args) {
1961
+ let wantSpoke;
1962
+ try {
1963
+ wantSpoke = getAddress(args.spokeAddress).toLowerCase();
1964
+ } catch {
1965
+ return false;
1966
+ }
1967
+ const u0 = getAddress(args.contextUnderlying).toLowerCase();
1968
+ const positions = await fetchAaveV4UserPositionsForChain({ user: args.user, chainId: args.chainId });
1969
+ const pos = positions.find((p) => {
1970
+ const a = (p.spoke?.address ?? "").trim();
1971
+ if (!a) return false;
1972
+ try {
1973
+ return getAddress(a).toLowerCase() === wantSpoke;
1974
+ } catch {
1975
+ return false;
1976
+ }
1977
+ });
1978
+ if (!pos) return false;
1979
+ const supplies = await fetchAaveV4UserSuppliesForPosition(pos.id);
1980
+ const row = supplies.find((s) => {
1981
+ const a = (s.reserve?.asset?.underlying?.address ?? "").trim();
1982
+ if (!a) return false;
1983
+ try {
1984
+ return getAddress(a).toLowerCase() === u0;
1985
+ } catch {
1986
+ return false;
1987
+ }
1988
+ });
1989
+ if (!row) return false;
1990
+ const bal = parseFloat((row.balance?.amount?.value ?? "").trim());
1991
+ if (!Number.isFinite(bal) || bal <= 0) return false;
1992
+ return row.isCollateral === true;
1993
+ }
1994
+ function formatAaveV4DecimalString(raw, maxFractionDigits = 6) {
1995
+ const s = (raw ?? "").trim();
1996
+ if (!s) return "\u2014";
1997
+ const n = Number(s);
1998
+ if (!Number.isFinite(n)) return s;
1999
+ if (Math.abs(n) >= 1e9) return n.toExponential(2);
2000
+ return n.toLocaleString(void 0, { maximumFractionDigits: maxFractionDigits });
2001
+ }
2002
+ function formatAaveV4RiskNotionalString(raw) {
2003
+ const s = (raw ?? "").trim();
2004
+ if (!s) return "\u2014";
2005
+ const n = Number(s);
2006
+ if (!Number.isFinite(n)) return s;
2007
+ if (n === 0) return "0";
2008
+ if (Math.abs(n) >= 1e9) return n.toExponential(2);
2009
+ if (n > 0 && n < 0.5) {
2010
+ return n.toLocaleString(void 0, { maximumSignificantDigits: 4, maximumFractionDigits: 8 });
2011
+ }
2012
+ return n.toLocaleString(void 0, { maximumFractionDigits: 6 });
2013
+ }
2014
+ function formatAaveV4HealthFactor(raw) {
2015
+ if (raw == null || String(raw).trim() === "") return "\u2014";
2016
+ return formatAaveV4HealthFactorInner(String(raw).trim());
2017
+ }
2018
+ var HF_EPS = 1e-9;
2019
+ function aaveV4WithdrawHealthGate(args) {
2020
+ const { hasBorrowDebt, liquidationConfig: liq } = args;
2021
+ const r0 = args.resultingHealthFactor;
2022
+ if (!hasBorrowDebt) {
2023
+ return { outcome: "allow" };
2024
+ }
2025
+ if (r0 == null || !Number.isFinite(r0)) {
2026
+ return { outcome: "block", reason: "Could not determine health factor after withdrawal." };
2027
+ }
2028
+ const r = r0;
2029
+ const t = liq == null ? NaN : Number(liq.targetHealthFactor);
2030
+ const m = liq == null ? NaN : Number(liq.healthFactorForMaxBonus);
2031
+ if (r <= 1 + HF_EPS) {
2032
+ return {
2033
+ outcome: "block",
2034
+ reason: "This withdrawal would leave health factor at or below 1.0 (liquidation range)."
2035
+ };
2036
+ }
2037
+ if (Number.isFinite(m) && m > 1 + HF_EPS && r <= m + HF_EPS) {
2038
+ return {
2039
+ outcome: "block",
2040
+ reason: `This withdrawal would put health factor at or below the spoke\u2019s max-liquidation-bonus threshold (${m}).`
2041
+ };
2042
+ }
2043
+ if (Number.isFinite(t) && r < t - HF_EPS) {
2044
+ return {
2045
+ outcome: "confirm",
2046
+ reason: `The resulting health factor would be below this market\u2019s target (${t.toFixed(4)}).`,
2047
+ targetHealthFactor: t,
2048
+ healthFactorForMaxBonus: Number.isFinite(m) ? m : 0
2049
+ };
2050
+ }
2051
+ return { outcome: "allow" };
2052
+ }
2053
+ function aaveV4BorrowHealthGate(args) {
2054
+ return aaveV4WithdrawHealthGate({
2055
+ resultingHealthFactor: args.resultingHealthFactor,
2056
+ hasBorrowDebt: true,
2057
+ liquidationConfig: args.liquidationConfig
2058
+ });
2059
+ }
2060
+ function aaveV4RepayHealthGate(args) {
2061
+ if (!args.strict) {
2062
+ return { outcome: "allow" };
2063
+ }
2064
+ return aaveV4WithdrawHealthGate({
2065
+ resultingHealthFactor: args.resultingHealthFactor,
2066
+ hasBorrowDebt: true,
2067
+ liquidationConfig: args.liquidationConfig
2068
+ });
2069
+ }
2070
+
2071
+ // src/protocols/evm/aave-v4/positionActionsApi.ts
2072
+ var PREVIEW_WITHDRAW = `
2073
+ query AaveV4PreviewWithdraw($req: PreviewRequest!) {
2074
+ preview(request: $req) {
2075
+ __typename
2076
+ ... on PreviewUserPosition {
2077
+ id
2078
+ healthFactor {
2079
+ __typename
2080
+ ... on HealthFactorVariation {
2081
+ current
2082
+ after
2083
+ }
2084
+ ... on HealthFactorError {
2085
+ reason
2086
+ current
2087
+ after
2088
+ }
2089
+ }
2090
+ }
2091
+ }
2092
+ }
2093
+ `;
2094
+ var USER_CLAIMABLE = `
2095
+ query AaveV4UserClaimableRewards($req: UserClaimableRewardsRequest!) {
2096
+ userClaimableRewards(request: $req) {
2097
+ __typename
2098
+ ... on UserMerklClaimableReward {
2099
+ id
2100
+ claimable {
2101
+ amount { value }
2102
+ exchange { value name symbol }
2103
+ token {
2104
+ address
2105
+ info { symbol name }
2106
+ }
2107
+ }
2108
+ }
2109
+ }
2110
+ }
2111
+ `;
2112
+ var CLAIM_REWARDS = `
2113
+ query AaveV4ClaimRewards($req: ClaimRewardsRequest!) {
2114
+ claimRewards(request: $req) {
2115
+ to
2116
+ from
2117
+ data
2118
+ value
2119
+ chainId
2120
+ }
2121
+ }
2122
+ `;
2123
+ function parseBigDecimalHf(s) {
2124
+ if (s == null || !String(s).trim()) return null;
2125
+ const n = Number(String(s).trim());
2126
+ return Number.isFinite(n) ? n : null;
2127
+ }
2128
+ async function previewAaveV4WithdrawResultingHf(args) {
2129
+ const req = {
2130
+ action: {
2131
+ withdraw: {
2132
+ sender: args.user,
2133
+ reserve: args.reserveId,
2134
+ amount: { erc20: { exact: args.amountExactHuman } }
2135
+ }
2136
+ }
2137
+ };
2138
+ const d = await aaveV4Gql(PREVIEW_WITHDRAW, { req });
2139
+ const p = d.preview;
2140
+ if (p?.__typename !== "PreviewUserPosition") {
2141
+ return { resultingHf: null, error: "Withdraw preview is not available for this request." };
2142
+ }
2143
+ const hf = p.healthFactor;
2144
+ if (hf?.__typename === "HealthFactorError") {
2145
+ return { resultingHf: null, error: hf.reason ?? "Invalid withdrawal for this position." };
2146
+ }
2147
+ if (hf?.__typename === "HealthFactorVariation") {
2148
+ return { resultingHf: parseBigDecimalHf(hf.after), error: null };
2149
+ }
2150
+ return { resultingHf: null, error: "Could not read health factor from preview." };
2151
+ }
2152
+ async function previewAaveV4BorrowResultingHf(args) {
2153
+ const req = {
2154
+ action: {
2155
+ borrow: {
2156
+ sender: args.user,
2157
+ reserve: args.reserveGraphqlId,
2158
+ amount: { erc20: { value: args.amountExactHuman } }
2159
+ }
2160
+ }
2161
+ };
2162
+ const d = await aaveV4Gql(PREVIEW_WITHDRAW, { req });
2163
+ const p = d.preview;
2164
+ if (p?.__typename !== "PreviewUserPosition") {
2165
+ return { resultingHf: null, error: "Borrow preview is not available for this request." };
2166
+ }
2167
+ const hf = p.healthFactor;
2168
+ if (hf?.__typename === "HealthFactorError") {
2169
+ return { resultingHf: null, error: hf.reason ?? "Invalid borrow for this position." };
2170
+ }
2171
+ if (hf?.__typename === "HealthFactorVariation") {
2172
+ return { resultingHf: parseBigDecimalHf(hf.after), error: null };
2173
+ }
2174
+ return { resultingHf: null, error: "Could not read health factor from borrow preview." };
2175
+ }
2176
+ var PREVIEW_REPAY = `
2177
+ query AaveV4PreviewRepay($req: PreviewRequest!) {
2178
+ preview(request: $req) {
2179
+ __typename
2180
+ ... on PreviewUserPosition {
2181
+ id
2182
+ healthFactor {
2183
+ __typename
2184
+ ... on HealthFactorVariation {
2185
+ current
2186
+ after
2187
+ }
2188
+ ... on HealthFactorError {
2189
+ reason
2190
+ current
2191
+ after
2192
+ }
2193
+ }
2194
+ }
2195
+ }
2196
+ }
2197
+ `;
2198
+ async function previewAaveV4RepayResultingHf(args) {
2199
+ const req = {
2200
+ action: {
2201
+ repay: {
2202
+ sender: args.user,
2203
+ reserve: args.reserveGraphqlId,
2204
+ amount: { erc20: { value: { exact: args.amountExactHuman } } }
2205
+ }
2206
+ }
2207
+ };
2208
+ const d = await aaveV4Gql(PREVIEW_REPAY, { req });
2209
+ const p = d.preview;
2210
+ if (p?.__typename !== "PreviewUserPosition") {
2211
+ return { resultingHf: null, error: "Repay preview is not available for this request." };
2212
+ }
2213
+ const hf = p.healthFactor;
2214
+ if (hf?.__typename === "HealthFactorError") {
2215
+ return { resultingHf: null, error: hf.reason ?? "Invalid repay for this position." };
2216
+ }
2217
+ if (hf?.__typename === "HealthFactorVariation") {
2218
+ return { resultingHf: parseBigDecimalHf(hf.after), error: null };
2219
+ }
2220
+ return { resultingHf: null, error: "Could not read health factor from repay preview." };
2221
+ }
2222
+ async function fetchAaveV4MerklClaimableRewardsForChain(args) {
2223
+ const d = await aaveV4Gql(USER_CLAIMABLE, { req: { user: args.user, chainId: args.chainId } });
2224
+ const out = [];
2225
+ for (const r of d.userClaimableRewards ?? []) {
2226
+ if (r.__typename !== "UserMerklClaimableReward" || !("claimable" in r)) continue;
2227
+ const id = (r.id ?? "").trim();
2228
+ if (!id) continue;
2229
+ const c = r.claimable;
2230
+ const sym = (c?.token?.info?.symbol ?? "").trim() || "\u2014";
2231
+ const name = (c?.token?.info?.name ?? "").trim() || sym;
2232
+ const addr = (c?.token?.address ?? "").trim();
2233
+ const amt = (c?.amount?.value ?? "").trim();
2234
+ const exV = (c?.exchange?.value ?? "").trim();
2235
+ const exName = (c?.exchange?.name ?? "").trim();
2236
+ const exSym = (c?.exchange?.symbol ?? "").trim();
2237
+ const exchangeLabel = exName && exSym && exName.toUpperCase() !== exSym.toUpperCase() ? exName : exSym || exName || "\u2014";
2238
+ let exchangeValue = null;
2239
+ if (exV) {
2240
+ const n = parseFloat(exV);
2241
+ exchangeValue = Number.isFinite(n) ? exV : null;
2242
+ }
2243
+ out.push({
2244
+ id,
2245
+ tokenSymbol: sym,
2246
+ tokenName: name,
2247
+ tokenAddress: addr,
2248
+ amountValue: amt,
2249
+ exchangeValue,
2250
+ exchangeLabel
2251
+ });
2252
+ }
2253
+ return out;
2254
+ }
2255
+ async function fetchAaveV4MerklClaimRewardIdsForChain(args) {
2256
+ const rows = await fetchAaveV4MerklClaimableRewardsForChain(args);
2257
+ return rows.map((r) => r.id);
2258
+ }
2259
+ async function fetchAaveV4ClaimRewardsCalldata(args) {
2260
+ if (args.rewardIds.length === 0) return null;
2261
+ const d = await aaveV4Gql(CLAIM_REWARDS, { req: { user: args.user, chainId: args.chainId, ids: args.rewardIds } });
2262
+ const c = d.claimRewards;
2263
+ if (!c) return null;
2264
+ return {
2265
+ to: c.to,
2266
+ from: c.from,
2267
+ data: c.data,
2268
+ value: c.value,
2269
+ chainId: c.chainId
2270
+ };
2271
+ }
2272
+
2273
+ // src/protocols/evm/aave-v4/loadSupportedChainIds.ts
2274
+ var cached = null;
2275
+ var inflight = null;
2276
+ function loadAaveV4SupportedChainIds() {
2277
+ if (cached) return Promise.resolve(cached);
2278
+ if (inflight) return inflight;
2279
+ inflight = (async () => {
2280
+ try {
2281
+ const s = await loadAaveV4SupportedChainIdsFromV4Api();
2282
+ cached = s;
2283
+ return s;
2284
+ } finally {
2285
+ inflight = null;
2286
+ }
2287
+ })();
2288
+ return inflight;
2289
+ }
2290
+
2291
+ // src/chains/evm/chainIdParse.ts
2292
+ function parseEvmChainIdToNumber(chainId) {
2293
+ if (chainId == null) return Number.NaN;
2294
+ if (typeof chainId === "bigint") {
2295
+ const n = Number(chainId);
2296
+ return Number.isSafeInteger(n) && n >= 0 ? n : Number.NaN;
2297
+ }
2298
+ if (typeof chainId === "number") {
2299
+ return Number.isInteger(chainId) && chainId >= 0 ? chainId : Number.NaN;
2300
+ }
2301
+ const t = String(chainId).trim();
2302
+ if (!t) return Number.NaN;
2303
+ const low = t.toLowerCase();
2304
+ if (low.startsWith("eip155:")) {
2305
+ const rest = t.slice("eip155:".length).trim();
2306
+ const n = Number.parseInt(rest, 10);
2307
+ return Number.isNaN(n) || n < 0 ? Number.NaN : n;
2308
+ }
2309
+ if (low.startsWith("0x")) {
2310
+ return Number.parseInt(t, 16);
2311
+ }
2312
+ return Number.parseInt(t, 10);
2313
+ }
2314
+
2315
+ // src/protocols/evm/aave-v4/reserveDisplay.ts
2316
+ function formatAavePercentDisplay(p) {
2317
+ if (!p) return "\u2014";
2318
+ const t = (p.formatted ?? "").trim();
2319
+ if (t) return t.includes("%") ? t : `${t}%`;
2320
+ const v = (p.value ?? "").trim();
2321
+ if (!v) return "\u2014";
2322
+ const n = Number(v) * 100;
2323
+ if (!Number.isFinite(n)) return "\u2014";
2324
+ if (n >= 0.01) return `${n.toFixed(2)}%`;
2325
+ if (n > 0) return `${n.toFixed(4)}%`;
2326
+ return "0%";
2327
+ }
2328
+ function aaveAvailableLiquidityDisplay(supplyInfo, borrowInfo) {
2329
+ const sTotal = supplyInfo?.total;
2330
+ const bAmt = borrowInfo?.total?.amount;
2331
+ if (!sTotal?.raw || sTotal.decimals == null) return "\u2014";
2332
+ if (!bAmt?.raw || bAmt.decimals == null) return "\u2014";
2333
+ try {
2334
+ if (sTotal.decimals !== bAmt.decimals) return "\u2014";
2335
+ const a = BigInt(sTotal.raw) - BigInt(bAmt.raw);
2336
+ if (a < 0n) return "0";
2337
+ return formatUnits(a, sTotal.decimals);
2338
+ } catch {
2339
+ return "\u2014";
2340
+ }
2341
+ }
2342
+ function aaveUnderlyingAddressForContext(args) {
2343
+ const raw = (args.contextContract ?? "").trim();
2344
+ try {
2345
+ const a = getAddress(raw);
2346
+ if (a.toLowerCase() === zeroAddress.toLowerCase() && args.chainNativeWrapped) {
2347
+ return getAddress(args.chainNativeWrapped.trim());
2348
+ }
2349
+ return a;
2350
+ } catch {
2351
+ return getAddress(zeroAddress);
2352
+ }
2353
+ }
2354
+ function isValidAaveChainId(assetsChainId) {
2355
+ if (assetsChainId == null) return false;
2356
+ const n = parseEvmChainIdToNumber(assetsChainId);
2357
+ return !Number.isNaN(n) && n >= 0;
2358
+ }
2359
+ function aaveReadSupplyMetrics(reserve, symbolForDisplay) {
2360
+ if (!reserve || typeof reserve !== "object") {
2361
+ return { depositedAmount: "\u2014", apy: "\u2014", totalDeposits: "\u2014", availableLiquidity: "\u2014" };
2362
+ }
2363
+ const r = reserve;
2364
+ const apy = formatAavePercentDisplay(r.supplyInfo?.apy);
2365
+ const tot = r.supplyInfo?.total?.value ?? "\u2014";
2366
+ const liq = aaveAvailableLiquidityDisplay(r.supplyInfo, r.borrowInfo);
2367
+ const dep = r.userState?.balance?.amount?.value ?? "\u2014";
2368
+ const sym = (symbolForDisplay ?? "").trim();
2369
+ return {
2370
+ depositedAmount: dep === "\u2014" ? "\u2014" : sym ? `${dep} ${sym}` : dep,
2371
+ apy,
2372
+ totalDeposits: tot === "\u2014" ? "\u2014" : sym ? `${tot} ${sym}` : tot,
2373
+ availableLiquidity: liq === "\u2014" ? "\u2014" : sym ? `${liq} ${sym}` : liq
2374
+ };
2375
+ }
1643
2376
 
1644
2377
  // src/protocols/evm/aave-v4/index.ts
1645
2378
  var AAVE_V4_PROTOCOL_ID = "aave-v4";
@@ -1661,6 +2394,6 @@ var aaveV4ProtocolModule = {
1661
2394
  };
1662
2395
  registerProtocolModule(aaveV4ProtocolModule);
1663
2396
 
1664
- export { AAVE_V4_GRAPHQL_URL, AAVE_V4_PROTOCOL_ID, AAVE_V4_SPOKE_BORROW_DEFAULT_GAS_UNITS, AAVE_V4_SPOKE_REPAY_DEFAULT_GAS_UNITS, AAVE_V4_SPOKE_SUPPLY_DEFAULT_GAS_UNITS, AAVE_V4_SPOKE_WITHDRAW_DEFAULT_GAS_UNITS, MIN_AAVE_V4_DEPOSIT_GAS_EXEC, aaveV4Gql, aaveV4KeyForNodeAssetRow, aaveV4ProtocolModule, aaveV4UiMarketIdForHubName, aggregateV4SupplyDisplay, borrowableAssetsFromHubReserves, buildAaveV4BorrowTableRowsFromHub, buildEvmMultisignBodyAaveV4DepositBatch, buildEvmMultisignBodyAaveV4MerklClaimRewards, buildEvmMultisignBodyAaveV4SpokeBorrow, buildEvmMultisignBodyAaveV4SpokeRepay, buildEvmMultisignBodyAaveV4SpokeWithdraw, buildEvmMultisignBodyEulerV2MerklDistributorClaim, buildEvmMultisignBodyEulerV2ReulUnlock, ensureAaveV4ChainTokenCache, fetchAaveV4Chains, fetchAaveV4HubReserves, fetchAaveV4HubsForChain, fetchAaveV4NativeWrappedToken, fetchAaveV4ReservesForUnderlying, fetchAaveV4SpokeReserveIdForUnderlying, fetchAaveV4SpokeReserveStatusForUnderlying, fetchAaveV4SupportedUnderlyingAddressSet, fetchAaveV4UserBorrowsDebtByUnderlyingForHub, findAaveV4HubReserveForChainUnderlying, findHubReserveForUnderlying, formatAaveV4AmountHumanFromApiString, formatAaveV4PercentDisplay, formatAaveV4ReserveLiquidityFromSummary, formatAaveV4RiskDisplay, formatAaveV4TokenAmount, isAaveV4DepositEvmSignRequest, loadAaveV4SupportedChainIdsFromV4Api, pickAaveV4ReserveRowForSpoke, resolveAaveV4DepositGasUnitsFromSignRequest, resolveAaveV4HubForUiMarket };
2397
+ export { AAVE_V4_GRAPHQL_URL, AAVE_V4_PROTOCOL_ID, AAVE_V4_SPOKE_BORROW_DEFAULT_GAS_UNITS, AAVE_V4_SPOKE_REPAY_DEFAULT_GAS_UNITS, AAVE_V4_SPOKE_SUPPLY_DEFAULT_GAS_UNITS, AAVE_V4_SPOKE_WITHDRAW_DEFAULT_GAS_UNITS, MIN_AAVE_V4_DEPOSIT_GAS_EXEC, aaveAvailableLiquidityDisplay, aaveReadSupplyMetrics, aaveUnderlyingAddressForContext, aaveV4BorrowHealthGate, aaveV4Gql, aaveV4KeyForNodeAssetRow, aaveV4ProtocolModule, aaveV4RepayHealthGate, aaveV4UiMarketIdForHubName, aaveV4UserHasAvailableBorrowCollateralForContextOnSpoke, aaveV4WithdrawHealthGate, aggregateV4SupplyDisplay, borrowableAssetsFromHubReserves, buildAaveV4BorrowTableRowsFromHub, buildEvmMultisignBodyAaveV4DepositBatch, buildEvmMultisignBodyAaveV4MerklClaimRewards, buildEvmMultisignBodyAaveV4SpokeBorrow, buildEvmMultisignBodyAaveV4SpokeRepay, buildEvmMultisignBodyAaveV4SpokeWithdraw, buildEvmMultisignBodyEulerV2MerklDistributorClaim, buildEvmMultisignBodyEulerV2ReulUnlock, ensureAaveV4ChainTokenCache, fetchAaveV4Chains, fetchAaveV4ClaimRewardsCalldata, fetchAaveV4HubReserves, fetchAaveV4HubsForChain, fetchAaveV4MerklClaimRewardIdsForChain, fetchAaveV4MerklClaimableRewardsForChain, fetchAaveV4NativeWrappedToken, fetchAaveV4ReservesForUnderlying, fetchAaveV4SpokeReserveIdForUnderlying, fetchAaveV4SpokeReserveStatusForUnderlying, fetchAaveV4SupportedUnderlyingAddressSet, fetchAaveV4UserBorrowsDebtByUnderlyingForHub, fetchAaveV4UserPositionById, fetchAaveV4UserPositionsByAssetOnChain, fetchAaveV4UserPositionsForChain, fetchAaveV4UserSuppliesForPosition, findAaveV4HubReserveForChainUnderlying, findHubReserveForUnderlying, formatAavePercentDisplay, formatAaveV4AmountHumanFromApiString, formatAaveV4DecimalString, formatAaveV4ExchangeLabel, formatAaveV4HealthFactor, formatAaveV4PercentDisplay, formatAaveV4PositionHealthFactor, formatAaveV4PositionPercent, formatAaveV4ReserveLiquidityFromSummary, formatAaveV4RiskDisplay, formatAaveV4RiskNotionalString, formatAaveV4TokenAmount, isAaveV4DepositEvmSignRequest, isValidAaveChainId, loadAaveV4SupportedChainIds, loadAaveV4SupportedChainIdsFromV4Api, parseBigDecimalHf, pickAaveV4ReserveRowForSpoke, previewAaveV4BorrowResultingHf, previewAaveV4RepayResultingHf, previewAaveV4WithdrawResultingHf, resolveAaveV4DepositGasUnitsFromSignRequest, resolveAaveV4HubForUiMarket };
1665
2398
  //# sourceMappingURL=index.js.map
1666
2399
  //# sourceMappingURL=index.js.map