From 64ad94d0b54a9100b601b7534a4f76dc9e730d52 Mon Sep 17 00:00:00 2001 From: Avi Date: Mon, 24 Aug 2026 20:53:45 -0500 Subject: [PATCH] Signer: listen before announcing so the handshake reply is not lost MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NIP-46 task created its notification receiver only after publishing the connect announcement. An automated client answers within milliseconds, so its ack and first request landed in the relay pool broadcast channel before a receiver existed and were dropped silently — the client then waited forever for a reply and never left its connect/QR screen (seen with Yakihonne). Open the notification stream right after adding relays, before connect/subscribe/announce, closing the drop window. Verified end-to-end with a reference NIP-46 client over live relays: before the fix get_public_key was never answered; after it the full round-trip (announce, ack, get_public_key) completes. --- src/signer.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/signer.rs b/src/signer.rs index 84e8d7a..303bccd 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -626,7 +626,11 @@ async fn run_sign_task(signer: Signer, app: Arc>, uri: C } }; - // 3. Connect to the client's relays. + // 3. Connect to the client's relays. The notification stream is opened + // BEFORE anything is sent or subscribed: the client acknowledges our + // announcement within milliseconds, and a receiver created afterwards + // would miss those early messages (tokio broadcast semantics), leaving + // the client waiting forever for a reply. let client = Client::new(keys.clone()); for url in &uri.relays { if let Err(err) = client.add_relay(url.to_string()).await { @@ -634,6 +638,7 @@ async fn run_sign_task(signer: Signer, app: Arc>, uri: C return; } } + let mut notifications = client.notifications(); client.connect().await; client.wait_for_connection(CONNECT_TIMEOUT).await; @@ -651,7 +656,6 @@ async fn run_sign_task(signer: Signer, app: Arc>, uri: C } // 6. Answer requests until the connection goes away or we are stopped. - let mut notifications = client.notifications(); loop { let notification = match notifications.recv().await { Ok(notification) => notification,