A sample application demonstrating how to build optimal USDC interoperability UX for wallets using Arc and Circle Gateway. This app showcases unified balance management, deposits, and cross-chain transfers across multiple EVM chains using Next.js and Supabase.
- Node.js 20.x or newer
- npm (automatically installed when Node.js is installed)
- Docker (for running Supabase locally)
- Circle Developer Controlled Wallets API key and Entity Secret
-
Clone the repository and install dependencies:
git clone git@github.com:circlefin/arc-multichain-wallet.git cd arc-multichain-wallet npm install -
Create a
.env.localfile in the project root:cp .env.example .env.local
Required variables:
# Supabase NEXT_PUBLIC_SUPABASE_URL=your_supabase_url NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your_publishable_or_anon_key # Circle CIRCLE_API_KEY=your_circle_api_key CIRCLE_ENTITY_SECRET=your_entity_secret
-
Set up Supabase (Local) This project uses local Supabase via Docker for development:
# Start local Supabase (requires Docker) npx supabase start # Push database migrations npx supabase db push
Note: If you prefer cloud-hosted Supabase, you can use:
npx supabase link npx supabase db push
-
Start the development server:
npm run dev
The app will be available at
http://localhost:3000.
- Built with Next.js and Supabase
- Uses Circle Gateway for unified USDC balance and cross-chain transfers
- Integrates Circle Developer Controlled Wallets for server-side wallet operations
- Demonstrates wallet connectivity with Wagmi and Viem
When you deposit USDC to the Gateway Wallet, it becomes part of your unified balance accessible from any supported chain. The Gateway Wallet uses the same address on all chains: 0x0077777d7EBA4688BDeF3E311b846F25870A19B9
- Approve Gateway Wallet to spend your USDC
- Call
deposit()to transfer USDC to Gateway - Balance becomes available across all chains after finalization
- Create and sign burn intent (EIP-712)
- Submit to Gateway API for attestation
- Call
gatewayMint()on destination chain - USDC minted on destination
| Variable | Scope | Purpose |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Public | Supabase project URL |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY |
Public | Supabase anonymous/public key |
CIRCLE_API_KEY |
Server-side | Circle API key for Gateway operations |
CIRCLE_ENTITY_SECRET |
Server-side | Circle entity secret for wallet operations |
- Designed for testnet only
- Requires valid Circle API credentials and Supabase configuration
- Private keys are processed server-side and never stored
- Never use mainnet private keys with this application
npm run dev: Start Next.js development server with auto-reloadnpx supabase start: Start local Supabase instance
This sample application:
- Assumes testnet usage only
- Handles secrets via environment variables
- Processes private keys server-side without storage
- Is not intended for production use without modification
See SECURITY.md for vulnerability reporting guidelines. Please report issues privately via Circle's bug bounty program.
To test the application, you'll need testnet USDC on the supported chains. Use the Circle Faucet to get free testnet tokens:
- Get Your Wallet Address: After signing up, your Circle Wallet addresses will be displayed in the dashboard
- Visit the Faucet: Go to https://faucet.circle.com/
- Request Tokens:
- Enter your wallet address
- Select the desired testnet (Arc Testnet, Base Sepolia, or Avalanche Fuji)
- Request USDC
- Wait for Confirmation: Transactions typically confirm within a few minutes
- Deposit to Gateway: Once received, use the "Deposit" tab to add USDC to your Gateway balance
- Arc Testnet: Primary chain for deposits and Gateway operations
- Base Sepolia: Ethereum Layer 2 testnet
- Avalanche Fuji: Avalanche testnet
When transferring USDC cross-chain, you'll need native tokens on the destination chain to pay for gas fees:
- Arc Testnet: USDC (no additional gas token needed)
- Base Sepolia: ETH (get from Base Sepolia Faucet)
- Avalanche Fuji: AVAX (get from Avalanche Faucet)
