1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-23 14:58:09 +00:00

feat(core): use new ETH send flow also for staking

This commit is contained in:
Ioan Bizău 2024-08-30 16:12:38 +02:00 committed by Ioan Bizău
parent c5f9fadbd1
commit ba8f0ea4bc
7 changed files with 150 additions and 89 deletions

View File

@ -0,0 +1 @@
[T3T1] Improved ETH staking flow.

View File

@ -327,6 +327,7 @@ static void _librust_qstrs(void) {
MP_QSTR_max_feerate; MP_QSTR_max_feerate;
MP_QSTR_max_len; MP_QSTR_max_len;
MP_QSTR_max_rounds; MP_QSTR_max_rounds;
MP_QSTR_message;
MP_QSTR_min_count; MP_QSTR_min_count;
MP_QSTR_misc__decrypt_value; MP_QSTR_misc__decrypt_value;
MP_QSTR_misc__encrypt_value; MP_QSTR_misc__encrypt_value;

View File

@ -31,7 +31,8 @@ use super::{
const MENU_ITEM_CANCEL: usize = 0; const MENU_ITEM_CANCEL: usize = 0;
const MENU_ITEM_FEE_INFO: usize = 1; const MENU_ITEM_FEE_INFO: usize = 1;
const MENU_ITEM_ACCOUNT_INFO: usize = 2; const MENU_ITEM_ADDRESS_INFO: usize = 2;
const MENU_ITEM_ACCOUNT_INFO: usize = 3;
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub enum ConfirmOutput { pub enum ConfirmOutput {
@ -117,9 +118,10 @@ impl FlowState for ConfirmOutputWithAmount {
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub enum ConfirmOutputWithSummary { pub enum ConfirmOutputWithSummary {
Address, Main,
AddressMenu, MainMenu,
AddressMenuCancel, MainMenuCancel,
AddressInfo,
Summary, Summary,
SummaryMenu, SummaryMenu,
SummaryMenuCancel, SummaryMenuCancel,
@ -138,12 +140,13 @@ impl FlowState for ConfirmOutputWithSummary {
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange { fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
match (self, direction) { match (self, direction) {
(Self::Address, SwipeDirection::Left) => Self::AddressMenu.swipe(direction), (Self::Main, SwipeDirection::Left) => Self::MainMenu.swipe(direction),
(Self::Address, SwipeDirection::Up) => Self::Summary.swipe(direction), (Self::Main, SwipeDirection::Up) => Self::Summary.swipe(direction),
(Self::AccountInfo, SwipeDirection::Right) => Self::AddressMenu.swipe(direction), (Self::AddressInfo, SwipeDirection::Right) => Self::MainMenu.swipe(direction),
(Self::AccountInfo, SwipeDirection::Right) => Self::MainMenu.swipe(direction),
(Self::Summary, SwipeDirection::Left) => Self::SummaryMenu.swipe(direction), (Self::Summary, SwipeDirection::Left) => Self::SummaryMenu.swipe(direction),
(Self::Summary, SwipeDirection::Up) => Self::Hold.swipe(direction), (Self::Summary, SwipeDirection::Up) => Self::Hold.swipe(direction),
(Self::Summary, SwipeDirection::Down) => Self::Address.swipe(direction), (Self::Summary, SwipeDirection::Down) => Self::Main.swipe(direction),
(Self::FeeInfo, SwipeDirection::Right) => Self::SummaryMenu.swipe(direction), (Self::FeeInfo, SwipeDirection::Right) => Self::SummaryMenu.swipe(direction),
(Self::Hold, SwipeDirection::Left) => Self::HoldMenu.swipe(direction), (Self::Hold, SwipeDirection::Left) => Self::HoldMenu.swipe(direction),
(Self::Hold, SwipeDirection::Down) => Self::Summary.swipe(direction), (Self::Hold, SwipeDirection::Down) => Self::Summary.swipe(direction),
@ -153,11 +156,12 @@ impl FlowState for ConfirmOutputWithSummary {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(Self::Address, FlowMsg::Info) => Self::AddressMenu.transit(), (Self::Main, FlowMsg::Info) => Self::MainMenu.transit(),
(Self::AddressMenu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => { (Self::MainMenu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => {
Self::AddressMenuCancel.swipe_left() Self::MainMenuCancel.swipe_left()
} }
(Self::AddressMenuCancel, FlowMsg::Cancelled) => Self::AddressMenu.swipe_right(), (Self::MainMenuCancel, FlowMsg::Cancelled) => Self::MainMenu.swipe_right(),
(Self::AddressInfo, FlowMsg::Info) => Self::MainMenu.transit(),
(Self::Summary, FlowMsg::Info) => Self::SummaryMenu.transit(), (Self::Summary, FlowMsg::Info) => Self::SummaryMenu.transit(),
(Self::SummaryMenu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => { (Self::SummaryMenu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => {
Self::SummaryMenuCancel.swipe_left() Self::SummaryMenuCancel.swipe_left()
@ -169,18 +173,21 @@ impl FlowState for ConfirmOutputWithSummary {
} }
(Self::HoldMenuCancel, FlowMsg::Cancelled) => Self::HoldMenu.swipe_right(), (Self::HoldMenuCancel, FlowMsg::Cancelled) => Self::HoldMenu.swipe_right(),
(Self::SummaryMenu, FlowMsg::Choice(MENU_ITEM_FEE_INFO)) => Self::FeeInfo.swipe_left(), (Self::SummaryMenu, FlowMsg::Choice(MENU_ITEM_FEE_INFO)) => Self::FeeInfo.swipe_left(),
(Self::AddressMenu, FlowMsg::Choice(MENU_ITEM_ACCOUNT_INFO)) => { (Self::MainMenu, FlowMsg::Choice(MENU_ITEM_ADDRESS_INFO)) => {
Self::AddressInfo.swipe_left()
}
(Self::MainMenu, FlowMsg::Choice(MENU_ITEM_ACCOUNT_INFO)) => {
Self::AccountInfo.swipe_left() Self::AccountInfo.swipe_left()
} }
(Self::AddressMenu, FlowMsg::Cancelled) => Self::Address.swipe_right(), (Self::MainMenu, FlowMsg::Cancelled) => Self::Main.swipe_right(),
(Self::SummaryMenu, FlowMsg::Cancelled) => Self::Summary.swipe_right(), (Self::SummaryMenu, FlowMsg::Cancelled) => Self::Summary.swipe_right(),
(Self::FeeInfo, FlowMsg::Cancelled) => Self::SummaryMenu.swipe_right(), (Self::FeeInfo, FlowMsg::Cancelled) => Self::SummaryMenu.swipe_right(),
(Self::HoldMenu, FlowMsg::Cancelled) => Self::Hold.swipe_right(), (Self::HoldMenu, FlowMsg::Cancelled) => Self::Hold.swipe_right(),
( (
Self::AddressMenuCancel | Self::SummaryMenuCancel | Self::HoldMenuCancel, Self::MainMenuCancel | Self::SummaryMenuCancel | Self::HoldMenuCancel,
FlowMsg::Confirmed, FlowMsg::Confirmed,
) => self.return_msg(FlowMsg::Cancelled), ) => self.return_msg(FlowMsg::Cancelled),
(Self::Address, FlowMsg::Cancelled) => Self::AddressMenu.transit(), (Self::Main, FlowMsg::Cancelled) => Self::MainMenu.transit(),
(Self::Summary, FlowMsg::Cancelled) => Self::SummaryMenu.transit(), (Self::Summary, FlowMsg::Cancelled) => Self::SummaryMenu.transit(),
(Self::Hold, FlowMsg::Cancelled) => Self::HoldMenu.transit(), (Self::Hold, FlowMsg::Cancelled) => Self::HoldMenu.transit(),
(Self::Hold, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed), (Self::Hold, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
@ -213,6 +220,7 @@ pub extern "C" fn new_confirm_output(n_args: usize, args: *const Obj, kwargs: *m
fn new_confirm_output_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Error> { fn new_confirm_output_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Error> {
let title: Option<TString> = kwargs.get(Qstr::MP_QSTR_title)?.try_into_option()?; let title: Option<TString> = kwargs.get(Qstr::MP_QSTR_title)?.try_into_option()?;
let subtitle: Option<TString> = kwargs.get(Qstr::MP_QSTR_subtitle)?.try_into_option()?;
let account: Option<TString> = kwargs.get(Qstr::MP_QSTR_account)?.try_into_option()?; let account: Option<TString> = kwargs.get(Qstr::MP_QSTR_account)?.try_into_option()?;
let account_path: Option<TString> = let account_path: Option<TString> =
@ -221,12 +229,16 @@ fn new_confirm_output_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
let br_name: TString = kwargs.get(Qstr::MP_QSTR_br_name)?.try_into()?; let br_name: TString = kwargs.get(Qstr::MP_QSTR_br_name)?.try_into()?;
let br_code: u16 = kwargs.get(Qstr::MP_QSTR_br_code)?.try_into()?; let br_code: u16 = kwargs.get(Qstr::MP_QSTR_br_code)?.try_into()?;
let address: Obj = kwargs.get(Qstr::MP_QSTR_address)?; let message: Obj = kwargs.get(Qstr::MP_QSTR_message)?;
let amount: Option<Obj> = kwargs.get(Qstr::MP_QSTR_amount)?.try_into_option()?; let amount: Option<Obj> = kwargs.get(Qstr::MP_QSTR_amount)?.try_into_option()?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?; let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let text_mono: bool = kwargs.get_or(Qstr::MP_QSTR_text_mono, true)?; let text_mono: bool = kwargs.get_or(Qstr::MP_QSTR_text_mono, true)?;
let address: Option<Obj> = kwargs.get(Qstr::MP_QSTR_address)?.try_into_option()?;
let address_title: Option<TString> =
kwargs.get(Qstr::MP_QSTR_address_title)?.try_into_option()?;
let summary_items: Obj = kwargs.get(Qstr::MP_QSTR_summary_items)?; let summary_items: Obj = kwargs.get(Qstr::MP_QSTR_summary_items)?;
let fee_items: Obj = kwargs.get(Qstr::MP_QSTR_fee_items)?; let fee_items: Obj = kwargs.get(Qstr::MP_QSTR_fee_items)?;
@ -241,9 +253,9 @@ fn new_confirm_output_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
let cancel_text: Option<TString> = kwargs.get(Qstr::MP_QSTR_cancel_text)?.try_into_option()?; let cancel_text: Option<TString> = kwargs.get(Qstr::MP_QSTR_cancel_text)?.try_into_option()?;
// Address // Main
let content_address = ConfirmBlobParams::new(TR::words__address.into(), address, None) let main_content = ConfirmBlobParams::new(title.unwrap_or(TString::empty()), message, None)
.with_subtitle(title) .with_subtitle(subtitle)
.with_menu_button() .with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None) .with_footer(TR::instructions__swipe_up.into(), None)
.with_chunkify(chunkify) .with_chunkify(chunkify)
@ -251,55 +263,59 @@ fn new_confirm_output_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
.into_layout()? .into_layout()?
.one_button_request(ButtonRequest::from_num(br_code, br_name)); .one_button_request(ButtonRequest::from_num(br_code, br_name));
// AddressMenu // MainMenu
let mut address_menu = VerticalMenu::empty(); let mut main_menu = VerticalMenu::empty();
let mut address_menu_items = Vec::<usize, 2>::new(); let mut main_menu_items = Vec::<usize, 3>::new();
if address.is_some() {
main_menu = main_menu.item(
theme::ICON_CHEVRON_RIGHT,
address_title.unwrap_or(TR::words__address.into()),
);
unwrap!(main_menu_items.push(MENU_ITEM_ADDRESS_INFO));
}
if account.is_some() && account_path.is_some() { if account.is_some() && account_path.is_some() {
address_menu = address_menu.item( main_menu = main_menu.item(
theme::ICON_CHEVRON_RIGHT, theme::ICON_CHEVRON_RIGHT,
TR::address_details__account_info.into(), TR::address_details__account_info.into(),
); );
unwrap!(address_menu_items.push(MENU_ITEM_ACCOUNT_INFO)); unwrap!(main_menu_items.push(MENU_ITEM_ACCOUNT_INFO));
} }
address_menu = address_menu.danger( main_menu = main_menu.danger(
theme::ICON_CANCEL, theme::ICON_CANCEL,
cancel_text.unwrap_or(TR::send__cancel_sign.into()), cancel_text.unwrap_or(TR::send__cancel_sign.into()),
); );
unwrap!(address_menu_items.push(MENU_ITEM_CANCEL)); unwrap!(main_menu_items.push(MENU_ITEM_CANCEL));
let content_address_menu = Frame::left_aligned(TString::empty(), address_menu) let content_main_menu = Frame::left_aligned(TString::empty(), main_menu)
.with_cancel_button() .with_cancel_button()
.with_swipe(SwipeDirection::Right, SwipeSettings::immediate()) .with_swipe(SwipeDirection::Right, SwipeSettings::immediate())
.map(move |msg| match msg { .map(move |msg| match msg {
FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => { FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => {
let selected_item = address_menu_items[i]; let selected_item = main_menu_items[i];
Some(FlowMsg::Choice(selected_item)) Some(FlowMsg::Choice(selected_item))
} }
FrameMsg::Button(_) => Some(FlowMsg::Cancelled), FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
}); });
// AccountInfo // AccountInfo
let ad = AddressDetails::new(TR::send__send_from.into(), account, account_path)?; let ac = AddressDetails::new(TR::send__send_from.into(), account, account_path)?;
let content_account = ad.map(|_| Some(FlowMsg::Cancelled)); let account_content = ac.map(|_| Some(FlowMsg::Cancelled));
let res = if amount.is_some() { let res = if amount.is_some() {
let content_amount = ConfirmBlobParams::new( let content_amount =
TR::words__amount.into(), ConfirmBlobParams::new(TR::words__amount.into(), amount.unwrap(), None)
amount.unwrap_or(Obj::const_none()), .with_subtitle(subtitle)
None, .with_menu_button()
) .with_footer(TR::instructions__swipe_up.into(), None)
.with_subtitle(title) .with_text_mono(text_mono)
.with_menu_button() .with_swipe_down()
.with_footer(TR::instructions__swipe_up.into(), None) .into_layout()?
.with_text_mono(text_mono) .one_button_request(ButtonRequest::from_num(br_code, br_name));
.with_swipe_down()
.into_layout()?
.one_button_request(ButtonRequest::from_num(br_code, br_name));
SwipeFlow::new(&ConfirmOutputWithAmount::Address)? SwipeFlow::new(&ConfirmOutputWithAmount::Address)?
.with_page(&ConfirmOutputWithAmount::Address, content_address)? .with_page(&ConfirmOutputWithAmount::Address, main_content)?
.with_page(&ConfirmOutputWithAmount::Amount, content_amount)? .with_page(&ConfirmOutputWithAmount::Amount, content_amount)?
.with_page(&ConfirmOutputWithAmount::Menu, content_address_menu)? .with_page(&ConfirmOutputWithAmount::Menu, content_main_menu)?
.with_page(&ConfirmOutputWithAmount::AccountInfo, content_account)? .with_page(&ConfirmOutputWithAmount::AccountInfo, account_content)?
.with_page(&ConfirmOutputWithAmount::CancelTap, get_cancel_page())? .with_page(&ConfirmOutputWithAmount::CancelTap, get_cancel_page())?
} else if summary_items != Obj::const_none() { } else if summary_items != Obj::const_none() {
// Summary // Summary
@ -389,14 +405,31 @@ fn new_confirm_output_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
FrameMsg::Button(_) => Some(FlowMsg::Cancelled), FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
}); });
SwipeFlow::new(&ConfirmOutputWithSummary::Address)? let mut flow = SwipeFlow::new(&ConfirmOutputWithSummary::Main)?
.with_page(&ConfirmOutputWithSummary::Address, content_address)? .with_page(&ConfirmOutputWithSummary::Main, main_content)?
.with_page(&ConfirmOutputWithSummary::AddressMenu, content_address_menu)? .with_page(&ConfirmOutputWithSummary::MainMenu, content_main_menu)?
.with_page( .with_page(&ConfirmOutputWithSummary::MainMenuCancel, get_cancel_page())?;
&ConfirmOutputWithSummary::AddressMenuCancel, if address.is_some() {
get_cancel_page(), let address_content = ConfirmBlobParams::new(
)? address_title.unwrap_or(TR::words__address.into()),
.with_page(&ConfirmOutputWithSummary::Summary, content_summary)? address.unwrap(),
None,
)
.with_cancel_button()
.with_chunkify(true)
.with_text_mono(true)
.into_layout()?;
flow = flow.with_page(&ConfirmOutputWithSummary::AddressInfo, address_content)?;
} else {
// dummy page - this will never be shown since there is no menu item pointing to
// it, but the page has to exist in the flow
flow = flow.with_page(
&ConfirmOutputWithSummary::AddressInfo,
Frame::left_aligned(TString::empty(), VerticalMenu::empty())
.map(|_| Some(FlowMsg::Cancelled)),
)?;
}
flow.with_page(&ConfirmOutputWithSummary::Summary, content_summary)?
.with_page(&ConfirmOutputWithSummary::SummaryMenu, content_summary_menu)? .with_page(&ConfirmOutputWithSummary::SummaryMenu, content_summary_menu)?
.with_page( .with_page(
&ConfirmOutputWithSummary::SummaryMenuCancel, &ConfirmOutputWithSummary::SummaryMenuCancel,
@ -406,12 +439,12 @@ fn new_confirm_output_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
.with_page(&ConfirmOutputWithSummary::Hold, content_hold)? .with_page(&ConfirmOutputWithSummary::Hold, content_hold)?
.with_page(&ConfirmOutputWithSummary::HoldMenu, content_hold_menu)? .with_page(&ConfirmOutputWithSummary::HoldMenu, content_hold_menu)?
.with_page(&ConfirmOutputWithSummary::HoldMenuCancel, get_cancel_page())? .with_page(&ConfirmOutputWithSummary::HoldMenuCancel, get_cancel_page())?
.with_page(&ConfirmOutputWithSummary::AccountInfo, content_account)? .with_page(&ConfirmOutputWithSummary::AccountInfo, account_content)?
} else { } else {
SwipeFlow::new(&ConfirmOutput::Address)? SwipeFlow::new(&ConfirmOutput::Address)?
.with_page(&ConfirmOutput::Address, content_address)? .with_page(&ConfirmOutput::Address, main_content)?
.with_page(&ConfirmOutput::Menu, content_address_menu)? .with_page(&ConfirmOutput::Menu, content_main_menu)?
.with_page(&ConfirmOutput::AccountInfo, content_account)? .with_page(&ConfirmOutput::AccountInfo, account_content)?
.with_page(&ConfirmOutput::CancelTap, get_cancel_page())? .with_page(&ConfirmOutput::CancelTap, get_cancel_page())?
}; };

View File

@ -30,6 +30,7 @@ pub struct ConfirmBlobParams {
description: Option<TString<'static>>, description: Option<TString<'static>>,
extra: Option<TString<'static>>, extra: Option<TString<'static>>,
menu_button: bool, menu_button: bool,
cancel_button: bool,
chunkify: bool, chunkify: bool,
text_mono: bool, text_mono: bool,
swipe_down: bool, swipe_down: bool,
@ -50,6 +51,7 @@ impl ConfirmBlobParams {
description, description,
extra: None, extra: None,
menu_button: false, menu_button: false,
cancel_button: false,
chunkify: false, chunkify: false,
text_mono: true, text_mono: true,
swipe_down: false, swipe_down: false,
@ -71,6 +73,11 @@ impl ConfirmBlobParams {
self self
} }
pub const fn with_cancel_button(mut self) -> Self {
self.cancel_button = true;
self
}
pub const fn with_swipe_down(mut self) -> Self { pub const fn with_swipe_down(mut self) -> Self {
self.swipe_down = true; self.swipe_down = true;
self self
@ -128,6 +135,9 @@ impl ConfirmBlobParams {
if self.menu_button { if self.menu_button {
frame = frame.with_menu_button(); frame = frame.with_menu_button();
} }
if self.cancel_button {
frame = frame.with_cancel_button();
}
if let Some(instruction) = self.footer_instruction { if let Some(instruction) = self.footer_instruction {
frame = frame.with_footer(instruction, self.footer_description); frame = frame.with_footer(instruction, self.footer_description);
frame = frame.with_swipe(SwipeDirection::Left, SwipeSettings::default()); frame = frame.with_swipe(SwipeDirection::Left, SwipeSettings::default());

View File

@ -1678,13 +1678,17 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// def flow_confirm_output( /// def flow_confirm_output(
/// *, /// *,
/// title: str | None, /// title: str | None,
/// address: str, /// subtitle: str | None,
/// message: str,
/// amount: str | None, /// amount: str | None,
/// chunkify: bool, /// chunkify: bool,
/// text_mono: bool,
/// account: str | None, /// account: str | None,
/// account_path: str | None, /// account_path: str | None,
/// br_code: ButtonRequestType, /// br_code: ButtonRequestType,
/// br_name: str, /// br_name: str,
/// address: str | None,
/// address_title: str | None,
/// summary_items: Iterable[tuple[str, str]] | None = None, /// summary_items: Iterable[tuple[str, str]] | None = None,
/// fee_items: Iterable[tuple[str, str]] | None = None, /// fee_items: Iterable[tuple[str, str]] | None = None,
/// summary_title: str | None = None, /// summary_title: str | None = None,

View File

@ -573,13 +573,17 @@ def flow_warning_hi_prio(
def flow_confirm_output( def flow_confirm_output(
*, *,
title: str | None, title: str | None,
address: str, subtitle: str | None,
message: str,
amount: str | None, amount: str | None,
chunkify: bool, chunkify: bool,
text_mono: bool,
account: str | None, account: str | None,
account_path: str | None, account_path: str | None,
br_code: ButtonRequestType, br_code: ButtonRequestType,
br_name: str, br_name: str,
address: str | None,
address_title: str | None,
summary_items: Iterable[tuple[str, str]] | None = None, summary_items: Iterable[tuple[str, str]] | None = None,
fee_items: Iterable[tuple[str, str]] | None = None, fee_items: Iterable[tuple[str, str]] | None = None,
summary_title: str | None = None, summary_title: str | None = None,

View File

@ -649,12 +649,16 @@ async def confirm_output(
await raise_if_not_confirmed( await raise_if_not_confirmed(
RustLayout( RustLayout(
trezorui2.flow_confirm_output( trezorui2.flow_confirm_output(
title=title, title=TR.words__address,
address=address, subtitle=title,
message=address,
amount=amount, amount=amount,
chunkify=chunkify, chunkify=chunkify,
text_mono=True,
account=source_account, account=source_account,
account_path=source_account_path, account_path=source_account_path,
address=None,
address_title=None,
br_code=br_code, br_code=br_code,
br_name="confirm_output", br_name="confirm_output",
summary_items=None, summary_items=None,
@ -1032,12 +1036,16 @@ if not utils.BITCOIN_ONLY:
await raise_if_not_confirmed( await raise_if_not_confirmed(
RustLayout( RustLayout(
trezorui2.flow_confirm_output( trezorui2.flow_confirm_output(
title=TR.words__recipient, title=TR.words__address,
address=recipient, subtitle=TR.words__recipient,
message=recipient,
amount=None, amount=None,
chunkify=chunkify, chunkify=chunkify,
text_mono=True,
account=None, account=None,
account_path=None, account_path=None,
address=None,
address_title=None,
br_code=ButtonRequestType.Other, br_code=ButtonRequestType.Other,
br_name="confirm_output", br_name="confirm_output",
summary_items=( summary_items=(
@ -1066,36 +1074,36 @@ if not utils.BITCOIN_ONLY:
br_name: str = "confirm_ethereum_staking_tx", br_name: str = "confirm_ethereum_staking_tx",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
) -> None: ) -> None:
# intro
await confirm_value(
title,
intro_question,
"",
br_name,
br_code,
verb=verb,
value_text_mono=False,
info_items=(("", address),),
info_title=address_title,
chunkify_info=chunkify,
)
# confirmation
if verb == TR.ethereum__staking_claim: if verb == TR.ethereum__staking_claim:
items = ((TR.send__maximum_fee, maximum_fee),) summary_items = ((TR.send__maximum_fee, maximum_fee),)
else: else:
items = ( summary_items = (
(TR.words__amount, total_amount), (TR.words__amount, total_amount),
(TR.send__maximum_fee, maximum_fee), (TR.send__maximum_fee, maximum_fee),
) )
await _confirm_summary( await raise_if_not_confirmed(
items=items, RustLayout(
title=title, trezorui2.flow_confirm_output(
info_title=TR.confirm_total__title_fee, title=verb,
info_items=info_items, subtitle=None,
br_name=br_name, message=intro_question,
br_code=br_code, amount=None,
chunkify=False,
text_mono=False,
account=None,
account_path=None,
br_code=br_code,
br_name=br_name,
address=address,
address_title=address_title,
summary_items=summary_items,
fee_items=info_items,
summary_title=verb,
summary_br_name="confirm_total",
summary_br_code=ButtonRequestType.SignTx,
cancel_text=TR.buttons__cancel, # cancel staking
)
)
) )
def confirm_solana_tx( def confirm_solana_tx(