From 0615b1bbc2a75deda0a019ea9f1401b160b91135 Mon Sep 17 00:00:00 2001 From: obrusvit Date: Sun, 21 Apr 2024 22:43:12 +0200 Subject: [PATCH] feat(core/ui): T3T1 confirm backup flow --- core/embed/rust/librust_qstr.h | 6 ++ .../generated/translated_string.rs | 3 + .../rust/src/ui/model_mercury/flow/mod.rs | 2 + .../embed/rust/src/ui/model_mercury/layout.rs | 68 ++++++++++++------- .../rust/src/ui/model_mercury/theme/mod.rs | 35 ++++++++++ core/mocks/generated/trezorui2.pyi | 10 +++ core/mocks/trezortranslate_keys.pyi | 1 + .../src/trezor/ui/layouts/mercury/__init__.py | 32 +++------ core/src/trezor/ui/layouts/mercury/reset.py | 34 ++++++++-- core/translations/en.json | 1 + core/translations/order.json | 3 +- core/translations/signatures.json | 6 +- 12 files changed, 142 insertions(+), 59 deletions(-) diff --git a/core/embed/rust/librust_qstr.h b/core/embed/rust/librust_qstr.h index e4b40810d..47e9d42ac 100644 --- a/core/embed/rust/librust_qstr.h +++ b/core/embed/rust/librust_qstr.h @@ -150,6 +150,7 @@ static void _librust_qstrs(void) { MP_QSTR_confirm_action; MP_QSTR_confirm_address; MP_QSTR_confirm_backup; + MP_QSTR_confirm_backup_written_down; MP_QSTR_confirm_blob; MP_QSTR_confirm_coinjoin; MP_QSTR_confirm_emphasized; @@ -173,6 +174,7 @@ static void _librust_qstrs(void) { MP_QSTR_confirm_value; MP_QSTR_confirm_with_info; MP_QSTR_count; + MP_QSTR_create_backup_flow; MP_QSTR_data; MP_QSTR_data_hash; MP_QSTR_data_len; @@ -232,6 +234,9 @@ static void _librust_qstrs(void) { MP_QSTR_inputs__return; MP_QSTR_inputs__show; MP_QSTR_inputs__space; + MP_QSTR_instructions__hold_to_confirm; + MP_QSTR_instructions__swipe_up; + MP_QSTR_instructions__tap_to_confirm; MP_QSTR_is_type_of; MP_QSTR_items; MP_QSTR_joint__title; @@ -620,6 +625,7 @@ static void _librust_qstrs(void) { MP_QSTR_words__error; MP_QSTR_words__fee; MP_QSTR_words__from; + MP_QSTR_words__important; MP_QSTR_words__keep_it_safe; MP_QSTR_words__know_what_your_doing; MP_QSTR_words__my_trezor; diff --git a/core/embed/rust/src/translations/generated/translated_string.rs b/core/embed/rust/src/translations/generated/translated_string.rs index 7e774c70f..44acb3d31 100644 --- a/core/embed/rust/src/translations/generated/translated_string.rs +++ b/core/embed/rust/src/translations/generated/translated_string.rs @@ -1254,6 +1254,7 @@ pub enum TranslatedString { instructions__swipe_up = 853, // "Swipe up" instructions__tap_to_confirm = 854, // "Tap to confirm" instructions__hold_to_confirm = 855, // "Hold to confirm" + words__important = 856, // "Important" } impl TranslatedString { @@ -2503,6 +2504,7 @@ impl TranslatedString { Self::instructions__swipe_up => "Swipe up", Self::instructions__tap_to_confirm => "Tap to confirm", Self::instructions__hold_to_confirm => "Hold to confirm", + Self::words__important => "Important", } } @@ -3753,6 +3755,7 @@ impl TranslatedString { Qstr::MP_QSTR_instructions__swipe_up => Some(Self::instructions__swipe_up), Qstr::MP_QSTR_instructions__tap_to_confirm => Some(Self::instructions__tap_to_confirm), Qstr::MP_QSTR_instructions__hold_to_confirm => Some(Self::instructions__hold_to_confirm), + Qstr::MP_QSTR_words__important => Some(Self::words__important), _ => None, } } diff --git a/core/embed/rust/src/ui/model_mercury/flow/mod.rs b/core/embed/rust/src/ui/model_mercury/flow/mod.rs index 6cd147fa8..1bffe2ea1 100644 --- a/core/embed/rust/src/ui/model_mercury/flow/mod.rs +++ b/core/embed/rust/src/ui/model_mercury/flow/mod.rs @@ -1,5 +1,7 @@ pub mod get_address; pub mod confirm_reset_device; +pub mod create_backup; pub use get_address::GetAddress; pub use confirm_reset_device::ConfirmResetDevice; +pub use create_backup::CreateBackup; diff --git a/core/embed/rust/src/ui/model_mercury/layout.rs b/core/embed/rust/src/ui/model_mercury/layout.rs index 76b30e6bf..2378150b1 100644 --- a/core/embed/rust/src/ui/model_mercury/layout.rs +++ b/core/embed/rust/src/ui/model_mercury/layout.rs @@ -1018,42 +1018,50 @@ extern "C" fn new_confirm_fido(n_args: usize, args: *const Obj, kwargs: *mut Map extern "C" fn new_show_warning(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { let block = move |_args: &[Obj], kwargs: &Map| { - let icon = BlendedImage::new( - theme::IMAGE_BG_OCTAGON, - theme::IMAGE_FG_WARN, - theme::WARN_COLOR, - theme::FG, - theme::BG, - ); - new_show_modal(kwargs, icon, theme::button_reset()) + let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; + let value: TString = kwargs.get_or(Qstr::MP_QSTR_value, "".into())?; + + let content = SwipeUpScreen::new(Paragraphs::new([Paragraph::new( + &theme::TEXT_MAIN_GREY_LIGHT, + value, + )])); + let obj = LayoutObj::new( + Frame::left_aligned(title, content) + .with_warning_button() + .button_styled(theme::button_warning_low()) + .with_footer(TR::instructions__swipe_up.into(), None), + )?; + Ok(obj.into()) }; unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } extern "C" fn new_show_success(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { let block = move |_args: &[Obj], kwargs: &Map| { - let icon = BlendedImage::new( - theme::IMAGE_BG_CIRCLE, - theme::IMAGE_FG_SUCCESS, - theme::SUCCESS_COLOR, - theme::FG, - theme::BG, - ); - new_show_modal(kwargs, icon, theme::button_confirm()) + let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; + let content = StatusScreen::new_success(); + let obj = LayoutObj::new( + Frame::left_aligned(title, content) + .with_footer(TR::instructions__swipe_up.into(), None), + )?; + Ok(obj.into()) }; unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } extern "C" fn new_show_info(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { let block = move |_args: &[Obj], kwargs: &Map| { - let icon = BlendedImage::new( - theme::IMAGE_BG_CIRCLE, - theme::IMAGE_FG_INFO, - theme::INFO_COLOR, - theme::FG, - theme::BG, - ); - new_show_modal(kwargs, icon, theme::button_info()) + let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; + let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?; + let content = SwipeUpScreen::new(Paragraphs::new([Paragraph::new( + &theme::TEXT_MAIN_GREY_LIGHT, + description, + )])); + let obj = LayoutObj::new( + Frame::left_aligned(title, content) + .with_footer(TR::instructions__swipe_up.into(), None), + )?; + Ok(obj.into()) }; unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } @@ -1330,7 +1338,7 @@ extern "C" fn new_confirm_backup_written_down( args: *const Obj, kwargs: *mut Map, ) -> Obj { - let block = move |_args: &[Obj], _kwargs: &Map| { + let block = move |_args: &[Obj], kwargs: &Map| { let content = PromptScreen::new_hold_to_confirm(); let frame_with_hold_to_confirm = Frame::left_aligned("I wrote down all words in order.".into(), content) @@ -2044,6 +2052,11 @@ pub static mp_module_trezorui2: Module = obj_module! { /// information, 3) Cancel transaction""" Qstr::MP_QSTR_show_tx_context_menu => obj_fn_kw!(0, new_show_tx_context_menu).as_obj(), + // TODO: This is just POC + /// def create_backup_flow() -> LayoutObj[UiResult] + /// """Start create backup or skip flow.""" + Qstr::MP_QSTR_create_backup_flow => obj_fn_kw!(0, flow::create_backup::new_create_backup).as_obj(), + /// def show_share_words( /// *, /// title: str, @@ -2052,6 +2065,11 @@ pub static mp_module_trezorui2: Module = obj_module! { /// """Show mnemonic for backup.""" Qstr::MP_QSTR_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(), + // TODO: This is just POC + /// def confirm_backup_written_down() -> LayoutObj[UiResult] + /// """Confirm with the user that backup words are written down.""" + Qstr::MP_QSTR_confirm_backup_written_down => obj_fn_kw!(0, new_confirm_backup_written_down).as_obj(), + /// def request_number( /// *, /// title: str, diff --git a/core/embed/rust/src/ui/model_mercury/theme/mod.rs b/core/embed/rust/src/ui/model_mercury/theme/mod.rs index a1325449c..10e1700b4 100644 --- a/core/embed/rust/src/ui/model_mercury/theme/mod.rs +++ b/core/embed/rust/src/ui/model_mercury/theme/mod.rs @@ -292,6 +292,41 @@ pub const fn button_warning_high() -> ButtonStyleSheet { } } +pub const fn button_warning_low() -> ButtonStyleSheet { + ButtonStyleSheet { + normal: &ButtonStyle { + font: Font::DEMIBOLD, + text_color: GREY_LIGHT, + button_color: BG, + icon_color: GREEN_LIME, + background_color: BG, + border_color: BG, + border_radius: RADIUS, + border_width: 0, + }, + active: &ButtonStyle { + font: Font::DEMIBOLD, + text_color: GREY_LIGHT, + button_color: BG, + icon_color: GREEN_LIME, + background_color: BG, + border_color: FG, + border_radius: RADIUS, + border_width: 0, + }, + disabled: &ButtonStyle { + font: Font::DEMIBOLD, + text_color: GREY_LIGHT, + button_color: BG, + icon_color: GREEN_LIME, + background_color: BG, + border_color: BG, + border_radius: RADIUS, + border_width: 0, + }, + } +} + // TODO: delete pub const fn button_confirm() -> ButtonStyleSheet { ButtonStyleSheet { diff --git a/core/mocks/generated/trezorui2.pyi b/core/mocks/generated/trezorui2.pyi index f4fb27f2d..9f5a2de49 100644 --- a/core/mocks/generated/trezorui2.pyi +++ b/core/mocks/generated/trezorui2.pyi @@ -395,6 +395,11 @@ def show_tx_context_menu() -> LayoutObj[int]: information, 3) Cancel transaction""" +# rust/src/ui/model_mercury/layout.rs +def create_backup_flow() -> LayoutObj[UiResult] +"""Start create backup or skip flow.""" + + # rust/src/ui/model_mercury/layout.rs def show_share_words( *, @@ -404,6 +409,11 @@ def show_share_words( """Show mnemonic for backup.""" +# rust/src/ui/model_mercury/layout.rs +def confirm_backup_written_down() -> LayoutObj[UiResult] +"""Confirm with the user that backup words are written down.""" + + # rust/src/ui/model_mercury/layout.rs def request_number( *, diff --git a/core/mocks/trezortranslate_keys.pyi b/core/mocks/trezortranslate_keys.pyi index f43c313da..ee0fc0c0c 100644 --- a/core/mocks/trezortranslate_keys.pyi +++ b/core/mocks/trezortranslate_keys.pyi @@ -833,6 +833,7 @@ class TR: words__error: str = "Error" words__fee: str = "Fee" words__from: str = "from" + words__important: str = "Important" words__keep_it_safe: str = "Keep it safe!" words__know_what_your_doing: str = "Continue only if you know what you are doing!" words__my_trezor: str = "My Trezor" diff --git a/core/src/trezor/ui/layouts/mercury/__init__.py b/core/src/trezor/ui/layouts/mercury/__init__.py index f946047b4..af012cfef 100644 --- a/core/src/trezor/ui/layouts/mercury/__init__.py +++ b/core/src/trezor/ui/layouts/mercury/__init__.py @@ -340,37 +340,21 @@ async def confirm_reset_device(title: str, recovery: bool = False) -> None: ) -# TODO cleanup @ redesign async def prompt_backup() -> bool: - result = await interact( - RustLayout( - trezorui2.confirm_action( - title=TR.words__title_success, - action=TR.backup__new_wallet_successfully_created, - description=TR.backup__it_should_be_backed_up, - verb=TR.buttons__back_up, - verb_cancel=TR.buttons__skip, - ) - ), + # result = await interact(RustLayout(trezorui2.)) + await interact( + RustLayout(trezorui2.show_success(title=TR.backup__new_wallet_created)), "backup_device", ButtonRequestType.ResetDevice, ) - if result is CONFIRMED: - return True result = await interact( - RustLayout( - trezorui2.confirm_action( - title=TR.words__warning.upper(), - action=TR.backup__want_to_skip, - description=TR.backup__can_back_up_anytime, - verb=TR.buttons__back_up, - verb_cancel=TR.buttons__skip, - ) - ), + # TODO: this is just POC + RustLayout(trezorui2.create_backup_flow()), "backup_device", ButtonRequestType.ResetDevice, ) + return result is CONFIRMED @@ -586,8 +570,8 @@ async def show_success( interact( RustLayout( trezorui2.show_success( - title=content, - description=subheader or "", + title=subheader or "", + description="", button=button.upper(), allow_cancel=False, ) diff --git a/core/src/trezor/ui/layouts/mercury/reset.py b/core/src/trezor/ui/layouts/mercury/reset.py index c0d9dd46e..337ab74d4 100644 --- a/core/src/trezor/ui/layouts/mercury/reset.py +++ b/core/src/trezor/ui/layouts/mercury/reset.py @@ -32,9 +32,16 @@ async def show_share_words( group_index + 1, share_index + 1 ) + await RustLayout( + trezorui2.show_share_words( + title=title, + pages=share_words, + ), + ) + result = await interact( RustLayout( - trezorui2.show_share_words( + trezorui2.confirm_backup_written_down( title=title, pages=share_words, ), @@ -42,6 +49,13 @@ async def show_share_words( "backup_words", ButtonRequestType.ResetDevice, ) + + result = await RustLayout( + trezorui2.show_info( + title="Check wallet backup", + description="Let's do a quick check of your backup.", + ) + ) if result != CONFIRMED: raise ActionCancelled @@ -296,15 +310,22 @@ async def slip39_advanced_prompt_group_threshold(num_of_groups: int) -> int: async def show_warning_backup(slip39: bool) -> None: result = await interact( RustLayout( - trezorui2.show_info( - title=TR.reset__never_make_digital_copy, - button=TR.buttons__ok_i_understand, + trezorui2.show_warning( + title=TR.words__important, + value=TR.reset__never_make_digital_copy, + button="", allow_cancel=False, ) ), "backup_warning", ButtonRequestType.ResetDevice, ) + result = await RustLayout( + trezorui2.show_info( + title="Wallet backup", + description="Write the following words in order on your wallet backup card.", + ) + ) if result != CONFIRMED: raise ActionCancelled @@ -332,8 +353,9 @@ async def show_reset_warning( RustLayout( trezorui2.show_warning( title=subheader or "", - description=content, - button=button.upper(), + description="", + value=content, + button="", allow_cancel=False, ) ), diff --git a/core/translations/en.json b/core/translations/en.json index bcd31e85e..720415ac1 100644 --- a/core/translations/en.json +++ b/core/translations/en.json @@ -835,6 +835,7 @@ "words__error": "Error", "words__fee": "Fee", "words__from": "from", + "words__important": "Important", "words__keep_it_safe": "Keep it safe!", "words__know_what_your_doing": "Continue only if you know what you are doing!", "words__my_trezor": "My Trezor", diff --git a/core/translations/order.json b/core/translations/order.json index 444bcec4f..49b154e5f 100644 --- a/core/translations/order.json +++ b/core/translations/order.json @@ -854,5 +854,6 @@ "852": "cardano__vote_delegation", "853": "instructions__swipe_up", "854": "instructions__tap_to_confirm", - "855": "instructions__hold_to_confirm" + "855": "instructions__hold_to_confirm", + "856": "words__important" } diff --git a/core/translations/signatures.json b/core/translations/signatures.json index 566126774..394ade0b7 100644 --- a/core/translations/signatures.json +++ b/core/translations/signatures.json @@ -1,8 +1,8 @@ { "current": { - "merkle_root": "ba39f116679b466d0b1192964d3037d54f5e2486c1ba6e2fc6de522f984f6f0c", - "datetime": "2024-05-17T10:09:38.714090", - "commit": "e797e871c50530f1c1058e588e3ec0ead9f5b13f" + "merkle_root": "04a116dbd20d79235dd81e26fa428eb7c5f4971e76f08a47cde1ec98c959e586", + "datetime": "2024-05-17T10:12:24.161735", + "commit": "aea8bdbe8f9cc2fe629e624a06f4f1b1af6e0a8f" }, "history": [ {