@@ -1054,20 +1054,14 @@ pub(crate) fn handle_compile_subcommand(
10541054#[ cfg( feature = "hwi" ) ]
10551055pub async fn handle_hwi_subcommand (
10561056 network : Network ,
1057- wallet_opts : & WalletOpts ,
1057+ hwi_opts : & HwiOpts ,
10581058 subcommand : HwiSubCommand ,
10591059) -> Result < serde_json:: Value , Error > {
10601060 match subcommand {
10611061 HwiSubCommand :: Devices => {
1062- let devices = crate :: utils:: connect_to_hardware_wallet (
1063- wallet. network ( ) ,
1064- wallet_opts,
1065- Some ( wallet) ,
1066- )
1067- . await ?;
1068- let device = if let Some ( device) = device {
1062+ let devices = crate :: utils:: connect_to_hardware_wallet ( network, hwi_opts) . await ?;
1063+ let device = if let Some ( device) = devices {
10691064 json ! ( {
1070- "type" : device. device_kind( ) . to_string( ) ,
10711065 "fingerprint" : device. get_master_fingerprint( ) . await ?. to_string( ) ,
10721066 "model" : device. device_kind( ) . to_string( ) ,
10731067 } )
@@ -1077,97 +1071,82 @@ pub async fn handle_hwi_subcommand(
10771071 Ok ( json ! ( { "devices" : device } ) )
10781072 }
10791073 HwiSubCommand :: Register => {
1080- let policy = wallet_opts . ext_descriptor . clone ( ) . ok_or_else ( || {
1074+ let policy = hwi_opts . ext_descriptor . clone ( ) . ok_or_else ( || {
10811075 Error :: Generic ( "External descriptor required for wallet registration" . to_string ( ) )
10821076 } ) ?;
1083- let wallet_name = wallet_opts . wallet . clone ( ) . ok_or_else ( || {
1077+ let wallet_name = hwi_opts . wallet . clone ( ) . ok_or_else ( || {
10841078 Error :: Generic ( "Wallet name is required for wallet registration" . to_string ( ) )
10851079 } ) ?;
10861080
1087- let home_dir = prepare_home_dir ( None ) ?;
1088- let database_path = prepare_wallet_db_dir ( & wallet_opts. wallet , & home_dir) ?;
1089- #[ cfg( feature = "sqlite" ) ]
1090- let wallet = {
1091- let mut persister = match & wallet_opts. database_type {
1092- DatabaseType :: Sqlite => {
1093- let db_file = database_path. join ( "wallet.sqlite" ) ;
1094- let connection = Connection :: open ( db_file) ?;
1095- log:: debug!( "Sqlite database opened successfully" ) ;
1096- connection
1081+ let device = crate :: utils:: connect_to_hardware_wallet ( network, hwi_opts) . await ?;
1082+
1083+ match device {
1084+ None => Ok ( json ! ( {
1085+ "success" : false ,
1086+ "error" : "No hardware wallet detected"
1087+ } ) ) ,
1088+ Some ( device) => match device. register_wallet ( & wallet_name, & policy) . await {
1089+ Ok ( hmac_opt) => {
1090+ let hmac_hex = hmac_opt. map ( |h| {
1091+ let bytes: & [ u8 ] = & h;
1092+ bytes. to_lower_hex_string ( )
1093+ } ) ;
1094+ Ok ( json ! ( {
1095+ "success" : true ,
1096+ "hmac" : hmac_hex
1097+ } ) )
10971098 }
1098- } ;
1099- let mut wallet = new_persisted_wallet ( network, & mut persister, wallet_opts) ?;
1100- wallet. persist ( & mut persister) ?;
1101- wallet
1102- } ;
1103- #[ cfg( not( feature = "sqlite" ) ) ]
1104- let wallet = new_wallet ( network, wallet_opts) ?;
1105-
1106- let device = crate :: utils:: connect_to_hardware_wallet (
1107- wallet. network ( ) ,
1108- wallet_opts,
1109- Some ( wallet) ,
1110- )
1111- . await ?;
1112- let hmac = if let Some ( device) = device {
1113- let hmac = device. register_wallet ( & wallet_name, & policy) . await ?;
1114- hmac. map ( |h| h. to_lower_hex_string ( ) )
1115- } else {
1116- None
1117- } ;
1118- Ok ( json ! ( { "hmac" : hmac } ) )
1099+ Err ( e) => Err ( Error :: Generic ( format ! ( "Wallet registration failed: {e}" ) ) ) ,
1100+ } ,
1101+ }
11191102 }
11201103 HwiSubCommand :: Address => {
1104+ let ext_descriptor = hwi_opts. ext_descriptor . clone ( ) . ok_or_else ( || {
1105+ Error :: Generic ( "External descriptor required for address generation" . to_string ( ) )
1106+ } ) ?;
1107+ let wallet_name = hwi_opts. wallet . clone ( ) . ok_or_else ( || {
1108+ Error :: Generic ( "Wallet name is required for address generation" . to_string ( ) )
1109+ } ) ?;
1110+
1111+ let database = hwi_opts. database_type . clone ( ) . ok_or_else ( || {
1112+ Error :: Generic ( "Database type is required for address generation" . to_string ( ) )
1113+ } ) ?;
1114+
11211115 let home_dir = prepare_home_dir ( None ) ?;
1122- let database_path = prepare_wallet_db_dir ( & wallet_opts. wallet , & home_dir) ?;
1116+ let database_path = prepare_wallet_db_dir ( & Some ( wallet_name. clone ( ) ) , & home_dir) ?;
1117+
1118+ let wallet_opts = WalletOpts {
1119+ wallet : Some ( wallet_name) ,
1120+ verbose : false ,
1121+ ext_descriptor : Some ( ext_descriptor) ,
1122+ int_descriptor : None ,
1123+ #[ cfg( feature = "sqlite" ) ]
1124+ database_type : database,
1125+ } ;
1126+
11231127 #[ cfg( feature = "sqlite" ) ]
1124- let wallet = {
1125- let mut persister = match & wallet_opts. database_type {
1126- DatabaseType :: Sqlite => {
1127- let db_file = database_path. join ( "wallet.sqlite" ) ;
1128- let connection = Connection :: open ( db_file) ?;
1129- log:: debug!( "Sqlite database opened successfully" ) ;
1130- connection
1131- }
1132- } ;
1133- let mut wallet = new_persisted_wallet ( network, & mut persister, wallet_opts) ?;
1128+ let mut wallet = if hwi_opts. database_type . is_some ( ) {
1129+ let db_file = database_path. join ( "wallet.sqlite" ) ;
1130+ let mut persister = Connection :: open ( db_file) ?;
1131+ let mut wallet = new_persisted_wallet ( network, & mut persister, & wallet_opts) ?;
11341132 wallet. persist ( & mut persister) ?;
11351133 wallet
1134+ } else {
1135+ return Err ( Error :: Generic (
1136+ "Could not connect to sqlite database" . to_string ( ) ,
1137+ ) ) ;
11361138 } ;
1139+
11371140 #[ cfg( not( feature = "sqlite" ) ) ]
1138- let wallet = new_wallet ( network, wallet_opts) ?;
1141+ let mut wallet = new_wallet ( network, & wallet_opts) ?;
11391142
11401143 let address = wallet. next_unused_address ( KeychainKind :: External ) ;
11411144 Ok ( json ! ( { "address" : address. address } ) )
11421145 }
11431146 HwiSubCommand :: Sign { psbt } => {
1144- let home_dir = prepare_home_dir ( None ) ?;
1145- let database_path = prepare_wallet_db_dir ( & wallet_opts. wallet , & home_dir) ?;
1146- #[ cfg( feature = "sqlite" ) ]
1147- let wallet = {
1148- let mut persister = match & wallet_opts. database_type {
1149- DatabaseType :: Sqlite => {
1150- let db_file = database_path. join ( "wallet.sqlite" ) ;
1151- let connection = Connection :: open ( db_file) ?;
1152- log:: debug!( "Sqlite database opened successfully" ) ;
1153- connection
1154- }
1155- } ;
1156- let mut wallet = new_persisted_wallet ( network, & mut persister, wallet_opts) ?;
1157- wallet. persist ( & mut persister) ?;
1158- wallet
1159- } ;
1160- #[ cfg( not( feature = "sqlite" ) ) ]
1161- let wallet = new_wallet ( network, wallet_opts) ?;
1162-
11631147 let mut psbt = Psbt :: from_str ( & psbt)
11641148 . map_err ( |e| Error :: Generic ( format ! ( "Failed to parse PSBT: {e}" ) ) ) ?;
1165- let device = crate :: utils:: connect_to_hardware_wallet (
1166- wallet. network ( ) ,
1167- wallet_opts,
1168- Some ( wallet) ,
1169- )
1170- . await ?;
1149+ let device = crate :: utils:: connect_to_hardware_wallet ( network, hwi_opts) . await ?;
11711150 let signed_psbt = if let Some ( device) = device {
11721151 device
11731152 . sign_tx ( & mut psbt)
@@ -1390,6 +1369,15 @@ pub(crate) async fn handle_command(cli_opts: CliOpts) -> Result<String, Error> {
13901369 }
13911370 Ok ( "" . to_string ( ) )
13921371 }
1372+
1373+ #[ cfg( feature = "hwi" ) ]
1374+ CliSubCommand :: Hwi {
1375+ hwi_opts,
1376+ subcommand,
1377+ } => {
1378+ let result = handle_hwi_subcommand ( network, & hwi_opts, subcommand) . await ?;
1379+ Ok ( serde_json:: to_string_pretty ( & result) . map_err ( |e| Error :: SerdeJson ( e) ) ?)
1380+ }
13931381 } ;
13941382 result
13951383}
0 commit comments