Skip to content
Alchemy Logo

How EIP-7702 Works

Alchemy Smart Wallets use EIP-7702 by default to give users access to all Smart Wallet capabilities including gas sponsorship, batching, and more - while keeping the same address.

EIP-7702 enables EOAs (Externally Owned Accounts) to delegate control to Smart Wallets that can execute code directly from their addresses. When using Transaction APIs:

  • You can use your signer address directly as the account address - no need to call wallet_requestAccount first
  • Transaction APIs automatically detect whether a user must first delegate via EIP-7702
  • If delegation is required, Transaction APIs prepare the correct authorization payload
  • Your application prompts the user to sign when required
  • We combine the delegation and transaction into a single onchain submission

Once delegated, the user's account behaves as a Smart Wallet while keeping the same address and assets. Subsequent transactions only require a single user operation signature.

For implementation details, see the Send Transactions guide.

If you need to use a traditional Smart Contract Account instead of EIP-7702, you can opt out of the default 7702 behavior by calling wallet_requestAccount first.

When you call wallet_requestAccount with a signer address, it creates a dedicated Smart Contract Account address. Using this SCA address (instead of your signer address) in subsequent API calls will bypass 7702 mode.

If you've already used a signer address in 7702 mode (e.g. by calling wallet_prepareCalls with the signer address), you'll need to specify creationHint: { accountType: "sma-b" } when calling wallet_requestAccount to create a separate Smart Contract Account for that signer.

When to use SCA mode:

  • Backwards compatibility with existing Smart Contract Accounts
  • Using chains that don't yet support EIP-7702
  • Using a signer that doesn't support signing EIP-7702 authorizations
  • Specific requirements for smart contract account architecture
import type { Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { sepolia } from "viem/chains";
import { createSmartWalletClient, alchemyWalletTransport } from "@alchemy/wallet-apis";
 
const client = createSmartWalletClient({
  transport: alchemyWalletTransport({ apiKey: "YOUR_API_KEY" }),
  chain: sepolia,
  signer: privateKeyToAccount("0xYOUR_PRIVATE_KEY" as const),
});
 
// Request a Smart Contract Account
const { address } = await client.requestAccount({ creationHint: { accountType: "sma-b" } });
 
// Pass the SCA address as the account to use non-7702 mode
await client.sendCalls({
  account: address,
  calls: [...],
});

How Wallet APIs handle delegation and signing

When interacting with Wallet APIs, delegation is handled automatically as part of transaction preparation.

If a user has not yet delegated on the target chain, the API response will include multiple signature requests:

  1. An EIP-7702 authorization signature (for delegation)
  2. An ERC-4337 user operation signature (for the transaction itself)

Your application is responsible for:

  • Prompting the user to sign each request
  • Returning the signatures to Alchemy

We combine these signatures into a single UserOperation and submits it to the bundler. After delegation is completed, future requests only require a user operation signature.

EIP-7702 authorization signing

When delegation is required, Wallet APIs return a Prepared EIP-7702 Authorization object.

This includes:

  • The delegation contract address
  • A nonce
  • The chain ID
  • A signatureRequest describing how the authorization must be signed

For quick testing purposes, you can simply use eth_sign to sign the signatureRequest.rawPayload.

For production usage, we recommend:

  • Verifying the delegation address is trusted
  • Using a dedicated EIP-7702 signing utility to compute the hash to sign

Example of signing utility:

Delegation-only (smart account upgrade) flows

You do not need to send a dummy or no-op transaction to perform delegation.

If a user needs to upgrade to a Smart Wallet:

  • Call wallet_prepareCalls with your intended calls (or an empty call set)
  • Wallet APIs detect that delegation is required
  • The response includes the required authorization and user operation signature requests

We handle combining delegation with the user operation automatically.

Wallet compatibility considerations

Some wallets restrict or block signing EIP-7702 authorizations for security reasons.

In particular:

  • MetaMask only allows delegation to its own contract via its UI
  • MetaMask does not support signing arbitrary EIP-7702 authorization payloads

For MetaMask users, you may need to rely on wallet-native features such as ERC-5792 batching instead of direct EIP-7702 delegation flows.

Ensure your users’ wallets support EIP-7702 authorization signing before enabling this flow.

EIP-7702 delegations

EIP-7702 delegation is now the default mode for Alchemy Smart Wallets. When you use your signer address directly with wallet_prepareCalls or other Transaction APIs, 7702 mode is automatically enabled.

The eip7702Auth capability supports the interface defined in ERC-7902.

Currently, Wallet APIs only support delegation to the following contract: 0x69007702764179f14F51cdce752f4f775d74E139 (Modular Account v2)

All other delegation addresses will be rejected.

Once delegated, an account remains delegated until the delegation is replaced or removed.

To reset an account back to a pure EOA, delegate to 0x0000000000000000000000000000000000000000 as defined in EIP-7702.

Un-delegating accounts

To remove a delegation and return an account to a pure EOA, you must re-delegate to the zero address: 0x0000000000000000000000000000000000000000.

Bundlers cannot relay undelegations, so you must submit this transaction directly from the account (with enough native gas token to cover fees). If you are re-delegating to another 4337 account, the bundler can relay the delegation.

To undelegate:

  1. Fund the account with a native gas token.
  2. Sign an EIP-7702 authorization delegating to address(0) with currentNonce + 1.
  3. Send an empty transaction (using currentNonce) that includes the authorization.

We recommend using Viem to sign the EIP-7702 authorization (with executor: self): Viem signAuthorization.

Using @account-kit/wallet-client (v4.x.x)?

The examples on this page use @alchemy/wallet-apis (v5.x.x). If you're using @account-kit/wallet-client (v4.x.x), the client setup looks like this:

client.ts (v4.x.x)
import { LocalAccountSigner } from "@aa-sdk/core";
import { createSmartWalletClient } from "@account-kit/wallet-client";
import { alchemy, sepolia } from "@account-kit/infra";
 
const signer = LocalAccountSigner.privateKeyToAccountSigner("0xYOUR_PRIVATE_KEY" as const);
 
export const client = createSmartWalletClient({
  transport: alchemy({ apiKey: "YOUR_API_KEY" }),
  chain: sepolia,
  signer,
  account: signer.address, // can also be passed per action as `from` or `account`
  // Optional: sponsor gas for your users (see "Sponsor gas" guide)
  policyId: "YOUR_POLICY_ID", 
});

Key v4.x.x differences:

  • Account address must be specified on the client or per action (from or account). In v5.x.x, the client automatically uses the signer's address as the account address via EIP-7702.
  • Chain imports come directly from @account-kit/infra instead of viem/chains.
  • Numeric values use hex strings: value: "0x0" instead of value: BigInt(0).
  • In v4.x.x, the paymaster capability on prepareCalls or sendCalls is called paymasterService instead of paymaster, or you can set the policyId directly on the client.
  • Signers use LocalAccountSigner / WalletClientSigner from @aa-sdk/core. In v5.x.x, a viem LocalAccount or WalletClient is used directly.

See the full migration guide for a complete cheat sheet.

Build more:

Was this page helpful?