diff --git a/crates/sp_client/src/api.rs b/crates/sp_client/src/api.rs index 5674539..48489dd 100644 --- a/crates/sp_client/src/api.rs +++ b/crates/sp_client/src/api.rs @@ -1,7 +1,10 @@ +use std::collections::HashMap; + use rand::Rng; use anyhow::Error as AnyhowError; use serde_json::Error as SerdeJsonError; +use shamir::SecretData; use sp_backend::bitcoin::secp256k1::SecretKey; use sp_backend::silentpayments::Error as SpError; @@ -15,7 +18,7 @@ use sp_backend::spclient::SpendKey; use sp_backend::spclient::{derive_keys_from_seed, OutputList, SpClient}; use web_sys::js_sys::JsString; -use crate::user::User; +use crate::user::{User, UserKeys}; type ApiResult = Result; @@ -59,9 +62,9 @@ impl Into for ApiError { #[derive(Tsify, Serialize, Deserialize)] #[tsify(into_wasm_abi)] #[allow(non_camel_case_types)] -pub struct generate_create_user_return { +pub struct GenerateCreateUserReturn { pub user: User, - pub output_list: OutputList + pub output_list_vec: Vec, } #[wasm_bindgen] @@ -69,11 +72,22 @@ pub fn setup() { wasm_logger::init(wasm_logger::Config::default()); } +#[wasm_bindgen] +pub fn test_fn() { + log::info!("test"); +} + +// Should be transfered to annother module +pub struct GenerateSPWallet { + pub sp_client: SpClient, + pub sp_outputs: OutputList, +} + pub fn generate_sp_wallet( label: Option, birthday: u32, is_testnet: bool, -) -> ApiResult { +) -> ApiResult { let mut seed = [0u8; 64]; rand::thread_rng().fill(&mut seed); let (scan_sk, spend_sk) = derive_keys_from_seed(&seed, is_testnet)?; @@ -90,7 +104,7 @@ pub fn generate_sp_wallet( our_address.to_string() ); - let sp_client_json = serde_json::to_string(&sp_client)?; + //let sp_client_json = serde_json::to_string(&sp_client)?; // Generate an empty outputs let sp_outputs = OutputList::new( @@ -98,11 +112,11 @@ pub fn generate_sp_wallet( our_address.get_spend_key(), birthday, ); - let sp_outputs_json = serde_json::to_string(&sp_outputs)?; + //let sp_outputs_json = serde_json::to_string(&sp_outputs)?; - let res = generate_sp_wallet_return { - sp_client_json, - sp_outputs_json, + let res = GenerateSPWallet { + sp_client, + sp_outputs, }; Ok(res) @@ -116,26 +130,64 @@ pub fn get_receiving_address(sp_client: String) -> String { #[wasm_bindgen] pub fn create_user( - password: JsString, - image_to_recover: &[u8], - image_to_revoke: &[u8], + password: String, label: Option, birthday: u32, -) -> ApiResult { +) -> ApiResult { + let mut output_list: Vec = Vec::new(); + log::info!("Ok0"); + //recover + let sp_wallet_recover = generate_sp_wallet(label.clone(), birthday, true)?; + output_list.push(sp_wallet_recover.sp_outputs); + let recover_scan_key = sp_wallet_recover.sp_client.get_scan_key(); + let recover_spend_key = match sp_wallet_recover.sp_client.get_spend_key() { + SpendKey::Secret(key) => key, + SpendKey::Public(_) => { + return Err(ApiError::from(AnyhowError::msg( + "No recover spend key created on Signet", + ))) + } + }; + let recover_keys = UserKeys::add_keys_recover(recover_scan_key, recover_spend_key); + log::info!("Ok1"); + //revoke + let sp_wallet_revoke = generate_sp_wallet(label.clone(), birthday, true)?; + output_list.push(sp_wallet_revoke.sp_outputs); + let revoke_scan_key = sp_wallet_revoke.sp_client.get_scan_key(); + let revoke_spend_key = match sp_wallet_revoke.sp_client.get_spend_key() { + SpendKey::Secret(key) => key, + SpendKey::Public(_) => { + return Err(ApiError::from(AnyhowError::msg( + "No revoke spend key created on Signet", + ))) + } + }; + let revoke_keys = UserKeys::add_keys_revoke(revoke_scan_key, revoke_spend_key); + //mainet + let sp_wallet_main = generate_sp_wallet(label, birthday, false)?; + output_list.push(sp_wallet_main.sp_outputs); + let main_scan_key = sp_wallet_main.sp_client.get_scan_key(); + let main_spend_key = match sp_wallet_main.sp_client.get_spend_key() { + SpendKey::Secret(key) => key, + SpendKey::Public(_) => { + return Err(ApiError::from(AnyhowError::msg( + "No spend key created on Mainet", + ))) + } + }; + let main_keys = UserKeys::add_keys_main(main_scan_key, main_spend_key); - // todo: struct with sp_client{revoke, recover, main} - let sp_client_recover = generate_sp_wallet(label, birthday, true)?; - let sp_client_revoke = generate_sp_wallet(label, birthday, true)?; - let sp_client_main = generate_sp_wallet(label, birthday, false)?; + let user_keys = UserKeys::new(recover_keys, revoke_keys, main_keys); + log::info!("Ok2"); - let user = User::new( - recover_spend_key, - revoke_spend_key, - revoke_scan_key, - &password, - image_to_recover, - image_to_revoke, - )?; + let user = User::new(user_keys, password)?; - Ok(user) + let generate_user = GenerateCreateUserReturn { + user, + output_list_vec: output_list, + }; + log::info!("Ok3"); + + + Ok(generate_user) } diff --git a/crates/sp_client/src/user.rs b/crates/sp_client/src/user.rs index 844f283..fcadd92 100644 --- a/crates/sp_client/src/user.rs +++ b/crates/sp_client/src/user.rs @@ -37,6 +37,62 @@ use crate::aesgcm::{Aes256Encryption, Purpose}; //extern crate shamir; //use shamir::SecretData; +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum KeyType { + Recover(SpKeys), + Revoke(SpKeys), + Main(SpKeys), +} +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SpKeys { + pub scan_key: SecretKey, + pub spend_key: SecretKey, +} +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct UserKeys { + pub recover_keys: KeyType, + pub revoke_keys: KeyType, + pub main_keys: KeyType, +} + +impl UserKeys { + pub fn new(recover_keys: KeyType, revoke_keys: KeyType, main_keys: KeyType) -> Self { + UserKeys { + recover_keys, + revoke_keys, + main_keys, + } + } + pub fn add_keys_recover(scan_key: SecretKey, spend_key: SecretKey) -> KeyType { + let sp_keys = SpKeys { + scan_key, + spend_key, + }; + KeyType::Recover((sp_keys)) + } + pub fn add_keys_revoke(scan_key: SecretKey, spend_key: SecretKey) -> KeyType { + let sp_keys = SpKeys { + scan_key, + spend_key, + }; + KeyType::Revoke((sp_keys)) + } + pub fn add_keys_main(scan_key: SecretKey, spend_key: SecretKey) -> KeyType { + let sp_keys = SpKeys { + scan_key, + spend_key, + }; + KeyType::Main((sp_keys)) + } + + pub fn get_keys(&self, key_type: KeyType) -> SpKeys { + match key_type { + KeyType::Recover(keys) => keys, + KeyType::Revoke(keys) => keys, + KeyType::Main(keys) => keys, + } + } +} #[derive(Debug, Serialize, Deserialize, Clone, Tsify)] #[tsify(into_wasm_abi, from_wasm_abi)] @@ -50,20 +106,21 @@ pub struct User { impl User { pub fn new( - recover_spend_key: SecretKey, - revoke_spend_key: SecretKey, - revoke_scan_key: SecretKey, + user_keys: UserKeys, user_password: String, - ) -> Result { + ) -> Result { let mut rng = thread_rng(); // image revoke // We just take the 2 revoke keys + let revoke_scan_key = user_keys.get_keys(user_keys.revoke_keys.clone()).scan_key; + let revoke_spend_key = user_keys.get_keys(user_keys.revoke_keys.clone()).spend_key; let mut revoke_data = Vec::with_capacity(64); revoke_data.extend_from_slice(revoke_scan_key.as_ref()); revoke_data.extend_from_slice(revoke_spend_key.as_ref()); // split recover spend key + let recover_spend_key = user_keys.get_keys(user_keys.recover_keys.clone()).spend_key; let (part1_key, part2_key) = recover_spend_key.as_ref().split_at(SECRET_KEY_SIZE / 2); let mut recover_data = Vec::::with_capacity(64); // 32 * 2 @@ -347,7 +404,7 @@ pub fn read_exif(image: &[u8]) -> Result, String> { // let base64_string = base64::encode(decoded_data); // base64_string // } - +/* #[cfg(test)] mod tests { use super::*; // Import everything from the outer module @@ -389,4 +446,4 @@ mod tests { assert!(format!("{}", retrieved_recover_spend.unwrap().display_secret()) == RECOVER_SPEND) } -} +}*/