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:
parent
c5f9fadbd1
commit
ba8f0ea4bc
1
core/.changelog.d/noissue.fixed
Normal file
1
core/.changelog.d/noissue.fixed
Normal file
@ -0,0 +1 @@
|
|||||||
|
[T3T1] Improved ETH staking flow.
|
@ -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;
|
||||||
|
@ -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())?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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());
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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(
|
||||||
|
Loading…
Reference in New Issue
Block a user