
{"id":44294,"date":"2025-02-13T14:56:58","date_gmt":"2025-02-13T14:56:58","guid":{"rendered":"https:\/\/mycryptomania.com\/?p=44294"},"modified":"2025-02-13T14:56:58","modified_gmt":"2025-02-13T14:56:58","slug":"understanding-account-abstraction-aa-and-how-bundlers-work-a-deep-dive-with-minimal-bundler","status":"publish","type":"post","link":"https:\/\/mycryptomania.com\/?p=44294","title":{"rendered":"Understanding Account Abstraction (AA) and How Bundlers Work\u200a\u2014\u200aA Deep Dive with Minimal Bundler"},"content":{"rendered":"<h3>Understanding Account Abstraction (AA) and How Bundlers Work\u200a\u2014\u200aA Deep Dive with Minimal\u00a0Bundler<\/h3>\n<p>Ethereum has come a long way from its inception, and one of the most talked-about advancements in recent years is <strong>Account Abstraction (AA)<\/strong>.<\/p>\n<p>But what does <strong>AA<\/strong> actually do? How do <strong>Bundlers<\/strong> and <strong>Paymasters<\/strong> work? And most importantly, why does this change how transactions work?<\/p>\n<p>In this post, we\u2019ll break it all down with a <strong>real implementation<\/strong>: a minimal Bundler built using <strong>Biconomy\u2019s AA infrastructure<\/strong>.<\/p>\n<h3>\ud83d\udca1 The Problem with\u00a0EOAs<\/h3>\n<p>Ethereum started with <strong>Externally Owned Accounts (EOAs)<\/strong>\u200a\u2014\u200awallets controlled by a private\u00a0key.<\/p>\n<p>But EOAs have some <strong>major limitations<\/strong>:<\/p>\n<p>\u274c Lose your key? Say goodbye to your\u00a0funds.<\/p>\n<p>\u274c You always need <strong>ETH<\/strong> to pay for\u00a0gas.<\/p>\n<p>\u274c No custom transaction rules, just simple to, value, and data\u00a0fields.<\/p>\n<p>Account Abstraction (AA) <strong>fixes<\/strong> these problems by allowing users to use <strong>smart contract wallets<\/strong> instead of\u00a0EOAs.<\/p>\n<h3>\ud83d\udd25 What is Account Abstraction (AA)?<\/h3>\n<p>Instead of EOAs, <strong>AA introduces smart contract wallets<\/strong>, which\u00a0can:<\/p>\n<p>\u2705 Allow multi-signatures.<\/p>\n<p>\u2705 Let you <strong>pay gas in any token<\/strong> (or have someone else pay it for\u00a0you).<\/p>\n<p>\u2705 Enable <strong>social recovery<\/strong> and custom authentication logic.<\/p>\n<p>But to make this work, we need a <strong>new way<\/strong> to send transactions, and that\u2019s where <strong>Bundlers<\/strong> and <strong>Paymasters<\/strong> come\u00a0in.<\/p>\n<h3>\ud83d\ude80 How Transactions Work in Account Abstraction<\/h3>\n<p>A <strong>normal Ethereum transaction<\/strong> goes directly to the mempool, waiting to be picked up by miners or validators.<\/p>\n<p>With <strong>AA<\/strong>, the flow is different:<\/p>\n<p>The user <strong>creates a UserOperation<\/strong>.Sends it to a <strong>Bundler<\/strong>, NOT the\u00a0mempool.The <strong>Bundler validates<\/strong> and submits it to the\u00a0network.<\/p>\n<p>But what exactly does a <strong>Bundler<\/strong>\u00a0do?<\/p>\n<h3>\ud83d\udd04 What is a\u00a0Bundler?<\/h3>\n<p>A <strong>Bundler<\/strong> is like a miner, but specifically for <strong>AA transactions<\/strong>.<\/p>\n<p>It does the following:<\/p>\n<p>Accepts <strong>UserOperations<\/strong>.Validates them by checking: \ud83d\udd39 Signatures \ud83d\udd39 Gas limits and balances \ud83d\udd39 The validateUserOp() function in the smart contract\u00a0wallet.Packs <strong>UserOperations<\/strong> into a <strong>regular Ethereum transaction<\/strong> and sends it to the blockchain.<\/p>\n<p>Without a Bundler, <strong>AA wallets wouldn\u2019t work<\/strong>, as normal transactions require an <strong>EOA\u00a0sender<\/strong>.<\/p>\n<p>But who pays for gas? That\u2019s where <strong>Paymasters<\/strong> come\u00a0in.<\/p>\n<h3>\ud83d\udcb0 What is a Paymaster?<\/h3>\n<p>A <strong>Paymaster<\/strong> is a smart contract that <strong>sponsors gas\u00a0fees<\/strong>.<\/p>\n<p>It allows:<\/p>\n<p>\ud83d\udd39 Users to <strong>pay gas in any ERC-20\u00a0token<\/strong>.<\/p>\n<p>\ud83d\udd39 DApps to <strong>sponsor transactions<\/strong> for better\u00a0UX.<\/p>\n<p>\ud83d\udd39 Gasless transactions where users don\u2019t pay at\u00a0all.<\/p>\n<p>Without a Paymaster, <strong>AA wallets still need ETH<\/strong> for gas, which brings us back to the original\u00a0problem.<\/p>\n<h3>\ud83d\udee0\ufe0f Building a Minimal Bundler (with\u00a0Code)<\/h3>\n<p>To understand this process better, I built <strong>Minimal Bundler<\/strong>\u200a\u2014\u200aa simple Bundler implementation that works with Biconomy\u2019s AA infrastructure.<\/p>\n<p>It does the following:<\/p>\n<p>Accepts <strong>ERC-4337 UserOperations<\/strong>.Uses two different EOAs to send transactions (to avoid failures).Works on <strong>Sepolia\u00a0testnet<\/strong>.<\/p>\n<h3>Key Code: Handling a UserOperation<\/h3>\n<p>Here\u2019s how <strong>Minimal Bundler<\/strong> processes a <strong>UserOperation<\/strong>:<\/p>\n<p>import {<br \/>  createWalletClient,<br \/>  createPublicClient,<br \/>  encodeFunctionData,<br \/>  http,<br \/>} from &#8220;viem&#8221;;<br \/>import { sepolia } from &#8220;viem\/chains&#8221;;<br \/>import { privateKeyToAccount } from &#8220;viem\/accounts&#8221;;<br \/>import ENTRY_POINT_ABI from &#8220;..\/..\/abis\/EntryPointAbi.json&#8221;;<br \/>import { env } from &#8220;..\/..\/config\/env&#8221;;const ENTRY_POINT_ADDRESS = &#8220;0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789&#8221;;const walletClient1 = createWalletClient({<br \/>  chain: sepolia,<br \/>  transport: http(env.RPC_URL),<br \/>  account: privateKeyToAccount(`0x${env.PRIVATE_KEY_1}`),<br \/>});const walletClient2 = createWalletClient({<br \/>  chain: sepolia,<br \/>  transport: http(env.RPC_URL),<br \/>  account: privateKeyToAccount(`0x${env.PRIVATE_KEY_2}`),<br \/>});const publicClient = createPublicClient({<br \/>  chain: sepolia,<br \/>  transport: http(env.RPC_URL),<br \/>});let pick = 0;function pickWalletClient() {<br \/>  pick = 1 &#8211; pick; \/\/ flip 0 -&gt; 1, 1 -&gt; 0<br \/>  return pick === 0 ? walletClient1 : walletClient2;<br \/>}export async function handleSingleUserOp(userOp: any) {<br \/>  try {<br \/>    const walletClient = pickWalletClient();<br \/>    const [beneficiary] = await walletClient.getAddresses();    const data = encodeFunctionData({<br \/>      abi: ENTRY_POINT_ABI,<br \/>      functionName: &#8220;handleOps&#8221;,<br \/>      args: [[userOp], beneficiary],<br \/>    });    console.log(&#8220;\ud83d\udd39 Encoded handleOps calldata&#8221;);    const txHash = await walletClient.sendTransaction({<br \/>      to: ENTRY_POINT_ADDRESS,<br \/>      data,<br \/>    });    console.log(`Transaction sent: ${txHash}`);    return { transactionHash: txHash };<br \/>  } catch (err) {<br \/>    console.error(&#8220;Error in handleSingleUserOp:&#8221;, err);<br \/>    throw err;<br \/>  }<br \/>}<\/p>\n<p>This function:<\/p>\n<p>1\ufe0f\u20e3 Picks a wallet (to prevent stuck transactions).<\/p>\n<p>2\ufe0f\u20e3 Encodes a <strong>UserOperation<\/strong> for the EntryPoint contract.<\/p>\n<p>3\ufe0f\u20e3 Sends it as a <strong>transaction<\/strong>.<\/p>\n<p>Check the <strong>Minimal Bundler repo<\/strong> to see the full implementation: <a href=\"https:\/\/github.com\/craterface77\/minimal-bundler\"><strong>GitHub<\/strong><\/a><\/p>\n<h3>\ud83d\udee0\ufe0f Testing the\u00a0Bundler<\/h3>\n<h3>API Endpoint: eth_sendUserOperation<\/h3>\n<p>You can test by sending a <strong>UserOperation<\/strong> request:<\/p>\n<p>{<br \/>  &#8220;jsonrpc&#8221;: &#8220;2.0&#8221;,<br \/>  &#8220;method&#8221;: &#8220;eth_sendUserOperation&#8221;,<br \/>  &#8220;params&#8221;: [{<br \/>    &#8220;sender&#8221;: &#8220;0x&#8230;&#8221;,<br \/>    &#8220;nonce&#8221;: &#8220;0x&#8230;&#8221;,<br \/>    &#8220;initCode&#8221;: &#8220;0x&#8230;&#8221;,<br \/>    &#8220;callData&#8221;: &#8220;0x&#8230;&#8221;,<br \/>    &#8220;signature&#8221;: &#8220;0x&#8230;&#8221;,<br \/>    &#8220;paymasterAndData&#8221;: &#8220;0x&#8221;,<br \/>    &#8220;maxFeePerGas&#8221;: &#8220;0x&#8230;&#8221;,<br \/>    &#8220;maxPriorityFeePerGas&#8221;: &#8220;0x&#8230;&#8221;,<br \/>    &#8220;verificationGasLimit&#8221;: &#8220;0x&#8230;&#8221;,<br \/>    &#8220;callGasLimit&#8221;: &#8220;0x&#8230;&#8221;,<br \/>    &#8220;preVerificationGas&#8221;: &#8220;0x&#8230;&#8221;<br \/>  }, &#8220;0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789&#8221;],<br \/>  &#8220;id&#8221;: 1<br \/>}<\/p>\n<h3>\ud83c\udfaf Conclusion<\/h3>\n<p><strong>Account Abstraction<\/strong> is a game-changer for Ethereum UX. <strong>Bundlers<\/strong> and <strong>Paymasters<\/strong> make it possible to: \u2714\ufe0f Remove the need for EOAs. \u2714\ufe0f Allow gas payments in any token. \u2714\ufe0f Enable more flexible authentication.<\/p>\n<p>Want to see it in action? <strong>Try Minimal Bundler now!<\/strong>\u00a0\ud83d\ude80<\/p>\n<p><strong>References:<\/strong><\/p>\n<p><a href=\"https:\/\/github.com\/craterface77\/minimal-bundler\">GitHub Repo<\/a><a href=\"https:\/\/github.com\/bcnmy\">Biconomy<\/a><a href=\"https:\/\/github.com\/bcnmy\/sdk-examples\">Biconomy SDK\u00a0Examples<\/a><\/p>\n<p><strong>My Links:<\/strong><\/p>\n<p><a href=\"https:\/\/linktr.ee\/0xoleh\">Links<\/a> | <a href=\"https:\/\/www.buymeacoffee.com\/0xoleh\">BuyMeACoffe<\/a><\/p>\n<p><a href=\"https:\/\/medium.com\/coinmonks\/understanding-account-abstraction-aa-and-how-bundlers-work-a-deep-dive-with-minimal-bundler-eab6c90581fa\">Understanding Account Abstraction (AA) and How Bundlers Work\u200a\u2014\u200aA Deep Dive with Minimal Bundler<\/a> was originally published in <a href=\"https:\/\/medium.com\/coinmonks\">Coinmonks<\/a> on Medium, where people are continuing the conversation by highlighting and responding to this story.<\/p>","protected":false},"excerpt":{"rendered":"<p>Understanding Account Abstraction (AA) and How Bundlers Work\u200a\u2014\u200aA Deep Dive with Minimal\u00a0Bundler Ethereum has come a long way from its inception, and one of the most talked-about advancements in recent years is Account Abstraction (AA). But what does AA actually do? How do Bundlers and Paymasters work? And most importantly, why does this change how [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-44294","post","type-post","status-publish","format-standard","hentry","category-interesting"],"_links":{"self":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/posts\/44294"}],"collection":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=44294"}],"version-history":[{"count":0,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/posts\/44294\/revisions"}],"wp:attachment":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=44294"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=44294"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=44294"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}