From 2a91052b021d02039cf8a609414e0bc01db90cd6 Mon Sep 17 00:00:00 2001 From: Martin Milata Date: Thu, 25 Mar 2021 12:32:10 +0100 Subject: [PATCH] refactor(core/ui): move altcoin and webauthn layouts to separate file Also fix types. --- core/SConscript.firmware | 7 +- core/SConscript.unix | 7 +- core/src/all_modules.py | 28 +++- core/src/apps/binance/layout.py | 3 +- core/src/apps/bitcoin/sign_tx/layout.py | 7 +- core/src/apps/ethereum/layout.py | 8 +- core/src/apps/ripple/layout.py | 3 +- core/src/apps/stellar/layout.py | 2 +- .../apps/webauthn/add_resident_credential.py | 4 +- core/src/apps/webauthn/fido2.py | 3 +- .../webauthn/remove_resident_credential.py | 2 +- core/src/trezor/ui/layouts/tt/__init__.py | 154 +----------------- core/src/trezor/ui/layouts/tt/altcoin.py | 105 ++++++++++++ core/src/trezor/ui/layouts/tt/webauthn.py | 37 +++++ 14 files changed, 200 insertions(+), 170 deletions(-) create mode 100644 core/src/trezor/ui/layouts/tt/altcoin.py create mode 100644 core/src/trezor/ui/layouts/tt/webauthn.py diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 648f60e80..27515558e 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -523,7 +523,12 @@ if FROZEN: if TREZOR_MODEL == 'T': SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/components/tt/*.py')) SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/constants/tt.py')) - SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/__init__.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/reset.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/recovery.py')) + if EVERYTHING: + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/altcoin.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/webauthn.py')) elif TREZOR_MODEL == '1': SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/components/t1/*.py')) SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/constants/t1.py')) diff --git a/core/SConscript.unix b/core/SConscript.unix index 533a44563..0f5b0fe90 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -478,7 +478,12 @@ if FROZEN: if TREZOR_MODEL == 'T': SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/components/tt/*.py')) SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/constants/tt.py')) - SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/__init__.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/reset.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/recovery.py')) + if EVERYTHING: + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/altcoin.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/webauthn.py')) elif TREZOR_MODEL == '1': SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/components/t1/*.py')) SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/constants/t1.py')) diff --git a/core/src/all_modules.py b/core/src/all_modules.py index ee13835c7..82100b224 100644 --- a/core/src/all_modules.py +++ b/core/src/all_modules.py @@ -156,12 +156,20 @@ trezor.ui.components.tt.confirm import trezor.ui.components.tt.confirm trezor.ui.components.tt.info import trezor.ui.components.tt.info +trezor.ui.components.tt.keyboard_bip39 +import trezor.ui.components.tt.keyboard_bip39 +trezor.ui.components.tt.keyboard_slip39 +import trezor.ui.components.tt.keyboard_slip39 trezor.ui.components.tt.num_input import trezor.ui.components.tt.num_input trezor.ui.components.tt.passphrase import trezor.ui.components.tt.passphrase trezor.ui.components.tt.pin import trezor.ui.components.tt.pin +trezor.ui.components.tt.recovery +import trezor.ui.components.tt.recovery +trezor.ui.components.tt.reset +import trezor.ui.components.tt.reset trezor.ui.components.tt.scroll import trezor.ui.components.tt.scroll trezor.ui.components.tt.swipe @@ -186,6 +194,12 @@ trezor.ui.layouts.t1 import trezor.ui.layouts.t1 trezor.ui.layouts.tt import trezor.ui.layouts.tt +trezor.ui.layouts.tt.altcoin +import trezor.ui.layouts.tt.altcoin +trezor.ui.layouts.tt.recovery +import trezor.ui.layouts.tt.recovery +trezor.ui.layouts.tt.reset +import trezor.ui.layouts.tt.reset trezor.ui.loader import trezor.ui.loader trezor.ui.popup @@ -290,8 +304,6 @@ apps.common.confirm import apps.common.confirm apps.common.keychain import apps.common.keychain -apps.common.layout -import apps.common.layout apps.common.passphrase import apps.common.passphrase apps.common.paths @@ -340,10 +352,6 @@ apps.management.recovery_device import apps.management.recovery_device apps.management.recovery_device.homescreen import apps.management.recovery_device.homescreen -apps.management.recovery_device.keyboard_bip39 -import apps.management.recovery_device.keyboard_bip39 -apps.management.recovery_device.keyboard_slip39 -import apps.management.recovery_device.keyboard_slip39 apps.management.recovery_device.layout import apps.management.recovery_device.layout apps.management.recovery_device.recover @@ -400,6 +408,12 @@ if utils.BITCOIN_ONLY: import trezor.enums.TezosBallotType trezor.enums.TezosContractType import trezor.enums.TezosContractType + trezor.ui.components.common.webauthn + import trezor.ui.components.common.webauthn + trezor.ui.components.tt.webauthn + import trezor.ui.components.tt.webauthn + trezor.ui.layouts.tt.webauthn + import trezor.ui.layouts.tt.webauthn apps.binance import apps.binance apps.binance.get_address @@ -686,8 +700,6 @@ if utils.BITCOIN_ONLY: import apps.webauthn.add_resident_credential apps.webauthn.common import apps.webauthn.common - apps.webauthn.confirm - import apps.webauthn.confirm apps.webauthn.credential import apps.webauthn.credential apps.webauthn.fido2 diff --git a/core/src/apps/binance/layout.py b/core/src/apps/binance/layout.py index 134628cd8..f8127476b 100644 --- a/core/src/apps/binance/layout.py +++ b/core/src/apps/binance/layout.py @@ -6,7 +6,8 @@ from trezor.messages import ( BinanceTransferMsg, ) from trezor.strings import format_amount -from trezor.ui.layouts import confirm_properties, confirm_transfer_binance +from trezor.ui.layouts import confirm_properties +from trezor.ui.layouts.tt.altcoin import confirm_transfer_binance from . import helpers diff --git a/core/src/apps/bitcoin/sign_tx/layout.py b/core/src/apps/bitcoin/sign_tx/layout.py index 77206ccf2..a79e05386 100644 --- a/core/src/apps/bitcoin/sign_tx/layout.py +++ b/core/src/apps/bitcoin/sign_tx/layout.py @@ -1,6 +1,7 @@ from micropython import const from ubinascii import hexlify +from trezor import utils from trezor.enums import AmountUnit, ButtonRequestType, OutputScriptType from trezor.strings import format_amount from trezor.ui import layouts @@ -8,6 +9,10 @@ from trezor.ui import layouts from .. import addresses from . import omni +if not utils.BITCOIN_ONLY: + from trezor.ui.layouts.tt import altcoin + + if False: from trezor import wire from trezor.messages import TxOutput @@ -73,7 +78,7 @@ async def confirm_decred_sstx_submission( assert output.address is not None address_short = addresses.address_short(coin, output.address) - await layouts.confirm_decred_sstx_submission( + await altcoin.confirm_decred_sstx_submission( ctx, address_short, format_coin_amount(output.amount, coin, amount_unit) ) diff --git a/core/src/apps/ethereum/layout.py b/core/src/apps/ethereum/layout.py index 87f73f5a4..0e37bb634 100644 --- a/core/src/apps/ethereum/layout.py +++ b/core/src/apps/ethereum/layout.py @@ -3,12 +3,8 @@ from ubinascii import hexlify from trezor import ui from trezor.enums import ButtonRequestType from trezor.strings import format_amount -from trezor.ui.layouts import ( - confirm_address, - confirm_blob, - confirm_output, - confirm_total_ethereum, -) +from trezor.ui.layouts import confirm_address, confirm_blob, confirm_output +from trezor.ui.layouts.tt.altcoin import confirm_total_ethereum from . import networks, tokens from .address import address_from_bytes diff --git a/core/src/apps/ripple/layout.py b/core/src/apps/ripple/layout.py index 1ebc532e6..8106ed726 100644 --- a/core/src/apps/ripple/layout.py +++ b/core/src/apps/ripple/layout.py @@ -1,6 +1,7 @@ from trezor.enums import ButtonRequestType from trezor.strings import format_amount -from trezor.ui.layouts import confirm_metadata, confirm_total_ripple +from trezor.ui.layouts import confirm_metadata +from trezor.ui.layouts.tt.altcoin import confirm_total_ripple from . import helpers diff --git a/core/src/apps/stellar/layout.py b/core/src/apps/stellar/layout.py index 331192c5e..c4897e5ba 100644 --- a/core/src/apps/stellar/layout.py +++ b/core/src/apps/stellar/layout.py @@ -5,8 +5,8 @@ from trezor.ui.layouts import ( confirm_address, confirm_blob, confirm_metadata, - confirm_timebounds_stellar, ) +from trezor.ui.layouts.tt.altcoin import confirm_timebounds_stellar from . import consts diff --git a/core/src/apps/webauthn/add_resident_credential.py b/core/src/apps/webauthn/add_resident_credential.py index 2a72e67df..3a5c48852 100644 --- a/core/src/apps/webauthn/add_resident_credential.py +++ b/core/src/apps/webauthn/add_resident_credential.py @@ -1,7 +1,9 @@ import storage.device from trezor import wire from trezor.messages import Success, WebAuthnAddResidentCredential -from trezor.ui.layouts import confirm_webauthn, show_error_and_raise +from trezor.ui.components.common.webauthn import ConfirmInfo +from trezor.ui.layouts import show_error_and_raise +from trezor.ui.layouts.tt.webauthn import confirm_webauthn from .credential import Fido2Credential from .resident_credentials import store_resident_credential diff --git a/core/src/apps/webauthn/fido2.py b/core/src/apps/webauthn/fido2.py index 248928f48..86b53bd31 100644 --- a/core/src/apps/webauthn/fido2.py +++ b/core/src/apps/webauthn/fido2.py @@ -11,7 +11,8 @@ from trezor.crypto import aes, der, hashlib, hmac, random from trezor.crypto.curve import nist256p1 from trezor.ui.components.common.confirm import Pageable from trezor.ui.components.common.webauthn import ConfirmInfo -from trezor.ui.layouts import confirm_webauthn, confirm_webauthn_reset, show_popup +from trezor.ui.layouts import show_popup +from trezor.ui.layouts.tt.webauthn import confirm_webauthn, confirm_webauthn_reset from apps.base import set_homescreen from apps.common import cbor diff --git a/core/src/apps/webauthn/remove_resident_credential.py b/core/src/apps/webauthn/remove_resident_credential.py index cf6583503..ab4efd17d 100644 --- a/core/src/apps/webauthn/remove_resident_credential.py +++ b/core/src/apps/webauthn/remove_resident_credential.py @@ -3,7 +3,7 @@ import storage.resident_credentials from trezor import wire from trezor.messages import Success, WebAuthnRemoveResidentCredential from trezor.ui.components.common.webauthn import ConfirmInfo -from trezor.ui.layouts import confirm_webauthn +from trezor.ui.layouts.tt.webauthn import confirm_webauthn from .credential import Fido2Credential from .resident_credentials import get_resident_credential diff --git a/core/src/trezor/ui/layouts/tt/__init__.py b/core/src/trezor/ui/layouts/tt/__init__.py index 3bfec71d2..4b0202586 100644 --- a/core/src/trezor/ui/layouts/tt/__init__.py +++ b/core/src/trezor/ui/layouts/tt/__init__.py @@ -11,10 +11,9 @@ from trezor.utils import chunks, chunks_intersperse from ...components.common import break_path_to_lines from ...components.common.confirm import is_confirmed, raise_if_cancelled -from ...components.common.webauthn import ConfirmInfo from ...components.tt import passphrase, pin from ...components.tt.button import ButtonCancel, ButtonDefault -from ...components.tt.confirm import Confirm, ConfirmPageable, HoldToConfirm, Pageable +from ...components.tt.confirm import Confirm, HoldToConfirm from ...components.tt.scroll import ( PAGEBREAK, Paginated, @@ -22,7 +21,6 @@ from ...components.tt.scroll import ( paginate_text, ) from ...components.tt.text import LINE_WIDTH_PAGINATED, Span, Text -from ...components.tt.webauthn import ConfirmContent from ...constants.tt import ( MONO_ADDR_PER_LINE, MONO_HEX_PER_LINE, @@ -34,15 +32,9 @@ from ...constants.tt import ( from ..common import button_request, interact if False: - from typing import ( - Awaitable, - Iterator, - NoReturn, - Sequence, - Tuple, - ) + from typing import Awaitable, Iterator, NoReturn, Sequence - from .common import PropertyType, ExceptionType + from ..common import PropertyType, ExceptionType __all__ = ( @@ -62,23 +54,16 @@ __all__ = ( "show_xpub", "show_warning", "confirm_output", - "confirm_decred_sstx_submission", "confirm_blob", "confirm_properties", "confirm_total", - "confirm_total_ethereum", - "confirm_total_ripple", "confirm_joint_total", "confirm_metadata", "confirm_replacement", "confirm_modify_output", "confirm_modify_fee", "confirm_coinjoin", - "confirm_timebounds_stellar", - "confirm_transfer_binance", "show_popup", - "confirm_webauthn", - "confirm_webauthn_reset", "draw_simple_text", "request_passphrase_on_device", "request_pin_on_device", @@ -237,10 +222,6 @@ def _show_qr( return Confirm(Container(qr, text), cancel=cancel, cancel_style=ButtonDefault) -def _split_address(address: str) -> Iterator[str]: - return chunks_intersperse(address, MONO_ADDR_PER_LINE) - - def _truncate_hex( hex_data: str, lines: int = TEXT_MAX_LINES, @@ -522,25 +503,6 @@ async def confirm_output( await raise_if_cancelled(interact(ctx, content, "confirm_output", br_code)) -async def confirm_decred_sstx_submission( - ctx: wire.GenericContext, - address: str, - amount: str, -) -> None: - text = Text("Purchase ticket", ui.ICON_SEND, ui.GREEN, new_lines=False) - text.normal(amount) - text.normal("\nwith voting rights to\n") - text.mono(*_split_address(address)) - await raise_if_cancelled( - interact( - ctx, - Confirm(text), - "confirm_decred_sstx_submission", - ButtonRequestType.ConfirmOutput, - ) - ) - - async def confirm_blob( ctx: wire.GenericContext, br_type: str, @@ -784,38 +746,6 @@ async def confirm_total( await raise_if_cancelled(interact(ctx, HoldToConfirm(text), br_type, br_code)) -# TODO cleanup @ redesign -async def confirm_total_ethereum( - ctx: wire.GenericContext, total_amount: str, gas_price: str, fee_max: str -) -> None: - text = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN, new_lines=False) - text.bold(total_amount) - text.normal(" ", ui.GREY, "Gas price:", ui.FG) - text.bold(gas_price) - text.normal(" ", ui.GREY, "Maximum fee:", ui.FG) - text.bold(fee_max) - await raise_if_cancelled( - interact(ctx, HoldToConfirm(text), "confirm_total", ButtonRequestType.SignTx) - ) - - -# TODO cleanup @ redesign -async def confirm_total_ripple( - ctx: wire.GenericContext, - address: str, - amount: str, -) -> None: - title = "Confirm sending" - text = Text(title, ui.ICON_SEND, ui.GREEN, new_lines=False) - text.bold("{} XRP\n".format(amount)) - text.normal("to\n") - text.mono(*_split_address(address)) - - await raise_if_cancelled( - interact(ctx, HoldToConfirm(text), "confirm_output", ButtonRequestType.SignTx) - ) - - async def confirm_joint_total( ctx: wire.GenericContext, spending_amount: str, total_amount: str ) -> None: @@ -882,7 +812,7 @@ async def confirm_modify_output( page1 = Text("Modify amount", ui.ICON_SEND, ui.GREEN, new_lines=False) page1.normal("Address:\n") page1.br_half() - page1.mono(*_split_address(address)) + page1.mono(*chunks_intersperse(address, MONO_ADDR_PER_LINE)) page2 = Text("Modify amount", ui.ICON_SEND, ui.GREEN, new_lines=False) if sign < 0: @@ -966,7 +896,7 @@ async def confirm_signverify( text = Text(header, new_lines=False) text.bold("Confirm address:\n") - text.mono(*_split_address(address)) + text.mono(*chunks_intersperse(address, MONO_ADDR_PER_LINE)) await raise_if_cancelled( interact(ctx, Confirm(text), br_type, ButtonRequestType.Other) ) @@ -985,55 +915,10 @@ async def confirm_signverify( ) -# TODO cleanup @ redesign -async def confirm_timebounds_stellar( - ctx: wire.GenericContext, start: int, end: int -) -> None: - text = Text("Confirm timebounds", ui.ICON_SEND, ui.GREEN) - text.bold("Valid from (UTC):") - if start: - text.normal(str(start)) - else: - text.mono("[no restriction]") - - text.bold("Valid to (UTC):") - if end: - text.normal(str(end)) - else: - text.mono("[no restriction]") - - await raise_if_cancelled( - interact( - ctx, Confirm(text), "confirm_timebounds", ButtonRequestType.ConfirmOutput - ) - ) - - -# TODO cleanup @ redesign -async def confirm_transfer_binance( - ctx: wire.GenericContext, inputs_outputs: Sequence[Tuple[str, str, str]] -) -> None: - pages: list[ui.Component] = [] - for title, amount, address in inputs_outputs: - coin_page = Text(title, ui.ICON_SEND, icon_color=ui.GREEN, new_lines=False) - coin_page.bold(amount) - coin_page.normal("\nto\n") - coin_page.mono(*_split_address(address)) - pages.append(coin_page) - - pages[-1] = HoldToConfirm(pages[-1]) - - await raise_if_cancelled( - interact( - ctx, Paginated(pages), "confirm_transfer", ButtonRequestType.ConfirmOutput - ) - ) - - async def show_popup( title: str, description: str, - subtitle: Optional[str] = None, + subtitle: str | None = None, description_param: str = "", timeout_ms: int = 3000, ) -> None: @@ -1045,31 +930,6 @@ async def show_popup( await Popup(text, timeout_ms) -async def confirm_webauthn( - ctx: Optional[wire.GenericContext], - info: ConfirmInfo, - pageable: Optional[Pageable] = None, -) -> bool: - if pageable is not None: - confirm: ui.Layout = ConfirmPageable(pageable, ConfirmContent(info)) - else: - confirm = Confirm(ConfirmContent(info)) - - if ctx is None: - return is_confirmed(await confirm) - else: - return is_confirmed( - await interact(ctx, confirm, "confirm_webauthn", ButtonRequestType.Other) - ) - - -async def confirm_webauthn_reset() -> bool: - text = Text("FIDO2 Reset", ui.ICON_CONFIG) - text.normal("Do you really want to") - text.bold("erase all credentials?") - return is_confirmed(await Confirm(text)) - - def draw_simple_text(title: str, description: str = "") -> None: text = Text(title, ui.ICON_CONFIG, new_lines=False) text.normal(description) @@ -1093,7 +953,7 @@ async def request_passphrase_on_device(ctx: wire.GenericContext, max_len: int) - async def request_pin_on_device( ctx: wire.GenericContext, prompt: str, - attempts_remaining: Optional[int], + attempts_remaining: int | None, allow_cancel: bool, ) -> str: await button_request(ctx, "pin_device", code=ButtonRequestType.PinEntry) diff --git a/core/src/trezor/ui/layouts/tt/altcoin.py b/core/src/trezor/ui/layouts/tt/altcoin.py new file mode 100644 index 000000000..8fcacb35f --- /dev/null +++ b/core/src/trezor/ui/layouts/tt/altcoin.py @@ -0,0 +1,105 @@ +from trezor import ui, wire +from trezor.enums import ButtonRequestType +from trezor.utils import chunks_intersperse + +from ...components.common.confirm import raise_if_cancelled +from ...components.tt.confirm import Confirm, HoldToConfirm +from ...components.tt.scroll import Paginated +from ...components.tt.text import Text +from ...constants.tt import MONO_ADDR_PER_LINE +from ..common import interact + +if False: + from typing import Sequence + + +async def confirm_total_ethereum( + ctx: wire.GenericContext, total_amount: str, gas_price: str, fee_max: str +) -> None: + text = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN, new_lines=False) + text.bold(total_amount) + text.normal(" ", ui.GREY, "Gas price:", ui.FG) + text.bold(gas_price) + text.normal(" ", ui.GREY, "Maximum fee:", ui.FG) + text.bold(fee_max) + await raise_if_cancelled( + interact(ctx, HoldToConfirm(text), "confirm_total", ButtonRequestType.SignTx) + ) + + +async def confirm_total_ripple( + ctx: wire.GenericContext, + address: str, + amount: str, +) -> None: + title = "Confirm sending" + text = Text(title, ui.ICON_SEND, ui.GREEN, new_lines=False) + text.bold("{} XRP\n".format(amount)) + text.normal("to\n") + text.mono(*chunks_intersperse(address, MONO_ADDR_PER_LINE)) + + await raise_if_cancelled( + interact(ctx, HoldToConfirm(text), "confirm_output", ButtonRequestType.SignTx) + ) + + +async def confirm_timebounds_stellar( + ctx: wire.GenericContext, start: int, end: int +) -> None: + text = Text("Confirm timebounds", ui.ICON_SEND, ui.GREEN) + text.bold("Valid from (UTC):") + if start: + text.normal(str(start)) + else: + text.mono("[no restriction]") + + text.bold("Valid to (UTC):") + if end: + text.normal(str(end)) + else: + text.mono("[no restriction]") + + await raise_if_cancelled( + interact( + ctx, Confirm(text), "confirm_timebounds", ButtonRequestType.ConfirmOutput + ) + ) + + +async def confirm_transfer_binance( + ctx: wire.GenericContext, inputs_outputs: Sequence[tuple[str, str, str]] +) -> None: + pages: list[ui.Component] = [] + for title, amount, address in inputs_outputs: + coin_page = Text(title, ui.ICON_SEND, icon_color=ui.GREEN, new_lines=False) + coin_page.bold(amount) + coin_page.normal("\nto\n") + coin_page.mono(*chunks_intersperse(address, MONO_ADDR_PER_LINE)) + pages.append(coin_page) + + pages[-1] = HoldToConfirm(pages[-1]) + + await raise_if_cancelled( + interact( + ctx, Paginated(pages), "confirm_transfer", ButtonRequestType.ConfirmOutput + ) + ) + + +async def confirm_decred_sstx_submission( + ctx: wire.GenericContext, + address: str, + amount: str, +) -> None: + text = Text("Purchase ticket", ui.ICON_SEND, ui.GREEN, new_lines=False) + text.normal(amount) + text.normal("\nwith voting rights to\n") + text.mono(*chunks_intersperse(address, MONO_ADDR_PER_LINE)) + await raise_if_cancelled( + interact( + ctx, + Confirm(text), + "confirm_decred_sstx_submission", + ButtonRequestType.ConfirmOutput, + ) + ) diff --git a/core/src/trezor/ui/layouts/tt/webauthn.py b/core/src/trezor/ui/layouts/tt/webauthn.py new file mode 100644 index 000000000..c31ec164d --- /dev/null +++ b/core/src/trezor/ui/layouts/tt/webauthn.py @@ -0,0 +1,37 @@ +from trezor import ui, wire +from trezor.enums import ButtonRequestType + +from ...components.common.confirm import is_confirmed +from ...components.common.webauthn import ConfirmInfo +from ...components.tt.confirm import Confirm, ConfirmPageable, Pageable +from ...components.tt.text import Text +from ...components.tt.webauthn import ConfirmContent +from ..common import interact + +if False: + from typing import Optional + + +async def confirm_webauthn( + ctx: Optional[wire.GenericContext], + info: ConfirmInfo, + pageable: Optional[Pageable] = None, +) -> bool: + if pageable is not None: + confirm: ui.Layout = ConfirmPageable(pageable, ConfirmContent(info)) + else: + confirm = Confirm(ConfirmContent(info)) + + if ctx is None: + return is_confirmed(await confirm) + else: + return is_confirmed( + await interact(ctx, confirm, "confirm_webauthn", ButtonRequestType.Other) + ) + + +async def confirm_webauthn_reset() -> bool: + text = Text("FIDO2 Reset", ui.ICON_CONFIG) + text.normal("Do you really want to") + text.bold("erase all credentials?") + return is_confirmed(await Confirm(text))