From 31473356affb8d33b489c298c322958f2bacc822 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Wed, 6 Sep 2023 17:49:45 +0300 Subject: [PATCH] convert from wallet to bech32 address or pubkey --- multiversx_sdk_cli/cli_wallet.py | 27 ++++++++++++++++++++- multiversx_sdk_cli/tests/test_cli_wallet.py | 22 +++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/multiversx_sdk_cli/cli_wallet.py b/multiversx_sdk_cli/cli_wallet.py index 523f8159..97b8a934 100644 --- a/multiversx_sdk_cli/cli_wallet.py +++ b/multiversx_sdk_cli/cli_wallet.py @@ -20,6 +20,9 @@ WALLET_FORMAT_KEYSTORE_MNEMONIC = "keystore-mnemonic" WALLET_FORMAT_KEYSTORE_SECRET_KEY = "keystore-secret-key" WALLET_FORMAT_PEM = "pem" +WALLET_FORMAT_BECH32_ADDRESS = "bech32_address" +WALLET_FORMAT_PUBLIC_KEY = "public_key" + WALLET_FORMATS = [ WALLET_FORMAT_RAW_MNEMONIC, WALLET_FORMAT_KEYSTORE_MNEMONIC, @@ -27,6 +30,10 @@ WALLET_FORMAT_PEM, ] +WALLET_FORMATS_AND_ADDRESSES: List[str] = [] +WALLET_FORMATS_AND_ADDRESSES.extend(WALLET_FORMATS) +WALLET_FORMATS_AND_ADDRESSES.extend([WALLET_FORMAT_BECH32_ADDRESS, WALLET_FORMAT_PUBLIC_KEY]) + def setup_parser(args: List[str], subparsers: Any) -> Any: parser = cli_shared.add_group_subparser( @@ -56,7 +63,7 @@ def setup_parser(args: List[str], subparsers: Any) -> Any: sub.add_argument("--infile", help="path to the input file") sub.add_argument("--outfile", help="path to the output file") sub.add_argument("--in-format", required=True, choices=WALLET_FORMATS, help="the format of the input file") - sub.add_argument("--out-format", required=True, choices=WALLET_FORMATS, help="the format of the output file") + sub.add_argument("--out-format", required=True, choices=WALLET_FORMATS_AND_ADDRESSES, help="the format of the output file") sub.add_argument("--address-index", help=f"the address index, if input format is {WALLET_FORMAT_RAW_MNEMONIC}, {WALLET_FORMAT_KEYSTORE_MNEMONIC} or {WALLET_FORMAT_PEM} (with multiple entries) and the output format is {WALLET_FORMAT_KEYSTORE_SECRET_KEY} or {WALLET_FORMAT_PEM}", type=int, default=0) sub.add_argument("--address-hrp", help=f"the human-readable part of the address, when the output format is {WALLET_FORMAT_KEYSTORE_SECRET_KEY} or {WALLET_FORMAT_PEM} (default: %(default)s)", type=str, default=DEFAULT_HRP) sub.set_defaults(func=convert_wallet) @@ -209,6 +216,24 @@ def _create_wallet_content( pem = UserPEM(address.bech32(), secret_key) return pem.to_text() + if out_format == WALLET_FORMAT_BECH32_ADDRESS: + if mnemonic: + secret_key = mnemonic.derive_key(address_index) + assert secret_key is not None + + pubkey = secret_key.generate_public_key() + address = pubkey.to_address(address_hrp) + return address.bech32() + + if out_format == WALLET_FORMAT_PUBLIC_KEY: + if mnemonic: + secret_key = mnemonic.derive_key(address_index) + assert secret_key is not None + + pubkey = secret_key.generate_public_key() + address = pubkey.to_address(address_hrp) + return address.hex() # type: ignore + raise KnownError(f"Cannot create wallet, unknown output format: <{out_format}>. Make sure to use one of following: {WALLET_FORMATS}.") diff --git a/multiversx_sdk_cli/tests/test_cli_wallet.py b/multiversx_sdk_cli/tests/test_cli_wallet.py index 86b29ba4..a73cc572 100644 --- a/multiversx_sdk_cli/tests/test_cli_wallet.py +++ b/multiversx_sdk_cli/tests/test_cli_wallet.py @@ -217,6 +217,28 @@ def test_wallet_bech32_decode(capsys: Any): assert out == "0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1" +def test_wallet_convert_pem_to_bech32_address(capsys: Any): + infile = testdata_path / "alice.pem" + + main([ + "wallet", "convert", "--infile", str(infile), "--in-format", "pem", "--out-format", "bech32_address" + ]) + + out = _read_stdout(capsys).strip("Output:\n\n") + assert out == "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" + + +def test_wallet_convert_pem_to_pubkey(capsys: Any): + infile = testdata_path / "alice.pem" + + main([ + "wallet", "convert", "--infile", str(infile), "--in-format", "pem", "--out-format", "public_key" + ]) + + out = _read_stdout(capsys).strip("Output:\n\n") + assert out == "0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1" + + def _read_stdout_mnemonic(capsys: Any) -> str: return _read_stdout(capsys).replace("Mnemonic:", "").strip()