Skip to content

Quickstart -- EIP-7702

EIP-7702 is an upcoming Ethereum upgrade that will allow for attaching a piece of EVM code to a EOA, effectively turning it into a "dual account" that can function simultaneously as a EOA and a smart account. You can learn more about EIP-7702 from our blog series here and here.

In practical terms, this means that EOA users can now enjoy most of the benefits of AA, such as gas sponsorship, transaction batching, session keys, chain abstraction, and more.

In this example, we will upgrade a EOA into a ZeroDev smart account (Kernel) and send a gasless batched transaction from it.

Complete example

Here's the complete code example for you to reference as you follow along.

You can run the example with npx ts-node 7702/7702.ts after you set up the repo.

Install packages

You will be using the following packages:

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

Create a project for a 7702-compatible network

In this example, we will use the Sepolia testnet, but you can use any 7702-compatible network such as Holesky and Odyssey.

  • Go to the ZeroDev dashboard and create a project for Sepolia.
  • Enable gas sponsorship for Sepolia under Gas Policies.
  • Create a .env file as follows:
ZERODEV_RPC=

Use the ZeroDev RPC for Sepolia from the dashboard.

Set up the ZeroDev SDK

Set up a ZeroDev account using the 7702 helper functions:

import { create7702KernelAccount, create7702KernelAccountClient } from "@zerodev/ecdsa-validator";
import { createZeroDevPaymasterClient } from "@zerodev/sdk";
import { KERNEL_V3_3 } from "@zerodev/sdk/constants";
 
const kernelVersion = KERNEL_V3_3;
 
const signer = privateKeyToAccount(generatePrivateKey());
 
const publicClient = createPublicClient({
  transport: http(),
  chain,
});
 
const account = await create7702KernelAccount(publicClient, {
  signer,
  entryPoint,
  kernelVersion
})
 
const paymasterClient = createZeroDevPaymasterClient({
  chain,
  transport: http(ZERODEV_RPC),
});
 
const kernelClient = create7702KernelAccountClient({
  account,
  chain,
  bundlerTransport: http(ZERODEV_RPC),
  paymaster: paymasterClient,
  client: publicClient,
  userOperation: {
    estimateFeesPerGas: async ({ bundlerClient }) => {
      return getUserOperationGasPrice(bundlerClient)
    }
  }
})

Don't worry if the code doesn't make too much sense -- you can read more about the setup process here.

Comparing to the normal setup process, the only differences are that you are using create7702KernelAccount and create7702KernelAccountClient, instead of the normal createKernelAccount and createKernelAccountClient.

Using the ZeroDev SDK

Now you can use the ZeroDev SDK as usual. For example, to send a gasless batched UserOp:

const userOpHash = await kernelClient.sendUserOperation({
  callData: await kernelClient.account.encodeCalls([
    {
      to: zeroAddress,
      value: BigInt(0),
      data: "0x",
    },
    {
      to: zeroAddress,
      value: BigInt(0),
      data: "0x",
    },
  ]),
})
 
await kernelClient.waitForUserOperationReceipt({
  hash: userOpHash,
})
 
console.log("UserOp completed")

Congratulations! You just sent your first gasless, batched transaction using a EOA. You can see it by looking up your account on the Sepolia explorer. Note that you may need to look under "Internal Transactions" because UserOps do not appear as regular transactions.

Easy, right? Now explore the rest of the ZeroDev docs and see what you can do with your "smart EOA."