Live video on the AT Protocol
at next 109 lines 3.2 kB view raw
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}