host_nostr.rs (3291B)
1 //! Daemon-owned Nostr client adapter. 2 //! 3 //! Radroots protocol crates deliberately do not own relay clients, process 4 //! lifecycle, or service keys. This private adapter keeps those host concerns 5 //! in `radrootsd` while using upstream protocol values at the explicit edge. 6 7 use core::time::Duration; 8 9 pub(crate) use nostr::{ 10 Event, Filter, Keys, Kind, Metadata, PublicKey, SecretKey, SubscriptionId, Timestamp, 11 }; 12 pub(crate) use nostr_sdk::RelayPoolNotification; 13 pub(crate) use radroots_nostr::event::{ 14 ApplicationHandlerSpec, build_application_handler, build_profile, 15 }; 16 17 #[derive(Clone)] 18 pub(crate) struct DaemonNostrClient { 19 inner: nostr_sdk::Client, 20 } 21 22 impl DaemonNostrClient { 23 pub(crate) fn signerless() -> Self { 24 let inner = nostr_sdk::Client::default(); 25 inner.automatic_authentication(false); 26 Self { inner } 27 } 28 29 pub(crate) fn with_keys(keys: Keys) -> Self { 30 let inner = nostr_sdk::Client::new(keys); 31 inner.automatic_authentication(false); 32 Self { inner } 33 } 34 35 #[cfg(test)] 36 pub(crate) fn from_identity(identity: &crate::app::identity_storage::DaemonIdentity) -> Self { 37 Self::with_keys(identity.keys().clone()) 38 } 39 40 pub(crate) fn into_inner(self) -> nostr_sdk::Client { 41 self.inner 42 } 43 44 pub(crate) async fn connect(&self) { 45 self.inner.connect().await; 46 } 47 48 pub(crate) async fn wait_for_connection(&self, timeout: Duration) { 49 self.inner.wait_for_connection(timeout).await; 50 } 51 52 pub(crate) async fn add_relay(&self, url: &str) -> Result<bool, nostr_sdk::client::Error> { 53 self.inner.add_relay(url).await 54 } 55 56 pub(crate) async fn add_read_relay(&self, url: &str) -> Result<bool, nostr_sdk::client::Error> { 57 self.inner.add_read_relay(url).await 58 } 59 60 pub(crate) async fn relays( 61 &self, 62 ) -> std::collections::HashMap<nostr::RelayUrl, nostr_sdk::Relay> { 63 self.inner.relays().await 64 } 65 66 pub(crate) async fn fetch_events( 67 &self, 68 filter: Filter, 69 timeout: Duration, 70 ) -> Result<Vec<Event>, nostr_sdk::client::Error> { 71 self.inner 72 .fetch_events(filter, timeout) 73 .await 74 .map(|events| events.to_vec()) 75 } 76 77 pub(crate) async fn subscribe( 78 &self, 79 filter: Filter, 80 options: Option<nostr_sdk::SubscribeAutoCloseOptions>, 81 ) -> Result<nostr_sdk::prelude::Output<SubscriptionId>, nostr_sdk::client::Error> { 82 self.inner.subscribe(filter, options).await 83 } 84 85 pub(crate) async fn unsubscribe(&self, subscription_id: &SubscriptionId) { 86 self.inner.unsubscribe(subscription_id).await; 87 } 88 89 pub(crate) async fn send_event( 90 &self, 91 event: &Event, 92 ) -> Result<nostr_sdk::prelude::Output<nostr::EventId>, nostr_sdk::client::Error> { 93 self.inner.send_event(event).await 94 } 95 } 96 97 pub(crate) fn parse_public_key(value: &str) -> Result<PublicKey, radroots_nostr::Error> { 98 radroots_nostr::key::parse_public_key(value).and_then(radroots_nostr::key::public_key_to_nostr) 99 } 100 101 pub(crate) fn with_filter_tag( 102 filter: Filter, 103 tag: &str, 104 values: Vec<String>, 105 ) -> Result<Filter, radroots_nostr::Error> { 106 radroots_nostr::filter::with_tag(filter, tag, values) 107 }