UNPKG

@biconomy/ecosystem

Version:

Testing infrastructure for abstractjs with ephemeral networks

130 lines (113 loc) 3.13 kB
import { EntrypointAbi, createSmartAccountClient, toNexusAccount } from "@biconomy/abstractjs" import { http, type Address, encodeFunctionData, erc20Abi, parseEther } from "viem" import { toPackedUserOperation } from "viem/account-abstraction" import { ENTRYPOINT_V07_ADDRESS, FREE_MINT_ERC20, NEXUS_IMPLEMENTATION_ADDRESS, getBalance, toClients } from "../src" import type { Infra } from "../src/toEcosystem" export const benchmark7702 = async ({ bundler, network: { rpcUrl, chain } }: Infra) => { const { publicClient, walletClients, testClient, accounts } = await toClients( { rpcUrl, chain } ) const nexusAccount = await toNexusAccount({ signer: accounts[0], chain, transport: http(rpcUrl) }) const nexusAccountClient = createSmartAccountClient({ account: nexusAccount, chain, transport: http(bundler.url), mock: true }) await testClient.setBalance({ address: nexusAccount.address, value: parseEther("10") }) const eip7702Account = accounts[8] const someWallet = accounts[9] const eip7702AccountClient = walletClients[8] const someWalletClient = walletClients[9] const userOp = await nexusAccountClient.prepareUserOperation({ calls: [ { to: FREE_MINT_ERC20, value: 0n, data: encodeFunctionData({ abi: erc20Abi, functionName: "transfer", args: [someWallet.address, parseEther("1")] }) } ] }) // update sender to be the eip7702Account address userOp.sender = eip7702Account.address userOp.factory = "0x" userOp.factoryData = "0x" const updatedHash = nexusAccount.getUserOpHash(userOp) const sig = await eip7702Account.signMessage({ message: { raw: updatedHash } }) userOp.signature = sig const nonce = await publicClient.getTransactionCount({ address: eip7702Account.address }) // sign eip7702 authorization with viem const authorization = await eip7702AccountClient.prepareAuthorization({ account: eip7702Account, contractAddress: NEXUS_IMPLEMENTATION_ADDRESS, chainId: 0, nonce: nonce }) const signedAuthorization = await eip7702AccountClient.signAuthorization(authorization) const packedUserOp = toPackedUserOperation(userOp) const balanceBefore = await getBalance( publicClient, someWallet.address, FREE_MINT_ERC20 ) const handleOpsHash = await someWalletClient.sendTransaction({ authorizationList: [signedAuthorization], data: encodeFunctionData({ abi: EntrypointAbi, functionName: "handleOps", args: [[packedUserOp], eip7702Account.address] }), to: ENTRYPOINT_V07_ADDRESS }) // get the receipt const receipt = await publicClient.waitForTransactionReceipt({ hash: handleOpsHash }) const balanceAfter = await getBalance( publicClient, someWallet.address, FREE_MINT_ERC20 ) if (balanceAfter - balanceBefore !== parseEther("1")) { throw new Error("Balance has not changed properly") } console.log("Delegate EOA to Nexus via 7702 + send ERC20", receipt.gasUsed) }