def show_all_keys(): """ Prints all keys and mnemonics (if available). """ root_path = DEFAULT_ROOT_PATH config = load_config(root_path, "config.yaml") private_keys = keychain.get_all_private_keys() selected = config["selected_network"] prefix = config["network_overrides"]["config"][selected]["address_prefix"] if len(private_keys) == 0: print("There are no saved private keys") return print("Showing all private keys:") for sk, seed in private_keys: print("") print("Fingerprint:", sk.get_g1().get_fingerprint()) print("Master public key (m):", sk.get_g1()) print("Master private key (m):", bytes(sk).hex()) print( "Farmer public key (m/12381/8444/0/0)::", master_sk_to_farmer_sk(sk).get_g1(), ) print("Pool public key (m/12381/8444/1/0):", master_sk_to_pool_sk(sk).get_g1()) print( "First wallet key (m/12381/8444/2/0):", master_sk_to_wallet_sk(sk, uint32(0)).get_g1(), ) print( "First wallet address:", encode_puzzle_hash(create_puzzlehash_for_pk(master_sk_to_wallet_sk(sk, uint32(0)).get_g1()), prefix), ) assert seed is not None mnemonic = bytes_to_mnemonic(seed) print(" Mnemonic seed (24 secret words):") print(mnemonic)
def show_all_keys(show_mnemonic: bool): """ Prints all keys and mnemonics (if available). """ root_path = DEFAULT_ROOT_PATH config = load_config(root_path, "config.yaml") private_keys = keychain.get_all_private_keys() selected = config["selected_network"] prefix = config["network_overrides"]["config"][selected]["address_prefix"] if len(private_keys) == 0: print("There are no saved private keys") return None msg = "Showing all public keys derived from your private keys:" if show_mnemonic: msg = "Showing all public and private keys" print(msg) result_list = [] for sk, seed in private_keys: # print("") # print("Fingerprint:", sk.get_g1().get_fingerprint()) # print("Master public key (m):", sk.get_g1()) # print( # "Farmer public key (m/12381/8444/0/0):", # master_sk_to_farmer_sk(sk).get_g1(), # ) # print("Pool public key (m/12381/8444/1/0):", master_sk_to_pool_sk(sk).get_g1()) # print( # "First wallet address:", # encode_puzzle_hash(create_puzzlehash_for_pk(master_sk_to_wallet_sk(sk, uint32(0)).get_g1()), prefix), # ) # assert seed is not None # print("Master private key (m):", bytes(sk).hex()) # print( # "First wallet secret key (m/12381/8444/2/0):", # master_sk_to_wallet_sk(sk, uint32(0)).get_g1(), # ) mnemonic = bytes_to_mnemonic(seed) # print(" Mnemonic seed (24 secret words):") # print(mnemonic) data = { "fingerprint": sk.get_g1().get_fingerprint(), "mnemonic": ','.join(mnemonic.split()), "address": encode_puzzle_hash( create_puzzlehash_for_pk( master_sk_to_wallet_sk(sk, uint32(0)).get_g1()), prefix), "master": sk.get_g1(), "farmer": master_sk_to_farmer_sk(sk).get_g1(), "pool": master_sk_to_pool_sk(sk).get_g1(), } result_list.append(data) return result_list
def test_bip39_test_vectors_trezor(self): with open("tests/util/bip39_test_vectors.json") as f: all_vectors = json.loads(f.read()) for vector_list in all_vectors["english"]: entropy_bytes = bytes.fromhex(vector_list[0]) mnemonic = vector_list[1] seed = bytes.fromhex(vector_list[2]) assert bytes_from_mnemonic(mnemonic) == entropy_bytes assert bytes_to_mnemonic(entropy_bytes) == mnemonic assert mnemonic_to_seed(mnemonic, "TREZOR") == seed
async def get_private_key(self, request): fingerprint = request["fingerprint"] sk, seed = await self._get_private_key(fingerprint) if sk is not None: s = bytes_to_mnemonic(seed) if seed is not None else None return { "private_key": { "fingerprint": fingerprint, "sk": bytes(sk).hex(), "pk": bytes(sk.get_g1()).hex(), "seed": s, }, } return {"success": False, "private_key": {"fingerprint": fingerprint}}
async def get_key_for_fingerprint(self, fingerprint: Optional[int]) -> Optional[PrivateKey]: """ Locates and returns a private key matching the provided fingerprint """ key: Optional[PrivateKey] = None if self.use_local_keychain(): private_keys = self.keychain.get_all_private_keys() if len(private_keys) == 0: raise KeyringIsEmpty() else: if fingerprint is not None: for sk, _ in private_keys: if sk.get_g1().get_fingerprint() == fingerprint: key = sk break else: key = private_keys[0][0] else: response, success = await self.get_response_for_request( "get_key_for_fingerprint", {"fingerprint": fingerprint} ) if success: pk = response["data"].get("pk", None) ent = response["data"].get("entropy", None) if pk is None or ent is None: err = f"Missing pk and/or ent in {response.get('command')} response" self.log.error(f"{err}") raise MalformedKeychainResponse(f"{err}") else: mnemonic = bytes_to_mnemonic(bytes.fromhex(ent)) seed = mnemonic_to_seed(mnemonic, passphrase="") private_key = AugSchemeMPL.key_gen(seed) if bytes(private_key.get_g1()).hex() == pk: key = private_key else: err = "G1Elements don't match" self.log.error(f"{err}") else: self.handle_error(response) return key
async def get_first_private_key(self) -> Optional[PrivateKey]: """ Forwards to Keychain.get_first_private_key() """ key: Optional[PrivateKey] = None if self.use_local_keychain(): sk_ent = self.keychain.get_first_private_key() if sk_ent: key = sk_ent[0] else: response, success = await self.get_response_for_request("get_first_private_key", {}) if success: private_key = response["data"].get("private_key", None) if private_key is None: err = f"Missing private_key in {response.get('command')} response" self.log.error(f"{err}") raise MalformedKeychainResponse(f"{err}") else: pk = private_key.get("pk", None) ent_str = private_key.get("entropy", None) if pk is None or ent_str is None: err = f"Missing pk and/or ent in {response.get('command')} response" self.log.error(f"{err}") raise MalformedKeychainResponse(f"{err}") ent = bytes.fromhex(ent_str) mnemonic = bytes_to_mnemonic(ent) seed = mnemonic_to_seed(mnemonic, passphrase="") sk = AugSchemeMPL.key_gen(seed) if bytes(sk.get_g1()).hex() == pk: key = sk else: err = "G1Elements don't match" self.log.error(f"{err}") else: self.handle_error(response) return key
async def get_all_private_keys(self) -> List[Tuple[PrivateKey, bytes]]: """ Forwards to Keychain.get_all_private_keys() """ keys: List[Tuple[PrivateKey, bytes]] = [] if self.use_local_keychain(): keys = self.keychain.get_all_private_keys() else: response, success = await self.get_response_for_request("get_all_private_keys", {}) if success: private_keys = response["data"].get("private_keys", None) if private_keys is None: err = f"Missing private_keys in {response.get('command')} response" self.log.error(f"{err}") raise MalformedKeychainResponse(f"{err}") else: for key_dict in private_keys: pk = key_dict.get("pk", None) ent_str = key_dict.get("entropy", None) if pk is None or ent_str is None: err = f"Missing pk and/or ent in {response.get('command')} response" self.log.error(f"{err}") continue # We'll skip the incomplete key entry ent = bytes.fromhex(ent_str) mnemonic = bytes_to_mnemonic(ent) seed = mnemonic_to_seed(mnemonic, passphrase="") key = AugSchemeMPL.key_gen(seed) if bytes(key.get_g1()).hex() == pk: keys.append((key, ent)) else: err = "G1Elements don't match" self.log.error(f"{err}") else: self.handle_error(response) return keys
async def setup_wallet_node( port, consensus_constants: ConsensusConstants, local_bt, full_node_port=None, introducer_port=None, key_seed=None, starting_height=None, ): config = bt.config["wallet"] config["port"] = port config["rpc_port"] = port + 1000 if starting_height is not None: config["starting_height"] = starting_height config["initial_num_public_keys"] = 5 entropy = token_bytes(32) keychain = Keychain(entropy.hex(), True) if key_seed is None: key_seed = entropy keychain.add_private_key(bytes_to_mnemonic(key_seed), "") first_pk = keychain.get_first_public_key() assert first_pk is not None db_path_key_suffix = str(first_pk.get_fingerprint()) db_name = f"test-wallet-db-{port}-KEY.sqlite" db_path_replaced: str = db_name.replace("KEY", db_path_key_suffix) db_path = bt.root_path / db_path_replaced if db_path.exists(): db_path.unlink() config["database_path"] = str(db_name) config["testing"] = True config["introducer_peer"]["host"] = self_hostname if introducer_port is not None: config["introducer_peer"]["port"] = introducer_port config["peer_connect_interval"] = 10 else: config["introducer_peer"] = None if full_node_port is not None: config["full_node_peer"] = {} config["full_node_peer"]["host"] = self_hostname config["full_node_peer"]["port"] = full_node_port else: del config["full_node_peer"] kwargs = service_kwargs_for_wallet(local_bt.root_path, config, consensus_constants, keychain) kwargs.update( parse_cli_args=False, connect_to_daemon=False, ) service = Service(**kwargs) await service.start(new_wallet=True) yield service._node, service._node.server service.stop() await service.wait_closed() if db_path.exists(): db_path.unlink() keychain.delete_all_keys()
def test_basic_add_delete(self): kc: Keychain = Keychain(user="******", service="chia-testing-1.8.0") kc.delete_all_keys() assert kc._get_free_private_key_index() == 0 assert len(kc.get_all_private_keys()) == 0 assert kc.get_first_private_key() is None assert kc.get_first_public_key() is None mnemonic = generate_mnemonic() entropy = bytes_from_mnemonic(mnemonic) assert bytes_to_mnemonic(entropy) == mnemonic mnemonic_2 = generate_mnemonic() # misspelled words in the mnemonic bad_mnemonic = mnemonic.split(" ") bad_mnemonic[6] = "ZZZZZZ" self.assertRaisesRegex( ValueError, "'ZZZZZZ' is not in the mnemonic dictionary; may be misspelled", bytes_from_mnemonic, " ".join(bad_mnemonic), ) kc.add_private_key(mnemonic, "") assert kc._get_free_private_key_index() == 1 assert len(kc.get_all_private_keys()) == 1 kc.add_private_key(mnemonic_2, "") kc.add_private_key(mnemonic_2, "") # checks to not add duplicates assert kc._get_free_private_key_index() == 2 assert len(kc.get_all_private_keys()) == 2 assert kc._get_free_private_key_index() == 2 assert len(kc.get_all_private_keys()) == 2 assert len(kc.get_all_public_keys()) == 2 assert kc.get_all_private_keys()[0] == kc.get_first_private_key() assert kc.get_all_public_keys()[0] == kc.get_first_public_key() assert len(kc.get_all_private_keys()) == 2 seed_2 = mnemonic_to_seed(mnemonic, "") seed_key_2 = AugSchemeMPL.key_gen(seed_2) kc.delete_key_by_fingerprint(seed_key_2.get_g1().get_fingerprint()) assert kc._get_free_private_key_index() == 0 assert len(kc.get_all_private_keys()) == 1 kc.delete_all_keys() assert kc._get_free_private_key_index() == 0 assert len(kc.get_all_private_keys()) == 0 kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "my passphrase") kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "") kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "third passphrase") assert len(kc.get_all_public_keys()) == 3 assert len(kc.get_all_private_keys()) == 1 assert len(kc.get_all_private_keys(["my passphrase", ""])) == 2 assert len( kc.get_all_private_keys( ["my passphrase", "", "third passphrase", "another"])) == 3 assert len(kc.get_all_private_keys(["my passhrase wrong"])) == 0 assert kc.get_first_private_key() is not None assert kc.get_first_private_key(["bad passphrase"]) is None assert kc.get_first_public_key() is not None kc.delete_all_keys() kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "my passphrase") assert kc.get_first_public_key() is not None
def test_basic_add_delete(self): kc: Keychain = Keychain(testing=True) kc.delete_all_keys() assert kc._get_free_private_key_index() == 0 assert len(kc.get_all_private_keys()) == 0 assert kc.get_first_private_key() is None assert kc.get_first_public_key() is None mnemonic = generate_mnemonic() entropy = bytes_from_mnemonic(mnemonic) assert bytes_to_mnemonic(entropy) == mnemonic mnemonic_2 = generate_mnemonic() kc.add_private_key(mnemonic, "") assert kc._get_free_private_key_index() == 1 assert len(kc.get_all_private_keys()) == 1 kc.add_private_key(mnemonic_2, "") kc.add_private_key(mnemonic_2, "") # checks to not add duplicates assert kc._get_free_private_key_index() == 2 assert len(kc.get_all_private_keys()) == 2 assert kc._get_free_private_key_index() == 2 assert len(kc.get_all_private_keys()) == 2 assert len(kc.get_all_public_keys()) == 2 assert kc.get_all_private_keys()[0] == kc.get_first_private_key() assert kc.get_all_public_keys()[0] == kc.get_first_public_key() assert len(kc.get_all_private_keys()) == 2 seed_2 = mnemonic_to_seed(mnemonic, "") seed_key_2 = AugSchemeMPL.key_gen(seed_2) kc.delete_key_by_fingerprint(seed_key_2.get_g1().get_fingerprint()) assert kc._get_free_private_key_index() == 0 assert len(kc.get_all_private_keys()) == 1 kc.delete_all_keys() assert kc._get_free_private_key_index() == 0 assert len(kc.get_all_private_keys()) == 0 kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "my passphrase") kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "") kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "third passphrase") assert len(kc.get_all_public_keys()) == 3 assert len(kc.get_all_private_keys()) == 1 assert len(kc.get_all_private_keys(["my passphrase", ""])) == 2 assert len( kc.get_all_private_keys( ["my passphrase", "", "third passphrase", "another"])) == 3 assert len(kc.get_all_private_keys(["my passhrase wrong"])) == 0 assert kc.get_first_private_key() is not None assert kc.get_first_private_key(["bad passphrase"]) is None assert kc.get_first_public_key() is not None kc.delete_all_keys() kc.add_private_key(bytes_to_mnemonic(token_bytes(32)), "my passphrase") assert kc.get_first_public_key() is not None