From c0174ff21754399f6bcc7cd42c18fa06b5eb9422 Mon Sep 17 00:00:00 2001 From: Martin Milata Date: Wed, 10 Mar 2021 12:56:44 +0100 Subject: [PATCH] refactor(core/ui): raise exception on dialog cancel by default --- core/src/apps/base.py | 6 +- core/src/apps/binance/get_public_key.py | 4 +- core/src/apps/bitcoin/authorize_coinjoin.py | 30 ++-- core/src/apps/bitcoin/get_ownership_proof.py | 34 ++-- core/src/apps/bitcoin/get_public_key.py | 4 +- core/src/apps/bitcoin/sign_message.py | 4 +- core/src/apps/bitcoin/sign_tx/layout.py | 113 +++++------- core/src/apps/bitcoin/verify_message.py | 14 +- core/src/apps/cardano/get_public_key.py | 4 +- core/src/apps/common/paths.py | 4 +- core/src/apps/common/request_pin.py | 14 +- core/src/apps/common/sdcard.py | 52 +++--- core/src/apps/debug/load_device.py | 16 +- core/src/apps/ethereum/get_public_key.py | 4 +- core/src/apps/ethereum/sign_message.py | 4 +- core/src/apps/ethereum/verify_message.py | 6 +- core/src/apps/lisk/get_public_key.py | 4 +- core/src/apps/lisk/layout.py | 4 +- core/src/apps/lisk/sign_message.py | 4 +- core/src/apps/lisk/verify_message.py | 6 +- core/src/apps/management/apply_settings.py | 170 ++++++++---------- core/src/apps/management/change_pin.py | 52 +++--- core/src/apps/management/change_wipe_code.py | 4 +- .../management/recovery_device/homescreen.py | 8 +- .../apps/management/recovery_device/layout.py | 72 ++++---- .../apps/management/reset_device/__init__.py | 4 +- .../apps/management/reset_device/layout.py | 74 +++----- core/src/apps/management/sd_protect.py | 25 ++- core/src/apps/management/wipe_device.py | 4 +- core/src/apps/misc/cipher_key_value.py | 6 +- core/src/apps/misc/get_ecdh_session_key.py | 18 +- core/src/apps/misc/get_entropy.py | 18 +- core/src/apps/misc/sign_identity.py | 8 +- core/src/apps/monero/layout/confirms.py | 74 ++++---- core/src/apps/tezos/get_public_key.py | 4 +- .../apps/webauthn/add_resident_credential.py | 19 +- .../webauthn/list_resident_credentials.py | 14 +- .../trezor/ui/components/common/confirm.py | 10 +- core/src/trezor/ui/layouts/common.py | 6 - core/src/trezor/ui/layouts/tt.py | 160 +++++++++-------- 40 files changed, 489 insertions(+), 592 deletions(-) diff --git a/core/src/apps/base.py b/core/src/apps/base.py index e75a60951..42bd36023 100644 --- a/core/src/apps/base.py +++ b/core/src/apps/base.py @@ -129,12 +129,10 @@ async def handle_EndSession(ctx: wire.Context, msg: EndSession) -> Success: async def handle_Ping(ctx: wire.Context, msg: Ping) -> Success: if msg.button_protection: - from trezor.ui.layouts import require, confirm_action + from trezor.ui.layouts import confirm_action from trezor.messages.ButtonRequestType import ProtectCall - await require( - confirm_action(ctx, "ping", "Confirm", "ping", br_code=ProtectCall) - ) + await confirm_action(ctx, "ping", "Confirm", "ping", br_code=ProtectCall) return Success(message=msg.message) diff --git a/core/src/apps/binance/get_public_key.py b/core/src/apps/binance/get_public_key.py index 4c6f98c5c..b62a99d1e 100644 --- a/core/src/apps/binance/get_public_key.py +++ b/core/src/apps/binance/get_public_key.py @@ -2,7 +2,7 @@ from ubinascii import hexlify from trezor.messages.BinanceGetPublicKey import BinanceGetPublicKey from trezor.messages.BinancePublicKey import BinancePublicKey -from trezor.ui.layouts import require, show_pubkey +from trezor.ui.layouts import show_pubkey from apps.common import paths from apps.common.keychain import Keychain, auto_keychain @@ -15,6 +15,6 @@ async def get_public_key(ctx, msg: BinanceGetPublicKey, keychain: Keychain): pubkey = node.public_key() if msg.show_display: - await require(show_pubkey(ctx, hexlify(pubkey).decode())) + await show_pubkey(ctx, hexlify(pubkey).decode()) return BinancePublicKey(public_key=pubkey) diff --git a/core/src/apps/bitcoin/authorize_coinjoin.py b/core/src/apps/bitcoin/authorize_coinjoin.py index a978173b4..4a4ae63dc 100644 --- a/core/src/apps/bitcoin/authorize_coinjoin.py +++ b/core/src/apps/bitcoin/authorize_coinjoin.py @@ -4,7 +4,7 @@ from trezor import ui from trezor.messages.AuthorizeCoinJoin import AuthorizeCoinJoin from trezor.messages.Success import Success from trezor.strings import format_amount -from trezor.ui.layouts import confirm_action, confirm_coinjoin, require +from trezor.ui.layouts import confirm_action, confirm_coinjoin from apps.base import set_authorization from apps.common.paths import validate_path @@ -45,16 +45,14 @@ async def authorize_coinjoin(ctx: wire.Context, msg: AuthorizeCoinJoin) -> Succe ), ) - await require( - confirm_action( - ctx, - "coinjoin_coordinator", - title="Authorize CoinJoin", - description="Do you really want to take part in a CoinJoin transaction at:\n{}", - description_param=msg.coordinator, - description_param_font=ui.MONO, - icon=ui.ICON_RECOVERY, - ) + await confirm_action( + ctx, + "coinjoin_coordinator", + title="Authorize CoinJoin", + description="Do you really want to take part in a CoinJoin transaction at:\n{}", + description_param=msg.coordinator, + description_param_font=ui.MONO, + icon=ui.ICON_RECOVERY, ) fee_per_anonymity = None @@ -62,12 +60,10 @@ async def authorize_coinjoin(ctx: wire.Context, msg: AuthorizeCoinJoin) -> Succe fee_per_anonymity = format_amount( msg.fee_per_anonymity, FEE_PER_ANONYMITY_DECIMALS ) - await require( - confirm_coinjoin( - ctx, - fee_per_anonymity, - format_coin_amount(msg.max_total_fee, coin, msg.amount_unit), - ) + await confirm_coinjoin( + ctx, + fee_per_anonymity, + format_coin_amount(msg.max_total_fee, coin, msg.amount_unit), ) set_authorization(CoinJoinAuthorization(msg, keychain, coin)) diff --git a/core/src/apps/bitcoin/get_ownership_proof.py b/core/src/apps/bitcoin/get_ownership_proof.py index 5d46d1c36..54b72c7b2 100644 --- a/core/src/apps/bitcoin/get_ownership_proof.py +++ b/core/src/apps/bitcoin/get_ownership_proof.py @@ -3,7 +3,7 @@ from ubinascii import hexlify from trezor import ui, wire from trezor.messages.GetOwnershipProof import GetOwnershipProof from trezor.messages.OwnershipProof import OwnershipProof -from trezor.ui.layouts import confirm_action, confirm_hex, require +from trezor.ui.layouts import confirm_action, confirm_hex from apps.common.paths import validate_path @@ -65,26 +65,22 @@ async def get_ownership_proof( # In order to set the "user confirmation" bit in the proof, the user must actually confirm. if msg.user_confirmation and not authorization: if not msg.commitment_data: - await require( - confirm_action( - ctx, - "confirm_ownership_proof", - title="Proof of ownership", - description="Do you want to create a proof of ownership?", - ) + await confirm_action( + ctx, + "confirm_ownership_proof", + title="Proof of ownership", + description="Do you want to create a proof of ownership?", ) else: - await require( - confirm_hex( - ctx, - "confirm_ownership_proof", - title="Proof of ownership", - description="Do you want to create a proof of ownership for:", - data=hexlify(msg.commitment_data).decode(), - icon=ui.ICON_CONFIG, - icon_color=ui.ORANGE_ICON, - truncate_middle=True, - ) + await confirm_hex( + ctx, + "confirm_ownership_proof", + title="Proof of ownership", + description="Do you want to create a proof of ownership for:", + data=hexlify(msg.commitment_data).decode(), + icon=ui.ICON_CONFIG, + icon_color=ui.ORANGE_ICON, + truncate_middle=True, ) ownership_proof, signature = generate_proof( diff --git a/core/src/apps/bitcoin/get_public_key.py b/core/src/apps/bitcoin/get_public_key.py index f6d89d9fe..07b3fcc16 100644 --- a/core/src/apps/bitcoin/get_public_key.py +++ b/core/src/apps/bitcoin/get_public_key.py @@ -2,7 +2,7 @@ from trezor import wire from trezor.messages import InputScriptType from trezor.messages.HDNodeType import HDNodeType from trezor.messages.PublicKey import PublicKey -from trezor.ui.layouts import require, show_xpub +from trezor.ui.layouts import show_xpub from apps.common import coins, paths from apps.common.keychain import get_keychain @@ -59,7 +59,7 @@ async def get_public_key(ctx: wire.Context, msg: GetPublicKey) -> PublicKey: ) if msg.show_display: - await require(show_xpub(ctx, node_xpub, "XPUB", "Cancel")) + await show_xpub(ctx, node_xpub, "XPUB", "Cancel") return PublicKey( node=node_type, diff --git a/core/src/apps/bitcoin/sign_message.py b/core/src/apps/bitcoin/sign_message.py index 1acb660ca..8eb17a1a5 100644 --- a/core/src/apps/bitcoin/sign_message.py +++ b/core/src/apps/bitcoin/sign_message.py @@ -2,7 +2,7 @@ from trezor import wire from trezor.crypto.curve import secp256k1 from trezor.messages.InputScriptType import SPENDADDRESS, SPENDP2SHWITNESS, SPENDWITNESS from trezor.messages.MessageSignature import MessageSignature -from trezor.ui.layouts import confirm_signverify, require +from trezor.ui.layouts import confirm_signverify from apps.common.paths import validate_path from apps.common.signverify import decode_message, message_digest @@ -26,7 +26,7 @@ async def sign_message( script_type = msg.script_type or 0 await validate_path(ctx, keychain, address_n) - await require(confirm_signverify(ctx, coin.coin_shortcut, decode_message(message))) + await confirm_signverify(ctx, coin.coin_shortcut, decode_message(message)) node = keychain.derive(address_n) seckey = node.private_key() diff --git a/core/src/apps/bitcoin/sign_tx/layout.py b/core/src/apps/bitcoin/sign_tx/layout.py index 1a304dde7..2d1be1957 100644 --- a/core/src/apps/bitcoin/sign_tx/layout.py +++ b/core/src/apps/bitcoin/sign_tx/layout.py @@ -4,7 +4,6 @@ from ubinascii import hexlify from trezor.messages import AmountUnit, ButtonRequestType, OutputScriptType from trezor.strings import format_amount from trezor.ui import layouts -from trezor.ui.layouts import require from .. import addresses from . import omni @@ -70,7 +69,7 @@ async def confirm_output( ctx, address_short, format_coin_amount(output.amount, coin, amount_unit) ) - await require(layout) + await layout async def confirm_decred_sstx_submission( @@ -79,20 +78,16 @@ async def confirm_decred_sstx_submission( assert output.address is not None address_short = addresses.address_short(coin, output.address) - await require( - layouts.confirm_decred_sstx_submission( - ctx, address_short, format_coin_amount(output.amount, coin, amount_unit) - ) + await layouts.confirm_decred_sstx_submission( + ctx, address_short, format_coin_amount(output.amount, coin, amount_unit) ) async def confirm_replacement(ctx: wire.Context, description: str, txid: bytes) -> None: - await require( - layouts.confirm_replacement( - ctx, - description, - hexlify(txid).decode(), - ) + await layouts.confirm_replacement( + ctx, + description, + hexlify(txid).decode(), ) @@ -106,14 +101,12 @@ async def confirm_modify_output( assert txo.address is not None address_short = addresses.address_short(coin, txo.address) amount_change = txo.amount - orig_txo.amount - await require( - layouts.confirm_modify_output( - ctx, - address_short, - amount_change, - format_coin_amount(abs(amount_change), coin, amount_unit), - format_coin_amount(txo.amount, coin, amount_unit), - ) + await layouts.confirm_modify_output( + ctx, + address_short, + amount_change, + format_coin_amount(abs(amount_change), coin, amount_unit), + format_coin_amount(txo.amount, coin, amount_unit), ) @@ -124,13 +117,11 @@ async def confirm_modify_fee( coin: CoinInfo, amount_unit: EnumTypeAmountUnit, ) -> None: - await require( - layouts.confirm_modify_fee( - ctx, - user_fee_change, - format_coin_amount(abs(user_fee_change), coin, amount_unit), - format_coin_amount(total_fee_new, coin, amount_unit), - ) + await layouts.confirm_modify_fee( + ctx, + user_fee_change, + format_coin_amount(abs(user_fee_change), coin, amount_unit), + format_coin_amount(total_fee_new, coin, amount_unit), ) @@ -141,12 +132,10 @@ async def confirm_joint_total( coin: CoinInfo, amount_unit: EnumTypeAmountUnit, ) -> None: - await require( - layouts.confirm_joint_total( - ctx, - spending_amount=format_coin_amount(spending, coin, amount_unit), - total_amount=format_coin_amount(total, coin, amount_unit), - ), + await layouts.confirm_joint_total( + ctx, + spending_amount=format_coin_amount(spending, coin, amount_unit), + total_amount=format_coin_amount(total, coin, amount_unit), ) @@ -157,12 +146,10 @@ async def confirm_total( coin: CoinInfo, amount_unit: EnumTypeAmountUnit, ) -> None: - await require( - layouts.confirm_total( - ctx, - total_amount=format_coin_amount(spending, coin, amount_unit), - fee_amount=format_coin_amount(fee, coin, amount_unit), - ), + await layouts.confirm_total( + ctx, + total_amount=format_coin_amount(spending, coin, amount_unit), + fee_amount=format_coin_amount(fee, coin, amount_unit), ) @@ -170,30 +157,26 @@ async def confirm_feeoverthreshold( ctx: wire.Context, fee: int, coin: CoinInfo, amount_unit: EnumTypeAmountUnit ) -> None: fee_amount = format_coin_amount(fee, coin, amount_unit) - await require( - layouts.confirm_metadata( - ctx, - "fee_over_threshold", - "High fee", - "The fee of\n{}is unexpectedly high.", - fee_amount, - ButtonRequestType.FeeOverThreshold, - ) + await layouts.confirm_metadata( + ctx, + "fee_over_threshold", + "High fee", + "The fee of\n{}is unexpectedly high.", + fee_amount, + ButtonRequestType.FeeOverThreshold, ) async def confirm_change_count_over_threshold( ctx: wire.Context, change_count: int ) -> None: - await require( - layouts.confirm_metadata( - ctx, - "change_count_over_threshold", - "Warning", - "There are {}\nchange-outputs.\n", - str(change_count), - ButtonRequestType.SignTx, - ) + await layouts.confirm_metadata( + ctx, + "change_count_over_threshold", + "Warning", + "There are {}\nchange-outputs.\n", + str(change_count), + ButtonRequestType.SignTx, ) @@ -213,13 +196,11 @@ async def confirm_nondefault_locktime( text = "Locktime for this\ntransaction is set to\ntimestamp:\n{}" param = str(lock_time) - await require( - layouts.confirm_metadata( - ctx, - "nondefault_locktime", - title, - text, - param, - br_code=ButtonRequestType.SignTx, - ) + await layouts.confirm_metadata( + ctx, + "nondefault_locktime", + title, + text, + param, + br_code=ButtonRequestType.SignTx, ) diff --git a/core/src/apps/bitcoin/verify_message.py b/core/src/apps/bitcoin/verify_message.py index cb6a55b05..4e60b48e5 100644 --- a/core/src/apps/bitcoin/verify_message.py +++ b/core/src/apps/bitcoin/verify_message.py @@ -2,7 +2,7 @@ from trezor import wire from trezor.crypto.curve import secp256k1 from trezor.messages.InputScriptType import SPENDADDRESS, SPENDP2SHWITNESS, SPENDWITNESS from trezor.messages.Success import Success -from trezor.ui.layouts import confirm_signverify, require +from trezor.ui.layouts import confirm_signverify from apps.common import coins from apps.common.signverify import decode_message, message_digest @@ -63,13 +63,11 @@ async def verify_message(ctx: wire.Context, msg: VerifyMessage) -> Success: if addr != address: raise wire.ProcessError("Invalid signature") - await require( - confirm_signverify( - ctx, - coin.coin_shortcut, - decode_message(message), - address=address_short(coin, address), - ) + await confirm_signverify( + ctx, + coin.coin_shortcut, + decode_message(message), + address=address_short(coin, address), ) return Success(message="Message verified") diff --git a/core/src/apps/cardano/get_public_key.py b/core/src/apps/cardano/get_public_key.py index 36573b11c..42ba051ce 100644 --- a/core/src/apps/cardano/get_public_key.py +++ b/core/src/apps/cardano/get_public_key.py @@ -3,7 +3,7 @@ from ubinascii import hexlify from trezor import log, wire from trezor.messages.CardanoPublicKey import CardanoPublicKey from trezor.messages.HDNodeType import HDNodeType -from trezor.ui.layouts import require, show_pubkey +from trezor.ui.layouts import show_pubkey from apps.common import paths from apps.common.seed import remove_ed25519_prefix @@ -36,7 +36,7 @@ async def get_public_key( raise wire.ProcessError("Deriving public key failed") if msg.show_display: - await require(show_pubkey(ctx, hexlify(key.node.public_key).decode())) + await show_pubkey(ctx, hexlify(key.node.public_key).decode()) return key diff --git a/core/src/apps/common/paths.py b/core/src/apps/common/paths.py index ed7e93c66..55ee31b9d 100644 --- a/core/src/apps/common/paths.py +++ b/core/src/apps/common/paths.py @@ -1,5 +1,5 @@ from trezor.ui.constants import MONO_CHARS_PER_LINE -from trezor.ui.layouts import confirm_path_warning, require +from trezor.ui.layouts import confirm_path_warning from . import HARDENED from .layout import address_n_to_str @@ -259,7 +259,7 @@ async def validate_path( async def show_path_warning(ctx: wire.Context, path: Bip32Path) -> None: - await require(confirm_path_warning(ctx, address_n_to_str(path))) + await confirm_path_warning(ctx, address_n_to_str(path)) def is_hardened(i: int) -> bool: diff --git a/core/src/apps/common/request_pin.py b/core/src/apps/common/request_pin.py index e81e25c13..bc38209b5 100644 --- a/core/src/apps/common/request_pin.py +++ b/core/src/apps/common/request_pin.py @@ -123,26 +123,28 @@ async def verify_user_pin( async def error_pin_invalid(ctx: wire.Context) -> NoReturn: - from trezor.ui.layouts import show_error + from trezor.ui.layouts import show_error_and_raise - await show_error( + await show_error_and_raise( ctx, "warning_wrong_pin", header="Wrong PIN", content="The PIN you entered is invalid.", red=True, + exc=wire.PinInvalid, ) - raise wire.PinInvalid + assert False async def error_pin_matches_wipe_code(ctx: wire.Context) -> NoReturn: - from trezor.ui.layouts import show_error + from trezor.ui.layouts import show_error_and_raise - await show_error( + await show_error_and_raise( ctx, "warning_invalid_new_pin", header="Invalid PIN", content="The new PIN must be different from your\nwipe code.", red=True, + exc=wire.PinInvalid, ) - raise wire.PinInvalid + assert False diff --git a/core/src/apps/common/sdcard.py b/core/src/apps/common/sdcard.py index e52815a3a..317e75b6a 100644 --- a/core/src/apps/common/sdcard.py +++ b/core/src/apps/common/sdcard.py @@ -1,7 +1,7 @@ import storage.sd_salt from storage.sd_salt import SD_CARD_HOT_SWAPPABLE from trezor import fatfs, sdcard, ui, wire -from trezor.ui.layouts import confirm_action, show_error +from trezor.ui.layouts import confirm_action, show_error_and_raise if False: from typing import Optional @@ -11,9 +11,9 @@ class SdCardUnavailable(wire.ProcessError): pass -async def _wrong_card_dialog(ctx: wire.GenericContext) -> bool: +async def _confirm_retry_wrong_card(ctx: wire.GenericContext) -> None: if SD_CARD_HOT_SWAPPABLE: - return await confirm_action( + await confirm_action( ctx, "warning_wrong_sd", "SD card protection", @@ -23,20 +23,22 @@ async def _wrong_card_dialog(ctx: wire.GenericContext) -> bool: verb_cancel="Abort", icon=ui.ICON_WRONG, larger_vspace=True, + exc=SdCardUnavailable("Wrong SD card."), ) else: - return await show_error( + await show_error_and_raise( ctx, "warning_wrong_sd", header="SD card protection", subheader="Wrong SD card.", content="Please unplug the\ndevice and insert the correct SD card.", + exc=SdCardUnavailable("Wrong SD card."), ) -async def insert_card_dialog(ctx: wire.GenericContext) -> bool: +async def _confirm_retry_insert_card(ctx: wire.GenericContext) -> None: if SD_CARD_HOT_SWAPPABLE: - return await confirm_action( + await confirm_action( ctx, "warning_no_sd", "SD card protection", @@ -46,20 +48,22 @@ async def insert_card_dialog(ctx: wire.GenericContext) -> bool: verb_cancel="Abort", icon=ui.ICON_WRONG, larger_vspace=True, + exc=SdCardUnavailable("SD card required."), ) else: - return await show_error( + await show_error_and_raise( ctx, "warning_no_sd", header="SD card protection", subheader="SD card required.", content="Please unplug the\ndevice and insert your SD card.", + exc=SdCardUnavailable("SD card required."), ) -async def format_card_dialog(ctx: wire.GenericContext) -> bool: +async def _confirm_format_card(ctx: wire.GenericContext) -> None: # Format card? yes/no - if not await confirm_action( + await confirm_action( ctx, "warning_format_sd", "SD card error", @@ -70,11 +74,11 @@ async def format_card_dialog(ctx: wire.GenericContext) -> bool: verb="Format", verb_cancel="Cancel", larger_vspace=True, - ): - return False + exc=SdCardUnavailable("SD card not formatted."), + ) # Confirm formatting - return await confirm_action( + await confirm_action( ctx, "confirm_format_sd", "Format SD card", @@ -86,11 +90,15 @@ async def format_card_dialog(ctx: wire.GenericContext) -> bool: icon_color=ui.RED, hold=True, larger_vspace=True, + exc=SdCardUnavailable("SD card not formatted."), ) -async def sd_problem_dialog(ctx: wire.GenericContext) -> bool: - return await confirm_action( +async def confirm_retry_sd( + ctx: wire.GenericContext, + exc: wire.ProcessError = SdCardUnavailable("Error accessing SD card."), +) -> None: + await confirm_action( ctx, "warning_sd_retry", "SD card problem", @@ -100,6 +108,7 @@ async def sd_problem_dialog(ctx: wire.GenericContext) -> bool: icon_color=ui.RED, verb="Retry", verb_cancel="Abort", + exc=exc, ) @@ -116,8 +125,7 @@ async def ensure_sdcard( mounted. """ while not sdcard.is_present(): - if not await insert_card_dialog(ctx): - raise SdCardUnavailable("SD card required.") + await _confirm_retry_insert_card(ctx) if not ensure_filesystem: return @@ -134,8 +142,7 @@ async def ensure_sdcard( # no error when mounting return - if not await format_card_dialog(ctx): - raise SdCardUnavailable("SD card not formatted.") + await _confirm_format_card(ctx) # Proceed to formatting. Failure is caught by the outside OSError handler with sdcard.filesystem(mounted=False): @@ -148,8 +155,7 @@ async def ensure_sdcard( except OSError: # formatting failed, or generic I/O error (SD card power-on failed) - if not await sd_problem_dialog(ctx): - raise SdCardUnavailable("Error accessing SD card.") + await confirm_retry_sd(ctx) async def request_sd_salt( @@ -163,12 +169,10 @@ async def request_sd_salt( try: return storage.sd_salt.load_sd_salt() except (storage.sd_salt.WrongSdCard, fatfs.NoFilesystem): - if not await _wrong_card_dialog(ctx): - raise SdCardUnavailable("Wrong SD card.") + await _confirm_retry_wrong_card(ctx) except OSError: # Generic problem with loading the SD salt (hardware problem, or we could # not read the file, or there is a staged salt which cannot be committed). # In either case, there is no good way to recover. If the user clicks Retry, # we will try again. - if not await sd_problem_dialog(ctx): - raise SdCardUnavailable("Error accessing SD card.") + await confirm_retry_sd(ctx) diff --git a/core/src/apps/debug/load_device.py b/core/src/apps/debug/load_device.py index 91933033a..4da3e4337 100644 --- a/core/src/apps/debug/load_device.py +++ b/core/src/apps/debug/load_device.py @@ -4,7 +4,7 @@ from trezor import config, wire from trezor.crypto import bip39, slip39 from trezor.messages import BackupType from trezor.messages.Success import Success -from trezor.ui.layouts import confirm_action, require +from trezor.ui.layouts import confirm_action from apps.management import backup_types @@ -68,12 +68,10 @@ def _validate(msg) -> int: async def _warn(ctx: wire.Context): - await require( - confirm_action( - ctx, - "warn_loading_seed", - "Loading seed", - "Loading private seed\nis not recommended.", - "Continue only if you\nknow what you are doing!", - ) + await confirm_action( + ctx, + "warn_loading_seed", + "Loading seed", + "Loading private seed\nis not recommended.", + "Continue only if you\nknow what you are doing!", ) diff --git a/core/src/apps/ethereum/get_public_key.py b/core/src/apps/ethereum/get_public_key.py index abaeed2ae..909bc1502 100644 --- a/core/src/apps/ethereum/get_public_key.py +++ b/core/src/apps/ethereum/get_public_key.py @@ -2,7 +2,7 @@ from ubinascii import hexlify from trezor.messages.EthereumPublicKey import EthereumPublicKey from trezor.messages.HDNodeType import HDNodeType -from trezor.ui.layouts import require, show_pubkey +from trezor.ui.layouts import show_pubkey from apps.common import coins, paths @@ -30,6 +30,6 @@ async def get_public_key(ctx, msg, keychain): ) if msg.show_display: - await require(show_pubkey(ctx, hexlify(pubkey).decode())) + await show_pubkey(ctx, hexlify(pubkey).decode()) return EthereumPublicKey(node=node_type, xpub=node_xpub) diff --git a/core/src/apps/ethereum/sign_message.py b/core/src/apps/ethereum/sign_message.py index 7a90421a7..52c81166a 100644 --- a/core/src/apps/ethereum/sign_message.py +++ b/core/src/apps/ethereum/sign_message.py @@ -1,7 +1,7 @@ from trezor.crypto.curve import secp256k1 from trezor.crypto.hashlib import sha3_256 from trezor.messages.EthereumMessageSignature import EthereumMessageSignature -from trezor.ui.layouts import confirm_signverify, require +from trezor.ui.layouts import confirm_signverify from trezor.utils import HashWriter from apps.common import paths @@ -23,7 +23,7 @@ def message_digest(message): @with_keychain_from_path(*PATTERNS_ADDRESS) async def sign_message(ctx, msg, keychain): await paths.validate_path(ctx, keychain, msg.address_n) - await require(confirm_signverify(ctx, "ETH", decode_message(msg.message))) + await confirm_signverify(ctx, "ETH", decode_message(msg.message)) node = keychain.derive(msg.address_n) signature = secp256k1.sign( diff --git a/core/src/apps/ethereum/verify_message.py b/core/src/apps/ethereum/verify_message.py index 1031d1502..4c3a66058 100644 --- a/core/src/apps/ethereum/verify_message.py +++ b/core/src/apps/ethereum/verify_message.py @@ -2,7 +2,7 @@ from trezor import wire from trezor.crypto.curve import secp256k1 from trezor.crypto.hashlib import sha3_256 from trezor.messages.Success import Success -from trezor.ui.layouts import confirm_signverify, require +from trezor.ui.layouts import confirm_signverify from apps.common.signverify import decode_message @@ -29,8 +29,6 @@ async def verify_message(ctx, msg): address = address_from_bytes(address_bytes) - await require( - confirm_signverify(ctx, "ETH", decode_message(msg.message), address=address) - ) + await confirm_signverify(ctx, "ETH", decode_message(msg.message), address=address) return Success(message="Message verified") diff --git a/core/src/apps/lisk/get_public_key.py b/core/src/apps/lisk/get_public_key.py index 79b2dae5e..8fe023209 100644 --- a/core/src/apps/lisk/get_public_key.py +++ b/core/src/apps/lisk/get_public_key.py @@ -1,7 +1,7 @@ from ubinascii import hexlify from trezor.messages.LiskPublicKey import LiskPublicKey -from trezor.ui.layouts import require, show_pubkey +from trezor.ui.layouts import show_pubkey from apps.common import paths from apps.common.keychain import auto_keychain @@ -16,6 +16,6 @@ async def get_public_key(ctx, msg, keychain): pubkey = pubkey[1:] # skip ed25519 pubkey marker if msg.show_display: - await require(show_pubkey(ctx, hexlify(pubkey).decode())) + await show_pubkey(ctx, hexlify(pubkey).decode()) return LiskPublicKey(public_key=pubkey) diff --git a/core/src/apps/lisk/layout.py b/core/src/apps/lisk/layout.py index f3b1f3eab..55ee1b5d5 100644 --- a/core/src/apps/lisk/layout.py +++ b/core/src/apps/lisk/layout.py @@ -4,7 +4,7 @@ from trezor import ui from trezor.messages import ButtonRequestType from trezor.strings import format_amount from trezor.ui.components.tt.text import Text -from trezor.ui.layouts import require, show_pubkey +from trezor.ui.layouts import show_pubkey from trezor.utils import chunks from apps.common.confirm import require_confirm, require_hold_to_confirm @@ -36,7 +36,7 @@ async def require_confirm_vote_tx(ctx, votes): async def require_confirm_public_key(ctx, public_key): - return await require(show_pubkey(ctx, hexlify(public_key).decode())) + return await show_pubkey(ctx, hexlify(public_key).decode()) async def require_confirm_multisig(ctx, multisignature): diff --git a/core/src/apps/lisk/sign_message.py b/core/src/apps/lisk/sign_message.py index 9c61e68d6..3690cd832 100644 --- a/core/src/apps/lisk/sign_message.py +++ b/core/src/apps/lisk/sign_message.py @@ -1,7 +1,7 @@ from trezor.crypto.curve import ed25519 from trezor.crypto.hashlib import sha256 from trezor.messages.LiskMessageSignature import LiskMessageSignature -from trezor.ui.layouts import confirm_signverify, require +from trezor.ui.layouts import confirm_signverify from trezor.utils import HashWriter from apps.common import paths @@ -23,7 +23,7 @@ def message_digest(message): @auto_keychain(__name__) async def sign_message(ctx, msg, keychain): await paths.validate_path(ctx, keychain, msg.address_n) - await require(confirm_signverify(ctx, "Lisk", decode_message(msg.message))) + await confirm_signverify(ctx, "Lisk", decode_message(msg.message)) node = keychain.derive(msg.address_n) seckey = node.private_key() diff --git a/core/src/apps/lisk/verify_message.py b/core/src/apps/lisk/verify_message.py index 1b0af0b09..e52875e6c 100644 --- a/core/src/apps/lisk/verify_message.py +++ b/core/src/apps/lisk/verify_message.py @@ -1,7 +1,7 @@ from trezor import wire from trezor.crypto.curve import ed25519 from trezor.messages.Success import Success -from trezor.ui.layouts import confirm_signverify, require +from trezor.ui.layouts import confirm_signverify from apps.common.signverify import decode_message @@ -16,8 +16,6 @@ async def verify_message(ctx, msg): raise wire.ProcessError("Invalid signature") address = get_address_from_public_key(msg.public_key) - await require( - confirm_signverify(ctx, "Lisk", decode_message(msg.message), address=address) - ) + await confirm_signverify(ctx, "Lisk", decode_message(msg.message), address=address) return Success(message="Message verified") diff --git a/core/src/apps/management/apply_settings.py b/core/src/apps/management/apply_settings.py index 18f2dfa71..cfef5b5db 100644 --- a/core/src/apps/management/apply_settings.py +++ b/core/src/apps/management/apply_settings.py @@ -3,7 +3,7 @@ from trezor import ui, wire from trezor.messages import ButtonRequestType, SafetyCheckLevel from trezor.messages.Success import Success from trezor.strings import format_duration_ms -from trezor.ui.layouts import confirm_action, require +from trezor.ui.layouts import confirm_action from apps.base import reload_settings_from_storage from apps.common import safety_checks @@ -100,27 +100,23 @@ async def apply_settings(ctx: wire.Context, msg: ApplySettings): async def require_confirm_change_homescreen(ctx): - await require( - confirm_action( - ctx, - "set_homescreen", - "Set homescreen", - description="Do you really want to change the homescreen image?", - br_code=ButtonRequestType.ProtectCall, - ) + await confirm_action( + ctx, + "set_homescreen", + "Set homescreen", + description="Do you really want to change the homescreen image?", + br_code=ButtonRequestType.ProtectCall, ) async def require_confirm_change_label(ctx, label): - await require( - confirm_action( - ctx, - "set_label", - "Change label", - description="Do you really want to change the label to {}?", - description_param=label, - br_code=ButtonRequestType.ProtectCall, - ) + await confirm_action( + ctx, + "set_label", + "Change label", + description="Do you really want to change the label to {}?", + description_param=label, + br_code=ButtonRequestType.ProtectCall, ) @@ -129,14 +125,12 @@ async def require_confirm_change_passphrase(ctx, use): description = "Do you really want to enable passphrase encryption?" else: description = "Do you really want to disable passphrase encryption?" - await require( - confirm_action( - ctx, - "set_passphrase", - "Enable passphrase" if use else "Disable passphrase", - description=description, - br_code=ButtonRequestType.ProtectCall, - ) + await confirm_action( + ctx, + "set_passphrase", + "Enable passphrase" if use else "Disable passphrase", + description=description, + br_code=ButtonRequestType.ProtectCall, ) @@ -147,14 +141,12 @@ async def require_confirm_change_passphrase_source( description = "Do you really want to enter passphrase always on the device?" else: description = "Do you want to revoke the passphrase on device setting?" - await require( - confirm_action( - ctx, - "set_passphrase_source", - "Passphrase source", - description=description, - br_code=ButtonRequestType.ProtectCall, - ) + await confirm_action( + ctx, + "set_passphrase_source", + "Passphrase source", + description=description, + br_code=ButtonRequestType.ProtectCall, ) @@ -169,70 +161,60 @@ async def require_confirm_change_display_rotation(ctx, rotation): label = "west" else: raise wire.DataError("Unsupported display rotation") - await require( - confirm_action( - ctx, - "set_rotation", - "Change rotation", - description="Do you really want to change display rotation to {}?", - description_param=label, - br_code=ButtonRequestType.ProtectCall, - ) + await confirm_action( + ctx, + "set_rotation", + "Change rotation", + description="Do you really want to change display rotation to {}?", + description_param=label, + br_code=ButtonRequestType.ProtectCall, ) async def require_confirm_change_autolock_delay(ctx, delay_ms): - await require( - confirm_action( - ctx, - "set_autolock_delay", - "Auto-lock delay", - description="Do you really want to auto-lock your device after {}?", - description_param=format_duration_ms(delay_ms), - br_code=ButtonRequestType.ProtectCall, - ) + await confirm_action( + ctx, + "set_autolock_delay", + "Auto-lock delay", + description="Do you really want to auto-lock your device after {}?", + description_param=format_duration_ms(delay_ms), + br_code=ButtonRequestType.ProtectCall, ) async def require_confirm_safety_checks(ctx, level: EnumTypeSafetyCheckLevel) -> None: if level == SafetyCheckLevel.PromptAlways: - await require( - confirm_action( - ctx, - "set_safety_checks", - "Safety override", - hold=True, - verb="Hold to confirm", - description="Trezor will allow you to approve some actions which might be unsafe.", - action="Are you sure?", - reverse=True, - larger_vspace=True, - br_code=ButtonRequestType.ProtectCall, - ) + await confirm_action( + ctx, + "set_safety_checks", + "Safety override", + hold=True, + verb="Hold to confirm", + description="Trezor will allow you to approve some actions which might be unsafe.", + action="Are you sure?", + reverse=True, + larger_vspace=True, + br_code=ButtonRequestType.ProtectCall, ) elif level == SafetyCheckLevel.PromptTemporarily: - await require( - confirm_action( - ctx, - "set_safety_checks", - "Safety override", - hold=True, - verb="Hold to confirm", - description="Trezor will temporarily allow you to approve some actions which might be unsafe.", - action="Are you sure?", - reverse=True, - br_code=ButtonRequestType.ProtectCall, - ) + await confirm_action( + ctx, + "set_safety_checks", + "Safety override", + hold=True, + verb="Hold to confirm", + description="Trezor will temporarily allow you to approve some actions which might be unsafe.", + action="Are you sure?", + reverse=True, + br_code=ButtonRequestType.ProtectCall, ) elif level == SafetyCheckLevel.Strict: - await require( - confirm_action( - ctx, - "set_safety_checks", - "Safety checks", - description="Do you really want to enforce strict safety checks (recommended)?", - br_code=ButtonRequestType.ProtectCall, - ) + await confirm_action( + ctx, + "set_safety_checks", + "Safety checks", + description="Do you really want to enforce strict safety checks (recommended)?", + br_code=ButtonRequestType.ProtectCall, ) else: raise ValueError # enum value out of range @@ -240,14 +222,12 @@ async def require_confirm_safety_checks(ctx, level: EnumTypeSafetyCheckLevel) -> async def require_confirm_experimental_features(ctx, enable: bool) -> None: if enable: - await require( - confirm_action( - ctx, - "set_experimental_features", - "Experimental mode", - description="Enable experimental features?", - action="Only for development and beta testing!", - reverse=True, - br_code=ButtonRequestType.ProtectCall, - ) + await confirm_action( + ctx, + "set_experimental_features", + "Experimental mode", + description="Enable experimental features?", + action="Only for development and beta testing!", + reverse=True, + br_code=ButtonRequestType.ProtectCall, ) diff --git a/core/src/apps/management/change_pin.py b/core/src/apps/management/change_pin.py index c21416e26..13842e8d3 100644 --- a/core/src/apps/management/change_pin.py +++ b/core/src/apps/management/change_pin.py @@ -1,7 +1,7 @@ from storage.device import is_initialized from trezor import config, wire from trezor.messages.Success import Success -from trezor.ui.layouts import confirm_action, require, show_success +from trezor.ui.layouts import confirm_action, show_success from apps.common.request_pin import ( error_pin_invalid, @@ -53,7 +53,7 @@ async def change_pin(ctx: wire.Context, msg: ChangePin) -> Success: msg_screen = "You have successfully disabled PIN protection." msg_wire = "PIN removed" - await require(show_success(ctx, "success_pin", msg_screen)) + await show_success(ctx, "success_pin", msg_screen) return Success(message=msg_wire) @@ -61,39 +61,33 @@ def require_confirm_change_pin(ctx: wire.Context, msg: ChangePin) -> None: has_pin = config.has_pin() if msg.remove and has_pin: # removing pin - return require( - confirm_action( - ctx, - "set_pin", - "Remove PIN", - description="Do you really want to", - action="disable PIN protection?", - reverse=True, - ) + return confirm_action( + ctx, + "set_pin", + "Remove PIN", + description="Do you really want to", + action="disable PIN protection?", + reverse=True, ) if not msg.remove and has_pin: # changing pin - return require( - confirm_action( - ctx, - "set_pin", - "Change PIN", - description="Do you really want to", - action="change your PIN?", - reverse=True, - ) + return confirm_action( + ctx, + "set_pin", + "Change PIN", + description="Do you really want to", + action="change your PIN?", + reverse=True, ) if not msg.remove and not has_pin: # setting new pin - return require( - confirm_action( - ctx, - "set_pin", - "Enable PIN", - description="Do you really want to", - action="enable PIN protection?", - reverse=True, - ) + return confirm_action( + ctx, + "set_pin", + "Enable PIN", + description="Do you really want to", + action="enable PIN protection?", + reverse=True, ) # removing non-existing PIN diff --git a/core/src/apps/management/change_wipe_code.py b/core/src/apps/management/change_wipe_code.py index 2088e89f4..845a2f7d1 100644 --- a/core/src/apps/management/change_wipe_code.py +++ b/core/src/apps/management/change_wipe_code.py @@ -2,7 +2,7 @@ from storage.device import is_initialized from trezor import config, ui, wire from trezor.messages.Success import Success from trezor.ui.components.tt.text import Text -from trezor.ui.layouts import require, show_success +from trezor.ui.layouts import show_success from trezor.ui.popup import Popup from apps.common.confirm import require_confirm @@ -52,7 +52,7 @@ async def change_wipe_code(ctx: wire.Context, msg: ChangeWipeCode) -> Success: msg_screen = "You have successfully disabled the wipe code." msg_wire = "Wipe code removed" - await require(show_success(ctx, "success_wipe_code", msg_screen)) + await show_success(ctx, "success_wipe_code", msg_screen) return Success(message=msg_wire) diff --git a/core/src/apps/management/recovery_device/homescreen.py b/core/src/apps/management/recovery_device/homescreen.py index da5137b44..dcdd2d742 100644 --- a/core/src/apps/management/recovery_device/homescreen.py +++ b/core/src/apps/management/recovery_device/homescreen.py @@ -8,7 +8,7 @@ from trezor.crypto.hashlib import sha256 from trezor.errors import MnemonicError from trezor.messages import BackupType from trezor.messages.Success import Success -from trezor.ui.layouts import require, show_success +from trezor.ui.layouts import show_success from apps.common import mnemonic from apps.homescreen.homescreen import homescreen @@ -146,10 +146,8 @@ async def _finish_recovery( storage.recovery.end_progress() - await require( - show_success( - ctx, "success_recovery", "You have successfully recovered your wallet." - ) + await show_success( + ctx, "success_recovery", "You have successfully recovered your wallet." ) return Success(message="Device recovered") diff --git a/core/src/apps/management/recovery_device/layout.py b/core/src/apps/management/recovery_device/layout.py index 48b7054c5..38c01af7e 100644 --- a/core/src/apps/management/recovery_device/layout.py +++ b/core/src/apps/management/recovery_device/layout.py @@ -5,7 +5,7 @@ from trezor.messages import ButtonRequestType from trezor.ui.components.tt.scroll import Paginated from trezor.ui.components.tt.text import Text from trezor.ui.components.tt.word_select import WordSelector -from trezor.ui.layouts import confirm_action, require, show_success, show_warning +from trezor.ui.layouts import confirm_action, show_success, show_warning from apps.common import button_request from apps.common.confirm import confirm, info_confirm, require_confirm @@ -21,9 +21,9 @@ if False: from trezor.messages.ResetDevice import EnumTypeBackupType -async def confirm_abort(ctx: wire.GenericContext, dry_run: bool = False) -> bool: +async def confirm_abort(ctx: wire.GenericContext, dry_run: bool = False) -> None: if dry_run: - return await confirm_action( + await confirm_action( ctx, "abort_recovery", "Abort seed check", @@ -32,7 +32,7 @@ async def confirm_abort(ctx: wire.GenericContext, dry_run: bool = False) -> bool br_code=ButtonRequestType.ProtectCall, ) else: - return await confirm_action( + await confirm_action( ctx, "abort_recovery", "Abort recovery", @@ -146,17 +146,13 @@ async def show_dry_run_result( text = "The entered recovery\nshares are valid and\nmatch what is currently\nin the device." else: text = "The entered recovery\nseed is valid and\nmatches the one\nin the device." - await require( - show_success(ctx, "success_dry_recovery", text, button="Continue") - ) + await show_success(ctx, "success_dry_recovery", text, button="Continue") else: if is_slip39: text = "The entered recovery\nshares are valid but\ndo not match what is\ncurrently in the device." else: text = "The entered recovery\nseed is valid but does\nnot match the one\nin the device." - await require( - show_warning(ctx, "warning_dry_recovery", text, button="Continue") - ) + await show_warning(ctx, "warning_dry_recovery", text, button="Continue") async def show_dry_run_different_type(ctx: wire.GenericContext) -> None: @@ -171,50 +167,40 @@ async def show_dry_run_different_type(ctx: wire.GenericContext) -> None: async def show_invalid_mnemonic(ctx: wire.GenericContext, word_count: int) -> None: if backup_types.is_slip39_word_count(word_count): - await require( - show_warning( - ctx, - "warning_invalid_share", - "You have entered\nan invalid recovery\nshare.", - ) + await show_warning( + ctx, + "warning_invalid_share", + "You have entered\nan invalid recovery\nshare.", ) else: - await require( - show_warning( - ctx, - "warning_invalid_seed", - "You have entered\nan invalid recovery\nseed.", - ) + await show_warning( + ctx, + "warning_invalid_seed", + "You have entered\nan invalid recovery\nseed.", ) async def show_share_already_added(ctx: wire.GenericContext) -> None: - await require( - show_warning( - ctx, - "warning_known_share", - "Share already entered,\nplease enter\na different share.", - ) + await show_warning( + ctx, + "warning_known_share", + "Share already entered,\nplease enter\na different share.", ) async def show_identifier_mismatch(ctx: wire.GenericContext) -> None: - await require( - show_warning( - ctx, - "warning_mismatched_share", - "You have entered\na share from another\nShamir Backup.", - ) + await show_warning( + ctx, + "warning_mismatched_share", + "You have entered\na share from another\nShamir Backup.", ) async def show_group_threshold_reached(ctx: wire.GenericContext) -> None: - await require( - show_warning( - ctx, - "warning_group_threshold", - "Threshold of this\ngroup has been reached.\nInput share from\ndifferent group.", - ) + await show_warning( + ctx, + "warning_group_threshold", + "Threshold of this\ngroup has been reached.\nInput share from\ndifferent group.", ) @@ -288,5 +274,9 @@ async def homescreen_dialog( break # user has chosen to abort, confirm the choice dry_run = storage.recovery.is_dry_run() - if await confirm_abort(ctx, dry_run): + try: + await confirm_abort(ctx, dry_run) + except wire.ActionCancelled: + pass + else: raise RecoveryAborted diff --git a/core/src/apps/management/reset_device/__init__.py b/core/src/apps/management/reset_device/__init__.py index d8e7aafd7..567e74e6f 100644 --- a/core/src/apps/management/reset_device/__init__.py +++ b/core/src/apps/management/reset_device/__init__.py @@ -6,7 +6,7 @@ from trezor.messages import BackupType from trezor.messages.EntropyAck import EntropyAck from trezor.messages.EntropyRequest import EntropyRequest from trezor.messages.Success import Success -from trezor.ui.layouts import confirm_backup, confirm_reset_device, require +from trezor.ui.layouts import confirm_backup, confirm_reset_device from trezor.ui.loader import LoadingAnimation from .. import backup_types @@ -33,7 +33,7 @@ async def reset_device(ctx: wire.Context, msg: ResetDevice) -> Success: prompt = "Create a new wallet\nwith Super Shamir?" else: prompt = "Do you want to create\na new wallet?" - await require(confirm_reset_device(ctx, prompt)) + await confirm_reset_device(ctx, prompt) await LoadingAnimation() # wipe storage to make sure the device is in a clear state diff --git a/core/src/apps/management/reset_device/layout.py b/core/src/apps/management/reset_device/layout.py index 166c3696a..d0a079db5 100644 --- a/core/src/apps/management/reset_device/layout.py +++ b/core/src/apps/management/reset_device/layout.py @@ -9,13 +9,7 @@ from trezor.ui.components.tt.info import InfoConfirm from trezor.ui.components.tt.num_input import NumInput from trezor.ui.components.tt.scroll import Paginated from trezor.ui.components.tt.text import Text -from trezor.ui.layouts import ( - confirm_action, - confirm_hex, - require, - show_success, - show_warning, -) +from trezor.ui.layouts import confirm_action, confirm_hex, show_success, show_warning from apps.common.confirm import confirm, require_hold_to_confirm @@ -28,17 +22,15 @@ if __debug__: async def show_internal_entropy(ctx, entropy: bytes): - await require( - confirm_hex( - ctx, - "entropy", - "Internal entropy", - data=ubinascii.hexlify(entropy).decode(), - icon=ui.ICON_RESET, - icon_color=ui.ORANGE_ICON, - width=16, - br_code=ButtonRequestType.ResetDevice, - ) + await confirm_hex( + ctx, + "entropy", + "Internal entropy", + data=ubinascii.hexlify(entropy).decode(), + icon=ui.ICON_RESET, + icon_color=ui.ORANGE_ICON, + width=16, + br_code=ButtonRequestType.ResetDevice, ) @@ -192,9 +184,7 @@ async def _show_confirmation_success( ) text = "Continue with the next\nshare." - return await require( - show_success(ctx, "success_recovery", text, subheader=subheader) - ) + return await show_success(ctx, "success_recovery", text, subheader=subheader) async def _show_confirmation_failure(ctx, share_index): @@ -202,16 +192,14 @@ async def _show_confirmation_failure(ctx, share_index): header = "Recovery seed" else: header = "Recovery share #%s" % (share_index + 1) - await require( - show_warning( - ctx, - "warning_backup_check", - header=header, - subheader="That is the wrong word.", - content="Please check again.", - button="Check again", - br_code=ButtonRequestType.ResetDevice, - ) + await show_warning( + ctx, + "warning_backup_check", + header=header, + subheader="That is the wrong word.", + content="Please check again.", + button="Check again", + br_code=ButtonRequestType.ResetDevice, ) @@ -220,25 +208,21 @@ async def show_backup_warning(ctx, slip39=False): description = "Never make a digital copy of your recovery shares and never upload them online!" else: description = "Never make a digital copy of your recovery seed and never upload\nit online!" - await require( - confirm_action( - ctx, - "backup_warning", - "Caution", - description=description, - verb="I understand", - verb_cancel=None, - icon=ui.ICON_NOCOPY, - br_code=ButtonRequestType.ResetDevice, - ) + await confirm_action( + ctx, + "backup_warning", + "Caution", + description=description, + verb="I understand", + verb_cancel=None, + icon=ui.ICON_NOCOPY, + br_code=ButtonRequestType.ResetDevice, ) async def show_backup_success(ctx): text = "Use your backup\nwhen you need to\nrecover your wallet." - await require( - show_success(ctx, "success_backup", text, subheader="Your backup is done.") - ) + await show_success(ctx, "success_backup", text, subheader="Your backup is done.") # BIP39 diff --git a/core/src/apps/management/sd_protect.py b/core/src/apps/management/sd_protect.py index a113bcae5..ea4efb6ab 100644 --- a/core/src/apps/management/sd_protect.py +++ b/core/src/apps/management/sd_protect.py @@ -4,14 +4,14 @@ from trezor import config, wire from trezor.crypto import random from trezor.messages import SdProtectOperationType from trezor.messages.Success import Success -from trezor.ui.layouts import confirm_action, require, show_success +from trezor.ui.layouts import confirm_action, show_success from apps.common.request_pin import ( error_pin_invalid, request_pin, request_pin_and_sd_salt, ) -from apps.common.sdcard import ensure_sdcard, sd_problem_dialog +from apps.common.sdcard import confirm_retry_sd, ensure_sdcard if False: from typing import Awaitable, Tuple @@ -33,8 +33,7 @@ async def _set_salt( try: return storage.sd_salt.set_sd_salt(salt, salt_tag, stage) except OSError: - if not await sd_problem_dialog(ctx): - raise wire.ProcessError("SD card I/O error.") + await confirm_retry_sd(ctx, exc=wire.ProcessError("SD card I/O error.")) async def sd_protect(ctx: wire.Context, msg: SdProtect) -> Success: @@ -84,8 +83,8 @@ async def sd_protect_enable(ctx: wire.Context, msg: SdProtect) -> Success: storage.device.set_sd_salt_auth_key(salt_auth_key) - await require( - show_success(ctx, "success_sd", "You have successfully enabled SD protection.") + await show_success( + ctx, "success_sd", "You have successfully enabled SD protection." ) return Success(message="SD card protection enabled") @@ -118,8 +117,8 @@ async def sd_protect_disable(ctx: wire.Context, msg: SdProtect) -> Success: # because overall SD-protection was successfully disabled. pass - await require( - show_success(ctx, "success_sd", "You have successfully disabled SD protection.") + await show_success( + ctx, "success_sd", "You have successfully disabled SD protection." ) return Success(message="SD card protection disabled") @@ -155,10 +154,8 @@ async def sd_protect_refresh(ctx: wire.Context, msg: SdProtect) -> Success: # SD-protection was successfully refreshed. pass - await require( - show_success( - ctx, "success_sd", "You have successfully refreshed SD protection." - ) + await show_success( + ctx, "success_sd", "You have successfully refreshed SD protection." ) return Success(message="SD card protection refreshed") @@ -173,6 +170,4 @@ def require_confirm_sd_protect(ctx: wire.Context, msg: SdProtect) -> Awaitable[N else: raise wire.ProcessError("Unknown operation") - return require( - confirm_action(ctx, "set_sd", "SD card protection", description=text) - ) + return confirm_action(ctx, "set_sd", "SD card protection", description=text) diff --git a/core/src/apps/management/wipe_device.py b/core/src/apps/management/wipe_device.py index 1d3e56538..f0cfae21d 100644 --- a/core/src/apps/management/wipe_device.py +++ b/core/src/apps/management/wipe_device.py @@ -1,12 +1,12 @@ import storage from trezor.messages.Success import Success -from trezor.ui.layouts import confirm_wipe, require +from trezor.ui.layouts import confirm_wipe from .apply_settings import reload_settings_from_storage async def wipe_device(ctx, msg): - await require(confirm_wipe(ctx)) + await confirm_wipe(ctx) storage.wipe() reload_settings_from_storage() diff --git a/core/src/apps/misc/cipher_key_value.py b/core/src/apps/misc/cipher_key_value.py index 83d65a67e..173f1d18f 100644 --- a/core/src/apps/misc/cipher_key_value.py +++ b/core/src/apps/misc/cipher_key_value.py @@ -1,7 +1,7 @@ from trezor import wire from trezor.crypto import aes, hmac from trezor.messages.CipheredKeyValue import CipheredKeyValue -from trezor.ui.layouts import confirm_action, require +from trezor.ui.layouts import confirm_action from apps.common.keychain import get_keychain from apps.common.paths import AlwaysMatchingSchema @@ -27,9 +27,7 @@ async def cipher_key_value(ctx: Context, msg: CipherKeyValue) -> CipheredKeyValu title = "Encrypt value" else: title = "Decrypt value" - await require( - confirm_action(ctx, "cipher_key_value", title, description=msg.key) - ) + await confirm_action(ctx, "cipher_key_value", title, description=msg.key) node = keychain.derive(msg.address_n) value = compute_cipher_key_value(msg, node.private_key()) diff --git a/core/src/apps/misc/get_ecdh_session_key.py b/core/src/apps/misc/get_ecdh_session_key.py index 06f76379c..b3a0a6885 100644 --- a/core/src/apps/misc/get_ecdh_session_key.py +++ b/core/src/apps/misc/get_ecdh_session_key.py @@ -3,7 +3,7 @@ from ustruct import pack, unpack from trezor import ui, wire from trezor.crypto.hashlib import sha256 from trezor.messages.ECDHSessionKey import ECDHSessionKey -from trezor.ui.layouts import confirm_hex, require +from trezor.ui.layouts import confirm_hex from apps.common import HARDENED from apps.common.keychain import get_keychain @@ -47,15 +47,13 @@ async def require_confirm_ecdh_session_key( ctx: wire.Context, identity: IdentityType ) -> None: proto = identity.proto.upper() if identity.proto else "identity" - await require( - confirm_hex( - ctx, - "ecdh_session_key", - "Decrypt %s" % proto, - serialize_identity_without_proto(identity), - icon=ui.ICON_DEFAULT, - icon_color=ui.ORANGE_ICON, - ) + await confirm_hex( + ctx, + "ecdh_session_key", + "Decrypt %s" % proto, + serialize_identity_without_proto(identity), + icon=ui.ICON_DEFAULT, + icon_color=ui.ORANGE_ICON, ) diff --git a/core/src/apps/misc/get_entropy.py b/core/src/apps/misc/get_entropy.py index 86dfa76e8..a1d8d102f 100644 --- a/core/src/apps/misc/get_entropy.py +++ b/core/src/apps/misc/get_entropy.py @@ -1,7 +1,7 @@ from trezor.crypto import random from trezor.messages import ButtonRequestType from trezor.messages.Entropy import Entropy -from trezor.ui.layouts import confirm_action, require +from trezor.ui.layouts import confirm_action if False: from trezor.wire import Context @@ -9,15 +9,13 @@ if False: async def get_entropy(ctx: Context, msg: GetEntropy) -> Entropy: - await require( - confirm_action( - ctx, - "get_entropy", - "Confirm entropy", - action="Do you really want\nto send entropy?", - description="Continue only if you\nknow what you are doing!", - br_code=ButtonRequestType.ProtectCall, - ) + await confirm_action( + ctx, + "get_entropy", + "Confirm entropy", + action="Do you really want\nto send entropy?", + description="Continue only if you\nknow what you are doing!", + br_code=ButtonRequestType.ProtectCall, ) size = min(msg.size, 1024) diff --git a/core/src/apps/misc/sign_identity.py b/core/src/apps/misc/sign_identity.py index 80f74270b..4f86afe87 100644 --- a/core/src/apps/misc/sign_identity.py +++ b/core/src/apps/misc/sign_identity.py @@ -3,7 +3,7 @@ from ustruct import pack, unpack from trezor import wire from trezor.crypto.hashlib import sha256 from trezor.messages.SignedIdentity import SignedIdentity -from trezor.ui.layouts import confirm_sign_identity, require +from trezor.ui.layouts import confirm_sign_identity from apps.common import HARDENED, coininfo from apps.common.keychain import get_keychain @@ -84,10 +84,8 @@ async def require_confirm_sign_identity( ctx: wire.Context, identity: IdentityType, challenge_visual: Optional[str] ) -> None: proto = identity.proto.upper() if identity.proto else "identity" - await require( - confirm_sign_identity( - ctx, proto, serialize_identity_without_proto(identity), challenge_visual - ) + await confirm_sign_identity( + ctx, proto, serialize_identity_without_proto(identity), challenge_visual ) diff --git a/core/src/apps/monero/layout/confirms.py b/core/src/apps/monero/layout/confirms.py index a4cf85e25..198bbf496 100644 --- a/core/src/apps/monero/layout/confirms.py +++ b/core/src/apps/monero/layout/confirms.py @@ -3,7 +3,7 @@ from ubinascii import hexlify from trezor import ui, wire from trezor.messages import ButtonRequestType from trezor.ui.components.tt.text import Text -from trezor.ui.layouts import confirm_action, require +from trezor.ui.layouts import confirm_action from trezor.ui.popup import Popup from trezor.utils import chunks @@ -23,44 +23,38 @@ if False: async def require_confirm_watchkey(ctx): - await require( - confirm_action( - ctx, - "get_watchkey", - "Confirm export", - description="Do you really want to export watch-only credentials?", - icon=ui.ICON_SEND, - icon_color=ui.GREEN, - br_code=ButtonRequestType.SignTx, - ) + await confirm_action( + ctx, + "get_watchkey", + "Confirm export", + description="Do you really want to export watch-only credentials?", + icon=ui.ICON_SEND, + icon_color=ui.GREEN, + br_code=ButtonRequestType.SignTx, ) async def require_confirm_keyimage_sync(ctx): - await require( - confirm_action( - ctx, - "key_image_sync", - "Confirm ki sync", - description="Do you really want to\nsync key images?", - icon=ui.ICON_SEND, - icon_color=ui.GREEN, - br_code=ButtonRequestType.SignTx, - ) + await confirm_action( + ctx, + "key_image_sync", + "Confirm ki sync", + description="Do you really want to\nsync key images?", + icon=ui.ICON_SEND, + icon_color=ui.GREEN, + br_code=ButtonRequestType.SignTx, ) async def require_confirm_live_refresh(ctx): - await require( - confirm_action( - ctx, - "live_refresh", - "Confirm refresh", - description="Do you really want to\nstart refresh?", - icon=ui.ICON_SEND, - icon_color=ui.GREEN, - br_code=ButtonRequestType.SignTx, - ) + await confirm_action( + ctx, + "live_refresh", + "Confirm refresh", + description="Do you really want to\nstart refresh?", + icon=ui.ICON_SEND, + icon_color=ui.GREEN, + br_code=ButtonRequestType.SignTx, ) @@ -69,16 +63,14 @@ async def require_confirm_tx_key(ctx, export_key=False): description = "Do you really want to export tx_key?" else: description = "Do you really want to export tx_der\nfor tx_proof?" - await require( - confirm_action( - ctx, - "export_tx_key", - "Confirm export", - description=description, - icon=ui.ICON_SEND, - icon_color=ui.GREEN, - br_code=ButtonRequestType.SignTx, - ) + await confirm_action( + ctx, + "export_tx_key", + "Confirm export", + description=description, + icon=ui.ICON_SEND, + icon_color=ui.GREEN, + br_code=ButtonRequestType.SignTx, ) diff --git a/core/src/apps/tezos/get_public_key.py b/core/src/apps/tezos/get_public_key.py index a528c1d14..fbd043d97 100644 --- a/core/src/apps/tezos/get_public_key.py +++ b/core/src/apps/tezos/get_public_key.py @@ -1,5 +1,5 @@ from trezor.messages.TezosPublicKey import TezosPublicKey -from trezor.ui.layouts import require, show_pubkey +from trezor.ui.layouts import show_pubkey from apps.common import paths, seed from apps.common.keychain import with_slip44_keychain @@ -16,6 +16,6 @@ async def get_public_key(ctx, msg, keychain): pk_prefixed = helpers.base58_encode_check(pk, prefix=helpers.TEZOS_PUBLICKEY_PREFIX) if msg.show_display: - await require(show_pubkey(ctx, pk_prefixed)) + await show_pubkey(ctx, pk_prefixed) return TezosPublicKey(public_key=pk_prefixed) diff --git a/core/src/apps/webauthn/add_resident_credential.py b/core/src/apps/webauthn/add_resident_credential.py index 822f26f09..0bf2109a3 100644 --- a/core/src/apps/webauthn/add_resident_credential.py +++ b/core/src/apps/webauthn/add_resident_credential.py @@ -2,7 +2,7 @@ import storage.device from trezor import wire from trezor.messages.Success import Success from trezor.messages.WebAuthnAddResidentCredential import WebAuthnAddResidentCredential -from trezor.ui.layouts import require, show_error +from trezor.ui.layouts import show_error_and_raise from apps.common.confirm import require_confirm @@ -41,17 +41,14 @@ async def add_resident_credential( try: cred = Fido2Credential.from_cred_id(bytes(msg.credential_id), None) except Exception: - await require( - show_error( - ctx, - "warning_credential", - header="Import credential", - button="Close", - content="The credential you are trying to import does\nnot belong to this authenticator.", - red=True, - ) + await show_error_and_raise( + ctx, + "warning_credential", + header="Import credential", + button="Close", + content="The credential you are trying to import does\nnot belong to this authenticator.", + red=True, ) - raise wire.ActionCancelled content = ConfirmContent(ConfirmAddCredential(cred)) await require_confirm(ctx, content) diff --git a/core/src/apps/webauthn/list_resident_credentials.py b/core/src/apps/webauthn/list_resident_credentials.py index 8d7fa405c..9cee7fea1 100644 --- a/core/src/apps/webauthn/list_resident_credentials.py +++ b/core/src/apps/webauthn/list_resident_credentials.py @@ -4,7 +4,7 @@ from trezor.messages.WebAuthnCredentials import WebAuthnCredentials from trezor.messages.WebAuthnListResidentCredentials import ( WebAuthnListResidentCredentials, ) -from trezor.ui.layouts import confirm_action, require +from trezor.ui.layouts import confirm_action from . import resident_credentials @@ -12,13 +12,11 @@ from . import resident_credentials async def list_resident_credentials( ctx: wire.Context, msg: WebAuthnListResidentCredentials ) -> WebAuthnCredentials: - await require( - confirm_action( - ctx, - "credentials_list", - title="List credentials", - description="Do you want to export information about the resident credentials stored on this device?", - ) + await confirm_action( + ctx, + "credentials_list", + title="List credentials", + description="Do you want to export information about the resident credentials stored on this device?", ) creds = [ WebAuthnCredential( diff --git a/core/src/trezor/ui/components/common/confirm.py b/core/src/trezor/ui/components/common/confirm.py index 941d36409..4a163ea78 100644 --- a/core/src/trezor/ui/components/common/confirm.py +++ b/core/src/trezor/ui/components/common/confirm.py @@ -1,10 +1,10 @@ -from trezor import loop, ui +from trezor import loop, ui, wire if __debug__: from apps.debug import confirm_signal if False: - from typing import List, Tuple, Optional, Any + from typing import List, Tuple, Optional, Any, Awaitable CONFIRMED = object() CANCELLED = object() @@ -15,6 +15,12 @@ def is_confirmed(x: Any) -> bool: return x is CONFIRMED +async def raise_if_cancelled(a: Awaitable, exc: Any = wire.ActionCancelled) -> None: + result = await a + if result is CANCELLED: + raise exc + + class ConfirmBase(ui.Layout): def __init__( self, diff --git a/core/src/trezor/ui/layouts/common.py b/core/src/trezor/ui/layouts/common.py index 0b41ed595..74c0d0ca9 100644 --- a/core/src/trezor/ui/layouts/common.py +++ b/core/src/trezor/ui/layouts/common.py @@ -11,12 +11,6 @@ if False: LayoutType = Awaitable[Any] -async def require(a: Awaitable[bool]) -> None: - result = await a - if not result: - raise wire.ActionCancelled - - async def interact( ctx: wire.GenericContext, layout: LayoutType, diff --git a/core/src/trezor/ui/layouts/tt.py b/core/src/trezor/ui/layouts/tt.py index dbb6a8299..52d8b82ad 100644 --- a/core/src/trezor/ui/layouts/tt.py +++ b/core/src/trezor/ui/layouts/tt.py @@ -1,6 +1,6 @@ from micropython import const -from trezor import ui +from trezor import ui, wire from trezor.messages import ButtonRequestType from trezor.ui.container import Container from trezor.ui.loader import LoaderDanger @@ -8,7 +8,7 @@ from trezor.ui.qr import Qr from trezor.utils import chunks from ..components.common import break_path_to_lines -from ..components.common.confirm import is_confirmed +from ..components.common.confirm import is_confirmed, raise_if_cancelled from ..components.tt.button import ButtonCancel, ButtonDefault from ..components.tt.confirm import Confirm, HoldToConfirm from ..components.tt.scroll import Paginated, paginate_text @@ -24,13 +24,23 @@ from ..constants.tt import ( from .common import interact if False: - from typing import Any, Iterator, List, Sequence, Union, Optional, Awaitable + from typing import ( + Iterator, + List, + Sequence, + Type, + Union, + Optional, + Awaitable, + NoReturn, + ) - from trezor import wire from trezor.messages.ButtonRequest import EnumTypeButtonRequestType from ..components.common.text import TextContent + ExceptionType = Union[BaseException, Type[BaseException]] + __all__ = ( "confirm_action", "confirm_wipe", @@ -40,7 +50,7 @@ __all__ = ( "confirm_sign_identity", "confirm_signverify", "show_address", - "show_error", + "show_error_and_raise", "show_pubkey", "show_success", "show_xpub", @@ -73,9 +83,10 @@ async def confirm_action( icon_color: int = None, # TODO cleanup @ redesign reverse: bool = False, # TODO cleanup @ redesign larger_vspace: bool = False, # TODO cleanup @ redesign + exc: ExceptionType = wire.ActionCancelled, br_code: EnumTypeButtonRequestType = ButtonRequestType.Other, **kwargs: Any, -) -> bool: +) -> None: text = Text( title, icon if icon is not None else ui.ICON_DEFAULT, @@ -107,23 +118,24 @@ async def confirm_action( ) cls = HoldToConfirm if hold else Confirm - return is_confirmed( - await interact( + await raise_if_cancelled( + interact( ctx, cls(text, confirm=verb, cancel=verb_cancel), br_type, br_code, - ) + ), + exc, ) # TODO cleanup @ redesign -async def confirm_wipe(ctx: wire.GenericContext) -> bool: +async def confirm_wipe(ctx: wire.GenericContext) -> None: text = Text("Wipe device", ui.ICON_WIPE, ui.RED) text.normal("Do you really want to", "wipe the device?", "") text.bold("All data will be lost.") - return is_confirmed( - await interact( + await raise_if_cancelled( + interact( ctx, HoldToConfirm(text, confirm_style=ButtonCancel, loader_style=LoaderDanger), "wipe_device", @@ -132,7 +144,7 @@ async def confirm_wipe(ctx: wire.GenericContext) -> bool: ) -async def confirm_reset_device(ctx: wire.GenericContext, prompt: str) -> bool: +async def confirm_reset_device(ctx: wire.GenericContext, prompt: str) -> None: text = Text("Create new wallet", ui.ICON_RESET, new_lines=False) text.bold(prompt) text.br() @@ -141,8 +153,8 @@ async def confirm_reset_device(ctx: wire.GenericContext, prompt: str) -> bool: text.br() text.normal("to ") text.bold("https://trezor.io/tos") - return is_confirmed( - await interact( + await raise_if_cancelled( + interact( ctx, Confirm(text, major_confirm=True), "setup_device", @@ -184,13 +196,13 @@ async def confirm_backup(ctx: wire.GenericContext) -> bool: return confirmed -async def confirm_path_warning(ctx: wire.GenericContext, path: str) -> bool: +async def confirm_path_warning(ctx: wire.GenericContext, path: str) -> None: text = Text("Confirm path", ui.ICON_WRONG, ui.RED) text.normal("Path") text.mono(*break_path_to_lines(path, MONO_CHARS_PER_LINE)) text.normal("is unknown.", "Are you sure?") - return is_confirmed( - await interact( + await raise_if_cancelled( + interact( ctx, Confirm(text), "path_warning", @@ -266,9 +278,9 @@ def _show_xpub(xpub: str, desc: str, cancel: str) -> Paginated: async def show_xpub( ctx: wire.GenericContext, xpub: str, desc: str, cancel: str -) -> bool: - return is_confirmed( - await interact( +) -> None: + await raise_if_cancelled( + interact( ctx, _show_xpub(xpub, desc, cancel), "show_xpub", @@ -329,7 +341,7 @@ async def show_address( def show_pubkey( ctx: wire.Context, pubkey: str, title: str = "Confirm public key" -) -> Awaitable[bool]: +) -> Awaitable[None]: return confirm_hex( ctx, br_type="show_pubkey", @@ -351,24 +363,26 @@ async def _show_modal( button_cancel: Optional[str], icon: str, icon_color: int, -) -> bool: + exc: ExceptionType = wire.ActionCancelled, +) -> None: text = Text(header, icon, icon_color, new_lines=False) if subheader: text.bold(subheader) text.br() text.br_half() text.normal(content) - return is_confirmed( - await interact( + await raise_if_cancelled( + interact( ctx, Confirm(text, confirm=button_confirm, cancel=button_cancel), br_type, br_code, - ) + ), + exc, ) -def show_error( +async def show_error_and_raise( ctx: wire.GenericContext, br_type: str, content: str, @@ -376,8 +390,9 @@ def show_error( subheader: Optional[str] = None, button: str = "Close", red: bool = False, -) -> Awaitable[bool]: - return _show_modal( + exc: ExceptionType = wire.ActionCancelled, +) -> NoReturn: + await _show_modal( ctx, br_type=br_type, br_code=ButtonRequestType.Other, @@ -388,7 +403,9 @@ def show_error( button_cancel=button, icon=ui.ICON_WRONG, icon_color=ui.RED if red else ui.ORANGE_ICON, + exc=exc, ) + raise exc def show_warning( @@ -399,7 +416,7 @@ def show_warning( subheader: Optional[str] = None, button: str = "Try again", br_code: EnumTypeButtonRequestType = ButtonRequestType.Warning, -) -> Awaitable[bool]: +) -> Awaitable[None]: return _show_modal( ctx, br_type=br_type, @@ -420,7 +437,7 @@ def show_success( content: str, subheader: Optional[str] = None, button: str = "Continue", -) -> Awaitable[bool]: +) -> Awaitable[None]: return _show_modal( ctx, br_type=br_type, @@ -439,14 +456,12 @@ async def confirm_output( ctx: wire.GenericContext, address: str, amount: str, -) -> bool: +) -> None: text = Text("Confirm sending", ui.ICON_SEND, ui.GREEN) text.normal(amount + " to") text.mono(*_split_address(address)) - return is_confirmed( - await interact( - ctx, Confirm(text), "confirm_output", ButtonRequestType.ConfirmOutput - ) + await raise_if_cancelled( + interact(ctx, Confirm(text), "confirm_output", ButtonRequestType.ConfirmOutput) ) @@ -454,13 +469,13 @@ async def confirm_decred_sstx_submission( ctx: wire.GenericContext, address: str, amount: str, -) -> bool: +) -> None: text = Text("Purchase ticket", ui.ICON_SEND, ui.GREEN) text.normal(amount) text.normal("with voting rights to") text.mono(*_split_address(address)) - return is_confirmed( - await interact( + await raise_if_cancelled( + interact( ctx, Confirm(text), "confirm_decred_sstx_submission", @@ -480,7 +495,7 @@ async def confirm_hex( icon_color: int = ui.GREEN, # TODO cleanup @ redesign width: int = MONO_HEX_PER_LINE, truncate_middle: bool = False, -) -> bool: +) -> None: text = Text(title, icon, icon_color, new_lines=False) description_lines = 0 if description is not None: @@ -496,34 +511,32 @@ async def confirm_hex( ) ) content: ui.Layout = Confirm(text) - return is_confirmed(await interact(ctx, content, br_type, br_code)) + await raise_if_cancelled(interact(ctx, content, br_type, br_code)) async def confirm_total( ctx: wire.GenericContext, total_amount: str, fee_amount: str -) -> bool: +) -> None: text = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN) text.normal("Total amount:") text.bold(total_amount) text.normal("including fee:") text.bold(fee_amount) - return is_confirmed( - await interact( - ctx, HoldToConfirm(text), "confirm_total", ButtonRequestType.SignTx - ) + await raise_if_cancelled( + interact(ctx, HoldToConfirm(text), "confirm_total", ButtonRequestType.SignTx) ) async def confirm_joint_total( ctx: wire.GenericContext, spending_amount: str, total_amount: str -) -> bool: +) -> None: text = Text("Joint transaction", ui.ICON_SEND, ui.GREEN) text.normal("You are contributing:") text.bold(spending_amount) text.normal("to the total amount:") text.bold(total_amount) - return is_confirmed( - await interact( + await raise_if_cancelled( + interact( ctx, HoldToConfirm(text), "confirm_joint_total", ButtonRequestType.SignTx ) ) @@ -536,26 +549,24 @@ async def confirm_metadata( content: str, param: Optional[str] = None, br_code: EnumTypeButtonRequestType = ButtonRequestType.SignTx, -) -> bool: +) -> None: text = Text(title, ui.ICON_SEND, ui.GREEN, new_lines=False) text.format_parametrized(content, param if param is not None else "") text.br() text.normal("Continue?") - return is_confirmed(await interact(ctx, Confirm(text), br_type, br_code)) + await raise_if_cancelled(interact(ctx, Confirm(text), br_type, br_code)) async def confirm_replacement( ctx: wire.GenericContext, description: str, txid: str -) -> bool: +) -> None: text = Text(description, ui.ICON_SEND, ui.GREEN) text.normal("Confirm transaction ID:") text.mono(*_truncate_hex(txid, TEXT_MAX_LINES - 1)) - return is_confirmed( - await interact( - ctx, Confirm(text), "confirm_replacement", ButtonRequestType.SignTx - ) + await raise_if_cancelled( + interact(ctx, Confirm(text), "confirm_replacement", ButtonRequestType.SignTx) ) @@ -565,7 +576,7 @@ async def confirm_modify_output( sign: int, amount_change: str, amount_new: str, -) -> bool: +) -> None: page1 = Text("Modify amount", ui.ICON_SEND, ui.GREEN) page1.normal("Address:") page1.br_half() @@ -581,7 +592,7 @@ async def confirm_modify_output( page2.normal("New amount:") page2.bold(amount_new) - return is_confirmed( + await raise_if_cancelled( interact( ctx, Paginated([page1, Confirm(page2)]), @@ -596,7 +607,7 @@ async def confirm_modify_fee( sign: int, user_fee_change: str, total_fee_new: str, -) -> bool: +) -> None: text = Text("Modify fee", ui.ICON_SEND, ui.GREEN) if sign == 0: text.normal("Your fee did not change.") @@ -609,31 +620,29 @@ async def confirm_modify_fee( text.br_half() text.normal("Transaction fee:") text.bold(total_fee_new) - return is_confirmed( - await interact(ctx, HoldToConfirm(text), "modify_fee", ButtonRequestType.SignTx) + await raise_if_cancelled( + interact(ctx, HoldToConfirm(text), "modify_fee", ButtonRequestType.SignTx) ) async def confirm_coinjoin( ctx: wire.GenericContext, fee_per_anonymity: Optional[str], total_fee: str -) -> bool: +) -> None: text = Text("Authorize CoinJoin", ui.ICON_RECOVERY, new_lines=False) if fee_per_anonymity is not None: text.normal("Fee per anonymity set:\n") text.bold("{} %\n".format(fee_per_anonymity)) text.normal("Maximum total fees:\n") text.bold(total_fee) - return is_confirmed( - await interact( - ctx, HoldToConfirm(text), "coinjoin_final", ButtonRequestType.Other - ) + await raise_if_cancelled( + interact(ctx, HoldToConfirm(text), "coinjoin_final", ButtonRequestType.Other) ) # TODO cleanup @ redesign async def confirm_sign_identity( ctx: wire.GenericContext, proto: str, identity: str, challenge_visual: Optional[str] -) -> bool: +) -> None: lines: List[TextContent] = [] if challenge_visual: lines.append(challenge_visual) @@ -643,14 +652,14 @@ async def confirm_sign_identity( text = Text("Sign %s" % proto) text.normal(*lines) - return is_confirmed( - await interact(ctx, Confirm(text), "sign_identity", ButtonRequestType.Other) + await raise_if_cancelled( + interact(ctx, Confirm(text), "sign_identity", ButtonRequestType.Other) ) async def confirm_signverify( ctx: wire.GenericContext, coin: str, message: str, address: str = None -) -> bool: +) -> None: if address: header = "Verify {} message".format(coin) font = ui.MONO @@ -659,17 +668,16 @@ async def confirm_signverify( text = Text(header) text.bold("Confirm address:") text.mono(*_split_address(address)) - if not is_confirmed( - await interact(ctx, Confirm(text), br_type, ButtonRequestType.Other) - ): - return False + await raise_if_cancelled( + interact(ctx, Confirm(text), br_type, ButtonRequestType.Other) + ) else: header = "Sign {} message".format(coin) font = ui.NORMAL br_type = "sign_message" - return is_confirmed( - await interact( + await raise_if_cancelled( + interact( ctx, paginate_text(message, header, font=font), br_type,