EIP-7702 allows an Externally Owned Account (EOA) to delegate its execution to a smart contract. After delegation, the EOA behaves as if it were a smart contract — it can have modules, guards, multi-sig logic — while remaining a standard EOA that signs transactions with its private key.
In IBEx.Fi, EIP-7702 is implemented alongside the existing
ERC-4337 Safe flow. A walletMode field distinguishes
between the two:
| walletMode | Description |
|---|---|
SAFE_4337 |
Traditional Safe Smart Contract Wallet via ERC-4337 (default) |
EOA_7702 |
EOA with EIP-7702 delegation to SafeEIP7702Proxy |
Both modes use the same API endpoints (/v1.2/auth/signup,
/v1.2/auth/signin, /v1.2/safes/operations).
<proxy_address>"authorizationList + setup() calldata0xef0100<proxy_address>setup() executes in the context of the EOA (EOA's storage)
Key concept: The code points to the SafeEIP7702Proxy,
but the storage lives on the EOA itself. Calling enableModule()
on the EOA stores the module in the EOA's storage, using the proxy's logic.
For EOA-based authentication (MetaMask, hardware wallets), two dedicated endpoints exist:
| Endpoint | Purpose |
|---|---|
POST /v1.2/auth/wallet-challenge |
Generates a SIWE-like challenge nonce for the wallet to sign |
POST /v1.2/auth/wallet-signin |
Verifies the wallet signature, creates user records if new, issues JWT tokens |
The response includes walletMode: "EOA_7702" and a delegations
array showing active EIP-7702 delegations per chain.
EIP-7702 supports gas sponsorship: a relayer account pays for transaction gas while the EOA only signs the authorization.
EOA signs authorization → Sponsor sends tx (pays gas) → EOA gets delegated
Controlled by EIP7702_SPONSOR_PRIVATE_KEY:
submitSponsoredDelegation())Once delegated, the EOA can call any Safe function on itself — enable modules, manage owners, execute transactions:
# Enable a module
cast send "$EOA" "enableModule(address)" "$MODULE" --private-key "$KEY"
# Check module status
cast call "$EOA" "isModuleEnabled(address)(bool)" "$MODULE"
# Check Safe state
cast call "$EOA" "getThreshold()(uint256)"
cast call "$EOA" "getOwners()(address[])"
# Verify delegation code
cast code "$EOA" # → 0xef0100
When the signer's walletMode is EOA_7702, the backend:
getSafe() — no ERC-4337 Safe to initializeMetaTransactionData[] — same operation handlers
work regardless of walletModeEIP-7702 requires the Pectra (Prague/Electra) upgrade. Not all chains support it yet:
| Chain | Chain ID | EIP-7702 |
|---|---|---|
| Ethereum Sepolia | 11155111 | ✅ Yes (post-Pectra) |
| Gnosis Chain | 100 | ❌ Not yet |
| Arbitrum Sepolia | 421614 | ❌ Not yet |
| Aspect | SAFE_4337 | EOA_7702 |
|---|---|---|
| Address | New contract address | Keeps original EOA address |
| Deployment | Via initCode in UserOp |
EIP-7702 delegation (Type 4 tx) |
| Execution | Bundler → EntryPoint → Safe | Direct transaction on EOA |
| Gas | Paymaster-sponsored | Sponsor-relayed or self-paid |
| Auth | WebAuthn passkey only | Wallet signature (MetaMask etc.) or passkey |
| Chain requirement | Any EVM chain | Pectra-enabled chains only |
| Contract | Address |
|---|---|
| SafeEIP7702ProxyFactory | 0x83179ba29ee581ea29cbee36869d535190498fdb |
| Safe Singleton L2 v1.4.1 | 0x29fcB43b46531BcA003ddC8FCB67FFE91900C762 |
Source: github.com/5afe/safe-eip7702