| 
									
										
										
										
											2021-04-29 01:42:21 -06:00
										 |  |  | use {
 | 
					
						
							|  |  |  |     crate::keypair::{
 | 
					
						
							|  |  |  |         keypair_from_seed_phrase, pubkey_from_path, resolve_signer_from_path, signer_from_path,
 | 
					
						
							|  |  |  |         ASK_KEYWORD, SKIP_SEED_PHRASE_VALIDATION_ARG,
 | 
					
						
							|  |  |  |     },
 | 
					
						
							|  |  |  |     chrono::DateTime,
 | 
					
						
							|  |  |  |     clap::ArgMatches,
 | 
					
						
							|  |  |  |     solana_remote_wallet::remote_wallet::RemoteWalletManager,
 | 
					
						
							|  |  |  |     solana_sdk::{
 | 
					
						
							|  |  |  |         clock::UnixTimestamp,
 | 
					
						
							|  |  |  |         commitment_config::CommitmentConfig,
 | 
					
						
							|  |  |  |         genesis_config::ClusterType,
 | 
					
						
							|  |  |  |         native_token::sol_to_lamports,
 | 
					
						
							|  |  |  |         pubkey::Pubkey,
 | 
					
						
							|  |  |  |         signature::{read_keypair_file, Keypair, Signature, Signer},
 | 
					
						
							|  |  |  |     },
 | 
					
						
							|  |  |  |     std::{str::FromStr, sync::Arc},
 | 
					
						
							| 
									
										
										
										
											2020-02-21 14:55:53 -07:00
										 |  |  | };
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 10:35:07 -05:00
										 |  |  | // Sentinel value used to indicate to write to screen instead of file
 | 
					
						
							|  |  |  | pub const STDOUT_OUTFILE_TOKEN: &str = "-";
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  | // Return parsed values from matches at `name`
 | 
					
						
							|  |  |  | pub fn values_of<T>(matches: &ArgMatches<'_>, name: &str) -> Option<Vec<T>>
 | 
					
						
							|  |  |  | where
 | 
					
						
							|  |  |  |     T: std::str::FromStr,
 | 
					
						
							|  |  |  |     <T as std::str::FromStr>::Err: std::fmt::Debug,
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  |     matches
 | 
					
						
							|  |  |  |         .values_of(name)
 | 
					
						
							|  |  |  |         .map(|xs| xs.map(|x| x.parse::<T>().unwrap()).collect())
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Return a parsed value from matches at `name`
 | 
					
						
							|  |  |  | pub fn value_of<T>(matches: &ArgMatches<'_>, name: &str) -> Option<T>
 | 
					
						
							|  |  |  | where
 | 
					
						
							|  |  |  |     T: std::str::FromStr,
 | 
					
						
							|  |  |  |     <T as std::str::FromStr>::Err: std::fmt::Debug,
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  |     if let Some(value) = matches.value_of(name) {
 | 
					
						
							|  |  |  |         value.parse::<T>().ok()
 | 
					
						
							|  |  |  |     } else {
 | 
					
						
							|  |  |  |         None
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-30 22:57:47 -07:00
										 |  |  | pub fn unix_timestamp_from_rfc3339_datetime(
 | 
					
						
							|  |  |  |     matches: &ArgMatches<'_>,
 | 
					
						
							|  |  |  |     name: &str,
 | 
					
						
							|  |  |  | ) -> Option<UnixTimestamp> {
 | 
					
						
							| 
									
										
										
										
											2019-12-19 14:37:47 -08:00
										 |  |  |     matches.value_of(name).and_then(|value| {
 | 
					
						
							|  |  |  |         DateTime::parse_from_rfc3339(value)
 | 
					
						
							|  |  |  |             .ok()
 | 
					
						
							|  |  |  |             .map(|date_time| date_time.timestamp())
 | 
					
						
							|  |  |  |     })
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  | // Return the keypair for an argument with filename `name` or None if not present.
 | 
					
						
							|  |  |  | pub fn keypair_of(matches: &ArgMatches<'_>, name: &str) -> Option<Keypair> {
 | 
					
						
							|  |  |  |     if let Some(value) = matches.value_of(name) {
 | 
					
						
							| 
									
										
										
										
											2019-11-23 11:55:43 -05:00
										 |  |  |         if value == ASK_KEYWORD {
 | 
					
						
							|  |  |  |             let skip_validation = matches.is_present(SKIP_SEED_PHRASE_VALIDATION_ARG.name);
 | 
					
						
							| 
									
										
										
										
											2021-05-10 19:28:47 -06:00
										 |  |  |             keypair_from_seed_phrase(name, skip_validation, true, None, true).ok()
 | 
					
						
							| 
									
										
										
										
											2019-11-23 11:55:43 -05:00
										 |  |  |         } else {
 | 
					
						
							|  |  |  |             read_keypair_file(value).ok()
 | 
					
						
							|  |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  |     } else {
 | 
					
						
							|  |  |  |         None
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-31 08:23:42 -07:00
										 |  |  | pub fn keypairs_of(matches: &ArgMatches<'_>, name: &str) -> Option<Vec<Keypair>> {
 | 
					
						
							|  |  |  |     matches.values_of(name).map(|values| {
 | 
					
						
							|  |  |  |         values
 | 
					
						
							|  |  |  |             .filter_map(|value| {
 | 
					
						
							|  |  |  |                 if value == ASK_KEYWORD {
 | 
					
						
							|  |  |  |                     let skip_validation = matches.is_present(SKIP_SEED_PHRASE_VALIDATION_ARG.name);
 | 
					
						
							| 
									
										
										
										
											2021-05-10 19:28:47 -06:00
										 |  |  |                     keypair_from_seed_phrase(name, skip_validation, true, None, true).ok()
 | 
					
						
							| 
									
										
										
										
											2020-03-31 08:23:42 -07:00
										 |  |  |                 } else {
 | 
					
						
							|  |  |  |                     read_keypair_file(value).ok()
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							|  |  |  |             })
 | 
					
						
							|  |  |  |             .collect()
 | 
					
						
							|  |  |  |     })
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  | // Return a pubkey for an argument that can itself be parsed into a pubkey,
 | 
					
						
							|  |  |  | // or is a filename that can be read as a keypair
 | 
					
						
							|  |  |  | pub fn pubkey_of(matches: &ArgMatches<'_>, name: &str) -> Option<Pubkey> {
 | 
					
						
							|  |  |  |     value_of(matches, name).or_else(|| keypair_of(matches, name).map(|keypair| keypair.pubkey()))
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-17 12:10:52 -07:00
										 |  |  | pub fn pubkeys_of(matches: &ArgMatches<'_>, name: &str) -> Option<Vec<Pubkey>> {
 | 
					
						
							|  |  |  |     matches.values_of(name).map(|values| {
 | 
					
						
							|  |  |  |         values
 | 
					
						
							|  |  |  |             .map(|value| {
 | 
					
						
							|  |  |  |                 value.parse::<Pubkey>().unwrap_or_else(|_| {
 | 
					
						
							|  |  |  |                     read_keypair_file(value)
 | 
					
						
							|  |  |  |                         .expect("read_keypair_file failed")
 | 
					
						
							|  |  |  |                         .pubkey()
 | 
					
						
							|  |  |  |                 })
 | 
					
						
							|  |  |  |             })
 | 
					
						
							|  |  |  |             .collect()
 | 
					
						
							|  |  |  |     })
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-25 21:09:57 -08:00
										 |  |  | // Return pubkey/signature pairs for a string of the form pubkey=signature
 | 
					
						
							|  |  |  | pub fn pubkeys_sigs_of(matches: &ArgMatches<'_>, name: &str) -> Option<Vec<(Pubkey, Signature)>> {
 | 
					
						
							|  |  |  |     matches.values_of(name).map(|values| {
 | 
					
						
							|  |  |  |         values
 | 
					
						
							|  |  |  |             .map(|pubkey_signer_string| {
 | 
					
						
							|  |  |  |                 let mut signer = pubkey_signer_string.split('=');
 | 
					
						
							|  |  |  |                 let key = Pubkey::from_str(signer.next().unwrap()).unwrap();
 | 
					
						
							|  |  |  |                 let sig = Signature::from_str(signer.next().unwrap()).unwrap();
 | 
					
						
							|  |  |  |                 (key, sig)
 | 
					
						
							|  |  |  |             })
 | 
					
						
							|  |  |  |             .collect()
 | 
					
						
							|  |  |  |     })
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 14:55:53 -07:00
										 |  |  | // Return a signer from matches at `name`
 | 
					
						
							| 
									
										
										
										
											2020-02-24 17:03:30 -07:00
										 |  |  | #[allow(clippy::type_complexity)]
 | 
					
						
							| 
									
										
										
										
											2020-02-21 14:55:53 -07:00
										 |  |  | pub fn signer_of(
 | 
					
						
							|  |  |  |     matches: &ArgMatches<'_>,
 | 
					
						
							| 
									
										
										
										
											2020-02-24 17:03:30 -07:00
										 |  |  |     name: &str,
 | 
					
						
							| 
									
										
										
										
											2020-04-18 12:54:21 -06:00
										 |  |  |     wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
 | 
					
						
							| 
									
										
										
										
											2020-02-24 17:03:30 -07:00
										 |  |  | ) -> Result<(Option<Box<dyn Signer>>, Option<Pubkey>), Box<dyn std::error::Error>> {
 | 
					
						
							| 
									
										
										
										
											2020-02-21 14:55:53 -07:00
										 |  |  |     if let Some(location) = matches.value_of(name) {
 | 
					
						
							| 
									
										
										
										
											2020-02-24 17:03:30 -07:00
										 |  |  |         let signer = signer_from_path(matches, location, name, wallet_manager)?;
 | 
					
						
							|  |  |  |         let signer_pubkey = signer.pubkey();
 | 
					
						
							|  |  |  |         Ok((Some(signer), Some(signer_pubkey)))
 | 
					
						
							| 
									
										
										
										
											2020-02-21 14:55:53 -07:00
										 |  |  |     } else {
 | 
					
						
							| 
									
										
										
										
											2020-02-24 17:03:30 -07:00
										 |  |  |         Ok((None, None))
 | 
					
						
							| 
									
										
										
										
											2020-02-21 14:55:53 -07:00
										 |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-09 00:02:24 -06:00
										 |  |  | pub fn pubkey_of_signer(
 | 
					
						
							|  |  |  |     matches: &ArgMatches<'_>,
 | 
					
						
							|  |  |  |     name: &str,
 | 
					
						
							| 
									
										
										
										
											2020-04-18 12:54:21 -06:00
										 |  |  |     wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
 | 
					
						
							| 
									
										
										
										
											2020-03-09 00:02:24 -06:00
										 |  |  | ) -> Result<Option<Pubkey>, Box<dyn std::error::Error>> {
 | 
					
						
							|  |  |  |     if let Some(location) = matches.value_of(name) {
 | 
					
						
							|  |  |  |         Ok(Some(pubkey_from_path(
 | 
					
						
							|  |  |  |             matches,
 | 
					
						
							|  |  |  |             location,
 | 
					
						
							|  |  |  |             name,
 | 
					
						
							|  |  |  |             wallet_manager,
 | 
					
						
							|  |  |  |         )?))
 | 
					
						
							|  |  |  |     } else {
 | 
					
						
							|  |  |  |         Ok(None)
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-16 16:17:13 -06:00
										 |  |  | pub fn pubkeys_of_multiple_signers(
 | 
					
						
							|  |  |  |     matches: &ArgMatches<'_>,
 | 
					
						
							|  |  |  |     name: &str,
 | 
					
						
							| 
									
										
										
										
											2020-04-18 12:54:21 -06:00
										 |  |  |     wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
 | 
					
						
							| 
									
										
										
										
											2020-03-16 16:17:13 -06:00
										 |  |  | ) -> Result<Option<Vec<Pubkey>>, Box<dyn std::error::Error>> {
 | 
					
						
							|  |  |  |     if let Some(pubkey_matches) = matches.values_of(name) {
 | 
					
						
							|  |  |  |         let mut pubkeys: Vec<Pubkey> = vec![];
 | 
					
						
							|  |  |  |         for signer in pubkey_matches {
 | 
					
						
							|  |  |  |             pubkeys.push(pubkey_from_path(matches, signer, name, wallet_manager)?);
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |         Ok(Some(pubkeys))
 | 
					
						
							|  |  |  |     } else {
 | 
					
						
							|  |  |  |         Ok(None)
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-14 20:48:41 -07:00
										 |  |  | pub fn resolve_signer(
 | 
					
						
							|  |  |  |     matches: &ArgMatches<'_>,
 | 
					
						
							|  |  |  |     name: &str,
 | 
					
						
							| 
									
										
										
										
											2020-04-18 12:54:21 -06:00
										 |  |  |     wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
 | 
					
						
							| 
									
										
										
										
											2020-03-14 20:48:41 -07:00
										 |  |  | ) -> Result<Option<String>, Box<dyn std::error::Error>> {
 | 
					
						
							| 
									
										
										
										
											2021-01-23 11:55:15 -08:00
										 |  |  |     resolve_signer_from_path(
 | 
					
						
							| 
									
										
										
										
											2020-03-14 20:48:41 -07:00
										 |  |  |         matches,
 | 
					
						
							|  |  |  |         matches.value_of(name).unwrap(),
 | 
					
						
							|  |  |  |         name,
 | 
					
						
							|  |  |  |         wallet_manager,
 | 
					
						
							| 
									
										
										
										
											2021-01-23 11:55:15 -08:00
										 |  |  |     )
 | 
					
						
							| 
									
										
										
										
											2020-03-14 20:48:41 -07:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-15 12:53:52 -07:00
										 |  |  | pub fn lamports_of_sol(matches: &ArgMatches<'_>, name: &str) -> Option<u64> {
 | 
					
						
							|  |  |  |     value_of(matches, name).map(sol_to_lamports)
 | 
					
						
							| 
									
										
										
										
											2019-09-29 21:18:15 -07:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-08 23:55:09 +09:00
										 |  |  | pub fn cluster_type_of(matches: &ArgMatches<'_>, name: &str) -> Option<ClusterType> {
 | 
					
						
							|  |  |  |     value_of(matches, name)
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-29 22:55:33 -06:00
										 |  |  | pub fn commitment_of(matches: &ArgMatches<'_>, name: &str) -> Option<CommitmentConfig> {
 | 
					
						
							| 
									
										
										
										
											2021-01-20 09:48:10 -07:00
										 |  |  |     matches
 | 
					
						
							|  |  |  |         .value_of(name)
 | 
					
						
							|  |  |  |         .map(|value| CommitmentConfig::from_str(value).unwrap_or_default())
 | 
					
						
							| 
									
										
										
										
											2020-04-29 22:55:33 -06:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  | #[cfg(test)]
 | 
					
						
							|  |  |  | mod tests {
 | 
					
						
							| 
									
										
										
										
											2021-12-03 09:00:31 -08:00
										 |  |  |     use {
 | 
					
						
							|  |  |  |         super::*,
 | 
					
						
							|  |  |  |         clap::{App, Arg},
 | 
					
						
							|  |  |  |         solana_sdk::signature::write_keypair_file,
 | 
					
						
							|  |  |  |         std::fs,
 | 
					
						
							|  |  |  |     };
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     fn app<'ab, 'v>() -> App<'ab, 'v> {
 | 
					
						
							|  |  |  |         App::new("test")
 | 
					
						
							|  |  |  |             .arg(
 | 
					
						
							|  |  |  |                 Arg::with_name("multiple")
 | 
					
						
							|  |  |  |                     .long("multiple")
 | 
					
						
							|  |  |  |                     .takes_value(true)
 | 
					
						
							|  |  |  |                     .multiple(true),
 | 
					
						
							|  |  |  |             )
 | 
					
						
							|  |  |  |             .arg(Arg::with_name("single").takes_value(true).long("single"))
 | 
					
						
							| 
									
										
										
										
											2019-12-10 00:24:44 -08:00
										 |  |  |             .arg(Arg::with_name("unit").takes_value(true).long("unit"))
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fn tmp_file_path(name: &str, pubkey: &Pubkey) -> String {
 | 
					
						
							|  |  |  |         use std::env;
 | 
					
						
							|  |  |  |         let out_dir = env::var("FARF_DIR").unwrap_or_else(|_| "farf".to_string());
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-22 21:25:54 -07:00
										 |  |  |         format!("{}/tmp/{}-{}", out_dir, name, pubkey)
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #[test]
 | 
					
						
							|  |  |  |     fn test_values_of() {
 | 
					
						
							|  |  |  |         let matches =
 | 
					
						
							|  |  |  |             app()
 | 
					
						
							|  |  |  |                 .clone()
 | 
					
						
							|  |  |  |                 .get_matches_from(vec!["test", "--multiple", "50", "--multiple", "39"]);
 | 
					
						
							|  |  |  |         assert_eq!(values_of(&matches, "multiple"), Some(vec![50, 39]));
 | 
					
						
							|  |  |  |         assert_eq!(values_of::<u64>(&matches, "single"), None);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-19 12:12:08 -07:00
										 |  |  |         let pubkey0 = solana_sdk::pubkey::new_rand();
 | 
					
						
							|  |  |  |         let pubkey1 = solana_sdk::pubkey::new_rand();
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  |         let matches = app().clone().get_matches_from(vec![
 | 
					
						
							|  |  |  |             "test",
 | 
					
						
							|  |  |  |             "--multiple",
 | 
					
						
							|  |  |  |             &pubkey0.to_string(),
 | 
					
						
							|  |  |  |             "--multiple",
 | 
					
						
							|  |  |  |             &pubkey1.to_string(),
 | 
					
						
							|  |  |  |         ]);
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             values_of(&matches, "multiple"),
 | 
					
						
							|  |  |  |             Some(vec![pubkey0, pubkey1])
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #[test]
 | 
					
						
							|  |  |  |     fn test_value_of() {
 | 
					
						
							|  |  |  |         let matches = app()
 | 
					
						
							|  |  |  |             .clone()
 | 
					
						
							|  |  |  |             .get_matches_from(vec!["test", "--single", "50"]);
 | 
					
						
							|  |  |  |         assert_eq!(value_of(&matches, "single"), Some(50));
 | 
					
						
							|  |  |  |         assert_eq!(value_of::<u64>(&matches, "multiple"), None);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-19 12:12:08 -07:00
										 |  |  |         let pubkey = solana_sdk::pubkey::new_rand();
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  |         let matches = app()
 | 
					
						
							|  |  |  |             .clone()
 | 
					
						
							|  |  |  |             .get_matches_from(vec!["test", "--single", &pubkey.to_string()]);
 | 
					
						
							|  |  |  |         assert_eq!(value_of(&matches, "single"), Some(pubkey));
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #[test]
 | 
					
						
							|  |  |  |     fn test_keypair_of() {
 | 
					
						
							|  |  |  |         let keypair = Keypair::new();
 | 
					
						
							| 
									
										
										
										
											2020-01-17 12:10:52 -07:00
										 |  |  |         let outfile = tmp_file_path("test_keypair_of.json", &keypair.pubkey());
 | 
					
						
							| 
									
										
										
										
											2019-10-10 17:01:03 -06:00
										 |  |  |         let _ = write_keypair_file(&keypair, &outfile).unwrap();
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let matches = app()
 | 
					
						
							|  |  |  |             .clone()
 | 
					
						
							|  |  |  |             .get_matches_from(vec!["test", "--single", &outfile]);
 | 
					
						
							| 
									
										
										
										
											2019-11-07 17:08:10 -08:00
										 |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             keypair_of(&matches, "single").unwrap().pubkey(),
 | 
					
						
							|  |  |  |             keypair.pubkey()
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  |         assert!(keypair_of(&matches, "multiple").is_none());
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let matches =
 | 
					
						
							|  |  |  |             app()
 | 
					
						
							|  |  |  |                 .clone()
 | 
					
						
							|  |  |  |                 .get_matches_from(vec!["test", "--single", "random_keypair_file.json"]);
 | 
					
						
							| 
									
										
										
										
											2019-11-07 17:08:10 -08:00
										 |  |  |         assert!(keypair_of(&matches, "single").is_none());
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         fs::remove_file(&outfile).unwrap();
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #[test]
 | 
					
						
							|  |  |  |     fn test_pubkey_of() {
 | 
					
						
							|  |  |  |         let keypair = Keypair::new();
 | 
					
						
							| 
									
										
										
										
											2020-01-17 12:10:52 -07:00
										 |  |  |         let outfile = tmp_file_path("test_pubkey_of.json", &keypair.pubkey());
 | 
					
						
							| 
									
										
										
										
											2019-10-10 17:01:03 -06:00
										 |  |  |         let _ = write_keypair_file(&keypair, &outfile).unwrap();
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let matches = app()
 | 
					
						
							|  |  |  |             .clone()
 | 
					
						
							|  |  |  |             .get_matches_from(vec!["test", "--single", &outfile]);
 | 
					
						
							|  |  |  |         assert_eq!(pubkey_of(&matches, "single"), Some(keypair.pubkey()));
 | 
					
						
							|  |  |  |         assert_eq!(pubkey_of(&matches, "multiple"), None);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let matches =
 | 
					
						
							|  |  |  |             app()
 | 
					
						
							|  |  |  |                 .clone()
 | 
					
						
							|  |  |  |                 .get_matches_from(vec!["test", "--single", &keypair.pubkey().to_string()]);
 | 
					
						
							|  |  |  |         assert_eq!(pubkey_of(&matches, "single"), Some(keypair.pubkey()));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let matches =
 | 
					
						
							|  |  |  |             app()
 | 
					
						
							|  |  |  |                 .clone()
 | 
					
						
							|  |  |  |                 .get_matches_from(vec!["test", "--single", "random_keypair_file.json"]);
 | 
					
						
							|  |  |  |         assert_eq!(pubkey_of(&matches, "single"), None);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fs::remove_file(&outfile).unwrap();
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2019-11-25 21:09:57 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-17 12:10:52 -07:00
										 |  |  |     #[test]
 | 
					
						
							|  |  |  |     fn test_pubkeys_of() {
 | 
					
						
							|  |  |  |         let keypair = Keypair::new();
 | 
					
						
							|  |  |  |         let outfile = tmp_file_path("test_pubkeys_of.json", &keypair.pubkey());
 | 
					
						
							|  |  |  |         let _ = write_keypair_file(&keypair, &outfile).unwrap();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let matches = app().clone().get_matches_from(vec![
 | 
					
						
							|  |  |  |             "test",
 | 
					
						
							|  |  |  |             "--multiple",
 | 
					
						
							|  |  |  |             &keypair.pubkey().to_string(),
 | 
					
						
							|  |  |  |             "--multiple",
 | 
					
						
							|  |  |  |             &outfile,
 | 
					
						
							|  |  |  |         ]);
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             pubkeys_of(&matches, "multiple"),
 | 
					
						
							|  |  |  |             Some(vec![keypair.pubkey(), keypair.pubkey()])
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  |         fs::remove_file(&outfile).unwrap();
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-25 21:09:57 -08:00
										 |  |  |     #[test]
 | 
					
						
							|  |  |  |     fn test_pubkeys_sigs_of() {
 | 
					
						
							| 
									
										
										
										
											2020-10-19 12:12:08 -07:00
										 |  |  |         let key1 = solana_sdk::pubkey::new_rand();
 | 
					
						
							|  |  |  |         let key2 = solana_sdk::pubkey::new_rand();
 | 
					
						
							| 
									
										
										
										
											2019-11-25 21:09:57 -08:00
										 |  |  |         let sig1 = Keypair::new().sign_message(&[0u8]);
 | 
					
						
							|  |  |  |         let sig2 = Keypair::new().sign_message(&[1u8]);
 | 
					
						
							|  |  |  |         let signer1 = format!("{}={}", key1, sig1);
 | 
					
						
							|  |  |  |         let signer2 = format!("{}={}", key2, sig2);
 | 
					
						
							|  |  |  |         let matches = app().clone().get_matches_from(vec![
 | 
					
						
							|  |  |  |             "test",
 | 
					
						
							|  |  |  |             "--multiple",
 | 
					
						
							|  |  |  |             &signer1,
 | 
					
						
							|  |  |  |             "--multiple",
 | 
					
						
							|  |  |  |             &signer2,
 | 
					
						
							|  |  |  |         ]);
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             pubkeys_sigs_of(&matches, "multiple"),
 | 
					
						
							|  |  |  |             Some(vec![(key1, sig1), (key2, sig2)])
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2019-12-10 00:24:44 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     #[test]
 | 
					
						
							| 
									
										
										
										
											2020-02-15 12:53:52 -07:00
										 |  |  |     fn test_lamports_of_sol() {
 | 
					
						
							| 
									
										
										
										
											2019-12-10 00:24:44 -08:00
										 |  |  |         let matches = app()
 | 
					
						
							|  |  |  |             .clone()
 | 
					
						
							| 
									
										
										
										
											2020-02-15 12:53:52 -07:00
										 |  |  |             .get_matches_from(vec!["test", "--single", "50"]);
 | 
					
						
							| 
									
										
										
										
											2020-05-15 17:35:43 +01:00
										 |  |  |         assert_eq!(lamports_of_sol(&matches, "single"), Some(50_000_000_000));
 | 
					
						
							| 
									
										
										
										
											2020-02-15 12:53:52 -07:00
										 |  |  |         assert_eq!(lamports_of_sol(&matches, "multiple"), None);
 | 
					
						
							| 
									
										
										
										
											2019-12-10 11:29:17 -07:00
										 |  |  |         let matches = app()
 | 
					
						
							|  |  |  |             .clone()
 | 
					
						
							| 
									
										
										
										
											2020-02-15 12:53:52 -07:00
										 |  |  |             .get_matches_from(vec!["test", "--single", "1.5"]);
 | 
					
						
							| 
									
										
										
										
											2020-05-15 17:35:43 +01:00
										 |  |  |         assert_eq!(lamports_of_sol(&matches, "single"), Some(1_500_000_000));
 | 
					
						
							| 
									
										
										
										
											2020-02-15 12:53:52 -07:00
										 |  |  |         assert_eq!(lamports_of_sol(&matches, "multiple"), None);
 | 
					
						
							| 
									
										
										
										
											2019-12-10 11:29:17 -07:00
										 |  |  |         let matches = app()
 | 
					
						
							|  |  |  |             .clone()
 | 
					
						
							| 
									
										
										
										
											2020-02-15 12:53:52 -07:00
										 |  |  |             .get_matches_from(vec!["test", "--single", "0.03"]);
 | 
					
						
							| 
									
										
										
										
											2020-05-15 17:35:43 +01:00
										 |  |  |         assert_eq!(lamports_of_sol(&matches, "single"), Some(30_000_000));
 | 
					
						
							| 
									
										
										
										
											2019-12-10 00:24:44 -08:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2019-09-18 10:29:57 -06:00
										 |  |  | }
 |