coins_bip32/
primitives.rs

1use crate::Bip32Error;
2use coins_core::ser::ByteFormat;
3use std::io::{Read, Write};
4
5/// We treat the bip32 xpub bip49 ypub and bip84 zpub convention as a hint regarding address type.
6/// Downstream crates are free to follow or ignore these hints when generating addresses from
7/// extended keys.
8#[derive(Eq, PartialEq, Debug, Clone, Copy)]
9pub enum Hint {
10    /// Standard Bip32 hint
11    Legacy,
12    /// Bip32 + Bip49 hint for Witness-via-P2SH
13    Compatibility,
14    /// Bip32 + Bip84 hint for Native SegWit
15    SegWit,
16}
17
18/// A 4-byte key fingerprint
19#[derive(Eq, PartialEq, Clone, Copy, serde::Serialize, serde::Deserialize)]
20pub struct KeyFingerprint(pub [u8; 4]);
21
22impl From<[u8; 4]> for KeyFingerprint {
23    fn from(v: [u8; 4]) -> Self {
24        Self(v)
25    }
26}
27
28impl ByteFormat for KeyFingerprint {
29    type Error = Bip32Error;
30
31    fn serialized_length(&self) -> usize {
32        4
33    }
34
35    fn read_from<R>(reader: &mut R) -> Result<Self, Self::Error>
36    where
37        R: Read,
38        Self: std::marker::Sized,
39    {
40        let mut buf = [0u8; 4];
41        reader.read_exact(&mut buf)?;
42        Ok(Self(buf))
43    }
44
45    fn write_to<W>(&self, writer: &mut W) -> Result<usize, Self::Error>
46    where
47        W: Write,
48    {
49        Ok(writer.write(&self.0)?)
50    }
51}
52
53impl KeyFingerprint {
54    /// Determines if the slice represents the same key fingerprint
55    pub fn eq_slice(self, other: &[u8]) -> bool {
56        self.0 == other
57    }
58}
59
60impl std::fmt::Debug for KeyFingerprint {
61    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62        f.write_fmt(format_args!("KeyFingerprint {:x?}", self.0))
63    }
64}
65
66/// A 32-byte chain code
67#[derive(Eq, PartialEq, Debug, Clone, Copy)]
68pub struct ChainCode(pub [u8; 32]);
69
70impl From<[u8; 32]> for ChainCode {
71    fn from(v: [u8; 32]) -> Self {
72        Self(v)
73    }
74}
75
76/// Info associated with an extended key
77#[derive(Copy, Clone, Debug)]
78pub struct XKeyInfo {
79    /// The key depth in the HD tree
80    pub depth: u8,
81    /// The 4-byte Fingerprint of the parent
82    pub parent: KeyFingerprint,
83    /// The 4-byte derivation index of the key. If the most-significant byte is set, this key is
84    /// hardened
85    pub index: u32,
86    /// The 32-byte chain code used to generate child keys
87    pub chain_code: ChainCode,
88    /// The key's stanadard output type preference
89    pub hint: Hint,
90}
91
92impl PartialEq for XKeyInfo {
93    fn eq(&self, other: &XKeyInfo) -> bool {
94        self.depth == other.depth
95            && self.parent == other.parent
96            && self.index == other.index
97            && self.chain_code == other.chain_code
98    }
99}