1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
pub mod account; pub mod device; mod error; pub mod id; pub mod key; pub mod wallet; pub use crate::error::{Error, Result}; use substrate_subxt::system::System; use substrate_subxt::Runtime; use sunshine_core::bip39::{Language, Mnemonic}; use sunshine_core::{ChainClient, ExposeSecret, Key, Keystore, SecretString}; pub fn ask_for_new_password(length: u8) -> std::result::Result<SecretString, std::io::Error> { loop { let password = ask_for_password("Please enter a new password (8+ characters):\n", length)?; let password2 = ask_for_password("Please confirm your new password:\n", length)?; if password.expose_secret() == password2.expose_secret() { return Ok(password); } println!("Passwords don't match."); } } pub fn ask_for_password( prompt: &str, length: u8, ) -> std::result::Result<SecretString, std::io::Error> { loop { let password = SecretString::new(rpassword::prompt_password_stdout(prompt)?); if password.expose_secret().len() >= length as usize { return Ok(password); } println!( "Password too short, needs to be at least {} characters.", length ); } } pub async fn ask_for_phrase(prompt: &str) -> std::result::Result<Mnemonic, std::io::Error> { loop { println!("{}", prompt); let mut words = Vec::with_capacity(24); while words.len() < 24 { let mut line = String::new(); async_std::io::stdin().read_line(&mut line).await?; for word in line.split(' ') { words.push(word.trim().to_string()); } } println!(); if let Ok(mnemonic) = Mnemonic::from_phrase(&words.join(" "), Language::English) { return Ok(mnemonic); } println!("Invalid mnemonic"); } } pub async fn set_device_key<T, C>( client: &mut C, paperkey: bool, suri: Option<&str>, force: bool, ) -> Result<<T as System>::AccountId, C::Error> where T: Runtime, C: ChainClient<T>, { if client.keystore().chain_signer().is_some() && !force { return Err(Error::HasDeviceKey); } let password = ask_for_new_password(8)?; let dk = if paperkey { let mnemonic = ask_for_phrase("Please enter your backup phrase:").await?; <C::Keystore as Keystore<T>>::Key::from_mnemonic(&mnemonic)? } else if let Some(suri) = &suri { <C::Keystore as Keystore<T>>::Key::from_suri(&suri)? } else { <C::Keystore as Keystore<T>>::Key::generate().await }; client .keystore_mut() .set_device_key(&dk, &password, force) .await .map_err(|e| Error::Client(e.into()))?; Ok(dk.to_account_id()) }