Enable remote-wallet signing in solana-keygen (#8267)
* Add fallible methods to KeypairUtil * Add RemoteKeypair struct and impl KeypairUtil * Implement RemoteKeypair in keygen; also add parse_keypair_path for cleanup
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
use crate::remote_wallet::{
|
||||
initialize_wallet_manager, DerivationPath, RemoteWallet, RemoteWalletError, RemoteWalletInfo,
|
||||
use crate::{
|
||||
remote_keypair::RemoteKeypair,
|
||||
remote_wallet::{
|
||||
initialize_wallet_manager, DerivationPath, RemoteWallet, RemoteWalletError,
|
||||
RemoteWalletInfo, RemoteWalletType,
|
||||
},
|
||||
};
|
||||
use dialoguer::{theme::ColorfulTheme, Select};
|
||||
use log::*;
|
||||
@@ -365,3 +369,13 @@ pub fn get_ledger_from_info(
|
||||
};
|
||||
wallet_manager.get_ledger(&wallet_base_pubkey)
|
||||
}
|
||||
|
||||
pub fn generate_remote_keypair(
|
||||
ledger: Arc<LedgerWallet>,
|
||||
derivation_path: DerivationPath,
|
||||
) -> RemoteKeypair {
|
||||
RemoteKeypair {
|
||||
wallet_type: RemoteWalletType::Ledger(ledger),
|
||||
derivation_path,
|
||||
}
|
||||
}
|
||||
|
@@ -1,2 +1,3 @@
|
||||
pub mod ledger;
|
||||
pub mod remote_keypair;
|
||||
pub mod remote_wallet;
|
||||
|
38
remote-wallet/src/remote_keypair.rs
Normal file
38
remote-wallet/src/remote_keypair.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
use crate::remote_wallet::{DerivationPath, RemoteWallet, RemoteWalletType};
|
||||
use solana_sdk::{
|
||||
pubkey::Pubkey,
|
||||
signature::{KeypairUtil, Signature},
|
||||
};
|
||||
use std::error;
|
||||
|
||||
pub struct RemoteKeypair {
|
||||
pub wallet_type: RemoteWalletType,
|
||||
pub derivation_path: DerivationPath,
|
||||
}
|
||||
|
||||
impl RemoteKeypair {
|
||||
pub fn new(wallet_type: RemoteWalletType, derivation_path: DerivationPath) -> Self {
|
||||
Self {
|
||||
wallet_type,
|
||||
derivation_path,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl KeypairUtil for RemoteKeypair {
|
||||
fn try_pubkey(&self) -> Result<Pubkey, Box<dyn error::Error>> {
|
||||
match &self.wallet_type {
|
||||
RemoteWalletType::Ledger(wallet) => wallet
|
||||
.get_pubkey(&self.derivation_path)
|
||||
.map_err(|e| e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn try_sign_message(&self, message: &[u8]) -> Result<Signature, Box<dyn error::Error>> {
|
||||
match &self.wallet_type {
|
||||
RemoteWalletType::Ledger(wallet) => wallet
|
||||
.sign_message(&self.derivation_path, message)
|
||||
.map_err(|e| e.into()),
|
||||
}
|
||||
}
|
||||
}
|
@@ -192,7 +192,6 @@ pub struct RemoteWalletInfo {
|
||||
|
||||
impl RemoteWalletInfo {
|
||||
pub fn parse_path(mut path: String) -> Result<(Self, DerivationPath), RemoteWalletError> {
|
||||
let mut path = path.split_off(6);
|
||||
if path.ends_with('/') {
|
||||
path.pop();
|
||||
}
|
||||
@@ -288,7 +287,22 @@ mod tests {
|
||||
fn test_parse_path() {
|
||||
let pubkey = Pubkey::new_rand();
|
||||
let (wallet_info, derivation_path) =
|
||||
RemoteWalletInfo::parse_path(format!("usb://ledger/nano-s/{:?}/44/501/1/2", pubkey))
|
||||
RemoteWalletInfo::parse_path(format!("ledger/nano-s/{:?}/44/501/1/2", pubkey)).unwrap();
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
model: "nano-s".to_string(),
|
||||
manufacturer: "ledger".to_string(),
|
||||
serial: "".to_string(),
|
||||
pubkey,
|
||||
}));
|
||||
assert_eq!(
|
||||
derivation_path,
|
||||
DerivationPath {
|
||||
account: 1,
|
||||
change: Some(2),
|
||||
}
|
||||
);
|
||||
let (wallet_info, derivation_path) =
|
||||
RemoteWalletInfo::parse_path(format!("ledger/nano-s/{:?}/44'/501'/1'/2'", pubkey))
|
||||
.unwrap();
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
model: "nano-s".to_string(),
|
||||
@@ -303,35 +317,13 @@ mod tests {
|
||||
change: Some(2),
|
||||
}
|
||||
);
|
||||
let (wallet_info, derivation_path) = RemoteWalletInfo::parse_path(format!(
|
||||
"usb://ledger/nano-s/{:?}/44'/501'/1'/2'",
|
||||
pubkey
|
||||
))
|
||||
.unwrap();
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
model: "nano-s".to_string(),
|
||||
manufacturer: "ledger".to_string(),
|
||||
serial: "".to_string(),
|
||||
pubkey,
|
||||
}));
|
||||
assert_eq!(
|
||||
derivation_path,
|
||||
DerivationPath {
|
||||
account: 1,
|
||||
change: Some(2),
|
||||
}
|
||||
);
|
||||
|
||||
assert!(RemoteWalletInfo::parse_path(format!(
|
||||
"usb://ledger/nano-s/{:?}/43/501/1/2",
|
||||
pubkey
|
||||
))
|
||||
.is_err());
|
||||
assert!(RemoteWalletInfo::parse_path(format!(
|
||||
"usb://ledger/nano-s/{:?}/44/500/1/2",
|
||||
pubkey
|
||||
))
|
||||
.is_err());
|
||||
assert!(
|
||||
RemoteWalletInfo::parse_path(format!("ledger/nano-s/{:?}/43/501/1/2", pubkey)).is_err()
|
||||
);
|
||||
assert!(
|
||||
RemoteWalletInfo::parse_path(format!("ledger/nano-s/{:?}/44/500/1/2", pubkey)).is_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Reference in New Issue
Block a user