From d53af98feb1a70f0d5ddd0410fb25a0744c5b51a Mon Sep 17 00:00:00 2001 From: Ren Amamiya Date: Wed, 18 Mar 2026 14:00:06 +0700 Subject: [PATCH] fix --- crates/chat/src/lib.rs | 6 +- crates/chat/src/room.rs | 137 ++++++++++++++++++++++------------ crates/state/src/constants.rs | 6 +- crates/state/src/lib.rs | 13 +++- 4 files changed, 108 insertions(+), 54 deletions(-) diff --git a/crates/chat/src/lib.rs b/crates/chat/src/lib.rs index bbf8a96..a2d9b61 100644 --- a/crates/chat/src/lib.rs +++ b/crates/chat/src/lib.rs @@ -708,8 +708,10 @@ async fn extract_rumor( async fn try_unwrap(signer: &Arc, gift_wrap: &Event) -> Result { // Try with the device signer first if let Some(signer) = signer.get_encryption_signer().await { - log::info!("trying with device signer"); - return try_unwrap_with(gift_wrap, &signer).await; + log::info!("trying with encryption key"); + if let Ok(unwrapped) = try_unwrap_with(gift_wrap, &signer).await { + return Ok(unwrapped); + } } // Fallback to the user's signer diff --git a/crates/chat/src/room.rs b/crates/chat/src/room.rs index 1d02b7d..f8829c1 100644 --- a/crates/chat/src/room.rs +++ b/crates/chat/src/room.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use std::hash::{Hash, Hasher}; use std::time::Duration; -use anyhow::Error; +use anyhow::{Error, anyhow}; use common::EventUtils; use gpui::{App, AppContext, Context, EventEmitter, SharedString, Task}; use itertools::Itertools; @@ -513,46 +513,46 @@ impl Room { // Handle encryption signer requirements if signer_kind.encryption() { + // Receiver didn't set up a decoupled encryption key if announcement.is_none() { reports.push(SendReport::new(public_key).error(NO_DEKEY)); continue; } + + // Sender didn't set up a decoupled encryption key if encryption_signer.is_none() { reports.push(SendReport::new(sender.public_key()).error(USER_NO_DEKEY)); continue; } } - // Determine receiver and signer - let (receiver, signer) = match signer_kind { + // Determine the signer to use + let signer = match signer_kind { SignerKind::Auto => { - if let Some(announcement) = announcement { - if let Some(enc_signer) = encryption_signer.as_ref() { - (announcement.public_key(), enc_signer.clone()) - } else { - (member.public_key(), user_signer.clone()) - } + if announcement.is_some() + && let Some(encryption_signer) = encryption_signer.clone() + { + // Safe to unwrap due to earlier checks + encryption_signer } else { - (member.public_key(), user_signer.clone()) + user_signer.clone() } } SignerKind::Encryption => { // Safe to unwrap due to earlier checks - ( - announcement.unwrap().public_key(), - encryption_signer.as_ref().unwrap().clone(), - ) + encryption_signer.as_ref().unwrap().clone() } - SignerKind::User => (member.public_key(), user_signer.clone()), + SignerKind::User => user_signer.clone(), }; - match send_gift_wrap(&client, &signer, relays, &receiver, &rumor, public_key).await - { - Ok((report, _)) => { + // Send the gift wrap event and collect the report + match send_gift_wrap(&client, &signer, &member, &rumor, signer_kind, relays).await { + Ok(report) => { reports.push(report); sents += 1; } - Err(report) => { + Err(error) => { + let report = SendReport::new(public_key).error(error.to_string()); reports.push(report); } } @@ -562,12 +562,32 @@ impl Room { if backup && sents >= 1 { let public_key = sender.public_key(); let relays = sender.messaging_relays(); - let signer = encryption_signer.as_ref().unwrap_or(&user_signer); - match send_gift_wrap(&client, signer, relays, &public_key, &rumor, public_key).await - { - Ok((report, _)) => reports.push(report), - Err(report) => reports.push(report), + // Determine the signer to use + let signer = match signer_kind { + SignerKind::Auto => { + if sender.announcement().is_some() + && let Some(encryption_signer) = encryption_signer.clone() + { + // Safe to unwrap due to earlier checks + encryption_signer + } else { + user_signer.clone() + } + } + SignerKind::Encryption => { + // Safe to unwrap due to earlier checks + encryption_signer.as_ref().unwrap().clone() + } + SignerKind::User => user_signer.clone(), + }; + + match send_gift_wrap(&client, &signer, &sender, &rumor, signer_kind, relays).await { + Ok(report) => reports.push(report), + Err(error) => { + let report = SendReport::new(public_key).error(error.to_string()); + reports.push(report); + } } } @@ -580,37 +600,56 @@ impl Room { async fn send_gift_wrap( client: &Client, signer: &T, - to: &[RelayUrl], - receiver: &PublicKey, + receiver: &Person, rumor: &UnsignedEvent, - public_key: PublicKey, -) -> Result<(SendReport, bool), SendReport> + config: &SignerKind, + to: &[RelayUrl], +) -> Result where T: NostrSigner + 'static, { - match EventBuilder::gift_wrap(signer, receiver, rumor.clone(), []).await { - Ok(event) => { - // Connect to each relay before sending - for url in to.iter() { - client.add_relay(url).and_connect().await.ok(); - } + let mut extra_tags = vec![]; - // Send the event to each relay - match client - .send_event(&event) - .to(to) - .ack_policy(AckPolicy::none()) - .await - { - Ok(output) => Ok(( - SendReport::new(public_key) - .gift_wrap_id(event.id) - .output(output), - true, - )), - Err(e) => Err(SendReport::new(public_key).error(e.to_string())), + // Determine the receiver public key based on the config + let receiver = match config { + SignerKind::Auto => { + if let Some(announcement) = receiver.announcement().as_ref() { + extra_tags.push(Tag::public_key(receiver.public_key())); + announcement.public_key() + } else { + receiver.public_key() } } - Err(e) => Err(SendReport::new(public_key).error(e.to_string())), + SignerKind::Encryption => { + if let Some(announcement) = receiver.announcement().as_ref() { + extra_tags.push(Tag::public_key(receiver.public_key())); + announcement.public_key() + } else { + return Err(anyhow!("User has no encryption announcement")); + } + } + SignerKind::User => receiver.public_key(), + }; + + // Construct the gift wrap event + let event = EventBuilder::gift_wrap(signer, &receiver, rumor.clone(), extra_tags).await?; + + // Connect to each relay before sending + for url in to.iter() { + client.add_relay(url).and_connect().await.ok(); } + + // Send the gift wrap event and collect the report + let report = client + .send_event(&event) + .to(to) + .ack_policy(AckPolicy::none()) + .await + .map(|output| { + SendReport::new(receiver) + .gift_wrap_id(event.id) + .output(output) + })?; + + Ok(report) } diff --git a/crates/state/src/constants.rs b/crates/state/src/constants.rs index eb6bec7..296b498 100644 --- a/crates/state/src/constants.rs +++ b/crates/state/src/constants.rs @@ -36,14 +36,16 @@ pub const NOSTR_CONNECT_RELAY: &str = "wss://relay.nip46.com"; /// Default vertex relays pub const WOT_RELAYS: [&str; 1] = ["wss://relay.vertexlab.io"]; +/// Default search relays +pub const INDEXER_RELAYS: [&str; 1] = ["wss://indexer.coracle.social"]; + /// Default search relays pub const SEARCH_RELAYS: [&str; 2] = ["wss://antiprimal.net", "wss://search.nos.today"]; /// Default bootstrap relays -pub const BOOTSTRAP_RELAYS: [&str; 4] = [ +pub const BOOTSTRAP_RELAYS: [&str; 3] = [ "wss://relay.damus.io", "wss://relay.primal.net", - "wss://indexer.coracle.social", "wss://user.kindpag.es", ]; diff --git a/crates/state/src/lib.rs b/crates/state/src/lib.rs index 125130f..1734786 100644 --- a/crates/state/src/lib.rs +++ b/crates/state/src/lib.rs @@ -188,7 +188,18 @@ impl NostrRegistry { let task: Task> = cx.background_spawn(async move { // Add search relay to the relay pool for url in SEARCH_RELAYS.into_iter() { - client.add_relay(url).await?; + client + .add_relay(url) + .capabilities(RelayCapabilities::READ) + .await?; + } + + // Add indexer relay to the relay pool + for url in INDEXER_RELAYS.into_iter() { + client + .add_relay(url) + .capabilities(RelayCapabilities::DISCOVERY) + .await?; } // Add bootstrap relay to the relay pool