remote-wallet: Select hardware wallets based on host device path
This commit is contained in:
committed by
Trent Nelson
parent
2c38865e70
commit
8e3353d9ef
@ -339,6 +339,7 @@ impl RemoteWallet for LedgerWallet {
|
|||||||
.clone()
|
.clone()
|
||||||
.unwrap_or("Unknown")
|
.unwrap_or("Unknown")
|
||||||
.to_string();
|
.to_string();
|
||||||
|
let host_device_path = dev_info.path().to_string_lossy().to_string();
|
||||||
let version = self.get_firmware_version()?;
|
let version = self.get_firmware_version()?;
|
||||||
self.version = version;
|
self.version = version;
|
||||||
let pubkey_result = self.get_pubkey(&DerivationPath::default(), false);
|
let pubkey_result = self.get_pubkey(&DerivationPath::default(), false);
|
||||||
@ -350,6 +351,7 @@ impl RemoteWallet for LedgerWallet {
|
|||||||
model,
|
model,
|
||||||
manufacturer,
|
manufacturer,
|
||||||
serial,
|
serial,
|
||||||
|
host_device_path,
|
||||||
pubkey,
|
pubkey,
|
||||||
error,
|
error,
|
||||||
})
|
})
|
||||||
@ -521,17 +523,17 @@ pub fn get_ledger_from_info(
|
|||||||
return Err(device.error.clone().unwrap());
|
return Err(device.error.clone().unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut matches: Vec<(Pubkey, String)> = matches
|
let mut matches: Vec<(String, String)> = matches
|
||||||
.filter(|&device_info| device_info.error.is_none())
|
.filter(|&device_info| device_info.error.is_none())
|
||||||
.map(|device_info| (device_info.pubkey, device_info.get_pretty_path()))
|
.map(|device_info| (device_info.host_device_path.clone(), device_info.get_pretty_path()))
|
||||||
.collect();
|
.collect();
|
||||||
if matches.is_empty() {
|
if matches.is_empty() {
|
||||||
return Err(RemoteWalletError::NoDeviceFound);
|
return Err(RemoteWalletError::NoDeviceFound);
|
||||||
}
|
}
|
||||||
matches.sort_by(|a, b| a.1.cmp(&b.1));
|
matches.sort_by(|a, b| a.1.cmp(&b.1));
|
||||||
let (pubkeys, device_paths): (Vec<Pubkey>, Vec<String>) = matches.into_iter().unzip();
|
let (host_device_paths, device_paths): (Vec<Pubkey>, Vec<String>) = matches.into_iter().unzip();
|
||||||
|
|
||||||
let wallet_base_pubkey = if pubkeys.len() > 1 {
|
let wallet_host_device_path = if host_device_paths.len() > 1 {
|
||||||
let selection = Select::with_theme(&ColorfulTheme::default())
|
let selection = Select::with_theme(&ColorfulTheme::default())
|
||||||
.with_prompt(&format!(
|
.with_prompt(&format!(
|
||||||
"Multiple hardware wallets found. Please select a device for {:?}",
|
"Multiple hardware wallets found. Please select a device for {:?}",
|
||||||
@ -541,11 +543,11 @@ pub fn get_ledger_from_info(
|
|||||||
.items(&device_paths[..])
|
.items(&device_paths[..])
|
||||||
.interact()
|
.interact()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
pubkeys[selection]
|
&host_device_paths[selection]
|
||||||
} else {
|
} else {
|
||||||
pubkeys[0]
|
&host_device_paths[0]
|
||||||
};
|
};
|
||||||
wallet_manager.get_ledger(&wallet_base_pubkey)
|
wallet_manager.get_ledger(wallet_host_device_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -152,11 +152,14 @@ impl RemoteWalletManager {
|
|||||||
|
|
||||||
/// Get a particular wallet
|
/// Get a particular wallet
|
||||||
#[allow(unreachable_patterns)]
|
#[allow(unreachable_patterns)]
|
||||||
pub fn get_ledger(&self, pubkey: &Pubkey) -> Result<Arc<LedgerWallet>, RemoteWalletError> {
|
pub fn get_ledger(
|
||||||
|
&self,
|
||||||
|
host_device_path: &str,
|
||||||
|
) -> Result<Arc<LedgerWallet>, RemoteWalletError> {
|
||||||
self.devices
|
self.devices
|
||||||
.read()
|
.read()
|
||||||
.iter()
|
.iter()
|
||||||
.find(|device| &device.info.pubkey == pubkey)
|
.find(|device| device.info.host_device_path == host_device_path)
|
||||||
.ok_or(RemoteWalletError::PubkeyNotFound)
|
.ok_or(RemoteWalletError::PubkeyNotFound)
|
||||||
.and_then(|device| match &device.wallet_type {
|
.and_then(|device| match &device.wallet_type {
|
||||||
RemoteWalletType::Ledger(ledger) => Ok(ledger.clone()),
|
RemoteWalletType::Ledger(ledger) => Ok(ledger.clone()),
|
||||||
@ -237,6 +240,8 @@ pub struct RemoteWalletInfo {
|
|||||||
pub manufacturer: String,
|
pub manufacturer: String,
|
||||||
/// RemoteWallet device serial number
|
/// RemoteWallet device serial number
|
||||||
pub serial: String,
|
pub serial: String,
|
||||||
|
/// RemoteWallet host device path
|
||||||
|
pub host_device_path: String,
|
||||||
/// Base pubkey of device at Solana derivation path
|
/// Base pubkey of device at Solana derivation path
|
||||||
pub pubkey: Pubkey,
|
pub pubkey: Pubkey,
|
||||||
/// Initial read error
|
/// Initial read error
|
||||||
@ -449,6 +454,7 @@ mod tests {
|
|||||||
model: "nano-s".to_string(),
|
model: "nano-s".to_string(),
|
||||||
manufacturer: "ledger".to_string(),
|
manufacturer: "ledger".to_string(),
|
||||||
serial: "".to_string(),
|
serial: "".to_string(),
|
||||||
|
host_device_path: "/host/device/path".to_string(),
|
||||||
pubkey,
|
pubkey,
|
||||||
error: None,
|
error: None,
|
||||||
}));
|
}));
|
||||||
@ -465,6 +471,7 @@ mod tests {
|
|||||||
model: "nano-s".to_string(),
|
model: "nano-s".to_string(),
|
||||||
manufacturer: "ledger".to_string(),
|
manufacturer: "ledger".to_string(),
|
||||||
serial: "".to_string(),
|
serial: "".to_string(),
|
||||||
|
host_device_path: "/host/device/path".to_string(),
|
||||||
pubkey,
|
pubkey,
|
||||||
error: None,
|
error: None,
|
||||||
}));
|
}));
|
||||||
@ -481,6 +488,7 @@ mod tests {
|
|||||||
model: "nano-s".to_string(),
|
model: "nano-s".to_string(),
|
||||||
manufacturer: "ledger".to_string(),
|
manufacturer: "ledger".to_string(),
|
||||||
serial: "".to_string(),
|
serial: "".to_string(),
|
||||||
|
host_device_path: "/host/device/path".to_string(),
|
||||||
pubkey,
|
pubkey,
|
||||||
error: None,
|
error: None,
|
||||||
}));
|
}));
|
||||||
@ -497,6 +505,7 @@ mod tests {
|
|||||||
model: "nano-s".to_string(),
|
model: "nano-s".to_string(),
|
||||||
manufacturer: "ledger".to_string(),
|
manufacturer: "ledger".to_string(),
|
||||||
serial: "".to_string(),
|
serial: "".to_string(),
|
||||||
|
host_device_path: "/host/device/path".to_string(),
|
||||||
pubkey,
|
pubkey,
|
||||||
error: None,
|
error: None,
|
||||||
}));
|
}));
|
||||||
@ -513,6 +522,7 @@ mod tests {
|
|||||||
model: "nano-s".to_string(),
|
model: "nano-s".to_string(),
|
||||||
manufacturer: "ledger".to_string(),
|
manufacturer: "ledger".to_string(),
|
||||||
serial: "".to_string(),
|
serial: "".to_string(),
|
||||||
|
host_device_path: "/host/device/path".to_string(),
|
||||||
pubkey,
|
pubkey,
|
||||||
error: None,
|
error: None,
|
||||||
}));
|
}));
|
||||||
@ -531,6 +541,7 @@ mod tests {
|
|||||||
model: "nano-s".to_string(),
|
model: "nano-s".to_string(),
|
||||||
manufacturer: "ledger".to_string(),
|
manufacturer: "ledger".to_string(),
|
||||||
serial: "".to_string(),
|
serial: "".to_string(),
|
||||||
|
host_device_path: "/host/device/path".to_string(),
|
||||||
pubkey: Pubkey::default(),
|
pubkey: Pubkey::default(),
|
||||||
error: None,
|
error: None,
|
||||||
}));
|
}));
|
||||||
@ -547,6 +558,7 @@ mod tests {
|
|||||||
model: "".to_string(),
|
model: "".to_string(),
|
||||||
manufacturer: "ledger".to_string(),
|
manufacturer: "ledger".to_string(),
|
||||||
serial: "".to_string(),
|
serial: "".to_string(),
|
||||||
|
host_device_path: "/host/device/path".to_string(),
|
||||||
pubkey: Pubkey::default(),
|
pubkey: Pubkey::default(),
|
||||||
error: None,
|
error: None,
|
||||||
}));
|
}));
|
||||||
@ -581,6 +593,7 @@ mod tests {
|
|||||||
manufacturer: "Ledger".to_string(),
|
manufacturer: "Ledger".to_string(),
|
||||||
model: "Nano S".to_string(),
|
model: "Nano S".to_string(),
|
||||||
serial: "0001".to_string(),
|
serial: "0001".to_string(),
|
||||||
|
host_device_path: "/host/device/path".to_string(),
|
||||||
pubkey,
|
pubkey,
|
||||||
error: None,
|
error: None,
|
||||||
};
|
};
|
||||||
@ -593,6 +606,8 @@ mod tests {
|
|||||||
assert!(info.matches(&test_info));
|
assert!(info.matches(&test_info));
|
||||||
test_info.model = "Nano S".to_string();
|
test_info.model = "Nano S".to_string();
|
||||||
assert!(info.matches(&test_info));
|
assert!(info.matches(&test_info));
|
||||||
|
test_info.host_device_path = "/host/device/path".to_string();
|
||||||
|
assert!(info.matches(&test_info));
|
||||||
let another_pubkey = Pubkey::new_rand();
|
let another_pubkey = Pubkey::new_rand();
|
||||||
test_info.pubkey = another_pubkey;
|
test_info.pubkey = another_pubkey;
|
||||||
assert!(!info.matches(&test_info));
|
assert!(!info.matches(&test_info));
|
||||||
@ -608,6 +623,7 @@ mod tests {
|
|||||||
model: "nano-s".to_string(),
|
model: "nano-s".to_string(),
|
||||||
manufacturer: "ledger".to_string(),
|
manufacturer: "ledger".to_string(),
|
||||||
serial: "".to_string(),
|
serial: "".to_string(),
|
||||||
|
host_device_path: "/host/device/path".to_string(),
|
||||||
pubkey,
|
pubkey,
|
||||||
error: None,
|
error: None,
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user