1. 项目概述为AI Agent赋能的aelf区块链钱包技能包如果你正在开发一个需要与aelf区块链交互的AI Agent或者你希望让Claude、Cursor这类AI工具能帮你管理数字资产、查询链上数据那么你很可能需要一套标准化的“技能”。portkey/eoa-agent-skills正是为此而生。它是一个专为Portkey EOA钱包设计的AI Agent技能库提供了MCP、CLI和SDK三种标准接口让AI能够安全、便捷地执行钱包创建、资产查询、代币转账、合约调用等一系列链上操作。简单来说这个项目把复杂的区块链交互封装成了AI能直接理解和调用的“工具”。开发者无需从零开始编写与aelf节点通信、处理交易签名、解析合约ABI的底层代码直接引入这个技能包你的AI助手就立刻获得了管理aelf链上资产的能力。这对于构建自动化交易机器人、链上数据分析助手、或是用户友好的资产管理AI界面来说是一个强大的基础设施。2. 核心架构与设计思路拆解2.1 为什么选择“技能包”模式在AI Agent领域一个核心挑战是如何让大语言模型LLM安全、可靠地执行外部操作。直接让模型生成并执行任意代码是危险且不可控的。portkey/eoa-agent-skills采用了“技能”或“工具”模式其设计哲学可以概括为“定义边界提供接口”。定义边界所有可能的链上操作被预先定义为一组有限的、经过严格测试的“技能”如portkey_transfer,portkey_call_view_method。AI Agent只能调用这些明确定义的技能而不能执行范围之外的任意操作这极大地提升了安全性。提供接口每个技能都有清晰的输入参数、输出格式和错误处理。对于MCP模式这符合Model Context Protocol标准对于CLI它是一组命令行参数对于SDK它是一系列TypeScript函数。这种一致性使得技能可以在不同运行时如Claude Desktop、自定义Node.js后端、终端脚本中无缝切换。这种设计将区块链交互的复杂性从AI的“推理逻辑”中剥离出来AI只需要学会“在什么情况下调用哪个技能并传递什么参数”而具体的加密签名、RPC调用、交易构造等细节则由技能包可靠地处理。2.2 三层适配器与统一核心杜绝逻辑重复项目的架构清晰地体现了“关注点分离”的原则。从README中我们可以看到其核心目录结构index.ts (SDK) ─┐ server.ts (MCP) ─┼─ src/core/ ── lib/ portkey_eoa_skill.ts (CLI) ─┘ (纯业务逻辑) (基础设施)src/core/这是项目的心脏。所有与aelf区块链交互的核心业务逻辑都集中在这里例如如何生成一个钱包密钥对、如何构造一笔转账交易、如何查询某个地址的Token余额。这些函数是“纯净”的它们只关心业务逻辑不关心自己被谁调用。适配器层MCP, CLI, SDK这三个入口文件是核心逻辑的三种不同“外壳”。server.ts将核心功能包装成符合MCP标准的工具供Claude等AI工具调用。portkey_eoa_skill.ts将核心功能映射为命令行参数方便在终端或脚本中使用。index.ts将核心功能导出为干净的JavaScript/TypeScript API供开发者直接集成到自己的应用或Agent框架如LangChain中。这种架构的最大优势是维护性。当你需要修复一个转账逻辑的bug时你只需要修改src/core/里的一个函数MCP、CLI、SDK三种使用方式都会自动获得修复彻底避免了同一段逻辑在三个地方重复编写可能带来的不一致性。2.3 钱包安全与状态管理设计处理私钥是区块链应用中最敏感的部分。该项目采用了分层的安全策略本地加密存储通过PORTKEY_WALLET_PASSWORD环境变量设置的密码对钱包的私钥进行AES加密后存储在本地文件系统默认在~/.portkey/eoa/wallets/。这确保了私钥不会以明文形式持久化。运行时隔离私钥仅在执行需要签名的操作如转账时在内存中被短暂解密使用操作完成后立即从内存中清除。跨技能签名上下文这是一个非常实用的设计。当用户通过portkey_create_wallet创建一个钱包后该钱包的地址信息不包含私钥会被写入一个共享的上下文文件~/.portkey/skill-wallet/context.v1.json。这样其他需要知道“当前活跃钱包是哪个”的技能可能来自不同项目可以读取这个文件而执行签名时则通过“显式提供私钥 - 读取上下文找到钱包地址再结合环境变量密码解密 - 直接使用环境变量私钥”的优先级来获取签名权限。这既方便了多技能协作又保证了私钥不出安全边界。3. 三种消费模式详解与选型指南3.1 MCP模式与AI工具深度集成MCP是当前让AI安全使用外部工具最热门的协议。portkey/eoa-agent-skills的MCP服务器让Claude Desktop、Cursor等工具能直接“拥有”区块链能力。配置与激活配置MCP服务器通常需要编辑AI客户端的配置文件。以Claude Desktop为例你需要在其配置目录如~/Library/Application Support/Claude/claude_desktop_config.json中添加如下片段{ mcpServers: { portkey-eoa-agent-skills: { command: bun, args: [run, /ABSOLUTE/PATH/TO/eoa-agent-skills/src/mcp/server.ts], env: { PORTKEY_NETWORK: mainnet, PORTKEY_WALLET_PASSWORD: 你的加密密码 } } } }配置完成后重启Claude Desktop你就可以在对话中直接要求AI“用我的aelf钱包查一下ELF余额”或者“向这个地址转0.1个ELF”。AI会自动识别可用的portkey_get_token_balance或portkey_transfer工具并引导你提供必要的参数如地址、金额最终执行操作。实操心得在配置args路径时务必使用绝对路径。相对路径在MCP服务器启动时可能会因工作目录不同而导致找不到模块。另外PORTKEY_WALLET_PASSWORD是加密本地钱包文件用的如果只是查询操作可以不设置但转账等写操作就必须有了。3.2 CLI模式自动化脚本与快速测试利器CLI模式非常适合编写自动化脚本或进行快速的功能测试。所有功能都通过一个统一的入口脚本portkey_eoa_skill.ts来调用。典型使用场景批量操作你需要给100个空投地址分发代币。可以写一个Shell脚本循环读取地址列表并调用bun run portkey_eoa_skill.ts transfer ...。监控警报结合Cron任务定期运行bun run portkey_eoa_skill.ts query balance ...当余额低于某个阈值时发送通知。CI/CD流程在部署智能合约后自动运行CLI命令调用一个视图方法来验证合约状态。命令结构解析CLI采用了“资源-操作”的结构非常清晰。bun run portkey_eoa_skill.ts 资源 操作 [选项]例如wallet create创建钱包资源。query balance对“查询”资源执行“余额”操作。contract send对“合约”资源执行“发送”写操作。一个复杂的合约调用示例假设你要调用一个共振合约的JoinPairQueue方法这是一个需要支付Gas的写操作。bun run portkey_eoa_skill.ts contract send \ --contract-address 28Lot71VrWm1WxrEjuDqaepywi7gYyZwHysUcztjkHGFsPPrZy \ --method JoinPairQueue \ --params {} \ # 该方法无需参数但需传递空对象 --chain-id tDVV \ # 侧链ID --address YOUR_AELF_ADDRESS \ # 调用者地址 --password YOUR_WALLET_PASSWORD # 解密私钥进行签名注意事项--params参数要求是JSON字符串。对于空参数必须传递{}而不是留空。留空会导致解析错误。对于字符串类型的参数需要额外转义如your_string_value外层单引号是Shell引用内层双引号是JSON字符串标识。3.3 SDK模式自定义AI Agent与后端服务的基石对于想要深度定制或将功能嵌入自己Node.js/TypeScript应用的开发者SDK模式提供了最大的灵活性。你可以在LangChain Agent、LlamaIndex的Tool中直接导入这些函数。基础集成示例import { getConfig, getTokenList, transfer } from portkey/eoa-agent-skills; import { ChatOpenAI } from langchain/openai; import { DynamicStructuredTool } from langchain/core/tools; // 1. 初始化配置 const config getConfig(testnet); // 使用测试网 // 2. 将技能包装成LangChain Tool const tools [ new DynamicStructuredTool({ name: get_aelf_token_balance, description: 获取指定aelf地址的代币余额列表, schema: z.object({ address: z.string().describe(要查询的aelf区块链地址) }), func: async ({ address }) { const result await getTokenList(config, { address }); return JSON.stringify(result.data, null, 2); }, }), new DynamicStructuredTool({ name: transfer_aelf_token, description: 在aelf链上进行代币转账, schema: z.object({ privateKey: z.string().describe(发送者钱包的私钥确保在安全环境中), to: z.string().describe(接收者地址), symbol: z.string().describe(代币符号如ELF), amount: z.string().describe(转账金额以最小单位表示例如1 ELF 100000000), chainId: z.string().describe(链ID如AELF代表主链) }), func: async ({ privateKey, to, symbol, amount, chainId }) { const result await transfer(config, { privateKey, to, symbol, amount, chainId }); return 转账成功交易ID: ${result.transactionId}; }, }) ]; // 3. 创建Agent并运行 const model new ChatOpenAI({}); const agent await createReactAgent({ llm: model, tools }); const result await agent.invoke({ input: 帮我查一下地址2g...有哪些代币然后给地址3x...转0.5个ELF }); console.log(result);SDK模式的优势类型安全项目使用TypeScript开发提供了完整的类型定义在编码时就能获得参数提示和错误检查。组合自由你可以自由组合多个技能调用处理中间结果实现复杂的业务流。错误处理SDK函数返回Promise你可以使用try...catch进行精细的错误处理和重试逻辑。4. 核心功能实操与避坑指南4.1 钱包生命周期管理从创建到备份钱包管理是一切操作的起点。技能包提供了完整的生命周期支持。创建钱包bun run portkey_eoa_skill.ts wallet create --password YourStrongPassword123执行后会生成一个助记词12或24个单词和一个aelf地址。请立即、安全地备份助记词这是恢复钱包的唯一方式。密码用于加密存储本地钱包文件不会上传到任何服务器。导入钱包如果你已有助记词可以导入bun run portkey_eoa_skill.ts wallet import --mnemonic your twelve or twenty four words here --password YourNewPassword重要安全警告切勿在共享环境、不安全的终端历史记录或日志中留下助记词或私钥。--password参数在脚本中最好通过环境变量或安全输入方式传递避免在命令行中明文显示。备份与恢复portkey_backup_wallet工具提供了两种输出明文字段包含address,mnemonic,privateKey。这仅用于一次性查看或导入到其他不支持加密备份的钱包。备份后应从任何不安全介质中删除。加密的walletExport字段这是一个经过加密的字符串可以与密码一起通过portkey_import_wallet工具安全地恢复整个钱包包括本地加密存储的元数据。这是推荐的、更安全的备份方式。4.2 资产查询获取链上数据全景查询功能丰富且高效是构建数据看板或监控系统的基础。查询代币列表与余额portkey_get_token_list是最高效的接口它一次RPC调用就能返回指定地址在所有aelf链主链、侧链上的所有代币及其余额。这对于展示用户资产总览非常有用。查询交易历史portkey_get_transaction_history返回的是交易列表。要获取某笔交易的详细信息如输入输出、日志、状态需要使用portkey_get_transaction_detail并传入交易ID。实操心得aelf的链ID是一个重要概念。主链是AELF不同的侧链有各自的ID如tDVV,tDVW。在进行任何链特定操作查询余额、转账时都必须指定正确的chainId。你可以通过bun run portkey_eoa_skill.ts query chains命令获取所有可用链的信息。4.3 代币转账与跨链操作同链转账使用portkey_transfer。关键参数是amount它需要传入代币的最小单位。例如ELF代币有8位小数所以转账1个ELFamount需要传入100000000。aelf生态内跨链转账使用portkey_cross_chain_transfer。这用于将资产从aelf主链转移到某个侧链或者反之。这个过程涉及跨链桥合约通常需要支付少量ELF作为跨链手续费并且会有一定的确认时间若干个主链区块。通过eBridge进行跨生态转账这是更强大的功能允许资产在aelf链和外部EVM链如以太坊、BSC之间转移。使用portkey_ebridge_transfer。在操作前务必先用portkey_ebridge_info查询目标链的可用性、最小/最大转账金额、以及预估手续费。避坑指南跨链操作无论是aelf内部还是通过eBridge都不是即时到账的。务必在操作后保存好返回的交易ID并使用区块链浏览器或查询工具跟踪状态。eBridge转账通常需要先在源链上授权并锁定资产然后在目标链上领取这是一个两步过程。4.4 智能合约交互视图调用与发送调用这是与DeFi、NFT等去中心化应用交互的核心。技能包将其清晰地分为两类视图调用使用portkey_call_view_method或CLI的contract view。用于读取合约状态不消耗Gas不需要签名。方法识别通常合约中Get开头的方法都是视图方法。参数传递params必须是JSON字符串且其结构必须与合约方法的参数列表完全匹配。例如调用GetBalance方法它需要{“symbol”: “ELF”, “owner”: “address”}那么params就应该是{symbol:ELF,owner:2g...}。发送调用使用portkey_call_send_method或CLI的contract send。用于修改合约状态需要消耗Gas必须由拥有私钥的地址签名。典型场景授权代币Approve、质押Stake、交易Swap。费用估算在发送交易前强烈建议使用portkey_estimate_fee工具预估所需的Gas费用避免因Gas不足导致交易失败。一个常见的交互流程示例参与共振查询队列状态视图调用确认当前是否可以加入。bun run portkey_eoa_skill.ts contract view \ --contract-address [共振合约地址] \ --method GetPairQueueStatus \ --params 你的地址 \ --chain-id tDVV估算费用查看加入队列需要多少Gas。bun run portkey_eoa_skill.ts contract estimate-fee \ --contract-address [共振合约地址] \ --method JoinPairQueue \ --params {} \ --chain-id tDVV \ --address 你的地址执行加入发送调用bun run portkey_eoa_skill.ts contract send \ --contract-address [共振合约地址] \ --method JoinPairQueue \ --params {} \ --chain-id tDVV \ --address 你的地址 \ --password 你的钱包密码5. 环境配置、依赖管理与进阶部署5.1 环境变量详解项目通过环境变量来管理配置提供了灵活性和安全性。.env.example文件是模板。变量名作用与建议默认值PORTKEY_NETWORK指定连接的区块链网络。开发时用testnet生产环境用mainnet。mainnetPORTKEY_API_URL高级选项。覆盖默认的RPC节点URL。如果你有自己的节点或需要连接特定网关可以在这里设置。根据NETWORK自动选择PORTKEY_PRIVATE_KEY慎用。以明文形式设置私钥。这虽然方便尤其对于脚本但存在安全风险。更推荐使用加密的本地钱包文件。空PORTKEY_WALLET_DIR自定义本地加密钱包文件的存储目录。~/.portkey/eoa/wallets/PORTKEY_WALLET_PASSWORD核心安全变量。用于加密/解密本地钱包文件的密码。在MCP服务器或需要访问本地钱包的CLI脚本中必须设置。空PORTKEY_SKILL_WALLET_CONTEXT_PATH覆盖共享的活跃钱包上下文文件路径。用于多技能、多项目共享“当前钱包”状态。~/.portkey/skill-wallet/context.v1.json安全最佳实践永远不要将.env文件或其中包含密码、私钥的内容提交到版本控制系统如Git。应该将.env添加到.gitignore中。在生产服务器上通过Docker secrets、云服务商的环境变量管理或专门的密钥管理服务来设置这些变量。5.2 依赖管理与构建工具项目使用Bun作为主要的运行时和包管理器。Bun以其快速的启动速度和与Node.js良好的兼容性非常适合这类工具类项目。初始化与安装git clone [项目仓库地址] cd eoa-agent-skills bun install # 安装所有依赖运行测试bun test # 运行所有单元测试和集成测试 bun test tests/unit/ # 仅运行单元测试 bun run tests/e2e/mcp-verify.ts # 验证MCP服务器功能是否正常关于上游依赖漏洞README中提到了一个已知问题aelf-sdk依赖的elliptic库存在一个低危漏洞。这是一个上游依赖问题。对于大多数非金融核心应用这个风险是可控的。你可以通过bun audit命令查看详情并关注项目仓库的更新等待上游aelf-sdk升级其依赖后本项目也会随之更新。5.3 IronClaw WASM原生工具部署这是为追求极致性能和无依赖部署的进阶场景准备的。它将核心逻辑用Rust编写并编译为WebAssembly可以直接在IronClaw运行时中执行。本地构建与测试流程构建WASM模块bun run ironclaw:wasm:build。这个命令会调用Rust工具链编译位于ironclaw-wasm/目录下的原生代码。打包发布包bun run ironclaw:wasm:bundle。将编译好的.wasm文件和能力描述文件打包成IronClaw可识别的格式。本地安装ironclaw tool install ./artifacts/ironclaw/portkey-eoa-ironclaw.wasm。将工具安装到你的本地IronClaw环境中。关键注意事项状态隔离当前IronClaw WASM版本的钱包存储状态与Bun/Node.js版本的MCP/CLI/SDK是隔离的。这意味着你在MCP中创建的钱包在IronClaw工具中无法直接使用需要重新导入或创建。能力对等WASM版本实现了全部23个工具功能上是完备的。部署路径生产环境部署时应从GitHub Releases下载版本化的.tar.gz包进行安装而不是直接从源码构建。ClawHub主要作为发现和安装引导入口。6. 常见问题排查与实战技巧6.1 交易失败问题排查交易失败是开发中最常遇到的问题可以按以下步骤排查检查网络和地址确认PORTKEY_NETWORK设置正确发送和接收地址都是有效的aelf地址且位于正确的链上主链/侧链。确认余额和精度使用portkey_get_token_balance确认发送地址有足够的代币余额。特别注意金额单位确保传入的amount是正确的最小单位例如1 ELF 100000000。检查Gas费用使用portkey_estimate_fee预估Gas。确保发送地址有足够的ELF来支付这笔Gas费。aelf上的交易需要消耗ELF作为资源。验证合约调用对于合约调用仔细检查--method名称是否正确--params的JSON格式是否完全匹配合约方法的参数签名。一个常见的错误是参数类型不匹配比如合约需要int你却传了字符串。查看交易回执交易发送后会返回一个transactionId。使用portkey_get_transaction_detail或前往aelf区块链浏览器如explorer.aelf.io输入该ID查看交易详情。回执中的Status字段会明确显示Failed并且Error字段会给出失败原因例如Insufficient balance。6.2 MCP服务器连接或工具不可用如果在Claude Desktop中看不到Portkey的工具请检查配置文件路径与语法确保MCP服务器配置的路径是绝对路径且JSON格式正确没有缺少逗号或括号。环境变量确保在MCP配置中正确设置了必要的环境变量特别是PORTKEY_WALLET_PASSWORD如果使用本地钱包。服务器进程检查Bun进程是否正常运行。可以在终端手动运行bun run src/mcp/server.ts看是否有错误输出。客户端重启修改MCP配置后必须完全重启Claude Desktop或Cursor新的MCP服务器才会被加载。6.3 CLI命令参数格式错误CLI参数特别是JSON格式的--params是常见的错误源。空参数必须传{}。字符串参数需要双层引号。例如参数是一个地址字符串应该写为2g...。复杂对象参数是一个嵌套对象确保整个JSON字符串是有效的。可以先用一个在线JSON验证器校验再粘贴到命令行中。在Shell中使用单引号包裹整个JSON字符串可以避免很多转义问题。6.4 性能与优化建议批量查询尽量避免在循环中频繁调用portkey_get_token_balance查询单个代币。优先使用portkey_get_token_list一次性获取所有余额。连接池与超时如果你基于SDK构建高并发服务考虑对底层的HTTP客户端如axios配置连接池和合理的超时时间以应对网络波动。错误重试网络请求和区块链RPC调用可能因临时网络问题失败。在SDK集成中为关键操作如转账实现简单的指数退避重试机制。本地缓存对于不经常变化的数据如代币价格列表、链信息可以在应用层实现短期缓存减少不必要的RPC调用。6.5 安全红线私钥与助记词这是最高机密。永远不要硬编码在源码中不要提交到Git不要通过不安全的信道传输。使用加密的本地钱包文件配合密码是最佳实践。环境隔离开发、测试、生产环境使用不同的钱包和区块链网络testnet vs mainnet。切勿将测试网的私钥误用于主网。权限最小化在给AI Agent或自动化脚本授权时遵循最小权限原则。如果只是查询就不要提供签名能力。如果只是需要转账可以单独创建一个仅存有少量资金的热钱包而不是使用主钱包。依赖安全定期运行bun audit检查依赖漏洞并及时更新项目版本。这个技能包将aelf区块链的复杂性封装成了一组对AI友好的标准化接口。无论是想快速搭建一个链上查询机器人还是为你的DeFi策略构建一个自动执行Agent它都提供了一个坚实、安全且高效的起点。在实际集成中多花时间理解交易失败的回执信息善用费用估算功能并严格遵守安全规范就能让AI真正成为你在区块链世界中的得力助手。