From 245065852ba247dfb52987d968600f039b200bcf Mon Sep 17 00:00:00 2001 From: obrusvit Date: Thu, 7 Nov 2024 12:23:13 +0100 Subject: [PATCH] refactor(core): cleanup continue_recovery - `confirm_recovery` of model_t and model_r merged with `flow_continue_recovery` of mercury into a `continue_recovery_homepage` trait function - parameters were renamed to be more descriptive - model_t has also the remaining shares info passed in, but not used --- core/embed/rust/librust_qstr.h | 5 +- core/embed/rust/src/ui/api/firmware_upy.rs | 43 ++++++++++++++ ...overy.rs => continue_recovery_homepage.rs} | 10 ++-- .../rust/src/ui/model_mercury/flow/mod.rs | 4 +- .../embed/rust/src/ui/model_mercury/layout.rs | 43 -------------- .../src/ui/model_mercury/ui_features_fw.rs | 34 ++++++++++- core/embed/rust/src/ui/model_tr/layout.rs | 50 ----------------- .../rust/src/ui/model_tr/ui_features_fw.rs | 39 +++++++++++++ core/embed/rust/src/ui/model_tt/layout.rs | 56 ------------------- .../rust/src/ui/model_tt/ui_features_fw.rs | 43 ++++++++++++++ core/embed/rust/src/ui/ui_features_fw.rs | 9 +++ core/mocks/generated/trezorui2.pyi | 38 ------------- core/mocks/generated/trezorui_api.pyi | 13 +++++ .../src/trezor/ui/layouts/mercury/recovery.py | 11 ++-- core/src/trezor/ui/layouts/tr/recovery.py | 8 +-- core/src/trezor/ui/layouts/tt/recovery.py | 33 +++++++---- 16 files changed, 220 insertions(+), 219 deletions(-) rename core/embed/rust/src/ui/model_mercury/flow/{continue_recovery.rs => continue_recovery_homepage.rs} (98%) diff --git a/core/embed/rust/librust_qstr.h b/core/embed/rust/librust_qstr.h index 9d1185256e..2216ea0867 100644 --- a/core/embed/rust/librust_qstr.h +++ b/core/embed/rust/librust_qstr.h @@ -207,7 +207,6 @@ static void _librust_qstrs(void) { MP_QSTR_confirm_output_address; MP_QSTR_confirm_output_amount; MP_QSTR_confirm_properties; - MP_QSTR_confirm_recovery; MP_QSTR_confirm_reset_device; MP_QSTR_confirm_total; MP_QSTR_confirm_total__fee_rate; @@ -217,6 +216,7 @@ static void _librust_qstrs(void) { MP_QSTR_confirm_total__title_sending_from; MP_QSTR_confirm_value; MP_QSTR_confirm_with_info; + MP_QSTR_continue_recovery_homepage; MP_QSTR_count; MP_QSTR_current; MP_QSTR_danger; @@ -251,11 +251,9 @@ static void _librust_qstrs(void) { MP_QSTR_fingerprint; MP_QSTR_firmware_update__title; MP_QSTR_firmware_update__title_fingerprint; - MP_QSTR_first_screen; MP_QSTR_flow_confirm_output; MP_QSTR_flow_confirm_set_new_pin; MP_QSTR_flow_confirm_summary; - MP_QSTR_flow_continue_recovery; MP_QSTR_flow_get_address; MP_QSTR_flow_prompt_backup; MP_QSTR_flow_show_share_words; @@ -486,6 +484,7 @@ static void _librust_qstrs(void) { MP_QSTR_recovery__x_of_y_entered_template; MP_QSTR_recovery__you_have_entered; MP_QSTR_recovery_type; + MP_QSTR_remaining_shares; MP_QSTR_request_bip39; MP_QSTR_request_complete_repaint; MP_QSTR_request_number; diff --git a/core/embed/rust/src/ui/api/firmware_upy.rs b/core/embed/rust/src/ui/api/firmware_upy.rs index 707b035509..76e57fdd4e 100644 --- a/core/embed/rust/src/ui/api/firmware_upy.rs +++ b/core/embed/rust/src/ui/api/firmware_upy.rs @@ -167,6 +167,37 @@ extern "C" fn new_confirm_reset_device(n_args: usize, args: *const Obj, kwargs: unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } +extern "C" fn new_continue_recovery_homepage( + n_args: usize, + args: *const Obj, + kwargs: *mut Map, +) -> Obj { + let block = move |_args: &[Obj], kwargs: &Map| { + let text: TString = kwargs.get(Qstr::MP_QSTR_text)?.try_into()?; // #shares entered + let subtext: Option = kwargs.get(Qstr::MP_QSTR_subtext)?.try_into_option()?; // #shares remaining + let button: Option = kwargs + .get(Qstr::MP_QSTR_button) + .and_then(Obj::try_into_option) + .unwrap_or(None); + let recovery_type: RecoveryType = kwargs.get(Qstr::MP_QSTR_recovery_type)?.try_into()?; + let show_instructions: bool = kwargs.get_or(Qstr::MP_QSTR_show_instructions, false)?; + let remaining_shares: Option = kwargs + .get(Qstr::MP_QSTR_remaining_shares)? + .try_into_option()?; // info about remaining shares + + let obj = ModelUI::continue_recovery_homepage( + text, + subtext, + button, + recovery_type, + show_instructions, + remaining_shares, + )?; + Ok(obj.into()) + }; + unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } +} + extern "C" fn new_request_bip39(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { let block = move |_args: &[Obj], kwargs: &Map| { let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?; @@ -685,6 +716,18 @@ pub static mp_module_trezorui_api: Module = obj_module! { /// """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(), + /// def continue_recovery_homepage( + /// *, + /// text: str, + /// subtext: str | None, + /// button: str | None, + /// recovery_type: RecoveryType, + /// show_instructions: bool = False, # unused on TT + /// remaining_shares: Iterable[tuple[str, str]] | None = None, + /// ) -> LayoutObj[UiResult]: + /// """Device recovery homescreen.""" + Qstr::MP_QSTR_continue_recovery_homepage => obj_fn_kw!(0, new_continue_recovery_homepage).as_obj(), + /// def request_bip39( /// *, /// prompt: str, diff --git a/core/embed/rust/src/ui/model_mercury/flow/continue_recovery.rs b/core/embed/rust/src/ui/model_mercury/flow/continue_recovery_homepage.rs similarity index 98% rename from core/embed/rust/src/ui/model_mercury/flow/continue_recovery.rs rename to core/embed/rust/src/ui/model_mercury/flow/continue_recovery_homepage.rs index 6f37a24806..8dbdfe73b2 100644 --- a/core/embed/rust/src/ui/model_mercury/flow/continue_recovery.rs +++ b/core/embed/rust/src/ui/model_mercury/flow/continue_recovery_homepage.rs @@ -154,11 +154,11 @@ fn footer_update_fn( footer.update_page_counter(ctx, current_page, total_pages); } -pub fn new_continue_recovery( - first_screen: bool, - recovery_type: RecoveryType, +pub fn new_continue_recovery_homepage( text: TString<'static>, subtext: Option>, + recovery_type: RecoveryType, + show_instructions: bool, // 1st screen of the recovery process pages: Option>, ) -> Result { let (title, cancel_btn, cancel_title, cancel_intro) = match recovery_type { @@ -179,7 +179,7 @@ pub fn new_continue_recovery( let mut pars_main = ParagraphVecShort::new(); let footer_instruction; let footer_description; - if first_screen { + if show_instructions { pars_main.add(Paragraph::new( &theme::TEXT_MAIN_GREY_EXTRA_LIGHT, TR::recovery__enter_each_word, @@ -246,7 +246,7 @@ pub fn new_continue_recovery( _ => None, }); - let res = if first_screen { + let res = if show_instructions { let content_menu = Frame::left_aligned( TString::empty(), VerticalMenu::empty().danger(theme::ICON_CANCEL, cancel_btn.into()), 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 1ba469baf7..31de7f06b0 100644 --- a/core/embed/rust/src/ui/model_mercury/flow/mod.rs +++ b/core/embed/rust/src/ui/model_mercury/flow/mod.rs @@ -8,7 +8,7 @@ pub mod confirm_reset; pub mod confirm_set_new_pin; pub mod confirm_summary; pub mod confirm_with_info; -pub mod continue_recovery; +pub mod continue_recovery_homepage; pub mod get_address; pub mod prompt_backup; pub mod request_number; @@ -32,7 +32,7 @@ pub use confirm_reset::new_confirm_reset; pub use confirm_set_new_pin::SetNewPin; pub use confirm_summary::new_confirm_summary; pub use confirm_with_info::new_confirm_with_info; -pub use continue_recovery::new_continue_recovery; +pub use continue_recovery_homepage::new_continue_recovery_homepage; pub use get_address::GetAddress; pub use prompt_backup::PromptBackup; pub use request_number::RequestNumber; diff --git a/core/embed/rust/src/ui/model_mercury/layout.rs b/core/embed/rust/src/ui/model_mercury/layout.rs index 77d475b4d8..baa837a18c 100644 --- a/core/embed/rust/src/ui/model_mercury/layout.rs +++ b/core/embed/rust/src/ui/model_mercury/layout.rs @@ -752,38 +752,6 @@ extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mu unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } -extern "C" fn new_continue_recovery(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { - let block = move |_args: &[Obj], kwargs: &Map| { - let first_screen: bool = kwargs.get(Qstr::MP_QSTR_first_screen)?.try_into()?; - let recovery_type: RecoveryType = kwargs.get(Qstr::MP_QSTR_recovery_type)?.try_into()?; - let text: TString = kwargs.get(Qstr::MP_QSTR_text)?.try_into()?; // #shares entered - let subtext: Option = kwargs.get(Qstr::MP_QSTR_subtext)?.try_into_option()?; // #shares remaining - let pages: Option = kwargs.get(Qstr::MP_QSTR_pages)?.try_into_option()?; // info about remaining shares - - let pages_vec = if let Some(pages_obj) = pages { - let mut vec = ParagraphVecLong::new(); - for page in IterBuf::new().try_iterate(pages_obj)? { - let [title, description]: [TString; 2] = util::iter_into_array(page)?; - vec.add(Paragraph::new(&theme::TEXT_SUB_GREY, title)) - .add(Paragraph::new(&theme::TEXT_MONO_GREY_LIGHT, description).break_after()); - } - Some(vec) - } else { - None - }; - - let flow = flow::continue_recovery::new_continue_recovery( - first_screen, - recovery_type, - text, - subtext, - pages_vec, - )?; - Ok(LayoutObj::new_root(flow)?.into()) - }; - unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } -} - extern "C" fn new_get_address(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { let block = move |_args: &[Obj], kwargs: &Map| { let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; @@ -1013,17 +981,6 @@ pub static mp_module_trezorui2: Module = obj_module! { /// confirmation.""" Qstr::MP_QSTR_flow_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(), - /// def flow_continue_recovery( - /// *, - /// first_screen: bool, - /// recovery_type: RecoveryType, - /// text: str, - /// subtext: str | None = None, - /// pages: Iterable[tuple[str, str]] | None = None, - /// ) -> LayoutObj[UiResult]: - /// """Device recovery homescreen.""" - Qstr::MP_QSTR_flow_continue_recovery => obj_fn_kw!(0, new_continue_recovery).as_obj(), - /// def flow_get_address( /// *, /// address: str | bytes, diff --git a/core/embed/rust/src/ui/model_mercury/ui_features_fw.rs b/core/embed/rust/src/ui/model_mercury/ui_features_fw.rs index f145610a6d..8cc0f02b12 100644 --- a/core/embed/rust/src/ui/model_mercury/ui_features_fw.rs +++ b/core/embed/rust/src/ui/model_mercury/ui_features_fw.rs @@ -3,7 +3,7 @@ use core::cmp::Ordering; use crate::{ error::{value_error, Error}, io::BinaryData, - micropython::gc::Gc, + micropython::{gc::Gc, util}, strutil::TString, translations::TR, ui::{ @@ -220,6 +220,36 @@ impl UIFeaturesFirmware for ModelMercuryFeatures { super::component::check_homescreen_format(image) } + fn continue_recovery_homepage( + text: TString<'static>, + subtext: Option>, + _button: Option>, + recovery_type: RecoveryType, + show_instructions: bool, + remaining_shares: Option, + ) -> Result, Error> { + let pages_vec = if let Some(pages_obj) = remaining_shares { + let mut vec = ParagraphVecLong::new(); + for page in crate::micropython::iter::IterBuf::new().try_iterate(pages_obj)? { + let [title, description]: [TString; 2] = util::iter_into_array(page)?; + vec.add(Paragraph::new(&theme::TEXT_SUB_GREY, title)) + .add(Paragraph::new(&theme::TEXT_MONO_GREY_LIGHT, description).break_after()); + } + Some(vec) + } else { + None + }; + + let flow = flow::continue_recovery_homepage::new_continue_recovery_homepage( + text, + subtext, + recovery_type, + show_instructions, + pages_vec, + )?; + LayoutObj::new_root(flow) + } + fn request_bip39( prompt: TString<'static>, prefill_word: TString<'static>, @@ -504,7 +534,7 @@ impl UIFeaturesFirmware for ModelMercuryFeatures { ) -> Result { // Mercury: remaining shares is a part of `continue_recovery` flow Err::, Error>(Error::ValueError( - c"show remaining shares not supported", + c"show_remaining_shares not implemented", )) } diff --git a/core/embed/rust/src/ui/model_tr/layout.rs b/core/embed/rust/src/ui/model_tr/layout.rs index 7eda9dd61c..78e28fa70b 100644 --- a/core/embed/rust/src/ui/model_tr/layout.rs +++ b/core/embed/rust/src/ui/model_tr/layout.rs @@ -922,44 +922,6 @@ extern "C" fn new_show_share_words(n_args: usize, args: *const Obj, kwargs: *mut unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } -extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { - let block = move |_args: &[Obj], kwargs: &Map| { - let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?; - let button: TString<'static> = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?; - let recovery_type: RecoveryType = kwargs.get(Qstr::MP_QSTR_recovery_type)?.try_into()?; - let show_instructions: bool = kwargs.get(Qstr::MP_QSTR_show_instructions)?.try_into()?; - - let mut paragraphs = ParagraphVecShort::new(); - paragraphs.add(Paragraph::new(&theme::TEXT_NORMAL, description)); - if show_instructions { - paragraphs - .add(Paragraph::new( - &theme::TEXT_NORMAL, - TR::recovery__enter_each_word, - )) - .add(Paragraph::new( - &theme::TEXT_NORMAL, - TR::recovery__cursor_will_change, - )); - } - - let title = match recovery_type { - RecoveryType::DryRun => TR::recovery__title_dry_run, - RecoveryType::UnlockRepeatedBackup => TR::recovery__title_dry_run, - _ => TR::recovery__title, - }; - - content_in_button_page( - title.into(), - paragraphs.into_paragraphs(), - button, - Some("".into()), - false, - ) - }; - unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } -} - #[no_mangle] pub static mp_module_trezorui2: Module = obj_module! { /// from trezor import utils @@ -1139,16 +1101,4 @@ pub static mp_module_trezorui2: Module = obj_module! { /// ) -> LayoutObj[UiResult]: /// """Shows a backup seed.""" Qstr::MP_QSTR_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(), - - /// def confirm_recovery( - /// *, - /// title: str, # unused on TR - /// description: str, - /// button: str, - /// recovery_type: RecoveryType, - /// info_button: bool, # unused on TR - /// show_instructions: bool, - /// ) -> LayoutObj[UiResult]: - /// """Device recovery homescreen.""" - Qstr::MP_QSTR_confirm_recovery => obj_fn_kw!(0, new_confirm_recovery).as_obj(), }; diff --git a/core/embed/rust/src/ui/model_tr/ui_features_fw.rs b/core/embed/rust/src/ui/model_tr/ui_features_fw.rs index 6a60e9788f..f8dbfd2fd2 100644 --- a/core/embed/rust/src/ui/model_tr/ui_features_fw.rs +++ b/core/embed/rust/src/ui/model_tr/ui_features_fw.rs @@ -232,6 +232,45 @@ impl UIFeaturesFirmware for ModelTRFeatures { super::component::check_homescreen_format(image) } + fn continue_recovery_homepage( + text: TString<'static>, + _subtext: Option>, + button: Option>, + recovery_type: RecoveryType, + show_instructions: bool, + _remaining_shares: Option, + ) -> Result, Error> { + let mut paragraphs = ParagraphVecShort::new(); + let button = button.unwrap_or(TString::empty()); + paragraphs.add(Paragraph::new(&theme::TEXT_NORMAL, text)); + if show_instructions { + paragraphs + .add(Paragraph::new( + &theme::TEXT_NORMAL, + TR::recovery__enter_each_word, + )) + .add(Paragraph::new( + &theme::TEXT_NORMAL, + TR::recovery__cursor_will_change, + )); + } + + let title = match recovery_type { + RecoveryType::DryRun => TR::recovery__title_dry_run, + RecoveryType::UnlockRepeatedBackup => TR::recovery__title_dry_run, + _ => TR::recovery__title, + }; + + let layout = content_in_button_page( + title.into(), + paragraphs.into_paragraphs(), + button, + Some("".into()), + false, + )?; + LayoutObj::new_root(layout) + } + fn request_bip39( prompt: TString<'static>, prefill_word: TString<'static>, diff --git a/core/embed/rust/src/ui/model_tt/layout.rs b/core/embed/rust/src/ui/model_tt/layout.rs index 515dd44940..a8187099b8 100644 --- a/core/embed/rust/src/ui/model_tt/layout.rs +++ b/core/embed/rust/src/ui/model_tt/layout.rs @@ -808,50 +808,6 @@ extern "C" fn new_show_share_words(n_args: usize, args: *const Obj, kwargs: *mut unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } -extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { - let block = move |_args: &[Obj], kwargs: &Map| { - let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; - let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?; - let button: TString = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?; - let recovery_type: RecoveryType = kwargs.get(Qstr::MP_QSTR_recovery_type)?.try_into()?; - let info_button: bool = kwargs.get_or(Qstr::MP_QSTR_info_button, false)?; - - let paragraphs = Paragraphs::new([ - Paragraph::new(&theme::TEXT_DEMIBOLD, title), - Paragraph::new(&theme::TEXT_NORMAL, description), - ]) - .with_spacing(theme::RECOVERY_SPACING); - - let notification = match recovery_type { - RecoveryType::DryRun => TR::recovery__title_dry_run.into(), - RecoveryType::UnlockRepeatedBackup => TR::recovery__title_dry_run.into(), - _ => TR::recovery__title.into(), - }; - - let obj = if info_button { - LayoutObj::new(Frame::left_aligned( - theme::label_title(), - notification, - Dialog::new( - paragraphs, - Button::cancel_info_confirm( - TR::buttons__continue.into(), - TR::buttons__more_info.into(), - ), - ), - ))? - } else { - LayoutObj::new(Frame::left_aligned( - theme::label_title(), - notification, - Dialog::new(paragraphs, Button::cancel_confirm_text(None, Some(button))), - ))? - }; - Ok(obj.into()) - }; - unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } -} - #[no_mangle] pub static mp_module_trezorui2: Module = obj_module! { /// from trezor import utils @@ -1003,18 +959,6 @@ pub static mp_module_trezorui2: Module = obj_module! { /// ) -> LayoutObj[UiResult]: /// """Show mnemonic for backup. Expects the words pre-divided into individual pages.""" Qstr::MP_QSTR_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(), - - /// def confirm_recovery( - /// *, - /// title: str, - /// description: str, - /// button: str, - /// recovery_type: RecoveryType, - /// info_button: bool = False, - /// show_instructions: bool = False, # unused on TT - /// ) -> LayoutObj[UiResult]: - /// """Device recovery homescreen.""" - Qstr::MP_QSTR_confirm_recovery => obj_fn_kw!(0, new_confirm_recovery).as_obj(), }; #[cfg(test)] diff --git a/core/embed/rust/src/ui/model_tt/ui_features_fw.rs b/core/embed/rust/src/ui/model_tt/ui_features_fw.rs index 023b3893e9..b1b47d3a6d 100644 --- a/core/embed/rust/src/ui/model_tt/ui_features_fw.rs +++ b/core/embed/rust/src/ui/model_tt/ui_features_fw.rs @@ -248,6 +248,49 @@ impl UIFeaturesFirmware for ModelTTFeatures { super::component::check_homescreen_format(image, false) } + fn continue_recovery_homepage( + text: TString<'static>, + subtext: Option>, + button: Option>, + recovery_type: RecoveryType, + _show_instructions: bool, + remaining_shares: Option, + ) -> Result, Error> { + let paragraphs = Paragraphs::new([ + Paragraph::new(&theme::TEXT_DEMIBOLD, text), + Paragraph::new(&theme::TEXT_NORMAL, subtext.unwrap_or(TString::empty())), + ]) + .with_spacing(theme::RECOVERY_SPACING); + + let notification = match recovery_type { + RecoveryType::DryRun => TR::recovery__title_dry_run.into(), + RecoveryType::UnlockRepeatedBackup => TR::recovery__title_dry_run.into(), + _ => TR::recovery__title.into(), + }; + + // Model T shows remaining shares info in a separate layout + let show_info_button = remaining_shares.is_some(); + if show_info_button { + LayoutObj::new(Frame::left_aligned( + theme::label_title(), + notification, + Dialog::new( + paragraphs, + Button::cancel_info_confirm( + TR::buttons__continue.into(), + TR::buttons__more_info.into(), + ), + ), + )) + } else { + LayoutObj::new(Frame::left_aligned( + theme::label_title(), + notification, + Dialog::new(paragraphs, Button::cancel_confirm_text(None, button)), + )) + } + } + fn request_bip39( prompt: TString<'static>, prefill_word: TString<'static>, diff --git a/core/embed/rust/src/ui/ui_features_fw.rs b/core/embed/rust/src/ui/ui_features_fw.rs index 5039951ea5..cc62d9bd76 100644 --- a/core/embed/rust/src/ui/ui_features_fw.rs +++ b/core/embed/rust/src/ui/ui_features_fw.rs @@ -56,6 +56,15 @@ pub trait UIFeaturesFirmware { fn confirm_reset_device(recovery: bool) -> Result; + fn continue_recovery_homepage( + text: TString<'static>, + subtext: Option>, + button: Option>, + recovery_type: RecoveryType, + show_instructions: bool, + remaining_shares: Option, // TODO: replace Obj + ) -> Result, Error>; // TODO: return LayoutMaybeTrace + fn check_homescreen_format(image: BinaryData, accept_toif: bool) -> bool; fn request_bip39( diff --git a/core/mocks/generated/trezorui2.pyi b/core/mocks/generated/trezorui2.pyi index 2b2514c35e..720c27b87d 100644 --- a/core/mocks/generated/trezorui2.pyi +++ b/core/mocks/generated/trezorui2.pyi @@ -168,18 +168,6 @@ def flow_show_share_words( confirmation.""" -# rust/src/ui/model_mercury/layout.rs -def flow_continue_recovery( - *, - first_screen: bool, - recovery_type: RecoveryType, - text: str, - subtext: str | None = None, - pages: Iterable[tuple[str, str]] | None = None, -) -> LayoutObj[UiResult]: - """Device recovery homescreen.""" - - # rust/src/ui/model_mercury/layout.rs def flow_get_address( *, @@ -438,19 +426,6 @@ def show_share_words( share_words: Iterable[str], ) -> LayoutObj[UiResult]: """Shows a backup seed.""" - - -# rust/src/ui/model_tr/layout.rs -def confirm_recovery( - *, - title: str, # unused on TR - description: str, - button: str, - recovery_type: RecoveryType, - info_button: bool, # unused on TR - show_instructions: bool, -) -> LayoutObj[UiResult]: - """Device recovery homescreen.""" from trezor import utils from trezorui_api import * @@ -610,16 +585,3 @@ def show_share_words( pages: Iterable[str], ) -> LayoutObj[UiResult]: """Show mnemonic for backup. Expects the words pre-divided into individual pages.""" - - -# rust/src/ui/model_tt/layout.rs -def confirm_recovery( - *, - title: str, - description: str, - button: str, - recovery_type: RecoveryType, - info_button: bool = False, - show_instructions: bool = False, # unused on TT -) -> LayoutObj[UiResult]: - """Device recovery homescreen.""" diff --git a/core/mocks/generated/trezorui_api.pyi b/core/mocks/generated/trezorui_api.pyi index 3d9decf697..98474a578c 100644 --- a/core/mocks/generated/trezorui_api.pyi +++ b/core/mocks/generated/trezorui_api.pyi @@ -150,6 +150,19 @@ def confirm_reset_device(recovery: bool) -> LayoutObj[UiResult]: """Confirm TOS before creating wallet creation or wallet recovery.""" +# rust/src/ui/api/firmware_upy.rs +def continue_recovery_homepage( + *, + text: str, + subtext: str | None, + button: str | None, + recovery_type: RecoveryType, + show_instructions: bool = False, # unused on TT + remaining_shares: Iterable[tuple[str, str]] | None = None, +) -> LayoutObj[UiResult]: + """Device recovery homescreen.""" + + # rust/src/ui/api/firmware_upy.rs def request_bip39( *, diff --git a/core/src/trezor/ui/layouts/mercury/recovery.py b/core/src/trezor/ui/layouts/mercury/recovery.py index 775b6b3c68..21e1f1736b 100644 --- a/core/src/trezor/ui/layouts/mercury/recovery.py +++ b/core/src/trezor/ui/layouts/mercury/recovery.py @@ -100,7 +100,7 @@ async def show_group_share_success(share_index: int, group_index: int) -> None: async def continue_recovery( - button_label: str, # unused on mercury + _button_label: str, # unused on mercury text: str, subtext: str | None, recovery_type: RecoveryType, @@ -108,12 +108,13 @@ async def continue_recovery( remaining_shares_info: "RemainingSharesInfo | None" = None, ) -> bool: result = await interact( - trezorui2.flow_continue_recovery( - first_screen=show_instructions, - recovery_type=recovery_type, + trezorui_api.continue_recovery_homepage( text=text, subtext=subtext, - pages=( + button=None, + recovery_type=recovery_type, + show_instructions=show_instructions, + remaining_shares=( format_remaining_shares_info(remaining_shares_info) if remaining_shares_info else None diff --git a/core/src/trezor/ui/layouts/tr/recovery.py b/core/src/trezor/ui/layouts/tr/recovery.py index 4b200ed1c1..36496b914e 100644 --- a/core/src/trezor/ui/layouts/tr/recovery.py +++ b/core/src/trezor/ui/layouts/tr/recovery.py @@ -123,13 +123,13 @@ async def continue_recovery( if subtext: text += f"\n\n{subtext}" - homepage = trezorui2.confirm_recovery( - title="", - description=text, + homepage = trezorui_api.continue_recovery_homepage( + text=text, + subtext=None, button=button_label, recovery_type=recovery_type, - info_button=False, show_instructions=show_instructions, + remaining_shares=None, ) while True: result = await interact( diff --git a/core/src/trezor/ui/layouts/tt/recovery.py b/core/src/trezor/ui/layouts/tt/recovery.py index 6a9410599d..8f19c1d49d 100644 --- a/core/src/trezor/ui/layouts/tt/recovery.py +++ b/core/src/trezor/ui/layouts/tt/recovery.py @@ -51,14 +51,14 @@ async def request_word( return word -def show_remaining_shares( - groups: set[tuple[str, ...]], - shares_remaining: list[int], - group_threshold: int, -) -> Awaitable[trezorui_api.UiResult]: +def format_remaining_shares_info( + remaining_shares_info: "RemainingSharesInfo", +) -> list[tuple[str, str]]: from trezor import strings from trezor.crypto.slip39 import MAX_SHARE_COUNT + groups, shares_remaining, group_threshold = remaining_shares_info + pages: list[tuple[str, str]] = [] completed_groups = shares_remaining.count(0) @@ -81,6 +81,12 @@ def show_remaining_shares( words = "\n".join(group) pages.append((title, words)) + return pages + + +def show_remaining_shares( + pages: list[tuple[str, str]], +) -> Awaitable[trezorui_api.UiResult]: return interact( trezorui_api.show_remaining_shares(pages=pages), "show_shares", @@ -146,12 +152,17 @@ async def continue_recovery( else: description = subtext or "" - homepage = trezorui2.confirm_recovery( - title=text, - description=description, + remaining_shares = ( + format_remaining_shares_info(remaining_shares_info) + if remaining_shares_info + else None + ) + homepage = trezorui_api.continue_recovery_homepage( + text=text, + subtext=description, button=button_label, recovery_type=recovery_type, - info_button=remaining_shares_info is not None, + remaining_shares=remaining_shares, ) while True: @@ -164,8 +175,8 @@ async def continue_recovery( if result is trezorui_api.CONFIRMED: return True - elif result is trezorui_api.INFO and remaining_shares_info is not None: - await show_remaining_shares(*remaining_shares_info) + elif result is trezorui_api.INFO and remaining_shares is not None: + await show_remaining_shares(remaining_shares) else: try: await _confirm_abort(recovery_type != RecoveryType.NormalRecovery)