Skip to main content

mesh_api/
identity.rs

1#[derive(Debug, Clone)]
2pub struct OwnerKeypair(mesh_client::OwnerKeypair);
3
4impl OwnerKeypair {
5    const ENCODED_HEX_LEN: usize = 64 * 2;
6
7    pub fn generate() -> Self {
8        Self(mesh_client::OwnerKeypair::generate())
9    }
10
11    pub fn owner_id(&self) -> String {
12        self.0.owner_id()
13    }
14
15    pub fn from_bytes(signing_bytes: &[u8], encryption_bytes: &[u8]) -> Result<Self, String> {
16        mesh_client::OwnerKeypair::from_bytes(signing_bytes, encryption_bytes)
17            .map(Self)
18            .map_err(|err| err.to_string())
19    }
20
21    pub fn from_hex(encoded: &str) -> Result<Self, String> {
22        if encoded.len() != Self::ENCODED_HEX_LEN {
23            return Err(format!(
24                "owner keypair hex must be {} characters",
25                Self::ENCODED_HEX_LEN
26            ));
27        }
28
29        let bytes = hex::decode(encoded).map_err(|err| err.to_string())?;
30        let (signing_bytes, encryption_bytes) = bytes.split_at(32);
31        Self::from_bytes(signing_bytes, encryption_bytes)
32    }
33
34    pub fn to_hex(&self) -> String {
35        let mut bytes = Vec::with_capacity(64);
36        bytes.extend_from_slice(self.signing_bytes());
37        bytes.extend_from_slice(&self.encryption_bytes());
38        hex::encode(bytes)
39    }
40
41    pub fn signing_bytes(&self) -> &[u8; 32] {
42        self.0.signing_bytes()
43    }
44
45    pub fn encryption_bytes(&self) -> [u8; 32] {
46        self.0.encryption_bytes()
47    }
48
49    pub(crate) fn into_inner(self) -> mesh_client::OwnerKeypair {
50        self.0
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::OwnerKeypair;
57
58    #[test]
59    fn owner_keypair_hex_roundtrip() {
60        let keypair = OwnerKeypair::generate();
61        let encoded = keypair.to_hex();
62        let restored = OwnerKeypair::from_hex(&encoded).expect("hex roundtrip");
63        assert_eq!(keypair.owner_id(), restored.owner_id());
64        assert_eq!(keypair.to_hex(), restored.to_hex());
65    }
66
67    #[test]
68    fn owner_keypair_hex_requires_full_key_material() {
69        let err = OwnerKeypair::from_hex("deadbeef").expect_err("short hex must fail");
70        assert!(err.contains("128"));
71    }
72}