2
2
import logging
3
3
import os
4
4
from pathlib import Path
5
- from typing import Any
5
+ from typing import Any , Union
6
6
7
7
from multiversx_sdk import (
8
8
Address ,
21
21
from multiversx_sdk_cli .contracts import SmartContract
22
22
from multiversx_sdk_cli .cosign_transaction import cosign_transaction
23
23
from multiversx_sdk_cli .docker import is_docker_installed , run_docker
24
- from multiversx_sdk_cli .errors import DockerMissingError , NoWalletProvided
25
- from multiversx_sdk_cli .interfaces import IAddress
24
+ from multiversx_sdk_cli .errors import DockerMissingError
25
+ from multiversx_sdk_cli .interfaces import IAccount
26
26
from multiversx_sdk_cli .ux import show_warning
27
27
28
28
logger = logging .getLogger ("cli.contracts" )
@@ -32,15 +32,10 @@ def setup_parser(args: list[str], subparsers: Any) -> Any:
32
32
parser = cli_shared .add_group_subparser (
33
33
subparsers ,
34
34
"contract" ,
35
- "Build, deploy , upgrade and interact with Smart Contracts" ,
35
+ "Deploy , upgrade and interact with Smart Contracts" ,
36
36
)
37
37
subparsers = parser .add_subparsers ()
38
38
39
- sub = cli_shared .add_command_subparser (
40
- subparsers , "contract" , "build" , "Build a Smart Contract project. This command is DISABLED."
41
- )
42
- sub .set_defaults (func = build )
43
-
44
39
output_description = CLIOutputBuilder .describe (
45
40
with_contract = True , with_transaction_on_network = True , with_simulation = True
46
41
)
@@ -72,6 +67,7 @@ def setup_parser(args: list[str], subparsers: Any) -> Any:
72
67
)
73
68
cli_shared .add_broadcast_args (sub )
74
69
cli_shared .add_guardian_wallet_args (args , sub )
70
+ cli_shared .add_relayed_v3_wallet_args (args , sub )
75
71
76
72
sub .set_defaults (func = deploy )
77
73
@@ -103,6 +99,7 @@ def setup_parser(args: list[str], subparsers: Any) -> Any:
103
99
)
104
100
cli_shared .add_broadcast_args (sub )
105
101
cli_shared .add_guardian_wallet_args (args , sub )
102
+ cli_shared .add_relayed_v3_wallet_args (args , sub )
106
103
107
104
sub .set_defaults (func = call )
108
105
@@ -134,6 +131,7 @@ def setup_parser(args: list[str], subparsers: Any) -> Any:
134
131
)
135
132
cli_shared .add_broadcast_args (sub )
136
133
cli_shared .add_guardian_wallet_args (args , sub )
134
+ cli_shared .add_relayed_v3_wallet_args (args , sub )
137
135
138
136
sub .set_defaults (func = upgrade )
139
137
@@ -205,6 +203,11 @@ def setup_parser(args: list[str], subparsers: Any) -> Any:
205
203
)
206
204
sub .set_defaults (func = do_reproducible_build )
207
205
206
+ sub = cli_shared .add_command_subparser (
207
+ subparsers , "contract" , "build" , "Build a Smart Contract project. This command is DISABLED."
208
+ )
209
+ sub .set_defaults (func = build )
210
+
208
211
parser .epilog = cli_shared .build_group_epilog (subparsers )
209
212
return subparsers
210
213
@@ -274,7 +277,7 @@ def _add_contract_arg(sub: Any):
274
277
275
278
276
279
def _add_contract_abi_arg (sub : Any ):
277
- sub .add_argument ("--abi" , type = str , help = "the ABI of the Smart Contract" )
280
+ sub .add_argument ("--abi" , type = str , help = "the ABI file of the Smart Contract" )
278
281
279
282
280
283
def _add_function_arg (sub : Any ):
@@ -338,9 +341,20 @@ def deploy(args: Any):
338
341
cli_shared .check_guardian_and_options_args (args )
339
342
cli_shared .check_broadcast_args (args )
340
343
cli_shared .prepare_chain_id_in_args (args )
341
- cli_shared .prepare_nonce_in_args (args )
342
344
343
345
sender = cli_shared .prepare_account (args )
346
+
347
+ if not args .nonce :
348
+ nonce = cli_shared .get_current_nonce_for_address (sender .address , args .proxy )
349
+ else :
350
+ nonce = int (args .nonce )
351
+
352
+ guardian = cli_shared .load_guardian_account (args )
353
+ guardian_address = cli_shared .get_guardian_address (guardian , args )
354
+
355
+ relayer = cli_shared .load_relayer_account (args )
356
+ relayer_address = cli_shared .get_relayer_address (relayer , args )
357
+
344
358
config = TransactionsFactoryConfig (args .chain )
345
359
abi = Abi .load (Path (args .abi )) if args .abi else None
346
360
contract = SmartContract (config , abi )
@@ -358,45 +372,57 @@ def deploy(args: Any):
358
372
payable_by_sc = args .metadata_payable_by_sc ,
359
373
gas_limit = int (args .gas_limit ),
360
374
value = int (args .value ),
361
- nonce = int ( args . nonce ) ,
375
+ nonce = nonce ,
362
376
version = int (args .version ),
363
377
options = int (args .options ),
364
- guardian = args .guardian ,
378
+ guardian = guardian_address ,
379
+ relayer = relayer_address ,
365
380
)
366
- tx = _sign_guarded_tx (args , tx )
381
+ tx = _sign_guarded_tx_if_guardian (guardian , args , tx )
382
+ _sign_relayed_tx_if_relayer (relayer , tx )
367
383
368
384
address_computer = AddressComputer (NUMBER_OF_SHARDS )
369
- contract_address = address_computer .compute_contract_address (deployer = sender .address , deployment_nonce = args .nonce )
385
+ contract_address = address_computer .compute_contract_address (deployer = sender .address , deployment_nonce = tx .nonce )
370
386
371
387
logger .info ("Contract address: %s" , contract_address .to_bech32 ())
372
388
utils .log_explorer_contract_address (args .chain , contract_address .to_bech32 ())
373
389
374
390
_send_or_simulate (tx , contract_address , args )
375
391
376
392
377
- def _sign_guarded_tx (args : Any , tx : Transaction ) -> Transaction :
378
- try :
379
- guardian_account = cli_shared .prepare_guardian_account (args )
380
- except NoWalletProvided :
381
- guardian_account = None
382
-
383
- if guardian_account :
384
- tx .guardian_signature = bytes .fromhex (guardian_account .sign_transaction (tx ))
385
- elif args .guardian :
386
- tx = cosign_transaction (tx , args .guardian_service_url , args .guardian_2fa_code ) # type: ignore
393
+ def _sign_guarded_tx_if_guardian (guardian : Union [IAccount , None ], args : Any , tx : Transaction ) -> Transaction :
394
+ if guardian :
395
+ tx .guardian_signature = bytes .fromhex (guardian .sign_transaction (tx ))
396
+ elif tx .guardian and args .guardian_service_url and args .guardian_2fa_code :
397
+ tx = cosign_transaction (tx , args .guardian_service_url , args .guardian_2fa_code )
387
398
388
399
return tx
389
400
390
401
402
+ def _sign_relayed_tx_if_relayer (relayer : Union [IAccount , None ], tx : Transaction ):
403
+ if relayer and tx .relayer :
404
+ tx .relayer_signature = bytes .fromhex (relayer .sign_transaction (tx ))
405
+
406
+
391
407
def call (args : Any ):
392
408
logger .debug ("call" )
393
409
cli_shared .check_guardian_and_options_args (args )
394
410
cli_shared .check_broadcast_args (args )
395
411
cli_shared .prepare_chain_id_in_args (args )
396
- cli_shared .prepare_nonce_in_args (args )
397
412
398
413
sender = cli_shared .prepare_account (args )
399
414
415
+ if not args .nonce :
416
+ nonce = cli_shared .get_current_nonce_for_address (sender .address , args .proxy )
417
+ else :
418
+ nonce = int (args .nonce )
419
+
420
+ guardian = cli_shared .load_guardian_account (args )
421
+ guardian_address = cli_shared .get_guardian_address (guardian , args )
422
+
423
+ relayer = cli_shared .load_relayer_account (args )
424
+ relayer_address = cli_shared .get_relayer_address (relayer , args )
425
+
400
426
config = TransactionsFactoryConfig (args .chain )
401
427
abi = Abi .load (Path (args .abi )) if args .abi else None
402
428
contract = SmartContract (config , abi )
@@ -413,12 +439,14 @@ def call(args: Any):
413
439
gas_limit = int (args .gas_limit ),
414
440
value = int (args .value ),
415
441
transfers = args .token_transfers ,
416
- nonce = int ( args . nonce ) ,
442
+ nonce = nonce ,
417
443
version = int (args .version ),
418
444
options = int (args .options ),
419
- guardian = args .guardian ,
445
+ guardian = guardian_address ,
446
+ relayer = relayer_address ,
420
447
)
421
- tx = _sign_guarded_tx (args , tx )
448
+ tx = _sign_guarded_tx_if_guardian (guardian , args , tx )
449
+ _sign_relayed_tx_if_relayer (relayer , tx )
422
450
423
451
_send_or_simulate (tx , contract_address , args )
424
452
@@ -428,9 +456,20 @@ def upgrade(args: Any):
428
456
cli_shared .check_guardian_and_options_args (args )
429
457
cli_shared .check_broadcast_args (args )
430
458
cli_shared .prepare_chain_id_in_args (args )
431
- cli_shared .prepare_nonce_in_args (args )
432
459
433
460
sender = cli_shared .prepare_account (args )
461
+
462
+ if not args .nonce :
463
+ nonce = cli_shared .get_current_nonce_for_address (sender .address , args .proxy )
464
+ else :
465
+ nonce = int (args .nonce )
466
+
467
+ guardian = cli_shared .load_guardian_account (args )
468
+ guardian_address = cli_shared .get_guardian_address (guardian , args )
469
+
470
+ relayer = cli_shared .load_relayer_account (args )
471
+ relayer_address = cli_shared .get_relayer_address (relayer , args )
472
+
434
473
config = TransactionsFactoryConfig (args .chain )
435
474
abi = Abi .load (Path (args .abi )) if args .abi else None
436
475
contract = SmartContract (config , abi )
@@ -450,24 +489,23 @@ def upgrade(args: Any):
450
489
payable_by_sc = args .metadata_payable_by_sc ,
451
490
gas_limit = int (args .gas_limit ),
452
491
value = int (args .value ),
453
- nonce = int ( args . nonce ) ,
492
+ nonce = nonce ,
454
493
version = int (args .version ),
455
494
options = int (args .options ),
456
- guardian = args .guardian ,
495
+ guardian = guardian_address ,
496
+ relayer = relayer_address ,
457
497
)
458
- tx = _sign_guarded_tx (args , tx )
498
+ tx = _sign_guarded_tx_if_guardian (guardian , args , tx )
499
+ _sign_relayed_tx_if_relayer (relayer , tx )
459
500
460
501
_send_or_simulate (tx , contract_address , args )
461
502
462
503
463
504
def query (args : Any ):
464
505
logger .debug ("query" )
465
506
466
- # workaround so we can use the function below to set chainID
467
- args .chain = ""
468
- cli_shared .prepare_chain_id_in_args (args )
469
-
470
- factory_config = TransactionsFactoryConfig (args .chain )
507
+ # we don't need chainID to query a contract; we use the provided proxy
508
+ factory_config = TransactionsFactoryConfig ("" )
471
509
abi = Abi .load (Path (args .abi )) if args .abi else None
472
510
contract = SmartContract (factory_config , abi )
473
511
@@ -504,14 +542,14 @@ def _get_contract_arguments(args: Any) -> tuple[list[Any], bool]:
504
542
return args .arguments , True
505
543
506
544
507
- def _send_or_simulate (tx : Transaction , contract_address : IAddress , args : Any ):
545
+ def _send_or_simulate (tx : Transaction , contract_address : Address , args : Any ):
508
546
output_builder = cli_shared .send_or_simulate (tx , args , dump_output = False )
509
547
output_builder .set_contract_address (contract_address )
510
548
utils .dump_out_json (output_builder .build (), outfile = args .outfile )
511
549
512
550
513
551
def verify (args : Any ) -> None :
514
- contract = Address .from_bech32 (args .contract )
552
+ contract = Address .new_from_bech32 (args .contract )
515
553
verifier_url = args .verifier_url
516
554
517
555
packaged_src = Path (args .packaged_src ).expanduser ().resolve ()
0 commit comments