refactor(core): proper raise_if_not_confirmed behavior
What changed, and why it matters
This commit renames a helper function back from `raise_if_cancelled` to `raise_if_not_confirmed` and changes its behavior. Previously, the code only raised an error when the user explicitly cancelled. Now it also raises an error if the UI returns any unexpected result other than a confirmed success. This is a defensive hardening change across many on-device confirmation screens, intended to prevent the device from silently continuing when something other than a clear confirmation happens.
Treat as a hardening/refactor commit. Review that no caller relied on receiving a non-CONFIRMED/CANCELLED UiResult through `raise_if_not_confirmed`, since the new RuntimeError path could theoretically expose latent bugs. No immediate patch or incident response is indicated.
Security signals we found
Defensive validation of UI interaction results
Unexpected non-confirmed UI results now raise RuntimeError instead of being silently accepted
Broad refactor touching confirmation flows across multiple UI layouts
No explicit vulnerability or CVE mentioned in commit message
No changelog entry requested
Evidence from the diff
The refactor restores the name raise_if_not_confirmed and implements the matching semantics in core/src/trezor/ui/layouts/common.py. interact() gains a confirm_only=True flag: when set, it returns None on CONFIRMED, raises the configured exception on CANCELLED, and raises RuntimeError for any other UiResult. raise_if_not_confirmed() is now a thin wrapper that calls interact(..., confirm_only=True). All UI layout modules (bolt, caesar, delizia, eckhart) and THP pairing are updated to use the new name. The change is purely defensive; it does not introduce a known exploitable bug, but it closes a class of bugs where an unexpected layout result could be treated as success.
Changed components
core/src/trezor/ui/layouts/common.pycore/src/trezor/ui/layouts/bolt/__init__.pycore/src/trezor/ui/layouts/bolt/reset.pycore/src/trezor/ui/layouts/caesar/__init__.pycore/src/trezor/ui/layouts/caesar/reset.pycore/src/trezor/ui/layouts/delizia/__init__.pycore/src/trezor/ui/layouts/delizia/recovery.pycore/src/trezor/ui/layouts/delizia/reset.pycore/src/trezor/ui/layouts/eckhart/__init__.pycore/src/trezor/ui/layouts/eckhart/recovery.pycore/src/trezor/ui/layouts/eckhart/reset.pycore/src/trezor/wire/thp/ui.pycore/src/apps/homescreen/device_menu.pyInspect captured patch +160 / −116
diff --git a/core/src/apps/homescreen/device_menu.py b/core/src/apps/homescreen/device_menu.py
index 73f0006d..0ed80810 100644
--- a/core/src/apps/homescreen/device_menu.py
+++ b/core/src/apps/homescreen/device_menu.py
@@ -6,7 +6,7 @@ import storage.device as storage_device
import trezorble as ble
import trezorui_api
from trezor import TR, config, log, utils
-from trezor.ui.layouts import interact, raise_if_cancelled
+from trezor.ui.layouts import interact, raise_if_not_confirmed
from trezor.wire import ActionCancelled, PinCancelled
from trezorui_api import CANCELLED, DeviceMenuResult
@@ -164,7 +164,7 @@ async def handle_device_menu() -> None:
from apps.management.wipe_device import wipe_device
try:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.show_warning(
title=TR.homescreen__title_backup_failed,
button=TR.words__wipe,
diff --git a/core/src/trezor/ui/layouts/bolt/__init__.py b/core/src/trezor/ui/layouts/bolt/__init__.py
index e663da94..32f21476 100644
--- a/core/src/trezor/ui/layouts/bolt/__init__.py
+++ b/core/src/trezor/ui/layouts/bolt/__init__.py
@@ -5,7 +5,7 @@ from trezor import TR, ui, utils
from trezor.enums import ButtonRequestType, RecoveryType
from trezor.wire import ActionCancelled
-from ..common import draw_simple, interact, raise_if_cancelled, with_info
+from ..common import draw_simple, interact, raise_if_not_confirmed, with_info
if TYPE_CHECKING:
from buffer_types import AnyBytes, StrOrBytes
@@ -45,7 +45,7 @@ def confirm_action(
if description is not None and description_param is not None:
description = description.format(description_param)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_action(
title=title,
action=action,
@@ -77,7 +77,7 @@ def confirm_single(
assert template_str in description
begin, _separator, end = description.partition(template_str)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_emphasized(
title=title,
items=(begin, (True, description_param), end),
@@ -89,7 +89,7 @@ def confirm_single(
def confirm_reset_device(recovery: bool = False) -> Awaitable[None]:
- return raise_if_cancelled(
+ 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),
@@ -155,7 +155,7 @@ def confirm_path_warning(path: str, path_type: str | None = None) -> Awaitable[N
if not path_type
else f"{TR.words__unknown} {path_type.lower()}."
)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_warning(
title=title,
value=path,
@@ -204,7 +204,7 @@ def lock_time_disabled_warning() -> Awaitable[None]:
def confirm_homescreen(image: AnyBytes) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_homescreen(
title=TR.homescreen__title_set,
image=image,
@@ -436,7 +436,7 @@ def show_warning(
br_code: ButtonRequestType = ButtonRequestType.Warning,
) -> Awaitable[None]:
button = button or TR.buttons__continue # def_arg
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_warning(
title=content,
description=subheader or "",
@@ -470,7 +470,7 @@ def show_success(
button: str | None = None,
) -> Awaitable[None]:
button = button or TR.buttons__continue # def_arg
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_success(
title=content,
description=subheader or "",
@@ -502,7 +502,7 @@ async def confirm_payment_request(
is_swap = len(trades) != 0
for title, text in texts:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.confirm_value(
title=(title or (TR.words__swap if is_swap else TR.words__confirm)),
value=text,
@@ -762,7 +762,7 @@ def confirm_blob(
)
else:
assert not extra_confirmation_if_not_read
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
layout,
br_name,
br_code,
@@ -888,7 +888,7 @@ def confirm_properties(
if subtitle:
title += ": " + subtitle
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_properties(
title=title,
items=list(props),
@@ -1452,7 +1452,7 @@ if not utils.BITCOIN_ONLY:
def confirm_joint_total(spending_amount: str, total_amount: str) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
# FIXME: arguments for amount/fee are misused here
trezorui_api.confirm_summary(
amount=spending_amount,
@@ -1563,7 +1563,7 @@ def confirm_modify_fee(
def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_coinjoin(
max_rounds=str(max_rounds),
max_feerate=max_fee_per_vbyte,
@@ -1828,7 +1828,7 @@ def confirm_set_new_code(
information = TR.pin__info
br_name = "set_pin"
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_emphasized(
title=title,
items=(
diff --git a/core/src/trezor/ui/layouts/bolt/reset.py b/core/src/trezor/ui/layouts/bolt/reset.py
index ff4c1590..f722409c 100644
--- a/core/src/trezor/ui/layouts/bolt/reset.py
+++ b/core/src/trezor/ui/layouts/bolt/reset.py
@@ -4,7 +4,7 @@ import trezorui_api
from trezor import TR
from trezor.enums import ButtonRequestType
-from ..common import interact, raise_if_cancelled
+from ..common import interact, raise_if_not_confirmed
CONFIRMED = trezorui_api.CONFIRMED # global_import_cache
@@ -23,7 +23,7 @@ def show_share_words(
group_index + 1, share_index + 1
)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_share_words(
words=share_words,
title=title,
@@ -92,7 +92,7 @@ def slip39_show_checklist(
)
)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_checklist(
title=TR.reset__slip39_checklist_title,
button=TR.buttons__continue,
@@ -286,7 +286,7 @@ def show_intro_backup(single_share: bool, num_of_words: int | None) -> Awaitable
else:
description = TR.backup__info_multi_share_backup
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_info(
title="",
description=description,
diff --git a/core/src/trezor/ui/layouts/caesar/__init__.py b/core/src/trezor/ui/layouts/caesar/__init__.py
index a552c8f1..422ec6ac 100644
--- a/core/src/trezor/ui/layouts/caesar/__init__.py
+++ b/core/src/trezor/ui/layouts/caesar/__init__.py
@@ -5,7 +5,7 @@ from trezor import TR, ui, utils
from trezor.enums import ButtonRequestType, RecoveryType
from trezor.wire import ActionCancelled
-from ..common import draw_simple, interact, raise_if_cancelled
+from ..common import draw_simple, interact, raise_if_not_confirmed
if TYPE_CHECKING:
from buffer_types import AnyBytes, StrOrBytes
@@ -73,7 +73,7 @@ def confirm_action(
if description is not None and description_param is not None:
description = description.format(description_param)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_action(
title=title,
action=action,
@@ -115,7 +115,7 @@ def confirm_single(
def confirm_reset_device(
recovery: bool = False,
) -> Awaitable[None]:
- return raise_if_cancelled(
+ 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,
@@ -222,7 +222,7 @@ def lock_time_disabled_warning() -> Awaitable[ui.UiResult]:
def confirm_homescreen(image: AnyBytes) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_homescreen(
title=TR.homescreen__title_set,
image=image,
@@ -504,7 +504,7 @@ def show_danger(
) -> Awaitable[None]:
title = title or TR.words__warning
verb_cancel = verb_cancel or TR.buttons__cancel
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_danger(
title=title,
description=content,
@@ -569,7 +569,7 @@ async def confirm_payment_request(
is_swap = len(trades) != 0
for title, text in texts:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.confirm_value(
title=title or (TR.words__swap if is_swap else TR.words__confirm),
value=text,
@@ -773,7 +773,7 @@ def confirm_blob(
extra_confirmation_if_not_read,
)
else:
- return raise_if_cancelled(layout, br_name, br_code)
+ return raise_if_not_confirmed(layout, br_name, br_code)
async def _confirm_ask_pagination(
@@ -902,7 +902,7 @@ def confirm_properties(
if subtitle:
title += ": " + subtitle
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_properties(
title=title,
items=items,
@@ -913,7 +913,7 @@ def confirm_properties(
)
-async def confirm_value(
+def confirm_value(
title: str,
value: str,
description: str | None,
@@ -928,14 +928,14 @@ async def confirm_value(
chunkify: bool = False,
chunkify_info: bool = False,
cancel: bool = False,
-) -> None:
+) -> Awaitable[None]:
"""General confirmation dialog, used by many other confirm_* functions."""
if description and value:
description += ":"
if not info_items:
- return await raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_value(
title=title,
value=value,
@@ -979,7 +979,7 @@ async def confirm_value(
Details.from_layout(str(name), item_factory(str(name), str(value)))
for name, value, _is_data in info_items
)
- await confirm_with_menu(main, menu, br_name, br_code)
+ return confirm_with_menu(main, menu, br_name, br_code)
def confirm_total(
@@ -1008,7 +1008,7 @@ def confirm_total(
else None
)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_summary(
amount=total_amount,
amount_label=total_label,
@@ -1138,7 +1138,7 @@ if not utils.BITCOIN_ONLY:
if account_path
else None
)
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.confirm_summary(
amount=None,
amount_label=None,
@@ -1222,7 +1222,7 @@ if not utils.BITCOIN_ONLY:
else:
amount_title = f"{TR.words__amount}:"
amount_value = total_amount
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.confirm_summary(
amount=amount_value,
amount_label=amount_title,
@@ -1276,7 +1276,7 @@ if not utils.BITCOIN_ONLY:
amount_title if amount_title is not None else f"{TR.words__amount}:"
) # def_arg
fee_title = fee_title or TR.words__fee # def_arg
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_summary(
amount=amount,
amount_label=amount_title,
@@ -1365,7 +1365,7 @@ if not utils.BITCOIN_ONLY:
) -> Awaitable[None]:
amount_title = f"{TR.send__total_amount}:"
fee_title = TR.send__including_fee
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_summary(
amount=amount,
amount_label=amount_title,
@@ -1420,7 +1420,7 @@ if not utils.BITCOIN_ONLY:
)
try:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
summary_layout,
br_name,
br_code,
@@ -1436,7 +1436,7 @@ if not utils.BITCOIN_ONLY:
is_sending_from_trezor_account: bool,
extra_items: Iterable[PropertyType],
) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_summary(
amount=None,
amount_label=None,
@@ -1558,13 +1558,13 @@ async def confirm_modify_output(
send_button_request = True
while True:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
address_layout,
"modify_output" if send_button_request else None,
ButtonRequestType.ConfirmOutput,
)
try:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
modify_layout,
"modify_output" if send_button_request else None,
ButtonRequestType.ConfirmOutput,
@@ -1583,7 +1583,7 @@ def confirm_modify_fee(
total_fee_new: str,
fee_rate_amount: str | None = None,
) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_modify_fee(
title=title,
sign=sign,
@@ -1597,7 +1597,7 @@ def confirm_modify_fee(
def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_coinjoin(
max_rounds=str(max_rounds),
max_feerate=max_fee_per_vbyte,
@@ -1658,7 +1658,7 @@ async def confirm_signverify(
)
try:
if message_layout.page_count() <= LONG_MSG_PAGE_THRESHOLD:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
message_layout,
br_name,
BR_CODE_OTHER,
@@ -1784,7 +1784,7 @@ def _confirm_multiple_pages_texts(
verb: str,
br_code: ButtonRequestType = BR_CODE_OTHER,
) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.multiple_pages_texts(
title=title,
verb=verb,
@@ -1920,7 +1920,7 @@ async def success_pin_change(curpin: str | None, newpin: str | None) -> None:
def confirm_firmware_update(description: str, fingerprint: str) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_firmware_update(
description=description, fingerprint=fingerprint
),
diff --git a/core/src/trezor/ui/layouts/caesar/reset.py b/core/src/trezor/ui/layouts/caesar/reset.py
index d191e100..ef4a785f 100644
--- a/core/src/trezor/ui/layouts/caesar/reset.py
+++ b/core/src/trezor/ui/layouts/caesar/reset.py
@@ -4,7 +4,7 @@ import trezorui_api
from trezor import TR
from trezor.enums import ButtonRequestType
-from ..common import interact, raise_if_cancelled
+from ..common import interact, raise_if_not_confirmed
from . import confirm_action, show_success, show_warning
CONFIRMED = trezorui_api.CONFIRMED # global_import_cache
@@ -121,7 +121,7 @@ def slip39_show_checklist(
)
)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_checklist(
title=TR.reset__slip39_checklist_title,
button=TR.buttons__continue,
diff --git a/core/src/trezor/ui/layouts/common.py b/core/src/trezor/ui/layouts/common.py
index ee30acc8..10a74489 100644
--- a/core/src/trezor/ui/layouts/common.py
+++ b/core/src/trezor/ui/layouts/common.py
@@ -6,7 +6,7 @@ from trezor.enums import ButtonRequestType
from trezor.wire import ActionCancelled
if TYPE_CHECKING:
- from typing import Any, Awaitable, Callable, Coroutine, TypeVar
+ from typing import Any, Awaitable, Callable, Coroutine, Literal, TypeVar, overload
from trezorui_api import PropertyType # noqa: F401
@@ -16,13 +16,48 @@ if TYPE_CHECKING:
T = TypeVar("T")
+ @overload
+ async def interact(
+ layout_obj: ui.LayoutObj[Any],
+ br_name: str | None,
+ br_code: ButtonRequestType = ButtonRequestType.Other,
+ raise_on_cancel: ExceptionType | None = ActionCancelled,
+ *,
+ confirm_only: Literal[True],
+ ) -> None: ...
+
+ @overload
+ async def interact(
+ layout_obj: ui.LayoutObj[T],
+ br_name: str | None,
+ br_code: ButtonRequestType = ButtonRequestType.Other,
+ raise_on_cancel: ExceptionType | None = ActionCancelled,
+ *,
+ confirm_only: bool = False,
+ ) -> T: ...
+
async def interact(
layout_obj: ui.LayoutObj[T],
br_name: str | None,
br_code: ButtonRequestType = ButtonRequestType.Other,
raise_on_cancel: ExceptionType | None = ActionCancelled,
-) -> T:
+ *,
+ confirm_only: bool = False,
+) -> T | None:
+ """Return the result of user interaction with the layout.
+
+ If the result is CANCELLED, raise the specified exception (`ActionCancelled`
+ by default), unless `raise_on_cancel` is explicitly set to None.
+
+ Specify `confirm_only=True` to invoke "raise if not confirmed" behavior,
+ that is:
+ * if the result is CONFIRMED, return None
+ * if the result is CANCELLED, raise the `raise_on_cancel` exception
+ * on any other result (indicating a bug in the caller), raise a RuntimeError
+ Setting `raise_on_cancel=None` together with `confirm_only=True` invalid,
+ and a RuntimeError will be raised in the cancel case.
+ """
# shut down other workflows to prevent them from interfering with the current one
workflow.close_others()
# start the layout
@@ -33,20 +68,29 @@ async def interact(
layout.button_request_box.put((br_code, br_name))
# wait for the layout result
result = await layout.get_result()
+
# raise an exception if the user cancelled the action
if raise_on_cancel is not None and result is trezorui_api.CANCELLED:
raise raise_on_cancel
+
+ if confirm_only:
+ # raise_if_not_confirmed behavior: return None if the user confirmed the action
+ if result is trezorui_api.CONFIRMED:
+ return None
+ # if the result was CANCELLED, the earlier branch should have raised
+ # ...raise otherwise
+ raise RuntimeError # unexpected result
+
return result
-def raise_if_cancelled(
+def raise_if_not_confirmed(
layout_obj: ui.LayoutObj[ui.UiResult],
br_name: str | None,
br_code: ButtonRequestType = ButtonRequestType.Other,
exc: ExceptionType = ActionCancelled,
) -> Coroutine[Any, Any, None]:
- action = interact(layout_obj, br_name, br_code, exc)
- return action # type: ignore ["UiResult" is not assignable to "None"]
+ return interact(layout_obj, br_name, br_code, exc, confirm_only=True)
async def with_info(
diff --git a/core/src/trezor/ui/layouts/delizia/__init__.py b/core/src/trezor/ui/layouts/delizia/__init__.py
index 4fe476d1..15100138 100644
--- a/core/src/trezor/ui/layouts/delizia/__init__.py
+++ b/core/src/trezor/ui/layouts/delizia/__init__.py
@@ -5,7 +5,7 @@ from trezor import TR, ui, utils, workflow
from trezor.enums import ButtonRequestType, RecoveryType
from trezor.wire import ActionCancelled
-from ..common import draw_simple, interact, raise_if_cancelled, with_info
+from ..common import draw_simple, interact, raise_if_not_confirmed, with_info
if TYPE_CHECKING:
from buffer_types import AnyBytes, StrOrBytes
@@ -109,7 +109,7 @@ def confirm_single(
assert template_str in description
begin, _separator, end = description.partition(template_str)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_emphasized(
title=title,
items=(begin, (True, description_param), end),
@@ -121,7 +121,7 @@ def confirm_single(
def confirm_reset_device(recovery: bool = False) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_reset_device(recovery=recovery), None
)
@@ -188,7 +188,7 @@ def confirm_multisig_warning() -> Awaitable[None]:
def confirm_multisig_different_paths_warning() -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_danger(
title=f"{TR.words__important}!",
description=TR.send__multisig_different_paths,
@@ -227,7 +227,7 @@ def confirm_homescreen(
# in order to display the new homescreen image.
workflow.close_others()
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_homescreen(
title=TR.homescreen__title_set,
image=image,
@@ -346,7 +346,7 @@ async def show_address(
)
return result
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.flow_get_address(
address=address,
title=title or TR.address__title_receive_address,
@@ -379,7 +379,7 @@ async def show_pubkey(
br_name: str = "show_pubkey",
) -> None:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.flow_get_pubkey(
pubkey=pubkey,
title=title or title or TR.address__public_key,
@@ -430,7 +430,7 @@ def show_warning(
br_code: ButtonRequestType = ButtonRequestType.Warning,
) -> Awaitable[None]:
button = button or TR.buttons__continue # def_arg
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_warning(
title=TR.words__important,
value=content,
@@ -452,7 +452,7 @@ def show_danger(
) -> Awaitable[None]:
title = title or TR.words__warning
verb_cancel = verb_cancel or TR.buttons__cancel
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_danger(
title=title,
description=content,
@@ -471,7 +471,7 @@ def show_success(
button: str | None = None,
time_ms: int = 0,
) -> Coroutine[Any, Any, None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_success(
title=content,
button=button or "",
@@ -511,7 +511,7 @@ async def confirm_payment_request(
is_swap = len(trades) != 0
for title, text in texts:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.confirm_value(
title=(title or (TR.words__swap if is_swap else TR.words__confirm)),
value=text,
@@ -601,7 +601,7 @@ async def confirm_output(
else:
title = TR.send__title_sending_to
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.flow_confirm_output(
title=TR.words__address,
subtitle=title,
@@ -726,7 +726,7 @@ def confirm_blob(
chunkify=chunkify,
prompt_screen=prompt_screen,
)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
layout,
br_name,
br_code,
@@ -842,7 +842,7 @@ def confirm_properties(
verb: str | None = None,
) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_properties(
title=title,
subtitle=subtitle,
@@ -883,7 +883,7 @@ def confirm_total(
if fee_rate_amount:
fee_items.append((TR.confirm_total__fee_rate, fee_rate_amount, None))
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_summary(
amount=total_amount,
amount_label=total_label,
@@ -917,7 +917,7 @@ def _confirm_summary(
list(account_items) if account_items else None
)
extra_props: list[PropertyType] | None = list(extra_items) if extra_items else None
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_summary(
amount=amount,
amount_label=amount_label,
@@ -964,7 +964,7 @@ if not utils.BITCOIN_ONLY:
(TR.words__amount, total_amount, None),
(TR.send__maximum_fee, maximum_fee, None),
]
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.flow_confirm_output(
title=TR.words__address,
subtitle=(
@@ -1185,7 +1185,7 @@ if not utils.BITCOIN_ONLY:
(TR.send__maximum_fee, maximum_fee, None),
]
)
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.flow_confirm_output(
title=verb,
subtitle=None,
@@ -1278,7 +1278,7 @@ if not utils.BITCOIN_ONLY:
if amount_item:
summary_items.append(amount_item)
summary_items.append(fee_item)
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.flow_confirm_output(
title=title,
subtitle=None,
@@ -1456,7 +1456,7 @@ async def confirm_modify_output(
send_button_request = True
while True:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
address_layout,
"modify_output" if send_button_request else None,
ButtonRequestType.ConfirmOutput,
@@ -1498,7 +1498,7 @@ def confirm_modify_fee(
def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_coinjoin(
max_rounds=str(max_rounds),
max_feerate=max_fee_per_vbyte,
@@ -1738,7 +1738,7 @@ async def pin_wipe_code_exists_popup(
def confirm_set_new_code(
is_wipe_code: bool,
) -> Awaitable[None]:
- return raise_if_cancelled(
+ 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,
@@ -1785,7 +1785,7 @@ async def success_pin_change(curpin: str | None, newpin: str | None) -> None:
def confirm_firmware_update(description: str, fingerprint: str) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_firmware_update(
description=description, fingerprint=fingerprint
),
@@ -1796,7 +1796,7 @@ def confirm_firmware_update(description: str, fingerprint: str) -> Awaitable[Non
async def set_brightness(current: int | None = None) -> None:
br_name = "set_brightness"
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.set_brightness(current=current),
br_name,
BR_CODE_OTHER,
@@ -1807,7 +1807,7 @@ async def set_brightness(current: int | None = None) -> None:
def tutorial(br_code: ButtonRequestType = BR_CODE_OTHER) -> Awaitable[None]:
"""Showing users how to interact with the device."""
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.tutorial(),
"tutorial",
br_code,
diff --git a/core/src/trezor/ui/layouts/delizia/recovery.py b/core/src/trezor/ui/layouts/delizia/recovery.py
index 5865b777..7bc2836d 100644
--- a/core/src/trezor/ui/layouts/delizia/recovery.py
+++ b/core/src/trezor/ui/layouts/delizia/recovery.py
@@ -7,7 +7,7 @@ from trezor.enums import ButtonRequestType, RecoveryType
from apps.common import backup_types
from ..common import interact
-from . import raise_if_cancelled
+from . import raise_if_not_confirmed
CONFIRMED = trezorui_api.CONFIRMED # global_import_cache
CANCELLED = trezorui_api.CANCELLED # global_import_cache
@@ -91,7 +91,7 @@ def format_remaining_shares_info(
async def show_group_share_success(share_index: int, group_index: int) -> None:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.show_group_share_success(
lines=[
TR.recovery__you_have_entered,
@@ -180,7 +180,7 @@ async def show_recovery_warning(
br_code: ButtonRequestType = ButtonRequestType.Warning,
) -> None:
button = button or TR.buttons__try_again # def_arg
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.show_warning(
title=content or TR.words__warning,
value=subheader or "",
diff --git a/core/src/trezor/ui/layouts/delizia/reset.py b/core/src/trezor/ui/layouts/delizia/reset.py
index 62272850..2adf4eec 100644
--- a/core/src/trezor/ui/layouts/delizia/reset.py
+++ b/core/src/trezor/ui/layouts/delizia/reset.py
@@ -6,7 +6,7 @@ from trezor.enums import ButtonRequestType
from trezor.wire import ActionCancelled
from ..common import interact
-from . import raise_if_cancelled, show_success
+from . import raise_if_not_confirmed, show_success
CONFIRMED = trezorui_api.CONFIRMED # global_import_cache
@@ -37,7 +37,7 @@ def show_share_words(
assert len(instructions) < 3
text_confirm = TR.reset__words_written_down_template.format(words_count)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_share_words_extended(
words=share_words,
subtitle=subtitle,
@@ -327,7 +327,7 @@ def show_reset_warning(
button: str | None = None,
br_code: ButtonRequestType = ButtonRequestType.Warning,
) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_warning(
title=subheader or "",
description=content,
diff --git a/core/src/trezor/ui/layouts/eckhart/__init__.py b/core/src/trezor/ui/layouts/eckhart/__init__.py
index 5b6d6410..8cb87db2 100644
--- a/core/src/trezor/ui/layouts/eckhart/__init__.py
+++ b/core/src/trezor/ui/layouts/eckhart/__init__.py
@@ -5,7 +5,7 @@ from trezor import TR, ui, utils, workflow
from trezor.enums import ButtonRequestType, RecoveryType
from trezor.wire import ActionCancelled
-from ..common import draw_simple, interact, raise_if_cancelled, with_info
+from ..common import draw_simple, interact, raise_if_not_confirmed, with_info
if TYPE_CHECKING:
from buffer_types import AnyBytes, StrOrBytes
@@ -56,7 +56,7 @@ def confirm_action(
if description is not None and description_param is not None:
description = description.format(description_param)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_action(
title=title,
action=action,
@@ -77,7 +77,7 @@ def confirm_action(
def confirm_reset_device(recovery: bool = False) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_reset_device(recovery=recovery), None
)
@@ -183,7 +183,7 @@ def lock_time_disabled_warning() -> Awaitable[None]:
def confirm_homescreen(
image: AnyBytes,
) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_homescreen(
title=TR.homescreen__title_set,
image=image,
@@ -301,7 +301,7 @@ async def show_address(
if warning is None and multisig_index is not None:
warning = TR.send__receiving_to_multisig
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.flow_get_address(
address=address,
title=title or TR.words__receive,
@@ -334,7 +334,7 @@ async def show_pubkey(
br_name: str = "show_pubkey",
) -> None:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.flow_get_pubkey(
pubkey=pubkey,
title=title or TR.address__public_key,
@@ -385,7 +385,7 @@ def show_warning(
br_code: ButtonRequestType = ButtonRequestType.Warning,
) -> Awaitable[None]:
button = button or TR.words__continue_anyway # def_arg
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_warning(
title=TR.words__important,
button=button,
@@ -409,7 +409,7 @@ def show_danger(
) -> Awaitable[None]:
title = title or TR.words__warning
verb_cancel = verb_cancel or TR.buttons__cancel
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_danger(
title=title,
description=content,
@@ -430,7 +430,7 @@ def show_success(
time_ms: int = 0,
) -> Coroutine[Any, Any, None]:
button = button or TR.buttons__continue # def_arg
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_success(
title=subheader if subheader else TR.words__title_done,
button=button,
@@ -471,7 +471,7 @@ async def confirm_payment_request(
is_swap = len(trades) != 0
for title, text in texts:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.confirm_value(
title=(title or (TR.words__swap if is_swap else TR.words__confirm)),
value=text,
@@ -595,7 +595,7 @@ async def confirm_output(
else:
title = TR.send__title_sending_to
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.flow_confirm_output(
title=TR.words__send,
subtitle=title,
@@ -718,7 +718,7 @@ def confirm_blob(
chunkify=chunkify,
cancel=True,
)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
layout,
br_name,
br_code,
@@ -843,7 +843,7 @@ def confirm_properties(
if subtitle:
title += ": " + subtitle
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_properties(
title=title,
items=list(props),
@@ -882,7 +882,7 @@ def confirm_total(
if fee_rate_amount:
fee_items.append((TR.confirm_total__fee_rate, fee_rate_amount, True))
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_summary(
amount=total_amount,
amount_label=total_label,
@@ -917,7 +917,7 @@ def _confirm_summary(
list(account_items) if account_items else None
)
extra_props: list[PropertyType] | None = list(extra_items) if extra_items else None
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_summary(
amount=amount,
amount_label=amount_label,
@@ -978,7 +978,7 @@ if not utils.BITCOIN_ONLY:
fee_items: list[PropertyType] | None = (
list(fee_info_items) if fee_info_items else None
)
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.flow_confirm_output(
title=title,
subtitle=subtitle,
@@ -1214,7 +1214,7 @@ if not utils.BITCOIN_ONLY:
]
)
fee_items: list[PropertyType] | None = list(info_items) if info_items else None
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.flow_confirm_output(
title=verb,
subtitle=None,
@@ -1299,7 +1299,7 @@ if not utils.BITCOIN_ONLY:
summary_items: list[PropertyType] = [fee_item]
if amount_item:
summary_items.append(amount_item)
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.flow_confirm_output(
title=title,
subtitle=None,
@@ -1480,7 +1480,7 @@ async def confirm_modify_output(
send_button_request = True
while True:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
address_layout,
"modify_output" if send_button_request else None,
ButtonRequestType.ConfirmOutput,
@@ -1522,7 +1522,7 @@ def confirm_modify_fee(
def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_coinjoin(
max_rounds=str(max_rounds),
max_feerate=max_fee_per_vbyte,
@@ -1776,7 +1776,7 @@ async def pin_wipe_code_exists_popup(
def confirm_set_new_code(
is_wipe_code: bool,
) -> Awaitable[None]:
- return raise_if_cancelled(
+ 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,
@@ -1822,7 +1822,7 @@ async def success_pin_change(curpin: str | None, newpin: str | None) -> None:
def confirm_firmware_update(description: str, fingerprint: str) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.confirm_firmware_update(
description=description, fingerprint=fingerprint
),
@@ -1832,7 +1832,7 @@ def confirm_firmware_update(description: str, fingerprint: str) -> Awaitable[Non
def set_brightness(current: int | None = None) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.set_brightness(current=current),
"set_brightness",
BR_CODE_OTHER,
@@ -1841,7 +1841,7 @@ def set_brightness(current: int | None = None) -> Awaitable[None]:
def tutorial(br_code: ButtonRequestType = BR_CODE_OTHER) -> Awaitable[None]:
"""Showing users how to interact with the device."""
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.tutorial(),
"tutorial",
br_code,
diff --git a/core/src/trezor/ui/layouts/eckhart/recovery.py b/core/src/trezor/ui/layouts/eckhart/recovery.py
index f76c956f..151a7b63 100644
--- a/core/src/trezor/ui/layouts/eckhart/recovery.py
+++ b/core/src/trezor/ui/layouts/eckhart/recovery.py
@@ -7,7 +7,7 @@ from trezor.enums import ButtonRequestType, RecoveryType
from apps.common import backup_types
from ..common import interact
-from . import raise_if_cancelled
+from . import raise_if_not_confirmed
CONFIRMED = trezorui_api.CONFIRMED # global_import_cache
CANCELLED = trezorui_api.CANCELLED # global_import_cache
@@ -90,7 +90,7 @@ def format_remaining_shares_info(
async def show_group_share_success(share_index: int, group_index: int) -> None:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.show_group_share_success(
lines=[
f"{TR.recovery__share_from_group_entered_template.format(share_index + 1, group_index + 1)}",
@@ -176,7 +176,7 @@ async def show_recovery_warning(
button: str | None = None,
br_code: ButtonRequestType = ButtonRequestType.Warning,
) -> None:
- await raise_if_cancelled(
+ await raise_if_not_confirmed(
trezorui_api.show_warning(
title=subheader or TR.words__important,
value=content or "",
diff --git a/core/src/trezor/ui/layouts/eckhart/reset.py b/core/src/trezor/ui/layouts/eckhart/reset.py
index 2a5909e1..050bdb69 100644
--- a/core/src/trezor/ui/layouts/eckhart/reset.py
+++ b/core/src/trezor/ui/layouts/eckhart/reset.py
@@ -6,7 +6,7 @@ from trezor.enums import ButtonRequestType
from trezor.wire import ActionCancelled
from ..common import interact
-from . import raise_if_cancelled, show_success
+from . import raise_if_not_confirmed, show_success
CONFIRMED = trezorui_api.CONFIRMED # global_import_cache
@@ -58,7 +58,7 @@ def show_share_words(
text_confirm = TR.reset__words_written_down_template.format(words_count)
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_share_words_extended(
words=share_words,
subtitle=subtitle,
@@ -354,7 +354,7 @@ def show_reset_warning(
button: str | None = None,
br_code: ButtonRequestType = ButtonRequestType.Warning,
) -> Awaitable[None]:
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
trezorui_api.show_warning(
title=subheader or "",
description="",
diff --git a/core/src/trezor/wire/thp/ui.py b/core/src/trezor/wire/thp/ui.py
index 9e70f06c..7e793aeb 100644
--- a/core/src/trezor/wire/thp/ui.py
+++ b/core/src/trezor/wire/thp/ui.py
@@ -14,7 +14,7 @@ def confirm_pairing(
short_text: str,
long_text: str,
) -> Awaitable[None]:
- from trezor.ui.layouts.common import raise_if_cancelled
+ from trezor.ui.layouts.common import raise_if_not_confirmed
from trezorui_api import confirm_thp_pairing
if app_name and host_name:
@@ -24,7 +24,7 @@ def confirm_pairing(
args = (app_name or host_name or "(unknown)",)
description = short_text
- return raise_if_cancelled(
+ return raise_if_not_confirmed(
confirm_thp_pairing(title=title, description=description, args=args),
br_name=br_name,
)
Why this scored 45/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.