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
79
80
81
82
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()),
}
}
fn is_interactive(&self) -> bool {
true
}
}
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)
}
}