diff --git a/multiversx_sdk_cli/cli_delegation.py b/multiversx_sdk_cli/cli_delegation.py index feecd36d..255d1735 100644 --- a/multiversx_sdk_cli/cli_delegation.py +++ b/multiversx_sdk_cli/cli_delegation.py @@ -131,6 +131,15 @@ def setup_parser(args: List[str], subparsers: Any) -> Any: _add_common_arguments(args, sub) sub.set_defaults(func=set_metadata) + # convert validator to delegation contract + sub = cli_shared.add_command_subparser(subparsers, "staking-provider", "make-delegation-contract-from-validator", + "Create a delegation contract from validator data. Must be called by the node operator") + + sub.add_argument("--max-cap", required=True, help="total delegation cap in EGLD, fully denominated. Use value 0 for uncapped") + sub.add_argument("--fee", required=True, help=f"service fee as hundredths of percents. (e.g. a service fee of 37.45 percent is expressed by the integer 3745)") + _add_common_arguments(args, sub) + sub.set_defaults(func=make_new_contract_from_validator_data) + def _add_common_arguments(args: List[str], sub: Any): cli_shared.add_proxy_arg(sub) @@ -334,3 +343,17 @@ def set_metadata(args: Any): tx = delegation.prepare_transaction_for_setting_metadata(sender, args) cli_shared.send_or_simulate(tx, args) + + +def make_new_contract_from_validator_data(args: Any): + cli_shared.check_guardian_and_options_args(args) + cli_shared.check_broadcast_args(args) + cli_shared.prepare_chain_id_in_args(args) + cli_shared.prepare_nonce_in_args(args) + + sender = cli_shared.prepare_account(args) + config = TransactionsFactoryConfig(args.chain) + delegation = DelegationOperations(config) + + tx = delegation.prepare_transaction_for_creating_delegation_contract_from_validator(sender, args) + cli_shared.send_or_simulate(tx, args) diff --git a/multiversx_sdk_cli/delegation/staking_provider.py b/multiversx_sdk_cli/delegation/staking_provider.py index e8244ea0..beda7759 100644 --- a/multiversx_sdk_cli/delegation/staking_provider.py +++ b/multiversx_sdk_cli/delegation/staking_provider.py @@ -2,7 +2,8 @@ from typing import Any, List, Protocol, Tuple from multiversx_sdk import (Address, DelegationTransactionsFactory, - ValidatorPublicKey) + Transaction, ValidatorPublicKey) +from multiversx_sdk.core.serializer import args_to_string from multiversx_sdk_cli.errors import BadUsage from multiversx_sdk_cli.interfaces import IAddress, ITransaction @@ -307,6 +308,31 @@ def prepare_transaction_for_setting_metadata(self, owner: IAccount, args: Any) - return tx + def prepare_transaction_for_creating_delegation_contract_from_validator(self, owner: IAccount, args: Any) -> ITransaction: + receiver = "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqylllslmq6y6" + max_cap = int(args.max_cap) + fee = int(args.fee) + data = "makeNewContractFromValidatorData@" + args_to_string([max_cap, fee]) + + tx = Transaction( + sender=owner.address.to_bech32(), + receiver=receiver, + gas_limit=510000000, + chain_id=self._factory.config.chain_id, + data=data.encode(), + nonce=int(args.nonce), + version=int(args.version), + options=int(args.options), + guardian=args.guardian + ) + + if args.gas_limit: + tx.gas_limit = int(args.gas_limit) + + tx.signature = bytes.fromhex(owner.sign_transaction(tx)) + + return tx + def _load_validators_public_keys(self, args: Any) -> List[ValidatorPublicKey]: if args.bls_keys: return self._parse_public_bls_keys(args.bls_keys) diff --git a/multiversx_sdk_cli/tests/test_cli_staking_provider.py b/multiversx_sdk_cli/tests/test_cli_staking_provider.py index 51cb7687..c1eb03a1 100644 --- a/multiversx_sdk_cli/tests/test_cli_staking_provider.py +++ b/multiversx_sdk_cli/tests/test_cli_staking_provider.py @@ -374,6 +374,25 @@ def test_set_metadata(capsys: Any): assert transaction["gasLimit"] == 11131000 +def test_create_delegation_contract_from_validator(capsys: Any): + main([ + "staking-provider", "make-delegation-contract-from-validator", + "--max-cap", "0", + "--fee", "3745", + "--pem", str(alice), + "--nonce", "7", "--estimate-gas", + "--chain", "T" + ]) + tx = get_transaction(capsys) + data = tx["emittedTransactionData"] + transaction = tx["emittedTransaction"] + + assert data == "makeNewContractFromValidatorData@@0ea1" + assert transaction["sender"] == "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" + assert transaction["receiver"] == "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqylllslmq6y6" + assert transaction["gasLimit"] == 510000000 + + def _read_stdout(capsys: Any) -> str: return capsys.readouterr().out.strip()