本文提供了通过Pimlico Alto插件将ERC-4337兼容的打包器集成到区块链应用中的详细教程。内容涵盖了如何在BuildBear沙盒环境中安装和配置Pimlico Alto、使用permissionless.js管理智能账户,以及如何进行DAI与USDC的交换交易,同时提供了相关代码示例和调试工具介绍,适合开发者学习和实操。
本教程将指导你通过使用 Pimlico Alto 插件在区块链应用中集成与 ERC-4337 兼容的捆绑器以实现账户抽象。Pimlico Alto 简化了将用户操作打包为交易并通过标准 JSON-RPC 请求提交到区块链的过程。它支持 permissionless.js,使 Web3 应用程序开发和测试更加流畅。
Pimlico Alto 插件旨在与 BuildBear Sandbox 轻松集成,使得实施账户抽象(AA)功能变得简单。
使用标准方法与捆绑器进行交互:
BuildBear 提供无限访问本地和 ERC-20 代币,确保开发和测试顺利进行。
例如:
BuildBear Sandbox RPC URL: https://rpc.buildbear.io/parliamentary-katebishop-6df91ec9
Pimlico Client API: https://rpc.buildbear.io/parliamentary-katebishop-6df91ec9
确保安装所有必要的依赖。示例 package.json
:
{
"name": "pimlico-tutorial-template",
"version": "1.0.0",
"dependencies": {
"dotenv": "^16.3.1",
"ethers": "^6.13.5",
"permissionless": "^0.2.0",
"viem": "^2.20.0"
},
"devDependencies": {
"@types/node": "^20.11.10",
"tsx": "^3.13.0"
}
}
使用你的 BuildBear RPC URL 设置 buildbearSandboxUrl
。
const buildbearSandboxUrl = "https://rpc.buildbear.io/uzair";
设置 BuildBear Sandbox 网络
使用 viem 设置你的自定义 BuildBear Sandbox 网络
const BBSandboxNetwork = /*#__PURE__*/ defineChain({
id: 23351, // 重要:用你的 Sandbox 链 ID 替换此项
name: "BuildBear x Polygon Mainnet Sandbox", // 为你的网络命名
nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, // 分叉网络的原生货币
rpcUrls: {
default: {
http: [buildbearSandboxUrl],
},
},
blockExplorers: {
default: {
name: "BuildBear x Polygon Mainnet Scan", // 网络的区块浏览器
url: "https://explorer.buildbear.io/uzair",
apiUrl: "https://api.buildbear.io/uzair/api",
},
},
});
生成私钥(可选)
生成或检索智能账户的私钥,并将其存储在 .env 文件中。
const privateKey = process.env.PRIVATE_KEY || generatePrivateKey();
appendFileSync(".env", `nPRIVATE_KEY=${privateKey}`);
设置公共客户端
使用 BuildBear Sandbox RPC URL 创建一个新的公共客户端。
const privateKey = process.env.PRIVATE_KEY || generatePrivateKey();
appendFileSync(".env", `nPRIVATE_KEY=${privateKey}`);
设置 Pimlico 客户端
使用 BuildBear Sandbox RPC URL 和 EntryPoint 详细信息配置 Pimlico 客户端。
const pimlicoClient = createPimlicoClient({
transport: http(buildbearSandboxUrl),
entryPoint: { address: entryPoint07Address, version: "0.7" },
});
创建智能账户和客户端
使用私钥创建签名者,然后使用签名者创建一个 安全智能账户。使用智能账户设置智能账户客户端,从该智能账户发送交易和用户操作。
const signer = privateKeyToAccount(privateKey);
const account = await toSafeSmartAccount({
client: publicClient,
owners: [signer],
entryPoint: { address: entryPoint07Address, version: "0.7" },
version: "1.4.1",
});
const smartAccountClient = createSmartAccountClient({
account,
chain: BBSandboxNetwork,
bundlerTransport: http(buildbearSandboxUrl),
userOperation: {
estimateFeesPerGas: async () => (await pimlicoClient.getUserOperationGasPrice()).fast,
},
});
为你的智能账户钱包提供资金:由于不支持付款方,因此用户必须资助他们的钱包。资金不足或空钱包将在交易过程中导致错误。
可以使用所有 BuildBear 沙箱所支持的 RPC 方法为地址提供资金。
为了使用户操作正确工作,你需要拥有:
检查账户余额
if (+balance.toString() <= 0 || +daiBalanceBefore.toString() <= 0) {
console.log("====================================");
console.log(
`⚠️⚠️请用 DAI 和原生代币为你的账户提供资金,并尝试再次运行脚本。n智能账户地址: ${account.address}`
);
console.log("====================================");
exit();
} else {
console.log("====================================");
console.log(`智能账户地址: ${account.address}`);
console.log("====================================");
}
为智能账户提供资金
通过你的 BuildBear RPC Sandbox URL 调用以下参数以获取水龙头资金,或使用 Sandbox 控制面板上的水龙头进行资金提供。
原生代币水龙头
{
"jsonrpc": "2.0",
"id": 1,
"method": "buildbear_nativeFaucet",
"params": [{ "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "balance": "10000" }]
}
ERC 代币水龙头
{
"jsonrpc": "2.0",
"id": 1,
"method": "buildbear_nativeFaucet",
"params": [{ "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "balance": "10000" }]
}
设置辅助函数
// 辅助函数
// 获取智能账户的 USDC 余额
async function getUSDCBalance(): Promise<string> {
let res = await publicClient.readContract({
address: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
abi: ERC20Abi,
functionName: "balanceOf",
args: [account.address],
});
return formatUnits(res as bigint, 6).toString();
}// 获取智能账户的 DAI 余额
async function getDAIBalance(): Promise<string> {
let res = await publicClient.readContract({
address: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
abi: ERC20Abi,
functionName: "balanceOf",
args: [account.address],
});
return formatUnits(res as bigint, 18).toString();
}
发送交易
在账户中资金充足的情况下,通过智能账户客户端发送交易给捆绑器,指定接收者、值和可选数据。
初始化 DAI => USDC 兑换的参数
let swapParams = {
tokenIn: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063" as `0x${string}`, // DAI
tokenOut: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174" as `0x${string}`, // USDC
fee: 3000 as number, //费用
recipient: account.address, // 接受者
deadline: (Math.floor(Date.now() / 1000) + 60 * 30) as unknown as bigint, // 到期时间
amountIn: parseEther("1") as bigint, //amountIn
amountOutMinimum: 0 as unknown as bigint, //amountOutMinimum
sqrtPriceLimitX96: 0 as unknown as bigint, //sqrtPriceLimitX96
};
通过智能账户发送用户操作以:
exactInputSingle
交易到 UniswapV3Router 进行兑换// 发送用户操作以批准 DAI 并在 UniV3 上兑换 USDC
const txHash = await smartAccountClient.sendUserOperation({
account,
calls: [
{
to: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063" as `0x${string}`, //DAI
abi: parseAbi(["function approve(address,uint)"]),
functionName: "approve",
args: ["0xE592427A0AEce92De3Edee1F18E0157C05861564", parseEther("1")],
},
{
to: "0xE592427A0AEce92De3Edee1F18E0157C05861564",
abi: parseAbi([
"function exactInputSingle((address, address , uint24 , address , uint256 , uint256 , uint256 , uint160)) external payable returns (uint256 amountOut)",
]),
functionName: "exactInputSingle",
args: [
[
swapParams.tokenIn,
swapParams.tokenOut,
swapParams.fee,
swapParams.recipient,
swapParams.deadline,
swapParams.amountIn,
swapParams.amountOutMinimum,
swapParams.sqrtPriceLimitX96,
],
],
},
],
});
console.log("🟠 正在兑换 DAI....");let { receipt } = await smartAccountClient.waitForUserOperationReceipt({
hash: txHash,
});console.log(
`🟢用户操作已包含: https://explorer.buildbear.io/uzair/tx/${receipt.transactionHash}`
);balance = await publicClient.getBalance({ address: account.address }); // 获取发送者的余额
let daiBalanceAfter = await getDAIBalance();
let usdcBalanceAfter = await getUSDCBalance();console.log(
`🟢 太棒了! 🎉🎉 兑换 ${formatUnits(swapParams.amountIn, 18)} DAI 为 ${
+usdcBalanceAfter - +usdcBalanceBefore
} USDC`
);console.log("🟢 交易后的余额: ", formatEther(balance));
console.log("🟢 交易后的 DAI 余额: ", daiBalanceAfter);
console.log("🟢 交易后的 USDC 余额: ", usdcBalanceAfter);
使用 npm start
执行脚本,汇兑应当成功,产生以下输出:
====================================
智能账户地址: 0xa03Af1e5A78F70d8c7aCDb0ddaa2731E4A56E8FB
====================================
====================================
-------- 用户操作在 Uniswap V3 上将 DAI 兑换为 USDC,使用 Alto ---------
🟠交易前余额: 194.996055684952779832
🟠交易前 DAI 余额: 30000000192
🟠交易前 USDC 余额: 302.985378
====================================
🟠 正在批准 DAI....
====================================
🟠 正在兑换 DAI....
🟢用户操作已包含: https://explorer.buildbear.io/uzair/tx/0x243f6ad379bd4b306038d9afdcc842d60e14b33624050f37005724a45a99b33f
🟢 太棒了! 🎉🎉 兑换 1 DAI 为 0.9949579999999969 USDC
🟢 交易后的余额: 194.995769640950494282
🟢 交易后的 DAI 余额: 30000000191
🟢 交易后的 USDC 余额: 303.980336
点击“在 Sentio 上查看”,将打开一个 sentio 调试器,你可以在其中观察交易的概述,例如资金流动、调用跟踪和图表以及气体指标。
资金流动
描绘不同合约之间的资金流动及其执行顺序
调用跟踪
显示交易的整个调用轨迹,包括合约调用、合约内部调用的函数、输入和输出
调用图
类似于调用跟踪,但提供合约和函数调用的顶层视图
气体分析仪
描绘气体限制、实际消耗的气体、初始气体以及每个函数在函数调用过程中使用的气体
使用 Sentio 调试
除了概述之外,还有一个调试器标签页,可以查看和调试每个函数的单独调用,查看输入、气体指标和返回值。
还有一个合约部分,允许深入了解合约及其内部的函数
除了合约标签,还有一个事件标签,显示各个函数在交易过程中的事件排放。
最后,状态标签提供了交易所涉账户的交易前后的资金状态概览。
通过遵循本教程,你已成功设置了 BuildBear 上的 Pimlico Alto。使用 permissionless.js 配置了智能账户。为账户提供了资金并执行了一项在 Uniswap V3 上执行代币交换的用户操作。
要查看完整代码和示例,请查阅 GitHub 仓库!
- 原文链接: medium.com/buildbear/exe...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!