CLI: collect and deduplicate signers (#8398)

* Rename (keypair util is not a thing)

* Add method to generate_unique_signers

* Cli: refactor signer handling and remote-wallet init

* Fixup unit tests

* Fixup intergation tests

* Update keypair path print statement

* Remove &None

* Use deterministic key in test

* Retain storage-account as index

* Make signer index-handling less brittle

* Cache pubkey on RemoteKeypair::new

* Make signer_of consistent + return pubkey

* Remove &matches double references

* Nonce authorities need special handling
This commit is contained in:
Tyera Eulberg
2020-02-24 17:03:30 -07:00
committed by GitHub
parent 89baa94002
commit 12a9b5f35e
22 changed files with 2095 additions and 1635 deletions

View File

@@ -1,7 +1,8 @@
use crate::{
ledger::get_ledger_from_info,
remote_wallet::{
DerivationPath, RemoteWallet, RemoteWalletError, RemoteWalletInfo, RemoteWalletType,
DerivationPath, RemoteWallet, RemoteWalletError, RemoteWalletInfo, RemoteWalletManager,
RemoteWalletType,
},
};
use solana_sdk::{
@@ -12,24 +13,29 @@ use solana_sdk::{
pub struct RemoteKeypair {
pub wallet_type: RemoteWalletType,
pub derivation_path: DerivationPath,
pub pubkey: Pubkey,
}
impl RemoteKeypair {
pub fn new(wallet_type: RemoteWalletType, derivation_path: DerivationPath) -> Self {
Self {
pub fn new(
wallet_type: RemoteWalletType,
derivation_path: DerivationPath,
) -> Result<Self, RemoteWalletError> {
let pubkey = match &wallet_type {
RemoteWalletType::Ledger(wallet) => wallet.get_pubkey(&derivation_path)?,
};
Ok(Self {
wallet_type,
derivation_path,
}
pubkey,
})
}
}
impl Signer for RemoteKeypair {
fn try_pubkey(&self) -> Result<Pubkey, SignerError> {
match &self.wallet_type {
RemoteWalletType::Ledger(wallet) => wallet
.get_pubkey(&self.derivation_path)
.map_err(|e| e.into()),
}
Ok(self.pubkey)
}
fn try_sign_message(&self, message: &[u8]) -> Result<Signature, SignerError> {
@@ -44,17 +50,18 @@ impl Signer for RemoteKeypair {
pub fn generate_remote_keypair(
path: String,
explicit_derivation_path: Option<DerivationPath>,
wallet_manager: &RemoteWalletManager,
) -> Result<RemoteKeypair, RemoteWalletError> {
let (remote_wallet_info, mut derivation_path) = RemoteWalletInfo::parse_path(path)?;
if let Some(derivation) = explicit_derivation_path {
derivation_path = derivation;
}
if remote_wallet_info.manufacturer == "ledger" {
let ledger = get_ledger_from_info(remote_wallet_info)?;
Ok(RemoteKeypair {
wallet_type: RemoteWalletType::Ledger(ledger),
let ledger = get_ledger_from_info(remote_wallet_info, wallet_manager)?;
Ok(RemoteKeypair::new(
RemoteWalletType::Ledger(ledger),
derivation_path,
})
)?)
} else {
Err(RemoteWalletError::DeviceTypeMismatch)
}