1use crate::address::{Address, AddressError};
2use crate::extended_private_key::{ExtendedPrivateKey, ExtendedPrivateKeyError};
3use crate::extended_public_key::ExtendedPublicKey;
4use crate::format::Format;
5use crate::private_key::{PrivateKey, PrivateKeyError};
6use crate::public_key::PublicKey;
7use crate::wordlist::WordlistError;
8
9use rand::Rng;
10use std::{
11 fmt::{Debug, Display},
12 str::FromStr,
13};
14
15pub trait Mnemonic: Clone + Debug + Display + FromStr + Send + Sync + 'static + Eq + Sized {
17 type Address: Address;
18 type Format: Format;
19 type PrivateKey: PrivateKey;
20 type PublicKey: PublicKey;
21
22 fn new<R: Rng>(rng: &mut R) -> Result<Self, MnemonicError>;
24
25 fn from_phrase(phrase: &str) -> Result<Self, MnemonicError>;
27
28 fn to_phrase(&self) -> Result<String, MnemonicError>;
30
31 fn to_private_key(&self, password: Option<&str>) -> Result<Self::PrivateKey, MnemonicError>;
33
34 fn to_public_key(&self, password: Option<&str>) -> Result<Self::PublicKey, MnemonicError>;
36
37 fn to_address(&self, password: Option<&str>, format: &Self::Format) -> Result<Self::Address, MnemonicError>;
39}
40
41pub trait MnemonicCount: Mnemonic {
43 fn new_with_count<R: Rng>(rng: &mut R, word_count: u8) -> Result<Self, MnemonicError>;
45}
46
47pub trait MnemonicExtended: Mnemonic {
49 type ExtendedPrivateKey: ExtendedPrivateKey;
50 type ExtendedPublicKey: ExtendedPublicKey;
51
52 fn to_extended_private_key(&self, password: Option<&str>) -> Result<Self::ExtendedPrivateKey, MnemonicError>;
54
55 fn to_extended_public_key(&self, password: Option<&str>) -> Result<Self::ExtendedPublicKey, MnemonicError>;
57}
58
59#[derive(Debug, Fail)]
60pub enum MnemonicError {
61 #[fail(display = "{}", _0)]
62 AddressError(AddressError),
63
64 #[fail(display = "{}: {}", _0, _1)]
65 Crate(&'static str, String),
66
67 #[fail(display = "{}", _0)]
68 ExtendedPrivateKeyError(ExtendedPrivateKeyError),
69
70 #[fail(display = "Invalid checksum word: {{ expected: {:?}, found: {:?} }}", _0, _1)]
71 InvalidChecksumWord(String, String),
72
73 #[fail(display = "Invalid decoding from word to seed")]
74 InvalidDecoding,
75
76 #[fail(display = "Invalid entropy length: {}", _0)]
77 InvalidEntropyLength(usize),
78
79 #[fail(display = "Invalid wordlist index: {}", _0)]
80 InvalidIndex(usize),
81
82 #[fail(display = "Invalid phrase: {}", _0)]
83 InvalidPhrase(String),
84
85 #[fail(display = "Invalid word not found in monero: {}", _0)]
86 InvalidWord(String),
87
88 #[fail(display = "Invalid mnemonic word count: {}", _0)]
89 InvalidWordCount(u8),
90
91 #[fail(display = "Missing the last word (checksum)")]
92 MissingChecksumWord,
93
94 #[fail(display = "Missing word(s) in mnemonic")]
95 MissingWord,
96
97 #[fail(display = "{}", _0)]
98 PrivateKeyError(PrivateKeyError),
99
100 #[fail(display = "{}", _0)]
101 WordlistError(WordlistError),
102}
103
104impl From<AddressError> for MnemonicError {
105 fn from(error: AddressError) -> Self {
106 MnemonicError::AddressError(error)
107 }
108}
109
110impl From<ExtendedPrivateKeyError> for MnemonicError {
111 fn from(error: ExtendedPrivateKeyError) -> Self {
112 MnemonicError::ExtendedPrivateKeyError(error)
113 }
114}
115
116impl From<PrivateKeyError> for MnemonicError {
117 fn from(error: PrivateKeyError) -> Self {
118 MnemonicError::PrivateKeyError(error)
119 }
120}
121
122impl From<WordlistError> for MnemonicError {
123 fn from(error: WordlistError) -> Self {
124 MnemonicError::WordlistError(error)
125 }
126}
127
128impl From<rand_core::Error> for MnemonicError {
129 fn from(error: rand_core::Error) -> Self {
130 MnemonicError::Crate("rand", format!("{:?}", error))
131 }
132}
133
134impl From<std::io::Error> for MnemonicError {
135 fn from(error: std::io::Error) -> Self {
136 MnemonicError::Crate("std::io", format!("{:?}", error))
137 }
138}