A full-stack multichain dApp demonstrating wallet integration, cross-chain balance tracking, RPC failover, and modern UX patterns. Deployed on Base Sepolia and Arbitrum Sepolia testnets.
┌─────────────────────────────────────────────────────────────────────────────┐
│ MULTICHAIN ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ │
│ │ Frontend │ │
│ │ (Next.js) │ │
│ │ │ │
│ │ • RainbowKit │ │
│ │ • wagmi/viem │ │
│ │ • RPC Failover │ │
│ └────────┬────────┘ │
│ │ │
│ ┌─────────────┴─────────────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ Base Sepolia │ │ Arbitrum Sepolia │ │
│ │ │ │ │ │
│ │ ┌────────────────┐ │ │ ┌────────────────┐ │ │
│ │ │ MultiChainToken│ │ │ │ MultiChainToken│ │ │
│ │ │ (MCT) │ │ │ │ (MCT) │ │ │
│ │ └───────┬────────┘ │ │ └───────┬────────┘ │ │
│ │ │ │ │ │ │ │
│ │ ┌───────▼────────┐ │ │ ┌───────▼────────┐ │ │
│ │ │ Treasury │ │ │ │ Treasury │ │ │
│ │ │ Contract │ │ │ │ Contract │ │ │
│ │ └────────────────┘ │ │ └────────────────┘ │ │
│ └──────────────────────┘ └──────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────┐
│ RPC FAILOVER FLOW │
├───────────────────────────────────────────────────────┤
│ │
│ Request │
│ │ │
│ ▼ │
│ ┌─────────┐ Success ┌──────────┐ │
│ │Primary │────────────────►│ Return │ │
│ │ RPC │ │ Result │ │
│ └────┬────┘ └──────────┘ │
│ │ │
│ │ Failure/Timeout │
│ ▼ │
│ ┌─────────┐ Success ┌──────────┐ │
│ │ Backup │────────────────►│ Return │ │
│ │ RPC │ │ Result │ │
│ └────┬────┘ └──────────┘ │
│ │ │
│ │ Failure │
│ ▼ │
│ ┌─────────┐ │
│ │ Error │ │
│ │ Handler │ │
│ └─────────┘ │
│ │
└───────────────────────────────────────────────────────┘
┌──────────┐ sign ┌──────────┐ confirm ┌──────────┐
│ IDLE │─────────► │ SIGNING │────────────►│ PENDING │
└──────────┘ └──────────┘ └────┬─────┘
▲ │ │
│ │ reject │
│ ▼ success/fail
│ ┌──────────┐ │
└─────────────────│ FAILED │◄────────────────┘
reset └──────────┘ │
▼
┌──────────┐
│CONFIRMED │
└──────────┘
-
MultiChainToken (MCT): ERC-20 token deployed on both chains
- EIP-2612 permit for gasless approvals
- Capped supply per chain (10M tokens)
- Chain-aware with chainId tracking
-
Treasury: Deposit/reward system per chain
- Deposit tokens to earn rewards
- Proportional reward distribution
- Withdrawal cooldown for security
- Wallet Integration: RainbowKit + WalletConnect
- Chain Switcher: Seamless chain switching
- Multi-chain Balances: Aggregate view across chains
- RPC Failover: Automatic fallback to backup RPCs
- Transaction States: Clear feedback for all tx states
multichain-web3-dashboard/
├── contracts/
│ ├── src/
│ │ ├── MultiChainToken.sol
│ │ ├── Treasury.sol
│ │ └── interfaces/
│ ├── test/
│ │ ├── unit/
│ │ ├── fuzz/
│ │ └── invariant/
│ ├── script/
│ │ ├── Deploy.s.sol
│ │ └── Interactions.s.sol
│ └── foundry.toml
├── frontend/
│ ├── src/
│ │ ├── app/
│ │ ├── components/
│ │ ├── config/
│ │ ├── hooks/
│ │ └── types/
│ ├── package.json
│ └── tailwind.config.ts
├── .gitignore
└── README.md
cd contracts
forge install
forge buildcd frontend
npm installcd contracts
# All tests
forge test
# Verbose output
forge test -vvv
# Specific test file
forge test --match-path test/unit/Treasury.t.sol
# Fuzz tests
forge test --match-path test/fuzz/
# Invariant tests
forge test --match-path test/invariant/# Create .env file
cp .env.example .env
# Required variables:
# PRIVATE_KEY=your_private_key
# BASE_SEPOLIA_RPC_URL=your_base_rpc
# ARBITRUM_SEPOLIA_RPC_URL=your_arbitrum_rpc
# BASESCAN_API_KEY=your_api_key
# ARBISCAN_API_KEY=your_api_keycd contracts
# Deploy to Base Sepolia
forge script script/Deploy.s.sol:DeployBase \
--rpc-url $BASE_SEPOLIA_RPC_URL \
--broadcast \
--verify
# Deploy to Arbitrum Sepolia
forge script script/Deploy.s.sol:DeployArbitrum \
--rpc-url $ARBITRUM_SEPOLIA_RPC_URL \
--broadcast \
--verifycd frontend
npm run dev| Chain | Chain ID | RPC | Explorer |
|---|---|---|---|
| Base Sepolia | 84532 | https://sepolia.base.org | https://sepolia.basescan.org |
| Arbitrum Sepolia | 421614 | https://sepolia-rollup.arbitrum.io/rpc | https://sepolia.arbiscan.io |
Each chain has primary and backup RPC endpoints configured in frontend/src/config/chains.ts:
const CHAIN_CONFIG = {
[baseSepolia.id]: {
rpcUrls: [
'https://sepolia.base.org', // Primary
'https://base-sepolia-rpc.publicnode.com', // Backup
],
},
// ...
};- Reentrancy protection via OpenZeppelin's ReentrancyGuard
- Withdrawal cooldown prevents flash loan attacks
- Owner-only minting and reward distribution
- Supply capped per chain
- RPC failover prevents single point of failure
- Transaction state machine prevents duplicate submissions
- Clear error handling and user feedback
- Aggregate Balances: Show total across all chains at a glance
- Chain Cards: Individual chain details with easy switching
- Transaction Feedback: Visual states for signing → pending → confirmed
- Responsive Design: Works on mobile and desktop
- Dark Theme: Easy on the eyes, crypto-native aesthetic
| Error | Handling |
|---|---|
| RPC Failure | Automatic failover to backup |
| User Rejection | Reset to idle state |
| Transaction Failure | Show error message, allow retry |
| Network Mismatch | Prompt chain switch |
MIT