hashtree_resolver/nostr/
open.rs1use super::*;
2
3impl NostrRootResolver {
4 pub async fn resolve_open(&self, key: &str, window: Duration) -> Result<Cid, ResolverError> {
10 self.observe_roots(key, window, false).await
11 }
12
13 pub async fn resolve_ready(&self, key: &str, timeout: Duration) -> Result<Cid, ResolverError> {
17 self.observe_roots(key, timeout, true).await
18 }
19
20 async fn observe_roots(
21 &self,
22 key: &str,
23 window: Duration,
24 ready: bool,
25 ) -> Result<Cid, ResolverError> {
26 let (pubkey, tree_name) = Self::parse_key(key)?;
27 if self.config.relays.is_empty() {
28 return Err(ResolverError::Network(
29 "No active Nostr relays configured".into(),
30 ));
31 }
32 let filter = Self::build_tree_filter(pubkey, &tree_name);
33 let id = SubscriptionId::generate();
34 let mut notifications = self.client.notifications();
36 let mut latest: Option<(VerifiedEvent, Cid)> = None;
37 let observed: Result<Result<(), ResolverError>, _> = tokio::time::timeout(window, async {
38 self.client
39 .subscribe_with_id(id.clone(), filter, None)
40 .await
41 .map_err(|error| ResolverError::Network(error.to_string()))?;
42 loop {
43 let notification = notifications
44 .recv()
45 .await
46 .map_err(|error| ResolverError::Network(error.to_string()))?;
47 let RelayPoolNotification::Message {
50 message:
51 RelayMessage::Event {
52 subscription_id,
53 event,
54 },
55 ..
56 } = notification
57 else {
58 continue;
59 };
60 if subscription_id.as_ref() != &id {
61 continue;
62 }
63 let Ok(event) = VerifiedEvent::try_from(event.into_owned()) else {
64 continue;
65 };
66 if event.as_event().pubkey != pubkey || !is_matching_tree_event(&event, &tree_name)
67 {
68 continue;
69 }
70 let Some(cid) = self.cid_from_event(event.as_event()) else {
71 continue;
72 };
73 if latest.as_ref().is_none_or(|(current, _)| {
74 is_newer_event(event.as_event(), current.created_at(), Some(current.id()))
75 }) {
76 latest = Some((event, cid));
77 if ready {
78 return Ok(());
79 }
80 }
81 }
82 })
83 .await;
84 self.client.unsubscribe(&id).await;
85 if let Ok(result) = observed {
86 result?;
87 }
88 latest.map(|(_, cid)| cid).ok_or_else(|| {
89 ResolverError::Network(format!("Timed out waiting for a signed root for {key}"))
90 })
91 }
92}