| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add support for authenticating WebSocket clients using NIP-42 protocol,
enabling auth restrictions for normal Nostr clients.
Storage layer (internal/storage/auth.go):
- CreateAuthChallenge() - Generate random 32-byte challenge with 10min TTL
- ValidateAndConsumeChallenge() - Verify challenge validity and mark as used
- CleanupExpiredChallenges() - Remove old challenges from database
- Uses existing auth_challenges table
WebSocket handler (internal/handler/websocket/handler.go):
- Track authenticatedPubkey per connection
- Track authChallenge per connection
- requireAuth() - Check if operation requires authentication
- handleAuth() - Process AUTH responses (kind 22242 events)
- sendAuthChallenge() - Send AUTH challenge to client
- Enforce auth on EVENT (writes) and REQ (reads) messages
- Support separate read/write allowlists
Main (cmd/relay/main.go):
- Wire auth config from YAML to WebSocket handler
- Pass read/write enabled flags and allowed npub lists
NIP-42 Flow:
1. Client sends EVENT/REQ without auth
2. If auth required, relay sends: ["AUTH", "<challenge>"]
3. Client signs kind 22242 event with challenge tag
4. Client sends: ["AUTH", <signed-event>]
5. Relay validates signature, challenge, and allowlist
6. Connection marked as authenticated
7. Client can now EVENT/REQ
Example config to restrict writes to your npub:
```yaml
auth:
write:
enabled: true
allowed_npubs:
- npub1your-npub-here...
```
WebSocket clients (Damus, Amethyst, etc.) can now authenticate!
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add metrics tracking for WebSocket (NIP-01) subscriptions in addition
to existing gRPC subscription tracking.
Changes:
- Add Count() method to subscription.Manager
- Add MetricsRecorder interface to WebSocket handler
- Update subscription metrics when REQ/CLOSE messages processed
- Wire up metrics to WebSocket handler in main.go
Before: Only gRPC stream subscriptions were counted
After: Both gRPC and WebSocket subscriptions tracked accurately
This fixes the dashboard showing 0 subscriptions when clients connect
via WebSocket (e.g., nak req --stream).
|
| |
|
|
| |
Also removed internal/nostr package - now using northwest.io/nostr library.
|
| |
|
|
|
|
| |
Update module path from northwest.io/nostr-grpc to northwest.io/muxstr.
This includes updating all Go imports, protobuf definitions, generated
files, and documentation.
|
| |
|
|
|
|
|
|
|
|
| |
WebSocket connections start as GET requests with 'Upgrade: websocket'
header. The handler was serving HTML for ALL GET requests, preventing
WebSocket upgrades from ever happening.
Fix by checking for Upgrade header and only serving HTML/NIP-11 for
non-WebSocket GET requests. Now WebSocket connections return status
101 (Switching Protocols) instead of 200 (OK).
|
| |
|
|
|
|
|
|
|
|
| |
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
|
|
|
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!
|