From cb6734becf16deb8763c904f5d8df98f41407bf6 Mon Sep 17 00:00:00 2001
From: Alexandru Popenta <alexandru.p9913@gmail.com>
Date: Tue, 7 Nov 2023 12:43:47 +0200
Subject: [PATCH] fixes

---
 multiversx_sdk_cli/accounts.py             | 11 ++++--
 multiversx_sdk_cli/cli_delegation.py       |  2 +-
 multiversx_sdk_cli/cli_output.py           |  7 ++--
 multiversx_sdk_cli/contracts.py            | 30 ++++++++--------
 multiversx_sdk_cli/cosign_transaction.py   |  2 +-
 multiversx_sdk_cli/interfaces.py           | 40 ++++++++--------------
 multiversx_sdk_cli/tests/test_contracts.py |  2 +-
 multiversx_sdk_cli/transactions.py         | 30 ++++++++--------
 multiversx_sdk_cli/utils.py                |  6 +++-
 9 files changed, 66 insertions(+), 64 deletions(-)

diff --git a/multiversx_sdk_cli/accounts.py b/multiversx_sdk_cli/accounts.py
index 40adf2f4..bb563ae5 100644
--- a/multiversx_sdk_cli/accounts.py
+++ b/multiversx_sdk_cli/accounts.py
@@ -2,7 +2,8 @@
 from pathlib import Path
 from typing import Any, Optional, Protocol
 
-from multiversx_sdk_core import Address, Message, MessageComputer
+from multiversx_sdk_core import (Address, Message, MessageComputer,
+                                 TransactionComputer)
 from multiversx_sdk_network_providers.accounts import AccountOnNetwork
 from multiversx_sdk_wallet import UserSigner
 
@@ -69,7 +70,9 @@ def __init__(self,
 
     def sign_transaction(self, transaction: ITransaction) -> str:
         assert self.signer is not None
-        return self.signer.sign(transaction.serialize_for_signing()).hex()
+
+        transaction_computer = TransactionComputer()
+        return self.signer.sign(transaction_computer.compute_bytes_for_signing(transaction)).hex()
 
     def sign_message(self, data: bytes) -> str:
         assert self.signer is not None
@@ -95,8 +98,10 @@ def sign_transaction(self, transaction: ITransaction) -> str:
             transaction.version = TX_HASH_SIGN_VERSION
             transaction.options = TX_HASH_SIGN_OPTIONS
 
+        transaction_computer = TransactionComputer()
+
         signature = do_sign_transaction_with_ledger(
-            transaction.serialize_for_signing(),
+            transaction_computer.compute_bytes_for_signing(transaction),
             account_index=self.account_index,
             address_index=self.address_index,
             sign_using_hash=should_use_hash_signing
diff --git a/multiversx_sdk_cli/cli_delegation.py b/multiversx_sdk_cli/cli_delegation.py
index c0728ace..6b781e52 100644
--- a/multiversx_sdk_cli/cli_delegation.py
+++ b/multiversx_sdk_cli/cli_delegation.py
@@ -159,7 +159,7 @@ def get_contract_address_by_deploy_tx_hash(args: Any):
     transaction_events = transaction.logs.events
     if len(transaction_events) == 1:
         contract_address = transaction_events[0].address
-        print(contract_address.bech32())
+        print(contract_address.to_bech32())
     else:
         raise errors.ProgrammingError("Tx has more than one event. Make sure it's a staking provider SC Deploy transaction.")
 
diff --git a/multiversx_sdk_cli/cli_output.py b/multiversx_sdk_cli/cli_output.py
index 4d5abf64..36fb6ffe 100644
--- a/multiversx_sdk_cli/cli_output.py
+++ b/multiversx_sdk_cli/cli_output.py
@@ -51,12 +51,15 @@ def build(self) -> Dict[str, Any]:
         output: Dict[str, Any] = OrderedDict()
 
         if self.emitted_transaction:
-            emitted_transaction_dict = self.emitted_transaction.to_dictionary()
+            emitted_transaction_dict = self.emitted_transaction.__dict__
             emitted_transaction_hash = self.emitted_transaction_hash or ""
-            emitted_transaction_data = str(self.emitted_transaction.data)
+            emitted_transaction_data = self.emitted_transaction.data.decode()
             utils.omit_fields(emitted_transaction_dict, self.emitted_transaction_omitted_fields)
 
             output["emittedTransaction"] = emitted_transaction_dict
+            signature: bytes = output["emittedTransaction"]["signature"]
+            output["emittedTransaction"]["signature"] = signature.hex() if type(signature) is not str else signature
+
             output["emittedTransactionData"] = emitted_transaction_data
             output["emittedTransactionHash"] = emitted_transaction_hash
 
diff --git a/multiversx_sdk_cli/contracts.py b/multiversx_sdk_cli/contracts.py
index 4650c8a3..6575ce77 100644
--- a/multiversx_sdk_cli/contracts.py
+++ b/multiversx_sdk_cli/contracts.py
@@ -79,19 +79,19 @@ def deploy(self, owner: Account, arguments: List[Any], gas_price: int, gas_limit
 
         tx = Transaction(
             chain_id=chain,
-            sender=owner.address,
-            receiver=Address.new_from_bech32(ADDRESS_ZERO_BECH32),
+            sender=owner.address.to_bech32(),
+            receiver=ADDRESS_ZERO_BECH32,
             gas_limit=gas_limit,
             gas_price=gas_price,
             nonce=owner.nonce,
-            value=value,
-            data=self.prepare_deploy_transaction_data(arguments),
+            amount=value,
+            data=self.prepare_deploy_transaction_data(arguments).data,
             version=version,
             options=options
         )
 
         if guardian:
-            tx.guardian = Address.from_bech32(guardian)
+            tx.guardian = guardian
 
         tx.signature = bytes.fromhex(owner.sign_transaction(tx))
         return tx
@@ -115,19 +115,19 @@ def execute(self, caller: Account, function: str, arguments: List[str], gas_pric
 
         tx = Transaction(
             chain_id=chain,
-            sender=caller.address,
-            receiver=receiver,
+            sender=caller.address.to_bech32(),
+            receiver=receiver.to_bech32(),
             gas_limit=gas_limit,
             gas_price=gas_price,
             nonce=caller.nonce,
-            value=value,
-            data=self.prepare_execute_transaction_data(function, arguments),
+            amount=value,
+            data=self.prepare_execute_transaction_data(function, arguments).data,
             version=version,
             options=options
         )
 
         if guardian:
-            tx.guardian = Address.from_bech32(guardian)
+            tx.guardian = guardian
 
         tx.signature = bytes.fromhex(caller.sign_transaction(tx))
         return tx
@@ -151,19 +151,19 @@ def upgrade(self, owner: Account, arguments: List[Any], gas_price: int, gas_limi
 
         tx = Transaction(
             chain_id=chain,
-            sender=owner.address,
-            receiver=receiver,
+            sender=owner.address.to_bech32(),
+            receiver=receiver.to_bech32(),
             gas_limit=gas_limit,
             gas_price=gas_price,
             nonce=owner.nonce,
-            value=value,
-            data=self.prepare_upgrade_transaction_data(arguments),
+            amount=value,
+            data=self.prepare_upgrade_transaction_data(arguments).data,
             version=version,
             options=options
         )
 
         if guardian:
-            tx.guardian = Address.from_bech32(guardian)
+            tx.guardian = guardian
 
         tx.signature = bytes.fromhex(owner.sign_transaction(tx))
         return tx
diff --git a/multiversx_sdk_cli/cosign_transaction.py b/multiversx_sdk_cli/cosign_transaction.py
index 6c5383dc..26aada47 100644
--- a/multiversx_sdk_cli/cosign_transaction.py
+++ b/multiversx_sdk_cli/cosign_transaction.py
@@ -9,7 +9,7 @@
 def cosign_transaction(transaction: ITransaction, service_url: str, guardian_code: str) -> ITransaction:
     payload = {
         "code": f"{guardian_code}",
-        "transaction": transaction.to_dictionary()
+        "transaction": transaction.__dict__
     }
 
     url = f"{service_url}/sign-transaction"
diff --git a/multiversx_sdk_cli/interfaces.py b/multiversx_sdk_cli/interfaces.py
index 7e085b43..9e736b17 100644
--- a/multiversx_sdk_cli/interfaces.py
+++ b/multiversx_sdk_cli/interfaces.py
@@ -9,32 +9,22 @@ def to_bech32(self) -> str:
         ...
 
 
-ITransactionOptions = int
-ITransactionVersion = int
-ISignature = bytes
-
-
-class ITransactionPayload(Protocol):
-    data: bytes
-    def encoded(self) -> str: ...
-    def length(self) -> int: ...
-
-
 class ITransaction(Protocol):
-    version: ITransactionVersion
-    options: ITransactionOptions
-    signature: ISignature
-    guardian_signature: ISignature
-
-    @property
-    def data(self) -> ITransactionPayload:
-        ...
-
-    def serialize_for_signing(self) -> bytes:
-        ...
-
-    def to_dictionary(self, with_signature: bool = True) -> Dict[str, Any]:
-        ...
+    sender: str
+    receiver: str
+    gas_limit: int
+    chain_id: str
+    nonce: int
+    amount: int
+    sender_username: str
+    receiver_username: str
+    gas_price: int
+    data: bytes
+    version: int
+    options: int
+    guardian: str
+    signature: bytes
+    guardian_signature: bytes
 
 
 class IAccount(Protocol):
diff --git a/multiversx_sdk_cli/tests/test_contracts.py b/multiversx_sdk_cli/tests/test_contracts.py
index 2ea5674f..f6eed78d 100644
--- a/multiversx_sdk_cli/tests/test_contracts.py
+++ b/multiversx_sdk_cli/tests/test_contracts.py
@@ -35,7 +35,7 @@ def test_compute_address():
     assert contract.address.bech32() == "erd1qqqqqqqqqqqqqpgqhdjjyq8dr7v5yq9tv6v5vt9tfvd00vg7h40q6779zn"
 
     contract.owner.nonce = 1
-    contract.address = address_computer.compute_contract_address(contract.owner.address, contract.owner.nonce DEFAULT_HRP)
+    contract.address = address_computer.compute_contract_address(contract.owner.address, contract.owner.nonce)
     assert contract.address.hex() == "000000000000000005006e4f90488e27342f9a46e1809452c85ee7186566bd5e"
     assert contract.address.bech32() == "erd1qqqqqqqqqqqqqpgqde8eqjywyu6zlxjxuxqfg5kgtmn3setxh40qen8egy"
 
diff --git a/multiversx_sdk_cli/transactions.py b/multiversx_sdk_cli/transactions.py
index 5b8d2a9f..ba2cceee 100644
--- a/multiversx_sdk_cli/transactions.py
+++ b/multiversx_sdk_cli/transactions.py
@@ -69,21 +69,21 @@ def do_prepare_transaction(args: Any) -> Transaction:
 
     tx = Transaction(
         chain_id=args.chain,
-        sender=account.address,
-        receiver=Address.from_bech32(args.receiver),
+        sender=account.address.to_bech32(),
+        receiver=args.receiver,
         gas_limit=int(args.gas_limit),
         sender_username=getattr(args, "sender_username", ""),
         receiver_username=getattr(args, "receiver_username", ""),
         gas_price=int(args.gas_price),
-        data=TransactionPayload.from_str(args.data),
+        data=TransactionPayload.from_str(args.data).data,
         nonce=int(args.nonce),
-        value=int(args.value),
+        amount=int(args.value),
         version=int(args.version),
         options=int(args.options)
     )
 
     if args.guardian:
-        tx.guardian = Address.from_bech32(args.guardian)
+        tx.guardian = args.guardian
 
     tx.signature = bytes.fromhex(account.sign_transaction(tx))
     tx = sign_tx_by_guardian(args, tx)
@@ -148,12 +148,12 @@ def _send_transaction_and_wait_for_result(proxy: INetworkProvider, payload: ITra
 
 
 def tx_to_dictionary_as_inner(tx: Transaction) -> Dict[str, Any]:
-    dictionary = tx.to_dictionary()
-    dictionary["receiver"] = base64.b64encode(bytes.fromhex(tx.receiver.hex())).decode()  # type: ignore
-    dictionary["sender"] = base64.b64encode(bytes.fromhex(tx.sender.hex())).decode()  # type: ignore
-    dictionary["chainID"] = base64.b64encode(tx.chainID.encode()).decode()
+    dictionary = tx.__dict__
+    dictionary["receiver"] = base64.b64encode(Address.new_from_bech32(tx.receiver).get_public_key()).decode()
+    dictionary["sender"] = base64.b64encode(Address.new_from_bech32(tx.sender).get_public_key()).decode()
+    dictionary["chainID"] = base64.b64encode(tx.chain_id.encode()).decode()
     dictionary["signature"] = base64.b64encode(bytes(bytearray(tx.signature))).decode()
-    dictionary["value"] = tx.value
+    dictionary["value"] = tx.amount
 
     return dictionary
 
@@ -179,21 +179,21 @@ def load_transaction_from_file(f: TextIO) -> Transaction:
 
     loaded_tx = Transaction(
         chain_id=instance.chainID,
-        sender=Address.from_bech32(instance.sender),
-        receiver=Address.from_bech32(instance.receiver),
+        sender=instance.sender,
+        receiver=instance.receiver,
         sender_username=decode_field_value(instance.senderUsername),
         receiver_username=decode_field_value(instance.receiverUsername),
         gas_limit=instance.gasLimit,
         gas_price=instance.gasPrice,
-        value=int(instance.value),
-        data=TransactionPayload.from_encoded_str(instance.data),
+        amount=int(instance.value),
+        data=TransactionPayload.from_encoded_str(instance.data).data,
         version=instance.version,
         options=instance.options,
         nonce=instance.nonce
     )
 
     if instance.guardian:
-        loaded_tx.guardian = Address.from_bech32(instance.guardian)
+        loaded_tx.guardian = instance.guardian
 
     if instance.signature:
         loaded_tx.signature = bytes.fromhex(instance.signature)
diff --git a/multiversx_sdk_cli/utils.py b/multiversx_sdk_cli/utils.py
index 89ce3e5c..a4905076 100644
--- a/multiversx_sdk_cli/utils.py
+++ b/multiversx_sdk_cli/utils.py
@@ -1,3 +1,4 @@
+import base64
 import json
 import logging
 import os
@@ -40,9 +41,12 @@ def to_json(self):
 
 class BasicEncoder(json.JSONEncoder):
     def default(self, o: Any):
+        if isinstance(o, bytes):
+            # Encode bytes as a base64 string
+            return base64.b64encode(o).decode('utf-8')
         if isinstance(o, ISerializable):
             return o.to_dictionary()
-        return json.JSONEncoder.default(self, o)
+        return super().default(o)
 
 
 def omit_fields(data: Any, fields: List[str] = []):