muxstr
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
make build # Build relay
make build-client # Build test client
make build-all # Build both
Run the Relay
./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:
./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):
# Pipe events from nak
nak event "Hello from nak!" | ./bin/testclient
# Or generate a signed event
nak event --sec <nsec> --kind 1 "My message" | ./bin/testclient
With nak CLI (WebSocket/Nostr):
# 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 <nsec> | nak publish ws://localhost:8080
With Connect (HTTP/JSON):
# 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 for the full API.
Available RPCs
PublishEvent- Publish a single event (with validation)PublishBatch- Publish multiple eventsQueryEvents- Query events with filters (paginated)CountEvents- Count events matching filtersSubscribe- 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
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
