@portkey/eoa-agent-skills 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Portkey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # @portkey/eoa-agent-skills
2
+
3
+ AI Agent Skills for Portkey EOA Wallet on [aelf blockchain](https://aelf.com). Provides MCP, CLI, and SDK interfaces for wallet management, token transfers, asset queries, and smart contract interactions.
4
+
5
+ ## Features
6
+
7
+ - **Wallet Management**: Create, import, list, and backup EOA wallets with AES-encrypted local storage
8
+ - **Token Queries**: Check balances, prices, and token lists across aelf chains
9
+ - **NFT Queries**: Browse NFT collections and items
10
+ - **Transaction History**: Query and inspect past transactions
11
+ - **Token Transfers**: Same-chain and cross-chain transfers within aelf
12
+ - **Contract Interactions**: Generic view/send calls, approve, fee estimation
13
+ - **eBridge**: Cross-chain transfers between aelf and EVM chains
14
+
15
+ ## Consumption Modes
16
+
17
+ | Mode | Entry | Use Case |
18
+ |------|-------|----------|
19
+ | **MCP** | `src/mcp/server.ts` | Claude Desktop, Cursor, GPT, and other AI tools |
20
+ | **CLI** | `portkey_eoa_skill.ts` | Terminal scripts, OpenClaw |
21
+ | **SDK** | `index.ts` | LangChain, LlamaIndex, custom agents |
22
+
23
+ ## Quick Start
24
+
25
+ ### Install
26
+
27
+ ```bash
28
+ bun install
29
+ ```
30
+
31
+ ### One-Click Setup
32
+
33
+ ```bash
34
+ # Claude Desktop
35
+ bun run bin/setup.ts claude
36
+
37
+ # Cursor (project-level)
38
+ bun run bin/setup.ts cursor
39
+
40
+ # Cursor (global)
41
+ bun run bin/setup.ts cursor --global
42
+
43
+ # OpenClaw (output config)
44
+ bun run bin/setup.ts openclaw
45
+
46
+ # OpenClaw (merge into existing config)
47
+ bun run bin/setup.ts openclaw --config-path /path/to/openclaw-config.json
48
+
49
+ # Check status
50
+ bun run bin/setup.ts list
51
+ ```
52
+
53
+ ### Environment Variables
54
+
55
+ ```bash
56
+ cp .env.example .env
57
+ # Edit .env with your values
58
+ ```
59
+
60
+ | Variable | Description | Default |
61
+ |----------|-------------|---------|
62
+ | `PORTKEY_NETWORK` | `mainnet` | `mainnet` |
63
+ | `PORTKEY_API_URL` | Override API base URL | Auto from network |
64
+ | `PORTKEY_PRIVATE_KEY` | Plaintext private key (optional) | — |
65
+ | `PORTKEY_WALLET_DIR` | Custom wallet storage directory | `~/.portkey-agent/wallets/` |
66
+ | `PORTKEY_WALLET_PASSWORD` | Password for local wallet encryption | — |
67
+
68
+ ### MCP Server
69
+
70
+ ```bash
71
+ bun run src/mcp/server.ts
72
+ ```
73
+
74
+ Or add to your MCP client config (see `mcp-config.example.json`):
75
+
76
+ ```json
77
+ {
78
+ "mcpServers": {
79
+ "portkey-eoa-agent-skills": {
80
+ "command": "bun",
81
+ "args": ["run", "/path/to/src/mcp/server.ts"],
82
+ "env": {
83
+ "PORTKEY_NETWORK": "mainnet",
84
+ "PORTKEY_WALLET_PASSWORD": "your_password"
85
+ }
86
+ }
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### CLI Usage
92
+
93
+ ```bash
94
+ # Wallet
95
+ bun run portkey_eoa_skill.ts wallet create --password mypass
96
+ bun run portkey_eoa_skill.ts wallet list
97
+ bun run portkey_eoa_skill.ts wallet import --mnemonic "word1 word2 ..." --password mypass
98
+
99
+ # Queries
100
+ bun run portkey_eoa_skill.ts query tokens --address YOUR_ADDRESS
101
+ bun run portkey_eoa_skill.ts query balance --address YOUR_ADDRESS --symbol ELF --chain-id AELF
102
+ bun run portkey_eoa_skill.ts query price --symbols ELF,USDT
103
+ bun run portkey_eoa_skill.ts query history --address YOUR_ADDRESS
104
+ bun run portkey_eoa_skill.ts query chains
105
+
106
+ # Transfer
107
+ bun run portkey_eoa_skill.ts transfer --to RECIPIENT --symbol ELF --amount 100000000 --chain-id AELF
108
+
109
+ # Contract
110
+ bun run portkey_eoa_skill.ts contract view --contract-address ADDR --method GetBalance --params '{"symbol":"ELF","owner":"..."}' --chain-id AELF
111
+ ```
112
+
113
+ ### SDK Usage
114
+
115
+ ```typescript
116
+ import { getConfig, createWallet, getTokenList, transfer } from '@portkey/eoa-agent-skills';
117
+
118
+ const config = getConfig('mainnet');
119
+
120
+ // Create wallet
121
+ const wallet = await createWallet(config, { password: 'mypass' });
122
+ console.log('Address:', wallet.address);
123
+
124
+ // Query tokens
125
+ const tokens = await getTokenList(config, { address: wallet.address });
126
+ console.log('Tokens:', tokens.data);
127
+
128
+ // Transfer
129
+ const result = await transfer(config, {
130
+ privateKey: 'YOUR_PRIVATE_KEY',
131
+ to: 'RECIPIENT_ADDRESS',
132
+ symbol: 'ELF',
133
+ amount: '100000000',
134
+ chainId: 'AELF',
135
+ });
136
+ console.log('TX:', result.transactionId);
137
+ ```
138
+
139
+ ## MCP Tools (20 total)
140
+
141
+ ### Wallet Management (5)
142
+ - `portkey_create_wallet` — Create new wallet with encrypted local storage
143
+ - `portkey_import_wallet` — Import from mnemonic or private key
144
+ - `portkey_get_wallet_info` — View wallet public info
145
+ - `portkey_list_wallets` — List all local wallets
146
+ - `portkey_backup_wallet` — Export wallet credentials
147
+
148
+ ### Asset Queries (7)
149
+ - `portkey_get_token_list` — Token portfolio with balances
150
+ - `portkey_get_token_balance` — Single token balance
151
+ - `portkey_get_token_prices` — Token USD prices
152
+ - `portkey_get_nft_collections` — NFT collection list
153
+ - `portkey_get_nft_items` — NFT items in collection
154
+ - `portkey_get_transaction_history` — Transaction history
155
+ - `portkey_get_transaction_detail` — Single transaction detail
156
+
157
+ ### Transfers (2)
158
+ - `portkey_transfer` — Same-chain token transfer
159
+ - `portkey_cross_chain_transfer` — Cross-chain aelf transfer
160
+
161
+ ### Contract (4)
162
+ - `portkey_approve` — Token spending approval
163
+ - `portkey_call_view_method` — Generic contract read
164
+ - `portkey_call_send_method` — Generic contract write
165
+ - `portkey_estimate_fee` — Transaction fee estimation
166
+
167
+ ### eBridge (2)
168
+ - `portkey_ebridge_transfer` — eBridge cross-chain transfer
169
+ - `portkey_ebridge_info` — eBridge limits and fees
170
+
171
+ ## Architecture
172
+
173
+ ```
174
+ index.ts (SDK) ─┐
175
+ server.ts (MCP) ─┼─> src/core/ ──> lib/
176
+ skill.ts (CLI) ─┘ (pure logic) (infra)
177
+ ```
178
+
179
+ Three adapters call the same core functions — zero duplicated logic.
180
+
181
+ ## Testing
182
+
183
+ ```bash
184
+ bun test # All tests
185
+ bun test tests/unit/ # Unit tests
186
+ bun run tests/e2e/mcp-verify.ts # MCP verification
187
+ ```
188
+
189
+ ## License
190
+
191
+ MIT
@@ -0,0 +1,191 @@
1
+ # @portkey/eoa-agent-skills
2
+
3
+ [aelf 区块链](https://aelf.com) 上 Portkey EOA 钱包的 AI Agent Skills。提供 MCP、CLI 和 SDK 三种接口,覆盖钱包管理、Token 转账、资产查询和智能合约交互。
4
+
5
+ ## 功能
6
+
7
+ - **钱包管理**:创建、导入、列表、备份 EOA 钱包,本地 AES 加密存储
8
+ - **Token 查询**:查询余额、价格、Token 列表(跨链)
9
+ - **NFT 查询**:浏览 NFT Collection 和具体 Item
10
+ - **交易历史**:查询和检索历史交易
11
+ - **Token 转账**:aelf 同链和跨链转账
12
+ - **合约交互**:通用 view/send 调用、Approve、手续费预估
13
+ - **eBridge**:aelf 与 EVM 链之间的跨链转账
14
+
15
+ ## 消费方式
16
+
17
+ | 模式 | 入口 | 适用场景 |
18
+ |------|------|---------|
19
+ | **MCP** | `src/mcp/server.ts` | Claude Desktop、Cursor、GPT 等 AI 工具 |
20
+ | **CLI** | `portkey_eoa_skill.ts` | 终端脚本、OpenClaw |
21
+ | **SDK** | `index.ts` | LangChain、LlamaIndex、自定义 Agent |
22
+
23
+ ## 快速开始
24
+
25
+ ### 安装
26
+
27
+ ```bash
28
+ bun install
29
+ ```
30
+
31
+ ### 一键配置
32
+
33
+ ```bash
34
+ # Claude Desktop
35
+ bun run bin/setup.ts claude
36
+
37
+ # Cursor(项目级)
38
+ bun run bin/setup.ts cursor
39
+
40
+ # Cursor(全局)
41
+ bun run bin/setup.ts cursor --global
42
+
43
+ # OpenClaw(输出配置)
44
+ bun run bin/setup.ts openclaw
45
+
46
+ # OpenClaw(合并到已有配置文件)
47
+ bun run bin/setup.ts openclaw --config-path /path/to/openclaw-config.json
48
+
49
+ # 查看配置状态
50
+ bun run bin/setup.ts list
51
+ ```
52
+
53
+ ### 环境变量
54
+
55
+ ```bash
56
+ cp .env.example .env
57
+ # 编辑 .env 填入你的配置
58
+ ```
59
+
60
+ | 变量 | 说明 | 默认值 |
61
+ |------|------|--------|
62
+ | `PORTKEY_NETWORK` | `mainnet` | `mainnet` |
63
+ | `PORTKEY_API_URL` | 覆盖 API 基础 URL | 根据网络自动选择 |
64
+ | `PORTKEY_PRIVATE_KEY` | 明文私钥(可选) | — |
65
+ | `PORTKEY_WALLET_DIR` | 自定义钱包存储目录 | `~/.portkey-agent/wallets/` |
66
+ | `PORTKEY_WALLET_PASSWORD` | 本地钱包加密密码 | — |
67
+
68
+ ### MCP Server
69
+
70
+ ```bash
71
+ bun run src/mcp/server.ts
72
+ ```
73
+
74
+ 或添加到你的 MCP 客户端配置(参见 `mcp-config.example.json`):
75
+
76
+ ```json
77
+ {
78
+ "mcpServers": {
79
+ "portkey-eoa-agent-skills": {
80
+ "command": "bun",
81
+ "args": ["run", "/path/to/src/mcp/server.ts"],
82
+ "env": {
83
+ "PORTKEY_NETWORK": "mainnet",
84
+ "PORTKEY_WALLET_PASSWORD": "your_password"
85
+ }
86
+ }
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### CLI 使用
92
+
93
+ ```bash
94
+ # 钱包
95
+ bun run portkey_eoa_skill.ts wallet create --password mypass
96
+ bun run portkey_eoa_skill.ts wallet list
97
+ bun run portkey_eoa_skill.ts wallet import --mnemonic "word1 word2 ..." --password mypass
98
+
99
+ # 查询
100
+ bun run portkey_eoa_skill.ts query tokens --address 你的地址
101
+ bun run portkey_eoa_skill.ts query balance --address 你的地址 --symbol ELF --chain-id AELF
102
+ bun run portkey_eoa_skill.ts query price --symbols ELF,USDT
103
+ bun run portkey_eoa_skill.ts query history --address 你的地址
104
+ bun run portkey_eoa_skill.ts query chains
105
+
106
+ # 转账
107
+ bun run portkey_eoa_skill.ts transfer --to 收款地址 --symbol ELF --amount 100000000 --chain-id AELF
108
+
109
+ # 合约调用
110
+ bun run portkey_eoa_skill.ts contract view --contract-address 合约地址 --method GetBalance --params '{"symbol":"ELF","owner":"..."}' --chain-id AELF
111
+ ```
112
+
113
+ ### SDK 使用
114
+
115
+ ```typescript
116
+ import { getConfig, createWallet, getTokenList, transfer } from '@portkey/eoa-agent-skills';
117
+
118
+ const config = getConfig('mainnet');
119
+
120
+ // 创建钱包
121
+ const wallet = await createWallet(config, { password: 'mypass' });
122
+ console.log('地址:', wallet.address);
123
+
124
+ // 查询 Token
125
+ const tokens = await getTokenList(config, { address: wallet.address });
126
+ console.log('Tokens:', tokens.data);
127
+
128
+ // 转账
129
+ const result = await transfer(config, {
130
+ privateKey: '你的私钥',
131
+ to: '收款地址',
132
+ symbol: 'ELF',
133
+ amount: '100000000',
134
+ chainId: 'AELF',
135
+ });
136
+ console.log('交易ID:', result.transactionId);
137
+ ```
138
+
139
+ ## MCP Tools(共 20 个)
140
+
141
+ ### 钱包管理(5)
142
+ - `portkey_create_wallet` — 创建新钱包并加密存储
143
+ - `portkey_import_wallet` — 导入钱包(助记词/私钥)
144
+ - `portkey_get_wallet_info` — 查看钱包公开信息
145
+ - `portkey_list_wallets` — 列出所有本地钱包
146
+ - `portkey_backup_wallet` — 导出钱包凭证
147
+
148
+ ### 资产查询(7)
149
+ - `portkey_get_token_list` — Token 列表和余额
150
+ - `portkey_get_token_balance` — 单个 Token 余额
151
+ - `portkey_get_token_prices` — Token USD 价格
152
+ - `portkey_get_nft_collections` — NFT Collection 列表
153
+ - `portkey_get_nft_items` — Collection 内的 NFT
154
+ - `portkey_get_transaction_history` — 交易历史
155
+ - `portkey_get_transaction_detail` — 单笔交易详情
156
+
157
+ ### 转账(2)
158
+ - `portkey_transfer` — 同链 Token 转账
159
+ - `portkey_cross_chain_transfer` — aelf 跨链转账
160
+
161
+ ### 合约(4)
162
+ - `portkey_approve` — Token 授权
163
+ - `portkey_call_view_method` — 通用合约只读调用
164
+ - `portkey_call_send_method` — 通用合约写调用
165
+ - `portkey_estimate_fee` — 交易手续费预估
166
+
167
+ ### eBridge(2)
168
+ - `portkey_ebridge_transfer` — eBridge 跨链转账
169
+ - `portkey_ebridge_info` — eBridge 限额和手续费
170
+
171
+ ## 架构
172
+
173
+ ```
174
+ index.ts (SDK) ─┐
175
+ server.ts (MCP) ─┼─> src/core/ ──> lib/
176
+ skill.ts (CLI) ─┘ (纯逻辑) (基础设施)
177
+ ```
178
+
179
+ 三个适配器调用同一套 Core 函数——零重复逻辑。
180
+
181
+ ## 测试
182
+
183
+ ```bash
184
+ bun test # 所有测试
185
+ bun test tests/unit/ # 单元测试
186
+ bun run tests/e2e/mcp-verify.ts # MCP 验证
187
+ ```
188
+
189
+ ## License
190
+
191
+ MIT
@@ -0,0 +1,54 @@
1
+ import {
2
+ getPlatformPaths,
3
+ readJsonFile,
4
+ writeJsonFile,
5
+ mergeMcpConfig,
6
+ removeMcpConfig,
7
+ generateMcpEntry,
8
+ SERVER_NAME,
9
+ } from './utils.js';
10
+
11
+ export function setupClaude(opts: {
12
+ configPath?: string;
13
+ serverPath?: string;
14
+ force?: boolean;
15
+ }) {
16
+ const paths = getPlatformPaths();
17
+ const configPath = opts.configPath || paths.claude;
18
+ const existing = readJsonFile(configPath);
19
+ const entry = generateMcpEntry(opts.serverPath);
20
+ const { config, action } = mergeMcpConfig(
21
+ existing,
22
+ SERVER_NAME,
23
+ entry,
24
+ opts.force,
25
+ );
26
+
27
+ if (action === 'skipped') {
28
+ console.log(
29
+ `[SKIP] "${SERVER_NAME}" already exists in ${configPath}. Use --force to overwrite.`,
30
+ );
31
+ return;
32
+ }
33
+
34
+ writeJsonFile(configPath, config);
35
+ console.log(`[${action.toUpperCase()}] Claude Desktop config → ${configPath}`);
36
+ console.log(
37
+ '\nRemember to replace <YOUR_PRIVATE_KEY> and <YOUR_WALLET_PASSWORD> in the config.',
38
+ );
39
+ }
40
+
41
+ export function uninstallClaude(opts: { configPath?: string }) {
42
+ const paths = getPlatformPaths();
43
+ const configPath = opts.configPath || paths.claude;
44
+ const existing = readJsonFile(configPath);
45
+ const { config, removed } = removeMcpConfig(existing, SERVER_NAME);
46
+
47
+ if (!removed) {
48
+ console.log(`[SKIP] "${SERVER_NAME}" not found in ${configPath}`);
49
+ return;
50
+ }
51
+
52
+ writeJsonFile(configPath, config);
53
+ console.log(`[REMOVED] "${SERVER_NAME}" from ${configPath}`);
54
+ }
@@ -0,0 +1,63 @@
1
+ import {
2
+ getPlatformPaths,
3
+ readJsonFile,
4
+ writeJsonFile,
5
+ mergeMcpConfig,
6
+ removeMcpConfig,
7
+ generateMcpEntry,
8
+ SERVER_NAME,
9
+ } from './utils.js';
10
+
11
+ export function setupCursor(opts: {
12
+ global?: boolean;
13
+ configPath?: string;
14
+ serverPath?: string;
15
+ force?: boolean;
16
+ }) {
17
+ const paths = getPlatformPaths();
18
+ const configPath =
19
+ opts.configPath || (opts.global ? paths.cursorGlobal : paths.cursorProject);
20
+ const existing = readJsonFile(configPath);
21
+ const entry = generateMcpEntry(opts.serverPath);
22
+ const { config, action } = mergeMcpConfig(
23
+ existing,
24
+ SERVER_NAME,
25
+ entry,
26
+ opts.force,
27
+ );
28
+
29
+ if (action === 'skipped') {
30
+ console.log(
31
+ `[SKIP] "${SERVER_NAME}" already exists in ${configPath}. Use --force to overwrite.`,
32
+ );
33
+ return;
34
+ }
35
+
36
+ writeJsonFile(configPath, config);
37
+ const scope = opts.global ? 'global' : 'project-level';
38
+ console.log(
39
+ `[${action.toUpperCase()}] Cursor ${scope} config → ${configPath}`,
40
+ );
41
+ console.log(
42
+ '\nRemember to replace <YOUR_PRIVATE_KEY> and <YOUR_WALLET_PASSWORD> in the config.',
43
+ );
44
+ }
45
+
46
+ export function uninstallCursor(opts: {
47
+ global?: boolean;
48
+ configPath?: string;
49
+ }) {
50
+ const paths = getPlatformPaths();
51
+ const configPath =
52
+ opts.configPath || (opts.global ? paths.cursorGlobal : paths.cursorProject);
53
+ const existing = readJsonFile(configPath);
54
+ const { config, removed } = removeMcpConfig(existing, SERVER_NAME);
55
+
56
+ if (!removed) {
57
+ console.log(`[SKIP] "${SERVER_NAME}" not found in ${configPath}`);
58
+ return;
59
+ }
60
+
61
+ writeJsonFile(configPath, config);
62
+ console.log(`[REMOVED] "${SERVER_NAME}" from ${configPath}`);
63
+ }
@@ -0,0 +1,57 @@
1
+ import * as path from 'path';
2
+ import * as fs from 'fs';
3
+ import {
4
+ getPackageRoot,
5
+ readJsonFile,
6
+ writeJsonFile,
7
+ } from './utils.js';
8
+
9
+ export function setupOpenclaw(opts: {
10
+ configPath?: string;
11
+ cwd?: string;
12
+ force?: boolean;
13
+ }) {
14
+ const pkgRoot = getPackageRoot();
15
+ const openclawSrc = path.join(pkgRoot, 'openclaw.json');
16
+
17
+ if (!fs.existsSync(openclawSrc)) {
18
+ console.log('[ERROR] openclaw.json not found in package root');
19
+ return;
20
+ }
21
+
22
+ const openclawConfig = readJsonFile(openclawSrc);
23
+
24
+ // Replace cwd placeholder if specified
25
+ if (opts.cwd) {
26
+ if (openclawConfig.tools) {
27
+ for (const tool of openclawConfig.tools) {
28
+ if (tool.cwd) tool.cwd = opts.cwd;
29
+ }
30
+ }
31
+ }
32
+
33
+ if (opts.configPath) {
34
+ // Merge into existing config
35
+ const existing = readJsonFile(opts.configPath);
36
+ if (!existing.tools) existing.tools = [];
37
+
38
+ const existingNames = new Set(
39
+ existing.tools.map((t: any) => t.name),
40
+ );
41
+ let added = 0;
42
+ for (const tool of openclawConfig.tools || []) {
43
+ if (existingNames.has(tool.name) && !opts.force) continue;
44
+ existing.tools = existing.tools.filter(
45
+ (t: any) => t.name !== tool.name,
46
+ );
47
+ existing.tools.push(tool);
48
+ added++;
49
+ }
50
+
51
+ writeJsonFile(opts.configPath, existing);
52
+ console.log(`[DONE] Merged ${added} tools into ${opts.configPath}`);
53
+ } else {
54
+ // Just output the config
55
+ console.log(JSON.stringify(openclawConfig, null, 2));
56
+ }
57
+ }