From 1304b7ceaee39a4541317727300d4f3650c17222 Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Mon, 18 Sep 2023 11:52:20 +0200 Subject: [PATCH] sdk: wrap `Keys` in `Arc>` --- bindings/nostr-sdk-js/src/client/mod.rs | 4 +- crates/nostr-sdk/examples/nostr-connect.rs | 2 +- crates/nostr-sdk/src/client/blocking.rs | 2 +- crates/nostr-sdk/src/client/mod.rs | 45 ++++++++++++-------- crates/nostr-sdk/src/client/signer/remote.rs | 38 ++++++++++------- 5 files changed, 53 insertions(+), 38 deletions(-) diff --git a/bindings/nostr-sdk-js/src/client/mod.rs b/bindings/nostr-sdk-js/src/client/mod.rs index a41cf7d3f..e848cfeaa 100644 --- a/bindings/nostr-sdk-js/src/client/mod.rs +++ b/bindings/nostr-sdk-js/src/client/mod.rs @@ -38,8 +38,8 @@ impl JsClient { /// Get current `Keys` #[wasm_bindgen(getter)] - pub fn keys(&self) -> JsKeys { - self.inner.keys().into() + pub async fn keys(&self) -> JsKeys { + self.inner.keys().await.into() } /// Completely shutdown `Client` diff --git a/crates/nostr-sdk/examples/nostr-connect.rs b/crates/nostr-sdk/examples/nostr-connect.rs index 775828c49..d1fd996a0 100644 --- a/crates/nostr-sdk/examples/nostr-connect.rs +++ b/crates/nostr-sdk/examples/nostr-connect.rs @@ -20,7 +20,7 @@ async fn main() -> Result<()> { client.add_relay(relay_url, None).await?; let metadata = NostrConnectMetadata::new("Nostr SDK").url(Url::parse("https://example.com")?); - let nostr_connect_uri: NostrConnectURI = client.nostr_connect_uri(metadata)?; + let nostr_connect_uri: NostrConnectURI = client.nostr_connect_uri(metadata).await?; println!("\n###############################################\n"); println!("Nostr Connect URI: {nostr_connect_uri}"); diff --git a/crates/nostr-sdk/src/client/blocking.rs b/crates/nostr-sdk/src/client/blocking.rs index c1c360b9e..c6520fab8 100644 --- a/crates/nostr-sdk/src/client/blocking.rs +++ b/crates/nostr-sdk/src/client/blocking.rs @@ -71,7 +71,7 @@ impl Client { /// Get current [`Keys`] pub fn keys(&self) -> Keys { - self.client.keys() + RUNTIME.block_on(async { self.client.keys().await }) } /// Start a previously stopped client diff --git a/crates/nostr-sdk/src/client/mod.rs b/crates/nostr-sdk/src/client/mod.rs index 50c50769b..c275b8377 100644 --- a/crates/nostr-sdk/src/client/mod.rs +++ b/crates/nostr-sdk/src/client/mod.rs @@ -24,7 +24,7 @@ use nostr::{ Metadata, Result, Tag, }; use nostr_sdk_net::futures_util::Future; -use tokio::sync::broadcast; +use tokio::sync::{broadcast, RwLock}; #[cfg(feature = "blocking")] pub mod blocking; @@ -111,7 +111,7 @@ pub enum Error { #[derive(Debug, Clone)] pub struct Client { pool: RelayPool, - keys: Keys, + keys: Arc>, opts: Options, dropped: Arc, #[cfg(feature = "nip46")] @@ -167,7 +167,7 @@ impl Client { pub fn with_opts(keys: &Keys, opts: Options) -> Self { Self { pool: RelayPool::new(opts.pool), - keys: keys.clone(), + keys: Arc::new(RwLock::new(keys.clone())), opts, dropped: Arc::new(AtomicBool::new(false)), #[cfg(feature = "nip46")] @@ -190,7 +190,7 @@ impl Client { ) -> Self { Self { pool: RelayPool::new(opts.pool), - keys: app_keys.clone(), + keys: Arc::new(RwLock::new(app_keys.clone())), opts, dropped: Arc::new(AtomicBool::new(false)), remote_signer: Some(remote_signer), @@ -203,8 +203,9 @@ impl Client { } /// Get current [`Keys`] - pub fn keys(&self) -> Keys { - self.keys.clone() + pub async fn keys(&self) -> Keys { + let keys = self.keys.read().await; + keys.clone() } /// Get [`RelayPool`] @@ -214,7 +215,7 @@ impl Client { /// Get NIP46 uri #[cfg(feature = "nip46")] - pub fn nostr_connect_uri( + pub async fn nostr_connect_uri( &self, metadata: NostrConnectMetadata, ) -> Result { @@ -222,8 +223,9 @@ impl Client { .remote_signer .as_ref() .ok_or(Error::SignerNotConfigured)?; + let keys = self.keys.read().await; Ok(NostrConnectURI::new( - self.keys.public_key(), + keys.public_key(), signer.relay_url(), metadata.name, )) @@ -724,20 +726,22 @@ impl Client { } } else { let difficulty: u8 = self.opts.get_difficulty(); + let keys = self.keys.read().await; if difficulty > 0 { - builder.to_pow_event(&self.keys, difficulty)? + builder.to_pow_event(&keys, difficulty)? } else { - builder.to_event(&self.keys)? + builder.to_event(&keys)? } }; #[cfg(not(feature = "nip46"))] let event: Event = { let difficulty: u8 = self.opts.get_difficulty(); + let keys = self.keys.read().await; if difficulty > 0 { - builder.to_pow_event(&self.keys, difficulty)? + builder.to_pow_event(&keys, difficulty)? } else { - builder.to_event(&self.keys)? + builder.to_event(&keys)? } }; @@ -846,17 +850,21 @@ impl Client { filter = filter.author(signer_public_key.to_string()); } else { - filter = filter.author(self.keys.public_key().to_string()); + let keys = self.keys.read().await; + filter = filter.author(keys.public_key().to_string()); } filter }; #[cfg(not(feature = "nip46"))] - let filter = Filter::new() - .author(self.keys.public_key().to_string()) - .kind(Kind::ContactList) - .limit(1); + let filter: Filter = { + let keys = self.keys.read().await; + Filter::new() + .author(keys.public_key().to_string()) + .kind(Kind::ContactList) + .limit(1) + }; Ok(vec![filter]) } @@ -1011,7 +1019,8 @@ impl Client { return Err(Error::ResponseNotMatchRequest); } } else { - EventBuilder::new_encrypted_direct_msg(&self.keys, receiver, msg, reply_to)? + let keys = self.keys.read().await; + EventBuilder::new_encrypted_direct_msg(&keys, receiver, msg, reply_to)? }; #[cfg(not(feature = "nip46"))] diff --git a/crates/nostr-sdk/src/client/signer/remote.rs b/crates/nostr-sdk/src/client/signer/remote.rs index 5bcee4a21..731263f7b 100644 --- a/crates/nostr-sdk/src/client/signer/remote.rs +++ b/crates/nostr-sdk/src/client/signer/remote.rs @@ -109,9 +109,14 @@ impl Client { .ok_or(Error::SignerNotConfigured)?; if signer.signer_public_key().await.is_none() { + let keys = self.keys.read().await; + let public_key = keys.public_key(); + let secret_key = keys.secret_key()?; + drop(keys); + let id = SubscriptionId::generate(); let filter = Filter::new() - .pubkey(self.keys.public_key()) + .pubkey(public_key) .kind(Kind::NostrConnect) .since(Timestamp::now()); @@ -127,14 +132,11 @@ impl Client { while let Ok(notification) = notifications.recv().await { if let RelayPoolNotification::Event(_url, event) = notification { if event.kind == Kind::NostrConnect { - let msg: String = nip04::decrypt( - &self.keys.secret_key()?, - &event.pubkey, - &event.content, - )?; + let msg: String = + nip04::decrypt(&secret_key, &event.pubkey, &event.content)?; let msg = Message::from_json(msg)?; - if let Ok(Request::Connect(public_key)) = msg.to_request() { - signer.set_signer_public_key(public_key).await; + if let Ok(Request::Connect(pk)) = msg.to_request() { + signer.set_signer_public_key(pk).await; break; } } @@ -172,14 +174,22 @@ impl Client { let msg = Message::request(req.clone()); let req_id = msg.id(); + let keys = self.keys.read().await; + let public_key = keys.public_key(); + let secret_key = keys.secret_key()?; + + // Build request + let event = EventBuilder::nostr_connect(&keys, signer_pubkey, msg)?.to_event(&keys)?; + + // Drop keys + drop(keys); + // Send request to signer - let event = - EventBuilder::nostr_connect(&self.keys, signer_pubkey, msg)?.to_event(&self.keys)?; self.send_event_to(signer.relay_url(), event).await?; let sub_id = SubscriptionId::generate(); let filter = Filter::new() - .pubkey(self.keys.public_key()) + .pubkey(public_key) .kind(Kind::NostrConnect) .since(Timestamp::now()); @@ -195,11 +205,7 @@ impl Client { while let Ok(notification) = notifications.recv().await { if let RelayPoolNotification::Event(_url, event) = notification { if event.kind == Kind::NostrConnect { - let msg = nip04::decrypt( - &self.keys.secret_key()?, - &event.pubkey, - &event.content, - )?; + let msg = nip04::decrypt(&secret_key, &event.pubkey, &event.content)?; let msg = Message::from_json(msg)?; tracing::debug!("New message received: {msg:?}");