use sharenet_passport::{ application::use_cases::*, infrastructure::*, ApplicationError, FileStorage, }; use rpassword::prompt_password; use hex; pub struct CliInterface; impl CliInterface { pub fn new() -> Self { Self } pub fn handle_create(&self, output: &str) -> Result<(), ApplicationError> { let password = prompt_password("Enter password for new passport: ").unwrap(); let confirm_password = prompt_password("Confirm password: ").unwrap(); if password != confirm_password { return Err(ApplicationError::UseCaseError("Passwords do not match".to_string())); } let use_case = CreatePassportUseCase::new( Bip39MnemonicGenerator, Ed25519KeyDeriver, XChaCha20FileEncryptor, FileSystemStorage, ); let (passport, recovery_phrase) = use_case.execute(&password, output)?; println!("āœ… Passport created successfully!"); println!("šŸ“„ Saved to: {}", output); println!("šŸ”‘ Public Key: {}", hex::encode(&passport.public_key().0)); println!("šŸ†” DID: {}", passport.did().as_str()); println!("\nšŸ“ IMPORTANT: Save your recovery phrase in a secure location!"); println!("Recovery phrase: {}", recovery_phrase.to_string()); Ok(()) } pub fn handle_import_recovery(&self, output: &str) -> Result<(), ApplicationError> { println!("Enter your 24-word recovery phrase:"); let mut recovery_words = Vec::new(); for i in 1..=24 { let word = prompt_password(&format!("Word {}: ", i)).unwrap(); recovery_words.push(word); } let password = prompt_password("Enter new password for passport file: ").unwrap(); let confirm_password = prompt_password("Confirm password: ").unwrap(); if password != confirm_password { return Err(ApplicationError::UseCaseError("Passwords do not match".to_string())); } let use_case = ImportFromRecoveryUseCase::new( Bip39MnemonicGenerator, Ed25519KeyDeriver, XChaCha20FileEncryptor, FileSystemStorage, ); let passport = use_case.execute(&recovery_words, &password, output)?; println!("āœ… Passport imported successfully!"); println!("šŸ“„ Saved to: {}", output); println!("šŸ”‘ Public Key: {}", hex::encode(&passport.public_key().0)); println!("šŸ†” DID: {}", passport.did().as_str()); Ok(()) } pub fn handle_import_file(&self, input: &str, output: Option<&str>) -> Result<(), ApplicationError> { let password = prompt_password("Enter password for passport file: ").unwrap(); let use_case = ImportFromFileUseCase::new( XChaCha20FileEncryptor, FileSystemStorage, ); let passport = use_case.execute(input, &password, output)?; println!("āœ… Passport imported successfully!"); if let Some(output_path) = output { println!("šŸ“„ Re-encrypted to: {}", output_path); } println!("šŸ”‘ Public Key: {}", hex::encode(&passport.public_key().0)); println!("šŸ†” DID: {}", passport.did().as_str()); Ok(()) } pub fn handle_export(&self, input: &str, output: &str) -> Result<(), ApplicationError> { let password = prompt_password("Enter password for passport file: ").unwrap(); let new_password = prompt_password("Enter new password for exported file: ").unwrap(); let confirm_password = prompt_password("Confirm new password: ").unwrap(); if new_password != confirm_password { return Err(ApplicationError::UseCaseError("Passwords do not match".to_string())); } // First import to get the passport let import_use_case = ImportFromFileUseCase::new( XChaCha20FileEncryptor, FileSystemStorage, ); let passport = import_use_case.execute(input, &password, None)?; // Then export with new password let export_use_case = ExportPassportUseCase::new( XChaCha20FileEncryptor, FileSystemStorage, ); export_use_case.execute(&passport, &new_password, output)?; println!("āœ… Passport exported successfully!"); println!("šŸ“„ Saved to: {}", output); Ok(()) } pub fn handle_info(&self, file: &str) -> Result<(), ApplicationError> { let passport_file = FileSystemStorage.load(file) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to load file: {}", e)))?; println!("šŸ“„ Passport File Information:"); println!(" File: {}", file); println!(" Version: {}", passport_file.version); println!(" Created: {}", passport_file.created_at); println!(" DID: {}", passport_file.did); println!(" Public Key: {}", hex::encode(&passport_file.public_key)); println!(" KDF: {}", passport_file.kdf); println!(" Cipher: {}", passport_file.cipher); Ok(()) } pub fn handle_sign(&self, file: &str, message: &str) -> Result<(), ApplicationError> { let password = prompt_password("Enter password for passport file: ").unwrap(); let import_use_case = ImportFromFileUseCase::new( XChaCha20FileEncryptor, FileSystemStorage, ); let passport = import_use_case.execute(file, &password, None)?; let sign_use_case = SignCardUseCase::new(); let signature = sign_use_case.execute(&passport, message)?; println!("āœ… Message signed successfully!"); println!("šŸ“ Message: {}", message); println!("šŸ” Signature: {}", hex::encode(&signature)); Ok(()) } }