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:
@ -1,16 +1,16 @@
|
||||
use crate::keypair::{
|
||||
keypair_from_seed_phrase, keypair_util_from_path, ASK_KEYWORD, SKIP_SEED_PHRASE_VALIDATION_ARG,
|
||||
keypair_from_seed_phrase, signer_from_path, ASK_KEYWORD, SKIP_SEED_PHRASE_VALIDATION_ARG,
|
||||
};
|
||||
use chrono::DateTime;
|
||||
use clap::ArgMatches;
|
||||
use solana_remote_wallet::remote_wallet::DerivationPath;
|
||||
use solana_remote_wallet::remote_wallet::{DerivationPath, RemoteWalletManager};
|
||||
use solana_sdk::{
|
||||
clock::UnixTimestamp,
|
||||
native_token::sol_to_lamports,
|
||||
pubkey::Pubkey,
|
||||
signature::{read_keypair_file, Keypair, Signature, Signer},
|
||||
};
|
||||
use std::str::FromStr;
|
||||
use std::{str::FromStr, sync::Arc};
|
||||
|
||||
// Return parsed values from matches at `name`
|
||||
pub fn values_of<T>(matches: &ArgMatches<'_>, name: &str) -> Option<Vec<T>>
|
||||
@ -96,14 +96,18 @@ pub fn pubkeys_sigs_of(matches: &ArgMatches<'_>, name: &str) -> Option<Vec<(Pubk
|
||||
}
|
||||
|
||||
// Return a signer from matches at `name`
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn signer_of(
|
||||
name: &str,
|
||||
matches: &ArgMatches<'_>,
|
||||
) -> Result<Option<Box<dyn Signer>>, Box<dyn std::error::Error>> {
|
||||
name: &str,
|
||||
wallet_manager: Option<&Arc<RemoteWalletManager>>,
|
||||
) -> Result<(Option<Box<dyn Signer>>, Option<Pubkey>), Box<dyn std::error::Error>> {
|
||||
if let Some(location) = matches.value_of(name) {
|
||||
keypair_util_from_path(matches, location, name).map(Some)
|
||||
let signer = signer_from_path(matches, location, name, wallet_manager)?;
|
||||
let signer_pubkey = signer.pubkey();
|
||||
Ok((Some(signer), Some(signer_pubkey)))
|
||||
} else {
|
||||
Ok(None)
|
||||
Ok((None, None))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::keypair::{parse_keypair_path, KeypairUrl, ASK_KEYWORD};
|
||||
use chrono::DateTime;
|
||||
use solana_remote_wallet::remote_keypair::generate_remote_keypair;
|
||||
use solana_sdk::{
|
||||
hash::Hash,
|
||||
pubkey::Pubkey,
|
||||
@ -53,9 +52,6 @@ pub fn is_pubkey_or_keypair_or_ask_keyword(string: String) -> Result<(), String>
|
||||
|
||||
pub fn is_valid_signer(string: String) -> Result<(), String> {
|
||||
match parse_keypair_path(&string) {
|
||||
KeypairUrl::Usb(path) => generate_remote_keypair(path, None)
|
||||
.map(|_| ())
|
||||
.map_err(|err| format!("{:?}", err)),
|
||||
KeypairUrl::Filepath(path) => is_keypair(path),
|
||||
_ => Ok(()),
|
||||
}
|
||||
|
@ -6,7 +6,10 @@ use crate::{
|
||||
use bip39::{Language, Mnemonic, Seed};
|
||||
use clap::{values_t, ArgMatches, Error, ErrorKind};
|
||||
use rpassword::prompt_password_stderr;
|
||||
use solana_remote_wallet::remote_keypair::generate_remote_keypair;
|
||||
use solana_remote_wallet::{
|
||||
remote_keypair::generate_remote_keypair,
|
||||
remote_wallet::{RemoteWalletError, RemoteWalletManager},
|
||||
};
|
||||
use solana_sdk::{
|
||||
pubkey::Pubkey,
|
||||
signature::{
|
||||
@ -19,6 +22,7 @@ use std::{
|
||||
io::{stdin, stdout, Write},
|
||||
process::exit,
|
||||
str::FromStr,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
pub enum KeypairUrl {
|
||||
@ -56,10 +60,11 @@ pub fn presigner_from_pubkey_sigs(
|
||||
})
|
||||
}
|
||||
|
||||
pub fn keypair_util_from_path(
|
||||
pub fn signer_from_path(
|
||||
matches: &ArgMatches,
|
||||
path: &str,
|
||||
keypair_name: &str,
|
||||
wallet_manager: Option<&Arc<RemoteWalletManager>>,
|
||||
) -> Result<Box<dyn Signer>, Box<dyn error::Error>> {
|
||||
match parse_keypair_path(path) {
|
||||
KeypairUrl::Ask => {
|
||||
@ -75,10 +80,17 @@ pub fn keypair_util_from_path(
|
||||
let mut stdin = std::io::stdin();
|
||||
Ok(Box::new(read_keypair(&mut stdin)?))
|
||||
}
|
||||
KeypairUrl::Usb(path) => Ok(Box::new(generate_remote_keypair(
|
||||
path,
|
||||
derivation_of(matches, "derivation_path"),
|
||||
)?)),
|
||||
KeypairUrl::Usb(path) => {
|
||||
if let Some(wallet_manager) = wallet_manager {
|
||||
Ok(Box::new(generate_remote_keypair(
|
||||
path,
|
||||
derivation_of(matches, "derivation_path"),
|
||||
wallet_manager,
|
||||
)?))
|
||||
} else {
|
||||
Err(RemoteWalletError::NoDeviceFound.into())
|
||||
}
|
||||
}
|
||||
KeypairUrl::Pubkey(pubkey) => {
|
||||
let presigner = pubkeys_sigs_of(matches, SIGNER_ARG.name)
|
||||
.as_ref()
|
||||
|
Reference in New Issue
Block a user