Cli: Add resolve-signer subcommand (#8859)
* Expose remote-wallet device pretty path * Add resolve-signer helpers * Add cli resolve-signer subcommand * Print pretty-path in waiting msg
This commit is contained in:
@ -55,6 +55,7 @@ mod commands {
|
||||
/// Ledger Wallet device
|
||||
pub struct LedgerWallet {
|
||||
pub device: hidapi::HidDevice,
|
||||
pub pretty_path: String,
|
||||
}
|
||||
|
||||
impl fmt::Debug for LedgerWallet {
|
||||
@ -65,7 +66,10 @@ impl fmt::Debug for LedgerWallet {
|
||||
|
||||
impl LedgerWallet {
|
||||
pub fn new(device: hidapi::HidDevice) -> Self {
|
||||
Self { device }
|
||||
Self {
|
||||
device,
|
||||
pretty_path: String::default(),
|
||||
}
|
||||
}
|
||||
|
||||
// Transport Protocol:
|
||||
@ -231,7 +235,10 @@ impl LedgerWallet {
|
||||
) -> Result<Vec<u8>, RemoteWalletError> {
|
||||
self.write(command, p1, p2, data)?;
|
||||
if p1 == P1_CONFIRM && is_last_part(p2) {
|
||||
println!("Waiting for remote wallet to approve...");
|
||||
println!(
|
||||
"Waiting for approval from remote wallet {}",
|
||||
self.pretty_path
|
||||
);
|
||||
let result = self.read()?;
|
||||
println!("{}Approved", CHECK_MARK);
|
||||
Ok(result)
|
||||
|
@ -14,6 +14,7 @@ pub struct RemoteKeypair {
|
||||
pub wallet_type: RemoteWalletType,
|
||||
pub derivation_path: DerivationPath,
|
||||
pub pubkey: Pubkey,
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
impl RemoteKeypair {
|
||||
@ -21,6 +22,7 @@ impl RemoteKeypair {
|
||||
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)?,
|
||||
@ -30,6 +32,7 @@ impl RemoteKeypair {
|
||||
wallet_type,
|
||||
derivation_path,
|
||||
pubkey,
|
||||
path,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -57,10 +60,12 @@ pub fn generate_remote_keypair(
|
||||
let (remote_wallet_info, derivation_path) = RemoteWalletInfo::parse_path(path)?;
|
||||
if remote_wallet_info.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)
|
||||
|
@ -105,8 +105,9 @@ impl RemoteWalletManager {
|
||||
if is_valid_ledger(device_info.vendor_id(), device_info.product_id()) {
|
||||
match usb.open_path(&device_info.path()) {
|
||||
Ok(device) => {
|
||||
let ledger = LedgerWallet::new(device);
|
||||
let mut ledger = LedgerWallet::new(device);
|
||||
if let Ok(info) = ledger.read_device(&device_info) {
|
||||
ledger.pretty_path = info.get_pretty_path();
|
||||
let path = device_info.path().to_str().unwrap().to_string();
|
||||
trace!("Found device: {:?}", info);
|
||||
v.push(Device {
|
||||
@ -328,6 +329,20 @@ impl fmt::Debug for DerivationPath {
|
||||
}
|
||||
}
|
||||
|
||||
impl DerivationPath {
|
||||
pub fn get_query(&self) -> String {
|
||||
if let Some(account) = self.account {
|
||||
if let Some(change) = self.change {
|
||||
format!("?key={}/{}", account, change)
|
||||
} else {
|
||||
format!("?key={}", account)
|
||||
}
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper to determine if a device is a valid HID
|
||||
pub fn is_valid_hid_device(usage_page: u16, interface_number: i32) -> bool {
|
||||
usage_page == HID_GLOBAL_USAGE_PAGE || interface_number == HID_USB_DEVICE_CLASS as i32
|
||||
@ -519,4 +534,40 @@ mod tests {
|
||||
test_info.pubkey = pubkey;
|
||||
assert!(info.matches(&test_info));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_pretty_path() {
|
||||
let pubkey = Pubkey::new_rand();
|
||||
let pubkey_str = pubkey.to_string();
|
||||
let remote_wallet_info = RemoteWalletInfo {
|
||||
model: "nano-s".to_string(),
|
||||
manufacturer: "ledger".to_string(),
|
||||
serial: "".to_string(),
|
||||
pubkey,
|
||||
error: None,
|
||||
};
|
||||
assert_eq!(
|
||||
remote_wallet_info.get_pretty_path(),
|
||||
format!("usb://ledger/nano-s/{}", pubkey_str)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_query() {
|
||||
let derivation_path = DerivationPath {
|
||||
account: None,
|
||||
change: None,
|
||||
};
|
||||
assert_eq!(derivation_path.get_query(), "".to_string());
|
||||
let derivation_path = DerivationPath {
|
||||
account: Some(1),
|
||||
change: None,
|
||||
};
|
||||
assert_eq!(derivation_path.get_query(), "?key=1".to_string());
|
||||
let derivation_path = DerivationPath {
|
||||
account: Some(1),
|
||||
change: Some(2),
|
||||
};
|
||||
assert_eq!(derivation_path.get_query(), "?key=1/2".to_string());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user