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