🔄 Switch to Chinese (Main Language) README_CN.md
A groundbreaking platform that merges mystical divination with Web3 prediction markets. Users explore their destiny through interactive 3D Tarot cards and engage in prediction games using the native project token, TRGL.
Tarot Prediction combines ancient tarot symbolism with blockchain technology to create a unique prediction market experience. Users draw 3D tarot cards, receive detailed card interpretations, and can stake TRGL tokens on their predictions with adjustable confidence levels.
- Mystical Ritual Flow - Enhanced user experience with a shuffling ceremony, deep breath focus, and immersive card drawing.
- Detailed Card Interpretations - Comprehensive meanings for both upright and reversed positions, keywords, and spiritual insights.
- Performance Optimized - Component-level memoization (React.memo), stabilized callback references, and optimized data fetching logic.
- 3D Tarot Experience - Immersive Three.js 3D card scene with floating animations and interactive selection.
- Real Tarot Card Art - Authentic tarot card imagery with high-quality assets.
- Wallet Integration - Seamless MetaMask connection with Monad Testnet auto-switching.
- Token System - TRGL token (Tarot Gold) with automated mint/burn economic model.
- Prediction Market - Stake tokens on predictions with confidence-based rewards (1.5x multiplier - 5% fee).
- UX Overhaul: Introduced a mystical ritual flow to make the divination feel authentic rather than just a button click.
- Stability Fixes: Synchronized frontend reward calculations with smart contract logic (5% protocol fee).
- Network Resilience: Improved chain ID handling and automatic network switching for Monad Testnet.
- Frontend Performance: Applied React.memo and useMemo for heavy 3D components to ensure smooth 60FPS interaction during rituals.
- React 18 + Vite
- Three.js / @react-three/fiber (3D cards)
- ethers.js v6 (Web3)
- CSS3 with animations
- Solidity ^0.8.20
- OpenZeppelin Contracts
- Hardhat (local development)
- Local Development: Hardhat/Anvil (Chain ID: 31337)
- Testnet: Monad Testnet (Chain ID: 10143)
tarot-dapp/
├── backend/
│ ├── contracts/
│ │ ├── TarotToken.sol # ERC20 token with minting capability
│ │ └── TarotPrediction.sol # Prediction market contract
│ ├── scripts/
│ │ ├── deploy.js # Main deployment script
│ │ ├── deploy-quick.js # Quick deploy (used by start-persistent-node.sh)
│ │ └── fund-reward.js # Fund reward pool (deprecated, now uses minting)
│ ├── hardhat.config.js
│ └── .env # Contains PRIVATE_KEY, MONAD_RPC_URL
│
├── frontend/
│ ├── src/
│ │ ├── assets/
│ │ │ └── Tarot/ # Tarot card images (fool.png, magician.png, high_priestess.png)
│ │ ├── components/
│ │ │ ├── MysticalBackground.jsx # Animated mystical background effects
│ │ │ ├── wallet/
│ │ │ ├── token/
│ │ │ ├── tarot/
│ │ │ └── prediction/
│ │ ├── services/
│ │ │ ├── blockchain.js
│ │ │ └── tarotData.js # Card data with image paths
│ │ ├── App.jsx
│ │ ├── main.jsx
│ │ └── index.css # Global styles with mystical animations
│ ├── .env.local # Updated by deployment script
│ └── vite.config.js
│
└── start-persistent-node.sh # One-command start for local development
# 1. Start persistent Anvil node with contract deployment
cd /path/to/tarot-dapp
bash start-persistent-node.sh
# 2. In another terminal, start frontend
cd frontend
npm run dev
# 3. Open http://localhost:3000The start-persistent-node.sh script will:
- Start Anvil with persistent state (
~/.tarot-chain/) - Deploy contracts automatically
- Authorize prediction contract to mint tokens
- Update frontend
.env.localwith new contract addresses
Create backend/.env file:
# For local development (optional, uses default accounts)
PRIVATE_KEY=
# For testnet deployment
MONAD_RPC_URL=https://testnet-rpc.monad.xyz/
PRIVATE_KEY=0xyour_private_key_hereFrontend uses frontend/.env.local, which is automatically generated by the deployment script:
VITE_RPC_URL=http://127.0.0.1:8545
VITE_CHAIN_ID=31337
VITE_CONTRACT_ADDRESS=0x...
VITE_PREDICTION_CONTRACT_ADDRESS=0x...For testnet, update manually:
VITE_RPC_URL=https://testnet-rpc.monad.xyz/
VITE_CHAIN_ID=10143
VITE_CONTRACT_ADDRESS=0xdeployed_token_address
VITE_PREDICTION_CONTRACT_ADDRESS=0xdeployed_prediction_addressLocal Network:
- Network Name: Hardhat Local
- RPC URL: http://127.0.0.1:8545
- Chain ID: 31337
- Currency: ETH
Monad Testnet:
- Network Name: Monad Testnet
- RPC URL: https://testnet-rpc.monad.xyz/
- Chain ID: 10143
- Currency: ETH
- Connect Wallet - Click "Connect MetaMask" and approve
- Claim Tokens - Click "Claim 1000 TRGL" to get test tokens
- Draw a Card - Click on a 3D tarot card to reveal
- Read Interpretation - View card meaning and keywords
- Make Prediction - Set confidence level and stake TRGL
- Submit - Confirm transaction to place prediction
- Claim Reward - After result is revealed, claim your reward
Reward = Stake × (Confidence% / 100) × 1.5 × 0.95
Example:
- Stake: 60 TRGL
- Confidence: 50%
- Reward: 60 × 0.5 × 1.5 × 0.95 = 42.75 TRGL
- Plus stake returned: 60 TRGL
- Total: 102.75 TRGL
Traditional Reward Pool Problem:
❌ Need pre-funded reward pool
❌ Pool runs out = no rewards
❌ Requires manual funding
❌ Deployment to new network needs many test tokens
Token Minting Solution:
✅ No pre-funding needed
✅ Each user gets 1000+ TRGL in rewards
✅ No test token management
✅ Self-sustaining system
How It Works:
TarotTokencontract has amint()functionTarotPredictioncontract is authorized as a minter- When user wins, prediction contract calls
mint()to create new tokens - New tokens go directly to the winner
- Total supply increases (max 10M TRGL)
// TarotToken.sol - Mint function
function mint(address to, uint256 amount) external onlyAuthorized {
_mint(to, amount);
emit TokensMinted(to, amount);
}
// TarotPrediction.sol - Uses mint instead of pool
uint256 reward = calculateReward(pred);
if (reward > 0) {
(bool success, ) = address(tarotToken).call(
abi.encodeWithSignature("mint(address,uint256)", msg.sender, reward)
);
require(success, "Mint failed");
}Features:
- ERC20 token with 10M max supply
- 1000 tokens per faucet claim
- Authorized minting for reward distribution
- Owner can authorize/revoke minters
Key Functions:
function faucet() external // Get 1000 TRGL (no limit)
function mint(address to, uint256 amount) external // Only authorized callers
function authorizeMinter(address minter) external // Owner onlyFeatures:
- Submit predictions on card outcomes (3 cards: Fool, Magician, High Priestess)
- Confidence-based reward multiplier (0-100)
- Automatic result reveal (demo mode)
- Mint-based reward distribution
Key Functions:
function submitPrediction(
uint256 _cardId,
uint256 _confidence,
CardOutcome _predictedOutcome,
uint256 _stake
) external returns (uint256)
function claimReward(uint256 _predictionId) external
function setCardOutcome(uint256 _cardId, CardOutcome _outcome) external // Owner only# Start/restart with fresh deployment
bash start-persistent-node.sh
# Stop node
pkill -f anvil
# Check logs
tail -f ~/.tarot-chain/anvil.log
# Data directory
~/.tarot-chain/
├── state.json # Blockchain state
├── contracts.env # Deployed contract addresses
├── anvil.log # Node logs
└── anvil.pid # Process ID- Update
backend/.envwith your PRIVATE_KEY and MONAD_RPC_URL - Update
frontend/.env.localwith testnet RPC and chain ID - Deploy contracts:
cd backend
npx hardhat run scripts/deploy.js --network monad_testnet- Update frontend contract addresses in
frontend/.env.local
┌─────────────────────────────────────────────────────────────┐
│ TarotToken (TRGL) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ • Mint function (authorized minter only) │ │
│ │ • Faucet for test tokens │ │
│ │ • Max supply: 10M TRGL │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ authorizeMinter() │ mint() │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ TarotPrediction │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ submitPrediction() │ │ │
│ │ │ - Stake tokens │ │ │
│ │ │ - Create prediction record │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ claimReward() │ │ │
│ │ │ - Return stake │ │ │
│ │ │ - Mint reward tokens │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
- ReentrancyGuard - Prevents reentrancy attacks on prediction contract
- Access Control - Owner-only functions for admin operations
- Input Validation - Card ID, confidence, stake range checks
- Balance Checks - Sufficient allowance and balance verification
- Authorized Minting - Only authorized contracts can mint tokens
- Real card images for The Fool, The Magician, and The High Priestess
- Mystical card back with golden moon and star decorations
- Golden borders and glowing effects on card selection
- Smooth 3D flip animations when revealing cards
- Animated star field with 80+ twinkling stars
- Central rotating mandala with golden rays and celestial symbols
- Floating moon decorations (🌙 ☾) with gentle animations
- 20 mystical runes (✦ ✧ ⭐ ⬡ ⬢) drifting across the screen
- Particle effects with golden glow
- Constellation lines connecting stars
- Black & gold color scheme with purple accents
- Elegant corner frames with ornate decorations
| Animation | Description |
|---|---|
starTwinkle |
Stars pulse with golden glow |
mandalaRotate |
Central mandala slowly rotates |
moonFloat |
Moons gently float and rotate |
runeFloat |
Mystical symbols drift across screen |
particleFloat |
Golden particles rise and fade |
goldenGlow |
Panels pulse with golden light |
- Golden gradient headers with shimmer effects
- Glassmorphism panels with blur backdrop
- Animated keyword tags with star icons
- Upright/Reversed color-coded interpretations (green/red)
- Responsive layout - 3D cards on desktop, simplified 2D on mobile
- Mobile: < 768px (2D simplified mode)
- Tablet: 768px - 1024px
- Desktop: > 1024px (Full 3D)
This project demonstrates:
- ✅ Full-stack Web3 development
- ✅ 3D graphics integration with blockchain
- ✅ Smart contract design with token minting
- ✅ User experience optimization
- ✅ Multi-network support (local + testnet)
- ✅ Sustainable tokenomics (no pre-funded pool needed)
MIT License
Built with ❤️ for the Monad Hackathon