2020-02-18 16:03:52 +00:00
|
|
|
from typing import List
|
|
|
|
|
|
|
|
from .mnemonic import get_seed
|
|
|
|
from .tree import (
|
|
|
|
derive_master_SK,
|
|
|
|
derive_child_SK,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def path_to_nodes(path: str) -> List[int]:
|
|
|
|
"""
|
2020-08-24 14:01:48 +00:00
|
|
|
Maps from a path string to a list of indices where each index represents the corresponding level in the path.
|
2020-02-18 16:03:52 +00:00
|
|
|
"""
|
|
|
|
path = path.replace(' ', '')
|
2020-09-14 13:16:33 +00:00
|
|
|
if not set(path).issubset(set('m1234567890/')):
|
|
|
|
raise ValueError(f"Invalid path {path}")
|
|
|
|
|
2020-02-18 16:03:52 +00:00
|
|
|
indices = path.split('/')
|
2020-09-14 13:16:33 +00:00
|
|
|
|
|
|
|
if indices[0] != 'm':
|
|
|
|
raise ValueError(f"The first character of path should be `m`. Got {indices[0]}.")
|
|
|
|
indices.pop(0)
|
|
|
|
|
2020-02-18 16:03:52 +00:00
|
|
|
return [int(index) for index in indices]
|
|
|
|
|
|
|
|
|
2020-05-26 09:32:20 +00:00
|
|
|
def mnemonic_and_path_to_key(*, mnemonic: str, path: str, password: str) -> int:
|
2020-02-18 16:03:52 +00:00
|
|
|
"""
|
2020-08-24 14:32:54 +00:00
|
|
|
Return the SK at position `path`, derived from `mnemonic`. The password is to be
|
|
|
|
compliant with BIP39 mnemonics that use passwords, but is not used by this CLI outside of tests.
|
2020-02-18 16:03:52 +00:00
|
|
|
"""
|
2020-02-28 12:02:29 +00:00
|
|
|
seed = get_seed(mnemonic=mnemonic, password=password)
|
2020-02-18 16:03:52 +00:00
|
|
|
sk = derive_master_SK(seed)
|
|
|
|
for node in path_to_nodes(path):
|
|
|
|
sk = derive_child_SK(parent_SK=sk, index=node)
|
2020-02-18 16:44:32 +00:00
|
|
|
return sk
|