aboutsummaryrefslogtreecommitdiffstats

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 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

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