1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
use { crate::{ ledger::get_ledger_from_info, locator::{Locator, Manufacturer}, remote_wallet::{ RemoteWallet, RemoteWalletError, RemoteWalletInfo, RemoteWalletManager, RemoteWalletType, }, }, solana_sdk::{ derivation_path::DerivationPath, pubkey::Pubkey, signature::{Signature, Signer, SignerError}, }, }; pub struct RemoteKeypair { pub wallet_type: RemoteWalletType, pub derivation_path: DerivationPath, pub pubkey: Pubkey, pub path: String, } impl RemoteKeypair { pub fn new( wallet_type: RemoteWalletType, derivation_path: DerivationPath, confirm_key: bool, path: String, ) -> Result<Self, RemoteWalletError> { let pubkey = match &wallet_type { RemoteWalletType::Ledger(wallet) => wallet.get_pubkey(&derivation_path, confirm_key)?, }; Ok(Self { wallet_type, derivation_path, pubkey, path, }) } } impl Signer for RemoteKeypair { fn try_pubkey(&self) -> Result<Pubkey, SignerError> { Ok(self.pubkey) } fn try_sign_message(&self, message: &[u8]) -> Result<Signature, SignerError> { match &self.wallet_type { RemoteWalletType::Ledger(wallet) => wallet .sign_message(&self.derivation_path, message) .map_err(|e| e.into()), } } } pub fn generate_remote_keypair( locator: Locator, derivation_path: DerivationPath, wallet_manager: &RemoteWalletManager, confirm_key: bool, keypair_name: &str, ) -> Result<RemoteKeypair, RemoteWalletError> { let remote_wallet_info = RemoteWalletInfo::parse_locator(locator); if remote_wallet_info.manufacturer == Manufacturer::Ledger { let ledger = get_ledger_from_info(remote_wallet_info, keypair_name, wallet_manager)?; let path = format!("{}{}", ledger.pretty_path, derivation_path.get_query()); Ok(RemoteKeypair::new( RemoteWalletType::Ledger(ledger), derivation_path, confirm_key, path, )?) } else { Err(RemoteWalletError::DeviceTypeMismatch) } }