EIP-7702 quickstart
This quickstart demonstrates how to upgrade your EOAExternally owned account (EOA) A private-key-controlled account with no built-in programmable execution logic. to support MetaMask smart accountMetaMask smart account A smart contract account created using the Smart Accounts Kit that supports programmable behavior, flexible signing options, and ERC-7710 delegations. functionality using an EIP-7702 transaction. This enables your EOA to leverage the benefits of account abstractionAccount abstraction A conceptual model for programmable onchain accounts, including flexible validation logic, custom signature schemes, and gas abstraction. ERC-4337 defines a mechanism for account abstraction., such as batch transactions, gas sponsorship, and delegationDelegation The ability for a MetaMask smart account to authorize another account to perform specific executions on its behalf..
Prerequisites
- Install Node.js v18 or later.
- Install Yarn, npm, or another package manager.
- Install Viem.
Steps
1. Install the Smart Accounts Kit
Install the Smart Accounts Kit:
- npm
- Yarn
- pnpm
- Bun
npm install @metamask/smart-accounts-kit
yarn add @metamask/smart-accounts-kit
pnpm add @metamask/smart-accounts-kit
bun add @metamask/smart-accounts-kit
2. Set up a Public Client
Set up a Public Client using Viem's createPublicClient function.
This client will let the EOA query the account state and interact with the blockchain network.
import { createPublicClient, http } from "viem";
import { sepolia as chain } from "viem/chains";
const publicClient = createPublicClient({
chain,
transport: http(),
});
3. Set up a Bundler Client
Set up a Bundler Client using Viem's createBundlerClient function.
This lets you use the bundlerBundler An ERC-4337 component that manages the alternate mempool: it collects user operations from smart accounts, packages them, and submits them to the network. service to estimate gas for user operationsUser operation A pseudo-transaction object defined by ERC-4337 that describes what a smart account should execute. User operations are submitted to the alternate mempool managed by bundlers. and submit transactions to the network.
import { createBundlerClient } from "viem/account-abstraction";
const bundlerClient = createBundlerClient({
client: publicClient,
transport: http("https://your-bundler-rpc.com"),
});
4. Set up a Wallet Client
Set up a Wallet Client using Viem's createWalletClient function.
This lets you sign and submit EIP-7702 authorizations.
import { createWalletClient, http } from "viem";
import { sepolia as chain } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
export const account = privateKeyToAccount("0x...");
export const walletClient = createWalletClient({
account,
chain,
transport: http(),
});
5. Authorize a 7702 delegation
Create an authorization to map the contract code to an EOAExternally owned account (EOA) A private-key-controlled account with no built-in programmable execution logic., and sign it
using Viem's signAuthorization action. The signAuthorization action
does not support JSON-RPC accounts.
This example uses EIP7702StatelessDeleGator as the EIP-7702 delegator contract.
It follows a stateless design, as it does not store signer data in the contract's state. This approach
provides a lightweight and secure way to upgrade an EOA to a MetaMask smart accountMetaMask smart account A smart contract account created using the Smart Accounts Kit that supports programmable behavior, flexible signing options, and ERC-7710 delegations..
import {
Implementation,
toMetaMaskSmartAccount,
getSmartAccountsEnvironment,
} from "@metamask/smart-accounts-kit";
import { privateKeyToAccount } from "viem/accounts";
const environment = getSmartAccountsEnvironment(sepolia.id);
const contractAddress = environment.implementations.EIP7702StatelessDeleGatorImpl;
const authorization = await walletClient.signAuthorization({
account,
contractAddress,
executor: "self",
});
6. Submit the authorization
Once you have signed an authorization, you can send an EIP-7702 transaction to set the EOA code. Since the authorization cannot be sent by itself, you can include it alongside a dummy transaction.
import { zeroAddress } from "viem";
const hash = await walletClient.sendTransaction({
authorizationList: [authorization],
data: "0x",
to: zeroAddress,
});
7. Create a MetaMask smart account
Create a smart accountMetaMask smart account A smart contract account created using the Smart Accounts Kit that supports programmable behavior, flexible signing options, and ERC-7710 delegations. instance for the EOA and start leveraging the benefits of account abstractionAccount abstraction A conceptual model for programmable onchain accounts, including flexible validation logic, custom signature schemes, and gas abstraction. ERC-4337 defines a mechanism for account abstraction..
import {
Implementation,
toMetaMaskSmartAccount,
} from "@metamask/smart-accounts-kit";
const addresses = await walletClient.getAddresses();
const address = addresses[0];
const smartAccount = await toMetaMaskSmartAccount({
client: publicClient,
implementation: Implementation.Stateless7702,
address,
signer: { walletClient },
});
8. Send a user operation
Send a user operationUser operation A pseudo-transaction object defined by ERC-4337 that describes what a smart account should execute. User operations are submitted to the alternate mempool managed by bundlers. through the upgraded EOA, using Viem's sendUserOperation method.
import { parseEther } from "viem";
// Appropriate fee per gas must be determined for the specific bundler being used.
const maxFeePerGas = 1n;
const maxPriorityFeePerGas = 1n;
const userOperationHash = await bundlerClient.sendUserOperation({
account: smartAccount,
calls: [
{
to: "0x1234567890123456789012345678901234567890",
value: parseEther("1")
}
],
maxFeePerGas,
maxPriorityFeePerGas
});
Next steps
- To grant specific permissions to other accounts from your smart account, create a delegation.
- To quickly bootstrap a MetaMask Smart Accounts project, use the CLI.
- You can also use MetaMask Connect to upgrade a MetaMask account to a smart account.