diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 83327b02d412..76ea3aac76ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,12 +48,19 @@ jobs: steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@stable + with: + target: wasm32-unknown-unknown - uses: taiki-e/install-action@cargo-hack - uses: Swatinem/rust-cache@v2 with: cache-on-failure: true - name: cargo hack - run: cargo hack check --target wasm32-unknown-unknown + run: | + cargo hack check --workspace --target wasm32-unknown-unknown \ + --exclude alloy-signer \ + --exclude alloy-signer-aws \ + --exclude alloy-signer-ledger \ + --exclude alloy-signer-trezor feature-checks: runs-on: ubuntu-latest diff --git a/crates/signer/Cargo.toml b/crates/signer/Cargo.toml index ac76a6888bdc..72f517a399fe 100644 --- a/crates/signer/Cargo.toml +++ b/crates/signer/Cargo.toml @@ -18,7 +18,6 @@ alloy-primitives.workspace = true elliptic-curve.workspace = true k256.workspace = true -rand.workspace = true thiserror.workspace = true async-trait.workspace = true @@ -32,6 +31,9 @@ eth-keystore = { version = "0.5.0", default-features = false, optional = true } coins-bip32 = { version = "0.8.7", default-features = false, optional = true } coins-bip39 = { version = "0.8.7", default-features = false, optional = true } +# rand +rand = { workspace = true, optional = true } + # yubi yubihsm = { version = "0.42", features = ["secp256k1", "http", "usb"], optional = true } @@ -49,6 +51,7 @@ coins-bip39 = { version = "0.8.7", default-features = false, features = ["englis [features] eip712 = ["dep:alloy-sol-types"] -keystore = ["dep:eth-keystore"] +keystore = ["dep:eth-keystore", "rand"] mnemonic = ["dep:coins-bip32", "dep:coins-bip39"] +rand = ["dep:rand"] yubihsm = ["dep:yubihsm"] diff --git a/crates/signer/src/wallet/mnemonic.rs b/crates/signer/src/wallet/mnemonic.rs index 90990e7ecb07..bd40afc58c50 100644 --- a/crates/signer/src/wallet/mnemonic.rs +++ b/crates/signer/src/wallet/mnemonic.rs @@ -5,10 +5,12 @@ use crate::{utils::secret_key_to_address, Wallet, WalletError}; use coins_bip32::path::DerivationPath; use coins_bip39::{Mnemonic, Wordlist}; use k256::ecdsa::SigningKey; -use rand::Rng; -use std::{fs::File, io::Write, marker::PhantomData, path::PathBuf, str::FromStr}; +use std::{marker::PhantomData, path::PathBuf}; use thiserror::Error; +#[cfg(feature = "rand")] +use rand::Rng; + const DEFAULT_DERIVATION_PATH_PREFIX: &str = "m/44'/60'/0'/0/"; const DEFAULT_DERIVATION_PATH: &str = "m/44'/60'/0'/0/0"; @@ -87,12 +89,11 @@ impl MnemonicBuilder { /// /// # Examples /// - /// ``` + /// ```no_run /// use alloy_signer::{coins_bip39::English, MnemonicBuilder}; - /// # async fn foo() -> Result<(), Box> { /// - /// let mut rng = rand::thread_rng(); - /// let wallet = MnemonicBuilder::::default().word_count(24).build_random(&mut rng)?; + /// # async fn foo() -> Result<(), Box> { + /// let wallet = MnemonicBuilder::::default().word_count(24).build()?; /// /// # Ok(()) /// # } @@ -110,7 +111,7 @@ impl MnemonicBuilder { /// Sets the derivation path of the child key to be derived. pub fn derivation_path>(mut self, path: T) -> Result { - self.derivation_path = DerivationPath::from_str(path.as_ref())?; + self.derivation_path = path.as_ref().parse()?; Ok(self) } @@ -139,6 +140,7 @@ impl MnemonicBuilder { /// Builds a `LocalWallet` using the parameters set in the mnemonic builder and constructing /// the phrase using the provided random number generator. + #[cfg(feature = "rand")] pub fn build_random(&self, rng: &mut R) -> Result, WalletError> { let mnemonic = match &self.phrase { None => Mnemonic::::new_with_count(rng, self.word_count)?, @@ -148,8 +150,7 @@ impl MnemonicBuilder { // Write the mnemonic phrase to storage if a directory has been provided. if let Some(dir) = &self.write_to { - let mut file = File::create(dir.as_path().join(wallet.address.to_string()))?; - file.write_all(mnemonic.to_phrase().as_bytes())?; + std::fs::write(dir.join(wallet.address.to_string()), mnemonic.to_phrase().as_bytes())?; } Ok(wallet) diff --git a/crates/signer/src/wallet/private_key.rs b/crates/signer/src/wallet/private_key.rs index 2e9702c29c36..16aabca604e2 100644 --- a/crates/signer/src/wallet/private_key.rs +++ b/crates/signer/src/wallet/private_key.rs @@ -7,10 +7,12 @@ use k256::{ ecdsa::{self, SigningKey}, FieldBytes, SecretKey as K256SecretKey, }; -use rand::{CryptoRng, Rng}; use std::str::FromStr; use thiserror::Error; +#[cfg(feature = "rand")] +use rand::{CryptoRng, Rng}; + #[cfg(feature = "keystore")] use {elliptic_curve::rand_core, eth_keystore::KeystoreError, std::path::Path}; @@ -61,12 +63,14 @@ impl Wallet { /// Creates a new random keypair seeded with [`rand::thread_rng()`]. #[inline] + #[cfg(feature = "rand")] pub fn random() -> Self { Self::random_with(&mut rand::thread_rng()) } /// Creates a new random keypair seeded with the provided RNG. #[inline] + #[cfg(feature = "rand")] pub fn random_with(rng: &mut R) -> Self { Self::new_pk(SigningKey::random(rng)) } @@ -84,7 +88,6 @@ impl Wallet { /// provided directory. Returns a tuple (Wallet, String) of the wallet instance for the /// keystore with its random UUID. Accepts an optional name for the keystore file. If `None`, /// the keystore is stored as the stringified UUID. - #[cfg(not(target_arch = "wasm32"))] #[inline] pub fn new_keystore( dir: P, @@ -102,7 +105,6 @@ impl Wallet { } /// Decrypts an encrypted JSON from the provided path to construct a Wallet instance - #[cfg(not(target_arch = "wasm32"))] #[inline] pub fn decrypt_keystore(keypath: P, password: S) -> Result where @@ -117,7 +119,6 @@ impl Wallet { /// provided directory. Returns a tuple (Wallet, String) of the wallet instance for the /// keystore with its random UUID. Accepts an optional name for the keystore file. If `None`, /// the keystore is stored as the stringified UUID. - #[cfg(not(target_arch = "wasm32"))] #[inline] pub fn encrypt_keystore( keypath: P, @@ -160,7 +161,6 @@ impl FromStr for Wallet { } #[cfg(test)] -#[cfg(not(target_arch = "wasm32"))] mod tests { use super::*; use crate::{LocalWallet, Signer};