1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-27 08:38:07 +00:00

refactor(core): move keyboards to UiFeatures

Make layouts utilizing keyboards a part of UiFeaturesFirmware
This commit is contained in:
obrusvit 2024-10-22 22:24:40 +02:00
parent f354a3d6ba
commit dab0b7f3cc
19 changed files with 335 additions and 423 deletions

View File

@ -258,7 +258,6 @@ static void _librust_qstrs(void) {
MP_QSTR_flow_get_address;
MP_QSTR_flow_prompt_backup;
MP_QSTR_flow_request_number;
MP_QSTR_flow_request_passphrase;
MP_QSTR_flow_show_share_words;
MP_QSTR_flow_warning_hi_prio;
MP_QSTR_get_language;

View File

@ -23,6 +23,54 @@ use crate::{
// free-standing functions exported to MicroPython mirror `trait
// UIFeaturesFirmware`
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()?;
let prefill_word: TString = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let can_go_back: bool = kwargs.get(Qstr::MP_QSTR_can_go_back)?.try_into()?;
let layout = ModelUI::request_bip39(prompt, prefill_word, can_go_back)?;
Ok(LayoutObj::new_root(layout)?.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_request_slip39(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], kwargs: &Map| {
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let prefill_word: TString = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let can_go_back: bool = kwargs.get(Qstr::MP_QSTR_can_go_back)?.try_into()?;
let layout = ModelUI::request_slip39(prompt, prefill_word, can_go_back)?;
Ok(LayoutObj::new_root(layout)?.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_request_pin(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()?;
let subprompt: TString = kwargs.get(Qstr::MP_QSTR_subprompt)?.try_into()?;
let allow_cancel: bool = kwargs.get_or(Qstr::MP_QSTR_allow_cancel, true)?;
let warning: bool = kwargs.get_or(Qstr::MP_QSTR_wrong_pin, false)?;
let layout = ModelUI::request_pin(prompt, subprompt, allow_cancel, warning)?;
Ok(LayoutObj::new_root(layout)?.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_request_passphrase(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()?;
let max_len: u32 = kwargs.get(Qstr::MP_QSTR_max_len)?.try_into()?;
let layout = ModelUI::request_passphrase(prompt, max_len)?;
Ok(LayoutObj::new_root(layout)?.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn show_info(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()?;
@ -134,6 +182,42 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// INFO: UiResult
Qstr::MP_QSTR_INFO => INFO.as_obj(),
/// def request_bip39(
/// *,
/// prompt: str,
/// prefill_word: str,
/// can_go_back: bool,
/// ) -> LayoutObj[str]:
/// """BIP39 word input keyboard."""
Qstr::MP_QSTR_request_bip39 => obj_fn_kw!(0, new_request_bip39).as_obj(),
/// def request_slip39(
/// *,
/// prompt: str,
/// prefill_word: str,
/// can_go_back: bool,
/// ) -> LayoutObj[str]:
/// """SLIP39 word input keyboard."""
Qstr::MP_QSTR_request_slip39 => obj_fn_kw!(0, new_request_slip39).as_obj(),
/// def request_pin(
/// *,
/// prompt: str,
/// subprompt: str,
/// allow_cancel: bool = True,
/// wrong_pin: bool = False,
/// ) -> LayoutObj[str | UiResult]:
/// """Request pin on device."""
Qstr::MP_QSTR_request_pin => obj_fn_kw!(0, new_request_pin).as_obj(),
/// def request_passphrase(
/// *,
/// prompt: str,
/// max_len: int,
/// ) -> LayoutObj[str | UiResult]:
/// """Passphrase input keyboard."""
Qstr::MP_QSTR_request_passphrase => obj_fn_kw!(0, new_request_passphrase).as_obj(),
/// def show_info(
/// *,
/// title: str,

View File

@ -1196,63 +1196,6 @@ extern "C" fn new_request_number(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_request_passphrase(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()?;
let _max_len: usize = kwargs.get(Qstr::MP_QSTR_max_len)?.try_into()?;
let flow = flow::request_passphrase::new_request_passphrase()?;
Ok(LayoutObj::new_root(flow)?.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_request_pin(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()?;
let subprompt: TString = kwargs.get(Qstr::MP_QSTR_subprompt)?.try_into()?;
let allow_cancel: bool = kwargs.get_or(Qstr::MP_QSTR_allow_cancel, true)?;
let warning: bool = kwargs.get_or(Qstr::MP_QSTR_wrong_pin, false)?;
let warning = if warning {
Some(TR::pin__wrong_pin.into())
} else {
None
};
Ok(LayoutObj::new(PinKeyboard::new(prompt, subprompt, warning, allow_cancel))?.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()?;
let prefill_word: TString = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let can_go_back: bool = kwargs.get(Qstr::MP_QSTR_can_go_back)?.try_into()?;
let obj = LayoutObj::new(MnemonicKeyboard::new(
prefill_word.map(Bip39Input::prefilled_word),
prompt,
can_go_back,
))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_request_slip39(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()?;
let prefill_word: TString = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let can_go_back: bool = kwargs.get(Qstr::MP_QSTR_can_go_back)?.try_into()?;
let obj = LayoutObj::new(MnemonicKeyboard::new(
prefill_word.map(Slip39Input::prefilled_word),
prompt,
can_go_back,
))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_select_word(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()?;
@ -1742,42 +1685,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Confirm coinjoin authorization."""
Qstr::MP_QSTR_confirm_coinjoin => obj_fn_kw!(0, new_confirm_coinjoin).as_obj(),
/// def request_pin(
/// *,
/// prompt: str,
/// subprompt: str,
/// allow_cancel: bool = True,
/// wrong_pin: bool = False,
/// ) -> LayoutObj[str | UiResult]:
/// """Request pin on device."""
Qstr::MP_QSTR_request_pin => obj_fn_kw!(0, new_request_pin).as_obj(),
/// def flow_request_passphrase(
/// *,
/// prompt: str,
/// max_len: int,
/// ) -> LayoutObj[str | UiResult]:
/// """Passphrase input keyboard."""
Qstr::MP_QSTR_flow_request_passphrase => obj_fn_kw!(0, new_request_passphrase).as_obj(),
/// def request_bip39(
/// *,
/// prompt: str,
/// prefill_word: str,
/// can_go_back: bool,
/// ) -> LayoutObj[str]:
/// """BIP39 word input keyboard."""
Qstr::MP_QSTR_request_bip39 => obj_fn_kw!(0, new_request_bip39).as_obj(),
/// def request_slip39(
/// *,
/// prompt: str,
/// prefill_word: str,
/// can_go_back: bool,
/// ) -> LayoutObj[str]:
/// """SLIP39 word input keyboard."""
Qstr::MP_QSTR_request_slip39 => obj_fn_kw!(0, new_request_slip39).as_obj(),
/// def select_word(
/// *,
/// title: str,

View File

@ -15,11 +15,63 @@ use crate::{
};
use super::{
component::{Frame, SwipeContent, SwipeUpScreen},
theme, ModelMercuryFeatures,
component::{
Bip39Input, Frame, MnemonicKeyboard, PinKeyboard, Slip39Input, SwipeContent, SwipeUpScreen,
}, flow, theme, ModelMercuryFeatures
};
impl UIFeaturesFirmware for ModelMercuryFeatures {
fn request_bip39(
prompt: TString<'static>,
prefill_word: TString<'static>,
can_go_back: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let layout = RootComponent::new(MnemonicKeyboard::new(
prefill_word.map(Bip39Input::prefilled_word),
prompt,
can_go_back,
));
Ok(layout)
}
fn request_slip39(
prompt: TString<'static>,
prefill_word: TString<'static>,
can_go_back: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let layout = RootComponent::new(MnemonicKeyboard::new(
prefill_word.map(Slip39Input::prefilled_word),
prompt,
can_go_back,
));
Ok(layout)
}
fn request_pin(
prompt: TString<'static>,
subprompt: TString<'static>,
allow_cancel: bool,
warning: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let warning = if warning {
Some(TR::pin__wrong_pin.into())
} else {
None
};
let layout = RootComponent::new(PinKeyboard::new(prompt, subprompt, warning, allow_cancel));
Ok(layout)
}
fn request_passphrase(
prompt: TString<'static>,
max_len: u32,
) -> Result<impl LayoutMaybeTrace, Error> {
let flow = flow::request_passphrase::new_request_passphrase()?;
Ok(flow)
}
fn show_info(
title: TString<'static>,
description: TString<'static>,

View File

@ -1234,66 +1234,6 @@ extern "C" fn new_confirm_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_request_pin(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], kwargs: &Map| {
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let subprompt: TString = kwargs.get(Qstr::MP_QSTR_subprompt)?.try_into()?;
let obj = LayoutObj::new(PinEntry::new(prompt, subprompt))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_request_passphrase(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], kwargs: &Map| {
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let obj = LayoutObj::new(Frame::new(prompt, PassphraseEntry::new()).with_title_centered())?;
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 = |_args: &[Obj], kwargs: &Map| {
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let prefill_word: TString = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let can_go_back: bool = kwargs.get(Qstr::MP_QSTR_can_go_back)?.try_into()?;
let obj = LayoutObj::new(
Frame::new(
prompt,
prefill_word
.map(|s| WordlistEntry::prefilled_word(s, WordlistType::Bip39, can_go_back)),
)
.with_title_centered(),
)?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_request_slip39(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], kwargs: &Map| {
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let prefill_word: TString = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let can_go_back: bool = kwargs.get(Qstr::MP_QSTR_can_go_back)?.try_into()?;
let obj = LayoutObj::new(
Frame::new(
prompt,
prefill_word
.map(|s| WordlistEntry::prefilled_word(s, WordlistType::Slip39, can_go_back)),
)
.with_title_centered(),
)?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_select_word(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], kwargs: &Map| {
// we ignore passed in `title` and use `description` in its place
@ -1884,42 +1824,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Confirm coinjoin authorization."""
Qstr::MP_QSTR_confirm_coinjoin => obj_fn_kw!(0, new_confirm_coinjoin).as_obj(),
/// def request_pin(
/// *,
/// prompt: str,
/// subprompt: str,
/// allow_cancel: bool = True, # unused on TR
/// wrong_pin: bool = False, # unused on TR
/// ) -> LayoutObj[str | UiResult]:
/// """Request pin on device."""
Qstr::MP_QSTR_request_pin => obj_fn_kw!(0, new_request_pin).as_obj(),
/// def request_passphrase(
/// *,
/// prompt: str,
/// max_len: int, # unused on TR
/// ) -> LayoutObj[str | UiResult]:
/// """Get passphrase."""
Qstr::MP_QSTR_request_passphrase => obj_fn_kw!(0, new_request_passphrase).as_obj(),
/// def request_bip39(
/// *,
/// prompt: str,
/// prefill_word: str,
/// can_go_back: bool,
/// ) -> LayoutObj[str]:
/// """Get recovery word for BIP39."""
Qstr::MP_QSTR_request_bip39 => obj_fn_kw!(0, new_request_bip39).as_obj(),
/// def request_slip39(
/// *,
/// prompt: str,
/// prefill_word: str,
/// can_go_back: bool,
/// ) -> LayoutObj[str]:
/// """SLIP39 word input keyboard."""
Qstr::MP_QSTR_request_slip39 => obj_fn_kw!(0, new_request_slip39).as_obj(),
/// def select_word(
/// *,
/// title: str, # unused on TR

View File

@ -12,6 +12,8 @@ mod screens;
pub mod theme;
pub struct ModelTRFeatures {}
#[cfg(feature = "micropython")]
pub mod ui_features_fw;
impl UIFeaturesCommon for ModelTRFeatures {

View File

@ -4,16 +4,71 @@ use crate::{
strutil::TString,
ui::{
component::{
text::paragraphs::{Paragraph, Paragraphs}, ComponentExt, Timeout
text::paragraphs::{Paragraph, Paragraphs},
ComponentExt, Timeout,
},
layout::obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
ui_features_fw::UIFeaturesFirmware,
},
};
use super::{component::Frame, theme, ModelTRFeatures};
use super::{
component::{Frame, PassphraseEntry, PinEntry, WordlistEntry, WordlistType},
theme, ModelTRFeatures,
};
impl UIFeaturesFirmware for ModelTRFeatures {
fn request_bip39(
prompt: TString<'static>,
prefill_word: TString<'static>,
can_go_back: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let layout = RootComponent::new(
Frame::new(
prompt,
prefill_word
.map(|s| WordlistEntry::prefilled_word(s, WordlistType::Bip39, can_go_back)),
)
.with_title_centered(),
);
Ok(layout)
}
fn request_slip39(
prompt: TString<'static>,
prefill_word: TString<'static>,
can_go_back: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let layout = RootComponent::new(
Frame::new(
prompt,
prefill_word
.map(|s| WordlistEntry::prefilled_word(s, WordlistType::Slip39, can_go_back)),
)
.with_title_centered(),
);
Ok(layout)
}
fn request_pin(
prompt: TString<'static>,
subprompt: TString<'static>,
allow_cancel: bool,
warning: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let layout = RootComponent::new(PinEntry::new(prompt, subprompt));
Ok(layout)
}
fn request_passphrase(
prompt: TString<'static>,
max_len: u32,
) -> Result<impl LayoutMaybeTrace, Error> {
let layout =
RootComponent::new(Frame::new(prompt, PassphraseEntry::new()).with_title_centered());
Ok(layout)
}
fn show_info(
title: TString<'static>,
description: TString<'static>,

View File

@ -1198,63 +1198,6 @@ extern "C" fn new_confirm_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_request_pin(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()?;
let subprompt: TString = kwargs.get(Qstr::MP_QSTR_subprompt)?.try_into()?;
let allow_cancel: bool = kwargs.get_or(Qstr::MP_QSTR_allow_cancel, true)?;
let warning: bool = kwargs.get_or(Qstr::MP_QSTR_wrong_pin, false)?;
let warning = if warning {
Some(TR::pin__wrong_pin.into())
} else {
None
};
let obj = LayoutObj::new(PinKeyboard::new(prompt, subprompt, warning, allow_cancel))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_request_passphrase(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()?;
let _max_len: u32 = kwargs.get(Qstr::MP_QSTR_max_len)?.try_into()?;
let obj = LayoutObj::new(PassphraseKeyboard::new())?;
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()?;
let prefill_word: TString = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let can_go_back: bool = kwargs.get(Qstr::MP_QSTR_can_go_back)?.try_into()?;
let obj = LayoutObj::new(MnemonicKeyboard::new(
prefill_word.map(Bip39Input::prefilled_word),
prompt,
can_go_back,
))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_request_slip39(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()?;
let prefill_word: TString = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let can_go_back: bool = kwargs.get(Qstr::MP_QSTR_can_go_back)?.try_into()?;
let obj = LayoutObj::new(MnemonicKeyboard::new(
prefill_word.map(Slip39Input::prefilled_word),
prompt,
can_go_back,
))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_select_word(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()?;
@ -1893,42 +1836,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Confirm coinjoin authorization."""
Qstr::MP_QSTR_confirm_coinjoin => obj_fn_kw!(0, new_confirm_coinjoin).as_obj(),
/// def request_pin(
/// *,
/// prompt: str,
/// subprompt: str,
/// allow_cancel: bool = True,
/// wrong_pin: bool = False,
/// ) -> LayoutObj[str | UiResult]:
/// """Request pin on device."""
Qstr::MP_QSTR_request_pin => obj_fn_kw!(0, new_request_pin).as_obj(),
/// def request_passphrase(
/// *,
/// prompt: str,
/// max_len: int,
/// ) -> LayoutObj[str | UiResult]:
/// """Passphrase input keyboard."""
Qstr::MP_QSTR_request_passphrase => obj_fn_kw!(0, new_request_passphrase).as_obj(),
/// def request_bip39(
/// *,
/// prompt: str,
/// prefill_word: str,
/// can_go_back: bool,
/// ) -> LayoutObj[str]:
/// """BIP39 word input keyboard."""
Qstr::MP_QSTR_request_bip39 => obj_fn_kw!(0, new_request_bip39).as_obj(),
/// def request_slip39(
/// *,
/// prompt: str,
/// prefill_word: str,
/// can_go_back: bool,
/// ) -> LayoutObj[str]:
/// """SLIP39 word input keyboard."""
Qstr::MP_QSTR_request_slip39 => obj_fn_kw!(0, new_request_slip39).as_obj(),
/// def select_word(
/// *,
/// title: str,

View File

@ -19,6 +19,8 @@ use crate::ui::{
};
pub struct ModelTTFeatures;
#[cfg(feature = "micropython")]
pub mod ui_features_fw;
impl UIFeaturesCommon for ModelTTFeatures {

View File

@ -2,6 +2,7 @@ use crate::{
error::Error,
micropython::gc::Gc,
strutil::TString,
translations::TR,
ui::{
component::{image::BlendedImage, ComponentExt, Empty, Timeout},
layout::obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
@ -10,11 +11,64 @@ use crate::{
};
use super::{
component::{Button, ButtonMsg, ButtonStyleSheet, CancelConfirmMsg, IconDialog},
component::{
Bip39Input, Button, ButtonMsg, ButtonStyleSheet, CancelConfirmMsg, IconDialog,
MnemonicKeyboard, PassphraseKeyboard, PinKeyboard, Slip39Input,
},
theme, ModelTTFeatures,
};
impl UIFeaturesFirmware for ModelTTFeatures {
fn request_bip39(
prompt: TString<'static>,
prefill_word: TString<'static>,
can_go_back: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let layout = RootComponent::new(MnemonicKeyboard::new(
prefill_word.map(Bip39Input::prefilled_word),
prompt,
can_go_back,
));
Ok(layout)
}
fn request_slip39(
prompt: TString<'static>,
prefill_word: TString<'static>,
can_go_back: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let layout = RootComponent::new(MnemonicKeyboard::new(
prefill_word.map(Slip39Input::prefilled_word),
prompt,
can_go_back,
));
Ok(layout)
}
fn request_pin(
prompt: TString<'static>,
subprompt: TString<'static>,
allow_cancel: bool,
warning: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let warning = if warning {
Some(TR::pin__wrong_pin.into())
} else {
None
};
let layout = RootComponent::new(PinKeyboard::new(prompt, subprompt, warning, allow_cancel));
Ok(layout)
}
fn request_passphrase(
prompt: TString<'static>,
max_len: u32,
) -> Result<impl LayoutMaybeTrace, Error> {
let layout = RootComponent::new(PassphraseKeyboard::new());
Ok(layout)
}
fn show_info(
title: TString<'static>,
description: TString<'static>,
@ -33,17 +87,17 @@ impl UIFeaturesFirmware for ModelTTFeatures {
theme::FG,
theme::BG,
);
let res = new_show_modal(
let obj = new_show_modal(
title,
TString::empty(),
description,
TString::empty(),
button,
false,
time_ms,
icon,
theme::button_info(),
)?;
Ok(res)
Ok(obj)
}
}

View File

@ -3,6 +3,30 @@ use crate::{error::Error, micropython::gc::Gc, strutil::TString};
use super::layout::obj::{LayoutMaybeTrace, LayoutObj};
pub trait UIFeaturesFirmware {
fn request_bip39(
prompt: TString<'static>,
prefill_word: TString<'static>,
can_go_back: bool,
) -> Result<impl LayoutMaybeTrace, Error>;
fn request_slip39(
prompt: TString<'static>,
prefill_word: TString<'static>,
can_go_back: bool,
) -> Result<impl LayoutMaybeTrace, Error>;
fn request_pin(
prompt: TString<'static>,
subprompt: TString<'static>,
allow_cancel: bool,
warning: bool,
) -> Result<impl LayoutMaybeTrace, Error>;
fn request_passphrase(
prompt: TString<'static>,
max_len: u32,
) -> Result<impl LayoutMaybeTrace, Error>;
fn show_info(
title: TString<'static>,
description: TString<'static>,

View File

@ -270,46 +270,6 @@ def confirm_coinjoin(
"""Confirm coinjoin authorization."""
# rust/src/ui/model_mercury/layout.rs
def request_pin(
*,
prompt: str,
subprompt: str,
allow_cancel: bool = True,
wrong_pin: bool = False,
) -> LayoutObj[str | UiResult]:
"""Request pin on device."""
# rust/src/ui/model_mercury/layout.rs
def flow_request_passphrase(
*,
prompt: str,
max_len: int,
) -> LayoutObj[str | UiResult]:
"""Passphrase input keyboard."""
# rust/src/ui/model_mercury/layout.rs
def request_bip39(
*,
prompt: str,
prefill_word: str,
can_go_back: bool,
) -> LayoutObj[str]:
"""BIP39 word input keyboard."""
# rust/src/ui/model_mercury/layout.rs
def request_slip39(
*,
prompt: str,
prefill_word: str,
can_go_back: bool,
) -> LayoutObj[str]:
"""SLIP39 word input keyboard."""
# rust/src/ui/model_mercury/layout.rs
def select_word(
*,
@ -824,46 +784,6 @@ def confirm_coinjoin(
"""Confirm coinjoin authorization."""
# rust/src/ui/model_tr/layout.rs
def request_pin(
*,
prompt: str,
subprompt: str,
allow_cancel: bool = True, # unused on TR
wrong_pin: bool = False, # unused on TR
) -> LayoutObj[str | UiResult]:
"""Request pin on device."""
# rust/src/ui/model_tr/layout.rs
def request_passphrase(
*,
prompt: str,
max_len: int, # unused on TR
) -> LayoutObj[str | UiResult]:
"""Get passphrase."""
# rust/src/ui/model_tr/layout.rs
def request_bip39(
*,
prompt: str,
prefill_word: str,
can_go_back: bool,
) -> LayoutObj[str]:
"""Get recovery word for BIP39."""
# rust/src/ui/model_tr/layout.rs
def request_slip39(
*,
prompt: str,
prefill_word: str,
can_go_back: bool,
) -> LayoutObj[str]:
"""SLIP39 word input keyboard."""
# rust/src/ui/model_tr/layout.rs
def select_word(
*,
@ -1277,46 +1197,6 @@ def confirm_coinjoin(
"""Confirm coinjoin authorization."""
# rust/src/ui/model_tt/layout.rs
def request_pin(
*,
prompt: str,
subprompt: str,
allow_cancel: bool = True,
wrong_pin: bool = False,
) -> LayoutObj[str | UiResult]:
"""Request pin on device."""
# rust/src/ui/model_tt/layout.rs
def request_passphrase(
*,
prompt: str,
max_len: int,
) -> LayoutObj[str | UiResult]:
"""Passphrase input keyboard."""
# rust/src/ui/model_tt/layout.rs
def request_bip39(
*,
prompt: str,
prefill_word: str,
can_go_back: bool,
) -> LayoutObj[str]:
"""BIP39 word input keyboard."""
# rust/src/ui/model_tt/layout.rs
def request_slip39(
*,
prompt: str,
prefill_word: str,
can_go_back: bool,
) -> LayoutObj[str]:
"""SLIP39 word input keyboard."""
# rust/src/ui/model_tt/layout.rs
def select_word(
*,

View File

@ -68,6 +68,46 @@ CANCELLED: UiResult
INFO: UiResult
# rust/src/ui/api/firmware_upy.rs
def request_bip39(
*,
prompt: str,
prefill_word: str,
can_go_back: bool,
) -> LayoutObj[str]:
"""BIP39 word input keyboard."""
# rust/src/ui/api/firmware_upy.rs
def request_slip39(
*,
prompt: str,
prefill_word: str,
can_go_back: bool,
) -> LayoutObj[str]:
"""SLIP39 word input keyboard."""
# rust/src/ui/api/firmware_upy.rs
def request_pin(
*,
prompt: str,
subprompt: str,
allow_cancel: bool = True,
wrong_pin: bool = False,
) -> LayoutObj[str | UiResult]:
"""Request pin on device."""
# rust/src/ui/api/firmware_upy.rs
def request_passphrase(
*,
prompt: str,
max_len: int,
) -> LayoutObj[str | UiResult]:
"""Passphrase input keyboard."""
# rust/src/ui/api/firmware_upy.rs
def show_info(
*,

View File

@ -1095,7 +1095,7 @@ def show_wait_text(message: str) -> None:
def request_passphrase_on_device(max_len: int) -> Awaitable[str]:
result = interact(
trezorui2.flow_request_passphrase(
trezorui_api.request_passphrase(
prompt=TR.passphrase__title_enter, max_len=max_len
),
"passphrase_device",
@ -1121,7 +1121,7 @@ def request_pin_on_device(
subprompt = f"{attempts_remaining} {TR.pin__tries_left}"
result = interact(
trezorui2.request_pin(
trezorui_api.request_pin(
prompt=prompt,
subprompt=subprompt,
allow_cancel=allow_cancel,

View File

@ -34,11 +34,11 @@ async def request_word(
prompt = TR.recovery__word_x_of_y_template.format(word_index + 1, word_count)
can_go_back = word_index > 0
if is_slip39:
keyboard = trezorui2.request_slip39(
keyboard = trezorui_api.request_slip39(
prompt=prompt, prefill_word=prefill_word, can_go_back=can_go_back
)
else:
keyboard = trezorui2.request_bip39(
keyboard = trezorui_api.request_bip39(
prompt=prompt, prefill_word=prefill_word, can_go_back=can_go_back
)

View File

@ -1153,7 +1153,7 @@ def show_wait_text(message: str) -> None:
async def request_passphrase_on_device(max_len: int) -> str:
result = await interact(
trezorui2.request_passphrase(
trezorui_api.request_passphrase(
prompt=TR.passphrase__title_enter,
max_len=max_len,
),
@ -1183,7 +1183,7 @@ async def request_pin_on_device(
subprompt = f"{attempts_remaining} {TR.pin__tries_left}"
result = await interact(
trezorui2.request_pin(
trezorui_api.request_pin(
prompt=prompt,
subprompt=subprompt,
allow_cancel=allow_cancel,

View File

@ -36,12 +36,12 @@ async def request_word(
can_go_back = word_index > 0
if is_slip39:
keyboard = trezorui2.request_slip39(
keyboard = trezorui_api.request_slip39(
prompt=prompt, prefill_word=prefill_word, can_go_back=can_go_back
)
else:
keyboard = trezorui2.request_bip39(
keyboard = trezorui_api.request_bip39(
prompt=prompt, prefill_word=prefill_word, can_go_back=can_go_back
)

View File

@ -1154,7 +1154,9 @@ def show_wait_text(message: str) -> None:
async def request_passphrase_on_device(max_len: int) -> str:
result = await interact(
trezorui2.request_passphrase(prompt="Enter passphrase", max_len=max_len),
trezorui_api.request_passphrase(
prompt=TR.passphrase__title_enter, max_len=max_len
),
"passphrase_device",
ButtonRequestType.PassphraseEntry,
raise_on_cancel=ActionCancelled("Passphrase entry cancelled"),
@ -1179,7 +1181,7 @@ async def request_pin_on_device(
subprompt = f"{attempts_remaining} {TR.pin__tries_left}"
result = await interact(
trezorui2.request_pin(
trezorui_api.request_pin(
prompt=prompt,
subprompt=subprompt,
allow_cancel=allow_cancel,

View File

@ -34,12 +34,12 @@ async def request_word(
prompt = TR.recovery__type_word_x_of_y_template.format(word_index + 1, word_count)
can_go_back = word_index > 0
if is_slip39:
keyboard = trezorui2.request_slip39(
keyboard = trezorui_api.request_slip39(
prompt=prompt, prefill_word=prefill_word, can_go_back=can_go_back
)
else:
keyboard = trezorui2.request_bip39(
keyboard = trezorui_api.request_bip39(
prompt=prompt, prefill_word=prefill_word, can_go_back=can_go_back
)