use rand::Rng; use anyhow::Error as AnyhowError; use sp_backend::silentpayments::Error as SpError; use serde_json::Error as SerdeJsonError; use serde::{Deserialize, Serialize}; use sp_backend::silentpayments::sending::SilentPaymentAddress; use tsify::Tsify; use wasm_bindgen::convert::FromWasmAbi; use wasm_bindgen::prelude::*; use sp_backend::spclient::SpendKey; use sp_backend::spclient::{derive_keys_from_seed, OutputList, SpClient}; type ApiResult = Result; const IS_TESTNET: bool = true; #[derive(Debug)] struct ApiError { message: String, } impl From for ApiError { fn from(value: AnyhowError) -> Self { ApiError {message: value.to_string()} } } impl From for ApiError { fn from(value: SpError) -> Self { ApiError { message: value.to_string() } } } impl From for ApiError { fn from(value: SerdeJsonError) -> Self { ApiError { message: value.to_string() } } } impl Into for ApiError { fn into(self) -> JsValue { JsValue::from_str(&self.message) } } #[derive(Tsify, Serialize, Deserialize)] #[tsify(into_wasm_abi)] #[allow(non_camel_case_types)] pub struct generate_sp_wallet_return { pub sp_client_json: String, pub sp_outputs_json: String, } #[wasm_bindgen] pub fn setup() { wasm_logger::init(wasm_logger::Config::default()); } #[wasm_bindgen] pub fn generate_sp_wallet( label: Option, birthday: u32, is_testnet: bool, ) -> ApiResult { let mut seed = [0u8; 64]; rand::thread_rng().fill(&mut seed); let (scan_sk, spend_sk) = derive_keys_from_seed(&seed, is_testnet)?; let sp_client = SpClient::new( label.unwrap_or("default".into()), scan_sk, SpendKey::Secret(spend_sk), None, IS_TESTNET, )?; let our_address: SilentPaymentAddress = sp_client.get_receiving_address().try_into()?; log::info!( "Created client for sp with address: {}", our_address.to_string() ); let sp_client_json = serde_json::to_string(&sp_client)?; // Generate an empty outputs let sp_outputs = OutputList::new( our_address.get_scan_key(), our_address.get_spend_key(), birthday, ); let sp_outputs_json = serde_json::to_string(&sp_outputs)?; let res = generate_sp_wallet_return { sp_client_json, sp_outputs_json, }; Ok(res) } #[wasm_bindgen] 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() }