iroh_node_util/rpc/client/
net.rs

1//! API to manage the iroh networking stack.
2//!
3//! The main entry point is the [`Client`].
4//!
5//! The client can be used to get information about the node, such as the
6//! [node id](Client::node_id) or [node address](Client::node_addr).
7//!
8//! It can also be used to provide additional information to the node, e.g.
9//! using the [add_node_addr](Client::add_node_addr) method.
10use std::net::SocketAddr;
11
12use anyhow::Result;
13use futures_lite::{Stream, StreamExt};
14use iroh::{endpoint::RemoteInfo, NodeAddr, NodeId, RelayUrl};
15use quic_rpc::RpcClient;
16use serde::{Deserialize, Serialize};
17
18use super::flatten;
19use crate::rpc::proto::{
20    net::{
21        AddAddrRequest, AddrRequest, IdRequest, RelayRequest, RemoteInfoRequest,
22        RemoteInfoResponse, RemoteInfosIterRequest,
23    },
24    RpcService,
25};
26
27/// Iroh net Client.
28///
29/// Cheaply clonable and threadsafe. Use the iroh `net::Client` to access the
30/// iroh net methods from a different thread, process, or remote machine.
31///
32/// The `node::Client` api allows you to get information *about* the iroh node,
33/// its status, and connection status to other nodes. It also allows you to
34/// provide address information about *other* nodes to your node.
35#[derive(Debug, Clone)]
36#[repr(transparent)]
37pub struct Client {
38    pub(super) rpc: RpcClient<RpcService>,
39}
40
41impl Client {
42    /// Creates a new net client
43    pub fn new(rpc: RpcClient<RpcService>) -> Self {
44        Self { rpc }
45    }
46
47    /// Fetches information about currently known remote nodes.
48    ///
49    /// This streams a *current snapshot*. It does not keep the stream open after finishing
50    /// transferring the snapshot.
51    ///
52    /// See also [`Endpoint::remote_info_iter`](iroh::Endpoint::remote_info_iter).
53    pub async fn remote_info_iter(&self) -> Result<impl Stream<Item = Result<RemoteInfo>>> {
54        let stream = self.rpc.server_streaming(RemoteInfosIterRequest {}).await?;
55        Ok(flatten(stream).map(|res| res.map(|res| res.info)))
56    }
57
58    /// Fetches node information about a remote iroh node identified by its [`NodeId`].
59    ///
60    /// See also [`Endpoint::remote_info`](iroh::Endpoint::remote_info).
61    pub async fn remote_info(&self, node_id: NodeId) -> Result<Option<RemoteInfo>> {
62        let RemoteInfoResponse { info } = self.rpc.rpc(RemoteInfoRequest { node_id }).await??;
63        Ok(info)
64    }
65
66    /// Fetches the node id of this node.
67    ///
68    /// See also [`Endpoint::node_id`](iroh::Endpoint::node_id).
69    pub async fn node_id(&self) -> Result<NodeId> {
70        let id = self.rpc.rpc(IdRequest).await??;
71        Ok(id)
72    }
73
74    /// Fetches the [`NodeAddr`] for this node.
75    ///
76    /// See also [`Endpoint::node_addr`](iroh::Endpoint::node_addr).
77    pub async fn node_addr(&self) -> Result<NodeAddr> {
78        let addr = self.rpc.rpc(AddrRequest).await??;
79        Ok(addr)
80    }
81
82    /// Adds a known node address to this node.
83    ///
84    /// See also [`Endpoint::add_node_addr`](iroh::Endpoint::add_node_addr).
85    pub async fn add_node_addr(&self, addr: NodeAddr) -> Result<()> {
86        self.rpc.rpc(AddAddrRequest { addr }).await??;
87        Ok(())
88    }
89
90    /// Returns the relay server we are connected to.
91    ///
92    /// See also [`Endpoint::home_relay`](iroh::Endpoint::home_relay).
93    pub async fn home_relay(&self) -> Result<Option<RelayUrl>> {
94        let relay = self.rpc.rpc(RelayRequest).await??;
95        Ok(relay)
96    }
97}
98
99/// The response to a version request
100#[derive(Debug, Serialize, Deserialize)]
101pub struct NodeStatus {
102    /// The node id and socket addresses of this node.
103    pub addr: NodeAddr,
104    /// The bound listening addresses of the node
105    pub listen_addrs: Vec<SocketAddr>,
106    /// The version of the node
107    pub version: String,
108    /// RPC address, if currently listening.
109    pub rpc_addr: Option<SocketAddr>,
110}