@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,470 @@
1
+ // @ts-nocheck — legacy code from absorbed plugins (lp-manager, lpinfo, dexscreener, defi-news, birdeye); strict types pending cleanup
2
+ import { strict as assert } from "node:assert";
3
+ import type { IAgentRuntime, TestSuite } from "@elizaos/core";
4
+ import { sendMessageAndWaitForResponse, setupScenario } from "./test-utils.ts";
5
+
6
+ // Mock services are registered in setupScenario; this stub is called for backward compatibility.
7
+ async function setupMockLpData(_runtime: IAgentRuntime) {}
8
+
9
+ /**
10
+ * Defines a suite of E2E tests for LP Manager plugin real-world Discord/Telegram scenarios.
11
+ *
12
+ * These scenarios simulate authentic user interactions with the LP management agent,
13
+ * covering the complete user journey from onboarding to advanced yield optimization.
14
+ */
15
+ export const lpManagerScenariosSuite: TestSuite = {
16
+ name: "LP Manager Plugin Real-World Scenarios",
17
+ tests: [
18
+ {
19
+ name: "Scenario 1: New User Onboarding - First Time LP Experience",
20
+ fn: async (runtime: IAgentRuntime) => {
21
+ await setupMockLpData(runtime);
22
+ const { user, room } = await setupScenario(runtime);
23
+
24
+ // Simulate natural Discord message from crypto newcomer
25
+ const response = await sendMessageAndWaitForResponse(
26
+ runtime,
27
+ room,
28
+ user,
29
+ "Hey! I keep hearing about providing liquidity to earn yield. Can you help me get started? I have some SOL and USDC sitting around doing nothing.",
30
+ );
31
+
32
+ console.log("Agent Response for New User Onboarding:", response.text);
33
+
34
+ assert(
35
+ typeof response.text === "string" && response.text.length > 0,
36
+ "Agent response should have a non-empty text property.",
37
+ );
38
+
39
+ // Should explain LP management and mention onboarding
40
+ assert.match(
41
+ response.text,
42
+ /liquidity|yield|onboard|vault|start|LP|provide/i,
43
+ `Expected response to acknowledge LP onboarding context, but got: "${response.text}"`,
44
+ );
45
+ },
46
+ },
47
+
48
+ {
49
+ name: "Scenario 2: User Vault Creation and Setup",
50
+ fn: async (runtime: IAgentRuntime) => {
51
+ await setupMockLpData(runtime);
52
+ const { user, room } = await setupScenario(runtime);
53
+
54
+ // User decides to proceed with onboarding
55
+ const response = await sendMessageAndWaitForResponse(
56
+ runtime,
57
+ room,
58
+ user,
59
+ "Yes, I want to start LP management. Set me up with a vault please!",
60
+ );
61
+
62
+ console.log("Agent Response for Vault Creation:", response.text);
63
+
64
+ assert(
65
+ typeof response.text === "string" && response.text.length > 0,
66
+ "Agent response should have a non-empty text property.",
67
+ );
68
+
69
+ // Should mention vault creation, public key, and auto-rebalance settings
70
+ assert.match(
71
+ response.text,
72
+ /vault|public key|onboard|auto.*rebalance|enabled|disabled/i,
73
+ `Expected response to acknowledge vault creation, but got: "${response.text}"`,
74
+ );
75
+ },
76
+ },
77
+
78
+ {
79
+ name: "Scenario 3: Simple LP Deposit - 'LP all my SOL and USDC'",
80
+ fn: async (runtime: IAgentRuntime) => {
81
+ await setupMockLpData(runtime);
82
+ const { user, room } = await setupScenario(runtime);
83
+
84
+ // User wants to deposit all their tokens
85
+ const response = await sendMessageAndWaitForResponse(
86
+ runtime,
87
+ room,
88
+ user,
89
+ "I want to LP all my SOL and USDC. Find me the best pool with good APR!",
90
+ );
91
+
92
+ console.log("Agent Response for LP All Tokens:", response.text);
93
+
94
+ assert(
95
+ typeof response.text === "string" && response.text.length > 0,
96
+ "Agent response should have a non-empty text property.",
97
+ );
98
+
99
+ // Should reference pools, APR, and LP deposit process
100
+ assert.match(
101
+ response.text,
102
+ /pool|APR|deposit|liquidity|SOL|USDC|yield|best/i,
103
+ `Expected response to acknowledge LP deposit request, but got: "${response.text}"`,
104
+ );
105
+ },
106
+ },
107
+
108
+ {
109
+ name: "Scenario 4: Specific Amount LP Deposit - 'LP 10 USDC'",
110
+ fn: async (runtime: IAgentRuntime) => {
111
+ await setupMockLpData(runtime);
112
+ const { user, room } = await setupScenario(runtime);
113
+
114
+ // User wants to deposit specific amount
115
+ const response = await sendMessageAndWaitForResponse(
116
+ runtime,
117
+ room,
118
+ user,
119
+ "Just LP 10 USDC for now. What SOL amount do I need to pair with it?",
120
+ );
121
+
122
+ console.log("Agent Response for Specific Amount LP:", response.text);
123
+
124
+ assert(
125
+ typeof response.text === "string" && response.text.length > 0,
126
+ "Agent response should have a non-empty text property.",
127
+ );
128
+
129
+ // Should calculate pairing amounts and explain ratio
130
+ assert.match(
131
+ response.text,
132
+ /10|USDC|SOL|pair|ratio|pool|amount|deposit/i,
133
+ `Expected response to acknowledge specific amount LP request, but got: "${response.text}"`,
134
+ );
135
+ },
136
+ },
137
+
138
+ {
139
+ name: "Scenario 5: Percentage-Based LP Deposit - 'LP 50% of my holdings'",
140
+ fn: async (runtime: IAgentRuntime) => {
141
+ await setupMockLpData(runtime);
142
+ const { user, room } = await setupScenario(runtime);
143
+
144
+ // User wants percentage-based deposit
145
+ const response = await sendMessageAndWaitForResponse(
146
+ runtime,
147
+ room,
148
+ user,
149
+ "I want to LP 50% of my SOL bag. Keep the rest for emergencies.",
150
+ );
151
+
152
+ console.log("Agent Response for Percentage LP:", response.text);
153
+
154
+ assert(
155
+ typeof response.text === "string" && response.text.length > 0,
156
+ "Agent response should have a non-empty text property.",
157
+ );
158
+
159
+ // Should calculate percentage and mention pool selection
160
+ assert.match(
161
+ response.text,
162
+ /50%|SOL|percentage|deposit|pool|liquidity|amount/i,
163
+ `Expected response to acknowledge percentage LP request, but got: "${response.text}"`,
164
+ );
165
+ },
166
+ },
167
+
168
+ {
169
+ name: "Scenario 6: Check LP Positions - 'Show me my LP positions'",
170
+ fn: async (runtime: IAgentRuntime) => {
171
+ await setupMockLpData(runtime);
172
+ const { user, room } = await setupScenario(runtime);
173
+
174
+ // User wants to see their current positions
175
+ const response = await sendMessageAndWaitForResponse(
176
+ runtime,
177
+ room,
178
+ user,
179
+ "Show me all my LP positions. How am I doing? What's my current yield?",
180
+ );
181
+
182
+ console.log("Agent Response for LP Position Check:", response.text);
183
+
184
+ assert(
185
+ typeof response.text === "string" && response.text.length > 0,
186
+ "Agent response should have a non-empty text property.",
187
+ );
188
+
189
+ // Should display positions with details
190
+ assert.match(
191
+ response.text,
192
+ /position|LP|value|yield|underlying|SOL|USDC|pool/i,
193
+ `Expected response to show LP positions, but got: "${response.text}"`,
194
+ );
195
+ },
196
+ },
197
+
198
+ {
199
+ name: "Scenario 7: Yield Optimization Discovery - Auto-rebalance Alert",
200
+ fn: async (runtime: IAgentRuntime) => {
201
+ await setupMockLpData(runtime);
202
+ const { user, room } = await setupScenario(runtime);
203
+
204
+ // Agent proactively suggests rebalancing
205
+ const response = await sendMessageAndWaitForResponse(
206
+ runtime,
207
+ room,
208
+ user,
209
+ "I heard there are higher yield opportunities. Can you check if I should move my LP to a better pool?",
210
+ );
211
+
212
+ console.log("Agent Response for Yield Optimization:", response.text);
213
+
214
+ assert(
215
+ typeof response.text === "string" && response.text.length > 0,
216
+ "Agent response should have a non-empty text property.",
217
+ );
218
+
219
+ // Should mention yield comparison and rebalancing opportunities
220
+ assert.match(
221
+ response.text,
222
+ /yield|APR|opportunity|rebalance|pool|higher|optimize|move/i,
223
+ `Expected response to acknowledge yield optimization request, but got: "${response.text}"`,
224
+ );
225
+ },
226
+ },
227
+
228
+ {
229
+ name: "Scenario 8: Auto-Rebalance Configuration - Risk Preferences",
230
+ fn: async (runtime: IAgentRuntime) => {
231
+ await setupMockLpData(runtime);
232
+ const { user, room } = await setupScenario(runtime);
233
+
234
+ // User wants to configure auto-rebalancing
235
+ const response = await sendMessageAndWaitForResponse(
236
+ runtime,
237
+ room,
238
+ user,
239
+ "I want to enable auto-rebalancing but only if the gain is at least 5%. Also, keep slippage under 1%. Can you set that up?",
240
+ );
241
+
242
+ console.log("Agent Response for Auto-Rebalance Setup:", response.text);
243
+
244
+ assert(
245
+ typeof response.text === "string" && response.text.length > 0,
246
+ "Agent response should have a non-empty text property.",
247
+ );
248
+
249
+ // Should acknowledge configuration settings
250
+ assert.match(
251
+ response.text,
252
+ /auto.*rebalance|5%|gain|slippage|1%|enable|configure|preference/i,
253
+ `Expected response to acknowledge auto-rebalance configuration, but got: "${response.text}"`,
254
+ );
255
+ },
256
+ },
257
+
258
+ {
259
+ name: "Scenario 9: Partial LP Withdrawal - 'Take profits'",
260
+ fn: async (runtime: IAgentRuntime) => {
261
+ await setupMockLpData(runtime);
262
+ const { user, room } = await setupScenario(runtime);
263
+
264
+ // User wants to take partial profits
265
+ const response = await sendMessageAndWaitForResponse(
266
+ runtime,
267
+ room,
268
+ user,
269
+ "SOL is pumping! I want to withdraw 30% of my LP position to take some profits.",
270
+ );
271
+
272
+ console.log("Agent Response for Partial Withdrawal:", response.text);
273
+
274
+ assert(
275
+ typeof response.text === "string" && response.text.length > 0,
276
+ "Agent response should have a non-empty text property.",
277
+ );
278
+
279
+ // Should handle percentage withdrawal
280
+ assert.match(
281
+ response.text,
282
+ /withdraw|30%|profit|LP|position|SOL|partial|remove/i,
283
+ `Expected response to acknowledge partial withdrawal request, but got: "${response.text}"`,
284
+ );
285
+ },
286
+ },
287
+
288
+ {
289
+ name: "Scenario 10: Emergency Full Withdrawal - 'Exit all positions'",
290
+ fn: async (runtime: IAgentRuntime) => {
291
+ await setupMockLpData(runtime);
292
+ const { user, room } = await setupScenario(runtime);
293
+
294
+ // User needs emergency withdrawal
295
+ const response = await sendMessageAndWaitForResponse(
296
+ runtime,
297
+ room,
298
+ user,
299
+ "Market is crashing! I need to exit all my LP positions immediately and get back to stablecoins.",
300
+ );
301
+
302
+ console.log("Agent Response for Emergency Withdrawal:", response.text);
303
+
304
+ assert(
305
+ typeof response.text === "string" && response.text.length > 0,
306
+ "Agent response should have a non-empty text property.",
307
+ );
308
+
309
+ // Should handle emergency exit scenario
310
+ assert.match(
311
+ response.text,
312
+ /exit|withdraw|all|position|emergency|market|crash|stable/i,
313
+ `Expected response to acknowledge emergency withdrawal, but got: "${response.text}"`,
314
+ );
315
+ },
316
+ },
317
+
318
+ {
319
+ name: "Scenario 11: Advanced Strategy - Stablecoin Focus",
320
+ fn: async (runtime: IAgentRuntime) => {
321
+ await setupMockLpData(runtime);
322
+ const { user, room } = await setupScenario(runtime);
323
+
324
+ // User wants conservative strategy
325
+ const response = await sendMessageAndWaitForResponse(
326
+ runtime,
327
+ room,
328
+ user,
329
+ "I'm risk-averse. Only show me stable pools like USDC/USDT. I want steady yield without impermanent loss risk.",
330
+ );
331
+
332
+ console.log("Agent Response for Stablecoin Strategy:", response.text);
333
+
334
+ assert(
335
+ typeof response.text === "string" && response.text.length > 0,
336
+ "Agent response should have a non-empty text property.",
337
+ );
338
+
339
+ // Should focus on stable pairs and low risk
340
+ assert.match(
341
+ response.text,
342
+ /stable|USDC|USDT|risk|impermanent.*loss|steady|yield|conservative/i,
343
+ `Expected response to acknowledge stablecoin strategy, but got: "${response.text}"`,
344
+ );
345
+ },
346
+ },
347
+
348
+ {
349
+ name: "Scenario 12: Pool Comparison and Analysis",
350
+ fn: async (runtime: IAgentRuntime) => {
351
+ await setupMockLpData(runtime);
352
+ const { user, room } = await setupScenario(runtime);
353
+
354
+ // User wants detailed pool analysis
355
+ const response = await sendMessageAndWaitForResponse(
356
+ runtime,
357
+ room,
358
+ user,
359
+ "Compare all the SOL/USDC pools for me. Show APRs, TVL, fees, and which DEX is best right now.",
360
+ );
361
+
362
+ console.log("Agent Response for Pool Comparison:", response.text);
363
+
364
+ assert(
365
+ typeof response.text === "string" && response.text.length > 0,
366
+ "Agent response should have a non-empty text property.",
367
+ );
368
+
369
+ // Should provide detailed comparison
370
+ assert.match(
371
+ response.text,
372
+ /compare|SOL.*USDC|APR|TVL|fee|DEX|pool|best|analysis/i,
373
+ `Expected response to provide pool comparison, but got: "${response.text}"`,
374
+ );
375
+ },
376
+ },
377
+
378
+ {
379
+ name: "Scenario 13: Transaction Cost Analysis - 'Is it worth rebalancing?'",
380
+ fn: async (runtime: IAgentRuntime) => {
381
+ await setupMockLpData(runtime);
382
+ const { user, room } = await setupScenario(runtime);
383
+
384
+ // User wants cost-benefit analysis
385
+ const response = await sendMessageAndWaitForResponse(
386
+ runtime,
387
+ room,
388
+ user,
389
+ "I see a pool with 2% higher APR. Is it worth paying the gas fees to move my position? Calculate the break-even point.",
390
+ );
391
+
392
+ console.log("Agent Response for Cost Analysis:", response.text);
393
+
394
+ assert(
395
+ typeof response.text === "string" && response.text.length > 0,
396
+ "Agent response should have a non-empty text property.",
397
+ );
398
+
399
+ // Should analyze costs vs benefits
400
+ assert.match(
401
+ response.text,
402
+ /2%|higher|APR|gas|fee|cost|break.*even|worth|calculate|rebalance/i,
403
+ `Expected response to analyze rebalancing costs, but got: "${response.text}"`,
404
+ );
405
+ },
406
+ },
407
+
408
+ {
409
+ name: "Scenario 14: Portfolio Diversification Strategy",
410
+ fn: async (runtime: IAgentRuntime) => {
411
+ await setupMockLpData(runtime);
412
+ const { user, room } = await setupScenario(runtime);
413
+
414
+ // User wants diversified approach
415
+ const response = await sendMessageAndWaitForResponse(
416
+ runtime,
417
+ room,
418
+ user,
419
+ "I don't want all my eggs in one basket. Split my liquidity across multiple pools - some stable, some growth. What do you recommend?",
420
+ );
421
+
422
+ console.log("Agent Response for Diversification:", response.text);
423
+
424
+ assert(
425
+ typeof response.text === "string" && response.text.length > 0,
426
+ "Agent response should have a non-empty text property.",
427
+ );
428
+
429
+ // Should suggest diversification strategy
430
+ assert.match(
431
+ response.text,
432
+ /diversify|split|multiple|pool|stable|growth|recommend|basket|strategy/i,
433
+ `Expected response to suggest diversification, but got: "${response.text}"`,
434
+ );
435
+ },
436
+ },
437
+
438
+ {
439
+ name: "Scenario 15: Performance Tracking and Analytics",
440
+ fn: async (runtime: IAgentRuntime) => {
441
+ await setupMockLpData(runtime);
442
+ const { user, room } = await setupScenario(runtime);
443
+
444
+ // User wants performance insights
445
+ const response = await sendMessageAndWaitForResponse(
446
+ runtime,
447
+ room,
448
+ user,
449
+ "How has my LP performance been this month? Show me total yield earned, impermanent loss, and compare to just HODLing.",
450
+ );
451
+
452
+ console.log("Agent Response for Performance Analytics:", response.text);
453
+
454
+ assert(
455
+ typeof response.text === "string" && response.text.length > 0,
456
+ "Agent response should have a non-empty text property.",
457
+ );
458
+
459
+ // Should provide performance analysis
460
+ assert.match(
461
+ response.text,
462
+ /performance|month|yield|earned|impermanent.*loss|HODL|compare|analytics/i,
463
+ `Expected response to provide performance analytics, but got: "${response.text}"`,
464
+ );
465
+ },
466
+ },
467
+ ],
468
+ };
469
+
470
+ export default lpManagerScenariosSuite;
@@ -0,0 +1,145 @@
1
+ // @ts-nocheck — legacy code from absorbed plugins (lp-manager, lpinfo, dexscreener, defi-news, birdeye); strict types pending cleanup
2
+ import { strict as assert } from "node:assert";
3
+ import {
4
+ asUUID,
5
+ ChannelType,
6
+ type Content,
7
+ createUniqueUuid,
8
+ type Entity,
9
+ EventType,
10
+ type IAgentRuntime,
11
+ type Memory,
12
+ type Room,
13
+ type World,
14
+ } from "@elizaos/core";
15
+ import { v4 as uuid } from "uuid";
16
+
17
+ /**
18
+ * Sets up a standard scenario environment for an E2E test.
19
+ *
20
+ * This function creates a world, a user, and a room, providing an
21
+ * isolated environment for each test case.
22
+ *
23
+ * @param runtime The live IAgentRuntime instance provided by the TestRunner.
24
+ * @returns A promise that resolves to an object containing the created world, user, and room.
25
+ */
26
+ export async function setupScenario(
27
+ runtime: IAgentRuntime,
28
+ ): Promise<{ user: Entity; room: Room; world: World }> {
29
+ assert(runtime.agentId, "Runtime must have an agentId to run a scenario");
30
+
31
+ // Set up mock environment for DEX plugins
32
+ process.env.RPC_URL =
33
+ process.env.RPC_URL || "https://api.mainnet-beta.solana.com";
34
+ process.env.SOLANA_PUBLIC_KEY =
35
+ process.env.SOLANA_PUBLIC_KEY || "11111111111111111111111111111111";
36
+ process.env.SOLANA_PRIVATE_KEY =
37
+ process.env.SOLANA_PRIVATE_KEY || "mockPrivateKeyForTesting";
38
+ // 1. Create a test user entity first, so we can assign ownership
39
+ const user: Entity = {
40
+ id: asUUID(uuid()),
41
+ names: ["Test User"],
42
+ agentId: runtime.agentId,
43
+ metadata: { type: "user" },
44
+ };
45
+ await runtime.createEntity(user);
46
+ assert(user.id, "Created user must have an id");
47
+
48
+ // 2. Create a World and assign the user as the owner.
49
+ // This is critical for providers that check for ownership.
50
+ const world: World = {
51
+ id: asUUID(uuid()),
52
+ agentId: runtime.agentId,
53
+ name: "E2E Test World",
54
+ serverId: "e2e-test-server",
55
+ metadata: {
56
+ ownership: {
57
+ ownerId: user.id,
58
+ },
59
+ settings: {
60
+ lp_manager: {
61
+ onboarding_enabled: true,
62
+ auto_rebalance_enabled: true,
63
+ default_slippage_bps: 50,
64
+ },
65
+ },
66
+ },
67
+ };
68
+ await runtime.ensureWorldExists(world);
69
+
70
+ // 3. Create a test room associated with the world
71
+ const room: Room = {
72
+ id: asUUID(uuid()),
73
+ name: "Test DM Room",
74
+ type: ChannelType.DM,
75
+ source: "e2e-test",
76
+ worldId: world.id,
77
+ serverId: world.serverId,
78
+ };
79
+ await runtime.createRoom(room);
80
+
81
+ // 4. Ensure both the agent and the user are participants in the room
82
+ await runtime.ensureParticipantInRoom(runtime.agentId, room.id);
83
+ await runtime.ensureParticipantInRoom(user.id, room.id);
84
+
85
+ // Register mock services for testing
86
+ // The real DEX plugins are not properly registering their services currently
87
+ const { registerMockDexServices } = await import(
88
+ "../services/__tests__/MockLpService.ts"
89
+ );
90
+ await registerMockDexServices(runtime);
91
+
92
+ // Wait for services to be registered
93
+ await new Promise((resolve) => setTimeout(resolve, 500));
94
+
95
+ return { user, room, world };
96
+ }
97
+
98
+ /**
99
+ * Simulates a user sending a message and waits for the agent's response.
100
+ *
101
+ * This function abstracts the event-driven nature of the message handler
102
+ * into a simple async function, making tests easier to write and read.
103
+ *
104
+ * @param runtime The live IAgentRuntime instance.
105
+ * @param room The room where the message is sent.
106
+ * @param user The user entity sending the message.
107
+ * @param text The content of the message.
108
+ * @returns A promise that resolves with the agent's response content.
109
+ */
110
+ export function sendMessageAndWaitForResponse(
111
+ runtime: IAgentRuntime,
112
+ room: Room,
113
+ user: Entity,
114
+ text: string,
115
+ ): Promise<Content> {
116
+ return new Promise((resolve) => {
117
+ assert(runtime.agentId, "Runtime must have an agentId to send a message");
118
+ assert(user.id, "User must have an id to send a message");
119
+
120
+ // Construct the message object, simulating an incoming message from a user
121
+ const message: Memory = {
122
+ id: createUniqueUuid(runtime, `${user.id}-${Date.now()}`),
123
+ agentId: runtime.agentId,
124
+ entityId: user.id,
125
+ roomId: room.id,
126
+ content: {
127
+ text,
128
+ },
129
+ createdAt: Date.now(),
130
+ };
131
+
132
+ // The callback function that the message handler will invoke with the agent's final response.
133
+ // We use this callback to resolve our promise.
134
+ const callback = (responseContent: Content) => {
135
+ resolve(responseContent);
136
+ };
137
+
138
+ // Emit the event to trigger the agent's message processing logic.
139
+ runtime.emitEvent(EventType.MESSAGE_RECEIVED, {
140
+ runtime,
141
+ message,
142
+ callback,
143
+ });
144
+ });
145
+ }