1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-30 18:38:27 +00:00

chore(eckhart): update pin flows for Eckhart UI

[no changelog]
This commit is contained in:
Lukas Bielesch 2025-05-16 13:31:49 +02:00 committed by Lukáš Bielesch
parent 7730e4c63b
commit 13a020202e
16 changed files with 1505 additions and 1276 deletions

View File

@ -434,11 +434,14 @@ static void _librust_qstrs(void) {
MP_QSTR_pin__mismatch;
MP_QSTR_pin__pin_mismatch;
MP_QSTR_pin__please_check_again;
MP_QSTR_pin__reenter;
MP_QSTR_pin__reenter_new;
MP_QSTR_pin__reenter_to_confirm;
MP_QSTR_pin__setup_completed;
MP_QSTR_pin__should_be_long;
MP_QSTR_pin__title_check_pin;
MP_QSTR_pin__title_settings;
MP_QSTR_pin__title_setup;
MP_QSTR_pin__title_wrong_pin;
MP_QSTR_pin__tries_left;
MP_QSTR_pin__turn_off;

View File

@ -716,7 +716,7 @@ pub enum TranslatedString {
pin__enter = 453, // "Enter PIN"
pin__enter_new = 454, // "Enter new PIN"
pin__entered_not_valid = 455, // "The PIN you have entered is not valid."
pin__info = 456, // "PIN will be required to access this device."
pin__info = 456, // {"Bolt": "PIN will be required to access this device.", "Caesar": "PIN will be required to access this device.", "Delizia": "PIN will be required to access this device.", "Eckhart": "The PIN will be required to access this device."}
pin__invalid_pin = 457, // "Invalid PIN"
pin__last_attempt = 458, // "Last attempt"
pin__mismatch = 459, // "Entered PINs do not match!"
@ -1238,7 +1238,7 @@ pub enum TranslatedString {
address__confirmed = 869, // "Receive address confirmed"
pin__cancel_description = 870, // "Continue without PIN"
pin__cancel_info = 871, // "Without a PIN, anyone can access this device."
pin__cancel_setup = 872, // "Cancel PIN setup"
pin__cancel_setup = 872, // {"Bolt": "Cancel PIN setup", "Caesar": "Cancel PIN setup", "Delizia": "Cancel PIN setup", "Eckhart": "Cancel PIN setup?"}
send__cancel_sign = 873, // "Cancel sign"
send__send_from = 874, // "Send from"
instructions__hold_to_sign = 875, // "Hold to sign"
@ -1440,6 +1440,9 @@ pub enum TranslatedString {
passphrase__access_hidden_wallet = 1035, // "Access hidden wallet"
passphrase__hidden_wallet = 1036, // "Hidden wallet"
passphrase__show = 1037, // "Show passphrase"
pin__reenter = 1038, // "Re-enter PIN"
pin__setup_completed = 1039, // "PIN setup completed."
pin__title_setup = 1040, // "Set PIN"
}
impl TranslatedString {
@ -2256,7 +2259,14 @@ impl TranslatedString {
(Self::pin__enter, "Enter PIN"),
(Self::pin__enter_new, "Enter new PIN"),
(Self::pin__entered_not_valid, "The PIN you have entered is not valid."),
#[cfg(feature = "layout_bolt")]
(Self::pin__info, "PIN will be required to access this device."),
#[cfg(feature = "layout_caesar")]
(Self::pin__info, "PIN will be required to access this device."),
#[cfg(feature = "layout_delizia")]
(Self::pin__info, "PIN will be required to access this device."),
#[cfg(feature = "layout_eckhart")]
(Self::pin__info, "The PIN will be required to access this device."),
(Self::pin__invalid_pin, "Invalid PIN"),
(Self::pin__last_attempt, "Last attempt"),
(Self::pin__mismatch, "Entered PINs do not match!"),
@ -2834,7 +2844,14 @@ impl TranslatedString {
(Self::address__confirmed, "Receive address confirmed"),
(Self::pin__cancel_description, "Continue without PIN"),
(Self::pin__cancel_info, "Without a PIN, anyone can access this device."),
#[cfg(feature = "layout_bolt")]
(Self::pin__cancel_setup, "Cancel PIN setup"),
#[cfg(feature = "layout_caesar")]
(Self::pin__cancel_setup, "Cancel PIN setup"),
#[cfg(feature = "layout_delizia")]
(Self::pin__cancel_setup, "Cancel PIN setup"),
#[cfg(feature = "layout_eckhart")]
(Self::pin__cancel_setup, "Cancel PIN setup?"),
(Self::send__cancel_sign, "Cancel sign"),
(Self::send__send_from, "Send from"),
(Self::instructions__hold_to_sign, "Hold to sign"),
@ -3101,6 +3118,9 @@ impl TranslatedString {
(Self::passphrase__access_hidden_wallet, "Access hidden wallet"),
(Self::passphrase__hidden_wallet, "Hidden wallet"),
(Self::passphrase__show, "Show passphrase"),
(Self::pin__reenter, "Re-enter PIN"),
(Self::pin__setup_completed, "PIN setup completed."),
(Self::pin__title_setup, "Set PIN"),
];
#[cfg(feature = "micropython")]
@ -3946,11 +3966,14 @@ impl TranslatedString {
(Qstr::MP_QSTR_pin__mismatch, Self::pin__mismatch),
(Qstr::MP_QSTR_pin__pin_mismatch, Self::pin__pin_mismatch),
(Qstr::MP_QSTR_pin__please_check_again, Self::pin__please_check_again),
(Qstr::MP_QSTR_pin__reenter, Self::pin__reenter),
(Qstr::MP_QSTR_pin__reenter_new, Self::pin__reenter_new),
(Qstr::MP_QSTR_pin__reenter_to_confirm, Self::pin__reenter_to_confirm),
(Qstr::MP_QSTR_pin__setup_completed, Self::pin__setup_completed),
(Qstr::MP_QSTR_pin__should_be_long, Self::pin__should_be_long),
(Qstr::MP_QSTR_pin__title_check_pin, Self::pin__title_check_pin),
(Qstr::MP_QSTR_pin__title_settings, Self::pin__title_settings),
(Qstr::MP_QSTR_pin__title_setup, Self::pin__title_setup),
(Qstr::MP_QSTR_pin__title_wrong_pin, Self::pin__title_wrong_pin),
(Qstr::MP_QSTR_pin__tries_left, Self::pin__tries_left),
(Qstr::MP_QSTR_pin__turn_off, Self::pin__turn_off),

View File

@ -51,12 +51,13 @@ impl<'a> PinKeyboard<'a> {
) -> Self {
Self {
allow_cancel,
major_prompt: Label::left_aligned(major_prompt, theme::TEXT_SMALL)
major_prompt: Label::left_aligned(major_prompt, theme::firmware::TEXT_SMALL)
.vertically_centered(),
minor_prompt: Label::right_aligned(minor_prompt, theme::TEXT_SMALL)
minor_prompt: Label::right_aligned(minor_prompt, theme::firmware::TEXT_SMALL)
.vertically_centered(),
major_warning: major_warning
.map(|text| Label::left_aligned(text, theme::TEXT_SMALL).vertically_centered()),
major_warning: major_warning.map(|text| {
Label::left_aligned(text, theme::firmware::TEXT_SMALL).vertically_centered()
}),
input: PinInput::new(),
keypad: Keypad::new_numeric(true),
warning_timer: Timer::new(),
@ -141,7 +142,7 @@ impl Component for PinKeyboard<'_> {
.place(input_touch_area.inset(KEYBOARD_INPUT_INSETS));
self.major_warning
.as_mut()
.map(|c| c.place(input_touch_area));
.map(|c| c.place(input_touch_area.inset(KEYBOARD_INPUT_INSETS)));
// Keypad placement
self.keypad.place(keypad_area);

View File

@ -12,7 +12,9 @@ use crate::{
FlowController, FlowMsg, SwipeFlow,
},
geometry::{Direction, LinearPlacement},
layout_eckhart::firmware::TextScreenMsg,
layout_eckhart::firmware::{
ShortMenuVec, TextScreenMsg, VerticalMenu, VerticalMenuScreen, VerticalMenuScreenMsg,
},
},
};
@ -25,7 +27,8 @@ use super::super::{
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum SetNewPin {
Intro,
CancelPin,
Menu,
Cancel,
}
impl FlowController for SetNewPin {
@ -40,10 +43,12 @@ impl FlowController for SetNewPin {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Intro, FlowMsg::Cancelled) => Self::CancelPin.goto(),
(Self::Intro, FlowMsg::Info) => Self::Menu.goto(),
(Self::Intro, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
(Self::CancelPin, FlowMsg::Cancelled) => Self::Intro.goto(),
(Self::CancelPin, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
(Self::Menu, FlowMsg::Choice(0)) => Self::Cancel.goto(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.goto(),
(Self::Cancel, FlowMsg::Cancelled) => Self::Intro.goto(),
(Self::Cancel, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
_ => self.do_nothing(),
}
}
@ -56,29 +61,43 @@ pub fn new_set_new_pin(
let paragraphs = Paragraphs::new(Paragraph::new(&theme::firmware::TEXT_REGULAR, description))
.with_placement(LinearPlacement::vertical());
let content_intro = TextScreen::new(paragraphs)
.with_header(Header::new(title))
.with_action_bar(ActionBar::new_cancel_confirm())
.with_header(Header::new(title).with_menu_button())
.with_action_bar(ActionBar::new_single(Button::with_text(
TR::buttons__continue.into(),
)))
.map(|msg| match msg {
TextScreenMsg::Cancelled => Some(FlowMsg::Cancelled),
TextScreenMsg::Menu => Some(FlowMsg::Info),
TextScreenMsg::Confirmed => Some(FlowMsg::Confirmed),
_ => None,
});
let content_menu = VerticalMenuScreen::new(VerticalMenu::<ShortMenuVec>::empty().with_item(
Button::new_menu_item(TR::buttons__cancel.into(), theme::menu_item_title_orange()),
))
.with_header(Header::new(title).with_close_button())
.map(|msg| match msg {
VerticalMenuScreenMsg::Close => Some(FlowMsg::Cancelled),
VerticalMenuScreenMsg::Selected(i) => Some(FlowMsg::Choice(i)),
_ => None,
});
let paragraphs_cancel_intro = ParagraphVecShort::from_iter([
Paragraph::new(
&theme::firmware::TEXT_REGULAR_WARNING,
TR::words__not_recommended,
),
Paragraph::new(&theme::firmware::TEXT_REGULAR, TR::pin__cancel_setup),
Paragraph::new(&theme::firmware::TEXT_REGULAR, TR::pin__cancel_info),
])
.into_paragraphs()
.with_placement(LinearPlacement::vertical());
.with_placement(LinearPlacement::vertical())
.with_spacing(24);
let content_cancel_pin = TextScreen::new(paragraphs_cancel_intro)
.with_header(Header::new(title))
let content_cancel = TextScreen::new(paragraphs_cancel_intro)
.with_header(
Header::new(TR::words__important.into())
.with_text_style(theme::label_title_danger())
.with_icon(theme::ICON_WARNING, theme::ORANGE),
)
.with_action_bar(ActionBar::new_double(
Button::with_icon(theme::ICON_CHEVRON_LEFT),
Button::with_text(TR::buttons__continue.into()),
Button::with_text(TR::buttons__continue.into()).styled(theme::button_cancel_gradient()),
))
.map(|msg| match msg {
TextScreenMsg::Cancelled => Some(FlowMsg::Cancelled),
@ -88,6 +107,7 @@ pub fn new_set_new_pin(
let mut res = SwipeFlow::new(&SetNewPin::Intro)?;
res.add_page(&SetNewPin::Intro, content_intro)?
.add_page(&SetNewPin::CancelPin, content_cancel_pin)?;
.add_page(&SetNewPin::Menu, content_menu)?
.add_page(&SetNewPin::Cancel, content_cancel)?;
Ok(res)
}

View File

@ -199,22 +199,22 @@ pub const fn button_confirm() -> ButtonStyleSheet {
pub const fn button_cancel() -> ButtonStyleSheet {
ButtonStyleSheet {
normal: &ButtonStyle {
font: fonts::FONT_SATOSHI_REGULAR_22, // unused
text_color: ORANGE, // unused
font: fonts::FONT_SATOSHI_MEDIUM_26,
text_color: ORANGE,
button_color: BG,
icon_color: ORANGE,
background_color: BG,
},
active: &ButtonStyle {
font: fonts::FONT_SATOSHI_REGULAR_22, // unused
text_color: ORANGE_DIMMED, //unused
font: fonts::FONT_SATOSHI_MEDIUM_26,
text_color: ORANGE_DIMMED,
button_color: ORANGE_EXTRA_DARK,
icon_color: ORANGE_DIMMED,
background_color: ORANGE_EXTRA_DARK,
},
disabled: &ButtonStyle {
font: fonts::FONT_SATOSHI_REGULAR_22, // unused
text_color: GREY_EXTRA_DARK, // unused
font: fonts::FONT_SATOSHI_MEDIUM_26,
text_color: GREY_EXTRA_DARK,
button_color: BG,
icon_color: GREY_EXTRA_DARK,
background_color: BG,
@ -225,22 +225,22 @@ pub const fn button_cancel() -> ButtonStyleSheet {
pub const fn button_cancel_gradient() -> ButtonStyleSheet {
ButtonStyleSheet {
normal: &ButtonStyle {
font: fonts::FONT_SATOSHI_REGULAR_22, // unused
text_color: ORANGE, // unused
font: fonts::FONT_SATOSHI_MEDIUM_26,
text_color: ORANGE,
button_color: ORANGE_DARK,
icon_color: ORANGE,
background_color: ORANGE_DARK,
},
active: &ButtonStyle {
font: fonts::FONT_SATOSHI_REGULAR_22, // unused
text_color: ORANGE_DIMMED, //unused
font: fonts::FONT_SATOSHI_MEDIUM_26,
text_color: ORANGE_DIMMED,
button_color: ORANGE_EXTRA_DARK,
icon_color: ORANGE_DIMMED,
background_color: ORANGE_EXTRA_DARK,
},
disabled: &ButtonStyle {
font: fonts::FONT_SATOSHI_REGULAR_22, // unused
text_color: GREY_EXTRA_DARK, // unused
font: fonts::FONT_SATOSHI_MEDIUM_26,
text_color: GREY_EXTRA_DARK,
button_color: BG,
icon_color: GREY_EXTRA_DARK,
background_color: BG,

View File

@ -544,11 +544,14 @@ class TR:
pin__mismatch: str = "Entered PINs do not match!"
pin__pin_mismatch: str = "PIN mismatch"
pin__please_check_again: str = "Please check again."
pin__reenter: str = "Re-enter PIN"
pin__reenter_new: str = "Re-enter new PIN"
pin__reenter_to_confirm: str = "Please re-enter PIN to confirm."
pin__setup_completed: str = "PIN setup completed."
pin__should_be_long: str = "PIN should be 4-50 digits long."
pin__title_check_pin: str = "Check PIN"
pin__title_settings: str = "PIN settings"
pin__title_setup: str = "Set PIN"
pin__title_wrong_pin: str = "Wrong PIN"
pin__tries_left: str = "tries left"
pin__turn_off: str = "Are you sure you want to turn off PIN protection?"

View File

@ -11,7 +11,7 @@ if TYPE_CHECKING:
async def change_pin(msg: ChangePin) -> Success:
from storage.device import is_initialized
from trezor.messages import Success
from trezor.ui.layouts import show_success
from trezor.ui.layouts import success_pin_change
from apps.common.request_pin import (
error_pin_invalid,
@ -49,39 +49,37 @@ async def change_pin(msg: ChangePin) -> Success:
if newpin:
if curpin:
msg_screen = TR.pin__changed
msg_wire = "PIN changed"
else:
msg_screen = TR.pin__enabled
msg_wire = "PIN enabled"
else:
msg_screen = TR.pin__disabled
msg_wire = "PIN removed"
await show_success("success_pin", msg_screen)
await success_pin_change(curpin, newpin)
return Success(message=msg_wire)
def _require_confirm_change_pin(msg: ChangePin) -> Awaitable[None]:
from trezor.ui.layouts import confirm_action, confirm_set_new_pin
from trezor.ui.layouts import (
confirm_change_pin,
confirm_remove_pin,
confirm_set_new_pin,
)
has_pin = config.has_pin()
if msg.remove and has_pin: # removing pin
return confirm_action(
return confirm_remove_pin(
"disable_pin",
TR.pin__title_settings,
description=TR.pin__turn_off,
verb=TR.buttons__turn_off,
)
if not msg.remove and has_pin: # changing pin
return confirm_action(
return confirm_change_pin(
"change_pin",
TR.pin__title_settings,
description=TR.pin__change,
verb=TR.buttons__change,
prompt_screen=False,
)
if not msg.remove and not has_pin: # setting new pin

View File

@ -1576,6 +1576,44 @@ def confirm_set_new_pin(
)
def confirm_change_pin(
br_name: str,
title: str,
description: str,
) -> Awaitable[None]:
return confirm_action(
br_name,
title,
description=description,
verb=TR.buttons__change,
)
def confirm_remove_pin(
br_name: str,
title: str,
description: str,
) -> Awaitable[None]:
return confirm_action(
br_name,
title,
description=description,
verb=TR.buttons__turn_off,
)
async def success_pin_change(curpin: str | None, newpin: str | None) -> None:
if newpin:
if curpin:
msg_screen = TR.pin__changed
else:
msg_screen = TR.pin__enabled
else:
msg_screen = TR.pin__disabled
await show_success("success_pin", msg_screen)
async def confirm_firmware_update(description: str, fingerprint: str) -> None:
main = trezorui_api.confirm_value(
title=TR.firmware_update__title,

View File

@ -1617,6 +1617,44 @@ async def confirm_set_new_pin(
)
def confirm_change_pin(
br_name: str,
title: str,
description: str,
) -> Awaitable[None]:
return confirm_action(
br_name,
title,
description=description,
verb=TR.buttons__change,
)
def confirm_remove_pin(
br_name: str,
title: str,
description: str,
) -> Awaitable[None]:
return confirm_action(
br_name,
title,
description=description,
verb=TR.buttons__turn_off,
)
async def success_pin_change(curpin: str | None, newpin: str | None) -> None:
if newpin:
if curpin:
msg_screen = TR.pin__changed
else:
msg_screen = TR.pin__enabled
else:
msg_screen = TR.pin__disabled
await show_success("success_pin", msg_screen)
def confirm_firmware_update(description: str, fingerprint: str) -> Awaitable[None]:
return raise_if_not_confirmed(
trezorui_api.confirm_firmware_update(

View File

@ -1436,6 +1436,45 @@ def confirm_set_new_pin(
)
def confirm_change_pin(
br_name: str,
title: str,
description: str,
) -> Awaitable[None]:
return confirm_action(
br_name,
title,
description=description,
verb=TR.buttons__change,
prompt_screen=False,
)
def confirm_remove_pin(
br_name: str,
title: str,
description: str,
) -> Awaitable[None]:
return confirm_action(
br_name,
title,
description=description,
verb=TR.buttons__turn_off,
)
async def success_pin_change(curpin: str | None, newpin: str | None) -> None:
if newpin:
if curpin:
msg_screen = TR.pin__changed
else:
msg_screen = TR.pin__enabled
else:
msg_screen = TR.pin__disabled
await show_success("success_pin", msg_screen)
def confirm_firmware_update(description: str, fingerprint: str) -> Awaitable[None]:
return raise_if_not_confirmed(
trezorui_api.confirm_firmware_update(

View File

@ -1410,15 +1410,15 @@ async def confirm_reenter_pin(is_wipe_code: bool = False) -> None:
def pin_mismatch_popup(is_wipe_code: bool = False) -> Awaitable[ui.UiResult]:
title = TR.wipe_code__mismatch if is_wipe_code else TR.pin__mismatch
description = TR.wipe_code__enter_new if is_wipe_code else TR.pin__reenter_new
description = TR.wipe_code__mismatch if is_wipe_code else TR.pin__mismatch
button = TR.wipe_code__enter_new if is_wipe_code else TR.pin__reenter
br_name = "wipe_code_mismatch" if is_wipe_code else "pin_mismatch"
return interact(
error_popup(
title,
TR.words__important,
description,
button=TR.buttons__try_again,
button=button,
),
br_name,
BR_CODE_OTHER,
@ -1428,7 +1428,7 @@ def pin_mismatch_popup(is_wipe_code: bool = False) -> Awaitable[ui.UiResult]:
def wipe_code_same_as_pin_popup() -> Awaitable[ui.UiResult]:
return interact(
error_popup(
TR.wipe_code__invalid,
TR.words__important,
TR.wipe_code__diff_from_pin,
button=TR.buttons__try_again,
),
@ -1445,12 +1445,50 @@ def confirm_set_new_pin(
br_code: ButtonRequestType = BR_CODE_OTHER,
) -> Awaitable[None]:
return raise_if_not_confirmed(
trezorui_api.flow_confirm_set_new_pin(title=title, description=description),
trezorui_api.flow_confirm_set_new_pin(title=title, description=information),
br_name,
br_code,
)
def confirm_change_pin(
br_name: str,
title: str,
description: str,
) -> Awaitable[None]:
return confirm_action(
br_name,
title,
description=description,
verb=TR.buttons__continue,
)
def confirm_remove_pin(
br_name: str,
title: str,
description: str,
) -> Awaitable[None]:
return confirm_action(
br_name,
title,
description=description,
verb=TR.buttons__continue,
)
async def success_pin_change(curpin: str | None, newpin: str | None) -> None:
if newpin:
if curpin:
msg_screen = TR.pin__changed
else:
msg_screen = TR.pin__setup_completed
else:
msg_screen = TR.pin__disabled
await show_success("success_pin", msg_screen, button=TR.buttons__close)
def confirm_firmware_update(description: str, fingerprint: str) -> Awaitable[None]:
return raise_if_not_confirmed(
trezorui_api.confirm_firmware_update(

View File

@ -635,27 +635,41 @@
"passphrase__wallet": "Passphrase wallet",
"pin__cancel_description": "Continue without PIN",
"pin__cancel_info": "Without a PIN, anyone can access this device.",
"pin__cancel_setup": "Cancel PIN setup",
"pin__cancel_setup": {
"Bolt": "Cancel PIN setup",
"Caesar": "Cancel PIN setup",
"Delizia": "Cancel PIN setup",
"Eckhart": "Cancel PIN setup?"
},
"pin__change": "Change PIN?",
"pin__changed": "PIN changed.",
"pin__cursor_will_change": "Position of the cursor will change between entries for enhanced security.",
"pin__diff_from_wipe_code": "The new PIN must be different from your wipe code.",
"pin__disabled": "PIN protection\nturned off.",
"pin__enabled": "PIN protection\nturned on.",
"pin__setup_completed": "PIN setup completed.",
"pin__enter": "Enter PIN",
"pin__enter_new": "Enter new PIN",
"pin__entered_not_valid": "The PIN you have entered is not valid.",
"pin__info": "PIN will be required to access this device.",
"pin__info": {
"Bolt": "PIN will be required to access this device.",
"Caesar": "PIN will be required to access this device.",
"Delizia": "PIN will be required to access this device.",
"Eckhart": "The PIN will be required to access this device."
},
"pin__invalid_pin": "Invalid PIN",
"pin__last_attempt": "Last attempt",
"pin__mismatch": "Entered PINs do not match!",
"pin__pin_mismatch": "PIN mismatch",
"pin__please_check_again": "Please check again.",
"pin__reenter_new": "Re-enter new PIN",
"pin__reenter": "Re-enter PIN",
"pin__reenter_to_confirm": "Please re-enter PIN to confirm.",
"pin__should_be_long": "PIN should be 4-50 digits long.",
"pin__title_check_pin": "Check PIN",
"pin__title_settings": "PIN settings",
"pin__title_setup": "Set PIN",
"pin__title_wrong_pin": "Wrong PIN",
"pin__tries_left": "tries left",
"pin__turn_off": "Are you sure you want to turn off PIN protection?",

View File

@ -1036,5 +1036,8 @@
"1034": "firmware_update__restart",
"1035": "passphrase__access_hidden_wallet",
"1036": "passphrase__hidden_wallet",
"1037": "passphrase__show"
"1037": "passphrase__show",
"1038": "pin__reenter",
"1039": "pin__setup_completed",
"1040": "pin__title_setup"
}

View File

@ -1,8 +1,8 @@
{
"current": {
"merkle_root": "c87d48b82b2ed77c7458c6a3724e21821331a241f2361fc85fe5a7ba7407f7ba",
"datetime": "2025-06-07T11:46:44.720527+00:00",
"commit": "bc038c764e1f5aba5cdbf12e0465e5e130a13298"
"merkle_root": "14925b1bd4dcbdd44a3fb0fa412fa6a8bb6a467bb26156859b6e4747f030cc9f",
"datetime": "2025-06-08T14:07:14.202875+00:00",
"commit": "7730e4c63bcffef3537e7174252b4114b74852e4"
},
"history": [
{

View File

@ -101,9 +101,13 @@ def prepare(
elif situation == Situation.PIN_SETUP:
# Set new PIN
device_handler.run(device.change_pin) # type: ignore
assert (
TR.pin__turn_on in debug.read_layout().text_content()
or TR.pin__info in debug.read_layout().text_content()
text_content = debug.read_layout().text_content()
assert any(
needle in text_content
for needle in [
TR.pin__turn_on,
TR.pin__info,
]
)
if debug.layout_type in (
LayoutType.Bolt,
@ -130,7 +134,14 @@ def prepare(
device_handler.run(device.change_wipe_code) # type: ignore
if old_pin:
_input_see_confirm(debug, old_pin)
assert TR.wipe_code__turn_on in debug.read_layout().text_content()
text_content = debug.read_layout().text_content()
assert any(
needle in text_content
for needle in [
TR.wipe_code__turn_on,
TR.wipe_code__info,
]
)
go_next(debug)
if debug.layout_type is LayoutType.Caesar:
go_next(debug)

File diff suppressed because it is too large Load Diff