EIP-7702 is an upgrade to EVM blockchains that enables externally owned accounts (EOAs) to set their code to that of a smart contract. In practical terms, this means that EOA wallets will gain AA (account abstraction) capabilities such as transaction bundling, gas sponsorship, and custom permissions.Privy supports all low level interfaces required by 7702 - signing authorizations and sending type 4 transactions, allowing you to use any implementation of EIP-7702. Use the following guides to get started with EIP-7702 in your application:
Privy provides methods to sign EIP-7702 authorizations using the user’s embedded wallet. This authorization is a cryptographic signature that allows an EOA to set its code to that of a smart contract, enabling the EOA to behave like a smart account.Learn more about signing EIP-7702 authorizations in our dedicated guide.Learn more about using the signed authorization in the integration guides below!
Detect current 7702 authorization state and implementation address
You can determine whether an EOA is currently delegated via EIP-7702 and read the authorized implementation address with a single eth_getCode call on the EOA address.Under EIP-7702, an authorized EOA temporarily exposes a small bytecode stub that begins with the magic prefix 0xef0100, followed immediately by the 20-byte implementation address. If eth_getCode returns empty code (0x or 0x0), the EOA is not currently delegated on that chain. The snippets below return the current implementation address or null.
Viem
Ethers
Report incorrect code
Copy
Ask AI
import {createPublicClient, http} from 'viem';import {mainnet} from 'viem/chains'; // replace with your chainconst publicClient = createPublicClient({ chain: mainnet, transport: http('your RPC URL here')});const address = '0x...'; // the EOA address hereconst code = (await publicClient.getCode({address}))?.toLowerCase() ?? '0x';const prefixIndex = code.indexOf('0xef0100');const authorizedImplementationAddress = prefixIndex === -1 ? null : (`0x${code.slice(prefixIndex + 8, prefixIndex + 48)}` as `0x${string}`);
Authorization state is per-chain. Under 7702, an authorized EOA will return non-empty code with
the 0xef0100 prefix; other non-empty code indicates a deployed contract account.
In this guide, we will transform your Privy embedded wallet into a smart wallet with features like gas sponsorship, batch transactions, granular permissions, and more using EIP-7702 support from Alchemy.
Create an app: visit the Alchemy dashboard to create a new app, if you don’t already have one.
Make sure to enable networks that support EIP-7702 such as Ethereum Mainnet or Sepolia.
Save the app’s API Key that will be used later.
Enable gas sponsorship: visit the Gas Manager dashboard and create a new sponsorship policy for the app you created in step 1. This policy will be used to set rules on how much of user’s gas you want to sponsor.
Make sure to enable gas sponsorship on a chain that support EIP-7702 such as Ethereum Mainnet or Sepolia.
Save the Policy ID that will be used later.
Now that you have your API key and Policy ID, you can set up your smart wallets.
If you’re already using a Privy embedded wallet, update your configuration to support EIP-7702 with embedded wallets. If you don’t yet have authentication configured, you can follow this guide to get set up.Make sure your PrivyProvider has the following embeddedWallets settings and ensure you set the defaultChain and supportedChains to the 7702 supported chain you chose in step 1.
Now that you have authentication working, adapt the Privy signer to be able to sign 7702 authorizations to upgrade to smart accounts.1. Get the Privy embedded wallet
4. Upgrade to smart accounts and send sponsored transactions
Now that you have a SmartAccountSigner instance, follow this guide to create a smart account client (createModularAccountV2Client ) and start sending sponsored transactions. You’ll need:
the SmartAccountSigner instance defined in step 3
the API key and the policy ID from step 1
Once you define the client, you can send sponsored transactions with your embedded EOA and access other advanced smart account features! This client will handle all of the logic of delegating to a new smart account, if not already, and signing transactions. If you don’t yet have a signer, follow this guide to get set up.Looking for a complete working example? See this working example integrating Privy embedded EOAs with EIP-7702 and Alchemy Smart Wallets.
You just upgraded your EOA and sent your first sponsored transaction using EIP-7702!If you want to leverage other smart account capabilities such as batching and permissions, check out the Alchemy docs.
In this guide we’ll see a quick example of using the Biconomy’s Modular Execution Environment (MEE) stack with Privy!
To keep things short, this guide will show you a simple example of single-chain orchestration
with cross-chain gas. However, the Biconomy MEE stack supports multi-chain orchestration cases. If
you’re looking to build a multi-chain DeFi strategy - read the Biconomy
Docs
To install the Biconomy Nexus 1.2.0 smart account on the address of your Privy embedded
wallet EOA, you need to sign the following authorization. Note: This is using the
signAuthorization method exposed by the useSignAuthorization Privy hook.
Report incorrect code
Copy
Ask AI
import {useSign7702Authorization} from '@privy-io/react-auth';import {baseSepolia} from '@privy-io/chains';const {signAuthorization} = useSign7702Authorization();const NEXUS_V120 = '0x000000004F43C49e93C970E84001853a70923B03';const authorization = await signAuthorization({ contractAddress: NEXUS_V120, chainId: baseSepolia.id, // or 0 for universal nonce: 0});
After signing, you can submit a transaction through Biconomy MEE Relayers. Notice
few things for this transaction:
Gas is paid with USDC
Gas is paid on a different chain than the instruction being executed
The amount arg in the ERC-20 transfer call is not fixed to a value, but uses
runtimeERC20BalanceOf which will inject the full amount of USDC available.
If you’ve used the chainId === 0 for your authorization you can store it (e.g. in localStorage or DB) and
replay it for other chains in the future. This gives your users an even more seamless UX.
In this guide, we’ll demonstrate how to use Pimlico, a bundler and paymaster service for ERC-4337 accounts, to enable your users to send gasless transactions using EIP-7702 authorization.
Want to see a full end to end example? Check out our starter repo
here
1. Sign up for a Pimlico account and get your API key
Head to the Pimlico dashboard here and create an account. Generate an API key and create a sponsorship policy for the network you plan to use (optional). Make note of your API key and sponsorship policy ID.
3. Create a simple smart account with Permissionless SDK
Permissionless provides a simple way to create a smart account client that can send user operations with EIP-7702 authorization. All you need is the user’s embedded wallet and the Pimlico API key.
Report incorrect code
Copy
Ask AI
import {useEffect} from 'react';import {usePrivy, useSign7702Authorization, useWallets} from '@privy-io/react-auth';import {useSetActiveWallet} from '@privy-io/wagmi';import {useWalletClient} from 'wagmi';import {createPublicClient, http, zeroAddress, Hex} from 'viem';import {sepolia} from 'viem/chains';import {createSmartAccountClient} from 'permissionless';import {createPimlicoClient} from 'permissionless/clients/pimlico';import {to7702SimpleSmartAccount} from 'permissionless/accounts';// Get the Privy embedded walletconst {wallets} = useWallets();const {data: walletClient} = useWalletClient();const embeddedWallet = wallets.find((wallet) => wallet.walletClientType === 'privy');// Set the embedded wallet as activeconst {setActiveWallet} = useSetActiveWallet();useEffect(() => { if (embeddedWallet) { setActiveWallet(embeddedWallet); }}, [embeddedWallet, setActiveWallet]);// Create a public client for the chainconst publicClient = createPublicClient({ chain: sepolia, transport: http(process.env.NEXT_PUBLIC_SEPOLIA_RPC_URL)});// Create a Pimlico clientconst pimlicoApiKey = process.env.NEXT_PUBLIC_PIMLICO_API_KEY;const pimlicoUrl = `https://api.pimlico.io/v2/${sepolia.id}/rpc?apikey=${pimlicoApiKey}`;const pimlicoClient = createPimlicoClient({ chain: sepolia, transport: http(pimlicoUrl)});// Create a 7702 simple smart accountconst simple7702Account = await to7702SimpleSmartAccount({ client: publicClient, owner: walletClient});// Create the smart account clientconst smartAccountClient = createSmartAccountClient({ client: publicClient, chain: sepolia, account: simple7702Account, paymaster: pimlicoClient, bundlerTransport: http(pimlicoUrl)});
Privy provides methods to sign EIP-7702 authorizations using the user’s embedded wallet. This authorization is a cryptographic signature that allows an EOA to set its code to that of a smart contract, enabling the EOA to behave like a smart account.
That’s it! You’ve just executed a gasless transaction from a normal EOA upgraded with EIP-7702 using Pimlico as the bundler and paymaster service.Explore the rest of the Pimlico docs to learn about advanced features like batching transactions, gas estimation, and more.
Want to see a full end to end example? Check out our starter repo
here!
In this guide, we’ll demonstrate how to use Porto, a universal blockchain account infrastructure with native cross-chain interoperability, together with Privy to upgrade your EOA wallets with EIP-7702.
With the account upgraded, you can now send transactions through Porto’s relay infrastructure with advanced features like gas sponsorship and cross-chain capabilities:
Report incorrect code
Copy
Ask AI
import {encodeFunctionData} from 'viem';// Example: Send a transaction to mint an NFTconst result = await RelayActions.sendCalls(client, { account, chain: Chains.baseSepolia, calls: [ { to: nftContractAddress, data: encodeFunctionData({ abi: nftAbi, functionName: 'mint', args: [account.address] }) } ]});console.log('Transaction sent:', result);
// Get the status of a transactionconst status = await RelayActions.getCallsStatus(client, { account, callHash: result.hash});console.log('Transaction status:', status);
In this guide, we demonstrate using ZeroDev, a toolkit for creating smart accounts, together with Privy to enable your users to send gasless (sponsored) transactions.
Want to see a full end to end example? Check out our starter repo
here!
1. Sign up for a ZeroDev account and create a project
Head to the ZeroDev dashboard and create a project on a chain that supports EIP-7702.Set up a gas sponsorship policy to enable sending sponsored transactions. Copy the Bundler RPC and Paymaster RPC for the network you plan to use.
Configure your app to create embedded wallets for all users. Also configure Privy to not show its default wallet UIs. Instead, we recommend you use your own custom UIs for showing users the user operations they sign.Update your PrivyProvider configuration to include the following properties:
3. Create a 7702 Kernel account with the ZeroDev SDK
ZeroDev exposes helper functions that take care of generating the 7702 authorization for you. All you need to provide is the signer for the user’s embedded wallet and the Kernel version you want to use.
Report incorrect code
Copy
Ask AI
import { createZeroDevPaymasterClient, createKernelAccountClient, createKernelAccount} from '@zerodev/sdk';import {KERNEL_V3_3} from '@zerodev/sdk/constants';import {getEntryPoint} from '@zerodev/sdk/constants';import {createWalletClient, createPublicClient, custom, http, zeroAddress, Hex} from 'viem';import {odysseyTestnet} from 'viem/chains';// Select the chain and Kernel version you want to useconst chain = odysseyTestnet;const kernelVersion = KERNEL_V3_3;const kernelAddresses = KernelVersionToAddressesMap[kernelVersion];const entryPoint = getEntryPoint('0.7');// Grab the embedded wallet created by Privyconst {wallets} = useWallets();const embeddedWallet = wallets.find((wallet) => wallet.walletClientType === 'privy');// Build viem clients for the wallet & public RPCconst walletClient = createWalletClient({ account: embeddedWallet.address as Hex, chain, transport: custom(await embeddedWallet.getEthereumProvider())});const publicClient = createPublicClient({ chain, transport: http()});// Sign the EIP-7702 authorizationconst authorization = await signAuthorization({ contractAddress: kernelAddresses.accountImplementationAddress, chainId: chain.id});// Create the 7702 Kernel account (no deployment occurs!)const account = await createKernelAccount(publicClient, { eip7702Account: walletClient, entryPoint, kernelVersion, eip7702Auth: authorization});
Behind the scenes ZeroDev generates the EIP-7702 authorization and binds the Kernel implementation code to the EOA, giving it smart-account super-powers while keeping the same address.
4. Configure the ZeroDev client for sponsored transactions
Report incorrect code
Copy
Ask AI
const paymasterRpc = 'YOUR_PAYMASTER_RPC_URL';const bundlerRpc = 'YOUR_BUNDLER_RPC_URL';// Create a paymaster client so the user does not need ETHconst paymasterClient = createZeroDevPaymasterClient({ chain, transport: http(paymasterRpc)});// Build a Kernel client that will create & submit UserOperationsconst kernelClient = createKernelAccountClient({ account, chain, bundlerTransport: http(bundlerRpc), paymaster: paymasterClient, client: publicClient});
That’s it! You’ve just executed a gasless transaction from a normal EOA upgraded with EIP-7702.Explore the rest of the ZeroDev docs to learn about batching, session keys, cross-chain actions and more.