diff --git a/README.md b/README.md index 2006af6..dee86a1 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ flowchart LR 3. **Fan-Out** - Subscription requests are sent to all configured relays 4. **Aggregation** - Events from all relays are collected and deduplicated 5. **Response** - Events are sent back to the client with the original subscription ID -6. **Publish Acknowledgement** - Every `EVENT` a client publishes gets exactly one `["OK", , , ]` reply (NIP-01): `true` as soon as any relay accepts it, `false` once every relay has rejected it, the wait times out (10 s), or no relay is connected. A `REQ` while no relay is configured at all is answered with `CLOSED` +6. **Publish Acknowledgement** - Every `EVENT` a client publishes gets exactly one `["OK", , , ]` reply (NIP-01): `true` as soon as any relay accepts it, `false` once every relay has rejected it, the wait times out (10 s), or no relay is connected ## Configuration diff --git a/config.json b/config.json index 048a5a7..b9e4956 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "name": "Nostr Client", "short_description": "Nostr relay multiplexer", - "version": "1.2.0-aio.3", + "version": "1.2.0-aio.2", "tile": "/nostrclient/static/images/nostr-bitcoin.png", "contributors": ["calle", "motorina0", "dni"], "min_lnbits_version": "1.4.0", diff --git a/router.py b/router.py index 8446512..53ce387 100644 --- a/router.py +++ b/router.py @@ -195,7 +195,7 @@ class NostrRouter: assert len(json_data), "Bad JSON array" if json_data[0] == "REQ": - await self._handle_client_req(json_data) + self._handle_client_req(json_data) return if json_data[0] == "CLOSE": @@ -223,29 +223,15 @@ class NostrRouter: self.pending_publishes[event_id] = PendingPublish(event_id, len(connected)) nostr_client.relay_manager.publish_message(json_str) - async def _handle_client_req(self, json_data): + def _handle_client_req(self, json_data): subscription_id = json_data[1] logger.info(f"New subscription: '{subscription_id}'") - if not nostr_client.relay_manager.relays: - # NIP-01: nothing will ever serve this subscription, so refuse it. - # Only when no relay is configured at all: a configured relay that - # is merely reconnecting gets the cached subscription replayed. - await self._send_closed(subscription_id, "error: no relay connections") - return subscription_id_rewritten = urlsafe_short_hash() self.original_subscription_ids[subscription_id_rewritten] = subscription_id filters = json_data[2:] nostr_client.relay_manager.add_subscription(subscription_id_rewritten, filters) - async def _send_closed(self, subscription_id: str, message: str): - try: - await self.websocket.send_text( - json.dumps(["CLOSED", subscription_id, message]) - ) - except Exception as e: - logger.debug(f"Failed to send CLOSED for '{subscription_id}': {e}") - def _handle_client_close(self, subscription_id): subscription_id_rewritten = next( ( diff --git a/tests/test_router_ok.py b/tests/test_router_ok.py index e13301a..44863a1 100644 --- a/tests/test_router_ok.py +++ b/tests/test_router_ok.py @@ -25,14 +25,10 @@ class FakeRelayManager: def __init__(self, relays: dict[str, FakeRelay]): self.relays = relays self.published: list[str] = [] - self.subscriptions: list[str] = [] def publish_message(self, message: str): self.published.append(message) - def add_subscription(self, subscription_id: str, filters): - self.subscriptions.append(subscription_id) - def close_subscriptions(self, subscriptions): pass @@ -143,25 +139,3 @@ async def test_stop_drops_pending_publishes(monkeypatch): assert router.pending_publishes == {} assert NostrRouter.received_command_results == {} - - -@pytest.mark.asyncio -async def test_req_without_configured_relays_is_closed(monkeypatch): - router, ws, manager = _router(monkeypatch, {}) - - await router._handle_client_to_nostr(json.dumps(["REQ", "sub1", {"kinds": [1]}])) - - assert ws.sent == [["CLOSED", "sub1", "error: no relay connections"]] - assert router.subscriptions == [] - assert manager.subscriptions == [] - - -@pytest.mark.asyncio -async def test_req_with_configured_but_disconnected_relay_is_kept(monkeypatch): - router, ws, manager = _router(monkeypatch, {"wss://a": FakeRelay(False)}) - - await router._handle_client_to_nostr(json.dumps(["REQ", "sub1", {"kinds": [1]}])) - - assert ws.sent == [] - assert len(router.subscriptions) == 1 - assert len(manager.subscriptions) == 1