No description
- TypeScript 77.9%
- HTML 21.4%
- Dockerfile 0.7%
|
All checks were successful
Build and Push Docker Image / build (push) Successful in 1m20s
- Lightning Address (LUD-16): proxy /.well-known/lnurlp/:name to user's real Lightning wallet provider with SSRF protection and upstream status checks - Import/Export: GET /api/nip05/export and POST /api/nip05/import with atomic transactions and skip/overwrite conflict modes - Rate limiting: token bucket middleware on /.well-known/* endpoints, configurable via RATE_LIMIT_MAX and RATE_LIMIT_WINDOW env vars - NIP-65 relay sync: background job fetches kind:10002 events via nostr-tools, with relays_source column to protect manual relay edits, configurable via RELAY_SYNC_ENABLED/RELAYS/INTERVAL env vars - Admin UI updated with lightning address field, import/export buttons, sync relays button, and relay source indicators - 92 tests covering all new functionality |
||
|---|---|---|
| .forgejo/workflows | ||
| docs | ||
| src | ||
| tests | ||
| .dockerignore | ||
| .gitignore | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| package.json | ||
| pnpm-lock.yaml | ||
| README.md | ||
| tsconfig.json | ||
NIP-05 Service
A dynamic NIP-05 identity service for Nostr. Maps human-readable names to public keys via /.well-known/nostr.json, with an admin API and web UI for managing entries.
Built for edufeed.org, but works with any domain.
Features
- NIP-05 endpoint — serves
/.well-known/nostr.jsonwith CORS headers, optional relay hints - Admin API — CRUD for entries and API keys, authenticated via Bearer tokens
- Admin UI — tab-based web interface at
/adminfor managing entries and API keys - Service integration — other services register NIP-05 identifiers via the API with a shared secret
- SQLite storage — single-file database, no external dependencies
Quick Start
# Install dependencies
pnpm install
# Run in development
ADMIN_PASSWORD=secret pnpm dev
# Run tests
pnpm test
On first start, a default API key is printed to stdout. Save it.
API
Public
| Method | Path | Description |
|---|---|---|
GET |
/.well-known/nostr.json?name=<name> |
NIP-05 lookup |
Protected (Bearer token or admin session)
| Method | Path | Description |
|---|---|---|
GET |
/api/nip05 |
List all entries |
POST |
/api/nip05 |
Create entry {name, pubkey, relays?} |
PUT |
/api/nip05/:name |
Update entry {pubkey?, relays?} |
DELETE |
/api/nip05/:name |
Delete entry |
GET |
/api/keys |
List API keys |
POST |
/api/keys |
Create key {name} — returns plaintext once |
DELETE |
/api/keys/:id |
Revoke key |
Example
# Register a NIP-05 identifier
curl -X POST http://localhost:3000/api/nip05 \
-H "Authorization: Bearer <api-key>" \
-H "Content-Type: application/json" \
-d '{"name":"alice","pubkey":"aabb...","relays":["wss://relay.example.com"]}'
# Verify
curl 'http://localhost:3000/.well-known/nostr.json?name=alice'
Configuration
| Variable | Description | Default |
|---|---|---|
ADMIN_PASSWORD |
Password for admin UI login | (required) |
PORT |
Server port | 3000 |
DATABASE_PATH |
SQLite file path | ./data/nip05.db |
Deployment
See docs/deployment.md for Docker and reverse proxy setup (Traefik, nginx, Caddy).
# Docker
ADMIN_PASSWORD=secret docker compose up -d
In production, your reverse proxy routes /.well-known/nostr.json on your domain to this service. The admin UI and API can be on a separate subdomain or kept internal.
Tech Stack
- Hono — HTTP framework
- better-sqlite3 — SQLite
- TypeScript + Vitest