@elizaos/plugin-wallet 2.0.0-beta.1

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 (200) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +64 -0
  3. package/auto-enable.ts +76 -0
  4. package/dist/LpManagementService-BWrQ5-cO.mjs +353 -0
  5. package/dist/MockLpService-D_Apn4Fd.mjs +99 -0
  6. package/dist/aerodrome-CfnESC32.mjs +890 -0
  7. package/dist/chunk-hT5z_Zn9.mjs +35 -0
  8. package/dist/index.d.mts +34727 -0
  9. package/dist/index.mjs +21590 -0
  10. package/dist/lib/server-wallet-trade.d.mts +34 -0
  11. package/dist/lib/server-wallet-trade.mjs +306 -0
  12. package/dist/meteora-BPX39hZo.mjs +22640 -0
  13. package/dist/orca-Bybp1HXO.mjs +249 -0
  14. package/dist/pancakeswp-CkEXlXti.mjs +604 -0
  15. package/dist/plugin-ZO_MTyd0.mjs +529 -0
  16. package/dist/raydium-rfaM9yEf.mjs +539 -0
  17. package/dist/sdk/index.d.mts +32492 -0
  18. package/dist/sdk/index.mjs +6415 -0
  19. package/dist/types-D5252NZk.mjs +487 -0
  20. package/dist/uniswap-CReXgXVN.mjs +573 -0
  21. package/dist/wallet-action.d.mts +6 -0
  22. package/dist/wallet-action.mjs +820 -0
  23. package/package.json +152 -0
  24. package/src/actions/failure-codes.ts +79 -0
  25. package/src/actions/index.ts +1 -0
  26. package/src/analytics/birdeye/actions/wallet-search-address.ts +9 -0
  27. package/src/analytics/birdeye/birdeye-task.ts +175 -0
  28. package/src/analytics/birdeye/birdeye.ts +813 -0
  29. package/src/analytics/birdeye/constants.ts +74 -0
  30. package/src/analytics/birdeye/providers/agent-portfolio-provider.ts +18 -0
  31. package/src/analytics/birdeye/providers/market.ts +227 -0
  32. package/src/analytics/birdeye/providers/portfolio-factory.test.ts +138 -0
  33. package/src/analytics/birdeye/providers/portfolio-factory.ts +252 -0
  34. package/src/analytics/birdeye/providers/trending.ts +365 -0
  35. package/src/analytics/birdeye/providers/wallet.ts +14 -0
  36. package/src/analytics/birdeye/search-category.test.ts +207 -0
  37. package/src/analytics/birdeye/search-category.ts +506 -0
  38. package/src/analytics/birdeye/service.ts +992 -0
  39. package/src/analytics/birdeye/tasks/birdeye.ts +232 -0
  40. package/src/analytics/birdeye/types/api/common.ts +305 -0
  41. package/src/analytics/birdeye/types/api/defi.ts +220 -0
  42. package/src/analytics/birdeye/types/api/pair.ts +200 -0
  43. package/src/analytics/birdeye/types/api/search.ts +86 -0
  44. package/src/analytics/birdeye/types/api/token.ts +635 -0
  45. package/src/analytics/birdeye/types/api/trader.ts +76 -0
  46. package/src/analytics/birdeye/types/api/wallet.ts +181 -0
  47. package/src/analytics/birdeye/types/shared.ts +106 -0
  48. package/src/analytics/birdeye/utils.ts +700 -0
  49. package/src/analytics/dexscreener/errors.ts +28 -0
  50. package/src/analytics/dexscreener/index.ts +3 -0
  51. package/src/analytics/dexscreener/search-category.test.ts +49 -0
  52. package/src/analytics/dexscreener/search-category.ts +42 -0
  53. package/src/analytics/dexscreener/service.ts +595 -0
  54. package/src/analytics/dexscreener/types.ts +128 -0
  55. package/src/analytics/lpinfo/index.d.ts +7 -0
  56. package/src/analytics/lpinfo/index.ts +52 -0
  57. package/src/analytics/lpinfo/kamino/README.md +102 -0
  58. package/src/analytics/lpinfo/kamino/index.ts +24 -0
  59. package/src/analytics/lpinfo/kamino/providers/kaminoLiquidityProvider.ts +422 -0
  60. package/src/analytics/lpinfo/kamino/providers/kaminoPoolProvider.ts +365 -0
  61. package/src/analytics/lpinfo/kamino/providers/kaminoProvider.ts +496 -0
  62. package/src/analytics/lpinfo/kamino/services/kaminoLiquidityService.ts +1123 -0
  63. package/src/analytics/lpinfo/kamino/services/kaminoService.ts +758 -0
  64. package/src/analytics/lpinfo/steer/README.md +169 -0
  65. package/src/analytics/lpinfo/steer/index.ts +23 -0
  66. package/src/analytics/lpinfo/steer/providers/steerLiquidityProvider.ts +544 -0
  67. package/src/analytics/lpinfo/steer/services/steerLiquidityService.ts +1690 -0
  68. package/src/analytics/lpinfo/steer/steer-display-types.ts +99 -0
  69. package/src/analytics/news/index.ts +52 -0
  70. package/src/analytics/news/interfaces/types.ts +222 -0
  71. package/src/analytics/news/providers/defiNewsProvider.ts +734 -0
  72. package/src/analytics/news/services/newsDataService.ts +332 -0
  73. package/src/analytics/news/utils/formatters.ts +151 -0
  74. package/src/analytics/token-info/action.ts +240 -0
  75. package/src/analytics/token-info/index.ts +3 -0
  76. package/src/analytics/token-info/params.ts +215 -0
  77. package/src/analytics/token-info/providers.ts +681 -0
  78. package/src/analytics/token-info/service.ts +168 -0
  79. package/src/analytics/token-info/types.ts +74 -0
  80. package/src/audit/audit-log.ts +45 -0
  81. package/src/browser-shim/build-shim.ts +123 -0
  82. package/src/browser-shim/index.ts +5 -0
  83. package/src/browser-shim/shim.template.js +563 -0
  84. package/src/chains/evm/.github/workflows/npm-deploy.yml +112 -0
  85. package/src/chains/evm/LICENSE +21 -0
  86. package/src/chains/evm/README.md +106 -0
  87. package/src/chains/evm/actions/helpers.ts +147 -0
  88. package/src/chains/evm/actions/swap.ts +839 -0
  89. package/src/chains/evm/actions/transfer.ts +254 -0
  90. package/src/chains/evm/biome.json +61 -0
  91. package/src/chains/evm/bridge-router.ts +660 -0
  92. package/src/chains/evm/build.ts +89 -0
  93. package/src/chains/evm/chain-handler.ts +416 -0
  94. package/src/chains/evm/constants.ts +23 -0
  95. package/src/chains/evm/contracts/artifacts/OZGovernor.json +1707 -0
  96. package/src/chains/evm/contracts/artifacts/TimelockController.json +1007 -0
  97. package/src/chains/evm/contracts/artifacts/VoteToken.json +895 -0
  98. package/src/chains/evm/dex/aerodrome/index.ts +34 -0
  99. package/src/chains/evm/dex/aerodrome/services/AerodromeLpService.ts +558 -0
  100. package/src/chains/evm/dex/aerodrome/types.ts +318 -0
  101. package/src/chains/evm/dex/pancakeswp/index.ts +35 -0
  102. package/src/chains/evm/dex/pancakeswp/services/PancakeSwapV3LpService.ts +743 -0
  103. package/src/chains/evm/dex/pancakeswp/types.ts +65 -0
  104. package/src/chains/evm/dex/uniswap/index.ts +35 -0
  105. package/src/chains/evm/dex/uniswap/services/UniswapV3LpService.ts +759 -0
  106. package/src/chains/evm/dex/uniswap/types.ts +390 -0
  107. package/src/chains/evm/generated/specs/spec-helpers.ts +73 -0
  108. package/src/chains/evm/generated/specs/specs.ts +151 -0
  109. package/src/chains/evm/gov-router.ts +250 -0
  110. package/src/chains/evm/index.browser.ts +16 -0
  111. package/src/chains/evm/index.ts +31 -0
  112. package/src/chains/evm/prompts.ts +193 -0
  113. package/src/chains/evm/providers/get-balance.ts +123 -0
  114. package/src/chains/evm/providers/wallet.ts +715 -0
  115. package/src/chains/evm/routes/sign.ts +333 -0
  116. package/src/chains/evm/rpc-providers.ts +410 -0
  117. package/src/chains/evm/service.ts +140 -0
  118. package/src/chains/evm/templates/index.ts +10 -0
  119. package/src/chains/evm/types/index.ts +432 -0
  120. package/src/chains/evm/vitest.config.ts +18 -0
  121. package/src/chains/registry.ts +668 -0
  122. package/src/chains/solana/README.md +367 -0
  123. package/src/chains/wallet-action.ts +533 -0
  124. package/src/chains/wallet-router.test.ts +296 -0
  125. package/src/contracts.ts +65 -0
  126. package/src/core-augmentation.ts +10 -0
  127. package/src/index.ts +71 -0
  128. package/src/lib/server-wallet-trade.ts +192 -0
  129. package/src/lib/wallet-export-guard.ts +330 -0
  130. package/src/lp/actions/liquidity.ts +827 -0
  131. package/src/lp/e2e/real-token-tests.ts +428 -0
  132. package/src/lp/e2e/scenarios.ts +470 -0
  133. package/src/lp/e2e/test-utils.ts +145 -0
  134. package/src/lp/lp-manager-entry.ts +303 -0
  135. package/src/lp/services/ConcentratedLiquidityService.ts +120 -0
  136. package/src/lp/services/DexInteractionService.ts +226 -0
  137. package/src/lp/services/LpManagementService.test.ts +148 -0
  138. package/src/lp/services/LpManagementService.ts +632 -0
  139. package/src/lp/services/UserLpProfileService.ts +163 -0
  140. package/src/lp/services/VaultService.ts +153 -0
  141. package/src/lp/services/YieldOptimizationService.ts +344 -0
  142. package/src/lp/services/__tests__/MockLpService.ts +146 -0
  143. package/src/lp/tasks/LpAutoRebalanceTask.ts +117 -0
  144. package/src/lp/tasks/__tests__/LpAutoRebalanceTask.test.ts +370 -0
  145. package/src/lp/types.ts +582 -0
  146. package/src/lp/utils/solanaClient.ts +143 -0
  147. package/src/plugin.ts +125 -0
  148. package/src/policy/policy.ts +19 -0
  149. package/src/providers/canonical-provider.ts +27 -0
  150. package/src/providers/unified-wallet-provider.ts +79 -0
  151. package/src/register-routes.ts +11 -0
  152. package/src/routes/plugin.ts +47 -0
  153. package/src/routes/wallet-market-overview-route.ts +869 -0
  154. package/src/sdk/abi.ts +258 -0
  155. package/src/sdk/bridge/abis.ts +126 -0
  156. package/src/sdk/bridge/client.ts +518 -0
  157. package/src/sdk/bridge/index.ts +56 -0
  158. package/src/sdk/bridge/solana.ts +604 -0
  159. package/src/sdk/bridge/types.ts +202 -0
  160. package/src/sdk/convenience.ts +347 -0
  161. package/src/sdk/escrow/MutualStakeEscrow.ts +480 -0
  162. package/src/sdk/escrow/types.ts +64 -0
  163. package/src/sdk/escrow/verifiers.ts +73 -0
  164. package/src/sdk/identity/erc8004.ts +692 -0
  165. package/src/sdk/identity/reputation.ts +449 -0
  166. package/src/sdk/identity/uaid.ts +497 -0
  167. package/src/sdk/identity/validation.ts +372 -0
  168. package/src/sdk/index.ts +763 -0
  169. package/src/sdk/policy/SpendingPolicy.ts +260 -0
  170. package/src/sdk/policy/UptoBillingPolicy.ts +320 -0
  171. package/src/sdk/router/PaymentRouter.ts +215 -0
  172. package/src/sdk/router/index.ts +8 -0
  173. package/src/sdk/swap/SwapModule.ts +310 -0
  174. package/src/sdk/swap/abi.ts +117 -0
  175. package/src/sdk/swap/index.ts +34 -0
  176. package/src/sdk/swap/types.ts +135 -0
  177. package/src/sdk/tokens/decimals.ts +140 -0
  178. package/src/sdk/tokens/registry.ts +911 -0
  179. package/src/sdk/tokens/solana.ts +419 -0
  180. package/src/sdk/tokens/transfers.ts +327 -0
  181. package/src/sdk/types.ts +158 -0
  182. package/src/sdk/wallet-core.ts +115 -0
  183. package/src/sdk/x402/budget.ts +168 -0
  184. package/src/sdk/x402/chains/abstract/index.ts +280 -0
  185. package/src/sdk/x402/client.ts +320 -0
  186. package/src/sdk/x402/index.ts +46 -0
  187. package/src/sdk/x402/middleware.ts +92 -0
  188. package/src/sdk/x402/multi-asset.ts +144 -0
  189. package/src/sdk/x402/types.ts +156 -0
  190. package/src/services/wallet-backend-service.ts +328 -0
  191. package/src/types/wallet-router.ts +227 -0
  192. package/src/utils/intent-trajectory.ts +106 -0
  193. package/src/wallet/backend.ts +62 -0
  194. package/src/wallet/errors.ts +49 -0
  195. package/src/wallet/index.ts +27 -0
  196. package/src/wallet/local-eoa-backend.ts +201 -0
  197. package/src/wallet/pending.ts +60 -0
  198. package/src/wallet/select-backend.ts +47 -0
  199. package/src/wallet/steward-backend.ts +161 -0
  200. package/src/wallet-action.ts +1 -0
@@ -0,0 +1,573 @@
1
+ import { n as __exportAll } from "./chunk-hT5z_Zn9.mjs";
2
+ import { o as registerLpProtocolProvider, r as createEvmLpProtocolProvider } from "./LpManagementService-BWrQ5-cO.mjs";
3
+ import { a as UNISWAP_V3_POOL_ABI, i as UNISWAP_V3_FEE_TIERS, n as UNISWAP_V3_ADDRESSES, o as UNISWAP_V3_POSITION_MANAGER_ABI, r as UNISWAP_V3_FACTORY_ABI, t as ERC20_ABI } from "./types-D5252NZk.mjs";
4
+ import { Service, logger } from "@elizaos/core";
5
+ import { createPublicClient, createWalletClient, http, maxUint128 } from "viem";
6
+ import * as viemChains from "viem/chains";
7
+ import { privateKeyToAccount } from "viem/accounts";
8
+ //#region src/chains/evm/dex/uniswap/services/UniswapV3LpService.ts
9
+ const SUPPORTED_CHAIN_IDS = [
10
+ 1,
11
+ 8453,
12
+ 42161,
13
+ 137,
14
+ 10
15
+ ];
16
+ function getViemChain(chainId) {
17
+ const chain = {
18
+ 1: viemChains.mainnet,
19
+ 8453: viemChains.base,
20
+ 42161: viemChains.arbitrum,
21
+ 137: viemChains.polygon,
22
+ 10: viemChains.optimism
23
+ }[chainId];
24
+ if (!chain) throw new Error(`Unsupported chain ID: ${chainId}`);
25
+ return chain;
26
+ }
27
+ var UniswapV3LpService = class UniswapV3LpService extends Service {
28
+ static serviceType = "uniswap-v3-lp";
29
+ capabilityDescription = "Provides Uniswap V3 liquidity pool management for EVM chains.";
30
+ publicClients = /* @__PURE__ */ new Map();
31
+ walletClients = /* @__PURE__ */ new Map();
32
+ rpcUrls = /* @__PURE__ */ new Map();
33
+ constructor(runtime) {
34
+ super(runtime);
35
+ if (runtime) this.initializeRpcUrls();
36
+ }
37
+ initializeRpcUrls() {
38
+ for (const [chainId, envKeys] of Object.entries({
39
+ 1: [
40
+ "ETHEREUM_RPC_URL",
41
+ "ETH_RPC_URL",
42
+ "EVM_PROVIDER_MAINNET"
43
+ ],
44
+ 8453: ["BASE_RPC_URL", "EVM_PROVIDER_BASE"],
45
+ 42161: ["ARBITRUM_RPC_URL", "EVM_PROVIDER_ARBITRUM"],
46
+ 137: ["POLYGON_RPC_URL", "EVM_PROVIDER_POLYGON"],
47
+ 10: ["OPTIMISM_RPC_URL", "EVM_PROVIDER_OPTIMISM"]
48
+ })) for (const key of envKeys) {
49
+ const rpcUrl = this.runtime.getSetting(key);
50
+ if (rpcUrl && typeof rpcUrl === "string") {
51
+ this.rpcUrls.set(Number(chainId), rpcUrl);
52
+ break;
53
+ }
54
+ }
55
+ }
56
+ getPublicClient(chainId) {
57
+ let client = this.publicClients.get(chainId);
58
+ if (client) return client;
59
+ const rpcUrl = this.rpcUrls.get(chainId);
60
+ client = createPublicClient({
61
+ chain: getViemChain(chainId),
62
+ transport: rpcUrl ? http(rpcUrl) : http()
63
+ });
64
+ this.publicClients.set(chainId, client);
65
+ return client;
66
+ }
67
+ getWalletClient(chainId, privateKey) {
68
+ const cacheKey = chainId;
69
+ let client = this.walletClients.get(cacheKey);
70
+ if (client) return client;
71
+ const rpcUrl = this.rpcUrls.get(chainId);
72
+ const chain = getViemChain(chainId);
73
+ const account = privateKeyToAccount(privateKey);
74
+ client = createWalletClient({
75
+ chain,
76
+ transport: rpcUrl ? http(rpcUrl) : http(),
77
+ account
78
+ });
79
+ this.walletClients.set(cacheKey, client);
80
+ return client;
81
+ }
82
+ static async start(runtime) {
83
+ const service = new UniswapV3LpService(runtime);
84
+ logger.info("[UniswapV3LpService] started");
85
+ return service;
86
+ }
87
+ async stop() {
88
+ this.publicClients.clear();
89
+ this.walletClients.clear();
90
+ logger.info("[UniswapV3LpService] stopped");
91
+ }
92
+ getDexName() {
93
+ return "uniswap";
94
+ }
95
+ getSupportedChainIds() {
96
+ return SUPPORTED_CHAIN_IDS.filter((chainId) => UNISWAP_V3_ADDRESSES[chainId] !== void 0);
97
+ }
98
+ supportsChain(chainId) {
99
+ return this.getSupportedChainIds().includes(chainId);
100
+ }
101
+ async getPools(chainId, tokenA, tokenB, feeTier) {
102
+ if (!this.supportsChain(chainId)) {
103
+ logger.warn(`[UniswapV3LpService] Chain ${chainId} not supported`);
104
+ return [];
105
+ }
106
+ const addresses = UNISWAP_V3_ADDRESSES[chainId];
107
+ if (!addresses) return [];
108
+ const client = this.getPublicClient(chainId);
109
+ const pools = [];
110
+ if (tokenA && tokenB) {
111
+ const feeTiers = feeTier ? [feeTier] : Object.values(UNISWAP_V3_FEE_TIERS);
112
+ for (const fee of feeTiers) try {
113
+ const poolAddress = await client.readContract({
114
+ address: addresses.factory,
115
+ abi: UNISWAP_V3_FACTORY_ABI,
116
+ functionName: "getPool",
117
+ args: [
118
+ tokenA,
119
+ tokenB,
120
+ fee
121
+ ]
122
+ });
123
+ if (poolAddress && poolAddress !== "0x0000000000000000000000000000000000000000") {
124
+ const poolInfo = await this.getPoolInfo(chainId, poolAddress);
125
+ if (poolInfo) pools.push(poolInfo);
126
+ }
127
+ } catch (_error) {
128
+ logger.debug(`[UniswapV3LpService] No pool found for ${tokenA}/${tokenB} at fee ${fee}`);
129
+ }
130
+ }
131
+ return pools;
132
+ }
133
+ async getPoolInfo(chainId, poolAddress) {
134
+ const client = this.getPublicClient(chainId);
135
+ const chain = getViemChain(chainId);
136
+ try {
137
+ const [token0, token1, fee, tickSpacing, _liquidity, slot0] = await Promise.all([
138
+ client.readContract({
139
+ address: poolAddress,
140
+ abi: UNISWAP_V3_POOL_ABI,
141
+ functionName: "token0"
142
+ }),
143
+ client.readContract({
144
+ address: poolAddress,
145
+ abi: UNISWAP_V3_POOL_ABI,
146
+ functionName: "token1"
147
+ }),
148
+ client.readContract({
149
+ address: poolAddress,
150
+ abi: UNISWAP_V3_POOL_ABI,
151
+ functionName: "fee"
152
+ }),
153
+ client.readContract({
154
+ address: poolAddress,
155
+ abi: UNISWAP_V3_POOL_ABI,
156
+ functionName: "tickSpacing"
157
+ }),
158
+ client.readContract({
159
+ address: poolAddress,
160
+ abi: UNISWAP_V3_POOL_ABI,
161
+ functionName: "liquidity"
162
+ }),
163
+ client.readContract({
164
+ address: poolAddress,
165
+ abi: UNISWAP_V3_POOL_ABI,
166
+ functionName: "slot0"
167
+ })
168
+ ]);
169
+ const [symbol0, decimals0, symbol1, decimals1] = await Promise.all([
170
+ client.readContract({
171
+ address: token0,
172
+ abi: ERC20_ABI,
173
+ functionName: "symbol"
174
+ }).catch(() => "UNKNOWN"),
175
+ client.readContract({
176
+ address: token0,
177
+ abi: ERC20_ABI,
178
+ functionName: "decimals"
179
+ }).catch(() => 18),
180
+ client.readContract({
181
+ address: token1,
182
+ abi: ERC20_ABI,
183
+ functionName: "symbol"
184
+ }).catch(() => "UNKNOWN"),
185
+ client.readContract({
186
+ address: token1,
187
+ abi: ERC20_ABI,
188
+ functionName: "decimals"
189
+ }).catch(() => 18)
190
+ ]);
191
+ return {
192
+ id: poolAddress,
193
+ dex: "uniswap",
194
+ chainId,
195
+ chainName: chain.name,
196
+ poolAddress,
197
+ tokenA: {
198
+ address: token0,
199
+ symbol: symbol0,
200
+ decimals: Number(decimals0)
201
+ },
202
+ tokenB: {
203
+ address: token1,
204
+ symbol: symbol1,
205
+ decimals: Number(decimals1)
206
+ },
207
+ feeTier: Number(fee),
208
+ tickSpacing: Number(tickSpacing),
209
+ currentTick: Number(slot0[1]),
210
+ sqrtPriceX96: slot0[0],
211
+ fee: Number(fee) / 1e6,
212
+ displayName: `${symbol0}/${symbol1} (${Number(fee) / 1e4}%)`
213
+ };
214
+ } catch (error) {
215
+ logger.error(`[UniswapV3LpService] Error fetching pool info for ${poolAddress}:`, error instanceof Error ? error.message : String(error));
216
+ return null;
217
+ }
218
+ }
219
+ async addLiquidity(params) {
220
+ if (!this.supportsChain(params.chainId)) return {
221
+ success: false,
222
+ error: `Chain ${params.chainId} not supported`
223
+ };
224
+ const addresses = UNISWAP_V3_ADDRESSES[params.chainId];
225
+ if (!addresses) return {
226
+ success: false,
227
+ error: "Uniswap V3 not deployed on this chain"
228
+ };
229
+ try {
230
+ const publicClient = this.getPublicClient(params.chainId);
231
+ const walletClient = this.getWalletClient(params.chainId, params.wallet.privateKey);
232
+ const poolInfo = await this.getPoolInfo(params.chainId, params.poolAddress);
233
+ if (!poolInfo) return {
234
+ success: false,
235
+ error: "Pool not found"
236
+ };
237
+ const slippageMultiplier = BigInt(1e4 - params.slippageBps);
238
+ const amount0Min = params.tokenAAmount * slippageMultiplier / 10000n;
239
+ const amount1Min = (params.tokenBAmount ?? 0n) * slippageMultiplier / 10000n;
240
+ await this.approveToken(params.chainId, params.wallet.privateKey, poolInfo.tokenA.address, addresses.nonfungiblePositionManager, params.tokenAAmount);
241
+ if (params.tokenBAmount && params.tokenBAmount > 0n) await this.approveToken(params.chainId, params.wallet.privateKey, poolInfo.tokenB.address, addresses.nonfungiblePositionManager, params.tokenBAmount);
242
+ const deadline = params.deadline ?? BigInt(Math.floor(Date.now() / 1e3) + 1800);
243
+ const tickLower = params.tickLower ?? poolInfo.currentTick - 1e3;
244
+ const tickUpper = params.tickUpper ?? poolInfo.currentTick + 1e3;
245
+ const tickSpacing = poolInfo.tickSpacing ?? 60;
246
+ const alignedTickLower = Math.floor(tickLower / tickSpacing) * tickSpacing;
247
+ const alignedTickUpper = Math.ceil(tickUpper / tickSpacing) * tickSpacing;
248
+ const mintParams = {
249
+ token0: poolInfo.tokenA.address,
250
+ token1: poolInfo.tokenB.address,
251
+ fee: poolInfo.feeTier,
252
+ tickLower: alignedTickLower,
253
+ tickUpper: alignedTickUpper,
254
+ amount0Desired: params.tokenAAmount,
255
+ amount1Desired: params.tokenBAmount ?? 0n,
256
+ amount0Min,
257
+ amount1Min,
258
+ recipient: params.wallet.address,
259
+ deadline
260
+ };
261
+ const { request } = await publicClient.simulateContract({
262
+ address: addresses.nonfungiblePositionManager,
263
+ abi: UNISWAP_V3_POSITION_MANAGER_ABI,
264
+ functionName: "mint",
265
+ args: [mintParams],
266
+ account: walletClient.account
267
+ });
268
+ const hash = await walletClient.writeContract(request);
269
+ const receipt = await publicClient.waitForTransactionReceipt({ hash });
270
+ return {
271
+ success: receipt.status === "success",
272
+ transactionId: hash,
273
+ hash,
274
+ chainId: params.chainId,
275
+ blockNumber: receipt.blockNumber,
276
+ gasUsed: receipt.gasUsed,
277
+ data: {
278
+ poolAddress: params.poolAddress,
279
+ tickLower: alignedTickLower,
280
+ tickUpper: alignedTickUpper
281
+ }
282
+ };
283
+ } catch (error) {
284
+ const errorMsg = error instanceof Error ? error.message : String(error);
285
+ logger.error("[UniswapV3LpService] Error adding liquidity:", errorMsg);
286
+ return {
287
+ success: false,
288
+ error: errorMsg || "Unknown error adding liquidity"
289
+ };
290
+ }
291
+ }
292
+ async removeLiquidity(params) {
293
+ if (!this.supportsChain(params.chainId)) return {
294
+ success: false,
295
+ error: `Chain ${params.chainId} not supported`
296
+ };
297
+ const addresses = UNISWAP_V3_ADDRESSES[params.chainId];
298
+ if (!addresses) return {
299
+ success: false,
300
+ error: "Uniswap V3 not deployed on this chain"
301
+ };
302
+ if (!params.tokenId) return {
303
+ success: false,
304
+ error: "Position token ID required for Uniswap V3"
305
+ };
306
+ try {
307
+ const publicClient = this.getPublicClient(params.chainId);
308
+ const walletClient = this.getWalletClient(params.chainId, params.wallet.privateKey);
309
+ const position = await this.getPositionFromContract(params.chainId, params.tokenId);
310
+ if (!position) return {
311
+ success: false,
312
+ error: "Position not found"
313
+ };
314
+ let liquidityToRemove = position.liquidity;
315
+ if (params.percentageToRemove && params.percentageToRemove < 100) liquidityToRemove = position.liquidity * BigInt(params.percentageToRemove) / 100n;
316
+ const deadline = params.deadline ?? BigInt(Math.floor(Date.now() / 1e3) + 1800);
317
+ BigInt(1e4 - params.slippageBps);
318
+ const decreaseParams = {
319
+ tokenId: params.tokenId,
320
+ liquidity: liquidityToRemove,
321
+ amount0Min: 0n,
322
+ amount1Min: 0n,
323
+ deadline
324
+ };
325
+ const { request: decreaseRequest } = await publicClient.simulateContract({
326
+ address: addresses.nonfungiblePositionManager,
327
+ abi: UNISWAP_V3_POSITION_MANAGER_ABI,
328
+ functionName: "decreaseLiquidity",
329
+ args: [decreaseParams],
330
+ account: walletClient.account
331
+ });
332
+ const decreaseHash = await walletClient.writeContract(decreaseRequest);
333
+ await publicClient.waitForTransactionReceipt({ hash: decreaseHash });
334
+ const collectParams = {
335
+ tokenId: params.tokenId,
336
+ recipient: params.wallet.address,
337
+ amount0Max: maxUint128,
338
+ amount1Max: maxUint128
339
+ };
340
+ const { request: collectRequest } = await publicClient.simulateContract({
341
+ address: addresses.nonfungiblePositionManager,
342
+ abi: UNISWAP_V3_POSITION_MANAGER_ABI,
343
+ functionName: "collect",
344
+ args: [collectParams],
345
+ account: walletClient.account
346
+ });
347
+ const collectHash = await walletClient.writeContract(collectRequest);
348
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: collectHash });
349
+ if (params.percentageToRemove === 100 || !params.percentageToRemove) try {
350
+ const { request: burnRequest } = await publicClient.simulateContract({
351
+ address: addresses.nonfungiblePositionManager,
352
+ abi: UNISWAP_V3_POSITION_MANAGER_ABI,
353
+ functionName: "burn",
354
+ args: [params.tokenId],
355
+ account: walletClient.account
356
+ });
357
+ await walletClient.writeContract(burnRequest);
358
+ } catch (burnError) {
359
+ logger.debug("[UniswapV3LpService] Could not burn position NFT:", burnError instanceof Error ? burnError.message : String(burnError));
360
+ }
361
+ return {
362
+ success: receipt.status === "success",
363
+ transactionId: collectHash,
364
+ hash: collectHash,
365
+ chainId: params.chainId,
366
+ blockNumber: receipt.blockNumber,
367
+ gasUsed: receipt.gasUsed
368
+ };
369
+ } catch (error) {
370
+ const errorMsg = error instanceof Error ? error.message : String(error);
371
+ logger.error("[UniswapV3LpService] Error removing liquidity:", errorMsg);
372
+ return {
373
+ success: false,
374
+ error: errorMsg || "Unknown error removing liquidity"
375
+ };
376
+ }
377
+ }
378
+ async getPositionFromContract(chainId, tokenId) {
379
+ const addresses = UNISWAP_V3_ADDRESSES[chainId];
380
+ if (!addresses) return null;
381
+ const client = this.getPublicClient(chainId);
382
+ try {
383
+ const result = await client.readContract({
384
+ address: addresses.nonfungiblePositionManager,
385
+ abi: UNISWAP_V3_POSITION_MANAGER_ABI,
386
+ functionName: "positions",
387
+ args: [tokenId]
388
+ });
389
+ return {
390
+ tokenId,
391
+ nonce: result[0],
392
+ operator: result[1],
393
+ token0: result[2],
394
+ token1: result[3],
395
+ fee: result[4],
396
+ tickLower: result[5],
397
+ tickUpper: result[6],
398
+ liquidity: result[7],
399
+ feeGrowthInside0LastX128: result[8],
400
+ feeGrowthInside1LastX128: result[9],
401
+ tokensOwed0: result[10],
402
+ tokensOwed1: result[11]
403
+ };
404
+ } catch (error) {
405
+ logger.error(`[UniswapV3LpService] Error fetching position ${tokenId}:`, error instanceof Error ? error.message : String(error));
406
+ return null;
407
+ }
408
+ }
409
+ async getPositionDetails(chainId, owner, poolAddress, tokenId) {
410
+ if (!this.supportsChain(chainId)) return null;
411
+ if (tokenId) {
412
+ const position = await this.getPositionFromContract(chainId, tokenId);
413
+ if (!position) return null;
414
+ const client = this.getPublicClient(chainId);
415
+ getViemChain(chainId);
416
+ const [symbol0, decimals0, symbol1, decimals1] = await Promise.all([
417
+ client.readContract({
418
+ address: position.token0,
419
+ abi: ERC20_ABI,
420
+ functionName: "symbol"
421
+ }).catch(() => "UNKNOWN"),
422
+ client.readContract({
423
+ address: position.token0,
424
+ abi: ERC20_ABI,
425
+ functionName: "decimals"
426
+ }).catch(() => 18),
427
+ client.readContract({
428
+ address: position.token1,
429
+ abi: ERC20_ABI,
430
+ functionName: "symbol"
431
+ }).catch(() => "UNKNOWN"),
432
+ client.readContract({
433
+ address: position.token1,
434
+ abi: ERC20_ABI,
435
+ functionName: "decimals"
436
+ }).catch(() => 18)
437
+ ]);
438
+ return {
439
+ poolId: poolAddress,
440
+ dex: "uniswap",
441
+ chainId,
442
+ owner,
443
+ tokenId: position.tokenId,
444
+ tickLower: position.tickLower,
445
+ tickUpper: position.tickUpper,
446
+ liquidity: position.liquidity,
447
+ lpTokenBalance: {
448
+ address: poolAddress,
449
+ balance: position.liquidity.toString(),
450
+ decimals: 0,
451
+ symbol: `UNI-V3-${symbol0}/${symbol1}`
452
+ },
453
+ underlyingTokens: [{
454
+ address: position.token0,
455
+ balance: position.tokensOwed0.toString(),
456
+ decimals: Number(decimals0),
457
+ symbol: symbol0
458
+ }, {
459
+ address: position.token1,
460
+ balance: position.tokensOwed1.toString(),
461
+ decimals: Number(decimals1),
462
+ symbol: symbol1
463
+ }]
464
+ };
465
+ }
466
+ return (await this.getAllPositions(chainId, owner)).find((p) => p.poolId.toLowerCase() === poolAddress.toLowerCase()) ?? null;
467
+ }
468
+ async getAllPositions(chainId, owner) {
469
+ if (!this.supportsChain(chainId)) return [];
470
+ const addresses = UNISWAP_V3_ADDRESSES[chainId];
471
+ if (!addresses) return [];
472
+ const client = this.getPublicClient(chainId);
473
+ const positions = [];
474
+ try {
475
+ const balance = await client.readContract({
476
+ address: addresses.nonfungiblePositionManager,
477
+ abi: UNISWAP_V3_POSITION_MANAGER_ABI,
478
+ functionName: "balanceOf",
479
+ args: [owner]
480
+ });
481
+ for (let i = 0; i < Number(balance); i++) {
482
+ const tokenId = await client.readContract({
483
+ address: addresses.nonfungiblePositionManager,
484
+ abi: UNISWAP_V3_POSITION_MANAGER_ABI,
485
+ functionName: "tokenOfOwnerByIndex",
486
+ args: [owner, BigInt(i)]
487
+ });
488
+ const position = await this.getPositionFromContract(chainId, tokenId);
489
+ if (position && position.liquidity > 0n) {
490
+ const poolAddress = await client.readContract({
491
+ address: addresses.factory,
492
+ abi: UNISWAP_V3_FACTORY_ABI,
493
+ functionName: "getPool",
494
+ args: [
495
+ position.token0,
496
+ position.token1,
497
+ position.fee
498
+ ]
499
+ });
500
+ if (poolAddress) {
501
+ const details = await this.getPositionDetails(chainId, owner, poolAddress, tokenId);
502
+ if (details) positions.push(details);
503
+ }
504
+ }
505
+ }
506
+ } catch (error) {
507
+ logger.error("[UniswapV3LpService] Error fetching all positions:", error instanceof Error ? error.message : String(error));
508
+ }
509
+ return positions;
510
+ }
511
+ async getMarketData(poolAddresses) {
512
+ const result = {};
513
+ for (const address of poolAddresses) for (const chainId of this.getSupportedChainIds()) try {
514
+ const poolInfo = await this.getPoolInfo(chainId, address);
515
+ if (poolInfo) {
516
+ result[address] = poolInfo;
517
+ break;
518
+ }
519
+ } catch {}
520
+ return result;
521
+ }
522
+ async approveToken(chainId, privateKey, tokenAddress, spenderAddress, amount) {
523
+ const publicClient = this.getPublicClient(chainId);
524
+ const walletClient = this.getWalletClient(chainId, privateKey);
525
+ if (await publicClient.readContract({
526
+ address: tokenAddress,
527
+ abi: ERC20_ABI,
528
+ functionName: "allowance",
529
+ args: [walletClient.account?.address, spenderAddress]
530
+ }) >= amount) return;
531
+ logger.info(`[UniswapV3LpService] Approving ${tokenAddress} for ${spenderAddress}`);
532
+ const { request } = await publicClient.simulateContract({
533
+ address: tokenAddress,
534
+ abi: ERC20_ABI,
535
+ functionName: "approve",
536
+ args: [spenderAddress, amount],
537
+ account: walletClient.account
538
+ });
539
+ const hash = await walletClient.writeContract(request);
540
+ await publicClient.waitForTransactionReceipt({ hash });
541
+ logger.info(`[UniswapV3LpService] Token approved: ${hash}`);
542
+ }
543
+ };
544
+ //#endregion
545
+ //#region src/chains/evm/dex/uniswap/index.ts
546
+ var uniswap_exports = /* @__PURE__ */ __exportAll({
547
+ ERC20_ABI: () => ERC20_ABI,
548
+ UNISWAP_V3_ADDRESSES: () => UNISWAP_V3_ADDRESSES,
549
+ UNISWAP_V3_FACTORY_ABI: () => UNISWAP_V3_FACTORY_ABI,
550
+ UNISWAP_V3_FEE_TIERS: () => UNISWAP_V3_FEE_TIERS,
551
+ UNISWAP_V3_POOL_ABI: () => UNISWAP_V3_POOL_ABI,
552
+ UNISWAP_V3_POSITION_MANAGER_ABI: () => UNISWAP_V3_POSITION_MANAGER_ABI,
553
+ UniswapV3LpService: () => UniswapV3LpService,
554
+ default: () => uniswapPlugin,
555
+ uniswapPlugin: () => uniswapPlugin
556
+ });
557
+ const uniswapPlugin = {
558
+ name: "@elizaos/plugin-lp-manager/uniswap",
559
+ description: "Uniswap V3 liquidity pool management plugin",
560
+ services: [UniswapV3LpService],
561
+ actions: [],
562
+ providers: [],
563
+ init: async (_config, runtime) => {
564
+ console.info("Uniswap V3 Plugin initialized");
565
+ await registerLpProtocolProvider(runtime, createEvmLpProtocolProvider({
566
+ dex: "uniswap",
567
+ label: "Uniswap V3",
568
+ service: runtime.getService(UniswapV3LpService.serviceType) ?? await UniswapV3LpService.start(runtime)
569
+ }));
570
+ }
571
+ };
572
+ //#endregion
573
+ export { uniswap_exports as n, UniswapV3LpService as r, uniswapPlugin as t };
@@ -0,0 +1,6 @@
1
+ import { Action } from "@elizaos/core";
2
+
3
+ //#region src/chains/wallet-action.d.ts
4
+ declare const walletRouterAction: Action;
5
+ //#endregion
6
+ export { walletRouterAction as default, walletRouterAction };