recon-crypto-mcp 0.1.0

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 (204) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +153 -0
  3. package/dist/abis/aave-pool.d.ts +174 -0
  4. package/dist/abis/aave-pool.js +101 -0
  5. package/dist/abis/aave-pool.js.map +1 -0
  6. package/dist/abis/aave-ui-pool-data-provider.d.ts +232 -0
  7. package/dist/abis/aave-ui-pool-data-provider.js +107 -0
  8. package/dist/abis/aave-ui-pool-data-provider.js.map +1 -0
  9. package/dist/abis/access-control.d.ts +94 -0
  10. package/dist/abis/access-control.js +51 -0
  11. package/dist/abis/access-control.js.map +1 -0
  12. package/dist/abis/compound-comet.d.ts +120 -0
  13. package/dist/abis/compound-comet.js +84 -0
  14. package/dist/abis/compound-comet.js.map +1 -0
  15. package/dist/abis/eigenlayer-delegation-manager.d.ts +23 -0
  16. package/dist/abis/eigenlayer-delegation-manager.js +18 -0
  17. package/dist/abis/eigenlayer-delegation-manager.js.map +1 -0
  18. package/dist/abis/eigenlayer-strategy-manager.d.ts +53 -0
  19. package/dist/abis/eigenlayer-strategy-manager.js +47 -0
  20. package/dist/abis/eigenlayer-strategy-manager.js.map +1 -0
  21. package/dist/abis/erc20.d.ts +78 -0
  22. package/dist/abis/erc20.js +10 -0
  23. package/dist/abis/erc20.js.map +1 -0
  24. package/dist/abis/lido.d.ts +80 -0
  25. package/dist/abis/lido.js +60 -0
  26. package/dist/abis/lido.js.map +1 -0
  27. package/dist/abis/morpho-blue.d.ts +321 -0
  28. package/dist/abis/morpho-blue.js +193 -0
  29. package/dist/abis/morpho-blue.js.map +1 -0
  30. package/dist/abis/uniswap-pool.d.ts +70 -0
  31. package/dist/abis/uniswap-pool.js +53 -0
  32. package/dist/abis/uniswap-pool.js.map +1 -0
  33. package/dist/abis/uniswap-position-manager.d.ts +71 -0
  34. package/dist/abis/uniswap-position-manager.js +41 -0
  35. package/dist/abis/uniswap-position-manager.js.map +1 -0
  36. package/dist/config/cache.d.ts +12 -0
  37. package/dist/config/cache.js +12 -0
  38. package/dist/config/cache.js.map +1 -0
  39. package/dist/config/chains.d.ts +24 -0
  40. package/dist/config/chains.js +158 -0
  41. package/dist/config/chains.js.map +1 -0
  42. package/dist/config/contracts.d.ts +107 -0
  43. package/dist/config/contracts.js +123 -0
  44. package/dist/config/contracts.js.map +1 -0
  45. package/dist/config/user-config.d.ts +15 -0
  46. package/dist/config/user-config.js +93 -0
  47. package/dist/config/user-config.js.map +1 -0
  48. package/dist/data/apis/etherscan.d.ts +30 -0
  49. package/dist/data/apis/etherscan.js +109 -0
  50. package/dist/data/apis/etherscan.js.map +1 -0
  51. package/dist/data/cache.d.ts +18 -0
  52. package/dist/data/cache.js +47 -0
  53. package/dist/data/cache.js.map +1 -0
  54. package/dist/data/format.d.ts +6 -0
  55. package/dist/data/format.js +44 -0
  56. package/dist/data/format.js.map +1 -0
  57. package/dist/data/prices.d.ts +12 -0
  58. package/dist/data/prices.js +81 -0
  59. package/dist/data/prices.js.map +1 -0
  60. package/dist/data/rpc.d.ts +17 -0
  61. package/dist/data/rpc.js +68 -0
  62. package/dist/data/rpc.js.map +1 -0
  63. package/dist/index.d.ts +2 -0
  64. package/dist/index.js +344 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/modules/balances/index.d.ts +20 -0
  67. package/dist/modules/balances/index.js +49 -0
  68. package/dist/modules/balances/index.js.map +1 -0
  69. package/dist/modules/balances/schemas.d.ts +32 -0
  70. package/dist/modules/balances/schemas.js +21 -0
  71. package/dist/modules/balances/schemas.js.map +1 -0
  72. package/dist/modules/bitcoin/index.d.ts +26 -0
  73. package/dist/modules/bitcoin/index.js +128 -0
  74. package/dist/modules/bitcoin/index.js.map +1 -0
  75. package/dist/modules/bitcoin/schemas.d.ts +49 -0
  76. package/dist/modules/bitcoin/schemas.js +51 -0
  77. package/dist/modules/bitcoin/schemas.js.map +1 -0
  78. package/dist/modules/bitcoin/send.d.ts +52 -0
  79. package/dist/modules/bitcoin/send.js +158 -0
  80. package/dist/modules/bitcoin/send.js.map +1 -0
  81. package/dist/modules/bitcoin/utxo.d.ts +99 -0
  82. package/dist/modules/bitcoin/utxo.js +116 -0
  83. package/dist/modules/bitcoin/utxo.js.map +1 -0
  84. package/dist/modules/compound/actions.d.ts +8 -0
  85. package/dist/modules/compound/actions.js +154 -0
  86. package/dist/modules/compound/actions.js.map +1 -0
  87. package/dist/modules/compound/index.d.ts +26 -0
  88. package/dist/modules/compound/index.js +141 -0
  89. package/dist/modules/compound/index.js.map +1 -0
  90. package/dist/modules/compound/schemas.d.ts +95 -0
  91. package/dist/modules/compound/schemas.js +37 -0
  92. package/dist/modules/compound/schemas.js.map +1 -0
  93. package/dist/modules/execution/index.d.ts +51 -0
  94. package/dist/modules/execution/index.js +271 -0
  95. package/dist/modules/execution/index.js.map +1 -0
  96. package/dist/modules/execution/schemas.d.ts +183 -0
  97. package/dist/modules/execution/schemas.js +88 -0
  98. package/dist/modules/execution/schemas.js.map +1 -0
  99. package/dist/modules/feedback/index.d.ts +28 -0
  100. package/dist/modules/feedback/index.js +161 -0
  101. package/dist/modules/feedback/index.js.map +1 -0
  102. package/dist/modules/feedback/rate-limit.d.ts +15 -0
  103. package/dist/modules/feedback/rate-limit.js +110 -0
  104. package/dist/modules/feedback/rate-limit.js.map +1 -0
  105. package/dist/modules/feedback/schemas.d.ts +41 -0
  106. package/dist/modules/feedback/schemas.js +40 -0
  107. package/dist/modules/feedback/schemas.js.map +1 -0
  108. package/dist/modules/morpho/actions.d.ts +8 -0
  109. package/dist/modules/morpho/actions.js +265 -0
  110. package/dist/modules/morpho/actions.js.map +1 -0
  111. package/dist/modules/morpho/index.d.ts +26 -0
  112. package/dist/modules/morpho/index.js +94 -0
  113. package/dist/modules/morpho/index.js.map +1 -0
  114. package/dist/modules/morpho/schemas.d.ts +130 -0
  115. package/dist/modules/morpho/schemas.js +34 -0
  116. package/dist/modules/morpho/schemas.js.map +1 -0
  117. package/dist/modules/portfolio/index.d.ts +3 -0
  118. package/dist/modules/portfolio/index.js +197 -0
  119. package/dist/modules/portfolio/index.js.map +1 -0
  120. package/dist/modules/portfolio/schemas.d.ts +20 -0
  121. package/dist/modules/portfolio/schemas.js +15 -0
  122. package/dist/modules/portfolio/schemas.js.map +1 -0
  123. package/dist/modules/positions/aave.d.ts +22 -0
  124. package/dist/modules/positions/aave.js +197 -0
  125. package/dist/modules/positions/aave.js.map +1 -0
  126. package/dist/modules/positions/actions.d.ts +18 -0
  127. package/dist/modules/positions/actions.js +205 -0
  128. package/dist/modules/positions/actions.js.map +1 -0
  129. package/dist/modules/positions/index.d.ts +37 -0
  130. package/dist/modules/positions/index.js +59 -0
  131. package/dist/modules/positions/index.js.map +1 -0
  132. package/dist/modules/positions/schemas.d.ts +55 -0
  133. package/dist/modules/positions/schemas.js +25 -0
  134. package/dist/modules/positions/schemas.js.map +1 -0
  135. package/dist/modules/positions/uniswap.d.ts +4 -0
  136. package/dist/modules/positions/uniswap.js +181 -0
  137. package/dist/modules/positions/uniswap.js.map +1 -0
  138. package/dist/modules/prices/index.d.ts +19 -0
  139. package/dist/modules/prices/index.js +22 -0
  140. package/dist/modules/prices/index.js.map +1 -0
  141. package/dist/modules/security/index.d.ts +26 -0
  142. package/dist/modules/security/index.js +13 -0
  143. package/dist/modules/security/index.js.map +1 -0
  144. package/dist/modules/security/permissions.d.ts +8 -0
  145. package/dist/modules/security/permissions.js +96 -0
  146. package/dist/modules/security/permissions.js.map +1 -0
  147. package/dist/modules/security/risk-score.d.ts +18 -0
  148. package/dist/modules/security/risk-score.js +116 -0
  149. package/dist/modules/security/risk-score.js.map +1 -0
  150. package/dist/modules/security/schemas.d.ts +31 -0
  151. package/dist/modules/security/schemas.js +16 -0
  152. package/dist/modules/security/schemas.js.map +1 -0
  153. package/dist/modules/security/verification.d.ts +4 -0
  154. package/dist/modules/security/verification.js +82 -0
  155. package/dist/modules/security/verification.js.map +1 -0
  156. package/dist/modules/shared/approval.d.ts +71 -0
  157. package/dist/modules/shared/approval.js +130 -0
  158. package/dist/modules/shared/approval.js.map +1 -0
  159. package/dist/modules/staking/actions.d.ts +22 -0
  160. package/dist/modules/staking/actions.js +100 -0
  161. package/dist/modules/staking/actions.js.map +1 -0
  162. package/dist/modules/staking/eigenlayer.d.ts +14 -0
  163. package/dist/modules/staking/eigenlayer.js +105 -0
  164. package/dist/modules/staking/eigenlayer.js.map +1 -0
  165. package/dist/modules/staking/index.d.ts +24 -0
  166. package/dist/modules/staking/index.js +59 -0
  167. package/dist/modules/staking/index.js.map +1 -0
  168. package/dist/modules/staking/lido.d.ts +14 -0
  169. package/dist/modules/staking/lido.js +113 -0
  170. package/dist/modules/staking/lido.js.map +1 -0
  171. package/dist/modules/staking/schemas.d.ts +34 -0
  172. package/dist/modules/staking/schemas.js +20 -0
  173. package/dist/modules/staking/schemas.js.map +1 -0
  174. package/dist/modules/swap/index.d.ts +47 -0
  175. package/dist/modules/swap/index.js +376 -0
  176. package/dist/modules/swap/index.js.map +1 -0
  177. package/dist/modules/swap/lifi.d.ts +17 -0
  178. package/dist/modules/swap/lifi.js +44 -0
  179. package/dist/modules/swap/lifi.js.map +1 -0
  180. package/dist/modules/swap/oneinch.d.ts +26 -0
  181. package/dist/modules/swap/oneinch.js +33 -0
  182. package/dist/modules/swap/oneinch.js.map +1 -0
  183. package/dist/modules/swap/schemas.d.ts +65 -0
  184. package/dist/modules/swap/schemas.js +46 -0
  185. package/dist/modules/swap/schemas.js.map +1 -0
  186. package/dist/setup.d.ts +2 -0
  187. package/dist/setup.js +257 -0
  188. package/dist/setup.js.map +1 -0
  189. package/dist/signing/pre-sign-check.d.ts +8 -0
  190. package/dist/signing/pre-sign-check.js +231 -0
  191. package/dist/signing/pre-sign-check.js.map +1 -0
  192. package/dist/signing/session.d.ts +28 -0
  193. package/dist/signing/session.js +26 -0
  194. package/dist/signing/session.js.map +1 -0
  195. package/dist/signing/tx-store.d.ts +29 -0
  196. package/dist/signing/tx-store.js +85 -0
  197. package/dist/signing/tx-store.js.map +1 -0
  198. package/dist/signing/walletconnect.d.ts +33 -0
  199. package/dist/signing/walletconnect.js +226 -0
  200. package/dist/signing/walletconnect.js.map +1 -0
  201. package/dist/types/index.d.ts +222 -0
  202. package/dist/types/index.js +18 -0
  203. package/dist/types/index.js.map +1 -0
  204. package/package.json +134 -0
@@ -0,0 +1,71 @@
1
+ export declare const uniswapPositionManagerAbi: readonly [{
2
+ readonly type: "function";
3
+ readonly name: "balanceOf";
4
+ readonly stateMutability: "view";
5
+ readonly inputs: readonly [{
6
+ readonly name: "owner";
7
+ readonly type: "address";
8
+ }];
9
+ readonly outputs: readonly [{
10
+ readonly type: "uint256";
11
+ }];
12
+ }, {
13
+ readonly type: "function";
14
+ readonly name: "tokenOfOwnerByIndex";
15
+ readonly stateMutability: "view";
16
+ readonly inputs: readonly [{
17
+ readonly name: "owner";
18
+ readonly type: "address";
19
+ }, {
20
+ readonly name: "index";
21
+ readonly type: "uint256";
22
+ }];
23
+ readonly outputs: readonly [{
24
+ readonly type: "uint256";
25
+ }];
26
+ }, {
27
+ readonly type: "function";
28
+ readonly name: "positions";
29
+ readonly stateMutability: "view";
30
+ readonly inputs: readonly [{
31
+ readonly name: "tokenId";
32
+ readonly type: "uint256";
33
+ }];
34
+ readonly outputs: readonly [{
35
+ readonly name: "nonce";
36
+ readonly type: "uint96";
37
+ }, {
38
+ readonly name: "operator";
39
+ readonly type: "address";
40
+ }, {
41
+ readonly name: "token0";
42
+ readonly type: "address";
43
+ }, {
44
+ readonly name: "token1";
45
+ readonly type: "address";
46
+ }, {
47
+ readonly name: "fee";
48
+ readonly type: "uint24";
49
+ }, {
50
+ readonly name: "tickLower";
51
+ readonly type: "int24";
52
+ }, {
53
+ readonly name: "tickUpper";
54
+ readonly type: "int24";
55
+ }, {
56
+ readonly name: "liquidity";
57
+ readonly type: "uint128";
58
+ }, {
59
+ readonly name: "feeGrowthInside0LastX128";
60
+ readonly type: "uint256";
61
+ }, {
62
+ readonly name: "feeGrowthInside1LastX128";
63
+ readonly type: "uint256";
64
+ }, {
65
+ readonly name: "tokensOwed0";
66
+ readonly type: "uint128";
67
+ }, {
68
+ readonly name: "tokensOwed1";
69
+ readonly type: "uint128";
70
+ }];
71
+ }];
@@ -0,0 +1,41 @@
1
+ // Uniswap V3 NonfungiblePositionManager — functions needed to enumerate LP NFTs.
2
+ export const uniswapPositionManagerAbi = [
3
+ {
4
+ type: "function",
5
+ name: "balanceOf",
6
+ stateMutability: "view",
7
+ inputs: [{ name: "owner", type: "address" }],
8
+ outputs: [{ type: "uint256" }],
9
+ },
10
+ {
11
+ type: "function",
12
+ name: "tokenOfOwnerByIndex",
13
+ stateMutability: "view",
14
+ inputs: [
15
+ { name: "owner", type: "address" },
16
+ { name: "index", type: "uint256" },
17
+ ],
18
+ outputs: [{ type: "uint256" }],
19
+ },
20
+ {
21
+ type: "function",
22
+ name: "positions",
23
+ stateMutability: "view",
24
+ inputs: [{ name: "tokenId", type: "uint256" }],
25
+ outputs: [
26
+ { name: "nonce", type: "uint96" },
27
+ { name: "operator", type: "address" },
28
+ { name: "token0", type: "address" },
29
+ { name: "token1", type: "address" },
30
+ { name: "fee", type: "uint24" },
31
+ { name: "tickLower", type: "int24" },
32
+ { name: "tickUpper", type: "int24" },
33
+ { name: "liquidity", type: "uint128" },
34
+ { name: "feeGrowthInside0LastX128", type: "uint256" },
35
+ { name: "feeGrowthInside1LastX128", type: "uint256" },
36
+ { name: "tokensOwed0", type: "uint128" },
37
+ { name: "tokensOwed1", type: "uint128" },
38
+ ],
39
+ },
40
+ ];
41
+ //# sourceMappingURL=uniswap-position-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uniswap-position-manager.js","sourceRoot":"","sources":["../../src/abis/uniswap-position-manager.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,WAAW;QACjB,eAAe,EAAE,MAAM;QACvB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC5C,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;KAC/B;IACD;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,qBAAqB;QAC3B,eAAe,EAAE,MAAM;QACvB,MAAM,EAAE;YACN,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;YAClC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;SACnC;QACD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;KAC/B;IACD;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,WAAW;QACjB,eAAe,EAAE,MAAM;QACvB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC9C,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE;YACjC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;YACrC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE;YACnC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE;YACnC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC/B,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE;YACpC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE;YACpC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE;YACtC,EAAE,IAAI,EAAE,0BAA0B,EAAE,IAAI,EAAE,SAAS,EAAE;YACrD,EAAE,IAAI,EAAE,0BAA0B,EAAE,IAAI,EAAE,SAAS,EAAE;YACrD,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE;YACxC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE;SACzC;KACF;CACO,CAAC"}
@@ -0,0 +1,12 @@
1
+ /** TTLs (milliseconds) for the in-memory cache, keyed by data category. */
2
+ export declare const CACHE_TTL: {
3
+ readonly PRICE: 30000;
4
+ readonly POSITION: 60000;
5
+ readonly STAKING: 120000;
6
+ readonly YIELD: 600000;
7
+ readonly SECURITY_VERIFICATION: 86400000;
8
+ readonly SECURITY_PERMISSIONS: 3600000;
9
+ readonly PROTOCOL_RISK: 3600000;
10
+ readonly IMMUNEFI: 86400000;
11
+ };
12
+ export type CacheTTLKey = keyof typeof CACHE_TTL;
@@ -0,0 +1,12 @@
1
+ /** TTLs (milliseconds) for the in-memory cache, keyed by data category. */
2
+ export const CACHE_TTL = {
3
+ PRICE: 30_000,
4
+ POSITION: 60_000,
5
+ STAKING: 120_000,
6
+ YIELD: 600_000,
7
+ SECURITY_VERIFICATION: 86_400_000,
8
+ SECURITY_PERMISSIONS: 3_600_000,
9
+ PROTOCOL_RISK: 3_600_000,
10
+ IMMUNEFI: 86_400_000,
11
+ };
12
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/config/cache.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE,MAAM;IAChB,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,OAAO;IACd,qBAAqB,EAAE,UAAU;IACjC,oBAAoB,EAAE,SAAS;IAC/B,aAAa,EAAE,SAAS;IACxB,QAAQ,EAAE,UAAU;CACZ,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { Chain } from "viem";
2
+ import type { SupportedChain, UserConfig } from "../types/index.js";
3
+ export declare const VIEM_CHAINS: Record<SupportedChain, Chain>;
4
+ export declare class RpcConfigError extends Error {
5
+ constructor(message: string);
6
+ }
7
+ /**
8
+ * Reject RPC URLs that are obviously unsafe to talk to:
9
+ * - non-https (http plaintext leaks your wallet query pattern to anything on
10
+ * the network path)
11
+ * - loopback / private / link-local hosts (RFC1918, 127/8, ::1, *.local).
12
+ * Private-range URLs in a shared config are a strong indicator something
13
+ * got mis-pasted (e.g. a neighbour's dev box) and we'd rather fail loud
14
+ * than exfiltrate wallet addresses to an unexpected host.
15
+ * Callers who intentionally want to hit a local forked node (anvil, hardhat,
16
+ * etc.) can opt out with RECON_ALLOW_INSECURE_RPC=1.
17
+ */
18
+ export declare function validateRpcUrl(chain: SupportedChain, url: string): void;
19
+ export declare function isPrivateOrLoopbackHost(host: string): boolean;
20
+ /**
21
+ * Resolve the RPC URL for a given chain based on env vars (highest priority)
22
+ * then the user's ~/.recon-crypto-mcp/config.json.
23
+ */
24
+ export declare function resolveRpcUrl(chain: SupportedChain, userConfig: UserConfig | null): string;
@@ -0,0 +1,158 @@
1
+ import { mainnet, arbitrum, polygon } from "viem/chains";
2
+ export const VIEM_CHAINS = {
3
+ ethereum: mainnet,
4
+ arbitrum,
5
+ polygon,
6
+ };
7
+ /** URL path segment per provider + chain. */
8
+ const PROVIDER_URL_TEMPLATES = {
9
+ infura: {
10
+ ethereum: (k) => `https://mainnet.infura.io/v3/${k}`,
11
+ arbitrum: (k) => `https://arbitrum-mainnet.infura.io/v3/${k}`,
12
+ polygon: (k) => `https://polygon-mainnet.infura.io/v3/${k}`,
13
+ },
14
+ alchemy: {
15
+ ethereum: (k) => `https://eth-mainnet.g.alchemy.com/v2/${k}`,
16
+ arbitrum: (k) => `https://arb-mainnet.g.alchemy.com/v2/${k}`,
17
+ polygon: (k) => `https://polygon-mainnet.g.alchemy.com/v2/${k}`,
18
+ },
19
+ };
20
+ const ENV_URL_VAR = {
21
+ ethereum: "ETHEREUM_RPC_URL",
22
+ arbitrum: "ARBITRUM_RPC_URL",
23
+ polygon: "POLYGON_RPC_URL",
24
+ };
25
+ export class RpcConfigError extends Error {
26
+ constructor(message) {
27
+ super(message);
28
+ this.name = "RpcConfigError";
29
+ }
30
+ }
31
+ /**
32
+ * Reject RPC URLs that are obviously unsafe to talk to:
33
+ * - non-https (http plaintext leaks your wallet query pattern to anything on
34
+ * the network path)
35
+ * - loopback / private / link-local hosts (RFC1918, 127/8, ::1, *.local).
36
+ * Private-range URLs in a shared config are a strong indicator something
37
+ * got mis-pasted (e.g. a neighbour's dev box) and we'd rather fail loud
38
+ * than exfiltrate wallet addresses to an unexpected host.
39
+ * Callers who intentionally want to hit a local forked node (anvil, hardhat,
40
+ * etc.) can opt out with RECON_ALLOW_INSECURE_RPC=1.
41
+ */
42
+ export function validateRpcUrl(chain, url) {
43
+ if (process.env.RECON_ALLOW_INSECURE_RPC === "1")
44
+ return;
45
+ let parsed;
46
+ try {
47
+ parsed = new URL(url);
48
+ }
49
+ catch {
50
+ throw new RpcConfigError(`RPC URL for ${chain} is not a valid URL: ${url}. Fix it via \`recon-crypto-mcp-setup\` or the relevant env var.`);
51
+ }
52
+ if (parsed.protocol !== "https:") {
53
+ throw new RpcConfigError(`RPC URL for ${chain} must use https (got ${parsed.protocol}//). ` +
54
+ `Plaintext RPCs leak wallet addresses to anyone on the network path. ` +
55
+ `Set RECON_ALLOW_INSECURE_RPC=1 only if you're pointing at a local anvil/hardhat fork.`);
56
+ }
57
+ const host = parsed.hostname.toLowerCase();
58
+ if (isPrivateOrLoopbackHost(host)) {
59
+ throw new RpcConfigError(`RPC URL for ${chain} points at a private/loopback host (${host}). ` +
60
+ `This is almost always a mis-pasted config. ` +
61
+ `Set RECON_ALLOW_INSECURE_RPC=1 if you intend to hit a local fork.`);
62
+ }
63
+ }
64
+ export function isPrivateOrLoopbackHost(host) {
65
+ // Strip IPv6 bracket form. The URL parser can return hostnames like "[::1]"
66
+ // or "[fe80::1]"; normalise to the bare address for matching.
67
+ let h = host;
68
+ if (h.startsWith("[") && h.endsWith("]"))
69
+ h = h.slice(1, -1);
70
+ h = h.toLowerCase();
71
+ if (h === "localhost" || h.endsWith(".local") || h.endsWith(".localhost"))
72
+ return true;
73
+ // IPv4 literal.
74
+ const v4 = h.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
75
+ if (v4 && isPrivateOrLoopbackIPv4(Number(v4[1]), Number(v4[2]))) {
76
+ return true;
77
+ }
78
+ // IPv4-mapped IPv6, e.g. ::ffff:10.0.0.1 or ::ffff:c0a8:0001.
79
+ const mapped = h.match(/^::ffff:(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
80
+ if (mapped && isPrivateOrLoopbackIPv4(Number(mapped[1]), Number(mapped[2]))) {
81
+ return true;
82
+ }
83
+ // IPv6 literals. We match on prefix rather than fully parsing the address
84
+ // because the forms we care about all have a fixed high-order signature:
85
+ // ::1 loopback
86
+ // fc00::/7 ULA (matches fc.. and fd.. as first hex pair)
87
+ // fe80::/10 link-local (fe8., fe9., fea., feb.)
88
+ // :: unspecified
89
+ if (h === "::1" || h === "::")
90
+ return true;
91
+ // Hex-pair prefix — first group before ':' or string end.
92
+ const firstGroup = h.split(":")[0];
93
+ if (/^fc[0-9a-f]{0,2}$/.test(firstGroup) || /^fd[0-9a-f]{0,2}$/.test(firstGroup)) {
94
+ return true;
95
+ }
96
+ if (/^fe[89ab][0-9a-f]?$/.test(firstGroup)) {
97
+ return true;
98
+ }
99
+ return false;
100
+ }
101
+ function isPrivateOrLoopbackIPv4(a, b) {
102
+ if (a === 10)
103
+ return true;
104
+ if (a === 127)
105
+ return true;
106
+ if (a === 172 && b >= 16 && b <= 31)
107
+ return true;
108
+ if (a === 192 && b === 168)
109
+ return true;
110
+ if (a === 169 && b === 254)
111
+ return true; // link-local
112
+ if (a === 0)
113
+ return true;
114
+ return false;
115
+ }
116
+ /**
117
+ * Resolve the RPC URL for a given chain based on env vars (highest priority)
118
+ * then the user's ~/.recon-crypto-mcp/config.json.
119
+ */
120
+ export function resolveRpcUrl(chain, userConfig) {
121
+ const url = resolveRpcUrlRaw(chain, userConfig);
122
+ validateRpcUrl(chain, url);
123
+ return url;
124
+ }
125
+ function resolveRpcUrlRaw(chain, userConfig) {
126
+ // Env overrides — per-chain full URL beats everything.
127
+ const envChainUrl = process.env[ENV_URL_VAR[chain]];
128
+ if (envChainUrl)
129
+ return envChainUrl;
130
+ // Env provider + key.
131
+ const envProvider = process.env.RPC_PROVIDER?.toLowerCase();
132
+ const envKey = process.env.RPC_API_KEY;
133
+ if (envProvider && envProvider !== "custom" && envKey) {
134
+ if (envProvider !== "infura" && envProvider !== "alchemy") {
135
+ throw new RpcConfigError(`Unknown RPC_PROVIDER: ${envProvider}`);
136
+ }
137
+ return PROVIDER_URL_TEMPLATES[envProvider][chain](envKey);
138
+ }
139
+ // User config file.
140
+ if (userConfig) {
141
+ const { provider, apiKey, customUrls } = userConfig.rpc;
142
+ if (provider === "custom") {
143
+ const url = customUrls?.[chain];
144
+ if (url)
145
+ return url;
146
+ throw new RpcConfigError(`No custom RPC URL configured for chain "${chain}". Re-run \`recon-crypto-mcp-setup\`.`);
147
+ }
148
+ if (provider === "infura" || provider === "alchemy") {
149
+ if (!apiKey) {
150
+ throw new RpcConfigError(`Missing API key for RPC provider "${provider}". Re-run \`recon-crypto-mcp-setup\`.`);
151
+ }
152
+ return PROVIDER_URL_TEMPLATES[provider][chain](apiKey);
153
+ }
154
+ }
155
+ throw new RpcConfigError(`No RPC provider configured for chain "${chain}". ` +
156
+ `Run \`recon-crypto-mcp-setup\` to configure Infura, Alchemy, or a custom endpoint.`);
157
+ }
158
+ //# sourceMappingURL=chains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chains.js","sourceRoot":"","sources":["../../src/config/chains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAIzD,MAAM,CAAC,MAAM,WAAW,GAAkC;IACxD,QAAQ,EAAE,OAAO;IACjB,QAAQ;IACR,OAAO;CACR,CAAC;AAEF,6CAA6C;AAC7C,MAAM,sBAAsB,GAA4F;IACtH,MAAM,EAAE;QACN,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,gCAAgC,CAAC,EAAE;QACpD,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,yCAAyC,CAAC,EAAE;QAC7D,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,wCAAwC,CAAC,EAAE;KAC5D;IACD,OAAO,EAAE;QACP,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,wCAAwC,CAAC,EAAE;QAC5D,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,wCAAwC,CAAC,EAAE;QAC5D,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,4CAA4C,CAAC,EAAE;KAChE;CACF,CAAC;AAEF,MAAM,WAAW,GAAmC;IAClD,QAAQ,EAAE,kBAAkB;IAC5B,QAAQ,EAAE,kBAAkB;IAC5B,OAAO,EAAE,iBAAiB;CAC3B,CAAC;AAEF,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,KAAqB,EAAE,GAAW;IAC/D,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,GAAG;QAAE,OAAO;IACzD,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,cAAc,CACtB,eAAe,KAAK,wBAAwB,GAAG,kEAAkE,CAClH,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,cAAc,CACtB,eAAe,KAAK,wBAAwB,MAAM,CAAC,QAAQ,OAAO;YAChE,sEAAsE;YACtE,uFAAuF,CAC1F,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC3C,IAAI,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,cAAc,CACtB,eAAe,KAAK,uCAAuC,IAAI,KAAK;YAClE,6CAA6C;YAC7C,mEAAmE,CACtE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,4EAA4E;IAC5E,8DAA8D;IAC9D,IAAI,CAAC,GAAG,IAAI,CAAC;IACb,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAEpB,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvF,gBAAgB;IAChB,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;IACnE,IAAI,EAAE,IAAI,uBAAuB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8DAA8D;IAC9D,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;IAC9E,IAAI,MAAM,IAAI,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0EAA0E;IAC1E,yEAAyE;IACzE,6BAA6B;IAC7B,kEAAkE;IAClE,wDAAwD;IACxD,gCAAgC;IAChC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC3C,0DAA0D;IAC1D,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACjF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,qBAAqB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,uBAAuB,CAAC,CAAS,EAAE,CAAS;IACnD,IAAI,CAAC,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACxC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC,CAAC,aAAa;IACtD,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzB,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAqB,EAAE,UAA6B;IAChF,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAChD,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC3B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAqB,EAAE,UAA6B;IAC5E,uDAAuD;IACvD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IACpD,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IAEpC,sBAAsB;IACtB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,WAAW,EAA6B,CAAC;IACvF,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IACvC,IAAI,WAAW,IAAI,WAAW,KAAK,QAAQ,IAAI,MAAM,EAAE,CAAC;QACtD,IAAI,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC1D,MAAM,IAAI,cAAc,CAAC,yBAAyB,WAAW,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,sBAAsB,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;IAC5D,CAAC;IAED,oBAAoB;IACpB,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC;QACxD,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,GAAG;gBAAE,OAAO,GAAG,CAAC;YACpB,MAAM,IAAI,cAAc,CACtB,2CAA2C,KAAK,uCAAuC,CACxF,CAAC;QACJ,CAAC;QACD,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACpD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,cAAc,CACtB,qCAAqC,QAAQ,uCAAuC,CACrF,CAAC;YACJ,CAAC;YACD,OAAO,sBAAsB,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,MAAM,IAAI,cAAc,CACtB,yCAAyC,KAAK,KAAK;QACjD,oFAAoF,CACvF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,107 @@
1
+ import type { SupportedChain } from "../types/index.js";
2
+ /**
3
+ * Canonical contract addresses per chain.
4
+ * Source: Aave V3 deployments, Uniswap V3 deployments, Lido docs, EigenLayer repo.
5
+ */
6
+ export declare const CONTRACTS: {
7
+ readonly ethereum: {
8
+ readonly aave: {
9
+ readonly poolAddressProvider: "0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e";
10
+ readonly uiPoolDataProvider: "0x3F78BBD206e4D3c504Eb854232EdA7e47E9Fd8FC";
11
+ readonly pool: "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2";
12
+ };
13
+ readonly uniswap: {
14
+ readonly positionManager: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88";
15
+ readonly factory: "0x1F98431c8aD98523631AE4a59f267346ea31F984";
16
+ };
17
+ readonly lido: {
18
+ readonly stETH: "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84";
19
+ readonly wstETH: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0";
20
+ readonly withdrawalQueue: "0x889edC2eDab5f40e902b864aD4d7AdE8E412F9B1";
21
+ };
22
+ readonly eigenlayer: {
23
+ readonly strategyManager: "0x858646372CC42E1A627fcE94aa7A7033e7CF075A";
24
+ readonly delegationManager: "0x39053D51B77DC0d36036Fc1fCc8Cb819df8Ef37A";
25
+ };
26
+ readonly tokens: {
27
+ readonly USDC: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
28
+ readonly USDT: "0xdAC17F958D2ee523a2206206994597C13D831ec7";
29
+ readonly DAI: "0x6B175474E89094C44Da98b954EedeAC495271d0F";
30
+ readonly WETH: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
31
+ readonly WBTC: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599";
32
+ readonly LINK: "0x514910771AF9Ca656af840dff83E8264EcF986CA";
33
+ readonly UNI: "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984";
34
+ readonly AAVE: "0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9";
35
+ readonly LDO: "0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32";
36
+ };
37
+ readonly compound: {
38
+ readonly cUSDCv3: "0xc3d688B66703497DAA19211EEdff47f25384cdc3";
39
+ readonly cUSDTv3: "0x3Afdc9BCA9213A35503b077a6072F3D0d5AB0840";
40
+ readonly cWETHv3: "0xA17581A9E3356d9A858b789D68B4d866e593aE94";
41
+ readonly cwstETHv3: "0x3D0bb1ccaB520A66e607822fC55BC921738fAFE3";
42
+ };
43
+ readonly morpho: {
44
+ /** Morpho Blue singleton on Ethereum. */
45
+ readonly blue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb";
46
+ };
47
+ };
48
+ readonly arbitrum: {
49
+ readonly aave: {
50
+ readonly poolAddressProvider: "0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb";
51
+ readonly uiPoolDataProvider: "0x5c5228aC8BC1528482514aF3e27E692495148717";
52
+ readonly pool: "0x794a61358D6845594F94dc1DB02A252b5b4814aD";
53
+ };
54
+ readonly uniswap: {
55
+ readonly positionManager: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88";
56
+ readonly factory: "0x1F98431c8aD98523631AE4a59f267346ea31F984";
57
+ };
58
+ readonly lido: {
59
+ readonly wstETH: "0x5979D7b546E38E414F7E9822514be443A4800529";
60
+ };
61
+ readonly tokens: {
62
+ readonly USDC: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831";
63
+ readonly "USDC.e": "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8";
64
+ readonly USDT: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9";
65
+ readonly DAI: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1";
66
+ readonly WETH: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1";
67
+ readonly WBTC: "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f";
68
+ readonly LINK: "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4";
69
+ readonly ARB: "0x912CE59144191C1204E64559FE8253a0e49E6548";
70
+ };
71
+ readonly compound: {
72
+ readonly cUSDCv3: "0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf";
73
+ readonly "cUSDC.ev3": "0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA";
74
+ readonly cUSDTv3: "0xd98Be00b5D27fc98112BdE293e487f8D4cA57d07";
75
+ readonly cWETHv3: "0x6f7D514bbD4aFf3BcD1140B7344b32f063dEe486";
76
+ };
77
+ };
78
+ readonly polygon: {
79
+ readonly aave: {
80
+ readonly poolAddressProvider: "0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb";
81
+ readonly uiPoolDataProvider: "0xC69728f11E9E6127733751c8410432913123acf1";
82
+ readonly pool: "0x794a61358D6845594F94dc1DB02A252b5b4814aD";
83
+ };
84
+ readonly uniswap: {
85
+ readonly positionManager: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88";
86
+ readonly factory: "0x1F98431c8aD98523631AE4a59f267346ea31F984";
87
+ };
88
+ readonly tokens: {
89
+ readonly USDC: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359";
90
+ readonly "USDC.e": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
91
+ readonly USDT: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F";
92
+ readonly DAI: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063";
93
+ readonly WETH: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619";
94
+ readonly WMATIC: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270";
95
+ readonly WBTC: "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6";
96
+ readonly LINK: "0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39";
97
+ readonly AAVE: "0xD6DF932A45C0f255f85145f286eA0b292B21C90B";
98
+ };
99
+ readonly compound: {
100
+ readonly cUSDCv3: "0xF25212E676D1F7F89Cd72fFEe66158f541246445";
101
+ readonly "cUSDT.ev3": "0xaeB318360f27748Acb200CE616E389A6C9409a07";
102
+ };
103
+ };
104
+ };
105
+ export type ChainContracts<C extends SupportedChain> = (typeof CONTRACTS)[C];
106
+ /** Native asset symbol per chain. */
107
+ export declare const NATIVE_SYMBOL: Record<SupportedChain, string>;
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Canonical contract addresses per chain.
3
+ * Source: Aave V3 deployments, Uniswap V3 deployments, Lido docs, EigenLayer repo.
4
+ */
5
+ export const CONTRACTS = {
6
+ ethereum: {
7
+ aave: {
8
+ poolAddressProvider: "0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e",
9
+ uiPoolDataProvider: "0x3F78BBD206e4D3c504Eb854232EdA7e47E9Fd8FC",
10
+ // Pinned Pool address used by the pre-sign safety check. Derived from
11
+ // PoolAddressesProvider.getPool() at deploy time and stable since Aave
12
+ // V3 launch on this chain. Used in place of a live getPool() read so a
13
+ // compromised RPC cannot forge a malicious pool into our allowlist.
14
+ pool: "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
15
+ },
16
+ uniswap: {
17
+ positionManager: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
18
+ factory: "0x1F98431c8aD98523631AE4a59f267346ea31F984",
19
+ },
20
+ lido: {
21
+ stETH: "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
22
+ wstETH: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
23
+ withdrawalQueue: "0x889edC2eDab5f40e902b864aD4d7AdE8E412F9B1",
24
+ },
25
+ eigenlayer: {
26
+ strategyManager: "0x858646372CC42E1A627fcE94aa7A7033e7CF075A",
27
+ // EIP-55 checksum: second `f` is lowercase in the canonical form. viem's readContract
28
+ // re-validates address checksums and will throw InvalidAddressError otherwise.
29
+ delegationManager: "0x39053D51B77DC0d36036Fc1fCc8Cb819df8Ef37A",
30
+ },
31
+ // Common ERC-20 tokens used for portfolio summary.
32
+ tokens: {
33
+ USDC: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
34
+ USDT: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
35
+ DAI: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
36
+ WETH: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
37
+ WBTC: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
38
+ LINK: "0x514910771AF9Ca656af840dff83E8264EcF986CA",
39
+ UNI: "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
40
+ AAVE: "0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9",
41
+ LDO: "0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32",
42
+ },
43
+ compound: {
44
+ cUSDCv3: "0xc3d688B66703497DAA19211EEdff47f25384cdc3",
45
+ cUSDTv3: "0x3Afdc9BCA9213A35503b077a6072F3D0d5AB0840",
46
+ cWETHv3: "0xA17581A9E3356d9A858b789D68B4d866e593aE94",
47
+ cwstETHv3: "0x3D0bb1ccaB520A66e607822fC55BC921738fAFE3",
48
+ },
49
+ morpho: {
50
+ /** Morpho Blue singleton on Ethereum. */
51
+ blue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
52
+ },
53
+ },
54
+ arbitrum: {
55
+ aave: {
56
+ poolAddressProvider: "0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb",
57
+ uiPoolDataProvider: "0x5c5228aC8BC1528482514aF3e27E692495148717",
58
+ pool: "0x794a61358D6845594F94dc1DB02A252b5b4814aD",
59
+ },
60
+ uniswap: {
61
+ positionManager: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
62
+ factory: "0x1F98431c8aD98523631AE4a59f267346ea31F984",
63
+ },
64
+ lido: {
65
+ wstETH: "0x5979D7b546E38E414F7E9822514be443A4800529",
66
+ },
67
+ tokens: {
68
+ USDC: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
69
+ "USDC.e": "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8",
70
+ USDT: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
71
+ DAI: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1",
72
+ WETH: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
73
+ WBTC: "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f",
74
+ LINK: "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4",
75
+ ARB: "0x912CE59144191C1204E64559FE8253a0e49E6548",
76
+ },
77
+ compound: {
78
+ cUSDCv3: "0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf",
79
+ "cUSDC.ev3": "0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA",
80
+ cUSDTv3: "0xd98Be00b5D27fc98112BdE293e487f8D4cA57d07",
81
+ cWETHv3: "0x6f7D514bbD4aFf3BcD1140B7344b32f063dEe486",
82
+ },
83
+ },
84
+ polygon: {
85
+ aave: {
86
+ // Aave V3 uses the same PoolAddressesProvider address across most L2s
87
+ // (deterministic deploy); UiPoolDataProviderV3 is chain-specific.
88
+ poolAddressProvider: "0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb",
89
+ uiPoolDataProvider: "0xC69728f11E9E6127733751c8410432913123acf1",
90
+ pool: "0x794a61358D6845594F94dc1DB02A252b5b4814aD",
91
+ },
92
+ uniswap: {
93
+ positionManager: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
94
+ factory: "0x1F98431c8aD98523631AE4a59f267346ea31F984",
95
+ },
96
+ // Lido has no native deployment on Polygon (stMATIC is a separate protocol
97
+ // from a different team); we intentionally omit the `lido` entry so the
98
+ // staking reader short-circuits for this chain.
99
+ tokens: {
100
+ USDC: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
101
+ "USDC.e": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
102
+ USDT: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
103
+ DAI: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
104
+ WETH: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619",
105
+ WMATIC: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",
106
+ WBTC: "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6",
107
+ LINK: "0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39",
108
+ AAVE: "0xD6DF932A45C0f255f85145f286eA0b292B21C90B",
109
+ },
110
+ compound: {
111
+ cUSDCv3: "0xF25212E676D1F7F89Cd72fFEe66158f541246445",
112
+ "cUSDT.ev3": "0xaeB318360f27748Acb200CE616E389A6C9409a07",
113
+ },
114
+ },
115
+ };
116
+ /** Native asset symbol per chain. */
117
+ export const NATIVE_SYMBOL = {
118
+ ethereum: "ETH",
119
+ arbitrum: "ETH",
120
+ // Polygon's native token is MATIC (rebranding to POL is in progress — same contract).
121
+ polygon: "MATIC",
122
+ };
123
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/config/contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { UserConfig } from "../types/index.js";
2
+ /** Read the user config file; returns null if it doesn't exist. Throws on malformed JSON. */
3
+ export declare function readUserConfig(): UserConfig | null;
4
+ export declare function writeUserConfig(config: UserConfig): void;
5
+ export declare function onRpcConfigChange(hook: () => void): void;
6
+ /** Merge a partial update into the existing config (or create a fresh one). */
7
+ export declare function patchUserConfig(patch: Partial<UserConfig>): UserConfig;
8
+ export declare function getConfigPath(): string;
9
+ export declare function getConfigDir(): string;
10
+ /** Pull the Etherscan API key from env (highest priority) or user config. */
11
+ export declare function resolveEtherscanApiKey(userConfig: UserConfig | null): string | undefined;
12
+ /** Pull the 1inch Developer Portal API key from env or user config; undefined if none set. */
13
+ export declare function resolveOneInchApiKey(userConfig: UserConfig | null): string | undefined;
14
+ /** Pull the WalletConnect project ID from env or user config; undefined if none set. */
15
+ export declare function resolveWalletConnectProjectId(userConfig: UserConfig | null): string | undefined;