- Renamed examples directory to `_archive` to reflect legacy status. - Updated README.md to reflect current status of vault module, including migration from Sameh's implementation to Lee's. - Temporarily disabled Rhai scripting integration for the vault. - Added notes regarding current and future development steps.
127 lines
3.8 KiB
Rust
127 lines
3.8 KiB
Rust
//! Ethereum wallet implementation.
|
|
|
|
use ethers::prelude::*;
|
|
use ethers::signers::{LocalWallet, Signer, Wallet};
|
|
use ethers::utils::hex;
|
|
use k256::ecdsa::SigningKey;
|
|
use sha2::{Digest, Sha256};
|
|
use std::str::FromStr;
|
|
|
|
use super::networks::NetworkConfig;
|
|
use crate::error::CryptoError;
|
|
use crate::keyspace::KeyPair;
|
|
|
|
/// An Ethereum wallet derived from a keypair.
|
|
#[derive(Debug, Clone)]
|
|
pub struct EthereumWallet {
|
|
pub address: Address,
|
|
pub wallet: Wallet<SigningKey>,
|
|
pub network: NetworkConfig,
|
|
}
|
|
|
|
impl EthereumWallet {
|
|
/// Creates a new Ethereum wallet from a keypair for a specific network.
|
|
pub fn from_keypair(
|
|
keypair: &crate::keyspace::keypair_types::KeyPair,
|
|
network: NetworkConfig,
|
|
) -> Result<Self, CryptoError> {
|
|
// Get the private key bytes from the keypair
|
|
let private_key_bytes = keypair.signing_key.to_bytes();
|
|
|
|
// Convert to a hex string (without 0x prefix)
|
|
let private_key_hex = hex::encode(private_key_bytes);
|
|
|
|
// Create an Ethereum wallet from the private key
|
|
let wallet = LocalWallet::from_str(&private_key_hex)
|
|
.map_err(|_e| CryptoError::InvalidKeyLength)?
|
|
.with_chain_id(network.chain_id);
|
|
|
|
// Get the Ethereum address
|
|
let address = wallet.address();
|
|
|
|
Ok(EthereumWallet {
|
|
address,
|
|
wallet,
|
|
network,
|
|
})
|
|
}
|
|
|
|
/// Creates a new Ethereum wallet from a name and keypair (deterministic derivation) for a specific network.
|
|
pub fn from_name_and_keypair(
|
|
name: &str,
|
|
keypair: &KeyPair,
|
|
network: NetworkConfig,
|
|
) -> Result<Self, CryptoError> {
|
|
// Get the private key bytes from the keypair
|
|
let private_key_bytes = keypair.signing_key.to_bytes();
|
|
|
|
// Create a deterministic seed by combining name and private key
|
|
let mut hasher = Sha256::default();
|
|
hasher.update(name.as_bytes());
|
|
hasher.update(&private_key_bytes);
|
|
let seed = hasher.finalize();
|
|
|
|
// Use the seed as a private key
|
|
let private_key_hex = hex::encode(seed);
|
|
|
|
// Create an Ethereum wallet from the derived private key
|
|
let wallet = LocalWallet::from_str(&private_key_hex)
|
|
.map_err(|_e| CryptoError::InvalidKeyLength)?
|
|
.with_chain_id(network.chain_id);
|
|
|
|
// Get the Ethereum address
|
|
let address = wallet.address();
|
|
|
|
Ok(EthereumWallet {
|
|
address,
|
|
wallet,
|
|
network,
|
|
})
|
|
}
|
|
|
|
/// Creates a new Ethereum wallet from a private key for a specific network.
|
|
pub fn from_private_key(
|
|
private_key: &str,
|
|
network: NetworkConfig,
|
|
) -> Result<Self, CryptoError> {
|
|
// Remove 0x prefix if present
|
|
let private_key_clean = private_key.trim_start_matches("0x");
|
|
|
|
// Create an Ethereum wallet from the private key
|
|
let wallet = LocalWallet::from_str(private_key_clean)
|
|
.map_err(|_e| CryptoError::InvalidKeyLength)?
|
|
.with_chain_id(network.chain_id);
|
|
|
|
// Get the Ethereum address
|
|
let address = wallet.address();
|
|
|
|
Ok(EthereumWallet {
|
|
address,
|
|
wallet,
|
|
network,
|
|
})
|
|
}
|
|
|
|
/// Gets the Ethereum address as a string.
|
|
pub fn address_string(&self) -> String {
|
|
format!("{:?}", self.address)
|
|
}
|
|
|
|
/// Signs a message with the Ethereum wallet.
|
|
pub async fn sign_message(&self, message: &[u8]) -> Result<String, CryptoError> {
|
|
let signature = self
|
|
.wallet
|
|
.sign_message(message)
|
|
.await
|
|
.map_err(|e| CryptoError::SignatureFormatError(e.to_string()))?;
|
|
|
|
Ok(signature.to_string())
|
|
}
|
|
|
|
/// Gets the private key as a hex string.
|
|
pub fn private_key_hex(&self) -> String {
|
|
let bytes = self.wallet.signer().to_bytes();
|
|
hex::encode(bytes)
|
|
}
|
|
}
|