From d21f8fb42a538d10009ada3d3ed4005a3451e83c Mon Sep 17 00:00:00 2001 From: Jeff Cruikshank Date: Thu, 5 May 2022 17:02:19 -0700 Subject: [PATCH 1/2] Support searching derived addresses on testnet. --- chia/cmds/keys.py | 4 ++++ chia/cmds/keys_funcs.py | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/chia/cmds/keys.py b/chia/cmds/keys.py index 227ffabb8297..d7d109468770 100644 --- a/chia/cmds/keys.py +++ b/chia/cmds/keys.py @@ -215,6 +215,7 @@ def derive_cmd(ctx: click.Context, fingerprint: Optional[int], filename: Optiona "non-observer derivation should be used at that index. Example HD path: m/12381n/8444n/2/", type=str, ) +@click.option("--prefix", "-x", help="Address prefix (xch for mainnet, txch for testnet)", default=None, type=str) @click.pass_context def search_cmd( ctx: click.Context, @@ -224,6 +225,7 @@ def search_cmd( show_progress: bool, search_type: Tuple[str, ...], derive_from_hd_path: Optional[str], + prefix: Optional[str], ): import sys from .keys_funcs import search_derive, resolve_derivation_master_key @@ -238,6 +240,7 @@ def search_cmd( private_key = resolve_derivation_master_key(filename if filename is not None else fingerprint) found: bool = search_derive( + ctx.obj["root_path"], private_key, search_terms, limit, @@ -245,6 +248,7 @@ def search_cmd( show_progress, ("all",) if "all" in search_type else search_type, derive_from_hd_path, + prefix, ) sys.exit(0 if found else 1) diff --git a/chia/cmds/keys_funcs.py b/chia/cmds/keys_funcs.py index 1d9af0580756..0e59f6f6e699 100644 --- a/chia/cmds/keys_funcs.py +++ b/chia/cmds/keys_funcs.py @@ -245,6 +245,7 @@ def _search_derived( search_public_key: bool, search_private_key: bool, search_address: bool, + prefix: str, ) -> List[str]: # Return a subset of search_terms that were found """ Performs a shallow search of keys derived from the current sk for items matching @@ -291,7 +292,7 @@ class DerivedSearchResultType(Enum): if search_address: # Generate a wallet address using the standard p2_delegated_puzzle_or_hidden_puzzle puzzle # TODO: consider generating addresses using other puzzles - address = encode_puzzle_hash(create_puzzlehash_for_pk(child_pk), "xch") + address = encode_puzzle_hash(create_puzzlehash_for_pk(child_pk), prefix) for term in remaining_search_terms: found_item: Any = None @@ -344,6 +345,7 @@ class DerivedSearchResultType(Enum): def search_derive( + root_path: Path, private_key: Optional[PrivateKey], search_terms: Tuple[str, ...], limit: int, @@ -351,6 +353,7 @@ def search_derive( show_progress: bool, search_types: Tuple[str, ...], derive_from_hd_path: Optional[str], + prefix: Optional[str], ) -> bool: """ Searches for items derived from the provided private key, or if not specified, @@ -366,6 +369,11 @@ def search_derive( search_public_key = "public_key" in search_types search_private_key = "private_key" in search_types + if prefix is None: + config: Dict = load_config(root_path, "config.yaml") + selected: str = config["selected_network"] + prefix = config["network_overrides"]["config"][selected]["address_prefix"] + if "all" in search_types: search_address = True search_public_key = True @@ -402,6 +410,7 @@ def search_derive( search_public_key, search_private_key, search_address, + prefix, ) # Update remaining_search_terms @@ -447,6 +456,7 @@ def search_derive( search_public_key, search_private_key, search_address, + prefix, ) # Update remaining_search_terms From 6413ddb0cd169adee6488621ad54dfc77423129d Mon Sep 17 00:00:00 2001 From: Jeff Cruikshank Date: Thu, 5 May 2022 17:17:56 -0700 Subject: [PATCH 2/2] Added tests --- tests/core/cmds/test_keys.py | 110 +++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/tests/core/cmds/test_keys.py b/tests/core/cmds/test_keys.py index a874541df431..573a46b99975 100644 --- a/tests/core/cmds/test_keys.py +++ b/tests/core/cmds/test_keys.py @@ -608,6 +608,56 @@ def test_derive_search_wallet_address(self, tmp_path, keyring_with_one_key): != -1 ) + def test_derive_search_wallet_testnet_address(self, tmp_path, keyring_with_one_key): + """ + Test the `chia keys derive search` command, searching for a testnet wallet address + """ + + keychain = keyring_with_one_key + keys_root_path = keychain.keyring_wrapper.keys_root_path + + runner = CliRunner() + init_result: Result = runner.invoke( + cli, ["--root-path", os.fspath(tmp_path), "--keys-root-path", os.fspath(keys_root_path), "init"] + ) + + assert init_result.exit_code == 0 + assert len(keychain.get_all_private_keys()) == 1 + + runner = CliRunner() + result: Result = runner.invoke( + cli, + [ + "--root-path", + os.fspath(tmp_path), + "--keys-root-path", + os.fspath(keys_root_path), + "keys", + "derive", + "--fingerprint", + str(TEST_FINGERPRINT), + "search", + "--limit", + "40", + "--search-type", + "address", + "txch1mnr0ygu7lvmk3nfgzmncfk39fwu0dv933yrcv97nd6pmrt7fzmhs2v6lg7", + "--prefix", + "txch", + ], + ) + + assert result.exit_code == 0 + assert ( + result.output.find( + ( + "Found wallet address: " + "txch1mnr0ygu7lvmk3nfgzmncfk39fwu0dv933yrcv97nd6pmrt7fzmhs2v6lg7 (HD path: m/12381/8444/2/30)" + ) + ) + != -1 + ) + def test_derive_search_failure(self, tmp_path, keyring_with_one_key): """ Test the `chia keys derive search` command with a failing search. @@ -755,6 +805,66 @@ def test_derive_wallet_address(self, tmp_path, keyring_with_one_key): != -1 ) + def test_derive_wallet_testnet_address(self, tmp_path, keyring_with_one_key): + """ + Test the `chia keys derive wallet-address` command, generating a couple of testnet wallet addresses. + """ + + keychain = keyring_with_one_key + keys_root_path = keychain.keyring_wrapper.keys_root_path + + runner = CliRunner() + init_result: Result = runner.invoke( + cli, ["--root-path", os.fspath(tmp_path), "--keys-root-path", os.fspath(keys_root_path), "init"] + ) + + assert init_result.exit_code == 0 + assert len(keychain.get_all_private_keys()) == 1 + + runner = CliRunner() + result: Result = runner.invoke( + cli, + [ + "--root-path", + os.fspath(tmp_path), + "--keys-root-path", + os.fspath(keys_root_path), + "keys", + "derive", + "--fingerprint", + str(TEST_FINGERPRINT), + "wallet-address", + "--index", + "50", + "--count", + "2", + "--non-observer-derivation", + "--show-hd-path", + "--prefix", + "txch", + ], + ) + + assert result.exit_code == 0 + assert ( + result.output.find( + ( + "Wallet address 50 (m/12381n/8444n/2n/50n): " + "txch1jp2u7an0mn9hdlw2x05nmje49gwgzmqyvh0qmh6008yksetuvkfshfylvn" + ) + ) + != -1 + ) + assert ( + result.output.find( + ( + "Wallet address 51 (m/12381n/8444n/2n/51n): " + "txch1006n6l3x5e8exar8mlj004znjl5pq0tq73h76kz0yergswnjzn8s3utl6c" + ) + ) + != -1 + ) + def test_derive_child_keys(self, tmp_path, keyring_with_one_key): """ Test the `chia keys derive child-keys` command, generating a couple of derived keys.