╔═══════════════════════════════════════════╗
║ r s h . p w ║
║ free subdomains for developers ║
╚═══════════════════════════════════════════╝
Rust web service — register subdomains, manage DNS, buy premium names onchain via stablecoins (USDC on L2).
🔗 Live instance: rsh.pw
- Free subdomains — get
your-name.rsh.pwfor free (1 per IP) - Premium names — rare/short names from $5 to $100 (one-time, permanent)
- DNS management — A, AAAA, CNAME, TXT records via Cloudflare API
- Cloudflare proxy — free SSL, DDoS protection, CDN
- Onchain payments — USDC stablecoin on Arbitrum, Polygon, or Base
- Coupons & sales — discount codes, wallet credits, timed sales
- API / CLI — full REST API with Bearer token auth + Swagger docs
- OAuth login — sign in with GitHub or GitLab
- Guide templates — deploy guides for Vercel, Netlify, Cloudflare Pages, VPS
┌──────────────────────────────────────────────────┐
│ rsh.pw │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ Axum │ │ Askama │ │ sled DB │ │
│ │ (HTTP) │ │ (templ.) │ │ (embedded) │ │
│ └────┬─────┘ └──────────┘ └───────┬───────┘ │
│ │ │ │
│ ┌────▼───────────────────────────────▼───────┐ │
│ │ Cloudflare DNS API │ │
│ └────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────┐ │
│ │ Onchain (Arbitrum / Polygon / Base) │ │
│ │ USDC payment detection │ │
│ └────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
# 1. Clone
git clone https://github.com/Baconana-chan/rsh.pw-up && cd rsh.pw
# 2. Configure
cp .env.example .env
# Edit .env — add GitHub OAuth, Cloudflare API token, etc.
# 3. Run
cargo run --release
# 4. Open
open http://localhost:3000Note: always build with
--releasein production — session cookies get theSecureflag only in release builds.
- Rust (edition 2021)
- Cloudflare account (free tier works) with a domain
| Service | Purpose | Free Tier |
|---|---|---|
| Cloudflare | DNS management | ✓ |
| GitHub OAuth App | Authentication | ✓ |
| GitLab OAuth App | Authentication | ✓ |
| L2 RPC (Alchemy/Infura/QuickNode) | Onchain payment scanning | ✓ |
All config via environment variables (see .env.example):
# Core
SLED_DB_PATH=rsh.db
APP_URL=https://your-domain.tld # public URL — drives OAuth redirects & CORS
SESSION_SECRET=<random> # openssl rand -base64 32
PORT=3000 # internal listen port; put reverse proxy in front
# Metrics (optional; unset = /metrics disabled)
METRICS_TOKEN=<random>
# OAuth
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
GITLAB_CLIENT_ID=...
GITLAB_CLIENT_SECRET=...
# Cloudflare
CLOUDFLARE_API_TOKEN=...
CLOUDFLARE_ZONE_ID=...
# Onchain (one RPC per chain)
ONCHAIN_SEED_PHRASE=...
ONCHAIN_ARBITRUM_RPC=...
ONCHAIN_POLYGON_RPC=...
ONCHAIN_BASE_RPC=...
# Admin user IDs (comma-separated)
ADMIN_USER_IDS=...Interactive API reference at /docs (terminal-themed, with live "try it" console). Machine-readable OpenAPI spec at /openapi.json.
GET /api/v1/subdomains — list user's subdomains
POST /api/v1/subdomains — create subdomain
PATCH /api/v1/subdomains/{name} — update DNS record
DELETE /api/v1/subdomains/{name} — delete subdomain
GET /api/v1/check/{name} — check availability
GET /api/v1/premium — list premium names
POST /api/v1/premium/buy — buy premium (onchain)
POST /api/v1/premium/buy-with-balance — buy from wallet
GET /api/v1/wallet — wallet balance
GET /api/v1/wallet/transactions — wallet history
POST /api/v1/coupons/validate — validate coupon
POST /api/v1/coupons/redeem — redeem wallet credit
GET /api/v1/sales/active — active sales
GET /api/v1/payments — payment history
POST /api/v1/payments/{id}/retry — retry expired payment
POST /api/v1/tokens — create API token
# Via session cookie (browser — login with GitHub/GitLab)
# Via Bearer token (CLI)
curl -H "Authorization: Bearer rshpw_..." https://your-domain.tld/api/v1/subdomainsTwo supported paths:
cargo build --release
sudo ./scripts/deploy-systemd.sh # installs binary, user, service unit
sudo cp deploy/Caddyfile /etc/caddy/Caddyfile
sudo systemctl reload caddy- Keep the origin port (default
3000) firewalled from the internet — the proxy is the only public entrypoint. The rate limiter trusts forwarding headers (CF-Connecting-IP) only under this assumption. - Back up the data directory (
/var/lib/rshpw/by default) — sled is an embedded store; a directory copy is a full backup.
docker compose up -d --build| Server | Config | SSL |
|---|---|---|
| Caddy | deploy/Caddyfile |
Auto (Let's Encrypt) |
| Nginx | deploy/nginx.conf |
Certbot recommended |
The bundled Caddyfile assumes Cloudflare-proxied DNS and normalizes client-IP headers accordingly.
# Check
cargo check
# Run with logs
RUST_LOG=rshpw=debug cargo run
# Format
cargo fmt
# Lint
cargo clippy
# Test
cargo testSee SECURITY.md.
Highlights:
- OAuth-only auth (no password storage), hashed API tokens
- CSRF protection on all cookie-authenticated mutations
- CAS-guarded money paths: payments settle exactly once, coupons are atomic against concurrent redemption
- Rate limiting per client IP, IP/user ban lists
- Security headers + CSP on every response
See CONTRIBUTING.md.
MIT — see LICENSE.
built with 🦀 Rust + Axum + sled