@@ -87,7 +87,7 @@ impl fmt::Debug for Error {
8787}
8888
8989impl error:: Error for Error {
90- fn cause ( & self ) -> Option < & error:: Error > {
90+ fn cause ( & self ) -> Option < & dyn error:: Error > {
9191 None
9292 }
9393
@@ -162,7 +162,7 @@ impl Mnemonic {
162162 }
163163
164164 /// Generate a new Mnemonic in the given language.
165- /// For the different supported word counts, see documentation on [Mnemonoc ].
165+ /// For the different supported word counts, see documentation on [Mnemonic ].
166166 #[ cfg( feature = "rand" ) ]
167167 pub fn generate_in ( language : Language , word_count : usize ) -> Result < Mnemonic , Error > {
168168 if word_count < 6 || word_count % 6 != 0 || word_count > 24 {
@@ -177,7 +177,7 @@ impl Mnemonic {
177177 }
178178
179179 /// Generate a new Mnemonic in English.
180- /// For the different supported word counts, see documentation on [Mnemonoc ].
180+ /// For the different supported word counts, see documentation on [Mnemonic ].
181181 #[ cfg( feature = "rand" ) ]
182182 pub fn generate ( word_count : usize ) -> Result < Mnemonic , Error > {
183183 Mnemonic :: generate_in ( Language :: English , word_count)
@@ -349,6 +349,26 @@ impl Mnemonic {
349349 entropy. truncate ( entropy_bytes) ;
350350 entropy
351351 }
352+
353+ /// Calculates the final word (based on the checksum) of a manually generated mnemonic.
354+ /// There are multiple valid checksums, the first one (alphabetically) is picked.
355+ pub fn finalize_mnemonic < ' a , S : Into < Cow < ' a , str > > > ( s : S ) -> Result < Mnemonic , Error > {
356+ let mut cow = s. into ( ) ;
357+ Mnemonic :: normalize_utf8_cow ( & mut cow) ;
358+ let language = Self :: language_of ( & cow) ?;
359+
360+ for word in language. word_list ( ) {
361+ let mnemonic = format ! ( "{} {}" , cow, word) ;
362+ match Self :: validate_in ( language, & mnemonic) {
363+ Ok ( ( ) ) => return Ok ( Mnemonic ( mnemonic) ) ,
364+ Err ( e) => match e {
365+ Error :: InvalidChecksum => { } ,
366+ _ => return Err ( e)
367+ }
368+ }
369+ }
370+ Err ( Error :: InvalidChecksum )
371+ }
352372}
353373
354374impl fmt:: Display for Mnemonic {
@@ -519,7 +539,7 @@ mod tests {
519539 let entropy = Vec :: < u8 > :: from_hex ( & vector. 0 ) . unwrap ( ) ;
520540 let mnemonic_str = vector. 1 ;
521541 let seed = Vec :: < u8 > :: from_hex ( & vector. 2 ) . unwrap ( ) ;
522-
542+
523543 let mnemonic = Mnemonic :: from_entropy ( & entropy) . unwrap ( ) ;
524544
525545 assert_eq ! ( & mnemonic. to_string( ) , mnemonic_str,
@@ -760,4 +780,26 @@ mod tests {
760780 "failed vector: {}" , mnemonic_str) ;
761781 }
762782 }
783+
784+ #[ test]
785+ fn test_finalize_mnemonic ( ) {
786+ let vectors = [
787+ (
788+ "ozone drill grab fiber curtain grace pudding thank cruise elder eight" ,
789+ "about"
790+ ) ,
791+ (
792+ "light rule cinnamon wrap drastic word pride squirrel upgrade then income fatal apart sustain crack supply proud" ,
793+ "access"
794+ ) ,
795+ (
796+ "hamster diagram private dutch cause delay private meat slide toddler razor book happy fancy gospel tennis maple dilemma loan word shrug inflict delay" ,
797+ "balance"
798+ ) ,
799+ ] ;
800+
801+ for vector in & vectors {
802+ assert_eq ! ( format!( "{} {}" , vector. 0 , vector. 1 ) , Mnemonic :: finalize_mnemonic( vector. 0 ) . unwrap( ) . 0 ) ;
803+ }
804+ }
763805}
0 commit comments