use futures::future::join_all; use nostr_rs_client::Pool; use nostr_rs_relayer::Relayer; use nostr_rs_storage_base::Storage; use nostr_rs_types::types::{Addr, Filter, Id}; use tokio::{net::TcpListener, task::JoinHandle}; use url::Url; pub struct Stoppable(Option>>); impl From>> for Stoppable { fn from(value: Vec>) -> Self { Self(Some(value)) } } impl Drop for Stoppable { fn drop(&mut self) { if let Some(tasks) = self.0.take() { for join_handle in tasks.into_iter() { join_handle.abort(); } } } } #[derive(thiserror::Error, Debug)] pub enum Error { #[error("Relayer: {0}")] Relayer(#[from] nostr_rs_relayer::Error), #[error("Client error: {0}")] Client(#[from] nostr_rs_client::Error), } pub struct PersonalRelayer { relayer: Relayer, accounts: Vec, } impl PersonalRelayer { pub async fn new(storage: T, accounts: Vec, client_urls: Vec) -> Result { let pool = Pool::new_with_clients(client_urls); join_all( accounts .iter() .map(|account| { pool.subscribe( Filter { authors: vec![account.clone()], ..Default::default() } .into(), ) }) .collect::>(), ) .await .into_iter() .collect::, _>>()?; Ok(Self { relayer: Relayer::new(Some(storage), Some(pool))?, accounts, }) } pub fn main(self, server: TcpListener) -> Result { let (relayer, handle) = self.relayer.main(server)?; let tasks = vec![handle, tokio::spawn(async move {})]; Ok(tasks.into()) } }