For the complete documentation index, see llms.txt. This page is also available as markdown.

Creating a Smart Account

Impatient? Check out a complete example here.

At the core of account abstraction is the smart account -- an account powered by a smart contract. ZeroDev is built on Kernel, a modular smart account that can be customized with plugins.

When you create a Kernel account, you set it up with a validator, which is a type of plugin that handles how the account validates UserOps. In this tutorial, we will be using the ECDSA validator, which works like a normal EOA by validating signatures from a ECDSA private key. ZeroDev supports other validators such as passkeys and multisig.

We will be using a local private key, but the ECDSA validator also works with third-party auth providers.

Installation

npm i @zerodev/sdk @zerodev/ecdsa-validator
yarn add @zerodev/sdk @zerodev/ecdsa-validator
pnpm i @zerodev/sdk @zerodev/ecdsa-validator
bun add @zerodev/sdk @zerodev/ecdsa-validator

API

Picking an EntryPoint

Currently there are two versions of ERC-4337 that are used in production. They are referred to as "EntryPoint 0.6" and "EntryPoint 0.7", where "EntryPoint" refers to the singleton ERC-4337 contract.

If you are building a new application, we recommend using EntryPoint 0.7 (Kernel v3), which gives you the latest and greatest features and optimizations. If you already have an application using EntryPoint 0.6 (Kernel v2), just stick with it -- it will be supported indefinitely.

In this tutorial, we will use EntryPoint 0.7. Start by selecting an EntryPoint:

const entryPoint = getEntryPoint("0.7")

Picking a Kernel version

Kernel is the smart account that ZeroDev builds on. ZeroDev SDK used to implicitly use the latest version of Kernel, which has caused some compatibility issues when people upgrade the SDK. Therefore, starting from ZeroDev SDK v5.3, we require that you explicitly specify the Kernel version. This is how you generally should choose:

  • If you had already been in production with ZeroDev SDK v4 or lower, use Kernel version 2.4 with EntryPoint 0.6.
  • If you had already been in production with ZeroDev SDK v5, use Kernel version 3.0 with EntryPoint 0.7.
  • If you are still in development or starting a new project, use Kernel version 3.1 with EntryPoint 0.7.
import { KERNEL_V3_1 } from "@zerodev/sdk/constants"

const kernelVersion = KERNEL_V3_1

Creating a public client

In Viem, a public client is an interface to a JSON-RPC API such as Infura or Alchemy.

import { createPublicClient, http } from "viem"
import { base } from 'viem/chains'

const publicClient = createPublicClient({
  // In production, you will want to set your RPC provider here (e.g. Infura/Alchemy).
  transport: http(),
  chain: base,
})

Creating a signer

As aforementioned, a Kernel account using a ECDSA validator is "owned" by a signer, which is anything that can sign messages with a private key.

Since Kernel is built on top of Viem, we can use any Viem account as the signer. In this example, we create a signer from a private key:

import { Hex } from "viem"
import { privateKeyToAccount } from "viem/accounts"

const signer = privateKeyToAccount("PRIVATE_KEY" as Hex)

Replace PRIVATE_KEY with an actual private key. You can generate a random one here.

Creating a ECDSA validator

Then create a ECDSA validator from the signer:

import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator"

const ecdsaValidator = await signerToEcdsaValidator(publicClient, {
  signer,
  entryPoint,
  kernelVersion
})

Create a Kernel account

Next, create a Kernel account with the ECDSA validator:

import { createKernelAccount } from "@zerodev/sdk"

const account = await createKernelAccount(publicClient, {
  plugins: {
    sudo: ecdsaValidator,
  },
  entryPoint,
  kernelVersion
})

Create an account client

Now that we have an account, we can finally construct an "account client," which is the equivalent of a wallet client in Viem that allows you to send UserOps to bundlers.

import { createKernelAccountClient } from "@zerodev/sdk"
import { http } from "viem"
import { base } from 'viem/chains'

const kernelClient = createKernelAccountClient({
  account,

  // Replace with your chain
  chain: base,

  // Find the RPC in your ZeroDev dashboard
  bundlerTransport: http('ZERODEV_RPC'),

  // Required - the public client
  client: publicClient,

  // Optional -- only if you want to use a paymaster
  paymaster: {
    getPaymasterData(userOperation) {
      return paymasterClient.sponsorUserOperation({userOperation})
    }  
  },
})

Note that:

  • You need to replace the ZERODEV_RPC with the RPC found on your ZeroDev dashboard.
  • You need to make sure to set the right chain.
  • paymaster only needs to be specified if you want to use a paymaster.

Now you are ready to do things with your smart account, like sending UserOps!

FAQs

On this page