mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-21 09:39:02 +00:00
feat(eckahrt): continue recovery flow
This commit is contained in:
parent
a99aa3144f
commit
60b453f4f0
@ -536,6 +536,8 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_reset__number_of_shares_info;
|
||||
MP_QSTR_reset__one_share;
|
||||
MP_QSTR_reset__only_one_share_will_be_created;
|
||||
MP_QSTR_reset__recovery_share_description;
|
||||
MP_QSTR_reset__recovery_share_number;
|
||||
MP_QSTR_reset__recovery_share_title_template;
|
||||
MP_QSTR_reset__recovery_wallet_backup_title;
|
||||
MP_QSTR_reset__repeat_for_all_shares;
|
||||
@ -797,6 +799,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_words__really_wanna;
|
||||
MP_QSTR_words__receive;
|
||||
MP_QSTR_words__recipient;
|
||||
MP_QSTR_words__recovery_share;
|
||||
MP_QSTR_words__settings;
|
||||
MP_QSTR_words__sign;
|
||||
MP_QSTR_words__signer;
|
||||
|
@ -806,14 +806,14 @@ pub enum TranslatedString {
|
||||
recovery__title_recover = 522, // "Recover wallet"
|
||||
recovery__title_remaining_shares = 523, // "Remaining shares"
|
||||
recovery__type_word_x_of_y_template = 524, // "Type word {0} of {1}"
|
||||
recovery__wallet_recovered = 525, // "Wallet recovery completed"
|
||||
recovery__wallet_recovered = 525, // {"Bolt": "Wallet recovery completed", "Caesar": "Wallet recovery completed", "Delizia": "Wallet recovery completed", "Eckhart": "Wallet recovery completed."}
|
||||
recovery__wanna_cancel_dry_run = 526, // "Are you sure you want to cancel the backup check?"
|
||||
recovery__wanna_cancel_recovery = 527, // "Are you sure you want to cancel the recovery process?"
|
||||
recovery__word_count_template = 528, // "({0} words)"
|
||||
recovery__word_x_of_y_template = 529, // "Word {0} of {1}"
|
||||
recovery__x_more_items_starting_template_plural = 530, // "{count} more {plural} starting"
|
||||
recovery__x_more_shares_needed_template_plural = 531, // "{count} more {plural} needed"
|
||||
recovery__x_of_y_entered_template = 532, // "{0} of {1} shares entered"
|
||||
recovery__x_of_y_entered_template = 532, // {"Bolt": "{0} of {1} shares entered", "Caesar": "{0} of {1} shares entered", "Delizia": "{0} of {1} shares entered", "Eckhart": "{0} of {1} shares entered."}
|
||||
recovery__you_have_entered = 533, // "You have entered"
|
||||
reset__advanced_group_threshold_info = 534, // "The group threshold specifies the number of groups required to recover your wallet."
|
||||
reset__all_x_of_y_template = 535, // "all {0} of {1} shares"
|
||||
@ -1412,6 +1412,9 @@ pub enum TranslatedString {
|
||||
words__pay_attention = 998, // "Pay attention"
|
||||
address__check_with_source = 999, // "Check the address with source."
|
||||
words__receive = 1000, // "Receive"
|
||||
reset__recovery_share_description = 1001, // "A recovery share is a list of words you wrote down when setting up your Trezor."
|
||||
reset__recovery_share_number = 1002, // "Your wallet backup consists of 1 to 16 shares."
|
||||
words__recovery_share = 1003, // "Recovery share"
|
||||
}
|
||||
|
||||
impl TranslatedString {
|
||||
@ -2221,14 +2224,28 @@ impl TranslatedString {
|
||||
Self::recovery__title_recover => "Recover wallet",
|
||||
Self::recovery__title_remaining_shares => "Remaining shares",
|
||||
Self::recovery__type_word_x_of_y_template => "Type word {0} of {1}",
|
||||
#[cfg(feature = "layout_bolt")]
|
||||
Self::recovery__wallet_recovered => "Wallet recovery completed",
|
||||
#[cfg(feature = "layout_caesar")]
|
||||
Self::recovery__wallet_recovered => "Wallet recovery completed",
|
||||
#[cfg(feature = "layout_delizia")]
|
||||
Self::recovery__wallet_recovered => "Wallet recovery completed",
|
||||
#[cfg(feature = "layout_eckhart")]
|
||||
Self::recovery__wallet_recovered => "Wallet recovery completed.",
|
||||
Self::recovery__wanna_cancel_dry_run => "Are you sure you want to cancel the backup check?",
|
||||
Self::recovery__wanna_cancel_recovery => "Are you sure you want to cancel the recovery process?",
|
||||
Self::recovery__word_count_template => "({0} words)",
|
||||
Self::recovery__word_x_of_y_template => "Word {0} of {1}",
|
||||
Self::recovery__x_more_items_starting_template_plural => "{count} more {plural} starting",
|
||||
Self::recovery__x_more_shares_needed_template_plural => "{count} more {plural} needed",
|
||||
#[cfg(feature = "layout_bolt")]
|
||||
Self::recovery__x_of_y_entered_template => "{0} of {1} shares entered",
|
||||
#[cfg(feature = "layout_caesar")]
|
||||
Self::recovery__x_of_y_entered_template => "{0} of {1} shares entered",
|
||||
#[cfg(feature = "layout_delizia")]
|
||||
Self::recovery__x_of_y_entered_template => "{0} of {1} shares entered",
|
||||
#[cfg(feature = "layout_eckhart")]
|
||||
Self::recovery__x_of_y_entered_template => "{0} of {1} shares entered.",
|
||||
Self::recovery__you_have_entered => "You have entered",
|
||||
Self::reset__advanced_group_threshold_info => "The group threshold specifies the number of groups required to recover your wallet.",
|
||||
Self::reset__all_x_of_y_template => "all {0} of {1} shares",
|
||||
@ -2904,6 +2921,9 @@ impl TranslatedString {
|
||||
Self::words__pay_attention => "Pay attention",
|
||||
Self::address__check_with_source => "Check the address with source.",
|
||||
Self::words__receive => "Receive",
|
||||
Self::reset__recovery_share_description => "A recovery share is a list of words you wrote down when setting up your Trezor.",
|
||||
Self::reset__recovery_share_number => "Your wallet backup consists of 1 to 16 shares.",
|
||||
Self::words__recovery_share => "Recovery share",
|
||||
}
|
||||
}
|
||||
|
||||
@ -4311,6 +4331,9 @@ impl TranslatedString {
|
||||
Qstr::MP_QSTR_words__pay_attention => Some(Self::words__pay_attention),
|
||||
Qstr::MP_QSTR_address__check_with_source => Some(Self::address__check_with_source),
|
||||
Qstr::MP_QSTR_words__receive => Some(Self::words__receive),
|
||||
Qstr::MP_QSTR_reset__recovery_share_description => Some(Self::reset__recovery_share_description),
|
||||
Qstr::MP_QSTR_reset__recovery_share_number => Some(Self::reset__recovery_share_number),
|
||||
Qstr::MP_QSTR_words__recovery_share => Some(Self::words__recovery_share),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,332 @@
|
||||
use crate::{
|
||||
error,
|
||||
strutil::TString,
|
||||
translations::TR,
|
||||
ui::{
|
||||
button_request::{ButtonRequest, ButtonRequestCode},
|
||||
component::{
|
||||
button_request::ButtonRequestExt,
|
||||
text::paragraphs::{
|
||||
Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort, VecExt,
|
||||
},
|
||||
ComponentExt,
|
||||
},
|
||||
flow::{
|
||||
base::{Decision, DecisionBuilder as _},
|
||||
FlowController, FlowMsg, SwipeFlow,
|
||||
},
|
||||
geometry::{Alignment, Direction, LinearPlacement, Offset},
|
||||
layout::util::RecoveryType,
|
||||
},
|
||||
};
|
||||
|
||||
use super::super::{
|
||||
component::Button,
|
||||
firmware::{
|
||||
ActionBar, Header, TextScreen, TextScreenMsg, VerticalMenu, VerticalMenuScreen,
|
||||
VerticalMenuScreenMsg,
|
||||
},
|
||||
theme,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ContinueRecoveryBeforeShares {
|
||||
Main,
|
||||
Menu,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ContinueRecoveryBetweenShares {
|
||||
Main,
|
||||
Menu,
|
||||
Cancel,
|
||||
RecoveryShare,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ContinueRecoveryBetweenSharesAdvanced {
|
||||
Main,
|
||||
Menu,
|
||||
Cancel,
|
||||
RemainingShares,
|
||||
}
|
||||
|
||||
impl FlowController for ContinueRecoveryBeforeShares {
|
||||
#[inline]
|
||||
fn index(&'static self) -> usize {
|
||||
*self as usize
|
||||
}
|
||||
|
||||
fn handle_swipe(&'static self, _direction: Direction) -> Decision {
|
||||
self.do_nothing()
|
||||
}
|
||||
|
||||
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
|
||||
match (self, msg) {
|
||||
(Self::Main, FlowMsg::Info) => Self::Menu.goto(),
|
||||
(Self::Main, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
|
||||
(Self::Menu, FlowMsg::Cancelled) => Self::Main.goto(),
|
||||
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FlowController for ContinueRecoveryBetweenShares {
|
||||
#[inline]
|
||||
fn index(&'static self) -> usize {
|
||||
*self as usize
|
||||
}
|
||||
|
||||
fn handle_swipe(&'static self, _direction: Direction) -> Decision {
|
||||
self.do_nothing()
|
||||
}
|
||||
|
||||
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
|
||||
match (self, msg) {
|
||||
(Self::Main, FlowMsg::Info) => Self::Menu.goto(),
|
||||
(Self::Main, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
|
||||
(Self::Menu, FlowMsg::Choice(0)) => Self::RecoveryShare.goto(),
|
||||
(Self::Menu, FlowMsg::Choice(1)) => Self::Cancel.goto(),
|
||||
(Self::Menu, FlowMsg::Cancelled) => Self::Main.goto(),
|
||||
(Self::Cancel, FlowMsg::Cancelled) => Self::Menu.goto(),
|
||||
(Self::Cancel, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
|
||||
(Self::RecoveryShare, _) => Self::Menu.goto(),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FlowController for ContinueRecoveryBetweenSharesAdvanced {
|
||||
#[inline]
|
||||
fn index(&'static self) -> usize {
|
||||
*self as usize
|
||||
}
|
||||
|
||||
fn handle_swipe(&'static self, _direction: Direction) -> Decision {
|
||||
self.do_nothing()
|
||||
}
|
||||
|
||||
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
|
||||
match (self, msg) {
|
||||
(Self::Main, FlowMsg::Info) => Self::Menu.goto(),
|
||||
(Self::Main, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
|
||||
(Self::Menu, FlowMsg::Choice(0)) => Self::RemainingShares.goto(),
|
||||
(Self::Menu, FlowMsg::Choice(1)) => Self::Cancel.goto(),
|
||||
(Self::Menu, FlowMsg::Cancelled) => Self::Main.goto(),
|
||||
(Self::Cancel, FlowMsg::Cancelled) => Self::Menu.goto(),
|
||||
(Self::Cancel, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
|
||||
(Self::RemainingShares, _) => Self::Menu.goto(),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_continue_recovery_homepage(
|
||||
text: TString<'static>,
|
||||
subtext: Option<TString<'static>>,
|
||||
recovery_type: RecoveryType,
|
||||
show_instructions: bool, // 1st screen of the recovery process
|
||||
pages: Option<ParagraphVecLong<'static>>,
|
||||
) -> Result<SwipeFlow, error::Error> {
|
||||
let (header, confirm_btn, cancel_btn, cancel_title, cancel_intro) = match recovery_type {
|
||||
RecoveryType::Normal if show_instructions => (
|
||||
Header::new(TR::recovery__title.into()).with_menu_button(),
|
||||
TR::buttons__continue,
|
||||
TR::recovery__title_cancel_recovery,
|
||||
TR::recovery__title,
|
||||
TR::recovery__wanna_cancel_recovery,
|
||||
),
|
||||
RecoveryType::Normal => (
|
||||
Header::new(TR::words__title_done.into())
|
||||
.with_text_style(theme::label_title_confirm())
|
||||
.with_icon(theme::ICON_DONE, theme::GREEN_LIGHT)
|
||||
.with_menu_button(),
|
||||
TR::instructions__enter_next_share,
|
||||
TR::recovery__title_cancel_recovery,
|
||||
TR::recovery__title,
|
||||
TR::recovery__wanna_cancel_recovery,
|
||||
),
|
||||
_ => (
|
||||
Header::new(TR::recovery__title_dry_run.into()).with_menu_button(),
|
||||
TR::buttons__continue,
|
||||
TR::recovery__cancel_dry_run,
|
||||
TR::recovery__title_dry_run,
|
||||
TR::recovery__wanna_cancel_dry_run,
|
||||
),
|
||||
};
|
||||
|
||||
let mut pars_main = ParagraphVecShort::new();
|
||||
if show_instructions {
|
||||
pars_main.add(Paragraph::new(
|
||||
&theme::TEXT_REGULAR,
|
||||
TR::recovery__enter_each_word,
|
||||
));
|
||||
} else {
|
||||
pars_main.add(Paragraph::new(&theme::TEXT_REGULAR, text));
|
||||
if let Some(sub) = subtext {
|
||||
pars_main.add(Paragraph::new(&theme::TEXT_REGULAR, sub).with_top_padding(10));
|
||||
}
|
||||
};
|
||||
|
||||
let content_main = TextScreen::new(
|
||||
pars_main
|
||||
.into_paragraphs()
|
||||
.with_placement(LinearPlacement::vertical()),
|
||||
)
|
||||
.with_header(header)
|
||||
.with_action_bar(ActionBar::new_single(Button::with_text(confirm_btn.into())))
|
||||
.repeated_button_request(ButtonRequest::new(
|
||||
ButtonRequestCode::RecoveryHomepage,
|
||||
"recovery".into(),
|
||||
))
|
||||
.map(|msg| match msg {
|
||||
TextScreenMsg::Confirmed => Some(FlowMsg::Confirmed),
|
||||
TextScreenMsg::Menu => Some(FlowMsg::Info),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
let paragraphs_cancel = Paragraph::new(&theme::TEXT_REGULAR, cancel_intro)
|
||||
.into_paragraphs()
|
||||
.with_placement(LinearPlacement::vertical());
|
||||
|
||||
let content_cancel = TextScreen::new(paragraphs_cancel)
|
||||
.with_header(Header::new(cancel_title.into()))
|
||||
.with_action_bar(ActionBar::new_double(
|
||||
Button::with_icon(theme::ICON_CHEVRON_LEFT),
|
||||
Button::with_text(TR::buttons__cancel.into()).styled(theme::button_cancel()),
|
||||
))
|
||||
.map(|msg| match msg {
|
||||
TextScreenMsg::Confirmed => Some(FlowMsg::Confirmed),
|
||||
TextScreenMsg::Cancelled => Some(FlowMsg::Cancelled),
|
||||
_ => None,
|
||||
})
|
||||
.repeated_button_request(ButtonRequest::new(
|
||||
ButtonRequestCode::ProtectCall,
|
||||
"abort_recovery".into(),
|
||||
));
|
||||
|
||||
let res = if show_instructions {
|
||||
let content_menu = VerticalMenuScreen::new(
|
||||
VerticalMenu::empty().item(
|
||||
Button::with_text(cancel_btn.into())
|
||||
.styled(theme::menu_item_title_orange())
|
||||
.with_text_align(Alignment::Start)
|
||||
.with_content_offset(Offset::x(12)),
|
||||
),
|
||||
)
|
||||
.with_header(Header::new(TString::empty()).with_close_button())
|
||||
.map(|msg| match msg {
|
||||
VerticalMenuScreenMsg::Selected(i) => Some(FlowMsg::Choice(i)),
|
||||
VerticalMenuScreenMsg::Close => Some(FlowMsg::Cancelled),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
let mut res = SwipeFlow::new(&ContinueRecoveryBeforeShares::Main)?;
|
||||
res.add_page(&ContinueRecoveryBeforeShares::Main, content_main)?
|
||||
.add_page(&ContinueRecoveryBeforeShares::Menu, content_menu)?;
|
||||
res
|
||||
} else if pages.is_none() {
|
||||
let content_menu = VerticalMenuScreen::new(
|
||||
VerticalMenu::empty()
|
||||
.item(
|
||||
Button::with_text_and_subtext(
|
||||
TR::words__recovery_share.into(),
|
||||
TR::buttons__more_info.into(),
|
||||
)
|
||||
.styled(theme::menu_item_title())
|
||||
.with_text_align(Alignment::Start)
|
||||
.with_content_offset(Offset::x(12)),
|
||||
)
|
||||
.item(
|
||||
Button::with_text(cancel_btn.into())
|
||||
.styled(theme::menu_item_title_orange())
|
||||
.with_text_align(Alignment::Start)
|
||||
.with_content_offset(Offset::x(12)),
|
||||
),
|
||||
)
|
||||
.with_header(Header::new(TR::recovery__title.into()).with_close_button())
|
||||
.map(|msg| match msg {
|
||||
VerticalMenuScreenMsg::Selected(i) => Some(FlowMsg::Choice(i)),
|
||||
VerticalMenuScreenMsg::Close => Some(FlowMsg::Cancelled),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
let paragraphs_recovery_share = ParagraphVecShort::from_iter([
|
||||
Paragraph::new(&theme::TEXT_REGULAR, TR::reset__recovery_share_description)
|
||||
.with_bottom_padding(10),
|
||||
Paragraph::new(&theme::TEXT_REGULAR, TR::reset__recovery_share_number),
|
||||
])
|
||||
.into_paragraphs()
|
||||
.with_placement(LinearPlacement::vertical());
|
||||
|
||||
let content_recovery_share = TextScreen::new(paragraphs_recovery_share)
|
||||
.with_header(Header::new(TR::words__recovery_share.into()).with_close_button())
|
||||
.map(|_| Some(FlowMsg::Cancelled))
|
||||
.repeated_button_request(ButtonRequest::new(
|
||||
ButtonRequestCode::Other,
|
||||
"recovery_share".into(),
|
||||
));
|
||||
|
||||
let mut res = SwipeFlow::new(&ContinueRecoveryBetweenShares::Main)?;
|
||||
res.add_page(&ContinueRecoveryBetweenShares::Main, content_main)?
|
||||
.add_page(&ContinueRecoveryBetweenShares::Menu, content_menu)?
|
||||
.add_page(&ContinueRecoveryBetweenShares::Cancel, content_cancel)?
|
||||
.add_page(
|
||||
&ContinueRecoveryBetweenShares::RecoveryShare,
|
||||
content_recovery_share,
|
||||
)?;
|
||||
res
|
||||
} else {
|
||||
let content_menu = VerticalMenuScreen::new(
|
||||
VerticalMenu::empty()
|
||||
.item(
|
||||
Button::with_text(TR::recovery__title_remaining_shares.into())
|
||||
.styled(theme::menu_item_title())
|
||||
.with_text_align(Alignment::Start)
|
||||
.with_content_offset(Offset::x(12)),
|
||||
)
|
||||
.item(
|
||||
Button::with_text(cancel_btn.into())
|
||||
.styled(theme::menu_item_title_orange())
|
||||
.with_text_align(Alignment::Start)
|
||||
.with_content_offset(Offset::x(12)),
|
||||
),
|
||||
)
|
||||
.with_header(Header::new(TString::empty()).with_close_button())
|
||||
.map(|msg| match msg {
|
||||
VerticalMenuScreenMsg::Selected(i) => Some(FlowMsg::Choice(i)),
|
||||
VerticalMenuScreenMsg::Close => Some(FlowMsg::Cancelled),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
let n_remaining_shares = pages.as_ref().unwrap().len() / 2;
|
||||
let content_remaining_shares = TextScreen::new(
|
||||
pages
|
||||
.unwrap()
|
||||
.into_paragraphs()
|
||||
.with_placement(LinearPlacement::vertical()),
|
||||
)
|
||||
.with_header(Header::new(TR::recovery__title_remaining_shares.into()).with_close_button())
|
||||
.map(|_| Some(FlowMsg::Cancelled))
|
||||
.repeated_button_request(ButtonRequest::new(
|
||||
ButtonRequestCode::Other,
|
||||
"show_shares".into(),
|
||||
))
|
||||
.with_pages(move |_| n_remaining_shares);
|
||||
|
||||
let mut res = SwipeFlow::new(&ContinueRecoveryBetweenSharesAdvanced::Main)?;
|
||||
res.add_page(&ContinueRecoveryBetweenSharesAdvanced::Main, content_main)?
|
||||
.add_page(&ContinueRecoveryBetweenSharesAdvanced::Menu, content_menu)?
|
||||
.add_page(
|
||||
&ContinueRecoveryBetweenSharesAdvanced::Cancel,
|
||||
content_cancel,
|
||||
)?
|
||||
.add_page(
|
||||
&ContinueRecoveryBetweenSharesAdvanced::RemainingShares,
|
||||
content_remaining_shares,
|
||||
)?;
|
||||
res
|
||||
};
|
||||
Ok(res)
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
pub mod confirm_reset;
|
||||
pub mod confirm_set_new_pin;
|
||||
pub mod continue_recovery_homepage;
|
||||
pub mod get_address;
|
||||
pub mod prompt_backup;
|
||||
pub mod request_passphrase;
|
||||
@ -8,6 +9,7 @@ pub mod show_share_words;
|
||||
|
||||
pub use confirm_reset::new_confirm_reset;
|
||||
pub use confirm_set_new_pin::new_set_new_pin;
|
||||
pub use continue_recovery_homepage::new_continue_recovery_homepage;
|
||||
pub use get_address::GetAddress;
|
||||
pub use prompt_backup::PromptBackup;
|
||||
pub use request_passphrase::RequestPassphrase;
|
||||
|
@ -11,7 +11,8 @@ use crate::{
|
||||
text::{
|
||||
op::OpTextLayout,
|
||||
paragraphs::{
|
||||
Checklist, Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt,
|
||||
Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort,
|
||||
Paragraphs, VecExt,
|
||||
},
|
||||
},
|
||||
Empty, FormattedText,
|
||||
@ -326,14 +327,33 @@ impl FirmwareUI for UIEckhart {
|
||||
}
|
||||
|
||||
fn continue_recovery_homepage(
|
||||
_text: TString<'static>,
|
||||
_subtext: Option<TString<'static>>,
|
||||
text: TString<'static>,
|
||||
subtext: Option<TString<'static>>,
|
||||
_button: Option<TString<'static>>,
|
||||
_recovery_type: RecoveryType,
|
||||
_show_instructions: bool,
|
||||
_remaining_shares: Option<Obj>,
|
||||
recovery_type: RecoveryType,
|
||||
show_instructions: bool,
|
||||
remaining_shares: Option<Obj>,
|
||||
) -> Result<Gc<LayoutObj>, Error> {
|
||||
Err::<Gc<LayoutObj>, Error>(Error::ValueError(c"not implemented"))
|
||||
let pages_vec = if let Some(pages_obj) = remaining_shares {
|
||||
let mut vec = ParagraphVecLong::new();
|
||||
for page in IterBuf::new().try_iterate(pages_obj)? {
|
||||
let [title, description]: [TString; 2] = util::iter_into_array(page)?;
|
||||
vec.add(Paragraph::new(&theme::TEXT_REGULAR, title))
|
||||
.add(Paragraph::new(&theme::TEXT_MONO_LIGHT, description).break_after());
|
||||
}
|
||||
Some(vec)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let flow = flow::continue_recovery_homepage::new_continue_recovery_homepage(
|
||||
text,
|
||||
subtext,
|
||||
recovery_type,
|
||||
show_instructions,
|
||||
pages_vec,
|
||||
)?;
|
||||
LayoutObj::new_root(flow)
|
||||
}
|
||||
|
||||
fn flow_confirm_output(
|
||||
|
@ -659,6 +659,8 @@ class TR:
|
||||
reset__number_of_shares_info: str = "= total number of unique word lists used for wallet backup."
|
||||
reset__one_share: str = "1 share"
|
||||
reset__only_one_share_will_be_created: str = "Only one share will be created."
|
||||
reset__recovery_share_description: str = "A recovery share is a list of words you wrote down when setting up your Trezor."
|
||||
reset__recovery_share_number: str = "Your wallet backup consists of 1 to 16 shares."
|
||||
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."
|
||||
@ -974,6 +976,7 @@ class TR:
|
||||
words__really_wanna: str = "Do you really want to"
|
||||
words__receive: str = "Receive"
|
||||
words__recipient: str = "Recipient"
|
||||
words__recovery_share: str = "Recovery share"
|
||||
words__settings: str = "Settings"
|
||||
words__sign: str = "Sign"
|
||||
words__signer: str = "Signer"
|
||||
|
@ -99,7 +99,7 @@ async def show_group_share_success(share_index: int, group_index: int) -> None:
|
||||
|
||||
|
||||
async def continue_recovery(
|
||||
_button_label: str, # unused on delizia
|
||||
_button_label: str, # unused on eckhart
|
||||
text: str,
|
||||
subtext: str | None,
|
||||
recovery_type: RecoveryType,
|
||||
|
@ -638,14 +638,24 @@
|
||||
"recovery__type_word_x_of_y_template": "Type word {0} of {1}",
|
||||
"recovery__unlock_repeated_backup": "Create additional backup?",
|
||||
"recovery__unlock_repeated_backup_verb": "Create backup",
|
||||
"recovery__wallet_recovered": "Wallet recovery completed",
|
||||
"recovery__wallet_recovered": {
|
||||
"Bolt": "Wallet recovery completed",
|
||||
"Caesar": "Wallet recovery completed",
|
||||
"Delizia": "Wallet recovery completed",
|
||||
"Eckhart": "Wallet recovery completed."
|
||||
},
|
||||
"recovery__wanna_cancel_dry_run": "Are you sure you want to cancel the backup check?",
|
||||
"recovery__wanna_cancel_recovery": "Are you sure you want to cancel the recovery process?",
|
||||
"recovery__word_count_template": "({0} words)",
|
||||
"recovery__word_x_of_y_template": "Word {0} of {1}",
|
||||
"recovery__x_more_items_starting_template_plural": "{count} more {plural} starting",
|
||||
"recovery__x_more_shares_needed_template_plural": "{count} more {plural} needed",
|
||||
"recovery__x_of_y_entered_template": "{0} of {1} shares entered",
|
||||
"recovery__x_of_y_entered_template": {
|
||||
"Bolt": "{0} of {1} shares entered",
|
||||
"Caesar": "{0} of {1} shares entered",
|
||||
"Delizia": "{0} of {1} shares entered",
|
||||
"Eckhart": "{0} of {1} shares entered."
|
||||
},
|
||||
"recovery__you_have_entered": "You have entered",
|
||||
"reset__advanced_group_threshold_info": "The group threshold specifies the number of groups required to recover your wallet.",
|
||||
"reset__all_x_of_y_template": "all {0} of {1} shares",
|
||||
@ -697,6 +707,8 @@
|
||||
"reset__one_share": "1 share",
|
||||
"reset__only_one_share_will_be_created": "Only one share will be created.",
|
||||
"reset__recovery_share_title_template": "Recovery share #{0}",
|
||||
"reset__recovery_share_description": "A recovery share is a list of words you wrote down when setting up your Trezor.",
|
||||
"reset__recovery_share_number": "Your wallet backup consists of 1 to 16 shares.",
|
||||
"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.",
|
||||
@ -1031,6 +1043,7 @@
|
||||
"words__really_wanna": "Do you really want to",
|
||||
"words__receive": "Receive",
|
||||
"words__recipient": "Recipient",
|
||||
"words__recovery_share": "Recovery share",
|
||||
"words__settings": "Settings",
|
||||
"words__sign": "Sign",
|
||||
"words__signer": "Signer",
|
||||
|
@ -999,5 +999,8 @@
|
||||
"997": "backup__not_recommend",
|
||||
"998": "words__pay_attention",
|
||||
"999": "address__check_with_source",
|
||||
"1000": "words__receive"
|
||||
"1000": "words__receive",
|
||||
"1001": "reset__recovery_share_description",
|
||||
"1002": "reset__recovery_share_number",
|
||||
"1003": "words__recovery_share"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user