nostrclient never answered a client's EVENT with the NIP-01 `["OK", <id>, <accepted>, <message>]` command result. Clients built on nostr-tools and similar libraries wait for that reply before treating a publish as successful, so NWC wallet apps paired through the public endpoint reported "publish failed" even though the request had been fanned out and answered. Relay OKs now flow through the message pool like events and notices. The router tracks each EVENT a client publishes and replies exactly once: `true` as soon as any relay accepts, `false` once every relay connected at publish time has rejected it, after a 10 s timeout, or immediately when no relay is connected. OKs nobody is waiting on are dropped at the pump so the shared result map cannot grow unbounded. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013Tbyw6FwjhEJg3gHfPHxWt
4.5 KiB
Nostrclient - LNbits extension
For more about LNBits extension check this tutorial
Overview
nostrclient is an always-on Nostr relay multiplexer that simplifies connecting to multiple Nostr relays. Instead of your Nostr client managing connections to dozens of relays, you connect to a single WebSocket endpoint provided by nostrclient, which then fans out your requests to all configured relays and aggregates the responses back to you.
Why Use This?
- Simplified Client Configuration - Connect to one endpoint instead of managing multiple relay connections
- Always-On Connectivity - Your LNbits instance maintains persistent connections to relays
- Resource Efficient - Share relay connections across multiple clients
- Subscription Management - Automatic subscription ID rewriting prevents conflicts between clients
Architecture
flowchart LR
A[Client A] -->|WebSocket| N
B[Client B] -->|WebSocket| N
C[Client C] -->|WebSocket| N
N[nostrclient<br/>Router] -->|Fan Out| R1[Relay A]
N -->|Fan Out| R2[Relay B]
N -->|Fan Out| R3[Relay C]
N -->|Fan Out| R4[Relay D]
R1 -.->|Aggregate| N
R2 -.->|Aggregate| N
R3 -.->|Aggregate| N
R4 -.->|Aggregate| N
Key Feature: The router rewrites subscription IDs to prevent conflicts when multiple clients use the same IDs.
Features
- Multi-Relay Multiplexing - Connect to multiple Nostr relays through a single WebSocket
- Public & Private Endpoints - Configurable public and private WebSocket access
- Automatic Reconnection - Failed relays are automatically retried with exponential backoff
- Subscription Deduplication - Events are deduplicated before being sent to clients
- Health Monitoring - Track relay connection status, latency, and error rates
- Test Endpoint - Send test messages to verify your setup is working
How It Works
- Client Connection - Your Nostr client connects to the nostrclient WebSocket endpoint
- Subscription Rewriting - Each subscription ID is rewritten to prevent conflicts between multiple clients
- Fan-Out - Subscription requests are sent to all configured relays
- Aggregation - Events from all relays are collected and deduplicated
- Response - Events are sent back to the client with the original subscription ID
- Publish Acknowledgement - Every
EVENTa client publishes gets exactly one["OK", <id>, <accepted>, <message>]reply (NIP-01):trueas soon as any relay accepts it,falseonce every relay has rejected it, the wait times out (10 s), or no relay is connected
Configuration
WebSocket Endpoints
- Public Endpoint:
/api/v1/relay- Available to anyone (if enabled) - Private Endpoint:
/api/v1/{encrypted_id}- Requires valid encrypted endpoint ID
Configure endpoint access in the extension settings:
private_ws- Enable/disable private WebSocket accesspublic_ws- Enable/disable public WebSocket access
Adding Relays
Use the nostrclient UI to add/remove Nostr relays. The extension will automatically:
- Connect to new relays
- Publish existing subscriptions to new relays
- Monitor relay health and reconnect as needed
Testing
Test Endpoint Functionality
The Test Endpoint feature helps verify that your nostrclient WebSocket endpoint works correctly.
How to test:
- Navigate to the nostrclient extension in LNbits
- Use the Test Endpoint feature
- Send a DM to yourself (or a temporary account)
- Verify that messages are sent and received correctly
https://user-images.githubusercontent.com/2951406/236780745-929c33c2-2502-49be-84a3-db02a7aabc0e.mp4
Troubleshooting
Connection Issues
- Check relay status - View relay health in the nostrclient UI
- Verify endpoint configuration - Ensure public_ws or private_ws is enabled
- Check logs - Review LNbits logs for connection errors
Subscription Not Receiving Events
- Verify relays are connected - Check the relay status in the UI
- Test with known event - Use the Test Endpoint to verify connectivity
- Check relay compatibility - Some relays may not support all Nostr features
Development
This extension uses uv for dependency management.
Quick Start
# Format code
make format
# Run type checks and linting
make check
# Run tests
make test
For more development commands, see the Makefile.
License
MIT License - see LICENSE