From c40196db044284824433f2f9d6e72365154fe3a2 Mon Sep 17 00:00:00 2001 From: Surinder Singh Matoo Date: Sat, 16 Mar 2024 00:07:33 +0530 Subject: [PATCH] adaptor code cleanup --- extensions/adapter/Cargo.toml | 36 ---- extensions/adapter/src/client.rs | 119 ------------- extensions/adapter/src/imports.rs | 42 ----- extensions/adapter/src/ipc.rs | 270 ------------------------------ extensions/adapter/src/lib.rs | 47 ------ extensions/adapter/src/server.rs | 208 ----------------------- 6 files changed, 722 deletions(-) delete mode 100644 extensions/adapter/Cargo.toml delete mode 100644 extensions/adapter/src/client.rs delete mode 100644 extensions/adapter/src/imports.rs delete mode 100644 extensions/adapter/src/ipc.rs delete mode 100644 extensions/adapter/src/lib.rs delete mode 100644 extensions/adapter/src/server.rs diff --git a/extensions/adapter/Cargo.toml b/extensions/adapter/Cargo.toml deleted file mode 100644 index d1e8b1f..0000000 --- a/extensions/adapter/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "kaspa-ng-chrome" -publish = false -version.workspace = true -authors.workspace = true -license.workspace = true -edition.workspace = true -repository.workspace = true - -[features] -browser-extension = ["kaspa-ng-core/browser-extension"] -# default = [] -default = ["browser-extension"] - -[lib] -crate-type = ["cdylib", "lib"] - -[dependencies] -kaspa-ng-core = { workspace = true, features = ["browser-extension"] } -# kaspa-ng-core = { workspace = true } -kaspa-wallet-core.workspace = true -workflow-chrome.workspace = true -workflow-core.workspace = true -workflow-log.workspace = true -workflow-store.workspace = true -workflow-wasm.workspace = true - -async-trait.workspace = true -borsh.workspace = true -chrome-sys.workspace = true -js-sys.workspace = true -kaspa-ng-macros.workspace = true -kaspa-utils.workspace = true -rand.workspace = true -wasm-bindgen-futures.workspace = true -wasm-bindgen.workspace = true \ No newline at end of file diff --git a/extensions/adapter/src/client.rs b/extensions/adapter/src/client.rs deleted file mode 100644 index 26ecf9f..0000000 --- a/extensions/adapter/src/client.rs +++ /dev/null @@ -1,119 +0,0 @@ -use crate::imports::*; - -// #[derive(Default)] -pub struct ClientTransport { - application_events: ApplicationEventsChannel, - closure: Mutex>>, - chrome_extension_id: String, -} - -unsafe impl Send for ClientTransport {} -unsafe impl Sync for ClientTransport {} - -#[async_trait] -impl BorshCodec for ClientTransport { - async fn call(&self, op: u64, data: Vec) -> Result> { - let (tx, rx) = oneshot::>>(); - spawn_local(async move { - match send_message(&req_to_jsv(Target::Wallet, op, &data)).await { - Ok(jsv) => { - let resp = jsv_to_resp(&jsv); - tx.send(resp).await.unwrap(); - } - Err(err) => { - log_error!("error sending message: {err:?}"); - tx.send(Err(err.into())).await.unwrap(); - } - }; - }); - rx.recv() - .await - .map_err(|_| Error::custom("Client transport receive channel error"))? - } -} - -impl ClientTransport { - pub fn new(application_events: ApplicationEventsChannel) -> Self { - Self { - application_events, - chrome_extension_id: runtime_id().unwrap(), - closure: Mutex::new(None), - } - } - - pub fn start(self: &Arc) { - // self.runtime.start(); - self.register_listener(); - } - - fn register_listener(self: &Arc) { - let this = self.clone(); - - let closure = Rc::new(Closure::new( - // move |msg, sender: Sender, callback: JsValue| -> JsValue { - move |msg, sender: Sender, _callback: JsValue| -> JsValue { - // let callback = js_sys::Function::from(callback); - log_info!("CLIENT RECEIVED MESSAGE: {:?}", msg); - if let Err(err) = this.handle_notification(msg, sender) { - log_error!("notification handling error: {:?}", err); - } - JsValue::from(false) - }, - )); - - log_info!("CLIENT REGISTERING LISTENER..."); - add_listener(closure.clone().as_ref()); - *self.closure.lock().unwrap() = Some(closure); - } - - fn handle_notification( - self: &Arc, - msg: JsValue, - sender: Sender, - // callback: Function, - ) -> Result<()> { - log_info!("CLIENT HANDLING NOTIFICATION..."); - if let Some(id) = sender.id() { - if id != self.chrome_extension_id { - return Err(Error::custom( - "Unknown sender id - foreign requests are forbidden", - )); - } - } else { - return Err(Error::custom("Sender is missing id")); - } - - log_info!( - "[WASM] notification: {:?}, sender id:{:?}", - msg, - sender.id(), - // callback - ); - - let (target, data) = jsv_to_notify(msg)?; - - match target { - Target::Wallet => { - let event = Box::new(Events::try_from_slice(&data)?); - - self.application_events - .sender - .try_send(kaspa_ng_core::events::Events::Wallet { event }) - .unwrap(); - - // spawn_local(async move { - - // let resp = resp_to_jsv(self.wallet_server.call_with_borsh(op, &data).await); - // if let Err(err) = callback.call1(&JsValue::UNDEFINED, &resp) { - // log_error!("onMessage callback error: {:?}", err); - // } - // }); - } - Target::Runtime => { - todo!() - } - } - - Ok(()) - } -} diff --git a/extensions/adapter/src/imports.rs b/extensions/adapter/src/imports.rs deleted file mode 100644 index b396155..0000000 --- a/extensions/adapter/src/imports.rs +++ /dev/null @@ -1,42 +0,0 @@ -pub use crate::server::Server; -pub use kaspa_ng_core::app; -pub use kaspa_wallet_core::api::transport::{Codec, WalletClient}; -pub use kaspa_wallet_core::api::WalletApi; -// pub use std::sync::Arc; -pub use async_trait::async_trait; -pub use kaspa_ng_core::events::ApplicationEventsChannel; -pub use wasm_bindgen::prelude::*; -pub use workflow_log::*; -// pub use kaspa_ng_core::events::ApplicationEventsChannel; -pub use kaspa_wallet_core::api::transport::BorshCodec; -pub use kaspa_wallet_core::error::Error; -pub use kaspa_wallet_core::events::Events; -pub use kaspa_wallet_core::result::Result; -pub use wasm_bindgen_futures::spawn_local; -pub use workflow_core::channel::oneshot; -// pub use workflow_log::*; -pub use crate::ipc::*; -// pub use async_trait::async_trait; -pub use js_sys::Function; -// pub use kaspa_ng_core::events::ApplicationEventsChannel; -pub use kaspa_ng_core::settings::Settings; -pub use kaspa_wallet_core::api::transport::{EventHandler, WalletServer}; -// pub use kaspa_wallet_core::error::Error; -// pub use kaspa_wallet_core::events::Events; -pub use kaspa_wallet_core::prelude::Wallet as CoreWallet; -// pub use kaspa_wallet_core::result::Result; -pub use std::rc::Rc; -pub use std::sync::{Arc, Mutex}; -// pub use wasm_bindgen::prelude::*; -// pub use wasm_bindgen_futures::spawn_local; -// pub use workflow_log::prelude::*; -pub use chrome_sys::prelude::*; -// use kaspa_ng_core::servers::Server; -// use kaspa_ng_macros::*; -pub use kaspa_utils::hex::*; -// use kaspa_wallet_core::encryption::sha256_hash; -// pub use kaspa_wallet_core::error::Error; -// use kaspa_wallet_core::result::Result; -// use rand::Rng; -// use wasm_bindgen::prelude::*; -pub use borsh::{BorshDeserialize, BorshSerialize}; diff --git a/extensions/adapter/src/ipc.rs b/extensions/adapter/src/ipc.rs deleted file mode 100644 index f5d26d6..0000000 --- a/extensions/adapter/src/ipc.rs +++ /dev/null @@ -1,270 +0,0 @@ -use crate::imports::*; - -// const SUCCESS: u8 = 0; -// const ERROR: u8 = 1; -pub type ListenerClosure = Closure JsValue>; - -#[repr(u8)] -#[derive(Debug, BorshSerialize, BorshDeserialize)] -pub enum Target { - Wallet = 0, - Runtime = 1, -} - -impl TryFrom for Target { - type Error = Error; - - fn try_from(value: u8) -> Result { - match value { - 0 => Ok(Target::Wallet), - 1 => Ok(Target::Runtime), - _ => Err(Error::custom("invalid message target")), - } - } -} - -#[repr(u8)] -#[derive(Debug, BorshSerialize, BorshDeserialize)] -enum ServerMessageKind { - Success = 0, - Error = 1, - Notification = 2, -} - -impl TryFrom for ServerMessageKind { - type Error = Error; - - fn try_from(value: u8) -> Result { - match value { - 0 => Ok(ServerMessageKind::Success), - 1 => Ok(ServerMessageKind::Error), - 2 => Ok(ServerMessageKind::Notification), - _ => Err(Error::custom("invalid server message kind")), - } - } -} - -// fn mask_data() -> &'static [u8; 128] { -// static mut MASK: Option> = None; -// unsafe { -// MASK.get_or_insert_with(|| { -// let mut data = crnd!().to_vec(); -// data.extend( -// runtime_id() -// .expect("missing runtime id") -// .as_bytes() -// .to_vec(), -// ); -// data = sha256_hash(&data).as_ref().to_vec(); -// (0..3).for_each(|_| { -// data.extend(sha256_hash(&data).as_ref()); -// }); -// Box::new(data.try_into().unwrap()) -// }) -// } -// } - -// fn mask(data: &mut [u8], src: &[u8], index: &mut usize, mask: &[u8]) { -// for i in 0..src.len() { -// data[i] = src[i] ^ mask[*index]; -// *index += 1; -// if *index == mask.len() { -// *index = 0; -// } -// } -// } - -#[derive(BorshSerialize, BorshDeserialize)] -pub struct ClientMessage { - target: Target, - op: u64, - data: Vec, -} - -#[derive(Debug, BorshSerialize, BorshDeserialize)] -pub struct ServerMessage { - target: Target, - kind: ServerMessageKind, - // op : Option, - data: Vec, -} - -pub fn req_to_jsv(target: Target, op: u64, src: &[u8]) -> JsValue { - let request = ClientMessage { - target, - op, - data: src.to_vec(), - }; - - let data = request.try_to_vec().unwrap(); - - // let mask_data = mask_data(); - // let mut index = rand::thread_rng().gen::() % mask_data.len(); - // let mut data = vec![0; src.len() + 2 + 8]; - // data[0] = index as u8; - // data[1] = target as u8 ^ mask_data[index]; - // index += 1; - // // mask(&mut data[1..1], &[target as u8], &mut index, mask_data); - // mask( - // &mut data[2..10], - // op.to_le_bytes().as_ref(), - // &mut index, - // mask_data, - // ); - // mask(&mut data[10..], src, &mut index, mask_data); - // let data = - JsValue::from(data.to_hex()) -} - -pub fn jsv_to_req(src: JsValue) -> Result<(Target, u64, Vec)> { - let src = Vec::::from_hex( - src.as_string() - .ok_or(Error::custom("expecting string"))? - .as_str(), - )?; - if src.len() < 10 { - return Err(Error::custom("invalid message length")); - } - - let request = ClientMessage::try_from_slice(&src).unwrap(); - Ok((request.target, request.op, request.data)) - - // let mask_data = mask_data(); - // let mut index = src[0] as usize; - // let mut data = vec![0; src.len() - 1]; - // mask(&mut data, &src[1..], &mut index, mask_data); - // let target = Target::try_from(data[0])?; - // let op = u64::from_le_bytes(data[1..9].try_into().unwrap()); - // Ok((target, op, data[9..].to_vec())) -} - -pub fn resp_to_jsv(target: Target, response: Result>) -> JsValue { - // let mask_data = mask_data(); - // let mut index = rand::thread_rng().gen::() % (mask_data.len() - 1); - - match response { - Ok(src) => { - let response = ServerMessage { - target, // : Target::Runtime, - kind: ServerMessageKind::Success, - // op : None, - data: src, - }; - - let data = response.try_to_vec().unwrap(); - - // let mut data = vec![0; src.len() + 2]; - // data[0] = index as u8; - // data[1] = ServerMessageKind::Success as u8 ^ mask_data[index]; - // index += 1; - // mask(&mut data[2..], &src, &mut index, mask_data); - JsValue::from(data.to_hex()) - } - Err(error) => { - let response = ServerMessage { - target: Target::Runtime, - kind: ServerMessageKind::Error, - // op : None, - data: error.to_string().as_bytes().to_vec(), - }; - - let data = response.try_to_vec().unwrap(); - // let error = error.to_string(); - // let src = error.as_bytes(); - // let mut data = vec![0; src.len() + 2]; - // data[0] = index as u8; - // data[1] = ServerMessageKind::Error as u8 ^ mask_data[index]; - // index += 1; - // mask(&mut data[2..], src, &mut index, mask_data); - JsValue::from(data.to_hex()) - } - } -} - -pub fn jsv_to_resp(jsv: &JsValue) -> Result> { - let src = Vec::::from_hex( - jsv.as_string() - .ok_or(Error::custom("expecting string"))? - .as_str(), - )?; - if src.len() < 2 { - return Err(Error::custom("invalid message length")); - } - - let response = ServerMessage::try_from_slice(&src).unwrap(); - - // let mask_data = mask_data(); - // let mut index = src[0] as usize; - // let mut data = vec![0; src.len() - 1]; - // mask(&mut data, &src[1..], &mut index, mask_data); - - // let kind = ServerMessageKind::try_from(data[0])?; - match response.kind { - ServerMessageKind::Success => Ok(response.data), - ServerMessageKind::Error => { - let error = String::from_utf8(response.data)?; - Err(Error::custom(error)) - } - _ => Err(Error::custom("invalid response code")), - } -} - -// ---- - -// pub fn notify_to_jsv(op: u64, src: &[u8]) -> JsValue { -pub fn notify_to_jsv(target: Target, src: &[u8]) -> JsValue { - // let notify = - - let notify = ServerMessage { - target, //: Target::Runtime, - kind: ServerMessageKind::Notification, - // op : Some(op), - data: src.to_vec(), - }; - - let data = notify.try_to_vec().unwrap(); - // } - - // let mask_data = mask_data(); - // let mut index = rand::thread_rng().gen::() % mask_data.len(); - // let mut data = vec![0; src.len() + 5]; - // data[0] = index as u8; - // mask( - // &mut data[1..9], - // op.to_le_bytes().as_ref(), - // &mut index, - // mask_data, - // ); - // mask(&mut data[9..], src, &mut index, mask_data); - JsValue::from(data.to_hex()) -} - -// pub fn jsv_to_notify(src: JsValue) -> Result<(u64, Vec)> { -pub fn jsv_to_notify(src: JsValue) -> Result<(Target, Vec)> { - let src = Vec::::from_hex( - src.as_string() - .ok_or(Error::custom("expecting string"))? - .as_str(), - )?; - // if src.len() < 9 { - // return Err(Error::custom("invalid message length")); - // } - - let notify = ServerMessage::try_from_slice(&src).unwrap(); - log_info!("### NOTIFICATION MESSAGE: {:?}", notify); - match notify.kind { - // ServerMessageKind::Notification => Ok((notify.op.unwrap(), notify.data)), - ServerMessageKind::Notification => Ok((notify.target, notify.data)), - _ => Err(Error::custom( - "Error: jsv_to_notify trying to parse a non-notification message", - )), - // _ => Err(Error::custom("invalid notification code")), - } - - // let mask_data = mask_data(); - // let mut index = src[0] as usize; - // let mut data = vec![0; src.len() - 1]; - // mask(&mut data, &src[1..], &mut index, mask_data); - // let op = u64::from_le_bytes(data[0..8].try_into().unwrap()); - // Ok((op, data[8..].to_vec())) -} diff --git a/extensions/adapter/src/lib.rs b/extensions/adapter/src/lib.rs deleted file mode 100644 index d8f96ed..0000000 --- a/extensions/adapter/src/lib.rs +++ /dev/null @@ -1,47 +0,0 @@ -pub mod client; -pub mod imports; -pub mod ipc; -pub mod server; - -use crate::imports::*; - -static mut SERVER: Option> = None; -// background script -#[wasm_bindgen] -pub async fn kaspa_ng_background() { - log_info!("kaspa_ng_background called successfully in the background!"); - workflow_wasm::panic::init_console_panic_hook(); - - let server = Arc::new(Server::new().await); - unsafe { - SERVER = Some(server.clone()); - } - server.start().await; -} - -// extension popup -#[wasm_bindgen] -pub async fn kaspa_ng_main() { - log_info!("kaspa_ng_main called successfully in the popup!"); - workflow_wasm::panic::init_console_panic_hook(); - - let application_events = ApplicationEventsChannel::unbounded(); - - let client_transport = Arc::new(client::ClientTransport::new(application_events.clone())); - let borsh_transport = Codec::Borsh(client_transport.clone()); - let wallet_client: Arc = Arc::new(WalletClient::new(borsh_transport)); - - log_info!("STARTING CLIENT TRANSPORT"); - client_transport.start(); - - let response = wallet_client - .clone() - .ping(Some("hello world!".to_string())) - .await - .expect("ping failed"); - log_info!("Client received response: {response:?}"); - - if let Err(err) = app::kaspa_ng_main(Some(wallet_client), Some(application_events)).await { - log_error!("Error: {err}"); - } -} diff --git a/extensions/adapter/src/server.rs b/extensions/adapter/src/server.rs deleted file mode 100644 index ca58e92..0000000 --- a/extensions/adapter/src/server.rs +++ /dev/null @@ -1,208 +0,0 @@ -use kaspa_ng_core::imports::KaspaRpcClient; -// use kaspa_wallet_core::rpc::{Rpc, WrpcEncoding}; -use kaspa_wallet_core::rpc::{ - ConnectOptions, ConnectStrategy, DynRpcApi, NotificationMode, Rpc, RpcCtl, WrpcEncoding, -}; - -use crate::imports::*; - -pub struct Server { - #[allow(dead_code)] - wallet: Arc, - wallet_server: Arc, - closure: Mutex>>, - chrome_extension_id: String, -} - -unsafe impl Send for Server {} -unsafe impl Sync for Server {} - -// impl Default for Server { -// fn default() -> Self { -// Self::new() -// } -// } - -impl Server { - pub async fn new() -> Self { - // TODO @surinder - let settings = Settings::load().await.unwrap_or_else(|err| { - log_error!("Unable to load settings: {err}"); - Settings::default() - }); - - // let _r = - settings.store().await.unwrap(); - workflow_chrome::storage::__chrome_storage_unit_test().await; - - let storage = CoreWallet::local_store().unwrap_or_else(|e| { - panic!("Failed to open local store: {}", e); - }); - - let list = storage.wallet_list().await.unwrap(); - - log_info!("wallet_list: {:?}", list); - log_info!("storage storage: {:?}", storage.descriptor()); - - let rpc = Self::create_rpc_client().expect("Unable to create RPC client"); - - let wallet = Arc::new( - CoreWallet::try_with_rpc(Some(rpc), storage, None).unwrap_or_else(|e| { - panic!("Failed to create wallet instance: {}", e); - }), - ); - - let event_handler = Arc::new(ServerEventHandler::default()); - - let wallet_server = Arc::new(WalletServer::new(wallet.clone(), event_handler)); - - let _application_events = ApplicationEventsChannel::unbounded(); - // let kaspa = Arc::new(KaspaService::new(application_events.clone(), &settings)); - // let runtime = Runtime::new(&[kaspa.clone()]); - log_info!("Server init complete"); - - Self { - chrome_extension_id: runtime_id().unwrap(), - closure: Mutex::new(None), - wallet, - wallet_server, - // runtime, - } - } - - pub fn create_rpc_client() -> Result { - let wrpc_client = Arc::new(KaspaRpcClient::new_with_args( - WrpcEncoding::Borsh, - NotificationMode::MultiListeners, - None, - None, - None, - )?); - let rpc_ctl = wrpc_client.ctl().clone(); - let rpc_api: Arc = wrpc_client; - Ok(Rpc::new(rpc_api, rpc_ctl)) - } - - pub async fn start(self: &Arc) { - log_info!("Server starting..."); - // self.runtime.start(); - self.register_listener(); - self.wallet_server.start(); - - log_info!("Starting wallet..."); - self.wallet - .start() - .await - .expect("Unable to start wallet service"); - } - - fn register_listener(self: &Arc) { - let this = self.clone(); - - let closure = Rc::new(Closure::new( - move |msg, sender: Sender, callback: JsValue| -> JsValue { - let callback = js_sys::Function::from(callback); - - match this.clone().handle_message(msg, sender, callback.clone()) { - Ok(_) => JsValue::from(true), - Err(err) => { - log_error!("message handling error: {:?}", err); - - let resp = resp_to_jsv(Target::Wallet, Err(err)); - if let Err(err) = callback.call1(&JsValue::UNDEFINED, &resp) { - log_error!("onMessage callback error in error handler: {:?}", err); - } - JsValue::from(false) - } - } - }, - )); - - add_listener(closure.clone().as_ref()); - *self.closure.lock().unwrap() = Some(closure); - } - - fn handle_message( - self: Arc, - msg: JsValue, - sender: Sender, - callback: Function, - ) -> Result<()> { - if let Some(id) = sender.id() { - if id != self.chrome_extension_id { - return Err(Error::custom( - "Unknown sender id - foreign requests are forbidden", - )); - } - } else { - return Err(Error::custom("Sender is missing id")); - } - - log_info!( - "[WASM] msg: {:?}, sender id:{:?}, {:?}", - msg, - sender.id(), - callback - ); - - let (target, op, data) = jsv_to_req(msg)?; - - match target { - Target::Wallet => { - spawn_local(async move { - let resp = resp_to_jsv( - Target::Wallet, - self.wallet_server.call_with_borsh(op, &data).await, - ); - if let Err(err) = callback.call1(&JsValue::UNDEFINED, &resp) { - log_error!("onMessage callback error: {:?}", err); - } - }); - } - Target::Runtime => { - todo!() - } - } - - Ok(()) - } - - // TODO - implement - // fn _post_notify(&self, op: u64, data: Vec) -> Result<()> { - // spawn_local(async move { - // if let Err(err) = send_message(¬ify_to_jsv(op, &data)).await { - // log_warn!("Unable to post notification: {:?}", err); - // } - // }); - - // Ok(()) - // } - - // fn start(self: &Arc) { - - // } -} - -#[derive(Default)] -struct ServerEventHandler {} - -#[async_trait] -impl EventHandler for ServerEventHandler { - async fn handle_event(&self, event: &Box) { - log_info!("EVENT HANDLER - POSTING NOTIFICATION!"); - - let data = event.try_to_vec().unwrap(); - spawn_local(async move { - let data = notify_to_jsv(Target::Wallet, &data); - log_info!("EVENT HANDLER - SENDING MESSAGE!"); - if let Err(err) = send_message(&data).await { - log_warn!("Unable to post notification: {:?}", err); - } - }); - } - - // async fn handle_event(&self, event: JsValue) -> Result<()> { - // log_info!("event: {:?}", event); - // Ok(()) - // } -}