def test_str_from_bip32_path() -> None: der_path = "/44h/0h" assert str_from_bip32_path(der_path) == "m" + der_path m_fngrprnt = "deadbeef" assert str_from_bip32_path(der_path, m_fngrprnt) == m_fngrprnt + der_path err_msg = "invalid master fingerprint length: " with pytest.raises(BTClibValueError, match=err_msg): str_from_bip32_path(der_path, "baaaad")
def to_dict(self, check_validity: bool = True) -> Dict[str, str]: if check_validity: self.assert_valid() return { "master_fingerprint": self.master_fingerprint.hex(), "path": str_from_bip32_path(self.der_path), }
def encode_to_bip32_derivs( hd_key_paths: Mapping[bytes, BIP32KeyOrigin]) -> List[_BIP32Deriv]: "Return the json representation of the dataclass element." return [{ "pub_key": pub_key.hex(), "master_fingerprint": key_origin.master_fingerprint.hex(), "path": str_from_bip32_path(key_origin.der_path), } for pub_key, key_origin in sorted(hd_key_paths.items())]
def test_from_bip32_path_str() -> None: test_reg_str_vectors = [ # account 0, external branch, address_index 463 ("m/0" + _HARDENING + "/0/463", [0x80000000, 0, 463]), # account 0, internal branch, address_index 267 ("m/0" + _HARDENING + "/1/267", [0x80000000, 1, 267]), ] for bip32_path_str, bip32_path_ints in test_reg_str_vectors: # recover ints from str assert bip32_path_ints == _indexes_from_bip32_path_str(bip32_path_str) assert bip32_path_ints == indexes_from_bip32_path(bip32_path_str) # recover ints from ints assert bip32_path_ints == indexes_from_bip32_path(bip32_path_ints) # recover str from str assert bip32_path_str == str_from_bip32_path(bip32_path_str) # recover str from ints assert bip32_path_str == str_from_bip32_path(bip32_path_ints) # ensure bytes from ints == bytes from str bip32_path_bytes = bytes_from_bip32_path(bip32_path_ints) assert bip32_path_bytes == bytes_from_bip32_path(bip32_path_str) # recover ints from bytes assert bip32_path_ints == indexes_from_bip32_path(bip32_path_bytes) # recover str from bytes assert bip32_path_str == str_from_bip32_path(bip32_path_bytes) test_irregular_str_vectors = [ # account 0, external branch, address_index 463 ("m / 0 h / 0 / 463", [0x80000000, 0, 463]), ("m / 0 H / 0 / 463", [0x80000000, 0, 463]), ("m // 0' / 0 / 463", [0x80000000, 0, 463]), # account 0, internal branch, address_index 267 ("m / 0 h / 1 / 267", [0x80000000, 1, 267]), ("m / 0 H / 1 / 267", [0x80000000, 1, 267]), ("m // 0' / 1 / 267", [0x80000000, 1, 267]), ] for bip32_path_str, bip32_path_ints in test_irregular_str_vectors: # recover ints from str assert bip32_path_ints == _indexes_from_bip32_path_str(bip32_path_str) assert bip32_path_ints == indexes_from_bip32_path(bip32_path_str) # recover ints from ints assert bip32_path_ints == indexes_from_bip32_path(bip32_path_ints) # irregular str != normalized str assert bip32_path_str != str_from_bip32_path(bip32_path_str) # irregular str != normalized str from ints assert bip32_path_str != str_from_bip32_path(bip32_path_ints) # ensure bytes from ints == bytes from str bip32_path_bytes = bytes_from_bip32_path(bip32_path_ints) assert bip32_path_bytes == bytes_from_bip32_path(bip32_path_str) # recover ints from bytes assert bip32_path_ints == indexes_from_bip32_path(bip32_path_bytes) # irregular str != normalized str from bytes assert bip32_path_str != str_from_bip32_path(bip32_path_bytes) with pytest.raises(BTClibValueError, match="invalid index: "): _indexes_from_bip32_path_str("m/1/2/-3h/4") with pytest.raises(BTClibValueError, match="invalid index: "): _indexes_from_bip32_path_str("m/1/2/-3/4") i = 0x80000000 with pytest.raises(BTClibValueError, match="invalid index: "): _indexes_from_bip32_path_str(f"m/1/2/{i}/4") with pytest.raises(BTClibValueError, match="invalid index: "): _indexes_from_bip32_path_str(f"m/1/2/{i}h/4")
def description(self) -> str: return str_from_bip32_path(self.der_path, self.master_fingerprint)