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
use crate::{ ledger::get_ledger_from_info, remote_wallet::{ DerivationPath, RemoteWallet, RemoteWalletError, RemoteWalletInfo, RemoteWalletManager, RemoteWalletType, }, }; use solana_sdk::{ 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( path: String, wallet_manager: &RemoteWalletManager, confirm_key: bool, keypair_name: &str, ) -> Result<RemoteKeypair, RemoteWalletError> { let (remote_wallet_info, derivation_path) = RemoteWalletInfo::parse_path(path)?; if remote_wallet_info.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) } }