Refactor SignerSource to expose DerivationPath to other kinds of signers (#16933)
* One use statement * Add stdin uri scheme * Convert parse_signer_source to return Result * A-Z deps * Convert Usb data to Locator * Pull DerivationPath out of Locator * Wrap SignerSource to share derivation_path * Review comments * Check Filepath existence, readability in parse_signer_source
This commit is contained in:
@ -1,8 +1,5 @@
|
||||
use {
|
||||
solana_sdk::{
|
||||
derivation_path::{DerivationPath, DerivationPathError},
|
||||
pubkey::{ParsePubkeyError, Pubkey},
|
||||
},
|
||||
solana_sdk::pubkey::{ParsePubkeyError, Pubkey},
|
||||
std::{
|
||||
convert::{Infallible, TryFrom, TryInto},
|
||||
str::FromStr,
|
||||
@ -77,8 +74,6 @@ pub enum LocatorError {
|
||||
#[error(transparent)]
|
||||
PubkeyError(#[from] ParsePubkeyError),
|
||||
#[error(transparent)]
|
||||
DerivationPathError(#[from] DerivationPathError),
|
||||
#[error(transparent)]
|
||||
UriReferenceError(#[from] URIReferenceError),
|
||||
#[error("unimplemented scheme")]
|
||||
UnimplementedScheme,
|
||||
@ -96,15 +91,12 @@ impl From<Infallible> for LocatorError {
|
||||
pub struct Locator {
|
||||
pub manufacturer: Manufacturer,
|
||||
pub pubkey: Option<Pubkey>,
|
||||
pub derivation_path: Option<DerivationPath>,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Locator {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let maybe_path = self.pubkey.map(|p| p.to_string());
|
||||
let path = maybe_path.as_deref().unwrap_or("/");
|
||||
let maybe_query = self.derivation_path.as_ref().map(|d| d.get_query());
|
||||
let maybe_query2 = maybe_query.as_ref().map(|q| &q[1..]);
|
||||
|
||||
let mut builder = URIReferenceBuilder::new();
|
||||
builder
|
||||
@ -113,8 +105,6 @@ impl std::fmt::Display for Locator {
|
||||
.try_authority(Some(self.manufacturer.as_ref()))
|
||||
.unwrap()
|
||||
.try_path(path)
|
||||
.unwrap()
|
||||
.try_query(maybe_query2)
|
||||
.unwrap();
|
||||
|
||||
let uri = builder.build().unwrap();
|
||||
@ -141,28 +131,7 @@ impl Locator {
|
||||
None
|
||||
}
|
||||
});
|
||||
let key = if let Some(query) = uri.query() {
|
||||
let query_str = query.as_str();
|
||||
let query = qstring::QString::from(query_str);
|
||||
if query.len() > 1 {
|
||||
return Err(DerivationPathError::InvalidDerivationPath(
|
||||
"invalid query string, extra fields not supported".to_string(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
let key = query.get("key");
|
||||
if key.is_none() {
|
||||
return Err(DerivationPathError::InvalidDerivationPath(format!(
|
||||
"invalid query string `{}`, only `key` supported",
|
||||
query_str,
|
||||
))
|
||||
.into());
|
||||
}
|
||||
key.map(|v| v.to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Self::new_from_parts(host.as_str(), path, key.as_deref())
|
||||
Self::new_from_parts(host.as_str(), path)
|
||||
}
|
||||
(Some(_scheme), Some(_host)) => Err(LocatorError::UnimplementedScheme),
|
||||
(None, Some(_host)) => Err(LocatorError::UnimplementedScheme),
|
||||
@ -170,18 +139,15 @@ impl Locator {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_parts<V, VE, P, PE, D, DE>(
|
||||
pub fn new_from_parts<V, VE, P, PE>(
|
||||
manufacturer: V,
|
||||
pubkey: Option<P>,
|
||||
derivation_path: Option<D>,
|
||||
) -> Result<Self, LocatorError>
|
||||
where
|
||||
VE: Into<LocatorError>,
|
||||
V: TryInto<Manufacturer, Error = VE>,
|
||||
PE: Into<LocatorError>,
|
||||
P: TryInto<Pubkey, Error = PE>,
|
||||
DE: Into<LocatorError>,
|
||||
D: TryInto<DerivationPath, Error = DE>,
|
||||
{
|
||||
let manufacturer = manufacturer.try_into().map_err(|e| e.into())?;
|
||||
let pubkey = if let Some(pubkey) = pubkey {
|
||||
@ -189,15 +155,9 @@ impl Locator {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let derivation_path = if let Some(derivation_path) = derivation_path {
|
||||
Some(derivation_path.try_into().map_err(|e| e.into())?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok(Self {
|
||||
manufacturer,
|
||||
pubkey,
|
||||
derivation_path,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -225,76 +185,50 @@ mod tests {
|
||||
let manufacturer_str = "ledger";
|
||||
let pubkey = Pubkey::new_unique();
|
||||
let pubkey_str = pubkey.to_string();
|
||||
let derivation_path = DerivationPath::new_bip44(Some(0), Some(0));
|
||||
let derivation_path_str = "0/0";
|
||||
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: None,
|
||||
derivation_path: None,
|
||||
};
|
||||
assert!(matches!(
|
||||
Locator::new_from_parts(manufacturer, None::<Pubkey>, None::<DerivationPath>),
|
||||
Locator::new_from_parts(manufacturer, None::<Pubkey>),
|
||||
Ok(e) if e == expect,
|
||||
));
|
||||
assert!(matches!(
|
||||
Locator::new_from_parts(manufacturer_str, None::<Pubkey>, None::<DerivationPath>),
|
||||
Locator::new_from_parts(manufacturer_str, None::<Pubkey>),
|
||||
Ok(e) if e == expect,
|
||||
));
|
||||
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: Some(pubkey),
|
||||
derivation_path: None,
|
||||
};
|
||||
assert!(matches!(
|
||||
Locator::new_from_parts(manufacturer, Some(pubkey), None::<DerivationPath>),
|
||||
Locator::new_from_parts(manufacturer, Some(pubkey)),
|
||||
Ok(e) if e == expect,
|
||||
));
|
||||
assert!(matches!(
|
||||
Locator::new_from_parts(manufacturer_str, Some(pubkey_str.as_str()), None::<DerivationPath>),
|
||||
Ok(e) if e == expect,
|
||||
));
|
||||
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: None,
|
||||
derivation_path: Some(derivation_path.clone()),
|
||||
};
|
||||
assert!(matches!(
|
||||
Locator::new_from_parts(manufacturer, None::<Pubkey>, Some(derivation_path)),
|
||||
Ok(e) if e == expect,
|
||||
));
|
||||
assert!(matches!(
|
||||
Locator::new_from_parts(manufacturer, None::<Pubkey>, Some(derivation_path_str)),
|
||||
Locator::new_from_parts(manufacturer_str, Some(pubkey_str.as_str())),
|
||||
Ok(e) if e == expect,
|
||||
));
|
||||
|
||||
assert!(matches!(
|
||||
Locator::new_from_parts("bad-manufacturer", None::<Pubkey>, None::<DerivationPath>),
|
||||
Locator::new_from_parts("bad-manufacturer", None::<Pubkey>),
|
||||
Err(LocatorError::ManufacturerError(e)) if e == ManufacturerError,
|
||||
));
|
||||
assert!(matches!(
|
||||
Locator::new_from_parts(manufacturer, Some("bad-pubkey"), None::<DerivationPath>),
|
||||
Locator::new_from_parts(manufacturer, Some("bad-pubkey")),
|
||||
Err(LocatorError::PubkeyError(e)) if e == ParsePubkeyError::Invalid,
|
||||
));
|
||||
let bad_path = "bad-derivation-path".to_string();
|
||||
assert!(matches!(
|
||||
Locator::new_from_parts(manufacturer, None::<Pubkey>, Some(bad_path.as_str())),
|
||||
Err(LocatorError::DerivationPathError(
|
||||
DerivationPathError::InvalidDerivationPath(_)
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_locator_new_from_uri() {
|
||||
let derivation_path = DerivationPath::new_bip44(Some(0), Some(0));
|
||||
let manufacturer = Manufacturer::Ledger;
|
||||
let pubkey = Pubkey::new_unique();
|
||||
let pubkey_str = pubkey.to_string();
|
||||
|
||||
// usb://ledger/{PUBKEY}?key=0'/0'
|
||||
// usb://ledger/{PUBKEY}?key=0/0
|
||||
let mut builder = URIReferenceBuilder::new();
|
||||
builder
|
||||
.try_scheme(Some("usb"))
|
||||
@ -309,7 +243,6 @@ mod tests {
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: Some(pubkey),
|
||||
derivation_path: Some(derivation_path.clone()),
|
||||
};
|
||||
assert_eq!(Locator::new_from_uri(&uri), Ok(expect));
|
||||
|
||||
@ -326,7 +259,6 @@ mod tests {
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: Some(pubkey),
|
||||
derivation_path: None,
|
||||
};
|
||||
assert_eq!(Locator::new_from_uri(&uri), Ok(expect));
|
||||
|
||||
@ -343,7 +275,6 @@ mod tests {
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: None,
|
||||
derivation_path: None,
|
||||
};
|
||||
assert_eq!(Locator::new_from_uri(&uri), Ok(expect));
|
||||
|
||||
@ -360,64 +291,6 @@ mod tests {
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: None,
|
||||
derivation_path: None,
|
||||
};
|
||||
assert_eq!(Locator::new_from_uri(&uri), Ok(expect));
|
||||
|
||||
// usb://ledger?key=0/0
|
||||
let mut builder = URIReferenceBuilder::new();
|
||||
builder
|
||||
.try_scheme(Some("usb"))
|
||||
.unwrap()
|
||||
.try_authority(Some(Manufacturer::Ledger.as_ref()))
|
||||
.unwrap()
|
||||
.try_path("")
|
||||
.unwrap()
|
||||
.try_query(Some("key=0/0"))
|
||||
.unwrap();
|
||||
let uri = builder.build().unwrap();
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: None,
|
||||
derivation_path: Some(derivation_path.clone()),
|
||||
};
|
||||
assert_eq!(Locator::new_from_uri(&uri), Ok(expect));
|
||||
|
||||
// usb://ledger?key=0'/0'
|
||||
let mut builder = URIReferenceBuilder::new();
|
||||
builder
|
||||
.try_scheme(Some("usb"))
|
||||
.unwrap()
|
||||
.try_authority(Some(Manufacturer::Ledger.as_ref()))
|
||||
.unwrap()
|
||||
.try_path("")
|
||||
.unwrap()
|
||||
.try_query(Some("key=0'/0'"))
|
||||
.unwrap();
|
||||
let uri = builder.build().unwrap();
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: None,
|
||||
derivation_path: Some(derivation_path.clone()),
|
||||
};
|
||||
assert_eq!(Locator::new_from_uri(&uri), Ok(expect));
|
||||
|
||||
// usb://ledger/?key=0/0
|
||||
let mut builder = URIReferenceBuilder::new();
|
||||
builder
|
||||
.try_scheme(Some("usb"))
|
||||
.unwrap()
|
||||
.try_authority(Some(Manufacturer::Ledger.as_ref()))
|
||||
.unwrap()
|
||||
.try_path("/")
|
||||
.unwrap()
|
||||
.try_query(Some("key=0/0"))
|
||||
.unwrap();
|
||||
let uri = builder.build().unwrap();
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: None,
|
||||
derivation_path: Some(derivation_path),
|
||||
};
|
||||
assert_eq!(Locator::new_from_uri(&uri), Ok(expect));
|
||||
|
||||
@ -465,79 +338,10 @@ mod tests {
|
||||
Locator::new_from_uri(&uri),
|
||||
Err(LocatorError::PubkeyError(ParsePubkeyError::Invalid))
|
||||
);
|
||||
|
||||
// usb://ledger?bad-key=0/0
|
||||
let mut builder = URIReferenceBuilder::new();
|
||||
builder
|
||||
.try_scheme(Some("usb"))
|
||||
.unwrap()
|
||||
.try_authority(Some(Manufacturer::Ledger.as_ref()))
|
||||
.unwrap()
|
||||
.try_path("")
|
||||
.unwrap()
|
||||
.try_query(Some("bad-key=0/0"))
|
||||
.unwrap();
|
||||
let uri = builder.build().unwrap();
|
||||
assert!(matches!(
|
||||
Locator::new_from_uri(&uri),
|
||||
Err(LocatorError::DerivationPathError(_))
|
||||
));
|
||||
|
||||
// usb://ledger?key=bad-value
|
||||
let mut builder = URIReferenceBuilder::new();
|
||||
builder
|
||||
.try_scheme(Some("usb"))
|
||||
.unwrap()
|
||||
.try_authority(Some(Manufacturer::Ledger.as_ref()))
|
||||
.unwrap()
|
||||
.try_path("")
|
||||
.unwrap()
|
||||
.try_query(Some("key=bad-value"))
|
||||
.unwrap();
|
||||
let uri = builder.build().unwrap();
|
||||
assert!(matches!(
|
||||
Locator::new_from_uri(&uri),
|
||||
Err(LocatorError::DerivationPathError(_))
|
||||
));
|
||||
|
||||
// usb://ledger?key=
|
||||
let mut builder = URIReferenceBuilder::new();
|
||||
builder
|
||||
.try_scheme(Some("usb"))
|
||||
.unwrap()
|
||||
.try_authority(Some(Manufacturer::Ledger.as_ref()))
|
||||
.unwrap()
|
||||
.try_path("")
|
||||
.unwrap()
|
||||
.try_query(Some("key="))
|
||||
.unwrap();
|
||||
let uri = builder.build().unwrap();
|
||||
assert!(matches!(
|
||||
Locator::new_from_uri(&uri),
|
||||
Err(LocatorError::DerivationPathError(_))
|
||||
));
|
||||
|
||||
// usb://ledger?key
|
||||
let mut builder = URIReferenceBuilder::new();
|
||||
builder
|
||||
.try_scheme(Some("usb"))
|
||||
.unwrap()
|
||||
.try_authority(Some(Manufacturer::Ledger.as_ref()))
|
||||
.unwrap()
|
||||
.try_path("")
|
||||
.unwrap()
|
||||
.try_query(Some("key"))
|
||||
.unwrap();
|
||||
let uri = builder.build().unwrap();
|
||||
assert!(matches!(
|
||||
Locator::new_from_uri(&uri),
|
||||
Err(LocatorError::DerivationPathError(_))
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_locator_new_from_path() {
|
||||
let derivation_path = DerivationPath::new_bip44(Some(0), Some(0));
|
||||
let manufacturer = Manufacturer::Ledger;
|
||||
let pubkey = Pubkey::new_unique();
|
||||
let path = format!("usb://ledger/{}?key=0/0", pubkey);
|
||||
@ -548,7 +352,6 @@ mod tests {
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: Some(pubkey),
|
||||
derivation_path: Some(derivation_path.clone()),
|
||||
};
|
||||
assert_eq!(Locator::new_from_path(path), Ok(expect));
|
||||
|
||||
@ -557,7 +360,6 @@ mod tests {
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: Some(pubkey),
|
||||
derivation_path: None,
|
||||
};
|
||||
assert_eq!(Locator::new_from_path(path), Ok(expect));
|
||||
|
||||
@ -566,7 +368,6 @@ mod tests {
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: None,
|
||||
derivation_path: None,
|
||||
};
|
||||
assert_eq!(Locator::new_from_path(path), Ok(expect));
|
||||
|
||||
@ -575,25 +376,6 @@ mod tests {
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: None,
|
||||
derivation_path: None,
|
||||
};
|
||||
assert_eq!(Locator::new_from_path(path), Ok(expect));
|
||||
|
||||
// usb://ledger?key=0'/0'
|
||||
let path = "usb://ledger?key=0'/0'";
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: None,
|
||||
derivation_path: Some(derivation_path.clone()),
|
||||
};
|
||||
assert_eq!(Locator::new_from_path(path), Ok(expect));
|
||||
|
||||
// usb://ledger/?key=0'/0'
|
||||
let path = "usb://ledger?key=0'/0'";
|
||||
let expect = Locator {
|
||||
manufacturer,
|
||||
pubkey: None,
|
||||
derivation_path: Some(derivation_path),
|
||||
};
|
||||
assert_eq!(Locator::new_from_path(path), Ok(expect));
|
||||
|
||||
@ -617,40 +399,5 @@ mod tests {
|
||||
Locator::new_from_path(path),
|
||||
Err(LocatorError::PubkeyError(ParsePubkeyError::Invalid))
|
||||
);
|
||||
|
||||
// usb://ledger?bad-key=0/0
|
||||
let path = "usb://ledger?bad-key=0/0";
|
||||
assert!(matches!(
|
||||
Locator::new_from_path(path),
|
||||
Err(LocatorError::DerivationPathError(_))
|
||||
));
|
||||
|
||||
// usb://ledger?bad-key=0'/0'
|
||||
let path = "usb://ledger?bad-key=0'/0'";
|
||||
assert!(matches!(
|
||||
Locator::new_from_path(path),
|
||||
Err(LocatorError::DerivationPathError(_))
|
||||
));
|
||||
|
||||
// usb://ledger?key=bad-value
|
||||
let path = format!("usb://ledger/{}?key=bad-value", pubkey);
|
||||
assert!(matches!(
|
||||
Locator::new_from_path(path),
|
||||
Err(LocatorError::DerivationPathError(_))
|
||||
));
|
||||
|
||||
// usb://ledger?key=
|
||||
let path = format!("usb://ledger/{}?key=", pubkey);
|
||||
assert!(matches!(
|
||||
Locator::new_from_path(path),
|
||||
Err(LocatorError::DerivationPathError(_))
|
||||
));
|
||||
|
||||
// usb://ledger?key
|
||||
let path = format!("usb://ledger/{}?key", pubkey);
|
||||
assert!(matches!(
|
||||
Locator::new_from_path(path),
|
||||
Err(LocatorError::DerivationPathError(_))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use {
|
||||
crate::{
|
||||
ledger::get_ledger_from_info,
|
||||
locator::Manufacturer,
|
||||
locator::{Locator, Manufacturer},
|
||||
remote_wallet::{
|
||||
RemoteWallet, RemoteWalletError, RemoteWalletInfo, RemoteWalletManager,
|
||||
RemoteWalletType,
|
||||
@ -56,12 +56,13 @@ impl Signer for RemoteKeypair {
|
||||
}
|
||||
|
||||
pub fn generate_remote_keypair(
|
||||
path: String,
|
||||
locator: Locator,
|
||||
derivation_path: DerivationPath,
|
||||
wallet_manager: &RemoteWalletManager,
|
||||
confirm_key: bool,
|
||||
keypair_name: &str,
|
||||
) -> Result<RemoteKeypair, RemoteWalletError> {
|
||||
let (remote_wallet_info, derivation_path) = RemoteWalletInfo::parse_path(path)?;
|
||||
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());
|
||||
|
@ -253,20 +253,12 @@ pub struct RemoteWalletInfo {
|
||||
}
|
||||
|
||||
impl RemoteWalletInfo {
|
||||
pub fn parse_path(path: String) -> Result<(Self, DerivationPath), RemoteWalletError> {
|
||||
let Locator {
|
||||
manufacturer,
|
||||
pubkey,
|
||||
derivation_path,
|
||||
} = Locator::new_from_path(path)?;
|
||||
Ok((
|
||||
RemoteWalletInfo {
|
||||
manufacturer,
|
||||
pubkey: pubkey.unwrap_or_default(),
|
||||
..RemoteWalletInfo::default()
|
||||
},
|
||||
derivation_path.unwrap_or_default(),
|
||||
))
|
||||
pub fn parse_locator(locator: Locator) -> Self {
|
||||
RemoteWalletInfo {
|
||||
manufacturer: locator.manufacturer,
|
||||
pubkey: locator.pubkey.unwrap_or_default(),
|
||||
..RemoteWalletInfo::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_pretty_path(&self) -> String {
|
||||
@ -308,10 +300,13 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_path() {
|
||||
fn test_parse_locator() {
|
||||
let pubkey = solana_sdk::pubkey::new_rand();
|
||||
let (wallet_info, derivation_path) =
|
||||
RemoteWalletInfo::parse_path(format!("usb://ledger/{:?}?key=1/2", pubkey)).unwrap();
|
||||
let locator = Locator {
|
||||
manufacturer: Manufacturer::Ledger,
|
||||
pubkey: Some(pubkey),
|
||||
};
|
||||
let wallet_info = RemoteWalletInfo::parse_locator(locator);
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
model: "nano-s".to_string(),
|
||||
manufacturer: Manufacturer::Ledger,
|
||||
@ -320,33 +315,13 @@ mod tests {
|
||||
pubkey,
|
||||
error: None,
|
||||
}));
|
||||
assert_eq!(derivation_path, DerivationPath::new_bip44(Some(1), Some(2)));
|
||||
let (wallet_info, derivation_path) =
|
||||
RemoteWalletInfo::parse_path(format!("usb://ledger/{:?}?key=1'/2'", pubkey)).unwrap();
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
model: "nano-s".to_string(),
|
||||
manufacturer: Manufacturer::Ledger,
|
||||
serial: "".to_string(),
|
||||
host_device_path: "/host/device/path".to_string(),
|
||||
pubkey,
|
||||
error: None,
|
||||
}));
|
||||
assert_eq!(derivation_path, DerivationPath::new_bip44(Some(1), Some(2)));
|
||||
let (wallet_info, derivation_path) =
|
||||
RemoteWalletInfo::parse_path(format!("usb://ledger/{:?}?key=1\'/2\'", pubkey)).unwrap();
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
model: "nano-s".to_string(),
|
||||
manufacturer: Manufacturer::Ledger,
|
||||
serial: "".to_string(),
|
||||
host_device_path: "/host/device/path".to_string(),
|
||||
pubkey,
|
||||
error: None,
|
||||
}));
|
||||
assert_eq!(derivation_path, DerivationPath::new_bip44(Some(1), Some(2)));
|
||||
|
||||
// Test that wallet id need not be complete for key derivation to work
|
||||
let (wallet_info, derivation_path) =
|
||||
RemoteWalletInfo::parse_path("usb://ledger?key=1".to_string()).unwrap();
|
||||
// Test that pubkey need not be populated
|
||||
let locator = Locator {
|
||||
manufacturer: Manufacturer::Ledger,
|
||||
pubkey: None,
|
||||
};
|
||||
let wallet_info = RemoteWalletInfo::parse_locator(locator);
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
model: "nano-s".to_string(),
|
||||
manufacturer: Manufacturer::Ledger,
|
||||
@ -355,33 +330,6 @@ mod tests {
|
||||
pubkey: Pubkey::default(),
|
||||
error: None,
|
||||
}));
|
||||
assert_eq!(derivation_path, DerivationPath::new_bip44(Some(1), None));
|
||||
let (wallet_info, derivation_path) =
|
||||
RemoteWalletInfo::parse_path("usb://ledger/?key=1/2".to_string()).unwrap();
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
model: "".to_string(),
|
||||
manufacturer: Manufacturer::Ledger,
|
||||
serial: "".to_string(),
|
||||
host_device_path: "/host/device/path".to_string(),
|
||||
pubkey: Pubkey::default(),
|
||||
error: None,
|
||||
}));
|
||||
assert_eq!(derivation_path, DerivationPath::new_bip44(Some(1), Some(2)));
|
||||
|
||||
// Failure cases
|
||||
assert!(
|
||||
RemoteWalletInfo::parse_path("usb://ledger/bad-pubkey?key=1/2".to_string()).is_err()
|
||||
);
|
||||
assert!(RemoteWalletInfo::parse_path("usb://?key=1/2".to_string()).is_err());
|
||||
assert!(RemoteWalletInfo::parse_path("usb:/ledger?key=1/2".to_string()).is_err());
|
||||
assert!(RemoteWalletInfo::parse_path("ledger?key=1/2".to_string()).is_err());
|
||||
assert!(RemoteWalletInfo::parse_path("usb://ledger?key=1/2/3".to_string()).is_err());
|
||||
// Other query strings cause an error
|
||||
assert!(
|
||||
RemoteWalletInfo::parse_path("usb://ledger/?key=1/2&test=other".to_string()).is_err()
|
||||
);
|
||||
assert!(RemoteWalletInfo::parse_path("usb://ledger/?Key=1/2".to_string()).is_err());
|
||||
assert!(RemoteWalletInfo::parse_path("usb://ledger/?test=other".to_string()).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Reference in New Issue
Block a user