Skip to main content

fips_core/endpoint/
nostr.rs

1use super::*;
2
3impl FipsEndpoint {
4    /// Snapshot signed machine-rating events for peers with enough local
5    /// health evidence. Event signing remains inside the FIPS node identity.
6    pub async fn peer_rating_events(
7        &self,
8        scope: impl Into<String>,
9    ) -> Result<Vec<nostr::Event>, FipsEndpointError> {
10        let (response_tx, response_rx) = oneshot::channel();
11        self.control(
12            "peer rating snapshot",
13            NodeEndpointControlCommand::PeerRatingEvents {
14                scope: scope.into(),
15                response_tx,
16            },
17            response_rx,
18        )
19        .await?
20        .map_err(FipsEndpointError::Node)
21    }
22
23    /// Feed a signed Nostr event received by an external adapter into FIPS.
24    ///
25    /// Public peer adverts and ratings enter their validated discovery caches;
26    /// targeted ephemeral relay datagrams enter the Nostr relay transport.
27    /// Unsupported, invalid, stale, or incorrectly addressed events return
28    /// `false`.
29    pub async fn ingest_nostr_event(&self, event: nostr::Event) -> Result<bool, FipsEndpointError> {
30        let (response_tx, response_rx) = oneshot::channel();
31        self.control(
32            "Nostr event ingest",
33            NodeEndpointControlCommand::IngestNostrEvent { event, response_tx },
34            response_rx,
35        )
36        .await
37    }
38
39    /// Compatibility name for callers that only feed discovery events.
40    pub async fn ingest_nostr_discovery_event(
41        &self,
42        event: nostr::Event,
43    ) -> Result<bool, FipsEndpointError> {
44        self.ingest_nostr_event(event).await
45    }
46
47    #[deprecated(since = "0.3.98", note = "use ingest_nostr_discovery_event")]
48    pub async fn ingest_nostr_pubsub_event(
49        &self,
50        event: nostr::Event,
51    ) -> Result<bool, FipsEndpointError> {
52        self.ingest_nostr_event(event).await
53    }
54
55    /// Drain signed ephemeral FIPS datagram events for the external relay
56    /// adapter. Relay selection remains outside FIPS.
57    pub async fn drain_nostr_relay_events(
58        &self,
59        limit: usize,
60    ) -> Result<Vec<nostr::Event>, FipsEndpointError> {
61        let (response_tx, response_rx) = oneshot::channel();
62        self.control(
63            "Nostr relay event drain",
64            NodeEndpointControlCommand::DrainNostrRelayEvents {
65                limit: limit.max(1),
66                response_tx,
67            },
68            response_rx,
69        )
70        .await
71    }
72
73    /// Snapshot the endpoint addresses this node is currently advertising via
74    /// Nostr discovery.
75    pub async fn local_advertised_endpoints(
76        &self,
77    ) -> Result<Vec<crate::discovery::nostr::OverlayEndpointAdvert>, FipsEndpointError> {
78        let (response_tx, response_rx) = oneshot::channel();
79        self.control(
80            "local advert snapshot",
81            NodeEndpointControlCommand::LocalAdvertSnapshot { response_tx },
82            response_rx,
83        )
84        .await
85    }
86
87    /// Return the signed local peer advert for an external peerfinding provider.
88    ///
89    /// This only creates the ordinary kind 37195 event; it does not select or
90    /// contact relays. `None` means advertising is disabled or no local
91    /// transport currently has an advert-eligible endpoint.
92    pub async fn local_nostr_discovery_advert_event(
93        &self,
94    ) -> Result<Option<nostr::Event>, FipsEndpointError> {
95        let (response_tx, response_rx) = oneshot::channel();
96        match self
97            .control(
98                "local Nostr discovery advert",
99                NodeEndpointControlCommand::LocalNostrDiscoveryAdvertEvent { response_tx },
100                response_rx,
101            )
102            .await?
103        {
104            Ok(event) => Ok(event),
105            Err(error) => Err(FipsEndpointError::Node(error)),
106        }
107    }
108
109    /// Snapshot live Nostr relay states used by the embedded endpoint.
110    pub async fn relay_statuses(&self) -> Result<Vec<FipsEndpointRelayStatus>, FipsEndpointError> {
111        let (response_tx, response_rx) = oneshot::channel();
112        self.control(
113            "relay snapshot",
114            NodeEndpointControlCommand::RelaySnapshot { response_tx },
115            response_rx,
116        )
117        .await
118        .map(|relays| {
119            relays
120                .into_iter()
121                .map(FipsEndpointRelayStatus::from)
122                .collect()
123        })
124    }
125
126    /// Replace Nostr discovery relays without rebuilding the endpoint.
127    pub async fn update_relays(&self, advert_relays: Vec<String>) -> Result<(), FipsEndpointError> {
128        let (response_tx, response_rx) = oneshot::channel();
129        self.control(
130            "relay update",
131            NodeEndpointControlCommand::UpdateRelays {
132                advert_relays,
133                response_tx,
134            },
135            response_rx,
136        )
137        .await?
138        .map_err(FipsEndpointError::Node)
139    }
140}