Skip to content

refactor(signer-local): replace eth-keystore with inline keystore implementation#3831

Open
decofe wants to merge 2 commits intomainfrom
zerosnacks/remove-eth-keystore-dep
Open

refactor(signer-local): replace eth-keystore with inline keystore implementation#3831
decofe wants to merge 2 commits intomainfrom
zerosnacks/remove-eth-keystore-dep

Conversation

@decofe
Copy link
Copy Markdown
Contributor

@decofe decofe commented Mar 23, 2026

Removes the eth-keystore dependency from alloy-signer-local by reimplementing the Web3 Secret Storage keystore logic directly.

Motivation

eth-keystore is unmaintained (last published 2022). Inlining the implementation gives alloy full control over the keystore code, removes an external dependency, and allows using alloy primitives natively.

Changes

  • New keystore module (src/keystore/mod.rs): Reimplements new, decrypt_key, encrypt_key and all keystore types (EthKeystore, CryptoJson, CipherparamsJson, KdfType, KdfparamsType, KeystoreError)
  • Replaces transitive deps with direct deps: aes, ctr, scrypt, pbkdf2, hmac, sha2, uuid — same crates, just owned directly behind the keystore feature
  • Uses alloy primitives: alloy_primitives::keccak256 (replaces sha3), alloy_primitives::hex (replaces hex crate), alloy_primitives::Address (replaces ethereum_types::H160)
  • Removes keystore-geth-compat feature: Address field is now Option<Address> always, no feature flag needed
  • Adds input validation: dklen >= 32, iv >= 16 bytes, scrypt n must be a power of two (integer ilog2 instead of float log2)
  • Renames error variant: LocalSignerError::EthKeystoreErrorLocalSignerError::KeystoreError

Breaking changes

  • LocalSignerError::EthKeystoreError renamed to LocalSignerError::KeystoreError with inner type keystore::KeystoreError instead of eth_keystore::KeystoreError
  • keystore-geth-compat / signer-keystore-geth-compat features removed
  • EthKeystore::address is now Option<Address> instead of being conditionally compiled

Prompted by: zerosnacks

…lementation

Removes the eth-keystore dependency by reimplementing the Web3 Secret
Storage keystore logic directly using alloy primitives and the same
underlying crypto crates (aes, ctr, scrypt, pbkdf2, hmac, sha2).

- Uses alloy_primitives::keccak256 instead of sha3::Keccak256
- Uses alloy_primitives::hex for serde helpers instead of the hex crate
- Uses alloy_primitives::Address instead of ethereum_types::H160
- Replaces keystore-geth-compat feature with always-available
  Option<Address> on EthKeystore
- Adds input validation: dklen >= 32, iv >= 16 bytes, scrypt n must
  be a power of two (uses integer ilog2 instead of float log2)
- Renames error variant from EthKeystoreError to KeystoreError
- Re-exports keystore types from crate root under keystore feature

Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019d1c07-7274-7568-8ce0-a01fc3f8c7ca
- Re-add keystore-geth-compat feature that derives address from pk
  during encrypt_key using alloy_signer::utils::secret_key_to_address
- Add Apache-2.0 attribution to eth-keystore (Rohit Narurkar) in
  module doc header
- Restore geth-compat test asserting address is populated
- Fix KeystoreError display strings to match original eth-keystore
  messages (Mac Mismatch, IO:, serde-json:, scrypt)

Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019d1c07-7274-7568-8ce0-a01fc3f8c7ca
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants