Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support searching derived addresses on testnet. #11449

Merged
merged 2 commits into from
May 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions chia/cmds/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand All @@ -238,13 +240,15 @@ 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,
non_observer_derivation,
show_progress,
("all",) if "all" in search_type else search_type,
derive_from_hd_path,
prefix,
)

sys.exit(0 if found else 1)
Expand Down
12 changes: 11 additions & 1 deletion chia/cmds/keys_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -344,13 +345,15 @@ class DerivedSearchResultType(Enum):


def search_derive(
root_path: Path,
private_key: Optional[PrivateKey],
search_terms: Tuple[str, ...],
limit: int,
non_observer_derivation: bool,
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,
Expand All @@ -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
Expand Down Expand Up @@ -402,6 +410,7 @@ def search_derive(
search_public_key,
search_private_key,
search_address,
prefix,
)

# Update remaining_search_terms
Expand Down Expand Up @@ -447,6 +456,7 @@ def search_derive(
search_public_key,
search_private_key,
search_address,
prefix,
)

# Update remaining_search_terms
Expand Down
110 changes: 110 additions & 0 deletions tests/core/cmds/test_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down