Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🚌 The Praise Board

A decentralized tipping board on Ethereum Sepolia.
Support community heroes like Ifeoma β€” who maintains your city's bus timetables for free β€” with instant, fee-free ETH tips. Every tip is recorded permanently on-chain.


✨ Features

  • 🦊 MetaMask / WalletConnect integration via RainbowKit
  • ⚑ Instant ETH tips with short appreciation notes
  • πŸ“œ Fully on-chain supporter wall β€” zero databases, zero middlemen
  • πŸ”„ Real-time updates via contract events
  • πŸ‘‘ Owner withdrawal for Ifeoma to claim her tips
  • 🌐 ENS-ready address display (shortened + Etherscan links)
  • πŸ“± Responsive design β€” works on mobile and desktop
  • 🎨 Premium dark-mode UI with glassmorphism and animations

πŸ—οΈ Architecture

blockchain_proj/
β”œβ”€β”€ contracts/
β”‚   └── PraiseBoard.sol         # Ownable Solidity contract
β”œβ”€β”€ scripts/
β”‚   └── deploy.ts               # Hardhat deploy script
β”œβ”€β”€ test/
β”‚   └── PraiseBoard.test.ts     # Full test suite (13 tests)
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ abis/PraiseBoard.ts # Contract ABI (typed)
β”‚   β”‚   β”œβ”€β”€ config/wagmi.ts     # Wagmi + RainbowKit config
β”‚   β”‚   β”œβ”€β”€ hooks/
β”‚   β”‚   β”‚   β”œβ”€β”€ usePraiseBoard.ts   # Contract interactions
β”‚   β”‚   β”‚   └── useWalletState.ts   # Wallet / network state
β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”œβ”€β”€ ConnectButton.tsx   # Wallet connect
β”‚   β”‚   β”‚   β”œβ”€β”€ NetworkGuard.tsx    # Wrong network banner
β”‚   β”‚   β”‚   β”œβ”€β”€ TipForm.tsx         # Send tip UI
β”‚   β”‚   β”‚   β”œβ”€β”€ SupporterWall.tsx   # Live on-chain feed
β”‚   β”‚   β”‚   └── WithdrawButton.tsx  # Owner withdraw panel
β”‚   β”‚   β”œβ”€β”€ App.tsx
β”‚   β”‚   └── main.tsx
β”‚   └── index.html
β”œβ”€β”€ hardhat.config.ts
β”œβ”€β”€ .env.example
└── README.md

πŸ› οΈ Tech Stack

Layer Technology
Smart Contract Solidity 0.8.24, OpenZeppelin 5.x
Dev Framework Hardhat 2.x + TypeScript
Blockchain Ethereum Sepolia
RPC QuickNode
Frontend React 18, Vite 5, TypeScript
Web3 Client wagmi 2.x + viem 2.x
Wallet UI RainbowKit 2.x
State TanStack React Query 5
Styling Vanilla CSS (dark glassmorphism)

πŸ“‹ Contract Details

Property Value
Contract Name PraiseBoard
Network Ethereum Sepolia (chainId: 11155111)
Contract Address 0x___FILL_AFTER_DEPLOYMENT___
Deploy Tx Hash 0x___FILL_AFTER_DEPLOYMENT___
Solidity ^0.8.24
License MIT

πŸš€ Deployment Instructions

Prerequisites

  • Node.js 18+
  • A funded Sepolia wallet (get test ETH at sepoliafaucet.com)
  • QuickNode Sepolia RPC URL

1. Clone & install

git clone https://github.com/Harshad710/praise-board.git
cd blockchain_proj
npm install

2. Set environment variables

cp .env.example .env

Edit .env:

QUICKNODE_URL=https://your-endpoint.quiknode.pro/your-key/
PRIVATE_KEY=your_deployer_private_key

3. Compile the contract

npx hardhat compile

4. Run tests

npx hardhat test

5. Deploy to Sepolia

npx hardhat run scripts/deploy.ts --network sepolia

Copy the printed contract address.

6. (Optional) Verify on Etherscan

npx hardhat verify --network sepolia <CONTRACT_ADDRESS>

πŸ’» Running the Frontend Locally

1. Install frontend dependencies

cd frontend
npm install

2. Set frontend environment variables

cp .env.example .env

Edit frontend/.env:

VITE_CONTRACT_ADDRESS=0xYourDeployedContractAddress
VITE_QUICKNODE_URL=https://your-endpoint.quiknode.pro/your-key/
VITE_WALLETCONNECT_PROJECT_ID=your_walletconnect_project_id

Note: Get a free WalletConnect project ID at cloud.walletconnect.com

3. Start the dev server

npm run dev

Open http://localhost:5173


🌍 Environment Variables

Root (Hardhat)

Variable Required Description
QUICKNODE_URL Yes QuickNode Sepolia RPC endpoint URL
PRIVATE_KEY Yes Deployer wallet private key

Frontend (frontend/.env)

Variable Required Description
VITE_CONTRACT_ADDRESS Yes Deployed PraiseBoard contract address
VITE_QUICKNODE_URL Yes QuickNode Sepolia RPC for frontend
VITE_WALLETCONNECT_PROJECT_ID Yes WalletConnect project ID

πŸ“Έ Screenshots

[Add screenshots after running the frontend]

  • Home page with connect prompt
  • Connected wallet + tip form
  • Pending transaction state
  • Success state with Etherscan link
  • Supporter wall with tips

βœ… Acceptance Criteria Checklist

  • Connect MetaMask / WalletConnect
  • Send ETH tip with short note
  • Note capped at 200 bytes on-chain + client-side validation
  • Tip recorded on-chain (Tip[] struct array)
  • NewTip event emitted on each tip
  • Supporter wall reads ONLY from blockchain (no database)
  • Live wall refresh on new tip (event listener + refetch)
  • Supporter wall sorted newest-first
  • Owner withdraw function
  • Wrong network detection + one-click switch to Sepolia
  • Wallet not installed error handling
  • User rejected transaction error handling
  • Insufficient funds error handling
  • Zero ETH tip rejected (ZeroTipNotAllowed custom error)
  • Long note rejected (NoteTooLong custom error)
  • Pending transaction state (spinner + Etherscan link)
  • Success state with confirmation
  • Hardhat tests: 13 passing tests
  • TypeScript throughout
  • ESLint + Prettier configured
  • Checks-Effects-Interactions pattern in contract
  • OpenZeppelin Ownable inherited
  • Custom errors (no require strings)
  • getAllTips() view function
  • Responsive design (mobile + desktop)

πŸ§ͺ Test Results

PraiseBoard
  Deployment
    βœ“ should set the deployer as the owner
    βœ“ should start with zero tips
  receiveTip
    βœ“ should accept a valid tip and emit NewTip event
    βœ“ should store the sender address correctly
    βœ“ should store the amount correctly
    βœ“ should store the note correctly
    βœ“ should store a non-zero timestamp
    βœ“ should reject a zero-ETH tip with ZeroTipNotAllowed
    βœ“ should reject a note longer than 200 bytes with NoteTooLong
    βœ“ should accept a note of exactly 200 bytes
    βœ“ should accumulate multiple tips from different senders
  getAllTips
    βœ“ should return an empty array when no tips have been sent
    βœ“ should return all tips in correct order
  withdraw
    βœ“ should allow the owner to withdraw all funds
    βœ“ should reject withdrawal from a non-owner account
    βœ“ should reject withdrawal when balance is zero

16 passing

πŸ”’ Security Notes

  • Custom errors used throughout (no revert strings) β€” gas efficient
  • Checks-Effects-Interactions pattern in receiveTip and withdraw
  • onlyOwner modifier from OpenZeppelin guards withdrawal
  • Note length capped at 200 bytes on-chain
  • Zero-value tips rejected with custom error
  • Pull-over-push withdrawal pattern β€” no automatic transfers to external addresses

πŸ“„ License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages