1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-24 07:18:09 +00:00

refactor(core/ui): use LayoutObj signatures in layout files

* make sure every confirm_* returns None
* prefer "def -> Awaitable[T]" to "async def -> T" everywhere (avoids one useless allocation per call)
* type-check return values from Rust layouts
This commit is contained in:
matejcik 2024-02-29 11:56:34 +01:00 committed by matejcik
parent 0304484ca6
commit 34965ca2cb
7 changed files with 196 additions and 186 deletions

View File

@ -2061,7 +2061,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// def select_word_count( /// def select_word_count(
/// *, /// *,
/// dry_run: bool, # unused on TR /// dry_run: bool, # unused on TR
/// ) -> int | str: # TR returns str
/// ) -> LayoutObj[int | str]: /// ) -> LayoutObj[int | str]:
/// """Select mnemonic word count from (12, 18, 20, 24, 33).""" /// """Select mnemonic word count from (12, 18, 20, 24, 33)."""
Qstr::MP_QSTR_select_word_count => obj_fn_kw!(0, new_select_word_count).as_obj(), Qstr::MP_QSTR_select_word_count => obj_fn_kw!(0, new_select_word_count).as_obj(),
@ -2124,7 +2123,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Ask whether to update firmware, optionally show fingerprint. Shared with bootloader.""" /// """Ask whether to update firmware, optionally show fingerprint. Shared with bootloader."""
Qstr::MP_QSTR_confirm_firmware_update => obj_fn_kw!(0, new_confirm_firmware_update).as_obj(), Qstr::MP_QSTR_confirm_firmware_update => obj_fn_kw!(0, new_confirm_firmware_update).as_obj(),
/// def show_wait_text(/, message: str) -> None: /// def show_wait_text(message: str, /) -> None:
/// """Show single-line text in the middle of the screen.""" /// """Show single-line text in the middle of the screen."""
Qstr::MP_QSTR_show_wait_text => obj_fn_1!(new_show_wait_text).as_obj(), Qstr::MP_QSTR_show_wait_text => obj_fn_1!(new_show_wait_text).as_obj(),
}; };

View File

@ -2179,7 +2179,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Ask whether to update firmware, optionally show fingerprint. Shared with bootloader.""" /// """Ask whether to update firmware, optionally show fingerprint. Shared with bootloader."""
Qstr::MP_QSTR_confirm_firmware_update => obj_fn_kw!(0, new_confirm_firmware_update).as_obj(), Qstr::MP_QSTR_confirm_firmware_update => obj_fn_kw!(0, new_confirm_firmware_update).as_obj(),
/// def show_wait_text(/, message: str) -> LayoutObj[None]: /// def show_wait_text(message: str, /) -> LayoutObj[None]:
/// """Show single-line text in the middle of the screen.""" /// """Show single-line text in the middle of the screen."""
Qstr::MP_QSTR_show_wait_text => obj_fn_1!(new_show_wait_text).as_obj(), Qstr::MP_QSTR_show_wait_text => obj_fn_1!(new_show_wait_text).as_obj(),
}; };

View File

@ -384,7 +384,6 @@ def confirm_recovery(
def select_word_count( def select_word_count(
*, *,
dry_run: bool, # unused on TR dry_run: bool, # unused on TR
) -> int | str: # TR returns str
) -> LayoutObj[int | str]: ) -> LayoutObj[int | str]:
"""Select mnemonic word count from (12, 18, 20, 24, 33).""" """Select mnemonic word count from (12, 18, 20, 24, 33)."""
@ -454,7 +453,7 @@ def confirm_firmware_update(
# rust/src/ui/model_tr/layout.rs # rust/src/ui/model_tr/layout.rs
def show_wait_text(/, message: str) -> None: def show_wait_text(message: str, /) -> None:
"""Show single-line text in the middle of the screen.""" """Show single-line text in the middle of the screen."""
from trezor import utils from trezor import utils
T = TypeVar("T") T = TypeVar("T")
@ -972,5 +971,5 @@ def confirm_firmware_update(
# rust/src/ui/model_tt/layout.rs # rust/src/ui/model_tt/layout.rs
def show_wait_text(/, message: str) -> LayoutObj[None]: def show_wait_text(message: str, /) -> LayoutObj[None]:
"""Show single-line text in the middle of the screen.""" """Show single-line text in the middle of the screen."""

View File

@ -5,6 +5,17 @@ from typing import TYPE_CHECKING, Any, Awaitable, Generator
from trezor import loop, utils from trezor import loop, utils
if TYPE_CHECKING:
from typing import Generic, TypeVar
from trezorui2 import UiResult # noqa: F401
T = TypeVar("T")
else:
Generic = [object]
T = 0
# all rendering is done through a singleton of `Display` # all rendering is done through a singleton of `Display`
display = Display() display = Display()
@ -113,7 +124,7 @@ class Cancelled(Exception):
""" """
class Layout: class Layout(Generic[T]):
""" """
Abstract class. Abstract class.
@ -123,7 +134,7 @@ class Layout:
raised, usually from some of the child components. raised, usually from some of the child components.
""" """
async def __iter__(self) -> Any: async def __iter__(self) -> T:
""" """
Run the layout and wait until it completes. Returns the result value. Run the layout and wait until it completes. Returns the result value.
Usually not overridden. Usually not overridden.
@ -155,8 +166,8 @@ class Layout:
if TYPE_CHECKING: if TYPE_CHECKING:
def __await__(self) -> Generator: def __await__(self) -> Generator[Any, Any, T]:
return self.__iter__() # type: ignore [Expression of type "Coroutine[Any, Any, Any]" cannot be assigned to return type "Generator[Unknown, Unknown, Unknown]"] return self.__iter__() # type: ignore [Coroutine[Any, Any, T@Layout]" is incompatible with "Generator[Any, Any, T@Layout]"]
else: else:
__await__ = __iter__ __await__ = __iter__

View File

@ -6,9 +6,11 @@ from trezor.messages import ButtonAck, ButtonRequest
from trezor.wire import context from trezor.wire import context
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Awaitable, Protocol from typing import Awaitable, Protocol, TypeVar
LayoutType = Awaitable[Any] T = TypeVar("T")
LayoutType = Awaitable
PropertyType = tuple[str | None, str | bytes | None] PropertyType = tuple[str | None, str | bytes | None]
ExceptionType = BaseException | type[BaseException] ExceptionType = BaseException | type[BaseException]
@ -28,10 +30,10 @@ async def button_request(
async def interact( async def interact(
layout: LayoutType, layout: LayoutType[T],
br_type: str, br_type: str,
br_code: ButtonRequestType = ButtonRequestType.Other, br_code: ButtonRequestType = ButtonRequestType.Other,
) -> Any: ) -> T:
pages = None pages = None
if hasattr(layout, "page_count") and layout.page_count() > 1: # type: ignore [Cannot access member "page_count" for type "LayoutType"] if hasattr(layout, "page_count") and layout.page_count() > 1: # type: ignore [Cannot access member "page_count" for type "LayoutType"]
# We know for certain how many pages the layout will have # We know for certain how many pages the layout will have

View File

@ -15,6 +15,12 @@ if TYPE_CHECKING:
T = TypeVar("T") T = TypeVar("T")
LayoutParentType = ui.Layout[T]
else:
LayoutParentType = [ui.Layout]
T = 0
CONFIRMED = trezorui2.CONFIRMED CONFIRMED = trezorui2.CONFIRMED
CANCELLED = trezorui2.CANCELLED CANCELLED = trezorui2.CANCELLED
@ -29,9 +35,9 @@ if __debug__:
trezorui2.disable_animation(bool(DISABLE_ANIMATION)) trezorui2.disable_animation(bool(DISABLE_ANIMATION))
class RustLayout(ui.Layout): class RustLayout(LayoutParentType[T]):
# pylint: disable=super-init-not-called # pylint: disable=super-init-not-called
def __init__(self, layout: Any): def __init__(self, layout: trezorui2.LayoutObj[T]):
self.layout = layout self.layout = layout
self.timer = loop.Timer() self.timer = loop.Timer()
self.layout.attach_timer_fn(self.set_timer) self.layout.attach_timer_fn(self.set_timer)
@ -245,7 +251,7 @@ class RustLayout(ui.Layout):
return self.layout.page_count() return self.layout.page_count()
def draw_simple(layout: Any) -> None: def draw_simple(layout: trezorui2.LayoutObj[Any]) -> None:
# Simple drawing not supported for layouts that set timers. # Simple drawing not supported for layouts that set timers.
def dummy_set_timer(token: int, deadline: int) -> None: def dummy_set_timer(token: int, deadline: int) -> None:
raise RuntimeError raise RuntimeError
@ -257,7 +263,7 @@ def draw_simple(layout: Any) -> None:
# Temporary function, so we know where it is used # Temporary function, so we know where it is used
# Should be gradually replaced by custom designs/layouts # Should be gradually replaced by custom designs/layouts
async def _placeholder_confirm( def _placeholder_confirm(
br_type: str, br_type: str,
title: str, title: str,
data: str | None = None, data: str | None = None,
@ -267,9 +273,9 @@ async def _placeholder_confirm(
verb_cancel: str | None = "", verb_cancel: str | None = "",
hold: bool = False, hold: bool = False,
br_code: ButtonRequestType = BR_TYPE_OTHER, br_code: ButtonRequestType = BR_TYPE_OTHER,
) -> Any: ) -> Awaitable[None]:
verb = verb or TR.buttons__confirm # def_arg verb = verb or TR.buttons__confirm # def_arg
return await confirm_action( return confirm_action(
br_type, br_type,
title.upper(), title.upper(),
data, data,
@ -311,14 +317,15 @@ async def get_bool(
return result is CONFIRMED return result is CONFIRMED
async def raise_if_not_confirmed(a: Awaitable[T], exc: Any = ActionCancelled) -> T: async def raise_if_not_confirmed(
a: Awaitable[ui.UiResult], exc: Any = ActionCancelled
) -> None:
result = await a result = await a
if result is not CONFIRMED: if result is not CONFIRMED:
raise exc raise exc
return result
async def confirm_action( def confirm_action(
br_type: str, br_type: str,
title: str, title: str,
action: str | None = None, action: str | None = None,
@ -331,7 +338,7 @@ async def confirm_action(
reverse: bool = False, reverse: bool = False,
exc: ExceptionType = ActionCancelled, exc: ExceptionType = ActionCancelled,
br_code: ButtonRequestType = BR_TYPE_OTHER, br_code: ButtonRequestType = BR_TYPE_OTHER,
) -> None: ) -> Awaitable[None]:
verb = verb or TR.buttons__confirm # def_arg verb = verb or TR.buttons__confirm # def_arg
if verb_cancel is not None: if verb_cancel is not None:
verb_cancel = verb_cancel.upper() verb_cancel = verb_cancel.upper()
@ -339,7 +346,7 @@ async def confirm_action(
if description is not None and description_param is not None: if description is not None and description_param is not None:
description = description.format(description_param) description = description.format(description_param)
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_action( trezorui2.confirm_action(
@ -359,13 +366,13 @@ async def confirm_action(
) )
async def confirm_single( def confirm_single(
br_type: str, br_type: str,
title: str, title: str,
description: str, description: str,
description_param: str | None = None, description_param: str | None = None,
verb: str | None = None, verb: str | None = None,
) -> None: ) -> Awaitable[None]:
description_param = description_param or "" description_param = description_param or ""
# Placeholders are coming from translations in form of {0} # Placeholders are coming from translations in form of {0}
@ -374,7 +381,7 @@ async def confirm_single(
template_str = "{}" template_str = "{}"
begin, _separator, end = description.partition(template_str) begin, _separator, end = description.partition(template_str)
await confirm_action( return confirm_action(
br_type, br_type,
title, title,
description=begin + description_param + end, description=begin + description_param + end,
@ -383,16 +390,16 @@ async def confirm_single(
) )
async def confirm_reset_device( def confirm_reset_device(
title: str, title: str,
recovery: bool = False, recovery: bool = False,
) -> None: ) -> Awaitable[None]:
if recovery: if recovery:
button = TR.reset__button_recover button = TR.reset__button_recover
else: else:
button = TR.reset__button_create button = TR.reset__button_create
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_reset_device( trezorui2.confirm_reset_device(
@ -432,12 +439,12 @@ async def prompt_backup() -> bool:
) )
async def confirm_path_warning( def confirm_path_warning(
path: str, path: str,
path_type: str | None = None, path_type: str | None = None,
) -> None: ) -> Awaitable[None]:
title = f"{TR.words__unknown} {path_type if path_type else 'path'}" title = f"{TR.words__unknown} {path_type if path_type else 'path'}"
return await _placeholder_confirm( return _placeholder_confirm(
"path_warning", "path_warning",
title.upper(), title.upper(),
description=path, description=path,
@ -445,10 +452,8 @@ async def confirm_path_warning(
) )
async def confirm_homescreen( def confirm_homescreen(image: bytes) -> Awaitable[None]:
image: bytes, return raise_if_not_confirmed(
) -> None:
await raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_homescreen( trezorui2.confirm_homescreen(
@ -572,7 +577,7 @@ def show_pubkey(
) )
async def _show_modal( def _show_modal(
br_type: str, br_type: str,
header: str, header: str,
subheader: str | None, subheader: str | None,
@ -581,8 +586,8 @@ async def _show_modal(
button_cancel: str | None, button_cancel: str | None,
br_code: ButtonRequestType, br_code: ButtonRequestType,
exc: ExceptionType = ActionCancelled, exc: ExceptionType = ActionCancelled,
) -> None: ) -> Awaitable[None]:
await confirm_action( return confirm_action(
br_type, br_type,
header.upper(), header.upper(),
subheader, subheader,
@ -612,13 +617,13 @@ async def show_error_and_raise(
raise exc raise exc
async def show_warning( def show_warning(
br_type: str, br_type: str,
content: str, content: str,
subheader: str | None = None, subheader: str | None = None,
button: str | None = None, button: str | None = None,
br_code: ButtonRequestType = ButtonRequestType.Warning, br_code: ButtonRequestType = ButtonRequestType.Warning,
) -> None: ) -> Awaitable[None]:
from trezor import translations from trezor import translations
button = button or TR.buttons__continue # def_arg button = button or TR.buttons__continue # def_arg
@ -630,7 +635,7 @@ async def show_warning(
if content and subheader and translations.get_language() == "en-US": if content and subheader and translations.get_language() == "en-US":
content = content + "\n" content = content + "\n"
await interact( return interact(
RustLayout( RustLayout(
trezorui2.show_warning( # type: ignore [Argument missing for parameter "title"] trezorui2.show_warning( # type: ignore [Argument missing for parameter "title"]
button=button.upper(), button=button.upper(),
@ -724,11 +729,9 @@ async def confirm_output(
return return
async def tutorial( def tutorial(br_code: ButtonRequestType = BR_TYPE_OTHER) -> Awaitable[None]:
br_code: ButtonRequestType = BR_TYPE_OTHER,
) -> None:
"""Showing users how to interact with the device.""" """Showing users how to interact with the device."""
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout(trezorui2.tutorial()), RustLayout(trezorui2.tutorial()),
"tutorial", "tutorial",
@ -737,13 +740,13 @@ async def tutorial(
) )
async def confirm_payment_request( def confirm_payment_request(
recipient_name: str, recipient_name: str,
amount: str, amount: str,
memos: list[str], memos: list[str],
) -> Any: ) -> Awaitable[None]:
memos_str = "\n".join(memos) memos_str = "\n".join(memos)
return await _placeholder_confirm( return _placeholder_confirm(
"confirm_payment_request", "confirm_payment_request",
TR.send__title_confirm_sending, TR.send__title_confirm_sending,
description=f"{amount} to\n{recipient_name}\n{memos_str}", description=f"{amount} to\n{recipient_name}\n{memos_str}",
@ -792,7 +795,7 @@ async def should_show_more(
raise ActionCancelled raise ActionCancelled
async def confirm_blob( def confirm_blob(
br_type: str, br_type: str,
title: str, title: str,
data: bytes | str, data: bytes | str,
@ -803,7 +806,7 @@ async def confirm_blob(
br_code: ButtonRequestType = BR_TYPE_OTHER, br_code: ButtonRequestType = BR_TYPE_OTHER,
ask_pagination: bool = False, ask_pagination: bool = False,
chunkify: bool = False, chunkify: bool = False,
) -> None: ) -> Awaitable[None]:
verb = verb or TR.buttons__confirm # def_arg verb = verb or TR.buttons__confirm # def_arg
title = title.upper() title = title.upper()
layout = RustLayout( layout = RustLayout(
@ -821,12 +824,12 @@ async def confirm_blob(
if ask_pagination and layout.page_count() > 1: if ask_pagination and layout.page_count() > 1:
assert not hold assert not hold
await _confirm_ask_pagination( return _confirm_ask_pagination(
br_type, title, data, description or "", verb_cancel, br_code br_type, title, data, description or "", verb_cancel, br_code
) )
else: else:
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
layout, layout,
br_type, br_type,
@ -843,7 +846,7 @@ async def _confirm_ask_pagination(
verb_cancel: str | None, verb_cancel: str | None,
br_code: ButtonRequestType, br_code: ButtonRequestType,
) -> None: ) -> None:
paginated: ui.Layout | None = None paginated: RustLayout[trezorui2.UiResult] | None = None
# TODO: make should_show_more/confirm_more accept bytes directly # TODO: make should_show_more/confirm_more accept bytes directly
if isinstance(data, bytes): if isinstance(data, bytes):
from ubinascii import hexlify from ubinascii import hexlify
@ -892,14 +895,14 @@ def confirm_address(
) )
async def confirm_text( def confirm_text(
br_type: str, br_type: str,
title: str, title: str,
data: str, data: str,
description: str | None = None, description: str | None = None,
br_code: ButtonRequestType = BR_TYPE_OTHER, br_code: ButtonRequestType = BR_TYPE_OTHER,
) -> Any: ) -> Awaitable[None]:
return await _placeholder_confirm( return _placeholder_confirm(
br_type, br_type,
title, title,
data, data,
@ -925,13 +928,13 @@ def confirm_amount(
) )
async def confirm_properties( def confirm_properties(
br_type: str, br_type: str,
title: str, title: str,
props: Iterable[PropertyType], props: Iterable[PropertyType],
hold: bool = False, hold: bool = False,
br_code: ButtonRequestType = ButtonRequestType.ConfirmOutput, br_code: ButtonRequestType = ButtonRequestType.ConfirmOutput,
) -> None: ) -> Awaitable[None]:
from ubinascii import hexlify from ubinascii import hexlify
def handle_bytes(prop: PropertyType): def handle_bytes(prop: PropertyType):
@ -943,7 +946,7 @@ async def confirm_properties(
is_data = prop[1] and " " not in prop[1] is_data = prop[1] and " " not in prop[1]
return (prop[0], prop[1], is_data) return (prop[0], prop[1], is_data)
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_properties( trezorui2.confirm_properties(
@ -1021,7 +1024,7 @@ async def confirm_value(
result = await ctx_wait(should_show_more_layout) result = await ctx_wait(should_show_more_layout)
if result is CONFIRMED: if result is CONFIRMED:
break return
elif result is INFO: elif result is INFO:
info_title, info_value = info_items_list[0] info_title, info_value = info_items_list[0]
await ctx_wait( await ctx_wait(
@ -1043,7 +1046,7 @@ async def confirm_value(
raise ActionCancelled raise ActionCancelled
async def confirm_total( def confirm_total(
total_amount: str, total_amount: str,
fee_amount: str, fee_amount: str,
fee_rate_amount: str | None = None, fee_rate_amount: str | None = None,
@ -1053,10 +1056,10 @@ async def confirm_total(
account_label: str | None = None, account_label: str | None = None,
br_type: str = "confirm_total", br_type: str = "confirm_total",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
) -> None: ) -> Awaitable[None]:
total_label = total_label or TR.send__total_amount # def_arg total_label = total_label or TR.send__total_amount # def_arg
fee_label = fee_label or TR.send__including_fee # def_arg fee_label = fee_label or TR.send__including_fee # def_arg
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
# TODO: resolve these differences in TT's and TR's confirm_total # TODO: resolve these differences in TT's and TR's confirm_total
@ -1088,7 +1091,6 @@ async def confirm_ethereum_staking_tx(
br_type: str = "confirm_ethereum_staking_tx", br_type: str = "confirm_ethereum_staking_tx",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
) -> None: ) -> None:
# intro # intro
await confirm_value( await confirm_value(
title, title,
@ -1126,7 +1128,7 @@ async def confirm_ethereum_staking_tx(
) )
async def confirm_solana_tx( def confirm_solana_tx(
amount: str, amount: str,
fee: str, fee: str,
items: Iterable[tuple[str, str]], items: Iterable[tuple[str, str]],
@ -1134,12 +1136,12 @@ async def confirm_solana_tx(
fee_title: str | None = None, fee_title: str | None = None,
br_type: str = "confirm_solana_tx", br_type: str = "confirm_solana_tx",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
): ) -> Awaitable[None]:
amount_title = ( amount_title = (
amount_title if amount_title is not None else f"{TR.words__amount}:" amount_title if amount_title is not None else f"{TR.words__amount}:"
) # def_arg ) # def_arg
fee_title = fee_title or TR.words__fee # def_arg fee_title = fee_title or TR.words__fee # def_arg
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.altcoin_tx_summary( trezorui2.altcoin_tx_summary(
@ -1200,8 +1202,8 @@ async def confirm_ethereum_tx(
continue continue
async def confirm_joint_total(spending_amount: str, total_amount: str) -> None: def confirm_joint_total(spending_amount: str, total_amount: str) -> Awaitable[None]:
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_joint_total( trezorui2.confirm_joint_total(
@ -1215,15 +1217,15 @@ async def confirm_joint_total(spending_amount: str, total_amount: str) -> None:
) )
async def confirm_metadata( def confirm_metadata(
br_type: str, br_type: str,
title: str, title: str,
content: str, content: str,
param: str | None = None, param: str | None = None,
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
hold: bool = False, hold: bool = False,
) -> None: ) -> Awaitable[None]:
await _placeholder_confirm( return _placeholder_confirm(
br_type, br_type,
title.upper(), title.upper(),
description=content.format(param), description=content.format(param),
@ -1232,8 +1234,8 @@ async def confirm_metadata(
) )
async def confirm_replacement(description: str, txid: str) -> None: def confirm_replacement(description: str, txid: str) -> Awaitable[None]:
await confirm_value( return confirm_value(
description.upper(), description.upper(),
txid, txid,
TR.send__transaction_id, TR.send__transaction_id,
@ -1292,14 +1294,14 @@ async def confirm_modify_output(
break break
async def confirm_modify_fee( def confirm_modify_fee(
title: str, title: str,
sign: int, sign: int,
user_fee_change: str, user_fee_change: str,
total_fee_new: str, total_fee_new: str,
fee_rate_amount: str | None = None, fee_rate_amount: str | None = None,
) -> None: ) -> Awaitable[None]:
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_modify_fee( trezorui2.confirm_modify_fee(
@ -1316,8 +1318,8 @@ async def confirm_modify_fee(
) )
async def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> None: def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> Awaitable[None]:
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_coinjoin( trezorui2.confirm_coinjoin(
@ -1332,15 +1334,15 @@ async def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> None:
# TODO cleanup @ redesign # TODO cleanup @ redesign
async def confirm_sign_identity( def confirm_sign_identity(
proto: str, identity: str, challenge_visual: str | None proto: str, identity: str, challenge_visual: str | None
) -> None: ) -> Awaitable[None]:
text = "" text = ""
if challenge_visual: if challenge_visual:
text += f"{challenge_visual}\n\n" text += f"{challenge_visual}\n\n"
text += identity text += identity
await _placeholder_confirm( return _placeholder_confirm(
"confirm_sign_identity", "confirm_sign_identity",
f"{TR.words__sign} {proto}".upper(), f"{TR.words__sign} {proto}".upper(),
text, text,
@ -1383,7 +1385,7 @@ async def confirm_signverify(
break break
async def show_error_popup( def show_error_popup(
title: str, title: str,
description: str, description: str,
subtitle: str | None = None, subtitle: str | None = None,
@ -1391,19 +1393,20 @@ async def show_error_popup(
*, *,
button: str = "", button: str = "",
timeout_ms: int = 0, timeout_ms: int = 0,
) -> None: ) -> Awaitable[None]:
if button: if button:
raise NotImplementedError("Button not implemented") raise NotImplementedError("Button not implemented")
description = description.format(description_param) description = description.format(description_param)
if subtitle: if subtitle:
description = f"{subtitle}\n{description}" description = f"{subtitle}\n{description}"
await RustLayout( layout = RustLayout(
trezorui2.show_info( trezorui2.show_info(
title=title, title=title,
description=description, description=description,
time_ms=timeout_ms, time_ms=timeout_ms,
) )
) )
return layout # type: ignore [Expression of type "RustLayout[UiResult]" cannot be assigned to return type "Awaitable[None]"]
def request_passphrase_on_host() -> None: def request_passphrase_on_host() -> None:
@ -1468,15 +1471,13 @@ async def request_pin_on_device(
return result return result
async def confirm_reenter_pin( def confirm_reenter_pin(is_wipe_code: bool = False) -> Awaitable[None]:
is_wipe_code: bool = False,
) -> None:
br_type = "reenter_wipe_code" if is_wipe_code else "reenter_pin" br_type = "reenter_wipe_code" if is_wipe_code else "reenter_pin"
title = TR.wipe_code__title_check if is_wipe_code else TR.pin__title_check_pin title = TR.wipe_code__title_check if is_wipe_code else TR.pin__title_check_pin
description = ( description = (
TR.wipe_code__reenter_to_confirm if is_wipe_code else TR.pin__reenter_to_confirm TR.wipe_code__reenter_to_confirm if is_wipe_code else TR.pin__reenter_to_confirm
) )
return await confirm_action( return confirm_action(
br_type, br_type,
title, title,
description=description, description=description,
@ -1486,14 +1487,14 @@ async def confirm_reenter_pin(
) )
async def _confirm_multiple_pages_texts( def _confirm_multiple_pages_texts(
br_type: str, br_type: str,
title: str, title: str,
items: list[str], items: list[str],
verb: str, verb: str,
br_code: ButtonRequestType = BR_TYPE_OTHER, br_code: ButtonRequestType = BR_TYPE_OTHER,
) -> None: ) -> Awaitable[None]:
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.multiple_pages_texts( trezorui2.multiple_pages_texts(
@ -1508,12 +1509,10 @@ async def _confirm_multiple_pages_texts(
) )
async def pin_mismatch_popup( def pin_mismatch_popup(is_wipe_code: bool = False) -> Awaitable[None]:
is_wipe_code: bool = False,
) -> None:
description = TR.wipe_code__mismatch if is_wipe_code else TR.pin__mismatch description = TR.wipe_code__mismatch if is_wipe_code else TR.pin__mismatch
br_code = "wipe_code_mismatch" if is_wipe_code else "pin_mismatch" br_code = "wipe_code_mismatch" if is_wipe_code else "pin_mismatch"
return await show_warning( return show_warning(
br_code, br_code,
description, description,
TR.pin__please_check_again, TR.pin__please_check_again,
@ -1522,8 +1521,8 @@ async def pin_mismatch_popup(
) )
async def wipe_code_same_as_pin_popup() -> None: def wipe_code_same_as_pin_popup() -> Awaitable[None]:
return await confirm_action( return confirm_action(
"wipe_code_same_as_pin", "wipe_code_same_as_pin",
TR.wipe_code__title_invalid, TR.wipe_code__title_invalid,
description=TR.wipe_code__diff_from_pin, description=TR.wipe_code__diff_from_pin,
@ -1566,8 +1565,8 @@ async def confirm_set_new_pin(
) )
async def confirm_firmware_update(description: str, fingerprint: str) -> None: def confirm_firmware_update(description: str, fingerprint: str) -> Awaitable[None]:
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_firmware_update( trezorui2.confirm_firmware_update(

View File

@ -15,6 +15,12 @@ if TYPE_CHECKING:
T = TypeVar("T") T = TypeVar("T")
LayoutParentType = ui.Layout[T]
else:
LayoutParentType = [ui.Layout]
T = 0
BR_TYPE_OTHER = ButtonRequestType.Other # global_import_cache BR_TYPE_OTHER = ButtonRequestType.Other # global_import_cache
@ -29,11 +35,11 @@ if __debug__:
trezorui2.disable_animation(bool(DISABLE_ANIMATION)) trezorui2.disable_animation(bool(DISABLE_ANIMATION))
class RustLayout(ui.Layout): class RustLayout(LayoutParentType[T]):
BACKLIGHT_LEVEL = ui.style.BACKLIGHT_NORMAL BACKLIGHT_LEVEL = ui.style.BACKLIGHT_NORMAL
# pylint: disable=super-init-not-called # pylint: disable=super-init-not-called
def __init__(self, layout: Any): def __init__(self, layout: trezorui2.LayoutObj[T]):
self.layout = layout self.layout = layout
self.timer = loop.Timer() self.timer = loop.Timer()
self.layout.attach_timer_fn(self.set_timer) self.layout.attach_timer_fn(self.set_timer)
@ -216,7 +222,7 @@ class RustLayout(ui.Layout):
return self.layout.page_count() return self.layout.page_count()
def draw_simple(layout: Any) -> None: def draw_simple(layout: trezorui2.LayoutObj[Any]) -> None:
# Simple drawing not supported for layouts that set timers. # Simple drawing not supported for layouts that set timers.
def dummy_set_timer(token: int, deadline: int) -> None: def dummy_set_timer(token: int, deadline: int) -> None:
raise RuntimeError raise RuntimeError
@ -228,14 +234,15 @@ def draw_simple(layout: Any) -> None:
ui.backlight_fade(ui.style.BACKLIGHT_NORMAL) ui.backlight_fade(ui.style.BACKLIGHT_NORMAL)
async def raise_if_not_confirmed(a: Awaitable[T], exc: Any = ActionCancelled) -> T: async def raise_if_not_confirmed(
a: Awaitable[ui.UiResult], exc: Any = ActionCancelled
) -> None:
result = await a result = await a
if result is not CONFIRMED: if result is not CONFIRMED:
raise exc raise exc
return result
async def confirm_action( def confirm_action(
br_type: str, br_type: str,
title: str, title: str,
action: str | None = None, action: str | None = None,
@ -248,7 +255,7 @@ async def confirm_action(
reverse: bool = False, reverse: bool = False,
exc: ExceptionType = ActionCancelled, exc: ExceptionType = ActionCancelled,
br_code: ButtonRequestType = BR_TYPE_OTHER, br_code: ButtonRequestType = BR_TYPE_OTHER,
) -> None: ) -> Awaitable[None]:
if verb is not None: if verb is not None:
verb = verb.upper() verb = verb.upper()
if verb_cancel is not None: if verb_cancel is not None:
@ -257,7 +264,7 @@ async def confirm_action(
if description is not None and description_param is not None: if description is not None and description_param is not None:
description = description.format(description_param) description = description.format(description_param)
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_action( trezorui2.confirm_action(
@ -278,13 +285,13 @@ async def confirm_action(
) )
async def confirm_single( def confirm_single(
br_type: str, br_type: str,
title: str, title: str,
description: str, description: str,
description_param: str | None = None, description_param: str | None = None,
verb: str | None = None, verb: str | None = None,
) -> None: ) -> Awaitable[None]:
if verb is not None: if verb is not None:
verb = verb.upper() verb = verb.upper()
description_param = description_param or "" description_param = description_param or ""
@ -295,7 +302,7 @@ async def confirm_single(
template_str = "{}" template_str = "{}"
begin, _separator, end = description.partition(template_str) begin, _separator, end = description.partition(template_str)
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_emphasized( trezorui2.confirm_emphasized(
@ -310,13 +317,13 @@ async def confirm_single(
) )
async def confirm_reset_device(title: str, recovery: bool = False) -> None: def confirm_reset_device(title: str, recovery: bool = False) -> Awaitable[None]:
if recovery: if recovery:
button = TR.reset__button_recover button = TR.reset__button_recover
else: else:
button = TR.reset__button_create button = TR.reset__button_create
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_reset_device( trezorui2.confirm_reset_device(
@ -368,16 +375,13 @@ async def prompt_backup() -> bool:
return result is CONFIRMED return result is CONFIRMED
async def confirm_path_warning( def confirm_path_warning(path: str, path_type: str | None = None) -> Awaitable[None]:
path: str,
path_type: str | None = None,
) -> None:
title = ( title = (
TR.addr_mismatch__wrong_derivation_path TR.addr_mismatch__wrong_derivation_path
if not path_type if not path_type
else f"{TR.words__unknown} {path_type.lower()}." else f"{TR.words__unknown} {path_type.lower()}."
) )
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.show_warning( trezorui2.show_warning(
@ -393,10 +397,8 @@ async def confirm_path_warning(
) )
async def confirm_homescreen( def confirm_homescreen(image: bytes) -> Awaitable[None]:
image: bytes, return raise_if_not_confirmed(
) -> None:
await raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_homescreen( trezorui2.confirm_homescreen(
@ -546,15 +548,15 @@ async def show_error_and_raise(
raise exc raise exc
async def show_warning( def show_warning(
br_type: str, br_type: str,
content: str, content: str,
subheader: str | None = None, subheader: str | None = None,
button: str | None = None, button: str | None = None,
br_code: ButtonRequestType = ButtonRequestType.Warning, br_code: ButtonRequestType = ButtonRequestType.Warning,
) -> None: ) -> Awaitable[None]:
button = button or TR.buttons__continue # def_arg button = button or TR.buttons__continue # def_arg
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.show_warning( trezorui2.show_warning(
@ -569,14 +571,14 @@ async def show_warning(
) )
async def show_success( def show_success(
br_type: str, br_type: str,
content: str, content: str,
subheader: str | None = None, subheader: str | None = None,
button: str | None = None, button: str | None = None,
) -> None: ) -> Awaitable[None]:
button = button or TR.buttons__continue # def_arg button = button or TR.buttons__continue # def_arg
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.show_success( trezorui2.show_success(
@ -762,7 +764,7 @@ async def _confirm_ask_pagination(
assert False assert False
async def confirm_blob( def confirm_blob(
br_type: str, br_type: str,
title: str, title: str,
data: bytes | str, data: bytes | str,
@ -773,7 +775,7 @@ async def confirm_blob(
br_code: ButtonRequestType = BR_TYPE_OTHER, br_code: ButtonRequestType = BR_TYPE_OTHER,
ask_pagination: bool = False, ask_pagination: bool = False,
chunkify: bool = False, chunkify: bool = False,
) -> None: ) -> Awaitable[None]:
verb = verb or TR.buttons__confirm # def_arg verb = verb or TR.buttons__confirm # def_arg
title = title.upper() title = title.upper()
layout = RustLayout( layout = RustLayout(
@ -791,10 +793,10 @@ async def confirm_blob(
if ask_pagination and layout.page_count() > 1: if ask_pagination and layout.page_count() > 1:
assert not hold assert not hold
await _confirm_ask_pagination(br_type, title, data, description or "", br_code) return _confirm_ask_pagination(br_type, title, data, description or "", br_code)
else: else:
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
layout, layout,
br_type, br_type,
@ -803,14 +805,14 @@ async def confirm_blob(
) )
async def confirm_address( def confirm_address(
title: str, title: str,
address: str, address: str,
description: str | None = None, description: str | None = None,
br_type: str = "confirm_address", br_type: str = "confirm_address",
br_code: ButtonRequestType = BR_TYPE_OTHER, br_code: ButtonRequestType = BR_TYPE_OTHER,
) -> None: ) -> Awaitable[None]:
return await confirm_value( return confirm_value(
title, title,
address, address,
description or "", description or "",
@ -820,14 +822,14 @@ async def confirm_address(
) )
async def confirm_text( def confirm_text(
br_type: str, br_type: str,
title: str, title: str,
data: str, data: str,
description: str | None = None, description: str | None = None,
br_code: ButtonRequestType = BR_TYPE_OTHER, br_code: ButtonRequestType = BR_TYPE_OTHER,
) -> None: ) -> Awaitable[None]:
return await confirm_value( return confirm_value(
title, title,
data, data,
description or "", description or "",
@ -908,17 +910,17 @@ def confirm_value(
) )
async def confirm_properties( def confirm_properties(
br_type: str, br_type: str,
title: str, title: str,
props: Iterable[PropertyType], props: Iterable[PropertyType],
hold: bool = False, hold: bool = False,
br_code: ButtonRequestType = ButtonRequestType.ConfirmOutput, br_code: ButtonRequestType = ButtonRequestType.ConfirmOutput,
) -> None: ) -> Awaitable[None]:
# Monospace flag for values that are bytes. # Monospace flag for values that are bytes.
items = [(prop[0], prop[1], isinstance(prop[1], bytes)) for prop in props] items = [(prop[0], prop[1], isinstance(prop[1], bytes)) for prop in props]
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_properties( trezorui2.confirm_properties(
@ -933,7 +935,7 @@ async def confirm_properties(
) )
async def confirm_total( def confirm_total(
total_amount: str, total_amount: str,
fee_amount: str, fee_amount: str,
title: str | None = None, title: str | None = None,
@ -943,7 +945,7 @@ async def confirm_total(
fee_rate_amount: str | None = None, fee_rate_amount: str | None = None,
br_type: str = "confirm_total", br_type: str = "confirm_total",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
) -> None: ) -> Awaitable[None]:
title = title or TR.words__title_summary # def_arg title = title or TR.words__title_summary # def_arg
total_label = total_label or TR.send__total_amount # def_arg total_label = total_label or TR.send__total_amount # def_arg
fee_label = fee_label or TR.send__including_fee # def_arg fee_label = fee_label or TR.send__including_fee # def_arg
@ -958,7 +960,7 @@ async def confirm_total(
if fee_rate_amount: if fee_rate_amount:
info_items.append((TR.confirm_total__fee_rate, fee_rate_amount)) info_items.append((TR.confirm_total__fee_rate, fee_rate_amount))
await confirm_summary( return confirm_summary(
items, items,
TR.words__title_summary, TR.words__title_summary,
info_items=info_items, info_items=info_items,
@ -967,14 +969,14 @@ async def confirm_total(
) )
async def confirm_summary( def confirm_summary(
items: Iterable[tuple[str, str]], items: Iterable[tuple[str, str]],
title: str | None = None, title: str | None = None,
info_items: Iterable[tuple[str, str]] | None = None, info_items: Iterable[tuple[str, str]] | None = None,
info_title: str | None = None, info_title: str | None = None,
br_type: str = "confirm_total", br_type: str = "confirm_total",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
) -> None: ) -> Awaitable[None]:
title = title or TR.words__title_summary # def_arg title = title or TR.words__title_summary # def_arg
total_layout = RustLayout( total_layout = RustLayout(
@ -991,7 +993,9 @@ async def confirm_summary(
items=info_items, items=info_items,
) )
) )
await raise_if_not_confirmed(with_info(total_layout, info_layout, br_type, br_code)) return raise_if_not_confirmed(
with_info(total_layout, info_layout, br_type, br_code)
)
async def confirm_ethereum_tx( async def confirm_ethereum_tx(
@ -1054,7 +1058,6 @@ async def confirm_ethereum_staking_tx(
br_type: str = "confirm_ethereum_staking_tx", br_type: str = "confirm_ethereum_staking_tx",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
) -> None: ) -> None:
# intro # intro
await confirm_value( await confirm_value(
title, title,
@ -1087,7 +1090,7 @@ async def confirm_ethereum_staking_tx(
) )
async def confirm_solana_tx( def confirm_solana_tx(
amount: str, amount: str,
fee: str, fee: str,
items: Iterable[tuple[str, str]], items: Iterable[tuple[str, str]],
@ -1095,12 +1098,12 @@ async def confirm_solana_tx(
fee_title: str | None = None, fee_title: str | None = None,
br_type: str = "confirm_solana_tx", br_type: str = "confirm_solana_tx",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
): ) -> Awaitable[None]:
amount_title = ( amount_title = (
amount_title if amount_title is not None else f"{TR.words__amount}:" amount_title if amount_title is not None else f"{TR.words__amount}:"
) # def_arg ) # def_arg
fee_title = fee_title or TR.words__fee # def_arg fee_title = fee_title or TR.words__fee # def_arg
await confirm_summary( return confirm_summary(
((amount_title, amount), (fee_title, fee)), ((amount_title, amount), (fee_title, fee)),
info_items=items, info_items=items,
br_type=br_type, br_type=br_type,
@ -1108,8 +1111,8 @@ async def confirm_solana_tx(
) )
async def confirm_joint_total(spending_amount: str, total_amount: str) -> None: def confirm_joint_total(spending_amount: str, total_amount: str) -> Awaitable[None]:
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_total( trezorui2.confirm_total(
@ -1126,7 +1129,7 @@ async def confirm_joint_total(spending_amount: str, total_amount: str) -> None:
) )
async def confirm_metadata( def confirm_metadata(
br_type: str, br_type: str,
title: str, title: str,
content: str, content: str,
@ -1134,9 +1137,9 @@ async def confirm_metadata(
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
hold: bool = False, hold: bool = False,
verb: str | None = None, verb: str | None = None,
) -> None: ) -> Awaitable[None]:
verb = verb or TR.buttons__continue # def_arg verb = verb or TR.buttons__continue # def_arg
await confirm_action( return confirm_action(
br_type, br_type,
title=title.upper(), title=title.upper(),
action="", action="",
@ -1148,8 +1151,8 @@ async def confirm_metadata(
) )
async def confirm_replacement(title: str, txid: str) -> None: def confirm_replacement(title: str, txid: str) -> Awaitable[None]:
await confirm_blob( return confirm_blob(
"confirm_replacement", "confirm_replacement",
title.upper(), title.upper(),
txid, txid,
@ -1209,11 +1212,11 @@ async def confirm_modify_output(
async def with_info( async def with_info(
main_layout: RustLayout, main_layout: RustLayout[T],
info_layout: RustLayout, info_layout: RustLayout[Any],
br_type: str, br_type: str,
br_code: ButtonRequestType, br_code: ButtonRequestType,
) -> Any: ) -> T:
await button_request(br_type, br_code, pages=main_layout.page_count()) await button_request(br_type, br_code, pages=main_layout.page_count())
while True: while True:
@ -1229,13 +1232,13 @@ async def with_info(
return result return result
async def confirm_modify_fee( def confirm_modify_fee(
title: str, title: str,
sign: int, sign: int,
user_fee_change: str, user_fee_change: str,
total_fee_new: str, total_fee_new: str,
fee_rate_amount: str | None = None, fee_rate_amount: str | None = None,
) -> None: ) -> Awaitable[None]:
fee_layout = RustLayout( fee_layout = RustLayout(
trezorui2.confirm_modify_fee( trezorui2.confirm_modify_fee(
title=title.upper(), title=title.upper(),
@ -1254,13 +1257,13 @@ async def confirm_modify_fee(
items=items, items=items,
) )
) )
await raise_if_not_confirmed( return raise_if_not_confirmed(
with_info(fee_layout, info_layout, "modify_fee", ButtonRequestType.SignTx) with_info(fee_layout, info_layout, "modify_fee", ButtonRequestType.SignTx)
) )
async def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> None: def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> Awaitable[None]:
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_coinjoin( trezorui2.confirm_coinjoin(
@ -1275,10 +1278,10 @@ async def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> None:
# TODO cleanup @ redesign # TODO cleanup @ redesign
async def confirm_sign_identity( def confirm_sign_identity(
proto: str, identity: str, challenge_visual: str | None proto: str, identity: str, challenge_visual: str | None
) -> None: ) -> Awaitable[None]:
await confirm_blob( return confirm_blob(
"sign_identity", "sign_identity",
f"{TR.words__sign} {proto}", f"{TR.words__sign} {proto}",
identity, identity,
@ -1368,7 +1371,7 @@ async def confirm_signverify(
address_layout.request_complete_repaint() address_layout.request_complete_repaint()
async def show_error_popup( def show_error_popup(
title: str, title: str,
description: str, description: str,
subtitle: str | None = None, subtitle: str | None = None,
@ -1376,13 +1379,13 @@ async def show_error_popup(
*, *,
button: str = "", button: str = "",
timeout_ms: int = 0, timeout_ms: int = 0,
) -> None: ) -> Awaitable[None]:
if not button and not timeout_ms: if not button and not timeout_ms:
raise ValueError("Either button or timeout_ms must be set") raise ValueError("Either button or timeout_ms must be set")
if subtitle: if subtitle:
title += f"\n{subtitle}" title += f"\n{subtitle}"
await RustLayout( layout = RustLayout(
trezorui2.show_error( trezorui2.show_error(
title=title, title=title,
description=description.format(description_param), description=description.format(description_param),
@ -1391,6 +1394,7 @@ async def show_error_popup(
allow_cancel=False, allow_cancel=False,
) )
) )
return layout # type: ignore [Expression of type "RustLayout[UiResult]" cannot be assigned to return type "Awaitable[None]"]
def request_passphrase_on_host() -> None: def request_passphrase_on_host() -> None:
@ -1456,16 +1460,12 @@ async def request_pin_on_device(
return result return result
async def confirm_reenter_pin( async def confirm_reenter_pin(is_wipe_code: bool = False) -> None:
is_wipe_code: bool = False,
) -> None:
"""Not supported for TT.""" """Not supported for TT."""
pass pass
async def pin_mismatch_popup( async def pin_mismatch_popup(is_wipe_code: bool = False) -> None:
is_wipe_code: bool = False,
) -> None:
await button_request("pin_mismatch", code=BR_TYPE_OTHER) await button_request("pin_mismatch", code=BR_TYPE_OTHER)
title = TR.wipe_code__wipe_code_mismatch if is_wipe_code else TR.pin__pin_mismatch title = TR.wipe_code__wipe_code_mismatch if is_wipe_code else TR.pin__pin_mismatch
description = TR.wipe_code__mismatch if is_wipe_code else TR.pin__mismatch description = TR.wipe_code__mismatch if is_wipe_code else TR.pin__mismatch
@ -1485,14 +1485,14 @@ async def wipe_code_same_as_pin_popup() -> None:
) )
async def confirm_set_new_pin( def confirm_set_new_pin(
br_type: str, br_type: str,
title: str, title: str,
description: str, description: str,
information: str, information: str,
br_code: ButtonRequestType = BR_TYPE_OTHER, br_code: ButtonRequestType = BR_TYPE_OTHER,
) -> None: ) -> Awaitable[None]:
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_emphasized( trezorui2.confirm_emphasized(
@ -1510,8 +1510,8 @@ async def confirm_set_new_pin(
) )
async def confirm_firmware_update(description: str, fingerprint: str) -> None: def confirm_firmware_update(description: str, fingerprint: str) -> Awaitable[None]:
await raise_if_not_confirmed( return raise_if_not_confirmed(
interact( interact(
RustLayout( RustLayout(
trezorui2.confirm_firmware_update( trezorui2.confirm_firmware_update(