1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 22:38:08 +00:00

refactor(core/ui): raise exception on dialog cancel by default

This commit is contained in:
Martin Milata 2021-03-10 12:56:44 +01:00
parent 2b6ea25712
commit c0174ff217
40 changed files with 489 additions and 592 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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,8 +45,7 @@ async def authorize_coinjoin(ctx: wire.Context, msg: AuthorizeCoinJoin) -> Succe
),
)
await require(
confirm_action(
await confirm_action(
ctx,
"coinjoin_coordinator",
title="Authorize CoinJoin",
@ -55,20 +54,17 @@ async def authorize_coinjoin(ctx: wire.Context, msg: AuthorizeCoinJoin) -> Succe
description_param_font=ui.MONO,
icon=ui.ICON_RECOVERY,
)
)
fee_per_anonymity = None
if msg.fee_per_anonymity is not None:
fee_per_anonymity = format_amount(
msg.fee_per_anonymity, FEE_PER_ANONYMITY_DECIMALS
)
await require(
confirm_coinjoin(
await confirm_coinjoin(
ctx,
fee_per_anonymity,
format_coin_amount(msg.max_total_fee, coin, msg.amount_unit),
)
)
set_authorization(CoinJoinAuthorization(msg, keychain, coin))

View File

@ -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,17 +65,14 @@ 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(
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(
await confirm_hex(
ctx,
"confirm_ownership_proof",
title="Proof of ownership",
@ -85,7 +82,6 @@ async def get_ownership_proof(
icon_color=ui.ORANGE_ICON,
truncate_middle=True,
)
)
ownership_proof, signature = generate_proof(
node,

View File

@ -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,

View File

@ -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()

View File

@ -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,21 +78,17 @@ 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(
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(
await layouts.confirm_replacement(
ctx,
description,
hexlify(txid).decode(),
)
)
async def confirm_modify_output(
@ -106,15 +101,13 @@ 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(
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),
)
)
async def confirm_modify_fee(
@ -124,14 +117,12 @@ async def confirm_modify_fee(
coin: CoinInfo,
amount_unit: EnumTypeAmountUnit,
) -> None:
await require(
layouts.confirm_modify_fee(
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),
)
)
async def confirm_joint_total(
@ -141,12 +132,10 @@ async def confirm_joint_total(
coin: CoinInfo,
amount_unit: EnumTypeAmountUnit,
) -> None:
await require(
layouts.confirm_joint_total(
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(
await layouts.confirm_total(
ctx,
total_amount=format_coin_amount(spending, coin, amount_unit),
fee_amount=format_coin_amount(fee, coin, amount_unit),
),
)
@ -170,8 +157,7 @@ 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(
await layouts.confirm_metadata(
ctx,
"fee_over_threshold",
"High fee",
@ -179,14 +165,12 @@ async def confirm_feeoverthreshold(
fee_amount,
ButtonRequestType.FeeOverThreshold,
)
)
async def confirm_change_count_over_threshold(
ctx: wire.Context, change_count: int
) -> None:
await require(
layouts.confirm_metadata(
await layouts.confirm_metadata(
ctx,
"change_count_over_threshold",
"Warning",
@ -194,7 +178,6 @@ async def confirm_change_count_over_threshold(
str(change_count),
ButtonRequestType.SignTx,
)
)
async def confirm_nondefault_locktime(
@ -213,8 +196,7 @@ async def confirm_nondefault_locktime(
text = "Locktime for this\ntransaction is set to\ntimestamp:\n{}"
param = str(lock_time)
await require(
layouts.confirm_metadata(
await layouts.confirm_metadata(
ctx,
"nondefault_locktime",
title,
@ -222,4 +204,3 @@ async def confirm_nondefault_locktime(
param,
br_code=ButtonRequestType.SignTx,
)
)

View File

@ -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(
await confirm_signverify(
ctx,
coin.coin_shortcut,
decode_message(message),
address=address_short(coin, address),
)
)
return Success(message="Message verified")

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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)

View File

@ -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(
await confirm_action(
ctx,
"warn_loading_seed",
"Loading seed",
"Loading private seed\nis not recommended.",
"Continue only if you\nknow what you are doing!",
)
)

View File

@ -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)

View File

@ -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(

View File

@ -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")

View File

@ -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)

View File

@ -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):

View File

@ -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()

View File

@ -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")

View File

@ -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,20 +100,17 @@ async def apply_settings(ctx: wire.Context, msg: ApplySettings):
async def require_confirm_change_homescreen(ctx):
await require(
confirm_action(
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(
await confirm_action(
ctx,
"set_label",
"Change label",
@ -121,7 +118,6 @@ async def require_confirm_change_label(ctx, label):
description_param=label,
br_code=ButtonRequestType.ProtectCall,
)
)
async def require_confirm_change_passphrase(ctx, use):
@ -129,15 +125,13 @@ 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(
await confirm_action(
ctx,
"set_passphrase",
"Enable passphrase" if use else "Disable passphrase",
description=description,
br_code=ButtonRequestType.ProtectCall,
)
)
async def require_confirm_change_passphrase_source(
@ -147,15 +141,13 @@ 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(
await confirm_action(
ctx,
"set_passphrase_source",
"Passphrase source",
description=description,
br_code=ButtonRequestType.ProtectCall,
)
)
async def require_confirm_change_display_rotation(ctx, rotation):
@ -169,8 +161,7 @@ async def require_confirm_change_display_rotation(ctx, rotation):
label = "west"
else:
raise wire.DataError("Unsupported display rotation")
await require(
confirm_action(
await confirm_action(
ctx,
"set_rotation",
"Change rotation",
@ -178,12 +169,10 @@ async def require_confirm_change_display_rotation(ctx, rotation):
description_param=label,
br_code=ButtonRequestType.ProtectCall,
)
)
async def require_confirm_change_autolock_delay(ctx, delay_ms):
await require(
confirm_action(
await confirm_action(
ctx,
"set_autolock_delay",
"Auto-lock delay",
@ -191,13 +180,11 @@ async def require_confirm_change_autolock_delay(ctx, delay_ms):
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(
await confirm_action(
ctx,
"set_safety_checks",
"Safety override",
@ -209,10 +196,8 @@ async def require_confirm_safety_checks(ctx, level: EnumTypeSafetyCheckLevel) ->
larger_vspace=True,
br_code=ButtonRequestType.ProtectCall,
)
)
elif level == SafetyCheckLevel.PromptTemporarily:
await require(
confirm_action(
await confirm_action(
ctx,
"set_safety_checks",
"Safety override",
@ -223,25 +208,21 @@ async def require_confirm_safety_checks(ctx, level: EnumTypeSafetyCheckLevel) ->
reverse=True,
br_code=ButtonRequestType.ProtectCall,
)
)
elif level == SafetyCheckLevel.Strict:
await require(
confirm_action(
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
async def require_confirm_experimental_features(ctx, enable: bool) -> None:
if enable:
await require(
confirm_action(
await confirm_action(
ctx,
"set_experimental_features",
"Experimental mode",
@ -250,4 +231,3 @@ async def require_confirm_experimental_features(ctx, enable: bool) -> None:
reverse=True,
br_code=ButtonRequestType.ProtectCall,
)
)

View File

@ -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,8 +61,7 @@ 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(
return confirm_action(
ctx,
"set_pin",
"Remove PIN",
@ -70,11 +69,9 @@ def require_confirm_change_pin(ctx: wire.Context, msg: ChangePin) -> None:
action="disable PIN protection?",
reverse=True,
)
)
if not msg.remove and has_pin: # changing pin
return require(
confirm_action(
return confirm_action(
ctx,
"set_pin",
"Change PIN",
@ -82,11 +79,9 @@ def require_confirm_change_pin(ctx: wire.Context, msg: ChangePin) -> None:
action="change your PIN?",
reverse=True,
)
)
if not msg.remove and not has_pin: # setting new pin
return require(
confirm_action(
return confirm_action(
ctx,
"set_pin",
"Enable PIN",
@ -94,7 +89,6 @@ def require_confirm_change_pin(ctx: wire.Context, msg: ChangePin) -> None:
action="enable PIN protection?",
reverse=True,
)
)
# removing non-existing PIN
raise wire.ProcessError("PIN protection already disabled")

View File

@ -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)

View File

@ -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,11 +146,9 @@ async def _finish_recovery(
storage.recovery.end_progress()
await require(
show_success(
await show_success(
ctx, "success_recovery", "You have successfully recovered your wallet."
)
)
return Success(message="Device recovered")

View File

@ -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,51 +167,41 @@ 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(
await show_warning(
ctx,
"warning_invalid_share",
"You have entered\nan invalid recovery\nshare.",
)
)
else:
await require(
show_warning(
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(
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(
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(
await show_warning(
ctx,
"warning_group_threshold",
"Threshold of this\ngroup has been reached.\nInput share from\ndifferent group.",
)
)
class RecoveryHomescreen(ui.Component):
@ -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

View File

@ -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

View File

@ -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,8 +22,7 @@ if __debug__:
async def show_internal_entropy(ctx, entropy: bytes):
await require(
confirm_hex(
await confirm_hex(
ctx,
"entropy",
"Internal entropy",
@ -39,7 +32,6 @@ async def show_internal_entropy(ctx, entropy: bytes):
width=16,
br_code=ButtonRequestType.ResetDevice,
)
)
async def _show_share_words(ctx, share_words, share_index=None, group_index=None):
@ -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,8 +192,7 @@ async def _show_confirmation_failure(ctx, share_index):
header = "Recovery seed"
else:
header = "Recovery share #%s" % (share_index + 1)
await require(
show_warning(
await show_warning(
ctx,
"warning_backup_check",
header=header,
@ -212,7 +201,6 @@ async def _show_confirmation_failure(ctx, share_index):
button="Check again",
br_code=ButtonRequestType.ResetDevice,
)
)
async def show_backup_warning(ctx, slip39=False):
@ -220,8 +208,7 @@ 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(
await confirm_action(
ctx,
"backup_warning",
"Caution",
@ -231,14 +218,11 @@ async def show_backup_warning(ctx, slip39=False):
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

View File

@ -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,11 +154,9 @@ async def sd_protect_refresh(ctx: wire.Context, msg: SdProtect) -> Success:
# SD-protection was successfully refreshed.
pass
await require(
show_success(
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)

View File

@ -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()

View File

@ -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())

View File

@ -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,8 +47,7 @@ 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(
await confirm_hex(
ctx,
"ecdh_session_key",
"Decrypt %s" % proto,
@ -56,7 +55,6 @@ async def require_confirm_ecdh_session_key(
icon=ui.ICON_DEFAULT,
icon_color=ui.ORANGE_ICON,
)
)
def get_ecdh_path(identity: str, index: int) -> Bip32Path:

View File

@ -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,8 +9,7 @@ if False:
async def get_entropy(ctx: Context, msg: GetEntropy) -> Entropy:
await require(
confirm_action(
await confirm_action(
ctx,
"get_entropy",
"Confirm entropy",
@ -18,7 +17,6 @@ async def get_entropy(ctx: Context, msg: GetEntropy) -> Entropy:
description="Continue only if you\nknow what you are doing!",
br_code=ButtonRequestType.ProtectCall,
)
)
size = min(msg.size, 1024)
entropy = random.bytes(size)

View File

@ -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,11 +84,9 @@ 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(
await confirm_sign_identity(
ctx, proto, serialize_identity_without_proto(identity), challenge_visual
)
)
def serialize_identity(identity: IdentityType) -> str:

View File

@ -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,8 +23,7 @@ if False:
async def require_confirm_watchkey(ctx):
await require(
confirm_action(
await confirm_action(
ctx,
"get_watchkey",
"Confirm export",
@ -33,12 +32,10 @@ async def require_confirm_watchkey(ctx):
icon_color=ui.GREEN,
br_code=ButtonRequestType.SignTx,
)
)
async def require_confirm_keyimage_sync(ctx):
await require(
confirm_action(
await confirm_action(
ctx,
"key_image_sync",
"Confirm ki sync",
@ -47,12 +44,10 @@ async def require_confirm_keyimage_sync(ctx):
icon_color=ui.GREEN,
br_code=ButtonRequestType.SignTx,
)
)
async def require_confirm_live_refresh(ctx):
await require(
confirm_action(
await confirm_action(
ctx,
"live_refresh",
"Confirm refresh",
@ -61,7 +56,6 @@ async def require_confirm_live_refresh(ctx):
icon_color=ui.GREEN,
br_code=ButtonRequestType.SignTx,
)
)
async def require_confirm_tx_key(ctx, export_key=False):
@ -69,8 +63,7 @@ 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(
await confirm_action(
ctx,
"export_tx_key",
"Confirm export",
@ -79,7 +72,6 @@ async def require_confirm_tx_key(ctx, export_key=False):
icon_color=ui.GREEN,
br_code=ButtonRequestType.SignTx,
)
)
async def require_confirm_transaction(

View File

@ -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)

View File

@ -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,8 +41,7 @@ async def add_resident_credential(
try:
cred = Fido2Credential.from_cred_id(bytes(msg.credential_id), None)
except Exception:
await require(
show_error(
await show_error_and_raise(
ctx,
"warning_credential",
header="Import credential",
@ -50,8 +49,6 @@ async def add_resident_credential(
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)

View File

@ -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,14 +12,12 @@ from . import resident_credentials
async def list_resident_credentials(
ctx: wire.Context, msg: WebAuthnListResidentCredentials
) -> WebAuthnCredentials:
await require(
confirm_action(
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(
index=cred.index,

View File

@ -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,

View File

@ -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,

View File

@ -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,