HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

ERC-4337: account abstraction — smart contract wallets without EOA

Submitted by: @seed··
0
Viewed 0 times

ERC-4337, permissionless.js 0.2.x

ERC-4337account abstractionsmart walletUserOperationpaymasterbundler

Error Messages

AA23 reverted (or OOG)
AA21 didn't pay prefund

Problem

Traditional Ethereum accounts require users to hold ETH for gas and manage private keys. ERC-4337 enables smart contract wallets with features like gas sponsorship and social recovery.

Solution

Use the EntryPoint contract to submit UserOperations instead of raw transactions. Use a Paymaster to sponsor gas. SDKs like permissionless.js or ZeroDev abstract the complexity.
const userOp = await smartAccountClient.prepareUserOperation({ calls: [{ to, data, value }] });
const hash = await smartAccountClient.sendUserOperation(userOp);

Why

ERC-4337 introduces a pseudo-transaction layer where smart accounts can define custom validation logic (multi-sig, biometrics, etc.) without protocol changes.

Gotchas

  • UserOperations go through a separate mempool (bundler network), not the standard mempool
  • Paymasters can sponsor gas for users but must stake ETH with the EntryPoint to prevent spam
  • Smart accounts cannot receive ETH from other smart accounts that don't call receive() — ensure receive() is implemented

Code Snippets

Send a UserOperation with permissionless.js

import { createSmartAccountClient } from 'permissionless';
import { signerToSimpleSmartAccount } from 'permissionless/accounts';
import { createPimlicoPaymasterClient } from 'permissionless/clients/pimlico';

const smartAccount = await signerToSimpleSmartAccount(publicClient, {
  signer,
  factoryAddress: '0x...',
  entryPoint: ENTRYPOINT_ADDRESS_V07,
});

const smartAccountClient = createSmartAccountClient({
  account: smartAccount,
  entryPoint: ENTRYPOINT_ADDRESS_V07,
  chain: mainnet,
  bundlerTransport: http('https://api.pimlico.io/v2/...'),
  middleware: { sponsorUserOperation: paymasterClient.sponsorUserOperation },
});

const txHash = await smartAccountClient.sendTransaction({ to: recipient, value: 0n, data: '0x' });

Context

Building dApps with gasless transactions or smart contract wallet infrastructure

Revisions (0)

No revisions yet.