DIAP 智能体网络现已集成 ERC-4337 账户抽象标准,为智能体提供更安全、更灵活的链上钱包解决方案。
智能体生态
├── 传统方式(EOA)
│ └── 智能体使用外部账户(私钥管理)
│
└── ERC-4337 方式(推荐)
├── DIAPAccount(智能体账户合约)
│ ├── Owner(主人完全控制)
│ ├── Session Keys(智能体临时授权)
│ ├── 支出限额(每日/单笔)
│ └── 白名单(允许的合约)
│
├── DIAPAccountFactory(账户工厂)
│ └── 使用 CREATE2 创建可预测地址
│
└── DIAPPaymaster(Gas 赞助)
└── 为智能体操作支付 Gas
智能体的 ERC-4337 账户合约,支持:
- Owner 控制:主人拥有完全控制权
- Session Keys:智能体的临时授权密钥
- 支出限额:每日和单笔限额控制
- 白名单:只能与授权的合约交互
- EIP-1271:标准签名验证
- 冻结机制:紧急情况下冻结账户
账户工厂合约,负责:
- 使用 Minimal Proxy 模式创建账户
- CREATE2 部署,地址可预测
- 维护账户注册表
- 批量创建账户
Gas 赞助合约,提供:
- 为智能体操作支付 Gas
- 每日 Gas 配额管理
- 账户和目标白名单
- Gas 使用统计
# 部署到测试网
npx hardhat run scripts/deploy-aa.js --network sepolia
# 部署到主网
npx hardhat run scripts/deploy-aa.js --network mainnet// 设置 AccountFactory 地址
await agentNetwork.setAccountFactory(accountFactoryAddress);// 添加 DIAP 生态合约到白名单
await paymaster.batchAddTargetToWhitelist([
diapTokenAddress,
diapAgentNetworkAddress,
diapPaymentCoreAddress,
diapVerificationAddress
]);
// 设置默认每日配额
await paymaster.setDefaultDailyQuota(ethers.utils.parseEther("0.01"));
// 添加存款
await paymaster.addDeposit({ value: ethers.utils.parseEther("1.0") });// 注册智能体并创建 AA 账户
const tx = await agentNetwork.registerAgentWithAA(
didDocument, // IPNS 名称
publicKey, // 公钥
stakedAmount, // 质押数量
salt // 用于生成唯一地址的盐值
);
const receipt = await tx.wait();
const aaAccountAddress = receipt.events.find(
e => e.event === 'AAAccountCreated'
).args.aaAccount;
console.log("AA 账户地址:", aaAccountAddress);import { Client } from "userop";
// 初始化客户端
const client = await Client.init(rpcUrl, {
entryPoint: ENTRY_POINT_ADDRESS,
factory: accountFactoryAddress,
});
// 构建 UserOperation
const userOp = await client.buildUserOperation({
target: agentNetworkAddress,
data: encodeFunctionData({
abi: agentNetworkABI,
functionName: "registerAgentWithAA",
args: [didDocument, publicKey, stakedAmount, salt],
}),
});
// 签名并发送
const result = await client.sendUserOperation(userOp);
console.log("UserOp Hash:", result.userOpHash);// 主人添加 Session Key
await aaAccount.addSessionKey(
sessionKeyAddress, // Session Key 地址
Math.floor(Date.now() / 1000) + 30 * 24 * 3600, // 30 天后过期
ethers.utils.parseEther("1000"), // 每日限额 1000 DIAP
ethers.utils.parseEther("100") // 单笔限额 100 DIAP
);// 智能体使用 Session Key 发起操作
const sessionKeyProvider = new SessionKeyProvider(
sessionKeyPrivateKey,
aaAccountAddress
);
// 发起支付
await sessionKeyProvider.sendTransaction({
to: paymentCoreAddress,
data: createPaymentData,
});// 添加合约到白名单
await aaAccount.addToWhitelist(contractAddress);
// 批量添加
await aaAccount.batchAddToWhitelist([
address1,
address2,
address3
]);
// 移除
await aaAccount.removeFromWhitelist(contractAddress);// 设置每日限额
await aaAccount.setDefaultDailyLimit(
ethers.utils.parseEther("2000") // 2000 DIAP
);
// 设置单笔限额
await aaAccount.setDefaultPerTxLimit(
ethers.utils.parseEther("200") // 200 DIAP
);// 冻结账户
await aaAccount.freeze();
// 解冻账户
await aaAccount.unfreeze();
// 转移所有权
await aaAccount.transferOwnership(newOwnerAddress);// 获取智能体的 AA 账户地址
const aaAccount = await agentNetwork.getAgentAAAccount(agentAddress);
// 检查是否使用 AA 账户
const isAA = await agentNetwork.isAgentUsingAA(agentAddress);
// 获取代币余额
const balance = await agentNetwork.getAgentTokenBalance(agentAddress);const sessionKeyInfo = await aaAccount.getSessionKeyInfo(sessionKeyAddress);
console.log({
validUntil: sessionKeyInfo.validUntil,
dailyLimit: sessionKeyInfo.dailyLimit,
perTxLimit: sessionKeyInfo.perTxLimit,
spentToday: sessionKeyInfo.spentToday,
remainingToday: sessionKeyInfo.remainingToday,
isActive: sessionKeyInfo.isActive
});const quotaInfo = await paymaster.getGasQuotaInfo(aaAccountAddress);
console.log({
dailyQuota: quotaInfo.dailyQuota,
usedToday: quotaInfo.usedToday,
remainingToday: quotaInfo.remainingToday,
isActive: quotaInfo.isActive
});import { Client, Presets } from "userop";
// 创建客户端
const client = await Client.init(rpcUrl, {
entryPoint: ENTRY_POINT_ADDRESS,
factory: accountFactoryAddress,
paymaster: paymasterAddress,
});
// 构建并发送 UserOperation
const builder = await Presets.Builder.SimpleAccount.init(
signerOrProvider,
rpcUrl,
{
entryPoint: ENTRY_POINT_ADDRESS,
factory: accountFactoryAddress,
}
);
const userOp = await builder.execute(
targetAddress,
value,
callData
);
const result = await client.sendUserOperation(userOp);import { AlchemyProvider } from "@alchemy/aa-alchemy";
import { LocalAccountSigner } from "@alchemy/aa-core";
const provider = new AlchemyProvider({
apiKey: ALCHEMY_API_KEY,
chain: sepolia,
entryPointAddress: ENTRY_POINT_ADDRESS,
});
const signer = LocalAccountSigner.privateKeyToAccountSigner(privateKey);
const smartAccountAddress = await provider.getAddress();
// 发送交易
const result = await provider.sendUserOperation({
target: targetAddress,
data: callData,
value: 0n,
});- ✅ 定期轮换 Session Keys(建议每月)
- ✅ 设置合理的有效期(不超过 90 天)
- ✅ 使用最小权限原则(最低限额)
- ✅ 监控 Session Key 使用情况
- ❌ 不要共享 Session Key 私钥
- ✅ 根据智能体用途设置合理限额
- ✅ 定期审查和调整限额
- ✅ 为高价值操作设置更严格的限制
- ❌ 不要设置过高的限额
- ✅ 只添加经过审计的合约
- ✅ 定期审查白名单
- ✅ 移除不再使用的合约
- ❌ 不要添加未知合约
- ✅ 监控账户余额变化
- ✅ 监控异常交易模式
- ✅ 设置余额低于阈值的告警
- ✅ 记录所有重要操作
| 操作 | Gas 消耗 | 成本(50 gwei) |
|---|---|---|
| 创建 AA 账户 | ~200,000 | ~$0.50 |
| 添加 Session Key | ~50,000 | ~$0.13 |
| 通过 AA 转账 | ~100,000 | ~$0.25 |
| 批量操作(5个) | ~300,000 | ~$0.75 |
- 100 个智能体
- 每个智能体每天 10 笔交易
- Paymaster 赞助 Gas
估算:
- Gas 消耗:~1 ETH/月
- Bundler 费用:$0-500/月
- 总计:~$2,000-2,500/月
可能原因:
- Gas 配额不足
- 不在白名单中
- 签名无效
- 限额超出
解决方案:
// 检查配额
const quota = await paymaster.getGasQuotaInfo(aaAccount);
console.log("剩余配额:", quota.remainingToday);
// 检查白名单
const isWhitelisted = await aaAccount.isWhitelisted(targetAddress);
console.log("是否在白名单:", isWhitelisted);可能原因:
- Session Key 已过期
- 限额已用完
- Session Key 未激活
解决方案:
// 检查 Session Key 状态
const info = await aaAccount.getSessionKeyInfo(sessionKeyAddress);
console.log("Session Key 信息:", info);
// 如果过期,添加新的
if (info.validUntil < Date.now() / 1000) {
await aaAccount.addSessionKey(/* ... */);
}可能原因:
- Paymaster 余额不足
- 账户不在白名单
- 目标合约不在白名单
解决方案:
// 检查 Paymaster 余额
const deposit = await paymaster.getDeposit();
console.log("Paymaster 余额:", ethers.utils.formatEther(deposit));
// 添加存款
if (deposit.lt(ethers.utils.parseEther("0.1"))) {
await paymaster.addDeposit({ value: ethers.utils.parseEther("1.0") });
}// 1. 创建 AA 账户
const aaAccount = await accountFactory.createAccount(ownerAddress, salt);
// 2. 转移资产
await token.transfer(aaAccount, balance);
// 3. 配置 AA 账户
await aaAccount.addSessionKey(/* ... */);
await aaAccount.addToWhitelist(/* ... */);
// 4. 更新智能体信息(需要合约支持)
// 这一步需要在 AgentNetwork 中添加迁移函数如有问题,请:
- 查看本文档的故障排查部分
- 查看合约代码注释
- 提交 GitHub Issue
- 联系技术支持团队