diff --git a/multiversx_sdk_cli/cli_shared.py b/multiversx_sdk_cli/cli_shared.py index 75fa665d..d6f87eb9 100644 --- a/multiversx_sdk_cli/cli_shared.py +++ b/multiversx_sdk_cli/cli_shared.py @@ -100,7 +100,7 @@ def add_guardian_args(sub: Any): def add_wallet_args(args: List[str], sub: Any): sub.add_argument("--pem", required=check_if_sign_method_required(args, "--pem"), help="🔑 the PEM file, if keyfile not provided") - sub.add_argument("--pem-index", default=0, help="🔑 the index in the PEM file (default: %(default)s)") + sub.add_argument("--pem-index", type=int, default=0, help="🔑 the index in the PEM file (default: %(default)s)") sub.add_argument("--keyfile", required=check_if_sign_method_required(args, "--keyfile"), help="🔑 a JSON keyfile, if PEM not provided") sub.add_argument("--passfile", help="🔑 a file containing keyfile's password, if keyfile provided") sub.add_argument("--ledger", action="store_true", required=check_if_sign_method_required(args, "--ledger"), default=False, help="🔐 bool flag for signing transaction using ledger") @@ -111,7 +111,7 @@ def add_wallet_args(args: List[str], sub: Any): def add_guardian_wallet_args(args: List[str], sub: Any): sub.add_argument("--guardian-pem", required=check_if_sign_method_required(args, "--guardian-pem"), help="🔑 the PEM file, if keyfile not provided") - sub.add_argument("--guardian-pem-index", default=0, help="🔑 the index in the PEM file (default: %(default)s)") + sub.add_argument("--guardian-pem-index", type=int, default=0, help="🔑 the index in the PEM file (default: %(default)s)") sub.add_argument("--guardian-keyfile", required=check_if_sign_method_required(args, "--guardian-keyfile"), help="🔑 a JSON keyfile, if PEM not provided") sub.add_argument("--guardian-passfile", help="🔑 a file containing keyfile's password, if keyfile provided") sub.add_argument("--guardian-ledger", action="store_true", required=check_if_sign_method_required(args, "--guardian-ledger"), default=False, help="🔐 bool flag for signing transaction using ledger") diff --git a/multiversx_sdk_cli/tests/test_cli_validators.sh b/multiversx_sdk_cli/tests/test_cli_validators.sh index 69db881c..dad1eb52 100755 --- a/multiversx_sdk_cli/tests/test_cli_validators.sh +++ b/multiversx_sdk_cli/tests/test_cli_validators.sh @@ -9,7 +9,7 @@ testAll() { echo "Stake with recall nonce" ${CLI} --verbose validator stake --pem="${USERS}/alice.pem" --value="2500${DENOMINATION}" --validators-file=./testdata/validators.json --reward-address=${REWARD_ADDRESS} --chain=${CHAIN_ID} --proxy=${PROXY} --estimate-gas --recall-nonce --send || return 1 echo "Stake with provided nonce" - ${CLI} --verbose validator stake --pem="${USERS}/bob.pem" --value="2500${DENOMINATION}" --validators-file=./testdata/validators.json --reward-address=${REWARD_ADDRESS} --chain=${CHAIN_ID} --proxy=${PROXY} --estimate-gas --nonce=5000 --send || return 1 + ${CLI} --verbose validator stake --pem="${USERS}/bob.pem" --value="2500${DENOMINATION}" --validators-file=./testdata/validators.json --reward-address=${REWARD_ADDRESS} --chain=${CHAIN_ID} --proxy=${PROXY} --estimate-gas --nonce=300 --send || return 1 echo "Stake with topUP" diff --git a/multiversx_sdk_cli/tests/test_cli_wallet.py b/multiversx_sdk_cli/tests/test_cli_wallet.py index aef3bf74..2e495382 100644 --- a/multiversx_sdk_cli/tests/test_cli_wallet.py +++ b/multiversx_sdk_cli/tests/test_cli_wallet.py @@ -298,6 +298,74 @@ def test_verify_not_signed_message(capsys: Any): assert all(word in out for word in text) +def test_sign_and_verify_message_with_multi_address_pem(capsys: Any): + multi_address_pem_path = testdata_path / "multiple_addresses.pem" + message = "test" + + return_code = main(["wallet", "sign-message", "--message", message, "--pem", str(multi_address_pem_path), "--pem-index", "0"]) + out = json.loads(_read_stdout(capsys)) + + assert False if return_code else True + assert out == { + "address": "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", + "message": "test", + "signature": "0x7aff43cd6e3d880a65033bf0a1b16274854fd7dfa9fe5faa7fa9a665ee851afd4c449310f5f1697d348e42d1819eaef69080e33e7652d7393521ed50d7427a0e" + } + + return_code = main(["wallet", "verify-message", + "--address", "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", + "--message", message, + "--signature", "0x7aff43cd6e3d880a65033bf0a1b16274854fd7dfa9fe5faa7fa9a665ee851afd4c449310f5f1697d348e42d1819eaef69080e33e7652d7393521ed50d7427a0e" + ]) + assert False if return_code else True + + out = _read_stdout(capsys) + text = """SUCCESS: The message "test" was signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""".split() + assert all(word in out for word in text) + + return_code = main(["wallet", "sign-message", "--message", message, "--pem", str(multi_address_pem_path), "--pem-index", "1"]) + out = json.loads(_read_stdout(capsys)) + + assert False if return_code else True + assert out == { + "address": "erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx", + "message": "test", + "signature": "0x50024bd755f8801e4ffbe76f93e6b8d82220673981cc44952a52bbfa02d262020ce933a2216e0e16e838dc5691f5701a1e0c250279cdae29268344d1523ea805" + } + + return_code = main(["wallet", "verify-message", + "--address", "erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx", + "--message", message, + "--signature", "0x50024bd755f8801e4ffbe76f93e6b8d82220673981cc44952a52bbfa02d262020ce933a2216e0e16e838dc5691f5701a1e0c250279cdae29268344d1523ea805" + ]) + assert False if return_code else True + + out = _read_stdout(capsys) + text = """SUCCESS: The message "test" was signed by erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx""".split() + assert all(word in out for word in text) + + return_code = main(["wallet", "sign-message", "--message", message, "--pem", str(multi_address_pem_path), "--pem-index", "2"]) + out = json.loads(_read_stdout(capsys)) + + assert False if return_code else True + assert out == { + "address": "erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8", + "message": "test", + "signature": "0x99dd1ebf2bf47a7cb99f362d2458b5c83c727686517c97c877babeb8be7f840c543785edf2f9688a1fc2c076b0887d8ee6d2be7b181bba4dc3984a4ee406fa0f" + } + + return_code = main(["wallet", "verify-message", + "--address", "erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8", + "--message", message, + "--signature", "0x99dd1ebf2bf47a7cb99f362d2458b5c83c727686517c97c877babeb8be7f840c543785edf2f9688a1fc2c076b0887d8ee6d2be7b181bba4dc3984a4ee406fa0f" + ]) + assert False if return_code else True + + out = _read_stdout(capsys) + text = """SUCCESS: The message "test" was signed by erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8""".split() + assert all(word in out for word in text) + + def _read_stdout_mnemonic(capsys: Any) -> str: return _read_stdout(capsys).replace("Mnemonic:", "").strip() diff --git a/multiversx_sdk_cli/tests/testdata/multiple_addresses.pem b/multiversx_sdk_cli/tests/testdata/multiple_addresses.pem new file mode 100644 index 00000000..c8e708ef --- /dev/null +++ b/multiversx_sdk_cli/tests/testdata/multiple_addresses.pem @@ -0,0 +1,15 @@ +-----BEGIN PRIVATE KEY for erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th----- +NDEzZjQyNTc1ZjdmMjZmYWQzMzE3YTc3ODc3MTIxMmZkYjgwMjQ1ODUwOTgxZTQ4 +YjU4YTRmMjVlMzQ0ZThmOTAxMzk0NzJlZmY2ODg2NzcxYTk4MmYzMDgzZGE1ZDQy +MWYyNGMyOTE4MWU2Mzg4ODIyOGRjODFjYTYwZDY5ZTE= +-----END PRIVATE KEY for erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th----- +-----BEGIN PRIVATE KEY for erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx----- +YjhjYTZmODIwM2ZiNGI1NDVhOGU4M2M1Mzg0ZGEwMzNjNDE1ZGIxNTViNTNmYjVi +OGViYTdmZjVhMDM5ZDYzOTgwNDlkNjM5ZTVhNjk4MGQxY2QyMzkyYWJjY2U0MTAy +OWNkYTc0YTE1NjM1MjNhMjAyZjA5NjQxY2MyNjE4Zjg= +-----END PRIVATE KEY for erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx----- +-----BEGIN PRIVATE KEY for erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8----- +ZTI1M2E1NzFjYTE1M2RjMmFlZTg0NTgxOWY3NGJjYzk3NzNiMDU4NmVkZWFkMTVh +OTRjYjcyMzVhNTAyNzQzNmIyYTExNTU1Y2U1MjFlNDk0NGUwOWFiMTc1NDlkODVi +NDg3ZGNkMjZjODRiNTAxN2EzOWUzMWEzNjcwODg5YmE= +-----END PRIVATE KEY for erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8-----