Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

CLI: collect and deduplicate signers (bp #8398) #8423

Merged
merged 1 commit into from
Feb 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions clap-utils/src/input_parsers.rs
Original file line number Diff line number Diff line change
@@ -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>>
Expand Down Expand Up @@ -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))
}
}

Expand Down
4 changes: 0 additions & 4 deletions clap-utils/src/input_validators.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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(()),
}
Expand Down
24 changes: 18 additions & 6 deletions clap-utils/src/keypair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand All @@ -19,6 +22,7 @@ use std::{
io::{stdin, stdout, Write},
process::exit,
str::FromStr,
sync::Arc,
};

pub enum KeypairUrl {
Expand Down Expand Up @@ -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 => {
Expand All @@ -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()
Expand Down
Loading