@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,604 @@
|
|
|
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, 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/pancakeswp/types.ts
|
|
9
|
+
/**
|
|
10
|
+
* PancakeSwap V3 specific types
|
|
11
|
+
* PancakeSwap V3 is based on Uniswap V3 with some modifications
|
|
12
|
+
*/
|
|
13
|
+
const PANCAKESWAP_V3_FEE_TIERS = {
|
|
14
|
+
LOWEST: 100,
|
|
15
|
+
LOW: 500,
|
|
16
|
+
MEDIUM: 2500,
|
|
17
|
+
HIGH: 1e4
|
|
18
|
+
};
|
|
19
|
+
const PANCAKESWAP_V3_ADDRESSES = {
|
|
20
|
+
56: {
|
|
21
|
+
factory: "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865",
|
|
22
|
+
nonfungiblePositionManager: "0x46A15B0b27311cedF172AB29E4f4766fbE7F4364",
|
|
23
|
+
swapRouter: "0x1b81D678ffb9C0263b24A97847620C99d213eB14",
|
|
24
|
+
quoter: "0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997"
|
|
25
|
+
},
|
|
26
|
+
1: {
|
|
27
|
+
factory: "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865",
|
|
28
|
+
nonfungiblePositionManager: "0x46A15B0b27311cedF172AB29E4f4766fbE7F4364",
|
|
29
|
+
swapRouter: "0x1b81D678ffb9C0263b24A97847620C99d213eB14",
|
|
30
|
+
quoter: "0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997"
|
|
31
|
+
},
|
|
32
|
+
42161: {
|
|
33
|
+
factory: "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865",
|
|
34
|
+
nonfungiblePositionManager: "0x46A15B0b27311cedF172AB29E4f4766fbE7F4364",
|
|
35
|
+
swapRouter: "0x1b81D678ffb9C0263b24A97847620C99d213eB14",
|
|
36
|
+
quoter: "0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997"
|
|
37
|
+
},
|
|
38
|
+
8453: {
|
|
39
|
+
factory: "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865",
|
|
40
|
+
nonfungiblePositionManager: "0x46A15B0b27311cedF172AB29E4f4766fbE7F4364",
|
|
41
|
+
swapRouter: "0x1b81D678ffb9C0263b24A97847620C99d213eB14",
|
|
42
|
+
quoter: "0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997"
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/chains/evm/dex/pancakeswp/services/PancakeSwapV3LpService.ts
|
|
47
|
+
const SUPPORTED_CHAIN_IDS = [
|
|
48
|
+
56,
|
|
49
|
+
1,
|
|
50
|
+
42161,
|
|
51
|
+
8453
|
|
52
|
+
];
|
|
53
|
+
function getViemChain(chainId) {
|
|
54
|
+
const chain = {
|
|
55
|
+
1: viemChains.mainnet,
|
|
56
|
+
56: viemChains.bsc,
|
|
57
|
+
42161: viemChains.arbitrum,
|
|
58
|
+
8453: viemChains.base
|
|
59
|
+
}[chainId];
|
|
60
|
+
if (!chain) throw new Error(`Unsupported chain ID: ${chainId}`);
|
|
61
|
+
return chain;
|
|
62
|
+
}
|
|
63
|
+
var PancakeSwapV3LpService = class PancakeSwapV3LpService extends Service {
|
|
64
|
+
static serviceType = "pancakeswap-v3-lp";
|
|
65
|
+
capabilityDescription = "Provides PancakeSwap V3 liquidity pool management for EVM chains.";
|
|
66
|
+
publicClients = /* @__PURE__ */ new Map();
|
|
67
|
+
walletClients = /* @__PURE__ */ new Map();
|
|
68
|
+
rpcUrls = /* @__PURE__ */ new Map();
|
|
69
|
+
constructor(runtime) {
|
|
70
|
+
super(runtime);
|
|
71
|
+
if (runtime) this.initializeRpcUrls();
|
|
72
|
+
}
|
|
73
|
+
initializeRpcUrls() {
|
|
74
|
+
for (const [chainId, envKeys] of Object.entries({
|
|
75
|
+
1: [
|
|
76
|
+
"ETHEREUM_RPC_URL",
|
|
77
|
+
"ETH_RPC_URL",
|
|
78
|
+
"EVM_PROVIDER_MAINNET"
|
|
79
|
+
],
|
|
80
|
+
56: [
|
|
81
|
+
"BSC_RPC_URL",
|
|
82
|
+
"BNB_RPC_URL",
|
|
83
|
+
"EVM_PROVIDER_BSC"
|
|
84
|
+
],
|
|
85
|
+
42161: ["ARBITRUM_RPC_URL", "EVM_PROVIDER_ARBITRUM"],
|
|
86
|
+
8453: ["BASE_RPC_URL", "EVM_PROVIDER_BASE"]
|
|
87
|
+
})) for (const key of envKeys) {
|
|
88
|
+
const rpcUrl = this.runtime.getSetting(key);
|
|
89
|
+
if (rpcUrl && typeof rpcUrl === "string") {
|
|
90
|
+
this.rpcUrls.set(Number(chainId), rpcUrl);
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
getPublicClient(chainId) {
|
|
96
|
+
let client = this.publicClients.get(chainId);
|
|
97
|
+
if (client) return client;
|
|
98
|
+
const rpcUrl = this.rpcUrls.get(chainId);
|
|
99
|
+
client = createPublicClient({
|
|
100
|
+
chain: getViemChain(chainId),
|
|
101
|
+
transport: rpcUrl ? http(rpcUrl) : http()
|
|
102
|
+
});
|
|
103
|
+
this.publicClients.set(chainId, client);
|
|
104
|
+
return client;
|
|
105
|
+
}
|
|
106
|
+
getWalletClient(chainId, privateKey) {
|
|
107
|
+
const cacheKey = chainId;
|
|
108
|
+
let client = this.walletClients.get(cacheKey);
|
|
109
|
+
if (client) return client;
|
|
110
|
+
const rpcUrl = this.rpcUrls.get(chainId);
|
|
111
|
+
const chain = getViemChain(chainId);
|
|
112
|
+
const account = privateKeyToAccount(privateKey);
|
|
113
|
+
client = createWalletClient({
|
|
114
|
+
chain,
|
|
115
|
+
transport: rpcUrl ? http(rpcUrl) : http(),
|
|
116
|
+
account
|
|
117
|
+
});
|
|
118
|
+
this.walletClients.set(cacheKey, client);
|
|
119
|
+
return client;
|
|
120
|
+
}
|
|
121
|
+
static async start(runtime) {
|
|
122
|
+
const service = new PancakeSwapV3LpService(runtime);
|
|
123
|
+
logger.info("[PancakeSwapV3LpService] started");
|
|
124
|
+
return service;
|
|
125
|
+
}
|
|
126
|
+
async stop() {
|
|
127
|
+
this.publicClients.clear();
|
|
128
|
+
this.walletClients.clear();
|
|
129
|
+
logger.info("[PancakeSwapV3LpService] stopped");
|
|
130
|
+
}
|
|
131
|
+
getDexName() {
|
|
132
|
+
return "pancakeswap";
|
|
133
|
+
}
|
|
134
|
+
getSupportedChainIds() {
|
|
135
|
+
return SUPPORTED_CHAIN_IDS.filter((chainId) => PANCAKESWAP_V3_ADDRESSES[chainId] !== void 0);
|
|
136
|
+
}
|
|
137
|
+
supportsChain(chainId) {
|
|
138
|
+
return this.getSupportedChainIds().includes(chainId);
|
|
139
|
+
}
|
|
140
|
+
async getPools(chainId, tokenA, tokenB, feeTier) {
|
|
141
|
+
if (!this.supportsChain(chainId)) {
|
|
142
|
+
logger.warn(`[PancakeSwapV3LpService] Chain ${chainId} not supported`);
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
const addresses = PANCAKESWAP_V3_ADDRESSES[chainId];
|
|
146
|
+
if (!addresses) return [];
|
|
147
|
+
const client = this.getPublicClient(chainId);
|
|
148
|
+
const pools = [];
|
|
149
|
+
if (tokenA && tokenB) {
|
|
150
|
+
const feeTiers = feeTier ? [feeTier] : Object.values(PANCAKESWAP_V3_FEE_TIERS);
|
|
151
|
+
for (const fee of feeTiers) try {
|
|
152
|
+
const poolAddress = await client.readContract({
|
|
153
|
+
address: addresses.factory,
|
|
154
|
+
abi: UNISWAP_V3_FACTORY_ABI,
|
|
155
|
+
functionName: "getPool",
|
|
156
|
+
args: [
|
|
157
|
+
tokenA,
|
|
158
|
+
tokenB,
|
|
159
|
+
fee
|
|
160
|
+
]
|
|
161
|
+
});
|
|
162
|
+
if (poolAddress && poolAddress !== "0x0000000000000000000000000000000000000000") {
|
|
163
|
+
const poolInfo = await this.getPoolInfo(chainId, poolAddress);
|
|
164
|
+
if (poolInfo) pools.push(poolInfo);
|
|
165
|
+
}
|
|
166
|
+
} catch (_error) {
|
|
167
|
+
logger.debug(`[PancakeSwapV3LpService] No pool found for ${tokenA}/${tokenB} at fee ${fee}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return pools;
|
|
171
|
+
}
|
|
172
|
+
async getPoolInfo(chainId, poolAddress) {
|
|
173
|
+
const client = this.getPublicClient(chainId);
|
|
174
|
+
const chain = getViemChain(chainId);
|
|
175
|
+
try {
|
|
176
|
+
const [token0, token1, fee, tickSpacing, _liquidity, slot0] = await Promise.all([
|
|
177
|
+
client.readContract({
|
|
178
|
+
address: poolAddress,
|
|
179
|
+
abi: UNISWAP_V3_POOL_ABI,
|
|
180
|
+
functionName: "token0"
|
|
181
|
+
}),
|
|
182
|
+
client.readContract({
|
|
183
|
+
address: poolAddress,
|
|
184
|
+
abi: UNISWAP_V3_POOL_ABI,
|
|
185
|
+
functionName: "token1"
|
|
186
|
+
}),
|
|
187
|
+
client.readContract({
|
|
188
|
+
address: poolAddress,
|
|
189
|
+
abi: UNISWAP_V3_POOL_ABI,
|
|
190
|
+
functionName: "fee"
|
|
191
|
+
}),
|
|
192
|
+
client.readContract({
|
|
193
|
+
address: poolAddress,
|
|
194
|
+
abi: UNISWAP_V3_POOL_ABI,
|
|
195
|
+
functionName: "tickSpacing"
|
|
196
|
+
}),
|
|
197
|
+
client.readContract({
|
|
198
|
+
address: poolAddress,
|
|
199
|
+
abi: UNISWAP_V3_POOL_ABI,
|
|
200
|
+
functionName: "liquidity"
|
|
201
|
+
}),
|
|
202
|
+
client.readContract({
|
|
203
|
+
address: poolAddress,
|
|
204
|
+
abi: UNISWAP_V3_POOL_ABI,
|
|
205
|
+
functionName: "slot0"
|
|
206
|
+
})
|
|
207
|
+
]);
|
|
208
|
+
const [symbol0, decimals0, symbol1, decimals1] = await Promise.all([
|
|
209
|
+
client.readContract({
|
|
210
|
+
address: token0,
|
|
211
|
+
abi: ERC20_ABI,
|
|
212
|
+
functionName: "symbol"
|
|
213
|
+
}).catch(() => "UNKNOWN"),
|
|
214
|
+
client.readContract({
|
|
215
|
+
address: token0,
|
|
216
|
+
abi: ERC20_ABI,
|
|
217
|
+
functionName: "decimals"
|
|
218
|
+
}).catch(() => 18),
|
|
219
|
+
client.readContract({
|
|
220
|
+
address: token1,
|
|
221
|
+
abi: ERC20_ABI,
|
|
222
|
+
functionName: "symbol"
|
|
223
|
+
}).catch(() => "UNKNOWN"),
|
|
224
|
+
client.readContract({
|
|
225
|
+
address: token1,
|
|
226
|
+
abi: ERC20_ABI,
|
|
227
|
+
functionName: "decimals"
|
|
228
|
+
}).catch(() => 18)
|
|
229
|
+
]);
|
|
230
|
+
return {
|
|
231
|
+
id: poolAddress,
|
|
232
|
+
dex: "pancakeswap",
|
|
233
|
+
chainId,
|
|
234
|
+
chainName: chain.name,
|
|
235
|
+
poolAddress,
|
|
236
|
+
tokenA: {
|
|
237
|
+
address: token0,
|
|
238
|
+
symbol: symbol0,
|
|
239
|
+
decimals: Number(decimals0)
|
|
240
|
+
},
|
|
241
|
+
tokenB: {
|
|
242
|
+
address: token1,
|
|
243
|
+
symbol: symbol1,
|
|
244
|
+
decimals: Number(decimals1)
|
|
245
|
+
},
|
|
246
|
+
feeTier: Number(fee),
|
|
247
|
+
tickSpacing: Number(tickSpacing),
|
|
248
|
+
currentTick: Number(slot0[1]),
|
|
249
|
+
sqrtPriceX96: slot0[0],
|
|
250
|
+
fee: Number(fee) / 1e6,
|
|
251
|
+
displayName: `${symbol0}/${symbol1} (${Number(fee) / 1e4}%)`
|
|
252
|
+
};
|
|
253
|
+
} catch (error) {
|
|
254
|
+
logger.error(`[PancakeSwapV3LpService] Error fetching pool info for ${poolAddress}:`, error);
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
async addLiquidity(params) {
|
|
259
|
+
if (!this.supportsChain(params.chainId)) return {
|
|
260
|
+
success: false,
|
|
261
|
+
error: `Chain ${params.chainId} not supported`
|
|
262
|
+
};
|
|
263
|
+
const addresses = PANCAKESWAP_V3_ADDRESSES[params.chainId];
|
|
264
|
+
if (!addresses) return {
|
|
265
|
+
success: false,
|
|
266
|
+
error: "PancakeSwap V3 not deployed on this chain"
|
|
267
|
+
};
|
|
268
|
+
try {
|
|
269
|
+
const publicClient = this.getPublicClient(params.chainId);
|
|
270
|
+
const walletClient = this.getWalletClient(params.chainId, params.wallet.privateKey);
|
|
271
|
+
const poolInfo = await this.getPoolInfo(params.chainId, params.poolAddress);
|
|
272
|
+
if (!poolInfo) return {
|
|
273
|
+
success: false,
|
|
274
|
+
error: "Pool not found"
|
|
275
|
+
};
|
|
276
|
+
const slippageMultiplier = BigInt(1e4 - params.slippageBps);
|
|
277
|
+
const amount0Min = params.tokenAAmount * slippageMultiplier / 10000n;
|
|
278
|
+
const amount1Min = (params.tokenBAmount ?? 0n) * slippageMultiplier / 10000n;
|
|
279
|
+
await this.approveToken(params.chainId, params.wallet.privateKey, poolInfo.tokenA.address, addresses.nonfungiblePositionManager, params.tokenAAmount);
|
|
280
|
+
if (params.tokenBAmount && params.tokenBAmount > 0n) await this.approveToken(params.chainId, params.wallet.privateKey, poolInfo.tokenB.address, addresses.nonfungiblePositionManager, params.tokenBAmount);
|
|
281
|
+
const deadline = params.deadline ?? BigInt(Math.floor(Date.now() / 1e3) + 1800);
|
|
282
|
+
const tickLower = params.tickLower ?? poolInfo.currentTick - 1e3;
|
|
283
|
+
const tickUpper = params.tickUpper ?? poolInfo.currentTick + 1e3;
|
|
284
|
+
const tickSpacing = poolInfo.tickSpacing ?? 50;
|
|
285
|
+
const alignedTickLower = Math.floor(tickLower / tickSpacing) * tickSpacing;
|
|
286
|
+
const alignedTickUpper = Math.ceil(tickUpper / tickSpacing) * tickSpacing;
|
|
287
|
+
const mintParams = {
|
|
288
|
+
token0: poolInfo.tokenA.address,
|
|
289
|
+
token1: poolInfo.tokenB.address,
|
|
290
|
+
fee: poolInfo.feeTier,
|
|
291
|
+
tickLower: alignedTickLower,
|
|
292
|
+
tickUpper: alignedTickUpper,
|
|
293
|
+
amount0Desired: params.tokenAAmount,
|
|
294
|
+
amount1Desired: params.tokenBAmount ?? 0n,
|
|
295
|
+
amount0Min,
|
|
296
|
+
amount1Min,
|
|
297
|
+
recipient: params.wallet.address,
|
|
298
|
+
deadline
|
|
299
|
+
};
|
|
300
|
+
const { request } = await publicClient.simulateContract({
|
|
301
|
+
address: addresses.nonfungiblePositionManager,
|
|
302
|
+
abi: UNISWAP_V3_POSITION_MANAGER_ABI,
|
|
303
|
+
functionName: "mint",
|
|
304
|
+
args: [mintParams],
|
|
305
|
+
account: walletClient.account
|
|
306
|
+
});
|
|
307
|
+
const hash = await walletClient.writeContract(request);
|
|
308
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
309
|
+
return {
|
|
310
|
+
success: receipt.status === "success",
|
|
311
|
+
transactionId: hash,
|
|
312
|
+
hash,
|
|
313
|
+
chainId: params.chainId,
|
|
314
|
+
blockNumber: receipt.blockNumber,
|
|
315
|
+
gasUsed: receipt.gasUsed,
|
|
316
|
+
data: {
|
|
317
|
+
poolAddress: params.poolAddress,
|
|
318
|
+
tickLower: alignedTickLower,
|
|
319
|
+
tickUpper: alignedTickUpper
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
} catch (error) {
|
|
323
|
+
logger.error("[PancakeSwapV3LpService] Error adding liquidity:", error);
|
|
324
|
+
return {
|
|
325
|
+
success: false,
|
|
326
|
+
error: error instanceof Error ? error.message : "Unknown error adding liquidity"
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
async removeLiquidity(params) {
|
|
331
|
+
if (!this.supportsChain(params.chainId)) return {
|
|
332
|
+
success: false,
|
|
333
|
+
error: `Chain ${params.chainId} not supported`
|
|
334
|
+
};
|
|
335
|
+
const addresses = PANCAKESWAP_V3_ADDRESSES[params.chainId];
|
|
336
|
+
if (!addresses) return {
|
|
337
|
+
success: false,
|
|
338
|
+
error: "PancakeSwap V3 not deployed on this chain"
|
|
339
|
+
};
|
|
340
|
+
if (!params.tokenId) return {
|
|
341
|
+
success: false,
|
|
342
|
+
error: "Position token ID required for PancakeSwap V3"
|
|
343
|
+
};
|
|
344
|
+
try {
|
|
345
|
+
const publicClient = this.getPublicClient(params.chainId);
|
|
346
|
+
const walletClient = this.getWalletClient(params.chainId, params.wallet.privateKey);
|
|
347
|
+
const position = await this.getPositionFromContract(params.chainId, params.tokenId);
|
|
348
|
+
if (!position) return {
|
|
349
|
+
success: false,
|
|
350
|
+
error: "Position not found"
|
|
351
|
+
};
|
|
352
|
+
let liquidityToRemove = position.liquidity;
|
|
353
|
+
if (params.percentageToRemove && params.percentageToRemove < 100) liquidityToRemove = position.liquidity * BigInt(params.percentageToRemove) / 100n;
|
|
354
|
+
const deadline = params.deadline ?? BigInt(Math.floor(Date.now() / 1e3) + 1800);
|
|
355
|
+
const decreaseParams = {
|
|
356
|
+
tokenId: params.tokenId,
|
|
357
|
+
liquidity: liquidityToRemove,
|
|
358
|
+
amount0Min: 0n,
|
|
359
|
+
amount1Min: 0n,
|
|
360
|
+
deadline
|
|
361
|
+
};
|
|
362
|
+
const { request: decreaseRequest } = await publicClient.simulateContract({
|
|
363
|
+
address: addresses.nonfungiblePositionManager,
|
|
364
|
+
abi: UNISWAP_V3_POSITION_MANAGER_ABI,
|
|
365
|
+
functionName: "decreaseLiquidity",
|
|
366
|
+
args: [decreaseParams],
|
|
367
|
+
account: walletClient.account
|
|
368
|
+
});
|
|
369
|
+
const decreaseHash = await walletClient.writeContract(decreaseRequest);
|
|
370
|
+
await publicClient.waitForTransactionReceipt({ hash: decreaseHash });
|
|
371
|
+
const collectParams = {
|
|
372
|
+
tokenId: params.tokenId,
|
|
373
|
+
recipient: params.wallet.address,
|
|
374
|
+
amount0Max: maxUint128,
|
|
375
|
+
amount1Max: maxUint128
|
|
376
|
+
};
|
|
377
|
+
const { request: collectRequest } = await publicClient.simulateContract({
|
|
378
|
+
address: addresses.nonfungiblePositionManager,
|
|
379
|
+
abi: UNISWAP_V3_POSITION_MANAGER_ABI,
|
|
380
|
+
functionName: "collect",
|
|
381
|
+
args: [collectParams],
|
|
382
|
+
account: walletClient.account
|
|
383
|
+
});
|
|
384
|
+
const collectHash = await walletClient.writeContract(collectRequest);
|
|
385
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: collectHash });
|
|
386
|
+
if (params.percentageToRemove === 100 || !params.percentageToRemove) try {
|
|
387
|
+
const { request: burnRequest } = await publicClient.simulateContract({
|
|
388
|
+
address: addresses.nonfungiblePositionManager,
|
|
389
|
+
abi: UNISWAP_V3_POSITION_MANAGER_ABI,
|
|
390
|
+
functionName: "burn",
|
|
391
|
+
args: [params.tokenId],
|
|
392
|
+
account: walletClient.account
|
|
393
|
+
});
|
|
394
|
+
await walletClient.writeContract(burnRequest);
|
|
395
|
+
} catch (burnError) {
|
|
396
|
+
logger.debug("[PancakeSwapV3LpService] Could not burn position NFT:", burnError);
|
|
397
|
+
}
|
|
398
|
+
return {
|
|
399
|
+
success: receipt.status === "success",
|
|
400
|
+
transactionId: collectHash,
|
|
401
|
+
hash: collectHash,
|
|
402
|
+
chainId: params.chainId,
|
|
403
|
+
blockNumber: receipt.blockNumber,
|
|
404
|
+
gasUsed: receipt.gasUsed
|
|
405
|
+
};
|
|
406
|
+
} catch (error) {
|
|
407
|
+
logger.error("[PancakeSwapV3LpService] Error removing liquidity:", error);
|
|
408
|
+
return {
|
|
409
|
+
success: false,
|
|
410
|
+
error: error instanceof Error ? error.message : "Unknown error removing liquidity"
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
async getPositionFromContract(chainId, tokenId) {
|
|
415
|
+
const addresses = PANCAKESWAP_V3_ADDRESSES[chainId];
|
|
416
|
+
if (!addresses) return null;
|
|
417
|
+
const client = this.getPublicClient(chainId);
|
|
418
|
+
try {
|
|
419
|
+
const result = await client.readContract({
|
|
420
|
+
address: addresses.nonfungiblePositionManager,
|
|
421
|
+
abi: UNISWAP_V3_POSITION_MANAGER_ABI,
|
|
422
|
+
functionName: "positions",
|
|
423
|
+
args: [tokenId]
|
|
424
|
+
});
|
|
425
|
+
return {
|
|
426
|
+
tokenId,
|
|
427
|
+
nonce: result[0],
|
|
428
|
+
operator: result[1],
|
|
429
|
+
token0: result[2],
|
|
430
|
+
token1: result[3],
|
|
431
|
+
fee: result[4],
|
|
432
|
+
tickLower: result[5],
|
|
433
|
+
tickUpper: result[6],
|
|
434
|
+
liquidity: result[7],
|
|
435
|
+
feeGrowthInside0LastX128: result[8],
|
|
436
|
+
feeGrowthInside1LastX128: result[9],
|
|
437
|
+
tokensOwed0: result[10],
|
|
438
|
+
tokensOwed1: result[11]
|
|
439
|
+
};
|
|
440
|
+
} catch (error) {
|
|
441
|
+
logger.error(`[PancakeSwapV3LpService] Error fetching position ${tokenId}:`, error);
|
|
442
|
+
return null;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
async getPositionDetails(chainId, owner, poolAddress, tokenId) {
|
|
446
|
+
if (!this.supportsChain(chainId)) return null;
|
|
447
|
+
if (tokenId) {
|
|
448
|
+
const position = await this.getPositionFromContract(chainId, tokenId);
|
|
449
|
+
if (!position) return null;
|
|
450
|
+
const client = this.getPublicClient(chainId);
|
|
451
|
+
const [symbol0, decimals0, symbol1, decimals1] = await Promise.all([
|
|
452
|
+
client.readContract({
|
|
453
|
+
address: position.token0,
|
|
454
|
+
abi: ERC20_ABI,
|
|
455
|
+
functionName: "symbol"
|
|
456
|
+
}).catch(() => "UNKNOWN"),
|
|
457
|
+
client.readContract({
|
|
458
|
+
address: position.token0,
|
|
459
|
+
abi: ERC20_ABI,
|
|
460
|
+
functionName: "decimals"
|
|
461
|
+
}).catch(() => 18),
|
|
462
|
+
client.readContract({
|
|
463
|
+
address: position.token1,
|
|
464
|
+
abi: ERC20_ABI,
|
|
465
|
+
functionName: "symbol"
|
|
466
|
+
}).catch(() => "UNKNOWN"),
|
|
467
|
+
client.readContract({
|
|
468
|
+
address: position.token1,
|
|
469
|
+
abi: ERC20_ABI,
|
|
470
|
+
functionName: "decimals"
|
|
471
|
+
}).catch(() => 18)
|
|
472
|
+
]);
|
|
473
|
+
return {
|
|
474
|
+
poolId: poolAddress,
|
|
475
|
+
dex: "pancakeswap",
|
|
476
|
+
chainId,
|
|
477
|
+
owner,
|
|
478
|
+
tokenId: position.tokenId,
|
|
479
|
+
tickLower: position.tickLower,
|
|
480
|
+
tickUpper: position.tickUpper,
|
|
481
|
+
liquidity: position.liquidity,
|
|
482
|
+
lpTokenBalance: {
|
|
483
|
+
address: poolAddress,
|
|
484
|
+
balance: position.liquidity.toString(),
|
|
485
|
+
decimals: 0,
|
|
486
|
+
symbol: `PCS-V3-${symbol0}/${symbol1}`
|
|
487
|
+
},
|
|
488
|
+
underlyingTokens: [{
|
|
489
|
+
address: position.token0,
|
|
490
|
+
balance: position.tokensOwed0.toString(),
|
|
491
|
+
decimals: Number(decimals0),
|
|
492
|
+
symbol: symbol0
|
|
493
|
+
}, {
|
|
494
|
+
address: position.token1,
|
|
495
|
+
balance: position.tokensOwed1.toString(),
|
|
496
|
+
decimals: Number(decimals1),
|
|
497
|
+
symbol: symbol1
|
|
498
|
+
}]
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
return (await this.getAllPositions(chainId, owner)).find((p) => p.poolId.toLowerCase() === poolAddress.toLowerCase()) ?? null;
|
|
502
|
+
}
|
|
503
|
+
async getAllPositions(chainId, owner) {
|
|
504
|
+
if (!this.supportsChain(chainId)) return [];
|
|
505
|
+
const addresses = PANCAKESWAP_V3_ADDRESSES[chainId];
|
|
506
|
+
if (!addresses) return [];
|
|
507
|
+
const client = this.getPublicClient(chainId);
|
|
508
|
+
const positions = [];
|
|
509
|
+
try {
|
|
510
|
+
const balance = await client.readContract({
|
|
511
|
+
address: addresses.nonfungiblePositionManager,
|
|
512
|
+
abi: UNISWAP_V3_POSITION_MANAGER_ABI,
|
|
513
|
+
functionName: "balanceOf",
|
|
514
|
+
args: [owner]
|
|
515
|
+
});
|
|
516
|
+
for (let i = 0; i < Number(balance); i++) {
|
|
517
|
+
const tokenId = await client.readContract({
|
|
518
|
+
address: addresses.nonfungiblePositionManager,
|
|
519
|
+
abi: UNISWAP_V3_POSITION_MANAGER_ABI,
|
|
520
|
+
functionName: "tokenOfOwnerByIndex",
|
|
521
|
+
args: [owner, BigInt(i)]
|
|
522
|
+
});
|
|
523
|
+
const position = await this.getPositionFromContract(chainId, tokenId);
|
|
524
|
+
if (position && position.liquidity > 0n) {
|
|
525
|
+
const poolAddress = await client.readContract({
|
|
526
|
+
address: addresses.factory,
|
|
527
|
+
abi: UNISWAP_V3_FACTORY_ABI,
|
|
528
|
+
functionName: "getPool",
|
|
529
|
+
args: [
|
|
530
|
+
position.token0,
|
|
531
|
+
position.token1,
|
|
532
|
+
position.fee
|
|
533
|
+
]
|
|
534
|
+
});
|
|
535
|
+
if (poolAddress) {
|
|
536
|
+
const details = await this.getPositionDetails(chainId, owner, poolAddress, tokenId);
|
|
537
|
+
if (details) positions.push(details);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
} catch (error) {
|
|
542
|
+
logger.error("[PancakeSwapV3LpService] Error fetching all positions:", error);
|
|
543
|
+
}
|
|
544
|
+
return positions;
|
|
545
|
+
}
|
|
546
|
+
async getMarketData(poolAddresses) {
|
|
547
|
+
const result = {};
|
|
548
|
+
for (const address of poolAddresses) for (const chainId of this.getSupportedChainIds()) try {
|
|
549
|
+
const poolInfo = await this.getPoolInfo(chainId, address);
|
|
550
|
+
if (poolInfo) {
|
|
551
|
+
result[address] = poolInfo;
|
|
552
|
+
break;
|
|
553
|
+
}
|
|
554
|
+
} catch {}
|
|
555
|
+
return result;
|
|
556
|
+
}
|
|
557
|
+
async approveToken(chainId, privateKey, tokenAddress, spenderAddress, amount) {
|
|
558
|
+
const publicClient = this.getPublicClient(chainId);
|
|
559
|
+
const walletClient = this.getWalletClient(chainId, privateKey);
|
|
560
|
+
if (await publicClient.readContract({
|
|
561
|
+
address: tokenAddress,
|
|
562
|
+
abi: ERC20_ABI,
|
|
563
|
+
functionName: "allowance",
|
|
564
|
+
args: [walletClient.account?.address, spenderAddress]
|
|
565
|
+
}) >= amount) return;
|
|
566
|
+
logger.info(`[PancakeSwapV3LpService] Approving ${tokenAddress} for ${spenderAddress}`);
|
|
567
|
+
const { request } = await publicClient.simulateContract({
|
|
568
|
+
address: tokenAddress,
|
|
569
|
+
abi: ERC20_ABI,
|
|
570
|
+
functionName: "approve",
|
|
571
|
+
args: [spenderAddress, amount],
|
|
572
|
+
account: walletClient.account
|
|
573
|
+
});
|
|
574
|
+
const hash = await walletClient.writeContract(request);
|
|
575
|
+
await publicClient.waitForTransactionReceipt({ hash });
|
|
576
|
+
logger.info(`[PancakeSwapV3LpService] Token approved: ${hash}`);
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
//#endregion
|
|
580
|
+
//#region src/chains/evm/dex/pancakeswp/index.ts
|
|
581
|
+
var pancakeswp_exports = /* @__PURE__ */ __exportAll({
|
|
582
|
+
PANCAKESWAP_V3_ADDRESSES: () => PANCAKESWAP_V3_ADDRESSES,
|
|
583
|
+
PANCAKESWAP_V3_FEE_TIERS: () => PANCAKESWAP_V3_FEE_TIERS,
|
|
584
|
+
PancakeSwapV3LpService: () => PancakeSwapV3LpService,
|
|
585
|
+
default: () => pancakeswapPlugin,
|
|
586
|
+
pancakeswapPlugin: () => pancakeswapPlugin
|
|
587
|
+
});
|
|
588
|
+
const pancakeswapPlugin = {
|
|
589
|
+
name: "@elizaos/plugin-lp-manager/pancakeswap",
|
|
590
|
+
description: "PancakeSwap V3 liquidity pool management plugin",
|
|
591
|
+
services: [PancakeSwapV3LpService],
|
|
592
|
+
actions: [],
|
|
593
|
+
providers: [],
|
|
594
|
+
init: async (_config, runtime) => {
|
|
595
|
+
console.info("PancakeSwap V3 Plugin initialized");
|
|
596
|
+
await registerLpProtocolProvider(runtime, createEvmLpProtocolProvider({
|
|
597
|
+
dex: "pancakeswap",
|
|
598
|
+
label: "PancakeSwap V3",
|
|
599
|
+
service: runtime.getService(PancakeSwapV3LpService.serviceType) ?? await PancakeSwapV3LpService.start(runtime)
|
|
600
|
+
}));
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
//#endregion
|
|
604
|
+
export { pancakeswp_exports as n, PancakeSwapV3LpService as r, pancakeswapPlugin as t };
|