Skip to content

Commit

Permalink
Merge pull request #468 from multiversx/revert-466-integrate-sdk-py-v1
Browse files Browse the repository at this point in the history
Revert "Integrate latest sdk-py v1"
  • Loading branch information
popenta authored Jan 29, 2025
2 parents de9754c + 40f75cb commit 704bcf4
Show file tree
Hide file tree
Showing 15 changed files with 168 additions and 122 deletions.
25 changes: 17 additions & 8 deletions multiversx_sdk_cli/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
from pathlib import Path
from typing import Any, Optional, Protocol

from multiversx_sdk import (Address, Message, MessageComputer, Transaction,
TransactionComputer, UserSigner, AccountOnNetwork)
from multiversx_sdk import (Address, Message, MessageComputer,
TransactionComputer, UserSigner)
from multiversx_sdk.network_providers.accounts import AccountOnNetwork

from multiversx_sdk_cli.config import get_address_hrp
from multiversx_sdk_cli.interfaces import IAccount, IAddress
from multiversx_sdk_cli.interfaces import IAccount, IAddress, ITransaction
from multiversx_sdk_cli.ledger.config import compare_versions
from multiversx_sdk_cli.ledger.ledger_app_handler import \
SIGN_USING_HASH_VERSION
Expand All @@ -19,12 +20,20 @@


class INetworkProvider(Protocol):
def get_account(self, address: Address) -> AccountOnNetwork:
def get_account(self, address: IAddress) -> AccountOnNetwork:
...


class EmptyAddress(IAddress):
def to_hex(self) -> str:
return ""

def to_bech32(self) -> str:
return ""


class AccountBase(IAccount):
def __init__(self, address: Any = Address.empty()) -> None:
def __init__(self, address: Any = EmptyAddress()) -> None:
self.address = address
self.nonce: int = 0

Expand All @@ -33,7 +42,7 @@ def sync_nonce(self, proxy: INetworkProvider):
self.nonce = proxy.get_account(self.address).nonce
logger.debug(f"AccountBase.sync_nonce() done: {self.nonce}")

def sign_transaction(self, transaction: Transaction) -> str:
def sign_transaction(self, transaction: ITransaction) -> str:
raise NotImplementedError

def sign_message(self, data: bytes) -> str:
Expand All @@ -58,7 +67,7 @@ def __init__(self,
self.signer = UserSigner.from_wallet(key_file_path, password)
self.address = Address(self.signer.get_pubkey().buffer, get_address_hrp())

def sign_transaction(self, transaction: Transaction) -> str:
def sign_transaction(self, transaction: ITransaction) -> str:
assert self.signer is not None

transaction_computer = TransactionComputer()
Expand All @@ -84,7 +93,7 @@ def __init__(self, account_index: int = 0, address_index: int = 0) -> None:
self.address_index = address_index
self.address = Address.new_from_bech32(do_get_ledger_address(account_index=account_index, address_index=address_index))

def sign_transaction(self, transaction: Transaction) -> str:
def sign_transaction(self, transaction: ITransaction) -> str:
ledger_version = do_get_ledger_version()
should_use_hash_signing = compare_versions(ledger_version, SIGN_USING_HASH_VERSION) >= 0

Expand Down
2 changes: 1 addition & 1 deletion multiversx_sdk_cli/cli_accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ def get_account(args: Any):
elif args.username:
print(account.username)
else:
utils.dump_out_json(account.raw)
utils.dump_out_json(account.to_dictionary())
19 changes: 10 additions & 9 deletions multiversx_sdk_cli/cli_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
from collections import OrderedDict
from typing import Any, Dict, List, Optional, Union

from multiversx_sdk import Transaction, TransactionOnNetwork
from multiversx_sdk import TransactionsConverter

from multiversx_sdk_cli import utils
from multiversx_sdk_cli.interfaces import IAddress
from multiversx_sdk_cli.interfaces import IAddress, ITransaction
from multiversx_sdk_cli.utils import ISerializable

logger = logging.getLogger("cli.output")
Expand All @@ -15,18 +15,18 @@
class CLIOutputBuilder:
def __init__(self) -> None:
self.emitted_transaction_hash: Optional[str] = None
self.emitted_transaction: Union[Transaction, None] = None
self.emitted_transaction: Union[ITransaction, None] = None
self.emitted_transaction_omitted_fields: List[str] = []
self.contract_address: Union[IAddress, None] = None
self.transaction_on_network: Union[TransactionOnNetwork, None] = None
self.transaction_on_network: Union[ISerializable, None] = None
self.transaction_on_network_omitted_fields: List[str] = []
self.simulation_results: Union[ISerializable, None] = None

def set_emitted_transaction_hash(self, hash: str):
self.emitted_transaction_hash = hash
return self

def set_emitted_transaction(self, emitted_transaction: Transaction, omitted_fields: List[str] = []):
def set_emitted_transaction(self, emitted_transaction: ITransaction, omitted_fields: List[str] = []):
self.emitted_transaction = emitted_transaction
self.emitted_transaction_omitted_fields = omitted_fields
return self
Expand All @@ -35,10 +35,10 @@ def set_contract_address(self, contract_address: IAddress):
self.contract_address = contract_address
return self

def set_awaited_transaction(self, awaited_transaction: TransactionOnNetwork, omitted_fields: List[str] = []):
def set_awaited_transaction(self, awaited_transaction: ISerializable, omitted_fields: List[str] = []):
return self.set_transaction_on_network(awaited_transaction, omitted_fields)

def set_transaction_on_network(self, transaction_on_network: TransactionOnNetwork, omitted_fields: List[str] = []):
def set_transaction_on_network(self, transaction_on_network: ISerializable, omitted_fields: List[str] = []):
self.transaction_on_network = transaction_on_network
self.transaction_on_network_omitted_fields = omitted_fields
return self
Expand All @@ -51,7 +51,8 @@ def build(self) -> Dict[str, Any]:
output: Dict[str, Any] = OrderedDict()

if self.emitted_transaction:
emitted_transaction_dict = self.emitted_transaction.to_dictionary()
tx_converter = TransactionsConverter()
emitted_transaction_dict = tx_converter.transaction_to_dictionary(self.emitted_transaction)
emitted_transaction_hash = self.emitted_transaction_hash or ""
emitted_transaction_data = self.emitted_transaction.data.decode()
utils.omit_fields(emitted_transaction_dict, self.emitted_transaction_omitted_fields)
Expand All @@ -65,7 +66,7 @@ def build(self) -> Dict[str, Any]:
output["contractAddress"] = contract_address

if self.transaction_on_network:
transaction_on_network_dict = self.transaction_on_network.raw
transaction_on_network_dict = self.transaction_on_network.to_dictionary()
utils.omit_fields(transaction_on_network_dict, self.transaction_on_network_omitted_fields)
output["transactionOnNetwork"] = transaction_on_network_dict

Expand Down
6 changes: 3 additions & 3 deletions multiversx_sdk_cli/cli_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from argparse import FileType
from typing import Any, Dict, List, Text, cast

from multiversx_sdk import Address, ProxyNetworkProvider, Transaction
from multiversx_sdk import Address, ProxyNetworkProvider

from multiversx_sdk_cli import config, errors, utils
from multiversx_sdk_cli.accounts import Account, LedgerAccount
Expand Down Expand Up @@ -290,7 +290,7 @@ def check_options_for_guarded_tx(options: int):
raise errors.BadUsage("Invalid guarded transaction's options. The second least significant bit must be set")


def send_or_simulate(tx: Transaction, args: Any, dump_output: bool = True) -> CLIOutputBuilder:
def send_or_simulate(tx: ITransaction, args: Any, dump_output: bool = True) -> CLIOutputBuilder:
network_provider_config = config.get_config_for_network_providers()
proxy = ProxyNetworkProvider(url=args.proxy, config=network_provider_config)

Expand All @@ -312,7 +312,7 @@ def send_or_simulate(tx: Transaction, args: Any, dump_output: bool = True) -> CL
output_builder.set_awaited_transaction(transaction_on_network)
elif send_only:
hash = proxy.send_transaction(tx)
output_builder.set_emitted_transaction_hash(hash.hex())
output_builder.set_emitted_transaction_hash(hash)
elif simulate:
simulation = Simulator(proxy).run(tx)
output_builder.set_simulation_results(simulation)
Expand Down
6 changes: 3 additions & 3 deletions multiversx_sdk_cli/cli_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def send_transaction(args: Any):

try:
tx_hash = proxy.send_transaction(tx)
output.set_emitted_transaction_hash(tx_hash.hex())
output.set_emitted_transaction_hash(tx_hash)
finally:
output = output.set_emitted_transaction(tx).build()
utils.dump_out_json(output, outfile=args.outfile)
Expand All @@ -120,7 +120,7 @@ def get_transaction(args: Any):
config = get_config_for_network_providers()
proxy = ProxyNetworkProvider(url=args.proxy, config=config)

transaction = proxy.get_transaction(args.hash)
transaction = proxy.get_transaction(args.hash, True)
output = CLIOutputBuilder().set_transaction_on_network(transaction, omit_fields).build()
utils.dump_out_json(output)

Expand Down Expand Up @@ -162,7 +162,7 @@ def relay_transaction(args: Any):
tx = load_transaction_from_file(args.infile)
relayer = cli_shared.prepare_relayer_account(args)

if tx.relayer != relayer.address:
if tx.relayer != relayer.address.to_bech32():
raise IncorrectWalletError("Relayer wallet does not match the relayer's address set in the transaction.")

tx.relayer_signature = bytes.fromhex(relayer.sign_transaction(tx))
Expand Down
65 changes: 40 additions & 25 deletions multiversx_sdk_cli/contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
from pathlib import Path
from typing import Any, List, Optional, Protocol, Union

from multiversx_sdk import (Address,
SmartContractController, SmartContractQuery, SmartContractQueryResponse,
from multiversx_sdk import (Address, QueryRunnerAdapter,
SmartContractQueriesController,
SmartContractTransactionsFactory, Token,
TokenComputer, TokenTransfer, Transaction, TransactionsFactoryConfig, TransactionOnNetwork, AwaitingOptions)
from multiversx_sdk.abi import Abi, BytesValue, BigUIntValue, AddressValue, BoolValue, StringValue
TokenComputer, TokenTransfer, Transaction,
TransactionPayload)
from multiversx_sdk.abi import Abi

from multiversx_sdk_cli import errors
from multiversx_sdk_cli.accounts import Account
from multiversx_sdk_cli.config import get_address_hrp
from multiversx_sdk_cli.interfaces import IAddress

logger = logging.getLogger("contracts")

Expand All @@ -21,19 +23,31 @@


class INetworkProvider(Protocol):
def query_contract(self, query: SmartContractQuery) -> SmartContractQueryResponse:
def query_contract(self, query: Any) -> 'IContractQueryResponse':
...

def await_transaction_completed(
self, transaction_hash: Union[bytes, str], options: Optional[AwaitingOptions] = None
) -> TransactionOnNetwork:

class IContractQueryResponse(Protocol):
return_data: List[str]
return_code: str
return_message: str
gas_used: int

def get_return_data_parts(self) -> List[bytes]:
...


class IConfig(Protocol):
chain_id: str
min_gas_limit: int
gas_limit_per_byte: int
gas_limit_claim_developer_rewards: int
gas_limit_change_owner_address: int


class SmartContract:
def __init__(self, config: TransactionsFactoryConfig, abi: Optional[Abi] = None):
def __init__(self, config: IConfig, abi: Optional[Abi] = None):
self._abi = abi
self._config = config
self._factory = SmartContractTransactionsFactory(config, abi)

def prepare_deploy_transaction(self,
Expand All @@ -50,7 +64,7 @@ def prepare_deploy_transaction(self,
nonce: int,
version: int,
options: int,
guardian: Address) -> Transaction:
guardian: str) -> Transaction:
args = arguments if arguments else []
if should_prepare_args:
args = self._prepare_args_for_factory(args)
Expand Down Expand Up @@ -86,7 +100,7 @@ def prepare_execute_transaction(self,
nonce: int,
version: int,
options: int,
guardian: Address) -> Transaction:
guardian: str) -> Transaction:
token_transfers = self._prepare_token_transfers(transfers) if transfers else []

args = arguments if arguments else []
Expand All @@ -112,7 +126,7 @@ def prepare_execute_transaction(self,

def prepare_upgrade_transaction(self,
owner: Account,
contract: Address,
contract: IAddress,
bytecode: Path,
arguments: Union[List[str], None],
should_prepare_args: bool,
Expand All @@ -125,7 +139,7 @@ def prepare_upgrade_transaction(self,
nonce: int,
version: int,
options: int,
guardian: Address) -> Transaction:
guardian: str) -> Transaction:
args = arguments if arguments else []
if should_prepare_args:
args = self._prepare_args_for_factory(args)
Expand All @@ -151,7 +165,7 @@ def prepare_upgrade_transaction(self,
return tx

def query_contract(self,
contract_address: Address,
contract_address: IAddress,
proxy: INetworkProvider,
function: str,
arguments: Optional[List[Any]],
Expand All @@ -160,11 +174,12 @@ def query_contract(self,
if should_prepare_args:
args = self._prepare_args_for_factory(args)

sc_query_controller = SmartContractController(self._config.chain_id, proxy, self._abi)
query_runner = QueryRunnerAdapter(proxy)
sc_query_controller = SmartContractQueriesController(query_runner, self._abi)

try:
response = sc_query_controller.query(
contract=contract_address,
contract=contract_address.to_bech32(),
function=function,
arguments=args
)
Expand Down Expand Up @@ -193,17 +208,17 @@ def _prepare_args_for_factory(self, arguments: List[str]) -> List[Any]:

for arg in arguments:
if arg.startswith(HEX_PREFIX):
args.append(BytesValue(self._hex_to_bytes(arg)))
args.append(self._hex_to_bytes(arg))
elif arg.isnumeric():
args.append(BigUIntValue(int(arg)))
args.append(int(arg))
elif arg.startswith(get_address_hrp()):
args.append(AddressValue.new_from_address(Address.new_from_bech32(arg)))
args.append(Address.new_from_bech32(arg))
elif arg.lower() == FALSE_STR_LOWER:
args.append(BoolValue(False))
args.append(False)
elif arg.lower() == TRUE_STR_LOWER:
args.append(BoolValue(True))
args.append(True)
elif arg.startswith(STR_PREFIX):
args.append(StringValue(arg[len(STR_PREFIX):]))
args.append(arg[len(STR_PREFIX):])
else:
raise errors.BadUserInput(f"Unknown argument type for argument: `{arg}`. Use `mxpy contract <sub-command> --help` to check all supported arguments")

Expand All @@ -216,13 +231,13 @@ def _hex_to_bytes(self, arg: str):
return bytes.fromhex(argument)


def prepare_execute_transaction_data(function: str, arguments: List[Any]) -> str:
def prepare_execute_transaction_data(function: str, arguments: List[Any]) -> TransactionPayload:
tx_data = function

for arg in arguments:
tx_data += f"@{_prepare_argument(arg)}"

return tx_data
return TransactionPayload.from_str(tx_data)


# only used for stake operations
Expand Down
8 changes: 5 additions & 3 deletions multiversx_sdk_cli/cosign_transaction.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
from typing import Any

from multiversx_sdk import Transaction
import requests
from multiversx_sdk import TransactionsConverter

from multiversx_sdk_cli.errors import GuardianServiceError
from multiversx_sdk_cli.interfaces import ITransaction


def cosign_transaction(transaction: Transaction, service_url: str, guardian_code: str) -> Transaction:
def cosign_transaction(transaction: ITransaction, service_url: str, guardian_code: str) -> ITransaction:
tx_converter = TransactionsConverter()
payload = {
"code": f"{guardian_code}",
"transactions": [transaction.to_dictionary()]
"transactions": [tx_converter.transaction_to_dictionary(transaction)]
}

# we call sign-multiple-transactions to be allowed a bigger payload (e.g. deploying large contracts)
Expand Down
Loading

0 comments on commit 704bcf4

Please sign in to comment.