Gasless USDC claiming for sSPORK holders via Unicorn.eth integration
Created by: @cryptowampum
Developed with: Claude AI
License: MIT
A Merkle tree-based USDC rewards distribution system for sSPORK token holders. Users can claim their rewards through either:
- π¦ Unicorn wallets (gasless claiming via App Centers)
- πΌ Regular wallets (MetaMask, WalletConnect, etc.)
- β Gasless claiming with Unicorn smart account wallets
- β Secure Merkle proofs for reward verification
- β CSV processing to generate distribution data
- β Multi-wallet support (Unicorn + traditional wallets)
- β Mobile responsive interface
- β One-click AutoConnect from Unicorn App Centers
- Node.js 16+
- Git
- A CSV file with wallet addresses and reward amounts
git clone https://github.com/your-org/sspork-rewards-distribution.git
cd sspork-rewards-distribution
npm install# Prepare your CSV file with simple format: address,usdc_reward
cp your-rewards.csv data/sspork-holders.csv
# Generate Merkle tree and proofs (simplified version)
npm run process-csv-simple data/sspork-holders.csvThis generates:
merkle-proofs.json- Frontend datadeployment-info.json- Contract deployment data
# Copy environment variables
cp .env.example .env
# Edit .env with your private key and network settings
# Deploy to Polygon testnet
npm run deploy-contract-testnet
# Deploy to Polygon mainnet
npm run deploy-contractEdit src/config/contracts.js with your deployed contract address:
export const MERKLE_DISTRIBUTOR_ADDRESS = "0x..."; // Your deployed contractnpm startVisit http://localhost:3000
npm run build
# Deploy build/ folder to Vercel, Netlify, or your preferred hostFill out the App Center submission form with your deployed URL.
sspork-rewards-distribution/
βββ public/ # Static assets
βββ src/
β βββ components/ # React components
β β βββ MerkleDistributor.jsx
β β βββ WalletConnection.jsx
β βββ config/ # Configuration files
β β βββ unicorn.js # Unicorn wallet setup
β β βββ contracts.js # Contract addresses
β βββ hooks/ # Custom React hooks
β βββ App.js # Main application
βββ contracts/ # Solidity smart contracts
β βββ USDCMerkleDistributor.sol
βββ scripts/ # Utility scripts
β βββ csv-to-merkle.js # CSV processing
β βββ deploy.js # Contract deployment
βββ data/ # Data files
βββ hardhat.config.js # Hardhat configuration
βββ README.md
# Wallet & Network
PRIVATE_KEY=your_deployment_wallet_private_key
POLYGON_RPC_URL=https://polygon-rpc.com
MUMBAI_RPC_URL=https://rpc-mumbai.matic.today
# Contract Verification
POLYGONSCAN_API_KEY=your_polygonscan_api_key
# Frontend
REACT_APP_CONTRACT_ADDRESS=your_deployed_contract_address
REACT_APP_NETWORK=polygonYour sSPORK holders CSV should follow this simple format:
address,usdc_reward
0x742d35Cc6635C0532925a3b8D710432D8c14C3C1,500.50
0x8ba1f109551bD432803012645Hac136c,1001.00
0x...,750.25
Clean and simple - just addresses and their USDC rewards! π―
- User clicks dApp in their community's app center
- AutoConnect - instant wallet connection (no selection needed)
- Check eligibility - automatic lookup of their address
- Claim rewards - gasless transaction via Unicorn smart account
- Done! - USDC appears in wallet with zero gas fees
- User visits dApp URL directly
- Connect wallet - choose from available options
- Check eligibility - see reward amount if eligible
- Claim rewards - pay gas fees normally (~$3-8)
- Done! - USDC transferred to wallet
- Merkle proof verification - Cryptographically secure eligibility
- Single claim per address - Prevents double-spending
- ReentrancyGuard - Contract-level protection
- Owner controls - Emergency functions for admin
- Audited patterns - Based on OpenZeppelin standards
npm test# Test with mock URL parameters
http://localhost:3000/?walletId=inApp&authCookie=demo123npm run verify-contract -- DEPLOYED_CONTRACT_ADDRESS- Polygon: ~$1-5 in MATIC
- Ethereum: ~$50-200 in ETH
- Total USDC needed: Sum of all rewards in your CSV
- Recommend 1-2% buffer for precision
- Free options: Vercel, Netlify, GitHub Pages
- Custom domain: ~$10/year
Track these key metrics:
- Total unique visitors
- Wallet connection rate
- Successful claim rate
- Unicorn vs EOA wallet usage
- Contract USDC balance
- Gas savings provided to users
Recommended tools:
- Google Analytics for web metrics
- Polygonscan for on-chain monitoring
- Custom dashboard reading contract events
"Not eligible"
- Verify CSV address format is correct
- Check address is in processed merkle-proofs.json
"Transaction failed"
- Ensure contract has sufficient USDC balance
- Check network settings match deployment
Wallet won't connect
- Verify network (Polygon) in wallet settings
- Check if using supported wallet
- Smart Contract Issues: OpenZeppelin Forum
- Unicorn Integration: Discord
- General Issues: Create an issue in this repository
Track distribution success:
- Total claims processed
- Percentage of eligible users who claimed
- Gas savings provided via Unicorn wallets
- User feedback and satisfaction
Contract owner can withdraw unclaimed USDC after distribution period:
// Only contract owner can call
await contract.withdrawRemainingUSDC();For subsequent distributions:
- Process new CSV data
- Deploy new contract with new Merkle root
- Update frontend configuration
- Reuse same codebase and Unicorn integration
- Fork the repository
- Create feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open Pull Request
- Follow existing code style and patterns
- Add tests for new features
- Update documentation for changes
- Ensure mobile responsiveness
- Test both Unicorn and EOA wallet flows
This project is licensed under the MIT License - see the LICENSE file for details.
- @cryptowampum - Product vision and requirements
- Claude AI - Technical architecture and development
- Unicorn.eth - Gasless wallet infrastructure and AutoConnect
- OpenZeppelin - Secure smart contract patterns
- Thirdweb - Web3 development framework
- Live dApp (update after deployment)
- Contract on Polygonscan (update after deployment)
- Unicorn App Center Submission
- Project Documentation
Built with β€οΈ for the sSPORK community