refactor: Improve Rhai test runner and vault module code
Some checks are pending
Rhai Tests / Run Rhai Tests (push) Waiting to run

- Updated the Rhai test runner script to correctly find test files.
- Improved the structure and formatting of the `vault.rs` module.
- Minor code style improvements in multiple files.
This commit is contained in:
Mahmoud Emad
2025-05-12 12:47:37 +03:00
parent a8ed0900fd
commit 3a0900fc15
5 changed files with 154 additions and 141 deletions

View File

@@ -1,29 +1,28 @@
//! Rhai bindings for SAL crypto functionality
use rhai::{Engine, Dynamic, EvalAltResult};
use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64};
use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _};
use ethers::types::{Address, U256};
use once_cell::sync::Lazy;
use rhai::{Dynamic, Engine, EvalAltResult};
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
use std::collections::HashMap;
use std::sync::Mutex;
use once_cell::sync::Lazy;
use tokio::runtime::Runtime;
use ethers::types::{Address, U256};
use std::str::FromStr;
use std::sync::Mutex;
use tokio::runtime::Runtime;
use crate::vault::{keypair, ethereum};
use crate::vault::ethereum::contract_utils::{prepare_function_arguments, convert_token_to_rhai};
use crate::vault::ethereum::contract_utils::{convert_token_to_rhai, prepare_function_arguments};
use crate::vault::{ethereum, keypair};
use symmetric_impl::implementation as symmetric_impl;
use crate::vault::symmetric::implementation as symmetric_impl;
// Global Tokio runtime for blocking async operations
static RUNTIME: Lazy<Mutex<Runtime>> = Lazy::new(|| {
Mutex::new(Runtime::new().expect("Failed to create Tokio runtime"))
});
static RUNTIME: Lazy<Mutex<Runtime>> =
Lazy::new(|| Mutex::new(Runtime::new().expect("Failed to create Tokio runtime")));
// Global provider registry
static PROVIDERS: Lazy<Mutex<HashMap<String, ethers::providers::Provider<ethers::providers::Http>>>> = Lazy::new(|| {
Mutex::new(HashMap::new())
});
static PROVIDERS: Lazy<
Mutex<HashMap<String, ethers::providers::Provider<ethers::providers::Http>>>,
> = Lazy::new(|| Mutex::new(HashMap::new()));
// Key space management functions
fn load_key_space(name: &str, password: &str) -> bool {
@@ -90,7 +89,8 @@ fn create_key_space(name: &str, password: &str) -> bool {
match keypair::get_current_space() {
Ok(space) => {
// Encrypt the key space
let encrypted_space = match symmetric_impl::encrypt_key_space(&space, password) {
let encrypted_space = match symmetric_impl::encrypt_key_space(&space, password)
{
Ok(encrypted) => encrypted,
Err(e) => {
log::error!("Error encrypting key space: {}", e);
@@ -99,13 +99,14 @@ fn create_key_space(name: &str, password: &str) -> bool {
};
// Serialize the encrypted space
let serialized = match symmetric_impl::serialize_encrypted_space(&encrypted_space) {
Ok(json) => json,
Err(e) => {
log::error!("Error serializing encrypted space: {}", e);
return false;
}
};
let serialized =
match symmetric_impl::serialize_encrypted_space(&encrypted_space) {
Ok(json) => json,
Err(e) => {
log::error!("Error serializing encrypted space: {}", e);
return false;
}
};
// Get the key spaces directory
let home_dir = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
@@ -114,7 +115,7 @@ fn create_key_space(name: &str, password: &str) -> bool {
// Create directory if it doesn't exist
if !key_spaces_dir.exists() {
match fs::create_dir_all(&key_spaces_dir) {
Ok(_) => {},
Ok(_) => {}
Err(e) => {
log::error!("Error creating key spaces directory: {}", e);
return false;
@@ -128,19 +129,19 @@ fn create_key_space(name: &str, password: &str) -> bool {
Ok(_) => {
log::info!("Key space created and saved to {}", space_path.display());
true
},
}
Err(e) => {
log::error!("Error writing key space file: {}", e);
false
}
}
},
}
Err(e) => {
log::error!("Error getting current space: {}", e);
false
}
}
},
}
Err(e) => {
log::error!("Error creating key space: {}", e);
false
@@ -177,7 +178,7 @@ fn auto_save_key_space(password: &str) -> bool {
// Create directory if it doesn't exist
if !key_spaces_dir.exists() {
match fs::create_dir_all(&key_spaces_dir) {
Ok(_) => {},
Ok(_) => {}
Err(e) => {
log::error!("Error creating key spaces directory: {}", e);
return false;
@@ -191,13 +192,13 @@ fn auto_save_key_space(password: &str) -> bool {
Ok(_) => {
log::info!("Key space saved to {}", space_path.display());
true
},
}
Err(e) => {
log::error!("Error writing key space file: {}", e);
false
}
}
},
}
Err(e) => {
log::error!("Error getting current space: {}", e);
false
@@ -207,21 +208,17 @@ fn auto_save_key_space(password: &str) -> bool {
fn encrypt_key_space(password: &str) -> String {
match keypair::get_current_space() {
Ok(space) => {
match symmetric_impl::encrypt_key_space(&space, password) {
Ok(encrypted_space) => {
match serde_json::to_string(&encrypted_space) {
Ok(json) => json,
Err(e) => {
log::error!("Error serializing encrypted space: {}", e);
String::new()
}
}
},
Ok(space) => match symmetric_impl::encrypt_key_space(&space, password) {
Ok(encrypted_space) => match serde_json::to_string(&encrypted_space) {
Ok(json) => json,
Err(e) => {
log::error!("Error encrypting key space: {}", e);
log::error!("Error serializing encrypted space: {}", e);
String::new()
}
},
Err(e) => {
log::error!("Error encrypting key space: {}", e);
String::new()
}
},
Err(e) => {
@@ -235,13 +232,11 @@ fn decrypt_key_space(encrypted: &str, password: &str) -> bool {
match serde_json::from_str(encrypted) {
Ok(encrypted_space) => {
match symmetric_impl::decrypt_key_space(&encrypted_space, password) {
Ok(space) => {
match keypair::set_current_space(space) {
Ok(_) => true,
Err(e) => {
log::error!("Error setting current space: {}", e);
false
}
Ok(space) => match keypair::set_current_space(space) {
Ok(_) => true,
Err(e) => {
log::error!("Error setting current space: {}", e);
false
}
},
Err(e) => {
@@ -249,7 +244,7 @@ fn decrypt_key_space(encrypted: &str, password: &str) -> bool {
false
}
}
},
}
Err(e) => {
log::error!("Error parsing encrypted space: {}", e);
false
@@ -263,7 +258,7 @@ fn create_keypair(name: &str, password: &str) -> bool {
Ok(_) => {
// Auto-save the key space after creating a keypair
auto_save_key_space(password)
},
}
Err(e) => {
log::error!("Error creating keypair: {}", e);
false
@@ -306,13 +301,11 @@ fn sign(message: &str) -> String {
fn verify(message: &str, signature: &str) -> bool {
let message_bytes = message.as_bytes();
match BASE64.decode(signature) {
Ok(signature_bytes) => {
match keypair::keypair_verify(message_bytes, &signature_bytes) {
Ok(is_valid) => is_valid,
Err(e) => {
log::error!("Error verifying signature: {}", e);
false
}
Ok(signature_bytes) => match keypair::keypair_verify(message_bytes, &signature_bytes) {
Ok(is_valid) => is_valid,
Err(e) => {
log::error!("Error verifying signature: {}", e);
false
}
},
Err(e) => {
@@ -339,7 +332,7 @@ fn encrypt(key: &str, message: &str) -> String {
String::new()
}
}
},
}
Err(e) => {
log::error!("Error decoding key: {}", e);
String::new()
@@ -349,30 +342,26 @@ fn encrypt(key: &str, message: &str) -> String {
fn decrypt(key: &str, ciphertext: &str) -> String {
match BASE64.decode(key) {
Ok(key_bytes) => {
match BASE64.decode(ciphertext) {
Ok(ciphertext_bytes) => {
match symmetric_impl::decrypt_symmetric(&key_bytes, &ciphertext_bytes) {
Ok(plaintext) => {
match String::from_utf8(plaintext) {
Ok(text) => text,
Err(e) => {
log::error!("Error converting plaintext to string: {}", e);
String::new()
}
}
},
Ok(key_bytes) => match BASE64.decode(ciphertext) {
Ok(ciphertext_bytes) => {
match symmetric_impl::decrypt_symmetric(&key_bytes, &ciphertext_bytes) {
Ok(plaintext) => match String::from_utf8(plaintext) {
Ok(text) => text,
Err(e) => {
log::error!("Error decrypting ciphertext: {}", e);
log::error!("Error converting plaintext to string: {}", e);
String::new()
}
},
Err(e) => {
log::error!("Error decrypting ciphertext: {}", e);
String::new()
}
},
Err(e) => {
log::error!("Error decoding ciphertext: {}", e);
String::new()
}
}
Err(e) => {
log::error!("Error decoding ciphertext: {}", e);
String::new()
}
},
Err(e) => {
log::error!("Error decoding key: {}", e);
@@ -478,7 +467,11 @@ fn get_wallet_address_for_network(network_name: &str) -> String {
match ethereum::get_current_ethereum_wallet_for_network(network_name_proper) {
Ok(wallet) => wallet.address_string(),
Err(e) => {
log::error!("Error getting wallet address for network {}: {}", network_name, e);
log::error!(
"Error getting wallet address for network {}: {}",
network_name,
e
);
String::new()
}
}
@@ -542,7 +535,11 @@ fn create_wallet_from_private_key_for_network(private_key: &str, network_name: &
match ethereum::create_ethereum_wallet_from_private_key_for_network(private_key, network) {
Ok(_) => true,
Err(e) => {
log::error!("Error creating wallet from private key for network {}: {}", network_name, e);
log::error!(
"Error creating wallet from private key for network {}: {}",
network_name,
e
);
false
}
}
@@ -563,7 +560,7 @@ fn create_agung_provider() -> String {
log::error!("Failed to acquire provider registry lock");
String::new()
},
}
Err(e) => {
log::error!("Error creating Agung provider: {}", e);
String::new()
@@ -619,9 +616,7 @@ fn get_balance(network_name: &str, address: &str) -> String {
};
// Execute the balance query in a blocking manner
match rt.block_on(async {
ethereum::get_balance(&provider, addr).await
}) {
match rt.block_on(async { ethereum::get_balance(&provider, addr).await }) {
Ok(balance) => balance.to_string(),
Err(e) => {
log::error!("Failed to get balance: {}", e);
@@ -687,9 +682,7 @@ fn send_eth(wallet_network: &str, to_address: &str, amount_str: &str) -> String
};
// Execute the transaction in a blocking manner
match rt.block_on(async {
ethereum::send_eth(&wallet, &provider, to_addr, amount).await
}) {
match rt.block_on(async { ethereum::send_eth(&wallet, &provider, to_addr, amount).await }) {
Ok(tx_hash) => format!("{:?}", tx_hash),
Err(e) => {
log::error!("Transaction failed: {}", e);
@@ -731,7 +724,7 @@ fn load_contract_abi(network_name: &str, address: &str, abi_json: &str) -> Strin
String::new()
}
}
},
}
Err(e) => {
log::error!("Error creating contract: {}", e);
String::new()
@@ -916,14 +909,20 @@ pub fn register_crypto_module(engine: &mut Engine) -> Result<(), Box<EvalAltResu
// Register generic network functions
engine.register_fn("create_wallet_for_network", create_wallet_for_network);
engine.register_fn("get_wallet_address_for_network", get_wallet_address_for_network);
engine.register_fn(
"get_wallet_address_for_network",
get_wallet_address_for_network,
);
engine.register_fn("clear_wallets_for_network", clear_wallets_for_network);
engine.register_fn("list_supported_networks", list_supported_networks);
engine.register_fn("get_network_token_symbol", get_network_token_symbol);
engine.register_fn("get_network_explorer_url", get_network_explorer_url);
// Register new Ethereum functions for wallet creation from private key and transactions
engine.register_fn("create_wallet_from_private_key_for_network", create_wallet_from_private_key_for_network);
engine.register_fn(
"create_wallet_from_private_key_for_network",
create_wallet_from_private_key_for_network,
);
engine.register_fn("create_agung_provider", create_agung_provider);
engine.register_fn("send_eth", send_eth);
engine.register_fn("get_balance", get_balance);