2021-04-16 15:03:24 -07:00
|
|
|
use {
|
|
|
|
crate::{
|
|
|
|
ledger::get_ledger_from_info,
|
|
|
|
remote_wallet::{
|
2021-04-24 00:57:55 -07:00
|
|
|
Manufacturer, RemoteWallet, RemoteWalletError, RemoteWalletInfo, RemoteWalletManager,
|
2021-04-16 15:03:24 -07:00
|
|
|
RemoteWalletType,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
solana_sdk::{
|
|
|
|
derivation_path::DerivationPath,
|
|
|
|
pubkey::Pubkey,
|
|
|
|
signature::{Signature, Signer, SignerError},
|
2020-02-14 08:38:35 -08:00
|
|
|
},
|
2020-02-13 13:08:35 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
pub struct RemoteKeypair {
|
|
|
|
pub wallet_type: RemoteWalletType,
|
|
|
|
pub derivation_path: DerivationPath,
|
2020-02-24 16:03:30 -08:00
|
|
|
pub pubkey: Pubkey,
|
2020-03-14 20:48:41 -07:00
|
|
|
pub path: String,
|
2020-02-13 13:08:35 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl RemoteKeypair {
|
2020-02-24 16:03:30 -08:00
|
|
|
pub fn new(
|
|
|
|
wallet_type: RemoteWalletType,
|
|
|
|
derivation_path: DerivationPath,
|
2020-02-26 14:24:44 -08:00
|
|
|
confirm_key: bool,
|
2020-03-14 20:48:41 -07:00
|
|
|
path: String,
|
2020-02-24 16:03:30 -08:00
|
|
|
) -> Result<Self, RemoteWalletError> {
|
|
|
|
let pubkey = match &wallet_type {
|
2020-02-26 14:24:44 -08:00
|
|
|
RemoteWalletType::Ledger(wallet) => wallet.get_pubkey(&derivation_path, confirm_key)?,
|
2020-02-24 16:03:30 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
Ok(Self {
|
2020-02-13 13:08:35 -08:00
|
|
|
wallet_type,
|
|
|
|
derivation_path,
|
2020-02-24 16:03:30 -08:00
|
|
|
pubkey,
|
2020-03-14 20:48:41 -07:00
|
|
|
path,
|
2020-02-24 16:03:30 -08:00
|
|
|
})
|
2020-02-13 13:08:35 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-20 13:28:55 -08:00
|
|
|
impl Signer for RemoteKeypair {
|
2020-02-20 19:04:53 -08:00
|
|
|
fn try_pubkey(&self) -> Result<Pubkey, SignerError> {
|
2020-02-24 16:03:30 -08:00
|
|
|
Ok(self.pubkey)
|
2020-02-13 13:08:35 -08:00
|
|
|
}
|
|
|
|
|
2020-02-20 19:04:53 -08:00
|
|
|
fn try_sign_message(&self, message: &[u8]) -> Result<Signature, SignerError> {
|
2020-02-13 13:08:35 -08:00
|
|
|
match &self.wallet_type {
|
|
|
|
RemoteWalletType::Ledger(wallet) => wallet
|
|
|
|
.sign_message(&self.derivation_path, message)
|
|
|
|
.map_err(|e| e.into()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-14 08:38:35 -08:00
|
|
|
|
|
|
|
pub fn generate_remote_keypair(
|
|
|
|
path: String,
|
2020-02-24 16:03:30 -08:00
|
|
|
wallet_manager: &RemoteWalletManager,
|
2020-02-26 14:24:44 -08:00
|
|
|
confirm_key: bool,
|
2020-03-06 15:03:23 -08:00
|
|
|
keypair_name: &str,
|
2020-02-14 08:38:35 -08:00
|
|
|
) -> Result<RemoteKeypair, RemoteWalletError> {
|
2020-03-09 17:49:01 -07:00
|
|
|
let (remote_wallet_info, derivation_path) = RemoteWalletInfo::parse_path(path)?;
|
2021-04-24 00:57:55 -07:00
|
|
|
if remote_wallet_info.manufacturer == Manufacturer::Ledger {
|
2020-03-06 15:03:23 -08:00
|
|
|
let ledger = get_ledger_from_info(remote_wallet_info, keypair_name, wallet_manager)?;
|
2020-03-14 20:48:41 -07:00
|
|
|
let path = format!("{}{}", ledger.pretty_path, derivation_path.get_query());
|
2020-02-24 16:03:30 -08:00
|
|
|
Ok(RemoteKeypair::new(
|
|
|
|
RemoteWalletType::Ledger(ledger),
|
2020-02-14 08:38:35 -08:00
|
|
|
derivation_path,
|
2020-02-26 14:24:44 -08:00
|
|
|
confirm_key,
|
2020-03-14 20:48:41 -07:00
|
|
|
path,
|
2020-02-24 16:03:30 -08:00
|
|
|
)?)
|
2020-02-14 08:38:35 -08:00
|
|
|
} else {
|
|
|
|
Err(RemoteWalletError::DeviceTypeMismatch)
|
|
|
|
}
|
|
|
|
}
|