use std::path::Path;
use std::fs;
use std::io::Write;
use serde_json::Value;
use solana_sdk::signature::Keypair;
use solana_sdk::signer::Signer;
use crate::{decrypt_key, generate_encryption_key_simple, interactive};
pub type Result<T> = std::result::Result<T, String>;
pub fn ensure_wallet_ready(wallet_path: &str) -> Result<Keypair> {
if wallet_exists(wallet_path) {
println!("โ
Wallet found at: {}", wallet_path);
println!("๐ Starting interactive wallet unlock...\n");
unlock_wallet(wallet_path)
} else {
println!("โ ๏ธ Wallet not found at: {}", wallet_path);
println!("๐ Starting interactive wallet creation...\n");
create_wallet(wallet_path)?;
println!("\nNow unlocking the newly created wallet...\n");
unlock_wallet(wallet_path)
}
}
pub fn wallet_exists(path: &str) -> bool {
Path::new(path).exists()
}
pub fn get_wallet_pubkey(wallet_path: &str) -> Result<String> {
let content = fs::read_to_string(wallet_path)
.map_err(|e| format!("Failed to read wallet: {}", e))?;
let data: Value = serde_json::from_str(&content)
.map_err(|e| format!("Invalid wallet format: {}", e))?;
data["public_key"]
.as_str()
.map(String::from)
.ok_or_else(|| "Public key not found in wallet file".to_string())
}
fn create_wallet(output_path: &str) -> Result<()> {
println!("๐ Interactive Wallet Creation");
println!("โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ");
println!("\nYou will be guided through the wallet creation process.");
println!("The wallet will be saved to: {}\n", output_path);
interactive::show_main_menu()?;
if !wallet_exists(output_path) {
println!("\nโ ๏ธ Note: Wallet was not saved to the expected path.");
println!(" Expected: {}", output_path);
println!(" Please make sure to save your wallet to this location.");
return Err(format!("Wallet not created at expected path: {}", output_path));
}
println!("\nโ
Wallet created successfully!");
println!("๐ Location: {}", output_path);
Ok(())
}
fn unlock_wallet(wallet_path: &str) -> Result<Keypair> {
if !wallet_exists(wallet_path) {
return Err(format!("Wallet file not found: {}", wallet_path));
}
println!("๐ Unlocking wallet: {}", wallet_path);
let content = fs::read_to_string(wallet_path)
.map_err(|e| format!("Failed to read wallet: {}", e))?;
let data: Value = serde_json::from_str(&content)
.map_err(|e| format!("Invalid wallet format: {}", e))?;
let encrypted_key = data["encrypted_private_key"]
.as_str()
.ok_or_else(|| "Encrypted private key not found in wallet file".to_string())?;
print!("๐ Enter wallet password: ");
std::io::stdout().flush().unwrap();
let password = rpassword::read_password()
.map_err(|e| format!("Failed to read password: {}", e))?;
let encryption_key = generate_encryption_key_simple(&password);
let private_key = decrypt_key(encrypted_key, &encryption_key)?;
let keypair = Keypair::from_base58_string(&private_key);
println!("โ
Wallet unlocked successfully!");
println!("๐ Address: {}", keypair.pubkey());
Ok(keypair)
}