zoe_app_primitives/
relay.rs

1use std::net::SocketAddr;
2
3use serde::{Deserialize, Serialize};
4use zoe_wire_protocol::Ed25519VerifyingKey;
5
6use crate::Metadata;
7
8/// Relay endpoint information for group participants
9///
10/// Contains the network address and public key needed to connect to a relay server.
11/// Multiple relay endpoints can be provided to a group participant for redundancy,
12/// with the list order indicating priority preference.
13#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
14pub struct RelayEndpoint {
15    /// Network address of the relay server
16    ///
17    /// This is the socket address (IP:port) where the relay server
18    /// can be reached for QUIC connections.
19    pub address: SocketAddr,
20
21    /// Ed25519 public key of the relay server
22    ///
23    /// Used to verify the relay server's identity during the QUIC TLS handshake.
24    /// This prevents man-in-the-middle attacks and ensures the client is
25    /// connecting to the correct relay server.
26    pub public_key: Ed25519VerifyingKey,
27
28    /// Optional human-readable name for the relay
29    ///
30    /// Can be used for display purposes or debugging. Examples:
31    /// "Primary Relay", "EU West", "Backup Server", etc.
32    pub name: Option<String>,
33
34    /// Additional relay metadata
35    ///
36    /// Can store information like geographic region, performance metrics,
37    /// supported features, or other relay-specific data.
38    pub metadata: Vec<Metadata>,
39}
40
41impl RelayEndpoint {
42    /// Create a new relay endpoint with minimal required fields
43    pub fn new(address: SocketAddr, public_key: Ed25519VerifyingKey) -> Self {
44        Self {
45            address,
46            public_key,
47            name: None,
48            metadata: Vec::new(),
49        }
50    }
51
52    /// Set a human-readable name for this relay
53    pub fn with_name(mut self, name: String) -> Self {
54        self.name = Some(name);
55        self
56    }
57
58    /// Add metadata to this relay endpoint
59    pub fn with_metadata(mut self, metadata: Metadata) -> Self {
60        self.metadata.push(metadata);
61        self
62    }
63
64    /// Get the relay's display name (name if set, otherwise address)
65    pub fn display_name(&self) -> String {
66        self.name
67            .clone()
68            .unwrap_or_else(|| self.address.to_string())
69    }
70}