contextvm_sdk/relay/
mod.rs1#[cfg(any(test, feature = "test-utils"))]
6pub mod mock;
7#[cfg(any(test, feature = "test-utils"))]
8pub use mock::MockRelayPool;
9
10use async_trait::async_trait;
11
12use crate::core::error::{Error, Result};
13use nostr_sdk::prelude::*;
14use std::sync::Arc;
15use std::time::Duration;
16
17#[async_trait]
19pub trait RelayPoolTrait: Send + Sync {
20 async fn connect(&self, relay_urls: &[String]) -> Result<()>;
22 async fn disconnect(&self) -> Result<()>;
24 async fn publish_event(&self, event: &Event) -> Result<EventId>;
26 async fn publish(&self, builder: EventBuilder) -> Result<EventId>;
28 async fn sign(&self, builder: EventBuilder) -> Result<Event>;
30 async fn signer(&self) -> Result<Arc<dyn NostrSigner>>;
32 fn notifications(&self) -> tokio::sync::broadcast::Receiver<RelayPoolNotification>;
34 async fn public_key(&self) -> Result<PublicKey>;
36 async fn subscribe(&self, filters: Vec<Filter>) -> Result<()>;
38 async fn publish_to(&self, urls: &[String], builder: EventBuilder) -> Result<EventId>;
40 async fn fetch_events(&self, filters: Vec<Filter>, timeout: Duration) -> Result<Vec<Event>>;
42}
43
44pub struct RelayPool {
46 client: Arc<Client>,
47}
48
49impl RelayPool {
50 pub async fn new<T>(signer: T) -> Result<Self>
52 where
53 T: IntoNostrSigner,
54 {
55 let client = Client::builder().signer(signer).build();
56
57 Ok(Self {
58 client: Arc::new(client),
59 })
60 }
61
62 pub async fn connect(&self, relay_urls: &[String]) -> Result<()> {
64 for url in relay_urls {
65 self.client
66 .add_relay(url)
67 .await
68 .map_err(|e| Error::Transport(e.to_string()))?;
69 }
70
71 self.client.connect().await;
72
73 Ok(())
74 }
75
76 pub async fn disconnect(&self) -> Result<()> {
78 self.client.disconnect().await;
79 Ok(())
80 }
81
82 pub async fn publish_event(&self, event: &Event) -> Result<EventId> {
84 let output = self
85 .client
86 .send_event(event)
87 .await
88 .map_err(|e| Error::Transport(e.to_string()))?;
89 Ok(output.val)
90 }
91
92 pub async fn publish(&self, builder: EventBuilder) -> Result<EventId> {
94 let output = self
95 .client
96 .send_event_builder(builder)
97 .await
98 .map_err(|e| Error::Transport(e.to_string()))?;
99 Ok(output.val)
100 }
101
102 pub async fn sign(&self, builder: EventBuilder) -> Result<Event> {
104 self.client
105 .sign_event_builder(builder)
106 .await
107 .map_err(|e| Error::Transport(e.to_string()))
108 }
109
110 pub fn client(&self) -> &Arc<Client> {
112 &self.client
113 }
114
115 pub fn notifications(&self) -> tokio::sync::broadcast::Receiver<RelayPoolNotification> {
117 self.client.notifications()
118 }
119
120 pub async fn public_key(&self) -> Result<PublicKey> {
122 let signer = self
123 .client
124 .signer()
125 .await
126 .map_err(|e| Error::Other(e.to_string()))?;
127 signer
128 .get_public_key()
129 .await
130 .map_err(|e| Error::Other(e.to_string()))
131 }
132
133 pub async fn subscribe(&self, filters: Vec<Filter>) -> Result<()> {
135 for filter in filters {
136 self.client
137 .subscribe(filter, None)
138 .await
139 .map_err(|e| Error::Transport(e.to_string()))?;
140 }
141 Ok(())
142 }
143
144 pub async fn publish_to(&self, urls: &[String], builder: EventBuilder) -> Result<EventId> {
146 let output = self
147 .client
148 .send_event_builder_to(urls, builder)
149 .await
150 .map_err(|e| Error::Transport(e.to_string()))?;
151 Ok(output.val)
152 }
153
154 pub async fn fetch_events(
156 &self,
157 filters: Vec<Filter>,
158 timeout: Duration,
159 ) -> Result<Vec<Event>> {
160 let mut all_events = Vec::new();
161 for filter in filters {
162 let events = self
163 .client
164 .fetch_events(filter, timeout)
165 .await
166 .map_err(|e| Error::Transport(e.to_string()))?;
167 all_events.extend(events);
168 }
169 Ok(all_events)
170 }
171}
172
173#[async_trait]
174impl RelayPoolTrait for RelayPool {
175 async fn connect(&self, relay_urls: &[String]) -> Result<()> {
176 RelayPool::connect(self, relay_urls).await
177 }
178
179 async fn disconnect(&self) -> Result<()> {
180 RelayPool::disconnect(self).await
181 }
182
183 async fn publish_event(&self, event: &Event) -> Result<EventId> {
184 RelayPool::publish_event(self, event).await
185 }
186
187 async fn publish(&self, builder: EventBuilder) -> Result<EventId> {
188 RelayPool::publish(self, builder).await
189 }
190
191 async fn sign(&self, builder: EventBuilder) -> Result<Event> {
192 RelayPool::sign(self, builder).await
193 }
194
195 async fn signer(&self) -> Result<Arc<dyn NostrSigner>> {
196 self.client
197 .signer()
198 .await
199 .map_err(|e| Error::Other(e.to_string()))
200 }
201
202 fn notifications(&self) -> tokio::sync::broadcast::Receiver<RelayPoolNotification> {
203 RelayPool::notifications(self)
204 }
205
206 async fn public_key(&self) -> Result<PublicKey> {
207 RelayPool::public_key(self).await
208 }
209
210 async fn subscribe(&self, filters: Vec<Filter>) -> Result<()> {
211 RelayPool::subscribe(self, filters).await
212 }
213
214 async fn publish_to(&self, urls: &[String], builder: EventBuilder) -> Result<EventId> {
215 RelayPool::publish_to(self, urls, builder).await
216 }
217
218 async fn fetch_events(&self, filters: Vec<Filter>, timeout: Duration) -> Result<Vec<Event>> {
219 RelayPool::fetch_events(self, filters, timeout).await
220 }
221}