New transaction type (0x04) that lets an EOA install a delegation pointer to a smart-contract implementation, so the EOA temporarily executes that contract's code without changing its address or nonce. Status: Final (Standards Track / Core). Activated on Ethereum mainnet in the Pectra hard fork on May 7, 2025 (epoch 364032 / slot 11649024).
- 01upgrading existing EOAs to smart-account UX without migration
- 02transaction batching from an EOA
- 03session keys / sub-keys for an EOA
- 04gas sponsorship for existing wallets
- 05passkey / social-recovery delegation
- pnpm add viem # viem >= 2.21 supports type 0x04 / signAuthorization / sendAuthorizationList
- # common implementation contracts: MetaMask Delegation Framework, Ithaca Odyssey, Kernel v3 7702 mode, Simple7702Account
Use ERC-7702 to delegate an EOA to a smart-contract implementation. The EOA signs an authorization tuple `(chainId, address, nonce)` with `signAuthorization` (viem) producing a y-parity + r + s. Include the signed authorization in a type-`0x04` (`SET_CODE_TX_TYPE`) transaction's `authorizationList`. After the tx lands, the EOA's code field becomes the delegation indicator `0xef0100 || <implementation address>` (23 bytes, prefix from EIP-3541's banned opcode), and any subsequent CALL to the EOA executes the implementation's bytecode in the EOA's storage context. Send the type-0x04 tx with `walletClient.sendTransaction({ authorizationList: [auth], to, data })` or, when the EOA itself is the sender, viem's `sendTransaction` will inline the auth. Combine with ERC-4337 (the EOA delegates to a 4337 account) or ERC-7579 (delegate to a modular account) for a full smart-wallet experience. Reset to a normal EOA by signing an authorization to `address(0)`.
- ⚑Mainnet activation: Pectra, May 7, 2025. Type-0x04 transactions revert on pre-Pectra blocks — gate by chainId and `block.number` >= activation block of the target chain (Sepolia, Holesky, Hoodi, OP, Base, Arbitrum each have their own activation).
- ⚑The authorization nonce is the EOA's account nonce AT INCLUSION TIME — if the EOA is also the tx sender, the nonce in the auth must be sender_nonce + 1. Off-by-one here is the most common bug.
- ⚑`chainId == 0` in an authorization means 'any chain' — convenient for testing but a footgun for cross-chain replay. Always set chainId explicitly in production.
- ⚑Storage is shared across delegations: switching implementation does NOT clear storage. Designs must use ERC-7201 namespaced storage or the next implementation will read garbage from the previous one's slots.
- ⚑An authorization is consumed (nonce burned) even if the inner call reverts — pay attention to gas/refund accounting.
- ⚑`tx.origin == msg.sender` checks that historically guarded EOAs no longer guarantee 'no code' — contracts relying on `code.length == 0` for the caller will see code on a delegated EOA.