Backend
Rust backend for the Nostr relay hosting platform. This service manages tenants, relays, invoices, and billing, and provisions relays by calling the zooid HTTP API. It authenticates requests using NIP-98.
Tech Stack
- Rust (Edition 2024)
- Axum (HTTP server)
- SQLx + SQLite (persistence)
- Nostr SDK (NIP-98 verification)
Layout
backend/
migrations/ # SQL migrations
src/
auth.rs # NIP-98 verification helper
config.rs # Env-based configuration
db.rs # SQLite pool + migrations
main.rs # Axum server entrypoint
models.rs # Data models
repo.rs # Data access layer
Configuration
Environment variables:
| Variable | Description | Default |
|---|---|---|
DATABASE_URL |
SQLite database URL | sqlite://data/hosting.db |
HOST |
Bind host | 127.0.0.1 |
PORT |
Bind port | 3000 |
ZOOID_API_URL |
Zooid API base URL | http://127.0.0.1:8032 |
PLATFORM_SECRET |
Platform Nostr secret key for NIP-98 auth | required |
RELAY_DOMAIN |
Relay base domain for subdomains | spaces.coracle.social |
NWC_URL |
Platform NWC URL for invoice generation | required for billing |
NOSTR_INDEXER_RELAYS |
Comma-separated relays to fetch kind 10050 DM relays |
required for notifications |
The database directory is created automatically if it doesn’t exist.
Database Schema
Created via migrations/0001_init.sql:
tenantsrelaysinvoicesinvoice_items
Running
cd backend
cargo run
Health check:
GET /healthz
NIP-98 Authentication
NIP-98 verification is implemented in auth.rs using the Rust Nostr SDK. It verifies:
- Authorization header format
- Event signature and kind
- URL + HTTP method tags
- Timestamp validity
This is ready to be used by API routes.
Billing Jobs
The backend runs an in-process billing loop that:
- Generates monthly invoices (using
NWC_URL) - Uses the tenant’s
tenant_nwc_urlfor recurring pull payments (if set) - Sends NIP-17 DMs with invoices when recurring is off
- Sends NIP-17 DMs on successful payment when recurring is on
API Routes
Tenant routes (all require NIP-98 auth; pubkey is inferred from the token):
GET /tenant— fetch (or create) tenantGET /tenant/relays— list tenant relaysPOST /tenant/relays— create relayGET /tenant/relays/:id— get relayPUT /tenant/relays/:id— update relayDELETE /tenant/relays/:id— deactivate relayGET /tenant/invoices— list invoicesPUT /tenant/billing— update tenant billing (NWC URL)
Admin routes (all require NIP-98 auth; pubkey must be in HOSTING_ADMIN_PUBKEYS):
GET /admin/tenants— list tenantsGET /admin/tenants/:pubkey— tenant detail (includes relays)PUT /admin/tenants/:pubkey— update tenant statusGET /admin/relays— list relaysGET /admin/relays/:id— get relayPUT /admin/relays/:id— update relayDELETE /admin/relays/:id— deactivate relay
Next Steps
- Add invoice generation and billing jobs
- On start, publish kind 0, 10002, 10050 to indexer relays based on env vars