@awaken-finance/agent-kit 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -184,12 +184,14 @@ All commands output standardized JSON on success. Errors go to stderr with `[ERR
184
184
 
185
185
  2. Update the path and environment variables:
186
186
 
187
+ **EOA mode** (direct private key signing):
188
+
187
189
  ```json
188
190
  {
189
191
  "mcpServers": {
190
192
  "awaken-agent-kit": {
191
193
  "command": "bun",
192
- "args": ["run", "/ABSOLUTE/PATH/TO/scripts/skills/src/mcp/server.ts"],
194
+ "args": ["run", "/ABSOLUTE/PATH/TO/src/mcp/server.ts"],
193
195
  "env": {
194
196
  "AELF_PRIVATE_KEY": "your_private_key_here",
195
197
  "AWAKEN_NETWORK": "mainnet"
@@ -199,6 +201,25 @@ All commands output standardized JSON on success. Errors go to stderr with `[ERR
199
201
  }
200
202
  ```
201
203
 
204
+ **CA mode** (Portkey Contract Account):
205
+
206
+ ```json
207
+ {
208
+ "mcpServers": {
209
+ "awaken-agent-kit": {
210
+ "command": "bun",
211
+ "args": ["run", "/ABSOLUTE/PATH/TO/src/mcp/server.ts"],
212
+ "env": {
213
+ "PORTKEY_PRIVATE_KEY": "your_manager_private_key",
214
+ "PORTKEY_CA_HASH": "your_ca_hash",
215
+ "PORTKEY_CA_ADDRESS": "your_ca_address",
216
+ "AWAKEN_NETWORK": "mainnet"
217
+ }
218
+ }
219
+ }
220
+ }
221
+ ```
222
+
202
223
  3. Start the MCP server manually (for debugging):
203
224
 
204
225
  ```bash
@@ -279,7 +300,10 @@ bun run test:e2e
279
300
 
280
301
  | Variable | Required | Default | Description |
281
302
  |----------|----------|---------|-------------|
282
- | `AELF_PRIVATE_KEY` | For trades | — | aelf wallet private key |
303
+ | `AELF_PRIVATE_KEY` | For trades (EOA) | — | aelf wallet private key |
304
+ | `PORTKEY_PRIVATE_KEY` | For trades (CA) | — | Portkey Manager private key |
305
+ | `PORTKEY_CA_HASH` | For trades (CA) | — | Portkey CA hash |
306
+ | `PORTKEY_CA_ADDRESS` | For trades (CA) | — | Portkey CA address |
283
307
  | `AWAKEN_NETWORK` | No | `mainnet` | `mainnet` or `testnet` |
284
308
  | `AWAKEN_RPC_URL` | No | Per network | Override RPC endpoint |
285
309
  | `AWAKEN_API_BASE_URL` | No | Per network | Override API endpoint |
@@ -3,12 +3,12 @@
3
3
  // Awaken Trade Skill - CLI Adapter (thin shell)
4
4
  // ============================================================
5
5
  // Commands: swap, add-liquidity, remove-liquidity, approve
6
- // Requires: AELF_PRIVATE_KEY env var
6
+ // Requires: AELF_PRIVATE_KEY (EOA) or PORTKEY_PRIVATE_KEY + CA env vars
7
7
  // Core logic lives in src/core/trade.ts
8
8
 
9
9
  import { Command } from 'commander';
10
+ import { createSignerFromEnv } from '@portkey/aelf-signer';
10
11
  import { getNetworkConfig, DEFAULT_SLIPPAGE } from './lib/config';
11
- import { getWalletByPrivateKey } from './lib/aelf-client';
12
12
  import { outputSuccess, outputError } from './cli-helpers';
13
13
  import { executeSwap, addLiquidity, removeLiquidity, approveTokenSpending } from './src/core/trade';
14
14
 
@@ -16,7 +16,7 @@ const program = new Command();
16
16
 
17
17
  program
18
18
  .name('awaken-trade')
19
- .description('Awaken DEX trading tool (requires AELF_PRIVATE_KEY)')
19
+ .description('Awaken DEX trading tool (requires AELF_PRIVATE_KEY or Portkey CA env vars)')
20
20
  .version('1.0.0')
21
21
  .option('--network <network>', 'Network: mainnet or testnet', process.env.AWAKEN_NETWORK || 'mainnet');
22
22
 
@@ -31,8 +31,8 @@ program
31
31
  .action(async (opts) => {
32
32
  try {
33
33
  const config = getNetworkConfig(program.opts().network);
34
- const wallet = getWalletByPrivateKey();
35
- const result = await executeSwap(config, wallet, {
34
+ const signer = createSignerFromEnv();
35
+ const result = await executeSwap(config, signer, {
36
36
  symbolIn: opts.symbolIn,
37
37
  symbolOut: opts.symbolOut,
38
38
  amountIn: opts.amountIn,
@@ -57,8 +57,8 @@ program
57
57
  .action(async (opts) => {
58
58
  try {
59
59
  const config = getNetworkConfig(program.opts().network);
60
- const wallet = getWalletByPrivateKey();
61
- const result = await addLiquidity(config, wallet, {
60
+ const signer = createSignerFromEnv();
61
+ const result = await addLiquidity(config, signer, {
62
62
  tokenA: opts.tokenA,
63
63
  tokenB: opts.tokenB,
64
64
  amountA: opts.amountA,
@@ -84,8 +84,8 @@ program
84
84
  .action(async (opts) => {
85
85
  try {
86
86
  const config = getNetworkConfig(program.opts().network);
87
- const wallet = getWalletByPrivateKey();
88
- const result = await removeLiquidity(config, wallet, {
87
+ const signer = createSignerFromEnv();
88
+ const result = await removeLiquidity(config, signer, {
89
89
  tokenA: opts.tokenA,
90
90
  tokenB: opts.tokenB,
91
91
  lpAmount: opts.lpAmount,
@@ -108,8 +108,8 @@ program
108
108
  .action(async (opts) => {
109
109
  try {
110
110
  const config = getNetworkConfig(program.opts().network);
111
- const wallet = getWalletByPrivateKey();
112
- const result = await approveTokenSpending(config, wallet, {
111
+ const signer = createSignerFromEnv();
112
+ const result = await approveTokenSpending(config, signer, {
113
113
  symbol: opts.symbol,
114
114
  spender: opts.spender,
115
115
  amount: opts.amount,
@@ -2,10 +2,11 @@
2
2
  // Awaken OpenClaw Skills - aelf SDK Client
3
3
  // ============================================================
4
4
  // Wraps aelf-sdk for both view (read) and send (write) contract calls.
5
- // For send methods, requires AELF_PRIVATE_KEY env var.
5
+ // Supports both EOA and CA wallets via @portkey/aelf-signer.
6
6
 
7
7
  import AElf from 'aelf-sdk';
8
8
  import BigNumber from 'bignumber.js';
9
+ import type { AelfSigner } from '@portkey/aelf-signer';
9
10
  import type { NetworkConfig, TxResult } from './types';
10
11
 
11
12
  // ---- Caches ----
@@ -141,21 +142,26 @@ export async function getTokenInfo(
141
142
 
142
143
  // ---- Approve ----
143
144
 
145
+ /**
146
+ * Approve a contract to spend tokens.
147
+ * Accepts AelfSigner (EOA or CA) — signing is handled transparently.
148
+ */
144
149
  export async function approveToken(
145
150
  config: NetworkConfig,
146
- wallet: any,
151
+ signer: AelfSigner,
147
152
  symbol: string,
148
153
  spender: string,
149
154
  amount: string,
150
155
  ): Promise<TxResult> {
151
- const result = await callSendMethod(config.rpcUrl, config.tokenContract, 'Approve', wallet, {
156
+ const result = await signer.sendContractCall(config.rpcUrl, config.tokenContract, 'Approve', {
152
157
  symbol,
153
158
  spender,
154
159
  amount,
155
160
  });
156
- const txId = result?.TransactionId || result?.transactionId;
157
- if (!txId) throw new Error('[ERROR] Approve failed: no transactionId returned');
158
- return getTxResult(config.rpcUrl, txId);
161
+ return {
162
+ transactionId: result.transactionId,
163
+ status: (result.txResult.Status || 'mined').toLowerCase(),
164
+ };
159
165
  }
160
166
 
161
167
  // ---- Utility ----
@@ -5,6 +5,7 @@
5
5
  "_cursor_project": ".cursor/mcp.json (in project root)",
6
6
  "_cursor_global": "~/.cursor/mcp.json",
7
7
 
8
+ "_eoa_mode": "EOA mode — direct private key signing:",
8
9
  "mcpServers": {
9
10
  "awaken-agent-kit": {
10
11
  "command": "bun",
@@ -14,5 +15,19 @@
14
15
  "AWAKEN_NETWORK": "mainnet"
15
16
  }
16
17
  }
18
+ },
19
+
20
+ "_ca_mode": "CA mode — Portkey Contract Account via ManagerForwardCall:",
21
+ "_mcpServers_ca_example": {
22
+ "awaken-agent-kit": {
23
+ "command": "bun",
24
+ "args": ["run", "/ABSOLUTE/PATH/TO/awaken-agent-skills/src/mcp/server.ts"],
25
+ "env": {
26
+ "PORTKEY_PRIVATE_KEY": "your_manager_private_key",
27
+ "PORTKEY_CA_HASH": "your_ca_hash",
28
+ "PORTKEY_CA_ADDRESS": "your_ca_address",
29
+ "AWAKEN_NETWORK": "mainnet"
30
+ }
31
+ }
17
32
  }
18
33
  }
package/openclaw.json CHANGED
@@ -33,25 +33,25 @@
33
33
  {
34
34
  "name": "awaken-trade-swap",
35
35
  "command": "bun run awaken_trade_skill.ts swap --symbol-in {{symbolIn}} --symbol-out {{symbolOut}} --amount-in {{amountIn}} --slippage {{slippage}}",
36
- "description": "Execute a token swap on Awaken DEX. REQUIRES AELF_PRIVATE_KEY env var. This sends a real on-chain transaction. Parameters: --symbol-in (token to sell), --symbol-out (token to buy), --amount-in (human-readable amount to sell), --slippage (tolerance, default 0.005 = 0.5%). The tool auto-queries the best route, approves if needed, and executes the swap. Returns: transactionId, estimated amounts, explorer URL.",
36
+ "description": "Execute a token swap on Awaken DEX. Requires wallet env vars: AELF_PRIVATE_KEY (EOA) or PORTKEY_PRIVATE_KEY + PORTKEY_CA_HASH + PORTKEY_CA_ADDRESS (CA). This sends a real on-chain transaction. Parameters: --symbol-in (token to sell), --symbol-out (token to buy), --amount-in (human-readable amount to sell), --slippage (tolerance, default 0.005 = 0.5%). The tool auto-queries the best route, approves if needed, and executes the swap. Returns: transactionId, estimated amounts, explorer URL.",
37
37
  "cwd": "."
38
38
  },
39
39
  {
40
40
  "name": "awaken-trade-add-liquidity",
41
41
  "command": "bun run awaken_trade_skill.ts add-liquidity --token-a {{tokenA}} --token-b {{tokenB}} --amount-a {{amountA}} --amount-b {{amountB}} --fee-rate {{feeRate}}",
42
- "description": "Add liquidity to an Awaken DEX trading pair. REQUIRES AELF_PRIVATE_KEY env var. Parameters: --token-a and --token-b (token symbols), --amount-a and --amount-b (human-readable amounts), --fee-rate (pool fee tier, default 0.3), --slippage (tolerance, default 0.005). Auto-approves both tokens before adding.",
42
+ "description": "Add liquidity to an Awaken DEX trading pair. Requires wallet env vars (EOA or CA). Parameters: --token-a and --token-b (token symbols), --amount-a and --amount-b (human-readable amounts), --fee-rate (pool fee tier, default 0.3), --slippage (tolerance, default 0.005). Auto-approves both tokens before adding.",
43
43
  "cwd": "."
44
44
  },
45
45
  {
46
46
  "name": "awaken-trade-remove-liquidity",
47
47
  "command": "bun run awaken_trade_skill.ts remove-liquidity --token-a {{tokenA}} --token-b {{tokenB}} --lp-amount {{lpAmount}} --fee-rate {{feeRate}}",
48
- "description": "Remove liquidity from an Awaken DEX trading pair. REQUIRES AELF_PRIVATE_KEY env var. Parameters: --token-a and --token-b (token symbols), --lp-amount (LP token amount to burn), --fee-rate (pool fee tier, default 0.3). Returns the underlying tokens to your wallet.",
48
+ "description": "Remove liquidity from an Awaken DEX trading pair. Requires wallet env vars (EOA or CA). Parameters: --token-a and --token-b (token symbols), --lp-amount (LP token amount to burn), --fee-rate (pool fee tier, default 0.3). Returns the underlying tokens to your wallet.",
49
49
  "cwd": "."
50
50
  },
51
51
  {
52
52
  "name": "awaken-trade-approve",
53
53
  "command": "bun run awaken_trade_skill.ts approve --symbol {{symbol}} --spender {{spender}} --amount {{amount}}",
54
- "description": "Approve a contract to spend your tokens. REQUIRES AELF_PRIVATE_KEY env var. Parameters: --symbol (token to approve), --spender (contract address), --amount (human-readable amount). Use this before swap/liquidity if you need manual control over approvals.",
54
+ "description": "Approve a contract to spend your tokens. Requires wallet env vars (EOA or CA). Parameters: --symbol (token to approve), --spender (contract address), --amount (human-readable amount). Use this before swap/liquidity if you need manual control over approvals.",
55
55
  "cwd": "."
56
56
  },
57
57
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awaken-finance/agent-kit",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "AI Agent toolkit for Awaken DEX on aelf blockchain — swap tokens, manage liquidity, fetch K-line data. Supports MCP, CLI, and SDK usage.",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -63,6 +63,7 @@
63
63
  "dependencies": {
64
64
  "@microsoft/signalr": "^8.0.0",
65
65
  "@modelcontextprotocol/sdk": "^1.26.0",
66
+ "@portkey/aelf-signer": "^1.0.0",
66
67
  "aelf-sdk": "^3.4.8",
67
68
  "axios": "^1.7.0",
68
69
  "bignumber.js": "^9.1.2",
package/src/core/trade.ts CHANGED
@@ -12,14 +12,12 @@ import {
12
12
  CHANNEL_ID,
13
13
  SWAP_LABS_FEE_RATE,
14
14
  } from '../../lib/config';
15
+ import type { AelfSigner } from '@portkey/aelf-signer';
15
16
  import {
16
- getWalletByPrivateKey,
17
- callSendMethod,
18
17
  callViewMethod,
19
18
  getTokenInfo,
20
19
  getAllowance,
21
20
  approveToken,
22
- getTxResult,
23
21
  timesDecimals,
24
22
  divDecimals,
25
23
  } from '../../lib/aelf-client';
@@ -33,24 +31,23 @@ import type {
33
31
  LiquidityRemoveResult,
34
32
  ApproveParams,
35
33
  ApproveResult,
36
- TxResult,
37
34
  } from '../../lib/types';
38
35
 
39
36
  // ---- Helper: ensure approval ----
40
37
 
41
38
  async function ensureApproval(
42
39
  config: NetworkConfig,
43
- wallet: any,
40
+ signer: AelfSigner,
44
41
  symbol: string,
45
42
  spender: string,
46
43
  requiredAmount: string,
47
44
  ): Promise<void> {
48
- const owner = wallet.address;
45
+ const owner = signer.address;
49
46
  const currentAllowance = await getAllowance(config.rpcUrl, config.tokenContract, symbol, owner, spender);
50
47
 
51
48
  if (new BigNumber(currentAllowance).lt(requiredAmount)) {
52
49
  const approveAmount = new BigNumber(requiredAmount).times(10).toFixed(0);
53
- await approveToken(config, wallet, symbol, spender, approveAmount);
50
+ await approveToken(config, signer, symbol, spender, approveAmount);
54
51
  }
55
52
  }
56
53
 
@@ -58,10 +55,10 @@ async function ensureApproval(
58
55
 
59
56
  export async function executeSwap(
60
57
  config: NetworkConfig,
61
- wallet: any,
58
+ signer: AelfSigner,
62
59
  params: SwapParams,
63
60
  ): Promise<SwapResult> {
64
- const account = wallet.address;
61
+ const account = signer.address;
65
62
  const slippage = params.slippage || DEFAULT_SLIPPAGE;
66
63
 
67
64
  // 1. Get token info
@@ -109,28 +106,23 @@ export async function executeSwap(
109
106
  const swapHookAddress = config.swapHookContract;
110
107
 
111
108
  // 5. Approve input token to swap hook contract
112
- await ensureApproval(config, wallet, params.symbolIn, swapHookAddress, rawAmountIn);
109
+ await ensureApproval(config, signer, params.symbolIn, swapHookAddress, rawAmountIn);
113
110
 
114
- // 6. Execute swap via swap hook contract
115
- const result = await callSendMethod(config.rpcUrl, swapHookAddress, 'SwapExactTokensForTokens', wallet, {
111
+ // 6. Execute swap via signer (EOA: direct sign, CA: ManagerForwardCall)
112
+ const sendResult = await signer.sendContractCall(config.rpcUrl, swapHookAddress, 'SwapExactTokensForTokens', {
116
113
  swapTokens,
117
114
  labsFeeRate: SWAP_LABS_FEE_RATE,
118
115
  });
119
116
 
120
- const txId = result?.TransactionId || result?.transactionId;
121
- if (!txId) throw new Error('Swap failed: no transactionId returned');
122
-
123
- const txResult = await getTxResult(config.rpcUrl, txId);
124
-
125
117
  return {
126
- transactionId: txResult.transactionId,
127
- status: txResult.status,
118
+ transactionId: sendResult.transactionId,
119
+ status: (sendResult.txResult.Status || 'mined').toLowerCase(),
128
120
  symbolIn: params.symbolIn,
129
121
  symbolOut: params.symbolOut,
130
122
  amountIn: params.amountIn,
131
123
  estimatedAmountOut: divDecimals(rawAmountOut, tokenOutInfo.decimals).toFixed(),
132
124
  minAmountOut: divDecimals(amountOutMin, tokenOutInfo.decimals).toFixed(),
133
- explorerUrl: `${config.explorerUrl}/tx/${txResult.transactionId}`,
125
+ explorerUrl: `${config.explorerUrl}/tx/${sendResult.transactionId}`,
134
126
  };
135
127
  }
136
128
 
@@ -138,10 +130,10 @@ export async function executeSwap(
138
130
 
139
131
  export async function addLiquidity(
140
132
  config: NetworkConfig,
141
- wallet: any,
133
+ signer: AelfSigner,
142
134
  params: LiquidityAddParams,
143
135
  ): Promise<LiquidityAddResult> {
144
- const account = wallet.address;
136
+ const account = signer.address;
145
137
  const feeRate = params.feeRate || '0.3';
146
138
  const slippage = params.slippage || DEFAULT_SLIPPAGE;
147
139
 
@@ -160,12 +152,12 @@ export async function addLiquidity(
160
152
 
161
153
  // Approve both tokens
162
154
  await Promise.all([
163
- ensureApproval(config, wallet, params.tokenA, routerAddress, rawAmountA),
164
- ensureApproval(config, wallet, params.tokenB, routerAddress, rawAmountB),
155
+ ensureApproval(config, signer, params.tokenA, routerAddress, rawAmountA),
156
+ ensureApproval(config, signer, params.tokenB, routerAddress, rawAmountB),
165
157
  ]);
166
158
 
167
- // Execute addLiquidity
168
- const result = await callSendMethod(config.rpcUrl, routerAddress, 'AddLiquidity', wallet, {
159
+ // Execute addLiquidity via signer
160
+ const sendResult = await signer.sendContractCall(config.rpcUrl, routerAddress, 'AddLiquidity', {
169
161
  symbolA: params.tokenA,
170
162
  symbolB: params.tokenB,
171
163
  amountADesired: rawAmountA,
@@ -177,20 +169,15 @@ export async function addLiquidity(
177
169
  channel: CHANNEL_ID,
178
170
  });
179
171
 
180
- const txId = result?.TransactionId || result?.transactionId;
181
- if (!txId) throw new Error('Add liquidity failed: no transactionId');
182
-
183
- const txResult = await getTxResult(config.rpcUrl, txId);
184
-
185
172
  return {
186
- transactionId: txResult.transactionId,
187
- status: txResult.status,
173
+ transactionId: sendResult.transactionId,
174
+ status: (sendResult.txResult.Status || 'mined').toLowerCase(),
188
175
  tokenA: params.tokenA,
189
176
  tokenB: params.tokenB,
190
177
  amountA: params.amountA,
191
178
  amountB: params.amountB,
192
179
  feeRate,
193
- explorerUrl: `${config.explorerUrl}/tx/${txResult.transactionId}`,
180
+ explorerUrl: `${config.explorerUrl}/tx/${sendResult.transactionId}`,
194
181
  };
195
182
  }
196
183
 
@@ -198,10 +185,10 @@ export async function addLiquidity(
198
185
 
199
186
  export async function removeLiquidity(
200
187
  config: NetworkConfig,
201
- wallet: any,
188
+ signer: AelfSigner,
202
189
  params: LiquidityRemoveParams,
203
190
  ): Promise<LiquidityRemoveResult> {
204
- const account = wallet.address;
191
+ const account = signer.address;
205
192
  const feeRate = params.feeRate || '0.3';
206
193
 
207
194
  const LP_DECIMALS = 8;
@@ -221,16 +208,15 @@ export async function removeLiquidity(
221
208
  spender: routerAddress,
222
209
  });
223
210
  if (new BigNumber(currentAllowance?.allowance ?? '0').lt(rawLiquidity)) {
224
- const approveResult = await callSendMethod(config.rpcUrl, factoryAddress, 'Approve', wallet, {
211
+ await signer.sendContractCall(config.rpcUrl, factoryAddress, 'Approve', {
225
212
  symbol: lpSymbol,
226
213
  spender: routerAddress,
227
214
  amount: new BigNumber(rawLiquidity).times(10).toFixed(0),
228
215
  });
229
- const approveTxId = approveResult?.TransactionId || approveResult?.transactionId;
230
- if (approveTxId) await getTxResult(config.rpcUrl, approveTxId);
231
216
  }
232
217
 
233
- const result = await callSendMethod(config.rpcUrl, routerAddress, 'RemoveLiquidity', wallet, {
218
+ // Remove liquidity via signer
219
+ const sendResult = await signer.sendContractCall(config.rpcUrl, routerAddress, 'RemoveLiquidity', {
234
220
  symbolA: params.tokenA,
235
221
  symbolB: params.tokenB,
236
222
  amountAMin: '1',
@@ -240,18 +226,13 @@ export async function removeLiquidity(
240
226
  deadline: { seconds: getDeadline(), nanos: 0 },
241
227
  });
242
228
 
243
- const txId = result?.TransactionId || result?.transactionId;
244
- if (!txId) throw new Error('Remove liquidity failed: no transactionId');
245
-
246
- const txResult = await getTxResult(config.rpcUrl, txId);
247
-
248
229
  return {
249
- transactionId: txResult.transactionId,
250
- status: txResult.status,
230
+ transactionId: sendResult.transactionId,
231
+ status: (sendResult.txResult.Status || 'mined').toLowerCase(),
251
232
  tokenA: params.tokenA,
252
233
  tokenB: params.tokenB,
253
234
  lpAmount: params.lpAmount,
254
- explorerUrl: `${config.explorerUrl}/tx/${txResult.transactionId}`,
235
+ explorerUrl: `${config.explorerUrl}/tx/${sendResult.transactionId}`,
255
236
  };
256
237
  }
257
238
 
@@ -259,13 +240,13 @@ export async function removeLiquidity(
259
240
 
260
241
  export async function approveTokenSpending(
261
242
  config: NetworkConfig,
262
- wallet: any,
243
+ signer: AelfSigner,
263
244
  params: ApproveParams,
264
245
  ): Promise<ApproveResult> {
265
246
  const tokenInfo = await getTokenInfo(config.rpcUrl, config.tokenContract, params.symbol);
266
247
  const rawAmount = timesDecimals(params.amount, tokenInfo.decimals).toFixed(0);
267
248
 
268
- const txResult = await approveToken(config, wallet, params.symbol, params.spender, rawAmount);
249
+ const txResult = await approveToken(config, signer, params.symbol, params.spender, rawAmount);
269
250
 
270
251
  return {
271
252
  transactionId: txResult.transactionId,
package/src/mcp/server.ts CHANGED
@@ -12,8 +12,8 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
12
12
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
13
13
  import { z } from 'zod';
14
14
 
15
+ import { createSignerFromEnv } from '@portkey/aelf-signer';
15
16
  import { getNetworkConfig } from '../../lib/config';
16
- import { getWalletByPrivateKey } from '../../lib/aelf-client';
17
17
  import { getQuote, getPair, getTokenBalance, getTokenAllowance, getLiquidityPositions } from '../core/query';
18
18
  import { executeSwap, addLiquidity, removeLiquidity, approveTokenSpending } from '../core/trade';
19
19
  import { fetchKline, getKlineIntervals } from '../core/kline';
@@ -151,14 +151,14 @@ server.registerTool(
151
151
  );
152
152
 
153
153
  // ============================================================
154
- // Trade Tools (require AELF_PRIVATE_KEY env var)
154
+ // Trade Tools (require AELF_PRIVATE_KEY or PORTKEY_PRIVATE_KEY + CA env vars)
155
155
  // ============================================================
156
156
 
157
157
  server.registerTool(
158
158
  'awaken_swap',
159
159
  {
160
160
  description:
161
- 'Execute a token swap on Awaken DEX. REQUIRES AELF_PRIVATE_KEY env var. Sends a real on-chain transaction. Auto-queries the best route, approves if needed, and executes the swap. Returns transactionId, estimated amounts, explorer URL.',
161
+ 'Execute a token swap on Awaken DEX. Requires wallet env vars (AELF_PRIVATE_KEY for EOA, or PORTKEY_PRIVATE_KEY + PORTKEY_CA_HASH + PORTKEY_CA_ADDRESS for CA). Sends a real on-chain transaction. Auto-queries the best route, approves if needed, and executes the swap. Returns transactionId, estimated amounts, explorer URL.',
162
162
  inputSchema: {
163
163
  symbolIn: z.string().describe('Token to sell (e.g. ELF)'),
164
164
  symbolOut: z.string().describe('Token to buy (e.g. USDT)'),
@@ -170,8 +170,8 @@ server.registerTool(
170
170
  async ({ symbolIn, symbolOut, amountIn, slippage, network }) => {
171
171
  try {
172
172
  const config = getNetworkConfig(network);
173
- const wallet = getWalletByPrivateKey();
174
- const result = await executeSwap(config, wallet, { symbolIn, symbolOut, amountIn, slippage });
173
+ const signer = createSignerFromEnv();
174
+ const result = await executeSwap(config, signer, { symbolIn, symbolOut, amountIn, slippage });
175
175
  return ok(result);
176
176
  } catch (err) {
177
177
  return fail(err);
@@ -183,7 +183,7 @@ server.registerTool(
183
183
  'awaken_add_liquidity',
184
184
  {
185
185
  description:
186
- 'Add liquidity to an Awaken DEX trading pair. REQUIRES AELF_PRIVATE_KEY env var. Auto-approves both tokens before adding.',
186
+ 'Add liquidity to an Awaken DEX trading pair. Requires wallet env vars (EOA or CA). Auto-approves both tokens before adding.',
187
187
  inputSchema: {
188
188
  tokenA: z.string().describe('Token A symbol (e.g. ELF)'),
189
189
  tokenB: z.string().describe('Token B symbol (e.g. USDT)'),
@@ -197,8 +197,8 @@ server.registerTool(
197
197
  async ({ tokenA, tokenB, amountA, amountB, feeRate, slippage, network }) => {
198
198
  try {
199
199
  const config = getNetworkConfig(network);
200
- const wallet = getWalletByPrivateKey();
201
- const result = await addLiquidity(config, wallet, { tokenA, tokenB, amountA, amountB, feeRate, slippage });
200
+ const signer = createSignerFromEnv();
201
+ const result = await addLiquidity(config, signer, { tokenA, tokenB, amountA, amountB, feeRate, slippage });
202
202
  return ok(result);
203
203
  } catch (err) {
204
204
  return fail(err);
@@ -210,7 +210,7 @@ server.registerTool(
210
210
  'awaken_remove_liquidity',
211
211
  {
212
212
  description:
213
- 'Remove liquidity from an Awaken DEX trading pair. REQUIRES AELF_PRIVATE_KEY env var. Returns the underlying tokens to your wallet.',
213
+ 'Remove liquidity from an Awaken DEX trading pair. Requires wallet env vars (EOA or CA). Returns the underlying tokens to your wallet.',
214
214
  inputSchema: {
215
215
  tokenA: z.string().describe('Token A symbol'),
216
216
  tokenB: z.string().describe('Token B symbol'),
@@ -222,8 +222,8 @@ server.registerTool(
222
222
  async ({ tokenA, tokenB, lpAmount, feeRate, network }) => {
223
223
  try {
224
224
  const config = getNetworkConfig(network);
225
- const wallet = getWalletByPrivateKey();
226
- const result = await removeLiquidity(config, wallet, { tokenA, tokenB, lpAmount, feeRate });
225
+ const signer = createSignerFromEnv();
226
+ const result = await removeLiquidity(config, signer, { tokenA, tokenB, lpAmount, feeRate });
227
227
  return ok(result);
228
228
  } catch (err) {
229
229
  return fail(err);
@@ -235,7 +235,7 @@ server.registerTool(
235
235
  'awaken_approve',
236
236
  {
237
237
  description:
238
- 'Approve a contract to spend your tokens. REQUIRES AELF_PRIVATE_KEY env var. Use this before swap/liquidity if you need manual control over approvals.',
238
+ 'Approve a contract to spend your tokens. Requires wallet env vars (EOA or CA). Use this before swap/liquidity if you need manual control over approvals.',
239
239
  inputSchema: {
240
240
  symbol: z.string().describe('Token to approve (e.g. ELF)'),
241
241
  spender: z.string().describe('Contract address to approve'),
@@ -246,8 +246,8 @@ server.registerTool(
246
246
  async ({ symbol, spender, amount, network }) => {
247
247
  try {
248
248
  const config = getNetworkConfig(network);
249
- const wallet = getWalletByPrivateKey();
250
- const result = await approveTokenSpending(config, wallet, { symbol, spender, amount });
249
+ const signer = createSignerFromEnv();
250
+ const result = await approveTokenSpending(config, signer, { symbol, spender, amount });
251
251
  return ok(result);
252
252
  } catch (err) {
253
253
  return fail(err);