from typing import List, Dict, Tuple def get_words_from_file(file_path) -> Tuple[dict, dict]: with open(file_path, "r") as words_file: lines_contents = words_file.read().splitlines() words = {index: word for index, word in enumerate(lines_contents)} indexes = {word: index for index, word in enumerate(lines_contents)} return words, indexes WORDS, INDEXES = get_words_from_file("bip39-english-words.txt") class MnemonicWord: def __init__(self, word: str): word = word.lstrip().rstrip().lower() if word not in WORDS.values(): raise ValueError(f"'{word}' is not a valid bip39 word.") self.word = word def as_int(self): return INDEXES[self.word] def as_binary(self): return bin(INDEXES[self.word]) class MnemonicPhrase: allowed_phrase_lengths = [12, 18, 24] def __init__(self, words: List[MnemonicWord]): if len(words) not in self.allowed_phrase_lengths: raise ValueError( f"The mnemonic phrase length should be one of {self.allowed_phrase_lengths}, but it was {len(words)}" ) self.words = {index: word for index, word in enumerate(words)} def __iter__(self): for index, word in self.words.items(): yield word def __getitem__(self, item): return self.words[item] def as_bin(self): binary_representation = "0b" + "".join( [word.as_binary()[2:] for word in self] ) return binary_representation def as_int(self): return int( self.as_bin(), base=2 ) class Seed: def __init__(self, seed_as_int: int): self._seed_as_int = seed_as_int @property def as_mnemonic(self) -> List[str]: return self._seed_as_mnemonic(self._seed) pass @property def as_integer(self) -> int: return self._seed_as_int @property def as_binary(self) -> str: return bin(self._seed_as_int) @property def as_hex(self) -> str: return hex(self._seed_as_int) @classmethod def from_mnemonic(cls, mnemonic_phrase: MnemonicPhrase): seed_as_int = mnemonic_phrase.as_int() return cls(seed_as_int) @classmethod def from_binary(cls, binary_seed_representation: str): return cls(int(binary_seed_representation, base=2)) @classmethod def from_integer(cls, int_seed_representation: int): return cls(int_seed_representation) @classmethod def from_hex(cls, hex_seed_representation: str): return cls(int(hex_seed_representation, base=16))