11use clap:: { Arg , Command } ;
22use kaspa_core:: kaspad_env:: version;
3+ use std:: io;
34use std:: net:: SocketAddr ;
5+ use std:: path:: PathBuf ;
46
57pub struct Args {
68 pub password : String ,
@@ -9,23 +11,26 @@ pub struct Args {
911 pub network_id : Option < String > ,
1012 pub listen_address : SocketAddr ,
1113 pub ecdsa : bool ,
14+ pub location : Option < PathBuf > ,
1215}
1316
1417impl Args {
15- pub fn parse ( ) -> Self {
18+ pub fn parse ( ) -> Result < Self , Box < dyn std :: error :: Error > > {
1619 let matches = cli ( ) . get_matches ( ) ;
17-
18- Args {
20+ let key_file = matches. get_one :: < PathBuf > ( "keys-file" ) . cloned ( ) ;
21+ let ( name, location) = parse_keys_file_arg ( key_file) ?;
22+ Ok ( Args {
1923 password : matches. get_one :: < String > ( "password" ) . cloned ( ) . expect ( "Password argument is missing." ) ,
20- name : matches . get_one :: < String > ( "name" ) . cloned ( ) ,
24+ name,
2125 rpc_server : matches. get_one :: < String > ( "rpc-server" ) . cloned ( ) ,
2226 network_id : matches. get_one :: < String > ( "network-id" ) . cloned ( ) ,
2327 listen_address : matches
2428 . get_one :: < SocketAddr > ( "listen-address" )
2529 . cloned ( )
2630 . unwrap_or_else ( || "127.0.0.1:8082" . parse ( ) . unwrap ( ) ) ,
2731 ecdsa : matches. get_one :: < bool > ( "ecdsa" ) . cloned ( ) . unwrap_or ( false ) ,
28- }
32+ location,
33+ } )
2934 }
3035}
3136
@@ -34,14 +39,6 @@ pub fn cli() -> Command {
3439 . about ( format ! ( "{} (kaspawalletd) v{}" , env!( "CARGO_PKG_DESCRIPTION" ) , version( ) ) )
3540 . version ( env ! ( "CARGO_PKG_VERSION" ) )
3641 . arg ( Arg :: new ( "password" ) . long ( "password" ) . short ( 'p' ) . value_name ( "password" ) . help ( "Path of password file" ) . required ( true ) )
37- . arg (
38- Arg :: new ( "name" )
39- . long ( "name" )
40- . short ( 'n' )
41- . value_name ( "name" )
42- . value_parser ( clap:: value_parser!( String ) )
43- . help ( "Name of wallet" ) ,
44- )
4542 . arg (
4643 Arg :: new ( "rpc-server" )
4744 . long ( "rpc-server" )
@@ -72,4 +69,42 @@ pub fn cli() -> Command {
7269 . value_parser ( clap:: value_parser!( bool ) )
7370 . help ( "Use ecdsa for transactions broadcast" ) ,
7471 )
72+ . arg ( Arg :: new ( "keys-file" ) . long ( "keys-file" ) . short ( 'f' ) . value_name ( "keys-file" ) . help ( "Keys file location" ) )
73+ }
74+
75+ fn parse_keys_file_arg ( keys_file : Option < PathBuf > ) -> Result < ( Option < String > , Option < PathBuf > ) , Box < dyn std:: error:: Error > > {
76+ if let Some ( keys_file) = keys_file {
77+ if keys_file. is_dir ( ) {
78+ Ok ( ( None , Some ( keys_file) ) )
79+ } else {
80+ let name = keys_file
81+ . file_name ( )
82+ . ok_or_else ( || io:: Error :: new ( io:: ErrorKind :: InvalidInput , "Invalid wallet file path" ) ) ?
83+ . to_str ( )
84+ . ok_or_else ( || io:: Error :: new ( io:: ErrorKind :: InvalidInput , "Wallet file path is not valid UTF-8" ) ) ?
85+ . to_owned ( ) ;
86+ Ok ( ( Some ( name) , keys_file. parent ( ) . map ( |p| p. to_owned ( ) ) ) )
87+ }
88+ } else {
89+ Ok ( ( None , None ) )
90+ }
91+ }
92+
93+ #[ cfg( test) ]
94+ mod tests {
95+ use super :: * ;
96+ use tempfile:: NamedTempFile ;
97+
98+ #[ test]
99+ fn test_parse_keys_file ( ) {
100+ // arrange
101+ let tmp_keys_file = NamedTempFile :: new ( ) . unwrap ( ) ;
102+
103+ // act
104+ let ( name, location) = parse_keys_file_arg ( Some ( tmp_keys_file. path ( ) . to_path_buf ( ) ) ) . unwrap ( ) ;
105+
106+ // assert
107+ assert_eq ! ( name, Some ( tmp_keys_file. path( ) . file_name( ) . unwrap( ) . to_str( ) . unwrap( ) . to_owned( ) ) ) ;
108+ assert_eq ! ( location, Some ( tmp_keys_file. path( ) . parent( ) . unwrap( ) . to_path_buf( ) ) ) ;
109+ }
75110}
0 commit comments