@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.
- package/LICENSE +21 -0
- package/README.md +64 -0
- package/auto-enable.ts +76 -0
- package/dist/LpManagementService-BWrQ5-cO.mjs +353 -0
- package/dist/MockLpService-D_Apn4Fd.mjs +99 -0
- package/dist/aerodrome-CfnESC32.mjs +890 -0
- package/dist/chunk-hT5z_Zn9.mjs +35 -0
- package/dist/index.d.mts +34727 -0
- package/dist/index.mjs +21590 -0
- package/dist/lib/server-wallet-trade.d.mts +34 -0
- package/dist/lib/server-wallet-trade.mjs +306 -0
- package/dist/meteora-BPX39hZo.mjs +22640 -0
- package/dist/orca-Bybp1HXO.mjs +249 -0
- package/dist/pancakeswp-CkEXlXti.mjs +604 -0
- package/dist/plugin-ZO_MTyd0.mjs +529 -0
- package/dist/raydium-rfaM9yEf.mjs +539 -0
- package/dist/sdk/index.d.mts +32492 -0
- package/dist/sdk/index.mjs +6415 -0
- package/dist/types-D5252NZk.mjs +487 -0
- package/dist/uniswap-CReXgXVN.mjs +573 -0
- package/dist/wallet-action.d.mts +6 -0
- package/dist/wallet-action.mjs +820 -0
- package/package.json +152 -0
- package/src/actions/failure-codes.ts +79 -0
- package/src/actions/index.ts +1 -0
- package/src/analytics/birdeye/actions/wallet-search-address.ts +9 -0
- package/src/analytics/birdeye/birdeye-task.ts +175 -0
- package/src/analytics/birdeye/birdeye.ts +813 -0
- package/src/analytics/birdeye/constants.ts +74 -0
- package/src/analytics/birdeye/providers/agent-portfolio-provider.ts +18 -0
- package/src/analytics/birdeye/providers/market.ts +227 -0
- package/src/analytics/birdeye/providers/portfolio-factory.test.ts +138 -0
- package/src/analytics/birdeye/providers/portfolio-factory.ts +252 -0
- package/src/analytics/birdeye/providers/trending.ts +365 -0
- package/src/analytics/birdeye/providers/wallet.ts +14 -0
- package/src/analytics/birdeye/search-category.test.ts +207 -0
- package/src/analytics/birdeye/search-category.ts +506 -0
- package/src/analytics/birdeye/service.ts +992 -0
- package/src/analytics/birdeye/tasks/birdeye.ts +232 -0
- package/src/analytics/birdeye/types/api/common.ts +305 -0
- package/src/analytics/birdeye/types/api/defi.ts +220 -0
- package/src/analytics/birdeye/types/api/pair.ts +200 -0
- package/src/analytics/birdeye/types/api/search.ts +86 -0
- package/src/analytics/birdeye/types/api/token.ts +635 -0
- package/src/analytics/birdeye/types/api/trader.ts +76 -0
- package/src/analytics/birdeye/types/api/wallet.ts +181 -0
- package/src/analytics/birdeye/types/shared.ts +106 -0
- package/src/analytics/birdeye/utils.ts +700 -0
- package/src/analytics/dexscreener/errors.ts +28 -0
- package/src/analytics/dexscreener/index.ts +3 -0
- package/src/analytics/dexscreener/search-category.test.ts +49 -0
- package/src/analytics/dexscreener/search-category.ts +42 -0
- package/src/analytics/dexscreener/service.ts +595 -0
- package/src/analytics/dexscreener/types.ts +128 -0
- package/src/analytics/lpinfo/index.d.ts +7 -0
- package/src/analytics/lpinfo/index.ts +52 -0
- package/src/analytics/lpinfo/kamino/README.md +102 -0
- package/src/analytics/lpinfo/kamino/index.ts +24 -0
- package/src/analytics/lpinfo/kamino/providers/kaminoLiquidityProvider.ts +422 -0
- package/src/analytics/lpinfo/kamino/providers/kaminoPoolProvider.ts +365 -0
- package/src/analytics/lpinfo/kamino/providers/kaminoProvider.ts +496 -0
- package/src/analytics/lpinfo/kamino/services/kaminoLiquidityService.ts +1123 -0
- package/src/analytics/lpinfo/kamino/services/kaminoService.ts +758 -0
- package/src/analytics/lpinfo/steer/README.md +169 -0
- package/src/analytics/lpinfo/steer/index.ts +23 -0
- package/src/analytics/lpinfo/steer/providers/steerLiquidityProvider.ts +544 -0
- package/src/analytics/lpinfo/steer/services/steerLiquidityService.ts +1690 -0
- package/src/analytics/lpinfo/steer/steer-display-types.ts +99 -0
- package/src/analytics/news/index.ts +52 -0
- package/src/analytics/news/interfaces/types.ts +222 -0
- package/src/analytics/news/providers/defiNewsProvider.ts +734 -0
- package/src/analytics/news/services/newsDataService.ts +332 -0
- package/src/analytics/news/utils/formatters.ts +151 -0
- package/src/analytics/token-info/action.ts +240 -0
- package/src/analytics/token-info/index.ts +3 -0
- package/src/analytics/token-info/params.ts +215 -0
- package/src/analytics/token-info/providers.ts +681 -0
- package/src/analytics/token-info/service.ts +168 -0
- package/src/analytics/token-info/types.ts +74 -0
- package/src/audit/audit-log.ts +45 -0
- package/src/browser-shim/build-shim.ts +123 -0
- package/src/browser-shim/index.ts +5 -0
- package/src/browser-shim/shim.template.js +563 -0
- package/src/chains/evm/.github/workflows/npm-deploy.yml +112 -0
- package/src/chains/evm/LICENSE +21 -0
- package/src/chains/evm/README.md +106 -0
- package/src/chains/evm/actions/helpers.ts +147 -0
- package/src/chains/evm/actions/swap.ts +839 -0
- package/src/chains/evm/actions/transfer.ts +254 -0
- package/src/chains/evm/biome.json +61 -0
- package/src/chains/evm/bridge-router.ts +660 -0
- package/src/chains/evm/build.ts +89 -0
- package/src/chains/evm/chain-handler.ts +416 -0
- package/src/chains/evm/constants.ts +23 -0
- package/src/chains/evm/contracts/artifacts/OZGovernor.json +1707 -0
- package/src/chains/evm/contracts/artifacts/TimelockController.json +1007 -0
- package/src/chains/evm/contracts/artifacts/VoteToken.json +895 -0
- package/src/chains/evm/dex/aerodrome/index.ts +34 -0
- package/src/chains/evm/dex/aerodrome/services/AerodromeLpService.ts +558 -0
- package/src/chains/evm/dex/aerodrome/types.ts +318 -0
- package/src/chains/evm/dex/pancakeswp/index.ts +35 -0
- package/src/chains/evm/dex/pancakeswp/services/PancakeSwapV3LpService.ts +743 -0
- package/src/chains/evm/dex/pancakeswp/types.ts +65 -0
- package/src/chains/evm/dex/uniswap/index.ts +35 -0
- package/src/chains/evm/dex/uniswap/services/UniswapV3LpService.ts +759 -0
- package/src/chains/evm/dex/uniswap/types.ts +390 -0
- package/src/chains/evm/generated/specs/spec-helpers.ts +73 -0
- package/src/chains/evm/generated/specs/specs.ts +151 -0
- package/src/chains/evm/gov-router.ts +250 -0
- package/src/chains/evm/index.browser.ts +16 -0
- package/src/chains/evm/index.ts +31 -0
- package/src/chains/evm/prompts.ts +193 -0
- package/src/chains/evm/providers/get-balance.ts +123 -0
- package/src/chains/evm/providers/wallet.ts +715 -0
- package/src/chains/evm/routes/sign.ts +333 -0
- package/src/chains/evm/rpc-providers.ts +410 -0
- package/src/chains/evm/service.ts +140 -0
- package/src/chains/evm/templates/index.ts +10 -0
- package/src/chains/evm/types/index.ts +432 -0
- package/src/chains/evm/vitest.config.ts +18 -0
- package/src/chains/registry.ts +668 -0
- package/src/chains/solana/README.md +367 -0
- package/src/chains/wallet-action.ts +533 -0
- package/src/chains/wallet-router.test.ts +296 -0
- package/src/contracts.ts +65 -0
- package/src/core-augmentation.ts +10 -0
- package/src/index.ts +71 -0
- package/src/lib/server-wallet-trade.ts +192 -0
- package/src/lib/wallet-export-guard.ts +330 -0
- package/src/lp/actions/liquidity.ts +827 -0
- package/src/lp/e2e/real-token-tests.ts +428 -0
- package/src/lp/e2e/scenarios.ts +470 -0
- package/src/lp/e2e/test-utils.ts +145 -0
- package/src/lp/lp-manager-entry.ts +303 -0
- package/src/lp/services/ConcentratedLiquidityService.ts +120 -0
- package/src/lp/services/DexInteractionService.ts +226 -0
- package/src/lp/services/LpManagementService.test.ts +148 -0
- package/src/lp/services/LpManagementService.ts +632 -0
- package/src/lp/services/UserLpProfileService.ts +163 -0
- package/src/lp/services/VaultService.ts +153 -0
- package/src/lp/services/YieldOptimizationService.ts +344 -0
- package/src/lp/services/__tests__/MockLpService.ts +146 -0
- package/src/lp/tasks/LpAutoRebalanceTask.ts +117 -0
- package/src/lp/tasks/__tests__/LpAutoRebalanceTask.test.ts +370 -0
- package/src/lp/types.ts +582 -0
- package/src/lp/utils/solanaClient.ts +143 -0
- package/src/plugin.ts +125 -0
- package/src/policy/policy.ts +19 -0
- package/src/providers/canonical-provider.ts +27 -0
- package/src/providers/unified-wallet-provider.ts +79 -0
- package/src/register-routes.ts +11 -0
- package/src/routes/plugin.ts +47 -0
- package/src/routes/wallet-market-overview-route.ts +869 -0
- package/src/sdk/abi.ts +258 -0
- package/src/sdk/bridge/abis.ts +126 -0
- package/src/sdk/bridge/client.ts +518 -0
- package/src/sdk/bridge/index.ts +56 -0
- package/src/sdk/bridge/solana.ts +604 -0
- package/src/sdk/bridge/types.ts +202 -0
- package/src/sdk/convenience.ts +347 -0
- package/src/sdk/escrow/MutualStakeEscrow.ts +480 -0
- package/src/sdk/escrow/types.ts +64 -0
- package/src/sdk/escrow/verifiers.ts +73 -0
- package/src/sdk/identity/erc8004.ts +692 -0
- package/src/sdk/identity/reputation.ts +449 -0
- package/src/sdk/identity/uaid.ts +497 -0
- package/src/sdk/identity/validation.ts +372 -0
- package/src/sdk/index.ts +763 -0
- package/src/sdk/policy/SpendingPolicy.ts +260 -0
- package/src/sdk/policy/UptoBillingPolicy.ts +320 -0
- package/src/sdk/router/PaymentRouter.ts +215 -0
- package/src/sdk/router/index.ts +8 -0
- package/src/sdk/swap/SwapModule.ts +310 -0
- package/src/sdk/swap/abi.ts +117 -0
- package/src/sdk/swap/index.ts +34 -0
- package/src/sdk/swap/types.ts +135 -0
- package/src/sdk/tokens/decimals.ts +140 -0
- package/src/sdk/tokens/registry.ts +911 -0
- package/src/sdk/tokens/solana.ts +419 -0
- package/src/sdk/tokens/transfers.ts +327 -0
- package/src/sdk/types.ts +158 -0
- package/src/sdk/wallet-core.ts +115 -0
- package/src/sdk/x402/budget.ts +168 -0
- package/src/sdk/x402/chains/abstract/index.ts +280 -0
- package/src/sdk/x402/client.ts +320 -0
- package/src/sdk/x402/index.ts +46 -0
- package/src/sdk/x402/middleware.ts +92 -0
- package/src/sdk/x402/multi-asset.ts +144 -0
- package/src/sdk/x402/types.ts +156 -0
- package/src/services/wallet-backend-service.ts +328 -0
- package/src/types/wallet-router.ts +227 -0
- package/src/utils/intent-trajectory.ts +106 -0
- package/src/wallet/backend.ts +62 -0
- package/src/wallet/errors.ts +49 -0
- package/src/wallet/index.ts +27 -0
- package/src/wallet/local-eoa-backend.ts +201 -0
- package/src/wallet/pending.ts +60 -0
- package/src/wallet/select-backend.ts +47 -0
- package/src/wallet/steward-backend.ts +161 -0
- package/src/wallet-action.ts +1 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
// @ts-nocheck — legacy code from absorbed plugins (lp-manager, lpinfo, dexscreener, defi-news, birdeye); strict types pending cleanup
|
|
2
|
+
import {
|
|
3
|
+
type IAgentRuntime,
|
|
4
|
+
logger,
|
|
5
|
+
type Plugin,
|
|
6
|
+
promoteSubactionsToActions,
|
|
7
|
+
} from "@elizaos/core";
|
|
8
|
+
import { liquidityAction } from "./actions/liquidity.ts";
|
|
9
|
+
import { realTokenTestsSuite } from "./e2e/real-token-tests.ts";
|
|
10
|
+
import { lpManagerScenariosSuite } from "./e2e/scenarios.ts";
|
|
11
|
+
import { ConcentratedLiquidityService } from "./services/ConcentratedLiquidityService.ts";
|
|
12
|
+
import { DexInteractionService } from "./services/DexInteractionService.ts";
|
|
13
|
+
import { LpManagementService } from "./services/LpManagementService.ts";
|
|
14
|
+
import { UserLpProfileService } from "./services/UserLpProfileService.ts";
|
|
15
|
+
import { VaultService } from "./services/VaultService.ts";
|
|
16
|
+
import { YieldOptimizationService } from "./services/YieldOptimizationService.ts";
|
|
17
|
+
// LpAutoRebalanceTask import removed - file doesn't exist
|
|
18
|
+
import type { EvmDex, SolanaDex } from "./types.ts";
|
|
19
|
+
|
|
20
|
+
// It's good practice to define a unique name for the plugin
|
|
21
|
+
export const LP_MANAGER_PLUGIN_NAME = "@elizaos/plugin-lp-manager";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Determines which DEXes to load based on available credentials and configuration
|
|
25
|
+
*/
|
|
26
|
+
function getDexConfiguration(runtime: IAgentRuntime): {
|
|
27
|
+
solanaDexes: SolanaDex[];
|
|
28
|
+
evmDexes: EvmDex[];
|
|
29
|
+
hasSolana: boolean;
|
|
30
|
+
hasEvm: boolean;
|
|
31
|
+
} {
|
|
32
|
+
const solanaPrivateKey = runtime.getSetting("SOLANA_PRIVATE_KEY");
|
|
33
|
+
const evmPrivateKey = runtime.getSetting("EVM_PRIVATE_KEY");
|
|
34
|
+
|
|
35
|
+
// Check for chain-specific RPC URLs to determine which chains are configured
|
|
36
|
+
const hasEthereumRpc = !!(
|
|
37
|
+
runtime.getSetting("ETHEREUM_RPC_URL") ||
|
|
38
|
+
runtime.getSetting("EVM_PROVIDER_MAINNET")
|
|
39
|
+
);
|
|
40
|
+
const hasBaseRpc = !!(
|
|
41
|
+
runtime.getSetting("BASE_RPC_URL") ||
|
|
42
|
+
runtime.getSetting("EVM_PROVIDER_BASE")
|
|
43
|
+
);
|
|
44
|
+
const hasBscRpc = !!(
|
|
45
|
+
runtime.getSetting("BSC_RPC_URL") || runtime.getSetting("EVM_PROVIDER_BSC")
|
|
46
|
+
);
|
|
47
|
+
const hasArbitrumRpc = !!(
|
|
48
|
+
runtime.getSetting("ARBITRUM_RPC_URL") ||
|
|
49
|
+
runtime.getSetting("EVM_PROVIDER_ARBITRUM")
|
|
50
|
+
);
|
|
51
|
+
const hasSolanaRpc = !!runtime.getSetting("SOLANA_RPC_URL");
|
|
52
|
+
|
|
53
|
+
const hasSolanaWallet = !!(
|
|
54
|
+
solanaPrivateKey && typeof solanaPrivateKey === "string"
|
|
55
|
+
);
|
|
56
|
+
const hasEvmWallet = !!(evmPrivateKey && typeof evmPrivateKey === "string");
|
|
57
|
+
const hasSolana = hasSolanaWallet || hasSolanaRpc;
|
|
58
|
+
const hasEvm =
|
|
59
|
+
hasEvmWallet || hasEthereumRpc || hasBaseRpc || hasBscRpc || hasArbitrumRpc;
|
|
60
|
+
|
|
61
|
+
// Determine Solana DEXes to load
|
|
62
|
+
const solanaDexes: SolanaDex[] = [];
|
|
63
|
+
if (hasSolana) {
|
|
64
|
+
// Check for specific DEX preferences from config, otherwise load all
|
|
65
|
+
const preferredSolanaDexes = runtime.getSetting("LP_SOLANA_DEXES");
|
|
66
|
+
if (preferredSolanaDexes && typeof preferredSolanaDexes === "string") {
|
|
67
|
+
const dexList = preferredSolanaDexes
|
|
68
|
+
.split(",")
|
|
69
|
+
.map((d) => d.trim().toLowerCase() as SolanaDex);
|
|
70
|
+
solanaDexes.push(
|
|
71
|
+
...dexList.filter((d) => ["raydium", "orca", "meteora"].includes(d)),
|
|
72
|
+
);
|
|
73
|
+
} else {
|
|
74
|
+
// Default: load all Solana DEXes
|
|
75
|
+
solanaDexes.push("raydium", "orca", "meteora");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Determine EVM DEXes to load based on available RPCs
|
|
80
|
+
const evmDexes: EvmDex[] = [];
|
|
81
|
+
if (hasEvm) {
|
|
82
|
+
const preferredEvmDexes = runtime.getSetting("LP_EVM_DEXES");
|
|
83
|
+
if (preferredEvmDexes && typeof preferredEvmDexes === "string") {
|
|
84
|
+
const dexList = preferredEvmDexes
|
|
85
|
+
.split(",")
|
|
86
|
+
.map((d) => d.trim().toLowerCase() as EvmDex);
|
|
87
|
+
evmDexes.push(
|
|
88
|
+
...dexList.filter((d) =>
|
|
89
|
+
["uniswap", "pancakeswap", "aerodrome"].includes(d),
|
|
90
|
+
),
|
|
91
|
+
);
|
|
92
|
+
} else {
|
|
93
|
+
// Auto-detect based on configured RPCs
|
|
94
|
+
if (hasEthereumRpc || hasArbitrumRpc) {
|
|
95
|
+
evmDexes.push("uniswap");
|
|
96
|
+
}
|
|
97
|
+
if (hasBscRpc || hasArbitrumRpc) {
|
|
98
|
+
evmDexes.push("pancakeswap");
|
|
99
|
+
}
|
|
100
|
+
if (hasBaseRpc) {
|
|
101
|
+
evmDexes.push("aerodrome");
|
|
102
|
+
if (!evmDexes.includes("uniswap")) {
|
|
103
|
+
evmDexes.push("uniswap"); // Uniswap is also on Base
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return { solanaDexes, evmDexes, hasSolana, hasEvm };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Dynamically loads Solana DEX plugins
|
|
114
|
+
*/
|
|
115
|
+
async function loadSolanaDexes(
|
|
116
|
+
dexes: SolanaDex[],
|
|
117
|
+
config: Record<string, string>,
|
|
118
|
+
runtime: IAgentRuntime,
|
|
119
|
+
): Promise<void> {
|
|
120
|
+
for (const dex of dexes) {
|
|
121
|
+
try {
|
|
122
|
+
switch (dex) {
|
|
123
|
+
case "raydium": {
|
|
124
|
+
const { raydiumPlugin } = await import(
|
|
125
|
+
"../chains/solana/dex/raydium/index.ts"
|
|
126
|
+
);
|
|
127
|
+
if (raydiumPlugin.init) {
|
|
128
|
+
await raydiumPlugin.init(config, runtime);
|
|
129
|
+
}
|
|
130
|
+
logger.info(`[LP Manager] Loaded Raydium DEX`);
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
case "orca": {
|
|
134
|
+
const { orcaPlugin } = await import(
|
|
135
|
+
"../chains/solana/dex/orca/index.ts"
|
|
136
|
+
);
|
|
137
|
+
if (orcaPlugin.init) {
|
|
138
|
+
await orcaPlugin.init(config, runtime);
|
|
139
|
+
}
|
|
140
|
+
logger.info(`[LP Manager] Loaded Orca DEX`);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case "meteora": {
|
|
144
|
+
const meteoraPlugin = await import(
|
|
145
|
+
"../chains/solana/dex/meteora/index.ts"
|
|
146
|
+
);
|
|
147
|
+
if (meteoraPlugin.default?.init) {
|
|
148
|
+
await meteoraPlugin.default.init(config, runtime);
|
|
149
|
+
}
|
|
150
|
+
logger.info(`[LP Manager] Loaded Meteora DEX`);
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
} catch (error: unknown) {
|
|
155
|
+
logger.warn(
|
|
156
|
+
`[LP Manager] Failed to load ${dex} DEX:`,
|
|
157
|
+
error instanceof Error ? error.message : String(error),
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Dynamically loads EVM DEX plugins
|
|
165
|
+
*/
|
|
166
|
+
async function loadEvmDexes(
|
|
167
|
+
dexes: EvmDex[],
|
|
168
|
+
config: Record<string, string>,
|
|
169
|
+
runtime: IAgentRuntime,
|
|
170
|
+
): Promise<void> {
|
|
171
|
+
for (const dex of dexes) {
|
|
172
|
+
try {
|
|
173
|
+
switch (dex) {
|
|
174
|
+
case "uniswap": {
|
|
175
|
+
const { uniswapPlugin } = await import(
|
|
176
|
+
"../chains/evm/dex/uniswap/index.ts"
|
|
177
|
+
);
|
|
178
|
+
if (uniswapPlugin.init) {
|
|
179
|
+
await uniswapPlugin.init(config, runtime);
|
|
180
|
+
}
|
|
181
|
+
logger.info(`[LP Manager] Loaded Uniswap V3 DEX`);
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
case "pancakeswap": {
|
|
185
|
+
const { pancakeswapPlugin } = await import(
|
|
186
|
+
"../chains/evm/dex/pancakeswp/index.ts"
|
|
187
|
+
);
|
|
188
|
+
if (pancakeswapPlugin.init) {
|
|
189
|
+
await pancakeswapPlugin.init(config, runtime);
|
|
190
|
+
}
|
|
191
|
+
logger.info(`[LP Manager] Loaded PancakeSwap V3 DEX`);
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
case "aerodrome": {
|
|
195
|
+
const { aerodromePlugin } = await import(
|
|
196
|
+
"../chains/evm/dex/aerodrome/index.ts"
|
|
197
|
+
);
|
|
198
|
+
if (aerodromePlugin.init) {
|
|
199
|
+
await aerodromePlugin.init(config, runtime);
|
|
200
|
+
}
|
|
201
|
+
logger.info(`[LP Manager] Loaded Aerodrome DEX`);
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
} catch (error: unknown) {
|
|
206
|
+
logger.warn(
|
|
207
|
+
`[LP Manager] Failed to load ${dex} DEX:`,
|
|
208
|
+
error instanceof Error ? error.message : String(error),
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const lpManagerPlugin: Plugin = {
|
|
215
|
+
name: LP_MANAGER_PLUGIN_NAME,
|
|
216
|
+
description:
|
|
217
|
+
"Unified Liquidity Pool manager for Solana DEXs (Raydium, Orca, Meteora) and EVM DEXs (Uniswap, PancakeSwap, Aerodrome).",
|
|
218
|
+
actions: [...promoteSubactionsToActions(liquidityAction)],
|
|
219
|
+
services: [
|
|
220
|
+
LpManagementService,
|
|
221
|
+
VaultService,
|
|
222
|
+
UserLpProfileService,
|
|
223
|
+
DexInteractionService,
|
|
224
|
+
YieldOptimizationService,
|
|
225
|
+
ConcentratedLiquidityService,
|
|
226
|
+
],
|
|
227
|
+
tests: [lpManagerScenariosSuite, realTokenTestsSuite],
|
|
228
|
+
|
|
229
|
+
init: async (
|
|
230
|
+
config: Record<string, string>,
|
|
231
|
+
runtime: IAgentRuntime,
|
|
232
|
+
): Promise<void> => {
|
|
233
|
+
logger.info(`[LP Manager] Initializing ${LP_MANAGER_PLUGIN_NAME}...`);
|
|
234
|
+
|
|
235
|
+
// Determine which DEXes to load based on configuration
|
|
236
|
+
const { solanaDexes, evmDexes, hasSolana, hasEvm } =
|
|
237
|
+
getDexConfiguration(runtime);
|
|
238
|
+
|
|
239
|
+
logger.info(`[LP Manager] Configuration detected:`);
|
|
240
|
+
logger.info(
|
|
241
|
+
` - Solana: ${hasSolana ? "enabled" : "disabled"} (DEXes: ${solanaDexes.join(", ") || "none"})`,
|
|
242
|
+
);
|
|
243
|
+
logger.info(
|
|
244
|
+
` - EVM: ${hasEvm ? "enabled" : "disabled"} (DEXes: ${evmDexes.join(", ") || "none"})`,
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
if (!hasSolana && !hasEvm) {
|
|
248
|
+
logger.warn(
|
|
249
|
+
`[LP Manager] No LP chain configuration found. Set SOLANA_RPC_URL, an EVM RPC URL, SOLANA_PRIVATE_KEY, or EVM_PRIVATE_KEY.`,
|
|
250
|
+
);
|
|
251
|
+
logger.warn(
|
|
252
|
+
`[LP Manager] No production mock LP services will be registered.`,
|
|
253
|
+
);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Load Solana DEXes
|
|
258
|
+
if (solanaDexes.length > 0) {
|
|
259
|
+
await loadSolanaDexes(solanaDexes, config, runtime);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Load EVM DEXes
|
|
263
|
+
if (evmDexes.length > 0) {
|
|
264
|
+
await loadEvmDexes(evmDexes, config, runtime);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
logger.info(
|
|
268
|
+
`[LP Manager] Plugin ${LP_MANAGER_PLUGIN_NAME} initialized successfully.`,
|
|
269
|
+
);
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
export default lpManagerPlugin;
|
|
274
|
+
|
|
275
|
+
export {
|
|
276
|
+
AerodromeLpService,
|
|
277
|
+
aerodromePlugin,
|
|
278
|
+
} from "../chains/evm/dex/aerodrome/index.ts";
|
|
279
|
+
export {
|
|
280
|
+
PancakeSwapV3LpService,
|
|
281
|
+
pancakeswapPlugin,
|
|
282
|
+
} from "../chains/evm/dex/pancakeswp/index.ts";
|
|
283
|
+
// Export sub-plugins for direct use
|
|
284
|
+
export {
|
|
285
|
+
UniswapV3LpService,
|
|
286
|
+
uniswapPlugin,
|
|
287
|
+
} from "../chains/evm/dex/uniswap/index.ts";
|
|
288
|
+
export { orcaPlugin } from "../chains/solana/dex/orca/index.ts";
|
|
289
|
+
export { raydiumPlugin } from "../chains/solana/dex/raydium/index.ts";
|
|
290
|
+
// Export types
|
|
291
|
+
export * from "./types.ts";
|
|
292
|
+
// Export all services and utilities
|
|
293
|
+
// Back-compat alias for older imports.
|
|
294
|
+
export {
|
|
295
|
+
ConcentratedLiquidityService,
|
|
296
|
+
DexInteractionService,
|
|
297
|
+
LpManagementService,
|
|
298
|
+
liquidityAction,
|
|
299
|
+
liquidityAction as LpManagementAgentAction,
|
|
300
|
+
UserLpProfileService,
|
|
301
|
+
VaultService,
|
|
302
|
+
YieldOptimizationService,
|
|
303
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// @ts-nocheck — legacy code from absorbed plugins (lp-manager, lpinfo, dexscreener, defi-news, birdeye); strict types pending cleanup
|
|
2
|
+
import { type IAgentRuntime, Service } from "@elizaos/core";
|
|
3
|
+
import type {
|
|
4
|
+
IConcentratedLiquidityService,
|
|
5
|
+
IConcentratedPosition,
|
|
6
|
+
IRangeParams,
|
|
7
|
+
} from "../types";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* ConcentratedLiquidityService provides foundation support for concentrated liquidity positions.
|
|
11
|
+
* This is a placeholder implementation that will be expanded when DEX plugins add concentrated liquidity support.
|
|
12
|
+
*/
|
|
13
|
+
export class ConcentratedLiquidityService
|
|
14
|
+
extends Service
|
|
15
|
+
implements IConcentratedLiquidityService
|
|
16
|
+
{
|
|
17
|
+
public static readonly serviceType = "concentrated-liquidity";
|
|
18
|
+
public readonly capabilityDescription =
|
|
19
|
+
"Manages concentrated liquidity positions with range selection and automated rebalancing";
|
|
20
|
+
|
|
21
|
+
static async start(
|
|
22
|
+
runtime: IAgentRuntime,
|
|
23
|
+
): Promise<ConcentratedLiquidityService> {
|
|
24
|
+
const service = new ConcentratedLiquidityService();
|
|
25
|
+
await service.start(runtime);
|
|
26
|
+
return service;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static async stop(_runtime: IAgentRuntime): Promise<void> {
|
|
30
|
+
// No cleanup needed for static stop
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async start(_runtime: IAgentRuntime): Promise<void> {
|
|
34
|
+
// Service initialization
|
|
35
|
+
this.isInitialized = true;
|
|
36
|
+
console.info(
|
|
37
|
+
"ConcentratedLiquidityService started - awaiting DEX integration",
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async stop(): Promise<void> {
|
|
42
|
+
this.isInitialized = false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async createConcentratedPosition(
|
|
46
|
+
_userId: string,
|
|
47
|
+
_params: IRangeParams,
|
|
48
|
+
): Promise<IConcentratedPosition> {
|
|
49
|
+
// Placeholder implementation
|
|
50
|
+
throw new Error(
|
|
51
|
+
"Concentrated liquidity positions are coming soon! This feature requires DEX integration.",
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async getConcentratedPositions(
|
|
56
|
+
userId: string,
|
|
57
|
+
): Promise<IConcentratedPosition[]> {
|
|
58
|
+
// Placeholder implementation
|
|
59
|
+
console.info(`Getting concentrated positions for user ${userId}`);
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async rebalanceConcentratedPosition(
|
|
64
|
+
_userId: string,
|
|
65
|
+
_positionId: string,
|
|
66
|
+
_newRangeParams?: Partial<IRangeParams>,
|
|
67
|
+
): Promise<IConcentratedPosition> {
|
|
68
|
+
// Placeholder implementation
|
|
69
|
+
throw new Error("Concentrated position rebalancing is coming soon!");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Calculate optimal price range based on volatility and target utilization
|
|
74
|
+
*/
|
|
75
|
+
calculateOptimalRange(
|
|
76
|
+
currentPrice: number,
|
|
77
|
+
rangeWidthPercent: number,
|
|
78
|
+
_targetUtilization: number = 80,
|
|
79
|
+
): { priceLower: number; priceUpper: number } {
|
|
80
|
+
// Simple symmetric range calculation
|
|
81
|
+
const halfWidth = rangeWidthPercent / 2;
|
|
82
|
+
const priceLower = currentPrice * (1 - halfWidth / 100);
|
|
83
|
+
const priceUpper = currentPrice * (1 + halfWidth / 100);
|
|
84
|
+
|
|
85
|
+
return { priceLower, priceUpper };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Check if current price is within the position's range
|
|
90
|
+
*/
|
|
91
|
+
isPriceInRange(
|
|
92
|
+
currentPrice: number,
|
|
93
|
+
priceLower: number,
|
|
94
|
+
priceUpper: number,
|
|
95
|
+
): boolean {
|
|
96
|
+
return currentPrice >= priceLower && currentPrice <= priceUpper;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Calculate how much of the liquidity is currently active
|
|
101
|
+
*/
|
|
102
|
+
calculateUtilization(
|
|
103
|
+
currentPrice: number,
|
|
104
|
+
priceLower: number,
|
|
105
|
+
priceUpper: number,
|
|
106
|
+
): number {
|
|
107
|
+
if (!this.isPriceInRange(currentPrice, priceLower, priceUpper)) {
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const priceRange = priceUpper - priceLower;
|
|
112
|
+
const distanceFromLower = currentPrice - priceLower;
|
|
113
|
+
const distanceFromUpper = priceUpper - currentPrice;
|
|
114
|
+
|
|
115
|
+
// Liquidity utilization is highest when price is in the middle of the range
|
|
116
|
+
const utilization =
|
|
117
|
+
(Math.min(distanceFromLower, distanceFromUpper) / (priceRange / 2)) * 100;
|
|
118
|
+
return Math.min(utilization, 100);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
// @ts-nocheck — legacy code from absorbed plugins (lp-manager, lpinfo, dexscreener, defi-news, birdeye); strict types pending cleanup
|
|
2
|
+
import { type IAgentRuntime, logger, Service } from "@elizaos/core";
|
|
3
|
+
import type {
|
|
4
|
+
AddLiquidityConfig,
|
|
5
|
+
IEvmLpService,
|
|
6
|
+
ILpService,
|
|
7
|
+
IUserLpProfileService,
|
|
8
|
+
LpPositionDetails,
|
|
9
|
+
PoolInfo,
|
|
10
|
+
RemoveLiquidityConfig,
|
|
11
|
+
TransactionResult,
|
|
12
|
+
} from "../types.ts";
|
|
13
|
+
import {
|
|
14
|
+
createEvmLpProtocolProvider,
|
|
15
|
+
createSolanaLpProtocolProvider,
|
|
16
|
+
getLpManagementService,
|
|
17
|
+
type LpManagementService,
|
|
18
|
+
} from "./LpManagementService.ts";
|
|
19
|
+
import type { UserLpProfileService } from "./UserLpProfileService.ts";
|
|
20
|
+
import type { VaultService } from "./VaultService.ts";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Backward-compatible facade for older LP manager internals.
|
|
24
|
+
* New routing and protocol ownership live in LpManagementService.
|
|
25
|
+
*/
|
|
26
|
+
export interface IDexInteractionService extends Service {
|
|
27
|
+
registerDexService(dexService: ILpService | IEvmLpService): void;
|
|
28
|
+
getPools(
|
|
29
|
+
dexName?: string,
|
|
30
|
+
tokenAMint?: string,
|
|
31
|
+
tokenBMint?: string,
|
|
32
|
+
): Promise<PoolInfo[]>;
|
|
33
|
+
addLiquidity(config: AddLiquidityConfig): Promise<TransactionResult>;
|
|
34
|
+
removeLiquidity(config: RemoveLiquidityConfig): Promise<TransactionResult>;
|
|
35
|
+
getLpPosition(
|
|
36
|
+
userId: string,
|
|
37
|
+
poolIdOrPositionIdentifier: string,
|
|
38
|
+
dexName: string,
|
|
39
|
+
): Promise<LpPositionDetails | null>;
|
|
40
|
+
getAllUserLpPositions(userId: string): Promise<LpPositionDetails[]>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class DexInteractionService
|
|
44
|
+
extends Service
|
|
45
|
+
implements IDexInteractionService
|
|
46
|
+
{
|
|
47
|
+
public static override readonly serviceType = "dex-interaction";
|
|
48
|
+
public readonly capabilityDescription =
|
|
49
|
+
"Compatibility facade for registered LP protocol providers.";
|
|
50
|
+
|
|
51
|
+
private lpManagementService!: LpManagementService;
|
|
52
|
+
private userLpProfileService!: IUserLpProfileService;
|
|
53
|
+
|
|
54
|
+
static async start(runtime: IAgentRuntime): Promise<DexInteractionService> {
|
|
55
|
+
const service = new DexInteractionService(runtime);
|
|
56
|
+
await service.start(runtime);
|
|
57
|
+
return service;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static async stop(_runtime: IAgentRuntime): Promise<void> {
|
|
61
|
+
// No static cleanup needed.
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async start(runtime: IAgentRuntime): Promise<void> {
|
|
65
|
+
const vaultService = runtime.getService<VaultService>("VaultService");
|
|
66
|
+
const userLpProfileService = runtime.getService<UserLpProfileService>(
|
|
67
|
+
"UserLpProfileService",
|
|
68
|
+
);
|
|
69
|
+
const lpManagementService = await getLpManagementService(runtime);
|
|
70
|
+
|
|
71
|
+
if (!vaultService || !userLpProfileService || !lpManagementService) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
"Required services (VaultService, UserLpProfileService, LpManagementService) not available.",
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
this.userLpProfileService = userLpProfileService;
|
|
78
|
+
this.lpManagementService = lpManagementService;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async stop(): Promise<void> {
|
|
82
|
+
// No-op; protocol providers are owned by LpManagementService.
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
rediscoverServices(): void {
|
|
86
|
+
// Retained for callers that used to trigger name-based discovery.
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
registerDexService(dexService: ILpService | IEvmLpService): void {
|
|
90
|
+
const dexName = dexService.getDexName();
|
|
91
|
+
const isEvm =
|
|
92
|
+
typeof (dexService as IEvmLpService).getSupportedChainIds === "function";
|
|
93
|
+
|
|
94
|
+
this.lpManagementService.registerProtocol(
|
|
95
|
+
isEvm
|
|
96
|
+
? createEvmLpProtocolProvider({
|
|
97
|
+
dex: dexName,
|
|
98
|
+
label: dexName,
|
|
99
|
+
service: dexService as IEvmLpService,
|
|
100
|
+
})
|
|
101
|
+
: createSolanaLpProtocolProvider({
|
|
102
|
+
dex: dexName,
|
|
103
|
+
label: dexName,
|
|
104
|
+
service: dexService as ILpService,
|
|
105
|
+
}),
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
getLpService(dexName: string): ILpService | IEvmLpService | undefined {
|
|
110
|
+
return this.lpManagementService.listProtocols({ dex: dexName })[0]
|
|
111
|
+
?.service as ILpService | IEvmLpService | undefined;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
getLpServices(): Array<ILpService | IEvmLpService> {
|
|
115
|
+
return this.lpManagementService
|
|
116
|
+
.listProtocols()
|
|
117
|
+
.map((protocol) => protocol.service)
|
|
118
|
+
.filter(Boolean) as Array<ILpService | IEvmLpService>;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
getDexService(dexName: string): ILpService | IEvmLpService {
|
|
122
|
+
const service = this.getLpService(dexName);
|
|
123
|
+
if (!service) {
|
|
124
|
+
throw new Error(`No service registered for DEX '${dexName}'`);
|
|
125
|
+
}
|
|
126
|
+
return service;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async getPools(
|
|
130
|
+
dexName?: string,
|
|
131
|
+
tokenAMint?: string,
|
|
132
|
+
tokenBMint?: string,
|
|
133
|
+
): Promise<PoolInfo[]> {
|
|
134
|
+
try {
|
|
135
|
+
return await this.lpManagementService.listPools({
|
|
136
|
+
dex: dexName,
|
|
137
|
+
tokenA: tokenAMint,
|
|
138
|
+
tokenB: tokenBMint,
|
|
139
|
+
});
|
|
140
|
+
} catch (error) {
|
|
141
|
+
logger.warn(
|
|
142
|
+
"[DexInteractionService] Failed to list LP pools",
|
|
143
|
+
error instanceof Error ? error.message : String(error),
|
|
144
|
+
);
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async addLiquidity(config: AddLiquidityConfig): Promise<TransactionResult> {
|
|
150
|
+
return this.lpManagementService.openPosition({
|
|
151
|
+
chain: "solana",
|
|
152
|
+
dex: config.dexName,
|
|
153
|
+
userVault: config.userVault,
|
|
154
|
+
pool: config.poolId,
|
|
155
|
+
amount: {
|
|
156
|
+
tokenA: config.tokenAAmountLamports,
|
|
157
|
+
tokenB: config.tokenBAmountLamports,
|
|
158
|
+
},
|
|
159
|
+
range: {
|
|
160
|
+
tickLowerIndex: config.tickLowerIndex,
|
|
161
|
+
tickUpperIndex: config.tickUpperIndex,
|
|
162
|
+
},
|
|
163
|
+
slippageBps: config.slippageBps,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async removeLiquidity(
|
|
168
|
+
config: RemoveLiquidityConfig,
|
|
169
|
+
): Promise<TransactionResult> {
|
|
170
|
+
return this.lpManagementService.closePosition({
|
|
171
|
+
chain: "solana",
|
|
172
|
+
dex: config.dexName,
|
|
173
|
+
userVault: config.userVault,
|
|
174
|
+
pool: config.poolId,
|
|
175
|
+
amount: { lpToken: config.lpTokenAmountLamports },
|
|
176
|
+
slippageBps: config.slippageBps,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async getLpPosition(
|
|
181
|
+
userId: string,
|
|
182
|
+
poolIdOrPositionIdentifier: string,
|
|
183
|
+
dexName: string,
|
|
184
|
+
): Promise<LpPositionDetails | null> {
|
|
185
|
+
const profile = await this.userLpProfileService.getProfile(userId);
|
|
186
|
+
if (!profile?.vaultPublicKey) {
|
|
187
|
+
throw new Error(
|
|
188
|
+
`User profile or vault public key not found for user ${userId}.`,
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
return this.lpManagementService.getPosition({
|
|
192
|
+
dex: dexName,
|
|
193
|
+
owner: profile.vaultPublicKey,
|
|
194
|
+
pool: poolIdOrPositionIdentifier,
|
|
195
|
+
position: poolIdOrPositionIdentifier,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async getAllUserLpPositions(userId: string): Promise<LpPositionDetails[]> {
|
|
200
|
+
const profile = await this.userLpProfileService.getProfile(userId);
|
|
201
|
+
if (!profile) return [];
|
|
202
|
+
|
|
203
|
+
const trackedPositions =
|
|
204
|
+
await this.userLpProfileService.getTrackedPositions(userId);
|
|
205
|
+
|
|
206
|
+
const positions: LpPositionDetails[] = [];
|
|
207
|
+
for (const tracked of trackedPositions) {
|
|
208
|
+
try {
|
|
209
|
+
const position = await this.lpManagementService.getPosition({
|
|
210
|
+
dex: tracked.dex,
|
|
211
|
+
owner: profile.vaultPublicKey,
|
|
212
|
+
pool: tracked.poolAddress,
|
|
213
|
+
position: tracked.positionIdentifier,
|
|
214
|
+
});
|
|
215
|
+
if (position) positions.push(position);
|
|
216
|
+
} catch (error) {
|
|
217
|
+
logger.warn(
|
|
218
|
+
`[DexInteractionService] Failed to fetch LP position ${tracked.positionIdentifier}`,
|
|
219
|
+
error instanceof Error ? error.message : String(error),
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return positions;
|
|
225
|
+
}
|
|
226
|
+
}
|