contextvm_sdk/relay/
mod.rs1pub mod mock;
6pub use mock::MockRelayPool;
7
8use async_trait::async_trait;
9
10use crate::core::error::{Error, Result};
11use nostr_sdk::prelude::*;
12use std::sync::Arc;
13
14#[async_trait]
16pub trait RelayPoolTrait: Send + Sync {
17 async fn connect(&self, relay_urls: &[String]) -> Result<()>;
19 async fn disconnect(&self) -> Result<()>;
21 async fn publish_event(&self, event: &Event) -> Result<EventId>;
23 async fn publish(&self, builder: EventBuilder) -> Result<EventId>;
25 async fn sign(&self, builder: EventBuilder) -> Result<Event>;
27 async fn signer(&self) -> Result<Arc<dyn NostrSigner>>;
29 fn notifications(&self) -> tokio::sync::broadcast::Receiver<RelayPoolNotification>;
31 async fn public_key(&self) -> Result<PublicKey>;
33 async fn subscribe(&self, filters: Vec<Filter>) -> Result<()>;
35}
36
37pub struct RelayPool {
39 client: Arc<Client>,
40}
41
42impl RelayPool {
43 pub async fn new<T>(signer: T) -> Result<Self>
45 where
46 T: IntoNostrSigner,
47 {
48 let client = Client::builder().signer(signer).build();
49
50 Ok(Self {
51 client: Arc::new(client),
52 })
53 }
54
55 pub async fn connect(&self, relay_urls: &[String]) -> Result<()> {
57 for url in relay_urls {
58 self.client
59 .add_relay(url)
60 .await
61 .map_err(|e| Error::Transport(e.to_string()))?;
62 }
63
64 self.client.connect().await;
65
66 Ok(())
67 }
68
69 pub async fn disconnect(&self) -> Result<()> {
71 self.client.disconnect().await;
72 Ok(())
73 }
74
75 pub async fn publish_event(&self, event: &Event) -> Result<EventId> {
77 let output = self
78 .client
79 .send_event(event)
80 .await
81 .map_err(|e| Error::Transport(e.to_string()))?;
82 Ok(output.val)
83 }
84
85 pub async fn publish(&self, builder: EventBuilder) -> Result<EventId> {
87 let output = self
88 .client
89 .send_event_builder(builder)
90 .await
91 .map_err(|e| Error::Transport(e.to_string()))?;
92 Ok(output.val)
93 }
94
95 pub async fn sign(&self, builder: EventBuilder) -> Result<Event> {
97 self.client
98 .sign_event_builder(builder)
99 .await
100 .map_err(|e| Error::Transport(e.to_string()))
101 }
102
103 pub fn client(&self) -> &Arc<Client> {
105 &self.client
106 }
107
108 pub fn notifications(&self) -> tokio::sync::broadcast::Receiver<RelayPoolNotification> {
110 self.client.notifications()
111 }
112
113 pub async fn public_key(&self) -> Result<PublicKey> {
115 let signer = self
116 .client
117 .signer()
118 .await
119 .map_err(|e| Error::Other(e.to_string()))?;
120 signer
121 .get_public_key()
122 .await
123 .map_err(|e| Error::Other(e.to_string()))
124 }
125
126 pub async fn subscribe(&self, filters: Vec<Filter>) -> Result<()> {
128 for filter in filters {
129 self.client
130 .subscribe(filter, None)
131 .await
132 .map_err(|e| Error::Transport(e.to_string()))?;
133 }
134 Ok(())
135 }
136}
137
138#[async_trait]
139impl RelayPoolTrait for RelayPool {
140 async fn connect(&self, relay_urls: &[String]) -> Result<()> {
141 RelayPool::connect(self, relay_urls).await
142 }
143
144 async fn disconnect(&self) -> Result<()> {
145 RelayPool::disconnect(self).await
146 }
147
148 async fn publish_event(&self, event: &Event) -> Result<EventId> {
149 RelayPool::publish_event(self, event).await
150 }
151
152 async fn publish(&self, builder: EventBuilder) -> Result<EventId> {
153 RelayPool::publish(self, builder).await
154 }
155
156 async fn sign(&self, builder: EventBuilder) -> Result<Event> {
157 RelayPool::sign(self, builder).await
158 }
159
160 async fn signer(&self) -> Result<Arc<dyn NostrSigner>> {
161 self.client
162 .signer()
163 .await
164 .map_err(|e| Error::Other(e.to_string()))
165 }
166
167 fn notifications(&self) -> tokio::sync::broadcast::Receiver<RelayPoolNotification> {
168 RelayPool::notifications(self)
169 }
170
171 async fn public_key(&self) -> Result<PublicKey> {
172 RelayPool::public_key(self).await
173 }
174
175 async fn subscribe(&self, filters: Vec<Filter>) -> Result<()> {
176 RelayPool::subscribe(self, filters).await
177 }
178}