| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
| |
Add automatic TLS detection for testclient:
- Use TLS for port 443
- Use TLS for non-localhost addresses
- Use insecure for localhost/127.0.0.1 (development)
Now works with both:
./bin/testclient # local
./bin/testclient -addr nostr-grpc.x.bdw.to:443 # production
|
| |
|
|
|
|
| |
When using --public-url, the gRPC endpoint is accessed via the
reverse proxy on standard HTTPS port 443, not the internal port
50051. Update display to show correct public-facing port.
|
| |
|
|
|
|
|
|
|
|
|
| |
The template was hardcoding 'ws://' prefix, but when using
--public-url we were already passing 'wss://'. This caused
the URL to display as 'ws://wss://domain/'.
Fix by:
- Removing 'ws://' prefix from template
- Always including protocol in the variable (ws:// or wss://)
- Also add http:// prefix for local development consistency
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add flag to specify public-facing domain when relay is behind
a reverse proxy that terminates TLS.
Usage:
./bin/relay --public-url nostr-grpc.x.bdw.to
When set, the index page displays:
- gRPC: nostr-grpc.x.bdw.to:50051
- Connect: https://nostr-grpc.x.bdw.to
- WebSocket: wss://nostr-grpc.x.bdw.to
When not set, falls back to local addresses (:50051, :8080)
for development environments.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Complete aesthetic reversal - from cyber-brutalist to minimal:
AESTHETIC: 1995 web document meets cypherpunks mailing list
- Courier New system font (no web fonts)
- Black on white for readability
- Semantic HTML with minimal CSS
- PGP signature blocks (cypherpunk heritage)
- Classic underlined blue links
- Horizontal rules for section breaks
- Looks like a .txt file rendered as HTML
PHILOSOPHY:
Throwback to when the web was just documents. No animations,
no grids, no gradients. Just semantic HTML, monospace type,
and information. Fast loading, accessible, timeless.
CYPHERPUNK TOUCHES:
- PGP signature blocks
- Hash fingerprints
- Technical language
- Cryptographic references
- Feels like reading crypto mailing list archives
Zero frameworks, zero build tools, maximum signal.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Complete visual overhaul with bold conceptual direction:
AESTHETIC: Cyber-brutalist terminal interface
- JetBrains Mono monospace throughout
- Deep black (#0a0e14) with cyan/green accents
- ASCII art Nostr logo with glitch animation
- Animated grid background (scrolling terminal feel)
- Terminal-style status bar with pulse indicators
- Protocol cards with scanning line effects
- Information-dense but organized layout
MOTION & EFFECTS:
- Glitching ASCII logo animation
- Scanning line on protocol cards
- Pulsing status indicators
- Animated grid background
- Staggered fade-in on page load
- Hover effects with glow
DIFFERENTIATION:
Feels like SSH into a relay node. Unapologetically technical,
embracing Nostr's decentralized, cypherpunk ethos. Zero generic
design patterns - full commitment to terminal aesthetic.
|
| |
|
|
|
|
|
|
|
|
| |
Add a beautiful HTML landing page when visiting relay in browser:
- Shows all three protocol endpoints (gRPC, Connect, WebSocket)
- Lists supported NIPs (01, 09, 11)
- Displays relay features and info
- Responsive design with gradient styling
- Serves on GET requests (regular Accept header)
- NIP-11 still served for Accept: application/nostr+json
|
| |
|
|
|
|
|
|
|
|
|
| |
Implement event deletion (NIP-09) using hard delete approach:
- Kind 5 events trigger deletion but are not stored themselves
- ProcessDeletion hard deletes referenced events (DELETE FROM events)
- Only authors can delete their own events (pubkey verification)
- Support multiple event IDs in single deletion request
- No deletions table needed (simpler schema)
- Added 4 deletion tests covering various scenarios
- All 45 tests passing
|
| |
|
|
|
|
|
|
|
|
| |
Remove deletion processing logic in favor of simpler approach:
- Remove deletions table from schema
- Delete deletions.go and deletions_test.go
- Remove ProcessDeletion from EventStore interface
- Kind 5 events now stored like any other event (no special handling)
- Update storage test to expect 2 tables instead of 3
- All 41 tests passing
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
NIP-11 (Relay Information Document):
- Serves relay metadata at GET / with Accept: application/nostr+json
- Returns name, description, supported NIPs, limitations
- CORS headers for browser compatibility
NIP-09 (Event Deletion):
- Kind 5 events delete events referenced in 'e' tags
- Only authors can delete their own events
- Soft delete (marks deleted=1)
- Records deletion in deletions table
- Works across all protocols (gRPC, Connect, WebSocket)
Fixed deletions schema:
- deleted_event_id as PRIMARY KEY (not deletion_event_id)
- Allows one deletion event to delete multiple events
3 new tests, 44 total tests passing
Supported NIPs now: 1, 9, 11
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Connect integration:
- Buf Connect codegen added to buf.gen.yaml
- Connect handler wraps gRPC server
- Serves on same port as WebSocket (:8080)
- HTTP/2 with h2c for cleartext HTTP/2
Now serving THREE protocols:
1. gRPC (native) on :50051 - binary, high performance
2. Connect on :8080/nostr.v1.NostrRelay/* - HTTP/JSON, browser compatible
3. WebSocket on :8080/ - Nostr standard protocol
All three protocols share:
- Same storage layer
- Same subscription manager
- Same validation logic
Browser-friendly! Call gRPC methods with fetch() or curl.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
WebSocket handler:
- NIP-01 protocol (EVENT, REQ, CLOSE, OK, EOSE, NOTICE)
- JSON envelope parsing
- Shares subscription manager with gRPC (unified event fan-out)
- Standard Nostr client compatibility
Relay now serves dual protocols:
- gRPC on :50051 (binary, high performance)
- WebSocket on :8080 (JSON, Nostr standard)
Both protocols share:
- Same storage layer
- Same subscription manager
- Same validation logic
Compatible with all Nostr clients!
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Subscription manager:
- Track active subscriptions across connections
- Filter matching with full NIP-01 support
- Event fan-out to matching subscribers
Subscribe RPC:
- Query stored events (past)
- Stream them to client
- Keep stream open for new events (real-time)
- Auto-generate subscription ID if not provided
PublishEvent now:
- Stores event
- Notifies all matching active subscriptions
- Streams to gRPC clients in real-time
4 new tests, all 41 tests passing
|
| |
|
|
|
|
|
|
| |
Usage:
- Standalone: ./bin/testclient (generates event)
- With nak: nak event "hello" | ./bin/testclient
Compatible with nak CLI for easy event generation
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Server (cmd/relay):
- gRPC server on :50051 (configurable)
- SQLite database (default: relay.db)
- Graceful shutdown on SIGTERM/SIGINT
Test client (cmd/testclient):
- Generates key
- Publishes event
- Queries events back
Build:
- make build (relay)
- make build-client (test client)
- make build-all (both)
|
| |
|
|
|
|
|
|
|
|
|
| |
Handler implementation:
- EventStore interface (consumer-side)
- Server with PublishEvent, QueryEvents, CountEvents, PublishBatch
- pb.Event <-> nostr.Event conversion helpers
- Signature and ID validation using existing nostr package
- Canonical JSON generation for storage
9 tests passing
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Query implementation:
- QueryEvents method with filter support
- Full NIP-01 filter support (ids, authors, kinds, tags, since, until, limit)
- ID and pubkey prefix matching
- Tag filtering using SQLite JSON functions
- Multiple filter UNION support
- DESC ordering by created_at
- Optional canonical JSON inclusion
23 tests passing, 1322 total lines
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Storage implementation:
- Concrete type with constructor (consumer-side interfaces)
- Event storage: protobuf + zstd-compressed canonical JSON
- Schema: events, deletions, replaceable_events, auth_challenges, rate_limits
- WAL mode, STRICT typing, optimized indexes
- Methods: StoreEvent, GetEvent, GetEventWithCanonical, DeleteEvent
Dependencies:
- modernc.org/sqlite v1.45.0 (pure Go SQLite driver)
- github.com/klauspost/compress v1.18.4 (zstd compression)
366 lines, 10 tests passing
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|