radrootsd

JSON-RPC bridge for Radroots event publishing
git clone https://radroots.dev/git/radrootsd.git
Log | Files | Refs | README | LICENSE

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 }