SmartWalletFactory
Overview
The SmartWalletFactory is a UUPS-upgradeable factory contract responsible for deploying deterministic SmartWallet instances using CREATE2. It enables AI agents and users to deploy multiple smart wallets per owner with predictable addresses, making wallet discovery and management efficient for MCP servers and frontend applications.
Key responsibilities:
Deploy SmartWallet instances with deterministic addresses
Track wallet ownership for registry and paymaster validation
Manage wallet implementation upgrades (pull-based model)
Enforce deployment limits and pausability for safety
Design highlights:
CREATE2 deterministic deployment — wallet addresses are computable before deployment
Multi-wallet support — each owner can deploy up to 50 wallets using different salts
Pull-based upgrades — wallets upgrade themselves by calling the factory's
walletImplementationregistryPausable deployments — factory owner can halt new wallet creation in emergencies
Ownership tracking — maintains a registry of all wallets per owner for efficient lookup
Architecture Context
The factory is designed to work seamlessly with ERC-4337 account abstraction:
Bundler integration —
getInitCode()provides the exact bytes needed for UserOperation initializationEntryPoint compatibility — wallets are deployed via EntryPoint's SenderCreator for gas efficiency
Paymaster support —
isValidWalletmapping allows paymasters to verify wallet authenticityMCP integration — predictable addresses enable MCP servers to compute wallet addresses client-side before deployment
State Variables
Constants
MAX_WALLETS_PER_OWNER
uint256
Maximum wallets per owner (50)
ENTRY_POINT
IEntryPoint
ERC-4337 EntryPoint contract (immutable)
WALLET_IMPLEMENTATION
address
Base SmartWallet implementation (immutable)
SENDER_CREATOR
ISenderCreator
EntryPoint's SenderCreator for CREATE2 deployment (immutable)
Mutable State
walletImplementation
address
Current upgrade target for wallets (updatable by owner)
isValidWallet
mapping(address => bool)
Registry of deployed wallets for validation
totalWallets
uint256
Total number of wallets deployed by this factory
Internal Storage
_ownerWallets
mapping(address => EnumerableSet.AddressSet)
All wallets per owner (for multi-wallet support)
Core Functions
createWallet
Deploys a new SmartWallet instance with deterministic address.
Parameters:
walletOwner
address
Wallet owner address (ECDSA or P256 signer)
guardian
address
Optional initial guardian (use address(0) to skip)
salt
uint256
Additional salt for CREATE2 (for multi-wallet support)
Returns:
wallet
address
Address of deployed wallet
Requirements:
Factory must not be paused
Owner must not exceed
MAX_WALLETS_PER_OWNERlimitUses CREATE2 for deterministic deployment via EntryPoint's SenderCreator
Usage (MCP context):
getWalletAddress
Computes the deterministic address of a wallet before deployment.
Parameters:
walletOwner
address
Wallet owner address
guardian
address
Initial guardian address
salt
uint256
Deployment salt
Returns:
<none>
address
Computed wallet address
Usage: Critical for MCP servers to compute wallet addresses client-side without network calls.
getInitCode
Returns ERC-4337 initCode for UserOperation deployment.
Parameters:
walletOwner
address
Wallet owner address
guardian
address
Initial guardian address
salt
uint256
Deployment salt
Returns:
<none>
bytes
initCode bytes for UserOperation.initCode
Usage:
View Functions
getWalletsForOwner
Returns all wallet addresses for a given owner.
Parameters:
walletOwner
address
Owner address to query
Returns:
<none>
address[]
Array of wallet addresses owned by walletOwner
Usage: Used by MCP servers and frontends to discover all wallets for an AI agent or user.
Admin Functions
setWalletImplementation
Updates the wallet implementation address for future upgrades.
Parameters:
newImplementation
address
New SmartWallet implementation address
Access Control: onlyOwner
Note: Wallets must individually call upgradeToLatest() to adopt the new implementation. This pull-based model prevents forced upgrades.
pause
Pauses all wallet deployments.
Access Control: onlyOwner
Effect: Prevents createWallet() calls until unpaused.
unpause
Unpauses wallet deployments.
Access Control: onlyOwner
Wallet Integration
notifyOwnershipTransfer
Called by SmartWallet when ownership is transferred to update factory mappings.
Parameters:
previousOwner
address
Previous wallet owner
newOwner
address
New wallet owner
Access Control: Only callable by valid wallets deployed by this factory
Note: This callback maintains the _ownerWallets registry in O(1) time using EnumerableSet. It ensures getWalletsForOwner() remains accurate after ownership transfers.
Utility Functions
version
Returns the factory version number.
Returns:
<none>
uint256
Factory version (1 for initial release)
Security Considerations
Access Control
Factory owner controls:
Wallet implementation upgrades via
setWalletImplementation()Deployment pausability via
pause()/unpause()Factory upgrades via UUPS
_authorizeUpgrade()
Deployment Limits
Per-owner limit: Maximum 50 wallets per owner prevents abuse
Pausable: Factory owner can halt deployments in emergencies
Upgrade Model
Pull-based upgrades: Wallets must explicitly call
upgradeToLatest()— no forced upgradesImplementation immutability:
WALLET_IMPLEMENTATIONis immutable; onlywalletImplementation(upgrade target) is mutable
Registry Integrity
Ownership tracking:
notifyOwnershipTransfer()keeps wallet-owner mappings accurateValidation support:
isValidWalletmapping enables paymasters to verify wallet authenticity
Integration Patterns
MCP Server Integration
Multi-Wallet Management
Paymaster Validation
Last updated