upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/client.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.rs')
-rw-r--r--src/client.rs72
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.
13use anyhow::Result; 13use anyhow::{Context, Result};
14use async_trait::async_trait; 14use async_trait::async_trait;
15use futures::future::join_all;
15#[cfg(test)] 16#[cfg(test)]
16use mockall::*; 17use mockall::*;
17use nostr::Event; 18use nostr::Event;
18 19
19pub struct Client { 20pub 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]
26pub trait Connect { 27pub 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
136fn 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}