pub fn signer_from_path_with_config(
    matches: &ArgMatches,
    path: &str,
    keypair_name: &str,
    wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
    config: &SignerFromPathConfig,
) -> Result<Box<dyn Signer>, Box<dyn error::Error>> {
    let SignerSource {
        kind,
        derivation_path,
        legacy,
    } = parse_signer_source(path)?;
    match kind {
        SignerSourceKind::Prompt => {
            let skip_validation = matches.is_present(SKIP_SEED_PHRASE_VALIDATION_ARG.name);
            Ok(Box::new(keypair_from_seed_phrase(
                keypair_name,
                skip_validation,
                false,
                derivation_path,
                legacy,
            )?))
        }
        SignerSourceKind::Filepath(path) => match read_keypair_file(&path) {
            Err(e) => Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                format!("could not read keypair file \"{}\". Run \"solana-keygen new\" to create a keypair file: {}", path, e),
            )
            .into()),
            Ok(file) => Ok(Box::new(file)),
        },
        SignerSourceKind::Stdin => {
            let mut stdin = std::io::stdin();
            Ok(Box::new(read_keypair(&mut stdin)?))
        }
        SignerSourceKind::Usb(locator) => {
            if wallet_manager.is_none() {
                *wallet_manager = maybe_wallet_manager()?;
            }
            if let Some(wallet_manager) = wallet_manager {
                Ok(Box::new(generate_remote_keypair(
                    locator,
                    derivation_path.unwrap_or_default(),
                    wallet_manager,
                    matches.is_present("confirm_key"),
                    keypair_name,
                )?))
            } else {
                Err(RemoteWalletError::NoDeviceFound.into())
            }
        }
        SignerSourceKind::Pubkey(pubkey) => {
            let presigner = pubkeys_sigs_of(matches, SIGNER_ARG.name)
                .as_ref()
                .and_then(|presigners| presigner_from_pubkey_sigs(&pubkey, presigners));
            if let Some(presigner) = presigner {
                Ok(Box::new(presigner))
            } else if config.allow_null_signer || matches.is_present(SIGN_ONLY_ARG.name) {
                Ok(Box::new(NullSigner::new(&pubkey)))
            } else {
                Err(std::io::Error::new(
                    std::io::ErrorKind::Other,
                    format!("missing signature for supplied pubkey: {}", pubkey),
                )
                .into())
            }
        }
    }
}
/// Loads a [Signer] from one of several possible sources.
///
/// The `path` is not strictly a file system path, but is interpreted as various
/// types of _signing source_, depending on its format, one of which is a path
/// to a keypair file. Some sources may require user interaction in the course
/// of calling this function.
///
/// This is the same as [`signer_from_path`] except that it additionaolly
/// accepts a [`SignerFromPathConfig`] argument.
///
/// If the `allow_null_signer` field of `config` is `true`, then pubkey signers
/// are allowed to have zero associated signatures via additional "signer"
/// command line arguments. It the same effect as if the "sign_only" clap
/// argument is present.
///
/// See [`signer_from_path`] for full documentation of how this function
/// interprets its arguments.
///
/// # Examples
///
/// This shows a reasonable way to set up clap to parse all possible signer
/// sources. Note the use of the [`OfflineArgs::offline_args`] method to add
/// correct clap definitions of the `--signer` and `--sign-only` arguments, as
/// required by the base-58 pubkey offline signing method.
///
/// [`OfflineArgs::offline_args`]: crate::offline::OfflineArgs::offline_args
///
/// ```no_run
/// use clap::{App, Arg, value_t_or_exit};
/// use solana_clap_utils::keypair::{signer_from_path_with_config, SignerFromPathConfig};
/// use solana_clap_utils::offline::OfflineArgs;
///
/// let clap_app = App::new("my-program")
///     // The argument we'll parse as a signer "path"
///     .arg(Arg::with_name("keypair")
///         .required(true)
///         .help("The default signer"))
///     .offline_args();
///
/// let clap_matches = clap_app.get_matches();
/// let keypair_str = value_t_or_exit!(clap_matches, "keypair", String);
/// let mut wallet_manager = None;
///
/// // Allow pubkey signers without accompanying signatures
/// let config = SignerFromPathConfig {
///     allow_null_signer: true,
/// };
///
/// let signer = signer_from_path_with_config(
///     &clap_matches,
///     &keypair_str,
///     "keypair",
///     &mut wallet_manager,
///     &config,
/// )?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
Loads a [Signer] from one of several possible sources.
The `path` is not strictly a file system path, but is interpreted as various
types of _signing source_, depending on its format, one of which is a path
to a keypair file. Some sources may require user interaction in the course
of calling this function.

This is the same as [`signer_from_path`] except that it additionaolly
accepts a [`SignerFromPathConfig`] argument.



See [`signer_from_path`] for full documentation of how this function
interprets its arguments.
Loads a [ Signer ] from one of several possible sources . The ` path ` is not strictly a file system path but is interpreted as various types of _signing source_ depending on its format one of which is a path to a keypair file . Some sources may require user interaction in the course of calling this function . This is the same as [ ` signer_from_path ` ] except that it additionaolly accepts a [ ` SignerFromPathConfig ` ] argument . See [ ` signer_from_path ` ] for full documentation of how this function interprets its arguments .
pub fn signer_from_path_with_config(
    matches: &ArgMatches,
    path: &str,
    keypair_name: &str,
    wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
    config: &SignerFromPathConfig,
) -> Result<Box<dyn Signer>, Box<dyn error::Error>> {
    let SignerSource {
        kind,
        derivation_path,
        legacy,
    } = parse_signer_source(path)?;
    match kind {
        SignerSourceKind::Prompt => {
            let skip_validation = matches.is_present(SKIP_SEED_PHRASE_VALIDATION_ARG.name);
            Ok(Box::new(keypair_from_seed_phrase(
                keypair_name,
                skip_validation,
                false,
                derivation_path,
                legacy,
            )?))
        }
        SignerSourceKind::Filepath(path) => match read_keypair_file(&path) {
            Err(e) => Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                format!("could not read keypair file \"{}\". Run \"solana-keygen new\" to create a keypair file: {}", path, e),
            )
            .into()),
            Ok(file) => Ok(Box::new(file)),
        },
        SignerSourceKind::Stdin => {
            let mut stdin = std::io::stdin();
            Ok(Box::new(read_keypair(&mut stdin)?))
        }
        SignerSourceKind::Usb(locator) => {
            if wallet_manager.is_none() {
                *wallet_manager = maybe_wallet_manager()?;
            }
            if let Some(wallet_manager) = wallet_manager {
                Ok(Box::new(generate_remote_keypair(
                    locator,
                    derivation_path.unwrap_or_default(),
                    wallet_manager,
                    matches.is_present("confirm_key"),
                    keypair_name,
                )?))
            } else {
                Err(RemoteWalletError::NoDeviceFound.into())
            }
        }
        SignerSourceKind::Pubkey(pubkey) => {
            let presigner = pubkeys_sigs_of(matches, SIGNER_ARG.name)
                .as_ref()
                .and_then(|presigners| presigner_from_pubkey_sigs(&pubkey, presigners));
            if let Some(presigner) = presigner {
                Ok(Box::new(presigner))
            } else if config.allow_null_signer || matches.is_present(SIGN_ONLY_ARG.name) {
                Ok(Box::new(NullSigner::new(&pubkey)))
            } else {
                Err(std::io::Error::new(
                    std::io::ErrorKind::Other,
                    format!("missing signature for supplied pubkey: {}", pubkey),
                )
                .into())
            }
        }
    }
}
pub fn signer_from_path_with_config ( matches : & ArgMatches , path : & str , keypair_name : & str , wallet_manager : & mut Option < Arc < RemoteWalletManager > > , config : & SignerFromPathConfig , ) -> Result < Box < dyn Signer > , Box < dyn error :: Error > > { let SignerSource { kind , derivation_path , legacy , } = parse_signer_source ( path ) ? ; match kind { SignerSourceKind :: Prompt => { let skip_validation = matches . is_present ( SKIP_SEED_PHRASE_VALIDATION_ARG . name ) ; Ok ( Box :: new ( keypair_from_seed_phrase ( keypair_name , skip_validation , false , derivation_path , legacy , ) ? ) ) } SignerSourceKind :: Filepath ( path ) => match read_keypair_file ( & path ) { Err ( e ) => Err ( std :: io :: Error :: new ( std :: io :: ErrorKind :: Other , format ! ( " \" \" \" \" " path e ) , ) . into ( ) ) , Ok ( file ) => Ok ( Box :: new ( file ) ) , } , SignerSourceKind :: Stdin => { let mut stdin = std :: io :: stdin ( ) ; Ok ( Box :: new ( read_keypair ( & mut stdin ) ? ) ) } SignerSourceKind :: Usb ( locator ) => { if wallet_manager . is_none ( ) { * wallet_manager = maybe_wallet_manager ( ) ? ; } if let Some ( wallet_manager ) = wallet_manager { Ok ( Box :: new ( generate_remote_keypair ( locator , derivation_path . unwrap_or_default ( ) , wallet_manager , matches . is_present ( " " ) , keypair_name , ) ? ) ) } else { Err ( RemoteWalletError :: NoDeviceFound . into ( ) ) } } SignerSourceKind :: Pubkey ( pubkey ) => { let presigner = pubkeys_sigs_of ( matches , SIGNER_ARG . name ) . as_ref ( ) . and_then ( | presigners | presigner_from_pubkey_sigs ( & pubkey , presigners ) ) ; if let Some ( presigner ) = presigner { Ok ( Box :: new ( presigner ) ) } else if config . allow_null_signer || matches . is_present ( SIGN_ONLY_ARG . name ) { Ok ( Box :: new ( NullSigner :: new ( & pubkey ) ) ) } else { Err ( std :: io :: Error :: new ( std :: io :: ErrorKind :: Other , format ! ( " " pubkey ) , ) . into ( ) ) } } } }
Loads a [Signer] from one of several possible sources.
Loads a [ Signer ] from one of several possible sources .
matches
&ArgMatches
path
&str
keypair_name
&str
wallet_manager
&mut Option<Arc<RemoteWalletManager>>
config
&SignerFromPathConfig
examples
This shows a reasonable way to set up clap to parse all possible signer
sources. Note the use of the [`OfflineArgs::offline_args`] method to add
correct clap definitions of the `--signer` and `--sign-only` arguments, as
required by the base-58 pubkey offline signing method.

[`OfflineArgs::offline_args`]: crate::offline::OfflineArgs::offline_args

```no_run
use clap::{App, Arg, value_t_or_exit};
use solana_clap_utils::keypair::{signer_from_path_with_config, SignerFromPathConfig};
use solana_clap_utils::offline::OfflineArgs.

let clap_app = App::new("my-program")
The argument we'll parse as a signer "path"
.arg(Arg::with_name("keypair")
.required(true)
.help("The default signer"))
.offline_args().



Allow pubkey signers without accompanying signatures
let config = SignerFromPathConfig {
allow_null_signer: true,
}.

let signer = signer_from_path_with_config(
&clap_matches,
&keypair_str,
"keypair",
&mut wallet_manager,
&config,
)?.
This shows a reasonable way to set up clap to parse all possible signer sources . Note the use of the [ ` OfflineArgs :: offline_args ` ] method to add correct clap definitions of the ` -- signer ` and ` -- sign - only ` arguments as required by the base - 58 pubkey offline signing method . [ ` OfflineArgs :: offline_args ` ] : crate :: offline :: OfflineArgs :: offline_args ` ` ` no_run use clap :: { App Arg value_t_or_exit } ; use solana_clap_utils :: keypair :: { signer_from_path_with_config SignerFromPathConfig } ; use solana_clap_utils :: offline :: OfflineArgs . let clap_app = App :: new ( " my - program " ) The argument we ' ll parse as a signer " path " . arg ( Arg :: with_name ( " keypair " ) . required ( true ) . help ( " The default signer " )) . offline_args () . Allow pubkey signers without accompanying signatures let config = SignerFromPathConfig { allow_null_signer : true } . let signer = signer_from_path_with_config ( &clap_matches &keypair_str " keypair " &mut wallet_manager &config ) ? .
ok::<(), box<dyn std::error::error>>(())
None