1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-19 05:58:09 +00:00

feat(core): improve ETH send flow

This commit is contained in:
Ioan Bizău 2024-08-08 15:13:43 +02:00 committed by Ioan Bizău
parent 07ac2fd4d8
commit 09d3301785
19 changed files with 356 additions and 267 deletions

View File

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

View File

@ -168,6 +168,7 @@ static void _librust_qstrs(void) {
MP_QSTR_can_go_back; MP_QSTR_can_go_back;
MP_QSTR_cancel_arrow; MP_QSTR_cancel_arrow;
MP_QSTR_cancel_cross; MP_QSTR_cancel_cross;
MP_QSTR_cancel_text;
MP_QSTR_case_sensitive; MP_QSTR_case_sensitive;
MP_QSTR_check_homescreen_format; MP_QSTR_check_homescreen_format;
MP_QSTR_chunkify; MP_QSTR_chunkify;

View File

@ -449,11 +449,11 @@ pub enum TranslatedString {
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
ethereum__data_size_template = 273, // "Size: {0} bytes" ethereum__data_size_template = 273, // "Size: {0} bytes"
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
ethereum__gas_limit = 274, // "Gas limit:" ethereum__gas_limit = 274, // "Gas limit"
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
ethereum__gas_price = 275, // "Gas price:" ethereum__gas_price = 275, // "Gas price"
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
ethereum__max_gas_price = 276, // "Max gas price:" ethereum__max_gas_price = 276, // "Max gas price"
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
ethereum__name_and_version = 277, // "Name and version" ethereum__name_and_version = 277, // "Name and version"
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
@ -461,7 +461,7 @@ pub enum TranslatedString {
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
ethereum__no_message_field = 279, // "No message field" ethereum__no_message_field = 279, // "No message field"
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
ethereum__priority_fee = 280, // "Priority fee:" ethereum__priority_fee = 280, // "Priority fee"
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
ethereum__show_full_array = 281, // "Show full array" ethereum__show_full_array = 281, // "Show full array"
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
@ -931,7 +931,7 @@ pub enum TranslatedString {
send__confirm_sending = 641, // "Sending amount" send__confirm_sending = 641, // "Sending amount"
send__from_multiple_accounts = 642, // "Sending from multiple accounts." send__from_multiple_accounts = 642, // "Sending from multiple accounts."
send__including_fee = 643, // "Including fee:" send__including_fee = 643, // "Including fee:"
send__maximum_fee = 644, // "Maximum fee:" send__maximum_fee = 644, // "Maximum fee"
send__receiving_to_multisig = 645, // "Receiving to a multisig address." send__receiving_to_multisig = 645, // "Receiving to a multisig address."
send__title_confirm_sending = 646, // "Confirm sending" send__title_confirm_sending = 646, // "Confirm sending"
send__title_joint_transaction = 647, // "Joint transaction" send__title_joint_transaction = 647, // "Joint transaction"
@ -1801,11 +1801,11 @@ impl TranslatedString {
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
Self::ethereum__data_size_template => "Size: {0} bytes", Self::ethereum__data_size_template => "Size: {0} bytes",
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
Self::ethereum__gas_limit => "Gas limit:", Self::ethereum__gas_limit => "Gas limit",
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
Self::ethereum__gas_price => "Gas price:", Self::ethereum__gas_price => "Gas price",
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
Self::ethereum__max_gas_price => "Max gas price:", Self::ethereum__max_gas_price => "Max gas price",
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
Self::ethereum__name_and_version => "Name and version", Self::ethereum__name_and_version => "Name and version",
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
@ -1813,7 +1813,7 @@ impl TranslatedString {
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
Self::ethereum__no_message_field => "No message field", Self::ethereum__no_message_field => "No message field",
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
Self::ethereum__priority_fee => "Priority fee:", Self::ethereum__priority_fee => "Priority fee",
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
Self::ethereum__show_full_array => "Show full array", Self::ethereum__show_full_array => "Show full array",
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
@ -2283,7 +2283,7 @@ impl TranslatedString {
Self::send__confirm_sending => "Sending amount", Self::send__confirm_sending => "Sending amount",
Self::send__from_multiple_accounts => "Sending from multiple accounts.", Self::send__from_multiple_accounts => "Sending from multiple accounts.",
Self::send__including_fee => "Including fee:", Self::send__including_fee => "Including fee:",
Self::send__maximum_fee => "Maximum fee:", Self::send__maximum_fee => "Maximum fee",
Self::send__receiving_to_multisig => "Receiving to a multisig address.", Self::send__receiving_to_multisig => "Receiving to a multisig address.",
Self::send__title_confirm_sending => "Confirm sending", Self::send__title_confirm_sending => "Confirm sending",
Self::send__title_joint_transaction => "Joint transaction", Self::send__title_joint_transaction => "Joint transaction",

View File

@ -1,3 +1,5 @@
use heapless::Vec;
use crate::{ use crate::{
error, error,
micropython::{map::Map, obj::Obj, qstr::Qstr, util}, micropython::{map::Map, obj::Obj, qstr::Qstr, util},
@ -25,11 +27,12 @@ use super::{
util::ConfirmBlobParams, util::ConfirmBlobParams,
}; };
const MENU_ITEM_CANCEL: usize = 0;
const MENU_ITEM_ACCOUNT_INFO: usize = 1;
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub enum ConfirmOutput { pub enum ConfirmOutput {
Address, Address,
Amount,
// Tap,
Menu, Menu,
AccountInfo, AccountInfo,
CancelTap, CancelTap,
@ -41,6 +44,47 @@ impl FlowState for ConfirmOutput {
*self as usize *self as usize
} }
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
match (self, direction) {
(Self::Address, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Address, SwipeDirection::Up) => self.return_msg(FlowMsg::Confirmed),
(Self::Menu, SwipeDirection::Right) => Self::Address.swipe(direction),
(Self::Menu, SwipeDirection::Left) => Self::AccountInfo.swipe(direction),
(Self::AccountInfo | Self::CancelTap, SwipeDirection::Right) => {
Self::Menu.swipe(direction)
}
_ => self.do_nothing(),
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) {
(_, FlowMsg::Info) => Self::Menu.transit(),
(Self::Menu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => Self::CancelTap.swipe_left(),
(Self::Menu, FlowMsg::Choice(MENU_ITEM_ACCOUNT_INFO)) => Self::AccountInfo.transit(),
(Self::Menu, FlowMsg::Cancelled) => Self::Address.swipe_right(),
(Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
(_, FlowMsg::Cancelled) => Self::Menu.transit(),
_ => self.do_nothing(),
}
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum ConfirmOutputWithAmount {
Address,
Amount,
Menu,
AccountInfo,
CancelTap,
}
impl FlowState for ConfirmOutputWithAmount {
#[inline]
fn index(&'static self) -> usize {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange { fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
match (self, direction) { match (self, direction) {
(Self::Address | Self::Amount, SwipeDirection::Left) => Self::Menu.swipe(direction), (Self::Address | Self::Amount, SwipeDirection::Left) => Self::Menu.swipe(direction),
@ -48,7 +92,6 @@ impl FlowState for ConfirmOutput {
(Self::Amount, SwipeDirection::Up) => self.return_msg(FlowMsg::Confirmed), (Self::Amount, SwipeDirection::Up) => self.return_msg(FlowMsg::Confirmed),
(Self::Amount, SwipeDirection::Down) => Self::Address.swipe(direction), (Self::Amount, SwipeDirection::Down) => Self::Address.swipe(direction),
(Self::Menu, SwipeDirection::Right) => Self::Address.swipe(direction), (Self::Menu, SwipeDirection::Right) => Self::Address.swipe(direction),
(Self::Menu, SwipeDirection::Left) => Self::AccountInfo.swipe(direction),
(Self::AccountInfo | Self::CancelTap, SwipeDirection::Right) => { (Self::AccountInfo | Self::CancelTap, SwipeDirection::Right) => {
Self::Menu.swipe(direction) Self::Menu.swipe(direction)
} }
@ -71,85 +114,107 @@ impl FlowState for ConfirmOutput {
#[allow(clippy::not_unsafe_ptr_arg_deref)] #[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn new_confirm_output(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { pub extern "C" fn new_confirm_output(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, ConfirmOutput::new_obj) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, new_confirm_output_obj) }
} }
impl ConfirmOutput { fn new_confirm_output_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Error> {
const EXTRA_PADDING: i16 = 6; let title: Option<TString> = kwargs.get(Qstr::MP_QSTR_title)?.try_into_option()?;
let account: Option<TString> = kwargs.get(Qstr::MP_QSTR_account)?.try_into_option()?;
let account_path: Option<TString> =
kwargs.get(Qstr::MP_QSTR_account_path)?.try_into_option()?;
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()?;
fn new_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Error> { let address: Obj = kwargs.get(Qstr::MP_QSTR_address)?;
let title: Option<TString> = kwargs.get(Qstr::MP_QSTR_title)?.try_into_option()?; let amount: Option<Obj> = kwargs.get(Qstr::MP_QSTR_amount)?.try_into_option()?;
let account: Option<TString> = kwargs.get(Qstr::MP_QSTR_account)?.try_into_option()?;
let account_path: Option<TString> =
kwargs.get(Qstr::MP_QSTR_account_path)?.try_into_option()?;
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 address: Obj = kwargs.get(Qstr::MP_QSTR_address)?; let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let amount: Obj = kwargs.get(Qstr::MP_QSTR_amount)?; let text_mono: bool = kwargs.get_or(Qstr::MP_QSTR_text_mono, true)?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?; let cancel_text: Option<TString> = kwargs.get(Qstr::MP_QSTR_cancel_text)?.try_into_option()?;
let text_mono: bool = kwargs.get_or(Qstr::MP_QSTR_text_mono, true)?;
// Address // Address
let content_address = ConfirmBlobParams::new(TR::words__address.into(), address, None) let content_address = ConfirmBlobParams::new(TR::words__address.into(), address, None)
.with_subtitle(title) .with_subtitle(title)
.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)
.with_text_mono(text_mono) .with_text_mono(text_mono)
.into_layout()? .into_layout()?
.one_button_request(ButtonRequest::from_num(br_code, br_name)); .one_button_request(ButtonRequest::from_num(br_code, br_name));
// Amount // Menu
let content_amount = ConfirmBlobParams::new(TR::words__amount.into(), amount, None) let mut menu = VerticalMenu::empty();
.with_subtitle(title) let mut menu_items = Vec::<usize, 3>::new();
.with_menu_button() if account.is_some() && account_path.is_some() {
.with_footer(TR::instructions__swipe_up.into(), None) menu = menu.item(
.with_text_mono(text_mono) theme::ICON_CHEVRON_RIGHT,
.with_swipe_down() TR::address_details__account_info.into(),
.into_layout()? );
.one_button_request(ButtonRequest::from_num(br_code, br_name)); menu_items.push(MENU_ITEM_ACCOUNT_INFO);
}
// Menu menu = menu.danger(
let content_menu = Frame::left_aligned( theme::ICON_CANCEL,
"".into(), cancel_text.unwrap_or(TR::send__cancel_sign.into()),
VerticalMenu::empty() );
.item(theme::ICON_CHEVRON_RIGHT, "Account info".into()) unwrap!(menu_items.push(MENU_ITEM_CANCEL));
.danger(theme::ICON_CANCEL, "Cancel sign".into()), let content_menu = Frame::left_aligned(TString::empty(), menu)
)
.with_cancel_button() .with_cancel_button()
.with_swipe(SwipeDirection::Right, SwipeSettings::immediate()) .with_swipe(SwipeDirection::Right, SwipeSettings::immediate())
.map(|msg| match msg { .map(move |msg| match msg {
FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => Some(FlowMsg::Choice(i)), FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => {
let selected_item = menu_items[i];
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 ad = AddressDetails::new(TR::send__send_from.into(), account, account_path)?;
let content_account = ad.map(|_| Some(FlowMsg::Cancelled)); let content_account = ad.map(|_| Some(FlowMsg::Cancelled));
// CancelTap // CancelTap
let content_cancel_tap = Frame::left_aligned( let content_cancel_tap = Frame::left_aligned(
TR::send__cancel_sign.into(), TR::send__cancel_sign.into(),
SwipeContent::new(PromptScreen::new_tap_to_cancel()), SwipeContent::new(PromptScreen::new_tap_to_cancel()),
)
.with_cancel_button()
.with_footer(TR::instructions__tap_to_confirm.into(), None)
.with_swipe(SwipeDirection::Down, SwipeSettings::default())
.with_swipe(SwipeDirection::Left, SwipeSettings::default())
.map(|msg| match msg {
FrameMsg::Content(PromptMsg::Confirmed) => Some(FlowMsg::Confirmed),
FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
_ => None,
});
let res = if amount.is_some() {
let content_amount = ConfirmBlobParams::new(
TR::words__amount.into(),
amount.unwrap_or(Obj::const_none()),
None,
) )
.with_cancel_button() .with_subtitle(title)
.with_footer(TR::instructions__tap_to_confirm.into(), None) .with_menu_button()
.with_swipe(SwipeDirection::Down, SwipeSettings::default()) .with_footer(TR::instructions__swipe_up.into(), None)
.with_swipe(SwipeDirection::Left, SwipeSettings::default()) .with_text_mono(text_mono)
.map(|msg| match msg { .with_swipe_down()
FrameMsg::Content(PromptMsg::Confirmed) => Some(FlowMsg::Confirmed), .into_layout()?
FrameMsg::Button(_) => Some(FlowMsg::Cancelled), .one_button_request(ButtonRequest::from_num(br_code, br_name));
_ => None,
});
let res = SwipeFlow::new(&ConfirmOutput::Address)? SwipeFlow::new(&ConfirmOutputWithAmount::Address)?
.with_page(&ConfirmOutputWithAmount::Address, content_address)?
.with_page(&ConfirmOutputWithAmount::Amount, content_amount)?
.with_page(&ConfirmOutputWithAmount::Menu, content_menu)?
.with_page(&ConfirmOutputWithAmount::AccountInfo, content_account)?
.with_page(&ConfirmOutputWithAmount::CancelTap, content_cancel_tap)?
} else {
SwipeFlow::new(&ConfirmOutput::Address)?
.with_page(&ConfirmOutput::Address, content_address)? .with_page(&ConfirmOutput::Address, content_address)?
.with_page(&ConfirmOutput::Amount, content_amount)?
.with_page(&ConfirmOutput::Menu, content_menu)? .with_page(&ConfirmOutput::Menu, content_menu)?
.with_page(&ConfirmOutput::AccountInfo, content_account)? .with_page(&ConfirmOutput::AccountInfo, content_account)?
.with_page(&ConfirmOutput::CancelTap, content_cancel_tap)?; .with_page(&ConfirmOutput::CancelTap, content_cancel_tap)?
Ok(LayoutObj::new(res)?.into()) };
}
Ok(LayoutObj::new(res)?.into())
} }

View File

@ -1,3 +1,5 @@
use heapless::Vec;
use crate::{ use crate::{
error, error,
micropython::{iter::IterBuf, map::Map, obj::Obj, qstr::Qstr, util}, micropython::{iter::IterBuf, map::Map, obj::Obj, qstr::Qstr, util},
@ -25,6 +27,10 @@ use super::{
util::ShowInfoParams, util::ShowInfoParams,
}; };
const MENU_ITEM_CANCEL: usize = 0;
const MENU_ITEM_FEE_INFO: usize = 1;
const MENU_ITEM_ACCOUNT_INFO: usize = 2;
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub enum ConfirmSummary { pub enum ConfirmSummary {
Summary, Summary,
@ -59,9 +65,9 @@ impl FlowState for ConfirmSummary {
match (self, msg) { match (self, msg) {
(_, FlowMsg::Info) => Self::Menu.transit(), (_, FlowMsg::Info) => Self::Menu.transit(),
(Self::Hold, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed), (Self::Hold, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
(Self::Menu, FlowMsg::Choice(0)) => Self::FeeInfo.swipe_left(), (Self::Menu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => Self::CancelTap.swipe_left(),
(Self::Menu, FlowMsg::Choice(1)) => Self::AccountInfo.swipe_left(), (Self::Menu, FlowMsg::Choice(MENU_ITEM_FEE_INFO)) => Self::FeeInfo.swipe_left(),
(Self::Menu, FlowMsg::Choice(2)) => Self::CancelTap.swipe_left(), (Self::Menu, FlowMsg::Choice(MENU_ITEM_ACCOUNT_INFO)) => Self::AccountInfo.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Summary.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::Summary.swipe_right(),
(Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled), (Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
(_, FlowMsg::Cancelled) => Self::Menu.transit(), (_, FlowMsg::Cancelled) => Self::Menu.transit(),
@ -83,6 +89,8 @@ impl ConfirmSummary {
let fee_items: Obj = kwargs.get(Qstr::MP_QSTR_fee_items)?; let fee_items: Obj = kwargs.get(Qstr::MP_QSTR_fee_items)?;
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 cancel_text: Option<TString> =
kwargs.get(Qstr::MP_QSTR_cancel_text)?.try_into_option()?;
// Summary // Summary
let mut summary = ShowInfoParams::new(title) let mut summary = ShowInfoParams::new(title)
@ -114,37 +122,59 @@ impl ConfirmSummary {
_ => None, _ => None,
}); });
// Menu
let content_menu = Frame::left_aligned(
"".into(),
VerticalMenu::empty()
.item(theme::ICON_CHEVRON_RIGHT, "Fee info".into())
.item(theme::ICON_CHEVRON_RIGHT, "Account info".into())
.danger(theme::ICON_CANCEL, "Cancel sign".into()),
)
.with_cancel_button()
.with_swipe(SwipeDirection::Right, SwipeSettings::immediate())
.map(|msg| match msg {
FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => Some(FlowMsg::Choice(i)),
FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
});
// FeeInfo // FeeInfo
let mut has_fee_info = false;
let mut fee = ShowInfoParams::new(TR::confirm_total__title_fee.into()).with_cancel_button(); let mut fee = ShowInfoParams::new(TR::confirm_total__title_fee.into()).with_cancel_button();
for pair in IterBuf::new().try_iterate(fee_items)? { for pair in IterBuf::new().try_iterate(fee_items)? {
let [label, value]: [TString; 2] = util::iter_into_array(pair)?; let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
fee = unwrap!(fee.add(label, value)); fee = unwrap!(fee.add(label, value));
has_fee_info = true;
} }
let content_fee = fee.into_layout()?; let content_fee = fee.into_layout()?;
// AccountInfo // AccountInfo
let mut has_account_info = false;
let mut account = ShowInfoParams::new(TR::send__send_from.into()).with_cancel_button(); let mut account = ShowInfoParams::new(TR::send__send_from.into()).with_cancel_button();
for pair in IterBuf::new().try_iterate(account_items)? { for pair in IterBuf::new().try_iterate(account_items)? {
let [label, value]: [TString; 2] = util::iter_into_array(pair)?; let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
account = unwrap!(account.add(label, value)); account = unwrap!(account.add(label, value));
has_account_info = true;
} }
let content_account = account.into_layout()?; let content_account = account.into_layout()?;
// Menu
let mut menu = VerticalMenu::empty();
let mut menu_items = Vec::<usize, 3>::new();
if has_fee_info {
menu = menu.item(
theme::ICON_CHEVRON_RIGHT,
TR::confirm_total__title_fee.into(),
);
menu_items.push(MENU_ITEM_FEE_INFO);
}
if has_account_info {
menu = menu.item(
theme::ICON_CHEVRON_RIGHT,
TR::address_details__account_info.into(),
);
menu_items.push(MENU_ITEM_ACCOUNT_INFO);
}
menu = menu.danger(
theme::ICON_CANCEL,
cancel_text.unwrap_or(TR::send__cancel_sign.into()),
);
unwrap!(menu_items.push(MENU_ITEM_CANCEL));
let content_menu = Frame::left_aligned(TString::empty(), menu)
.with_cancel_button()
.with_swipe(SwipeDirection::Right, SwipeSettings::immediate())
.map(move |msg| match msg {
FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => {
let selected_item = menu_items[i];
Some(FlowMsg::Choice(selected_item))
}
FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
});
// CancelTap // CancelTap
let content_cancel_tap = Frame::left_aligned( let content_cancel_tap = Frame::left_aligned(
TR::send__cancel_sign.into(), TR::send__cancel_sign.into(),

View File

@ -15,7 +15,7 @@ use crate::{
Component, SwipeDirection, Component, SwipeDirection,
}, },
flow::{FlowMsg, Swipable, SwipePage}, flow::{FlowMsg, Swipable, SwipePage},
layout::util::ConfirmBlob, layout::util::{ConfirmBlob, StrOrBytes},
model_mercury::component::SwipeContent, model_mercury::component::SwipeContent,
}, },
}; };
@ -102,7 +102,11 @@ impl ConfirmBlobParams {
let paragraphs = ConfirmBlob { let paragraphs = ConfirmBlob {
description: self.description.unwrap_or("".into()), description: self.description.unwrap_or("".into()),
extra: self.extra.unwrap_or("".into()), extra: self.extra.unwrap_or("".into()),
data: self.data.try_into()?, data: if self.data != Obj::const_none() {
self.data.try_into()?
} else {
StrOrBytes::Str("".into())
},
description_font: &theme::TEXT_NORMAL, description_font: &theme::TEXT_NORMAL,
extra_font: &theme::TEXT_DEMIBOLD, extra_font: &theme::TEXT_DEMIBOLD,
data_font: if self.chunkify { data_font: if self.chunkify {

View File

@ -1758,12 +1758,13 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *, /// *,
/// title: str | None, /// title: str | None,
/// address: str, /// address: str,
/// amount: str, /// amount: str | None,
/// chunkify: bool, /// chunkify: 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,
/// cancel_text: str | None = None,
/// ) -> LayoutObj[UiResult]: /// ) -> LayoutObj[UiResult]:
/// """Confirm recipient.""" /// """Confirm recipient."""
Qstr::MP_QSTR_flow_confirm_output => obj_fn_kw!(0, flow::new_confirm_output).as_obj(), Qstr::MP_QSTR_flow_confirm_output => obj_fn_kw!(0, flow::new_confirm_output).as_obj(),
@ -1776,6 +1777,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// fee_items: Iterable[tuple[str, str]], /// fee_items: Iterable[tuple[str, str]],
/// br_code: ButtonRequestType, /// br_code: ButtonRequestType,
/// br_name: str, /// br_name: str,
/// cancel_text: str | None = None,
/// ) -> LayoutObj[UiResult]: /// ) -> LayoutObj[UiResult]:
/// """Total summary and hold to confirm.""" /// """Total summary and hold to confirm."""
Qstr::MP_QSTR_flow_confirm_summary => obj_fn_kw!(0, flow::new_confirm_summary).as_obj(), Qstr::MP_QSTR_flow_confirm_summary => obj_fn_kw!(0, flow::new_confirm_summary).as_obj(),

View File

@ -579,12 +579,13 @@ def flow_confirm_output(
*, *,
title: str | None, title: str | None,
address: str, address: str,
amount: str, amount: str | None,
chunkify: bool, chunkify: 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,
cancel_text: str | None = None,
) -> LayoutObj[UiResult]: ) -> LayoutObj[UiResult]:
"""Confirm recipient.""" """Confirm recipient."""
@ -598,6 +599,7 @@ def flow_confirm_summary(
fee_items: Iterable[tuple[str, str]], fee_items: Iterable[tuple[str, str]],
br_code: ButtonRequestType, br_code: ButtonRequestType,
br_name: str, br_name: str,
cancel_text: str | None = None,
) -> LayoutObj[UiResult]: ) -> LayoutObj[UiResult]:
"""Total summary and hold to confirm.""" """Total summary and hold to confirm."""

View File

@ -297,13 +297,13 @@ class TR:
ethereum__amount_sent: str = "Amount sent:" ethereum__amount_sent: str = "Amount sent:"
ethereum__contract: str = "Contract:" ethereum__contract: str = "Contract:"
ethereum__data_size_template: str = "Size: {0} bytes" ethereum__data_size_template: str = "Size: {0} bytes"
ethereum__gas_limit: str = "Gas limit:" ethereum__gas_limit: str = "Gas limit"
ethereum__gas_price: str = "Gas price:" ethereum__gas_price: str = "Gas price"
ethereum__max_gas_price: str = "Max gas price:" ethereum__max_gas_price: str = "Max gas price"
ethereum__name_and_version: str = "Name and version" ethereum__name_and_version: str = "Name and version"
ethereum__new_contract: str = "new contract?" ethereum__new_contract: str = "new contract?"
ethereum__no_message_field: str = "No message field" ethereum__no_message_field: str = "No message field"
ethereum__priority_fee: str = "Priority fee:" ethereum__priority_fee: str = "Priority fee"
ethereum__show_full_array: str = "Show full array" ethereum__show_full_array: str = "Show full array"
ethereum__show_full_domain: str = "Show full domain" ethereum__show_full_domain: str = "Show full domain"
ethereum__show_full_message: str = "Show full message" ethereum__show_full_message: str = "Show full message"
@ -732,7 +732,7 @@ class TR:
send__from_multiple_accounts: str = "Sending from multiple accounts." send__from_multiple_accounts: str = "Sending from multiple accounts."
send__incl_transaction_fee: str = "incl. Transaction fee" send__incl_transaction_fee: str = "incl. Transaction fee"
send__including_fee: str = "Including fee:" send__including_fee: str = "Including fee:"
send__maximum_fee: str = "Maximum fee:" send__maximum_fee: str = "Maximum fee"
send__receiving_to_multisig: str = "Receiving to a multisig address." send__receiving_to_multisig: str = "Receiving to a multisig address."
send__send_from: str = "Send from" send__send_from: str = "Send from"
send__sign_transaction: str = "Sign transaction" send__sign_transaction: str = "Sign transaction"

View File

@ -625,7 +625,7 @@ def show_success(
async def confirm_output( async def confirm_output(
address: str, address: str,
amount: str, amount: str | None = None,
title: str | None = None, title: str | None = None,
hold: bool = False, hold: bool = False,
br_code: ButtonRequestType = ButtonRequestType.ConfirmOutput, br_code: ButtonRequestType = ButtonRequestType.ConfirmOutput,
@ -634,6 +634,7 @@ async def confirm_output(
chunkify: bool = False, chunkify: bool = False,
source_account: str | None = None, source_account: str | None = None,
source_account_path: str | None = None, source_account_path: str | None = None,
cancel_text: str | None = None,
) -> None: ) -> None:
if address_label is not None: if address_label is not None:
title = address_label title = address_label
@ -655,6 +656,7 @@ async def confirm_output(
account_path=source_account_path, account_path=source_account_path,
br_code=br_code, br_code=br_code,
br_name="confirm_output", br_name="confirm_output",
cancel_text=cancel_text,
) )
) )
) )
@ -976,18 +978,21 @@ def confirm_total(
account_items=account_items, account_items=account_items,
br_name=br_name, br_name=br_name,
br_code=br_code, br_code=br_code,
cancel_text=TR.send__cancel_sign,
) )
) )
) )
def confirm_summary( def _confirm_summary(
items: Iterable[tuple[str, str]], items: Iterable[tuple[str, str]] | None = None,
title: str | None = None, title: str | None = None,
info_items: Iterable[tuple[str, str]] | None = None, info_items: Iterable[tuple[str, str]] | None = None,
info_title: str | None = None, info_title: str | None = None,
fee_items: Iterable[tuple[str, str]] | None = None,
br_name: str = "confirm_total", br_name: str = "confirm_total",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
cancel_text: str | None = None,
) -> Awaitable[None]: ) -> Awaitable[None]:
# TODO: info_title # TODO: info_title
title = title or TR.words__title_summary # def_arg title = title or TR.words__title_summary # def_arg
@ -997,10 +1002,11 @@ def confirm_summary(
trezorui2.flow_confirm_summary( trezorui2.flow_confirm_summary(
title=title, title=title,
items=items or (), items=items or (),
fee_items=(), fee_items=fee_items or (),
account_items=info_items or (), account_items=info_items or (),
br_name=br_name, br_name=br_name,
br_code=br_code, br_code=br_code,
cancel_text=cancel_text,
) )
) )
) )
@ -1012,48 +1018,26 @@ if not utils.BITCOIN_ONLY:
recipient: str, recipient: str,
total_amount: str, total_amount: str,
maximum_fee: str, maximum_fee: str,
items: Iterable[tuple[str, str]], fee_info_items: Iterable[tuple[str, str]],
br_name: str = "confirm_ethereum_tx", br_name: str = "confirm_ethereum_tx",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
chunkify: bool = False, chunkify: bool = False,
) -> None: ) -> None:
info_layout = RustLayout( await confirm_output(
trezorui2.show_info_with_cancel( recipient,
title=TR.confirm_total__title_fee, title=TR.words__recipient,
items=items, chunkify=chunkify,
) cancel_text=TR.buttons__cancel,
) )
while True: await _confirm_summary(
# Allowing going back and forth between recipient and summary/details items=(
await confirm_blob( (TR.words__amount, total_amount),
br_name, (TR.send__maximum_fee, maximum_fee),
TR.words__recipient, ),
recipient, fee_items=fee_info_items,
verb=TR.buttons__continue, cancel_text=TR.buttons__cancel,
chunkify=chunkify, )
prompt_screen=False,
)
try:
total_layout = RustLayout(
trezorui2.confirm_total(
title=TR.words__title_summary,
items=[
(f"{TR.words__amount}:", total_amount),
(TR.send__maximum_fee, maximum_fee),
],
info_button=True,
cancel_arrow=True,
)
)
total_layout.request_complete_repaint()
await raise_if_not_confirmed(
with_info(total_layout, info_layout, br_name, br_code)
)
break
except ActionCancelled:
continue
async def confirm_ethereum_staking_tx( async def confirm_ethereum_staking_tx(
title: str, title: str,
@ -1088,11 +1072,11 @@ if not utils.BITCOIN_ONLY:
items = ((TR.send__maximum_fee, maximum_fee),) items = ((TR.send__maximum_fee, maximum_fee),)
else: else:
items = ( 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 _confirm_summary(
items, # items items=items,
title=title, title=title,
info_title=TR.confirm_total__title_fee, info_title=TR.confirm_total__title_fee,
info_items=info_items, info_items=info_items,
@ -1113,8 +1097,8 @@ if not utils.BITCOIN_ONLY:
amount_title if amount_title is not None else f"{TR.words__amount}:" amount_title if amount_title is not None else f"{TR.words__amount}:"
) # def_arg ) # def_arg
fee_title = fee_title or TR.words__fee # def_arg fee_title = fee_title or TR.words__fee # def_arg
return confirm_summary( return _confirm_summary(
((amount_title, amount), (fee_title, fee)), items=((amount_title, amount), (fee_title, fee)),
info_items=items, info_items=items,
br_name=br_name, br_name=br_name,
br_code=br_code, br_code=br_code,
@ -1122,11 +1106,11 @@ if not utils.BITCOIN_ONLY:
def confirm_joint_total(spending_amount: str, total_amount: str) -> Awaitable[None]: def confirm_joint_total(spending_amount: str, total_amount: str) -> Awaitable[None]:
return confirm_summary( return _confirm_summary(
items=[ items=(
(TR.send__you_are_contributing, spending_amount), (TR.send__you_are_contributing, spending_amount),
(TR.send__to_the_total_amount, total_amount), (TR.send__to_the_total_amount, total_amount),
], ),
title=TR.send__title_joint_transaction, title=TR.send__title_joint_transaction,
br_name="confirm_joint_total", br_name="confirm_joint_total",
br_code=ButtonRequestType.SignTx, br_code=ButtonRequestType.SignTx,

View File

@ -1216,7 +1216,7 @@ if not utils.BITCOIN_ONLY:
amount_title = verb amount_title = verb
amount_value = "" amount_value = ""
else: else:
amount_title = TR.words__amount + ":" amount_title = f"{TR.words__amount}:"
amount_value = total_amount amount_value = total_amount
await raise_if_not_confirmed( await raise_if_not_confirmed(
interact( interact(
@ -1224,9 +1224,9 @@ if not utils.BITCOIN_ONLY:
trezorui2.altcoin_tx_summary( trezorui2.altcoin_tx_summary(
amount_title=amount_title, amount_title=amount_title,
amount_value=amount_value, amount_value=amount_value,
fee_title=TR.send__maximum_fee, fee_title=f"{TR.send__maximum_fee}:",
fee_value=maximum_fee, fee_value=maximum_fee,
items=info_items, items=[(f"{k}:", v) for (k, v) in info_items],
cancel_cross=True, cancel_cross=True,
) )
), ),
@ -1269,7 +1269,7 @@ if not utils.BITCOIN_ONLY:
recipient: str, recipient: str,
total_amount: str, total_amount: str,
maximum_fee: str, maximum_fee: str,
items: Iterable[tuple[str, str]], fee_info_items: Iterable[tuple[str, str]],
br_name: str = "confirm_ethereum_tx", br_name: str = "confirm_ethereum_tx",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
chunkify: bool = False, chunkify: bool = False,
@ -1278,9 +1278,9 @@ if not utils.BITCOIN_ONLY:
trezorui2.altcoin_tx_summary( trezorui2.altcoin_tx_summary(
amount_title=f"{TR.words__amount}:", amount_title=f"{TR.words__amount}:",
amount_value=total_amount, amount_value=total_amount,
fee_title=TR.send__maximum_fee, fee_title=f"{TR.send__maximum_fee}:",
fee_value=maximum_fee, fee_value=maximum_fee,
items=items, items=[(f"{k}:", v) for (k, v) in fee_info_items],
) )
) )

View File

@ -1054,7 +1054,7 @@ def confirm_total(
if fee_rate_amount: if fee_rate_amount:
info_items.append((TR.confirm_total__fee_rate_colon, fee_rate_amount)) info_items.append((TR.confirm_total__fee_rate_colon, fee_rate_amount))
return confirm_summary( return _confirm_summary(
items, items,
TR.words__title_summary, TR.words__title_summary,
info_items=info_items, info_items=info_items,
@ -1063,7 +1063,7 @@ def confirm_total(
) )
def confirm_summary( def _confirm_summary(
items: Iterable[tuple[str, str]], items: Iterable[tuple[str, str]],
title: str | None = None, title: str | None = None,
info_items: Iterable[tuple[str, str]] | None = None, info_items: Iterable[tuple[str, str]] | None = None,
@ -1098,7 +1098,7 @@ if not utils.BITCOIN_ONLY:
recipient: str, recipient: str,
total_amount: str, total_amount: str,
maximum_fee: str, maximum_fee: str,
items: Iterable[tuple[str, str]], fee_info_items: Iterable[tuple[str, str]],
br_name: str = "confirm_ethereum_tx", br_name: str = "confirm_ethereum_tx",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
chunkify: bool = False, chunkify: bool = False,
@ -1108,7 +1108,7 @@ if not utils.BITCOIN_ONLY:
title=TR.words__title_summary, title=TR.words__title_summary,
items=[ items=[
(f"{TR.words__amount}:", total_amount), (f"{TR.words__amount}:", total_amount),
(TR.send__maximum_fee, maximum_fee), (f"{TR.send__maximum_fee}:", maximum_fee),
], ],
info_button=True, info_button=True,
cancel_arrow=True, cancel_arrow=True,
@ -1117,7 +1117,7 @@ if not utils.BITCOIN_ONLY:
info_layout = RustLayout( info_layout = RustLayout(
trezorui2.show_info_with_cancel( trezorui2.show_info_with_cancel(
title=TR.confirm_total__title_fee, title=TR.confirm_total__title_fee,
items=items, items=[(f"{k}:", v) for (k, v) in fee_info_items],
) )
) )
@ -1169,17 +1169,17 @@ if not utils.BITCOIN_ONLY:
# confirmation # confirmation
if verb == TR.ethereum__staking_claim: if verb == TR.ethereum__staking_claim:
items = ((TR.send__maximum_fee, maximum_fee),) items = ((f"{TR.send__maximum_fee}:", maximum_fee),)
else: else:
items = ( items = (
(TR.words__amount + ":", total_amount), (f"{TR.words__amount}:", total_amount),
(TR.send__maximum_fee, maximum_fee), (f"{TR.send__maximum_fee}:", maximum_fee),
) )
await confirm_summary( await _confirm_summary(
items, # items items, # items
title=title, title=title,
info_title=TR.confirm_total__title_fee, info_title=TR.confirm_total__title_fee,
info_items=info_items, info_items=[(f"{k}:", v) for (k, v) in info_items],
br_name=br_name, br_name=br_name,
br_code=br_code, br_code=br_code,
) )
@ -1197,7 +1197,7 @@ if not utils.BITCOIN_ONLY:
amount_title if amount_title is not None else f"{TR.words__amount}:" amount_title if amount_title is not None else f"{TR.words__amount}:"
) # def_arg ) # def_arg
fee_title = fee_title or TR.words__fee # def_arg fee_title = fee_title or TR.words__fee # def_arg
return confirm_summary( return _confirm_summary(
((amount_title, amount), (fee_title, fee)), ((amount_title, amount), (fee_title, fee)),
info_items=items, info_items=items,
br_name=br_name, br_name=br_name,

View File

@ -329,13 +329,13 @@
"ethereum__amount_sent": "Odeslaná částka:", "ethereum__amount_sent": "Odeslaná částka:",
"ethereum__contract": "Kontrakt:", "ethereum__contract": "Kontrakt:",
"ethereum__data_size_template": "Velikost: {0} bajtů", "ethereum__data_size_template": "Velikost: {0} bajtů",
"ethereum__gas_limit": "Limit gasu:", "ethereum__gas_limit": "Limit gasu",
"ethereum__gas_price": "Cena gasu:", "ethereum__gas_price": "Cena gasu",
"ethereum__max_gas_price": "Maximální cena gasu:", "ethereum__max_gas_price": "Maximální cena gasu",
"ethereum__name_and_version": "Název a verze", "ethereum__name_and_version": "Název a verze",
"ethereum__new_contract": "nový kontrakt?", "ethereum__new_contract": "nový kontrakt?",
"ethereum__no_message_field": "Žádné pole zprávy", "ethereum__no_message_field": "Žádné pole zprávy",
"ethereum__priority_fee": "Přednostní poplatek:", "ethereum__priority_fee": "Přednostní poplatek",
"ethereum__show_full_array": "Zobrazit celé pole", "ethereum__show_full_array": "Zobrazit celé pole",
"ethereum__show_full_domain": "Zobrazit celou doménu", "ethereum__show_full_domain": "Zobrazit celou doménu",
"ethereum__show_full_message": "Zobrazit celou zprávu", "ethereum__show_full_message": "Zobrazit celou zprávu",
@ -760,7 +760,7 @@
"send__from_multiple_accounts": "Odesílání z více účtů.", "send__from_multiple_accounts": "Odesílání z více účtů.",
"send__incl_transaction_fee": "vč. transakčního poplatku", "send__incl_transaction_fee": "vč. transakčního poplatku",
"send__including_fee": "Včetně poplatku:", "send__including_fee": "Včetně poplatku:",
"send__maximum_fee": "Maximální poplatek:", "send__maximum_fee": "Maximální poplatek",
"send__receiving_to_multisig": "Příjem na adresách multisig.", "send__receiving_to_multisig": "Příjem na adresách multisig.",
"send__send_from": "Odeslat z", "send__send_from": "Odeslat z",
"send__sign_transaction": "Podepsat transakci", "send__sign_transaction": "Podepsat transakci",

View File

@ -329,13 +329,13 @@
"ethereum__amount_sent": "Gesendeter Betrag:", "ethereum__amount_sent": "Gesendeter Betrag:",
"ethereum__contract": "Kontrakt:", "ethereum__contract": "Kontrakt:",
"ethereum__data_size_template": "Größe: {0} Bytes", "ethereum__data_size_template": "Größe: {0} Bytes",
"ethereum__gas_limit": "Gas-Grenze:", "ethereum__gas_limit": "Gas-Grenze",
"ethereum__gas_price": "Gas-Preis:", "ethereum__gas_price": "Gas-Preis",
"ethereum__max_gas_price": "Max. Gas-Preis:", "ethereum__max_gas_price": "Max. Gas-Preis",
"ethereum__name_and_version": "Name und Version", "ethereum__name_and_version": "Name und Version",
"ethereum__new_contract": "neuer Kontrakt?", "ethereum__new_contract": "neuer Kontrakt?",
"ethereum__no_message_field": "Kein Nachrichtenfeld", "ethereum__no_message_field": "Kein Nachrichtenfeld",
"ethereum__priority_fee": "Prioritätsgebühr:", "ethereum__priority_fee": "Prioritätsgebühr",
"ethereum__show_full_array": "Ganzes anzeigen", "ethereum__show_full_array": "Ganzes anzeigen",
"ethereum__show_full_domain": "Ganze anzeigen", "ethereum__show_full_domain": "Ganze anzeigen",
"ethereum__show_full_message": "Ganze zeigen", "ethereum__show_full_message": "Ganze zeigen",
@ -760,7 +760,7 @@
"send__from_multiple_accounts": "Von mehreren Konten gesendet.", "send__from_multiple_accounts": "Von mehreren Konten gesendet.",
"send__incl_transaction_fee": "inkl. Transaktionsgebühr", "send__incl_transaction_fee": "inkl. Transaktionsgebühr",
"send__including_fee": "Einschließ. Gebühr:", "send__including_fee": "Einschließ. Gebühr:",
"send__maximum_fee": "Max. Gebühr:", "send__maximum_fee": "Max. Gebühr",
"send__receiving_to_multisig": "Von Multisig-Adresse empfangen.", "send__receiving_to_multisig": "Von Multisig-Adresse empfangen.",
"send__send_from": "Senden von", "send__send_from": "Senden von",
"send__sign_transaction": "Transaktion signieren", "send__sign_transaction": "Transaktion signieren",

View File

@ -299,13 +299,13 @@
"ethereum__amount_sent": "Amount sent:", "ethereum__amount_sent": "Amount sent:",
"ethereum__contract": "Contract:", "ethereum__contract": "Contract:",
"ethereum__data_size_template": "Size: {0} bytes", "ethereum__data_size_template": "Size: {0} bytes",
"ethereum__gas_limit": "Gas limit:", "ethereum__gas_limit": "Gas limit",
"ethereum__gas_price": "Gas price:", "ethereum__gas_price": "Gas price",
"ethereum__max_gas_price": "Max gas price:", "ethereum__max_gas_price": "Max gas price",
"ethereum__name_and_version": "Name and version", "ethereum__name_and_version": "Name and version",
"ethereum__new_contract": "new contract?", "ethereum__new_contract": "new contract?",
"ethereum__no_message_field": "No message field", "ethereum__no_message_field": "No message field",
"ethereum__priority_fee": "Priority fee:", "ethereum__priority_fee": "Priority fee",
"ethereum__show_full_array": "Show full array", "ethereum__show_full_array": "Show full array",
"ethereum__show_full_domain": "Show full domain", "ethereum__show_full_domain": "Show full domain",
"ethereum__show_full_message": "Show full message", "ethereum__show_full_message": "Show full message",
@ -734,7 +734,7 @@
"send__from_multiple_accounts": "Sending from multiple accounts.", "send__from_multiple_accounts": "Sending from multiple accounts.",
"send__incl_transaction_fee": "incl. Transaction fee", "send__incl_transaction_fee": "incl. Transaction fee",
"send__including_fee": "Including fee:", "send__including_fee": "Including fee:",
"send__maximum_fee": "Maximum fee:", "send__maximum_fee": "Maximum fee",
"send__receiving_to_multisig": "Receiving to a multisig address.", "send__receiving_to_multisig": "Receiving to a multisig address.",
"send__send_from": "Send from", "send__send_from": "Send from",
"send__sign_transaction": "Sign transaction", "send__sign_transaction": "Sign transaction",

View File

@ -329,13 +329,13 @@
"ethereum__amount_sent": "Importe enviado:", "ethereum__amount_sent": "Importe enviado:",
"ethereum__contract": "Contrato:", "ethereum__contract": "Contrato:",
"ethereum__data_size_template": "Tamaño: {0} bytes", "ethereum__data_size_template": "Tamaño: {0} bytes",
"ethereum__gas_limit": "Límite de gas:", "ethereum__gas_limit": "Límite de gas",
"ethereum__gas_price": "Precio de gas:", "ethereum__gas_price": "Precio de gas",
"ethereum__max_gas_price": "Precio máximo de gas:", "ethereum__max_gas_price": "Precio máximo de gas",
"ethereum__name_and_version": "Nombre y versión", "ethereum__name_and_version": "Nombre y versión",
"ethereum__new_contract": "¿Nuevo contrato?", "ethereum__new_contract": "¿Nuevo contrato?",
"ethereum__no_message_field": "Sin campo de mensaje.", "ethereum__no_message_field": "Sin campo de mensaje.",
"ethereum__priority_fee": "Comisión de prioridad:", "ethereum__priority_fee": "Comisión de prioridad",
"ethereum__show_full_array": "Ver matriz íntegra.", "ethereum__show_full_array": "Ver matriz íntegra.",
"ethereum__show_full_domain": "Ver dominio íntegro.", "ethereum__show_full_domain": "Ver dominio íntegro.",
"ethereum__show_full_message": "Ver mensaje íntegro.", "ethereum__show_full_message": "Ver mensaje íntegro.",
@ -760,7 +760,7 @@
"send__from_multiple_accounts": "Enviando desde varias cuentas.", "send__from_multiple_accounts": "Enviando desde varias cuentas.",
"send__incl_transaction_fee": "incl. comisión de transacción", "send__incl_transaction_fee": "incl. comisión de transacción",
"send__including_fee": "Comisión incluida:", "send__including_fee": "Comisión incluida:",
"send__maximum_fee": "Comisión máxima:", "send__maximum_fee": "Comisión máxima",
"send__receiving_to_multisig": "Recepción en una dirección multifirma.", "send__receiving_to_multisig": "Recepción en una dirección multifirma.",
"send__send_from": "Enviar desde", "send__send_from": "Enviar desde",
"send__sign_transaction": "Firmar transacción", "send__sign_transaction": "Firmar transacción",

View File

@ -329,13 +329,13 @@
"ethereum__amount_sent": "Montant envoyé :", "ethereum__amount_sent": "Montant envoyé :",
"ethereum__contract": "Contrat :", "ethereum__contract": "Contrat :",
"ethereum__data_size_template": "Taille : {0} octets", "ethereum__data_size_template": "Taille : {0} octets",
"ethereum__gas_limit": "Limite de gaz :", "ethereum__gas_limit": "Limite de gaz",
"ethereum__gas_price": "Prix du gaz :", "ethereum__gas_price": "Prix du gaz",
"ethereum__max_gas_price": "Prix max du gaz :", "ethereum__max_gas_price": "Prix max du gaz",
"ethereum__name_and_version": "Nom et version", "ethereum__name_and_version": "Nom et version",
"ethereum__new_contract": "nouveau contrat ?", "ethereum__new_contract": "nouveau contrat ?",
"ethereum__no_message_field": "0 champ de mess.", "ethereum__no_message_field": "0 champ de mess.",
"ethereum__priority_fee": "Frais de priorité :", "ethereum__priority_fee": "Frais de priorité",
"ethereum__show_full_array": "Aff. liste complète", "ethereum__show_full_array": "Aff. liste complète",
"ethereum__show_full_domain": "Aff. domaine complet", "ethereum__show_full_domain": "Aff. domaine complet",
"ethereum__show_full_message": "Aff. message complet", "ethereum__show_full_message": "Aff. message complet",
@ -760,7 +760,7 @@
"send__from_multiple_accounts": "Envoi depuis plusieurs comptes.", "send__from_multiple_accounts": "Envoi depuis plusieurs comptes.",
"send__incl_transaction_fee": "Frais de transaction inclus", "send__incl_transaction_fee": "Frais de transaction inclus",
"send__including_fee": "Frais inclus :", "send__including_fee": "Frais inclus :",
"send__maximum_fee": "Frais max :", "send__maximum_fee": "Frais max",
"send__receiving_to_multisig": "Récep. vers adr. multisignatures.", "send__receiving_to_multisig": "Récep. vers adr. multisignatures.",
"send__send_from": "Envoyer depuis", "send__send_from": "Envoyer depuis",
"send__sign_transaction": "Signer la transaction", "send__sign_transaction": "Signer la transaction",

View File

@ -489,7 +489,7 @@ class EthereumFlow:
if info: if info:
self.debug.press_right(wait=True) self.debug.press_right(wait=True)
TR.assert_equals_multiple( TR.assert_equals_multiple(
self.debug.wait_layout().title(), self.debug.wait_layout().title().rstrip(":"),
[ [
"ethereum__staking_stake_address", "ethereum__staking_stake_address",
"ethereum__staking_claim_address", "ethereum__staking_claim_address",

View File

@ -19060,15 +19060,15 @@
"T3T1_en_cardano-test_sign_tx.py::test_cardano_sign_tx_failed[withdrawal_has_multisig_path]": "f6da157bdea4ae4d89661f12adc96ca99074f142d2e98e8fd339dfb0554cb0c9", "T3T1_en_cardano-test_sign_tx.py::test_cardano_sign_tx_failed[withdrawal_has_multisig_path]": "f6da157bdea4ae4d89661f12adc96ca99074f142d2e98e8fd339dfb0554cb0c9",
"T3T1_en_cardano-test_sign_tx.py::test_cardano_sign_tx_failed[withdrawal_has_non_staking_path]": "f6da157bdea4ae4d89661f12adc96ca99074f142d2e98e8fd339dfb0554cb0c9", "T3T1_en_cardano-test_sign_tx.py::test_cardano_sign_tx_failed[withdrawal_has_non_staking_path]": "f6da157bdea4ae4d89661f12adc96ca99074f142d2e98e8fd339dfb0554cb0c9",
"T3T1_en_cardano-test_sign_tx.py::test_cardano_sign_tx_failed[withdrawal_has_script_hash]": "f6da157bdea4ae4d89661f12adc96ca99074f142d2e98e8fd339dfb0554cb0c9", "T3T1_en_cardano-test_sign_tx.py::test_cardano_sign_tx_failed[withdrawal_has_script_hash]": "f6da157bdea4ae4d89661f12adc96ca99074f142d2e98e8fd339dfb0554cb0c9",
"T3T1_en_ethereum-test_definitions.py::test_builtin": "b605a64b843e89831e440ee9c44c1dc12a4bf5062d3279f707f34739257926b7", "T3T1_en_ethereum-test_definitions.py::test_builtin": "1c38c3525b07103255c0a4a0419579b3e12738b213f5556bb0ac54b1994a51ee",
"T3T1_en_ethereum-test_definitions.py::test_builtin_token": "2b10036d64f8d34e04cc27fe1057bae9ad70ad5d1f034fd76f39656040c2d492", "T3T1_en_ethereum-test_definitions.py::test_builtin_token": "1c324a3f0e193d488f0486614291bef80121b797873457e8af98842cc498c642",
"T3T1_en_ethereum-test_definitions.py::test_chain_id_allowed": "875e8029e1d22c55342149fefd1f12f9bcb075b0063d10e2c3fd7276bb6fbfdf", "T3T1_en_ethereum-test_definitions.py::test_chain_id_allowed": "e095804871f8cf67238d3b8da1a199ed74caa5bf393b6538f239e71e3160d4f0",
"T3T1_en_ethereum-test_definitions.py::test_chain_id_mismatch": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a", "T3T1_en_ethereum-test_definitions.py::test_chain_id_mismatch": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a",
"T3T1_en_ethereum-test_definitions.py::test_definition_does_not_override_builtin": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a", "T3T1_en_ethereum-test_definitions.py::test_definition_does_not_override_builtin": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a",
"T3T1_en_ethereum-test_definitions.py::test_external_chain_token_mismatch": "fcf99475735b6d37e98dc4a0dd5881b525b2161b41de2874667ca8017a5cf63b", "T3T1_en_ethereum-test_definitions.py::test_external_chain_token_mismatch": "3592082e46dbea15776f28853fbd5e48b6c7e8f44e6f66ee108bd0ae45cd5a87",
"T3T1_en_ethereum-test_definitions.py::test_external_chain_token_ok": "f7ea3fce70c0c26353e3c4b4bc0e9353ff5fc56d6cbf1c2056d2cb9819ef1269", "T3T1_en_ethereum-test_definitions.py::test_external_chain_token_ok": "1607ff438918c9a1654e7cc3606323388e5960ba47cbaa809130ac0efd2126c9",
"T3T1_en_ethereum-test_definitions.py::test_external_chain_without_token": "3c3c43f30da2c784304ce0fb0cf5bb04e9db57b13e8b6aaf5df283a0f7eb7896", "T3T1_en_ethereum-test_definitions.py::test_external_chain_without_token": "3077d3a17f228a281a9965e8252eccdf8f75b8ceead1f02626f918587812d971",
"T3T1_en_ethereum-test_definitions.py::test_external_token": "bde77578d3a09d6b480af2c2f60a062aa215bedbc85c7508188ef4cbac8cced4", "T3T1_en_ethereum-test_definitions.py::test_external_token": "5c931b0690457aa457322f10e617a36300ecbfddfc29578f826657155f821f7a",
"T3T1_en_ethereum-test_definitions.py::test_method_builtin[_call_getaddress]": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a", "T3T1_en_ethereum-test_definitions.py::test_method_builtin[_call_getaddress]": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a",
"T3T1_en_ethereum-test_definitions.py::test_method_builtin[_call_sign_typed_data]": "63ac4972e7937d0ea5ee6a25074d7e013c2fee272436772b015f741afe89b2c6", "T3T1_en_ethereum-test_definitions.py::test_method_builtin[_call_sign_typed_data]": "63ac4972e7937d0ea5ee6a25074d7e013c2fee272436772b015f741afe89b2c6",
"T3T1_en_ethereum-test_definitions.py::test_method_builtin[_call_signmessage]": "34651e0c0cd0ef2e87c0e34acb578d678943646d78d7013dce8e8744c11efb37", "T3T1_en_ethereum-test_definitions.py::test_method_builtin[_call_signmessage]": "34651e0c0cd0ef2e87c0e34acb578d678943646d78d7013dce8e8744c11efb37",
@ -19082,7 +19082,7 @@
"T3T1_en_ethereum-test_definitions.py::test_method_external_mismatch[_call_sign_typed_data]": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a", "T3T1_en_ethereum-test_definitions.py::test_method_external_mismatch[_call_sign_typed_data]": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a",
"T3T1_en_ethereum-test_definitions.py::test_method_external_mismatch[_call_signmessage]": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a", "T3T1_en_ethereum-test_definitions.py::test_method_external_mismatch[_call_signmessage]": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a",
"T3T1_en_ethereum-test_definitions.py::test_slip44_disallowed": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a", "T3T1_en_ethereum-test_definitions.py::test_slip44_disallowed": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a",
"T3T1_en_ethereum-test_definitions.py::test_slip44_external": "232d717c5343ba752e687911084e50f87b255fce1b4223a9be5d488e567e4dfe", "T3T1_en_ethereum-test_definitions.py::test_slip44_external": "851ef9c67c6ec26eef50b64121bf5c2f6b32347eac606909a89fd18f4e6f839e",
"T3T1_en_ethereum-test_definitions.py::test_slip44_external_disallowed": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a", "T3T1_en_ethereum-test_definitions.py::test_slip44_external_disallowed": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a",
"T3T1_en_ethereum-test_definitions_bad.py::test_bad_prefix": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a", "T3T1_en_ethereum-test_definitions_bad.py::test_bad_prefix": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a",
"T3T1_en_ethereum-test_definitions_bad.py::test_bad_proof": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a", "T3T1_en_ethereum-test_definitions_bad.py::test_bad_proof": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a",
@ -19143,67 +19143,67 @@
"T3T1_en_ethereum-test_sign_verify_message.py::test_verify[parameters6-result6]": "3575019909d7c8b10645e8dade7f30551a77e9af3560e07169a50fe62e3707a4", "T3T1_en_ethereum-test_sign_verify_message.py::test_verify[parameters6-result6]": "3575019909d7c8b10645e8dade7f30551a77e9af3560e07169a50fe62e3707a4",
"T3T1_en_ethereum-test_sign_verify_message.py::test_verify[parameters7-result7]": "6b233a31f5d1be062072e05a8b4e6fdcb8a2d3c2014f15650338ef68dafe9b35", "T3T1_en_ethereum-test_sign_verify_message.py::test_verify[parameters7-result7]": "6b233a31f5d1be062072e05a8b4e6fdcb8a2d3c2014f15650338ef68dafe9b35",
"T3T1_en_ethereum-test_sign_verify_message.py::test_verify_invalid": "e0d45bed5a75337e85b0e34607a4e8ce0793276639dec49a539755c0803a1359", "T3T1_en_ethereum-test_sign_verify_message.py::test_verify_invalid": "e0d45bed5a75337e85b0e34607a4e8ce0793276639dec49a539755c0803a1359",
"T3T1_en_ethereum-test_signtx.py::test_data_streaming": "9afdd28b61ba5366056e0af40147beeea3a36d90bffcf00a5f9c6cbed0c1f4fc", "T3T1_en_ethereum-test_signtx.py::test_data_streaming": "20445885c45bc572a81b8262c839d9a599dc302617d6932b0881ebd0577dff05",
"T3T1_en_ethereum-test_signtx.py::test_sanity_checks": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a", "T3T1_en_ethereum-test_signtx.py::test_sanity_checks": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a",
"T3T1_en_ethereum-test_signtx.py::test_sanity_checks_eip1559": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a", "T3T1_en_ethereum-test_signtx.py::test_sanity_checks_eip1559": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-Auxilium]": "8546ef13f253ad67c5cd4e624cf67f860939196f1dca0d55e4f399a4017dddc8", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-Auxilium]": "c6a1f1412737284f448906f4fff1503cdfe501580ac20c4df42b218ba2a12d20",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-ETC]": "445637b736d5e0cb2a00217ae7c55644ac50232ce33af63f847031b609d0bc1f", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-ETC]": "0737fbd6eaa79b22d396181983fe51d463e5346183cab92ea42e52ef1b3448e2",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-Ethereum]": "cfad113cdbb95b121cbc1a077b996600a4d640509ffed86013ea3e2ab35722be", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-Ethereum]": "95fcf561db853878ec6fdbaa1529cdcd64a6fcc29c6d6bf1ddc085f44c957a1f",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-Ledger Live legacy path0]": "a789be9eace7bc495530535b12eecc0bf8ef89142c530139e1c38c2175cd1e33", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-Ledger Live legacy path0]": "edb67eba2465e6a8ca2185ec7a9065d450119fd72c1c3433e05b9b338ff8bdb9",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-Ledger Live legacy path1]": "cfad113cdbb95b121cbc1a077b996600a4d640509ffed86013ea3e2ab35722be", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-Ledger Live legacy path1]": "95fcf561db853878ec6fdbaa1529cdcd64a6fcc29c6d6bf1ddc085f44c957a1f",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-Palm]": "8546ef13f253ad67c5cd4e624cf67f860939196f1dca0d55e4f399a4017dddc8", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-Palm]": "c6a1f1412737284f448906f4fff1503cdfe501580ac20c4df42b218ba2a12d20",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-Pirl]": "8546ef13f253ad67c5cd4e624cf67f860939196f1dca0d55e4f399a4017dddc8", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-Pirl]": "c6a1f1412737284f448906f4fff1503cdfe501580ac20c4df42b218ba2a12d20",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-Rinkeby]": "0c42808945204f4baa128f9783e07b02ceb621bfdd67370c6c447eced647f738", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-Rinkeby]": "97c1c18900c6e13ffb87eef423366e0d837d260d1e4bbcdb3dd1dcfb4e02ef44",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-Ropsten]": "0c42808945204f4baa128f9783e07b02ceb621bfdd67370c6c447eced647f738", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-Ropsten]": "97c1c18900c6e13ffb87eef423366e0d837d260d1e4bbcdb3dd1dcfb4e02ef44",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-Unknown_chain_id_eth_path]": "8546ef13f253ad67c5cd4e624cf67f860939196f1dca0d55e4f399a4017dddc8", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-Unknown_chain_id_eth_path]": "c6a1f1412737284f448906f4fff1503cdfe501580ac20c4df42b218ba2a12d20",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-Unknown_chain_id_testnet_path]": "8546ef13f253ad67c5cd4e624cf67f860939196f1dca0d55e4f399a4017dddc8", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-Unknown_chain_id_testnet_path]": "c6a1f1412737284f448906f4fff1503cdfe501580ac20c4df42b218ba2a12d20",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-data_1]": "b1a1b2c780248ea17574aa0e4e117d9b535235dca6bb684def66edfd3fe02c03", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-data_1]": "5a142ae14f8b19bde071fde2e45ec322a9d09d888167daa5ff6a0c7ee2da4820",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-data_2_bigdata]": "d21faaece2aff75ef8f2d2fd510d3409037ff51140d61e98bf258a466dc40df5", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-data_2_bigdata]": "bf1200bea695f6da3153cc67cb2728895d1d1f1940b450c80723e27a1015499b",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-erc20_token]": "b26b7dbfb483361a289c750310d4db34a2dfb7fb6b46c544166c1d735a8a9f12", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-erc20_token]": "698287e0c1d7779805428d6f4eebd7b6c679e493a525de0637b76bfd7d2b059b",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-max_chain_id]": "8546ef13f253ad67c5cd4e624cf67f860939196f1dca0d55e4f399a4017dddc8", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-max_chain_id]": "c6a1f1412737284f448906f4fff1503cdfe501580ac20c4df42b218ba2a12d20",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-max_chain_plus_one]": "8546ef13f253ad67c5cd4e624cf67f860939196f1dca0d55e4f399a4017dddc8", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-max_chain_plus_one]": "c6a1f1412737284f448906f4fff1503cdfe501580ac20c4df42b218ba2a12d20",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-max_uint64]": "8546ef13f253ad67c5cd4e624cf67f860939196f1dca0d55e4f399a4017dddc8", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-max_uint64]": "c6a1f1412737284f448906f4fff1503cdfe501580ac20c4df42b218ba2a12d20",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-newcontract]": "a3819dc3ca187456e7924ada6ac703ac98ee437b4af13b7f6c5d585e63c6c24e", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-newcontract]": "0d5d82c82e875b9d2e963873a872d5be66a4c211b7a8850c671a9fe97fd8e9cd",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-nodata_1]": "5716e12e1f096b2c76aa4c974489ef5ac130e93224853e07b8175264142609da", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-nodata_1]": "632cf49d9e43bd49d0b7b9665870c9f098484b105b58aec1633967e74a0038df",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-nodata_2_bigvalue]": "6478b2f7fe2bb5ba5b6877d7f9209b521da3a34d2a46a90071aca1cf73549fc1", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-nodata_2_bigvalue]": "6e243138bd300ac6cc4a73836fbb9a88ed6e6cbea0227e2d98ad1e634e699a02",
"T3T1_en_ethereum-test_signtx.py::test_signtx[False-wanchain]": "86f5f744d7aa31484f051d4ea28bcefbccca9900e0a98f4c8bc6ee8a9925aa43", "T3T1_en_ethereum-test_signtx.py::test_signtx[False-wanchain]": "f4655d67e71979154b56f58944435cfe858da4b06342a8c59bdb80342e6e706b",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-Auxilium]": "455dfefa74b046ef8912fda51027e43a43bf98ea1638403c559bb8d2f5d2a119", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-Auxilium]": "5fc3eb72f1f0c5cc8fd2486e7cc84b04fcac34a7e14df3a205dba57f86f89ffa",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-ETC]": "a56ec7acd67b5dc52c12ec0a0968e640bc8549175adfa97875f783704258dc03", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-ETC]": "107aab12ef0b6821dfb37bb8ae3aed646417783ea5e87ccf359f3e03402f8a4c",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-Ethereum]": "9c45a68b3e4308f632c2da333b353ee27b627f888c0ca2cab39a5a5e10268d77", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-Ethereum]": "0d4c80ec8b5063bceaecfeeefb05b88c45c520b9cd600db1332fd69cd59a9ed0",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-Ledger Live legacy path0]": "46e95812eb5319ec55f19be624c097b715538e0f2969c9804f00861d73de5baf", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-Ledger Live legacy path0]": "c22ef1979a4a203d8de0267acbd7eb71f5339fc92f952fa6306e8fd4b449bb4f",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-Ledger Live legacy path1]": "9c45a68b3e4308f632c2da333b353ee27b627f888c0ca2cab39a5a5e10268d77", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-Ledger Live legacy path1]": "0d4c80ec8b5063bceaecfeeefb05b88c45c520b9cd600db1332fd69cd59a9ed0",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-Palm]": "455dfefa74b046ef8912fda51027e43a43bf98ea1638403c559bb8d2f5d2a119", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-Palm]": "5fc3eb72f1f0c5cc8fd2486e7cc84b04fcac34a7e14df3a205dba57f86f89ffa",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-Pirl]": "455dfefa74b046ef8912fda51027e43a43bf98ea1638403c559bb8d2f5d2a119", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-Pirl]": "5fc3eb72f1f0c5cc8fd2486e7cc84b04fcac34a7e14df3a205dba57f86f89ffa",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-Rinkeby]": "954201170bf340c99a3f7e87d113a7d9b107617b0c2b01fb6e66204baec7a374", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-Rinkeby]": "3f00e3fbda900ea0bd0be4d90bbb89295b30f9fcd0ef3c3c5f99ae05599c95ab",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-Ropsten]": "954201170bf340c99a3f7e87d113a7d9b107617b0c2b01fb6e66204baec7a374", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-Ropsten]": "3f00e3fbda900ea0bd0be4d90bbb89295b30f9fcd0ef3c3c5f99ae05599c95ab",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-Unknown_chain_id_eth_path]": "455dfefa74b046ef8912fda51027e43a43bf98ea1638403c559bb8d2f5d2a119", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-Unknown_chain_id_eth_path]": "5fc3eb72f1f0c5cc8fd2486e7cc84b04fcac34a7e14df3a205dba57f86f89ffa",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-Unknown_chain_id_testnet_path]": "455dfefa74b046ef8912fda51027e43a43bf98ea1638403c559bb8d2f5d2a119", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-Unknown_chain_id_testnet_path]": "5fc3eb72f1f0c5cc8fd2486e7cc84b04fcac34a7e14df3a205dba57f86f89ffa",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-data_1]": "1933b03620922ff6fe108349f60abb54d1155afbf4ce41fa9f3737bfb9f4c060", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-data_1]": "b79f262928821e60e6e11eba33b63ee19be7d245f3b964d48d9e2083e6e7876a",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-data_2_bigdata]": "7340ab0c232fd712b41be5aef254fe4fc7a1da70fe52c204d6747e1988d37e89", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-data_2_bigdata]": "550f06fb050923d9560cbbd176c2c7cff325a3fc54c29e4646da91dfd4849f43",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-erc20_token]": "7af4ae79b354b8fbcbecc8a1e91965e64286c46e27561bd95c1dd0a955db2fff", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-erc20_token]": "8a38042860b1784ff248d9d371663f58762366420ec0c9fcdcd9f0b91720185a",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-max_chain_id]": "455dfefa74b046ef8912fda51027e43a43bf98ea1638403c559bb8d2f5d2a119", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-max_chain_id]": "5fc3eb72f1f0c5cc8fd2486e7cc84b04fcac34a7e14df3a205dba57f86f89ffa",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-max_chain_plus_one]": "455dfefa74b046ef8912fda51027e43a43bf98ea1638403c559bb8d2f5d2a119", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-max_chain_plus_one]": "5fc3eb72f1f0c5cc8fd2486e7cc84b04fcac34a7e14df3a205dba57f86f89ffa",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-max_uint64]": "455dfefa74b046ef8912fda51027e43a43bf98ea1638403c559bb8d2f5d2a119", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-max_uint64]": "5fc3eb72f1f0c5cc8fd2486e7cc84b04fcac34a7e14df3a205dba57f86f89ffa",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-newcontract]": "a3819dc3ca187456e7924ada6ac703ac98ee437b4af13b7f6c5d585e63c6c24e", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-newcontract]": "0d5d82c82e875b9d2e963873a872d5be66a4c211b7a8850c671a9fe97fd8e9cd",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-nodata_1]": "f35dcc06d20f1eb30acad5893efd6679500749390287e96971378da8cadf5a79", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-nodata_1]": "debda32ecd2270eeae53d61ce034ee54cf036143c5cf7c95cd7546821a11b386",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-nodata_2_bigvalue]": "5e9a56ed0d435eb71c086d851d2363ab3da1fd6a514a3d24b2dbbf9ac677295c", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-nodata_2_bigvalue]": "d4433efa0ba95ba14021dcd02d502dfe032709dd5be4b99e900904718c2ea5f2",
"T3T1_en_ethereum-test_signtx.py::test_signtx[True-wanchain]": "b1fe85ae0746d360ab7a3ca15ab43199686d57473aeb57efdfc4f74f8c6eb7c5", "T3T1_en_ethereum-test_signtx.py::test_signtx[True-wanchain]": "df2641d1a3e0037ceec2fd5effc2c0e5b72121b9edbadc02e6b71e955161ce78",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-Ledger Live legacy path]": "5716e12e1f096b2c76aa4c974489ef5ac130e93224853e07b8175264142609da", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-Ledger Live legacy path]": "632cf49d9e43bd49d0b7b9665870c9f098484b105b58aec1633967e74a0038df",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-data_1]": "b1a1b2c780248ea17574aa0e4e117d9b535235dca6bb684def66edfd3fe02c03", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-data_1]": "5a142ae14f8b19bde071fde2e45ec322a9d09d888167daa5ff6a0c7ee2da4820",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-data_2_bigdata]": "3a35cfeeaa140c480a1c91f824603be14f6a6744caf27e9569f4d11614991304", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-data_2_bigdata]": "f1406227fa8eeb0d6d428e3e219c6f4153014a9eb1edbaef3eafb17409f5a047",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-erc20]": "b26b7dbfb483361a289c750310d4db34a2dfb7fb6b46c544166c1d735a8a9f12", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-erc20]": "698287e0c1d7779805428d6f4eebd7b6c679e493a525de0637b76bfd7d2b059b",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-large_chainid]": "b610c76a4cbf67112f04a326d7bdaaf2469c6bae0c0ec79c2ea396cc00fe66a2", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-large_chainid]": "d72fa92841cb2263f015082b1f24a94ae8714b6ba77b01b5e50eb57eef2e5047",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-long_fees]": "4723bf6ce0bf8037da50c5bf2a534c8d7a9992a5081d37eb4ca966a314030b7b", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-long_fees]": "4960d78a5e24d30c04f9050f68e049f7bb3230d4b0772a41f8264b3b246aeaec",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-nodata]": "5716e12e1f096b2c76aa4c974489ef5ac130e93224853e07b8175264142609da", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[False-nodata]": "632cf49d9e43bd49d0b7b9665870c9f098484b105b58aec1633967e74a0038df",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-Ledger Live legacy path]": "f35dcc06d20f1eb30acad5893efd6679500749390287e96971378da8cadf5a79", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-Ledger Live legacy path]": "debda32ecd2270eeae53d61ce034ee54cf036143c5cf7c95cd7546821a11b386",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-data_1]": "1933b03620922ff6fe108349f60abb54d1155afbf4ce41fa9f3737bfb9f4c060", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-data_1]": "b79f262928821e60e6e11eba33b63ee19be7d245f3b964d48d9e2083e6e7876a",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-data_2_bigdata]": "cb3f46ea1416b8dc220280ea46043902656daf4f0827a1ddc632699c198234d4", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-data_2_bigdata]": "5a27a1a4c2e3d2c2f3ed011d1800bb66180337198e554c7367112ff16996be7f",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-erc20]": "7af4ae79b354b8fbcbecc8a1e91965e64286c46e27561bd95c1dd0a955db2fff", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-erc20]": "8a38042860b1784ff248d9d371663f58762366420ec0c9fcdcd9f0b91720185a",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-large_chainid]": "7de181bc17de9f3cb0281d4e0b4a56fefff71f27ea0953c02b755b445857adb0", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-large_chainid]": "3ab2081e1b532a71e89c411b06b5cd5d106337f9669f8126d2c3953d8298744c",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-long_fees]": "54ace8cfbfa5ec3115a6bb95de505f2a65eb9e08a7c1e8f31521c1891419515e", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-long_fees]": "9c800ca435400efbd04eff51474e21b9b9d1b4f8c2814e44ffe24b2d4ebc4ba7",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-nodata]": "f35dcc06d20f1eb30acad5893efd6679500749390287e96971378da8cadf5a79", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-nodata]": "debda32ecd2270eeae53d61ce034ee54cf036143c5cf7c95cd7546821a11b386",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559_access_list": "5727664e843777a2abbd1fe4a3334eefa023c84314842dbf7098363347172264", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559_access_list": "dd2790ac7fa5c240b051e85342d6368d0deac5a5cf8c7c8c4af1c09e3cf7182f",
"T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559_access_list_larger": "5727664e843777a2abbd1fe4a3334eefa023c84314842dbf7098363347172264", "T3T1_en_ethereum-test_signtx.py::test_signtx_eip1559_access_list_larger": "dd2790ac7fa5c240b051e85342d6368d0deac5a5cf8c7c8c4af1c09e3cf7182f",
"T3T1_en_ethereum-test_signtx.py::test_signtx_fee_info": "dab3a2a9c2a2e2429d6a749bf25ab272d8620881b7518c2036f78c2cdb3e2f44", "T3T1_en_ethereum-test_signtx.py::test_signtx_fee_info": "dab3a2a9c2a2e2429d6a749bf25ab272d8620881b7518c2036f78c2cdb3e2f44",
"T3T1_en_ethereum-test_signtx.py::test_signtx_go_back_from_summary": "6902b90abea50a3f6037a6e5d217e2e1704ab9dcaa0d114404ebc6b8da0b96a0", "T3T1_en_ethereum-test_signtx.py::test_signtx_go_back_from_summary": "6902b90abea50a3f6037a6e5d217e2e1704ab9dcaa0d114404ebc6b8da0b96a0",
"T3T1_en_ethereum-test_signtx.py::test_signtx_staking_bad_inputs[claim_bad_inputs_1]": "886a329a63547ee0f07547685dfc1c8677587c3471fe1bcba81c6a9363659185", "T3T1_en_ethereum-test_signtx.py::test_signtx_staking_bad_inputs[claim_bad_inputs_1]": "886a329a63547ee0f07547685dfc1c8677587c3471fe1bcba81c6a9363659185",
@ -19211,12 +19211,12 @@
"T3T1_en_ethereum-test_signtx.py::test_signtx_staking_bad_inputs[stake_bad_inputs_2]": "886a329a63547ee0f07547685dfc1c8677587c3471fe1bcba81c6a9363659185", "T3T1_en_ethereum-test_signtx.py::test_signtx_staking_bad_inputs[stake_bad_inputs_2]": "886a329a63547ee0f07547685dfc1c8677587c3471fe1bcba81c6a9363659185",
"T3T1_en_ethereum-test_signtx.py::test_signtx_staking_bad_inputs[unstake_bad_inputs_1]": "886a329a63547ee0f07547685dfc1c8677587c3471fe1bcba81c6a9363659185", "T3T1_en_ethereum-test_signtx.py::test_signtx_staking_bad_inputs[unstake_bad_inputs_1]": "886a329a63547ee0f07547685dfc1c8677587c3471fe1bcba81c6a9363659185",
"T3T1_en_ethereum-test_signtx.py::test_signtx_staking_bad_inputs[unstake_bad_inputs_2]": "886a329a63547ee0f07547685dfc1c8677587c3471fe1bcba81c6a9363659185", "T3T1_en_ethereum-test_signtx.py::test_signtx_staking_bad_inputs[unstake_bad_inputs_2]": "886a329a63547ee0f07547685dfc1c8677587c3471fe1bcba81c6a9363659185",
"T3T1_en_ethereum-test_signtx.py::test_signtx_staking_eip1559[claim_holesky]": "571cdbecf1aefa07a05f3d102342dd571f4b5dd23318e75911164b91b5cbc207", "T3T1_en_ethereum-test_signtx.py::test_signtx_staking_eip1559[claim_holesky]": "c7ba45c3cce4ec42f9410b450ffa1981bdc8ecc742561d7ce24dccc509a4ffdf",
"T3T1_en_ethereum-test_signtx.py::test_signtx_staking_eip1559[claim_mainnet]": "571cdbecf1aefa07a05f3d102342dd571f4b5dd23318e75911164b91b5cbc207", "T3T1_en_ethereum-test_signtx.py::test_signtx_staking_eip1559[claim_mainnet]": "c7ba45c3cce4ec42f9410b450ffa1981bdc8ecc742561d7ce24dccc509a4ffdf",
"T3T1_en_ethereum-test_signtx.py::test_signtx_staking_eip1559[stake_holesky]": "68e0f086eb6f19ec9ac84c8ca58399ec58ba6a7fcceb92921807926b5c00226a", "T3T1_en_ethereum-test_signtx.py::test_signtx_staking_eip1559[stake_holesky]": "56808444a3538fd30b93af84949b12d7b35923fb85db3e3c4378a6c3f6de070a",
"T3T1_en_ethereum-test_signtx.py::test_signtx_staking_eip1559[stake_main]": "68e0f086eb6f19ec9ac84c8ca58399ec58ba6a7fcceb92921807926b5c00226a", "T3T1_en_ethereum-test_signtx.py::test_signtx_staking_eip1559[stake_main]": "56808444a3538fd30b93af84949b12d7b35923fb85db3e3c4378a6c3f6de070a",
"T3T1_en_ethereum-test_signtx.py::test_signtx_staking_eip1559[unstake_holesky]": "45d4268452baf0a3fda5bf7688b697fdf5782bce4010d2b46c2a7fcbd5596c25", "T3T1_en_ethereum-test_signtx.py::test_signtx_staking_eip1559[unstake_holesky]": "4d658a17eca877e95db9da00e70f74f89b66370cbb9ef64ae015f7d37579380b",
"T3T1_en_ethereum-test_signtx.py::test_signtx_staking_eip1559[unstake_main]": "45d4268452baf0a3fda5bf7688b697fdf5782bce4010d2b46c2a7fcbd5596c25", "T3T1_en_ethereum-test_signtx.py::test_signtx_staking_eip1559[unstake_main]": "4d658a17eca877e95db9da00e70f74f89b66370cbb9ef64ae015f7d37579380b",
"T3T1_en_misc-test_msg_cipherkeyvalue.py::test_decrypt": "3f6963d82a094c2efea50fe683868b47bd9e165ff15dc520d80245ed48768874", "T3T1_en_misc-test_msg_cipherkeyvalue.py::test_decrypt": "3f6963d82a094c2efea50fe683868b47bd9e165ff15dc520d80245ed48768874",
"T3T1_en_misc-test_msg_cipherkeyvalue.py::test_decrypt_badlen": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a", "T3T1_en_misc-test_msg_cipherkeyvalue.py::test_decrypt_badlen": "5133fce02dd881612fb121f919b85166d9edf574147fc18d5ab9812f01a17e3a",
"T3T1_en_misc-test_msg_cipherkeyvalue.py::test_encrypt": "2e7bea46e6a2126dd9b0d3a7e0584dd3e089683fcb6987007d1642407fd841dd", "T3T1_en_misc-test_msg_cipherkeyvalue.py::test_encrypt": "2e7bea46e6a2126dd9b0d3a7e0584dd3e089683fcb6987007d1642407fd841dd",