Signer: listen before announcing so the handshake reply is not lost

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.
This commit is contained in:
Avi 2026-08-24 20:53:45 -05:00
commit 64ad94d0b5

View file

@ -626,7 +626,11 @@ async fn run_sign_task(signer: Signer, app: Arc<tokio::sync::Mutex<App>>, 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()); let client = Client::new(keys.clone());
for url in &uri.relays { for url in &uri.relays {
if let Err(err) = client.add_relay(url.to_string()).await { if let Err(err) = client.add_relay(url.to_string()).await {
@ -634,6 +638,7 @@ async fn run_sign_task(signer: Signer, app: Arc<tokio::sync::Mutex<App>>, uri: C
return; return;
} }
} }
let mut notifications = client.notifications();
client.connect().await; client.connect().await;
client.wait_for_connection(CONNECT_TIMEOUT).await; client.wait_for_connection(CONNECT_TIMEOUT).await;
@ -651,7 +656,6 @@ async fn run_sign_task(signer: Signer, app: Arc<tokio::sync::Mutex<App>>, uri: C
} }
// 6. Answer requests until the connection goes away or we are stopped. // 6. Answer requests until the connection goes away or we are stopped.
let mut notifications = client.notifications();
loop { loop {
let notification = match notifications.recv().await { let notification = match notifications.recv().await {
Ok(notification) => notification, Ok(notification) => notification,