fix: mnemonic words size on creation, wallet creation errors

This commit is contained in:
ardocrat 2024-08-08 03:01:08 +03:00
parent 040fab6ff8
commit e0351cea84
8 changed files with 77 additions and 60 deletions

2
Cargo.lock generated
View file

@ -3796,7 +3796,7 @@ dependencies = [
[[package]] [[package]]
name = "grim" name = "grim"
version = "0.1.0" version = "0.1.2"
dependencies = [ dependencies = [
"android-activity 0.6.0", "android-activity 0.6.0",
"android_logger", "android_logger",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "grim" name = "grim"
version = "0.1.0" version = "0.1.2"
authors = ["Ardocrat <ardocrat@proton.me>"] authors = ["Ardocrat <ardocrat@proton.me>"]
description = "Cross-platform GUI for Grin with focus on usability and availability to be used by anyone, anywhere." description = "Cross-platform GUI for Grin with focus on usability and availability to be used by anyone, anywhere."
license = "Apache-2.0" license = "Apache-2.0"

View file

@ -589,7 +589,7 @@ impl WalletsContent {
if self.pass_edit.is_empty() { if self.pass_edit.is_empty() {
return; return;
} }
match self.wallets.open_selected(self.pass_edit.clone()) { match self.wallets.open_selected(&self.pass_edit) {
Ok(_) => { Ok(_) => {
// Clear values. // Clear values.
self.pass_edit = "".to_string(); self.pass_edit = "".to_string();

View file

@ -43,7 +43,10 @@ pub struct WalletCreation {
/// Mnemonic phrase setup content. /// Mnemonic phrase setup content.
pub(crate) mnemonic_setup: MnemonicSetup, pub(crate) mnemonic_setup: MnemonicSetup,
/// Network setup content. /// Network setup content.
pub(crate) network_setup: ConnectionSettings pub(crate) network_setup: ConnectionSettings,
/// Flag to check if an error occurred during wallet creation.
creation_error: Option<String>,
} }
impl Default for WalletCreation { impl Default for WalletCreation {
@ -54,7 +57,8 @@ impl Default for WalletCreation {
name_edit: String::from(""), name_edit: String::from(""),
pass_edit: String::from(""), pass_edit: String::from(""),
mnemonic_setup: MnemonicSetup::default(), mnemonic_setup: MnemonicSetup::default(),
network_setup: ConnectionSettings::default() network_setup: ConnectionSettings::default(),
creation_error: None,
} }
} }
} }
@ -160,20 +164,32 @@ impl WalletCreation {
.confirm_words .confirm_words
.contains(&String::from("")); .contains(&String::from(""));
(text, available) (text, available)
}, }
Step::SetupConnection => (t!("wallets.setup_conn_desc"), true) Step::SetupConnection => {
(t!("wallets.setup_conn_desc"), self.creation_error.is_none())
}
}; };
// Show step description.
ui.add_space(2.0); // Show step description or error if entered phrase is not valid.
ui.label(RichText::new(step_text).size(16.0).color(Colors::gray())); if self.mnemonic_setup.valid_phrase && self.creation_error.is_none() {
ui.add_space(2.0);
// Show error if entered phrase is not valid.
if !self.mnemonic_setup.valid_phrase {
step_available = false;
ui.label(RichText::new(t!("wallets.not_valid_phrase"))
.size(16.0)
.color(Colors::red()));
ui.add_space(2.0); ui.add_space(2.0);
ui.label(RichText::new(step_text).size(16.0).color(Colors::gray()));
ui.add_space(2.0);
} else {
step_available = false;
// Show error text.
if let Some(err) = &self.creation_error {
ui.add_space(10.0);
ui.label(RichText::new(err)
.size(16.0)
.color(Colors::red()));
ui.add_space(10.0);
} else {
ui.label(RichText::new(&t!("wallets.not_valid_phrase"))
.size(16.0)
.color(Colors::red()));
ui.add_space(2.0);
};
} }
if step == Step::EnterMnemonic { if step == Step::EnterMnemonic {
ui.add_space(4.0); ui.add_space(4.0);
@ -278,24 +294,29 @@ impl WalletCreation {
}, },
Step::SetupConnection => { Step::SetupConnection => {
// Create wallet at last step. // Create wallet at last step.
let name = self.name_edit.clone();
let pass = self.pass_edit.clone();
let phrase = self.mnemonic_setup.mnemonic.get_phrase();
let conn_method = &self.network_setup.method; let conn_method = &self.network_setup.method;
let mut wallet = Wallet::create(name, match Wallet::create(&self.name_edit,
pass.clone(), &self.pass_edit,
phrase, &self.mnemonic_setup.mnemonic,
conn_method).unwrap(); conn_method) {
// Open created wallet. Ok(mut w) => {
wallet.open(pass).unwrap(); // Open created wallet.
// Pass created wallet to callback. w.open(&self.pass_edit).unwrap();
(on_create)(wallet); // Pass created wallet to callback.
// Reset input data. (on_create)(w);
self.step = None; // Reset input data.
self.name_edit = String::from(""); self.step = None;
self.pass_edit = String::from(""); self.name_edit = String::from("");
self.mnemonic_setup.reset(); self.pass_edit = String::from("");
None self.mnemonic_setup.reset();
None
}
Err(e) => {
self.creation_error = Some(format!("{:?}", e));
Some(Step::SetupConnection)
}
}
} }
} }
} else { } else {
@ -364,6 +385,7 @@ impl WalletCreation {
self.name_edit = String::from(""); self.name_edit = String::from("");
self.pass_edit = String::from(""); self.pass_edit = String::from("");
self.mnemonic_setup.reset(); self.mnemonic_setup.reset();
self.creation_error = None;
}, },
Step::ConfirmMnemonic => self.step = Some(Step::EnterMnemonic), Step::ConfirmMnemonic => self.step = Some(Step::EnterMnemonic),
Step::SetupConnection => self.step = Some(Step::EnterMnemonic) Step::SetupConnection => self.step = Some(Step::EnterMnemonic)

View file

@ -261,6 +261,7 @@ impl MnemonicSetup {
/// Reset mnemonic phrase to default values. /// Reset mnemonic phrase to default values.
pub fn reset(&mut self) { pub fn reset(&mut self) {
self.mnemonic = Mnemonic::default(); self.mnemonic = Mnemonic::default();
self.valid_phrase = true;
} }
/// Draw word input [`Modal`] content. /// Draw word input [`Modal`] content.
@ -307,8 +308,7 @@ impl MnemonicSetup {
self.word_edit = self.word_edit.trim().to_string(); self.word_edit = self.word_edit.trim().to_string();
// Check if word is valid. // Check if word is valid.
let word_index = self.word_num_edit - 1; if !self.mnemonic.is_valid_word(&self.word_edit) {
if !self.mnemonic.is_valid_word(&self.word_edit, word_index) {
self.valid_word_edit = false; self.valid_word_edit = false;
return; return;
} }
@ -321,6 +321,7 @@ impl MnemonicSetup {
}; };
// Save word at list. // Save word at list.
let word_index = self.word_num_edit - 1;
words.remove(word_index); words.remove(word_index);
words.insert(word_index, self.word_edit.clone()); words.insert(word_index, self.word_edit.clone());

View file

@ -133,11 +133,11 @@ impl WalletList {
} }
/// Open selected [`Wallet`]. /// Open selected [`Wallet`].
pub fn open_selected(&mut self, password: String) -> Result<(), Error> { pub fn open_selected(&mut self, password: &String) -> Result<(), Error> {
let selected_id = self.selected_id.clone(); let selected_id = self.selected_id.clone();
for w in self.mut_list() { for w in self.mut_list() {
if Some(w.get_config().id) == selected_id { if Some(w.get_config().id) == selected_id {
return w.open(password.clone()); return w.open(password);
} }
} }
Err(Error::GenericError("Wallet is not selected".to_string())) Err(Error::GenericError("Wallet is not selected".to_string()))

View file

@ -55,15 +55,9 @@ impl Mnemonic {
self.confirm_words = Self::empty_words(&self.size); self.confirm_words = Self::empty_words(&self.size);
} }
/// Check if provided word is in BIP39 format and equal to non-empty generated word at index. /// Check if provided word is in BIP39 format.
pub fn is_valid_word(&self, word: &String, index: usize) -> bool { pub fn is_valid_word(&self, word: &String) -> bool {
let valid = search(word).is_ok(); search(word).is_ok()
let equal = if let Some(gen_word) = self.words.get(index) {
gen_word.is_empty() || gen_word == word
} else {
false
};
valid && equal
} }
/// Check if current phrase is valid. /// Check if current phrase is valid.
@ -116,12 +110,12 @@ impl Mnemonic {
return; return;
} }
let mut words = vec![]; let mut words = vec![];
words_split.enumerate().for_each(|(i, word)| { words_split.for_each(|word| {
if confirmation && !self.is_valid_word(&word.to_string(), i) { if confirmation && !self.is_valid_word(&word.to_string()) {
words = vec![]; words = vec![];
return; return;
} }
words.insert(i, word.to_string()) words.push(word.to_string())
}); });
if confirmation { if confirmation {
if !words.is_empty() { if !words.is_empty() {

View file

@ -46,7 +46,7 @@ use rand::Rng;
use crate::AppConfig; use crate::AppConfig;
use crate::node::{Node, NodeConfig}; use crate::node::{Node, NodeConfig};
use crate::tor::Tor; use crate::tor::Tor;
use crate::wallet::{ConnectionsConfig, ExternalConnection, WalletConfig}; use crate::wallet::{ConnectionsConfig, ExternalConnection, Mnemonic, WalletConfig};
use crate::wallet::store::TxHeightStore; use crate::wallet::store::TxHeightStore;
use crate::wallet::types::{ConnectionMethod, WalletAccount, WalletData, WalletInstance, WalletTransaction}; use crate::wallet::types::{ConnectionMethod, WalletAccount, WalletData, WalletInstance, WalletTransaction};
@ -127,21 +127,21 @@ impl Wallet {
/// Create new wallet. /// Create new wallet.
pub fn create( pub fn create(
name: String, name: &String,
password: String, password: &String,
mnemonic: String, mnemonic: &Mnemonic,
conn_method: &ConnectionMethod conn_method: &ConnectionMethod
) -> Result<Wallet, Error> { ) -> Result<Wallet, Error> {
let mut config = WalletConfig::create(name, conn_method); let mut config = WalletConfig::create(name.clone(), conn_method);
let w = Wallet::new(config.clone()); let w = Wallet::new(config.clone());
{ {
let instance = Self::create_wallet_instance(&mut config)?; let instance = Self::create_wallet_instance(&mut config)?;
let mut w_lock = instance.lock(); let mut w_lock = instance.lock();
let p = w_lock.lc_provider()?; let p = w_lock.lc_provider()?;
p.create_wallet(None, p.create_wallet(None,
Some(ZeroingString::from(mnemonic.clone())), Some(ZeroingString::from(mnemonic.get_phrase())),
mnemonic.len(), mnemonic.size.entropy_size(),
ZeroingString::from(password), ZeroingString::from(password.clone()),
false, false,
)?; )?;
} }
@ -312,7 +312,7 @@ impl Wallet {
} }
/// Open the wallet and start [`WalletData`] sync at separate thread. /// Open the wallet and start [`WalletData`] sync at separate thread.
pub fn open(&mut self, password: String) -> Result<(), Error> { pub fn open(&mut self, password: &String) -> Result<(), Error> {
if self.is_open() { if self.is_open() {
return Err(Error::GenericError("Already opened".to_string())); return Err(Error::GenericError("Already opened".to_string()));
} }
@ -334,7 +334,7 @@ impl Wallet {
let instance = self.instance.clone().unwrap(); let instance = self.instance.clone().unwrap();
let mut wallet_lock = instance.lock(); let mut wallet_lock = instance.lock();
let lc = wallet_lock.lc_provider()?; let lc = wallet_lock.lc_provider()?;
match lc.open_wallet(None, ZeroingString::from(password), false, false) { match lc.open_wallet(None, ZeroingString::from(password.clone()), false, false) {
Ok(_) => { Ok(_) => {
// Reset an error on opening. // Reset an error on opening.
self.set_sync_error(false); self.set_sync_error(false);