# nostr-grpc A high-performance Nostr relay with gRPC and WebSocket support. ## Features - **gRPC-first**: Binary protobuf storage with gRPC API - **SQLite storage**: WAL mode, optimized indexes - **Event validation**: Signature and ID verification - **Nostr compatible**: NIP-01 compliant ## Quick Start ### Build ```bash make build # Build relay make build-client # Build test client make build-all # Build both ``` ### Run the Relay ```bash ./bin/relay # or with custom settings: ./bin/relay -grpc-addr :50051 -ws-addr :8080 -db relay.db ``` The relay will start: - **gRPC** (native) on `:50051` - **HTTP** server on `:8080`: - **Connect** (gRPC over HTTP/JSON) at `/nostr.v1.NostrRelay/*` - **WebSocket** (Nostr protocol) at `/` ### Test with Client **Standalone mode:** ```bash ./bin/testclient # Output: # Generated key: npub1... # Publishing event... # ✓ Event published successfully: abc123... # Querying events... # Found 1 events from author abc123... # - abc123...: Hello from gRPC client! ``` **With nak CLI (gRPC):** ```bash # Pipe events from nak nak event "Hello from nak!" | ./bin/testclient # Or generate a signed event nak event --sec --kind 1 "My message" | ./bin/testclient ``` **With nak CLI (WebSocket/Nostr):** ```bash # Standard Nostr clients work out of the box! nak req -k 1 --limit 10 ws://localhost:8080 # Publish via WebSocket echo '{"kind":1,"content":"hello","tags":[]}' | nak event --sec | nak publish ws://localhost:8080 ``` **With Connect (HTTP/JSON):** ```bash # Call gRPC methods over HTTP with JSON curl -X POST http://localhost:8080/nostr.v1.NostrRelay/PublishEvent \ -H "Content-Type: application/json" \ -d '{"event": {...}}' # Works from browsers, curl, fetch(), etc. ``` ## gRPC API See [proto/nostr/v1/nostr.proto](proto/nostr/v1/nostr.proto) for the full API. ### Available RPCs - `PublishEvent` - Publish a single event (with validation) - `PublishBatch` - Publish multiple events - `QueryEvents` - Query events with filters (paginated) - `CountEvents` - Count events matching filters - `Subscribe` - Stream events (past + real-time) ✅ - `Unsubscribe` - Close subscription ✅ ## Current Status **Phase 1: Complete** ✅ - ✅ SQLite storage with binary-first design - ✅ Event validation (ID, signature) - ✅ **Triple protocol support:** - **gRPC** (native binary protocol) - **Connect** (gRPC over HTTP/JSON - browser compatible!) - **WebSocket** (NIP-01 - standard Nostr protocol) - ✅ Subscribe/streaming (real-time event delivery) - ✅ Subscription management (filter matching, fan-out) - ✅ **NIP-09** - Event deletion (hard delete, authors can delete their own events) - ✅ **NIP-11** - Relay info document (GET with `Accept: application/nostr+json`) **Compatible with:** - Any gRPC client (Go, Python, JS, etc.) - Any HTTP client (curl, fetch, browsers) - Any Nostr client (Damus, Amethyst, Snort, Iris, Gossip, etc.) - nak CLI for testing ## Development ```bash make proto # Regenerate protobuf code make test # Run tests make proto-lint # Lint proto files ``` ## Architecture ``` ┌─────────────────┐ │ gRPC Client │ └────────┬────────┘ │ pb.Event ▼ ┌─────────────────┐ │ gRPC Handler │ ← validates using nostr.Event │ (convert.go) │ ← generates canonical JSON └────────┬────────┘ │ pb.Event + canonicalJSON ▼ ┌─────────────────┐ │ Storage Layer │ ← protobuf + compressed JSON │ (SQLite) │ ← query by filter └─────────────────┘ ``` ## License MIT