diff --git a/Cargo.lock b/Cargo.lock index 0983ee0..82a0241 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -596,7 +596,7 @@ dependencies = [ "bitflags 2.10.0", "cexpr", "clang-sys", - "itertools 0.13.0", + "itertools 0.11.0", "log", "prettyplease", "proc-macro2", @@ -616,7 +616,7 @@ dependencies = [ "bitflags 2.10.0", "cexpr", "clang-sys", - "itertools 0.13.0", + "itertools 0.11.0", "log", "prettyplease", "proc-macro2", @@ -1873,7 +1873,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3984,6 +3984,18 @@ dependencies = [ "nostr", ] +[[package]] +name = "nostr-gossip-memory" +version = "0.43.0" +source = "git+https://github.com/rust-nostr/nostr#8927f6630c071d982f9aa79fb9cd6807ae554abe" +dependencies = [ + "indexmap", + "lru", + "nostr", + "nostr-gossip", + "tokio", +] + [[package]] name = "nostr-lmdb" version = "0.43.0" @@ -4044,7 +4056,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -4920,7 +4932,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -5473,7 +5485,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.11.0", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -6150,6 +6162,7 @@ dependencies = [ "dirs 5.0.1", "flume", "log", + "nostr-gossip-memory", "nostr-lmdb", "nostr-sdk", "rustls", @@ -6503,7 +6516,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix 1.1.2", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -7745,7 +7758,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 3046151..2725454 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ reqwest_client = { git = "https://github.com/zed-industries/zed" } nostr = { git = "https://github.com/rust-nostr/nostr" } nostr-lmdb = { git = "https://github.com/rust-nostr/nostr" } nostr-connect = { git = "https://github.com/rust-nostr/nostr" } +nostr-gossip-memory = { git = "https://github.com/rust-nostr/nostr" } nostr-sdk = { git = "https://github.com/rust-nostr/nostr", features = [ "nip96", "nip59", "nip49", "nip44" ] } # Others diff --git a/crates/registry/src/room.rs b/crates/registry/src/room.rs index 1f0ebaf..337256c 100644 --- a/crates/registry/src/room.rs +++ b/crates/registry/src/room.rs @@ -566,12 +566,6 @@ impl Room { continue; } - // Ensure connection to the relays - for url in urls.iter() { - client.add_relay(url).await.ok(); - client.connect_relay(url).await.ok(); - } - // Get user's encryption public key if available let encryption = announcement_cache .get(&member) diff --git a/crates/states/Cargo.toml b/crates/states/Cargo.toml index b8a298c..5581fca 100644 --- a/crates/states/Cargo.toml +++ b/crates/states/Cargo.toml @@ -7,6 +7,7 @@ publish.workspace = true [dependencies] nostr-sdk.workspace = true nostr-lmdb.workspace = true +nostr-gossip-memory.workspace = true dirs.workspace = true smol.workspace = true diff --git a/crates/states/src/state/mod.rs b/crates/states/src/state/mod.rs index f6f33ac..f35b3d8 100644 --- a/crates/states/src/state/mod.rs +++ b/crates/states/src/state/mod.rs @@ -6,6 +6,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Duration; use anyhow::{anyhow, Context, Error}; +use nostr_gossip_memory::prelude::*; use nostr_lmdb::NostrLMDB; use nostr_sdk::prelude::*; use smol::lock::RwLock; @@ -71,18 +72,25 @@ impl AppState { .install_default() .ok(); - let lmdb = - NostrLMDB::open(config_dir().join("nostr")).expect("Database is NOT initialized"); + let path = config_dir().join("nostr"); + let lmdb = NostrLMDB::open(path).expect("Failed to initialize database"); + let gossip = NostrGossipMemory::unbounded(); + // Nostr client options let opts = ClientOptions::new() - .gossip(true) .automatic_authentication(false) .verify_subscriptions(false) .sleep_when_idle(SleepWhenIdle::Enabled { timeout: Duration::from_secs(600), }); - let client = ClientBuilder::default().database(lmdb).opts(opts).build(); + // Construct the nostr client + let client = ClientBuilder::default() + .gossip(gossip) + .database(lmdb) + .opts(opts) + .build(); + let device = RwLock::new(Device::default()); let event_tracker = RwLock::new(EventTracker::default()); let relay_cache = RwLock::new(HashMap::default()); @@ -136,18 +144,18 @@ impl AppState { loop { if let Ok(signer) = client.signer().await { - if let Ok(pk) = signer.get_public_key().await { + if let Ok(public_key) = signer.get_public_key().await { // Notify the app that the signer has been set - self.signal().send(SignalKind::SignerSet(pk)).await; + self.signal().send(SignalKind::SignerSet(public_key)).await; // Get user's gossip relays - self.get_nip65(pk).await.ok(); + self.get_nip65(public_key).await.ok(); // Initialize the relay and announcement caches self.init_cache().await.ok(); - // Initialize client keys - self.init_client_keys().await.ok(); + // Initialize client key + self.init_client_key().await.ok(); // Exit the loop break; @@ -242,10 +250,10 @@ impl AppState { } match event.kind { - // Encryption Keys announcement event + // Encryption Key announcement event Kind::Custom(10044) => { if let Ok(announcement) = self.extract_announcement(&event) { - if let Ok(true) = self.is_self_authored(&event).await { + if self.is_self_authored(&event).await { self.signal .send(SignalKind::EncryptionSet(announcement.clone())) .await; @@ -256,9 +264,9 @@ impl AppState { announcement_cache.insert(event.pubkey, Some(announcement)); } } - // Encryption Keys request event + // Encryption Key request event Kind::Custom(4454) => { - if let Ok(true) = self.is_self_authored(&event).await { + if self.is_self_authored(&event).await { if let Ok(announcement) = self.extract_announcement(&event) { self.signal .send(SignalKind::EncryptionRequest(announcement)) @@ -268,7 +276,7 @@ impl AppState { } // Encryption Keys response event Kind::Custom(4455) => { - if let Ok(true) = self.is_self_authored(&event).await { + if self.is_self_authored(&event).await { if let Ok(response) = self.extract_response(&event) { self.signal .send(SignalKind::EncryptionResponse(response)) @@ -278,7 +286,7 @@ impl AppState { } Kind::RelayList => { // Get events if relay list belongs to current user - if let Ok(true) = self.is_self_authored(&event).await { + if self.is_self_authored(&event).await { let author = event.pubkey; // Fetch user's metadata event @@ -310,7 +318,7 @@ impl AppState { .collect(); // Subscribe to gift wrap events if messaging relays belong to the current user - if let Ok(true) = self.is_self_authored(&event).await { + if self.is_self_authored(&event).await { if let Err(e) = self.get_messages(event.pubkey, &urls).await { log::error!("Failed to fetch messages: {e}"); } @@ -321,7 +329,7 @@ impl AppState { relay_cache.entry(event.pubkey).or_default().extend(urls); } Kind::ContactList => { - if let Ok(true) = self.is_self_authored(&event).await { + if self.is_self_authored(&event).await { let public_keys: HashSet = event.tags.public_keys().copied().collect(); @@ -481,11 +489,13 @@ impl AppState { } /// Check if event is published by current user - async fn is_self_authored(&self, event: &Event) -> Result { - let signer = self.client.signer().await?; - let public_key = signer.get_public_key().await?; - - Ok(public_key == event.pubkey) + async fn is_self_authored(&self, event: &Event) -> bool { + if let Ok(signer) = self.client.signer().await { + if let Ok(public_key) = signer.get_public_key().await { + return public_key == event.pubkey; + } + } + false } /// Subscribe for events that match the given kind for a given author @@ -514,7 +524,7 @@ impl AppState { } let filter = Filter::new() - .limit(authors.len() * kinds.len() + 20) + .limit(authors.len() * kinds.len() + 10) .authors(authors) .kinds(kinds); @@ -614,7 +624,7 @@ impl AppState { /// Initialize the client keys to communicate between clients /// /// NIP-4e: https://github.com/nostr-protocol/nips/blob/per-device-keys/4e.md - pub async fn init_client_keys(&self) -> Result<(), Error> { + pub async fn init_client_key(&self) -> Result<(), Error> { // Get the keys from the database or generate new ones let keys = self .get_keys("client")