Skip to content

Account Abstraction

Integrate Account Abstraction (ERC-4337) into viem.

While Account Abstraction is not built into the core viem library, you can use a third-party library like permissionless.js, ZeroDev and Biconomy to integrate with ERC-4337.

Libraries:

permissionless.js

permissionless.js is a TypeScript library built on viem for interacting with ERC-4337 bundlers, paymasters, and User Operations.

Below are instructions for setting up a Bundler Client.

1. Install

npm
npm i permissionless

2. Set up a Bundler Client

import { createClient, http } from 'viem'
import { mainnet } from 'viem/chains'
import { bundlerActions } from 'permissionless'
 
const bundlerClient = createClient({ 
  chain: mainnet,
  transport: http("https://api.pimlico.io/v1/goerli/rpc?apikey=YOUR_API_KEY_HERE")
}).extend(bundlerActions)

3. Consume Actions

Now you can consume Actions that are supported by permissionless.js.

See a full list of Bundler Actions.

import { createClient, http } from 'viem'
import { mainnet } from 'viem/chains'
import { bundlerActions } from 'permissionless'
 
const bundlerClient = createClient({ 
  chain: mainnet,
  transport: http("https://api.pimlico.io/v1/goerli/rpc?apikey=YOUR_API_KEY_HERE")
}).extend(bundlerActions)
 
const supportedEntryPoints = await bundlerClient.supportedEntryPoints() 

ZeroDev

ZeroDev is an SDK for building wallets and DApps using modular smart accounts. The SDK uses Viem's client-action architecture to model smart accounts and their plugins.

Below are instructions for setting up a smart account client (which interacts with bundlers using a modular smart account).

1. Install

Install the core SDK and a plugin.

npm
npm i @zerodev/sdk @zerodev/ecdsa-validator

2. Create a Public Client

import { createPublicClient, http } from 'viem'
 
const publicClient = createPublicClient({
  transport: http("RPC_URL"),  // use your RPC provider or bundler
})

3. Create an Account

This can be any Viem account type. In this case we use a Local Account.

import { privateKeyToAccount } from 'viem/accounts'
 
const account = privateKeyToAccount('0x...')  // replace with actual private key

4. Create a Validator Plugin

In this case, we are creating a smart account that uses ECDSA for validation (just like EOAs).

import { signerToEcdsaValidator } from '@zerodev/ecdsa-validator'
 
const ecdsaValidator = await signerToEcdsaValidator(publicClient, {
  signer: account,
})

5. Create a Smart Account

import { createKernelAccount } from '@zerodev/sdk'
 
const smartAccount = await createKernelAccount(publicClient, {
  plugins: {
    validator: ecdsaValidator,
  },
})

6. Create an account client

import { createKernelAccountClient } from '@zerodev/sdk'
import { http } from 'viem'
import { polygonMumbai } from 'viem/chains'
 
const kernelClient = createKernelAccountClient({
  account: smartAccount,
  chain: polygonMumbai,
  transport: http('BUNDLER_RPC'),  // use your bundler RPC
  sponsorUserOperation,  // optional -- only if you want to use a paymaster
})

7. Send UserOps

Now you can send UserOps using the account client:

const txnHash = await kernelClient.sendTransaction({
  to: '0x...',
  value: parseEther('0.1'),
})

You can also extend the account client with bundlerActions from Permissionless.js if you need to call any bundler RPCs:

import { bundlerActions } from 'permissionless'
 
const bundlerClient = kernelClient.extend(bundlerActions)
const receipt = await bundlerClient.waitForUserOperationReceipt({
  hash: userOpHash,
})

Biconomy

Biconomy offers a viem compatible SDK that can be used to interact with ERC-4337 Bundlers and Paymasters very easily with minimal integration required.

Below are instructions for setting up a smart account and sending a sponsored user operation.

1. Install

npm
npm i @biconomy/account

2. Create an Account

This can be any Viem Account type. In this case we use a Local Account.

import { privateKeyToAccount } from 'viem/accounts'
 
const account = privateKeyToAccount('0x...')  // replace with actual private key

3. Create a Smart Account Client

Head over to https://dashboard.biconomy.io/ to get your bundlerUrl and biconomyPaymasterApiKey.

import { createSmartAccountClient } from '@biconomy/account'
 
const smartAccount = await createSmartAccountClient({
  bundlerUrl,
  biconomyPaymasterApiKey,
  signer: account,
})

4. Send a Sponsored User Operation

const { wait } = await smartAccount.sendTransaction([{
  data: '0x...',
  to: '0x...',
}], {
  paymasterServiceData: {
    mode: PaymasterMode.SPONSORED,
  }
})