@continuumdao/ctm-mpc-defi 0.2.1 → 0.2.2

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