fork
Configure Feed
Select the types of activity you want to include in your feed.
Live video on the AT Protocol
fork
Configure Feed
Select the types of activity you want to include in your feed.
1use iroh_base::ticket::NodeTicket;
2use std::{str::FromStr, sync::Arc};
3
4use crate::public_key::PublicKey;
5
6/// A peer and it's addressing information.
7#[derive(Debug, Clone, PartialEq, Eq, uniffi::Object)]
8pub struct NodeAddr {
9 node_id: Arc<PublicKey>,
10 relay_url: Option<String>,
11 addresses: Vec<String>,
12}
13
14#[uniffi::export]
15impl NodeAddr {
16 /// Create a new [`NodeAddr`] with empty [`AddrInfo`].
17 #[uniffi::constructor]
18 pub fn new(node_id: &PublicKey, derp_url: Option<String>, addresses: Vec<String>) -> Self {
19 Self {
20 node_id: Arc::new(node_id.clone()),
21 relay_url: derp_url,
22 addresses,
23 }
24 }
25
26 pub fn node_id(&self) -> PublicKey {
27 self.node_id.as_ref().clone()
28 }
29
30 /// Get the direct addresses of this peer.
31 pub fn direct_addresses(&self) -> Vec<String> {
32 self.addresses.clone()
33 }
34
35 /// Get the home relay URL for this peer
36 pub fn relay_url(&self) -> Option<String> {
37 self.relay_url.clone()
38 }
39
40 /// Returns true if both NodeAddr's have the same values
41 pub fn equal(&self, other: &NodeAddr) -> bool {
42 self == other
43 }
44}
45
46/// Error when converting from ffi NodeAddr to iroh::NodeAddr
47#[derive(Debug, snafu::Snafu, uniffi::Error)]
48#[uniffi(flat_error)]
49#[snafu(visibility(pub(crate)))]
50pub enum NodeAddrError {
51 #[snafu(display("Invalid URL"), context(false))]
52 InvalidUrl { source: url::ParseError },
53 #[snafu(display("Invalid network address"), context(false))]
54 InvalidNetworkAddress { source: std::net::AddrParseError },
55}
56
57impl TryFrom<NodeAddr> for iroh::NodeAddr {
58 type Error = NodeAddrError;
59
60 fn try_from(value: NodeAddr) -> Result<Self, Self::Error> {
61 let mut node_addr = iroh::NodeAddr::new((&*value.node_id).into());
62 let addresses = value
63 .direct_addresses()
64 .into_iter()
65 .map(|addr| std::net::SocketAddr::from_str(&addr))
66 .collect::<Result<Vec<_>, _>>()?;
67
68 if let Some(derp_url) = value.relay_url() {
69 let url = url::Url::parse(&derp_url)?;
70
71 node_addr = node_addr.with_relay_url(url.into());
72 }
73 node_addr = node_addr.with_direct_addresses(addresses);
74 Ok(node_addr)
75 }
76}
77
78impl From<iroh::NodeAddr> for NodeAddr {
79 fn from(value: iroh::NodeAddr) -> Self {
80 NodeAddr {
81 node_id: Arc::new(value.node_id.into()),
82 relay_url: value.relay_url.map(|url| url.to_string()),
83 addresses: value
84 .direct_addresses
85 .into_iter()
86 .map(|d| d.to_string())
87 .collect(),
88 }
89 }
90}
91
92/// Error when converting from ffi NodeAddr to iroh::NodeAddr
93#[derive(Debug, snafu::Snafu, uniffi::Error)]
94#[uniffi(flat_error)]
95pub enum TicketError {
96 ParseError { message: String },
97}
98
99/// Get this node's ticket.
100#[uniffi::export]
101pub fn node_id_from_ticket(
102 ticket_str: String,
103) -> Result<Arc<crate::public_key::PublicKey>, TicketError> {
104 let ticket = NodeTicket::from_str(&ticket_str).map_err(|e| TicketError::ParseError {
105 message: e.to_string(),
106 })?;
107 let node_addr = ticket.node_addr();
108 Ok(Arc::new(node_addr.node_id.into()))
109}