100 lines
2.6 KiB
Python
100 lines
2.6 KiB
Python
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))
|