eForest Agent Skills:AI Agent与aelf区块链交互的MCP技能包详解
1. 项目概述:eForest Agent Skills,一个为AI Agent赋能的区块链技能包
如果你正在探索如何让AI助手(比如Claude、Cursor的AI功能)直接与aelf区块链和eForest NFT市场进行交互,那么你找对地方了。eForest Agent Skills这个开源项目,正是为了解决这个核心痛点而生。它不是一个简单的SDK,而是一个完整的“技能包”,将复杂的区块链操作——从创建代币、购买NFT发行权(SEED),到NFT的铸造、上架、交易、报价——封装成了AI Agent可以理解和调用的标准化工具。这意味着,开发者或普通用户可以通过自然语言指令,让AI助手帮你完成一系列链上操作,极大地降低了Web3应用开发和使用门槛。
这个项目的核心价值在于“桥接”。它一头连接着像Claude Desktop、Cursor IDE、IronClaw这类支持MCP(Model Context Protocol)协议的AI平台,另一头连接着aelf区块链及其生态应用eForest。通过提供CLI命令行工具、MCP Server和TypeScript SDK三种接入方式,它让AI Agent具备了直接操作链上资产的能力。无论是想快速测试一个NFT创意,还是构建一个自动化的链上资产管理机器人,这个工具包都提供了坚实的基础设施。接下来,我将为你深入拆解它的设计思路、核心功能以及如何在实际项目中落地使用,分享一些从代码和实践中得来的关键细节与避坑经验。
2. 核心架构与设计哲学:模块化、可插拔与优雅降级
2.1 技能化(Skillization)的设计理念
eForest Agent Skills最核心的设计转变,是从提供零散的“工具”转向提供结构化的“技能”。在v1版本之前,项目可能更侧重于单一的代币创建功能。而“Forest Skillization v1”的升级,标志着一个重要的架构演进: 将eForest NFT市场的完整能力体系,封装成一系列独立的、可组合的技能单元 。
这种设计带来的好处是显而易见的。首先, 统一了输入输出风格 。所有技能都遵循类似的参数结构和响应信封(Envelope),这使得不同团队开发的技能可以无缝协作,AI Agent在调用时无需为每个工具学习不同的“方言”。其次,它实现了 能力的渐进式暴露 。项目将技能分为P0(核心交易闭环)、P1(增长功能)和P2(扩展功能)三个优先级。在集成初期,你可以只启用最稳定、最核心的P0技能(如创建NFT、挂单、购买),随着项目成熟和需求明确,再逐步开放P1(如空投、白名单)和P2(如AI生成、小程序)技能。这种分层的设计,既保证了核心流程的稳定性,也为未来扩展留足了空间。
2.2 服务门控与优雅降级机制
在实际生产环境中,任何依赖外部区块链网络和API的服务都可能出现不稳定、维护或需要临时下线的情况。eForest Agent Skills内置了一套非常实用的 服务门控(Service Gating)系统 ,这是很多类似工具包所忽略的。
这套系统通过一系列环境变量来实现精细化的控制:
-
EFOREST_DISABLED_SERVICES: 用于彻底禁用某些技能域,例如在测试阶段可以先禁用AI相关功能:export EFOREST_DISABLED_SERVICES="forest.ai.*,forest.miniapp.*"。 -
EFOREST_MAINTENANCE_SERVICES: 将特定服务置为“维护模式”。处于此模式的服务在被调用时,会返回清晰的maintenance: true标志和友好的提示信息,而不是直接报错或超时,用户体验更好。 -
EFOREST_ENABLED_SERVICES: 反向白名单控制,只允许列表内的服务运行,安全性最高。
更重要的是它的
优雅降级(Graceful Degradation)
处理。当某个技能因网络、配置或维护原因不可用时,其返回的错误响应是结构化的(遵循项目的“错误契约”),包含了
code
(如
SERVICE_DISABLED
)、
message
、
retryable
等字段。AI Agent可以根据这些结构化信息,决定是重试、跳过还是向用户给出明确的解释,而不是面对一个无法解析的异常崩溃。这种设计极大地提升了AI工作流的鲁棒性。
2.3 配置优先级与上下文解析策略
在多环境、多用户的复杂场景下,配置管理是个头疼的问题。该项目采用了一个清晰且灵活的
配置解析优先级链
,从高到低依次为:1. 函数调用参数;2. CLI命令行参数;3.
EFOREST_*
/
AELF_*
环境变量;4.
.env
文件;5. 远程CMS配置;6. 代码默认值。
这个链条解决了一个关键问题:
如何安全地管理私钥等敏感信息?
最佳实践是,将网络类型(
EFOREST_NETWORK
)、RPC地址等公共配置放在项目
.env
文件或环境变量中,而将钱包私钥(
AELF_PRIVATE_KEY
)或CA凭证通过更高优先级的、临时的方式传入,例如在CLI命令中通过
--private-key
参数(但需注意命令行历史记录风险),或更安全地,利用其
跨技能签名者上下文(Cross-Skill signer context)
功能。
上下文解析策略是另一个亮点。当执行一个需要签名的操作(如购买NFT)时,系统会按以下顺序寻找签名者:1. 技能调用时显式传入的
privateKey
参数;2. 当前激活的共享钱包上下文文件(
~/.portkey/skill-wallet/context.v1.json
);3. 环境变量中配置的备用凭证。这意味着,用户或AI Agent可以在一个会话开始时“登录”或“选择”一个钱包,后续所有技能调用都会自动使用这个上下文,无需在每个操作中重复输入私钥,既方便又相对安全(尤其是配合加密的钱包文件使用时)。
3. 三大接入方式详解:CLI、MCP Server与SDK
3.1 CLI:面向开发者的快速验证工具
命令行接口是最直接、最透明的使用方式,非常适合开发者在构建或调试技能时进行快速验证。它封装了最基础的链上操作流程。
核心操作流程与参数解析
以创建一个新的同质化代币(FT)为例,完整的流程通常包含三步:
-
检查与预购SEED :在aelf链上创建代币符号(Symbol)需要先购买该符号的创建权,即SEED。
# 干跑(Dry-run)模式,仅估算费用,不上链 bun run cli buy-seed --symbol MYTOKEN --issuer 0xYourAddress --dry-run # 实际购买,限制最大花费2 ELF bun run cli buy-seed --symbol MYTOKEN --issuer 0xYourAddress --force 2这里有几个关键点:
--dry-run参数至关重要,它允许你在不花费任何Gas费的情况下模拟交易,确认参数是否正确、费用是否可接受。--force 2则是一个安全限制,防止因网络拥堵导致Gas费异常高昂时造成意外损失。 -
创建代币 :使用上一步获得的SEED来实际创建代币。
bun run cli create-token \ --symbol MYTOKEN \ --token-name "My Awesome Token" \ --seed-symbol SEED-321 \ # 上一步购买成功后返回的SEED符号 --total-supply 100000000 \ --decimals 8 \ --issue-chain tDVV # 指定在哪个侧链上发行注意
--issue-chain参数,aelf是一个多侧链架构的公链,你需要明确代币创建在哪个链上。tDVV和tDVW是常见的测试侧链。 -
发行代币 :将创建好的代币发行到指定地址。
bun run cli issue-token \ --symbol MYTOKEN \ --amount 10000000000000000 \ # 注意单位,这里是考虑了decimals后的最小单位 --to 0xRecipientAddress \ --chain tDVV这里最容易出错的是
--amount。因为代币有精度(decimals),这里的金额是代币的最小单位(如wei之于ETH)。如果decimals为8,那么想发行100个代币,这里的amount应该是100 * 10^8 = 10000000000。
CLI模式的适用场景与局限 CLI模式适合脚本化操作、CI/CD流水线集成或作为其他应用的底层调用封装。它的局限在于交互性不强,且需要用户对命令行和参数有较高理解。这正是MCP Server要解决的问题。
3.2 MCP Server:赋能AI Agent的核心桥梁
MCP(Model Context Protocol)是Anthropic提出的一种协议,旨在让AI模型能够安全、可控地调用外部工具。eForest Agent Skills作为MCP Server,是项目最核心的价值所在,它让Claude、Cursor等AI能够“理解”并操作区块链。
一键式集成与平台适配
项目提供了极其便捷的一键安装脚本,极大降低了集成门槛:
# 集成到Claude Desktop
bun run setup claude
# 集成到Cursor IDE(项目级别)
bun run setup cursor
# 集成到Cursor IDE(全局级别)
bun run setup cursor --global
# 集成到IronClaw
bun run setup ironclaw
运行这些命令后,工具会自动修改对应AI客户端的配置文件(如Claude Desktop的
claude_desktop_config.json
),注册MCP Server。之后,你在与AI对话时,就可以直接使用自然语言发出指令,例如:“帮我在eForest测试网上创建一个名为‘CyberPunk Ape’的NFT合集,并铸造第一个NFT给我。”
手动配置详解与安全考量
虽然一键安装很方便,但理解手动配置对于调试和高级用法很有必要。配置的核心是告诉AI客户端如何启动这个MCP Server。
EOA(外部拥有账户)模式配置 :
{
"mcpServers": {
"eforest-token": {
"command": "bun",
"args": ["run", "/absolute/path/to/eforest-agent-skills/src/mcp/server.ts"],
"env": {
"AELF_PRIVATE_KEY": "你的EOA私钥",
"EFOREST_NETWORK": "testnet"
}
}
}
}
这种模式最简单直接,私钥以环境变量形式传入。
安全警告
:永远不要将包含真实私钥的配置文件提交到版本控制系统(如Git)。应该使用环境变量或
.env
文件(确保
.env
在
.gitignore
中)。
CA(合约账户)模式配置 :
{
"mcpServers": {
"eforest-token": {
"command": "bun",
"args": ["run", "/absolute/path/to/eforest-agent-skills/src/mcp/server.ts"],
"env": {
"PORTKEY_PRIVATE_KEY": "你的管理器私钥",
"PORTKEY_CA_HASH": "你的CA合约哈希",
"PORTKEY_CA_ADDRESS": "你的CA合约地址",
"EFOREST_NETWORK": "mainnet"
}
}
}
}
CA模式提供了更高的安全性和功能(如社交恢复、多签)。它需要Portkey(aelf的智能钱包基础设施)的凭证。配置时需注意,这三个
PORTKEY_*
环境变量必须同时提供,缺一不可。
关于IronClaw集成的特别注意事项
IronClaw是一个AI Agent安全框架,它对安装的技能有“读写权限”的区分。项目文档特别强调了一个关键点: 不要依赖IronClaw自动安装的只读技能路径 。
当你运行
bun run setup ironclaw
时,它做了两件事:1. 在
~/.ironclaw/mcp-servers.json
中注册一个stdio MCP server;2. 将本地的
SKILL.md
描述文件复制到
~/.ironclaw/skills/eforest-agent-skills/
目录下。你必须确保AI Agent使用的是前者(MCP Server),因为它具备完整的读写能力。如果Agent错误地使用了后者(
installed_skills
目录下的技能副本),IronClaw可能会将其降级为只读工具,导致所有上链交易调用失败,而用户却难以察觉问题根源,只会看到AI“拒绝”执行写操作。
3.3 SDK:面向开发者的编程接口
对于想要将eForest功能深度集成到自己Node.js/TypeScript应用中的开发者,SDK提供了最灵活的方式。
基础调用模式
SDK的使用非常直观,核心是
dispatchForestSkill
函数:
import { dispatchForestSkill, getNetworkConfig } from '@eforest-finance/agent-skills';
async function getNFTPrice() {
const config = await getNetworkConfig({ env: 'testnet' });
const result = await dispatchForestSkill(
'aelf-forest-get-price-quote', // 技能名称
{
env: 'testnet',
payload: {
symbol: 'CYBER-APE-1', // NFT符号
include: ['tokenData', 'txFee'], // 希望返回的详细信息
},
},
{ config } // 可选的额外配置,会覆盖默认配置
);
if (!result.success) {
console.error(`失败: ${result.code} - ${result.message}`);
// 可以根据result.code进行特定错误处理,如SERVICE_DISABLED, MAINTENANCE等
if (result.maintenance) {
console.log('服务正在维护,请稍后再试。');
}
return;
}
console.log('NFT报价信息:', result.data);
// result.data 可能包含:地板价、版税、预估Gas费等信息
}
技能发现与动态调用
你不需要硬编码所有可用的技能名。SDK提供了
listForestSkills()
函数来动态获取当前注册的所有技能列表。这对于构建动态UI或工具平台非常有用:
import { listForestSkills } from '@eforest-finance/agent-skills';
const allSkills = listForestSkills();
console.log(`共有 ${allSkills.length} 个技能可用`);
// 可以按技能名中的域名进行过滤,例如只显示与市场相关的技能
const marketSkills = allSkills.filter(skill => skill.name.includes('market'));
错误处理的最佳实践
SDK强制使用了统一的响应信封(Envelope),这迫使开发者必须进行规范的错误处理。一个好的实践是封装一个通用的技能调用函数:
async function safeDispatchSkill(skillName, payload, options = {}) {
try {
const result = await dispatchForestSkill(skillName, payload, options);
if (!result.success) {
// 将结构化的错误转换为用户友好的消息,或触发特定的恢复逻辑
const userMessage = mapErrorCodeToMessage(result.code, result.message);
throw new Error(userMessage);
}
return result.data;
} catch (error) {
// 处理网络错误、超时等非业务错误
console.error(`调用技能 ${skillName} 失败:`, error);
// 可以考虑重试逻辑,特别是当 result.retryable 为 true 时
throw error;
}
}
// 错误码映射示例
function mapErrorCodeToMessage(code, detail) {
const map = {
'INVALID_PARAMS': `参数错误,请检查输入。详情:${detail}`,
'SERVICE_DISABLED': '该功能暂时不可用。',
'MAINTENANCE': '系统正在维护升级,请稍后再试。',
'INSUFFICIENT_BALANCE': '账户余额不足,请充值。',
};
return map[code] || `操作失败: ${detail}`;
}
4. Forest技能全解析:从核心交易到生态扩展
4.1 P0核心交易闭环:构建NFT市场的基础
P0技能集涵盖了NFT从创建到交易的一个完整闭环,是任何基于eForest构建应用的基础。理解这个工作流,就理解了NFT在链上的核心生命周期。
4.1.1 合集与物品的创建
一切始于合集(Collection)。你可以把合集理解为一个NFT系列,比如“无聊猿”系列。创建合集定义了该系列的基本元数据、版税规则等。
-
aelf-forest-create-collection: 创建NFT合集。关键参数包括symbol(合集符号,需唯一)、name、description,以及可选的royalty(版税费率,如0.05表示5%)。 -
aelf-forest-create-item/aelf-forest-batch-create-items: 在合集中创建单个或多个NFT物品。这里需要指定所属的collectionSymbol,以及每个NFT的metadata(通常是一个指向JSON文件的URI,包含图片、属性等信息)。批量创建能显著降低Gas费成本。
实操心得:元数据(Metadata)的托管 NFT的价值很大程度上取决于其元数据。切勿将元数据JSON和图片直接放在中心化服务器或项目代码里。推荐使用去中心化存储方案,如IPFS或Arweave。上传后,你会得到一个类似
ipfs://QmXYZ...或https://arweave.net/ABC...的URI,将其作为metadata参数传入。eForest前端会据此获取并展示你的NFT。一个常见的坑是,测试时用了本地HTTP链接,上线前忘记替换,导致NFT变成“无效图片”。
4.1.2 挂牌与购买:固定价格销售
创建NFT后,所有者可以将其挂牌出售。
-
aelf-forest-list-item: 将NFT以固定价格挂牌。需要指定symbol(NFT物品符号)、priceSymbol(计价代币,如ELF)、priceAmount(价格)和durationJson(挂牌时长,例如{"hours": 72}表示72小时)。 -
aelf-forest-buy-now: 买方调用此技能,以挂牌价直接购买NFT。调用后,NFT所有权和代币将自动通过智能合约交换。
4.1.3 报价与交易:更灵活的议价模式
除了固定价格,eForest还支持报价(Offer)模式,为市场提供了更多灵活性。
-
aelf-forest-make-offer: 潜在买家对某个NFT发起一个报价。这个报价在到期前一直有效,卖家可以随时接受。参数包括symbol、priceSymbol、priceAmount和expireTime。 -
aelf-forest-deal-offer: NFT所有者接受一个有效的报价,完成交易。 -
aelf-forest-cancel-offer: 报价方在到期前取消自己的报价。 -
aelf-forest-cancel-listing: NFT所有者取消自己的挂牌。
4.1.4 查询与转账
-
aelf-forest-get-price-quote: 这是一个非常重要的只读技能。在发起任何交易前,都应该先调用它来获取实时报价、预估的Gas费、版税等信息,做到心中有数。它的响应数据是进行用户界面展示和费用计算的直接依据。 -
aelf-forest-transfer-item: NFT所有者可以将NFT直接转账给另一个地址,无需经过市场。适用于赠予或转移到另一个钱包。
4.2 P1增长功能:空投、拍卖与白名单
P1技能旨在帮助项目方进行社区运营和增长。
4.2.1 空投(Drop)
空投是Web3项目吸引用户、奖励社区的常见手段。
-
aelf-forest-create-drop: 创建一个空投活动。需要定义空投的NFT合集、每个地址可领取数量、总数量、开始和结束时间等。 -
aelf-forest-claim-drop: 用户调用此技能来领取空投的NFT。后台会验证用户地址是否在白名单内、是否已领取、活动是否有效等。 -
aelf-forest-query-drop: 查询空投活动的详细信息或用户的领取状态。
4.2.2 英式拍卖(Auction)
aelf-forest-place-bid
支持英式拍卖模式。卖家可以设置一个起拍价和拍卖时长,买家在此期间出价,价高者得。这种模式常用于稀缺或高价值NFT的销售,能发现更公允的市场价格。智能合约会自动处理出价逻辑,并在结束时将NFT分配给最高出价者。
4.2.3 白名单(Whitelist)
白名单用于在公开销售前,给特定用户群体(如社区早期贡献者)优先购买权。
-
aelf-forest-whitelist-manage: 项目方管理白名单,可以添加或移除地址。 -
aelf-forest-whitelist-read: 查询某个地址是否在白名单中,或者获取整个白名单。
注意事项:链上白名单的成本 将白名单完全放在链上(通过智能合约存储)虽然透明公正,但每次添加地址都需要支付Gas费,对于大规模列表成本很高。一种常见的混合方案是:将白名单的Merkle Root存储在链上,验证时用户提供Merkle Proof。eForest的技能可能支持这两种模式,需要根据具体合约实现来选择。
4.3 P2扩展功能:AI生成、小程序与社交
P2技能展示了eForest生态的更多可能性,将NFT与更广泛的应用场景结合。
-
aelf-forest-ai-generate/aelf-forest-ai-retry: 与AI图像生成服务结合,用户可以通过描述词(prompt)直接生成NFT图像并铸造。retry技能允许用户基于之前的生成结果进行微调,这为创建可进化的、个性化的NFT提供了可能。 -
aelf-forest-create-platform-nft: 这可能允许第三方平台(如游戏、社交应用)在其自有平台上创建符合eForest标准的NFT,实现跨平台的资产互通。 -
aelf-forest-miniapp-action: 为NFT绑定可交互的小程序(DApp)。例如,一个音乐NFT可以绑定一个播放器小程序,一个游戏道具NFT可以绑定一个查看属性的小程序。这极大地扩展了NFT的实用价值。 -
aelf-forest-update-profile/aelf-forest-watch-market-signals: 这些技能指向了社交和实时功能。用户可以更新链上个人资料,或者订阅市场的实时事件(如某合集的地板价变动、大额交易等),为构建社交交易平台或监控工具提供了接口。
5. 高级配置与实战避坑指南
5.1 环境变量与网络配置详解
项目的灵活性很大程度上来自于其丰富的环境变量配置。正确理解这些变量是稳定运行的关键。
网络与RPC配置
-
EFOREST_NETWORK: 最基础的配置,设置为mainnet或testnet。它会自动加载对应网络的预设RPC和API地址。 -
EFOREST_RPC_URL/EFOREST_RPC_URL_TDVV/EFOREST_RPC_URL_TDVW: 如果你想覆盖默认的RPC节点,可以设置这些变量。例如,如果你有自己的aelf节点或使用更快的第三方节点,可以在这里指定。 注意 :主链和侧链的RPC是分开配置的,确保你操作的链与配置的RPC匹配。 -
EFOREST_API_URL: eForest后端API的地址。通常不需要修改,除非你在部署私有化的eForest市场服务。
服务开关配置(再强调) 合理使用服务开关,可以在开发、测试、生产环境中平滑切换。
- 开发环境 :可以启用所有技能,包括P2的实验性功能,方便测试。
-
预发布环境
:可能禁用
forest.ai.*和forest.miniapp.*,因为AI服务可能产生额外费用,小程序可能不稳定。 -
生产环境
:通常只启用P0和经过充分测试的P1技能(
forest.market.*,forest.drop.*等),确保核心交易稳定。
一个推荐的
.env
文件示例:
# 网络配置
EFOREST_NETWORK=testnet
# 可选:覆盖RPC,加速访问
# EFOREST_RPC_URL_TDVV=https://tdvv-test-node.eforest.finance
# 服务配置:在测试网禁用AI和MiniApp以节省资源
EFOREST_DISABLED_SERVICES=forest.ai.*,forest.miniapp.*
# 钱包配置(CA模式示例)- !!!切勿提交此文件到Git !!!
# PORTKEY_PRIVATE_KEY=pk_xxxx
# PORTKEY_CA_HASH=0xabc...
# PORTKEY_CA_ADDRESS=ELF_xxxx
绝对不要
将包含真实私钥的
.env
文件提交到版本库。应该使用
.env.example
文件列出需要的变量名,而将实际值通过CI/CD系统的Secret功能或本地环境注入。
5.2 Forest API路由映射:自定义后端集成
这是项目一个非常强大的高级功能。默认情况下,
aelf-forest-api-*
这类方法技能会调用eForest官方的API。但如果你部署了自己的市场后端,或者想将某些请求代理到自己的服务,就可以通过
EFOREST_FOREST_API_ACTION_MAP_JSON
环境变量来实现完全自定义的路由映射。
配置示例与解析
{
"aelf-forest-api-market": {
"fetchTokens": {
"method": "GET",
"path": "/app/market/tokens",
"auth": true,
"baseUrl": "https://api.my-forest.com" // 可选,覆盖基础URL
},
"fetchNFTDetail": {
"method": "GET",
"url": "https://my-custom-proxy.com/nft/{symbol}", // 完全自定义URL,支持路径参数
"auth": false
}
},
"aelf-forest-api-user": {
"fetchMyProfile": {
"method": "POST", // 可以是任何HTTP方法
"path": "/app/user/profile",
"auth": true,
"headers": { // 可以添加自定义请求头
"X-Custom-Header": "my-value"
}
}
}
}
将这个JSON字符串设置到环境变量
EFOREST_FOREST_API_ACTION_MAP_JSON
中。技能被调用时,会优先查找这个映射表,如果找到匹配的
技能名.动作名
,就按照映射的配置发起HTTP请求,而不是使用默认的官方API。
queryArrayFormat: "repeat"
的妙用
在处理一些老式或特殊的API时,数组查询参数可能需要
?key=a&key=b
的格式,而不是更常见的
?key[]=a&key[]=b
或
?key=a,b
。通过设置
"queryArrayFormat": "repeat"
,SDK会自动将数组参数转换为这种重复键的格式,省去了手动拼接URL的麻烦。
5.3 签名者上下文与多钱包管理
在复杂的应用场景中,一个AI Agent可能需要操作多个钱包(例如,一个用于项目方管理,一个用于用户交易)。项目的“跨技能签名者上下文”功能为此提供了优雅的解决方案。
上下文文件的工作原理
上下文文件(默认位于
~/.portkey/skill-wallet/context.v1.json
)存储了当前“活跃”钱包的信息。这个信息不是私钥本身,而是一个指向钱包的引用(如钱包文件路径、CA地址等)以及一些元数据。当技能被调用且没有显式提供签名者时,SDK会读取这个文件,加载对应的钱包,然后进行签名。
如何切换上下文? 项目本身可能不提供直接的上下文切换CLI,但你可以通过脚本或简单操作来管理:
-
手动编辑JSON文件
:直接修改
context.v1.json文件中的内容。 -
使用符号链接
:为不同钱包创建不同的上下文文件(如
context.alice.json,context.bob.json),然后通过切换符号链接的目标来切换活跃钱包:ln -sf context.alice.json context.v1.json。 -
在应用中动态设置
:如果你基于SDK开发应用,可以在调用
dispatchForestSkill时,通过options参数传入一个自定义的config对象,其中包含signer配置,这将覆盖上下文和环境变量。
加密钱包与密码管理 如果上下文指向的是一个加密的钱包文件(如Portkey的keystore),那么在签名时需要密码。有两种方式提供密码:
-
环境变量
:设置
PORTKEY_WALLET_PASSWORD或PORTKEY_CA_KEYSTORE_PASSWORD。这种方法方便但有一定安全风险,因为密码会留在进程环境里。 -
技能输入参数
:更安全的方式是在调用需要签名的技能时,通过
payload传入password字段。AI Agent可以在与用户交互时动态获取密码(确保交互通道安全),然后传入。密码仅在内存中短暂存在。
5.4 测试策略与CI/CD集成
项目提供了完善的测试套件,确保代码质量和集成稳定性。
分层测试策略
-
bun test:unit: 单元测试。快速验证单个函数、类的逻辑是否正确。这是开发过程中运行最频繁的测试。 -
bun test:integration: 集成测试。验证多个模块组合在一起是否能正确工作,例如技能调度器能否正确调用底层的AElf合约客户端。 -
bun test:e2e:smoke: 端到端冒烟测试。这是CI流水线(如PR合并前)的关卡。它会模拟完整的技能调用流程,但使用 干跑(dry-run)模式 ,不实际发送链上交易,因此是确定性的、快速的,且不消耗真实资源。 -
bun test:e2e:full: 完整的端到端测试。可能涉及更多的场景组合,但同样坚持干跑原则,避免对测试网造成负担。
在CI中安全运行测试 在GitHub Actions等CI环境中运行测试,需要特别注意秘密信息(Secrets)的管理。
# .github/workflows/test.yml 示例片段
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
- run: bun install
- run: bun test:unit
- run: bun test:integration
- run: bun test:e2e:smoke
env:
# 即使干跑不需要真实私钥,但某些配置可能仍需读取环境变量
EFOREST_NETWORK: testnet
# 绝对不要在这里写入真实的私钥!
# 如果需要测试真实签名,应使用专门为CI生成的、余额极少的测试网账户私钥,
# 并通过GitHub Secrets注入,且确保该工作流只在受保护的分支上运行。
关键点是: 永远不要在代码或日志中硬编码私钥 。即使是测试网私钥,一旦泄露也可能被滥用。使用CI平台提供的Secrets功能,并且确保测试不会在公开的日志中输出敏感信息。
6. 常见问题排查与解决方案实录
在实际开发和集成过程中,你难免会遇到一些问题。以下是我从项目经验和社区反馈中总结的一些常见问题及其排查思路。
6.1 技能调用失败:错误码速查表
当
dispatchForestSkill
返回
success: false
时,首先查看
code
字段。以下是常见错误码及其含义:
| 错误码 (code) | 可能原因 | 排查步骤 |
|---|---|---|
INVALID_PARAMS
| 输入参数不符合技能Schema要求。 |
1. 检查参数名是否拼写正确(注意大小写)。
2. 检查参数类型(如
priceAmount
应为数字,
durationJson
应为合法JSON字符串)。
3. 使用
dry-run
模式先测试参数。
|
SERVICE_DISABLED
| 该技能对应的服务已被环境变量禁用。 |
1. 检查
EFOREST_DISABLED_SERVICES
环境变量,确认是否包含了该技能的服务模式(如
forest.market.*
)。
2. 检查
EFOREST_ENABLED_SERVICES
是否设置了白名单,且当前技能不在其中。
|
MAINTENANCE
| 服务处于维护模式。 |
1. 检查
EFOREST_MAINTENANCE_SERVICES
环境变量。
2. 可能是后端API临时维护,查看官方公告或状态页。 |
NETWORK_ERROR
| 网络连接问题,无法访问RPC或API。 |
1. 检查
EFOREST_RPC_URL
和
EFOREST_API_URL
配置是否正确可达。
2. 检查本地网络或防火墙设置。 3. 尝试切换网络(如从
mainnet
到
testnet
)看是否复现。
|
SIGNER_NOT_FOUND
| 未找到有效的签名者来执行交易。 |
1. 检查是否提供了
privateKey
参数或配置了环境变量
AELF_PRIVATE_KEY
/
PORTKEY_*
。
2. 检查上下文文件
~/.portkey/skill-wallet/context.v1.json
是否存在且格式正确。
3. 如果是加密钱包,检查密码是否正确提供。 |
INSUFFICIENT_BALANCE
| 账户余额不足,无法支付Gas费或交易金额。 |
1. 确认操作的钱包地址在对应链上有足够的ELF代币支付Gas费。
2. 对于购买类操作,确认余额大于物品价格+预估Gas费。 |
CONTRACT_ERROR
| 智能合约执行失败。 |
1. 查看
message
和
details
字段,通常包含合约返回的具体错误信息(如“Symbol already exists”)。
2. 这可能是因为业务逻辑不满足(如重复创建符号、报价已过期等)。 |
6.2 MCP Server集成问题
问题:AI助手(如Claude)不显示eForest工具。
-
排查1:配置文件路径
。确认MCP Server配置被正确添加到了AI客户端的配置文件中。对于Claude Desktop,配置文件通常在
~/Library/Application Support/Claude/claude_desktop_config.json(Mac)或%APPDATA%\Claude\claude_desktop_config.json(Windows)。运行bun run setup claude后,检查该文件是否被修改。 -
排查2:Server启动失败
。AI客户端在启动时会尝试运行你配置的MCP Server命令。如果Server因为依赖缺失、配置错误而启动失败,工具就不会加载。查看AI客户端的日志文件(如果有),或者尝试在终端手动运行配置中的命令(如
bun run /path/to/server.ts),看是否有错误输出。 -
排查3:权限问题
。确保
bun和项目路径有正确的执行权限。
问题:IronClaw中,AI可以查询但无法执行写操作(如购买、创建)。
-
根本原因
:AI错误地使用了
installed_skills目录下的只读技能副本,而非MCP Server。 -
解决方案
:确保运行了
bun run setup ironclaw,并且IronClaw的配置指向的是stdio类型的MCP Server,而不是installed_skills路径。检查~/.ironclaw/mcp-servers.json文件内容。
6.3 交易长时间无确认或失败
问题:发送交易后,一直处于“Pending”状态。
- 原因1:Gas费过低 。在网络拥堵时,设置过低的Gas费可能导致交易迟迟不被矿工打包。
-
解决
:aelf链的交易通常由SDK或客户端自动估算Gas。确保你的RPC节点是同步的,并且网络配置正确。可以尝试稍后重试,或使用
get-price-quote技能获取实时的Gas费估算作为参考。 - 原因2:Nonce冲突 。如果你同时从同一个账户发送了多笔交易,可能会出现Nonce问题。
- 解决 :aelf的SDK通常会管理Nonce,但在极端情况下(如重启应用、多实例同时操作),可能需要手动重置或等待。最简单的办法是等待一段时间,或使用一个全新的账户进行下一笔交易。
问题:交易失败,但Gas费被扣除了。
- 原因 :这是区块链的常见情况。Gas费是支付给矿工执行计算的费用,即使交易因为业务逻辑失败(如余额不足、权限不足),计算已经发生,Gas费不会被退回。
-
预防
:务必在发送交易前进行充分的检查:使用
dry-run模式、调用get-price-quote查询费用和状态、确保业务条件满足(如SEED已购买、余额充足)。这能最大限度地减少无谓的Gas消耗。
6.4 性能优化与监控建议
1. RPC节点选择
:公共RPC节点可能在高负载时响应慢。对于生产环境,考虑使用付费的、专有的RPC节点服务,或自己搭建一个aelf节点,然后将
EFOREST_RPC_URL
指向它,能显著提升交易发送和查询速度。
2. 技能调用的异步与批处理
:SDK的
dispatchForestSkill
是异步的。当需要执行多个不依赖前后顺序的操作时(如给多个地址空投NFT),不要用
for
循环串行调用,这非常慢。应该利用
Promise.all()
进行并发处理。但要注意区块链交易的并发可能会引起Nonce问题,对于写操作需谨慎评估,或使用支持批量交易的特定技能(如
batch-create-items
)。
3. 监控与告警 :在生产环境中使用,建议添加监控。
-
日志
:确保SDK或你的应用记录了所有技能调用的
traceId。当用户报错时,可以通过traceId在服务端日志中定位完整的请求链路。 -
健康检查
:定期调用一个简单的只读技能(如
get-price-quote)来检查服务连通性。 -
错误率告警
:监控
SERVICE_DISABLED、MAINTENANCE和NETWORK_ERROR等错误码的出现频率,超过阈值时触发告警。
4. 依赖管理
:项目使用Bun作为运行时和包管理器。确保团队开发环境一致,锁定Bun的版本(在
package.json
中指定
"bun"
版本范围),避免因Bun版本升级导致的不兼容问题。在Docker化部署时,使用官方的Bun镜像作为基础镜像。
更多推荐



所有评论(0)