@@ -4,13 +4,13 @@ use std::sync::Arc;
44
55use anyhow:: { anyhow, Context , Result } ;
66use bitcoincore_rpc:: json:: WalletCreateFundedPsbtOptions ;
7- use bitcoincore_rpc:: { Auth , Client , RpcApi } ;
7+ use bitcoincore_rpc:: { bitcoincore_rpc_json , Auth , Client , RpcApi } ;
88use payjoin:: bitcoin:: consensus:: encode:: { deserialize, serialize_hex} ;
99use payjoin:: bitcoin:: consensus:: Encodable ;
10- use payjoin:: bitcoin:: psbt:: { Input , Psbt } ;
10+ use payjoin:: bitcoin:: psbt:: Psbt ;
1111use payjoin:: bitcoin:: {
12- Address , Amount , Denomination , FeeRate , Network , OutPoint , Script , Transaction , TxIn , TxOut ,
13- Txid ,
12+ Address , AddressType , Amount , Denomination , FeeRate , Network , OutPoint , Script , Transaction ,
13+ TxOut , Txid ,
1414} ;
1515use payjoin:: receive:: InputPair ;
1616
@@ -145,7 +145,15 @@ impl BitcoindWallet {
145145 . bitcoind
146146 . list_unspent ( None , None , None , None , None )
147147 . context ( "Failed to list unspent" ) ?;
148- Ok ( unspent. into_iter ( ) . map ( input_pair_from_list_unspent) . collect ( ) )
148+
149+ unspent
150+ . into_iter ( )
151+ . map ( |utxo| {
152+ let tx = self . bitcoind . get_transaction ( & utxo. txid , Some ( true ) ) ?. transaction ( ) ?;
153+ input_pair_from_list_unspent ( utxo, tx, self . network ( ) ?)
154+ } )
155+ . collect :: < Result < Vec < InputPair > , _ > > ( )
156+ . context ( "Failed to convert list unspent entry to InputPair" )
149157 }
150158
151159 /// Get the network this wallet is operating on
@@ -158,22 +166,56 @@ impl BitcoindWallet {
158166}
159167
160168pub fn input_pair_from_list_unspent (
161- utxo : bitcoincore_rpc:: bitcoincore_rpc_json:: ListUnspentResultEntry ,
162- ) -> InputPair {
163- let psbtin = Input {
164- // NOTE: non_witness_utxo is not necessary because bitcoin-cli always supplies
165- // witness_utxo, even for non-witness inputs
166- witness_utxo : Some ( TxOut {
167- value : utxo. amount ,
168- script_pubkey : utxo. script_pub_key . clone ( ) ,
169- } ) ,
170- redeem_script : utxo. redeem_script . clone ( ) ,
171- witness_script : utxo. witness_script . clone ( ) ,
172- ..Default :: default ( )
173- } ;
174- let txin = TxIn {
175- previous_output : OutPoint { txid : utxo. txid , vout : utxo. vout } ,
176- ..Default :: default ( )
177- } ;
178- InputPair :: new ( txin, psbtin) . expect ( "Input pair should be valid" )
169+ utxo : bitcoincore_rpc_json:: ListUnspentResultEntry ,
170+ tx : Transaction ,
171+ network : Network ,
172+ ) -> Result < InputPair > {
173+ match Address :: from_script ( utxo. script_pub_key . as_script ( ) , network) ?. address_type ( ) . ok_or (
174+ anyhow ! ( "Address is unknown, non-standard or related to the future witness version" ) ,
175+ ) ? {
176+ AddressType :: P2pkh => Ok ( InputPair :: new_p2pkh (
177+ Transaction {
178+ version : tx. version ,
179+ lock_time : tx. lock_time ,
180+ input : tx. input ,
181+ output : tx. output ,
182+ } ,
183+ OutPoint { txid : utxo. txid , vout : utxo. vout } ,
184+ None , // Default sequence
185+ ) ?) ,
186+ AddressType :: P2sh => {
187+ let redeem_script = utxo. redeem_script . ok_or ( anyhow ! ( "Missing redeem script" ) ) ?;
188+ Ok ( InputPair :: new_p2sh (
189+ Transaction {
190+ version : tx. version ,
191+ lock_time : tx. lock_time ,
192+ input : tx. input ,
193+ output : tx. output ,
194+ } ,
195+ OutPoint { txid : utxo. txid , vout : utxo. vout } ,
196+ redeem_script,
197+ None , // Default sequence
198+ ) ?)
199+ }
200+ AddressType :: P2wpkh => Ok ( InputPair :: new_p2wpkh (
201+ TxOut { value : utxo. amount , script_pubkey : utxo. script_pub_key } ,
202+ OutPoint { txid : utxo. txid , vout : utxo. vout } ,
203+ None ,
204+ ) ?) ,
205+ AddressType :: P2wsh => {
206+ let witness_script = utxo. witness_script . ok_or ( anyhow ! ( "Missing witness script" ) ) ?;
207+ Ok ( InputPair :: new_p2wsh (
208+ TxOut { value : utxo. amount , script_pubkey : utxo. script_pub_key } ,
209+ OutPoint { txid : utxo. txid , vout : utxo. vout } ,
210+ witness_script,
211+ None , // Default sequence
212+ ) ?)
213+ }
214+ AddressType :: P2tr => Ok ( InputPair :: new_p2tr (
215+ TxOut { value : utxo. amount , script_pubkey : utxo. script_pub_key } ,
216+ OutPoint { txid : utxo. txid , vout : utxo. vout } ,
217+ None , // Default sequence
218+ ) ?) ,
219+ _ => Err ( anyhow ! ( "Unsupported AddressType" ) ) , // AddressType is non-exhaustive
220+ }
179221}
0 commit comments