From 38beda800722b4cfcdae277dc0673d19b0e88fd0 Mon Sep 17 00:00:00 2001 From: Sosthene00 <674694@protonmail.ch> Date: Sat, 23 Mar 2024 23:24:00 +0100 Subject: [PATCH] Create new user --- crates/sp_client/Cargo.toml | 2 - crates/sp_client/src/api.rs | 59 ++++- crates/sp_client/src/user.rs | 410 ++++++++++++++++++----------------- src/services.ts | 10 +- 4 files changed, 275 insertions(+), 206 deletions(-) diff --git a/crates/sp_client/Cargo.toml b/crates/sp_client/Cargo.toml index 771af5c..52fc7ed 100644 --- a/crates/sp_client/Cargo.toml +++ b/crates/sp_client/Cargo.toml @@ -30,8 +30,6 @@ img-parts = "0.3.0" bytes = "1.5.0" scrypt = "0.11.0" shamir = "2.0.0" -bitcoin = { version = "0.31.1", features = ["serde", "base64"] } - [dev-dependencies] wasm-bindgen-test = "0.3" diff --git a/crates/sp_client/src/api.rs b/crates/sp_client/src/api.rs index d629df8..8f14e6f 100644 --- a/crates/sp_client/src/api.rs +++ b/crates/sp_client/src/api.rs @@ -1,8 +1,9 @@ use rand::Rng; use anyhow::Error as AnyhowError; -use sp_backend::silentpayments::Error as SpError; use serde_json::Error as SerdeJsonError; +use sp_backend::silentpayments::Error as SpError; +use sp_backend::bitcoin::secp256k1::SecretKey; use serde::{Deserialize, Serialize}; use sp_backend::silentpayments::sending::SilentPaymentAddress; @@ -12,6 +13,9 @@ use wasm_bindgen::prelude::*; 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; type ApiResult = Result; @@ -24,19 +28,25 @@ struct ApiError { impl From for ApiError { fn from(value: AnyhowError) -> Self { - ApiError {message: value.to_string()} + ApiError { + message: value.to_string(), + } } } impl From for ApiError { fn from(value: SpError) -> Self { - ApiError { message: value.to_string() } + ApiError { + message: value.to_string(), + } } } impl From for ApiError { fn from(value: SerdeJsonError) -> Self { - ApiError { message: value.to_string() } + ApiError { + message: value.to_string(), + } } } @@ -104,3 +114,44 @@ pub fn get_receiving_address(sp_client: String) -> String { let sp_client: SpClient = serde_json::from_str(&sp_client).unwrap(); sp_client.get_receiving_address() } + +#[wasm_bindgen] +pub fn create_user( + recover_wallet: String, + revoke_wallet: String, + password: JsString, + image_to_recover: &[u8], + image_to_revoke: &[u8], +) -> ApiResult { + let recover_sp_client: SpClient = serde_json::from_str(&recover_wallet)?; + let revoke_sp_client: SpClient = serde_json::from_str(&revoke_wallet)?; + let recover_spend_key: SecretKey = match recover_sp_client.get_spend_key() { + SpendKey::Secret(sk) => sk, + SpendKey::Public(_) => { + return Err(ApiError { + message: "Can't create user from a watch-only sp_client".to_owned(), + }) + } + }; + let revoke_spend_key: SecretKey = match revoke_sp_client.get_spend_key() { + SpendKey::Secret(sk) => sk, + SpendKey::Public(_) => { + return Err(ApiError { + message: "Can't create user from a watch-only sp_client".to_owned(), + }) + } + }; + + let revoke_scan_key = revoke_sp_client.get_scan_key(); + + let user = User::new( + recover_spend_key, + revoke_spend_key, + revoke_scan_key, + &password, + image_to_recover, + image_to_revoke, + )?; + + Ok(user) +} diff --git a/crates/sp_client/src/user.rs b/crates/sp_client/src/user.rs index c4ebc87..be1c61b 100644 --- a/crates/sp_client/src/user.rs +++ b/crates/sp_client/src/user.rs @@ -1,21 +1,37 @@ -use anyhow::Error; -use bitcoin::secp256k1::SecretKey; +use aes::cipher::generic_array::GenericArray; +use aes_gcm::aead::Aead; +use aes_gcm::AeadCore; +use aes_gcm::KeyInit; +use aes_gcm::{aead::Buffer, Aes256Gcm, Key}; +use anyhow::{Error, Result}; +use bytes::Buf; use rand::{self, thread_rng, Rng, RngCore}; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; +use sp_backend::bitcoin::hashes::Hash; +use sp_backend::bitcoin::hashes::HashEngine; +use sp_backend::bitcoin::hex::{DisplayHex, FromHex}; +use sp_backend::bitcoin::secp256k1::SecretKey; use tsify::Tsify; use wasm_bindgen::prelude::*; use wasm_bindgen::JsValue; use web_sys::console; +use web_sys::js_sys::JsString; use crate::aesgcm::{Aes256GcmIv96Bit, KeyEncryption}; -use crate::secretdata::SecretData; +// use crate::secretdata::SecretData; use bytes::Bytes; use hex; use sha2::{Digest, Sha256}; +use shamir::SecretData; use std::fs::File; +use std::io::Read; +use std::io::Write; +use std::str::FromStr; use crate::api::{generate_sp_wallet, generate_sp_wallet_return}; +use sp_backend::bitcoin::secp256k1::constants::SECRET_KEY_SIZE; +use sp_backend::silentpayments::bitcoin_hashes::sha256; use sp_backend::silentpayments::sending::SilentPaymentAddress; use sp_backend::spclient::SpendKey; use sp_backend::spclient::{OutputList, SpClient}; @@ -31,90 +47,100 @@ use scrypt::{ //extern crate shamir; //use shamir::SecretData; - -#[wasm_bindgen] -#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive(Debug, Serialize, Deserialize, Clone, Tsify)] +#[tsify(into_wasm_abi, from_wasm_abi)] pub struct User { - image_recover: ImageRecover, - image_revoke: ImageRevoke, - sharding: Sharding, - pre_id: String, - recovered_spend_key: Option, + image_recover: BackUpImage, + image_revoke: BackUpImage, + sharding: Sharding, + pre_id: String, + recovered_spend_key: Option, } -#[wasm_bindgen] impl User { - #[wasm_bindgen(constructor)] - pub fn new(new_password: &str, image_to_recover: &[u8], image_to_revoke: &[u8]) -> Self { - - let password = new_password.to_string(); - let random_seed1 = generate_random_key(32); - let random_seed2 = generate_random_key(32); - //wallet recover - let wallet_rec: String = match generate_sp_wallet(None,50000, true) { - Some(sp_wallet) => sp_wallet.sp_client_json, - None => panic!("No wallet recover available"), - }; - let sp_client_rec: SpClient = serde_json::from_str(&wallet_rec).unwrap(); - let priv_recover_scan_key_bytes = sp_client_rec.get_scan_key().secret_bytes(); - let priv_recover_scan_key = from_b64_to_hex(&base64::encode(priv_recover_scan_key_bytes)); - let priv_recover_spend_key_bytes = match sp_client_rec.get_spend_key(){ - SpendKey::Secret(key)=> key.secret_bytes(), - SpendKey::Public(_) => panic!("No recover spend key created on Signet"), - }; - let priv_recover_spend_key = from_b64_to_hex(&base64::encode(priv_recover_spend_key_bytes)); - console::log_2(&"priv_recover_spend_key".into(),&JsValue::from_str(&priv_recover_spend_key)); - //wallet revoke - let wallet_rev: String = match generate_sp_wallet(None, 50000, true) { - Some(sp_wallet) => sp_wallet.sp_client_json, - None => panic!("No wallet revoke available"), - }; - let sp_client_rev: SpClient = serde_json::from_str(&wallet_rec).unwrap(); - let priv_revoke_scan_key_bytes = sp_client_rev.get_scan_key().secret_bytes(); - let priv_revoke_scan_key = from_b64_to_hex(&base64::encode(priv_revoke_scan_key_bytes)); - let priv_revoke_spend_key_bytes = match sp_client_rev.get_spend_key(){ - SpendKey::Secret(key)=> key.secret_bytes(), - SpendKey::Public(_) => panic!("No revoke spend key created on Signet"), - }; - let priv_revoke_spend_key = from_b64_to_hex(&base64::encode(priv_revoke_spend_key_bytes)); - - //split recover spend key - let (part1_key, part2_key) = priv_recover_spend_key.split_at(priv_recover_spend_key.len()/2); - - //part1 enc - let pwd_hash_part1 = from_hex_to_b64(&sha_256(&format!("{}{}",password, &random_seed1))); + pub fn new( + recover_spend_key: SecretKey, + revoke_spend_key: SecretKey, + revoke_scan_key: SecretKey, + user_password: &JsString, + recover_image: &[u8], + revoke_image: &[u8], + ) -> Result { + // image revoke + // We just take the 2 revoke keys and put it in the revoke_img file + let mut revoke_data = [0u8; SECRET_KEY_SIZE * 2]; + revoke_data[..SECRET_KEY_SIZE].copy_from_slice(revoke_scan_key.as_ref()); + revoke_data[SECRET_KEY_SIZE..].copy_from_slice(revoke_spend_key.as_ref()); - //split recover spend key - let (part1_key, part2_key) = - priv_recover_spend_key.split_at(priv_recover_spend_key.len() / 2); + let revoke_img_with_data = BackUpImage::new_revoke(revoke_image, &revoke_data)?; + + // split recover 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(88); + + // generate 2 tokens of 32B entropy + let mut entropy_1 = [0u8; 32]; + entropy_1.copy_from_slice(&generate_random_key(32)); + let mut entropy_2 = [0u8; 32]; + entropy_2.copy_from_slice(&generate_random_key(32)); + + recover_data.extend_from_slice(&entropy_1); + recover_data.extend_from_slice(&entropy_2); + + // convert the password in a Vec + // Be careful of javascript strings: https://rustwasm.github.io/wasm-bindgen/reference/types/str.html#utf-16-vs-utf-8 + assert!(user_password.is_valid_utf16()); + let password: String = user_password.into(); + + // hash the concatenation + let mut engine = sha256::HashEngine::default(); + engine.write_all(&password.as_bytes()); + engine.write_all(&entropy_1); + let hash1 = sha256::Hash::from_engine(engine); + + // take it as a AES key + let key1: &Key = hash1.as_byte_array().try_into()?; + let cipher = Aes256Gcm::new(&key1); + + // encrypt the part1 of the key + let nonce1 = Aes256Gcm::generate_nonce(&mut thread_rng()); + let nonce2 = Aes256Gcm::generate_nonce(&mut thread_rng()); + let cipher_recover_part1 = cipher + .encrypt(&nonce1, part1_key) + .map_err(|e| anyhow::Error::msg(format!("{}", e)))?; + + log::debug!("cipher_part1 length: {}", cipher_recover_part1.len()); + + recover_data.extend_from_slice(&nonce1); + recover_data.extend_from_slice(&nonce2); + recover_data.extend_from_slice(&cipher_recover_part1); - //part1 enc - let pwd_hash_part1 = from_hex_to_b64(&sha_256(&format!("{}{}", password, &random_seed1))); - let key_enc_part1 = KeyEncryption::new(None, Some(pwd_hash_part1.clone()), None); - let part1_key_enc = key_enc_part1.enc_string(part1_key.to_string()); - //part2 enc - let pwd_hash_part2 = from_hex_to_b64(&sha_256(&format!("{}{}", password, random_seed2))); - let key_enc_part2 = KeyEncryption::new(None, Some(pwd_hash_part2.clone()), None); - let part2_key_enc = key_enc_part2.enc_string(part2_key.to_string()); //image recover - let image_recover = ImageRecover::new( - image_to_recover, - &random_seed1, - &random_seed2, - &part1_key_enc, - ); - //image revoke - //let priv_revoke_spend_key = wallet.priv_revoke_spend_key.to_owned(); - //let priv_revoke_scan_key = wallet.priv_revoke_scan_key.to_owned(); - let image_revoke = ImageRevoke::new( - image_to_revoke, - &priv_revoke_spend_key, - &priv_revoke_scan_key, - ); + let recover_img_with_data = BackUpImage::new_recover(recover_image, &recover_data)?; + + // encrypt the part 2 of the key + let mut engine = sha256::HashEngine::default(); + engine.write_all(&password.as_bytes()); + engine.write_all(&entropy_2); + let hash2 = sha256::Hash::from_engine(engine); + + // take it as a AES key + let key2: &Key = hash2.as_byte_array().try_into()?; + let cipher = Aes256Gcm::new(&key2); + + // encrypt the part2 of the key + let cipher_recover_part2 = cipher + .encrypt(&nonce2, part2_key) + .map_err(|e| anyhow::Error::msg(format!("{}", e)))?; + //create shardings - let sharding = Sharding::new(&part2_key_enc, 10u8); //nMembers = 10 for testing, need to recover nmember elsewhere - //Pre ID - let pre_id = sha_256(&format!("{}{}", password, part2_key_enc)); + let sharding = Sharding::new(&cipher_recover_part2.to_lower_hex_string(), 10u8); //nMembers = 10 for testing, need to recover nmember elsewhere + + //Pre ID + let mut engine = sha256::HashEngine::default(); + engine.write_all(&password.as_bytes()); + engine.write_all(&cipher_recover_part1); + let pre_id = sha256::Hash::from_engine(engine); //Create PRDList //@todo @@ -122,86 +148,118 @@ impl User { //@todo //Receive List Items (PCD) - console::log_1(&"authentication: ok".into()); - User { - image_recover, - image_revoke, + Ok(User { + image_recover: recover_img_with_data, + image_revoke: revoke_img_with_data, sharding, - pre_id, + pre_id: pre_id.to_string(), recovered_spend_key: None, - } + }) } - pub fn login(&self, password: &str, image_recover: &[u8]) -> Option { - let exif_image_bytes = read_exif(image_recover).unwrap_or_else(|error| { - panic!("Unable to read the image exif: {}", error); - }); + pub fn login(&self, user_password: JsString, image_recover: &[u8]) -> Result { + let mut retrieved_key = [0u8; 32]; + let mut entropy1 = [0u8; 32]; + let mut entropy2 = [0u8; 32]; + let mut nonce1 = [0u8; 12]; + let mut nonce2 = [0u8; 12]; + let mut part1_ciphertext = Vec::with_capacity(32); // just a guess - let exif_image_string = String::from_utf8(exif_image_bytes.to_vec()).unwrap(); - let exif_image_json: Value = serde_json::from_str(&exif_image_string).unwrap(); - let random_seed1 = exif_image_json["random_seed1"].as_str().unwrap_or("N/A"); - let random_seed2 = exif_image_json["random_seed2"].as_str().unwrap_or("N/A"); - let part1_key_enc = exif_image_json["part1_key_enc"].as_str().unwrap_or("N/A"); - let part1_recovered = Self::recover_part1(password, random_seed1, part1_key_enc); - let part1_trimmed = part1_recovered.trim_matches('"'); + assert!(user_password.is_valid_utf16()); + let password: String = user_password.into(); - //@todo: get shardings from member managers!! + let exif_image_bytes = + Bytes::from(read_exif(image_recover).map_err(|e| Error::msg(format!("{}", e)))?); + let mut reader = exif_image_bytes.reader(); + reader.read_exact(&mut entropy1)?; + reader.read_exact(&mut entropy2)?; + reader.read_exact(&mut nonce1)?; + reader.read_exact(&mut nonce2)?; + reader.read_to_end(&mut part1_ciphertext)?; + + retrieved_key[..16].copy_from_slice(&Self::recover_part1( + &password, + &entropy1, + &nonce1, + &part1_ciphertext, + )?); + + //@todo: get shardings from member managers! let shardings = self.sharding.shares_vec.clone(); // temporary - let part2_recovered = Self::recover_part2(&password, &random_seed2, shardings); - let part2_trimmed = part2_recovered.trim_matches('"'); - let recover_key_hex: String = format!("{}{}", part1_trimmed, part2_trimmed); + retrieved_key[16..].copy_from_slice(&Self::recover_part2( + &password, &entropy2, &nonce2, shardings, + )?); - Some(recover_key_hex) + let key = SecretKey::from_slice(&retrieved_key)?; + + Ok(key) } - fn recover_part1(password: &str, random_seed1: &str, part1_key_enc: &str) -> String { - let pwd_hash_part1 = from_hex_to_b64(&sha_256(&format!("{}{}", password, random_seed1))); - let key_dec_part1 = KeyEncryption::new(None, Some(pwd_hash_part1), None); - let part1_key_recovered = key_dec_part1 - .decode(part1_key_enc.to_string()) - .unwrap_or_else(|_| "".to_string()); - part1_key_recovered + fn recover_part1( + password: &str, + entropy: &[u8], + nonce: &[u8], + part1_ciphertext: &[u8], + ) -> Result> { + let mut engine = sha256::HashEngine::default(); + engine.write_all(&password.as_bytes()); + engine.write_all(&entropy); + let hash = sha256::Hash::from_engine(engine); + + let key: &Key = hash.as_byte_array().try_into()?; + let cipher = Aes256Gcm::new(&key); + + cipher + .decrypt(nonce.into(), part1_ciphertext) + .map_err(|e| anyhow::Error::msg(format!("{}", e))) } - fn recover_part2(password: &str, random_seed2: &str, shares_vec: Vec>) -> String { - let quorum_sharding = - (Sharding::QUORUM_SHARD * f32::from(shares_vec.len() as u8)).round() as u8; - let part2_key_enc = SecretData::recover_secret(quorum_sharding, shares_vec).unwrap(); - let pwd_hash_part2 = from_hex_to_b64(&sha_256(&format!("{}{}", password, random_seed2))); - let key_dec_part2 = KeyEncryption::new(None, Some(pwd_hash_part2), None); - let part2_key_recovered = key_dec_part2 - .decode(part2_key_enc) - .unwrap_or_else(|_| "".to_string()); - part2_key_recovered + fn recover_part2( + password: &str, + entropy: &[u8], + nonce: &[u8], + shares_vec: Vec>, + ) -> Result> { + let mut engine = sha256::HashEngine::default(); + engine.write_all(&password.as_bytes()); + engine.write_all(&entropy); + let hash = sha256::Hash::from_engine(engine); + + let shares_total: f32 = u8::try_from(shares_vec.len())?.try_into()?; + let quorum_sharding: u8 = (Sharding::QUORUM_SHARD * shares_total).round() as u8; + + let part2_key_enc = Vec::from_hex( + &SecretData::recover_secret(quorum_sharding, shares_vec) + .ok_or_else(|| anyhow::Error::msg("Failed to retrieve the sharded secret"))?, + )?; + + let key: &Key = hash.as_byte_array().try_into()?; + let cipher = Aes256Gcm::new(&key); + + cipher + .decrypt(nonce.into(), &*part2_key_enc) + .map_err(|e| anyhow::Error::msg(format!("{}", e))) } //not used - pub fn pbkdf2(password: &str, data: &str) -> String { - let data_salt = data.trim_end_matches('='); - let salt = SaltString::from_b64(data_salt) - .map(|s| s) - .unwrap_or_else(|_| panic!("Failed to parse salt value from base64 string")); + // pub fn pbkdf2(password: &str, data: &str) -> String { + // let data_salt = data.trim_end_matches('='); + // let salt = SaltString::from_b64(data_salt) + // .map(|s| s) + // .unwrap_or_else(|_| panic!("Failed to parse salt value from base64 string")); - let mut password_hash = String::new(); - if let Ok(pwd) = Scrypt.hash_password(password.as_bytes(), &salt) { - password_hash.push_str(&pwd.to_string()); - } - sha_256(&password_hash) - } - - pub fn get_image_recover(&self) -> Vec { - return self.image_recover.image_recover_bytes.clone(); - } + // let mut password_hash = String::new(); + // if let Ok(pwd) = Scrypt.hash_password(password.as_bytes(), &salt) { + // password_hash.push_str(&pwd.to_string()); + // } + // sha_256(&password_hash) + // } pub fn get_exif_image(&self, image: &[u8]) -> Vec { return read_exif(image).expect("Error reading the exif"); } - pub fn get_image_revoke(&self) -> Vec { - return self.image_revoke.image_revoke_bytes.clone(); - } - // Test sharing JS side pub fn get_shares(&self) -> Vec { self.sharding.shares_format_str.clone() @@ -223,52 +281,21 @@ impl User { } } -#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct ImageRecover { - image_recover_bytes: Vec, +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum BackUpImage { + Recover(Vec), + Revoke(Vec), } -impl ImageRecover { - pub fn new( - image_to_recover: &[u8], - random_seed1: &str, - random_seed2: &str, - part1_key_enc: &str, - ) -> Self { - let data_exif_json = json!({ - "random_seed1": random_seed1, - "random_seed2": random_seed2, - "part1_key_enc": part1_key_enc - }); - - let data = serde_json::to_string(&data_exif_json).unwrap(); - let image_recover = write_exif(image_to_recover, &data); - ImageRecover { - image_recover_bytes: image_recover.expect("Image recover not generated!"), - } +impl BackUpImage { + pub fn new_recover(image: &[u8], data: &[u8]) -> Result { + let img = write_exif(image, data)?; + Ok(Self::Recover(img)) } -} -#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct ImageRevoke { - image_revoke_bytes: Vec, -} -impl ImageRevoke { - pub fn new( - image_to_revoke: &[u8], - priv_revoke_spend_key: &str, - priv_revoke_scan_key: &str, - ) -> Self { - let data_exif_json = json!({ - "priv_revoke_spend_key":priv_revoke_spend_key, - "priv_revoke_scan_key":priv_revoke_scan_key - }); - - let data = serde_json::to_string(&data_exif_json).unwrap(); - let image_revoke = write_exif(image_to_revoke, &data); - ImageRevoke { - image_revoke_bytes: image_revoke.expect("Image revoke not generated!"), - } + pub fn new_revoke(image: &[u8], data: &[u8]) -> Result { + let img = write_exif(image, data)?; + Ok(Self::Recover(img)) } } @@ -315,27 +342,20 @@ impl Sharding { } //associated functions -pub fn generate_random_key(length: usize) -> String { +pub fn generate_random_key(length: usize) -> Vec { let mut rng = rand::thread_rng(); - let random_bytes: Vec = (0..length).map(|_| rng.gen_range(0x00..=0xFF)).collect(); - base64::encode(random_bytes) + let mut entropy = Vec::::with_capacity(length); + rng.fill_bytes(&mut entropy); + entropy } -pub fn sha_256(data: &str) -> String { - let mut hasher = Sha256::new(); - hasher.update(data); - let result = hasher.finalize(); - hex::encode(result) -} - -pub fn write_exif(image_to_recover: &[u8], data: &str) -> Result, String> { - let image_to_recover_bytes = Bytes::from(image_to_recover.to_vec()); - let mut jpeg = Jpeg::from_bytes(image_to_recover_bytes).unwrap(); - let data_bytes = Bytes::from(data.as_bytes().to_vec()); +pub fn write_exif(image_to_recover: &[u8], data: &[u8]) -> Result> { + let mut jpeg = Jpeg::from_bytes(Bytes::from(image_to_recover.to_vec()))?; + let data_bytes = Bytes::from(data.to_owned()); jpeg.set_exif(Some(data_bytes)); let output_image_bytes = jpeg.encoder().bytes(); - let output_image = output_image_bytes.as_ref(); - Ok(output_image.to_vec()) + let output_image = output_image_bytes.to_vec(); + Ok(output_image) } pub fn read_exif(image: &[u8]) -> Result, String> { diff --git a/src/services.ts b/src/services.ts index 3669c66..d6a65c6 100644 --- a/src/services.ts +++ b/src/services.ts @@ -1,4 +1,4 @@ -import { GenerateSpWalletReturn } from '../dist/pkg/sdk_client'; +import { generate_sp_wallet_return, User } from '../dist/pkg/sdk_client'; import IndexedDB from './database' import Processstore from './store/processstore'; import Userstore from './store/userstore'; @@ -26,7 +26,7 @@ class Services { this.sdkClient.setup(); } - public new_sp_client(label: string, current_tip: number, is_testnet: boolean): GenerateSpWalletReturn { + public new_sp_client(label: string, current_tip: number, is_testnet: boolean): generate_sp_wallet_return { return this.sdkClient.generate_sp_wallet(label, current_tip, is_testnet); } @@ -91,12 +91,12 @@ class Services { if (!Services.instance.isPasswordValid(password)) return; // TODO get secretpart1 from User object - // const user = new this.sdkClient.User(password); - let secretpart1 = "LKHGKJJJ3H"; + // const user: User = new this.sdkClient.create_user(password); + const user: User = this.sdkClient.create_user(password); + // let secretpart1 = "LKHGKJJJ3H"; try { let userstore = new Userstore; - userstore.secretpart1 = secretpart1; userstore.process = process; const indexedDb = await IndexedDB.getInstance(); const db = indexedDb.getDb();