@@ -81,6 +81,11 @@ impl OfflineWalletSubCommand {
8181 Self :: VerifyMessage ( verify_message_command) => verify_message_command
8282 . execute ( ctx) ?
8383 . write_out ( std:: io:: stdout ( ) ) ,
84+ Self :: LockUtxo ( lock_utxo) => lock_utxo. execute ( ctx) ?. write_out ( std:: io:: stdout ( ) ) ,
85+ Self :: UnlockUtxo ( unlock_utxo) => unlock_utxo. execute ( ctx) ?. write_out ( std:: io:: stdout ( ) ) ,
86+ Self :: LockedUtxos ( locked_utxos) => {
87+ locked_utxos. execute ( ctx) ?. write_out ( std:: io:: stdout ( ) )
88+ }
8489 }
8590 }
8691}
@@ -119,9 +124,13 @@ impl AppCommand<AppContext<OfflineOperations<'_>>> for UnspentCommand {
119124
120125 fn execute ( & self , ctx : & mut AppContext < OfflineOperations < ' _ > > ) -> Result < Self :: Output , Error > {
121126 let wallet = & mut ctx. state . wallet ;
122- let utxos = wallet
123- . list_unspent ( )
124- . map ( |utxo| UnspentDetails :: from_local_output ( & utxo, ctx. network ) )
127+ let outputs: Vec < _ > = wallet. list_unspent ( ) . collect ( ) ;
128+ let utxos = outputs
129+ . into_iter ( )
130+ . map ( |utxo| {
131+ let is_locked = wallet. is_outpoint_locked ( utxo. outpoint ) ;
132+ UnspentDetails :: from_local_output ( & utxo, ctx. network , is_locked)
133+ } )
125134 . collect ( ) ;
126135
127136 Ok ( ListResult :: new ( utxos) )
@@ -841,3 +850,65 @@ impl AppCommand<AppContext<OfflineOperations<'_>>> for VerifyMessageCommand {
841850 } )
842851 }
843852}
853+
854+ #[ derive( Parser , Debug , Clone , PartialEq ) ]
855+ pub struct LockUtxoCommand {
856+ /// Outpoint(s) to lock, format TXID:VOUT.
857+ #[ arg( env = "TXID:VOUT" , long = "utxo" , required = true , value_parser = parse_outpoint) ]
858+ pub utxos : Vec < OutPoint > ,
859+ }
860+
861+ impl AppCommand < AppContext < OfflineOperations < ' _ > > > for LockUtxoCommand {
862+ type Output = ListResult < String > ;
863+ fn execute ( & self , ctx : & mut AppContext < OfflineOperations < ' _ > > ) -> Result < Self :: Output , Error > {
864+ let wallet = & mut ctx. state . wallet ;
865+ for out_point in & self . utxos {
866+ if wallet. get_utxo ( * out_point) . is_none ( ) {
867+ eprintln ! ( "warning: {out_point} is not a known wallet UTXO; locking anyway" ) ;
868+ }
869+ wallet. lock_outpoint ( * out_point) ;
870+ }
871+ let locked = wallet
872+ . list_locked_outpoints ( )
873+ . map ( |o| o. to_string ( ) )
874+ . collect ( ) ;
875+ Ok ( ListResult :: new ( locked) )
876+ }
877+ }
878+
879+ #[ derive( Parser , Debug , Clone , PartialEq ) ]
880+ pub struct UnlockUtxoCommand {
881+ /// Outpoint(s) to unlock, format TXID:VOUT.
882+ #[ arg( env = "TXID:VOUT" , long = "utxo" , required = true , value_parser = parse_outpoint) ]
883+ pub utxos : Vec < OutPoint > ,
884+ }
885+
886+ impl AppCommand < AppContext < OfflineOperations < ' _ > > > for UnlockUtxoCommand {
887+ type Output = ListResult < String > ;
888+ fn execute ( & self , ctx : & mut AppContext < OfflineOperations < ' _ > > ) -> Result < Self :: Output , Error > {
889+ let wallet = & mut ctx. state . wallet ;
890+ for out_point in & self . utxos {
891+ wallet. unlock_outpoint ( * out_point) ;
892+ }
893+ let locked = wallet
894+ . list_locked_outpoints ( )
895+ . map ( |o| o. to_string ( ) )
896+ . collect ( ) ;
897+ Ok ( ListResult :: new ( locked) )
898+ }
899+ }
900+
901+ #[ derive( Parser , Debug , Clone , PartialEq ) ]
902+ pub struct LockedUtxosCommand { }
903+
904+ impl AppCommand < AppContext < OfflineOperations < ' _ > > > for LockedUtxosCommand {
905+ type Output = ListResult < String > ;
906+ fn execute ( & self , ctx : & mut AppContext < OfflineOperations < ' _ > > ) -> Result < Self :: Output , Error > {
907+ let wallet = & mut ctx. state . wallet ;
908+ let locked = wallet
909+ . list_locked_outpoints ( )
910+ . map ( |o| o. to_string ( ) )
911+ . collect ( ) ;
912+ Ok ( ListResult :: new ( locked) )
913+ }
914+ }
0 commit comments