From bbee98216a5bf0ad744b86904b78408c33db3ae1 Mon Sep 17 00:00:00 2001 From: Lukas Bielesch Date: Mon, 17 Mar 2025 09:07:56 +0100 Subject: [PATCH] chore(eckhart): make recovery notifications layout-specific --- .../management/recovery_device/homescreen.py | 3 +- .../apps/management/recovery_device/layout.py | 56 ++---------- core/src/trezor/ui/layouts/bolt/recovery.py | 60 +++++++++++++ core/src/trezor/ui/layouts/caesar/recovery.py | 60 +++++++++++++ .../src/trezor/ui/layouts/delizia/recovery.py | 60 +++++++++++++ .../src/trezor/ui/layouts/eckhart/__init__.py | 2 +- .../src/trezor/ui/layouts/eckhart/recovery.py | 85 +++++++++++++++++-- 7 files changed, 270 insertions(+), 56 deletions(-) diff --git a/core/src/apps/management/recovery_device/homescreen.py b/core/src/apps/management/recovery_device/homescreen.py index ed25e62533..8bb6ed163e 100644 --- a/core/src/apps/management/recovery_device/homescreen.py +++ b/core/src/apps/management/recovery_device/homescreen.py @@ -5,6 +5,7 @@ import storage.recovery as storage_recovery import storage.recovery_shares as storage_recovery_shares from trezor import TR, wire from trezor.messages import Success +from trezor.ui.layouts.recovery import show_invalid_mnemonic from apps.common import backup_types from apps.management.recovery_device.recover import RecoveryAborted @@ -126,7 +127,7 @@ async def _continue_recovery_process() -> Success: # that the first step is complete. is_first_step = False except MnemonicError: - await layout.show_invalid_mnemonic(word_count) + await show_invalid_mnemonic(word_count) assert backup_type is not None if recovery_type == RecoveryType.DryRun: diff --git a/core/src/apps/management/recovery_device/layout.py b/core/src/apps/management/recovery_device/layout.py index c86246e8e3..9afd71c964 100644 --- a/core/src/apps/management/recovery_device/layout.py +++ b/core/src/apps/management/recovery_device/layout.py @@ -3,7 +3,11 @@ from typing import TYPE_CHECKING from trezor import TR from trezor.ui.layouts.recovery import ( # noqa: F401 request_word_count, + show_already_added, + show_dry_run_result, show_group_share_success, + show_group_thresholod, + show_identifier_mismatch, show_recovery_warning, ) @@ -66,66 +70,20 @@ async def request_mnemonic( word_validity.check(backup_type, non_empty_words) except word_validity.AlreadyAdded: # show_share_already_added - await show_recovery_warning( - "warning_known_share", - TR.recovery__share_already_entered, - TR.recovery__enter_different_share, - ) + await show_already_added() return None except word_validity.IdentifierMismatch: # show_identifier_mismatch - await show_recovery_warning( - "warning_mismatched_share", - "", - TR.recovery__share_from_another_multi_share_backup, - ) + await show_identifier_mismatch() return None except word_validity.ThresholdReached: # show_group_threshold_reached - await show_recovery_warning( - "warning_group_threshold", - TR.recovery__group_threshold_reached, - TR.recovery__enter_share_from_diff_group, - ) + await show_group_thresholod() return None return " ".join(words) -async def show_dry_run_result(result: bool, is_slip39: bool) -> None: - from trezor.ui.layouts import show_success - - if result: - if is_slip39: - text = TR.recovery__dry_run_slip39_valid_match - else: - text = TR.recovery__dry_run_bip39_valid_match - await show_success("success_dry_recovery", text, button=TR.buttons__continue) - else: - if is_slip39: - text = TR.recovery__dry_run_slip39_valid_mismatch - else: - text = TR.recovery__dry_run_bip39_valid_mismatch - await show_recovery_warning( - "warning_dry_recovery", "", text, button=TR.buttons__continue - ) - - -async def show_invalid_mnemonic(word_count: int) -> None: - if backup_types.is_slip39_word_count(word_count): - await show_recovery_warning( - "warning_invalid_share", - TR.words__please_try_again, - TR.recovery__invalid_share_entered, - ) - else: - await show_recovery_warning( - "warning_invalid_seed", - TR.words__please_try_again, - TR.recovery__invalid_wallet_backup_entered, - ) - - def enter_share( word_count: int | None = None, entered_remaining: tuple[int, int] | None = None, diff --git a/core/src/trezor/ui/layouts/bolt/recovery.py b/core/src/trezor/ui/layouts/bolt/recovery.py index 1258feb331..a2a2fdfeb2 100644 --- a/core/src/trezor/ui/layouts/bolt/recovery.py +++ b/core/src/trezor/ui/layouts/bolt/recovery.py @@ -4,6 +4,8 @@ import trezorui_api from trezor import TR, ui from trezor.enums import ButtonRequestType +from apps.common import backup_types + from ..common import interact if TYPE_CHECKING: @@ -188,6 +190,45 @@ async def continue_recovery( return False +async def show_invalid_mnemonic(word_count: int) -> None: + if backup_types.is_slip39_word_count(word_count): + await show_recovery_warning( + "warning_invalid_share", + TR.words__please_try_again, + TR.recovery__invalid_share_entered, + ) + else: + await show_recovery_warning( + "warning_invalid_seed", + TR.words__please_try_again, + TR.recovery__invalid_wallet_backup_entered, + ) + + +async def show_identifier_mismatch() -> None: + await show_recovery_warning( + "warning_mismatched_share", + "", + TR.recovery__share_from_another_multi_share_backup, + ) + + +async def show_already_added() -> None: + await show_recovery_warning( + "warning_known_share", + TR.recovery__share_already_entered, + TR.recovery__enter_different_share, + ) + + +async def show_group_thresholod() -> None: + await show_recovery_warning( + "warning_group_threshold", + TR.recovery__group_threshold_reached, + TR.recovery__enter_share_from_diff_group, + ) + + def show_recovery_warning( br_name: str, content: str, @@ -207,3 +248,22 @@ def show_recovery_warning( br_name, br_code, ) + + +async def show_dry_run_result(result: bool, is_slip39: bool) -> None: + from trezor.ui.layouts import show_success + + if result: + if is_slip39: + text = TR.recovery__dry_run_slip39_valid_match + else: + text = TR.recovery__dry_run_bip39_valid_match + await show_success("success_dry_recovery", text, button=TR.buttons__continue) + else: + if is_slip39: + text = TR.recovery__dry_run_slip39_valid_mismatch + else: + text = TR.recovery__dry_run_bip39_valid_mismatch + await show_recovery_warning( + "warning_dry_recovery", "", text, button=TR.buttons__continue + ) diff --git a/core/src/trezor/ui/layouts/caesar/recovery.py b/core/src/trezor/ui/layouts/caesar/recovery.py index a1c8c8e3a5..e2431786b1 100644 --- a/core/src/trezor/ui/layouts/caesar/recovery.py +++ b/core/src/trezor/ui/layouts/caesar/recovery.py @@ -4,6 +4,8 @@ import trezorui_api from trezor import TR, ui from trezor.enums import ButtonRequestType, RecoveryType +from apps.common import backup_types + from ..common import interact from . import show_warning @@ -149,6 +151,45 @@ async def continue_recovery( return False +async def show_invalid_mnemonic(word_count: int) -> None: + if backup_types.is_slip39_word_count(word_count): + await show_recovery_warning( + "warning_invalid_share", + TR.words__please_try_again, + TR.recovery__invalid_share_entered, + ) + else: + await show_recovery_warning( + "warning_invalid_seed", + TR.words__please_try_again, + TR.recovery__invalid_wallet_backup_entered, + ) + + +async def show_identifier_mismatch() -> None: + await show_recovery_warning( + "warning_mismatched_share", + "", + TR.recovery__share_from_another_multi_share_backup, + ) + + +async def show_already_added() -> None: + await show_recovery_warning( + "warning_known_share", + TR.recovery__share_already_entered, + TR.recovery__enter_different_share, + ) + + +async def show_group_thresholod() -> None: + await show_recovery_warning( + "warning_group_threshold", + TR.recovery__group_threshold_reached, + TR.recovery__enter_share_from_diff_group, + ) + + def show_recovery_warning( br_name: str, content: str, @@ -158,3 +199,22 @@ def show_recovery_warning( ) -> Awaitable[ui.UiResult]: button = button or TR.buttons__try_again # def_arg return show_warning(br_name, content, subheader, button, br_code=br_code) + + +async def show_dry_run_result(result: bool, is_slip39: bool) -> None: + from trezor.ui.layouts import show_success + + if result: + if is_slip39: + text = TR.recovery__dry_run_slip39_valid_match + else: + text = TR.recovery__dry_run_bip39_valid_match + await show_success("success_dry_recovery", text, button=TR.buttons__continue) + else: + if is_slip39: + text = TR.recovery__dry_run_slip39_valid_mismatch + else: + text = TR.recovery__dry_run_bip39_valid_mismatch + await show_recovery_warning( + "warning_dry_recovery", "", text, button=TR.buttons__continue + ) diff --git a/core/src/trezor/ui/layouts/delizia/recovery.py b/core/src/trezor/ui/layouts/delizia/recovery.py index 82019bff4d..ec3ef43cb3 100644 --- a/core/src/trezor/ui/layouts/delizia/recovery.py +++ b/core/src/trezor/ui/layouts/delizia/recovery.py @@ -4,6 +4,8 @@ import trezorui_api from trezor import TR from trezor.enums import ButtonRequestType, RecoveryType +from apps.common import backup_types + from ..common import interact from . import raise_if_not_confirmed @@ -130,6 +132,45 @@ async def continue_recovery( return result is CONFIRMED +async def show_invalid_mnemonic(word_count: int) -> None: + if backup_types.is_slip39_word_count(word_count): + await show_recovery_warning( + "warning_invalid_share", + TR.words__please_try_again, + TR.recovery__invalid_share_entered, + ) + else: + await show_recovery_warning( + "warning_invalid_seed", + TR.words__please_try_again, + TR.recovery__invalid_wallet_backup_entered, + ) + + +async def show_identifier_mismatch() -> None: + await show_recovery_warning( + "warning_mismatched_share", + "", + TR.recovery__share_from_another_multi_share_backup, + ) + + +async def show_already_added() -> None: + await show_recovery_warning( + "warning_known_share", + TR.recovery__share_already_entered, + TR.recovery__enter_different_share, + ) + + +async def show_group_thresholod() -> None: + await show_recovery_warning( + "warning_group_threshold", + TR.recovery__group_threshold_reached, + TR.recovery__enter_share_from_diff_group, + ) + + async def show_recovery_warning( br_name: str, content: str, @@ -149,3 +190,22 @@ async def show_recovery_warning( br_name, br_code, ) + + +async def show_dry_run_result(result: bool, is_slip39: bool) -> None: + from trezor.ui.layouts import show_success + + if result: + if is_slip39: + text = TR.recovery__dry_run_slip39_valid_match + else: + text = TR.recovery__dry_run_bip39_valid_match + await show_success("success_dry_recovery", text, button=TR.buttons__continue) + else: + if is_slip39: + text = TR.recovery__dry_run_slip39_valid_mismatch + else: + text = TR.recovery__dry_run_bip39_valid_mismatch + await show_recovery_warning( + "warning_dry_recovery", "", text, button=TR.buttons__continue + ) diff --git a/core/src/trezor/ui/layouts/eckhart/__init__.py b/core/src/trezor/ui/layouts/eckhart/__init__.py index c3c72045e2..c53b094f36 100644 --- a/core/src/trezor/ui/layouts/eckhart/__init__.py +++ b/core/src/trezor/ui/layouts/eckhart/__init__.py @@ -369,7 +369,7 @@ def show_success( button = button or TR.buttons__continue # def_arg return raise_if_not_confirmed( trezorui_api.show_success( - title=subheader if subheader else "", + title=subheader if subheader else TR.words__title_done, button=button, description=content, allow_cancel=False, diff --git a/core/src/trezor/ui/layouts/eckhart/recovery.py b/core/src/trezor/ui/layouts/eckhart/recovery.py index 9df6a4b6fc..3b3c341cbe 100644 --- a/core/src/trezor/ui/layouts/eckhart/recovery.py +++ b/core/src/trezor/ui/layouts/eckhart/recovery.py @@ -4,6 +4,8 @@ import trezorui_api from trezor import TR from trezor.enums import ButtonRequestType, RecoveryType +from apps.common import backup_types + from ..common import interact from . import raise_if_not_confirmed @@ -11,6 +13,8 @@ CONFIRMED = trezorui_api.CONFIRMED # global_import_cache CANCELLED = trezorui_api.CANCELLED # global_import_cache INFO = trezorui_api.INFO # global_import_cache +SUCCESS_SCREEN_TIMEOUT_MS = 2000 + if TYPE_CHECKING: from apps.management.recovery_device.layout import RemainingSharesInfo @@ -126,22 +130,93 @@ async def continue_recovery( return result is CONFIRMED +async def show_invalid_mnemonic(word_count: int) -> None: + if backup_types.is_slip39_word_count(word_count): + await show_recovery_warning( + "warning_invalid_share", + TR.recovery__invalid_share_entered, + TR.words__important, + TR.words__try_again, + ) + else: + await show_recovery_warning( + "warning_invalid_seed", + TR.recovery__invalid_wallet_backup_entered, + TR.words__important, + TR.buttons__continue, + ) + + +async def show_identifier_mismatch() -> None: + await show_recovery_warning( + "warning_mismatched_share", + TR.recovery__share_from_another_multi_share_backup, + TR.words__important, + TR.buttons__continue, + ) + + +async def show_already_added() -> None: + await show_recovery_warning( + "warning_known_share", + f"{TR.recovery__share_already_entered}. {TR.recovery__enter_different_share}", + TR.words__important, + TR.buttons__continue, + ) + + +async def show_group_thresholod() -> None: + await show_recovery_warning( + "warning_group_threshold", + f"{TR.recovery__group_threshold_reached} {TR.recovery__enter_share_from_diff_group}", + TR.words__important, + TR.buttons__continue, + ) + + async def show_recovery_warning( br_name: str, - content: str, + content: str | None = None, subheader: str | None = None, button: str | None = None, br_code: ButtonRequestType = ButtonRequestType.Warning, ) -> None: - button = button or TR.buttons__try_again # def_arg await raise_if_not_confirmed( trezorui_api.show_warning( - title=content or TR.words__warning, - value=subheader or "", - button=button, + title=subheader or TR.words__important, + value=content or "", + button=button or TR.buttons__continue, description="", danger=True, + allow_cancel=False, ), br_name, br_code, ) + + +async def show_dry_run_result(result: bool, is_slip39: bool) -> None: + from trezor.ui.layouts import show_success + + if result: + if is_slip39: + text = TR.recovery__dry_run_slip39_valid_match + else: + text = TR.recovery__dry_run_bip39_valid_match + await show_success( + "success_dry_recovery", + text, + subheader=TR.words__title_done, + button=TR.buttons__continue, + ) + else: + if is_slip39: + text = TR.recovery__dry_run_slip39_valid_mismatch + else: + text = TR.recovery__dry_run_bip39_valid_mismatch + await show_recovery_warning( + "warning_dry_recovery", + content=text, + subheader="", + button=TR.buttons__continue, + )