penumbra_sdk_keys/keys/
bip44.rs1const PENUMBRA_COIN_TYPE: u32 = 6532;
4
5pub struct Bip44Path {
12 purpose: u32,
13 coin_type: u32,
14 account: u32,
15 change: Option<u32>,
16 address_index: Option<u32>,
17}
18
19impl Bip44Path {
20 pub fn new(account: u32) -> Self {
22 Self {
23 purpose: 44,
24 coin_type: PENUMBRA_COIN_TYPE,
25 account,
26 change: None,
27 address_index: None,
28 }
29 }
30
31 pub fn new_generic(
33 purpose: u32,
34 coin_type: u32,
35 account: u32,
36 change: Option<u32>,
37 address_index: Option<u32>,
38 ) -> Self {
39 Self {
40 purpose,
41 coin_type,
42 account,
43 change,
44 address_index,
45 }
46 }
47
48 pub fn purpose(&self) -> u32 {
50 self.purpose
51 }
52
53 pub fn coin_type(&self) -> u32 {
55 self.coin_type
56 }
57
58 pub fn account(&self) -> u32 {
60 self.account
61 }
62
63 pub fn change(&self) -> Option<u32> {
65 self.change
66 }
67
68 pub fn address_index(&self) -> Option<u32> {
70 self.address_index
71 }
72
73 pub fn path(&self) -> String {
74 let mut path = format!("m/44'/{}'/{}'", self.coin_type(), self.account());
75 if self.change().is_some() {
76 path = format!("{}/{}", path, self.change().expect("change will exist"));
77 }
78 if self.address_index().is_some() {
79 path = format!(
80 "{}/{}",
81 path,
82 self.address_index().expect("address index will exist")
83 );
84 }
85 path
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn test_bip44_path_full() {
95 let path = Bip44Path::new_generic(44, 6532, 0, Some(0), Some(0));
96 assert_eq!(path.path(), "m/44'/6532'/0'/0/0");
97 }
98
99 #[test]
100 fn test_bip44_path_account_level() {
101 let path = Bip44Path::new(0);
102 assert_eq!(path.path(), "m/44'/6532'/0'");
103 }
104}