git add .
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 2m3s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m36s

This commit is contained in:
2026-01-27 13:38:00 +07:00
parent 4a748ca3d1
commit a39725b1d3
10 changed files with 143 additions and 55 deletions

View File

@@ -16,7 +16,7 @@ use gpui::{
};
use nostr_sdk::prelude::*;
use smallvec::{smallvec, SmallVec};
use state::{tracker, NostrRegistry, GIFTWRAP_SUBSCRIPTION};
use state::{tracker, NostrRegistry, RelayState, GIFTWRAP_SUBSCRIPTION};
mod message;
mod room;
@@ -63,14 +63,17 @@ pub struct ChatRegistry {
/// Loading status of the registry
loading: bool,
/// Tracking the status of unwrapping gift wrap events.
tracking_flag: Arc<AtomicBool>,
/// Channel's sender for communication between nostr and gpui
sender: Sender<NostrEvent>,
/// Tracking the status of unwrapping gift wrap events.
tracking_flag: Arc<AtomicBool>,
/// Handle tracking asynchronous task
tracking: Option<Task<Result<(), Error>>>,
/// Handle notifications asynchronous task
notifications: Option<Task<Result<(), Error>>>,
notifications: Option<Task<()>>,
/// Tasks for asynchronous operations
tasks: Vec<Task<()>>,
@@ -112,7 +115,7 @@ impl ChatRegistry {
subscriptions.push(
// Observe the identity
cx.observe(&identity, |this, state, cx| {
if state.read(cx).has_public_key() {
if state.read(cx).messaging_relays_state() == RelayState::Set {
// Handle nostr notifications
this.handle_notifications(cx);
// Track unwrapping progress
@@ -162,8 +165,9 @@ impl ChatRegistry {
Self {
rooms: vec![],
loading: true,
tracking_flag,
sender: tx.clone(),
tracking_flag,
tracking: None,
notifications: None,
tasks,
_subscriptions: subscriptions,
@@ -181,7 +185,7 @@ impl ChatRegistry {
let status = self.tracking_flag.clone();
let tx = self.sender.clone();
self.tasks.push(cx.background_spawn(async move {
self.notifications = Some(cx.background_spawn(async move {
let initialized_at = Timestamp::now();
let subscription_id = SubscriptionId::new(GIFTWRAP_SUBSCRIPTION);
@@ -229,7 +233,7 @@ impl ChatRegistry {
}
},
Err(e) => {
log::warn!("Failed to unwrap: {e}");
log::warn!("Failed to unwrap the gift wrap event: {e}");
}
}
}
@@ -252,7 +256,7 @@ impl ChatRegistry {
let status = self.tracking_flag.clone();
let tx = self.sender.clone();
self.notifications = Some(cx.background_spawn(async move {
self.tracking = Some(cx.background_spawn(async move {
let loop_duration = Duration::from_secs(12);
let mut total_loops = 0;
@@ -607,29 +611,44 @@ impl ChatRegistry {
device_signer: &Option<Arc<dyn NostrSigner>>,
gift_wrap: &Event,
) -> Result<UnwrappedGift, Error> {
if let Some(signer) = device_signer.as_ref() {
let seal = signer
.nip44_decrypt(&gift_wrap.pubkey, &gift_wrap.content)
.await?;
// Try with the device signer first
if let Some(signer) = device_signer {
if let Ok(unwrapped) = Self::try_unwrap_with(gift_wrap, signer).await {
return Ok(unwrapped);
};
};
let seal: Event = Event::from_json(seal)?;
seal.verify_with_ctx(&SECP256K1)?;
let rumor = signer.nip44_decrypt(&seal.pubkey, &seal.content).await?;
let rumor = UnsignedEvent::from_json(rumor)?;
return Ok(UnwrappedGift {
sender: seal.pubkey,
rumor,
});
}
let signer = client.signer().await?;
let unwrapped = UnwrappedGift::from_gift_wrap(&signer, gift_wrap).await?;
// Try with the user's signer
let user_signer = client.signer().await?;
let unwrapped = UnwrappedGift::from_gift_wrap(&user_signer, gift_wrap).await?;
Ok(unwrapped)
}
/// Attempts to unwrap a gift wrap event with a given signer.
async fn try_unwrap_with(
gift_wrap: &Event,
signer: &Arc<dyn NostrSigner>,
) -> Result<UnwrappedGift, Error> {
// Get the sealed event
let seal = signer
.nip44_decrypt(&gift_wrap.pubkey, &gift_wrap.content)
.await?;
// Verify the sealed event
let seal: Event = Event::from_json(seal)?;
seal.verify_with_ctx(&SECP256K1)?;
// Get the rumor event
let rumor = signer.nip44_decrypt(&seal.pubkey, &seal.content).await?;
let rumor = UnsignedEvent::from_json(rumor)?;
Ok(UnwrappedGift {
sender: seal.pubkey,
rumor,
})
}
/// Stores an unwrapped event in local database with reference to original
async fn set_rumor(client: &Client, id: EventId, rumor: &UnsignedEvent) -> Result<(), Error> {
let rumor_id = rumor.id.context("Rumor is missing an event id")?;