From 3f3e08189b778ce267420403a1d3bc9dcca83c7e Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 14 Mar 2025 14:06:53 +0200 Subject: [PATCH 1/5] wip: improve guardian flow --- multiversx_sdk_cli/cli_shared.py | 79 +++++++++++++++------ multiversx_sdk_cli/cli_transactions.py | 1 - multiversx_sdk_cli/guardian_relayer_data.py | 16 +++++ multiversx_sdk_cli/interfaces.py | 24 +------ requirements.txt | 1 - 5 files changed, 74 insertions(+), 47 deletions(-) create mode 100644 multiversx_sdk_cli/guardian_relayer_data.py diff --git a/multiversx_sdk_cli/cli_shared.py b/multiversx_sdk_cli/cli_shared.py index 890c36b2..29a2b1e9 100644 --- a/multiversx_sdk_cli/cli_shared.py +++ b/multiversx_sdk_cli/cli_shared.py @@ -22,6 +22,7 @@ ) from multiversx_sdk_cli.constants import DEFAULT_GAS_PRICE, DEFAULT_TX_VERSION from multiversx_sdk_cli.errors import ArgumentsNotProvidedError, IncorrectWalletError +from multiversx_sdk_cli.guardian_relayer_data import GuardianRelayerData from multiversx_sdk_cli.interfaces import IAccount from multiversx_sdk_cli.simulation import Simulator from multiversx_sdk_cli.transactions import send_and_wait_for_result @@ -118,28 +119,10 @@ def add_tx_args( default=DEFAULT_TX_VERSION, help="the transaction version (default: %(default)s)", ) + sub.add_argument("--options", type=int, default=0, help="the transaction options (default: %(default)s)") - sub.add_argument("--relayer", help="the bech32 address of the relayer") - - add_guardian_args(sub) - - sub.add_argument("--options", type=int, default=0, help="the transaction options (default: 0)") - - -def add_guardian_args(sub: Any): - sub.add_argument("--guardian", type=str, help="the address of the guradian", default="") - sub.add_argument( - "--guardian-service-url", - type=str, - help="the url of the guardian service", - default="", - ) - sub.add_argument( - "--guardian-2fa-code", - type=str, - help="the 2fa code for the guardian", - default="", - ) + sub.add_argument("--relayer", type=str, help="the bech32 address of the relayer", default="") + sub.add_argument("--guardian", type=str, help="the bech32 address of the guradian", default="") def add_wallet_args(args: list[str], sub: Any): @@ -174,6 +157,18 @@ def add_wallet_args(args: list[str], sub: Any): def add_guardian_wallet_args(args: list[str], sub: Any): + sub.add_argument( + "--guardian-service-url", + type=str, + help="the url of the guardian service", + default="", + ) + sub.add_argument( + "--guardian-2fa-code", + type=str, + help="the 2fa code for the guardian", + default="", + ) sub.add_argument( "--guardian-pem", help="🔑 the PEM file, if keyfile not provided", @@ -313,6 +308,33 @@ def get_guardian_address(guardian: Union[IAccount, None], args: Any) -> Union[Ad return address_from_account or address_from_args +# check if account is guarded, api/proxy agnostic +# check if guardian is active +# get guardian address +# get guardian service (if TCS have the url ready) + +# def fetch_guardian_address_from_the_network(address: str, proxy_url: str) -> Address: +# network_provider_config = config.get_config_for_network_providers() +# proxy = ProxyNetworkProvider(url=proxy_url, config=network_provider_config) +# return proxy.get_account(Address.new_from_bech32(address)).address + + +def fetch_guardian_info(address: str, proxy_url: str) -> Union[tuple[Address, str], None]: + network_provider_config = config.get_config_for_network_providers() + proxy = ProxyNetworkProvider(url=proxy_url, config=network_provider_config) + + response = proxy.do_get_generic(f"/address/{address}/guardian-data").to_dictionary() + guardian_data = response.get("guardianData", {}) + + if not bool(guardian_data.get("guarded", "")): + return None + + guardian_address = Address.new_from_bech32(guardian_data.get("address", "")) + service_url = guardian_data.get("serviceUID", "") + + return None + + def get_relayer_address(relayer: Union[IAccount, None], args: Any) -> Union[Address, None]: address_from_account = relayer.address if relayer else None address_from_args = Address.new_from_bech32(args.relayer) if hasattr(args, "relayer") and args.relayer else None @@ -445,7 +467,7 @@ def prepare_sender(args: Any): return sender -def prepare_guardian(args: Any): +def prepare_guardian(args: Any) -> tuple[Union[IAccount, None], Union[Address, None]]: """Reurns a tuple containing the guardians's account and the account's address. If no account or address were provided, will return (None, None).""" guardian = load_guardian_account(args) @@ -453,9 +475,20 @@ def prepare_guardian(args: Any): return guardian, guardian_address -def prepare_relayer(args: Any): +def prepare_relayer(args: Any) -> tuple[Union[IAccount, None], Union[Address, None]]: """Reurns a tuple containing the relayer's account and the account's address. If no account or address were provided, will return (None, None).""" relayer = load_relayer_account(args) relayer_address = get_relayer_address(relayer, args) return relayer, relayer_address + + +def prepare_guardian_relayer_data(args: Any) -> GuardianRelayerData: + guardian, guardian_address = prepare_guardian(args) + relayer, relayer_address = prepare_relayer(args) + return GuardianRelayerData( + guardian=guardian, + guardian_address=guardian_address, + relayer=relayer, + relayer_address=relayer_address, + ) diff --git a/multiversx_sdk_cli/cli_transactions.py b/multiversx_sdk_cli/cli_transactions.py index 9dfe4819..3333d6db 100644 --- a/multiversx_sdk_cli/cli_transactions.py +++ b/multiversx_sdk_cli/cli_transactions.py @@ -86,7 +86,6 @@ def setup_parser(args: list[str], subparsers: Any) -> Any: cli_shared.add_outfile_arg(sub, what="the signed transaction") cli_shared.add_broadcast_args(sub) cli_shared.add_proxy_arg(sub) - cli_shared.add_guardian_args(sub) cli_shared.add_guardian_wallet_args(args, sub) cli_shared.add_relayed_v3_wallet_args(args, sub) sub.set_defaults(func=sign_transaction) diff --git a/multiversx_sdk_cli/guardian_relayer_data.py b/multiversx_sdk_cli/guardian_relayer_data.py new file mode 100644 index 00000000..a47268f6 --- /dev/null +++ b/multiversx_sdk_cli/guardian_relayer_data.py @@ -0,0 +1,16 @@ +from dataclasses import dataclass +from typing import Optional + +from multiversx_sdk import Address + +from multiversx_sdk_cli.interfaces import IAccount + + +@dataclass +class GuardianRelayerData: + guardian: Optional[IAccount] = None + guardian_address: Optional[Address] = None + guardian_service_url: Optional[str] = None + guardian_2fa_code: Optional[str] = None + relayer: Optional[IAccount] = None + relayer_address: Optional[Address] = None diff --git a/multiversx_sdk_cli/interfaces.py b/multiversx_sdk_cli/interfaces.py index b6d70e18..8a533e7c 100644 --- a/multiversx_sdk_cli/interfaces.py +++ b/multiversx_sdk_cli/interfaces.py @@ -1,29 +1,9 @@ -from typing import Any, Dict, Protocol +from typing import Any, Protocol from multiversx_sdk import Address, Transaction # fmt: off -class ITransaction(Protocol): - sender: str - receiver: str - gas_limit: int - chain_id: str - nonce: int - value: int - sender_username: str - receiver_username: str - gas_price: int - data: bytes - version: int - options: int - guardian: str - signature: bytes - guardian_signature: bytes - relayer: str - relayer_signature: bytes - - class IAccount(Protocol): address: Address @@ -32,5 +12,5 @@ def sign_transaction(self, transaction: Transaction) -> bytes: class ISimulateResponse(Protocol): - def to_dictionary(self) -> Dict[str, Any]: + def to_dictionary(self) -> dict[str, Any]: ... diff --git a/requirements.txt b/requirements.txt index 540ea6d4..04388f50 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,6 @@ types-toml requests>=2.32.0,<3.0.0 types-requests prettytable -types-prettytable ledgercomm[hid] rich==13.3.4 argcomplete==3.2.2 From da14733db2e13183a593436771a24fe6af40913e Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 17 Mar 2025 16:43:47 +0200 Subject: [PATCH 2/5] automatic fetching for guardian from the network --- .../base_transactions_controller.py | 20 +- multiversx_sdk_cli/cli_delegation.py | 234 +++++------ multiversx_sdk_cli/cli_shared.py | 118 +++++- multiversx_sdk_cli/cli_transactions.py | 17 +- multiversx_sdk_cli/cli_validators.py | 163 +++----- multiversx_sdk_cli/constants.py | 4 + .../delegation/staking_provider.py | 379 ++++++++---------- multiversx_sdk_cli/dns.py | 17 +- .../tests/test_cli_validators.py | 6 +- multiversx_sdk_cli/tests/test_transactions.py | 35 +- multiversx_sdk_cli/transactions.py | 28 +- multiversx_sdk_cli/validators.py | 274 ++++++------- 12 files changed, 600 insertions(+), 695 deletions(-) diff --git a/multiversx_sdk_cli/base_transactions_controller.py b/multiversx_sdk_cli/base_transactions_controller.py index 596e26b4..858d81ca 100644 --- a/multiversx_sdk_cli/base_transactions_controller.py +++ b/multiversx_sdk_cli/base_transactions_controller.py @@ -2,6 +2,10 @@ from multiversx_sdk import LedgerAccount, Transaction, TransactionComputer +from multiversx_sdk_cli.constants import ( + EXTRA_GAS_LIMIT_FOR_GUARDED_TRANSACTIONS, + EXTRA_GAS_LIMIT_FOR_RELAYED_TRANSACTIONS, +) from multiversx_sdk_cli.cosign_transaction import cosign_transaction from multiversx_sdk_cli.interfaces import IAccount @@ -16,8 +20,8 @@ def sign_transaction( sender: Optional[IAccount] = None, guardian: Optional[IAccount] = None, relayer: Optional[IAccount] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_service_url: Optional[str] = None, + guardian_2fa_code: Optional[str] = None, ): """Signs the transaction using the sender's account and, if required, additionally signs with the guardian's and relayer's accounts. Ensures the appropriate transaction options are set as needed.""" self._set_options_for_guarded_transaction_if_needed(transaction) @@ -34,6 +38,14 @@ def sign_transaction( ) self._sign_relayed_transaction_if_relayer(transaction, relayer) + def add_extra_gas_limit_if_required(self, transaction: Transaction): + """In case of guarded or relayed transactions, extra gas limit is added.""" + if transaction.guardian: + transaction.gas_limit += EXTRA_GAS_LIMIT_FOR_GUARDED_TRANSACTIONS + + if transaction.relayer: + transaction.gas_limit += EXTRA_GAS_LIMIT_FOR_RELAYED_TRANSACTIONS + def _set_options_for_guarded_transaction_if_needed(self, transaction: Transaction): if transaction.guardian: transaction_computer = TransactionComputer() @@ -58,8 +70,8 @@ def _sign_guarded_transaction_if_guardian( self, transaction: Transaction, guardian: Union[IAccount, None], - guardian_service_url: str, - guardian_2fa_code: str, + guardian_service_url: Union[str, None], + guardian_2fa_code: Union[str, None], ) -> Transaction: # If the guardian account is provided, we sign locally. Otherwise, we reach for the trusted cosign service. if guardian: diff --git a/multiversx_sdk_cli/cli_delegation.py b/multiversx_sdk_cli/cli_delegation.py index 5b1fb2a9..87bb8e07 100644 --- a/multiversx_sdk_cli/cli_delegation.py +++ b/multiversx_sdk_cli/cli_delegation.py @@ -427,8 +427,10 @@ def do_create_delegation_contract(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 delegation = _get_delegation_controller(args) @@ -443,12 +445,7 @@ def do_create_delegation_contract(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -475,8 +472,10 @@ def add_new_nodes(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 public_keys, signed_messages = _get_public_keys_and_signed_messages(args) @@ -493,12 +492,7 @@ def add_new_nodes(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -527,8 +521,10 @@ def remove_nodes(args: Any): _check_if_either_bls_keys_or_validators_file_are_provided(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 public_keys = _load_validators_public_keys(args) @@ -544,12 +540,7 @@ def remove_nodes(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -579,8 +570,10 @@ def stake_nodes(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 public_keys = _load_validators_public_keys(args) @@ -596,12 +589,7 @@ def stake_nodes(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -620,8 +608,10 @@ def unbond_nodes(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 public_keys = _load_validators_public_keys(args) @@ -637,12 +627,7 @@ def unbond_nodes(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -653,8 +638,10 @@ def unstake_nodes(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 public_keys = _load_validators_public_keys(args) @@ -670,12 +657,7 @@ def unstake_nodes(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -686,8 +668,10 @@ def unjail_nodes(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 public_keys = _load_validators_public_keys(args) @@ -703,12 +687,7 @@ def unjail_nodes(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -718,8 +697,10 @@ def delegate(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 value = int(args.value) @@ -734,12 +715,7 @@ def delegate(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -749,8 +725,10 @@ def claim_rewards(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -764,12 +742,7 @@ def claim_rewards(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -778,8 +751,10 @@ def redelegate_rewards(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -793,12 +768,7 @@ def redelegate_rewards(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -807,8 +777,10 @@ def undelegate(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 value = int(args.value) @@ -823,12 +795,7 @@ def undelegate(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -838,8 +805,10 @@ def withdraw(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -853,12 +822,7 @@ def withdraw(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -868,8 +832,10 @@ def change_service_fee(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -884,12 +850,7 @@ def change_service_fee(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -899,8 +860,10 @@ def modify_delegation_cap(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -915,12 +878,7 @@ def modify_delegation_cap(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -930,8 +888,10 @@ def automatic_activation(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -947,12 +907,7 @@ def automatic_activation(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -962,8 +917,10 @@ def redelegate_cap(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -979,12 +936,7 @@ def redelegate_cap(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -994,8 +946,10 @@ def set_metadata(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -1012,12 +966,7 @@ def set_metadata(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -1027,8 +976,10 @@ def make_new_contract_from_validator_data(args: Any): validate_arguments(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -1043,12 +994,7 @@ def make_new_contract_from_validator_data(args: Any): nonce=sender.nonce, version=int(args.version), options=int(args.options), - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) diff --git a/multiversx_sdk_cli/cli_shared.py b/multiversx_sdk_cli/cli_shared.py index 29a2b1e9..95242830 100644 --- a/multiversx_sdk_cli/cli_shared.py +++ b/multiversx_sdk_cli/cli_shared.py @@ -20,8 +20,16 @@ load_password, load_relayer_password, ) -from multiversx_sdk_cli.constants import DEFAULT_GAS_PRICE, DEFAULT_TX_VERSION -from multiversx_sdk_cli.errors import ArgumentsNotProvidedError, IncorrectWalletError +from multiversx_sdk_cli.constants import ( + DEFAULT_GAS_PRICE, + DEFAULT_TX_VERSION, + TCS_SERVICE_ID, +) +from multiversx_sdk_cli.errors import ( + ArgumentsNotProvidedError, + BadUsage, + IncorrectWalletError, +) from multiversx_sdk_cli.guardian_relayer_data import GuardianRelayerData from multiversx_sdk_cli.interfaces import IAccount from multiversx_sdk_cli.simulation import Simulator @@ -29,6 +37,19 @@ from multiversx_sdk_cli.utils import log_explorer_transaction from multiversx_sdk_cli.ux import show_warning +trusted_cosigner_service_url_by_chain_id = { + "1": "https://tools.multiversx.com/guardian", + "D": "https://devnet-tools.multiversx.com/guardian", + "T": "https://testnet-tools.multiversx.com/guardian", +} + + +def get_trusted_cosigner_service_url_by_chain_id(chain_id: str) -> str: + try: + return trusted_cosigner_service_url_by_chain_id[chain_id] + except: + raise BadUsage(f"Could not get Trusted Cosigner Service Url. No match found for chain id: {chain_id}") + def wider_help_formatter(prog: Text): return argparse.RawDescriptionHelpFormatter(prog, max_help_position=50, width=120) @@ -308,31 +329,84 @@ def get_guardian_address(guardian: Union[IAccount, None], args: Any) -> Union[Ad return address_from_account or address_from_args -# check if account is guarded, api/proxy agnostic -# check if guardian is active -# get guardian address -# get guardian service (if TCS have the url ready) +def get_guardian_and_relayer_data(sender: str, args: Any) -> GuardianRelayerData: + guardian = load_guardian_account(args) -# def fetch_guardian_address_from_the_network(address: str, proxy_url: str) -> Address: -# network_provider_config = config.get_config_for_network_providers() -# proxy = ProxyNetworkProvider(url=proxy_url, config=network_provider_config) -# return proxy.get_account(Address.new_from_bech32(address)).address + # get guardian address from account or from cli args + guardian_address = get_guardian_address(guardian, args) + relayer = load_relayer_account(args) + relayer_address = get_relayer_address(relayer, args) -def fetch_guardian_info(address: str, proxy_url: str) -> Union[tuple[Address, str], None]: - network_provider_config = config.get_config_for_network_providers() - proxy = ProxyNetworkProvider(url=proxy_url, config=network_provider_config) + guardian_and_relayer_data = GuardianRelayerData( + guardian=guardian, + guardian_address=guardian_address, + relayer=relayer, + relayer_address=relayer_address, + ) - response = proxy.do_get_generic(f"/address/{address}/guardian-data").to_dictionary() - guardian_data = response.get("guardianData", {}) + _get_guardian_data_from_network(sender, args, guardian_and_relayer_data) + return guardian_and_relayer_data + + +def _get_guardian_data_from_network(sender: str, args: Any, guardian_and_relayer_data: GuardianRelayerData): + """Updates the `guardian_and_relayer_data` parameter, that is later used.""" + + # if guardian not provided, get guardian from the network + if not guardian_and_relayer_data.guardian_address: + guardian_data = _get_guardian_data(sender, args.proxy) + + if guardian_data: + guardian_and_relayer_data.guardian_address = Address.new_from_bech32(guardian_data["guardian_address"]) + + # if tcs is used, set url, else get service url from args + tcs_url = guardian_data["cosigner_service_url"] + guardian_and_relayer_data.guardian_service_url = tcs_url if tcs_url else args.guardian_service_url + + if guardian_and_relayer_data.guardian_service_url: + guardian_and_relayer_data.guardian_2fa_code = _get_2fa_code(args) + + +def _get_guardian_data(address: str, proxy_url: str) -> Union[dict[str, str], None]: + if not proxy_url: + return None + + guardian_data = _fetch_guardian_data(address, proxy_url) if not bool(guardian_data.get("guarded", "")): return None - guardian_address = Address.new_from_bech32(guardian_data.get("address", "")) - service_url = guardian_data.get("serviceUID", "") + active_guardian = guardian_data.get("activeGuardian", {}) - return None + guardian_address = active_guardian.get("address", "") + service_id = active_guardian.get("serviceUID", "") + + cosigner_service_url = "" + + if service_id == TCS_SERVICE_ID: + chain_id = _fetch_chain_id(proxy_url) + cosigner_service_url = get_trusted_cosigner_service_url_by_chain_id(chain_id) + + return { + "guardian_address": guardian_address, + "cosigner_service_url": cosigner_service_url, + } + + +def _fetch_guardian_data(address: str, proxy_url: str) -> dict[str, Any]: + network_provider_config = config.get_config_for_network_providers() + proxy = ProxyNetworkProvider(url=proxy_url, config=network_provider_config) + + response = proxy.do_get_generic(f"/address/{address}/guardian-data").to_dictionary() + guardian_data: dict[str, Any] = response.get("guardianData", {}) + return guardian_data + + +def _get_2fa_code(args: Any) -> str: + code: str = args.guardian_2fa_code + if not code: + code = input("Please enter the two factor authentication code: ") + return code def get_relayer_address(relayer: Union[IAccount, None], args: Any) -> Union[Address, None]: @@ -381,9 +455,7 @@ def get_current_nonce_for_address(address: Address, proxy_url: Union[str, None]) def get_chain_id(chain_id: str, proxy_url: str) -> str: if chain_id and proxy_url: - network_provider_config = config.get_config_for_network_providers() - proxy = ProxyNetworkProvider(url=proxy_url, config=network_provider_config) - fetched_chain_id = proxy.get_network_config().chain_id + fetched_chain_id = _fetch_chain_id(proxy_url) if chain_id != fetched_chain_id: show_warning( @@ -394,6 +466,10 @@ def get_chain_id(chain_id: str, proxy_url: str) -> str: if chain_id: return chain_id + return _fetch_chain_id(proxy_url) + + +def _fetch_chain_id(proxy_url: str) -> str: network_provider_config = config.get_config_for_network_providers() proxy = ProxyNetworkProvider(url=proxy_url, config=network_provider_config) return proxy.get_network_config().chain_id diff --git a/multiversx_sdk_cli/cli_transactions.py b/multiversx_sdk_cli/cli_transactions.py index 3333d6db..27785f43 100644 --- a/multiversx_sdk_cli/cli_transactions.py +++ b/multiversx_sdk_cli/cli_transactions.py @@ -121,16 +121,14 @@ def create_transaction(args: Any): validate_chain_id_args(args) sender = cli_shared.prepare_sender(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) if args.data_file: args.data = Path(args.data_file).read_text() - guardian = cli_shared.load_guardian_account(args) - guardian_address = cli_shared.get_guardian_address(guardian, args) - - relayer = cli_shared.load_relayer_account(args) - relayer_address = cli_shared.get_relayer_address(relayer, args) - native_amount = int(args.value) gas_limit = int(args.gas_limit) if args.gas_limit else 0 @@ -151,12 +149,7 @@ def create_transaction(args: Any): options=args.options, token_transfers=transfers, data=args.data, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) diff --git a/multiversx_sdk_cli/cli_validators.py b/multiversx_sdk_cli/cli_validators.py index 31399aa6..7d06feb9 100644 --- a/multiversx_sdk_cli/cli_validators.py +++ b/multiversx_sdk_cli/cli_validators.py @@ -156,8 +156,10 @@ def validate_args(args: Any) -> None: def do_stake(args: Any): validate_args(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -174,12 +176,7 @@ def do_stake(args: Any): nonce=sender.nonce, version=args.version, options=args.options, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) else: validators_signers = _load_validators_signers(args.validators_pem) @@ -193,12 +190,7 @@ def do_stake(args: Any): version=args.version, options=args.options, rewards_address=rewards_address, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -228,8 +220,10 @@ def _parse_public_bls_keys(public_bls_keys: str) -> list[ValidatorPublicKey]: def do_unstake(args: Any): validate_args(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -245,12 +239,7 @@ def do_unstake(args: Any): nonce=sender.nonce, version=args.version, options=args.options, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -259,8 +248,10 @@ def do_unstake(args: Any): def do_unjail(args: Any): validate_args(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -276,12 +267,7 @@ def do_unjail(args: Any): nonce=sender.nonce, version=args.version, options=args.options, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -290,8 +276,10 @@ def do_unjail(args: Any): def do_unbond(args: Any): validate_args(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -307,12 +295,7 @@ def do_unbond(args: Any): nonce=sender.nonce, version=args.version, options=args.options, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -321,8 +304,10 @@ def do_unbond(args: Any): def change_reward_address(args: Any): validate_args(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -338,12 +323,7 @@ def change_reward_address(args: Any): nonce=sender.nonce, version=args.version, options=args.options, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -352,8 +332,10 @@ def change_reward_address(args: Any): def do_claim(args: Any): validate_args(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -367,12 +349,7 @@ def do_claim(args: Any): nonce=sender.nonce, version=args.version, options=args.options, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -381,8 +358,10 @@ def do_claim(args: Any): def do_unstake_nodes(args: Any): validate_args(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -399,12 +378,7 @@ def do_unstake_nodes(args: Any): nonce=sender.nonce, version=args.version, options=args.options, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -413,8 +387,10 @@ def do_unstake_nodes(args: Any): def do_unstake_tokens(args: Any): validate_args(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) value = int(args.unstake_value) @@ -430,12 +406,7 @@ def do_unstake_tokens(args: Any): nonce=sender.nonce, version=args.version, options=args.options, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -444,8 +415,10 @@ def do_unstake_tokens(args: Any): def do_unbond_nodes(args: Any): validate_args(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -462,12 +435,7 @@ def do_unbond_nodes(args: Any): nonce=sender.nonce, version=args.version, options=args.options, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -476,8 +444,10 @@ def do_unbond_nodes(args: Any): def do_unbond_tokens(args: Any): validate_args(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) value = int(args.unbond_value) @@ -493,12 +463,7 @@ def do_unbond_tokens(args: Any): nonce=sender.nonce, version=args.version, options=args.options, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -507,8 +472,10 @@ def do_unbond_tokens(args: Any): def do_clean_registered_data(args: Any): validate_args(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -522,12 +489,7 @@ def do_clean_registered_data(args: Any): nonce=sender.nonce, version=args.version, options=args.options, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) @@ -536,8 +498,10 @@ def do_clean_registered_data(args: Any): def do_restake_unstaked_nodes(args: Any): validate_args(args) sender = cli_shared.prepare_sender(args) - guardian, guardian_address = cli_shared.prepare_guardian(args) - relayer, relayer_address = cli_shared.prepare_relayer(args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) gas_limit = args.gas_limit if args.gas_limit else 0 @@ -553,12 +517,7 @@ def do_restake_unstaked_nodes(args: Any): nonce=sender.nonce, version=args.version, options=args.options, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) diff --git a/multiversx_sdk_cli/constants.py b/multiversx_sdk_cli/constants.py index 556611ac..9a997542 100644 --- a/multiversx_sdk_cli/constants.py +++ b/multiversx_sdk_cli/constants.py @@ -15,3 +15,7 @@ DEFAULT_GAS_PRICE = 1000000000 MIN_GAS_LIMIT = 50000 + +TCS_SERVICE_ID = "MultiversXTCSService" +EXTRA_GAS_LIMIT_FOR_GUARDED_TRANSACTIONS = 50_000 +EXTRA_GAS_LIMIT_FOR_RELAYED_TRANSACTIONS = 50_000 diff --git a/multiversx_sdk_cli/delegation/staking_provider.py b/multiversx_sdk_cli/delegation/staking_provider.py index 748405a7..17a8c377 100644 --- a/multiversx_sdk_cli/delegation/staking_provider.py +++ b/multiversx_sdk_cli/delegation/staking_provider.py @@ -1,5 +1,3 @@ -from typing import Optional - from multiversx_sdk import ( Address, DelegationTransactionsFactory, @@ -12,6 +10,7 @@ from multiversx_sdk_cli.base_transactions_controller import BaseTransactionsController from multiversx_sdk_cli.config import get_address_hrp from multiversx_sdk_cli.errors import BadUsage +from multiversx_sdk_cli.guardian_relayer_data import GuardianRelayerData from multiversx_sdk_cli.interfaces import IAccount DELEGATION_MANAGER_SC_ADDRESS_HEX = "000000000000000000010000000000000000000000000000000000000004ffff" @@ -32,12 +31,7 @@ def prepare_transaction_for_new_delegation_contract( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_new_delegation_contract( sender=owner.address, @@ -49,8 +43,10 @@ def prepare_transaction_for_new_delegation_contract( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -58,10 +54,10 @@ def prepare_transaction_for_new_delegation_contract( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -78,12 +74,7 @@ def prepare_transaction_for_adding_nodes( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_adding_nodes( sender=owner.address, @@ -96,8 +87,10 @@ def prepare_transaction_for_adding_nodes( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -105,10 +98,10 @@ def prepare_transaction_for_adding_nodes( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -124,12 +117,7 @@ def prepare_transaction_for_removing_nodes( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_removing_nodes( sender=owner.address, @@ -141,8 +129,10 @@ def prepare_transaction_for_removing_nodes( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -150,10 +140,10 @@ def prepare_transaction_for_removing_nodes( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -169,12 +159,7 @@ def prepare_transaction_for_staking_nodes( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_staking_nodes( sender=owner.address, @@ -186,8 +171,10 @@ def prepare_transaction_for_staking_nodes( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -195,10 +182,10 @@ def prepare_transaction_for_staking_nodes( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -214,12 +201,7 @@ def prepare_transaction_for_unbonding_nodes( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_unbonding_nodes( sender=owner.address, @@ -231,8 +213,10 @@ def prepare_transaction_for_unbonding_nodes( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -240,10 +224,10 @@ def prepare_transaction_for_unbonding_nodes( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -259,12 +243,7 @@ def prepare_transaction_for_unstaking_nodes( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_unstaking_nodes( sender=owner.address, @@ -276,8 +255,10 @@ def prepare_transaction_for_unstaking_nodes( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -285,10 +266,10 @@ def prepare_transaction_for_unstaking_nodes( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -304,12 +285,7 @@ def prepare_transaction_for_unjailing_nodes( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_unjailing_nodes( sender=owner.address, @@ -321,8 +297,10 @@ def prepare_transaction_for_unjailing_nodes( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -330,10 +308,10 @@ def prepare_transaction_for_unjailing_nodes( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -348,12 +326,7 @@ def prepare_transaction_for_delegating( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_delegating( sender=owner.address, @@ -364,8 +337,10 @@ def prepare_transaction_for_delegating( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -373,10 +348,10 @@ def prepare_transaction_for_delegating( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -391,12 +366,7 @@ def prepare_transaction_for_claiming_rewards( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_claiming_rewards( sender=owner.address, delegation_contract=delegation_contract @@ -406,8 +376,10 @@ def prepare_transaction_for_claiming_rewards( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -415,10 +387,10 @@ def prepare_transaction_for_claiming_rewards( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -433,12 +405,7 @@ def prepare_transaction_for_redelegating_rewards( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_redelegating_rewards( sender=owner.address, delegation_contract=delegation_contract @@ -448,8 +415,10 @@ def prepare_transaction_for_redelegating_rewards( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -457,10 +426,10 @@ def prepare_transaction_for_redelegating_rewards( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -475,12 +444,7 @@ def prepare_transaction_for_undelegating( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_undelegating( sender=owner.address, @@ -491,8 +455,10 @@ def prepare_transaction_for_undelegating( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -500,10 +466,10 @@ def prepare_transaction_for_undelegating( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -518,12 +484,7 @@ def prepare_transaction_for_withdrawing( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_withdrawing( sender=owner.address, delegation_contract=delegation_contract @@ -533,8 +494,10 @@ def prepare_transaction_for_withdrawing( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -542,10 +505,10 @@ def prepare_transaction_for_withdrawing( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -561,12 +524,7 @@ def prepare_transaction_for_changing_service_fee( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_changing_service_fee( sender=owner.address, @@ -578,8 +536,10 @@ def prepare_transaction_for_changing_service_fee( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -587,10 +547,10 @@ def prepare_transaction_for_changing_service_fee( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -606,12 +566,7 @@ def prepare_transaction_for_modifying_delegation_cap( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_modifying_delegation_cap( sender=owner.address, @@ -623,8 +578,10 @@ def prepare_transaction_for_modifying_delegation_cap( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -632,10 +589,10 @@ def prepare_transaction_for_modifying_delegation_cap( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -652,12 +609,7 @@ def prepare_transaction_for_automatic_activation( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: if set and unset: raise BadUsage("Cannot set and unset at the same time") @@ -678,8 +630,10 @@ def prepare_transaction_for_automatic_activation( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -687,10 +641,10 @@ def prepare_transaction_for_automatic_activation( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -707,12 +661,7 @@ def prepare_transaction_for_redelegate_cap( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: if set and unset: raise BadUsage("Cannot set and unset at the same time") @@ -733,8 +682,10 @@ def prepare_transaction_for_redelegate_cap( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -742,10 +693,10 @@ def prepare_transaction_for_redelegate_cap( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -763,12 +714,7 @@ def prepare_transaction_for_setting_metadata( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: tx = self._factory.create_transaction_for_setting_metadata( sender=owner.address, @@ -782,8 +728,10 @@ def prepare_transaction_for_setting_metadata( tx.nonce = nonce tx.version = version tx.options = options - tx.guardian = guardian_address - tx.relayer = relayer_address + tx.guardian = guardian_and_relayer_data.guardian_address + tx.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(tx) if gas_limit: tx.gas_limit = gas_limit @@ -791,10 +739,10 @@ def prepare_transaction_for_setting_metadata( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx @@ -811,12 +759,7 @@ def prepare_transaction_for_creating_delegation_contract_from_validator( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: receiver = Address.new_from_hex(DELEGATION_MANAGER_SC_ADDRESS_HEX, get_address_hrp()) @@ -834,8 +777,8 @@ def prepare_transaction_for_creating_delegation_contract_from_validator( nonce=nonce, version=version, options=options, - guardian=guardian_address, - relayer=relayer_address, + guardian=guardian_and_relayer_data.guardian_address, + relayer=guardian_and_relayer_data.relayer_address, gas_price=gas_price, value=value, ) @@ -846,10 +789,10 @@ def prepare_transaction_for_creating_delegation_contract_from_validator( self.sign_transaction( transaction=tx, sender=owner, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return tx diff --git a/multiversx_sdk_cli/dns.py b/multiversx_sdk_cli/dns.py index 8060840d..95ab0a85 100644 --- a/multiversx_sdk_cli/dns.py +++ b/multiversx_sdk_cli/dns.py @@ -67,12 +67,10 @@ def register(args: Any): validate_chain_id_args(args) sender = cli_shared.prepare_sender(args) - - guardian = cli_shared.load_guardian_account(args) - guardian_address = cli_shared.get_guardian_address(guardian, args) - - relayer = cli_shared.load_relayer_account(args) - relayer_address = cli_shared.get_relayer_address(relayer, args) + guardian_and_relayer_data = cli_shared.get_guardian_and_relayer_data( + sender=sender.address.to_bech32(), + args=args, + ) native_amount = int(args.value) @@ -92,12 +90,7 @@ def register(args: Any): version=args.version, options=args.options, data=data, - guardian_account=guardian, - guardian_address=guardian_address, - relayer_account=relayer, - relayer_address=relayer_address, - guardian_service_url=args.guardian_service_url, - guardian_2fa_code=args.guardian_2fa_code, + guardian_and_relayer_data=guardian_and_relayer_data, ) cli_shared.send_or_simulate(tx, args) diff --git a/multiversx_sdk_cli/tests/test_cli_validators.py b/multiversx_sdk_cli/tests/test_cli_validators.py index f90ce3ca..c482673d 100644 --- a/multiversx_sdk_cli/tests/test_cli_validators.py +++ b/multiversx_sdk_cli/tests/test_cli_validators.py @@ -134,7 +134,7 @@ def test_stake_with_relayer_and_guardian(capsys: Any): assert tx["receiver"] == "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l" assert tx["value"] == "2500000000000000000000" assert tx["nonce"] == 0 - assert tx["gasLimit"] == 11029500 + assert tx["gasLimit"] == 11129500 assert tx["chainID"] == "localnet" assert tx["version"] == 2 assert tx["options"] == 2 @@ -142,11 +142,11 @@ def test_stake_with_relayer_and_guardian(capsys: Any): assert tx["relayer"] == "erd1cqqxak4wun7508e0yj9ng843r6hv4mzd0hhpjpsejkpn9wa9yq8sj7u2u5" assert ( tx["signature"] - == "9ecca226c3e5913906a5f22971a0d84bb7a8c652e309ffab4073dea8bbd88caccc2ad9e33b6929f16acdedb676ad574ad66d520abd5b398469fa0cff3fc7ca03" + == "87e80ebb4bb31837a268ec209353615e77ecf8799353dff9a7c6c78f049d7a3ebca715840db14428e98925fc3b8b9137dbbe35ea33affe2420fa3b2f1e701d06" ) assert ( tx["guardianSignature"] - == "12c1ee05d34282555d85f7786dc0e7ffbce960de88fb75ba81a237bd1f2cc175f50ee42e60b2857bf2cd49d02de12a4017f1c95f14910fcc27bc7cb16b41ce04" + == "afb5e45bec458dae4b5ab80f8c6048a15faaeb2bcfaad90e6707de62bf3a931b440835ae8ec1dd767d52a5ed290583fe73b5302801ecfcd8e7c5908fdbf9b001" ) assert ( data diff --git a/multiversx_sdk_cli/tests/test_transactions.py b/multiversx_sdk_cli/tests/test_transactions.py index b5420b53..8a8c4e4c 100644 --- a/multiversx_sdk_cli/tests/test_transactions.py +++ b/multiversx_sdk_cli/tests/test_transactions.py @@ -2,6 +2,7 @@ from multiversx_sdk import Account, Address +from multiversx_sdk_cli.guardian_relayer_data import GuardianRelayerData from multiversx_sdk_cli.transactions import TransactionsController testdata = Path(__file__).parent / "testdata" @@ -12,6 +13,7 @@ class TestTransactionsController: alice = Account.new_from_pem(testdata / "alice.pem") def test_create_transaction_without_data_and_value(self): + guardian_relayer_data = GuardianRelayerData() transaction = self.controller.create_transaction( sender=self.alice, receiver=Address.new_from_bech32("erd1cqqxak4wun7508e0yj9ng843r6hv4mzd0hhpjpsejkpn9wa9yq8sj7u2u5"), @@ -21,6 +23,7 @@ def test_create_transaction_without_data_and_value(self): nonce=7, version=2, options=0, + guardian_and_relayer_data=guardian_relayer_data, ) assert transaction.sender == self.alice.address @@ -43,6 +46,7 @@ def test_create_transaction_without_data_and_value(self): ) def test_create_transfer_transaction(self): + guardian_relayer_data = GuardianRelayerData() transaction = self.controller.create_transaction( sender=self.alice, receiver=Address.new_from_bech32("erd1cqqxak4wun7508e0yj9ng843r6hv4mzd0hhpjpsejkpn9wa9yq8sj7u2u5"), @@ -52,6 +56,7 @@ def test_create_transfer_transaction(self): nonce=7, version=2, options=0, + guardian_and_relayer_data=guardian_relayer_data, ) assert transaction.sender == self.alice.address @@ -74,6 +79,7 @@ def test_create_transfer_transaction(self): ) def test_create_transaction_with_data(self): + guardian_relayer_data = GuardianRelayerData() transaction = self.controller.create_transaction( sender=self.alice, receiver=Address.new_from_bech32("erd1cqqxak4wun7508e0yj9ng843r6hv4mzd0hhpjpsejkpn9wa9yq8sj7u2u5"), @@ -84,6 +90,7 @@ def test_create_transaction_with_data(self): version=2, options=0, data="testdata", + guardian_and_relayer_data=guardian_relayer_data, ) assert transaction.sender == self.alice.address @@ -106,6 +113,11 @@ def test_create_transaction_with_data(self): ) def test_create_guarded_transaction(self): + guardian_relayer_data = GuardianRelayerData( + guardian=Account.new_from_pem(testdata / "testUser2.pem"), + guardian_address=Address.new_from_bech32("erd1ssmsc9022udc8pdw7wk3hxw74jr900xg28vwpz3z60gep66fasasl2nkm4"), + ) + transaction = self.controller.create_transaction( sender=self.alice, receiver=Address.new_from_bech32("erd1cqqxak4wun7508e0yj9ng843r6hv4mzd0hhpjpsejkpn9wa9yq8sj7u2u5"), @@ -116,8 +128,7 @@ def test_create_guarded_transaction(self): version=2, options=0, data="testdata", - guardian_address=Address.new_from_bech32("erd1ssmsc9022udc8pdw7wk3hxw74jr900xg28vwpz3z60gep66fasasl2nkm4"), - guardian_account=Account.new_from_pem(testdata / "testUser2.pem"), + guardian_and_relayer_data=guardian_relayer_data, ) assert transaction.sender == self.alice.address @@ -146,6 +157,11 @@ def test_create_guarded_transaction(self): ) def test_create_relayed_transaction(self): + guardian_relayer_data = GuardianRelayerData( + relayer=Account.new_from_pem(testdata / "testUser2.pem"), + relayer_address=Address.new_from_bech32("erd1ssmsc9022udc8pdw7wk3hxw74jr900xg28vwpz3z60gep66fasasl2nkm4"), + ) + transaction = self.controller.create_transaction( sender=self.alice, receiver=Address.new_from_bech32("erd1cqqxak4wun7508e0yj9ng843r6hv4mzd0hhpjpsejkpn9wa9yq8sj7u2u5"), @@ -156,8 +172,7 @@ def test_create_relayed_transaction(self): version=2, options=0, data="testdata", - relayer_address=Address.new_from_bech32("erd1ssmsc9022udc8pdw7wk3hxw74jr900xg28vwpz3z60gep66fasasl2nkm4"), - relayer_account=Account.new_from_pem(testdata / "testUser2.pem"), + guardian_and_relayer_data=guardian_relayer_data, ) assert transaction.sender == self.alice.address @@ -186,6 +201,13 @@ def test_create_relayed_transaction(self): ) def test_create_guarded_relayed_transaction(self): + guardian_relayer_data = GuardianRelayerData( + guardian=Account.new_from_pem(testdata / "testUser.pem"), + guardian_address=Address.new_from_bech32("erd1cqqxak4wun7508e0yj9ng843r6hv4mzd0hhpjpsejkpn9wa9yq8sj7u2u5"), + relayer=Account.new_from_pem(testdata / "testUser2.pem"), + relayer_address=Address.new_from_bech32("erd1ssmsc9022udc8pdw7wk3hxw74jr900xg28vwpz3z60gep66fasasl2nkm4"), + ) + transaction = self.controller.create_transaction( sender=self.alice, receiver=Address.new_from_bech32("erd1cqqxak4wun7508e0yj9ng843r6hv4mzd0hhpjpsejkpn9wa9yq8sj7u2u5"), @@ -196,10 +218,7 @@ def test_create_guarded_relayed_transaction(self): version=2, options=0, data="testdata", - guardian_address=Address.new_from_bech32("erd1cqqxak4wun7508e0yj9ng843r6hv4mzd0hhpjpsejkpn9wa9yq8sj7u2u5"), - guardian_account=Account.new_from_pem(testdata / "testUser.pem"), - relayer_address=Address.new_from_bech32("erd1ssmsc9022udc8pdw7wk3hxw74jr900xg28vwpz3z60gep66fasasl2nkm4"), - relayer_account=Account.new_from_pem(testdata / "testUser2.pem"), + guardian_and_relayer_data=guardian_relayer_data, ) assert transaction.sender == self.alice.address diff --git a/multiversx_sdk_cli/transactions.py b/multiversx_sdk_cli/transactions.py index cc261624..0d8d9772 100644 --- a/multiversx_sdk_cli/transactions.py +++ b/multiversx_sdk_cli/transactions.py @@ -18,6 +18,7 @@ from multiversx_sdk_cli import errors from multiversx_sdk_cli.base_transactions_controller import BaseTransactionsController from multiversx_sdk_cli.constants import MIN_GAS_LIMIT +from multiversx_sdk_cli.guardian_relayer_data import GuardianRelayerData from multiversx_sdk_cli.interfaces import IAccount logger = logging.getLogger("transactions") @@ -54,14 +55,9 @@ def create_transaction( nonce: int, version: int, options: int, + guardian_and_relayer_data: GuardianRelayerData, token_transfers: Optional[list[TokenTransfer]] = None, data: Optional[str] = None, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", ) -> Transaction: # if no value, token transfers or data provided, create plain transaction if not native_amount and not token_transfers and not data: @@ -80,23 +76,25 @@ def create_transaction( data=data.encode() if data else None, ) - if gas_limit: - transaction.gas_limit = gas_limit - transaction.gas_price = gas_price transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) + + if gas_limit: + transaction.gas_limit = gas_limit self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction diff --git a/multiversx_sdk_cli/validators.py b/multiversx_sdk_cli/validators.py index d5729621..74796834 100644 --- a/multiversx_sdk_cli/validators.py +++ b/multiversx_sdk_cli/validators.py @@ -10,6 +10,7 @@ ) from multiversx_sdk_cli.base_transactions_controller import BaseTransactionsController +from multiversx_sdk_cli.guardian_relayer_data import GuardianRelayerData from multiversx_sdk_cli.interfaces import IAccount from multiversx_sdk_cli.transactions import TransactionsController @@ -29,13 +30,8 @@ def create_transaction_for_staking( nonce: int, version: int, options: int, + guardian_and_relayer_data: GuardianRelayerData, rewards_address: Optional[Address] = None, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", ) -> Transaction: transaction = self.factory.create_transaction_for_staking( sender=sender.address, @@ -47,8 +43,10 @@ def create_transaction_for_staking( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -56,10 +54,10 @@ def create_transaction_for_staking( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction @@ -73,12 +71,7 @@ def create_transaction_for_topping_up( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: transaction = self.factory.create_transaction_for_topping_up( sender=sender.address, @@ -88,8 +81,10 @@ def create_transaction_for_topping_up( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -97,10 +92,10 @@ def create_transaction_for_topping_up( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction @@ -115,12 +110,7 @@ def create_transaction_for_unstaking( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: transaction = self.factory.create_transaction_for_unstaking( sender=sender.address, @@ -131,8 +121,10 @@ def create_transaction_for_unstaking( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -140,10 +132,10 @@ def create_transaction_for_unstaking( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction @@ -158,12 +150,7 @@ def create_transaction_for_unjailing( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: transaction = self.factory.create_transaction_for_unjailing( sender=sender.address, @@ -174,8 +161,10 @@ def create_transaction_for_unjailing( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -183,10 +172,10 @@ def create_transaction_for_unjailing( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction @@ -201,12 +190,7 @@ def create_transaction_for_unbonding( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: transaction = self.factory.create_transaction_for_unbonding( sender=sender.address, @@ -217,8 +201,10 @@ def create_transaction_for_unbonding( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -226,10 +212,10 @@ def create_transaction_for_unbonding( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction @@ -244,12 +230,7 @@ def create_transaction_for_changing_rewards_address( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: transaction = self.factory.create_transaction_for_changing_rewards_address( sender=sender.address, @@ -260,8 +241,10 @@ def create_transaction_for_changing_rewards_address( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -269,10 +252,10 @@ def create_transaction_for_changing_rewards_address( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction @@ -286,12 +269,7 @@ def create_transaction_for_claiming( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: transaction = self.factory.create_transaction_for_claiming( sender=sender.address, @@ -301,8 +279,10 @@ def create_transaction_for_claiming( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -310,10 +290,10 @@ def create_transaction_for_claiming( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction @@ -328,12 +308,7 @@ def create_transaction_for_unstaking_nodes( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: transaction = self.factory.create_transaction_for_unstaking_nodes( sender=sender.address, @@ -344,8 +319,10 @@ def create_transaction_for_unstaking_nodes( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -353,10 +330,10 @@ def create_transaction_for_unstaking_nodes( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction @@ -371,12 +348,7 @@ def create_transaction_for_unstaking_tokens( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: transaction = self.factory.create_transaction_for_unstaking_tokens( sender=sender.address, @@ -387,8 +359,10 @@ def create_transaction_for_unstaking_tokens( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -396,10 +370,10 @@ def create_transaction_for_unstaking_tokens( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction @@ -414,12 +388,7 @@ def create_transaction_for_unbonding_nodes( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: transaction = self.factory.create_transaction_for_unbonding_nodes( sender=sender.address, @@ -430,8 +399,10 @@ def create_transaction_for_unbonding_nodes( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -439,10 +410,10 @@ def create_transaction_for_unbonding_nodes( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction @@ -457,12 +428,7 @@ def create_transaction_for_unbonding_tokens( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: transaction = self.factory.create_transaction_for_unbonding_tokens( sender=sender.address, @@ -473,8 +439,10 @@ def create_transaction_for_unbonding_tokens( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -482,10 +450,10 @@ def create_transaction_for_unbonding_tokens( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction @@ -499,12 +467,7 @@ def create_transaction_for_cleaning_registered_data( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: transaction = self.factory.create_transaction_for_cleaning_registered_data( sender=sender.address, @@ -514,8 +477,10 @@ def create_transaction_for_cleaning_registered_data( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -523,10 +488,10 @@ def create_transaction_for_cleaning_registered_data( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction @@ -541,12 +506,7 @@ def create_transaction_for_restaking_unstaked_nodes( nonce: int, version: int, options: int, - guardian_account: Optional[IAccount] = None, - guardian_address: Optional[Address] = None, - relayer_account: Optional[IAccount] = None, - relayer_address: Optional[Address] = None, - guardian_service_url: str = "", - guardian_2fa_code: str = "", + guardian_and_relayer_data: GuardianRelayerData, ) -> Transaction: transaction = self.factory.create_transaction_for_restaking_unstaked_nodes( sender=sender.address, @@ -557,8 +517,10 @@ def create_transaction_for_restaking_unstaked_nodes( transaction.nonce = nonce transaction.version = version transaction.options = options - transaction.guardian = guardian_address - transaction.relayer = relayer_address + transaction.guardian = guardian_and_relayer_data.guardian_address + transaction.relayer = guardian_and_relayer_data.relayer_address + + self.add_extra_gas_limit_if_required(transaction) if gas_limit: transaction.gas_limit = gas_limit @@ -566,10 +528,10 @@ def create_transaction_for_restaking_unstaked_nodes( self.sign_transaction( transaction=transaction, sender=sender, - guardian=guardian_account, - relayer=relayer_account, - guardian_service_url=guardian_service_url, - guardian_2fa_code=guardian_2fa_code, + guardian=guardian_and_relayer_data.guardian, + relayer=guardian_and_relayer_data.relayer, + guardian_service_url=guardian_and_relayer_data.guardian_service_url, + guardian_2fa_code=guardian_and_relayer_data.guardian_2fa_code, ) return transaction From 55ae23c5936d3230f183bc322d201c1f2d8615a5 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 17 Mar 2025 17:09:00 +0200 Subject: [PATCH 3/5] set guardian from args if provided --- multiversx_sdk_cli/cli_shared.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/multiversx_sdk_cli/cli_shared.py b/multiversx_sdk_cli/cli_shared.py index 95242830..21094b01 100644 --- a/multiversx_sdk_cli/cli_shared.py +++ b/multiversx_sdk_cli/cli_shared.py @@ -345,7 +345,12 @@ def get_guardian_and_relayer_data(sender: str, args: Any) -> GuardianRelayerData relayer_address=relayer_address, ) - _get_guardian_data_from_network(sender, args, guardian_and_relayer_data) + if guardian_and_relayer_data.guardian_address: + guardian_and_relayer_data.guardian_service_url = args.guardian_service_url + guardian_and_relayer_data.guardian_2fa_code = args.guardian_2fa_code + else: + _get_guardian_data_from_network(sender, args, guardian_and_relayer_data) + return guardian_and_relayer_data @@ -353,18 +358,17 @@ def _get_guardian_data_from_network(sender: str, args: Any, guardian_and_relayer """Updates the `guardian_and_relayer_data` parameter, that is later used.""" # if guardian not provided, get guardian from the network - if not guardian_and_relayer_data.guardian_address: - guardian_data = _get_guardian_data(sender, args.proxy) + guardian_data = _get_guardian_data(sender, args.proxy) - if guardian_data: - guardian_and_relayer_data.guardian_address = Address.new_from_bech32(guardian_data["guardian_address"]) + if guardian_data: + guardian_and_relayer_data.guardian_address = Address.new_from_bech32(guardian_data["guardian_address"]) - # if tcs is used, set url, else get service url from args - tcs_url = guardian_data["cosigner_service_url"] - guardian_and_relayer_data.guardian_service_url = tcs_url if tcs_url else args.guardian_service_url + # if tcs is used, set url, else get service url from args + tcs_url = guardian_data["cosigner_service_url"] + guardian_and_relayer_data.guardian_service_url = tcs_url if tcs_url else args.guardian_service_url - if guardian_and_relayer_data.guardian_service_url: - guardian_and_relayer_data.guardian_2fa_code = _get_2fa_code(args) + if guardian_and_relayer_data.guardian_service_url: + guardian_and_relayer_data.guardian_2fa_code = _get_2fa_code(args) def _get_guardian_data(address: str, proxy_url: str) -> Union[dict[str, str], None]: From ef7410ef94f22c7b504d6f86ddb936f5308597e8 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 18 Mar 2025 14:01:10 +0200 Subject: [PATCH 4/5] fix typo --- multiversx_sdk_cli/cli_shared.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multiversx_sdk_cli/cli_shared.py b/multiversx_sdk_cli/cli_shared.py index 21094b01..f3017c8a 100644 --- a/multiversx_sdk_cli/cli_shared.py +++ b/multiversx_sdk_cli/cli_shared.py @@ -143,7 +143,7 @@ def add_tx_args( sub.add_argument("--options", type=int, default=0, help="the transaction options (default: %(default)s)") sub.add_argument("--relayer", type=str, help="the bech32 address of the relayer", default="") - sub.add_argument("--guardian", type=str, help="the bech32 address of the guradian", default="") + sub.add_argument("--guardian", type=str, help="the bech32 address of the guardian", default="") def add_wallet_args(args: list[str], sub: Any): From 4a6eac6e59418686c1548aa52620008459378107 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 21 Mar 2025 16:59:30 +0200 Subject: [PATCH 5/5] fixes after review --- multiversx_sdk_cli/cli_shared.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/multiversx_sdk_cli/cli_shared.py b/multiversx_sdk_cli/cli_shared.py index f3017c8a..00b1743b 100644 --- a/multiversx_sdk_cli/cli_shared.py +++ b/multiversx_sdk_cli/cli_shared.py @@ -368,7 +368,7 @@ def _get_guardian_data_from_network(sender: str, args: Any, guardian_and_relayer guardian_and_relayer_data.guardian_service_url = tcs_url if tcs_url else args.guardian_service_url if guardian_and_relayer_data.guardian_service_url: - guardian_and_relayer_data.guardian_2fa_code = _get_2fa_code(args) + guardian_and_relayer_data.guardian_2fa_code = _ask_for_2fa_code(args) def _get_guardian_data(address: str, proxy_url: str) -> Union[dict[str, str], None]: @@ -406,7 +406,7 @@ def _fetch_guardian_data(address: str, proxy_url: str) -> dict[str, Any]: return guardian_data -def _get_2fa_code(args: Any) -> str: +def _ask_for_2fa_code(args: Any) -> str: code: str = args.guardian_2fa_code if not code: code = input("Please enter the two factor authentication code: ")