@@ -1047,20 +1047,14 @@ pub(crate) fn handle_compile_subcommand(
10471047#[ cfg( feature = "hwi" ) ]
10481048pub async fn handle_hwi_subcommand (
10491049 network : Network ,
1050- wallet_opts : & WalletOpts ,
1050+ hwi_opts : & HwiOpts ,
10511051 subcommand : HwiSubCommand ,
10521052) -> Result < serde_json:: Value , Error > {
10531053 match subcommand {
10541054 HwiSubCommand :: Devices => {
1055- let devices = crate :: utils:: connect_to_hardware_wallet (
1056- wallet. network ( ) ,
1057- wallet_opts,
1058- Some ( wallet) ,
1059- )
1060- . await ?;
1061- let device = if let Some ( device) = device {
1055+ let devices = crate :: utils:: connect_to_hardware_wallet ( network, hwi_opts) . await ?;
1056+ let device = if let Some ( device) = devices {
10621057 json ! ( {
1063- "type" : device. device_kind( ) . to_string( ) ,
10641058 "fingerprint" : device. get_master_fingerprint( ) . await ?. to_string( ) ,
10651059 "model" : device. device_kind( ) . to_string( ) ,
10661060 } )
@@ -1070,97 +1064,82 @@ pub async fn handle_hwi_subcommand(
10701064 Ok ( json ! ( { "devices" : device } ) )
10711065 }
10721066 HwiSubCommand :: Register => {
1073- let policy = wallet_opts . ext_descriptor . clone ( ) . ok_or_else ( || {
1067+ let policy = hwi_opts . ext_descriptor . clone ( ) . ok_or_else ( || {
10741068 Error :: Generic ( "External descriptor required for wallet registration" . to_string ( ) )
10751069 } ) ?;
1076- let wallet_name = wallet_opts . wallet . clone ( ) . ok_or_else ( || {
1070+ let wallet_name = hwi_opts . wallet . clone ( ) . ok_or_else ( || {
10771071 Error :: Generic ( "Wallet name is required for wallet registration" . to_string ( ) )
10781072 } ) ?;
10791073
1080- let home_dir = prepare_home_dir ( None ) ?;
1081- let database_path = prepare_wallet_db_dir ( & wallet_opts. wallet , & home_dir) ?;
1082- #[ cfg( feature = "sqlite" ) ]
1083- let wallet = {
1084- let mut persister = match & wallet_opts. database_type {
1085- DatabaseType :: Sqlite => {
1086- let db_file = database_path. join ( "wallet.sqlite" ) ;
1087- let connection = Connection :: open ( db_file) ?;
1088- log:: debug!( "Sqlite database opened successfully" ) ;
1089- connection
1074+ let device = crate :: utils:: connect_to_hardware_wallet ( network, hwi_opts) . await ?;
1075+
1076+ match device {
1077+ None => Ok ( json ! ( {
1078+ "success" : false ,
1079+ "error" : "No hardware wallet detected"
1080+ } ) ) ,
1081+ Some ( device) => match device. register_wallet ( & wallet_name, & policy) . await {
1082+ Ok ( hmac_opt) => {
1083+ let hmac_hex = hmac_opt. map ( |h| {
1084+ let bytes: & [ u8 ] = & h;
1085+ bytes. to_lower_hex_string ( )
1086+ } ) ;
1087+ Ok ( json ! ( {
1088+ "success" : true ,
1089+ "hmac" : hmac_hex
1090+ } ) )
10901091 }
1091- } ;
1092- let mut wallet = new_persisted_wallet ( network, & mut persister, wallet_opts) ?;
1093- wallet. persist ( & mut persister) ?;
1094- wallet
1095- } ;
1096- #[ cfg( not( feature = "sqlite" ) ) ]
1097- let wallet = new_wallet ( network, wallet_opts) ?;
1098-
1099- let device = crate :: utils:: connect_to_hardware_wallet (
1100- wallet. network ( ) ,
1101- wallet_opts,
1102- Some ( wallet) ,
1103- )
1104- . await ?;
1105- let hmac = if let Some ( device) = device {
1106- let hmac = device. register_wallet ( & wallet_name, & policy) . await ?;
1107- hmac. map ( |h| h. to_lower_hex_string ( ) )
1108- } else {
1109- None
1110- } ;
1111- Ok ( json ! ( { "hmac" : hmac } ) )
1092+ Err ( e) => Err ( Error :: Generic ( format ! ( "Wallet registration failed: {e}" ) ) ) ,
1093+ } ,
1094+ }
11121095 }
11131096 HwiSubCommand :: Address => {
1097+ let ext_descriptor = hwi_opts. ext_descriptor . clone ( ) . ok_or_else ( || {
1098+ Error :: Generic ( "External descriptor required for address generation" . to_string ( ) )
1099+ } ) ?;
1100+ let wallet_name = hwi_opts. wallet . clone ( ) . ok_or_else ( || {
1101+ Error :: Generic ( "Wallet name is required for address generation" . to_string ( ) )
1102+ } ) ?;
1103+
1104+ let database = hwi_opts. database_type . clone ( ) . ok_or_else ( || {
1105+ Error :: Generic ( "Database type is required for address generation" . to_string ( ) )
1106+ } ) ?;
1107+
11141108 let home_dir = prepare_home_dir ( None ) ?;
1115- let database_path = prepare_wallet_db_dir ( & wallet_opts. wallet , & home_dir) ?;
1109+ let database_path = prepare_wallet_db_dir ( & Some ( wallet_name. clone ( ) ) , & home_dir) ?;
1110+
1111+ let wallet_opts = WalletOpts {
1112+ wallet : Some ( wallet_name) ,
1113+ verbose : false ,
1114+ ext_descriptor : Some ( ext_descriptor) ,
1115+ int_descriptor : None ,
1116+ #[ cfg( feature = "sqlite" ) ]
1117+ database_type : database,
1118+ } ;
1119+
11161120 #[ cfg( feature = "sqlite" ) ]
1117- let wallet = {
1118- let mut persister = match & wallet_opts. database_type {
1119- DatabaseType :: Sqlite => {
1120- let db_file = database_path. join ( "wallet.sqlite" ) ;
1121- let connection = Connection :: open ( db_file) ?;
1122- log:: debug!( "Sqlite database opened successfully" ) ;
1123- connection
1124- }
1125- } ;
1126- let mut wallet = new_persisted_wallet ( network, & mut persister, wallet_opts) ?;
1121+ let mut wallet = if hwi_opts. database_type . is_some ( ) {
1122+ let db_file = database_path. join ( "wallet.sqlite" ) ;
1123+ let mut persister = Connection :: open ( db_file) ?;
1124+ let mut wallet = new_persisted_wallet ( network, & mut persister, & wallet_opts) ?;
11271125 wallet. persist ( & mut persister) ?;
11281126 wallet
1127+ } else {
1128+ return Err ( Error :: Generic (
1129+ "Could not connect to sqlite database" . to_string ( ) ,
1130+ ) ) ;
11291131 } ;
1132+
11301133 #[ cfg( not( feature = "sqlite" ) ) ]
1131- let wallet = new_wallet ( network, wallet_opts) ?;
1134+ let mut wallet = new_wallet ( network, & wallet_opts) ?;
11321135
11331136 let address = wallet. next_unused_address ( KeychainKind :: External ) ;
11341137 Ok ( json ! ( { "address" : address. address } ) )
11351138 }
11361139 HwiSubCommand :: Sign { psbt } => {
1137- let home_dir = prepare_home_dir ( None ) ?;
1138- let database_path = prepare_wallet_db_dir ( & wallet_opts. wallet , & home_dir) ?;
1139- #[ cfg( feature = "sqlite" ) ]
1140- let wallet = {
1141- let mut persister = match & wallet_opts. database_type {
1142- DatabaseType :: Sqlite => {
1143- let db_file = database_path. join ( "wallet.sqlite" ) ;
1144- let connection = Connection :: open ( db_file) ?;
1145- log:: debug!( "Sqlite database opened successfully" ) ;
1146- connection
1147- }
1148- } ;
1149- let mut wallet = new_persisted_wallet ( network, & mut persister, wallet_opts) ?;
1150- wallet. persist ( & mut persister) ?;
1151- wallet
1152- } ;
1153- #[ cfg( not( feature = "sqlite" ) ) ]
1154- let wallet = new_wallet ( network, wallet_opts) ?;
1155-
11561140 let mut psbt = Psbt :: from_str ( & psbt)
11571141 . map_err ( |e| Error :: Generic ( format ! ( "Failed to parse PSBT: {e}" ) ) ) ?;
1158- let device = crate :: utils:: connect_to_hardware_wallet (
1159- wallet. network ( ) ,
1160- wallet_opts,
1161- Some ( wallet) ,
1162- )
1163- . await ?;
1142+ let device = crate :: utils:: connect_to_hardware_wallet ( network, hwi_opts) . await ?;
11641143 let signed_psbt = if let Some ( device) = device {
11651144 device
11661145 . sign_tx ( & mut psbt)
@@ -1383,6 +1362,15 @@ pub(crate) async fn handle_command(cli_opts: CliOpts) -> Result<String, Error> {
13831362 }
13841363 Ok ( "" . to_string ( ) )
13851364 }
1365+
1366+ #[ cfg( feature = "hwi" ) ]
1367+ CliSubCommand :: Hwi {
1368+ hwi_opts,
1369+ subcommand,
1370+ } => {
1371+ let result = handle_hwi_subcommand ( network, & hwi_opts, subcommand) . await ?;
1372+ Ok ( serde_json:: to_string_pretty ( & result) . map_err ( |e| Error :: SerdeJson ( e) ) ?)
1373+ }
13861374 } ;
13871375 result
13881376}
0 commit comments