2019-08-07 12:17:11 -07:00
use clap ::{ crate_description , crate_name , crate_version , Arg , ArgGroup , ArgMatches , SubCommand } ;
use console ::style ;
2019-08-22 13:51:16 -07:00
use solana_cli ::config ::{ self , Config } ;
use solana_cli ::display ::println_name_value ;
use solana_cli ::wallet ::{ app , parse_command , process_command , WalletConfig , WalletError } ;
2018-12-12 13:13:18 -08:00
use solana_sdk ::signature ::{ gen_keypair_file , 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 " ) {
let config = Config ::load ( config_file ) . unwrap_or_default ( ) ;
if let Some ( field ) = subcommand_matches . value_of ( " specific_setting " ) {
let value = match field {
" url " = > config . url ,
" keypair " = > config . keypair ,
_ = > unreachable! ( ) ,
} ;
println_name_value ( & format! ( " * {} : " , field ) , & value ) ;
} else {
println_name_value ( " Wallet Config: " , config_file ) ;
println_name_value ( " * url: " , & config . url ) ;
println_name_value ( " * keypair: " , & config . keypair ) ;
}
} else {
println! ( " {} Either provide the `--config` arg or ensure home directory exists to use the default config location " , style ( " No config file found. " ) . bold ( ) ) ;
}
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 ( ) ;
if let Some ( url ) = subcommand_matches . value_of ( " url " ) {
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 {
println! ( " {} Either provide the `--config` arg or ensure home directory exists to use the default config location " , style ( " No config file found. " ) . bold ( ) ) ;
}
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
2018-09-14 01:58:39 -07:00
let mut path = dirs ::home_dir ( ) . expect ( " home directory " ) ;
let id_path = if matches . is_present ( " keypair " ) {
matches . value_of ( " keypair " ) . unwrap ( )
2019-08-07 12:17:11 -07:00
} else if config . keypair ! = " " {
& config . keypair
2018-09-14 01:58:39 -07:00
} else {
path . extend ( & [ " .config " , " solana " , " id.json " ] ) ;
2018-09-14 17:13:12 -07: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 17:13:12 -07:00
}
2018-09-14 01:58:39 -07:00
path . to_str ( ) . unwrap ( )
} ;
2019-04-02 06:08:11 -07:00
let keypair = read_keypair ( id_path ) . or_else ( | err | {
2018-09-14 01:58:39 -07:00
Err ( WalletError ::BadParameter ( format! (
" {}: Unable to open keypair file: {} " ,
err , id_path
) ) )
} ) ? ;
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-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
}
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 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 " )
. short ( " c " )
. long ( " config " )
. value_name ( " PATH " )
. takes_value ( true )
. 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-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 " )
. 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 " )
. arg (
Arg ::with_name ( " url " )
. short ( " u " )
. long ( " url " )
. value_name ( " URL " )
. takes_value ( true )
. validator ( is_url )
. help ( " Set default JSON RPC URL to query " ) ,
)
. arg (
Arg ::with_name ( " keypair " )
. short ( " k " )
. long ( " keypair " )
. value_name ( " PATH " )
. takes_value ( true )
. help ( " /path/to/id.json " ) ,
)
. group (
ArgGroup ::with_name ( " config_settings " )
. args ( & [ " url " , " keypair " ] )
. 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
}