LLM Notice: This documentation site supports content negotiation for AI agents. Request any page with Accept: text/markdown or Accept: text/plain header to receive Markdown instead of HTML. Alternatively, append ?format=md to any URL. All markdown files are available at /md/ prefix paths. For all content in one file, visit /llms-full.txt
Skip to main content

ZeroDev Smart Account Integration for Flow EVM

Gas fees are one of the biggest barriers to blockchain adoption. ZeroDev solves this problem by enabling gasless transactions on Flow EVM through sponsored User Operations (UserOps), powered by an ERC-4337 compliant Kernel Smart Account.

With ZeroDev, you can eliminate gas fees for your users by sponsoring their transactions, utilize plugins for advanced features like Passkey support and Session Keys, improve user experience with seamless onboarding using Social Login, and support EIP-7702 for enhanced smart account functionality.

Objectives

After you complete this tutorial, you'll be able to:

  • Configure a ZeroDev project with the latest V3 RPC endpoint and Gas Sponsorship Policies
  • Set up the necessary clients using the Core SDK (@zerodev/sdk) and viem
  • Implement smart account creation and send sponsored User Operations on Flow EVM using KERNEL_V3_3

Prerequisites

Next.js and Modern Frontend Development

This tutorial uses Next.js. You don't need to be an expert, but it's helpful to be comfortable with development using a current React framework. You'll be on your own to select and use a package manager, manage Node versions, and other frontend environment tasks. If you don't have your own preference, you can just follow along with us and use Yarn.

Flow EVM and Smart Contract Development

This tutorial assumes you have basic familiarity with Flow EVM and smart contract development. You should understand how to interact with smart contracts and have experience with TypeScript or JavaScript development.

Setting up ZeroDev for sponsorship

Before you can enable gasless transactions, you need a ZeroDev Project ID and a configured Gas Sponsorship Policy.

Quick reference examples

For complete, runnable code examples that are kept up-to-date with the latest SDK changes, refer to these scripts:

Create your ZeroDev account and project configuration

  1. Sign up or log in to the ZeroDev Dashboard. The preferred dashboard version is V2.
  2. If you have an existing project, you can simply enable Flow Mainnet or Flow Testnet for it—you do not need to create a new project for every chain. This will use your existing Project ID.

Configure a gas sponsorship policy

To manage your gas costs and prevent over-spending, you must set up a Gas Sponsorship Policy:

  1. Navigate to the Gas Policies section within your project dashboard.
  2. Create a New Policy. Without a policy, ZeroDev will not sponsor any transactions.
  3. ZeroDev can front the gas costs and charge your credit card (post-pay), or you can purchase gas credits (pre-pay).

Obtain the ZeroDev RPC URL

The official V3 endpoint is the preferred method for connecting to the ZeroDev infrastructure, which includes the Paymaster and Bundler services.


_10
https://rpc.zerodev.app/api/v3/{YOUR_PROJECT_ID}/chain/{FLOW_EVM_CHAIN_ID}

Replace {YOUR_PROJECT_ID} with the ID from your dashboard.

Replace {FLOW_EVM_CHAIN_ID} with the Chain ID for Flow EVM: 747 for Mainnet or 545 for Testnet.

Send gasless transactions for your users

This section uses the Core SDK (@zerodev/sdk) and viem to set up the necessary clients and send a sponsored transaction.

Install all relevant dependencies


_10
# Using npm
_10
npm install @zerodev/sdk @zerodev/ecdsa-validator viem
_10
_10
# Using yarn
_10
yarn add @zerodev/sdk @zerodev/ecdsa-validator viem

Set up clients and the Kernel Smart Account

You must set up the Public Client using a public Flow EVM RPC, and the Kernel Account Client (which acts as the Bundler/Paymaster) using the ZeroDev V3 RPC.


_87
import {
_87
createKernelAccount,
_87
createKernelAccountClient,
_87
createZeroDevPaymasterClient,
_87
} from '@zerodev/sdk';
_87
import { getEntryPoint, KERNEL_V3_3 } from '@zerodev/sdk/constants';
_87
import { signerToEcdsaValidator } from '@zerodev/ecdsa-validator';
_87
import {
_87
http,
_87
createPublicClient,
_87
type Hex,
_87
parseAbi,
_87
defineChain,
_87
} from 'viem';
_87
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
_87
_87
// --- Custom Flow EVM Chain Definition (Testnet Example) ---
_87
// This is required if the chain is not natively supported by viem.
_87
const flowTestnetChain = defineChain({
_87
id: 545, // Flow EVM Testnet Chain ID
_87
name: 'Flow EVM Testnet',
_87
nativeCurrency: { name: 'FLOW', symbol: 'FLOW', decimals: 18 },
_87
rpcUrls: {
_87
default: {
_87
// Use the public Flow EVM Testnet RPC for the public client
_87
http: ['https://testnet.evm.nodes.onflow.org'],
_87
},
_87
},
_87
blockExplorers: {
_87
default: { name: 'FlowScan', url: 'https://evm-testnet.flowscan.io' },
_87
},
_87
});
_87
_87
// --- Configuration ---
_87
const ZERODEV_PROJECT_ID = 'YOUR_ZERODEV_PROJECT_ID';
_87
// Use the official Flow EVM Testnet Chain ID (545) in the V3 RPC
_87
const ZERODEV_RPC = `https://rpc.zerodev.app/api/v3/${ZERODEV_PROJECT_ID}/chain/545`;
_87
const PUBLIC_FLOW_RPC = flowTestnetChain.rpcUrls.default.http[0];
_87
_87
// 1. Setup Public Client (for reading chain state)
_87
const chain = flowTestnetChain;
_87
const publicClient = createPublicClient({
_87
transport: http(PUBLIC_FLOW_RPC),
_87
chain,
_87
});
_87
_87
// 2. Construct a Signer EOA (for account generation/testing)
_87
// We generate a private key for testing.
_87
const privateKey = generatePrivateKey();
_87
const signer = privateKeyToAccount(privateKey);
_87
const entryPoint = getEntryPoint('0.7');
_87
_87
// 3. Construct the Paymaster Client
_87
const zerodevPaymaster = createZeroDevPaymasterClient({
_87
chain,
_87
transport: http(ZERODEV_RPC),
_87
});
_87
_87
// 4. Construct the Kernel Smart Account
_87
const ecdsaValidator = await signerToEcdsaValidator(publicClient, {
_87
signer,
_87
entryPoint,
_87
kernelVersion: KERNEL_V3_3, // Use the latest stable Kernel version
_87
});
_87
_87
const account = await createKernelAccount(publicClient, {
_87
entryPoint,
_87
plugins: {
_87
sudo: ecdsaValidator,
_87
},
_87
kernelVersion: KERNEL_V3_3,
_87
});
_87
_87
console.log('Kernel Smart Account Address:', account.address);
_87
_87
// 5. Construct the Kernel Account Client (for sending UserOps)
_87
const kernelClient = createKernelAccountClient({
_87
account,
_87
chain,
_87
bundlerTransport: http(ZERODEV_RPC), // ZeroDev RPC acts as the Bundler
_87
paymaster: {
_87
// Explicitly configure the Paymaster for gas sponsorship
_87
getPaymasterData: (userOperation) => {
_87
return zerodevPaymaster.sponsorUserOperation({ userOperation });
_87
},
_87
},
_87
});

Send a gasless transaction (User Operation)

Using the kernelClient configured with the Paymaster middleware, the transaction will be wrapped in a User Operation (UserOp) and sponsored automatically.


_28
// Example target contract and function
_28
const targetContractAddress = '0xa8851f5f279eD47a292f09CA2b6D40736a51788E'; // Placeholder
_28
const contractABI = parseAbi(['function setValue(uint256 newValue) public']);
_28
const callData = await kernelClient.account.encodeCall({
_28
to: targetContractAddress,
_28
value: 0n,
_28
data: kernelClient.account.encodeFunctionData({
_28
abi: contractABI,
_28
functionName: 'setValue',
_28
args: [42n], // Example value
_28
}),
_28
});
_28
_28
// Send the gasless User Operation
_28
const userOpHash = await kernelClient.sendUserOperation({
_28
callData: callData,
_28
});
_28
_28
console.log('Submitted UserOp Hash:', userOpHash);
_28
console.log('Waiting for UserOp to be included on-chain...');
_28
_28
// Wait for the transaction to be mined
_28
const receipt = await kernelClient.waitForUserOperationReceipt({
_28
hash: userOpHash,
_28
});
_28
_28
console.log('UserOp confirmed!');
_28
console.log('Transaction Hash:', receipt.receipt.transactionHash);

Batching transactions

Kernel allows you to batch multiple transactions into a single sponsored User Operation.


_28
// Example of a batched User Operation (two calls in one)
_28
const userOpHashBatch = await kernelClient.sendUserOperation({
_28
callData: await kernelClient.account.encodeCalls([
_28
// First call
_28
{
_28
to: targetContractAddress,
_28
value: 0n,
_28
data: kernelClient.account.encodeFunctionData({
_28
abi: contractABI,
_28
functionName: 'setValue',
_28
args: [100n],
_28
}),
_28
},
_28
// Second call
_28
{
_28
to: targetContractAddress,
_28
value: 0n,
_28
data: kernelClient.account.encodeFunctionData({
_28
abi: contractABI,
_28
functionName: 'setValue',
_28
args: [200n],
_28
}),
_28
},
_28
]),
_28
});
_28
_28
console.log('Submitted Batched UserOp Hash:', userOpHashBatch);
_28
// ... wait for receipt

Conclusion

After you complete this tutorial, you'll be able to:

  • Configure a ZeroDev project with the latest V3 RPC endpoint and Gas Sponsorship Policies
  • Set up the necessary clients using the Core SDK (@zerodev/sdk) and viem
  • Implement smart account creation and send sponsored User Operations on Flow EVM using KERNEL_V3_3

You have successfully integrated the ZeroDev Smart Account and implemented gasless, batched transactions on Flow EVM using the latest best practices. This configuration, leveraging the V3 RPC and Kernel V3.3, ensures a seamless, gas-free experience for your users.