fix: keep NIP-46 signer subscription open

This commit is contained in:
Avi 2026-09-01 09:11:16 -05:00
commit 7605f51079

View file

@ -647,13 +647,13 @@ async fn run_sign_task(signer: Signer, app: Arc<tokio::sync::Mutex<App>>, uri: C
client.connect().and_wait(CONNECT_TIMEOUT).await; client.connect().and_wait(CONNECT_TIMEOUT).await;
// 4. Subscribe to the client's kind 24133 events so we hear its requests. // 4. Subscribe to the client's kind 24133 events so we hear its requests.
// `stream_events` opens its internal notification receiver as part of // Do not use `stream_events` here: it is an auto-closing historical-event
// subscribing, which must happen BEFORE we announce (step 5): the client // helper and ends at EOSE. NIP-46 needs a long-lived subscription because
// acknowledges within milliseconds and a receiver created afterwards would // the app sends requests after the initial handshake.
// miss those early messages (tokio broadcast semantics).
let filter = Filter::new().kind(Kind::NostrConnect).author(uri.peer); let filter = Filter::new().kind(Kind::NostrConnect).author(uri.peer);
let mut events = match client.stream_events(filter).await { let mut notifications = client.notifications();
Ok(events) => events, let subscription = match client.subscribe(filter).await {
Ok(subscription) => subscription,
Err(err) => { Err(err) => {
signer.fail(format!("Could not subscribe for messages: {err}")); signer.fail(format!("Could not subscribe for messages: {err}"));
return; return;
@ -666,20 +666,22 @@ async fn run_sign_task(signer: Signer, app: Arc<tokio::sync::Mutex<App>>, uri: C
return; return;
} }
// 6. Answer requests until the connection goes away or we are stopped. // 6. Answer requests until stopped. Notifications are persistent and do
// not terminate after EOSE, unlike `stream_events`.
loop { loop {
let (relay_url, incoming) = match events.next().await { let incoming = match notifications.next().await {
Some(next) => next, Some(nostr_sdk::client::ClientNotification::Event {
None => { subscription_id,
event,
..
}) if subscription_id == *subscription.id() => event,
Some(nostr_sdk::client::ClientNotification::Shutdown) | None => {
signer.fail("The signer connection was closed."); signer.fail("The signer connection was closed.");
return; return;
} }
Some(_) => continue,
}; };
let event = match incoming { let event = *incoming;
Ok(event) => event,
Err(_) => continue,
};
let _ = relay_url;
if event.kind != Kind::NostrConnect || event.pubkey != uri.peer { if event.kind != Kind::NostrConnect || event.pubkey != uri.peer {
continue; continue;
} }