2019-08-07 12:17:11 -07:00
|
|
|
use clap::{crate_description, crate_name, crate_version, Arg, ArgGroup, ArgMatches, SubCommand};
|
|
|
|
use console::style;
|
2019-09-03 10:38:12 -07:00
|
|
|
use solana_cli::{
|
|
|
|
config::{self, Config},
|
2019-09-05 10:14:23 -07:00
|
|
|
display::{println_name_value, println_name_value_or},
|
2019-09-03 10:38:12 -07:00
|
|
|
input_validators::is_url,
|
|
|
|
wallet::{app, parse_command, process_command, WalletConfig, WalletError},
|
|
|
|
};
|
2019-09-12 18:37:29 -07:00
|
|
|
use solana_sdk::signature::{read_keypair, KeypairUtil};
|
2018-06-29 10:38:00 -07:00
|
|
|
use std::error;
|
|
|
|
|
2019-08-07 12:17:11 -07:00
|
|
|
fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error>> {
|
|
|
|
let parse_args = match matches.subcommand() {
|
|
|
|
("get", Some(subcommand_matches)) => {
|
|
|
|
if let Some(config_file) = matches.value_of("config_file") {
|
2019-09-05 10:14:23 -07:00
|
|
|
let default_wallet_config = WalletConfig::default();
|
2019-08-07 12:17:11 -07:00
|
|
|
let config = Config::load(config_file).unwrap_or_default();
|
|
|
|
if let Some(field) = subcommand_matches.value_of("specific_setting") {
|
2019-09-05 10:14:23 -07:00
|
|
|
let (value, default_value) = match field {
|
|
|
|
"url" => (config.url, default_wallet_config.json_rpc_url),
|
|
|
|
"keypair" => (config.keypair, default_wallet_config.keypair_path),
|
2019-08-07 12:17:11 -07:00
|
|
|
_ => unreachable!(),
|
|
|
|
};
|
2019-09-05 10:14:23 -07:00
|
|
|
println_name_value_or(&format!("* {}:", field), &value, &default_value);
|
2019-08-07 12:17:11 -07:00
|
|
|
} else {
|
|
|
|
println_name_value("Wallet Config:", config_file);
|
2019-09-05 10:14:23 -07:00
|
|
|
println_name_value_or(
|
|
|
|
"* url:",
|
|
|
|
&config.url,
|
|
|
|
&default_wallet_config.json_rpc_url,
|
|
|
|
);
|
|
|
|
println_name_value_or(
|
|
|
|
"* keypair:",
|
|
|
|
&config.keypair,
|
|
|
|
&default_wallet_config.keypair_path,
|
|
|
|
);
|
2019-08-07 12:17:11 -07:00
|
|
|
}
|
|
|
|
} else {
|
2019-08-30 11:13:23 -07:00
|
|
|
println!(
|
|
|
|
"{} Either provide the `--config` arg or ensure home directory exists to use the default config location",
|
|
|
|
style("No config file found.").bold()
|
|
|
|
);
|
2019-08-07 12:17:11 -07:00
|
|
|
}
|
|
|
|
false
|
|
|
|
}
|
|
|
|
("set", Some(subcommand_matches)) => {
|
|
|
|
if let Some(config_file) = matches.value_of("config_file") {
|
|
|
|
let mut config = Config::load(config_file).unwrap_or_default();
|
2019-08-30 11:13:23 -07:00
|
|
|
if let Some(url) = subcommand_matches.value_of("json_rpc_url") {
|
2019-08-07 12:17:11 -07:00
|
|
|
config.url = url.to_string();
|
|
|
|
}
|
|
|
|
if let Some(keypair) = subcommand_matches.value_of("keypair") {
|
|
|
|
config.keypair = keypair.to_string();
|
|
|
|
}
|
|
|
|
config.save(config_file)?;
|
|
|
|
println_name_value("Wallet Config Updated:", config_file);
|
|
|
|
println_name_value("* url:", &config.url);
|
|
|
|
println_name_value("* keypair:", &config.keypair);
|
|
|
|
} else {
|
2019-08-30 11:13:23 -07:00
|
|
|
println!(
|
|
|
|
"{} Either provide the `--config` arg or ensure home directory exists to use the default config location",
|
|
|
|
style("No config file found.").bold()
|
|
|
|
);
|
2019-08-07 12:17:11 -07:00
|
|
|
}
|
|
|
|
false
|
|
|
|
}
|
|
|
|
_ => true,
|
|
|
|
};
|
|
|
|
Ok(parse_args)
|
|
|
|
}
|
|
|
|
|
2018-12-08 21:44:20 -08:00
|
|
|
pub fn parse_args(matches: &ArgMatches<'_>) -> Result<WalletConfig, Box<dyn error::Error>> {
|
2019-08-07 12:17:11 -07:00
|
|
|
let config = if let Some(config_file) = matches.value_of("config_file") {
|
|
|
|
Config::load(config_file).unwrap_or_default()
|
|
|
|
} else {
|
|
|
|
Config::default()
|
|
|
|
};
|
|
|
|
let json_rpc_url = if let Some(url) = matches.value_of("json_rpc_url") {
|
|
|
|
url.to_string()
|
|
|
|
} else if config.url != "" {
|
|
|
|
config.url
|
|
|
|
} else {
|
|
|
|
let default = WalletConfig::default();
|
|
|
|
default.json_rpc_url
|
|
|
|
};
|
2019-01-16 20:43:00 -08:00
|
|
|
|
2019-09-05 10:14:23 -07:00
|
|
|
let keypair_path = if matches.is_present("keypair") {
|
|
|
|
matches.value_of("keypair").unwrap().to_string()
|
2019-08-07 12:17:11 -07:00
|
|
|
} else if config.keypair != "" {
|
2019-09-05 10:14:23 -07:00
|
|
|
config.keypair
|
2018-09-14 01:58:39 -07:00
|
|
|
} else {
|
2019-09-05 10:14:23 -07:00
|
|
|
let default = WalletConfig::default();
|
|
|
|
if !std::path::Path::new(&default.keypair_path).exists() {
|
2019-09-12 18:37:29 -07:00
|
|
|
Err(WalletError::KeypairFileNotFound(
|
|
|
|
"Generate a new keypair with `solana-keygen new`".to_string(),
|
|
|
|
))?;
|
2018-09-14 17:13:12 -07:00
|
|
|
}
|
2019-09-05 10:14:23 -07:00
|
|
|
default.keypair_path
|
2018-09-14 01:58:39 -07:00
|
|
|
};
|
2019-09-05 10:14:23 -07:00
|
|
|
let keypair = read_keypair(&keypair_path).or_else(|err| {
|
2018-09-14 01:58:39 -07:00
|
|
|
Err(WalletError::BadParameter(format!(
|
|
|
|
"{}: Unable to open keypair file: {}",
|
2019-09-05 10:14:23 -07:00
|
|
|
err, keypair_path
|
2018-09-14 01:58:39 -07:00
|
|
|
)))
|
|
|
|
})?;
|
2018-06-29 10:38:00 -07:00
|
|
|
|
2019-04-02 06:08:11 -07:00
|
|
|
let command = parse_command(&keypair.pubkey(), &matches)?;
|
2018-09-14 01:58:39 -07:00
|
|
|
|
|
|
|
Ok(WalletConfig {
|
|
|
|
command,
|
2019-05-06 07:38:26 -07:00
|
|
|
json_rpc_url,
|
|
|
|
keypair,
|
2019-09-05 10:14:23 -07:00
|
|
|
keypair_path: keypair_path.to_string(),
|
2019-01-13 23:10:03 -08:00
|
|
|
rpc_client: None,
|
2018-09-14 01:58:39 -07:00
|
|
|
})
|
2018-06-29 10:38:00 -07:00
|
|
|
}
|
|
|
|
|
2018-12-08 21:44:20 -08:00
|
|
|
fn main() -> Result<(), Box<dyn error::Error>> {
|
2018-12-14 12:36:50 -08:00
|
|
|
solana_logger::setup();
|
2019-05-09 19:31:42 -07:00
|
|
|
let matches = app(crate_name!(), crate_description!(), crate_version!())
|
2019-08-07 12:17:11 -07:00
|
|
|
.arg({
|
|
|
|
let arg = Arg::with_name("config_file")
|
2019-08-30 11:13:23 -07:00
|
|
|
.short("C")
|
2019-08-07 12:17:11 -07:00
|
|
|
.long("config")
|
|
|
|
.value_name("PATH")
|
|
|
|
.takes_value(true)
|
2019-08-30 11:13:23 -07:00
|
|
|
.global(true)
|
2019-08-07 12:17:11 -07:00
|
|
|
.help("Configuration file to use");
|
|
|
|
if let Some(ref config_file) = *config::CONFIG_FILE {
|
|
|
|
arg.default_value(&config_file)
|
|
|
|
} else {
|
|
|
|
arg
|
|
|
|
}
|
|
|
|
})
|
2018-06-29 18:33:20 -07:00
|
|
|
.arg(
|
2019-05-06 07:38:26 -07:00
|
|
|
Arg::with_name("json_rpc_url")
|
|
|
|
.short("u")
|
|
|
|
.long("url")
|
|
|
|
.value_name("URL")
|
2019-01-16 20:43:00 -08:00
|
|
|
.takes_value(true)
|
2019-08-30 11:13:23 -07:00
|
|
|
.global(true)
|
2019-05-06 07:38:26 -07:00
|
|
|
.validator(is_url)
|
|
|
|
.help("JSON RPC URL for the solana cluster"),
|
2019-01-16 20:43:00 -08:00
|
|
|
)
|
|
|
|
.arg(
|
2018-07-12 15:02:14 -07:00
|
|
|
Arg::with_name("keypair")
|
|
|
|
.short("k")
|
|
|
|
.long("keypair")
|
2018-06-29 18:33:20 -07:00
|
|
|
.value_name("PATH")
|
2019-08-30 11:13:23 -07:00
|
|
|
.global(true)
|
2018-06-29 18:33:20 -07:00
|
|
|
.takes_value(true)
|
2018-07-12 15:02:14 -07:00
|
|
|
.help("/path/to/id.json"),
|
2019-01-16 20:43:00 -08:00
|
|
|
)
|
2019-08-07 12:17:11 -07:00
|
|
|
.subcommand(
|
|
|
|
SubCommand::with_name("get")
|
|
|
|
.about("Get wallet config settings")
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("specific_setting")
|
|
|
|
.index(1)
|
|
|
|
.value_name("CONFIG_FIELD")
|
|
|
|
.takes_value(true)
|
|
|
|
.possible_values(&["url", "keypair"])
|
|
|
|
.help("Return a specific config setting"),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
.subcommand(
|
|
|
|
SubCommand::with_name("set")
|
|
|
|
.about("Set a wallet config setting")
|
|
|
|
.group(
|
|
|
|
ArgGroup::with_name("config_settings")
|
2019-08-30 11:13:23 -07:00
|
|
|
.args(&["json_rpc_url", "keypair"])
|
2019-08-07 12:17:11 -07:00
|
|
|
.multiple(true)
|
|
|
|
.required(true),
|
|
|
|
),
|
|
|
|
)
|
2019-01-16 20:43:00 -08:00
|
|
|
.get_matches();
|
2018-06-26 22:52:34 -07:00
|
|
|
|
2019-08-07 12:17:11 -07:00
|
|
|
if parse_settings(&matches)? {
|
|
|
|
let config = parse_args(&matches)?;
|
|
|
|
let result = process_command(&config)?;
|
|
|
|
println!("{}", result);
|
|
|
|
}
|
2018-09-17 12:15:26 -07:00
|
|
|
Ok(())
|
2018-06-29 10:38:00 -07:00
|
|
|
}
|