update nostr sdk

This commit is contained in:
2026-05-17 14:38:07 +07:00
parent 6d60726f27
commit d2a17e54c4
19 changed files with 630 additions and 612 deletions

View File

@@ -1,15 +1,16 @@
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use std::sync::Arc;
use std::time::Duration;
use anyhow::{Error, anyhow};
use anyhow::Error;
use common::EventExt;
use gpui::{App, AppContext, Context, EventEmitter, SharedString, Task};
use itertools::Itertools;
use nostr_sdk::prelude::*;
use person::{Person, PersonRegistry};
use settings::{RoomConfig, SignerKind};
use state::{NostrRegistry, TIMEOUT};
use state::{CoopSigner, NostrRegistry, TIMEOUT};
use crate::NewMessage;
@@ -171,7 +172,8 @@ impl From<&UnsignedEvent> for Room {
let members = val.extract_public_keys();
let subject = val
.tags
.find(TagKind::Subject)
.iter()
.find(|tag| tag.kind() == "subject")
.and_then(|tag| tag.content().map(|s| s.to_owned().into()));
Room {
@@ -440,9 +442,7 @@ impl Room {
// Add subject tag if present
if let Some(value) = self.subject.as_ref() {
tags.push(Tag::from_standardized_without_cell(TagStandard::Subject(
value.to_string(),
)));
tags.push(Tag::custom("subject", vec![value.to_string()]));
}
// Add all reply tags
@@ -452,14 +452,13 @@ impl Room {
// Add all receiver tags
for member in members.into_iter() {
tags.push(Tag::from_standardized_without_cell(
TagStandard::PublicKey {
tags.push(
Nip01Tag::PublicKey {
public_key: member.public_key(),
relay_url: member.messaging_relay_hint(),
alias: None,
uppercase: false,
},
));
relay_hint: member.messaging_relay_hint(),
}
.to_tag(),
);
}
// Construct a direct message rumor event
@@ -474,9 +473,9 @@ impl Room {
/// Send rumor event to all members's messaging relays
pub fn send(&self, rumor: UnsignedEvent, cx: &App) -> Option<Task<Vec<SendReport>>> {
let config = self.config.clone();
let persons = PersonRegistry::global(cx);
let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client();
let signer = nostr.read(cx).signer();
@@ -484,6 +483,8 @@ impl Room {
let public_key = nostr.read(cx).signer().public_key()?;
let sender = persons.read(cx).get(&public_key, cx);
let config = self.config.clone();
// Get all members (excluding sender)
let members: Vec<Person> = self
.members
@@ -492,12 +493,10 @@ impl Room {
.map(|member| persons.read(cx).get(member, cx))
.collect();
Some(cx.background_spawn(async move {
Some(cx.spawn(async move |_cx| {
let signer_kind = config.signer_kind();
let backup = config.backup();
let user_signer = signer.get().await;
let encryption_signer = signer.get_encryption_signer().await;
let has_encryption_signer = signer.has_encryption_signer().await;
let mut sents = 0;
let mut reports = Vec::new();
@@ -516,33 +515,21 @@ impl Room {
}
// Sender didn't set up a decoupled encryption key
if encryption_signer.is_none() {
if !has_encryption_signer {
reports.push(SendReport::new(sender.public_key()).error(USER_NO_DEKEY));
continue;
}
}
// Determine the signer to use
let signer = match signer_kind {
SignerKind::Auto => {
if 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(),
let use_encryption = match signer_kind {
SignerKind::Auto => announcement.is_some() && has_encryption_signer,
SignerKind::Encryption => true,
SignerKind::User => false,
};
// Send the gift wrap event and collect the report
match send_gift_wrap(&client, &signer, &member, &rumor, signer_kind).await {
match send_gift_wrap(&client, &signer, &member, &rumor, use_encryption).await {
Ok(report) => {
reports.push(report);
sents += 1;
@@ -559,25 +546,13 @@ impl Room {
let public_key = sender.public_key();
// 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(),
let use_encryption = match signer_kind {
SignerKind::Auto => sender.announcement().is_some() && has_encryption_signer,
SignerKind::Encryption => true,
SignerKind::User => false,
};
match send_gift_wrap(&client, &signer, &sender, &rumor, signer_kind).await {
match send_gift_wrap(&client, &signer, &sender, &rumor, use_encryption).await {
Ok(report) => reports.push(report),
Err(error) => {
let report = SendReport::new(public_key).error(error.to_string());
@@ -592,22 +567,19 @@ impl Room {
}
// Helper function to send a gift-wrapped event
async fn send_gift_wrap<T>(
async fn send_gift_wrap(
client: &Client,
signer: &T,
signer: &Arc<CoopSigner>,
receiver: &Person,
rumor: &UnsignedEvent,
config: &SignerKind,
) -> Result<SendReport, Error>
where
T: NostrSigner + 'static,
{
let k_tag = Tag::custom(TagKind::k(), vec!["14"]);
encryption: bool,
) -> Result<SendReport, Error> {
let k_tag = Tag::custom("k", vec!["14"]);
let mut extra_tags = vec![k_tag];
// Determine the receiver public key based on the config
let receiver = match config {
SignerKind::Auto => {
let receiver = match encryption {
true => {
if let Some(announcement) = receiver.announcement().as_ref() {
extra_tags.push(Tag::public_key(receiver.public_key()));
announcement.public_key()
@@ -615,19 +587,20 @@ where
receiver.public_key()
}
}
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(),
false => receiver.public_key(),
};
// Construct the gift wrap event
let event = EventBuilder::gift_wrap(signer, &receiver, rumor.clone(), extra_tags).await?;
let event = match encryption {
true => {
let signer = signer.get_encryption_signer().await.unwrap();
EventBuilder::gift_wrap_async(&signer, &receiver, rumor.clone(), extra_tags).await?
}
false => {
let signer = signer.get().await;
EventBuilder::gift_wrap_async(&signer, &receiver, rumor.clone(), extra_tags).await?
}
};
// Send the gift wrap event and collect the report
let report = client