Skip to content

Commit d67b75c

Browse files
committed
workflows: use HAL for showing mnemonic and mnemonic quiz
`show_and_confirm_mnemonic(hal: ...)` did not use the HAL for all UI: show_mnemonic and confirm_mnemonic directly used the BitBox02 menu workflow without going through HAL. Can't use `hal().ui().menu(...)`, becaus: - these functions bolt a cancel prompt on top - show_mnemonic is not a normal menu where one can pick an entry, it's just a scroll-through for displaying the mnemonic This should make it possible to mock/fake/test the mneomnic workflow functions, and provide different implementations for them in future BitBox hardware.
1 parent 29e55e3 commit d67b75c

File tree

4 files changed

+51
-6
lines changed

4 files changed

+51
-6
lines changed

src/rust/bitbox02-rust/src/workflow.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ pub trait Workflows {
6868
label_middle: Option<&str>,
6969
label_right: Option<&str>,
7070
) -> trinary_choice::TrinaryChoice;
71+
72+
/// Display the BIP39 mnemonic to the user.
73+
async fn show_mnemonic(&mut self, words: &[&str]) -> Result<(), cancel::Error>;
74+
75+
/// Display these BIP39 mnemonic word choices to the user as part of the quiz to confirm the
76+
/// user backuped up the mnemonic correctly.
77+
async fn quiz_mnemonic_word(
78+
&mut self,
79+
choices: &[&str],
80+
title: &str,
81+
) -> Result<u8, cancel::Error>;
7182
}
7283

7384
pub struct RealWorkflows;
@@ -132,4 +143,16 @@ impl Workflows for RealWorkflows {
132143
) -> trinary_choice::TrinaryChoice {
133144
trinary_choice::choose(message, label_left, label_middle, label_right).await
134145
}
146+
147+
async fn show_mnemonic(&mut self, words: &[&str]) -> Result<(), cancel::Error> {
148+
mnemonic::show_mnemonic(words).await
149+
}
150+
151+
async fn quiz_mnemonic_word(
152+
&mut self,
153+
choices: &[&str],
154+
title: &str,
155+
) -> Result<u8, cancel::Error> {
156+
mnemonic::confirm_word(choices, title).await
157+
}
135158
}

src/rust/bitbox02-rust/src/workflow/mnemonic.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ fn create_random_unique_words(word: &str, length: u8) -> (u8, Vec<zeroize::Zeroi
7777
}
7878

7979
/// Displays all mnemonic words in a scroll-through screen.
80-
async fn show_mnemonic(words: &[&str]) -> Result<(), CancelError> {
80+
pub async fn show_mnemonic(words: &[&str]) -> Result<(), CancelError> {
8181
let result = RefCell::new(None);
8282
let mut component = bitbox02::ui::menu_create(bitbox02::ui::MenuParams {
8383
words,
@@ -94,7 +94,7 @@ async fn show_mnemonic(words: &[&str]) -> Result<(), CancelError> {
9494
}
9595

9696
/// Displays the `choices` to the user, returning the index of the selected choice.
97-
async fn confirm_word(choices: &[&str], title: &str) -> Result<u8, CancelError> {
97+
pub async fn confirm_word(choices: &[&str], title: &str) -> Result<u8, CancelError> {
9898
let result = RefCell::new(None);
9999
let mut component = bitbox02::ui::menu_create(bitbox02::ui::MenuParams {
100100
words: choices,
@@ -125,7 +125,7 @@ pub async fn show_and_confirm_mnemonic(
125125
.map_err(|_| CancelError::Cancelled)?;
126126

127127
// Part 1) Scroll through words
128-
show_mnemonic(words).await?;
128+
hal.ui().show_mnemonic(words).await?;
129129

130130
// Can only succeed due to `accept_only`.
131131
let _ = hal
@@ -147,9 +147,9 @@ pub async fn show_and_confirm_mnemonic(
147147
choices.push("Back to\nrecovery words");
148148
let back_idx = (choices.len() - 1) as u8;
149149
loop {
150-
match confirm_word(&choices, &title).await? {
150+
match hal.ui().quiz_mnemonic_word(&choices, &title).await? {
151151
selected_idx if selected_idx == correct_idx => break,
152-
selected_idx if selected_idx == back_idx => show_mnemonic(words).await?,
152+
selected_idx if selected_idx == back_idx => hal.ui().show_mnemonic(words).await?,
153153
_ => hal.ui().status("Incorrect word\nTry again", false).await,
154154
}
155155
}

src/rust/bitbox02-rust/src/workflow/mnemonic_c_unit_tests.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ pub use super::cancel::Error as CancelError;
1717
use alloc::string::String;
1818
use alloc::string::ToString;
1919

20+
pub async fn show_mnemonic(_words: &[&str]) -> Result<(), CancelError> {
21+
panic!("unused")
22+
}
23+
24+
pub async fn confirm_word(_choices: &[&str], _title: &str) -> Result<u8, CancelError> {
25+
panic!("unused")
26+
}
27+
2028
pub async fn show_and_confirm_mnemonic(
2129
_hal: &mut impl crate::hal::Hal,
2230
words: &[&str],

src/rust/bitbox02-rust/src/workflow/testing.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use super::{Workflows, confirm, menu, sdcard, transaction, trinary_choice, trinary_input_string};
15+
use super::{
16+
Workflows, cancel, confirm, menu, sdcard, transaction, trinary_choice, trinary_input_string,
17+
};
1618

1719
use alloc::boxed::Box;
1820
use alloc::string::String;
@@ -155,6 +157,18 @@ impl Workflows for TestingWorkflows<'_> {
155157
) -> trinary_choice::TrinaryChoice {
156158
todo!("not used in unit tests yet");
157159
}
160+
161+
async fn show_mnemonic(&mut self, _words: &[&str]) -> Result<(), cancel::Error> {
162+
todo!("not used in unit tests yet");
163+
}
164+
165+
async fn quiz_mnemonic_word(
166+
&mut self,
167+
_choices: &[&str],
168+
_title: &str,
169+
) -> Result<u8, cancel::Error> {
170+
todo!("not used in unit tests yet");
171+
}
158172
}
159173

160174
impl<'a> TestingWorkflows<'a> {

0 commit comments

Comments
 (0)