refactor and add peaq support

This commit is contained in:
2025-05-09 16:57:31 +03:00
parent 98ab2e1536
commit 07390c3cae
26 changed files with 1248 additions and 275 deletions

View File

@@ -4,10 +4,26 @@ use rhai::{Engine, Dynamic, FnPtr, EvalAltResult};
use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64};
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 crate::crypto::{keypair, symmetric, ethereum};
use crate::crypto::error::CryptoError;
use crate::crypto::kvs;
use crate::hero_vault::{keypair, symmetric, ethereum};
use crate::hero_vault::error::CryptoError;
use crate::hero_vault::kvs;
// Global Tokio runtime for blocking async operations
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())
});
// Key space management functions
fn load_key_space(name: &str, password: &str) -> bool {
@@ -366,8 +382,10 @@ fn decrypt(key: &str, ciphertext: &str) -> String {
}
// Ethereum operations
// Gnosis Chain operations
fn create_ethereum_wallet() -> bool {
match ethereum::create_ethereum_wallet() {
match ethereum::create_ethereum_wallet_for_network(ethereum::networks::gnosis()) {
Ok(_) => true,
Err(e) => {
log::error!("Error creating Ethereum wallet: {}", e);
@@ -377,7 +395,7 @@ fn create_ethereum_wallet() -> bool {
}
fn get_ethereum_address() -> String {
match ethereum::get_current_ethereum_wallet() {
match ethereum::get_current_ethereum_wallet_for_network("Gnosis") {
Ok(wallet) => wallet.address_string(),
Err(e) => {
log::error!("Error getting Ethereum address: {}", e);
@@ -386,6 +404,300 @@ fn get_ethereum_address() -> String {
}
}
// Peaq network operations
fn create_peaq_wallet() -> bool {
match ethereum::create_peaq_wallet() {
Ok(_) => true,
Err(e) => {
log::error!("Error creating Peaq wallet: {}", e);
false
}
}
}
fn get_peaq_address() -> String {
match ethereum::get_current_peaq_wallet() {
Ok(wallet) => wallet.address_string(),
Err(e) => {
log::error!("Error getting Peaq address: {}", e);
String::new()
}
}
}
// Agung testnet operations
fn create_agung_wallet() -> bool {
match ethereum::create_agung_wallet() {
Ok(_) => true,
Err(e) => {
log::error!("Error creating Agung wallet: {}", e);
false
}
}
}
fn get_agung_address() -> String {
match ethereum::get_current_agung_wallet() {
Ok(wallet) => wallet.address_string(),
Err(e) => {
log::error!("Error getting Agung address: {}", e);
String::new()
}
}
}
// Generic network operations
fn create_wallet_for_network(network_name: &str) -> bool {
let network = match ethereum::networks::get_network_by_name(network_name) {
Some(network) => network,
None => {
log::error!("Unknown network: {}", network_name);
return false;
}
};
match ethereum::create_ethereum_wallet_for_network(network) {
Ok(_) => true,
Err(e) => {
log::error!("Error creating wallet for network {}: {}", network_name, e);
false
}
}
}
// Get wallet address for a specific network
fn get_wallet_address_for_network(network_name: &str) -> String {
let network_name_proper = match ethereum::networks::get_proper_network_name(network_name) {
Some(name) => name,
None => {
log::error!("Unknown network: {}", network_name);
return String::new();
}
};
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);
String::new()
}
}
}
// Clear wallets for a specific network
fn clear_wallets_for_network(network_name: &str) -> bool {
let network_name_proper = match ethereum::networks::get_proper_network_name(network_name) {
Some(name) => name,
None => {
log::error!("Unknown network: {}", network_name);
return false;
}
};
ethereum::clear_ethereum_wallets_for_network(network_name_proper);
true
}
// List supported networks
fn list_supported_networks() -> rhai::Array {
let mut arr = rhai::Array::new();
for name in ethereum::networks::list_network_names() {
arr.push(Dynamic::from(name.to_lowercase()));
}
arr
}
// Get network token symbol
fn get_network_token_symbol(network_name: &str) -> String {
match ethereum::networks::get_network_by_name(network_name) {
Some(network) => network.token_symbol,
None => {
log::error!("Unknown network: {}", network_name);
String::new()
}
}
}
// Get network explorer URL
fn get_network_explorer_url(network_name: &str) -> String {
match ethereum::networks::get_network_by_name(network_name) {
Some(network) => network.explorer_url,
None => {
log::error!("Unknown network: {}", network_name);
String::new()
}
}
}
// Create a wallet from a private key for a specific network
fn create_wallet_from_private_key_for_network(private_key: &str, network_name: &str) -> bool {
let network = match ethereum::networks::get_network_by_name(network_name) {
Some(network) => network,
None => {
log::error!("Unknown network: {}", network_name);
return false;
}
};
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);
false
}
}
}
// Create a provider for the Agung network
fn create_agung_provider() -> String {
match ethereum::create_agung_provider() {
Ok(provider) => {
// Generate a unique ID for the provider
let id = format!("provider_{}", uuid::Uuid::new_v4());
// Store the provider in the registry
if let Ok(mut providers) = PROVIDERS.lock() {
providers.insert(id.clone(), provider);
return id;
}
log::error!("Failed to acquire provider registry lock");
String::new()
},
Err(e) => {
log::error!("Error creating Agung provider: {}", e);
String::new()
}
}
}
// Get the balance of an address on a specific network
fn get_balance(network_name: &str, address: &str) -> String {
// Get the runtime
let rt = match RUNTIME.lock() {
Ok(rt) => rt,
Err(e) => {
log::error!("Failed to acquire runtime lock: {}", e);
return String::new();
}
};
// Parse the address
let addr = match Address::from_str(address) {
Ok(addr) => addr,
Err(e) => {
log::error!("Invalid address format: {}", e);
return String::new();
}
};
// Get the proper network name
let network_name_proper = match ethereum::networks::get_proper_network_name(network_name) {
Some(name) => name,
None => {
log::error!("Unknown network: {}", network_name);
return String::new();
}
};
// Get the network config
let network = match ethereum::networks::get_network_by_name(network_name_proper) {
Some(n) => n,
None => {
log::error!("Failed to get network config for: {}", network_name_proper);
return String::new();
}
};
// Create a provider
let provider = match ethereum::create_provider(&network) {
Ok(p) => p,
Err(e) => {
log::error!("Failed to create provider: {}", e);
return String::new();
}
};
// Execute the balance query in a blocking manner
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);
String::new()
}
}
}
// Send ETH from one address to another using the blocking approach
fn send_eth(wallet_network: &str, to_address: &str, amount_str: &str) -> String {
// Get the runtime
let rt = match RUNTIME.lock() {
Ok(rt) => rt,
Err(e) => {
log::error!("Failed to acquire runtime lock: {}", e);
return String::new();
}
};
// Parse the address
let to_addr = match Address::from_str(to_address) {
Ok(addr) => addr,
Err(e) => {
log::error!("Invalid address format: {}", e);
return String::new();
}
};
// Parse the amount (using string to handle large numbers)
let amount = match U256::from_dec_str(amount_str) {
Ok(amt) => amt,
Err(e) => {
log::error!("Invalid amount format: {}", e);
return String::new();
}
};
// Get the proper network name
let network_name_proper = match ethereum::networks::get_proper_network_name(wallet_network) {
Some(name) => name,
None => {
log::error!("Unknown network: {}", wallet_network);
return String::new();
}
};
// Get the wallet
let wallet = match ethereum::get_current_ethereum_wallet_for_network(network_name_proper) {
Ok(w) => w,
Err(e) => {
log::error!("Failed to get wallet: {}", e);
return String::new();
}
};
// Create a provider
let provider = match ethereum::create_provider(&wallet.network) {
Ok(p) => p,
Err(e) => {
log::error!("Failed to create provider: {}", e);
return String::new();
}
};
// Execute the transaction in a blocking manner
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);
String::new()
}
}
}
/// Register crypto functions with the Rhai engine
pub fn register_crypto_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
// Register key space functions
@@ -408,9 +720,31 @@ pub fn register_crypto_module(engine: &mut Engine) -> Result<(), Box<EvalAltResu
engine.register_fn("encrypt", encrypt);
engine.register_fn("decrypt", decrypt);
// Register Ethereum functions
// Register Ethereum functions (Gnosis Chain)
engine.register_fn("create_ethereum_wallet", create_ethereum_wallet);
engine.register_fn("get_ethereum_address", get_ethereum_address);
// Register Peaq network functions
engine.register_fn("create_peaq_wallet", create_peaq_wallet);
engine.register_fn("get_peaq_address", get_peaq_address);
// Register Agung testnet functions
engine.register_fn("create_agung_wallet", create_agung_wallet);
engine.register_fn("get_agung_address", get_agung_address);
// 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("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_agung_provider", create_agung_provider);
engine.register_fn("send_eth", send_eth);
engine.register_fn("get_balance", get_balance);
Ok(())
}
}

View File

@@ -11,7 +11,7 @@ mod nerdctl;
mod git;
mod text;
mod rfs;
mod crypto;
mod hero_vault; // This module now uses hero_vault internally
#[cfg(test)]
mod tests;
@@ -75,7 +75,7 @@ pub use crate::text::{
pub use text::*;
// Re-export crypto module
pub use crypto::register_crypto_module;
pub use hero_vault::register_crypto_module;
// Rename copy functions to avoid conflicts
pub use os::copy as os_copy;
@@ -121,10 +121,10 @@ pub fn register(engine: &mut Engine) -> Result<(), Box<rhai::EvalAltResult>> {
rfs::register(engine)?;
// Register Crypto module functions
crypto::register_crypto_module(engine)?;
hero_vault::register_crypto_module(engine)?;
// Future modules can be registered here
Ok(())
}
}