refactor(core): enforce layout scoping for more Rust layouts
What changed, and why it matters
This commit is a follow-up code cleanup that wraps more on-screen user-interface helpers in a new 'layout context' pattern. It changes type annotations from LayoutObj to LayoutContext and converts several synchronous-looking wrapper functions into async functions that use Python 'with' blocks. There is no direct evidence in the commit of a fixable security bug; it appears to be a defensive refactoring to make UI resource lifetimes more predictable across Trezor firmware models.
Treat as routine defensive refactoring. Review PR #6812 and any related tests to confirm the LayoutContext scoping prevents use-after-free or double-activation issues, but no immediate security response is indicated by this commit alone.
Security signals we found
Refactoring of UI object lifetime management (LayoutContext scoping)
No new input validation, parsing, or cryptographic operations visible
No explicit security relevance stated by vendor in commit message or title
Follow-up to prior pull request #6812, suggesting ongoing hardening rather than a disclosed vulnerability fix
Evidence from the diff
The patch extends the layout-scoping work from PR #6812. It updates Rust-generated Micropython API stubs and mock .pyi files so that many UI helpers return LayoutContext[…] instead of LayoutObj[…]. Python layout wrappers for bolt, caesar, delizia, and eckhart are converted from returning Awaitable/LayoutObj to async functions that enter a LayoutContext and pass the inner layout to interact()/raise_if_not_confirmed()/with_info(). The same pattern is applied to device menu, BLE pairing, and THP pairing code. No logic changes, bounds checks, or input validations are added in the diff.
Changed components
core/embed/rust/src/ui/api/firmware_micropython.rscore/mocks/generated/trezorui_api.pyicore/src/apps/homescreen/device_menu.pycore/src/apps/management/ble/pair_new_device.pycore/src/trezor/ui/layouts/bolt/__init__.pycore/src/trezor/ui/layouts/bolt/fido.pycore/src/trezor/ui/layouts/caesar/__init__.pycore/src/trezor/ui/layouts/caesar/fido.pycore/src/trezor/ui/layouts/delizia/__init__.pycore/src/trezor/ui/layouts/delizia/fido.pycore/src/trezor/ui/layouts/eckhart/__init__.pycore/src/trezor/ui/layouts/eckhart/fido.pycore/src/trezor/wire/thp/ui.pyInspect captured patch +342 / −385
diff --git a/core/embed/rust/src/ui/api/firmware_micropython.rs b/core/embed/rust/src/ui/api/firmware_micropython.rs
index aab705b1..87698456 100644
--- a/core/embed/rust/src/ui/api/firmware_micropython.rs
+++ b/core/embed/rust/src/ui/api/firmware_micropython.rs
@@ -1600,7 +1600,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// *,
/// max_rounds: str,
/// max_feerate: str,
- /// ) -> LayoutObj[UiResult]:
+ /// ) -> LayoutContext[UiResult]:
/// """Confirm coinjoin authorization."""
Qstr::MP_QSTR_confirm_coinjoin => obj_fn_kw!(0, new_confirm_coinjoin).as_obj(),
@@ -1609,7 +1609,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// title: str,
/// items: Iterable[str | tuple[bool, str]],
/// verb: str | None = None,
- /// ) -> LayoutObj[UiResult]:
+ /// ) -> LayoutContext[UiResult]:
/// """Confirm formatted text that has been pre-split in python. For tuples
/// the first component is a bool indicating whether this part is emphasized."""
Qstr::MP_QSTR_confirm_emphasized => obj_fn_kw!(0, new_confirm_emphasized).as_obj(),
@@ -1620,7 +1620,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// app_name: str,
/// icon_name: str | None,
/// accounts: Sequence[str | None],
- /// ) -> LayoutObj[int | UiResult]:
+ /// ) -> LayoutContext[int | UiResult]:
/// """FIDO confirmation.
///
/// Returns page index in case of confirmation and CANCELLED otherwise.
@@ -1650,7 +1650,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// user_fee_change: str,
/// total_fee_new: str,
/// fee_rate_amount: str | None,
- /// ) -> LayoutObj[UiResult]:
+ /// ) -> LayoutContext[UiResult]:
/// """Decrease or increase transaction fee."""
Qstr::MP_QSTR_confirm_modify_fee => obj_fn_kw!(0, new_confirm_modify_fee).as_obj(),
@@ -1659,7 +1659,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// sign: int,
/// amount_change: str,
/// amount_new: str,
- /// ) -> LayoutObj[UiResult]:
+ /// ) -> LayoutContext[UiResult]:
/// """Decrease or increase output amount."""
Qstr::MP_QSTR_confirm_modify_output => obj_fn_kw!(0, new_confirm_modify_output).as_obj(),
@@ -1688,7 +1688,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// the value is to be rendered as binary with monospace font, False otherwise."""
Qstr::MP_QSTR_confirm_properties => obj_fn_kw!(0, new_confirm_properties).as_obj(),
- /// def confirm_reset_device(recovery: bool) -> LayoutObj[UiResult]:
+ /// def confirm_reset_device(recovery: bool) -> LayoutContext[UiResult]:
/// """Confirm TOS before creating wallet creation or wallet recovery."""
Qstr::MP_QSTR_confirm_reset_device => obj_fn_kw!(0, new_confirm_reset_device).as_obj(),
@@ -1748,7 +1748,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// def flow_confirm_set_new_code(
/// *,
/// is_wipe_code: bool,
- /// ) -> LayoutObj[UiResult]:
+ /// ) -> LayoutContext[UiResult]:
/// """Confirm new PIN/wipe code setup with an option to cancel action."""
Qstr::MP_QSTR_flow_confirm_set_new_code => obj_fn_kw!(0, new_flow_confirm_set_new_code).as_obj(),
@@ -1785,7 +1785,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// path: str | None,
/// br_code: ButtonRequestType,
/// br_name: str,
- /// ) -> LayoutObj[UiResult]:
+ /// ) -> LayoutContext[UiResult]:
/// """Get public key."""
Qstr::MP_QSTR_flow_get_pubkey => obj_fn_kw!(0, new_flow_get_pubkey).as_obj(),
@@ -1794,11 +1794,11 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// title: str,
/// verb: str,
/// items: Sequence[str],
- /// ) -> LayoutObj[UiResult]:
+ /// ) -> LayoutContext[UiResult]:
/// """Show multiple texts, each on its own page. TR specific."""
Qstr::MP_QSTR_multiple_pages_texts => obj_fn_kw!(0, new_multiple_pages_texts).as_obj(),
- /// def prompt_backup() -> LayoutObj[UiResult]:
+ /// def prompt_backup() -> LayoutContext[UiResult]:
/// """Strongly recommend user to do a backup."""
Qstr::MP_QSTR_prompt_backup => obj_fn_0!(new_prompt_backup).as_obj(),
@@ -1901,7 +1901,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// For unlocking a repeated backup, select between 20 and 33."""
Qstr::MP_QSTR_select_word_count => obj_fn_kw!(0, new_select_word_count).as_obj(),
- /// def set_brightness(*, current: int | None = None) -> LayoutObj[UiResult]:
+ /// def set_brightness(*, current: int | None = None) -> LayoutContext[UiResult]:
/// """Show the brightness configuration dialog."""
Qstr::MP_QSTR_set_brightness => obj_fn_kw!(0, new_set_brightness).as_obj(),
@@ -1987,7 +1987,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// led_enabled: bool | None,
/// about_items: Sequence[tuple[str | None, StrOrBytes | None, bool | None]],
/// production_year: str | None,
- /// ) -> LayoutObj[UiResult | tuple[int, int | None, int]]:
+ /// ) -> LayoutContext[UiResult | tuple[int, int | None, int]]:
/// """Show the device menu. Result is either CANCELLED or a tuple (action, action_arg, parent_menu_id)."""
Qstr::MP_QSTR_show_device_menu => obj_fn_kw!(0, new_show_device_menu).as_obj(),
@@ -1995,7 +1995,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// *,
/// description: str,
/// device_name: str,
- /// ) -> LayoutObj[UiResult]:
+ /// ) -> LayoutContext[UiResult]:
/// """Pairing device: first screen (device name).
/// Returns if BLEEvent::PairingRequest is received."""
Qstr::MP_QSTR_show_pairing_device_name => obj_fn_kw!(0, new_show_pairing_device_name).as_obj(),
@@ -2005,12 +2005,12 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// title: str,
/// description: str,
/// code: str,
- /// ) -> LayoutObj[UiResult]:
+ /// ) -> LayoutContext[UiResult]:
/// """BLE pairing: second screen (pairing code).
/// Returns on BLEEvent::{PairingCanceled, Disconnected}."""
Qstr::MP_QSTR_show_ble_pairing_code => obj_fn_kw!(0, new_show_ble_pairing_code).as_obj(),
- /// def wait_ble_host_confirmation() -> LayoutObj[UiResult]:
+ /// def wait_ble_host_confirmation() -> LayoutContext[UiResult]:
/// """Pairing device: third screen (waiting for host confirmation).
/// Returns on BLEEvent::{PairingCanceled, Disconnected}."""
Qstr::MP_QSTR_wait_ble_host_confirmation => obj_fn_kw!(0, new_wait_ble_host_confirmation).as_obj(),
@@ -2020,7 +2020,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// title: str,
/// description: str,
/// args: Iterable[str],
- /// ) -> LayoutObj[UiResult]:
+ /// ) -> LayoutContext[UiResult]:
/// """THP pairing: first screen (host and app names)."""
Qstr::MP_QSTR_confirm_thp_pairing => obj_fn_kw!(0, new_confirm_thp_pairing).as_obj(),
@@ -2029,7 +2029,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// title: str,
/// description: str,
/// code: str,
- /// ) -> LayoutObj[UiResult]:
+ /// ) -> LayoutContext[UiResult]:
/// """THP pairing: second screen (pairing code)."""
Qstr::MP_QSTR_show_thp_pairing_code => obj_fn_kw!(0, new_show_thp_pairing_code).as_obj(),
@@ -2149,7 +2149,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// """Success modal. No buttons shown when `button` is empty string."""
Qstr::MP_QSTR_show_success => obj_fn_kw!(0, new_show_success).as_obj(),
- /// def show_wait_text(message: str, /) -> LayoutObj[None]:
+ /// def show_wait_text(message: str, /) -> LayoutContext[None]:
/// """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(),
@@ -2170,7 +2170,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// the previous flow)"""
Qstr::MP_QSTR_confirm_cancel => obj_fn_kw!(0, new_confirm_cancel).as_obj(),
- /// def tutorial() -> LayoutObj[UiResult]:
+ /// def tutorial() -> LayoutContext[UiResult]:
/// """Show user how to interact with the device."""
Qstr::MP_QSTR_tutorial => obj_fn_kw!(0, new_tutorial).as_obj(),
diff --git a/core/mocks/generated/trezorui_api.pyi b/core/mocks/generated/trezorui_api.pyi
index 2183dfdc..e151e60b 100644
--- a/core/mocks/generated/trezorui_api.pyi
+++ b/core/mocks/generated/trezorui_api.pyi
@@ -228,7 +228,7 @@ def confirm_coinjoin(
*,
max_rounds: str,
max_feerate: str,
-) -> LayoutObj[UiResult]:
+) -> LayoutContext[UiResult]:
"""Confirm coinjoin authorization."""
@@ -238,7 +238,7 @@ def confirm_emphasized(
title: str,
items: Iterable[str | tuple[bool, str]],
verb: str | None = None,
-) -> LayoutObj[UiResult]:
+) -> LayoutContext[UiResult]:
"""Confirm formatted text that has been pre-split in python. For tuples
the first component is a bool indicating whether this part is emphasized."""
@@ -250,7 +250,7 @@ def confirm_fido(
app_name: str,
icon_name: str | None,
accounts: Sequence[str | None],
-) -> LayoutObj[int | UiResult]:
+) -> LayoutContext[int | UiResult]:
"""FIDO confirmation.
Returns page index in case of confirmation and CANCELLED otherwise.
"""
@@ -282,7 +282,7 @@ def confirm_modify_fee(
user_fee_change: str,
total_fee_new: str,
fee_rate_amount: str | None,
-) -> LayoutObj[UiResult]:
+) -> LayoutContext[UiResult]:
"""Decrease or increase transaction fee."""
@@ -292,7 +292,7 @@ def confirm_modify_output(
sign: int,
amount_change: str,
amount_new: str,
-) -> LayoutObj[UiResult]:
+) -> LayoutContext[UiResult]:
"""Decrease or increase output amount."""
@@ -324,7 +324,7 @@ def confirm_properties(
# rust/src/ui/api/firmware_micropython.rs
-def confirm_reset_device(recovery: bool) -> LayoutObj[UiResult]:
+def confirm_reset_device(recovery: bool) -> LayoutContext[UiResult]:
"""Confirm TOS before creating wallet creation or wallet recovery."""
@@ -386,7 +386,7 @@ def continue_recovery_homepage(
def flow_confirm_set_new_code(
*,
is_wipe_code: bool,
-) -> LayoutObj[UiResult]:
+) -> LayoutContext[UiResult]:
"""Confirm new PIN/wipe code setup with an option to cancel action."""
@@ -425,7 +425,7 @@ def flow_get_pubkey(
path: str | None,
br_code: ButtonRequestType,
br_name: str,
-) -> LayoutObj[UiResult]:
+) -> LayoutContext[UiResult]:
"""Get public key."""
@@ -435,12 +435,12 @@ def multiple_pages_texts(
title: str,
verb: str,
items: Sequence[str],
-) -> LayoutObj[UiResult]:
+) -> LayoutContext[UiResult]:
"""Show multiple texts, each on its own page. TR specific."""
# rust/src/ui/api/firmware_micropython.rs
-def prompt_backup() -> LayoutObj[UiResult]:
+def prompt_backup() -> LayoutContext[UiResult]:
"""Strongly recommend user to do a backup."""
@@ -554,7 +554,7 @@ def select_word_count(
# rust/src/ui/api/firmware_micropython.rs
-def set_brightness(*, current: int | None = None) -> LayoutObj[UiResult]:
+def set_brightness(*, current: int | None = None) -> LayoutContext[UiResult]:
"""Show the brightness configuration dialog."""
@@ -647,7 +647,7 @@ def show_device_menu(
led_enabled: bool | None,
about_items: Sequence[tuple[str | None, StrOrBytes | None, bool | None]],
production_year: str | None,
-) -> LayoutObj[UiResult | tuple[int, int | None, int]]:
+) -> LayoutContext[UiResult | tuple[int, int | None, int]]:
"""Show the device menu. Result is either CANCELLED or a tuple (action, action_arg, parent_menu_id)."""
@@ -656,7 +656,7 @@ def show_pairing_device_name(
*,
description: str,
device_name: str,
-) -> LayoutObj[UiResult]:
+) -> LayoutContext[UiResult]:
"""Pairing device: first screen (device name).
Returns if BLEEvent::PairingRequest is received."""
@@ -667,13 +667,13 @@ def show_ble_pairing_code(
title: str,
description: str,
code: str,
-) -> LayoutObj[UiResult]:
+) -> LayoutContext[UiResult]:
"""BLE pairing: second screen (pairing code).
Returns on BLEEvent::{PairingCanceled, Disconnected}."""
# rust/src/ui/api/firmware_micropython.rs
-def wait_ble_host_confirmation() -> LayoutObj[UiResult]:
+def wait_ble_host_confirmation() -> LayoutContext[UiResult]:
"""Pairing device: third screen (waiting for host confirmation).
Returns on BLEEvent::{PairingCanceled, Disconnected}."""
@@ -684,7 +684,7 @@ def confirm_thp_pairing(
title: str,
description: str,
args: Iterable[str],
-) -> LayoutObj[UiResult]:
+) -> LayoutContext[UiResult]:
"""THP pairing: first screen (host and app names)."""
@@ -694,7 +694,7 @@ def show_thp_pairing_code(
title: str,
description: str,
code: str,
-) -> LayoutObj[UiResult]:
+) -> LayoutContext[UiResult]:
"""THP pairing: second screen (pairing code)."""
@@ -827,7 +827,7 @@ def show_success(
# rust/src/ui/api/firmware_micropython.rs
-def show_wait_text(message: str, /) -> LayoutObj[None]:
+def show_wait_text(message: str, /) -> LayoutContext[None]:
"""Show single-line text in the middle of the screen."""
@@ -851,7 +851,7 @@ def confirm_cancel() -> LayoutContext[UiResult]:
# rust/src/ui/api/firmware_micropython.rs
-def tutorial() -> LayoutObj[UiResult]:
+def tutorial() -> LayoutContext[UiResult]:
"""Show user how to interact with the device."""
diff --git a/core/src/apps/homescreen/device_menu.py b/core/src/apps/homescreen/device_menu.py
index fc2390cb..e710ee54 100644
--- a/core/src/apps/homescreen/device_menu.py
+++ b/core/src/apps/homescreen/device_menu.py
@@ -133,48 +133,43 @@ async def handle_device_menu() -> None:
about_items.append((TR.sn__title, serial_no, True))
about_items.append((TR.words__made_in, "Ostrava, Czechia", False))
- menu_result = await interact(
- trezorui_api.show_device_menu(
- init_submenu_idx=init_submenu_idx,
- backup_failed=backup_failed,
- backup_needed=backup_needed,
- ble_enabled=ble_enabled,
- paired_devices=paired_devices,
- connected_idx=connected_idx,
- pin_enabled=config.has_pin() if is_initialized else None,
- auto_lock=get_auto_lock_delay(),
- wipe_code_enabled=(
- config.has_wipe_code()
- if (is_initialized and config.has_pin())
- else None
- ),
- backup_check_allowed=backup_finished,
- device_name=(
- (storage_device.get_label() or utils.MODEL_FULL_NAME)
- if is_initialized
- else None
- ),
- brightness=TR.brightness__title if is_initialized else None,
- tap_to_wake_enabled=(
- storage_device.get_tap_to_wake()
- if tap_to_wake_configurable
- else None
- ),
- haptics_enabled=(
- storage_device.get_haptic_feedback()
- if haptic_configurable
- else None
- ),
- led_enabled=(
- storage_device.get_rgb_led() if led_configurable else None
- ),
- about_items=about_items,
- production_year=production_year,
+ with trezorui_api.show_device_menu(
+ init_submenu_idx=init_submenu_idx,
+ backup_failed=backup_failed,
+ backup_needed=backup_needed,
+ ble_enabled=ble_enabled,
+ paired_devices=paired_devices,
+ connected_idx=connected_idx,
+ pin_enabled=config.has_pin() if is_initialized else None,
+ auto_lock=get_auto_lock_delay(),
+ wipe_code_enabled=(
+ config.has_wipe_code()
+ if (is_initialized and config.has_pin())
+ else None
),
- br_name=None,
- raise_on_cancel=None,
- layout_type=UsbAwareLayout,
- )
+ backup_check_allowed=backup_finished,
+ device_name=(
+ (storage_device.get_label() or utils.MODEL_FULL_NAME)
+ if is_initialized
+ else None
+ ),
+ brightness=TR.brightness__title if is_initialized else None,
+ tap_to_wake_enabled=(
+ storage_device.get_tap_to_wake() if tap_to_wake_configurable else None
+ ),
+ haptics_enabled=(
+ storage_device.get_haptic_feedback() if haptic_configurable else None
+ ),
+ led_enabled=(storage_device.get_rgb_led() if led_configurable else None),
+ about_items=about_items,
+ production_year=production_year,
+ ) as layout:
+ menu_result = await interact(
+ layout,
+ br_name=None,
+ raise_on_cancel=None,
+ layout_type=UsbAwareLayout,
+ )
if not isinstance(menu_result, tuple) or len(menu_result) != 3:
raise RuntimeError(f"Unknown menu {menu_result}")
diff --git a/core/src/apps/management/ble/pair_new_device.py b/core/src/apps/management/ble/pair_new_device.py
index 995599ac..00bc51da 100644
--- a/core/src/apps/management/ble/pair_new_device.py
+++ b/core/src/apps/management/ble/pair_new_device.py
@@ -39,29 +39,26 @@ async def pair_new_device() -> None:
label = ble.start_advertising(False, label)
result = None
try:
- code = await interact(
- trezorui_api.show_pairing_device_name(
- description=TR.thp__pair_name,
- device_name=label,
- ),
- None,
- )
+ with trezorui_api.show_pairing_device_name(
+ description=TR.thp__pair_name,
+ device_name=label,
+ ) as layout:
+ code = await interact(layout, None)
if not isinstance(code, int):
raise ActionCancelled
- result = await interact(
- trezorui_api.show_ble_pairing_code(
- title=TR.ble__pairing_title,
- description=TR.ble__pairing_match,
- code=f"{code:0>6}",
- ),
- None,
- )
+ with trezorui_api.show_ble_pairing_code(
+ title=TR.ble__pairing_title,
+ description=TR.ble__pairing_match,
+ code=f"{code:0>6}",
+ ) as layout:
+ result = await interact(layout, None)
if result is CONFIRMED:
ble.allow_pairing(code)
# wait for the host code confirmation
- await interact(trezorui_api.wait_ble_host_confirmation(), None)
+ with trezorui_api.wait_ble_host_confirmation() as layout:
+ await interact(layout, None)
finally:
if result is not CONFIRMED:
ble.reject_pairing()
diff --git a/core/src/trezor/ui/layouts/bolt/__init__.py b/core/src/trezor/ui/layouts/bolt/__init__.py
index 1a2b9952..f4b8ee63 100644
--- a/core/src/trezor/ui/layouts/bolt/__init__.py
+++ b/core/src/trezor/ui/layouts/bolt/__init__.py
@@ -66,13 +66,13 @@ def confirm_action(
)
-def confirm_single(
+async def confirm_single(
br_name: str,
title: str,
description: str,
description_param: str | None = None,
verb: str | None = None,
-) -> Awaitable[None]:
+) -> None:
description_param = description_param or ""
# Placeholders are coming from translations in form of {0}
@@ -80,23 +80,27 @@ def confirm_single(
assert template_str in description
begin, _separator, end = description.partition(template_str)
- return raise_if_not_confirmed(
- trezorui_api.confirm_emphasized(
- title=title,
- items=(begin, (True, description_param), end),
- verb=verb,
- ),
- br_name,
- ButtonRequestType.ProtectCall,
- )
+ with trezorui_api.confirm_emphasized(
+ title=title,
+ items=(begin, (True, description_param), end),
+ verb=verb,
+ ) as layout:
+ return await raise_if_not_confirmed(
+ layout, br_name, ButtonRequestType.ProtectCall
+ )
-def confirm_reset_device(recovery: bool = False) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.confirm_reset_device(recovery=recovery),
- "recover_device" if recovery else "setup_device",
- (ButtonRequestType.ProtectCall if recovery else ButtonRequestType.ResetDevice),
- )
+async def confirm_reset_device(recovery: bool = False) -> None:
+ with trezorui_api.confirm_reset_device(recovery=recovery) as layout:
+ return await raise_if_not_confirmed(
+ layout,
+ "recover_device" if recovery else "setup_device",
+ (
+ ButtonRequestType.ProtectCall
+ if recovery
+ else ButtonRequestType.ResetDevice
+ ),
+ )
async def prompt_recovery_check(recovery_type: RecoveryType) -> None:
@@ -325,18 +329,19 @@ async def show_address(
details_title = title
while True:
- result = await interact(
- trezorui_api.confirm_address(
- title=title,
- address=address,
- address_label=network or None,
- info_button=True,
- chunkify=chunkify,
- ),
- br_name if send_button_request else None,
- br_code,
- raise_on_cancel=None,
- )
+ with trezorui_api.confirm_address(
+ title=title,
+ address=address,
+ address_label=network or None,
+ info_button=True,
+ chunkify=chunkify,
+ ) as layout:
+ result = await interact(
+ layout,
+ br_name if send_button_request else None,
+ br_code,
+ raise_on_cancel=None,
+ )
send_button_request = False
@@ -1968,16 +1973,16 @@ async def confirm_modify_output(
return
-def confirm_modify_fee(
+async def confirm_modify_fee(
title: str,
sign: int,
user_fee_change: str,
total_fee_new: str,
fee_rate_amount: str | None = None,
-) -> Awaitable[None]:
+) -> None:
from ..properties import with_colon
- fee_layout = trezorui_api.confirm_modify_fee(
+ fee_ctx = trezorui_api.confirm_modify_fee(
title=title,
sign=sign,
user_fee_change=user_fee_change,
@@ -1987,22 +1992,22 @@ def confirm_modify_fee(
items: list[StrPropertyType] = []
if fee_rate_amount:
items.append((TR.bitcoin__new_fee_rate, fee_rate_amount, None))
- info_layout = trezorui_api.show_info_with_cancel(
+ info_ctx = trezorui_api.show_info_with_cancel(
title=TR.confirm_total__title_fee,
items=with_colon(items),
)
- return with_info(fee_layout, info_layout, "modify_fee", ButtonRequestType.SignTx)
+ with fee_ctx as fee_layout, info_ctx as info_layout:
+ return await with_info(
+ fee_layout, info_layout, "modify_fee", ButtonRequestType.SignTx
+ )
-def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.confirm_coinjoin(
- max_rounds=str(max_rounds),
- max_feerate=max_fee_per_vbyte,
- ),
- "coinjoin_final",
- BR_CODE_OTHER,
- )
+async def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> None:
+ with trezorui_api.confirm_coinjoin(
+ max_rounds=str(max_rounds),
+ max_feerate=max_fee_per_vbyte,
+ ) as layout:
+ return await raise_if_not_confirmed(layout, "coinjoin_final", BR_CODE_OTHER)
# TODO cleanup @ redesign
@@ -2144,7 +2149,8 @@ def request_passphrase_on_host() -> None:
def show_wait_text(message: str) -> None:
- draw_simple(trezorui_api.show_wait_text(message))
+ with trezorui_api.show_wait_text(message) as layout:
+ draw_simple(layout)
async def request_passphrase_on_device(max_len: int) -> str:
@@ -2249,9 +2255,7 @@ async def pin_wipe_code_exists_popup(
)
-def confirm_set_new_code(
- is_wipe_code: bool,
-) -> Awaitable[None]:
+async def confirm_set_new_code(is_wipe_code: bool) -> None:
if is_wipe_code:
title = TR.wipe_code__title_settings
description = TR.wipe_code__turn_on
@@ -2263,18 +2267,15 @@ def confirm_set_new_code(
information = TR.pin__info
br_name = "set_pin"
- return raise_if_not_confirmed(
- trezorui_api.confirm_emphasized(
- title=title,
- items=(
- (True, description + "\n\n"),
- information,
- ),
- verb=TR.buttons__turn_on,
+ with trezorui_api.confirm_emphasized(
+ title=title,
+ items=(
+ (True, description + "\n\n"),
+ information,
),
- br_name,
- BR_CODE_OTHER,
- )
+ verb=TR.buttons__turn_on,
+ ) as layout:
+ return await raise_if_not_confirmed(layout, br_name, BR_CODE_OTHER)
def confirm_change_pin(
@@ -2338,8 +2339,5 @@ async def confirm_firmware_update(description: str, fingerprint: str) -> None:
async def set_brightness(current: int | None = None) -> None:
- await interact(
- trezorui_api.set_brightness(current=current),
- "set_brightness",
- BR_CODE_OTHER,
- )
+ with trezorui_api.set_brightness(current=current) as layout:
+ await interact(layout, "set_brightness", BR_CODE_OTHER)
diff --git a/core/src/trezor/ui/layouts/bolt/fido.py b/core/src/trezor/ui/layouts/bolt/fido.py
index c8b1fbda..b7e64022 100644
--- a/core/src/trezor/ui/layouts/bolt/fido.py
+++ b/core/src/trezor/ui/layouts/bolt/fido.py
@@ -13,28 +13,28 @@ async def confirm_fido(
accounts: list[str | None],
) -> int:
"""Webauthn confirmation for one or more credentials."""
- confirm = trezorui_api.confirm_fido(
+ with trezorui_api.confirm_fido(
title=header,
app_name=app_name,
icon_name=icon_name,
accounts=accounts,
- )
- result = await interact(confirm, "confirm_fido", ButtonRequestType.Other)
+ ) as confirm:
+ result = await interact(confirm, "confirm_fido", ButtonRequestType.Other)
- if __debug__ and result is trezorui_api.CONFIRMED:
- # debuglink will directly inject a CONFIRMED message which we need to handle
- # by playing back a click to the Rust layout and getting out the selected number
- # that way
- from trezor import io
+ if __debug__ and result is trezorui_api.CONFIRMED:
+ # debuglink will directly inject a CONFIRMED message which we need to handle
+ # by playing back a click to the Rust layout and getting out the selected number
+ # that way
+ from trezor import io
- confirm.touch_event(io.TOUCH_START, 220, 220)
- confirm.paint()
- msg = confirm.touch_event(io.TOUCH_END, 220, 220)
- confirm.paint()
- assert msg is trezorui_api.LayoutState.DONE
- retval = confirm.return_value()
- assert isinstance(retval, int)
- return retval
+ confirm.touch_event(io.TOUCH_START, 220, 220)
+ confirm.paint()
+ msg = confirm.touch_event(io.TOUCH_END, 220, 220)
+ confirm.paint()
+ assert msg is trezorui_api.LayoutState.DONE
+ retval = confirm.return_value()
+ assert isinstance(retval, int)
+ return retval
# The Rust side returns either an int or `CANCELLED`. We detect the int situation
# and assume cancellation otherwise.
diff --git a/core/src/trezor/ui/layouts/caesar/__init__.py b/core/src/trezor/ui/layouts/caesar/__init__.py
index 124a469b..fea53f15 100644
--- a/core/src/trezor/ui/layouts/caesar/__init__.py
+++ b/core/src/trezor/ui/layouts/caesar/__init__.py
@@ -115,14 +115,17 @@ def confirm_single(
)
-def confirm_reset_device(
- recovery: bool = False,
-) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.confirm_reset_device(recovery=recovery),
- "recover_device" if recovery else "setup_device",
- ButtonRequestType.ProtectCall if recovery else ButtonRequestType.ResetDevice,
- )
+async def confirm_reset_device(recovery: bool = False) -> None:
+ with trezorui_api.confirm_reset_device(recovery=recovery) as layout:
+ return await raise_if_not_confirmed(
+ layout,
+ "recover_device" if recovery else "setup_device",
+ (
+ ButtonRequestType.ProtectCall
+ if recovery
+ else ButtonRequestType.ResetDevice
+ ),
+ )
async def prompt_recovery_check(recovery_type: RecoveryType) -> None:
@@ -150,12 +153,8 @@ async def prompt_backup() -> bool:
br_name = "backup_device"
br_code = ButtonRequestType.ResetDevice
- result = await interact(
- trezorui_api.prompt_backup(),
- br_name,
- br_code,
- raise_on_cancel=None,
- )
+ with trezorui_api.prompt_backup() as layout:
+ result = await interact(layout, br_name, br_code, raise_on_cancel=None)
if result is CONFIRMED:
return True
@@ -704,9 +703,10 @@ async def confirm_output(
return
-def tutorial(br_code: ButtonRequestType = BR_CODE_OTHER) -> Awaitable[ui.UiResult]:
+async def tutorial(br_code: ButtonRequestType = BR_CODE_OTHER) -> ui.UiResult:
"""Showing users how to interact with the device."""
- return interact(trezorui_api.tutorial(), "tutorial", br_code)
+ with trezorui_api.tutorial() as layout:
+ return await interact(layout, "tutorial", br_code)
async def should_show_more(
@@ -2035,35 +2035,31 @@ async def confirm_modify_output(
break
-def confirm_modify_fee(
+async def confirm_modify_fee(
title: str,
sign: int,
user_fee_change: str,
total_fee_new: str,
fee_rate_amount: str | None = None,
-) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.confirm_modify_fee(
- title=title,
- sign=sign,
- user_fee_change=user_fee_change,
- total_fee_new=total_fee_new,
- fee_rate_amount=fee_rate_amount,
- ),
- "modify_fee",
- ButtonRequestType.SignTx,
- )
+) -> None:
+ with trezorui_api.confirm_modify_fee(
+ title=title,
+ sign=sign,
+ user_fee_change=user_fee_change,
+ total_fee_new=total_fee_new,
+ fee_rate_amount=fee_rate_amount,
+ ) as layout:
+ return await raise_if_not_confirmed(
+ layout, "modify_fee", ButtonRequestType.SignTx
+ )
-def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.confirm_coinjoin(
- max_rounds=str(max_rounds),
- max_feerate=max_fee_per_vbyte,
- ),
- "coinjoin_final",
- BR_CODE_OTHER,
- )
+async def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> None:
+ with trezorui_api.confirm_coinjoin(
+ max_rounds=str(max_rounds),
+ max_feerate=max_fee_per_vbyte,
+ ) as layout:
+ return await raise_if_not_confirmed(layout, "coinjoin_final", BR_CODE_OTHER)
# TODO cleanup @ redesign
@@ -2168,7 +2164,8 @@ def request_passphrase_on_host() -> None:
def show_wait_text(message: str) -> None:
- draw_simple(trezorui_api.show_wait_text(message))
+ with trezorui_api.show_wait_text(message) as layout:
+ draw_simple(layout)
async def request_passphrase_on_device(max_len: int) -> str:
@@ -2236,22 +2233,17 @@ def confirm_reenter_pin(is_wipe_code: bool = False) -> Awaitable[None]:
)
-def _confirm_multiple_pages_texts(
+async def _confirm_multiple_pages_texts(
br_name: str,
title: str,
items: list[str],
verb: str,
br_code: ButtonRequestType = BR_CODE_OTHER,
-) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.multiple_pages_texts(
- title=title,
- verb=verb,
- items=items,
- ),
- br_name,
- br_code,
- )
+) -> None:
+ with trezorui_api.multiple_pages_texts(
+ title=title, verb=verb, items=items
+ ) as layout:
+ return await raise_if_not_confirmed(layout, br_name, br_code)
def pin_mismatch_popup(is_wipe_code: bool = False) -> Awaitable[None]:
@@ -2300,9 +2292,7 @@ async def pin_wipe_code_exists_popup(
)
-async def confirm_set_new_code(
- is_wipe_code: bool,
-) -> None:
+async def confirm_set_new_code(is_wipe_code: bool) -> None:
if is_wipe_code:
title = TR.wipe_code__title_settings
description = TR.wipe_code__turn_on
diff --git a/core/src/trezor/ui/layouts/caesar/fido.py b/core/src/trezor/ui/layouts/caesar/fido.py
index 4b7304b7..0251ec7f 100644
--- a/core/src/trezor/ui/layouts/caesar/fido.py
+++ b/core/src/trezor/ui/layouts/caesar/fido.py
@@ -13,13 +13,13 @@ async def confirm_fido(
accounts: list[str | None],
) -> int:
"""Webauthn confirmation for one or more credentials."""
- confirm = trezorui_api.confirm_fido(
+ with trezorui_api.confirm_fido(
title=header,
app_name=app_name,
icon_name=None,
accounts=accounts,
- )
- result = await interact(confirm, "confirm_fido", ButtonRequestType.Other)
+ ) as confirm:
+ result = await interact(confirm, "confirm_fido", ButtonRequestType.Other)
if isinstance(result, int):
return result
diff --git a/core/src/trezor/ui/layouts/delizia/__init__.py b/core/src/trezor/ui/layouts/delizia/__init__.py
index 694a68aa..a8cab6a8 100644
--- a/core/src/trezor/ui/layouts/delizia/__init__.py
+++ b/core/src/trezor/ui/layouts/delizia/__init__.py
@@ -95,13 +95,13 @@ def confirm_action(
)
-def confirm_single(
+async def confirm_single(
br_name: str,
title: str,
description: str,
description_param: str | None = None,
verb: str | None = None,
-) -> Awaitable[None]:
+) -> None:
description_param = description_param or ""
# Placeholders are coming from translations in form of {0}
@@ -109,21 +109,21 @@ def confirm_single(
assert template_str in description
begin, _separator, end = description.partition(template_str)
- return raise_if_not_confirmed(
- trezorui_api.confirm_emphasized(
- title=title,
- items=(begin, (True, description_param), end),
- verb=verb,
- ),
- br_name,
- ButtonRequestType.ProtectCall,
- )
+ with trezorui_api.confirm_emphasized(
+ title=title,
+ items=(begin, (True, description_param), end),
+ verb=verb,
+ ) as layout:
+ return await raise_if_not_confirmed(
+ layout,
+ br_name,
+ ButtonRequestType.ProtectCall,
+ )
-def confirm_reset_device(recovery: bool = False) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.confirm_reset_device(recovery=recovery), None
- )
+async def confirm_reset_device(recovery: bool = False) -> None:
+ with trezorui_api.confirm_reset_device(recovery=recovery) as layout:
+ return await raise_if_not_confirmed(layout, None)
async def prompt_recovery_check(recovery_type: RecoveryType) -> None:
@@ -154,12 +154,10 @@ async def show_wallet_created_success() -> None:
async def prompt_backup() -> bool:
- result = await interact(
- trezorui_api.prompt_backup(),
- "backup_device",
- ButtonRequestType.ResetDevice,
- raise_on_cancel=None,
- )
+ with trezorui_api.prompt_backup() as layout:
+ result = await interact(
+ layout, "backup_device", ButtonRequestType.ResetDevice, raise_on_cancel=None
+ )
return result is CONFIRMED
@@ -378,23 +376,21 @@ async def show_pubkey(
br_name: str = "show_pubkey",
) -> None:
- await raise_if_not_confirmed(
- trezorui_api.flow_get_pubkey(
- pubkey=pubkey,
- title=title or title or TR.address__public_key,
- subtitle=None,
- description=None,
- hint=None,
- chunkify=False,
- pubkey_qr=pubkey,
- case_sensitive=True,
- account=account,
- path=path,
- br_name=br_name,
- br_code=ButtonRequestType.PublicKey,
- ),
- None,
- )
+ with trezorui_api.flow_get_pubkey(
+ pubkey=pubkey,
+ title=title or title or TR.address__public_key,
+ subtitle=None,
+ description=None,
+ hint=None,
+ chunkify=False,
+ pubkey_qr=pubkey,
+ case_sensitive=True,
+ account=account,
+ path=path,
+ br_name=br_name,
+ br_code=ButtonRequestType.PublicKey,
+ ) as layout:
+ await raise_if_not_confirmed(layout, None)
show_continue_in_app(TR.address__public_key_confirmed)
@@ -1994,14 +1990,14 @@ async def confirm_modify_output(
break
-def confirm_modify_fee(
+async def confirm_modify_fee(
title: str,
sign: int,
user_fee_change: str,
total_fee_new: str,
fee_rate_amount: str | None = None,
-) -> Awaitable[None]:
- fee_layout = trezorui_api.confirm_modify_fee(
+) -> None:
+ fee_ctx = trezorui_api.confirm_modify_fee(
title=title,
sign=sign,
user_fee_change=user_fee_change,
@@ -2011,22 +2007,22 @@ def confirm_modify_fee(
items: list[StrPropertyType] = []
if fee_rate_amount:
items.append((TR.bitcoin__new_fee_rate, fee_rate_amount, None))
- info_layout = trezorui_api.show_info_with_cancel(
+ info_ctx = trezorui_api.show_info_with_cancel(
title=TR.confirm_total__title_fee,
items=items,
)
- return with_info(fee_layout, info_layout, "modify_fee", ButtonRequestType.SignTx)
+ with fee_ctx as fee_layout, info_ctx as info_layout:
+ return await with_info(
+ fee_layout, info_layout, "modify_fee", ButtonRequestType.SignTx
+ )
-def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.confirm_coinjoin(
- max_rounds=str(max_rounds),
- max_feerate=max_fee_per_vbyte,
- ),
- "coinjoin_final",
- BR_CODE_OTHER,
- )
+async def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> None:
+ with trezorui_api.confirm_coinjoin(
+ max_rounds=str(max_rounds),
+ max_feerate=max_fee_per_vbyte,
+ ) as layout:
+ return await raise_if_not_confirmed(layout, "coinjoin_final", BR_CODE_OTHER)
# TODO cleanup @ redesign
@@ -2153,7 +2149,8 @@ def request_passphrase_on_host() -> None:
def show_wait_text(message: str) -> None:
- draw_simple(trezorui_api.show_wait_text(message))
+ with trezorui_api.show_wait_text(message) as layout:
+ draw_simple(layout)
async def request_passphrase_on_device(max_len: int) -> str:
@@ -2256,14 +2253,13 @@ async def pin_wipe_code_exists_popup(
)
-def confirm_set_new_code(
- is_wipe_code: bool,
-) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.flow_confirm_set_new_code(is_wipe_code=is_wipe_code),
- "set_wipe_code" if is_wipe_code else "set_pin",
- BR_CODE_OTHER,
- )
+async def confirm_set_new_code(is_wipe_code: bool) -> None:
+ with trezorui_api.flow_confirm_set_new_code(is_wipe_code=is_wipe_code) as layout:
+ return await raise_if_not_confirmed(
+ layout,
+ "set_wipe_code" if is_wipe_code else "set_pin",
+ BR_CODE_OTHER,
+ )
def confirm_change_pin(
@@ -2317,23 +2313,16 @@ async def confirm_firmware_update(description: str, fingerprint: str) -> None:
async def set_brightness(current: int | None = None) -> None:
- br_name = "set_brightness"
- await raise_if_not_confirmed(
- trezorui_api.set_brightness(current=current),
- br_name,
- BR_CODE_OTHER,
- )
+ with trezorui_api.set_brightness(current=current) as layout:
+ await raise_if_not_confirmed(layout, "set_brightness", BR_CODE_OTHER)
show_continue_in_app(TR.brightness__changed_title)
-def tutorial(br_code: ButtonRequestType = BR_CODE_OTHER) -> Awaitable[None]:
+async def tutorial(br_code: ButtonRequestType = BR_CODE_OTHER) -> None:
"""Showing users how to interact with the device."""
- return raise_if_not_confirmed(
- trezorui_api.tutorial(),
- "tutorial",
- br_code,
- )
+ with trezorui_api.tutorial() as layout:
+ return await raise_if_not_confirmed(layout, "tutorial", br_code)
def create_details(
diff --git a/core/src/trezor/ui/layouts/delizia/fido.py b/core/src/trezor/ui/layouts/delizia/fido.py
index 45415ff2..a767fb2e 100644
--- a/core/src/trezor/ui/layouts/delizia/fido.py
+++ b/core/src/trezor/ui/layouts/delizia/fido.py
@@ -13,13 +13,13 @@ async def confirm_fido(
accounts: list[str | None],
) -> int:
"""Webauthn confirmation for one or more credentials."""
- confirm = trezorui_api.confirm_fido(
+ with trezorui_api.confirm_fido(
title=header,
app_name=app_name,
icon_name=icon_name,
accounts=accounts,
- )
- result = await interact(confirm, "confirm_fido", ButtonRequestType.Other)
+ ) as confirm:
+ result = await interact(confirm, "confirm_fido", ButtonRequestType.Other)
if __debug__ and result is trezorui_api.CONFIRMED:
# debuglink will directly inject a CONFIRMED message which we need to handle
diff --git a/core/src/trezor/ui/layouts/eckhart/__init__.py b/core/src/trezor/ui/layouts/eckhart/__init__.py
index 75bc5e37..ba34c30e 100644
--- a/core/src/trezor/ui/layouts/eckhart/__init__.py
+++ b/core/src/trezor/ui/layouts/eckhart/__init__.py
@@ -75,10 +75,9 @@ def confirm_action(
)
-def confirm_reset_device(recovery: bool = False) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.confirm_reset_device(recovery=recovery), None
- )
+async def confirm_reset_device(recovery: bool = False) -> None:
+ with trezorui_api.confirm_reset_device(recovery=recovery) as layout:
+ return await raise_if_not_confirmed(layout, None)
async def prompt_recovery_check(recovery_type: RecoveryType) -> None:
@@ -112,12 +111,13 @@ async def show_wallet_created_success() -> None:
async def prompt_backup() -> bool:
- result = await interact(
- trezorui_api.prompt_backup(),
- "backup_device",
- ButtonRequestType.ResetDevice,
- raise_on_cancel=None,
- )
+ with trezorui_api.prompt_backup() as layout:
+ result = await interact(
+ layout,
+ "backup_device",
+ ButtonRequestType.ResetDevice,
+ raise_on_cancel=None,
+ )
return result is CONFIRMED
@@ -330,23 +330,21 @@ async def show_pubkey(
br_name: str = "show_pubkey",
) -> None:
- await raise_if_not_confirmed(
- trezorui_api.flow_get_pubkey(
- pubkey=pubkey,
- title=title or TR.address__public_key,
- subtitle=account,
- description=None,
- hint=warning,
- chunkify=False,
- pubkey_qr=pubkey,
- case_sensitive=True,
- account=account,
- path=path,
- br_name=br_name,
- br_code=ButtonRequestType.PublicKey,
- ),
- None,
- )
+ with trezorui_api.flow_get_pubkey(
+ pubkey=pubkey,
+ title=title or TR.address__public_key,
+ subtitle=account,
+ description=None,
+ hint=warning,
+ chunkify=False,
+ pubkey_qr=pubkey,
+ case_sensitive=True,
+ account=account,
+ path=path,
+ br_name=br_name,
+ br_code=ButtonRequestType.PublicKey,
+ ) as layout:
+ await raise_if_not_confirmed(layout, None)
show_continue_in_app(TR.address__public_key_confirmed)
@@ -2071,14 +2069,14 @@ async def confirm_modify_output(
break
-def confirm_modify_fee(
+async def confirm_modify_fee(
title: str,
sign: int,
user_fee_change: str,
total_fee_new: str,
fee_rate_amount: str | None = None,
-) -> Awaitable[None]:
- fee_layout = trezorui_api.confirm_modify_fee(
+) -> None:
+ fee_ctx = trezorui_api.confirm_modify_fee(
title=title,
sign=sign,
user_fee_change=user_fee_change,
@@ -2088,22 +2086,22 @@ def confirm_modify_fee(
items: list[StrPropertyType] = []
if fee_rate_amount:
items.append((TR.bitcoin__new_fee_rate, fee_rate_amount, True))
- info_layout = trezorui_api.show_info_with_cancel(
+ info_ctx = trezorui_api.show_info_with_cancel(
title=TR.confirm_total__title_fee,
items=items,
)
- return with_info(fee_layout, info_layout, "modify_fee", ButtonRequestType.SignTx)
+ with fee_ctx as fee_layout, info_ctx as info_layout:
+ return await with_info(
+ fee_layout, info_layout, "modify_fee", ButtonRequestType.SignTx
+ )
-def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.confirm_coinjoin(
- max_rounds=str(max_rounds),
- max_feerate=max_fee_per_vbyte,
- ),
- "coinjoin_final",
- BR_CODE_OTHER,
- )
+async def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> None:
+ with trezorui_api.confirm_coinjoin(
+ max_rounds=str(max_rounds),
+ max_feerate=max_fee_per_vbyte,
+ ) as layout:
+ return await raise_if_not_confirmed(layout, "coinjoin_final", BR_CODE_OTHER)
# TODO cleanup @ redesign
@@ -2246,7 +2244,8 @@ def request_passphrase_on_host() -> None:
def show_wait_text(message: str) -> None:
- draw_simple(trezorui_api.show_wait_text(message))
+ with trezorui_api.show_wait_text(message) as layout:
+ draw_simple(layout)
async def request_passphrase_on_device(max_len: int) -> str:
@@ -2353,14 +2352,13 @@ async def pin_wipe_code_exists_popup(
)
-def confirm_set_new_code(
- is_wipe_code: bool,
-) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.flow_confirm_set_new_code(is_wipe_code=is_wipe_code),
- "set_wipe_code" if is_wipe_code else "set_pin",
- BR_CODE_OTHER,
- )
+async def confirm_set_new_code(is_wipe_code: bool) -> None:
+ with trezorui_api.flow_confirm_set_new_code(is_wipe_code=is_wipe_code) as layout:
+ return await raise_if_not_confirmed(
+ layout,
+ "set_wipe_code" if is_wipe_code else "set_pin",
+ BR_CODE_OTHER,
+ )
def confirm_change_pin(
@@ -2412,21 +2410,15 @@ async def confirm_firmware_update(description: str, fingerprint: str) -> None:
)
-def set_brightness(current: int | None = None) -> Awaitable[None]:
- return raise_if_not_confirmed(
- trezorui_api.set_brightness(current=current),
- "set_brightness",
- BR_CODE_OTHER,
- )
+async def set_brightness(current: int | None = None) -> None:
+ with trezorui_api.set_brightness(current=current) as layout:
+ return await raise_if_not_confirmed(layout, "set_brightness", BR_CODE_OTHER)
-def tutorial(br_code: ButtonRequestType = BR_CODE_OTHER) -> Awaitable[None]:
+async def tutorial(br_code: ButtonRequestType = BR_CODE_OTHER) -> None:
"""Showing users how to interact with the device."""
- return raise_if_not_confirmed(
- trezorui_api.tutorial(),
- "tutorial",
- br_code,
- )
+ with trezorui_api.tutorial() as layout:
+ return await raise_if_not_confirmed(layout, "tutorial", br_code)
def create_details(
diff --git a/core/src/trezor/ui/layouts/eckhart/fido.py b/core/src/trezor/ui/layouts/eckhart/fido.py
index b4d586bc..8a92a120 100644
--- a/core/src/trezor/ui/layouts/eckhart/fido.py
+++ b/core/src/trezor/ui/layouts/eckhart/fido.py
@@ -13,13 +13,13 @@ async def confirm_fido(
accounts: list[str | None],
) -> int:
"""Webauthn confirmation for one or more credentials."""
- confirm = trezorui_api.confirm_fido(
+ with trezorui_api.confirm_fido(
title=header,
app_name=app_name,
icon_name=icon_name,
accounts=accounts,
- )
- result = await interact(confirm, "confirm_fido", ButtonRequestType.Other)
+ ) as confirm:
+ result = await interact(confirm, "confirm_fido", ButtonRequestType.Other)
if __debug__ and result is trezorui_api.CONFIRMED:
# debuglink will directly inject a CONFIRMED message which we need to handle
diff --git a/core/src/trezor/wire/thp/ui.py b/core/src/trezor/wire/thp/ui.py
index ddeafebc..6cd84e23 100644
--- a/core/src/trezor/wire/thp/ui.py
+++ b/core/src/trezor/wire/thp/ui.py
@@ -6,14 +6,14 @@ if TYPE_CHECKING:
from trezorui_api import UiResult
-def confirm_pairing(
+async def confirm_pairing(
br_name: str,
title: str,
app_name: str | None,
host_name: str | None,
short_text: str,
long_text: str,
-) -> Awaitable[None]:
+) -> None:
from trezor.ui.layouts.common import raise_if_not_confirmed
from trezorui_api import confirm_thp_pairing
@@ -24,10 +24,8 @@ def confirm_pairing(
args = (app_name or host_name or "(unknown)",)
description = short_text
- return raise_if_not_confirmed(
- confirm_thp_pairing(title=title, description=description, args=args),
- br_name=br_name,
- )
+ with confirm_thp_pairing(title=title, description=description, args=args) as layout:
+ return await raise_if_not_confirmed(layout, br_name=br_name)
def show_autoconnect_credential_confirmation_screen(
@@ -81,14 +79,12 @@ async def show_code_entry_screen(
from trezor.ui.layouts.common import interact
from trezorui_api import show_thp_pairing_code
- return await interact(
- show_thp_pairing_code(
- title=TR.thp__code_title,
- description=TR.thp__code_entry.format(host_name),
- code=code_entry_str,
- ),
- br_name=None,
- )
+ with show_thp_pairing_code(
+ title=TR.thp__code_title,
+ description=TR.thp__code_entry.format(host_name),
+ code=code_entry_str,
+ ) as layout:
+ return await interact(layout, br_name=None)
async def show_nfc_screen() -> UiResult:
Why this scored 26/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.