diff --git a/core/embed/rust/src/ui/api/firmware_upy.rs b/core/embed/rust/src/ui/api/firmware_upy.rs index ac5b060da5..c3dc4d9eef 100644 --- a/core/embed/rust/src/ui/api/firmware_upy.rs +++ b/core/embed/rust/src/ui/api/firmware_upy.rs @@ -409,6 +409,15 @@ extern "C" fn new_show_progress_coinjoin(n_args: usize, args: *const Obj, kwargs unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } +extern "C" fn new_show_remaining_shares(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { + let block = move |_args: &[Obj], kwargs: &Map| { + let pages_iterable: Obj = kwargs.get(Qstr::MP_QSTR_pages)?; + let layout = ModelUI::show_remaining_shares(pages_iterable)?; + Ok(LayoutObj::new_root(layout)?.into()) + }; + unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } +} + extern "C" fn new_show_wait_text(message: Obj) -> Obj { let block = || { let message: TString<'static> = message.try_into()?; @@ -755,6 +764,13 @@ pub static mp_module_trezorui_api: Module = obj_module! { /// time_ms timeout is passed.""" Qstr::MP_QSTR_show_progress_coinjoin => obj_fn_kw!(0, new_show_progress_coinjoin).as_obj(), + /// def show_remaining_shares( + /// *, + /// pages: Iterable[tuple[str, str]], + /// ) -> LayoutObj[UiResult]: + /// """Shows SLIP39 state after info button is pressed on `confirm_recovery`.""" + Qstr::MP_QSTR_show_remaining_shares => obj_fn_kw!(0, new_show_remaining_shares).as_obj(), + /// def show_wait_text(message: str, /) -> LayoutObj[None]: /// """Show single-line text in the middle of the screen.""" Qstr::MP_QSTR_show_wait_text => obj_fn_1!(new_show_wait_text).as_obj(), 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 1f9651dac3..aee8c571ff 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 @@ -8,13 +8,10 @@ use crate::{ translations::TR, ui::{ component::{ - connect::Connect, - swipe_detect::SwipeSettings, - text::paragraphs::{ + connect::Connect, swipe_detect::SwipeSettings, text::paragraphs::{ Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort, Paragraphs, VecExt, - }, - CachedJpeg, ComponentExt, Never, Timeout, + }, CachedJpeg, ComponentExt, Empty, Never, Timeout }, geometry::{self, Direction}, layout::{ @@ -469,6 +466,15 @@ impl UIFeaturesFirmware for ModelMercuryFeatures { Ok(obj) } + fn show_remaining_shares( + pages_iterable: crate::micropython::obj::Obj, // TODO: replace Obj + ) -> Result { + // Mercury: remaining shares is a part of `continue_recovery` flow + Err::, Error>(Error::ValueError( + c"show remaining shares not supported", + )) + } + fn show_wait_text(text: TString<'static>) -> Result { let layout = RootComponent::new(Connect::new(text, theme::FG, theme::BG)); Ok(layout) 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 02a6409d50..be578d65a4 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 @@ -491,6 +491,14 @@ impl UIFeaturesFirmware for ModelTRFeatures { Ok(obj) } + fn show_remaining_shares( + pages_iterable: crate::micropython::obj::Obj, // TODO: replace Obj + ) -> Result { + Err::, Error>(Error::ValueError( + c"show remaining shares not supported", + )) + } + fn show_wait_text(text: TString<'static>) -> Result { let layout = RootComponent::new(Connect::new(text, theme::FG, theme::BG)); Ok(layout) diff --git a/core/embed/rust/src/ui/model_tt/layout.rs b/core/embed/rust/src/ui/model_tt/layout.rs index 48826bf0a6..421e0251a7 100644 --- a/core/embed/rust/src/ui/model_tt/layout.rs +++ b/core/embed/rust/src/ui/model_tt/layout.rs @@ -1023,31 +1023,6 @@ extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } -extern "C" fn new_show_remaining_shares(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { - let block = move |_args: &[Obj], kwargs: &Map| { - let pages_iterable: Obj = kwargs.get(Qstr::MP_QSTR_pages)?; - - let mut paragraphs = ParagraphVecLong::new(); - for page in IterBuf::new().try_iterate(pages_iterable)? { - let [title, description]: [TString; 2] = util::iter_into_array(page)?; - paragraphs - .add(Paragraph::new(&theme::TEXT_DEMIBOLD, title)) - .add(Paragraph::new(&theme::TEXT_NORMAL, description).break_after()); - } - - let obj = LayoutObj::new(Frame::left_aligned( - theme::label_title(), - TR::recovery__title_remaining_shares.into(), - ButtonPage::new(paragraphs.into_paragraphs(), theme::BG) - .with_cancel_confirm(None, Some(TR::buttons__continue.into())) - .with_confirm_style(theme::button_default()) - .without_cancel(), - ))?; - 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 @@ -1254,13 +1229,6 @@ pub static mp_module_trezorui2: Module = obj_module! { /// ) -> LayoutObj[UiResult]: /// """Device recovery homescreen.""" Qstr::MP_QSTR_confirm_recovery => obj_fn_kw!(0, new_confirm_recovery).as_obj(), - - /// def show_remaining_shares( - /// *, - /// pages: Iterable[tuple[str, str]], - /// ) -> LayoutObj[UiResult]: - /// """Shows SLIP39 state after info button is pressed on `confirm_recovery`.""" - Qstr::MP_QSTR_show_remaining_shares => obj_fn_kw!(0, new_show_remaining_shares).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 f52630731c..916919967c 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 @@ -539,6 +539,29 @@ impl UIFeaturesFirmware for ModelTTFeatures { Ok(obj) } + fn show_remaining_shares( + pages_iterable: crate::micropython::obj::Obj, // TODO: replace Obj + ) -> Result { + let mut paragraphs = ParagraphVecLong::new(); + for page in crate::micropython::iter::IterBuf::new().try_iterate(pages_iterable)? { + let [title, description]: [TString; 2] = + crate::micropython::util::iter_into_array(page)?; + paragraphs + .add(Paragraph::new(&theme::TEXT_DEMIBOLD, title)) + .add(Paragraph::new(&theme::TEXT_NORMAL, description).break_after()); + } + + let layout = RootComponent::new(Frame::left_aligned( + theme::label_title(), + TR::recovery__title_remaining_shares.into(), + ButtonPage::new(paragraphs.into_paragraphs(), theme::BG) + .with_cancel_confirm(None, Some(TR::buttons__continue.into())) + .with_confirm_style(theme::button_default()) + .without_cancel(), + )); + Ok(layout) + } + fn show_wait_text(text: TString<'static>) -> Result { let layout = RootComponent::new(Connect::new(text, theme::FG, theme::BG)); Ok(layout) diff --git a/core/embed/rust/src/ui/ui_features_fw.rs b/core/embed/rust/src/ui/ui_features_fw.rs index 3764c399cd..895dd9f582 100644 --- a/core/embed/rust/src/ui/ui_features_fw.rs +++ b/core/embed/rust/src/ui/ui_features_fw.rs @@ -1,4 +1,4 @@ -use crate::{error::Error, io::BinaryData, micropython::gc::Gc, strutil::TString}; +use crate::{error::Error, io::BinaryData, micropython::{gc::Gc, obj::Obj}, strutil::TString}; use super::layout::{ obj::{LayoutMaybeTrace, LayoutObj}, @@ -142,6 +142,10 @@ pub trait UIFeaturesFirmware { skip_first_paint: bool, ) -> Result, Error>; // TODO: return LayoutMaybeTrace + fn show_remaining_shares( + pages_iterable: Obj, // TODO: replace Obj + ) -> Result; + fn show_wait_text(text: TString<'static>) -> Result; fn tutorial() -> Result; diff --git a/core/mocks/generated/trezorui2.pyi b/core/mocks/generated/trezorui2.pyi index 63ef0de2eb..720ed3b904 100644 --- a/core/mocks/generated/trezorui2.pyi +++ b/core/mocks/generated/trezorui2.pyi @@ -727,11 +727,3 @@ def confirm_recovery( show_instructions: bool = False, # unused on TT ) -> LayoutObj[UiResult]: """Device recovery homescreen.""" - - -# rust/src/ui/model_tt/layout.rs -def show_remaining_shares( - *, - pages: Iterable[tuple[str, str]], -) -> LayoutObj[UiResult]: - """Shows SLIP39 state after info button is pressed on `confirm_recovery`.""" diff --git a/core/mocks/generated/trezorui_api.pyi b/core/mocks/generated/trezorui_api.pyi index 0602e03514..38af866829 100644 --- a/core/mocks/generated/trezorui_api.pyi +++ b/core/mocks/generated/trezorui_api.pyi @@ -315,6 +315,14 @@ def show_progress_coinjoin( time_ms timeout is passed.""" +# rust/src/ui/api/firmware_upy.rs +def show_remaining_shares( + *, + pages: Iterable[tuple[str, str]], +) -> LayoutObj[UiResult]: + """Shows SLIP39 state after info button is pressed on `confirm_recovery`.""" + + # rust/src/ui/api/firmware_upy.rs def show_wait_text(message: str, /) -> LayoutObj[None]: """Show single-line text in the middle of the screen.""" diff --git a/core/src/trezor/ui/layouts/tt/recovery.py b/core/src/trezor/ui/layouts/tt/recovery.py index 1f769fbf5c..e3b0f0e58e 100644 --- a/core/src/trezor/ui/layouts/tt/recovery.py +++ b/core/src/trezor/ui/layouts/tt/recovery.py @@ -82,7 +82,7 @@ def show_remaining_shares( pages.append((title, words)) return interact( - trezorui2.show_remaining_shares(pages=pages), + trezorui_api.show_remaining_shares(pages=pages), "show_shares", ButtonRequestType.Other, )