diff --git a/core/embed/rust/src/ui/api/firmware_upy.rs b/core/embed/rust/src/ui/api/firmware_upy.rs index dc4e210761..212a9bac86 100644 --- a/core/embed/rust/src/ui/api/firmware_upy.rs +++ b/core/embed/rust/src/ui/api/firmware_upy.rs @@ -85,6 +85,30 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } +extern "C" fn new_confirm_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()?; + let data: Obj = kwargs.get(Qstr::MP_QSTR_data)?; + let description: Option = kwargs + .get(Qstr::MP_QSTR_description) + .unwrap_or_else(|_| Obj::const_none()) + .try_into_option()?; + let extra: Option = kwargs + .get(Qstr::MP_QSTR_extra) + .unwrap_or_else(|_| Obj::const_none()) + .try_into_option()?; + let verb: Option = kwargs + .get(Qstr::MP_QSTR_verb) + .unwrap_or_else(|_| Obj::const_none()) + .try_into_option()?; + let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?; + + let layout = ModelUI::confirm_address(title, data, description, extra, verb, chunkify)?; + Ok(LayoutObj::new_root(layout)?.into()) + }; + unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } +} + extern "C" fn new_confirm_blob(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()?; @@ -910,6 +934,18 @@ pub static mp_module_trezorui_api: Module = obj_module! { /// """Confirm action.""" Qstr::MP_QSTR_confirm_action => obj_fn_kw!(0, new_confirm_action).as_obj(), + /// def confirm_address( + /// *, + /// title: str, + /// data: str | bytes, + /// description: str | None, + /// extra: str | None, + /// verb: str | None = None, + /// chunkify: bool = False, + /// ) -> LayoutObj[UiResult]: + /// """Confirm address.""" + Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(), + /// def confirm_blob( /// *, /// title: str, diff --git a/core/embed/rust/src/ui/model_mercury/layout.rs b/core/embed/rust/src/ui/model_mercury/layout.rs index 00a4d84413..a09210d696 100644 --- a/core/embed/rust/src/ui/model_mercury/layout.rs +++ b/core/embed/rust/src/ui/model_mercury/layout.rs @@ -298,22 +298,6 @@ extern "C" fn new_confirm_blob_intro(n_args: usize, args: *const Obj, kwargs: *m unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } -extern "C" fn new_confirm_firmware_update( - 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 fingerprint: TString = kwargs.get(Qstr::MP_QSTR_fingerprint)?.try_into()?; - - let flow = - flow::confirm_firmware_update::new_confirm_firmware_update(description, fingerprint)?; - Ok(LayoutObj::new_root(flow)?.into()) - }; - unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } -} - extern "C" fn new_confirm_set_new_pin(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()?; 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 04af80ae27..e4951621c6 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 @@ -22,7 +22,7 @@ use crate::{ geometry::{self, Direction}, layout::{ obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, - util::{PropsList, RecoveryType}, + util::{ConfirmBlob, PropsList, RecoveryType, StrOrBytes}, }, ui_features_fw::UIFeaturesFirmware, }, @@ -35,8 +35,8 @@ use super::{ SwipeContent, SwipeUpScreen, VerticalMenu, }, flow::{ - self, confirm_with_info, new_confirm_action_simple, ConfirmActionExtra, - ConfirmActionMenuStrings, ConfirmActionStrings, ConfirmBlobParams, + self, new_confirm_action_simple, ConfirmActionExtra, ConfirmActionMenuStrings, + ConfirmActionStrings, ConfirmBlobParams, }, theme, ModelMercuryFeatures, }; @@ -69,6 +69,20 @@ impl UIFeaturesFirmware for ModelMercuryFeatures { Ok(flow) } + fn confirm_address( + title: TString<'static>, + data: Obj, + description: Option>, + _extra: Option>, + _verb: Option>, + chunkify: bool, + ) -> Result { + // confirm_value is used instead + Err::, Error>(Error::ValueError( + c"confirm_address not implemented", + )) + } + fn confirm_blob( title: TString<'static>, data: Obj, diff --git a/core/embed/rust/src/ui/model_tr/layout.rs b/core/embed/rust/src/ui/model_tr/layout.rs index 5f73a86cd4..a093be6b8a 100644 --- a/core/embed/rust/src/ui/model_tr/layout.rs +++ b/core/embed/rust/src/ui/model_tr/layout.rs @@ -562,37 +562,6 @@ extern "C" fn new_altcoin_tx_summary(n_args: usize, args: *const Obj, kwargs: *m unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } -extern "C" fn new_confirm_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()?; - let address: TString = kwargs.get(Qstr::MP_QSTR_data)?.try_into()?; - let verb: TString<'static> = - kwargs.get_or(Qstr::MP_QSTR_verb, TR::buttons__confirm.into())?; - let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?; - - let get_page = move |page_index| { - assert!(page_index == 0); - - let btn_layout = ButtonLayout::cancel_armed_info(verb); - let btn_actions = ButtonActions::cancel_confirm_info(); - let style = if chunkify { - // Chunkifying the address into smaller pieces when requested - theme::TEXT_MONO_ADDRESS_CHUNKS - } else { - theme::TEXT_MONO_DATA - }; - let ops = OpTextLayout::new(style).text_mono(address); - let formatted = FormattedText::new(ops).vertically_centered(); - Page::new(btn_layout, btn_actions, formatted).with_title(title) - }; - let pages = FlowPages::new(get_page, 1); - - let obj = LayoutObj::new(Flow::new(pages))?; - Ok(obj.into()) - }; - unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } -} - extern "C" fn new_multiple_pages_texts(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()?; @@ -655,18 +624,6 @@ pub static mp_module_trezorui2: Module = obj_module! { /// Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(), - /// def confirm_address( - /// *, - /// title: str, - /// data: str, - /// description: str | None, # unused on TR - /// extra: str | None, # unused on TR - /// verb: str = "CONFIRM", - /// chunkify: bool = False, - /// ) -> LayoutObj[UiResult]: - /// """Confirm address.""" - Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(), - /// def confirm_backup() -> LayoutObj[UiResult]: /// """Strongly recommend user to do backup.""" Qstr::MP_QSTR_confirm_backup => obj_fn_kw!(0, new_confirm_backup).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 43cac66a12..b8dcae3193 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 @@ -83,6 +83,38 @@ impl UIFeaturesFirmware for ModelTRFeatures { ) } + fn confirm_address( + title: TString<'static>, + data: Obj, + description: Option>, + extra: Option>, + verb: Option>, + chunkify: bool, + ) -> Result { + let verb = verb.unwrap_or(TR::buttons__confirm.into()); + let address: TString = data.try_into()?; + + let get_page = move |page_index| { + assert!(page_index == 0); + + let btn_layout = ButtonLayout::cancel_armed_info(verb); + let btn_actions = ButtonActions::cancel_confirm_info(); + let style = if chunkify { + // Chunkifying the address into smaller pieces when requested + theme::TEXT_MONO_ADDRESS_CHUNKS + } else { + theme::TEXT_MONO_DATA + }; + let ops = OpTextLayout::new(style).text_mono(address); + let formatted = FormattedText::new(ops).vertically_centered(); + Page::new(btn_layout, btn_actions, formatted).with_title(title) + }; + let pages = FlowPages::new(get_page, 1); + + let layout = RootComponent::new(Flow::new(pages)); + Ok(layout) + } + fn confirm_blob( title: TString<'static>, data: Obj, diff --git a/core/embed/rust/src/ui/model_tt/layout.rs b/core/embed/rust/src/ui/model_tt/layout.rs index 04fafed3dc..9a7a92b0a4 100644 --- a/core/embed/rust/src/ui/model_tt/layout.rs +++ b/core/embed/rust/src/ui/model_tt/layout.rs @@ -352,48 +352,6 @@ extern "C" fn new_confirm_emphasized(n_args: usize, args: *const Obj, kwargs: *m unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } -extern "C" fn new_confirm_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()?; - let description: Option = - kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?; - let verb: TString = kwargs.get_or(Qstr::MP_QSTR_verb, TR::buttons__confirm.into())?; - let extra: Option = kwargs.get(Qstr::MP_QSTR_extra)?.try_into_option()?; - let data: Obj = kwargs.get(Qstr::MP_QSTR_data)?; - let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?; - - let data_style = if chunkify { - let address: TString = data.try_into()?; - theme::get_chunkified_text_style(address.len()) - } else { - &theme::TEXT_MONO - }; - - let paragraphs = ConfirmBlob { - description: description.unwrap_or("".into()), - extra: extra.unwrap_or("".into()), - data: data.try_into()?, - description_font: &theme::TEXT_NORMAL, - extra_font: &theme::TEXT_DEMIBOLD, - data_font: data_style, - } - .into_paragraphs(); - - let obj = LayoutObj::new( - Frame::left_aligned( - theme::label_title(), - title, - ButtonPage::new(paragraphs, theme::BG) - .with_swipe_left() - .with_cancel_confirm(None, Some(verb)), - ) - .with_info_button(), - )?; - Ok(obj.into()) - }; - unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } -} - extern "C" fn new_show_address_details(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { let block = move |_args: &[Obj], kwargs: &Map| { let qr_title: TString<'static> = kwargs.get(Qstr::MP_QSTR_qr_title)?.try_into()?; @@ -473,19 +431,6 @@ pub static mp_module_trezorui2: Module = obj_module! { /// the first component is a bool indicating whether this part is emphasized.""" Qstr::MP_QSTR_confirm_emphasized => obj_fn_kw!(0, new_confirm_emphasized).as_obj(), - /// def confirm_address( - /// *, - /// title: str, - /// data: str | bytes, - /// description: str | None, - /// verb: str | None = "CONFIRM", - /// extra: str | None, - /// chunkify: bool = False, - /// ) -> LayoutObj[UiResult]: - /// """Confirm address. Similar to `confirm_blob` but has corner info button - /// and allows left swipe which does the same thing as the button.""" - Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(), - /// def show_address_details( /// *, /// qr_title: str, 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 98cbe890c5..5d1502f678 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 @@ -80,6 +80,45 @@ impl UIFeaturesFirmware for ModelTTFeatures { Ok(layout) } + fn confirm_address( + title: TString<'static>, + data: Obj, + description: Option>, + extra: Option>, + verb: Option>, + chunkify: bool, + ) -> Result { + let verb = verb.unwrap_or(TR::buttons__confirm.into()); + let data_style = if chunkify { + let address: TString = data.try_into()?; + theme::get_chunkified_text_style(address.len()) + } else { + &theme::TEXT_MONO + }; + + let paragraphs = ConfirmBlob { + description: description.unwrap_or("".into()), + extra: extra.unwrap_or("".into()), + data: data.try_into()?, + description_font: &theme::TEXT_NORMAL, + extra_font: &theme::TEXT_DEMIBOLD, + data_font: data_style, + } + .into_paragraphs(); + + let layout = RootComponent::new( + Frame::left_aligned( + theme::label_title(), + title, + ButtonPage::new(paragraphs, theme::BG) + .with_swipe_left() + .with_cancel_confirm(None, Some(verb)), + ) + .with_info_button(), + ); + Ok(layout) + } + fn confirm_blob( title: TString<'static>, data: Obj, diff --git a/core/embed/rust/src/ui/ui_features_fw.rs b/core/embed/rust/src/ui/ui_features_fw.rs index 28c1d59467..26e71aa38e 100644 --- a/core/embed/rust/src/ui/ui_features_fw.rs +++ b/core/embed/rust/src/ui/ui_features_fw.rs @@ -26,6 +26,15 @@ pub trait UIFeaturesFirmware { prompt_title: Option>, ) -> Result; + fn confirm_address( + title: TString<'static>, + data: Obj, // TODO: replace Obj + description: Option>, + extra: Option>, + verb: Option>, + chunkify: bool, + ) -> Result; + fn confirm_blob( title: TString<'static>, data: Obj, // TODO: replace Obj diff --git a/core/mocks/generated/trezorui2.pyi b/core/mocks/generated/trezorui2.pyi index 397bc1af2e..8cceba5093 100644 --- a/core/mocks/generated/trezorui2.pyi +++ b/core/mocks/generated/trezorui2.pyi @@ -114,19 +114,6 @@ from trezor import utils from trezorui_api import * -# rust/src/ui/model_tr/layout.rs -def confirm_address( - *, - title: str, - data: str, - description: str | None, # unused on TR - extra: str | None, # unused on TR - verb: str = "CONFIRM", - chunkify: bool = False, -) -> LayoutObj[UiResult]: - """Confirm address.""" - - # rust/src/ui/model_tr/layout.rs def confirm_backup() -> LayoutObj[UiResult]: """Strongly recommend user to do backup.""" @@ -223,20 +210,6 @@ def confirm_emphasized( the first component is a bool indicating whether this part is emphasized.""" -# rust/src/ui/model_tt/layout.rs -def confirm_address( - *, - title: str, - data: str | bytes, - description: str | None, - verb: str | None = "CONFIRM", - extra: str | None, - chunkify: bool = False, -) -> LayoutObj[UiResult]: - """Confirm address. Similar to `confirm_blob` but has corner info button - and allows left swipe which does the same thing as the button.""" - - # rust/src/ui/model_tt/layout.rs def show_address_details( *, diff --git a/core/mocks/generated/trezorui_api.pyi b/core/mocks/generated/trezorui_api.pyi index ff8fd0a4ec..9ddb10a447 100644 --- a/core/mocks/generated/trezorui_api.pyi +++ b/core/mocks/generated/trezorui_api.pyi @@ -96,6 +96,19 @@ def confirm_action( """Confirm action.""" +# rust/src/ui/api/firmware_upy.rs +def confirm_address( + *, + title: str, + data: str | bytes, + description: str | None, + extra: str | None, + verb: str | None = None, + chunkify: bool = False, +) -> LayoutObj[UiResult]: + """Confirm address.""" + + # rust/src/ui/api/firmware_upy.rs def confirm_blob( *, diff --git a/core/src/trezor/ui/layouts/mercury/__init__.py b/core/src/trezor/ui/layouts/mercury/__init__.py index d5f936d8ae..0fccca4568 100644 --- a/core/src/trezor/ui/layouts/mercury/__init__.py +++ b/core/src/trezor/ui/layouts/mercury/__init__.py @@ -1030,7 +1030,7 @@ async def confirm_signverify( address_title = TR.sign_message__confirm_address br_name = "sign_message" - address_layout = trezorui2.confirm_value( + address_layout = trezorui_api.confirm_value( title=address_title, subtitle=None, description="", diff --git a/core/src/trezor/ui/layouts/tr/__init__.py b/core/src/trezor/ui/layouts/tr/__init__.py index 62c5bbe0b7..5dde34021d 100644 --- a/core/src/trezor/ui/layouts/tr/__init__.py +++ b/core/src/trezor/ui/layouts/tr/__init__.py @@ -256,7 +256,7 @@ async def show_address( while True: result = await interact( - trezorui2.confirm_address( + trezorui_api.confirm_address( title=title, data=address, description="", # unused on TR diff --git a/core/src/trezor/ui/layouts/tt/__init__.py b/core/src/trezor/ui/layouts/tt/__init__.py index c252db05de..2a28e37da3 100644 --- a/core/src/trezor/ui/layouts/tt/__init__.py +++ b/core/src/trezor/ui/layouts/tt/__init__.py @@ -242,7 +242,7 @@ async def show_address( while True: result = await interact( - trezorui2.confirm_address( + trezorui_api.confirm_address( title=title, data=address, description=network or "", @@ -1071,7 +1071,7 @@ async def confirm_signverify( address_title = TR.sign_message__confirm_address br_name = "sign_message" - address_layout = trezorui2.confirm_address( + address_layout = trezorui_api.confirm_address( title=address_title, data=address, description="",