Cloudflare Workers-based faucet for distributing testnet KNEX coins.
Live: https://faucet.knexcoins.com
- Serverless architecture on Cloudflare Workers (free tier)
- Cloudflare Turnstile for bot protection
- KV storage for rate limiting
- Cyberpunk neon UI theme
- Test mode for development
| Layer | Protection | Description |
|---|---|---|
| 1 | Cloudflare Turnstile | Invisible bot detection |
| 2 | Per-Address Rate Limit | 1 claim per address per 24 hours |
| 3 | Per-IP Rate Limit | 10 claims per IP per hour |
| 4 | Address Validation | Only valid K... addresses accepted |
KnexCoin addresses use the following format:
- Prefix:
K(capital letter) - Length: 56 characters total
- Encoding: Base32 (A-Z, 2-7)
- Example:
KABC2DEF3GHI4JKL5MNO6PQR7STU2VWX3YZ4ABC5DEF6GHI7JKL
| Tier | Monthly Cost | Capacity |
|---|---|---|
| Free | $0 | ~3,000 claims/day |
| Pro | $5 | ~10,000 claims/day |
npm install -g wrangler
wrangler logingit clone https://github.com/knexcoin/faucet.git
cd faucet
npm installwrangler kv:namespace create RATE_LIMITS
wrangler kv:namespace create CLAIMSUpdate wrangler.toml with the returned namespace IDs.
- Go to Cloudflare Dashboard > Turnstile
- Create a new widget for
faucet.knexcoins.com - Get your Site Key and Secret Key
- Update
TURNSTILE_SITE_KEYinwrangler.toml
wrangler secret put TURNSTILE_SECRET
# Paste your Turnstile secret key
# Optional - for production mode:
wrangler secret put FAUCET_PRIVATE_KEY
# Paste the faucet wallet's Ed25519 private key (hex)
wrangler secret put FAUCET_ADDRESS
# Paste the faucet wallet's public address (K...)
wrangler secret put NODE_RPC_URL
# E.g., https://testnet.knexcoin.com:7076# Test locally
npm run dev
# Deploy to production
npm run deployAdd a Workers Route in Cloudflare Dashboard, or use the route in wrangler.toml:
routes = [
{ pattern = "faucet.knexcoins.com/*", zone_name = "knexcoins.com" }
]Claim testnet KNEX.
Request:
{
"address": "KABC2DEF3GHI4JKL5MNO6PQR7STU2VWX3YZ4ABC5DEF6GHI7JKL",
"turnstile_token": "turnstile_response_token"
}Success Response (200):
{
"success": true,
"tx_hash": "abc123...",
"amount": "100",
"message": "Successfully sent 100 KNEX to K...",
"next_claim_at": "2026-02-02T14:00:00.000Z"
}Error Response (429):
{
"error": "Already claimed today",
"details": "Please wait 18 hours before claiming again",
"next_claim_at": "2026-02-02T14:00:00.000Z"
}Get faucet status and balance.
Response:
{
"status": "online",
"faucet_address": "K...",
"balance": "4,500,000 KNEX",
"claim_amount": "100 KNEX",
"rate_limits": {
"per_address": "1 claim per 24 hours",
"per_ip": "10 claims per hour"
}
}Get a PoW challenge (optional client-side computation).
Response:
{
"challenge": "a1b2c3...",
"difficulty": 4,
"message": "Find nonce where blake2b(challenge + nonce) starts with 4 zeros"
}When NODE_RPC_URL, FAUCET_ADDRESS, or FAUCET_PRIVATE_KEY are not configured, the faucet runs in test mode:
- Generates mock transaction hashes
- Useful for UI development and testing
- Rate limiting still works
Create a dedicated faucet wallet:
# Using the KnexCoin wallet or keygen tool
# Generate a new Ed25519 keypair
# Fund it with testnet allocation (5,000,000 KNEX recommended)Check faucet status:
curl https://faucet.knexcoins.com/api/statusView worker logs:
npm run tail
# or
wrangler tailEdit wrangler.toml to adjust:
| Variable | Default | Description |
|---|---|---|
FAUCET_AMOUNT |
10000 | Display amount (100 KNEX) |
DAILY_LIMIT_PER_ADDRESS |
1 | Claims per address per day |
HOURLY_LIMIT_PER_IP |
10 | Claims per IP per hour |
TURNSTILE_SITE_KEY |
- | Cloudflare Turnstile site key |
- Private Key Storage: Stored as Cloudflare secret (encrypted at rest)
- Rate Limiting: Dual rate limiting (address + IP) prevents abuse
- Turnstile: Cloudflare's invisible CAPTCHA blocks bots
- Address Validation: Strict regex validation prevents malformed requests
- CORS: Configured for cross-origin requests
"Turnstile verification failed" error:
- Ensure site key matches your domain in Cloudflare Dashboard
- Check that the secret key is correctly set via
wrangler secret
"Faucet transaction failed" error:
- Verify
NODE_RPC_URLis accessible from Cloudflare - Check faucet wallet balance
- Ensure private key format is correct (hex-encoded)
- If no node configured, faucet runs in test mode
Rate limit not resetting:
- KV TTL is 24 hours for addresses, 1 hour for IPs
- Wait for TTL to expire or clear KV manually in dashboard
MIT License - see LICENSE