EIP-7702 is enabled by default, giving you 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 to a smart wallet that can execute code directly from their addresses. When using Transaction APIs:
- Use your owner address directly as the account address - no need to call
wallet_requestAccountfirst - Transaction APIs automatically detect whether delegation via EIP-7702 is needed
- If delegation is required, Transaction APIs prepare the correct authorization payload
- Your application prompts for signing when required
- The delegation and transaction are combined into a single onchain submission
Once delegated, the account behaves as a Smart Wallet while keeping the same address and assets. Subsequent transactions require only a single signature.
For implementation details, see the Send Transactions guide.
If you need to use a traditional wallet instead of EIP-7702, opt out of the default 7702 behavior by calling wallet_requestAccount first.
When you call wallet_requestAccount with an owner address, it creates a dedicated smart wallet address. Using this address (instead of your owner address) in subsequent API calls bypasses 7702 mode.
If you've already used an owner address in 7702 mode (e.g. by calling wallet_prepareCalls with the owner address), specify creationHint: { accountType: "sma-b" } when calling wallet_requestAccount to create a separate smart wallet for that owner.
When to use non-7702 mode:
- Backwards compatibility with existing wallets
- Using chains that don't yet support EIP-7702
- Using an owner that doesn't support signing EIP-7702 authorizations
- Specific requirements for smart wallet 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 delegation has not yet occurred on the target chain, the API response includes multiple signature requests:
- An EIP-7702 authorization signature (for delegation)
- A transaction signature (for the transaction itself)
Your application is responsible for:
- Prompting for each signature
- Returning the signatures
These signatures are combined into a single transaction and submitted. After delegation is completed, future requests require only a transaction 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
signatureRequestdescribing how the authorization must be signed
For quick testing, use eth_sign to sign the signatureRequest.rawPayload.
For production usage:
- 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 wallet upgrade) flows
You do not need to send a dummy or no-op transaction to perform delegation.
If an account needs to upgrade to a smart wallet:
- Call
wallet_prepareCallswith your intended calls (or an empty call set) - Wallet APIs detect that delegation is required
- The response includes the required authorization and transaction signature requests
Combining delegation with the transaction is handled 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 the target wallets support EIP-7702 authorization signing before enabling this flow.
EIP-7702 delegations
EIP-7702 delegation is now the default mode for Smart Wallets. When you use your owner 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.
Undelegations cannot be relayed, 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 smart wallet, the transaction can be relayed.
To undelegate:
- Fund the account with a native gas token.
- Sign an EIP-7702 authorization delegating to
address(0)withcurrentNonce + 1. - Send an empty transaction (using
currentNonce) that includes the authorization.
Use 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:
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 (
fromoraccount). In v5.x.x, the client automatically uses the owner's address as the account address via EIP-7702. - Chain imports come directly from
@account-kit/infrainstead ofviem/chains. - Numeric values use hex strings:
value: "0x0"instead ofvalue: BigInt(0). - In v4.x.x, the paymaster capability on
prepareCallsorsendCallsis calledpaymasterServiceinstead ofpaymaster, or you can set thepolicyIddirectly on the client. - Owners use
LocalAccountSigner/WalletClientSignerfrom@aa-sdk/core. In v5.x.x, a viemLocalAccountorWalletClientis used directly.
See the full migration guide for a complete cheat sheet.
Build more: