bitcoin/psbt/
mod.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Partially Signed Bitcoin Transactions.
4//!
5//! Implementation of BIP174 Partially Signed Bitcoin Transaction Format as
6//! defined at <https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki>
7//! except we define PSBTs containing non-standard sighash types as invalid.
8//!
9
10#[macro_use]
11mod macros;
12mod error;
13mod map;
14pub mod raw;
15pub mod serialize;
16
17use core::{cmp, fmt};
18#[cfg(feature = "std")]
19use std::collections::{HashMap, HashSet};
20
21use internals::write_err;
22use secp256k1::{Keypair, Message, Secp256k1, Signing, Verification};
23
24use crate::bip32::{self, DerivationPath, KeySource, Xpriv, Xpub};
25use crate::blockdata::transaction::{self, Transaction, TxOut};
26use crate::crypto::key::{PrivateKey, PublicKey};
27use crate::crypto::{ecdsa, taproot};
28use crate::key::{TapTweak, XOnlyPublicKey};
29use crate::prelude::*;
30use crate::sighash::{self, EcdsaSighashType, Prevouts, SighashCache};
31use crate::{Amount, FeeRate, TapLeafHash, TapSighashType};
32
33#[rustfmt::skip]                // Keep public re-exports separate.
34#[doc(inline)]
35pub use self::{
36    map::{Input, Output, PsbtSighashType},
37    error::Error,
38};
39
40/// A Partially Signed Transaction.
41#[derive(Debug, Clone, PartialEq, Eq, Hash)]
42#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
43#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
44pub struct Psbt {
45    /// The unsigned transaction, scriptSigs and witnesses for each input must be empty.
46    pub unsigned_tx: Transaction,
47    /// The version number of this PSBT. If omitted, the version number is 0.
48    pub version: u32,
49    /// A global map from extended public keys to the used key fingerprint and
50    /// derivation path as defined by BIP 32.
51    pub xpub: BTreeMap<Xpub, KeySource>,
52    /// Global proprietary key-value pairs.
53    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
54    pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
55    /// Unknown global key-value pairs.
56    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
57    pub unknown: BTreeMap<raw::Key, Vec<u8>>,
58
59    /// The corresponding key-value map for each input in the unsigned transaction.
60    pub inputs: Vec<Input>,
61    /// The corresponding key-value map for each output in the unsigned transaction.
62    pub outputs: Vec<Output>,
63}
64
65impl Psbt {
66    /// Returns an iterator for the funding UTXOs of the psbt
67    ///
68    /// For each PSBT input that contains UTXO information `Ok` is returned containing that information.
69    /// The order of returned items is same as the order of inputs.
70    ///
71    /// ## Errors
72    ///
73    /// The function returns error when UTXO information is not present or is invalid.
74    ///
75    /// ## Panics
76    ///
77    /// The function panics if the length of transaction inputs is not equal to the length of PSBT inputs.
78    pub fn iter_funding_utxos(&self) -> impl Iterator<Item = Result<&TxOut, Error>> {
79        assert_eq!(self.inputs.len(), self.unsigned_tx.input.len());
80        self.unsigned_tx.input.iter().zip(&self.inputs).map(|(tx_input, psbt_input)| {
81            match (&psbt_input.witness_utxo, &psbt_input.non_witness_utxo) {
82                (Some(witness_utxo), _) => Ok(witness_utxo),
83                (None, Some(non_witness_utxo)) => {
84                    let vout = tx_input.previous_output.vout as usize;
85                    non_witness_utxo.output.get(vout).ok_or(Error::PsbtUtxoOutOfbounds)
86                }
87                (None, None) => Err(Error::MissingUtxo),
88            }
89        })
90    }
91
92    /// Checks that unsigned transaction does not have scriptSig's or witness data.
93    fn unsigned_tx_checks(&self) -> Result<(), Error> {
94        for txin in &self.unsigned_tx.input {
95            if !txin.script_sig.is_empty() {
96                return Err(Error::UnsignedTxHasScriptSigs);
97            }
98
99            if !txin.witness.is_empty() {
100                return Err(Error::UnsignedTxHasScriptWitnesses);
101            }
102        }
103
104        Ok(())
105    }
106
107    /// Creates a PSBT from an unsigned transaction.
108    ///
109    /// # Errors
110    ///
111    /// If transactions is not unsigned.
112    pub fn from_unsigned_tx(tx: Transaction) -> Result<Self, Error> {
113        let psbt = Psbt {
114            inputs: vec![Default::default(); tx.input.len()],
115            outputs: vec![Default::default(); tx.output.len()],
116
117            unsigned_tx: tx,
118            xpub: Default::default(),
119            version: 0,
120            proprietary: Default::default(),
121            unknown: Default::default(),
122        };
123        psbt.unsigned_tx_checks()?;
124        Ok(psbt)
125    }
126
127    /// The default `max_fee_rate` value used for extracting transactions with [`extract_tx`]
128    ///
129    /// As of 2023, even the biggest overpayers during the highest fee markets only paid around
130    /// 1000 sats/vByte. 25k sats/vByte is obviously a mistake at this point.
131    ///
132    /// [`extract_tx`]: Psbt::extract_tx
133    pub const DEFAULT_MAX_FEE_RATE: FeeRate = FeeRate::from_sat_per_vb_unchecked(25_000);
134
135    /// An alias for [`extract_tx_fee_rate_limit`].
136    ///
137    /// [`extract_tx_fee_rate_limit`]: Psbt::extract_tx_fee_rate_limit
138    pub fn extract_tx(self) -> Result<Transaction, ExtractTxError> {
139        self.internal_extract_tx_with_fee_rate_limit(Self::DEFAULT_MAX_FEE_RATE)
140    }
141
142    /// Extracts the [`Transaction`] from a [`Psbt`] by filling in the available signature information.
143    ///
144    /// ## Errors
145    ///
146    /// [`ExtractTxError`] variants will contain either the [`Psbt`] itself or the [`Transaction`]
147    /// that was extracted. These can be extracted from the Errors in order to recover.
148    /// See the error documentation for info on the variants. In general, it covers large fees.
149    pub fn extract_tx_fee_rate_limit(self) -> Result<Transaction, ExtractTxError> {
150        self.internal_extract_tx_with_fee_rate_limit(Self::DEFAULT_MAX_FEE_RATE)
151    }
152
153    /// Extracts the [`Transaction`] from a [`Psbt`] by filling in the available signature information.
154    ///
155    /// ## Errors
156    ///
157    /// See [`extract_tx`].
158    ///
159    /// [`extract_tx`]: Psbt::extract_tx
160    pub fn extract_tx_with_fee_rate_limit(
161        self,
162        max_fee_rate: FeeRate,
163    ) -> Result<Transaction, ExtractTxError> {
164        self.internal_extract_tx_with_fee_rate_limit(max_fee_rate)
165    }
166
167    /// Perform [`extract_tx_fee_rate_limit`] without the fee rate check.
168    ///
169    /// This can result in a transaction with absurdly high fees. Use with caution.
170    ///
171    /// [`extract_tx_fee_rate_limit`]: Psbt::extract_tx_fee_rate_limit
172    pub fn extract_tx_unchecked_fee_rate(self) -> Transaction { self.internal_extract_tx() }
173
174    #[inline]
175    fn internal_extract_tx(self) -> Transaction {
176        let mut tx: Transaction = self.unsigned_tx;
177
178        for (vin, psbtin) in tx.input.iter_mut().zip(self.inputs.into_iter()) {
179            vin.script_sig = psbtin.final_script_sig.unwrap_or_default();
180            vin.witness = psbtin.final_script_witness.unwrap_or_default();
181        }
182
183        tx
184    }
185
186    #[inline]
187    fn internal_extract_tx_with_fee_rate_limit(
188        self,
189        max_fee_rate: FeeRate,
190    ) -> Result<Transaction, ExtractTxError> {
191        let fee = match self.fee() {
192            Ok(fee) => fee,
193            Err(Error::MissingUtxo) =>
194                return Err(ExtractTxError::MissingInputValue { tx: self.internal_extract_tx() }),
195            Err(Error::NegativeFee) => return Err(ExtractTxError::SendingTooMuch { psbt: self }),
196            Err(Error::FeeOverflow) =>
197                return Err(ExtractTxError::AbsurdFeeRate {
198                    fee_rate: FeeRate::MAX,
199                    tx: self.internal_extract_tx(),
200                }),
201            _ => unreachable!(),
202        };
203
204        // Note: Move prevents usage of &self from now on.
205        let tx = self.internal_extract_tx();
206
207        // Now that the extracted Transaction is made, decide how to return it.
208        let fee_rate =
209            FeeRate::from_sat_per_kwu(fee.to_sat().saturating_mul(1000) / tx.weight().to_wu());
210        // Prefer to return an AbsurdFeeRate error when both trigger.
211        if fee_rate > max_fee_rate {
212            return Err(ExtractTxError::AbsurdFeeRate { fee_rate, tx });
213        }
214
215        Ok(tx)
216    }
217
218    /// Combines this [`Psbt`] with `other` PSBT as described by BIP 174.
219    ///
220    /// In accordance with BIP 174 this function is commutative i.e., `A.combine(B) == B.combine(A)`
221    pub fn combine(&mut self, other: Self) -> Result<(), Error> {
222        if self.unsigned_tx != other.unsigned_tx {
223            return Err(Error::UnexpectedUnsignedTx {
224                expected: Box::new(self.unsigned_tx.clone()),
225                actual: Box::new(other.unsigned_tx),
226            });
227        }
228
229        // BIP 174: The Combiner must remove any duplicate key-value pairs, in accordance with
230        //          the specification. It can pick arbitrarily when conflicts occur.
231
232        // Keeping the highest version
233        self.version = cmp::max(self.version, other.version);
234
235        // Merging xpubs
236        for (xpub, (fingerprint1, derivation1)) in other.xpub {
237            match self.xpub.entry(xpub) {
238                btree_map::Entry::Vacant(entry) => {
239                    entry.insert((fingerprint1, derivation1));
240                }
241                btree_map::Entry::Occupied(mut entry) => {
242                    // Here in case of the conflict we select the version with algorithm:
243                    // 1) if everything is equal we do nothing
244                    // 2) report an error if
245                    //    - derivation paths are equal and fingerprints are not
246                    //    - derivation paths are of the same length, but not equal
247                    //    - derivation paths has different length, but the shorter one
248                    //      is not the strict suffix of the longer one
249                    // 3) choose longest derivation otherwise
250
251                    let (fingerprint2, derivation2) = entry.get().clone();
252
253                    if (derivation1 == derivation2 && fingerprint1 == fingerprint2)
254                        || (derivation1.len() < derivation2.len()
255                            && derivation1[..]
256                                == derivation2[derivation2.len() - derivation1.len()..])
257                    {
258                        continue;
259                    } else if derivation2[..]
260                        == derivation1[derivation1.len() - derivation2.len()..]
261                    {
262                        entry.insert((fingerprint1, derivation1));
263                        continue;
264                    }
265                    return Err(Error::CombineInconsistentKeySources(Box::new(xpub)));
266                }
267            }
268        }
269
270        self.proprietary.extend(other.proprietary);
271        self.unknown.extend(other.unknown);
272
273        for (self_input, other_input) in self.inputs.iter_mut().zip(other.inputs.into_iter()) {
274            self_input.combine(other_input);
275        }
276
277        for (self_output, other_output) in self.outputs.iter_mut().zip(other.outputs.into_iter()) {
278            self_output.combine(other_output);
279        }
280
281        Ok(())
282    }
283
284    /// Attempts to create _all_ the required signatures for this PSBT using `k`.
285    ///
286    /// If you just want to sign an input with one specific key consider using `sighash_ecdsa` or
287    /// `sighash_taproot`. This function does not support scripts that contain `OP_CODESEPARATOR`.
288    ///
289    /// # Returns
290    ///
291    /// A map of input index -> keys used to sign, for Taproot specifics please see [`SigningKeys`].
292    ///
293    /// If an error is returned some signatures may already have been added to the PSBT. Since
294    /// `partial_sigs` is a [`BTreeMap`] it is safe to retry, previous sigs will be overwritten.
295    pub fn sign<C, K>(
296        &mut self,
297        k: &K,
298        secp: &Secp256k1<C>,
299    ) -> Result<SigningKeysMap, (SigningKeysMap, SigningErrors)>
300    where
301        C: Signing + Verification,
302        K: GetKey,
303    {
304        let tx = self.unsigned_tx.clone(); // clone because we need to mutably borrow when signing.
305        let mut cache = SighashCache::new(&tx);
306
307        let mut used = BTreeMap::new();
308        let mut errors = BTreeMap::new();
309
310        for i in 0..self.inputs.len() {
311            match self.signing_algorithm(i) {
312                Ok(SigningAlgorithm::Ecdsa) =>
313                    match self.bip32_sign_ecdsa(k, i, &mut cache, secp) {
314                        Ok(v) => {
315                            used.insert(i, SigningKeys::Ecdsa(v));
316                        }
317                        Err(e) => {
318                            errors.insert(i, e);
319                        }
320                    },
321                Ok(SigningAlgorithm::Schnorr) => {
322                    match self.bip32_sign_schnorr(k, i, &mut cache, secp) {
323                        Ok(v) => {
324                            used.insert(i, SigningKeys::Schnorr(v));
325                        }
326                        Err(e) => {
327                            errors.insert(i, e);
328                        }
329                    }
330                }
331                Err(e) => {
332                    errors.insert(i, e);
333                }
334            }
335        }
336        if errors.is_empty() {
337            Ok(used)
338        } else {
339            Err((used, errors))
340        }
341    }
342
343    /// Attempts to create all signatures required by this PSBT's `bip32_derivation` field, adding
344    /// them to `partial_sigs`.
345    ///
346    /// # Returns
347    ///
348    /// - Ok: A list of the public keys used in signing.
349    /// - Err: Error encountered trying to calculate the sighash AND we had the signing key.
350    fn bip32_sign_ecdsa<C, K, T>(
351        &mut self,
352        k: &K,
353        input_index: usize,
354        cache: &mut SighashCache<T>,
355        secp: &Secp256k1<C>,
356    ) -> Result<Vec<PublicKey>, SignError>
357    where
358        C: Signing,
359        T: Borrow<Transaction>,
360        K: GetKey,
361    {
362        let msg_sighash_ty_res = self.sighash_ecdsa(input_index, cache);
363
364        let input = &mut self.inputs[input_index]; // Index checked in call to `sighash_ecdsa`.
365
366        let mut used = vec![]; // List of pubkeys used to sign the input.
367
368        for (pk, key_source) in input.bip32_derivation.iter() {
369            let sk = if let Ok(Some(sk)) = k.get_key(KeyRequest::Bip32(key_source.clone()), secp) {
370                sk
371            } else if let Ok(Some(sk)) = k.get_key(KeyRequest::Pubkey(PublicKey::new(*pk)), secp) {
372                sk
373            } else {
374                continue;
375            };
376
377            // Only return the error if we have a secret key to sign this input.
378            let (msg, sighash_ty) = match msg_sighash_ty_res {
379                Err(e) => return Err(e),
380                Ok((msg, sighash_ty)) => (msg, sighash_ty),
381            };
382
383            let sig = ecdsa::Signature {
384                signature: secp.sign_ecdsa(&msg, &sk.inner),
385                sighash_type: sighash_ty,
386            };
387
388            let pk = sk.public_key(secp);
389
390            input.partial_sigs.insert(pk, sig);
391            used.push(pk);
392        }
393
394        Ok(used)
395    }
396
397    /// Attempts to create all signatures required by this PSBT's `tap_key_origins` field, adding
398    /// them to `tap_key_sig` or `tap_script_sigs`.
399    ///
400    /// # Returns
401    ///
402    /// - Ok: A list of the xonly public keys used in signing. When signing a key path spend we
403    ///   return the internal key.
404    /// - Err: Error encountered trying to calculate the sighash AND we had the signing key.
405    fn bip32_sign_schnorr<C, K, T>(
406        &mut self,
407        k: &K,
408        input_index: usize,
409        cache: &mut SighashCache<T>,
410        secp: &Secp256k1<C>,
411    ) -> Result<Vec<XOnlyPublicKey>, SignError>
412    where
413        C: Signing + Verification,
414        T: Borrow<Transaction>,
415        K: GetKey,
416    {
417        let mut input = self.checked_input(input_index)?.clone();
418
419        let mut used = vec![]; // List of pubkeys used to sign the input.
420
421        for (&xonly, (leaf_hashes, key_source)) in input.tap_key_origins.iter() {
422            let sk = if let Ok(Some(secret_key)) =
423                k.get_key(KeyRequest::Bip32(key_source.clone()), secp)
424            {
425                secret_key
426            } else if let Ok(Some(sk)) = k.get_key(KeyRequest::XOnlyPubkey(xonly), secp) {
427                sk
428            } else {
429                continue;
430            };
431
432            // Considering the responsibility of the PSBT's finalizer to extract valid signatures,
433            // the goal of this algorithm is to provide signatures to the best of our ability:
434            // 1) If the conditions for key path spend are met, proceed to provide the signature for key path spend
435            // 2) If the conditions for script path spend are met, proceed to provide the signature for script path spend
436
437            // key path spend
438            if let Some(internal_key) = input.tap_internal_key {
439                // BIP 371: The internal key does not have leaf hashes, so can be indicated with a hashes len of 0.
440
441                // Based on input.tap_internal_key.is_some() alone, it is not sufficient to determine whether it is a key path spend.
442                // According to BIP 371, we also need to consider the condition leaf_hashes.is_empty() for a more accurate determination.
443                if internal_key == xonly && leaf_hashes.is_empty() && input.tap_key_sig.is_none() {
444                    let (msg, sighash_type) = self.sighash_taproot(input_index, cache, None)?;
445                    let key_pair = Keypair::from_secret_key(secp, &sk.inner)
446                        .tap_tweak(secp, input.tap_merkle_root)
447                        .to_keypair();
448
449                    #[cfg(feature = "rand-std")]
450                    let signature = secp.sign_schnorr(&msg, &key_pair);
451                    #[cfg(not(feature = "rand-std"))]
452                    let signature = secp.sign_schnorr_no_aux_rand(&msg, &key_pair);
453
454                    let signature = taproot::Signature { signature, sighash_type };
455                    input.tap_key_sig = Some(signature);
456
457                    used.push(internal_key);
458                }
459            }
460
461            // script path spend
462            if let Some((leaf_hashes, _)) = input.tap_key_origins.get(&xonly) {
463                let leaf_hashes = leaf_hashes
464                    .iter()
465                    .filter(|lh| !input.tap_script_sigs.contains_key(&(xonly, **lh)))
466                    .cloned()
467                    .collect::<Vec<_>>();
468
469                if !leaf_hashes.is_empty() {
470                    let key_pair = Keypair::from_secret_key(secp, &sk.inner);
471
472                    for lh in leaf_hashes {
473                        let (msg, sighash_type) =
474                            self.sighash_taproot(input_index, cache, Some(lh))?;
475
476                        #[cfg(feature = "rand-std")]
477                        let signature = secp.sign_schnorr(&msg, &key_pair);
478                        #[cfg(not(feature = "rand-std"))]
479                        let signature = secp.sign_schnorr_no_aux_rand(&msg, &key_pair);
480
481                        let signature = taproot::Signature { signature, sighash_type };
482                        input.tap_script_sigs.insert((xonly, lh), signature);
483                    }
484
485                    used.push(sk.public_key(secp).into());
486                }
487            }
488        }
489
490        self.inputs[input_index] = input; // input_index is checked above.
491
492        Ok(used)
493    }
494
495    /// Returns the sighash message to sign an ECDSA input along with the sighash type.
496    ///
497    /// Uses the [`EcdsaSighashType`] from this input if one is specified. If no sighash type is
498    /// specified uses [`EcdsaSighashType::All`]. This function does not support scripts that
499    /// contain `OP_CODESEPARATOR`.
500    pub fn sighash_ecdsa<T: Borrow<Transaction>>(
501        &self,
502        input_index: usize,
503        cache: &mut SighashCache<T>,
504    ) -> Result<(Message, EcdsaSighashType), SignError> {
505        use OutputType::*;
506
507        if self.signing_algorithm(input_index)? != SigningAlgorithm::Ecdsa {
508            return Err(SignError::WrongSigningAlgorithm);
509        }
510
511        let input = self.checked_input(input_index)?;
512        let utxo = self.spend_utxo(input_index)?;
513        let spk = &utxo.script_pubkey; // scriptPubkey for input spend utxo.
514
515        let hash_ty = input.ecdsa_hash_ty().map_err(|_| SignError::InvalidSighashType)?; // Only support standard sighash types.
516
517        match self.output_type(input_index)? {
518            Bare => {
519                let sighash = cache
520                    .legacy_signature_hash(input_index, spk, hash_ty.to_u32())
521                    .expect("input checked above");
522                Ok((Message::from(sighash), hash_ty))
523            }
524            Sh => {
525                let script_code =
526                    input.redeem_script.as_ref().ok_or(SignError::MissingRedeemScript)?;
527                let sighash = cache
528                    .legacy_signature_hash(input_index, script_code, hash_ty.to_u32())
529                    .expect("input checked above");
530                Ok((Message::from(sighash), hash_ty))
531            }
532            Wpkh => {
533                let sighash = cache.p2wpkh_signature_hash(input_index, spk, utxo.value, hash_ty)?;
534                Ok((Message::from(sighash), hash_ty))
535            }
536            ShWpkh => {
537                let redeem_script = input.redeem_script.as_ref().expect("checked above");
538                let sighash =
539                    cache.p2wpkh_signature_hash(input_index, redeem_script, utxo.value, hash_ty)?;
540                Ok((Message::from(sighash), hash_ty))
541            }
542            Wsh | ShWsh => {
543                let witness_script =
544                    input.witness_script.as_ref().ok_or(SignError::MissingWitnessScript)?;
545                let sighash = cache
546                    .p2wsh_signature_hash(input_index, witness_script, utxo.value, hash_ty)
547                    .map_err(SignError::SegwitV0Sighash)?;
548                Ok((Message::from(sighash), hash_ty))
549            }
550            Tr => {
551                // This PSBT signing API is WIP, taproot to come shortly.
552                Err(SignError::Unsupported)
553            }
554        }
555    }
556
557    /// Returns the sighash message to sign an SCHNORR input along with the sighash type.
558    ///
559    /// Uses the [`TapSighashType`] from this input if one is specified. If no sighash type is
560    /// specified uses [`TapSighashType::Default`].
561    fn sighash_taproot<T: Borrow<Transaction>>(
562        &self,
563        input_index: usize,
564        cache: &mut SighashCache<T>,
565        leaf_hash: Option<TapLeafHash>,
566    ) -> Result<(Message, TapSighashType), SignError> {
567        use OutputType::*;
568
569        if self.signing_algorithm(input_index)? != SigningAlgorithm::Schnorr {
570            return Err(SignError::WrongSigningAlgorithm);
571        }
572
573        let input = self.checked_input(input_index)?;
574
575        match self.output_type(input_index)? {
576            Tr => {
577                let hash_ty = input
578                    .sighash_type
579                    .unwrap_or_else(|| TapSighashType::Default.into())
580                    .taproot_hash_ty()
581                    .map_err(|_| SignError::InvalidSighashType)?;
582
583                let spend_utxos =
584                    (0..self.inputs.len()).map(|i| self.spend_utxo(i).ok()).collect::<Vec<_>>();
585                let all_spend_utxos;
586
587                let is_anyone_can_pay = PsbtSighashType::from(hash_ty).to_u32() & 0x80 != 0;
588
589                let prev_outs = if is_anyone_can_pay {
590                    Prevouts::One(
591                        input_index,
592                        spend_utxos[input_index].ok_or(SignError::MissingSpendUtxo)?,
593                    )
594                } else if spend_utxos.iter().all(Option::is_some) {
595                    all_spend_utxos = spend_utxos.iter().filter_map(|x| *x).collect::<Vec<_>>();
596                    Prevouts::All(&all_spend_utxos)
597                } else {
598                    return Err(SignError::MissingSpendUtxo);
599                };
600
601                let sighash = if let Some(leaf_hash) = leaf_hash {
602                    cache.taproot_script_spend_signature_hash(
603                        input_index,
604                        &prev_outs,
605                        leaf_hash,
606                        hash_ty,
607                    )?
608                } else {
609                    cache.taproot_key_spend_signature_hash(input_index, &prev_outs, hash_ty)?
610                };
611                Ok((Message::from(sighash), hash_ty))
612            }
613            _ => Err(SignError::Unsupported),
614        }
615    }
616
617    /// Returns the spending utxo for this PSBT's input at `input_index`.
618    pub fn spend_utxo(&self, input_index: usize) -> Result<&TxOut, SignError> {
619        let input = self.checked_input(input_index)?;
620        let utxo = if let Some(witness_utxo) = &input.witness_utxo {
621            witness_utxo
622        } else if let Some(non_witness_utxo) = &input.non_witness_utxo {
623            let vout = self.unsigned_tx.input[input_index].previous_output.vout;
624            &non_witness_utxo.output[vout as usize]
625        } else {
626            return Err(SignError::MissingSpendUtxo);
627        };
628        Ok(utxo)
629    }
630
631    /// Gets the input at `input_index` after checking that it is a valid index.
632    fn checked_input(&self, input_index: usize) -> Result<&Input, IndexOutOfBoundsError> {
633        self.check_index_is_within_bounds(input_index)?;
634        Ok(&self.inputs[input_index])
635    }
636
637    /// Checks `input_index` is within bounds for the PSBT `inputs` array and
638    /// for the PSBT `unsigned_tx` `input` array.
639    fn check_index_is_within_bounds(
640        &self,
641        input_index: usize,
642    ) -> Result<(), IndexOutOfBoundsError> {
643        if input_index >= self.inputs.len() {
644            return Err(IndexOutOfBoundsError::Inputs {
645                index: input_index,
646                length: self.inputs.len(),
647            });
648        }
649
650        if input_index >= self.unsigned_tx.input.len() {
651            return Err(IndexOutOfBoundsError::TxInput {
652                index: input_index,
653                length: self.unsigned_tx.input.len(),
654            });
655        }
656
657        Ok(())
658    }
659
660    /// Returns the algorithm used to sign this PSBT's input at `input_index`.
661    fn signing_algorithm(&self, input_index: usize) -> Result<SigningAlgorithm, SignError> {
662        let output_type = self.output_type(input_index)?;
663        Ok(output_type.signing_algorithm())
664    }
665
666    /// Returns the [`OutputType`] of the spend utxo for this PBST's input at `input_index`.
667    fn output_type(&self, input_index: usize) -> Result<OutputType, SignError> {
668        let input = self.checked_input(input_index)?;
669        let utxo = self.spend_utxo(input_index)?;
670        let spk = utxo.script_pubkey.clone();
671
672        // Anything that is not segwit and is not p2sh is `Bare`.
673        if !(spk.is_witness_program() || spk.is_p2sh()) {
674            return Ok(OutputType::Bare);
675        }
676
677        if spk.is_p2wpkh() {
678            return Ok(OutputType::Wpkh);
679        }
680
681        if spk.is_p2wsh() {
682            return Ok(OutputType::Wsh);
683        }
684
685        if spk.is_p2sh() {
686            if input.redeem_script.as_ref().map(|s| s.is_p2wpkh()).unwrap_or(false) {
687                return Ok(OutputType::ShWpkh);
688            }
689            if input.redeem_script.as_ref().map(|x| x.is_p2wsh()).unwrap_or(false) {
690                return Ok(OutputType::ShWsh);
691            }
692            return Ok(OutputType::Sh);
693        }
694
695        if spk.is_p2tr() {
696            return Ok(OutputType::Tr);
697        }
698
699        // Something is wrong with the input scriptPubkey or we do not know how to sign
700        // because there has been a new softfork that we do not yet support.
701        Err(SignError::UnknownOutputType)
702    }
703
704    /// Calculates transaction fee.
705    ///
706    /// 'Fee' being the amount that will be paid for mining a transaction with the current inputs
707    /// and outputs i.e., the difference in value of the total inputs and the total outputs.
708    ///
709    /// ## Errors
710    ///
711    /// - [`Error::MissingUtxo`] when UTXO information for any input is not present or is invalid.
712    /// - [`Error::NegativeFee`] if calculated value is negative.
713    /// - [`Error::FeeOverflow`] if an integer overflow occurs.
714    pub fn fee(&self) -> Result<Amount, Error> {
715        let mut inputs: u64 = 0;
716        for utxo in self.iter_funding_utxos() {
717            inputs = inputs.checked_add(utxo?.value.to_sat()).ok_or(Error::FeeOverflow)?;
718        }
719        let mut outputs: u64 = 0;
720        for out in &self.unsigned_tx.output {
721            outputs = outputs.checked_add(out.value.to_sat()).ok_or(Error::FeeOverflow)?;
722        }
723        inputs.checked_sub(outputs).map(Amount::from_sat).ok_or(Error::NegativeFee)
724    }
725}
726
727/// Data required to call [`GetKey`] to get the private key to sign an input.
728#[derive(Clone, Debug, PartialEq, Eq)]
729#[non_exhaustive]
730pub enum KeyRequest {
731    /// Request a private key using the associated public key.
732    Pubkey(PublicKey),
733    /// Request a private key using BIP-32 fingerprint and derivation path.
734    Bip32(KeySource),
735    /// Request a private key using the associated x-only public key.
736    XOnlyPubkey(XOnlyPublicKey),
737}
738
739/// Trait to get a private key from a key request, key is then used to sign an input.
740pub trait GetKey {
741    /// An error occurred while getting the key.
742    type Error: core::fmt::Debug;
743
744    /// Attempts to get the private key for `key_request`.
745    ///
746    /// # Returns
747    /// - `Some(key)` if the key is found.
748    /// - `None` if the key was not found but no error was encountered.
749    /// - `Err` if an error was encountered while looking for the key.
750    fn get_key<C: Signing>(
751        &self,
752        key_request: KeyRequest,
753        secp: &Secp256k1<C>,
754    ) -> Result<Option<PrivateKey>, Self::Error>;
755}
756
757impl GetKey for Xpriv {
758    type Error = GetKeyError;
759
760    fn get_key<C: Signing>(
761        &self,
762        key_request: KeyRequest,
763        secp: &Secp256k1<C>,
764    ) -> Result<Option<PrivateKey>, Self::Error> {
765        match key_request {
766            KeyRequest::Pubkey(_) => Err(GetKeyError::NotSupported),
767            KeyRequest::XOnlyPubkey(_) => Err(GetKeyError::NotSupported),
768            KeyRequest::Bip32((fingerprint, path)) => {
769                let key = if self.fingerprint(secp) == fingerprint {
770                    let k = self.derive_priv(secp, &path)?;
771                    Some(k.to_priv())
772                } else if self.parent_fingerprint == fingerprint
773                    && !path.is_empty()
774                    && path[0] == self.child_number
775                {
776                    let path = DerivationPath::from_iter(path.into_iter().skip(1).copied());
777                    let k = self.derive_priv(secp, &path)?;
778                    Some(k.to_priv())
779                } else {
780                    None
781                };
782                Ok(key)
783            }
784        }
785    }
786}
787
788/// Map of input index -> signing key for that input (see [`SigningKeys`]).
789pub type SigningKeysMap = BTreeMap<usize, SigningKeys>;
790
791/// A list of keys used to sign an input.
792#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
793pub enum SigningKeys {
794    /// Keys used to sign an ECDSA input.
795    Ecdsa(Vec<PublicKey>),
796    /// Keys used to sign a Taproot input.
797    ///
798    /// - Key path spend: This is the internal key.
799    /// - Script path spend: This is the pubkey associated with the secret key that signed.
800    Schnorr(Vec<XOnlyPublicKey>),
801}
802
803/// Map of input index -> the error encountered while attempting to sign that input.
804pub type SigningErrors = BTreeMap<usize, SignError>;
805
806#[rustfmt::skip]
807macro_rules! impl_get_key_for_set {
808    ($set:ident) => {
809
810impl GetKey for $set<Xpriv> {
811    type Error = GetKeyError;
812
813    fn get_key<C: Signing>(
814        &self,
815        key_request: KeyRequest,
816        secp: &Secp256k1<C>
817    ) -> Result<Option<PrivateKey>, Self::Error> {
818        // OK to stop at the first error because Xpriv::get_key() can only fail
819        // if this isn't a KeyRequest::Bip32, which would fail for all Xprivs.
820        self.iter()
821            .find_map(|xpriv| xpriv.get_key(key_request.clone(), secp).transpose())
822            .transpose()
823    }
824}}}
825impl_get_key_for_set!(BTreeSet);
826#[cfg(feature = "std")]
827impl_get_key_for_set!(HashSet);
828
829#[rustfmt::skip]
830macro_rules! impl_get_key_for_pubkey_map {
831    ($map:ident) => {
832
833impl GetKey for $map<PublicKey, PrivateKey> {
834    type Error = GetKeyError;
835
836    fn get_key<C: Signing>(
837        &self,
838        key_request: KeyRequest,
839        _: &Secp256k1<C>,
840    ) -> Result<Option<PrivateKey>, Self::Error> {
841        match key_request {
842            KeyRequest::Pubkey(pk) => Ok(self.get(&pk).cloned()),
843            KeyRequest::XOnlyPubkey(xonly) => {
844                let pubkey_even = PublicKey::new(xonly.public_key(secp256k1::Parity::Even));
845                let key = self.get(&pubkey_even).cloned();
846
847                if key.is_some() {
848                    return Ok(key);
849                }
850
851                let pubkey_odd = PublicKey::new(xonly.public_key(secp256k1::Parity::Odd));
852                if let Some(priv_key) = self.get(&pubkey_odd).copied() {
853                    let negated_priv_key  = priv_key.negate();
854                    return Ok(Some(negated_priv_key));
855                }
856
857                Ok(None)
858            },
859            KeyRequest::Bip32(_) => Err(GetKeyError::NotSupported),
860        }
861    }
862}}}
863impl_get_key_for_pubkey_map!(BTreeMap);
864#[cfg(feature = "std")]
865impl_get_key_for_pubkey_map!(HashMap);
866
867#[rustfmt::skip]
868macro_rules! impl_get_key_for_xonly_map {
869    ($map:ident) => {
870
871impl GetKey for $map<XOnlyPublicKey, PrivateKey> {
872    type Error = GetKeyError;
873
874    fn get_key<C: Signing>(
875        &self,
876        key_request: KeyRequest,
877        secp: &Secp256k1<C>,
878    ) -> Result<Option<PrivateKey>, Self::Error> {
879        match key_request {
880            KeyRequest::XOnlyPubkey(xonly) => Ok(self.get(&xonly).cloned()),
881            KeyRequest::Pubkey(pk) => {
882                let (xonly, parity) = pk.inner.x_only_public_key();
883
884                if let Some(mut priv_key) = self.get(&XOnlyPublicKey::from(xonly)).cloned() {
885                    let computed_pk = priv_key.public_key(&secp);
886                    let (_, computed_parity) = computed_pk.inner.x_only_public_key();
887
888                    if computed_parity != parity {
889                        priv_key = priv_key.negate();
890                    }
891
892                    return Ok(Some(priv_key));
893                }
894
895                Ok(None)
896            },
897            KeyRequest::Bip32(_) => Err(GetKeyError::NotSupported),
898        }
899    }
900}}}
901impl_get_key_for_xonly_map!(BTreeMap);
902#[cfg(feature = "std")]
903impl_get_key_for_xonly_map!(HashMap);
904
905/// Errors when getting a key.
906#[derive(Debug, Clone, PartialEq, Eq)]
907#[non_exhaustive]
908pub enum GetKeyError {
909    /// A bip32 error.
910    Bip32(bip32::Error),
911    /// The GetKey operation is not supported for this key request.
912    NotSupported,
913}
914
915internals::impl_from_infallible!(GetKeyError);
916
917impl fmt::Display for GetKeyError {
918    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
919        use GetKeyError::*;
920
921        match *self {
922            Bip32(ref e) => write_err!(f, "a bip23 error"; e),
923            NotSupported =>
924                f.write_str("the GetKey operation is not supported for this key request"),
925        }
926    }
927}
928
929#[cfg(feature = "std")]
930impl std::error::Error for GetKeyError {
931    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
932        use GetKeyError::*;
933
934        match *self {
935            NotSupported => None,
936            Bip32(ref e) => Some(e),
937        }
938    }
939}
940
941impl From<bip32::Error> for GetKeyError {
942    fn from(e: bip32::Error) -> Self { GetKeyError::Bip32(e) }
943}
944
945/// The various output types supported by the Bitcoin network.
946#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
947#[non_exhaustive]
948pub enum OutputType {
949    /// An output of type: pay-to-pubkey or pay-to-pubkey-hash.
950    Bare,
951    /// A pay-to-witness-pubkey-hash output (P2WPKH).
952    Wpkh,
953    /// A pay-to-witness-script-hash output (P2WSH).
954    Wsh,
955    /// A nested segwit output, pay-to-witness-pubkey-hash nested in a pay-to-script-hash.
956    ShWpkh,
957    /// A nested segwit output, pay-to-witness-script-hash nested in a pay-to-script-hash.
958    ShWsh,
959    /// A pay-to-script-hash output excluding wrapped segwit (P2SH).
960    Sh,
961    /// A taproot output (P2TR).
962    Tr,
963}
964
965impl OutputType {
966    /// The signing algorithm used to sign this output type.
967    pub fn signing_algorithm(&self) -> SigningAlgorithm {
968        use OutputType::*;
969
970        match self {
971            Bare | Wpkh | Wsh | ShWpkh | ShWsh | Sh => SigningAlgorithm::Ecdsa,
972            Tr => SigningAlgorithm::Schnorr,
973        }
974    }
975}
976
977/// Signing algorithms supported by the Bitcoin network.
978#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
979pub enum SigningAlgorithm {
980    /// The Elliptic Curve Digital Signature Algorithm (see [wikipedia]).
981    ///
982    /// [wikipedia]: https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm
983    Ecdsa,
984    /// The Schnorr signature algorithm (see [wikipedia]).
985    ///
986    /// [wikipedia]: https://en.wikipedia.org/wiki/Schnorr_signature
987    Schnorr,
988}
989
990/// Errors encountered while calculating the sighash message.
991#[derive(Debug, Clone, PartialEq, Eq)]
992#[non_exhaustive]
993pub enum SignError {
994    /// Input index out of bounds.
995    IndexOutOfBounds(IndexOutOfBoundsError),
996    /// Invalid Sighash type.
997    InvalidSighashType,
998    /// Missing input utxo.
999    MissingInputUtxo,
1000    /// Missing Redeem script.
1001    MissingRedeemScript,
1002    /// Missing spending utxo.
1003    MissingSpendUtxo,
1004    /// Missing witness script.
1005    MissingWitnessScript,
1006    /// Signing algorithm and key type does not match.
1007    MismatchedAlgoKey,
1008    /// Attempted to ECDSA sign an non-ECDSA input.
1009    NotEcdsa,
1010    /// The `scriptPubkey` is not a P2WPKH script.
1011    NotWpkh,
1012    /// Sighash computation error (segwit v0 input).
1013    SegwitV0Sighash(transaction::InputsIndexError),
1014    /// Sighash computation error (p2wpkh input).
1015    P2wpkhSighash(sighash::P2wpkhError),
1016    /// Sighash computation error (taproot input).
1017    TaprootError(sighash::TaprootError),
1018    /// Unable to determine the output type.
1019    UnknownOutputType,
1020    /// Unable to find key.
1021    KeyNotFound,
1022    /// Attempt to sign an input with the wrong signing algorithm.
1023    WrongSigningAlgorithm,
1024    /// Signing request currently unsupported.
1025    Unsupported,
1026}
1027
1028internals::impl_from_infallible!(SignError);
1029
1030impl fmt::Display for SignError {
1031    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1032        use SignError::*;
1033
1034        match *self {
1035            IndexOutOfBounds(ref e) => write_err!(f, "index out of bounds"; e),
1036            InvalidSighashType => write!(f, "invalid sighash type"),
1037            MissingInputUtxo => write!(f, "missing input utxo in PBST"),
1038            MissingRedeemScript => write!(f, "missing redeem script"),
1039            MissingSpendUtxo => write!(f, "missing spend utxo in PSBT"),
1040            MissingWitnessScript => write!(f, "missing witness script"),
1041            MismatchedAlgoKey => write!(f, "signing algorithm and key type does not match"),
1042            NotEcdsa => write!(f, "attempted to ECDSA sign an non-ECDSA input"),
1043            NotWpkh => write!(f, "the scriptPubkey is not a P2WPKH script"),
1044            SegwitV0Sighash(ref e) => write_err!(f, "segwit v0 sighash"; e),
1045            P2wpkhSighash(ref e) => write_err!(f, "p2wpkh sighash"; e),
1046            TaprootError(ref e) => write_err!(f, "taproot sighash"; e),
1047            UnknownOutputType => write!(f, "unable to determine the output type"),
1048            KeyNotFound => write!(f, "unable to find key"),
1049            WrongSigningAlgorithm =>
1050                write!(f, "attempt to sign an input with the wrong signing algorithm"),
1051            Unsupported => write!(f, "signing request currently unsupported"),
1052        }
1053    }
1054}
1055
1056#[cfg(feature = "std")]
1057impl std::error::Error for SignError {
1058    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1059        use SignError::*;
1060
1061        match *self {
1062            SegwitV0Sighash(ref e) => Some(e),
1063            P2wpkhSighash(ref e) => Some(e),
1064            TaprootError(ref e) => Some(e),
1065            IndexOutOfBounds(ref e) => Some(e),
1066            InvalidSighashType
1067            | MissingInputUtxo
1068            | MissingRedeemScript
1069            | MissingSpendUtxo
1070            | MissingWitnessScript
1071            | MismatchedAlgoKey
1072            | NotEcdsa
1073            | NotWpkh
1074            | UnknownOutputType
1075            | KeyNotFound
1076            | WrongSigningAlgorithm
1077            | Unsupported => None,
1078        }
1079    }
1080}
1081
1082impl From<sighash::P2wpkhError> for SignError {
1083    fn from(e: sighash::P2wpkhError) -> Self { Self::P2wpkhSighash(e) }
1084}
1085
1086impl From<IndexOutOfBoundsError> for SignError {
1087    fn from(e: IndexOutOfBoundsError) -> Self { SignError::IndexOutOfBounds(e) }
1088}
1089
1090impl From<sighash::TaprootError> for SignError {
1091    fn from(e: sighash::TaprootError) -> Self { SignError::TaprootError(e) }
1092}
1093
1094/// This error is returned when extracting a [`Transaction`] from a [`Psbt`].
1095#[derive(Debug, Clone, PartialEq, Eq)]
1096#[non_exhaustive]
1097pub enum ExtractTxError {
1098    /// The [`FeeRate`] is too high
1099    AbsurdFeeRate {
1100        /// The [`FeeRate`]
1101        fee_rate: FeeRate,
1102        /// The extracted [`Transaction`] (use this to ignore the error)
1103        tx: Transaction,
1104    },
1105    /// One or more of the inputs lacks value information (witness_utxo or non_witness_utxo)
1106    MissingInputValue {
1107        /// The extracted [`Transaction`] (use this to ignore the error)
1108        tx: Transaction,
1109    },
1110    /// Input value is less than Output Value, and the [`Transaction`] would be invalid.
1111    SendingTooMuch {
1112        /// The original [`Psbt`] is returned untouched.
1113        psbt: Psbt,
1114    },
1115}
1116
1117internals::impl_from_infallible!(ExtractTxError);
1118
1119impl fmt::Display for ExtractTxError {
1120    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1121        use ExtractTxError::*;
1122
1123        match *self {
1124            AbsurdFeeRate { fee_rate, .. } =>
1125                write!(f, "An absurdly high fee rate of {}", fee_rate),
1126            MissingInputValue { .. } => write!(
1127                f,
1128                "One of the inputs lacked value information (witness_utxo or non_witness_utxo)"
1129            ),
1130            SendingTooMuch { .. } => write!(
1131                f,
1132                "Transaction would be invalid due to output value being greater than input value."
1133            ),
1134        }
1135    }
1136}
1137
1138#[cfg(feature = "std")]
1139impl std::error::Error for ExtractTxError {
1140    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1141        use ExtractTxError::*;
1142
1143        match *self {
1144            AbsurdFeeRate { .. } | MissingInputValue { .. } | SendingTooMuch { .. } => None,
1145        }
1146    }
1147}
1148
1149/// Input index out of bounds (actual index, maximum index allowed).
1150#[derive(Debug, Clone, PartialEq, Eq)]
1151#[non_exhaustive]
1152pub enum IndexOutOfBoundsError {
1153    /// The index is out of bounds for the `psbt.inputs` vector.
1154    Inputs {
1155        /// Attempted index access.
1156        index: usize,
1157        /// Length of the PBST inputs vector.
1158        length: usize,
1159    },
1160    /// The index is out of bounds for the `psbt.unsigned_tx.input` vector.
1161    TxInput {
1162        /// Attempted index access.
1163        index: usize,
1164        /// Length of the PBST's unsigned transaction input vector.
1165        length: usize,
1166    },
1167}
1168
1169internals::impl_from_infallible!(IndexOutOfBoundsError);
1170
1171impl fmt::Display for IndexOutOfBoundsError {
1172    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1173        use IndexOutOfBoundsError::*;
1174
1175        match *self {
1176            Inputs { ref index, ref length } => write!(
1177                f,
1178                "index {} is out-of-bounds for PSBT inputs vector length {}",
1179                index, length
1180            ),
1181            TxInput { ref index, ref length } => write!(
1182                f,
1183                "index {} is out-of-bounds for PSBT unsigned tx input vector length {}",
1184                index, length
1185            ),
1186        }
1187    }
1188}
1189
1190#[cfg(feature = "std")]
1191impl std::error::Error for IndexOutOfBoundsError {
1192    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1193        use IndexOutOfBoundsError::*;
1194
1195        match *self {
1196            Inputs { .. } | TxInput { .. } => None,
1197        }
1198    }
1199}
1200
1201#[cfg(feature = "base64")]
1202mod display_from_str {
1203    use core::fmt::{self, Display, Formatter};
1204    use core::str::FromStr;
1205
1206    use base64::display::Base64Display;
1207    use base64::prelude::{Engine as _, BASE64_STANDARD};
1208    use internals::write_err;
1209
1210    use super::{Error, Psbt};
1211
1212    /// Error encountered during PSBT decoding from Base64 string.
1213    #[derive(Debug)]
1214    #[non_exhaustive]
1215    pub enum PsbtParseError {
1216        /// Error in internal PSBT data structure.
1217        PsbtEncoding(Error),
1218        /// Error in PSBT Base64 encoding.
1219        Base64Encoding(::base64::DecodeError),
1220    }
1221
1222    internals::impl_from_infallible!(PsbtParseError);
1223
1224    impl Display for PsbtParseError {
1225        fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1226            use self::PsbtParseError::*;
1227
1228            match *self {
1229                PsbtEncoding(ref e) => write_err!(f, "error in internal PSBT data structure"; e),
1230                Base64Encoding(ref e) => write_err!(f, "error in PSBT base64 encoding"; e),
1231            }
1232        }
1233    }
1234
1235    #[cfg(feature = "std")]
1236    impl std::error::Error for PsbtParseError {
1237        fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1238            use self::PsbtParseError::*;
1239
1240            match self {
1241                PsbtEncoding(e) => Some(e),
1242                Base64Encoding(e) => Some(e),
1243            }
1244        }
1245    }
1246
1247    impl Display for Psbt {
1248        fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1249            write!(f, "{}", Base64Display::new(&self.serialize(), &BASE64_STANDARD))
1250        }
1251    }
1252
1253    impl FromStr for Psbt {
1254        type Err = PsbtParseError;
1255
1256        fn from_str(s: &str) -> Result<Self, Self::Err> {
1257            let data = BASE64_STANDARD.decode(s).map_err(PsbtParseError::Base64Encoding)?;
1258            Psbt::deserialize(&data).map_err(PsbtParseError::PsbtEncoding)
1259        }
1260    }
1261}
1262#[cfg(feature = "base64")]
1263pub use self::display_from_str::PsbtParseError;
1264
1265#[cfg(test)]
1266mod tests {
1267    use hashes::{hash160, ripemd160, sha256, Hash};
1268    use hex::{test_hex_unwrap as hex, FromHex};
1269    #[cfg(feature = "rand-std")]
1270    use {
1271        crate::bip32::{DerivationPath, Fingerprint},
1272        crate::key::WPubkeyHash,
1273        crate::locktime,
1274        crate::witness_version::WitnessVersion,
1275        crate::WitnessProgram,
1276        secp256k1::{All, SecretKey},
1277    };
1278
1279    use super::*;
1280    use crate::bip32::ChildNumber;
1281    use crate::blockdata::locktime::absolute;
1282    use crate::blockdata::script::ScriptBuf;
1283    use crate::blockdata::transaction::{self, OutPoint, Sequence, TxIn};
1284    use crate::blockdata::witness::Witness;
1285    use crate::network::NetworkKind;
1286    use crate::psbt::serialize::{Deserialize, Serialize};
1287
1288    #[track_caller]
1289    pub fn hex_psbt(s: &str) -> Result<Psbt, crate::psbt::error::Error> {
1290        let r = Vec::from_hex(s);
1291        match r {
1292            Err(_e) => panic!("unable to parse hex string {}", s),
1293            Ok(v) => Psbt::deserialize(&v),
1294        }
1295    }
1296
1297    #[track_caller]
1298    fn psbt_with_values(input: u64, output: u64) -> Psbt {
1299        Psbt {
1300            unsigned_tx: Transaction {
1301                version: transaction::Version::TWO,
1302                lock_time: absolute::LockTime::ZERO,
1303                input: vec![TxIn {
1304                    previous_output: OutPoint {
1305                        txid: "f61b1742ca13176464adb3cb66050c00787bb3a4eead37e985f2df1e37718126"
1306                            .parse()
1307                            .unwrap(),
1308                        vout: 0,
1309                    },
1310                    script_sig: ScriptBuf::new(),
1311                    sequence: Sequence::ENABLE_LOCKTIME_NO_RBF,
1312                    witness: Witness::default(),
1313                }],
1314                output: vec![TxOut {
1315                    value: Amount::from_sat(output),
1316                    script_pubkey: ScriptBuf::from_hex(
1317                        "a9143545e6e33b832c47050f24d3eeb93c9c03948bc787",
1318                    )
1319                    .unwrap(),
1320                }],
1321            },
1322            xpub: Default::default(),
1323            version: 0,
1324            proprietary: BTreeMap::new(),
1325            unknown: BTreeMap::new(),
1326
1327            inputs: vec![Input {
1328                witness_utxo: Some(TxOut {
1329                    value: Amount::from_sat(input),
1330                    script_pubkey: ScriptBuf::from_hex(
1331                        "a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587",
1332                    )
1333                    .unwrap(),
1334                }),
1335                ..Default::default()
1336            }],
1337            outputs: vec![],
1338        }
1339    }
1340
1341    #[test]
1342    fn trivial_psbt() {
1343        let psbt = Psbt {
1344            unsigned_tx: Transaction {
1345                version: transaction::Version::TWO,
1346                lock_time: absolute::LockTime::ZERO,
1347                input: vec![],
1348                output: vec![],
1349            },
1350            xpub: Default::default(),
1351            version: 0,
1352            proprietary: BTreeMap::new(),
1353            unknown: BTreeMap::new(),
1354
1355            inputs: vec![],
1356            outputs: vec![],
1357        };
1358        assert_eq!(psbt.serialize_hex(), "70736274ff01000a0200000000000000000000");
1359    }
1360
1361    #[test]
1362    fn psbt_uncompressed_key() {
1363        let psbt: Psbt = hex_psbt("70736274ff01003302000000010000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff000000000000420204bb0d5d0cca36e7b9c80f63bc04c1240babb83bcd2803ef7ac8b6e2af594291daec281e856c98d210c5ab14dfd5828761f8ee7d5f45ca21ad3e4c4b41b747a3a047304402204f67e2afb76142d44fae58a2495d33a3419daa26cd0db8d04f3452b63289ac0f022010762a9fb67e94cc5cad9026f6dc99ff7f070f4278d30fbc7d0c869dd38c7fe70100").unwrap();
1364        assert!(psbt.inputs[0].partial_sigs.len() == 1);
1365        let pk = psbt.inputs[0].partial_sigs.iter().next().unwrap().0;
1366        assert!(!pk.compressed);
1367    }
1368
1369    #[test]
1370    fn psbt_high_fee_checks() {
1371        let psbt = psbt_with_values(5_000_000_000_000, 1000);
1372        assert_eq!(
1373            psbt.clone().extract_tx().map_err(|e| match e {
1374                ExtractTxError::AbsurdFeeRate { fee_rate, .. } => fee_rate,
1375                _ => panic!(""),
1376            }),
1377            Err(FeeRate::from_sat_per_kwu(15060240960843))
1378        );
1379        assert_eq!(
1380            psbt.clone().extract_tx_fee_rate_limit().map_err(|e| match e {
1381                ExtractTxError::AbsurdFeeRate { fee_rate, .. } => fee_rate,
1382                _ => panic!(""),
1383            }),
1384            Err(FeeRate::from_sat_per_kwu(15060240960843))
1385        );
1386        assert_eq!(
1387            psbt.clone()
1388                .extract_tx_with_fee_rate_limit(FeeRate::from_sat_per_kwu(15060240960842))
1389                .map_err(|e| match e {
1390                    ExtractTxError::AbsurdFeeRate { fee_rate, .. } => fee_rate,
1391                    _ => panic!(""),
1392                }),
1393            Err(FeeRate::from_sat_per_kwu(15060240960843))
1394        );
1395        assert!(psbt
1396            .extract_tx_with_fee_rate_limit(FeeRate::from_sat_per_kwu(15060240960843))
1397            .is_ok());
1398
1399        // Testing that extract_tx will error at 25k sat/vbyte (6250000 sat/kwu)
1400        assert_eq!(
1401            psbt_with_values(2076001, 1000).extract_tx().map_err(|e| match e {
1402                ExtractTxError::AbsurdFeeRate { fee_rate, .. } => fee_rate,
1403                _ => panic!(""),
1404            }),
1405            Err(FeeRate::from_sat_per_kwu(6250003)) // 6250000 is 25k sat/vbyte
1406        );
1407
1408        // Lowering the input satoshis by 1 lowers the sat/kwu by 3
1409        // Putting it exactly at 25k sat/vbyte
1410        assert!(psbt_with_values(2076000, 1000).extract_tx().is_ok());
1411    }
1412
1413    #[test]
1414    fn serialize_then_deserialize_output() {
1415        let secp = &Secp256k1::new();
1416        let seed = hex!("000102030405060708090a0b0c0d0e0f");
1417
1418        let mut hd_keypaths: BTreeMap<secp256k1::PublicKey, KeySource> = Default::default();
1419
1420        let mut sk: Xpriv = Xpriv::new_master(NetworkKind::Main, &seed).unwrap();
1421
1422        let fprint = sk.fingerprint(secp);
1423
1424        let dpath: Vec<ChildNumber> = vec![
1425            ChildNumber::from_normal_idx(0).unwrap(),
1426            ChildNumber::from_normal_idx(1).unwrap(),
1427            ChildNumber::from_normal_idx(2).unwrap(),
1428            ChildNumber::from_normal_idx(4).unwrap(),
1429            ChildNumber::from_normal_idx(42).unwrap(),
1430            ChildNumber::from_hardened_idx(69).unwrap(),
1431            ChildNumber::from_normal_idx(420).unwrap(),
1432            ChildNumber::from_normal_idx(31337).unwrap(),
1433        ];
1434
1435        sk = sk.derive_priv(secp, &dpath).unwrap();
1436
1437        let pk = Xpub::from_priv(secp, &sk);
1438
1439        hd_keypaths.insert(pk.public_key, (fprint, dpath.into()));
1440
1441        let expected: Output = Output {
1442            redeem_script: Some(
1443                ScriptBuf::from_hex("76a914d0c59903c5bac2868760e90fd521a4665aa7652088ac").unwrap(),
1444            ),
1445            witness_script: Some(
1446                ScriptBuf::from_hex("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787").unwrap(),
1447            ),
1448            bip32_derivation: hd_keypaths,
1449            ..Default::default()
1450        };
1451
1452        let actual = Output::deserialize(&expected.serialize()).unwrap();
1453
1454        assert_eq!(expected, actual);
1455    }
1456
1457    #[test]
1458    fn serialize_then_deserialize_global() {
1459        let expected = Psbt {
1460            unsigned_tx: Transaction {
1461                version: transaction::Version::TWO,
1462                lock_time: absolute::LockTime::from_consensus(1257139),
1463                input: vec![TxIn {
1464                    previous_output: OutPoint {
1465                        txid: "f61b1742ca13176464adb3cb66050c00787bb3a4eead37e985f2df1e37718126"
1466                            .parse()
1467                            .unwrap(),
1468                        vout: 0,
1469                    },
1470                    script_sig: ScriptBuf::new(),
1471                    sequence: Sequence::ENABLE_LOCKTIME_NO_RBF,
1472                    witness: Witness::default(),
1473                }],
1474                output: vec![
1475                    TxOut {
1476                        value: Amount::from_sat(99_999_699),
1477                        script_pubkey: ScriptBuf::from_hex(
1478                            "76a914d0c59903c5bac2868760e90fd521a4665aa7652088ac",
1479                        )
1480                        .unwrap(),
1481                    },
1482                    TxOut {
1483                        value: Amount::from_sat(100_000_000),
1484                        script_pubkey: ScriptBuf::from_hex(
1485                            "a9143545e6e33b832c47050f24d3eeb93c9c03948bc787",
1486                        )
1487                        .unwrap(),
1488                    },
1489                ],
1490            },
1491            xpub: Default::default(),
1492            version: 0,
1493            proprietary: Default::default(),
1494            unknown: Default::default(),
1495            inputs: vec![Input::default()],
1496            outputs: vec![Output::default(), Output::default()],
1497        };
1498
1499        let actual: Psbt = Psbt::deserialize(&expected.serialize()).unwrap();
1500        assert_eq!(expected, actual);
1501    }
1502
1503    #[test]
1504    fn serialize_then_deserialize_psbtkvpair() {
1505        let expected = raw::Pair {
1506            key: raw::Key { type_value: 0u8, key: vec![42u8, 69u8] },
1507            value: vec![69u8, 42u8, 4u8],
1508        };
1509
1510        let actual = raw::Pair::deserialize(&expected.serialize()).unwrap();
1511
1512        assert_eq!(expected, actual);
1513    }
1514
1515    #[test]
1516    fn deserialize_and_serialize_psbt_with_two_partial_sigs() {
1517        let hex = "70736274ff0100890200000001207ae985d787dfe6143d5c58fad79cc7105e0e799fcf033b7f2ba17e62d7b3200000000000ffffffff02563d03000000000022002019899534b9a011043c0dd57c3ff9a381c3522c5f27c6a42319085b56ca543a1d6adc020000000000220020618b47a07ebecca4e156edb1b9ea7c24bdee0139fc049237965ffdaf56d5ee73000000000001012b801a0600000000002200201148e93e9315e37dbed2121be5239257af35adc03ffdfc5d914b083afa44dab82202025fe7371376d53cf8a2783917c28bf30bd690b0a4d4a207690093ca2b920ee076473044022007e06b362e89912abd4661f47945430739b006a85d1b2a16c01dc1a4bd07acab022061576d7aa834988b7ab94ef21d8eebd996ea59ea20529a19b15f0c9cebe3d8ac01220202b3fe93530020a8294f0e527e33fbdff184f047eb6b5a1558a352f62c29972f8a473044022002787f926d6817504431ee281183b8119b6845bfaa6befae45e13b6d430c9d2f02202859f149a6cd26ae2f03a107e7f33c7d91730dade305fe077bae677b5d44952a01010547522102b3fe93530020a8294f0e527e33fbdff184f047eb6b5a1558a352f62c29972f8a21025fe7371376d53cf8a2783917c28bf30bd690b0a4d4a207690093ca2b920ee07652ae0001014752210283ef76537f2d58ae3aa3a4bd8ae41c3f230ccadffb1a0bd3ca504d871cff05e7210353d79cc0cb1396f4ce278d005f16d948e02a6aec9ed1109f13747ecb1507b37b52ae00010147522102b3937241777b6665e0d694e52f9c1b188433641df852da6fc42187b5d8a368a321034cdd474f01cc5aa7ff834ad8bcc882a87e854affc775486bc2a9f62e8f49bd7852ae00";
1518        let psbt: Psbt = hex_psbt(hex).unwrap();
1519        assert_eq!(hex, psbt.serialize_hex());
1520    }
1521
1522    #[cfg(feature = "serde")]
1523    #[test]
1524    fn test_serde_psbt() {
1525        //! Create a full PSBT value with various fields filled and make sure it can be JSONized.
1526        use hashes::sha256d;
1527
1528        use crate::psbt::map::Input;
1529
1530        // create some values to use in the PSBT
1531        let tx = Transaction {
1532            version: transaction::Version::ONE,
1533            lock_time: absolute::LockTime::ZERO,
1534            input: vec![TxIn {
1535                previous_output: OutPoint {
1536                    txid: "e567952fb6cc33857f392efa3a46c995a28f69cca4bb1b37e0204dab1ec7a389"
1537                        .parse()
1538                        .unwrap(),
1539                    vout: 1,
1540                },
1541                script_sig: ScriptBuf::from_hex("160014be18d152a9b012039daf3da7de4f53349eecb985")
1542                    .unwrap(),
1543                sequence: Sequence::MAX,
1544                witness: Witness::from_slice(&[hex!(
1545                    "03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105"
1546                )]),
1547            }],
1548            output: vec![TxOut {
1549                value: Amount::from_sat(190_303_501_938),
1550                script_pubkey: ScriptBuf::from_hex(
1551                    "a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587",
1552                )
1553                .unwrap(),
1554            }],
1555        };
1556        let unknown: BTreeMap<raw::Key, Vec<u8>> =
1557            vec![(raw::Key { type_value: 1, key: vec![0, 1] }, vec![3, 4, 5])]
1558                .into_iter()
1559                .collect();
1560        let key_source = ("deadbeef".parse().unwrap(), "0'/1".parse().unwrap());
1561        let keypaths: BTreeMap<secp256k1::PublicKey, KeySource> = vec![(
1562            "0339880dc92394b7355e3d0439fa283c31de7590812ea011c4245c0674a685e883".parse().unwrap(),
1563            key_source.clone(),
1564        )]
1565        .into_iter()
1566        .collect();
1567
1568        let proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>> = vec![(
1569            raw::ProprietaryKey {
1570                prefix: "prefx".as_bytes().to_vec(),
1571                subtype: 42,
1572                key: "test_key".as_bytes().to_vec(),
1573            },
1574            vec![5, 6, 7],
1575        )]
1576        .into_iter()
1577        .collect();
1578
1579        let psbt = Psbt {
1580            version: 0,
1581            xpub: {
1582                let xpub: Xpub =
1583                    "xpub661MyMwAqRbcGoRVtwfvzZsq2VBJR1LAHfQstHUoxqDorV89vRoMxUZ27kLrraAj6MPi\
1584                    QfrDb27gigC1VS1dBXi5jGpxmMeBXEkKkcXUTg4".parse().unwrap();
1585                vec![(xpub, key_source)].into_iter().collect()
1586            },
1587            unsigned_tx: {
1588                let mut unsigned = tx.clone();
1589                unsigned.input[0].script_sig = ScriptBuf::new();
1590                unsigned.input[0].witness = Witness::default();
1591                unsigned
1592            },
1593            proprietary: proprietary.clone(),
1594            unknown: unknown.clone(),
1595
1596            inputs: vec![
1597                Input {
1598                    non_witness_utxo: Some(tx),
1599                    witness_utxo: Some(TxOut {
1600                        value: Amount::from_sat(190_303_501_938),
1601                        script_pubkey: ScriptBuf::from_hex("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587").unwrap(),
1602                    }),
1603                    sighash_type: Some("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY".parse::<PsbtSighashType>().unwrap()),
1604                    redeem_script: Some(vec![0x51].into()),
1605                    witness_script: None,
1606                    partial_sigs: vec![(
1607                        "0339880dc92394b7355e3d0439fa283c31de7590812ea011c4245c0674a685e883".parse().unwrap(),
1608                        "304402204f67e2afb76142d44fae58a2495d33a3419daa26cd0db8d04f3452b63289ac0f022010762a9fb67e94cc5cad9026f6dc99ff7f070f4278d30fbc7d0c869dd38c7fe701".parse().unwrap(),
1609                    )].into_iter().collect(),
1610                    bip32_derivation: keypaths.clone(),
1611                    final_script_witness: Some(Witness::from_slice(&[vec![1, 3], vec![5]])),
1612                    ripemd160_preimages: vec![(ripemd160::Hash::hash(&[]), vec![1, 2])].into_iter().collect(),
1613                    sha256_preimages: vec![(sha256::Hash::hash(&[]), vec![1, 2])].into_iter().collect(),
1614                    hash160_preimages: vec![(hash160::Hash::hash(&[]), vec![1, 2])].into_iter().collect(),
1615                    hash256_preimages: vec![(sha256d::Hash::hash(&[]), vec![1, 2])].into_iter().collect(),
1616                    proprietary: proprietary.clone(),
1617                    unknown: unknown.clone(),
1618                    ..Default::default()
1619                }
1620            ],
1621            outputs: vec![
1622                Output {
1623                    bip32_derivation: keypaths,
1624                    proprietary,
1625                    unknown,
1626                    ..Default::default()
1627                }
1628            ],
1629        };
1630        let encoded = serde_json::to_string(&psbt).unwrap();
1631        let decoded: Psbt = serde_json::from_str(&encoded).unwrap();
1632        assert_eq!(psbt, decoded);
1633    }
1634
1635    mod bip_vectors {
1636        #[cfg(feature = "base64")]
1637        use std::str::FromStr;
1638
1639        use super::*;
1640        use crate::psbt::map::Map;
1641
1642        #[test]
1643        #[should_panic(expected = "InvalidMagic")]
1644        fn invalid_vector_1() {
1645            hex_psbt("0200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf6000000006a473044022070b2245123e6bf474d60c5b50c043d4c691a5d2435f09a34a7662a9dc251790a022001329ca9dacf280bdf30740ec0390422422c81cb45839457aeb76fc12edd95b3012102657d118d3357b8e0f4c2cd46db7b39f6d9c38d9a70abcb9b2de5dc8dbfe4ce31feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300").unwrap();
1646        }
1647
1648        #[cfg(feature = "base64")]
1649        #[test]
1650        #[should_panic(expected = "InvalidMagic")]
1651        fn invalid_vector_1_base64() {
1652            Psbt::from_str("AgAAAAEmgXE3Ht/yhek3re6ks3t4AAwFZsuzrWRkFxPKQhcb9gAAAABqRzBEAiBwsiRRI+a/R01gxbUMBD1MaRpdJDXwmjSnZiqdwlF5CgIgATKcqdrPKAvfMHQOwDkEIkIsgctFg5RXrrdvwS7dlbMBIQJlfRGNM1e44PTCzUbbezn22cONmnCry5st5dyNv+TOMf7///8C09/1BQAAAAAZdqkU0MWZA8W6woaHYOkP1SGkZlqnZSCIrADh9QUAAAAAF6kUNUXm4zuDLEcFDyTT7rk8nAOUi8eHsy4TAA==").unwrap();
1653        }
1654
1655        #[test]
1656        #[should_panic(expected = "ConsensusEncoding")]
1657        fn invalid_vector_2() {
1658            hex_psbt("70736274ff0100750200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab30000000000")
1659                .unwrap();
1660        }
1661
1662        #[cfg(feature = "base64")]
1663        #[test]
1664        #[should_panic(expected = "ConsensusEncoding")]
1665        fn invalid_vector_2_base64() {
1666            Psbt::from_str("cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAA==")
1667                .unwrap();
1668        }
1669
1670        #[test]
1671        #[should_panic(expected = "UnsignedTxHasScriptSigs")]
1672        fn invalid_vector_3() {
1673            hex_psbt("70736274ff0100fd0a010200000002ab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be4000000006a47304402204759661797c01b036b25928948686218347d89864b719e1f7fcf57d1e511658702205309eabf56aa4d8891ffd111fdf1336f3a29da866d7f8486d75546ceedaf93190121035cdc61fc7ba971c0b501a646a2a83b102cb43881217ca682dc86e2d73fa88292feffffffab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40100000000feffffff02603bea0b000000001976a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac8e240000000000001976a9146f4620b553fa095e721b9ee0efe9fa039cca459788ac00000000000001012000e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787010416001485d13537f2e265405a34dbafa9e3dda01fb82308000000").unwrap();
1674        }
1675
1676        #[cfg(feature = "base64")]
1677        #[test]
1678        #[should_panic(expected = "UnsignedTxHasScriptSigs")]
1679        fn invalid_vector_3_base64() {
1680            Psbt::from_str("cHNidP8BAP0KAQIAAAACqwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QAAAAAakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpL+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAABASAA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHhwEEFgAUhdE1N/LiZUBaNNuvqePdoB+4IwgAAAA=").unwrap();
1681        }
1682
1683        #[test]
1684        #[should_panic(expected = "MustHaveUnsignedTx")]
1685        fn invalid_vector_4() {
1686            hex_psbt("70736274ff000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab30000000000").unwrap();
1687        }
1688
1689        #[cfg(feature = "base64")]
1690        #[test]
1691        #[should_panic(expected = "MustHaveUnsignedTx")]
1692        fn invalid_vector_4_base64() {
1693            Psbt::from_str("cHNidP8AAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAA==").unwrap();
1694        }
1695
1696        #[test]
1697        #[should_panic(expected = "DuplicateKey(Key { type_value: 0, key: [] })")]
1698        fn invalid_vector_5() {
1699            hex_psbt("70736274ff0100750200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab30000000001003f0200000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff010000000000000000036a010000000000000000").unwrap();
1700        }
1701
1702        #[cfg(feature = "base64")]
1703        #[test]
1704        #[should_panic(expected = "DuplicateKey(Key { type_value: 0, key: [] })")]
1705        fn invalid_vector_5_base64() {
1706            Psbt::from_str("cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAQA/AgAAAAH//////////////////////////////////////////wAAAAAA/////wEAAAAAAAAAAANqAQAAAAAAAAAA").unwrap();
1707        }
1708
1709        #[test]
1710        fn valid_vector_1() {
1711            let unserialized = Psbt {
1712                unsigned_tx: Transaction {
1713                    version: transaction::Version::TWO,
1714                    lock_time: absolute::LockTime::from_consensus(1257139),
1715                    input: vec![
1716                        TxIn {
1717                            previous_output: OutPoint {
1718                                txid: "f61b1742ca13176464adb3cb66050c00787bb3a4eead37e985f2df1e37718126".parse().unwrap(),
1719                                vout: 0,
1720                            },
1721                            script_sig: ScriptBuf::new(),
1722                            sequence: Sequence::ENABLE_LOCKTIME_NO_RBF,
1723                            witness: Witness::default(),
1724                        }
1725                    ],
1726                    output: vec![
1727                        TxOut {
1728                            value: Amount::from_sat(99_999_699),
1729                            script_pubkey: ScriptBuf::from_hex("76a914d0c59903c5bac2868760e90fd521a4665aa7652088ac").unwrap(),
1730                        },
1731                        TxOut {
1732                            value: Amount::from_sat(100_000_000),
1733                            script_pubkey: ScriptBuf::from_hex("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787").unwrap(),
1734                        },
1735                    ],
1736                },
1737                xpub: Default::default(),
1738                version: 0,
1739                proprietary: BTreeMap::new(),
1740                unknown: BTreeMap::new(),
1741
1742                inputs: vec![
1743                    Input {
1744                        non_witness_utxo: Some(Transaction {
1745                            version: transaction::Version::ONE,
1746                            lock_time: absolute::LockTime::ZERO,
1747                            input: vec![
1748                                TxIn {
1749                                    previous_output: OutPoint {
1750                                        txid: "e567952fb6cc33857f392efa3a46c995a28f69cca4bb1b37e0204dab1ec7a389".parse().unwrap(),
1751                                        vout: 1,
1752                                    },
1753                                    script_sig: ScriptBuf::from_hex("160014be18d152a9b012039daf3da7de4f53349eecb985").unwrap(),
1754                                    sequence: Sequence::MAX,
1755                                    witness: Witness::from_slice(&[
1756                                        hex!("304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c01"),
1757                                        hex!("03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105"),
1758                                    ]),
1759                                },
1760                                TxIn {
1761                                    previous_output: OutPoint {
1762                                        txid: "b490486aec3ae671012dddb2bb08466bef37720a533a894814ff1da743aaf886".parse().unwrap(),
1763                                        vout: 1,
1764                                    },
1765                                    script_sig: ScriptBuf::from_hex("160014fe3e9ef1a745e974d902c4355943abcb34bd5353").unwrap(),
1766                                    sequence: Sequence::MAX,
1767                                    witness: Witness::from_slice(&[
1768                                        hex!("3045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01"),
1769                                        hex!("0223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab3"),
1770                                    ]),
1771                                }
1772                            ],
1773                            output: vec![
1774                                TxOut {
1775                                    value: Amount::from_sat(200_000_000),
1776                                    script_pubkey: ScriptBuf::from_hex("76a91485cff1097fd9e008bb34af709c62197b38978a4888ac").unwrap(),
1777                                },
1778                                TxOut {
1779                                    value: Amount::from_sat(190_303_501_938),
1780                                    script_pubkey: ScriptBuf::from_hex("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587").unwrap(),
1781                                },
1782                            ],
1783                        }),
1784                        ..Default::default()
1785                    },
1786                ],
1787                outputs: vec![
1788                    Output {
1789                        ..Default::default()
1790                    },
1791                    Output {
1792                        ..Default::default()
1793                    },
1794                ],
1795            };
1796
1797            let base16str = "70736274ff0100750200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab300000000000000";
1798
1799            assert_eq!(unserialized.serialize_hex(), base16str);
1800            assert_eq!(unserialized, hex_psbt(base16str).unwrap());
1801
1802            #[cfg(feature = "base64")]
1803            {
1804                let base64str = "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAAAA";
1805                assert_eq!(Psbt::from_str(base64str).unwrap(), unserialized);
1806                assert_eq!(base64str, unserialized.to_string());
1807                assert_eq!(Psbt::from_str(base64str).unwrap(), hex_psbt(base16str).unwrap());
1808            }
1809        }
1810
1811        #[test]
1812        fn valid_vector_2() {
1813            let psbt: Psbt = hex_psbt("70736274ff0100a00200000002ab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40000000000feffffffab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40100000000feffffff02603bea0b000000001976a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac8e240000000000001976a9146f4620b553fa095e721b9ee0efe9fa039cca459788ac000000000001076a47304402204759661797c01b036b25928948686218347d89864b719e1f7fcf57d1e511658702205309eabf56aa4d8891ffd111fdf1336f3a29da866d7f8486d75546ceedaf93190121035cdc61fc7ba971c0b501a646a2a83b102cb43881217ca682dc86e2d73fa882920001012000e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787010416001485d13537f2e265405a34dbafa9e3dda01fb82308000000").unwrap();
1814
1815            assert_eq!(psbt.inputs.len(), 2);
1816            assert_eq!(psbt.outputs.len(), 2);
1817
1818            assert!(&psbt.inputs[0].final_script_sig.is_some());
1819
1820            let redeem_script = psbt.inputs[1].redeem_script.as_ref().unwrap();
1821            let expected_out =
1822                ScriptBuf::from_hex("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787").unwrap();
1823
1824            assert!(redeem_script.is_p2wpkh());
1825            assert_eq!(
1826                redeem_script.to_p2sh(),
1827                psbt.inputs[1].witness_utxo.as_ref().unwrap().script_pubkey
1828            );
1829            assert_eq!(redeem_script.to_p2sh(), expected_out);
1830
1831            for output in psbt.outputs {
1832                assert_eq!(output.get_pairs().len(), 0)
1833            }
1834        }
1835
1836        #[test]
1837        fn valid_vector_3() {
1838            let psbt: Psbt = hex_psbt("70736274ff0100750200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab30000000001030401000000000000").unwrap();
1839
1840            assert_eq!(psbt.inputs.len(), 1);
1841            assert_eq!(psbt.outputs.len(), 2);
1842
1843            let tx_input = &psbt.unsigned_tx.input[0];
1844            let psbt_non_witness_utxo = psbt.inputs[0].non_witness_utxo.as_ref().unwrap();
1845
1846            assert_eq!(tx_input.previous_output.txid, psbt_non_witness_utxo.compute_txid());
1847            assert!(psbt_non_witness_utxo.output[tx_input.previous_output.vout as usize]
1848                .script_pubkey
1849                .is_p2pkh());
1850            assert_eq!(
1851                psbt.inputs[0].sighash_type.as_ref().unwrap().ecdsa_hash_ty().unwrap(),
1852                EcdsaSighashType::All
1853            );
1854        }
1855
1856        #[test]
1857        fn valid_vector_4() {
1858            let psbt: Psbt = hex_psbt("70736274ff0100a00200000002ab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40000000000feffffffab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40100000000feffffff02603bea0b000000001976a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac8e240000000000001976a9146f4620b553fa095e721b9ee0efe9fa039cca459788ac00000000000100df0200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf6000000006a473044022070b2245123e6bf474d60c5b50c043d4c691a5d2435f09a34a7662a9dc251790a022001329ca9dacf280bdf30740ec0390422422c81cb45839457aeb76fc12edd95b3012102657d118d3357b8e0f4c2cd46db7b39f6d9c38d9a70abcb9b2de5dc8dbfe4ce31feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e13000001012000e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787010416001485d13537f2e265405a34dbafa9e3dda01fb8230800220202ead596687ca806043edc3de116cdf29d5e9257c196cd055cf698c8d02bf24e9910b4a6ba670000008000000080020000800022020394f62be9df19952c5587768aeb7698061ad2c4a25c894f47d8c162b4d7213d0510b4a6ba6700000080010000800200008000").unwrap();
1859
1860            assert_eq!(psbt.inputs.len(), 2);
1861            assert_eq!(psbt.outputs.len(), 2);
1862
1863            assert!(&psbt.inputs[0].final_script_sig.is_none());
1864            assert!(&psbt.inputs[1].final_script_sig.is_none());
1865
1866            let redeem_script = psbt.inputs[1].redeem_script.as_ref().unwrap();
1867            let expected_out =
1868                ScriptBuf::from_hex("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787").unwrap();
1869
1870            assert!(redeem_script.is_p2wpkh());
1871            assert_eq!(
1872                redeem_script.to_p2sh(),
1873                psbt.inputs[1].witness_utxo.as_ref().unwrap().script_pubkey
1874            );
1875            assert_eq!(redeem_script.to_p2sh(), expected_out);
1876
1877            for output in psbt.outputs {
1878                assert!(!output.get_pairs().is_empty())
1879            }
1880        }
1881
1882        #[test]
1883        fn valid_vector_5() {
1884            let psbt: Psbt = hex_psbt("70736274ff0100550200000001279a2323a5dfb51fc45f220fa58b0fc13e1e3342792a85d7e36cd6333b5cbc390000000000ffffffff01a05aea0b000000001976a914ffe9c0061097cc3b636f2cb0460fa4fc427d2b4588ac0000000000010120955eea0b0000000017a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87220203b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4646304302200424b58effaaa694e1559ea5c93bbfd4a89064224055cdf070b6771469442d07021f5c8eb0fea6516d60b8acb33ad64ede60e8785bfb3aa94b99bdf86151db9a9a010104220020771fd18ad459666dd49f3d564e3dbc42f4c84774e360ada16816a8ed488d5681010547522103b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd462103de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd52ae220603b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd4610b4a6ba67000000800000008004000080220603de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd10b4a6ba670000008000000080050000800000").unwrap();
1885
1886            assert_eq!(psbt.inputs.len(), 1);
1887            assert_eq!(psbt.outputs.len(), 1);
1888
1889            assert!(&psbt.inputs[0].final_script_sig.is_none());
1890
1891            let redeem_script = psbt.inputs[0].redeem_script.as_ref().unwrap();
1892            let expected_out =
1893                ScriptBuf::from_hex("a9146345200f68d189e1adc0df1c4d16ea8f14c0dbeb87").unwrap();
1894
1895            assert!(redeem_script.is_p2wsh());
1896            assert_eq!(
1897                redeem_script.to_p2sh(),
1898                psbt.inputs[0].witness_utxo.as_ref().unwrap().script_pubkey
1899            );
1900
1901            assert_eq!(redeem_script.to_p2sh(), expected_out);
1902        }
1903
1904        #[test]
1905        fn valid_vector_6() {
1906            let psbt: Psbt = hex_psbt("70736274ff01003f0200000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff010000000000000000036a010000000000000a0f0102030405060708090f0102030405060708090a0b0c0d0e0f0000").unwrap();
1907
1908            assert_eq!(psbt.inputs.len(), 1);
1909            assert_eq!(psbt.outputs.len(), 1);
1910
1911            let tx = &psbt.unsigned_tx;
1912            assert_eq!(
1913                tx.compute_txid(),
1914                "75c5c9665a570569ad77dd1279e6fd4628a093c4dcbf8d41532614044c14c115".parse().unwrap(),
1915            );
1916
1917            let mut unknown: BTreeMap<raw::Key, Vec<u8>> = BTreeMap::new();
1918            let key: raw::Key = raw::Key { type_value: 0x0fu8, key: hex!("010203040506070809") };
1919            let value: Vec<u8> = hex!("0102030405060708090a0b0c0d0e0f");
1920
1921            unknown.insert(key, value);
1922
1923            assert_eq!(psbt.inputs[0].unknown, unknown)
1924        }
1925    }
1926
1927    mod bip_371_vectors {
1928        use super::*;
1929
1930        #[test]
1931        fn invalid_vectors() {
1932            let err = hex_psbt("70736274ff010071020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff02787c01000000000016001483a7e34bd99ff03a4962ef8a1a101bb295461ece606b042a010000001600147ac369df1b20e033d6116623957b0ac49f3c52e8000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a075701172102fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa232000000").unwrap_err();
1933            assert_eq!(err.to_string(), "invalid xonly public key");
1934            let err = hex_psbt("70736274ff010071020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff02787c01000000000016001483a7e34bd99ff03a4962ef8a1a101bb295461ece606b042a010000001600147ac369df1b20e033d6116623957b0ac49f3c52e8000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a0757011342173bb3d36c074afb716fec6307a069a2e450b995f3c82785945ab8df0e24260dcd703b0cbf34de399184a9481ac2b3586db6601f026a77f7e4938481bc34751701aa000000").unwrap_err();
1935            #[cfg(feature = "std")]
1936            assert_eq!(err.to_string(), "invalid taproot signature");
1937            #[cfg(not(feature = "std"))]
1938            assert_eq!(
1939                err.to_string(),
1940                "invalid taproot signature: invalid taproot signature size: 66"
1941            );
1942            let err = hex_psbt("70736274ff010071020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff02787c01000000000016001483a7e34bd99ff03a4962ef8a1a101bb295461ece606b042a010000001600147ac369df1b20e033d6116623957b0ac49f3c52e8000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a0757221602fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa2321900772b2da75600008001000080000000800100000000000000000000").unwrap_err();
1943            assert_eq!(err.to_string(), "invalid xonly public key");
1944            let err = hex_psbt("70736274ff01007d020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff02887b0100000000001600142382871c7e8421a00093f754d91281e675874b9f606b042a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a0757000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a0757000001052102fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa23200").unwrap_err();
1945            assert_eq!(err.to_string(), "invalid xonly public key");
1946            let err = hex_psbt("70736274ff01007d020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff02887b0100000000001600142382871c7e8421a00093f754d91281e675874b9f606b042a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a0757000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a07570000220702fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa2321900772b2da7560000800100008000000080010000000000000000").unwrap_err();
1947            assert_eq!(err.to_string(), "invalid xonly public key");
1948            let err = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b6924214022cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b094089756aa3739ccc689ec0fcf3a360be32cc0b59b16e93a1e8bb4605726b2ca7a3ff706c4176649632b2cc68e1f912b8a578e3719ce7710885c7a966f49bcd43cb0000").unwrap_err();
1949            #[cfg(feature = "std")]
1950            assert_eq!(err.to_string(), "invalid hash when parsing slice");
1951            #[cfg(not(feature = "std"))]
1952            assert_eq!(
1953                err.to_string(),
1954                "invalid hash when parsing slice: invalid slice length 33 (expected 32)"
1955            );
1956            let err = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b69241142cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b094289756aa3739ccc689ec0fcf3a360be32cc0b59b16e93a1e8bb4605726b2ca7a3ff706c4176649632b2cc68e1f912b8a578e3719ce7710885c7a966f49bcd43cb01010000").unwrap_err();
1957            #[cfg(feature = "std")]
1958            assert_eq!(err.to_string(), "invalid taproot signature");
1959            #[cfg(not(feature = "std"))]
1960            assert_eq!(
1961                err.to_string(),
1962                "invalid taproot signature: invalid taproot signature size: 66"
1963            );
1964            let err = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b69241142cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b093989756aa3739ccc689ec0fcf3a360be32cc0b59b16e93a1e8bb4605726b2ca7a3ff706c4176649632b2cc68e1f912b8a578e3719ce7710885c7a966f49bcd43cb0000").unwrap_err();
1965            #[cfg(feature = "std")]
1966            assert_eq!(err.to_string(), "invalid taproot signature");
1967            #[cfg(not(feature = "std"))]
1968            assert_eq!(
1969                err.to_string(),
1970                "invalid taproot signature: invalid taproot signature size: 57"
1971            );
1972            let err = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b6926315c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac06f7d62059e9497a1a4a267569d9876da60101aff38e3529b9b939ce7f91ae970115f2e490af7cc45c4f78511f36057ce5c5a5c56325a29fb44dfc203f356e1f80023202cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2acc00000").unwrap_err();
1973            assert_eq!(err.to_string(), "invalid control block");
1974            let err = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b6926115c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac06f7d62059e9497a1a4a267569d9876da60101aff38e3529b9b939ce7f91ae970115f2e490af7cc45c4f78511f36057ce5c5a5c56325a29fb44dfc203f356e123202cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2acc00000").unwrap_err();
1975            assert_eq!(err.to_string(), "invalid control block");
1976        }
1977
1978        fn rtt_psbt(psbt: Psbt) {
1979            let enc = Psbt::serialize(&psbt);
1980            let psbt2 = Psbt::deserialize(&enc).unwrap();
1981            assert_eq!(psbt, psbt2);
1982        }
1983
1984        #[test]
1985        fn valid_psbt_vectors() {
1986            let psbt = hex_psbt("70736274ff010052020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff0148e6052a01000000160014768e1eeb4cf420866033f80aceff0f9720744969000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a07572116fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa2321900772b2da75600008001000080000000800100000000000000011720fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa232002202036b772a6db74d8753c98a827958de6c78ab3312109f37d3e0304484242ece73d818772b2da7540000800100008000000080000000000000000000").unwrap();
1987            let internal_key = psbt.inputs[0].tap_internal_key.unwrap();
1988            assert!(psbt.inputs[0].tap_key_origins.contains_key(&internal_key));
1989            rtt_psbt(psbt);
1990
1991            // vector 2
1992            let psbt = hex_psbt("70736274ff010052020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff0148e6052a01000000160014768e1eeb4cf420866033f80aceff0f9720744969000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a0757011340bb53ec917bad9d906af1ba87181c48b86ace5aae2b53605a725ca74625631476fc6f5baedaf4f2ee0f477f36f58f3970d5b8273b7e497b97af2e3f125c97af342116fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa2321900772b2da75600008001000080000000800100000000000000011720fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa232002202036b772a6db74d8753c98a827958de6c78ab3312109f37d3e0304484242ece73d818772b2da7540000800100008000000080000000000000000000").unwrap();
1993            let internal_key = psbt.inputs[0].tap_internal_key.unwrap();
1994            assert!(psbt.inputs[0].tap_key_origins.contains_key(&internal_key));
1995            assert!(psbt.inputs[0].tap_key_sig.is_some());
1996            rtt_psbt(psbt);
1997
1998            // vector 3
1999            let psbt = hex_psbt("70736274ff01005e020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff0148e6052a0100000022512083698e458c6664e1595d75da2597de1e22ee97d798e706c4c0a4b5a9823cd743000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a07572116fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa2321900772b2da75600008001000080000000800100000000000000011720fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa232000105201124da7aec92ccd06c954562647f437b138b95721a84be2bf2276bbddab3e67121071124da7aec92ccd06c954562647f437b138b95721a84be2bf2276bbddab3e6711900772b2da7560000800100008000000080000000000500000000").unwrap();
2000            let internal_key = psbt.outputs[0].tap_internal_key.unwrap();
2001            assert!(psbt.outputs[0].tap_key_origins.contains_key(&internal_key));
2002            rtt_psbt(psbt);
2003
2004            // vector 4
2005            let psbt = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a0100000022512083698e458c6664e1595d75da2597de1e22ee97d798e706c4c0a4b5a9823cd743000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b6926215c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac06f7d62059e9497a1a4a267569d9876da60101aff38e3529b9b939ce7f91ae970115f2e490af7cc45c4f78511f36057ce5c5a5c56325a29fb44dfc203f356e1f823202cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2acc04215c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac097c6e6fea5ff714ff5724499990810e406e98aa10f5bf7e5f6784bc1d0a9a6ce23204320b0bf16f011b53ea7be615924aa7f27e5d29ad20ea1155d848676c3bad1b2acc06215c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b09115f2e490af7cc45c4f78511f36057ce5c5a5c56325a29fb44dfc203f356e1f82320fa0f7a3cef3b1d0c0a6ce7d26e17ada0b2e5c92d19efad48b41859cb8a451ca9acc021162cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d23901cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b09772b2da7560000800100008002000080000000000000000021164320b0bf16f011b53ea7be615924aa7f27e5d29ad20ea1155d848676c3bad1b23901115f2e490af7cc45c4f78511f36057ce5c5a5c56325a29fb44dfc203f356e1f8772b2da75600008001000080010000800000000000000000211650929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac005007c461e5d2116fa0f7a3cef3b1d0c0a6ce7d26e17ada0b2e5c92d19efad48b41859cb8a451ca939016f7d62059e9497a1a4a267569d9876da60101aff38e3529b9b939ce7f91ae970772b2da7560000800100008003000080000000000000000001172050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0011820f0362e2f75a6f420a5bde3eb221d96ae6720cf25f81890c95b1d775acb515e65000105201124da7aec92ccd06c954562647f437b138b95721a84be2bf2276bbddab3e67121071124da7aec92ccd06c954562647f437b138b95721a84be2bf2276bbddab3e6711900772b2da7560000800100008000000080000000000500000000").unwrap();
2006            assert!(psbt.inputs[0].tap_internal_key.is_some());
2007            assert!(psbt.inputs[0].tap_merkle_root.is_some());
2008            assert!(!psbt.inputs[0].tap_key_origins.is_empty());
2009            assert!(!psbt.inputs[0].tap_scripts.is_empty());
2010            rtt_psbt(psbt);
2011
2012            // vector 5
2013            let psbt = hex_psbt("70736274ff01005e020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff0148e6052a010000002251200a8cbdc86de1ce1c0f9caeb22d6df7ced3683fe423e05d1e402a879341d6f6f5000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a07572116fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa2321900772b2da75600008001000080000000800100000000000000011720fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa2320001052050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac001066f02c02220736e572900fe1252589a2143c8f3c79f71a0412d2353af755e9701c782694a02ac02c02220631c5f3b5832b8fbdebfb19704ceeb323c21f40f7a24f43d68ef0cc26b125969ac01c0222044faa49a0338de488c8dfffecdfb6f329f380bd566ef20c8df6d813eab1c4273ac210744faa49a0338de488c8dfffecdfb6f329f380bd566ef20c8df6d813eab1c42733901f06b798b92a10ed9a9d0bbfd3af173a53b1617da3a4159ca008216cd856b2e0e772b2da75600008001000080010000800000000003000000210750929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac005007c461e5d2107631c5f3b5832b8fbdebfb19704ceeb323c21f40f7a24f43d68ef0cc26b125969390118ace409889785e0ea70ceebb8e1ca892a7a78eaede0f2e296cf435961a8f4ca772b2da756000080010000800200008000000000030000002107736e572900fe1252589a2143c8f3c79f71a0412d2353af755e9701c782694a02390129a5b4915090162d759afd3fe0f93fa3326056d0b4088cb933cae7826cb8d82c772b2da7560000800100008003000080000000000300000000").unwrap();
2014            assert!(psbt.outputs[0].tap_internal_key.is_some());
2015            assert!(!psbt.outputs[0].tap_key_origins.is_empty());
2016            assert!(psbt.outputs[0].tap_tree.is_some());
2017            rtt_psbt(psbt);
2018
2019            // vector 6
2020            let psbt = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a0100000022512083698e458c6664e1595d75da2597de1e22ee97d798e706c4c0a4b5a9823cd743000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b69241142cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b0940bf818d9757d6ffeb538ba057fb4c1fc4e0f5ef186e765beb564791e02af5fd3d5e2551d4e34e33d86f276b82c99c79aed3f0395a081efcd2cc2c65dd7e693d7941144320b0bf16f011b53ea7be615924aa7f27e5d29ad20ea1155d848676c3bad1b2115f2e490af7cc45c4f78511f36057ce5c5a5c56325a29fb44dfc203f356e1f840e1f1ab6fabfa26b236f21833719dc1d428ab768d80f91f9988d8abef47bfb863bb1f2a529f768c15f00ce34ec283cdc07e88f8428be28f6ef64043c32911811a4114fa0f7a3cef3b1d0c0a6ce7d26e17ada0b2e5c92d19efad48b41859cb8a451ca96f7d62059e9497a1a4a267569d9876da60101aff38e3529b9b939ce7f91ae97040ec1f0379206461c83342285423326708ab031f0da4a253ee45aafa5b8c92034d8b605490f8cd13e00f989989b97e215faa36f12dee3693d2daccf3781c1757f66215c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac06f7d62059e9497a1a4a267569d9876da60101aff38e3529b9b939ce7f91ae970115f2e490af7cc45c4f78511f36057ce5c5a5c56325a29fb44dfc203f356e1f823202cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2acc04215c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac097c6e6fea5ff714ff5724499990810e406e98aa10f5bf7e5f6784bc1d0a9a6ce23204320b0bf16f011b53ea7be615924aa7f27e5d29ad20ea1155d848676c3bad1b2acc06215c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b09115f2e490af7cc45c4f78511f36057ce5c5a5c56325a29fb44dfc203f356e1f82320fa0f7a3cef3b1d0c0a6ce7d26e17ada0b2e5c92d19efad48b41859cb8a451ca9acc021162cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d23901cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b09772b2da7560000800100008002000080000000000000000021164320b0bf16f011b53ea7be615924aa7f27e5d29ad20ea1155d848676c3bad1b23901115f2e490af7cc45c4f78511f36057ce5c5a5c56325a29fb44dfc203f356e1f8772b2da75600008001000080010000800000000000000000211650929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac005007c461e5d2116fa0f7a3cef3b1d0c0a6ce7d26e17ada0b2e5c92d19efad48b41859cb8a451ca939016f7d62059e9497a1a4a267569d9876da60101aff38e3529b9b939ce7f91ae970772b2da7560000800100008003000080000000000000000001172050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0011820f0362e2f75a6f420a5bde3eb221d96ae6720cf25f81890c95b1d775acb515e65000105201124da7aec92ccd06c954562647f437b138b95721a84be2bf2276bbddab3e67121071124da7aec92ccd06c954562647f437b138b95721a84be2bf2276bbddab3e6711900772b2da7560000800100008000000080000000000500000000").unwrap();
2021            assert!(psbt.inputs[0].tap_internal_key.is_some());
2022            assert!(psbt.inputs[0].tap_merkle_root.is_some());
2023            assert!(!psbt.inputs[0].tap_scripts.is_empty());
2024            assert!(!psbt.inputs[0].tap_script_sigs.is_empty());
2025            assert!(!psbt.inputs[0].tap_key_origins.is_empty());
2026            rtt_psbt(psbt);
2027        }
2028    }
2029
2030    #[test]
2031    fn serialize_and_deserialize_preimage_psbt() {
2032        // create a sha preimage map
2033        let mut sha256_preimages = BTreeMap::new();
2034        sha256_preimages.insert(sha256::Hash::hash(&[1u8, 2u8]), vec![1u8, 2u8]);
2035        sha256_preimages.insert(sha256::Hash::hash(&[1u8]), vec![1u8]);
2036
2037        // same for hash160
2038        let mut hash160_preimages = BTreeMap::new();
2039        hash160_preimages.insert(hash160::Hash::hash(&[1u8, 2u8]), vec![1u8, 2u8]);
2040        hash160_preimages.insert(hash160::Hash::hash(&[1u8]), vec![1u8]);
2041
2042        // same vector as valid_vector_1 from BIPs with added
2043        let mut unserialized = Psbt {
2044            unsigned_tx: Transaction {
2045                version: transaction::Version::TWO,
2046                lock_time: absolute::LockTime::from_consensus(1257139),
2047                input: vec![
2048                    TxIn {
2049                        previous_output: OutPoint {
2050                            txid: "f61b1742ca13176464adb3cb66050c00787bb3a4eead37e985f2df1e37718126".parse().unwrap(),
2051                            vout: 0,
2052                        },
2053                        script_sig: ScriptBuf::new(),
2054                        sequence: Sequence::ENABLE_LOCKTIME_NO_RBF,
2055                        witness: Witness::default(),
2056                    }
2057                ],
2058                output: vec![
2059                    TxOut {
2060                        value: Amount::from_sat(99_999_699),
2061                        script_pubkey: ScriptBuf::from_hex("76a914d0c59903c5bac2868760e90fd521a4665aa7652088ac").unwrap(),
2062                    },
2063                    TxOut {
2064                        value: Amount::from_sat(100_000_000),
2065                        script_pubkey: ScriptBuf::from_hex("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787").unwrap(),
2066                    },
2067                ],
2068            },
2069            version: 0,
2070            xpub: Default::default(),
2071            proprietary: Default::default(),
2072            unknown: BTreeMap::new(),
2073
2074            inputs: vec![
2075                Input {
2076                    non_witness_utxo: Some(Transaction {
2077                        version: transaction::Version::ONE,
2078                        lock_time: absolute::LockTime::ZERO,
2079                        input: vec![
2080                            TxIn {
2081                                previous_output: OutPoint {
2082                                    txid: "e567952fb6cc33857f392efa3a46c995a28f69cca4bb1b37e0204dab1ec7a389".parse().unwrap(),
2083                                    vout: 1,
2084                                },
2085                                script_sig: ScriptBuf::from_hex("160014be18d152a9b012039daf3da7de4f53349eecb985").unwrap(),
2086                                sequence: Sequence::MAX,
2087                                witness: Witness::from_slice(&[
2088                                    hex!("304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c01"),
2089                                    hex!("03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105"),
2090                                ]),
2091                            },
2092                            TxIn {
2093                                previous_output: OutPoint {
2094                                    txid: "b490486aec3ae671012dddb2bb08466bef37720a533a894814ff1da743aaf886".parse().unwrap(),
2095                                    vout: 1,
2096                                },
2097                                script_sig: ScriptBuf::from_hex("160014fe3e9ef1a745e974d902c4355943abcb34bd5353").unwrap(),
2098                                sequence: Sequence::MAX,
2099                                witness: Witness::from_slice(&[
2100                                    hex!("3045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01"),
2101                                    hex!("0223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab3"),
2102                                ]),
2103                            }
2104                        ],
2105                        output: vec![
2106                            TxOut {
2107                                value: Amount::from_sat(200_000_000),
2108                                script_pubkey: ScriptBuf::from_hex("76a91485cff1097fd9e008bb34af709c62197b38978a4888ac").unwrap(),
2109                            },
2110                            TxOut {
2111                                value: Amount::from_sat(190_303_501_938),
2112                                script_pubkey: ScriptBuf::from_hex("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587").unwrap(),
2113                            },
2114                        ],
2115                    }),
2116                    ..Default::default()
2117                },
2118            ],
2119            outputs: vec![
2120                Output {
2121                    ..Default::default()
2122                },
2123                Output {
2124                    ..Default::default()
2125                },
2126            ],
2127        };
2128        unserialized.inputs[0].hash160_preimages = hash160_preimages;
2129        unserialized.inputs[0].sha256_preimages = sha256_preimages;
2130
2131        let rtt: Psbt = hex_psbt(&unserialized.serialize_hex()).unwrap();
2132        assert_eq!(rtt, unserialized);
2133
2134        // Now add an ripemd160 with incorrect preimage
2135        let mut ripemd160_preimages = BTreeMap::new();
2136        ripemd160_preimages.insert(ripemd160::Hash::hash(&[17u8]), vec![18u8]);
2137        unserialized.inputs[0].ripemd160_preimages = ripemd160_preimages;
2138
2139        // Now the roundtrip should fail as the preimage is incorrect.
2140        let rtt: Result<Psbt, _> = hex_psbt(&unserialized.serialize_hex());
2141        assert!(rtt.is_err());
2142    }
2143
2144    #[test]
2145    fn serialize_and_deserialize_proprietary() {
2146        let mut psbt: Psbt = hex_psbt("70736274ff0100a00200000002ab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40000000000feffffffab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40100000000feffffff02603bea0b000000001976a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac8e240000000000001976a9146f4620b553fa095e721b9ee0efe9fa039cca459788ac000000000001076a47304402204759661797c01b036b25928948686218347d89864b719e1f7fcf57d1e511658702205309eabf56aa4d8891ffd111fdf1336f3a29da866d7f8486d75546ceedaf93190121035cdc61fc7ba971c0b501a646a2a83b102cb43881217ca682dc86e2d73fa882920001012000e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787010416001485d13537f2e265405a34dbafa9e3dda01fb82308000000").unwrap();
2147        psbt.proprietary.insert(
2148            raw::ProprietaryKey { prefix: b"test".to_vec(), subtype: 0u8, key: b"test".to_vec() },
2149            b"test".to_vec(),
2150        );
2151        assert!(!psbt.proprietary.is_empty());
2152        let rtt: Psbt = hex_psbt(&psbt.serialize_hex()).unwrap();
2153        assert!(!rtt.proprietary.is_empty());
2154    }
2155
2156    // PSBTs taken from BIP 174 test vectors.
2157    #[test]
2158    fn combine_psbts() {
2159        let mut psbt1 = hex_psbt(include_str!("../../tests/data/psbt1.hex")).unwrap();
2160        let psbt2 = hex_psbt(include_str!("../../tests/data/psbt2.hex")).unwrap();
2161        let psbt_combined = hex_psbt(include_str!("../../tests/data/psbt2.hex")).unwrap();
2162
2163        psbt1.combine(psbt2).expect("psbt combine to succeed");
2164        assert_eq!(psbt1, psbt_combined);
2165    }
2166
2167    #[test]
2168    fn combine_psbts_commutative() {
2169        let mut psbt1 = hex_psbt(include_str!("../../tests/data/psbt1.hex")).unwrap();
2170        let mut psbt2 = hex_psbt(include_str!("../../tests/data/psbt2.hex")).unwrap();
2171
2172        let psbt1_clone = psbt1.clone();
2173        let psbt2_clone = psbt2.clone();
2174
2175        psbt1.combine(psbt2_clone).expect("psbt1 combine to succeed");
2176        psbt2.combine(psbt1_clone).expect("psbt2 combine to succeed");
2177
2178        assert_eq!(psbt1, psbt2);
2179    }
2180
2181    #[cfg(feature = "rand-std")]
2182    fn gen_keys() -> (PrivateKey, PublicKey, Secp256k1<All>) {
2183        use secp256k1::rand::thread_rng;
2184
2185        let secp = Secp256k1::new();
2186
2187        let sk = SecretKey::new(&mut thread_rng());
2188        let priv_key = PrivateKey::new(sk, NetworkKind::Test);
2189        let pk = PublicKey::from_private_key(&secp, &priv_key);
2190
2191        (priv_key, pk, secp)
2192    }
2193
2194    #[test]
2195    #[cfg(feature = "rand-std")]
2196    fn get_key_btree_map() {
2197        let (priv_key, pk, secp) = gen_keys();
2198
2199        let mut key_map = BTreeMap::new();
2200        key_map.insert(pk, priv_key);
2201
2202        let got = key_map.get_key(KeyRequest::Pubkey(pk), &secp).expect("failed to get key");
2203        assert_eq!(got.unwrap(), priv_key)
2204    }
2205
2206    #[test]
2207    #[cfg(feature = "rand-std")]
2208    fn pubkey_map_get_key_negates_odd_parity_keys() {
2209        use crate::psbt::{GetKey, KeyRequest};
2210
2211        let (mut priv_key, mut pk, secp) = gen_keys();
2212        let (xonly, parity) = pk.inner.x_only_public_key();
2213
2214        let mut pubkey_map: HashMap<PublicKey, PrivateKey> = HashMap::new();
2215
2216        if parity == secp256k1::Parity::Even {
2217            priv_key = PrivateKey {
2218                compressed: priv_key.compressed,
2219                network: priv_key.network,
2220                inner: priv_key.inner.negate(),
2221            };
2222            pk = priv_key.public_key(&secp);
2223        }
2224
2225        pubkey_map.insert(pk, priv_key);
2226
2227        let req_result = pubkey_map.get_key(KeyRequest::XOnlyPubkey(xonly), &secp).unwrap();
2228
2229        let retrieved_key = req_result.unwrap();
2230
2231        let retrieved_pub_key = retrieved_key.public_key(&secp);
2232        let (retrieved_xonly, retrieved_parity) = retrieved_pub_key.inner.x_only_public_key();
2233
2234        assert_eq!(xonly, retrieved_xonly);
2235        assert_eq!(
2236            retrieved_parity,
2237            secp256k1::Parity::Even,
2238            "Key should be normalized to have even parity, even when original had odd parity"
2239        );
2240    }
2241
2242    #[test]
2243    fn fee() {
2244        let output_0_val = Amount::from_sat(99_999_699);
2245        let output_1_val = Amount::from_sat(100_000_000);
2246        let prev_output_val = Amount::from_sat(200_000_000);
2247
2248        let mut t = Psbt {
2249            unsigned_tx: Transaction {
2250                version: transaction::Version::TWO,
2251                lock_time: absolute::LockTime::from_consensus(1257139),
2252                input: vec![
2253                    TxIn {
2254                        previous_output: OutPoint {
2255                            txid: "f61b1742ca13176464adb3cb66050c00787bb3a4eead37e985f2df1e37718126".parse().unwrap(),
2256                            vout: 0,
2257                        },
2258                        sequence: Sequence::ENABLE_LOCKTIME_NO_RBF,
2259                        ..Default::default()
2260                    }
2261                ],
2262                output: vec![
2263                    TxOut {
2264                        value: output_0_val,
2265                        script_pubkey:  ScriptBuf::new()
2266                    },
2267                    TxOut {
2268                        value: output_1_val,
2269                        script_pubkey:  ScriptBuf::new()
2270                    },
2271                ],
2272            },
2273            xpub: Default::default(),
2274            version: 0,
2275            proprietary: BTreeMap::new(),
2276            unknown: BTreeMap::new(),
2277
2278            inputs: vec![
2279                Input {
2280                    non_witness_utxo: Some(Transaction {
2281                        version: transaction::Version::ONE,
2282                        lock_time: absolute::LockTime::ZERO,
2283                        input: vec![
2284                            TxIn {
2285                                previous_output: OutPoint {
2286                                    txid: "e567952fb6cc33857f392efa3a46c995a28f69cca4bb1b37e0204dab1ec7a389".parse().unwrap(),
2287                                    vout: 1,
2288                                },
2289                                sequence: Sequence::MAX,
2290                                ..Default::default()
2291                            },
2292                            TxIn {
2293                                previous_output: OutPoint {
2294                                    txid: "b490486aec3ae671012dddb2bb08466bef37720a533a894814ff1da743aaf886".parse().unwrap(),
2295                                    vout: 1,
2296                                },
2297                                sequence: Sequence::MAX,
2298                                ..Default::default()
2299                            }
2300                        ],
2301                        output: vec![
2302                            TxOut {
2303                                value: prev_output_val,
2304                                script_pubkey:  ScriptBuf::new()
2305                            },
2306                            TxOut {
2307                                value: Amount::from_sat(190_303_501_938),
2308                                script_pubkey:  ScriptBuf::new()
2309                            },
2310                        ],
2311                    }),
2312                    ..Default::default()
2313                },
2314            ],
2315            outputs: vec![
2316                Output {
2317                    ..Default::default()
2318                },
2319                Output {
2320                    ..Default::default()
2321                },
2322            ],
2323        };
2324        assert_eq!(
2325            t.fee().expect("fee calculation"),
2326            prev_output_val - (output_0_val + output_1_val)
2327        );
2328        // no previous output
2329        let mut t2 = t.clone();
2330        t2.inputs[0].non_witness_utxo = None;
2331        match t2.fee().unwrap_err() {
2332            Error::MissingUtxo => {}
2333            e => panic!("unexpected error: {:?}", e),
2334        }
2335        //  negative fee
2336        let mut t3 = t.clone();
2337        t3.unsigned_tx.output[0].value = prev_output_val;
2338        match t3.fee().unwrap_err() {
2339            Error::NegativeFee => {}
2340            e => panic!("unexpected error: {:?}", e),
2341        }
2342        // overflow
2343        t.unsigned_tx.output[0].value = Amount::MAX;
2344        t.unsigned_tx.output[1].value = Amount::MAX;
2345        match t.fee().unwrap_err() {
2346            Error::FeeOverflow => {}
2347            e => panic!("unexpected error: {:?}", e),
2348        }
2349    }
2350
2351    #[test]
2352    #[cfg(feature = "rand-std")]
2353    fn hashmap_can_sign_taproot() {
2354        let (priv_key, pk, secp) = gen_keys();
2355        let internal_key: XOnlyPublicKey = pk.inner.into();
2356
2357        let tx = Transaction {
2358            version: transaction::Version::TWO,
2359            lock_time: locktime::absolute::LockTime::ZERO,
2360            input: vec![TxIn::default()],
2361            output: vec![TxOut { value: Amount::ZERO, script_pubkey: ScriptBuf::new() }],
2362        };
2363
2364        let mut psbt = Psbt::from_unsigned_tx(tx).unwrap();
2365        psbt.inputs[0].tap_internal_key = Some(internal_key);
2366        psbt.inputs[0].witness_utxo = Some(transaction::TxOut {
2367            value: Amount::from_sat(10),
2368            script_pubkey: ScriptBuf::new_p2tr(&secp, internal_key, None),
2369        });
2370
2371        let mut key_map: HashMap<PublicKey, PrivateKey> = HashMap::new();
2372        key_map.insert(pk, priv_key);
2373
2374        let key_source = (Fingerprint::default(), DerivationPath::default());
2375        let mut tap_key_origins = std::collections::BTreeMap::new();
2376        tap_key_origins.insert(internal_key, (vec![], key_source));
2377        psbt.inputs[0].tap_key_origins = tap_key_origins;
2378
2379        let signing_keys = psbt.sign(&key_map, &secp).unwrap();
2380        assert_eq!(signing_keys.len(), 1);
2381        assert_eq!(signing_keys[&0], SigningKeys::Schnorr(vec![internal_key]));
2382    }
2383
2384    #[test]
2385    #[cfg(feature = "rand-std")]
2386    fn xonly_hashmap_can_sign_taproot() {
2387        let (priv_key, pk, secp) = gen_keys();
2388        let internal_key: XOnlyPublicKey = pk.inner.into();
2389
2390        let tx = Transaction {
2391            version: transaction::Version::TWO,
2392            lock_time: locktime::absolute::LockTime::ZERO,
2393            input: vec![TxIn::default()],
2394            output: vec![TxOut { value: Amount::ZERO, script_pubkey: ScriptBuf::new() }],
2395        };
2396
2397        let mut psbt = Psbt::from_unsigned_tx(tx).unwrap();
2398        psbt.inputs[0].tap_internal_key = Some(internal_key);
2399        psbt.inputs[0].witness_utxo = Some(transaction::TxOut {
2400            value: Amount::from_sat(10),
2401            script_pubkey: ScriptBuf::new_p2tr(&secp, internal_key, None),
2402        });
2403
2404        let mut xonly_key_map: HashMap<XOnlyPublicKey, PrivateKey> = HashMap::new();
2405        xonly_key_map.insert(internal_key, priv_key);
2406
2407        let key_source = (Fingerprint::default(), DerivationPath::default());
2408        let mut tap_key_origins = std::collections::BTreeMap::new();
2409        tap_key_origins.insert(internal_key, (vec![], key_source));
2410        psbt.inputs[0].tap_key_origins = tap_key_origins;
2411
2412        let signing_keys = psbt.sign(&xonly_key_map, &secp).unwrap();
2413        assert_eq!(signing_keys.len(), 1);
2414        assert_eq!(signing_keys[&0], SigningKeys::Schnorr(vec![internal_key]));
2415    }
2416
2417    #[test]
2418    #[cfg(feature = "rand-std")]
2419    fn sign_psbt() {
2420        let unsigned_tx = Transaction {
2421            version: transaction::Version::TWO,
2422            lock_time: absolute::LockTime::ZERO,
2423            input: vec![TxIn::default(), TxIn::default()],
2424            output: vec![TxOut::NULL],
2425        };
2426        let mut psbt = Psbt::from_unsigned_tx(unsigned_tx).unwrap();
2427
2428        let (priv_key, pk, secp) = gen_keys();
2429
2430        // key_map implements `GetKey` using KeyRequest::Pubkey. A pubkey key request does not use
2431        // keysource so we use default `KeySource` (fingreprint and derivation path) below.
2432        let mut key_map = BTreeMap::new();
2433        key_map.insert(pk, priv_key);
2434
2435        // First input we can spend. See comment above on key_map for why we use defaults here.
2436        let txout_wpkh = TxOut {
2437            value: Amount::from_sat(10),
2438            script_pubkey: ScriptBuf::new_p2wpkh(&WPubkeyHash::hash(&pk.to_bytes())),
2439        };
2440        psbt.inputs[0].witness_utxo = Some(txout_wpkh);
2441
2442        let mut map = BTreeMap::new();
2443        map.insert(pk.inner, (Fingerprint::default(), DerivationPath::default()));
2444        psbt.inputs[0].bip32_derivation = map;
2445
2446        // Second input is unspendable by us e.g., from another wallet that supports future upgrades.
2447        let unknown_prog = WitnessProgram::new(WitnessVersion::V4, &[0xaa; 34]).unwrap();
2448        let txout_unknown_future = TxOut {
2449            value: Amount::from_sat(10),
2450            script_pubkey: ScriptBuf::new_witness_program(&unknown_prog),
2451        };
2452        psbt.inputs[1].witness_utxo = Some(txout_unknown_future);
2453
2454        let (signing_keys, _) = psbt.sign(&key_map, &secp).unwrap_err();
2455
2456        assert_eq!(signing_keys.len(), 1);
2457        assert_eq!(signing_keys[&0], SigningKeys::Ecdsa(vec![pk]));
2458    }
2459}