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 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=<YOUR_RPC_FROM_DASHBOARD>

Use the ZeroDev RPC on your project page from the dashboard.

Upgrade EOA to smart account

To upgrade a EOA to a smart account, you need to sign an "authorization." You can create this authorization manually and pass it to the ZeroDev SDK, or you can let ZeroDev create this authorization automatically.

Automatically create the authorization

Set up a ZeroDev account using the 7702 helper functions:

import { createKernelAccount, createKernelAccountClient, createZeroDevPaymasterClient } from "@zerodev/sdk";
import { KERNEL_V3_3 } from "@zerodev/sdk/constants";
 
const kernelVersion = KERNEL_V3_3;
 
// This is the EOA you want to upgrade
const eip7702Account = privateKeyToAccount(generatePrivateKey());
 
const publicClient = createPublicClient({
  transport: http(),
  chain,
});
 
const account = await createKernelAccount(publicClient, {
  eip7702Account,
  entryPoint,
  kernelVersion
})
 
const paymasterClient = createZeroDevPaymasterClient({
  chain,
  transport: http(ZERODEV_RPC),
});
 
const kernelClient = createKernelAccountClient({
  account,
  chain,
  bundlerTransport: http(ZERODEV_RPC),
  paymaster: paymasterClient,
  client: publicClient,
  userOperation: {
    estimateFeesPerGas: async ({ bundlerClient }) => {
      return getUserOperationGasPrice(bundlerClient)
    }
  }
})

Note that in this example, eip7702Account is the EOA you want to upgrade. We are using a random EOA in this example but you should replace this with the actual EOA.

Manually create the authorization

You can create the authorization manually with Viem's signAuthorization function, then pass the authorization to the ZeroDev SDK.

When you create the authorization, make sure you are specifying Kernel as the smart account.

import { KERNEL_V3_3 } from "@zerodev/sdk/constants";
 
const authorization = await walletClient.signAuthorization({
  account: signer,
  contractAddress: KERNEL_V3_3,
})
 
const account = await createKernelAccount(publicClient, {
  signer,
  entryPoint,
  kernelVersion,
  eip7702Auth: authorization
})

Sending UserOps from the smart account

Once you have upgraded the EOA to a smart account, 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 try some of the more advanced examples for building with 7702, or explore the rest of the ZeroDev docs!