Skip to content

Commit

Permalink
initial commit of restore gui
Browse files Browse the repository at this point in the history
  • Loading branch information
yeastplume committed Mar 12, 2024
1 parent d93dc75 commit 2ab4063
Show file tree
Hide file tree
Showing 5 changed files with 294 additions and 0 deletions.
16 changes: 16 additions & 0 deletions crates/core/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,22 @@ where
}
}

pub async fn validate_mnemonic(
wallet_interface: Arc<RwLock<WalletInterface<L, C>>>,
mmemonic: String,
) -> Result<(), GrinWalletInterfaceError> {
let w = wallet_interface.write().unwrap();
match w.owner_api.as_ref() {
Some(o) => {
let mut w_lock = o.wallet_inst.lock();
let p = w_lock.lc_provider()?;
p.validate_mnemonic(mmemonic.into())
.map_err(|_| GrinWalletInterfaceError::OwnerAPINotInstantiated)
}
None => Err(GrinWalletInterfaceError::OwnerAPINotInstantiated),
}
}

/*pub async fn tx_lock_outputs(
wallet_interface: Arc<RwLock<WalletInterface<L, C>>>,
init_args: InitTxArgs,
Expand Down
3 changes: 3 additions & 0 deletions src/gui/element/wallet/setup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod init;
pub mod wallet_import;
pub mod wallet_import_success;
pub mod wallet_list;
pub mod wallet_restore;
pub mod wallet_setup;
pub mod wallet_success;

Expand All @@ -23,6 +24,7 @@ pub struct StateContainer {
pub setup_wallet_state: wallet_setup::StateContainer,
pub import_wallet_state: wallet_import::StateContainer,
pub setup_wallet_success_state: wallet_success::StateContainer,
pub setup_wallet_restore_state: wallet_restore::StateContainer,
pub import_wallet_success_state: wallet_import_success::StateContainer,
pub setup_wallet_list_state: wallet_list::StateContainer,
}
Expand All @@ -43,6 +45,7 @@ impl Default for StateContainer {
setup_init_state: Default::default(),
setup_wallet_state: Default::default(),
import_wallet_state: Default::default(),
setup_wallet_restore_state: Default::default(),
setup_wallet_success_state: Default::default(),
import_wallet_success_state: Default::default(),
setup_wallet_list_state: Default::default(),
Expand Down
268 changes: 268 additions & 0 deletions src/gui/element/wallet/setup/wallet_restore.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
use {
super::super::super::{
DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, SMALLER_FONT_SIZE,
},
crate::gui::{GrinGui, Interaction, Message},
crate::localization::localized_string,
crate::{log_error, Result},
anyhow::Context,
grin_gui_core::theme::ColorPalette,
grin_gui_core::theme::{
Column, Container, Element, PickList, Row, Scrollable, Text, TextInput,
},
grin_gui_core::wallet::WalletInterface,
grin_gui_core::{
config::{Config, Wallet},
fs::PersistentData,
node::ChainTypes::{self, Mainnet, Testnet},
},
iced::widget::{button, pick_list, scrollable, text_input, Button, Checkbox, Space},
iced::{alignment, Alignment, Command, Length},
iced_aw::Card,
std::path::PathBuf,
std::sync::{Arc, RwLock},
};

/*
TODO:
- search help in the wordlist
- card text input
*/

#[derive(Debug)]
pub struct StateContainer {
pub password: String,
pub top_level_directory: PathBuf,
pub display_name: String,
pub recovery_phrase_state: SeedState,
pub copy_button_state: button::State,
pub next_button_state: button::State,
pub is_valid: bool, // TODO: ZeroingString this
}

impl Default for StateContainer {
fn default() -> Self {
Self {
password: Default::default(),
top_level_directory: Default::default(),
display_name: Default::default(),
recovery_phrase_state: Default::default(),
copy_button_state: Default::default(),
next_button_state: Default::default(),
is_valid: false,
}
}
}
#[derive(Debug)]
pub struct SeedState {
input_state: String,
input_value: String,
}

impl Default for SeedState {
fn default() -> Self {
SeedState {
input_state: Default::default(),
input_value: Default::default(),
}
}
}

#[derive(Debug, Clone)]
pub enum LocalViewInteraction {
SeedInput(String),
SeedInputEnterPressed,
Submit,
WalletMnemonicOk,
WalletMnemonicError(Arc<RwLock<Option<anyhow::Error>>>),
WalletCreatedOk,
WalletCreateError(Arc<RwLock<Option<anyhow::Error>>>),
}

pub fn handle_message(
grin_gui: &mut GrinGui,
message: LocalViewInteraction,
) -> Result<Command<Message>> {
let state = &mut grin_gui.wallet_state.setup_state.setup_wallet_restore_state;
match message {
LocalViewInteraction::SeedInput(seed) => {
state.recovery_phrase_state.input_value = seed.clone();
let words = seed.split_whitespace();
let vec_words: Vec<&str> = words.collect();
let size_seed = vec_words.len();
if size_seed == 12 || size_seed == 24 {
let w = grin_gui.wallet_interface.clone();
let pass = state.recovery_phrase_state.input_value.clone();

let fut = move || WalletInterface::validate_mnemonic(w, pass);

return Ok(Command::perform(fut(), |r| {
match r.context("Failed to Restore Wallet From Seed") {
Ok(ret) => Message::Interaction(
Interaction::WalletSetupRestoreWalletViewInteraction(
LocalViewInteraction::WalletMnemonicOk,
),
),
Err(e) => Message::Interaction(
Interaction::WalletSetupRestoreWalletViewInteraction(
LocalViewInteraction::WalletMnemonicError(Arc::new(RwLock::new(
Some(e),
))),
),
),
}
}));
}
}

LocalViewInteraction::WalletMnemonicOk => {
state.is_valid = true;
}
LocalViewInteraction::SeedInputEnterPressed => {
//state.recovery_phrase_state.input_state.unfocus();
}
LocalViewInteraction::Submit => {
let password = state.password.clone();
let w = grin_gui.wallet_interface.clone();

/*let fut = move || {
WalletInterface::init(
w,
password,
state.top_level_directory.clone(),
state.display_name.clone(),
32,
)
};*/
}
LocalViewInteraction::WalletCreatedOk => {
grin_gui.wallet_state.setup_state.mode =
crate::gui::element::wallet::setup::Mode::WalletCreateSuccess;
let _ = grin_gui.config.save();
}
LocalViewInteraction::WalletMnemonicError(err) => {
state.is_valid = false;
grin_gui.error = err.write().unwrap().take();
if let Some(e) = grin_gui.error.as_ref() {
log_error(e);
}
}
LocalViewInteraction::WalletCreateError(err) => {
grin_gui.error = err.write().unwrap().take();
if let Some(e) = grin_gui.error.as_ref() {
log_error(e);
}
}
}
Ok(Command::none())
}

pub fn data_container<'a>(
color_palette: ColorPalette,
state: &'a mut StateContainer,
) -> Container<'a, Message> {
// Title row
let title = Text::new(localized_string("setup-grin-wallet-success"))
.size(DEFAULT_HEADER_FONT_SIZE)
.horizontal_alignment(alignment::Horizontal::Left);

let title_container =
Container::new(title).style(grin_gui_core::theme::ContainerStyle::NormalBackground);

let title_row = Row::new()
.push(title_container)
.align_items(Alignment::Center)
.spacing(20);

let description = Text::new(localized_string("setup-grin-wallet-recovery-phrase"))
.size(DEFAULT_FONT_SIZE)
.horizontal_alignment(alignment::Horizontal::Center);
let description_container =
Container::new(description).style(grin_gui_core::theme::ContainerStyle::NormalBackground);

let recovery_phrase_column = {
let recovery_phrase_input = TextInput::new(
&localized_string("password")[..],
&state.recovery_phrase_state.input_state,
)
.on_input(|s| {
Interaction::WalletSetupRestoreWalletViewInteraction(LocalViewInteraction::SeedInput(s))
})
.on_submit(Interaction::WalletSetupRestoreWalletViewInteraction(
LocalViewInteraction::SeedInputEnterPressed,
))
.size(DEFAULT_FONT_SIZE)
.padding(6)
.width(Length::Fixed(400.0))
.style(grin_gui_core::theme::TextInputStyle::AddonsQuery);

let recovery_phrase_input: Element<Interaction> = recovery_phrase_input.into();

let recovery_phrase_input_col = Column::new()
.push(recovery_phrase_input.map(Message::Interaction))
.spacing(DEFAULT_PADDING)
.align_items(Alignment::Center);

/*let check_seed = || {
!state.recovery_phrase_state.input_value.is_empty() && state.is_valid
};
let mut seed_entry_value = localized_string("");
if check_seed() {
seed_entry_value = localized_string("setup-grin-passwords-okay")
}
let seed_entry_status = Text::new(seed_entry_value)
.size(DEFAULT_FONT_SIZE)
.horizontal_alignment(alignment::Horizontal::Left);
let seed_entry_status_container = Container::new(seed_entry_status)
//.width(Length::Fill)
.style(style::NormalSuccessBackgroundContainer(color_palette));*/

Column::new().push(recovery_phrase_input_col) //.push(seed_entry_status_container)
};

let submit_button_label_container = Container::new(
Text::new(localized_string("setup-grin-wallet-done")).size(DEFAULT_FONT_SIZE),
)
.center_x()
.align_x(alignment::Horizontal::Center);

let mut next_button = Button::new(submit_button_label_container)
.style(grin_gui_core::theme::ButtonStyle::Primary);

if state.is_valid {
next_button = next_button.on_press(Interaction::WalletSetupRestoreWalletViewInteraction(
LocalViewInteraction::Submit,
));
}

let next_button: Element<Interaction> = next_button.into();

let unit_spacing = 15;

let colum = Column::new()
.push(title_row)
.push(Space::new(
Length::Fixed(0.0),
Length::Fixed(unit_spacing as f32 + 5.0),
))
.push(description_container)
.push(Space::new(
Length::Fixed(0.0),
Length::Fixed(unit_spacing as f32 + 5.0),
))
.push(recovery_phrase_column)
.push(Space::new(
Length::Fixed(0.0),
Length::Fixed(unit_spacing as f32 + 10.0),
))
.push(next_button.map(Message::Interaction))
.align_items(Alignment::Center);

Container::new(colum)
.center_y()
.center_x()
.width(Length::Fill)
}
3 changes: 3 additions & 0 deletions src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,9 @@ pub enum Interaction {
WalletSetupViewInteraction(element::wallet::setup::LocalViewInteraction),
WalletSetupInitViewInteraction(element::wallet::setup::init::LocalViewInteraction),
WalletSetupWalletViewInteraction(element::wallet::setup::wallet_setup::LocalViewInteraction),
WalletSetupRestoreWalletViewInteraction(
element::wallet::setup::wallet_restore::LocalViewInteraction,
),
WalletSetupImportWalletViewInteraction(
element::wallet::setup::wallet_import::LocalViewInteraction,
),
Expand Down
4 changes: 4 additions & 0 deletions src/gui/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ pub fn handle_message(grin_gui: &mut GrinGui, message: Message) -> Result<Comman
Message::Interaction(Interaction::WalletSetupWalletViewInteraction(l)) => {
return element::wallet::setup::wallet_setup::handle_message(grin_gui, l);
}
// Setup -> Wallet Restore Settings
Message::Interaction(Interaction::WalletSetupRestoreWalletViewInteraction(l)) => {
return element::wallet::setup::wallet_restore::handle_message(grin_gui, l);
}
// Setup -> Wallet Import Settings
Message::Interaction(Interaction::WalletSetupImportWalletViewInteraction(l)) => {
return element::wallet::setup::wallet_import::handle_message(grin_gui, l);
Expand Down

0 comments on commit 2ab4063

Please sign in to comment.