From e237328ec611a5891586530c1d3cb26c16c1093b Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Sun, 1 Oct 2023 00:00:00 +0100 Subject: feat(login) fetch user relays and metadata get user relay list and metadata events from relays when keys are used and last fetch attempt was more than an hour ago uses user's write relays if known, otherwise uses fallback relays to achieve this a method for intergration testing event fetching from relays was added --- src/client.rs | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 4 deletions(-) (limited to 'src/client.rs') 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 @@ // which is currently in nightly. alternatively we can use nightly as it looks // certain that the implementation is going to make it to stable but we don't // want to inadvertlty use other features of nightly that might be removed. -use anyhow::Result; +use anyhow::{Context, Result}; use async_trait::async_trait; +use futures::future::join_all; #[cfg(test)] use mockall::*; use nostr::Event; pub struct Client { client: nostr_sdk::Client, - pub fallback_relays: Vec, + fallback_relays: Vec, } -#[async_trait] #[cfg_attr(test, automock)] +#[async_trait] pub trait Connect { fn default() -> Self; fn new(opts: Params) -> Self; async fn connect(&self) -> Result<()>; async fn disconnect(&self) -> Result<()>; + fn get_fallback_relays(&self) -> &Vec; async fn send_event_to(&self, url: &str, event: nostr::event::Event) -> Result; + async fn get_events( + &self, + relays: Vec, + filters: Vec, + ) -> Result>; } #[async_trait] @@ -37,7 +44,7 @@ impl Connect for Client { Client { client: nostr_sdk::Client::new(&nostr::Keys::generate()), fallback_relays: vec![ - "ws://localhost:8080".to_string(), + "ws://localhost:8051".to_string(), "ws://localhost:8052".to_string(), ], } @@ -61,9 +68,52 @@ impl Connect for Client { Ok(()) } + fn get_fallback_relays(&self) -> &Vec { + &self.fallback_relays + } + async fn send_event_to(&self, url: &str, event: Event) -> Result { Ok(self.client.send_event_to(url, event).await?) } + + async fn get_events( + &self, + relays: Vec, + filters: Vec, + ) -> Result> { + // add relays + for relay in &relays { + self.client + .add_relay(relay.as_str(), None) + .await + .context("cannot add relay")?; + } + + let relays_map = self.client.relays().await; + + let relay_results = join_all( + relays + .clone() + .iter() + .map(|r| { + ( + relays_map.get(&nostr::Url::parse(r).unwrap()).unwrap(), + filters.clone(), + ) + }) + .map(|(relay, filters)| { + relay.get_events_of( + filters, + // 20 is nostr_sdk default + std::time::Duration::from_secs(20), + nostr_sdk::FilterOptions::ExitOnEOSE, + ) + }), + ) + .await; + + Ok(get_dedup_events(relay_results)) + } } #[derive(Default)] @@ -82,3 +132,17 @@ impl Params { self } } + +fn get_dedup_events( + relay_results: Vec, nostr_sdk::relay::Error>>, +) -> Vec { + let mut dedup_events: Vec = vec![]; + for events in relay_results.into_iter().flatten() { + for event in events { + if !dedup_events.iter().any(|e| event.id.eq(&e.id)) { + dedup_events.push(event); + } + } + } + dedup_events +} -- cgit v1.2.3