@@ -184,6 +184,55 @@ impl fmt::Display for AddressInfo {
184184/// A `CanonicalTx` managed by a `Wallet`.
185185pub type WalletTx < ' a > = CanonicalTx < ' a , Arc < Transaction > , ConfirmationBlockTime > ;
186186
187+ /// The finalization status for a single PSBT input.
188+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
189+ pub enum FinalizePsbtInputResult {
190+ /// The input was already finalized before this call.
191+ AlreadyFinalized ,
192+ /// The input was successfully finalized during this call.
193+ Finalized ,
194+ /// The wallet could not derive a descriptor for the input.
195+ MissingDescriptor ,
196+ /// The wallet found the descriptor but could not construct the input satisfaction.
197+ CouldNotSatisfy ,
198+ }
199+
200+ impl FinalizePsbtInputResult {
201+ /// Whether the input is finalized after this call.
202+ pub fn is_finalized ( & self ) -> bool {
203+ matches ! ( self , Self :: AlreadyFinalized | Self :: Finalized )
204+ }
205+ }
206+
207+ /// Holds per-input PSBT finalization results.
208+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
209+ pub struct FinalizePsbtResult {
210+ results : BTreeMap < usize , FinalizePsbtInputResult > ,
211+ }
212+
213+ impl FinalizePsbtResult {
214+ fn new ( results : BTreeMap < usize , FinalizePsbtInputResult > ) -> Self {
215+ Self { results }
216+ }
217+
218+ /// Whether all inputs are finalized after this call.
219+ pub fn is_finalized ( & self ) -> bool {
220+ self . results
221+ . values ( )
222+ . all ( FinalizePsbtInputResult :: is_finalized)
223+ }
224+
225+ /// Borrow the per-input finalization results.
226+ pub fn results ( & self ) -> & BTreeMap < usize , FinalizePsbtInputResult > {
227+ & self . results
228+ }
229+
230+ /// Consume the result and return the per-input finalization results.
231+ pub fn into_results ( self ) -> BTreeMap < usize , FinalizePsbtInputResult > {
232+ self . results
233+ }
234+ }
235+
187236impl Wallet {
188237 /// Build a new single descriptor [`Wallet`].
189238 ///
@@ -1796,7 +1845,7 @@ impl Wallet {
17961845
17971846 // Attempt to finalize.
17981847 if sign_options. try_finalize {
1799- self . finalize_psbt ( psbt, sign_options)
1848+ Ok ( self . finalize_psbt ( psbt, sign_options) ? . is_finalized ( ) )
18001849 } else {
18011850 Ok ( false )
18021851 }
@@ -1834,14 +1883,15 @@ impl Wallet {
18341883 /// and [BIP371](https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki)
18351884 /// for further information.
18361885 ///
1837- /// Returns `true` if the PSBT could be finalized, and `false` otherwise.
1886+ /// Returns per-input finalization results. Use `FinalizePsbtResult::is_finalized` to check
1887+ /// whether every input is finalized after this call.
18381888 ///
18391889 /// The [`SignOptions`] can be used to tweak the behavior of the finalizer.
18401890 pub fn finalize_psbt (
18411891 & self ,
18421892 psbt : & mut Psbt ,
18431893 sign_options : SignOptions ,
1844- ) -> Result < bool , SignerError > {
1894+ ) -> Result < FinalizePsbtResult , SignerError > {
18451895 let tx = & psbt. unsigned_tx ;
18461896 let chain_tip = self . chain . tip ( ) . block_id ( ) ;
18471897 let prev_txids = tx
@@ -1867,14 +1917,15 @@ impl Wallet {
18671917 } )
18681918 . collect :: < HashMap < Txid , u32 > > ( ) ;
18691919
1870- let mut finished = true ;
1920+ let mut results = BTreeMap :: new ( ) ;
18711921
18721922 for ( n, input) in tx. input . iter ( ) . enumerate ( ) {
18731923 let psbt_input = & psbt
18741924 . inputs
18751925 . get ( n)
18761926 . ok_or ( IndexOutOfBoundsError :: new ( n, psbt. inputs . len ( ) ) ) ?;
18771927 if psbt_input. final_script_sig . is_some ( ) || psbt_input. final_script_witness . is_some ( ) {
1928+ results. insert ( n, FinalizePsbtInputResult :: AlreadyFinalized ) ;
18781929 continue ;
18791930 }
18801931 let confirmation_height = confirmation_heights
@@ -1927,23 +1978,29 @@ impl Wallet {
19271978 if !tmp_input. witness . is_empty ( ) {
19281979 psbt_input. final_script_witness = Some ( tmp_input. witness ) ;
19291980 }
1981+ results. insert ( n, FinalizePsbtInputResult :: Finalized ) ;
1982+ }
1983+ Err ( _) => {
1984+ results. insert ( n, FinalizePsbtInputResult :: CouldNotSatisfy ) ;
19301985 }
1931- Err ( _) => finished = false ,
19321986 }
19331987 }
1934- None => finished = false ,
1988+ None => {
1989+ results. insert ( n, FinalizePsbtInputResult :: MissingDescriptor ) ;
1990+ }
19351991 }
19361992 }
19371993
19381994 // Clear derivation paths from outputs.
1939- if finished {
1995+ let finalized = FinalizePsbtResult :: new ( results) ;
1996+ if finalized. is_finalized ( ) {
19401997 for output in & mut psbt. outputs {
19411998 output. bip32_derivation . clear ( ) ;
19421999 output. tap_key_origins . clear ( ) ;
19432000 }
19442001 }
19452002
1946- Ok ( finished )
2003+ Ok ( finalized )
19472004 }
19482005
19492006 /// Return the secp256k1 context used for all signing operations.
0 commit comments