Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions multiversx_sdk_cli/cli_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,8 @@ def deploy(args: Any):
is_readable=args.metadata_readable,
is_payable=args.metadata_payable,
is_payable_by_sc=args.metadata_payable_by_sc,
guardian=guardian_and_relayer_data.guardian.address if guardian_and_relayer_data.guardian else None,
relayer=guardian_and_relayer_data.relayer.address if guardian_and_relayer_data.relayer else None,
guardian=guardian_and_relayer_data.guardian_address,
relayer=guardian_and_relayer_data.relayer_address,
gas_limit=args.gas_limit,
gas_price=args.gas_price,
)
Expand Down Expand Up @@ -428,8 +428,8 @@ def call(args: Any):
arguments=arguments,
native_transfer_amount=int(args.value),
token_transfers=token_transfers,
guardian=guardian_and_relayer_data.guardian.address if guardian_and_relayer_data.guardian else None,
relayer=guardian_and_relayer_data.relayer.address if guardian_and_relayer_data.relayer else None,
guardian=guardian_and_relayer_data.guardian_address,
relayer=guardian_and_relayer_data.relayer_address,
gas_limit=args.gas_limit,
gas_price=args.gas_price,
)
Expand Down Expand Up @@ -476,8 +476,8 @@ def upgrade(args: Any):
is_readable=args.metadata_readable,
is_payable=args.metadata_payable,
is_payable_by_sc=args.metadata_payable_by_sc,
guardian=guardian_and_relayer_data.guardian.address if guardian_and_relayer_data.guardian else None,
relayer=guardian_and_relayer_data.relayer.address if guardian_and_relayer_data.relayer else None,
guardian=guardian_and_relayer_data.guardian_address,
relayer=guardian_and_relayer_data.relayer_address,
gas_limit=args.gas_limit,
gas_price=args.gas_price,
)
Expand Down
136 changes: 80 additions & 56 deletions multiversx_sdk_cli/cli_governance.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
GovernanceController,
ProposalInfo,
ProxyNetworkProvider,
TransactionsFactoryConfig,
VoteType,
)

from multiversx_sdk_cli import cli_shared, utils
Expand All @@ -18,7 +18,7 @@
)
from multiversx_sdk_cli.cli_output import CLIOutputBuilder
from multiversx_sdk_cli.config import get_config_for_network_providers
from multiversx_sdk_cli.governance import GovernanceWrapper
from multiversx_sdk_cli.config_env import get_address_hrp


def setup_parser(args: list[str], subparsers: Any) -> Any:
Expand Down Expand Up @@ -196,6 +196,22 @@ def _ensure_args(args: Any):
validate_chain_id_args(args)


def _initialize_controller(args: Any) -> GovernanceController:
chain = args.chain if hasattr(args, "chain") else None
Copy link

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The hasattr check suggests inconsistent argument structure across different commands. Consider standardizing the argument structure or using getattr with a default value for cleaner code.

Suggested change
chain = args.chain if hasattr(args, "chain") else None
chain = getattr(args, "chain", None)

Copilot uses AI. Check for mistakes.
chain_id = cli_shared.get_chain_id(args.proxy, chain)
config = get_config_for_network_providers()
proxy_url = args.proxy if args.proxy else ""
proxy = ProxyNetworkProvider(url=proxy_url, config=config)
gas_estimator = cli_shared.initialize_gas_limit_estimator(args)

return GovernanceController(
chain_id=chain_id,
network_provider=proxy,
address_hrp=get_address_hrp(),
gas_limit_estimator=gas_estimator,
)


def create_proposal(args: Any):
_ensure_args(args)

Expand All @@ -204,24 +220,27 @@ def create_proposal(args: Any):
sender=sender.address.to_bech32(),
args=args,
)
chain_id = cli_shared.get_chain_id(args.proxy, args.chain)
gas_estimator = cli_shared.initialize_gas_limit_estimator(args)
controller = GovernanceWrapper(config=TransactionsFactoryConfig(chain_id), gas_limit_estimator=gas_estimator)

controller = _initialize_controller(args)
transaction = controller.create_transaction_for_new_proposal(
sender=sender,
nonce=sender.nonce,
commit_hash=args.commit_hash,
start_vote_epoch=args.start_vote_epoch,
end_vote_epoch=args.end_vote_epoch,
native_token_amount=args.value,
guardian=guardian_and_relayer_data.guardian_address,
relayer=guardian_and_relayer_data.relayer_address,
gas_limit=args.gas_limit,
gas_price=args.gas_price,
version=args.version,
options=args.options,
guardian_and_relayer_data=guardian_and_relayer_data,
)

cli_shared.alter_transaction_and_sign_again_if_needed(
args=args,
tx=transaction,
sender=sender,
guardian_and_relayer_data=guardian_and_relayer_data,
)
cli_shared.send_or_simulate(transaction, args)


Expand All @@ -233,22 +252,27 @@ def vote(args: Any):
sender=sender.address.to_bech32(),
args=args,
)
chain_id = cli_shared.get_chain_id(args.proxy, args.chain)
gas_estimator = cli_shared.initialize_gas_limit_estimator(args)
controller = GovernanceWrapper(config=TransactionsFactoryConfig(chain_id), gas_limit_estimator=gas_estimator)

[vote_value] = [v for v in VoteType if v.value == args.vote]
Copy link

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list comprehension with destructuring assignment will raise a ValueError if no matching vote type is found or if multiple matches exist. Use a more explicit approach with proper error handling.

Suggested change
[vote_value] = [v for v in VoteType if v.value == args.vote]
vote_value = next((v for v in VoteType if v.value == args.vote), None)
if vote_value is None:
raise ValueError(f"Invalid vote type: {args.vote}. Valid options are: {[v.value for v in VoteType]}")

Copilot uses AI. Check for mistakes.
controller = _initialize_controller(args)

transaction = controller.create_transaction_for_voting(
sender=sender,
nonce=sender.nonce,
proposal_nonce=args.proposal_nonce,
vote=args.vote,
vote=vote_value,
guardian=guardian_and_relayer_data.guardian_address,
relayer=guardian_and_relayer_data.relayer_address,
gas_limit=args.gas_limit,
gas_price=args.gas_price,
version=args.version,
options=args.options,
guardian_and_relayer_data=guardian_and_relayer_data,
)

cli_shared.alter_transaction_and_sign_again_if_needed(
args=args,
tx=transaction,
sender=sender,
guardian_and_relayer_data=guardian_and_relayer_data,
)
cli_shared.send_or_simulate(transaction, args)


Expand All @@ -260,21 +284,24 @@ def close_proposal(args: Any):
sender=sender.address.to_bech32(),
args=args,
)
chain_id = cli_shared.get_chain_id(args.proxy, args.chain)
gas_estimator = cli_shared.initialize_gas_limit_estimator(args)
controller = GovernanceWrapper(config=TransactionsFactoryConfig(chain_id), gas_limit_estimator=gas_estimator)

controller = _initialize_controller(args)
transaction = controller.create_transaction_for_closing_proposal(
sender=sender,
nonce=sender.nonce,
proposal_nonce=args.proposal_nonce,
guardian=guardian_and_relayer_data.guardian_address,
relayer=guardian_and_relayer_data.relayer_address,
gas_limit=args.gas_limit,
gas_price=args.gas_price,
version=args.version,
options=args.options,
guardian_and_relayer_data=guardian_and_relayer_data,
)

cli_shared.alter_transaction_and_sign_again_if_needed(
args=args,
tx=transaction,
sender=sender,
guardian_and_relayer_data=guardian_and_relayer_data,
)
cli_shared.send_or_simulate(transaction, args)


Expand All @@ -286,22 +313,26 @@ def clear_ended_proposals(args: Any):
sender=sender.address.to_bech32(),
args=args,
)
chain_id = cli_shared.get_chain_id(args.proxy, args.chain)
gas_estimator = cli_shared.initialize_gas_limit_estimator(args)
controller = GovernanceWrapper(config=TransactionsFactoryConfig(chain_id), gas_limit_estimator=gas_estimator)

proposers = [Address.new_from_bech32(proposer) for proposer in args.proposers]
controller = _initialize_controller(args)

transaction = controller.create_transaction_for_clearing_ended_proposals(
sender=sender,
nonce=sender.nonce,
proposers=proposers,
guardian=guardian_and_relayer_data.guardian_address,
relayer=guardian_and_relayer_data.relayer_address,
gas_limit=args.gas_limit,
gas_price=args.gas_price,
version=args.version,
options=args.options,
guardian_and_relayer_data=guardian_and_relayer_data,
)

cli_shared.alter_transaction_and_sign_again_if_needed(
args=args,
tx=transaction,
sender=sender,
guardian_and_relayer_data=guardian_and_relayer_data,
)
cli_shared.send_or_simulate(transaction, args)


Expand All @@ -313,20 +344,23 @@ def claim_accumulated_fees(args: Any):
sender=sender.address.to_bech32(),
args=args,
)
chain_id = cli_shared.get_chain_id(args.proxy, args.chain)
gas_estimator = cli_shared.initialize_gas_limit_estimator(args)
controller = GovernanceWrapper(config=TransactionsFactoryConfig(chain_id), gas_limit_estimator=gas_estimator)

controller = _initialize_controller(args)
transaction = controller.create_transaction_for_claiming_accumulated_fees(
sender=sender,
nonce=sender.nonce,
guardian=guardian_and_relayer_data.guardian_address,
relayer=guardian_and_relayer_data.relayer_address,
gas_limit=args.gas_limit,
gas_price=args.gas_price,
version=args.version,
options=args.options,
guardian_and_relayer_data=guardian_and_relayer_data,
)

cli_shared.alter_transaction_and_sign_again_if_needed(
args=args,
tx=transaction,
sender=sender,
guardian_and_relayer_data=guardian_and_relayer_data,
)
cli_shared.send_or_simulate(transaction, args)


Expand All @@ -338,10 +372,8 @@ def change_config(args: Any):
sender=sender.address.to_bech32(),
args=args,
)
chain_id = cli_shared.get_chain_id(args.proxy, args.chain)
gas_estimator = cli_shared.initialize_gas_limit_estimator(args)
controller = GovernanceWrapper(config=TransactionsFactoryConfig(chain_id), gas_limit_estimator=gas_estimator)

controller = _initialize_controller(args)
transaction = controller.create_transaction_for_changing_config(
sender=sender,
nonce=sender.nonce,
Expand All @@ -350,24 +382,25 @@ def change_config(args: Any):
min_quorum=args.min_quorum,
min_veto_threshold=args.min_veto_threshold,
min_pass_threshold=args.min_pass_threshold,
guardian=guardian_and_relayer_data.guardian_address,
relayer=guardian_and_relayer_data.relayer_address,
gas_limit=args.gas_limit,
gas_price=args.gas_price,
version=args.version,
options=args.options,
guardian_and_relayer_data=guardian_and_relayer_data,
)

cli_shared.alter_transaction_and_sign_again_if_needed(
args=args,
tx=transaction,
sender=sender,
guardian_and_relayer_data=guardian_and_relayer_data,
)
cli_shared.send_or_simulate(transaction, args)


def get_voting_power(args: Any):
validate_proxy_argument(args)

config = get_config_for_network_providers()
proxy = ProxyNetworkProvider(url=args.proxy, config=config)
chain_id = proxy.get_network_config().chain_id
controller = GovernanceController(chain_id, proxy)

controller = _initialize_controller(args)
user = Address.new_from_bech32(args.user)

voting_power = controller.get_voting_power(user)
Expand All @@ -377,10 +410,7 @@ def get_voting_power(args: Any):
def get_config(args: Any):
validate_proxy_argument(args)

config = get_config_for_network_providers()
proxy = ProxyNetworkProvider(url=args.proxy, config=config)
chain_id = proxy.get_network_config().chain_id
controller = GovernanceController(chain_id, proxy)
controller = _initialize_controller(args)

contract_config = controller.get_config()
utils.dump_out_json(_config_to_dict(contract_config))
Expand All @@ -389,10 +419,7 @@ def get_config(args: Any):
def get_proposal(args: Any):
validate_proxy_argument(args)

config = get_config_for_network_providers()
proxy = ProxyNetworkProvider(url=args.proxy, config=config)
chain_id = proxy.get_network_config().chain_id
controller = GovernanceController(chain_id, proxy)
controller = _initialize_controller(args)

info = controller.get_proposal(args.proposal_nonce)
utils.dump_out_json(_proposal_to_dict(info))
Expand All @@ -401,10 +428,7 @@ def get_proposal(args: Any):
def get_delegated_vote_info(args: Any):
validate_proxy_argument(args)

config = get_config_for_network_providers()
proxy = ProxyNetworkProvider(url=args.proxy, config=config)
chain_id = proxy.get_network_config().chain_id
controller = GovernanceController(chain_id, proxy)
controller = _initialize_controller(args)

contract = Address.new_from_bech32(args.contract)
user = Address.new_from_bech32(args.user)
Expand Down
18 changes: 10 additions & 8 deletions multiversx_sdk_cli/cli_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -870,30 +870,32 @@ def alter_transaction_and_sign_again_if_needed(

altered = _alter_version_and_options_if_provided(
args=args,
final_transaction=tx,
transaction=tx,
)

if altered: # sign only if something was altered
if altered:
# sign only if something was altered
_sign_transaction(tx, sender, guardian_and_relayer_data)
else:
_sign_transaction(tx, None, guardian_and_relayer_data) # sign only with guardian/relayer if needed
# sign only with guardian/relayer if needed
_sign_transaction(tx, None, guardian_and_relayer_data)


def _alter_version_and_options_if_provided(
args: Any,
final_transaction: Transaction,
transaction: Transaction,
) -> bool:
"""Alters the transaction version and options if they are provided in args.
Returns True if any alteration was made, False otherwise.
"""
altered = False

if args.version != DEFAULT_TX_VERSION and final_transaction.version != args.version:
final_transaction.version = args.version
if args.version != DEFAULT_TX_VERSION and transaction.version != args.version:
transaction.version = args.version
altered = True

if args.options and final_transaction.options != args.options:
final_transaction.options = args.options
if args.options and transaction.options != args.options:
transaction.options = args.options
altered = True

return altered
Expand Down
Loading
Loading