This commit is contained in:
2026-03-18 14:00:06 +07:00
parent f45abb58c7
commit d53af98feb
4 changed files with 108 additions and 54 deletions

View File

@@ -708,8 +708,10 @@ async fn extract_rumor(
async fn try_unwrap(signer: &Arc<CoopSigner>, gift_wrap: &Event) -> Result<UnwrappedGift, Error> {
// 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

View File

@@ -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<T>(
client: &Client,
signer: &T,
to: &[RelayUrl],
receiver: &PublicKey,
receiver: &Person,
rumor: &UnsignedEvent,
public_key: PublicKey,
) -> Result<(SendReport, bool), SendReport>
config: &SignerKind,
to: &[RelayUrl],
) -> Result<SendReport, Error>
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)
}

View File

@@ -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",
];

View File

@@ -188,7 +188,18 @@ impl NostrRegistry {
let task: Task<Result<(), Error>> = 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