diff options
Diffstat (limited to 'src/client.rs')
| -rw-r--r-- | src/client.rs | 72 |
1 files changed, 68 insertions, 4 deletions
diff --git a/src/client.rs b/src/client.rs index e0e0494..5ddf742 100644 --- a/src/client.rs +++ b/src/client.rs | |||
| @@ -10,25 +10,32 @@ | |||
| 10 | // which is currently in nightly. alternatively we can use nightly as it looks | 10 | // which is currently in nightly. alternatively we can use nightly as it looks |
| 11 | // certain that the implementation is going to make it to stable but we don't | 11 | // certain that the implementation is going to make it to stable but we don't |
| 12 | // want to inadvertlty use other features of nightly that might be removed. | 12 | // want to inadvertlty use other features of nightly that might be removed. |
| 13 | use anyhow::Result; | 13 | use anyhow::{Context, Result}; |
| 14 | use async_trait::async_trait; | 14 | use async_trait::async_trait; |
| 15 | use futures::future::join_all; | ||
| 15 | #[cfg(test)] | 16 | #[cfg(test)] |
| 16 | use mockall::*; | 17 | use mockall::*; |
| 17 | use nostr::Event; | 18 | use nostr::Event; |
| 18 | 19 | ||
| 19 | pub struct Client { | 20 | pub struct Client { |
| 20 | client: nostr_sdk::Client, | 21 | client: nostr_sdk::Client, |
| 21 | pub fallback_relays: Vec<String>, | 22 | fallback_relays: Vec<String>, |
| 22 | } | 23 | } |
| 23 | 24 | ||
| 24 | #[async_trait] | ||
| 25 | #[cfg_attr(test, automock)] | 25 | #[cfg_attr(test, automock)] |
| 26 | #[async_trait] | ||
| 26 | pub trait Connect { | 27 | pub trait Connect { |
| 27 | fn default() -> Self; | 28 | fn default() -> Self; |
| 28 | fn new(opts: Params) -> Self; | 29 | fn new(opts: Params) -> Self; |
| 29 | async fn connect(&self) -> Result<()>; | 30 | async fn connect(&self) -> Result<()>; |
| 30 | async fn disconnect(&self) -> Result<()>; | 31 | async fn disconnect(&self) -> Result<()>; |
| 32 | fn get_fallback_relays(&self) -> &Vec<String>; | ||
| 31 | async fn send_event_to(&self, url: &str, event: nostr::event::Event) -> Result<nostr::EventId>; | 33 | async fn send_event_to(&self, url: &str, event: nostr::event::Event) -> Result<nostr::EventId>; |
| 34 | async fn get_events( | ||
| 35 | &self, | ||
| 36 | relays: Vec<String>, | ||
| 37 | filters: Vec<nostr::Filter>, | ||
| 38 | ) -> Result<Vec<nostr::Event>>; | ||
| 32 | } | 39 | } |
| 33 | 40 | ||
| 34 | #[async_trait] | 41 | #[async_trait] |
| @@ -37,7 +44,7 @@ impl Connect for Client { | |||
| 37 | Client { | 44 | Client { |
| 38 | client: nostr_sdk::Client::new(&nostr::Keys::generate()), | 45 | client: nostr_sdk::Client::new(&nostr::Keys::generate()), |
| 39 | fallback_relays: vec![ | 46 | fallback_relays: vec![ |
| 40 | "ws://localhost:8080".to_string(), | 47 | "ws://localhost:8051".to_string(), |
| 41 | "ws://localhost:8052".to_string(), | 48 | "ws://localhost:8052".to_string(), |
| 42 | ], | 49 | ], |
| 43 | } | 50 | } |
| @@ -61,9 +68,52 @@ impl Connect for Client { | |||
| 61 | Ok(()) | 68 | Ok(()) |
| 62 | } | 69 | } |
| 63 | 70 | ||
| 71 | fn get_fallback_relays(&self) -> &Vec<String> { | ||
| 72 | &self.fallback_relays | ||
| 73 | } | ||
| 74 | |||
| 64 | async fn send_event_to(&self, url: &str, event: Event) -> Result<nostr::EventId> { | 75 | async fn send_event_to(&self, url: &str, event: Event) -> Result<nostr::EventId> { |
| 65 | Ok(self.client.send_event_to(url, event).await?) | 76 | Ok(self.client.send_event_to(url, event).await?) |
| 66 | } | 77 | } |
| 78 | |||
| 79 | async fn get_events( | ||
| 80 | &self, | ||
| 81 | relays: Vec<String>, | ||
| 82 | filters: Vec<nostr::Filter>, | ||
| 83 | ) -> Result<Vec<nostr::Event>> { | ||
| 84 | // add relays | ||
| 85 | for relay in &relays { | ||
| 86 | self.client | ||
| 87 | .add_relay(relay.as_str(), None) | ||
| 88 | .await | ||
| 89 | .context("cannot add relay")?; | ||
| 90 | } | ||
| 91 | |||
| 92 | let relays_map = self.client.relays().await; | ||
| 93 | |||
| 94 | let relay_results = join_all( | ||
| 95 | relays | ||
| 96 | .clone() | ||
| 97 | .iter() | ||
| 98 | .map(|r| { | ||
| 99 | ( | ||
| 100 | relays_map.get(&nostr::Url::parse(r).unwrap()).unwrap(), | ||
| 101 | filters.clone(), | ||
| 102 | ) | ||
| 103 | }) | ||
| 104 | .map(|(relay, filters)| { | ||
| 105 | relay.get_events_of( | ||
| 106 | filters, | ||
| 107 | // 20 is nostr_sdk default | ||
| 108 | std::time::Duration::from_secs(20), | ||
| 109 | nostr_sdk::FilterOptions::ExitOnEOSE, | ||
| 110 | ) | ||
| 111 | }), | ||
| 112 | ) | ||
| 113 | .await; | ||
| 114 | |||
| 115 | Ok(get_dedup_events(relay_results)) | ||
| 116 | } | ||
| 67 | } | 117 | } |
| 68 | 118 | ||
| 69 | #[derive(Default)] | 119 | #[derive(Default)] |
| @@ -82,3 +132,17 @@ impl Params { | |||
| 82 | self | 132 | self |
| 83 | } | 133 | } |
| 84 | } | 134 | } |
| 135 | |||
| 136 | fn get_dedup_events( | ||
| 137 | relay_results: Vec<Result<Vec<nostr::Event>, nostr_sdk::relay::Error>>, | ||
| 138 | ) -> Vec<Event> { | ||
| 139 | let mut dedup_events: Vec<Event> = vec![]; | ||
| 140 | for events in relay_results.into_iter().flatten() { | ||
| 141 | for event in events { | ||
| 142 | if !dedup_events.iter().any(|e| event.id.eq(&e.id)) { | ||
| 143 | dedup_events.push(event); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | } | ||
| 147 | dedup_events | ||
| 148 | } | ||