diff --git a/multiversx_sdk_cli/cli_wallet.py b/multiversx_sdk_cli/cli_wallet.py index 73489d7d..e9cd9a34 100644 --- a/multiversx_sdk_cli/cli_wallet.py +++ b/multiversx_sdk_cli/cli_wallet.py @@ -5,15 +5,15 @@ from pathlib import Path from typing import Any, List, Optional, Tuple -from multiversx_sdk_core import Address, MessageV1 -from multiversx_sdk_wallet import UserSecretKey, UserVerifier, UserWallet +from multiversx_sdk_core import Address +from multiversx_sdk_wallet import UserSecretKey, UserWallet from multiversx_sdk_wallet.mnemonic import Mnemonic from multiversx_sdk_wallet.user_pem import UserPEM from multiversx_sdk_cli import cli_shared, utils from multiversx_sdk_cli.constants import DEFAULT_HRP from multiversx_sdk_cli.errors import KnownError -from multiversx_sdk_cli.message import SignableMessage +from multiversx_sdk_cli.sign_verify import SignedMessage, sign_message from multiversx_sdk_cli.ux import show_critical_error, show_message logger = logging.getLogger("cli.wallet") @@ -88,15 +88,15 @@ def setup_parser(args: List[str], subparsers: Any) -> Any: ) sub.add_argument("--message", required=True, help="the message you want to sign") cli_shared.add_wallet_args(args, sub) - sub.set_defaults(func=sign_message) + sub.set_defaults(func=sign_user_message) sub = cli_shared.add_command_subparser( subparsers, "wallet", "verify-message", - "Verify a previously message" + "Verify a previously signed message" ) - sub.add_argument("--bech32-address", required=True, help="the bech32 address of the signer") + sub.add_argument("--address", required=True, help="the bech32 address of the signer") sub.add_argument("--message", required=True, help="the previously signed message(readable text, as it was signed)") sub.add_argument("--signature", required=True, help="the signature in hex format") sub.set_defaults(func=verify_signed_message) @@ -272,29 +272,21 @@ def do_bech32(args: Any): return result -def sign_message(args: Any): +def sign_user_message(args: Any): message: str = args.message account = cli_shared.prepare_account(args) - signable_message = SignableMessage(message, account) - signable_message.sign() - utils.dump_out_json(signable_message.to_dictionary()) + signed_message = sign_message(message, account) + utils.dump_out_json(signed_message.to_dictionary()) def verify_signed_message(args: Any): - bech32_address = args.bech32_address - verifier = UserVerifier.from_address(Address.from_bech32(bech32_address)) - + bech32_address = args.address message: str = args.message - verifiable_message = MessageV1.from_string(message) - signature: str = args.signature - if signature.startswith("0x"): - signature = signature[2:] - - verifiable_message.signature = bytes.fromhex(signature) - is_signed = verifier.verify(verifiable_message) + signed_message = SignedMessage(bech32_address, message, signature) + is_signed = signed_message.verify_signature() if is_signed: - show_message(f"""The message "{message}" was signed by {bech32_address}""") + show_message(f"""SUCCESS: The message "{message}" was signed by {bech32_address}""") else: - show_critical_error(f"""The message "{message}" was NOT signed by {bech32_address}""") + show_critical_error(f"""FAILED: The message "{message}" was NOT signed by {bech32_address}""") diff --git a/multiversx_sdk_cli/message.py b/multiversx_sdk_cli/message.py deleted file mode 100644 index 17000ac0..00000000 --- a/multiversx_sdk_cli/message.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Dict - -from multiversx_sdk_cli.accounts import Account - - -class SignableMessage: - def __init__(self, message: str, account: Account) -> None: - self.message = message - self.account = account - - def sign(self) -> None: - hex_signature = self.account.sign_message(self.message.encode()) - self.signature = bytes.fromhex(hex_signature) - - def to_dictionary(self) -> Dict[str, str]: - return { - "address": self.account.address.bech32(), - "message": self.message, - "signature": "0x" + self.signature.hex() - } diff --git a/multiversx_sdk_cli/sign_verify.py b/multiversx_sdk_cli/sign_verify.py new file mode 100644 index 00000000..6e893620 --- /dev/null +++ b/multiversx_sdk_cli/sign_verify.py @@ -0,0 +1,39 @@ +from typing import Dict + +from multiversx_sdk_core import Address, MessageV1 +from multiversx_sdk_wallet import UserVerifier + +from multiversx_sdk_cli.accounts import Account + + +class SignedMessage: + def __init__(self, address: str, message: str, signature: str) -> None: + self.address = address + self.message = message + + hex_prefixes = ["0x", "0X"] + signature_start_sequence = signature[0:2] + + if signature_start_sequence in hex_prefixes: + signature = signature[2:] + + self.signature = signature + + def verify_signature(self) -> bool: + verifier = UserVerifier.from_address(Address.from_bech32(self.address)) + verifiable_message = MessageV1.from_string(self.message) + verifiable_message.signature = bytes.fromhex(self.signature) + is_signed = verifier.verify(verifiable_message) + return is_signed + + def to_dictionary(self) -> Dict[str, str]: + return { + "address": self.address, + "message": self.message, + "signature": "0x" + self.signature + } + + +def sign_message(message: str, account: Account) -> SignedMessage: + signature = account.sign_message(message.encode()) + return SignedMessage(account.address.bech32(), message, signature) diff --git a/multiversx_sdk_cli/tests/test_cli_wallet.py b/multiversx_sdk_cli/tests/test_cli_wallet.py index 490b1b9f..aef3bf74 100644 --- a/multiversx_sdk_cli/tests/test_cli_wallet.py +++ b/multiversx_sdk_cli/tests/test_cli_wallet.py @@ -262,7 +262,7 @@ def test_verify_previously_signed_message(capsys: Any): return_code = main([ "wallet", "verify-message", - "--bech32-address", + "--address", address, "--message", message, @@ -272,7 +272,7 @@ def test_verify_previously_signed_message(capsys: Any): assert False if return_code else True out = _read_stdout(capsys) - text = """The message "test" was signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""".split() + text = """SUCCESS: The message "test" was signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""".split() assert all(word in out for word in text) @@ -284,7 +284,7 @@ def test_verify_not_signed_message(capsys: Any): return_code = main([ "wallet", "verify-message", - "--bech32-address", + "--address", address, "--message", message, @@ -294,7 +294,7 @@ def test_verify_not_signed_message(capsys: Any): assert False if return_code else True out = _read_stdout(capsys) - text = """The message "this message is not signed" was NOT signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""".split() + text = """FAILED: The message "this message is not signed" was NOT signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""".split() assert all(word in out for word in text)