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}