feat(core/ui): info screens before ShareWords

Inform the user about possible repeated words in 1-of-1 SLIP39.

Instruct the user to "repeat for all shares".

[no changelog]
pull/3911/head
obrusvit 3 weeks ago committed by matejcik
parent d4b854a95e
commit 25a9ef3cf5

@ -502,6 +502,7 @@ static void _librust_qstrs(void) {
MP_QSTR_reset__only_one_share_will_be_created;
MP_QSTR_reset__recovery_share_title_template;
MP_QSTR_reset__recovery_wallet_backup_title;
MP_QSTR_reset__repeat_for_all_shares;
MP_QSTR_reset__required_number_of_groups;
MP_QSTR_reset__select_correct_word;
MP_QSTR_reset__select_threshold;
@ -541,6 +542,7 @@ static void _librust_qstrs(void) {
MP_QSTR_reset__tos_link;
MP_QSTR_reset__total_number_of_shares_in_group_template;
MP_QSTR_reset__use_your_backup;
MP_QSTR_reset__words_may_repeat;
MP_QSTR_reset__words_written_down_template;
MP_QSTR_reset__write_down_words_template;
MP_QSTR_reset__wrong_word_selected;

@ -1334,6 +1334,8 @@ pub enum TranslatedString {
recovery__unlock_repeated_backup = 934, // "Create additional backup?"
recovery__unlock_repeated_backup_verb = 935, // "Unlock backup"
homescreen__set_default = 936, // "Do you really want to set default homescreen image?"
reset__words_may_repeat = 937, // "Words may repeat."
reset__repeat_for_all_shares = 938, // "Repeat for all shares."
}
impl TranslatedString {
@ -2663,6 +2665,8 @@ impl TranslatedString {
Self::recovery__unlock_repeated_backup => "Create additional backup?",
Self::recovery__unlock_repeated_backup_verb => "Unlock backup",
Self::homescreen__set_default => "Do you really want to set default homescreen image?",
Self::reset__words_may_repeat => "Words may repeat.",
Self::reset__repeat_for_all_shares => "Repeat for all shares.",
}
}
@ -3993,6 +3997,8 @@ impl TranslatedString {
Qstr::MP_QSTR_recovery__unlock_repeated_backup => Some(Self::recovery__unlock_repeated_backup),
Qstr::MP_QSTR_recovery__unlock_repeated_backup_verb => Some(Self::recovery__unlock_repeated_backup_verb),
Qstr::MP_QSTR_homescreen__set_default => Some(Self::homescreen__set_default),
Qstr::MP_QSTR_reset__words_may_repeat => Some(Self::reset__words_may_repeat),
Qstr::MP_QSTR_reset__repeat_for_all_shares => Some(Self::reset__repeat_for_all_shares),
_ => None,
}
}

@ -1,13 +1,13 @@
use crate::{
error,
micropython::{map::Map, obj::Obj, qstr::Qstr, util},
micropython::{iter::IterBuf, map::Map, obj::Obj, qstr::Qstr, util},
strutil::TString,
translations::TR,
ui::{
button_request::ButtonRequestCode,
component::{
swipe_detect::SwipeSettings,
text::paragraphs::{Paragraph, Paragraphs},
text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt},
ButtonRequestExt, ComponentExt, SwipeDirection,
},
flow::{base::Decision, flow_store, FlowMsg, FlowState, FlowStore, SwipeFlow},
@ -24,7 +24,6 @@ use super::super::{
#[derive(Copy, Clone, PartialEq, Eq, ToPrimitive)]
pub enum ShowShareWords {
// TODO: potentially also add there the 'never put anywhere digital' warning?
Instruction,
Words,
Confirm,
@ -80,16 +79,23 @@ impl ShowShareWords {
let subtitle: TString = kwargs.get(Qstr::MP_QSTR_subtitle)?.try_into()?;
let share_words_obj: Obj = kwargs.get(Qstr::MP_QSTR_words)?;
let share_words_vec: Vec<TString, 33> = util::iter_into_vec(share_words_obj)?;
let text_info: TString = kwargs.get(Qstr::MP_QSTR_text_info)?.try_into()?;
let text_info: Obj = kwargs.get(Qstr::MP_QSTR_text_info)?;
let text_confirm: TString = kwargs.get(Qstr::MP_QSTR_text_confirm)?.try_into()?;
let nwords = share_words_vec.len();
let mut instructions_paragraphs = ParagraphVecShort::new();
for item in IterBuf::new().try_iterate(text_info)? {
let text: TString = item.try_into()?;
instructions_paragraphs.add(Paragraph::new(&theme::TEXT_MAIN_GREY_LIGHT, text));
}
let paragraphs_spacing = 8;
let content_instruction = Frame::left_aligned(
title,
SwipeContent::new(Paragraphs::new(Paragraph::new(
&theme::TEXT_MAIN_GREY_LIGHT,
text_info,
))),
SwipeContent::new(
instructions_paragraphs
.into_paragraphs()
.with_spacing(paragraphs_spacing),
),
)
.with_subtitle(TR::words__instructions.into())
.with_footer(TR::instructions__swipe_up.into(), None)

@ -1688,7 +1688,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str,
/// subtitle: str,
/// words: Iterable[str],
/// text_info: str,
/// text_info: Iterable[str],
/// text_confirm: str,
/// ) -> LayoutObj[UiResult]:
/// """Show wallet backup words preceded by an instruction screen and followed by

@ -402,7 +402,7 @@ def flow_show_share_words(
title: str,
subtitle: str,
words: Iterable[str],
text_info: str,
text_info: Iterable[str],
text_confirm: str,
) -> LayoutObj[UiResult]:
"""Show wallet backup words preceded by an instruction screen and followed by

@ -638,6 +638,7 @@ class TR:
reset__only_one_share_will_be_created: str = "Only one share will be created."
reset__recovery_share_title_template: str = "Recovery share #{0}"
reset__recovery_wallet_backup_title: str = "Wallet backup"
reset__repeat_for_all_shares: str = "Repeat for all shares."
reset__required_number_of_groups: str = "The required number of groups for recovery."
reset__select_correct_word: str = "Select the correct word for each position."
reset__select_threshold: str = "Select the minimum shares required to recover your wallet."
@ -676,6 +677,7 @@ class TR:
reset__tos_link: str = "trezor.io/tos"
reset__total_number_of_shares_in_group_template: str = "Set the total number of shares in Group {0}."
reset__use_your_backup: str = "Use your backup when you need to recover your wallet."
reset__words_may_repeat: str = "Words may repeat."
reset__words_written_down_template: str = "I wrote down all {0} words in order."
reset__write_down_words_template: str = "Write the following {0} words in order on your wallet backup card."
reset__wrong_word_selected: str = "Wrong word selected!"

@ -32,7 +32,13 @@ async def show_share_words(
group_index + 1, share_index + 1
)
words_count = len(share_words)
text_info = TR.reset__write_down_words_template.format(words_count)
text_info = [TR.reset__write_down_words_template.format(words_count)]
if words_count == 20 and share_index is None:
# 1-of-1 SLIP39: inform the user about repeated words
text_info.append(TR.reset__words_may_repeat)
if share_index == 0:
# regular SLIP39, 1st share
text_info.append(TR.reset__repeat_for_all_shares)
text_confirm = TR.reset__words_written_down_template.format(words_count)
result = await RustLayout(

@ -642,6 +642,7 @@
"reset__only_one_share_will_be_created": "Only one share will be created.",
"reset__recovery_share_title_template": "Recovery share #{0}",
"reset__recovery_wallet_backup_title": "Wallet backup",
"reset__repeat_for_all_shares": "Repeat for all shares.",
"reset__required_number_of_groups": "The required number of groups for recovery.",
"reset__select_correct_word": "Select the correct word for each position.",
"reset__select_threshold": "Select the minimum shares required to recover your wallet.",
@ -680,6 +681,7 @@
"reset__tos_link": "trezor.io/tos",
"reset__total_number_of_shares_in_group_template": "Set the total number of shares in Group {0}.",
"reset__use_your_backup": "Use your backup when you need to recover your wallet.",
"reset__words_may_repeat": "Words may repeat.",
"reset__words_written_down_template": "I wrote down all {0} words in order.",
"reset__write_down_words_template": "Write the following {0} words in order on your wallet backup card.",
"reset__wrong_word_selected": "Wrong word selected!",
@ -942,4 +944,4 @@
"words__writable": "Writable",
"words__yes": "Yes"
}
}
}

@ -935,5 +935,7 @@
"933": "recovery__title_unlock_repeated_backup",
"934": "recovery__unlock_repeated_backup",
"935": "recovery__unlock_repeated_backup_verb",
"936": "homescreen__set_default"
"936": "homescreen__set_default",
"937": "reset__words_may_repeat",
"938": "reset__repeat_for_all_shares"
}

@ -1,8 +1,8 @@
{
"current": {
"merkle_root": "7a115e582a5f5f09b1850946030762360f55e516a60cf960dffc9ba174c2e4d2",
"datetime": "2024-06-02T11:07:12.183601",
"commit": "66496206ccbe9583203fbfebf8c9222e8c6379b8"
"merkle_root": "405ce2be8dcb492a1d4b25ec8aaeaa9914ff88594151beaceea52315172b11d0",
"datetime": "2024-06-03T12:40:07.498873",
"commit": "2ac4967ef190dac1fe238cc00878ff2d08e17bb5"
},
"history": [
{

@ -1554,7 +1554,9 @@ class InputFlowSlip39BasicResetRecovery(InputFlowBase):
# 6. threshold info
# 7. Set & confirm threshold value
# 8. Confirm show seeds
yield from click_through(self.debug, screens=9, code=B.ResetDevice)
# 9. Warning
# 10. Instructions
yield from click_through(self.debug, screens=10, code=B.ResetDevice)
# Mnemonic phrases
self.mnemonics = yield from load_N_shares(self.debug, 5)

Loading…
Cancel
Save