crypto_wallet_gen/wallets/
monero.rs1use anyhow::{anyhow, Result};
2use failure::Fail;
3use wagyu_model::private_key::PrivateKey;
4use wagyu_monero::format::MoneroFormat;
5use wagyu_monero::network::mainnet::Mainnet;
6use wagyu_monero::private_key::MoneroPrivateKey;
7
8use super::Wallet;
9use crate::bip32::HDPrivKey;
10use crate::seed::Seed;
11
12pub struct MoneroWallet {
13 private_key: MoneroPrivateKey<Mainnet>,
14}
15
16impl MoneroWallet {
17 pub fn from_seed(seed: &Seed) -> Result<Self> {
18 Ok(Self {
19 private_key: MoneroPrivateKey::from_seed(
20 &hex::encode(seed.to_bytes()),
21 &MoneroFormat::Standard,
22 )
23 .map_err(|err| err.compat())?,
24 })
25 }
26
27 pub fn address(&self) -> Result<String> {
28 Ok(format!(
29 "{}",
30 self.private_key
31 .to_address(&MoneroFormat::Standard)
32 .map_err(|err| err.compat())?
33 ))
34 }
35
36 pub fn private_spend_key(&self) -> String {
37 hex::encode(self.private_key.to_private_spend_key())
38 }
39
40 pub fn public_spend_key(&self) -> Result<String> {
41 Ok(hex::encode(
42 self.private_key
43 .to_public_key()
44 .to_public_spend_key()
45 .ok_or_else(|| anyhow!("Couldn't calculate public spend key"))?,
46 ))
47 }
48
49 pub fn private_view_key(&self) -> String {
50 hex::encode(self.private_key.to_private_view_key())
51 }
52}
53
54impl Wallet for MoneroWallet {
55 fn from_hd_key(private_key: HDPrivKey) -> Result<Self> {
56 Self::from_seed(&private_key.key_part())
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn example1() {
66 let seed =
68 Seed::from_hex("177c328073abe1486ceb190ee4ef544896f2ff0fe6b1c83d28de2cc68d22b106")
69 .unwrap();
70 let wallet = MoneroWallet::from_seed(&seed).unwrap();
71 assert_eq!(
72 "177c328073abe1486ceb190ee4ef544896f2ff0fe6b1c83d28de2cc68d22b106",
73 wallet.private_spend_key(),
74 );
75 assert_eq!(
76 "946f666fd47ba8c0c0f564ec3aea442f4e5d121fe35e00c63056daa6ee93fb7a",
77 wallet.public_spend_key().unwrap(),
78 );
79 assert_eq!(
80 "08b6eeff17cc5a66054b83d6ad710d8894100a6c672925ecc49cf2521af4c206",
81 wallet.private_view_key(),
82 );
83 assert_eq!("47FMqqLkqTVZExG8eJg5hV8uvrUvffjQsa9gS59tLiVxMWtAZH4SULSMhDnPiZDe4bUtGRv3wq7wcER8HymBEeDyDoXyvPa", wallet.address().unwrap());
84 }
85
86 #[test]
87 fn example2() {
88 let seed =
90 Seed::from_hex("786dbcf5c283165f77445327ddaf44a05104d54eb4e5920da776d1a844b20703")
91 .unwrap();
92 let wallet = MoneroWallet::from_seed(&seed).unwrap();
93 assert_eq!(
94 "786dbcf5c283165f77445327ddaf44a05104d54eb4e5920da776d1a844b20703",
95 wallet.private_spend_key(),
96 );
97 assert_eq!(
98 "c98e3bcbb80566d7b1fa9d4d02b4d1e6644cc322f820868dc5e528e175262183",
99 wallet.public_spend_key().unwrap(),
100 );
101 assert_eq!(
102 "17b4eda6613ded666609fcc3a88d2a27336734fe50f6766f917cccf5715ff704",
103 wallet.private_view_key(),
104 );
105 assert_eq!("49G7fW8KGG5d5WoqvjGBUtfY6AUmRSfJmQiNojwGYgCYP36TtVKf4ZgNPf3V15Mf1oB3QT745Hmop2acHnWrC86tJJGhaEi", wallet.address().unwrap());
106 }
107
108 #[test]
109 fn regression1() {
110 let seed =
113 Seed::from_hex("6734c05d337c2f4883eb710bc02be1c30f1b2d46b2657c46cc833eecb7d7cb10")
114 .unwrap();
115 let wallet = MoneroWallet::from_seed(&seed).unwrap();
116 assert_eq!(
117 "7a60ca0019191df0ac4e7a68e13102af0f1b2d46b2657c46cc833eecb7d7cb00",
118 wallet.private_spend_key(),
119 );
120 assert_eq!(
121 "cb778d7f9fbe165be14a255640745eda8625276469e51659759caf6b3c048b1c",
122 wallet.public_spend_key().unwrap(),
123 );
124 assert_eq!(
125 "f5467d54c558a8a34b5f7bdd51a032fbe95a92e242133780adcd29df5d87da00",
126 wallet.private_view_key(),
127 );
128 assert_eq!("49LKLAixdiuGNMPJne3E7odYxUvgzhGA1FxsNV6zeAUr5nCUXyjUXLugNiMRMiCnZUAck57e5xHE58wiwmtfAfxrTwzkrkX", wallet.address().unwrap());
129 }
130}