2019-05-09 19:31:42 -07:00
|
|
|
use clap::{crate_description, crate_name, crate_version, Arg, ArgMatches};
|
2018-12-12 13:13:18 -08:00
|
|
|
use solana_sdk::signature::{gen_keypair_file, read_keypair, KeypairUtil};
|
2019-05-09 19:31:42 -07:00
|
|
|
use solana_wallet::wallet::{app, parse_command, process_command, WalletConfig, WalletError};
|
2018-06-29 11:38:00 -06:00
|
|
|
use std::error;
|
|
|
|
|
2018-12-08 22:44:20 -07:00
|
|
|
pub fn parse_args(matches: &ArgMatches<'_>) -> Result<WalletConfig, Box<dyn error::Error>> {
|
2019-05-06 07:38:26 -07:00
|
|
|
let json_rpc_url = matches.value_of("json_rpc_url").unwrap().to_string();
|
2019-01-16 20:43:00 -08:00
|
|
|
|
|
|
|
let drone_host = if let Some(drone_host) = matches.value_of("drone_host") {
|
2019-04-13 19:34:27 -07:00
|
|
|
Some(solana_netutil::parse_host(drone_host).or_else(|err| {
|
|
|
|
Err(WalletError::BadParameter(format!(
|
|
|
|
"Invalid drone host: {:?}",
|
|
|
|
err
|
|
|
|
)))
|
|
|
|
})?)
|
2019-01-16 20:43:00 -08:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
let drone_port = matches
|
|
|
|
.value_of("drone_port")
|
|
|
|
.unwrap()
|
|
|
|
.parse()
|
2019-04-13 19:34:27 -07:00
|
|
|
.or_else(|err| {
|
|
|
|
Err(WalletError::BadParameter(format!(
|
|
|
|
"Invalid drone port: {:?}",
|
|
|
|
err
|
|
|
|
)))
|
|
|
|
})?;
|
2019-01-16 20:43:00 -08:00
|
|
|
|
2018-09-14 02:58:39 -06:00
|
|
|
let mut path = dirs::home_dir().expect("home directory");
|
|
|
|
let id_path = if matches.is_present("keypair") {
|
|
|
|
matches.value_of("keypair").unwrap()
|
|
|
|
} else {
|
|
|
|
path.extend(&[".config", "solana", "id.json"]);
|
2018-09-14 18:13:12 -06:00
|
|
|
if !path.exists() {
|
2019-05-08 23:00:48 -07:00
|
|
|
gen_keypair_file(path.to_str().unwrap())?;
|
2019-06-08 19:22:07 -07:00
|
|
|
println!("New keypair generated at: {}", path.to_str().unwrap());
|
2018-09-14 18:13:12 -06:00
|
|
|
}
|
|
|
|
|
2018-09-14 02:58:39 -06:00
|
|
|
path.to_str().unwrap()
|
|
|
|
};
|
2019-04-02 07:08:11 -06:00
|
|
|
let keypair = read_keypair(id_path).or_else(|err| {
|
2018-09-14 02:58:39 -06:00
|
|
|
Err(WalletError::BadParameter(format!(
|
|
|
|
"{}: Unable to open keypair file: {}",
|
|
|
|
err, id_path
|
|
|
|
)))
|
|
|
|
})?;
|
2018-06-29 11:38:00 -06:00
|
|
|
|
2019-04-02 07:08:11 -06:00
|
|
|
let command = parse_command(&keypair.pubkey(), &matches)?;
|
2018-09-14 02:58:39 -06:00
|
|
|
|
|
|
|
Ok(WalletConfig {
|
|
|
|
command,
|
2019-01-16 20:43:00 -08:00
|
|
|
drone_host,
|
|
|
|
drone_port,
|
2019-05-06 07:38:26 -07:00
|
|
|
json_rpc_url,
|
|
|
|
keypair,
|
2019-01-14 00:10:03 -07:00
|
|
|
rpc_client: None,
|
2018-09-14 02:58:39 -06:00
|
|
|
})
|
2018-06-29 11:38:00 -06:00
|
|
|
}
|
|
|
|
|
2019-05-06 07:38:26 -07:00
|
|
|
// Return an error if a url cannot be parsed.
|
|
|
|
fn is_url(string: String) -> Result<(), String> {
|
|
|
|
match url::Url::parse(&string) {
|
|
|
|
Ok(url) => {
|
|
|
|
if url.has_host() {
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Err("no host provided".to_string())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(err) => Err(format!("{:?}", err)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-08 22:44:20 -07:00
|
|
|
fn main() -> Result<(), Box<dyn error::Error>> {
|
2018-12-14 12:36:50 -08:00
|
|
|
solana_logger::setup();
|
2019-01-16 20:43:00 -08:00
|
|
|
|
2019-05-06 07:38:26 -07:00
|
|
|
let default = WalletConfig::default();
|
|
|
|
let default_drone_port = format!("{}", default.drone_port);
|
2019-01-16 20:43:00 -08:00
|
|
|
|
2019-05-09 19:31:42 -07:00
|
|
|
let matches = app(crate_name!(), crate_description!(), crate_version!())
|
2018-06-29 19:33:20 -06: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-05-06 07:38:26 -07:00
|
|
|
.default_value(&default.json_rpc_url)
|
|
|
|
.validator(is_url)
|
|
|
|
.help("JSON RPC URL for the solana cluster"),
|
2019-01-16 20:43:00 -08:00
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("drone_host")
|
|
|
|
.long("drone-host")
|
2019-05-06 07:38:26 -07:00
|
|
|
.value_name("HOST")
|
2019-01-16 20:43:00 -08:00
|
|
|
.takes_value(true)
|
2019-05-06 07:38:26 -07:00
|
|
|
.help("Drone host to use [default: same as the --url host]"),
|
2019-01-16 20:43:00 -08:00
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("drone_port")
|
|
|
|
.long("drone-port")
|
|
|
|
.value_name("PORT")
|
|
|
|
.takes_value(true)
|
|
|
|
.default_value(&default_drone_port)
|
|
|
|
.help("Drone port to use"),
|
|
|
|
)
|
|
|
|
.arg(
|
2018-07-12 16:02:14 -06:00
|
|
|
Arg::with_name("keypair")
|
|
|
|
.short("k")
|
|
|
|
.long("keypair")
|
2018-06-29 19:33:20 -06:00
|
|
|
.value_name("PATH")
|
|
|
|
.takes_value(true)
|
2018-07-12 16:02:14 -06:00
|
|
|
.help("/path/to/id.json"),
|
2019-01-16 20:43:00 -08:00
|
|
|
)
|
|
|
|
.get_matches();
|
2018-06-26 23:52:34 -06:00
|
|
|
|
2018-11-09 15:36:08 -07:00
|
|
|
let config = parse_args(&matches)?;
|
2018-09-20 23:27:06 -06:00
|
|
|
let result = process_command(&config)?;
|
2018-09-17 13:15:26 -06:00
|
|
|
println!("{}", result);
|
|
|
|
Ok(())
|
2018-06-29 11:38:00 -06:00
|
|
|
}
|