From e42c433ded3ec7ff2a5422ff65ce9958580bd49b Mon Sep 17 00:00:00 2001 From: obrusvit Date: Fri, 27 Sep 2024 13:08:48 +0200 Subject: [PATCH] feat(cardano): ask detail lvl only on complex tx - remove the choise of detail level ("Show simple" vs "Show all") when signing simple transactions - these are the transactions typically enabled by TrezorSuite. --- .../apps/cardano/sign_tx/ordinary_signer.py | 96 ++++++++++++++++--- core/src/apps/cardano/sign_tx/signer.py | 26 +++++ 2 files changed, 108 insertions(+), 14 deletions(-) diff --git a/core/src/apps/cardano/sign_tx/ordinary_signer.py b/core/src/apps/cardano/sign_tx/ordinary_signer.py index 4c7d24b819..4cedd4b942 100644 --- a/core/src/apps/cardano/sign_tx/ordinary_signer.py +++ b/core/src/apps/cardano/sign_tx/ordinary_signer.py @@ -3,9 +3,9 @@ from typing import TYPE_CHECKING from trezor import TR from trezor.wire import ProcessError -from .. import layout +from .. import layout, seed from ..helpers.paths import SCHEMA_MINT -from .signer import Signer +from .signer import Signer, SuiteTxType if TYPE_CHECKING: from trezor import messages @@ -19,6 +19,14 @@ class OrdinarySigner(Signer): SIGNING_MODE_TITLE = TR.cardano__confirming_transction + def __init__( + self, + msg: messages.CardanoSignTxInit, + keychain: seed.Keychain, + ): + super().__init__(msg, keychain) + self.suite_tx_type: SuiteTxType = self._suite_tx_type() + def _validate_tx_init(self) -> None: msg = self.msg # local_cache_attribute _assert_tx_init_cond = self._assert_tx_init_cond # local_cache_attribute @@ -29,21 +37,81 @@ class OrdinarySigner(Signer): _assert_tx_init_cond(msg.total_collateral is None) _assert_tx_init_cond(msg.reference_inputs_count == 0) - async def _confirm_tx(self, tx_hash: bytes) -> None: + def _suite_tx_type(self) -> SuiteTxType: msg = self.msg # local_cache_attribute + # NOTE: witness_request_count equals the number of inputs + # NOTE: what about required_signer? + if ( + msg.minting_asset_groups_count > 0 + or msg.required_signers_count > 0 + or msg.has_auxiliary_data + ): + # transaction has more advanced features + return SuiteTxType.NOT_SUITE_TX + if ( + msg.withdrawals_count > 0 + and msg.certificates_count == 0 + and msg.outputs_count == 1 + ): + return SuiteTxType.SIMPLE_STAKE_WITHDRAW + if ( + msg.withdrawals_count == 0 + and msg.certificates_count > 0 + and msg.outputs_count == 1 + ): + return SuiteTxType.SIMPLE_STAKE_DELEGATE + if ( + msg.withdrawals_count == 0 + and msg.certificates_count == 0 + and msg.outputs_count > 0 + ): + return SuiteTxType.SIMPLE_SEND + + return SuiteTxType.NOT_SUITE_TX + + async def _show_tx_init(self) -> None: # super() omitted intentionally - is_network_id_verifiable = self._is_network_id_verifiable() - await layout.confirm_tx( - msg.fee, - msg.network_id, - msg.protocol_magic, - msg.ttl, - msg.validity_interval_start, - msg.total_collateral, - is_network_id_verifiable, - tx_hash=None, - ) + # for OrdinarySigner, we do not show the prompt to choose level of details + if self.suite_tx_type is SuiteTxType.NOT_SUITE_TX: + self.should_show_details = await layout.show_tx_init( + self.SIGNING_MODE_TITLE + ) + elif self.suite_tx_type in ( + SuiteTxType.SIMPLE_STAKE_WITHDRAW, + SuiteTxType.SIMPLE_STAKE_DELEGATE, + ): + self.should_show_details = True + else: + self.should_show_details = False + + if not self._is_network_id_verifiable(): + await layout.warn_tx_network_unverifiable() + + async def _confirm_tx(self, tx_hash: bytes) -> None: + # super() omitted intentionally + msg = self.msg # local_cache_attribute + if self.suite_tx_type is SuiteTxType.SIMPLE_SEND: + await layout.confirm_tx( + self.total_amount, + msg.fee, + msg.network_id, + msg.protocol_magic, + msg.ttl, + msg.validity_interval_start, + ) + else: + is_network_id_verifiable = self._is_network_id_verifiable() + await layout.confirm_tx_details( + msg.network_id, + msg.protocol_magic, + msg.ttl, + msg.fee, + msg.validity_interval_start, + msg.total_collateral, + is_network_id_verifiable, + tx_hash=None, + ) def _validate_certificate(self, certificate: messages.CardanoTxCertificate) -> None: from trezor.enums import CardanoCertificateType diff --git a/core/src/apps/cardano/sign_tx/signer.py b/core/src/apps/cardano/sign_tx/signer.py index 7ef83a320a..336572a2b2 100644 --- a/core/src/apps/cardano/sign_tx/signer.py +++ b/core/src/apps/cardano/sign_tx/signer.py @@ -25,6 +25,7 @@ from ..helpers.paths import SCHEMA_STAKING from ..helpers.utils import derive_public_key if TYPE_CHECKING: + from enum import IntEnum from typing import Any, Awaitable, ClassVar from trezor.enums import CardanoAddressType @@ -35,6 +36,9 @@ if TYPE_CHECKING: from ..helpers.hash_builder_collection import HashBuilderEmbeddedCBOR CardanoTxResponseType = CardanoTxItemAck | messages.CardanoTxWitnessResponse +else: + IntEnum = object + _MINTING_POLICY_ID_LENGTH = const(28) _MAX_ASSET_NAME_LENGTH = const(32) @@ -69,6 +73,22 @@ _POOL_REGISTRATION_CERTIFICATE_ITEMS_COUNT = const(10) _MAX_CHUNK_SIZE = const(1024) +class SuiteTxType(IntEnum): + """ + The `SuiteTxType` class is an enumeration that serves to categorize transactions initiated by TrezorSuite. + + - `SIMPLE_SEND`: Represents a send transaction (possibly to multiple recipients) with no additional features. + - `SIMPLE_STAKE_DELEGATE`: Represents a simple stake delegation transaction with no additional features. + - `SIMPLE_STAKE_WITHDRAW`: Represents a simple stake withdrawal transaction with no additional features. + - `NOT_SUITE_TX`: Represents a transaction that is not a suite transaction. + """ + + SIMPLE_SEND = 0 + SIMPLE_STAKE_DELEGATE = 1 + SIMPLE_STAKE_WITHDRAW = 2 + NOT_SUITE_TX = 3 + + class Signer: """ This class encapsulates the entire tx signing process. By default, most tx items are @@ -117,6 +137,7 @@ class Signer: tx_dict_items_count, ProcessError("Invalid tx signing request") ) + self.suite_tx_type = SuiteTxType.NOT_SUITE_TX self.should_show_details = False async def sign(self) -> None: @@ -236,6 +257,7 @@ class Signer: raise ProcessError("Total collateral is out of range!") validate_network_info(msg.network_id, msg.protocol_magic) + async def _show_tx_init(self) -> None: self.should_show_details = await layout.show_tx_init(self.SIGNING_MODE_TITLE) @@ -373,6 +395,10 @@ class Signer: assert output.address is not None # _validate_output address = output.address + if self.suite_tx_type == SuiteTxType.SIMPLE_SEND: + output_type = n + else: + output_type = "change" if self._is_change_output(output) else "address" await layout.confirm_sending( output.amount, address,