A professional, production-ready Web3 faucet for the Ethereum Sepolia testnet.
Sends 0.1 ETH to developers for free — once every 24 hours per wallet + IP.
- Modern Web3 UI — Light & Dark mode with animated transitions
- Anti-abuse protection — Per-wallet + per-IP 24h cooldowns
- Bot protection — Cloudflare Turnstile CAPTCHA
- Real-time stats — Live faucet balance, total ETH distributed, total claims
- Transaction feedback — Copy hash button + direct Etherscan link
- Responsive — Works on mobile and desktop
- Secure — Helmet headers, rate limiting, input validation
/
├── client/
│ ├── index.html # Main UI
│ ├── styles.css # Styles (light + dark mode)
│ ├── app.js # Frontend logic
│ └── assets/
│ └── logo.svg # Faucet logo
│
├── server/
│ ├── server.js # Express API server
│ ├── database.js # SQLite (claims storage)
│ ├── faucet.js # ethers.js blockchain integration
│ └── .env # Environment config (see below)
│
└── package.json
npm installCopy .env from server/.env and fill in your values:
RPC_URL=https://rpc.sepolia.org
FAUCET_PRIVATE_KEY=0xYOUR_PRIVATE_KEY
FAUCET_ADDRESS=0xYOUR_FAUCET_ADDRESS
TURNSTILE_SECRET_KEY=your_turnstile_secret
TURNSTILE_SITE_KEY=your_turnstile_sitekey
PORT=3000
⚠️ Never commit your private key to version control!
- Go to Cloudflare Dashboard → Turnstile
- Create a new site (choose "Managed" challenge type)
- Copy Site Key → paste into
client/index.html(data-sitekey) - Copy Secret Key → paste into
server/.env(TURNSTILE_SECRET_KEY)
Send some Sepolia ETH to your FAUCET_ADDRESS.
Get free Sepolia ETH from: https://sepoliafaucet.com
# Production
npm start
# Development (auto-restart)
npm run devVisit: http://localhost:3000
Request 0.1 ETH from the faucet.
Request body:
{
"walletAddress": "0xYourWalletAddress",
"captchaToken": "turnstile_token_from_frontend"
}Success response (200):
{
"success": true,
"txHash": "0xabc123...",
"amount": 0.1,
"wallet": "0x...",
"message": "0.1 ETH sent to 0x..."
}Error responses:
400— Invalid wallet address or missing fields403— CAPTCHA verification failed429— Cooldown active (includeswaitSeconds)503— Transaction failed (low balance, RPC error)
Returns current faucet stats.
Response:
{
"balance": "4.2837",
"totalClaims": 142,
"totalDistributed": 14.2,
"claimAmount": 0.1,
"network": "Sepolia",
"chainId": 11155111
}| Layer | Mechanism |
|---|---|
| Bot prevention | Cloudflare Turnstile CAPTCHA |
| Wallet cooldown | SQLite — 1 claim/24h per address |
| IP cooldown | SQLite — 1 claim/24h per IP |
| Burst protection | express-rate-limit (5 req/15 min) |
| Headers | Helmet.js (CSP, HSTS, etc.) |
| Input validation | Regex + length checks |
server {
listen 80;
server_name faucet.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}Enable SSL with Certbot for HTTPS.
- Use a dedicated faucet wallet with only Sepolia ETH
- Monitor faucet balance and top up regularly
- Consider using Infura/Alchemy for reliable RPC (not public endpoints)
| Package | Purpose |
|---|---|
express |
HTTP server |
ethers v6 |
Ethereum transactions |
better-sqlite3 |
Fast SQLite database |
helmet |
Security headers |
express-rate-limit |
Rate limiting |
cors |
CORS headers |
dotenv |
Environment config |
MIT — free to use, modify, and deploy.