From 8188e682c95eb57fa6d8127df2be8c1b30797364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thoralf=20M=C3=BCller?= Date: Tue, 16 Apr 2024 10:19:09 +0200 Subject: [PATCH] Optimize wasm for explorer --- Cargo.toml | 9 ++++ bindings/core/Cargo.toml | 3 +- bindings/core/src/error.rs | 1 + bindings/core/src/lib.rs | 17 ++++-- bindings/core/src/method/mod.rs | 9 ++-- .../core/src/method_handler/call_method.rs | 15 +++--- bindings/core/src/method_handler/mod.rs | 8 +-- bindings/core/src/response.rs | 21 ++++++-- bindings/nodejs/Cargo.toml | 1 + bindings/package-lock.json | 6 --- bindings/python/Cargo.toml | 2 + bindings/wasm/Cargo.toml | 12 +++-- bindings/wasm/package.json | 3 ++ bindings/wasm/src/wallet.rs | 53 +++++++++++++++++-- 14 files changed, 124 insertions(+), 36 deletions(-) delete mode 100644 bindings/package-lock.json diff --git a/Cargo.toml b/Cargo.toml index 99647d0d92..8f021e7ece 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,3 +24,12 @@ codegen-units = 1 inherits = "release" lto = true strip = "symbols" +incremental = false + +[profile.wasm] +codegen-units = 1 +inherits = "release" +lto = true +strip = "symbols" +opt-level = "z" +incremental = false diff --git a/bindings/core/Cargo.toml b/bindings/core/Cargo.toml index b40dec229e..bd8cb36f5c 100644 --- a/bindings/core/Cargo.toml +++ b/bindings/core/Cargo.toml @@ -10,7 +10,7 @@ publish = false [dependencies] iota-sdk = { path = "../../sdk", default-features = false, features = [ - "wallet", + "client", "tls", ] } @@ -46,3 +46,4 @@ rocksdb = ["iota-sdk/rocksdb"] storage = ["iota-sdk/storage"] stronghold = ["iota-sdk/stronghold"] private_key_secret_manager = ["iota-sdk/private_key_secret_manager"] +wallet = ["iota-sdk/wallet"] diff --git a/bindings/core/src/error.rs b/bindings/core/src/error.rs index 0f57d0447d..54794903c8 100644 --- a/bindings/core/src/error.rs +++ b/bindings/core/src/error.rs @@ -16,6 +16,7 @@ pub enum Error { /// Client errors. #[error("{0}")] Client(#[from] iota_sdk::client::Error), + #[cfg(feature = "wallet")] /// Wallet errors. #[error("{0}")] Wallet(#[from] iota_sdk::wallet::Error), diff --git a/bindings/core/src/lib.rs b/bindings/core/src/lib.rs index 75ab8c4288..9fefde6379 100644 --- a/bindings/core/src/lib.rs +++ b/bindings/core/src/lib.rs @@ -11,13 +11,17 @@ mod response; use std::fmt::{Formatter, Result as FmtResult}; +#[cfg(feature = "wallet")] use derivative::Derivative; use fern_logger::{logger_init, LoggerConfig, LoggerOutputConfigBuilder}; pub use iota_sdk; +use iota_sdk::client::secret::SecretManagerDto; +#[cfg(feature = "wallet")] use iota_sdk::{ - client::secret::{SecretManager, SecretManagerDto}, + client::secret::SecretManager, wallet::{ClientOptions, Wallet}, }; +#[cfg(feature = "wallet")] use serde::Deserialize; #[cfg(feature = "mqtt")] @@ -26,10 +30,15 @@ pub use self::method_handler::listen_mqtt; pub use self::method_handler::CallMethod; pub use self::{ error::{Error, Result}, - method::{AccountMethod, ClientMethod, SecretManagerMethod, UtilsMethod, WalletMethod}, - method_handler::{call_client_method, call_secret_manager_method, call_utils_method, call_wallet_method}, + method::{ClientMethod, SecretManagerMethod, UtilsMethod}, + method_handler::{call_client_method, call_secret_manager_method, call_utils_method}, response::Response, }; +#[cfg(feature = "wallet")] +pub use self::{ + method::{AccountMethod, WalletMethod}, + method_handler::call_wallet_method, +}; pub fn init_logger(config: String) -> std::result::Result<(), fern_logger::Error> { let output_config: LoggerOutputConfigBuilder = serde_json::from_str(&config).expect("invalid logger config"); @@ -37,6 +46,7 @@ pub fn init_logger(config: String) -> std::result::Result<(), fern_logger::Error logger_init(config) } +#[cfg(feature = "wallet")] #[derive(Derivative, Deserialize, Default)] #[derivative(Debug)] #[serde(rename_all = "camelCase")] @@ -48,6 +58,7 @@ pub struct WalletOptions { pub secret_manager: Option, } +#[cfg(feature = "wallet")] impl WalletOptions { pub fn with_storage_path(mut self, storage_path: impl Into>) -> Self { self.storage_path = storage_path.into(); diff --git a/bindings/core/src/method/mod.rs b/bindings/core/src/method/mod.rs index 966b583013..82794bf9fa 100644 --- a/bindings/core/src/method/mod.rs +++ b/bindings/core/src/method/mod.rs @@ -1,13 +1,14 @@ // Copyright 2023 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +#[cfg(feature = "wallet")] mod account; mod client; mod secret_manager; mod utils; +#[cfg(feature = "wallet")] mod wallet; -pub use self::{ - account::AccountMethod, client::ClientMethod, secret_manager::SecretManagerMethod, utils::UtilsMethod, - wallet::WalletMethod, -}; +#[cfg(feature = "wallet")] +pub use self::{account::AccountMethod, wallet::WalletMethod}; +pub use self::{client::ClientMethod, secret_manager::SecretManagerMethod, utils::UtilsMethod}; diff --git a/bindings/core/src/method_handler/call_method.rs b/bindings/core/src/method_handler/call_method.rs index b0202468a1..ae02a89ac1 100644 --- a/bindings/core/src/method_handler/call_method.rs +++ b/bindings/core/src/method_handler/call_method.rs @@ -4,17 +4,18 @@ use std::pin::Pin; use futures::Future; -use iota_sdk::{ - client::{secret::SecretManager, Client}, - wallet::Wallet, -}; +use iota_sdk::client::{secret::SecretManager, Client}; +#[cfg(feature = "wallet")] +use iota_sdk::wallet::Wallet; use tokio::sync::RwLock; +#[cfg(feature = "wallet")] +use crate::{method::WalletMethod, method_handler::wallet::call_wallet_method_internal}; use crate::{ - method::{ClientMethod, SecretManagerMethod, WalletMethod}, + method::{ClientMethod, SecretManagerMethod}, method_handler::{ client::call_client_method_internal, secret_manager::call_secret_manager_method_internal, - utils::call_utils_method_internal, wallet::call_wallet_method_internal, + utils::call_utils_method_internal, }, panic::{convert_async_panics, convert_panics}, response::Response, @@ -36,6 +37,7 @@ impl CallMethod for Client { } } +#[cfg(feature = "wallet")] impl CallMethod for Wallet { type Method = WalletMethod; @@ -55,6 +57,7 @@ pub async fn call_client_method(client: &Client, method: ClientMethod) -> Respon response } +#[cfg(feature = "wallet")] /// Call a wallet method. pub async fn call_wallet_method(wallet: &Wallet, method: WalletMethod) -> Response { log::debug!("Wallet method: {method:?}"); diff --git a/bindings/core/src/method_handler/mod.rs b/bindings/core/src/method_handler/mod.rs index 49be54cf5e..51afec11ae 100644 --- a/bindings/core/src/method_handler/mod.rs +++ b/bindings/core/src/method_handler/mod.rs @@ -1,15 +1,17 @@ // Copyright 2023 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +#[cfg(feature = "wallet")] mod account; mod call_method; mod client; mod secret_manager; mod utils; +#[cfg(feature = "wallet")] mod wallet; -pub use call_method::{ - call_client_method, call_secret_manager_method, call_utils_method, call_wallet_method, CallMethod, -}; +#[cfg(feature = "wallet")] +pub use call_method::call_wallet_method; +pub use call_method::{call_client_method, call_secret_manager_method, call_utils_method, CallMethod}; #[cfg(feature = "mqtt")] pub use client::listen_mqtt; diff --git a/bindings/core/src/response.rs b/bindings/core/src/response.rs index 1d9921b694..889b679fdb 100644 --- a/bindings/core/src/response.rs +++ b/bindings/core/src/response.rs @@ -8,6 +8,11 @@ use std::collections::HashSet; use derivative::Derivative; #[cfg(feature = "ledger_nano")] use iota_sdk::client::secret::LedgerNanoStatus; +#[cfg(feature = "wallet")] +use iota_sdk::wallet::account::{ + types::{AccountAddress, AddressWithUnspentOutputs, Balance, OutputDataDto, TransactionDto}, + AccountDetailsDto, PreparedCreateNativeTokenTransactionDto, +}; use iota_sdk::{ client::{ api::{PreparedTransactionDataDto, SignedTransactionDataDto}, @@ -38,10 +43,6 @@ use iota_sdk::{ BlockDto, BlockId, }, }, - wallet::account::{ - types::{AccountAddress, AddressWithUnspentOutputs, Balance, OutputDataDto, TransactionDto}, - AccountDetailsDto, PreparedCreateNativeTokenTransactionDto, - }, }; use serde::Serialize; #[cfg(feature = "participation")] @@ -300,6 +301,7 @@ pub enum Response { Panic(String), // wallet responses + #[cfg(feature = "wallet")] /// Response for: /// - [`CreateAccount`](crate::method::WalletMethod::CreateAccount), /// - [`GetAccount`](crate::method::WalletMethod::GetAccount) @@ -307,12 +309,15 @@ pub enum Response { /// Response for: /// - [`GetAccountIndexes`](crate::method::WalletMethod::GetAccountIndexes) AccountIndexes(Vec), + #[cfg(feature = "wallet")] /// Response for: /// - [`GetAccounts`](crate::method::WalletMethod::GetAccounts) Accounts(Vec), + #[cfg(feature = "wallet")] /// Response for: /// - [`Addresses`](crate::method::AccountMethod::Addresses) Addresses(Vec), + #[cfg(feature = "wallet")] /// Response for: /// - [`AddressesWithUnspentOutputs`](crate::method::AccountMethod::AddressesWithUnspentOutputs) AddressesWithUnspentOutputs(Vec), @@ -326,9 +331,11 @@ pub enum Response { /// Response for: /// - [`ClaimableOutputs`](crate::method::AccountMethod::ClaimableOutputs) OutputIds(Vec), + #[cfg(feature = "wallet")] /// Response for: /// - [`GetOutput`](crate::method::AccountMethod::GetOutput) OutputData(Option>), + #[cfg(feature = "wallet")] /// Response for: /// - [`Outputs`](crate::method::AccountMethod::Outputs), /// - [`UnspentOutputs`](crate::method::AccountMethod::UnspentOutputs) @@ -350,13 +357,16 @@ pub enum Response { /// - [`PrepareTransaction`](crate::method::AccountMethod::PrepareTransaction) /// - [`PrepareVote`](crate::method::AccountMethod::PrepareVote) PreparedTransaction(PreparedTransactionDataDto), + #[cfg(feature = "wallet")] /// Response for: /// - [`PrepareCreateNativeToken`](crate::method::AccountMethod::PrepareCreateNativeToken), PreparedCreateNativeTokenTransaction(PreparedCreateNativeTokenTransactionDto), + #[cfg(feature = "wallet")] /// Response for: /// - [`GetIncomingTransaction`](crate::method::AccountMethod::GetIncomingTransaction) /// - [`GetTransaction`](crate::method::AccountMethod::GetTransaction), Transaction(Option>), + #[cfg(feature = "wallet")] /// Response for: /// - [`IncomingTransactions`](crate::method::AccountMethod::IncomingTransactions) /// - [`PendingTransactions`](crate::method::AccountMethod::PendingTransactions), @@ -365,14 +375,17 @@ pub enum Response { /// Response for: /// - [`SignTransactionEssence`](crate::method::AccountMethod::SignTransactionEssence) SignedTransactionData(SignedTransactionDataDto), + #[cfg(feature = "wallet")] /// GenerateAddress response. /// Response for: /// - [`GenerateEd25519Addresses`](crate::method::AccountMethod::GenerateEd25519Addresses) GeneratedAccountAddresses(Vec), + #[cfg(feature = "wallet")] /// Response for: /// - [`GetBalance`](crate::method::AccountMethod::GetBalance), /// - [`Sync`](crate::method::AccountMethod::Sync) Balance(Balance), + #[cfg(feature = "wallet")] /// Response for: /// - [`ClaimOutputs`](crate::method::AccountMethod::ClaimOutputs) /// - [`Send`](crate::method::AccountMethod::Send) diff --git a/bindings/nodejs/Cargo.toml b/bindings/nodejs/Cargo.toml index e05291b45d..ad5ceb1f4a 100644 --- a/bindings/nodejs/Cargo.toml +++ b/bindings/nodejs/Cargo.toml @@ -27,6 +27,7 @@ iota-sdk-bindings-core = { path = "../core", default-features = false, features "rocksdb", "mqtt", "private_key_secret_manager", + "wallet", ] } log = { version = "0.4.20", default-features = false } diff --git a/bindings/package-lock.json b/bindings/package-lock.json deleted file mode 100644 index 01602fd1b2..0000000000 --- a/bindings/package-lock.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "bindings", - "lockfileVersion": 2, - "requires": true, - "packages": {} -} diff --git a/bindings/python/Cargo.toml b/bindings/python/Cargo.toml index b426e14fff..6ccad068d7 100644 --- a/bindings/python/Cargo.toml +++ b/bindings/python/Cargo.toml @@ -25,6 +25,8 @@ iota-sdk-bindings-core = { path = "../core", default-features = false, features "storage", "stronghold", "mqtt", + "private_key_secret_manager", + "wallet", ] } futures = { version = "0.3.30", default-features = false } diff --git a/bindings/wasm/Cargo.toml b/bindings/wasm/Cargo.toml index 4ce03205fd..a1ece8fd7b 100644 --- a/bindings/wasm/Cargo.toml +++ b/bindings/wasm/Cargo.toml @@ -17,11 +17,7 @@ crate-type = ["cdylib"] doc = false [dependencies] -iota-sdk-bindings-core = { path = "../core", default-features = false, features = [ - "events", - "storage", - "private_key_secret_manager", -] } +iota-sdk-bindings-core = { path = "../core", default-features = false } console_error_panic_hook = { version = "0.1.7", default-features = false } js-sys = { version = "0.3.68", default-features = false, features = [] } @@ -41,3 +37,9 @@ getrandom = { version = "0.2.12", default-features = false, features = ["js"] } instant = { version = "0.1.12", default-features = false, features = [ "wasm-bindgen", ] } + +[features] +default = ["private_key_secret_manager", "wallet"] + +private_key_secret_manager = [ "iota-sdk-bindings-core/private_key_secret_manager" ] +wallet = [ "iota-sdk-bindings-core/events", "iota-sdk-bindings-core/storage", "iota-sdk-bindings-core/wallet" ] diff --git a/bindings/wasm/package.json b/bindings/wasm/package.json index ee768101e4..28ebff3e6c 100644 --- a/bindings/wasm/package.json +++ b/bindings/wasm/package.json @@ -24,6 +24,9 @@ "build:web": "node ./build_scripts/copyNodejsDefs.js && yarn run build:src && yarn run bundle:web && wasm-opt -O web/wasm/iota_sdk_wasm_bg.wasm -o web/wasm/iota_sdk_wasm_bg.wasm", "bundle:nodejs": "wasm-bindgen ../../target/wasm32-unknown-unknown/production/iota_sdk_wasm.wasm --typescript --weak-refs --target nodejs --out-dir node/wasm && node ./build_scripts/node && tsc --project tsconfig.node.json --outDir node/lib", "bundle:web": "wasm-bindgen ../../target/wasm32-unknown-unknown/production/iota_sdk_wasm.wasm --typescript --weak-refs --target web --out-dir web/wasm && node ./build_scripts/web && tsc --project tsconfig.web.json --outDir web/lib", + "build:src-client-only": "cargo build --lib --profile=wasm --target wasm32-unknown-unknown --no-default-features", + "build:web-client-only": "node ./build_scripts/copyNodejsDefs.js && yarn run build:src-client-only && yarn run bundle:web-client-only && wasm-opt -Oz web/wasm/iota_sdk_wasm_bg.wasm -o web/wasm/iota_sdk_wasm_bg.wasm", + "bundle:web-client-only": "wasm-bindgen ../../target/wasm32-unknown-unknown/wasm/iota_sdk_wasm.wasm --typescript --weak-refs --target web --out-dir web/wasm && node ./build_scripts/web && tsc --project tsconfig.node.json --outDir node/lib", "copy-nodejs-defs": "node ./build_scripts/copyNodejsDefs.js", "lint": "eslint --ignore-path .eslintignore --ext .js,.ts .", "format": "prettier --ignore-path .eslintignore -w \"{,*/**/}*.{ts,js,json}\"", diff --git a/bindings/wasm/src/wallet.rs b/bindings/wasm/src/wallet.rs index 874f03042d..614205f152 100644 --- a/bindings/wasm/src/wallet.rs +++ b/bindings/wasm/src/wallet.rs @@ -1,8 +1,9 @@ // Copyright 2023 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::sync::Arc; - +#[cfg(feature = "wallet")] +use crate::{client::ClientMethodHandler, secret_manager::SecretManagerMethodHandler}; +#[cfg(feature = "wallet")] use iota_sdk_bindings_core::{ call_wallet_method, iota_sdk::wallet::{ @@ -11,20 +12,29 @@ use iota_sdk_bindings_core::{ }, Response, WalletMethod, WalletOptions, }; +#[cfg(feature = "wallet")] +use std::sync::Arc; +#[cfg(feature = "wallet")] use tokio::sync::{ mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, Mutex, }; use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; -use crate::{client::ClientMethodHandler, secret_manager::SecretManagerMethodHandler}; - +#[cfg(feature = "wallet")] /// The Wallet method handler. #[wasm_bindgen(js_name = WalletMethodHandler)] pub struct WalletMethodHandler { wallet: Arc>>, } +#[cfg(not(feature = "wallet"))] +#[wasm_bindgen(js_name = createWallet)] +#[allow(non_snake_case)] +pub fn create_wallet(_options: String) -> Result { + Err(JsValue::from(js_sys::Error::new("wallet feature not enabled"))) +} +#[cfg(feature = "wallet")] /// Creates a method handler with the given options. #[wasm_bindgen(js_name = createWallet)] #[allow(non_snake_case)] @@ -42,12 +52,24 @@ pub fn create_wallet(options: String) -> Result { }) } +#[cfg(not(feature = "wallet"))] +#[wasm_bindgen(js_name = destroyWallet)] +pub async fn destroy_wallet(_method_handler: &js_sys::Object) -> Result<(), JsValue> { + Err(JsValue::from(js_sys::Error::new("wallet feature not enabled"))) +} +#[cfg(feature = "wallet")] #[wasm_bindgen(js_name = destroyWallet)] pub async fn destroy_wallet(method_handler: &WalletMethodHandler) -> Result<(), JsValue> { *method_handler.wallet.lock().await = None; Ok(()) } +#[cfg(not(feature = "wallet"))] +#[wasm_bindgen(js_name = getClientFromWallet)] +pub async fn get_client(_method_handler: &js_sys::Object) -> Result { + Err(JsValue::from(js_sys::Error::new("wallet feature not enabled"))) +} +#[cfg(feature = "wallet")] #[wasm_bindgen(js_name = getClientFromWallet)] pub async fn get_client(method_handler: &WalletMethodHandler) -> Result { let client = method_handler @@ -62,6 +84,12 @@ pub async fn get_client(method_handler: &WalletMethodHandler) -> Result Result { + Err(JsValue::from(js_sys::Error::new("wallet feature not enabled"))) +} +#[cfg(feature = "wallet")] #[wasm_bindgen(js_name = getSecretManagerFromWallet)] pub async fn get_secret_manager(method_handler: &WalletMethodHandler) -> Result { let secret_manager = method_handler @@ -76,6 +104,12 @@ pub async fn get_secret_manager(method_handler: &WalletMethodHandler) -> Result< Ok(SecretManagerMethodHandler { secret_manager }) } +#[cfg(not(feature = "wallet"))] +#[wasm_bindgen(js_name = callWalletMethodAsync)] +pub async fn call_wallet_method_async(_method: String, _method_handler: &js_sys::Object) -> Result { + Err(JsValue::from(js_sys::Error::new("wallet feature not enabled"))) +} +#[cfg(feature = "wallet")] /// Handles a method, returns the response as a JSON-encoded string. /// /// Returns an error if the response itself is an error or panic. @@ -101,6 +135,17 @@ pub async fn call_wallet_method_async(method: String, method_handler: &WalletMet } } +#[cfg(not(feature = "wallet"))] +#[wasm_bindgen(js_name = listenWalletAsync)] +pub async fn listen_wallet( + _vec: js_sys::Array, + _callback: js_sys::Function, + _method_handler: &js_sys::Object, +) -> Result { + Err(JsValue::from(js_sys::Error::new("wallet feature not enabled"))) +} + +#[cfg(feature = "wallet")] /// It takes a list of event types, registers a callback function, and then listens for events of those /// types ///