@@ -29,7 +29,7 @@ use std::cmp::{max, min};
29
29
use bitcoin:: base64:: prelude:: BASE64_STANDARD ;
30
30
use bitcoin:: base64:: Engine ;
31
31
use bitcoin:: psbt:: Psbt ;
32
- use bitcoin:: { Amount , FeeRate , OutPoint , Script , TxIn , TxOut , Weight } ;
32
+ use bitcoin:: { psbt , AddressType , Amount , FeeRate , OutPoint , Script , TxIn , TxOut , Weight } ;
33
33
34
34
mod error;
35
35
mod optional_parameters;
@@ -47,12 +47,50 @@ use error::{
47
47
} ;
48
48
use optional_parameters:: Params ;
49
49
50
- use crate :: psbt:: { InputPair , PsbtExt } ;
50
+ use crate :: psbt:: { InternalInputPair , PsbtExt , PsbtInputError } ;
51
51
52
52
pub trait Headers {
53
53
fn get_header ( & self , key : & str ) -> Option < & str > ;
54
54
}
55
55
56
+ /// Helper to construct a pair of (txin, psbtin) with some built-in validation
57
+ /// Use with [`InputPair::new`] to contribute receiver inputs.
58
+ #[ derive( Clone , Debug ) ]
59
+ pub struct InputPair {
60
+ pub ( crate ) txin : TxIn ,
61
+ pub ( crate ) psbtin : psbt:: Input ,
62
+ }
63
+
64
+ impl InputPair {
65
+ pub fn new ( txin : TxIn , psbtin : psbt:: Input ) -> Result < Self , PsbtInputError > {
66
+ let input_pair = Self { txin, psbtin } ;
67
+ let raw = InternalInputPair :: from ( & input_pair) ;
68
+ raw. validate_utxo ( true ) ?;
69
+ let address_type = raw. address_type ( ) ?;
70
+ if address_type == AddressType :: P2sh && input_pair. psbtin . redeem_script . is_none ( ) {
71
+ return Err ( PsbtInputError :: NoRedeemScript ) ;
72
+ }
73
+ Ok ( input_pair)
74
+ }
75
+
76
+ pub ( crate ) fn address_type ( & self ) -> AddressType {
77
+ InternalInputPair :: from ( self )
78
+ . address_type ( )
79
+ . expect ( "address type should have been validated in InputPair::new" )
80
+ }
81
+
82
+ pub ( crate ) fn previous_txout ( & self ) -> TxOut {
83
+ InternalInputPair :: from ( self )
84
+ . previous_txout ( )
85
+ . expect ( "UTXO information should have been validated in InputPair::new" )
86
+ . clone ( )
87
+ }
88
+ }
89
+
90
+ impl < ' a > From < & ' a InputPair > for InternalInputPair < ' a > {
91
+ fn from ( pair : & ' a InputPair ) -> Self { Self { psbtin : & pair. psbtin , txin : & pair. txin } }
92
+ }
93
+
56
94
/// The sender's original PSBT and optional parameters
57
95
///
58
96
/// This type is used to process the request. It is returned by
0 commit comments