From 0072c5255d73ced14f8b850e195238335ec68684 Mon Sep 17 00:00:00 2001 From: reya Date: Tue, 6 Jan 2026 14:59:27 +0700 Subject: [PATCH] . --- crates/chat/src/room.rs | 11 ++++++-- crates/relay_auth/src/lib.rs | 18 ++++++------ crates/state/src/gossip.rs | 4 +++ crates/state/src/lib.rs | 53 ++++++++++++++++++++++++++++++++++-- 4 files changed, 71 insertions(+), 15 deletions(-) diff --git a/crates/chat/src/room.rs b/crates/chat/src/room.rs index 427d950..24096dd 100644 --- a/crates/chat/src/room.rs +++ b/crates/chat/src/room.rs @@ -324,11 +324,16 @@ impl Room { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); let members = self.members(); + let id = SubscriptionId::new(format!("room-{}", self.id)); cx.background_spawn(async move { let signer = client.signer().await?; let public_key = signer.get_public_key().await?; - let opts = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE); + + // Subscription options + let opts = SubscribeAutoCloseOptions::default() + .timeout(Some(Duration::from_secs(2))) + .exit_policy(ReqExitPolicy::ExitOnEOSE); for member in members.into_iter() { if member == public_key { @@ -339,7 +344,9 @@ impl Room { let filter = Filter::new().kind(Kind::RelayList).author(member).limit(1); // Subscribe to get member's gossip relays - client.subscribe(filter, Some(opts)).await?; + client + .subscribe_with_id(id.clone(), filter, Some(opts)) + .await?; } Ok(()) diff --git a/crates/relay_auth/src/lib.rs b/crates/relay_auth/src/lib.rs index e63f361..1c25f04 100644 --- a/crates/relay_auth/src/lib.rs +++ b/crates/relay_auth/src/lib.rs @@ -100,10 +100,10 @@ impl RelayAuth { if auto_auth && is_authenticated { // Automatically authenticate if the relay is authenticated before - this.response(req.to_owned(), window, cx); + this.response(req, window, cx); } else { // Otherwise open the auth request popup - this.ask_for_approval(req.to_owned(), window, cx); + this.ask_for_approval(req, window, cx); } } }), @@ -111,9 +111,7 @@ impl RelayAuth { tasks.push( // Handle nostr notifications - cx.background_spawn(async move { - Self::handle_notifications(&client, &tx).await; - }), + cx.background_spawn(async move { Self::handle_notifications(&client, &tx).await }), ); tasks.push( @@ -138,7 +136,6 @@ impl RelayAuth { // Handle nostr notifications async fn handle_notifications(client: &Client, tx: &flume::Sender) { let mut notifications = client.notifications(); - let mut processed_challenges = HashSet::new(); while let Ok(notification) = notifications.recv().await { if let RelayPoolNotification::Message { @@ -146,10 +143,11 @@ impl RelayAuth { relay_url, } = notification { - if processed_challenges.insert(challenge.clone()) { - let request = AuthRequest::new(challenge, relay_url); - tx.send_async(request).await.ok(); - }; + let request = AuthRequest::new(challenge, relay_url); + + if let Err(e) = tx.send_async(request).await { + log::error!("Failed to send auth request: {}", e); + } } } } diff --git a/crates/state/src/gossip.rs b/crates/state/src/gossip.rs index 48440aa..1399827 100644 --- a/crates/state/src/gossip.rs +++ b/crates/state/src/gossip.rs @@ -69,6 +69,8 @@ impl Gossip { }) .take(3), ); + + log::info!("Updating gossip relays for: {}", event.pubkey); } /// Get messaging relays for a given public key @@ -99,5 +101,7 @@ impl Gossip { }) .take(3), ); + + log::info!("Updating messaging relays for: {}", event.pubkey); } } diff --git a/crates/state/src/lib.rs b/crates/state/src/lib.rs index 29cd288..3620635 100644 --- a/crates/state/src/lib.rs +++ b/crates/state/src/lib.rs @@ -214,7 +214,10 @@ impl NostrRegistry { while let Ok(notification) = notifications.recv().await { if let RelayPoolNotification::Message { message, relay_url } = notification { match message { - RelayMessage::Event { event, .. } => { + RelayMessage::Event { + event, + subscription_id, + } => { if !processed_events.insert(event.id) { // Skip if the event has already been processed continue; @@ -222,6 +225,11 @@ impl NostrRegistry { match event.kind { Kind::RelayList => { + // Automatically get messaging relays for each member when the user opens a room + if subscription_id.as_str().starts_with("room-") { + Self::get_messaging_relays_by(client, event.as_ref()).await?; + } + tx.send_async(event.into_owned()).await?; } Kind::InboxRelays => { @@ -253,6 +261,45 @@ impl NostrRegistry { Ok(()) } + /// Automatically get messaging relays from a received relay list + async fn get_messaging_relays_by(client: &Client, event: &Event) -> Result<(), Error> { + // Subscription options + let opts = SubscribeAutoCloseOptions::default() + .timeout(Some(Duration::from_secs(TIMEOUT))) + .exit_policy(ReqExitPolicy::ExitOnEOSE); + + // Extract write relays from event + let write_relays: Vec<&RelayUrl> = nip65::extract_relay_list(event) + .filter_map(|(url, metadata)| { + if metadata.is_none() || metadata == &Some(RelayMetadata::Write) { + Some(url) + } else { + None + } + }) + .collect(); + + // Ensure relay connections + for relay in write_relays.iter() { + client.add_write_relay(*relay).await?; + client.connect_relay(*relay).await?; + } + + // Construct filter for inbox relays + let filter = Filter::new() + .kind(Kind::InboxRelays) + .author(event.pubkey) + .limit(1); + + client + .subscribe_to(write_relays, vec![filter], Some(opts)) + .await?; + + log::info!("Getting inbox relays for: {}", event.pubkey); + + Ok(()) + } + /// Get or create a new app keys fn create_or_init_app_keys() -> Result { let dir = config_dir().join(".app_keys"); @@ -308,7 +355,7 @@ impl NostrRegistry { // Ensure relay connections cx.background_spawn(async move { for url in async_relays.iter() { - client.add_relay(url).await.ok(); + client.add_write_relay(url).await.ok(); client.connect_relay(url).await.ok(); } }) @@ -326,7 +373,7 @@ impl NostrRegistry { // Ensure relay connections cx.background_spawn(async move { for url in async_relays.iter() { - client.add_relay(url).await.ok(); + client.add_read_relay(url).await.ok(); client.connect_relay(url).await.ok(); } })