1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-29 02:48:18 +00:00

refactor(core): move confirm_address

This commit is contained in:
obrusvit 2024-11-24 17:21:48 +01:00
parent c8d7168b06
commit 8ff9b585bb
12 changed files with 169 additions and 155 deletions

View File

@ -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) } 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<TString> = kwargs
.get(Qstr::MP_QSTR_description)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let extra: Option<TString> = kwargs
.get(Qstr::MP_QSTR_extra)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb: Option<TString> = 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 { extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| { let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
@ -886,6 +910,18 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// """Confirm action.""" /// """Confirm action."""
Qstr::MP_QSTR_confirm_action => obj_fn_kw!(0, new_confirm_action).as_obj(), 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( /// def confirm_blob(
/// *, /// *,
/// title: str, /// title: str,

View File

@ -257,45 +257,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) } 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<TString> =
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
let extra: Option<TString> = 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();
flow::new_confirm_action_simple(
paragraphs,
ConfirmActionMenu::new(None, false, None),
ConfirmActionStrings::new(title, None, None, None),
false,
None,
)
.and_then(LayoutObj::new_root)
.map(Into::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 { 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 block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
@ -573,19 +534,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// the first component is a bool indicating whether this part is emphasized.""" /// 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(), 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(),
// TODO: supply more arguments for Wipe code setting when figma done // TODO: supply more arguments for Wipe code setting when figma done
/// def flow_confirm_set_new_pin( /// def flow_confirm_set_new_pin(
/// *, /// *,

View File

@ -22,7 +22,7 @@ use crate::{
geometry::{self, Direction}, geometry::{self, Direction},
layout::{ layout::{
obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
util::{PropsList, RecoveryType}, util::{ConfirmBlob, PropsList, RecoveryType},
}, },
ui_features_fw::UIFeaturesFirmware, ui_features_fw::UIFeaturesFirmware,
}, },
@ -69,6 +69,41 @@ impl UIFeaturesFirmware for ModelMercuryFeatures {
Ok(flow) Ok(flow)
} }
fn confirm_address(
title: TString<'static>,
data: Obj,
description: Option<TString<'static>>,
extra: Option<TString<'static>>,
_verb: Option<TString<'static>>,
chunkify: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
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 flow = flow::new_confirm_action_simple(
paragraphs,
ConfirmActionMenu::new(None, false, None),
ConfirmActionStrings::new(title, None, None, None),
false,
None,
)?;
Ok(flow)
}
fn confirm_blob( fn confirm_blob(
title: TString<'static>, title: TString<'static>,
data: Obj, data: Obj,

View File

@ -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) } 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 { 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 block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; 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(), 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]: /// def confirm_backup() -> LayoutObj[UiResult]:
/// """Strongly recommend user to do backup.""" /// """Strongly recommend user to do backup."""
Qstr::MP_QSTR_confirm_backup => obj_fn_kw!(0, new_confirm_backup).as_obj(), Qstr::MP_QSTR_confirm_backup => obj_fn_kw!(0, new_confirm_backup).as_obj(),

View File

@ -83,6 +83,38 @@ impl UIFeaturesFirmware for ModelTRFeatures {
) )
} }
fn confirm_address(
title: TString<'static>,
data: Obj,
description: Option<TString<'static>>,
extra: Option<TString<'static>>,
verb: Option<TString<'static>>,
chunkify: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
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( fn confirm_blob(
title: TString<'static>, title: TString<'static>,
data: Obj, data: Obj,

View File

@ -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) } 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<TString> =
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<TString> = 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 { 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 block = move |_args: &[Obj], kwargs: &Map| {
let qr_title: TString<'static> = kwargs.get(Qstr::MP_QSTR_qr_title)?.try_into()?; 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.""" /// 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(), 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( /// def show_address_details(
/// *, /// *,
/// qr_title: str, /// qr_title: str,

View File

@ -80,6 +80,45 @@ impl UIFeaturesFirmware for ModelTTFeatures {
Ok(layout) Ok(layout)
} }
fn confirm_address(
title: TString<'static>,
data: Obj,
description: Option<TString<'static>>,
extra: Option<TString<'static>>,
verb: Option<TString<'static>>,
chunkify: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
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( fn confirm_blob(
title: TString<'static>, title: TString<'static>,
data: Obj, data: Obj,

View File

@ -26,6 +26,15 @@ pub trait UIFeaturesFirmware {
prompt_title: Option<TString<'static>>, prompt_title: Option<TString<'static>>,
) -> Result<impl LayoutMaybeTrace, Error>; ) -> Result<impl LayoutMaybeTrace, Error>;
fn confirm_address(
title: TString<'static>,
data: Obj, // TODO: replace Obj
description: Option<TString<'static>>,
extra: Option<TString<'static>>,
verb: Option<TString<'static>>,
chunkify: bool,
) -> Result<impl LayoutMaybeTrace, Error>;
fn confirm_blob( fn confirm_blob(
title: TString<'static>, title: TString<'static>,
data: Obj, // TODO: replace Obj data: Obj, // TODO: replace Obj

View File

@ -96,6 +96,19 @@ def confirm_action(
"""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 # rust/src/ui/api/firmware_upy.rs
def confirm_blob( def confirm_blob(
*, *,

View File

@ -1004,7 +1004,7 @@ async def confirm_signverify(
address_title = TR.sign_message__confirm_address address_title = TR.sign_message__confirm_address
br_name = "sign_message" br_name = "sign_message"
address_layout = trezorui2.confirm_address( address_layout = trezorui_api.confirm_address(
title=address_title, title=address_title,
data=address, data=address,
description="", description="",

View File

@ -248,7 +248,7 @@ async def show_address(
while True: while True:
result = await interact( result = await interact(
trezorui2.confirm_address( trezorui_api.confirm_address(
title=title, title=title,
data=address, data=address,
description="", # unused on TR description="", # unused on TR

View File

@ -234,7 +234,7 @@ async def show_address(
while True: while True:
result = await interact( result = await interact(
trezorui2.confirm_address( trezorui_api.confirm_address(
title=title, title=title,
data=address, data=address,
description=network or "", description=network or "",
@ -1049,7 +1049,7 @@ async def confirm_signverify(
address_title = TR.sign_message__confirm_address address_title = TR.sign_message__confirm_address
br_name = "sign_message" br_name = "sign_message"
address_layout = trezorui2.confirm_address( address_layout = trezorui_api.confirm_address(
title=address_title, title=address_title,
data=address, data=address,
description="", description="",