@@ -805,6 +805,28 @@ pub trait NodeSigner {
805805 fn sign_gossip_message ( & self , msg : UnsignedGossipMessage ) -> Result < Signature , ( ) > ;
806806}
807807
808+ /// A trait that describes a wallet capable of creating a spending [`Transaction`] from a set of
809+ /// [`SpendableOutputDescriptor`]s.
810+ pub trait OutputSpender {
811+ /// Creates a [`Transaction`] which spends the given descriptors to the given outputs, plus an
812+ /// output to the given change destination (if sufficient change value remains). The
813+ /// transaction will have a feerate, at least, of the given value.
814+ ///
815+ /// The `locktime` argument is used to set the transaction's locktime. If `None`, the
816+ /// transaction will have a locktime of 0. It it recommended to set this to the current block
817+ /// height to avoid fee sniping, unless you have some specific reason to use a different
818+ /// locktime.
819+ ///
820+ /// Returns `Err(())` if the output value is greater than the input value minus required fee,
821+ /// if a descriptor was duplicated, or if an output descriptor `script_pubkey`
822+ /// does not match the one we can spend.
823+ fn spend_spendable_outputs < C : Signing > (
824+ & self , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > ,
825+ change_destination_script : ScriptBuf , feerate_sat_per_1000_weight : u32 ,
826+ locktime : Option < LockTime > , secp_ctx : & Secp256k1 < C > ,
827+ ) -> Result < Transaction , ( ) > ;
828+ }
829+
808830// Primarily needed in doctests because of https://github.com/rust-lang/rust/issues/67295
809831/// A dynamic [`SignerProvider`] temporarily needed for doc tests.
810832#[ cfg( taproot) ]
@@ -1991,50 +2013,6 @@ impl KeysManager {
19912013
19922014 Ok ( psbt)
19932015 }
1994-
1995- /// Creates a [`Transaction`] which spends the given descriptors to the given outputs, plus an
1996- /// output to the given change destination (if sufficient change value remains). The
1997- /// transaction will have a feerate, at least, of the given value.
1998- ///
1999- /// The `locktime` argument is used to set the transaction's locktime. If `None`, the
2000- /// transaction will have a locktime of 0. It it recommended to set this to the current block
2001- /// height to avoid fee sniping, unless you have some specific reason to use a different
2002- /// locktime.
2003- ///
2004- /// Returns `Err(())` if the output value is greater than the input value minus required fee,
2005- /// if a descriptor was duplicated, or if an output descriptor `script_pubkey`
2006- /// does not match the one we can spend.
2007- ///
2008- /// We do not enforce that outputs meet the dust limit or that any output scripts are standard.
2009- ///
2010- /// May panic if the [`SpendableOutputDescriptor`]s were not generated by channels which used
2011- /// this [`KeysManager`] or one of the [`InMemorySigner`] created by this [`KeysManager`].
2012- pub fn spend_spendable_outputs < C : Signing > (
2013- & self , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > ,
2014- change_destination_script : ScriptBuf , feerate_sat_per_1000_weight : u32 ,
2015- locktime : Option < LockTime > , secp_ctx : & Secp256k1 < C > ,
2016- ) -> Result < Transaction , ( ) > {
2017- let ( mut psbt, expected_max_weight) =
2018- SpendableOutputDescriptor :: create_spendable_outputs_psbt (
2019- descriptors,
2020- outputs,
2021- change_destination_script,
2022- feerate_sat_per_1000_weight,
2023- locktime,
2024- ) ?;
2025- psbt = self . sign_spendable_outputs_psbt ( descriptors, psbt, secp_ctx) ?;
2026-
2027- let spend_tx = psbt. extract_tx ( ) ;
2028-
2029- debug_assert ! ( expected_max_weight >= spend_tx. weight( ) . to_wu( ) ) ;
2030- // Note that witnesses with a signature vary somewhat in size, so allow
2031- // `expected_max_weight` to overshoot by up to 3 bytes per input.
2032- debug_assert ! (
2033- expected_max_weight <= spend_tx. weight( ) . to_wu( ) + descriptors. len( ) as u64 * 3
2034- ) ;
2035-
2036- Ok ( spend_tx)
2037- }
20382016}
20392017
20402018impl EntropySource for KeysManager {
@@ -2106,6 +2084,44 @@ impl NodeSigner for KeysManager {
21062084 }
21072085}
21082086
2087+ impl OutputSpender for KeysManager {
2088+ /// Creates a [`Transaction`] which spends the given descriptors to the given outputs, plus an
2089+ /// output to the given change destination (if sufficient change value remains).
2090+ ///
2091+ /// See [`OutputSpender::spend_spendable_outputs`] documentation for more information.
2092+ ///
2093+ /// We do not enforce that outputs meet the dust limit or that any output scripts are standard.
2094+ ///
2095+ /// May panic if the [`SpendableOutputDescriptor`]s were not generated by channels which used
2096+ /// this [`KeysManager`] or one of the [`InMemorySigner`] created by this [`KeysManager`].
2097+ fn spend_spendable_outputs < C : Signing > (
2098+ & self , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > ,
2099+ change_destination_script : ScriptBuf , feerate_sat_per_1000_weight : u32 ,
2100+ locktime : Option < LockTime > , secp_ctx : & Secp256k1 < C > ,
2101+ ) -> Result < Transaction , ( ) > {
2102+ let ( mut psbt, expected_max_weight) =
2103+ SpendableOutputDescriptor :: create_spendable_outputs_psbt (
2104+ descriptors,
2105+ outputs,
2106+ change_destination_script,
2107+ feerate_sat_per_1000_weight,
2108+ locktime,
2109+ ) ?;
2110+ psbt = self . sign_spendable_outputs_psbt ( descriptors, psbt, secp_ctx) ?;
2111+
2112+ let spend_tx = psbt. extract_tx ( ) ;
2113+
2114+ debug_assert ! ( expected_max_weight >= spend_tx. weight( ) . to_wu( ) ) ;
2115+ // Note that witnesses with a signature vary somewhat in size, so allow
2116+ // `expected_max_weight` to overshoot by up to 3 bytes per input.
2117+ debug_assert ! (
2118+ expected_max_weight <= spend_tx. weight( ) . to_wu( ) + descriptors. len( ) as u64 * 3
2119+ ) ;
2120+
2121+ Ok ( spend_tx)
2122+ }
2123+ }
2124+
21092125impl SignerProvider for KeysManager {
21102126 type EcdsaSigner = InMemorySigner ;
21112127 #[ cfg( taproot) ]
@@ -2238,6 +2254,25 @@ impl NodeSigner for PhantomKeysManager {
22382254 }
22392255}
22402256
2257+ impl OutputSpender for PhantomKeysManager {
2258+ /// See [`OutputSpender::spend_spendable_outputs`] and [`KeysManager::spend_spendable_outputs`]
2259+ /// for documentation on this method.
2260+ fn spend_spendable_outputs < C : Signing > (
2261+ & self , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > ,
2262+ change_destination_script : ScriptBuf , feerate_sat_per_1000_weight : u32 ,
2263+ locktime : Option < LockTime > , secp_ctx : & Secp256k1 < C > ,
2264+ ) -> Result < Transaction , ( ) > {
2265+ self . inner . spend_spendable_outputs (
2266+ descriptors,
2267+ outputs,
2268+ change_destination_script,
2269+ feerate_sat_per_1000_weight,
2270+ locktime,
2271+ secp_ctx,
2272+ )
2273+ }
2274+ }
2275+
22412276impl SignerProvider for PhantomKeysManager {
22422277 type EcdsaSigner = InMemorySigner ;
22432278 #[ cfg( taproot) ]
@@ -2299,22 +2334,6 @@ impl PhantomKeysManager {
22992334 }
23002335 }
23012336
2302- /// See [`KeysManager::spend_spendable_outputs`] for documentation on this method.
2303- pub fn spend_spendable_outputs < C : Signing > (
2304- & self , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > ,
2305- change_destination_script : ScriptBuf , feerate_sat_per_1000_weight : u32 ,
2306- locktime : Option < LockTime > , secp_ctx : & Secp256k1 < C > ,
2307- ) -> Result < Transaction , ( ) > {
2308- self . inner . spend_spendable_outputs (
2309- descriptors,
2310- outputs,
2311- change_destination_script,
2312- feerate_sat_per_1000_weight,
2313- locktime,
2314- secp_ctx,
2315- )
2316- }
2317-
23182337 /// See [`KeysManager::derive_channel_keys`] for documentation on this method.
23192338 pub fn derive_channel_keys (
23202339 & self , channel_value_satoshis : u64 , params : & [ u8 ; 32 ] ,
0 commit comments