A Next.js application demonstrating EIP-7702 smart account functionality using both ZeroDev and MetaMask Delegation Toolkit implementations. This project showcases how to upgrade Externally Owned Accounts (EOAs) to support smart account functionality with advanced loading states and user experience optimizations.
src/
βββ app/ # Next.js App Router pages
β βββ layout.tsx # Root layout
β βββ page.tsx # Home page (redirects to EIP-7702)
β βββ favicon.ico # App favicon
β βββ api/ # API routes
β β βββ local-addresses/ # Local addresses API
β β βββ wallet-operations/ # Wallet operations API
β β βββ wallet-status/ # Wallet status API
β βββ components/ # App-specific components
β βββ config/ # App configuration
β βββ eip7702/ # EIP-7702 route
β βββ metamask-debug/ # MetaMask debugging tools
β βββ metamask-permits/ # MetaMask permits demo
β βββ performance-demo/ # Performance demonstration
β βββ wallet-actions/ # Wallet operations route
β βββ wallet-demo/ # Wallet demo (legacy)
β βββ zerodev/ # ZeroDev route
βββ components/ # Reusable UI components
β βββ ui/ # Basic UI components
β β βββ PageSkeleton.tsx # Reusable skeleton loading component
β β βββ Button.tsx # Button component
β β βββ Card.tsx # Card component
β β βββ NetworkSelector.tsx # Network selection component
β β βββ index.ts # UI components export
β βββ layout/ # Layout components
β β βββ Navigation.tsx
β β βββ GlobalWalletManager.tsx
β β βββ ClientWrapper.tsx
β βββ wallet/ # Wallet-specific components
β β βββ WalletSelector.tsx
β β βββ WalletOperations.tsx
β β βββ index.ts
β βββ features/ # Feature-specific components
βββ features/ # Feature modules
β βββ eip7702/ # EIP-7702 MetaMask implementation
β βββ metamask-permits/ # MetaMask permits feature
β βββ wallet-actions/ # Wallet operations
β β βββ page.tsx
β β βββ components/ # Wallet action components
β β β βββ WalletStatus.tsx
β β β βββ UseCaseCard.tsx
β β β βββ EIP7702Authorization.tsx
β β β βββ ERC20Permit.tsx
β β β βββ OperationLogs.tsx
β β βββ types/ # Type definitions
β β βββ utils/ # Utility functions
β βββ wallet-demo/ # Wallet demo (legacy)
β βββ zerodev/ # ZeroDev implementation
βββ lib/ # Library configurations
β βββ providers.tsx # Wagmi providers
β βββ wallets/ # Modular wallet system
β βββ base-wallet.ts
β βββ local-key-wallet.ts
β βββ injected-wallet.ts
β βββ wallet-manager.ts
βββ hooks/ # Custom React hooks
β βββ useEIP7702.ts # EIP-7702 business logic
β βββ useWalletManager.ts # Wallet management hook
β βββ useWalletState.ts # Wallet state management
βββ contexts/ # React contexts
β βββ WalletContext.tsx # Global wallet state management
βββ types/ # TypeScript type definitions
β βββ index.ts
β βββ wallet.ts # Wallet type definitions
βββ utils/ # Utility functions
β βββ index.ts
βββ config/ # Configuration files
β βββ config.ts # Wagmi configuration
β βββ eip7702.ts # EIP-7702 settings
β βββ delegateeContracts.ts # Centralized delegatee contract configuration
β βββ addresses.ts # Contract addresses
β βββ index.ts # Configuration exports
β βββ README.md # Configuration documentation
βββ styles/ # Global styles
βββ globals.css
scripts/ # Command-line scripts βββ demo/ # Demo scripts β βββ demo-eip7702.ts βββ examples/ # Example implementations βββ run-7702-example.ts βββ run-7702-example-no-sponsor.ts βββ check-account.ts
docs/ # Documentation βββ api/ # API documentation βββ guides/ # User guides β βββ EIP7702_README.md βββ examples/ # Code examples
## π Features
### Advanced Loading State Management
- π¨ **Skeleton Loading**: Modern skeleton UI components for improved perceived performance
- β‘ **Granular Loading**: Smart loading states that only affect relevant UI sections
- π **Auto-Connection**: Seamless wallet auto-connection with proper loading feedback
- π± **Responsive Design**: Optimized loading states for all screen sizes
- π― **Context-Aware Loading**: Different loading states for different operations (auto-connect, account switching, delegation checking)
### Modular Wallet System
- π **Local Private Key Wallet**: Environment-based private key management
- Supports multiple private keys from `.env` file
- Legacy format: `PRIVATE_KEYS="0x111... 0x222... 0x333..."`
- Dynamic format: `KEY0=0x111...`, `KEY1=0x222...`, etc.
- Full EIP-7702 support with authorization signing
- Smart account creation and user operation sending
- π **Injected Wallet (MetaMask)**: Browser wallet integration
- MetaMask and other injected wallet support
- EIP-7702 with personal_sign implementation
- EIP-712 typed data signing
- User-friendly interface
- π **Embedded Wallet (Coming Soon)**: Privy integration
- Social login support
- Gasless transactions
- Enhanced user experience
- β‘ **Cross-Wallet EIP-7702 Features**:
- Authorization signing across all wallet types
- Smart account creation
- User operation sending
- Delegatee contract filtering and support checking
### ZeroDev Implementation
- π Smart Account creation with EIP-7702
- π° Send transactions with smart account
- π¨ Modern UI with Tailwind CSS
- π Wallet connection with RainbowKit
- β‘ Real-time transaction status
### MetaMask Delegation Toolkit Implementation
- π EIP-7702 authorization for delegatee contracts
- π§ MetaMask deleGator Core integration
- π Smart account creation using MetaMask's toolkit
- π€ User operation sending through upgraded EOAs
- π Real-time operation logging
## π οΈ Technology Stack
- **Framework**: [Next.js 15](https://nextjs.org/) with App Router
- **Smart Accounts**: [ZeroDev SDK](https://docs.zerodev.app/) & [MetaMask Delegation Toolkit](https://docs.metamask.io/delegation-toolkit/)
- **Ethereum**: [Viem](https://viem.sh/) & [Wagmi](https://wagmi.sh/)
- **UI**: [RainbowKit](https://www.rainbowkit.com/) & [Tailwind CSS](https://tailwindcss.com/)
- **Language**: TypeScript
- **Package Manager**: npm
## π Prerequisites
- Node.js 18+
- MetaMask wallet
- Sepolia testnet ETH
## π Quick Start
### 1. Installation
```bash
# Clone the repository
git clone <repository-url>
cd try7702
# Install dependencies
npm install
Create a .env.local file:
# ZeroDev Project ID (get from https://dashboard.zerodev.app)
ZERODEV_PROJECT_ID=your_zerodev_project_id_here
# Your private keys for testing (REQUIRED - quoted space-separated format)
PRIVATE_KEYS="0x111...111 0x222...222 0x333...333"
# Optional: WalletConnect Project ID
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_walletconnect_project_id_here- Never commit
.env.localto version control - Keep your ZeroDev Project ID private
- Use test accounts for development
The Modular Wallet System supports multiple private key formats:
PRIVATE_KEYS="0x1111111111111111111111111111111111111111111111111111111111111111 0x2222222222222222222222222222222222222222222222222222222222222222"KEY0=0x1111111111111111111111111111111111111111111111111111111111111111
KEY1=0x2222222222222222222222222222222222222222222222222222222222222222
KEY2=0x3333333333333333333333333333333333333333333333333333333333333333-
Local Private Key Wallet (Fully Implemented)
- Reads from environment variables
- Supports multiple key formats
- Full EIP-7702 functionality
-
Injected Wallet (MetaMask - Fully Implemented)
- Browser wallet integration
- EIP-7702 with personal_sign
- Account change detection
-
Embedded Wallet (Privy - Coming Soon)
- Social login support
- Gasless transactions
- Enhanced UX
# Start development server
npm run dev
# Open http://localhost:3000# Development
npm run dev # Start development server
npm run build # Build for production
npm run start # Start production server
npm run lint # Run ESLint
# Examples
npm run run-7702 # Run ZeroDev EIP-7702 example
npm run demo-metamask-7702 # Run MetaMask Delegation Toolkit example
npm run check-account # Check account statusThe application implements sophisticated loading state management:
- Initial Page Load: Full-page skeleton loading during app initialization
- Auto-Connection: Skeleton loading when automatically connecting to KEY0
- Account Switching: Granular loading for wallet status during account changes
- Delegation Checking: Smart loading states for delegation status verification
- PageSkeleton Component: Reusable skeleton UI for consistent loading experience
- Context-Aware Loading: Different loading states for different operations
- Non-Blocking UI: Available actions remain interactive during wallet operations
- Smart State Management: Loading states managed through React Context
The Modular Wallet System provides a unified interface for managing multiple wallet types:
- Select Wallet Type: Choose from available wallet types (Local Private Key, MetaMask, etc.)
- Configure Keys: For local wallets, select from available private keys
- Connect: Establish connection and verify account access
- Switch: Seamlessly switch between different wallet types
- Authorization: Sign EIP-7702 authorizations for delegatee contracts
- Smart Account Creation: Create MetaMask Smart Account instances
- User Operations: Send transactions through upgraded accounts
- Delegatee Management: Filter and validate supported contracts
- Unified API: Same interface across all wallet types
- Capability Detection: Automatic feature support checking
- Delegatee Filtering: Smart contract compatibility validation
- State Management: Consistent wallet state across the application
- Connect Wallet: Use the Connect Wallet button
- Choose Implementation:
- EIP-7702 Authorization:
/eip7702for MetaMask Delegation Toolkit - Wallet Actions:
/wallet-actionsfor wallet operations - ZeroDev Demo:
/zerodevfor ZeroDev EIP-7702
- EIP-7702 Authorization:
- Follow the Steps: Each implementation has a guided workflow
# Run ZeroDev example
npm run run-7702
# Run MetaMask example
npm run demo-metamask-7702
# Check account status
npm run check-accountThe application implements a sophisticated loading state management system:
-
src/contexts/WalletContext.tsx: Centralized wallet state management- Global loading states (
isAutoConnecting,isRenewingAccount) - Wallet connection and account management
- Delegation status tracking
- Non-blocking UI rendering
- Global loading states (
-
src/components/ui/PageSkeleton.tsx: Reusable skeleton loading component- Consistent loading UI across the application
- Mimics main page structure during loading
- Animated pulse effects for better UX
-
src/features/wallet-actions/components/: Granular loading componentsWalletStatus.tsx: Context-aware loading for wallet statusUseCaseCard.tsx: Interactive action cards with loading statesOperationLogs.tsx: Real-time operation logging
- Initial Load:
PageSkeletondisplayed during app initialization - Auto-Connection: Skeleton loading when connecting to default account
- Account Switching: Granular loading for wallet status section
- Delegation Checking: Smart loading states for delegation verification
- Action Execution: Non-blocking loading for specific operations
isAutoConnecting: Tracks automatic wallet connection processisRenewingAccount: Combines delegation checking and account switchingisLoading: General loading state for wallet operations- Granular Loading: Component-specific loading states for better UX
The project implements a sophisticated modular wallet system that supports multiple wallet types through a unified interface:
-
src/types/wallet.ts: TypeScript interfaces defining wallet contractsWalletInterface: Base interface for all wallet implementationsWalletAccount: Account information structureWalletCapabilities: Feature support matrixWalletType: Supported wallet types enumeration
-
src/lib/wallets/base-wallet.ts: Abstract base class providing common functionality- Standard wallet operations (connect, disconnect, sign)
- EIP-7702 authorization support
- Smart account creation capabilities
- User operation sending
-
src/lib/wallets/wallet-manager.ts: Central coordination system- Multi-wallet initialization and management
- Wallet switching and state management
- Capability checking and delegation
- React state change notifications
-
src/hooks/useWalletManager.ts: React integration layer- Wallet state management in React components
- Hook-based API for wallet operations
- Automatic state synchronization
-
src/lib/wallets/local-key-wallet.ts: Environment-based private key wallet- Reads private keys from environment variables
- Supports multiple key formats and indexing
- Full EIP-7702 implementation with MetaMask Delegation Toolkit
-
src/lib/wallets/injected-wallet.ts: Browser wallet integration- MetaMask and other injected wallet support
- EIP-7702 with personal_sign fallback
- Account change detection and handling
-
src/components/wallet/WalletSelector.tsx: Wallet selection interface- Available wallet detection and display
- Key selection for local wallets
- Connection status and switching
-
src/components/wallet/WalletOperations.tsx: Wallet operation interface- Account information display
- Transaction signing and sending
- EIP-7702 authorization workflow
- Unified Interface: All wallet types implement the same interface
- Capability Detection: Automatic feature support checking
- Delegatee Filtering: Smart contract support validation
- Cross-Wallet Compatibility: EIP-7702 works across all wallet types
- Type Safety: Full TypeScript support with strict typing
The project uses a feature-based architecture:
src/features/: Contains feature-specific codesrc/components/: Reusable UI componentssrc/hooks/: Custom React hooks for business logicsrc/lib/: Third-party library configurationssrc/utils/: Shared utility functionssrc/types/: TypeScript type definitions
- UI Components: Handle presentation and user interaction
- Custom Hooks: Manage business logic and state
- Utilities: Provide shared functionality
- Types: Ensure type safety across the application
The project uses a centralized configuration approach to prevent duplication:
src/config/delegateeContracts.ts: Single source of truth for delegatee contract informationsrc/config/eip7702.ts: Imports centralized configuration to avoid duplication- Benefits: Consistent contract data across the application, easier maintenance
// Centralized delegatee contracts (delegateeContracts.ts)
export const DELEGATEE_CONTRACTS: DelegateeContract[] = [
{
name: 'MetaMask deleGator Core',
description: 'Core delegation contract for MetaMask',
address: addresses.delegatee.metamask,
requiresInjected: true
},
// ... more contracts
]
// EIP-7702 configuration imports centralized data (eip7702.ts)
import { DELEGATEE_CONTRACTS } from './delegateeContracts'
export const EIP7702_CONFIG = {
// ... other config
delegateeContracts: DELEGATEE_CONTRACTS,
}Supported networks are configured in src/config/:
- Sepolia Testnet: Primary testing network
- Mainnet: Production deployment (when available)
Each feature can be configured independently:
- ZeroDev: Configured via environment variables
- MetaMask: Uses MetaMask Delegation Toolkit defaults
The Modular Wallet System is highly configurable:
# Private keys for local wallet
PRIVATE_KEYS="0x111... 0x222... 0x333..."
# OR
KEY0=0x111...
KEY1=0x222...
KEY2=0x333...
# ZeroDev configuration
ZERODEV_PROJECT_ID=your_project_id
# WalletConnect (optional)
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_walletconnect_idEach wallet type supports different capabilities:
-
Local Private Key Wallet:
- β EIP-7702 authorization signing
- β Smart account creation
- β User operation sending
- β Delegatee filtering
- β Transaction signing
-
Injected Wallet (MetaMask):
- β EIP-7702 authorization signing (with personal_sign)
- β EIP-712 typed data signing
- β Account change detection
β οΈ Limited smart account features
-
Embedded Wallet (Coming Soon):
- π Social login
- π Gasless transactions
- π Enhanced UX features
- EIP-7702 Guide: Detailed MetaMask implementation guide
- API Documentation: Technical API references
- Examples: Code examples and tutorials
- Improved UX: Skeleton loading provides better perceived performance
- Granular Control: Only affected UI sections show loading states
- Non-Blocking: Available actions remain interactive during operations
- Context-Aware: Different loading states for different operations
- Consistent Experience: Reusable skeleton components ensure consistency
- DRY Principle: No duplicate configuration across files
- Single Source of Truth: All contract data centralized
- Easier Maintenance: Changes only need to be made in one place
- Type Safety: Centralized type definitions prevent inconsistencies
- Unified Interface: Single API for multiple wallet types
- Type Safety: Full TypeScript support with strict typing
- Extensible: Easy to add new wallet implementations
- Capability Detection: Automatic feature support checking
- Cross-Wallet Compatibility: EIP-7702 works across all wallet types
- Flexibility: Choose from multiple wallet options
- Consistency: Same experience across different wallet types
- Security: Environment-based private key management
- Convenience: Seamless wallet switching
- Advanced Features: EIP-7702 and smart account support
- Development: Test with local private keys
- Production: Use MetaMask or other injected wallets
- Enterprise: Future embedded wallet integration
- DApps: Consistent wallet integration across applications
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- EIP-7702 Specification
- ZeroDev Documentation
- MetaMask Delegation Toolkit
- Viem Documentation
- Wagmi Documentation
For support and questions:
- Check the operation logs for detailed error information
- Review the documentation in the
docs/directory - Ensure you're connected to the correct network
- Verify your wallet has sufficient funds for gas fees
- Check loading states and skeleton UI for operation progress