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