//! 硬件钱包集成模块 //! //! 实现Ledger和Trezor硬件钱包支持、通信协议和设备管理 use crate::WalletError; use std::collections::HashMap; /// 硬件钱包类型 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum HardwareWalletType { /// Ledger Nano S LedgerNanoS, /// Ledger Nano X LedgerNanoX, /// Trezor One TrezorOne, /// Trezor Model T TrezorModelT, } impl HardwareWalletType { /// 获取设备名称 pub fn name(&self) -> &'static str { match self { HardwareWalletType::LedgerNanoS => "Ledger Nano S", HardwareWalletType::LedgerNanoX => "Ledger Nano X", HardwareWalletType::TrezorOne => "Trezor One", HardwareWalletType::TrezorModelT => "Trezor Model T", } } /// 是否为Ledger设备 pub fn is_ledger(&self) -> bool { matches!(self, HardwareWalletType::LedgerNanoS | HardwareWalletType::LedgerNanoX) } /// 是否为Trezor设备 pub fn is_trezor(&self) -> bool { matches!(self, HardwareWalletType::TrezorOne | HardwareWalletType::TrezorModelT) } } /// 设备连接状态 #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum DeviceStatus { /// 已连接 Connected, /// 已断开 Disconnected, /// 锁定中 Locked, /// 错误 Error, } /// 硬件钱包设备 #[derive(Debug, Clone)] pub struct HardwareDevice { /// 设备ID pub id: String, /// 设备类型 pub device_type: HardwareWalletType, /// 固件版本 pub firmware_version: String, /// 序列号 pub serial_number: String, /// 连接状态 pub status: DeviceStatus, /// 支持的币种 pub supported_coins: Vec, } impl HardwareDevice { /// 创建新设备 pub fn new( id: String, device_type: HardwareWalletType, firmware_version: String, serial_number: String ) -> Self { let supported_coins = match device_type { HardwareWalletType::LedgerNanoS | HardwareWalletType::LedgerNanoX => { vec!["BTC".to_string(), "ETH".to_string(), "NAC".to_string()] } HardwareWalletType::TrezorOne | HardwareWalletType::TrezorModelT => { vec!["BTC".to_string(), "ETH".to_string(), "NAC".to_string()] } }; HardwareDevice { id, device_type, firmware_version, serial_number, status: DeviceStatus::Disconnected, supported_coins, } } /// 检查是否支持币种 pub fn supports_coin(&self, coin: &str) -> bool { self.supported_coins.iter().any(|c| c == coin) } } /// 通信协议 pub trait CommunicationProtocol { /// 连接设备 fn connect(&mut self) -> Result<(), WalletError>; /// 断开设备 fn disconnect(&mut self) -> Result<(), WalletError>; /// 发送命令 fn send_command(&self, command: &[u8]) -> Result, WalletError>; /// 获取设备信息 fn get_device_info(&self) -> Result; } /// Ledger通信协议 pub struct LedgerProtocol { device_id: String, connected: bool, } impl LedgerProtocol { /// 创建新的Ledger协议实例 pub fn new(device_id: String) -> Self { LedgerProtocol { device_id, connected: false, } } /// Ledger APDU命令 fn apdu_command(&self, cla: u8, ins: u8, p1: u8, p2: u8, data: &[u8]) -> Vec { let mut command = vec![cla, ins, p1, p2, data.len() as u8]; command.extend_from_slice(data); command } } impl CommunicationProtocol for LedgerProtocol { fn connect(&mut self) -> Result<(), WalletError> { // 模拟连接 self.connected = true; Ok(()) } fn disconnect(&mut self) -> Result<(), WalletError> { self.connected = false; Ok(()) } fn send_command(&self, command: &[u8]) -> Result, WalletError> { if !self.connected { return Err(WalletError::NetworkError("Device not connected".to_string())); } // 模拟命令响应 Ok(vec![0x90, 0x00]) // 成功响应 } fn get_device_info(&self) -> Result { if !self.connected { return Err(WalletError::NetworkError("Device not connected".to_string())); } Ok(HardwareDevice::new( self.device_id.clone(), HardwareWalletType::LedgerNanoX, "2.1.0".to_string(), "LEDGER123456".to_string() )) } } /// Trezor通信协议 pub struct TrezorProtocol { device_id: String, connected: bool, } impl TrezorProtocol { /// 创建新的Trezor协议实例 pub fn new(device_id: String) -> Self { TrezorProtocol { device_id, connected: false, } } /// Trezor消息编码 fn encode_message(&self, message_type: u16, data: &[u8]) -> Vec { let mut encoded = vec![0x23, 0x23]; // 魔术头 encoded.extend_from_slice(&message_type.to_be_bytes()); encoded.extend_from_slice(&(data.len() as u32).to_be_bytes()); encoded.extend_from_slice(data); encoded } } impl CommunicationProtocol for TrezorProtocol { fn connect(&mut self) -> Result<(), WalletError> { self.connected = true; Ok(()) } fn disconnect(&mut self) -> Result<(), WalletError> { self.connected = false; Ok(()) } fn send_command(&self, command: &[u8]) -> Result, WalletError> { if !self.connected { return Err(WalletError::NetworkError("Device not connected".to_string())); } // 模拟命令响应 Ok(vec![0x00, 0x01]) // 成功响应 } fn get_device_info(&self) -> Result { if !self.connected { return Err(WalletError::NetworkError("Device not connected".to_string())); } Ok(HardwareDevice::new( self.device_id.clone(), HardwareWalletType::TrezorModelT, "2.4.0".to_string(), "TREZOR789012".to_string() )) } } /// 硬件钱包操作 pub trait HardwareWalletOps { /// 获取公钥 fn get_public_key(&self, path: &str) -> Result, WalletError>; /// 签名交易 fn sign_transaction(&self, path: &str, transaction: &[u8]) -> Result, WalletError>; /// 签名消息 fn sign_message(&self, path: &str, message: &[u8]) -> Result, WalletError>; /// 验证地址 fn verify_address(&self, path: &str, address: &str) -> Result; } /// Ledger钱包操作 pub struct LedgerWallet { protocol: LedgerProtocol, device: Option, } impl LedgerWallet { /// 创建新的Ledger钱包 pub fn new(device_id: String) -> Self { LedgerWallet { protocol: LedgerProtocol::new(device_id), device: None, } } /// 连接设备 pub fn connect(&mut self) -> Result<(), WalletError> { self.protocol.connect()?; self.device = Some(self.protocol.get_device_info()?); Ok(()) } /// 断开设备 pub fn disconnect(&mut self) -> Result<(), WalletError> { self.protocol.disconnect()?; self.device = None; Ok(()) } /// 获取设备信息 pub fn device(&self) -> Option<&HardwareDevice> { self.device.as_ref() } } impl HardwareWalletOps for LedgerWallet { fn get_public_key(&self, path: &str) -> Result, WalletError> { if self.device.is_none() { return Err(WalletError::NetworkError("Device not connected".to_string())); } // 构造获取公钥命令 let command = vec![0x80, 0x02, 0x00, 0x00, path.len() as u8]; let _response = self.protocol.send_command(&command)?; // 模拟返回公钥 Ok(vec![0x04; 65]) // 未压缩公钥 } fn sign_transaction(&self, path: &str, transaction: &[u8]) -> Result, WalletError> { if self.device.is_none() { return Err(WalletError::NetworkError("Device not connected".to_string())); } // 构造签名命令 let mut command = vec![0x80, 0x04, 0x00, 0x00]; command.push((path.len() + transaction.len()) as u8); command.extend_from_slice(path.as_bytes()); command.extend_from_slice(transaction); let _response = self.protocol.send_command(&command)?; // 模拟返回签名 Ok(vec![0x30; 71]) // DER编码签名 } fn sign_message(&self, path: &str, message: &[u8]) -> Result, WalletError> { if self.device.is_none() { return Err(WalletError::NetworkError("Device not connected".to_string())); } // 构造签名消息命令 let mut command = vec![0x80, 0x08, 0x00, 0x00]; command.push((path.len() + message.len()) as u8); command.extend_from_slice(path.as_bytes()); command.extend_from_slice(message); let _response = self.protocol.send_command(&command)?; // 模拟返回签名 Ok(vec![0x30; 71]) } fn verify_address(&self, path: &str, address: &str) -> Result { if self.device.is_none() { return Err(WalletError::NetworkError("Device not connected".to_string())); } // 获取公钥并验证地址 let _public_key = self.get_public_key(path)?; // 模拟地址验证 Ok(address.starts_with("0x")) } } /// Trezor钱包操作 pub struct TrezorWallet { protocol: TrezorProtocol, device: Option, } impl TrezorWallet { /// 创建新的Trezor钱包 pub fn new(device_id: String) -> Self { TrezorWallet { protocol: TrezorProtocol::new(device_id), device: None, } } /// 连接设备 pub fn connect(&mut self) -> Result<(), WalletError> { self.protocol.connect()?; self.device = Some(self.protocol.get_device_info()?); Ok(()) } /// 断开设备 pub fn disconnect(&mut self) -> Result<(), WalletError> { self.protocol.disconnect()?; self.device = None; Ok(()) } /// 获取设备信息 pub fn device(&self) -> Option<&HardwareDevice> { self.device.as_ref() } } impl HardwareWalletOps for TrezorWallet { fn get_public_key(&self, path: &str) -> Result, WalletError> { if self.device.is_none() { return Err(WalletError::NetworkError("Device not connected".to_string())); } // 构造获取公钥消息 let message = self.protocol.encode_message(11, path.as_bytes()); let _response = self.protocol.send_command(&message)?; // 模拟返回公钥 Ok(vec![0x04; 65]) } fn sign_transaction(&self, path: &str, transaction: &[u8]) -> Result, WalletError> { if self.device.is_none() { return Err(WalletError::NetworkError("Device not connected".to_string())); } // 构造签名消息 let mut data = path.as_bytes().to_vec(); data.extend_from_slice(transaction); let message = self.protocol.encode_message(15, &data); let _response = self.protocol.send_command(&message)?; // 模拟返回签名 Ok(vec![0x30; 71]) } fn sign_message(&self, path: &str, message: &[u8]) -> Result, WalletError> { if self.device.is_none() { return Err(WalletError::NetworkError("Device not connected".to_string())); } // 构造签名消息 let mut data = path.as_bytes().to_vec(); data.extend_from_slice(message); let msg = self.protocol.encode_message(38, &data); let _response = self.protocol.send_command(&msg)?; // 模拟返回签名 Ok(vec![0x30; 71]) } fn verify_address(&self, path: &str, address: &str) -> Result { if self.device.is_none() { return Err(WalletError::NetworkError("Device not connected".to_string())); } // 获取公钥并验证地址 let _public_key = self.get_public_key(path)?; // 模拟地址验证 Ok(address.starts_with("0x")) } } /// 设备管理器 pub struct DeviceManager { /// 已连接的设备 devices: HashMap>, /// 设备信息 device_info: HashMap, } impl DeviceManager { /// 创建新的设备管理器 pub fn new() -> Self { DeviceManager { devices: HashMap::new(), device_info: HashMap::new(), } } /// 扫描设备 pub fn scan_devices(&mut self) -> Result, WalletError> { // 模拟扫描设备 let devices = vec![ HardwareDevice::new( "ledger_001".to_string(), HardwareWalletType::LedgerNanoX, "2.1.0".to_string(), "LEDGER123456".to_string() ), HardwareDevice::new( "trezor_001".to_string(), HardwareWalletType::TrezorModelT, "2.4.0".to_string(), "TREZOR789012".to_string() ), ]; for device in &devices { self.device_info.insert(device.id.clone(), device.clone()); } Ok(devices) } /// 连接Ledger设备 pub fn connect_ledger(&mut self, device_id: String) -> Result<(), WalletError> { let mut wallet = LedgerWallet::new(device_id.clone()); wallet.connect()?; if let Some(device) = wallet.device() { self.device_info.insert(device_id.clone(), device.clone()); } self.devices.insert(device_id, Box::new(wallet)); Ok(()) } /// 连接Trezor设备 pub fn connect_trezor(&mut self, device_id: String) -> Result<(), WalletError> { let mut wallet = TrezorWallet::new(device_id.clone()); wallet.connect()?; if let Some(device) = wallet.device() { self.device_info.insert(device_id.clone(), device.clone()); } self.devices.insert(device_id, Box::new(wallet)); Ok(()) } /// 断开设备 pub fn disconnect(&mut self, device_id: &str) -> Result<(), WalletError> { self.devices.remove(device_id); if let Some(device) = self.device_info.get_mut(device_id) { device.status = DeviceStatus::Disconnected; } Ok(()) } /// 获取设备信息 pub fn get_device(&self, device_id: &str) -> Option<&HardwareDevice> { self.device_info.get(device_id) } /// 获取所有设备 pub fn list_devices(&self) -> Vec<&HardwareDevice> { self.device_info.values().collect() } /// 检查设备是否已连接 pub fn is_connected(&self, device_id: &str) -> bool { self.devices.contains_key(device_id) } } impl Default for DeviceManager { fn default() -> Self { Self::new() } } #[cfg(test)] mod tests { use super::*; #[test] fn test_hardware_wallet_type() { let ledger = HardwareWalletType::LedgerNanoX; assert!(ledger.is_ledger()); assert!(!ledger.is_trezor()); let trezor = HardwareWalletType::TrezorModelT; assert!(trezor.is_trezor()); assert!(!trezor.is_ledger()); } #[test] fn test_hardware_device_creation() { let device = HardwareDevice::new( "test_001".to_string(), HardwareWalletType::LedgerNanoX, "2.1.0".to_string(), "SERIAL123".to_string() ); assert_eq!(device.id, "test_001"); assert_eq!(device.status, DeviceStatus::Disconnected); assert!(device.supports_coin("NAC")); } #[test] fn test_ledger_protocol() { let mut protocol = LedgerProtocol::new("test_001".to_string()); assert!(protocol.connect().is_ok()); assert!(protocol.disconnect().is_ok()); } #[test] fn test_trezor_protocol() { let mut protocol = TrezorProtocol::new("test_001".to_string()); assert!(protocol.connect().is_ok()); assert!(protocol.disconnect().is_ok()); } #[test] fn test_ledger_wallet() { let mut wallet = LedgerWallet::new("test_001".to_string()); assert!(wallet.connect().is_ok()); assert!(wallet.device().is_some()); assert!(wallet.disconnect().is_ok()); } #[test] fn test_trezor_wallet() { let mut wallet = TrezorWallet::new("test_001".to_string()); assert!(wallet.connect().is_ok()); assert!(wallet.device().is_some()); assert!(wallet.disconnect().is_ok()); } #[test] fn test_get_public_key() { let mut wallet = LedgerWallet::new("test_001".to_string()); wallet.connect().unwrap(); let pubkey = wallet.get_public_key("m/44'/60'/0'/0/0").unwrap(); assert_eq!(pubkey.len(), 65); } #[test] fn test_sign_transaction() { let mut wallet = LedgerWallet::new("test_001".to_string()); wallet.connect().unwrap(); let signature = wallet.sign_transaction("m/44'/60'/0'/0/0", &[1, 2, 3]).unwrap(); assert_eq!(signature.len(), 71); } #[test] fn test_sign_message() { let mut wallet = TrezorWallet::new("test_001".to_string()); wallet.connect().unwrap(); let signature = wallet.sign_message("m/44'/60'/0'/0/0", b"Hello").unwrap(); assert_eq!(signature.len(), 71); } #[test] fn test_verify_address() { let mut wallet = LedgerWallet::new("test_001".to_string()); wallet.connect().unwrap(); let valid = wallet.verify_address("m/44'/60'/0'/0/0", "0x1234567890").unwrap(); assert!(valid); } #[test] fn test_device_manager() { let mut manager = DeviceManager::new(); let devices = manager.scan_devices().unwrap(); assert_eq!(devices.len(), 2); } #[test] fn test_connect_ledger() { let mut manager = DeviceManager::new(); assert!(manager.connect_ledger("ledger_001".to_string()).is_ok()); assert!(manager.is_connected("ledger_001")); } #[test] fn test_connect_trezor() { let mut manager = DeviceManager::new(); assert!(manager.connect_trezor("trezor_001".to_string()).is_ok()); assert!(manager.is_connected("trezor_001")); } #[test] fn test_disconnect_device() { let mut manager = DeviceManager::new(); manager.connect_ledger("ledger_001".to_string()).unwrap(); assert!(manager.disconnect("ledger_001").is_ok()); assert!(!manager.is_connected("ledger_001")); } #[test] fn test_list_devices() { let mut manager = DeviceManager::new(); manager.scan_devices().unwrap(); let devices = manager.list_devices(); assert_eq!(devices.len(), 2); } }