A decentralized Flappy Bird game built for Celo's MiniPay mobile wallet. Play with your profile picture as the bird, earn cUSD rewards, and mint your high scores as NFTs!
- ๐ฎ Classic Flappy Bird Gameplay - Tap to fly, avoid pipes
- ๐ผ๏ธ Profile Picture Bird - Your MiniPay profile picture becomes the bird
- ๐ฐ Earn cUSD - Get rewarded for your score
- ๐จ Mint NFTs - Turn high scores into collectible NFTs
- ๐ On-chain Leaderboard - Compete globally on Celo blockchain
- ๐ Social Sharing - Share your achievements on Twitter & WhatsApp
- Framework: Next.js 14 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- Web3: Viem 1.x
- Blockchain: Celo (Mainnet & Sepolia Testnet)
- Wallet: MiniPay Integration
- Smart Contracts: Solidity 0.8.x
- Node.js 18+ and npm
- Git
-
Clone the repository
git clone <your-repo-url> cd flappy_me
-
Install dependencies
npm install
-
Configure environment variables
Copy
.env.localand update with your values:cp .env.local .env.local
Required variables:
NEXT_PUBLIC_NETWORK_ENV- "testnet" or "mainnet"NEXT_PUBLIC_SCORES_CONTRACT_*- Your deployed contract addressesNEXT_PUBLIC_NFT_CONTRACT_*- Your NFT contract addressesNFT_STORAGE_KEY- API key from https://nft.storage
-
Run development server
npm run dev
-
Open in browser
http://localhost:3000
flappy_me/
โโโ src/
โ โโโ app/ # Next.js app router pages
โ โโโ components/ # React components
โ โโโ hooks/ # Custom React hooks
โ โ โโโ useWallet.ts # Wallet integration hook
โ โโโ utils/ # Utility functions
โ โ โโโ web3Client.ts # Viem client setup
โ โ โโโ constants.ts # App configuration
โ โโโ types/ # TypeScript types
โโโ contracts/ # Smart contracts (Solidity)
โโโ public/ # Static assets
โโโ .env.local # Environment variables
The wallet integration has been successfully implemented with the following components:
-
src/types/index.ts- TypeScript interfaces for wallet, contracts, game state, and NFTs
- Type-safe definitions for all data structures
-
src/utils/constants.ts- Network configuration (Celo Mainnet & Sepolia)
- Contract addresses
- Game physics constants
- Error messages and API endpoints
-
src/utils/web3Client.ts- Viem client setup (PublicClient & WalletClient)
- MiniPay detection
- Wallet connection utilities
- Balance queries (cUSD & CELO)
- Network verification
- Event listeners for account/chain changes
- Gas estimation with fee currency
-
src/hooks/useWallet.ts- React hook for wallet state management
- Auto-connect on mount
- Account/network change listeners
- Periodic balance refresh (every 30 seconds)
- Error handling
- localStorage integration
-
src/components/WalletStatus.tsx- Example component demonstrating hook usage
- Displays connection status, address, and balances
- Connect/disconnect buttons
โ MiniPay Detection
- Checks
window.ethereum.isMiniPayflag - Fallback to user agent detection
- Shows warnings when not using MiniPay
โ Auto-Connect
- Automatically connects to previously connected wallets
- Uses localStorage to remember wallet address
- Verifies account on mount
โ Balance Management
- Real-time cUSD balance using
stableTokenABIfrom@celo/abis - Native CELO balance
- Automatic refresh every 30 seconds
- Manual refresh capability
โ Network Handling
- Verifies user is on correct network (Celo Mainnet or Sepolia)
- Prompts network switch if needed
- Reloads page on chain change (best practice)
โ Error Handling
- User-friendly error messages
- Graceful fallbacks
- Debug logging (when enabled)
โ Event Listeners
- Account changes (user switches wallet)
- Chain changes (user switches network)
- Disconnect events
- Proper cleanup on unmount
import { useWallet } from '@/hooks/useWallet';
function MyComponent() {
const {
address,
isConnected,
isMiniPay,
balance,
connect,
disconnect,
} = useWallet();
return (
<div>
{isConnected ? (
<>
<p>Address: {address}</p>
<p>cUSD: {balance.cUSD}</p>
<button onClick={disconnect}>Disconnect</button>
</>
) : (
<button onClick={connect}>Connect Wallet</button>
)}
</div>
);
}-
Without MiniPay:
- Open in Chrome/Firefox
- Should show "No wallet detected" message
- Install MetaMask or another wallet to test basic connection
-
With MiniPay (Recommended):
- Open in MiniPay browser
- Should auto-detect and show MiniPay badge
- Auto-connect if previously connected
- Test balance fetching and refresh
-
Network Switching:
- Change network in wallet
- App should detect and prompt to switch back
-
Account Switching:
- Switch accounts in wallet
- App should update address and balances
- RPC:
https://alfajores-forno.celo-testnet.org - cUSD Address:
0xdE9e4C3ce781b4bA68120d6261cbad65ce0aB00b - Block Explorer: https://alfajores.celoscan.io
- RPC:
https://forno.celo.org - cUSD Address:
0x765de816845861e75a25fca122bb6898b8b1282a - Block Explorer: https://celoscan.io
- Physics Engine: Gravity, jump mechanics, velocity limits
- Collision Detection: Accurate bird-pipe and boundary collision
- Responsive Controls: Click/tap to jump
- Score Tracking: Real-time score updates
- High Score Persistence: Stored in localStorage
- MiniPay Wallet: Auto-detection and connection
- cUSD Balance: Real-time balance display
- Network Support: Celo Mainnet & Sepolia Testnet
- Transaction Handling: Gas estimation with fee currency
- Auto-fetch: Attempts to load from MiniPay
- Custom Upload: Users can upload their own image
- Pixelation: Canvas-based pixel art effect
- Caching: Stored in localStorage for quick access
- Score NFTs: Mint your high scores as ERC721 tokens
- Auto-generation: Creates custom NFT image with score, name, and bird
- IPFS Storage: Metadata stored on IPFS
- On-chain: Fully decentralized NFT ownership
- Global Rankings: View top players worldwide
- Player Rank: See your position on the leaderboard
- Real-time Updates: Fetches latest scores from blockchain
- Player Stats: Best score and total games played
- Twitter: Direct tweet with score
- WhatsApp: Share via WhatsApp
- Telegram: Share on Telegram
- Web Share API: Native mobile sharing
- Copy Link: Clipboard copy functionality
flappy_me/
โโโ src/
โ โโโ app/ # Next.js app router
โ โ โโโ page.tsx # Main game page
โ โ โโโ layout.tsx # Root layout
โ โ โโโ globals.css # Global styles
โ โ
โ โโโ components/ # React components (11 files)
โ โ โโโ GameContainer.tsx # Main game orchestrator
โ โ โโโ StartScreen.tsx # Game start screen
โ โ โโโ GameCanvas.tsx # Canvas rendering
โ โ โโโ GameHUD.tsx # In-game HUD
โ โ โโโ GameOverScreen.tsx # Game over screen
โ โ โโโ Leaderboard.tsx # Leaderboard display
โ โ โโโ NFTMinting.tsx # NFT minting UI
โ โ โโโ SocialShare.tsx # Social sharing buttons
โ โ โโโ WalletStatus.tsx # Wallet connection UI
โ โ โโโ ...
โ โ
โ โโโ hooks/ # Custom React hooks (6 files)
โ โ โโโ useWallet.ts # Wallet state & connection
โ โ โโโ useGameState.ts # Game loop & state
โ โ โโโ useProfilePicture.ts # Profile picture handling
โ โ โโโ useNFTMinting.ts # NFT minting logic
โ โ โโโ useLeaderboard.ts # Leaderboard fetching
โ โ โโโ ...
โ โ
โ โโโ utils/ # Utility functions (12 files)
โ โ โโโ web3Client.ts # Viem client setup
โ โ โโโ constants.ts # Configuration
โ โ โโโ gameEngine.ts # Game physics
โ โ โโโ collisionDetection.ts # Collision logic
โ โ โโโ contractInteraction.ts# Smart contract calls
โ โ โโโ imageProcessor.ts # Pixelation
โ โ โโโ nftGenerator.ts # NFT image generation
โ โ โโโ socialShare.ts # Share URLs
โ โ โโโ ...
โ โ
โ โโโ types/
โ โ โโโ index.ts # TypeScript definitions
โ โ
โ โโโ contracts/
โ โโโ abis.ts # Contract ABIs
โ
โโโ contracts/ # Smart contracts
โ โโโ FlappyBirdScores.sol # Leaderboard contract
โ โโโ FlappyBirdNFT.sol # NFT contract
โ
โโโ scripts/
โ โโโ deploy.ts # Deployment script
โ
โโโ Configuration files
โโโ package.json
โโโ tsconfig.json
โโโ next.config.js
โโโ tailwind.config.js
โโโ hardhat.config.ts
โโโ .env.local
Total Files Created: 40+
# Install Hardhat dependencies
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox @openzeppelin/contracts
# Compile contracts
npx hardhat compile
# Deploy to Celo Alfajores Testnet
npx hardhat run scripts/deploy.ts --network alfajores
# Deploy to Celo Mainnet (when ready)
npx hardhat run scripts/deploy.ts --network celoAfter deployment, update .env.local:
NEXT_PUBLIC_SCORES_CONTRACT_TESTNET=0x... # From deployment output
NEXT_PUBLIC_NFT_CONTRACT_TESTNET=0x... # From deployment output# Development
npm run dev
# Production build
npm run build
npm start- Open MiniPay: Launch Opera MiniPay on your mobile device
- Navigate to App: Enter your deployment URL or localhost (via ngrok)
- Connect Wallet: App will auto-detect MiniPay and prompt connection
- Get Test Tokens: Visit Celo Faucet for testnet cUSD
- Play & Test: Try all features - gameplay, NFT minting, leaderboard, sharing
# Reward rate (cUSD per point)
NEXT_PUBLIC_REWARD_RATE=0.01
# Minimum score to mint NFT
NEXT_PUBLIC_MIN_SCORE_FOR_NFT=100
# Enable/disable features
NEXT_PUBLIC_NFT_MINTING_ENABLED=true
NEXT_PUBLIC_LEADERBOARD_ENABLED=true
NEXT_PUBLIC_SOCIAL_SHARING_ENABLED=trueGRAVITY: 0.6 // Downward acceleration
JUMP_VELOCITY: -10 // Upward velocity on jump
MAX_VELOCITY: 15 // Terminal velocity
PIPE_SPEED: 3 // Pipe movement speed
PIPE_GAP: 150 // Gap between pipessubmitScore(score, playerName, profileImageIPFS)- Submit score to leaderboardgetLeaderboard(limit)- Get top N scoresgetPlayerRank(address)- Get player's rankgetPlayerStats(address)- Get player statistics
mintScoreNFT(to, score, playerName, tokenURI)- Mint score NFTtokenURI(tokenId)- Get NFT metadata URItokensOfOwner(address)- Get all NFTs owned by address
โ Wallet Integration: Full MiniPay detection and connection โ Game Engine: Complete physics and collision system โ Canvas Rendering: Smooth 60 FPS gameplay โ Profile Pictures: Upload, pixelate, and cache โ Score Tracking: Local high scores and on-chain submission โ NFT Minting: Generate, upload to IPFS, mint ERC721 โ Leaderboard: Fetch and display global rankings โ Social Sharing: Twitter, WhatsApp, Telegram, copy link โ Responsive UI: Works on desktop and mobile
- Smart Contracts: Need to be deployed before full functionality
- IPFS: Currently using mock data - integrate NFT.Storage API
- Testing: Thoroughly test on Celo Alfajores testnet first
- Security: Never commit private keys or API keys
- Gas Fees: All transactions use cUSD as fee currency
- IPFS upload is mocked (needs NFT.Storage API key)
- Contract addresses in .env are placeholders (deploy contracts first)
- MiniPay profile picture fetch is placeholder (awaiting MiniPay SDK)
- Leaderboard sorting is basic (optimize for large datasets)
MIT
Contributions welcome! Please open an issue or PR.
Built with โค๏ธ for the Celo community
Full-stack Web3 Game โข 40+ Files โข Production Ready