1#[cfg(feature = "silent-payments")]
27pub mod dleq;
28mod error;
29mod extract;
30mod map;
31#[cfg(feature = "miniscript")]
32mod miniscript;
33
34use core::fmt;
35use core::marker::PhantomData;
36#[cfg(feature = "std")]
37use std::collections::{HashMap, HashSet};
38
39use bitcoin::bip32::{self, KeySource, Xpriv};
40use bitcoin::key::{PrivateKey, PublicKey};
41use bitcoin::locktime::absolute;
42use bitcoin::secp256k1::{Message, Secp256k1, Signing};
43use bitcoin::sighash::{EcdsaSighashType, SighashCache};
44use bitcoin::{ecdsa, transaction, Amount, Sequence, Transaction, TxOut, Txid};
45
46use crate::error::{write_err, FeeError, FundingUtxoError};
47use crate::prelude::*;
48use crate::v2::map::Map;
49
50#[rustfmt::skip] #[doc(inline)]
52pub use self::{
53 error::{
54 DeserializeError, DetermineLockTimeError, IndexOutOfBoundsError, InputsNotModifiableError,
55 NotUnsignedError, OutputsNotModifiableError, PartialSigsSighashTypeError,
56 PsbtNotModifiableError, SignError,
57 },
58 extract::{Extractor, ExtractError, ExtractTxError, ExtractTxFeeRateError},
59 map::{
60 global::{self, Global},
62 input::{self, Input, InputBuilder},
63 output::{self, Output, OutputBuilder},
64 },
65};
66#[cfg(feature = "base64")]
67pub use self::display_from_str::ParsePsbtError;
68#[cfg(feature = "silent-payments")]
69pub use self::dleq::{DleqProof, InvalidLengthError};
70#[cfg(feature = "miniscript")]
71pub use self::miniscript::{
72 FinalizeError, FinalizeInputError, Finalizer, InputError, InterpreterCheckError,
73 InterpreterCheckInputError,
74};
75
76pub fn combine(this: Psbt, that: Psbt) -> Result<Psbt, CombineError> { this.combine_with(that) }
80#[derive(Debug, Clone, PartialEq, Eq, Hash)]
94#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
95pub struct Creator(Psbt);
96
97impl Creator {
98 pub fn new() -> Self {
100 let psbt = Psbt {
101 global: Global::default(),
102 inputs: Default::default(),
103 outputs: Default::default(),
104 };
105 Creator(psbt)
106 }
107
108 pub fn fallback_lock_time(mut self, fallback: absolute::LockTime) -> Self {
110 self.0.global.fallback_lock_time = Some(fallback);
111 self
112 }
113
114 pub fn sighash_single(mut self) -> Self {
116 self.0.global.set_sighash_single_flag();
117 self
118 }
119
120 pub fn inputs_modifiable(mut self) -> Self {
122 self.0.global.set_inputs_modifiable_flag();
123 self
124 }
125
126 pub fn outputs_modifiable(mut self) -> Self {
128 self.0.global.set_outputs_modifiable_flag();
129 self
130 }
131
132 pub fn transaction_version(mut self, version: transaction::Version) -> Self {
138 self.0.global.tx_version = version;
139 self
140 }
141
142 pub fn constructor_modifiable(self) -> Constructor<Modifiable> {
163 let mut psbt = self.0;
164 psbt.global.set_inputs_modifiable_flag();
165 psbt.global.set_outputs_modifiable_flag();
166 Constructor(psbt, PhantomData)
167 }
168
169 pub fn constructor_inputs_only_modifiable(self) -> Constructor<InputsOnlyModifiable> {
189 let mut psbt = self.0;
190 psbt.global.set_inputs_modifiable_flag();
191 psbt.global.clear_outputs_modifiable_flag();
192 Constructor(psbt, PhantomData)
193 }
194
195 pub fn constructor_outputs_only_modifiable(self) -> Constructor<OutputsOnlyModifiable> {
215 let mut psbt = self.0;
216 psbt.global.clear_inputs_modifiable_flag();
217 psbt.global.set_outputs_modifiable_flag();
218 Constructor(psbt, PhantomData)
219 }
220
221 pub fn psbt(self) -> Psbt { self.0 }
226}
227
228impl Default for Creator {
229 fn default() -> Self { Self::new() }
230}
231
232pub enum Modifiable {}
234pub enum InputsOnlyModifiable {}
236pub enum OutputsOnlyModifiable {}
238
239mod sealed {
240 pub trait Mod {}
241 impl Mod for super::Modifiable {}
242 impl Mod for super::InputsOnlyModifiable {}
243 impl Mod for super::OutputsOnlyModifiable {}
244}
245
246pub trait Mod: sealed::Mod + Sync + Send + Sized + Unpin {}
248
249impl Mod for Modifiable {}
250impl Mod for InputsOnlyModifiable {}
251impl Mod for OutputsOnlyModifiable {}
252
253#[derive(Debug, Clone, PartialEq, Eq, Hash)]
257#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
258pub struct Constructor<T>(Psbt, PhantomData<T>);
259
260impl<T: Mod> Constructor<T> {
261 pub fn no_more_inputs(mut self) -> Self {
263 self.0.global.clear_inputs_modifiable_flag();
264 self
265 }
266
267 pub fn no_more_outputs(mut self) -> Self {
269 self.0.global.clear_outputs_modifiable_flag();
270 self
271 }
272
273 pub fn updater(self) -> Result<Updater, DetermineLockTimeError> {
275 self.no_more_inputs().no_more_outputs().psbt().map(Updater)
276 }
277
278 pub fn psbt(self) -> Result<Psbt, DetermineLockTimeError> {
284 let _ = self.0.determine_lock_time()?;
285 Ok(self.0)
286 }
287}
288
289impl Constructor<Modifiable> {
290 pub fn new(psbt: Psbt) -> Result<Self, PsbtNotModifiableError> {
296 if !psbt.global.is_inputs_modifiable() {
297 Err(InputsNotModifiableError.into())
298 } else if !psbt.global.is_outputs_modifiable() {
299 Err(OutputsNotModifiableError.into())
300 } else {
301 Ok(Self(psbt, PhantomData))
302 }
303 }
304
305 pub fn input(mut self, input: Input) -> Self {
307 self.0.inputs.push(input);
308 self.0.global.input_count += 1;
309 self
310 }
311
312 pub fn output(mut self, output: Output) -> Self {
314 self.0.outputs.push(output);
315 self.0.global.output_count += 1;
316 self
317 }
318}
319impl Default for Constructor<Modifiable> {
321 fn default() -> Self { Creator::new().constructor_modifiable() }
322}
323
324impl Constructor<InputsOnlyModifiable> {
325 pub fn new(psbt: Psbt) -> Result<Self, InputsNotModifiableError> {
331 if psbt.global.is_inputs_modifiable() {
332 Ok(Self(psbt, PhantomData))
333 } else {
334 Err(InputsNotModifiableError)
335 }
336 }
337
338 pub fn input(mut self, input: Input) -> Self {
340 self.0.inputs.push(input);
341 self.0.global.input_count += 1;
342 self
343 }
344}
345
346impl Default for Constructor<InputsOnlyModifiable> {
348 fn default() -> Self { Creator::new().constructor_inputs_only_modifiable() }
349}
350
351impl Constructor<OutputsOnlyModifiable> {
352 pub fn new(psbt: Psbt) -> Result<Self, OutputsNotModifiableError> {
358 if psbt.global.is_outputs_modifiable() {
359 Ok(Self(psbt, PhantomData))
360 } else {
361 Err(OutputsNotModifiableError)
362 }
363 }
364
365 pub fn output(mut self, output: Output) -> Self {
367 self.0.outputs.push(output);
368 self.0.global.output_count += 1;
369 self
370 }
371}
372
373impl Default for Constructor<OutputsOnlyModifiable> {
375 fn default() -> Self { Creator::new().constructor_outputs_only_modifiable() }
376}
377
378#[derive(Debug, Clone, PartialEq, Eq, Hash)]
380#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
381pub struct Updater(Psbt);
382
383impl Updater {
384 pub fn new(psbt: Psbt) -> Result<Self, DetermineLockTimeError> {
388 let _ = psbt.determine_lock_time()?;
389 Ok(Self(psbt))
390 }
391
392 pub fn id(&self) -> Txid {
394 self.0.id().expect("Updater guarantees lock time can be determined")
395 }
396
397 pub fn set_sequence(
399 mut self,
400 n: Sequence,
401 input_index: usize,
402 ) -> Result<Updater, IndexOutOfBoundsError> {
403 let input = self.0.checked_input_mut(input_index)?;
404 input.sequence = Some(n);
405 Ok(self)
406 }
407
408 pub fn psbt(self) -> Psbt { self.0 }
423}
424
425impl TryFrom<Psbt> for Updater {
426 type Error = DetermineLockTimeError;
427
428 fn try_from(psbt: Psbt) -> Result<Self, Self::Error> { Self::new(psbt) }
429}
430
431#[derive(Debug, Clone, PartialEq, Eq, Hash)]
433#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
434pub struct Signer(Psbt);
435
436impl Signer {
437 pub fn new(psbt: Psbt) -> Result<Self, DetermineLockTimeError> {
441 let _ = psbt.determine_lock_time()?;
442 Ok(Self(psbt))
443 }
444
445 pub fn id(&self) -> Result<Txid, DetermineLockTimeError> { self.0.id() }
447
448 pub fn unsigned_tx(&self) -> Transaction {
450 self.0.unsigned_tx().expect("Signer guarantees lock time can be determined")
451 }
452
453 pub fn sign<C, K>(
470 self,
471 k: &K,
472 secp: &Secp256k1<C>,
473 ) -> Result<(Psbt, SigningKeys), (SigningKeys, SigningErrors)>
474 where
475 C: Signing,
476 K: GetKey,
477 {
478 let tx = self.unsigned_tx();
479 let mut psbt = self.psbt();
480
481 psbt.sign(tx, k, secp).map(|signing_keys| (psbt, signing_keys))
482 }
483
484 pub fn ecdsa_clear_tx_modifiable(&mut self, ty: EcdsaSighashType) {
489 self.0.clear_tx_modifiable(ty as u8)
490 }
491
492 pub fn psbt(self) -> Psbt { self.0 }
494}
495
496#[derive(Debug, Clone, PartialEq, Eq, Hash)]
498#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
499pub struct Psbt {
500 pub global: Global,
502 pub inputs: Vec<Input>,
504 pub outputs: Vec<Output>,
506}
507
508impl Psbt {
509 fn id(&self) -> Result<Txid, DetermineLockTimeError> {
513 let mut tx = self.unsigned_tx()?;
514 tx.input.iter_mut().for_each(|input| input.sequence = Sequence::ZERO);
516
517 Ok(tx.compute_txid())
518 }
519
520 fn unsigned_tx(&self) -> Result<Transaction, DetermineLockTimeError> {
525 let lock_time = self.determine_lock_time()?;
526
527 Ok(Transaction {
528 version: self.global.tx_version,
529 lock_time,
530 input: self.inputs.iter().map(|input| input.unsigned_tx_in()).collect(),
531 output: self.outputs.iter().map(|ouput| ouput.tx_out()).collect(),
532 })
533 }
534
535 pub fn determine_lock_time(&self) -> Result<absolute::LockTime, DetermineLockTimeError> {
539 let require_time_based_lock_time =
540 self.inputs.iter().any(|input| input.requires_time_based_lock_time());
541 let require_height_based_lock_time =
542 self.inputs.iter().any(|input| input.requires_height_based_lock_time());
543
544 if require_time_based_lock_time && require_height_based_lock_time {
545 return Err(DetermineLockTimeError);
546 }
547
548 let have_lock_time = self.inputs.iter().any(|input| input.has_lock_time());
549
550 let lock = if have_lock_time {
551 let all_inputs_satisfied_with_height_based_lock_time =
552 self.inputs.iter().all(|input| input.is_satisfied_with_height_based_lock_time());
553
554 if all_inputs_satisfied_with_height_based_lock_time {
556 let height = self
558 .inputs
559 .iter()
560 .map(|input| input.min_height)
561 .max()
562 .expect("we know we have at least one non-none min_height field")
563 .expect("so we know that max is non-none");
564 absolute::LockTime::from(height)
565 } else {
566 let time = self
567 .inputs
568 .iter()
569 .map(|input| input.min_time)
570 .max()
571 .expect("we know we have at least one non-none min_height field")
572 .expect("so we know that max is non-none");
573 absolute::LockTime::from(time)
574 }
575 } else {
576 self.global.fallback_lock_time.unwrap_or(absolute::LockTime::ZERO)
580 };
581
582 Ok(lock)
583 }
584
585 pub fn is_finalized(&self) -> bool { self.inputs.iter().all(|input| input.is_finalized()) }
587
588 pub fn serialize_hex(&self) -> String { self.serialize().to_lower_hex_string() }
590
591 pub fn serialize(&self) -> Vec<u8> {
593 let mut buf: Vec<u8> = Vec::new();
594
595 buf.extend_from_slice(b"psbt");
597
598 buf.push(0xff_u8);
599
600 buf.extend(self.global.serialize_map());
601
602 for i in &self.inputs {
603 buf.extend(i.serialize_map());
604 }
605
606 for i in &self.outputs {
607 buf.extend(i.serialize_map());
608 }
609
610 buf
611 }
612
613 pub fn deserialize(bytes: &[u8]) -> Result<Self, DeserializeError> {
615 use DeserializeError::*;
616
617 const MAGIC_BYTES: &[u8] = b"psbt";
618 if bytes.get(0..MAGIC_BYTES.len()) != Some(MAGIC_BYTES) {
619 return Err(InvalidMagic);
620 }
621
622 const PSBT_SERPARATOR: u8 = 0xff_u8;
623 if bytes.get(MAGIC_BYTES.len()) != Some(&PSBT_SERPARATOR) {
624 return Err(InvalidSeparator);
625 }
626
627 let mut d = bytes.get(5..).ok_or(NoMorePairs)?;
628
629 let global = Global::decode(&mut d)?;
630
631 let inputs: Vec<Input> = {
632 let inputs_len: usize = global.input_count;
633 let mut inputs: Vec<Input> = Vec::with_capacity(inputs_len);
634
635 for _ in 0..inputs_len {
636 inputs.push(Input::decode(&mut d)?);
637 }
638
639 inputs
640 };
641
642 let outputs: Vec<Output> = {
643 let outputs_len: usize = global.output_count;
644 let mut outputs: Vec<Output> = Vec::with_capacity(outputs_len);
645
646 for _ in 0..outputs_len {
647 outputs.push(Output::decode(&mut d)?)
648 }
649
650 outputs
651 };
652
653 Ok(Psbt { global, inputs, outputs })
654 }
655
656 pub fn iter_funding_utxos(&self) -> impl Iterator<Item = Result<&TxOut, FundingUtxoError>> {
665 self.inputs.iter().map(|input| input.funding_utxo())
666 }
667
668 pub fn combine_with(mut self, other: Self) -> Result<Psbt, CombineError> {
676 self.global.combine(other.global)?;
677
678 for (self_input, other_input) in self.inputs.iter_mut().zip(other.inputs.into_iter()) {
679 self_input.combine(other_input)?;
680 }
681
682 for (self_output, other_output) in self.outputs.iter_mut().zip(other.outputs.into_iter()) {
683 self_output.combine(other_output)?;
684 }
685
686 Ok(self)
687 }
688
689 fn clear_tx_modifiable(&mut self, sighash_type: u8) {
692 let ty = sighash_type;
693 if !(ty == 0x81 || ty == 0x82 || ty == 0x83) {
696 self.global.clear_inputs_modifiable_flag();
697 }
698
699 if !(ty == 0x02 || ty == 0x82) {
702 self.global.clear_outputs_modifiable_flag();
703 }
704
705 if ty == 0x03 || ty == 0x83 {
708 self.global.set_sighash_single_flag();
709 }
710 }
711
712 fn sign<C, K>(
729 &mut self,
730 tx: Transaction,
731 k: &K,
732 secp: &Secp256k1<C>,
733 ) -> Result<SigningKeys, (SigningKeys, SigningErrors)>
734 where
735 C: Signing,
736 K: GetKey,
737 {
738 let mut cache = SighashCache::new(&tx);
739
740 let mut used = BTreeMap::new();
741 let mut errors = BTreeMap::new();
742
743 for i in 0..self.global.input_count {
744 if let Ok(SigningAlgorithm::Ecdsa) = self.signing_algorithm(i) {
745 match self.bip32_sign_ecdsa(k, i, &mut cache, secp) {
746 Ok(v) => {
747 used.insert(i, v);
748 }
749 Err(e) => {
750 errors.insert(i, e);
751 }
752 }
753 };
754 }
755 if errors.is_empty() {
756 Ok(used)
757 } else {
758 Err((used, errors))
759 }
760 }
761
762 fn bip32_sign_ecdsa<C, K, T>(
770 &mut self,
771 k: &K,
772 input_index: usize,
773 cache: &mut SighashCache<T>,
774 secp: &Secp256k1<C>,
775 ) -> Result<Vec<PublicKey>, SignError>
776 where
777 C: Signing,
778 T: Borrow<Transaction>,
779 K: GetKey,
780 {
781 let msg_sighash_ty_res = self.sighash_ecdsa(input_index, cache);
782 let sighash_ty = msg_sighash_ty_res.clone().ok().map(|(_msg, sighash_ty)| sighash_ty);
783
784 let input = &mut self.inputs[input_index]; let mut used = vec![]; for (pk, key_source) in input.bip32_derivations.iter() {
788 let sk = if let Ok(Some(sk)) = k.get_key(KeyRequest::Bip32(key_source.clone()), secp) {
789 sk
790 } else if let Ok(Some(sk)) = k.get_key(KeyRequest::Pubkey(*pk), secp) {
791 sk
792 } else {
793 continue;
794 };
795
796 let (msg, sighash_ty) = match msg_sighash_ty_res {
798 Err(e) => return Err(e),
799 Ok((msg, sighash_ty)) => (msg, sighash_ty),
800 };
801
802 let sig = ecdsa::Signature {
803 signature: secp.sign_ecdsa(&msg, &sk.inner),
804 sighash_type: sighash_ty,
805 };
806
807 let pk = sk.public_key(secp);
808
809 input.partial_sigs.insert(pk, sig);
810 used.push(pk);
811 }
812
813 let ty = sighash_ty.expect("at this stage we know its ok");
814 self.clear_tx_modifiable(ty as u8);
815
816 Ok(used)
817 }
818
819 pub fn sighash_ecdsa<T: Borrow<Transaction>>(
825 &self,
826 input_index: usize,
827 cache: &mut SighashCache<T>,
828 ) -> Result<(Message, EcdsaSighashType), SignError> {
829 use OutputType::*;
830
831 if self.signing_algorithm(input_index)? != SigningAlgorithm::Ecdsa {
832 return Err(SignError::WrongSigningAlgorithm);
833 }
834
835 let input = self.checked_input(input_index)?;
836 let utxo = input.funding_utxo()?;
837 let spk = &utxo.script_pubkey; let hash_ty = input.ecdsa_hash_ty().map_err(|_| SignError::InvalidSighashType)?; match self.output_type(input_index)? {
842 Bare => {
843 let sighash = cache
844 .legacy_signature_hash(input_index, spk, hash_ty.to_u32())
845 .expect("input checked above");
846 Ok((Message::from(sighash), hash_ty))
847 }
848 Sh => {
849 let script_code =
850 input.redeem_script.as_ref().ok_or(SignError::MissingRedeemScript)?;
851 let sighash = cache
852 .legacy_signature_hash(input_index, script_code, hash_ty.to_u32())
853 .expect("input checked above");
854 Ok((Message::from(sighash), hash_ty))
855 }
856 Wpkh => {
857 let sighash = cache.p2wpkh_signature_hash(input_index, spk, utxo.value, hash_ty)?;
858 Ok((Message::from(sighash), hash_ty))
859 }
860 ShWpkh => {
861 let redeem_script = input.redeem_script.as_ref().expect("checked above");
862 let sighash =
863 cache.p2wpkh_signature_hash(input_index, redeem_script, utxo.value, hash_ty)?;
864 Ok((Message::from(sighash), hash_ty))
865 }
866 Wsh | ShWsh => {
867 let witness_script =
868 input.witness_script.as_ref().ok_or(SignError::MissingWitnessScript)?;
869 let sighash = cache
870 .p2wsh_signature_hash(input_index, witness_script, utxo.value, hash_ty)
871 .map_err(SignError::SegwitV0Sighash)?;
872 Ok((Message::from(sighash), hash_ty))
873 }
874 Tr => {
875 Err(SignError::Unsupported)
877 }
878 }
879 }
880
881 fn checked_input(&self, index: usize) -> Result<&Input, IndexOutOfBoundsError> {
883 self.check_input_index(index)?;
884 Ok(&self.inputs[index])
885 }
886
887 fn checked_input_mut(&mut self, index: usize) -> Result<&mut Input, IndexOutOfBoundsError> {
889 self.check_input_index(index)?;
890 Ok(&mut self.inputs[index])
891 }
892 fn check_input_index(&self, index: usize) -> Result<(), IndexOutOfBoundsError> {
894 if index >= self.inputs.len() {
895 return Err(IndexOutOfBoundsError::Inputs { index, length: self.inputs.len() });
896 }
897 if index >= self.global.input_count {
898 return Err(IndexOutOfBoundsError::Count { index, count: self.global.input_count });
899 }
900 Ok(())
901 }
902
903 fn signing_algorithm(&self, input_index: usize) -> Result<SigningAlgorithm, SignError> {
905 let output_type = self.output_type(input_index)?;
906 Ok(output_type.signing_algorithm())
907 }
908
909 fn output_type(&self, input_index: usize) -> Result<OutputType, SignError> {
911 let input = self.checked_input(input_index)?;
912 let utxo = input.funding_utxo()?;
913 let spk = utxo.script_pubkey.clone();
914
915 if !(spk.is_witness_program() || spk.is_p2sh()) {
917 return Ok(OutputType::Bare);
918 }
919
920 if spk.is_p2wpkh() {
921 return Ok(OutputType::Wpkh);
922 }
923
924 if spk.is_p2wsh() {
925 return Ok(OutputType::Wsh);
926 }
927
928 if spk.is_p2sh() {
929 if input.redeem_script.as_ref().map(|s| s.is_p2wpkh()).unwrap_or(false) {
930 return Ok(OutputType::ShWpkh);
931 }
932 if input.redeem_script.as_ref().map(|x| x.is_p2wsh()).unwrap_or(false) {
933 return Ok(OutputType::ShWsh);
934 }
935 return Ok(OutputType::Sh);
936 }
937
938 if spk.is_p2tr() {
939 return Ok(OutputType::Tr);
940 }
941
942 Err(SignError::UnknownOutputType)
945 }
946
947 pub fn fee(&self) -> Result<Amount, FeeError> {
952 use FeeError::*;
953
954 let mut input_value: u64 = 0;
956 for input in self.iter_funding_utxos() {
957 input_value = input_value.checked_add(input?.value.to_sat()).ok_or(InputOverflow)?;
958 }
959 let mut output_value: u64 = 0;
961 for output in &self.outputs {
962 output_value =
963 output_value.checked_add(output.amount.to_sat()).ok_or(OutputOverflow)?;
964 }
965
966 input_value.checked_sub(output_value).map(Amount::from_sat).ok_or(Negative)
967 }
968
969 #[cfg(feature = "miniscript")]
973 pub(crate) fn check_partial_sigs_sighash_type(
974 &self,
975 ) -> Result<(), PartialSigsSighashTypeError> {
976 use PartialSigsSighashTypeError::*;
977
978 for (input_index, input) in self.inputs.iter().enumerate() {
979 let target_ecdsa_sighash_ty = match input.sighash_type {
980 Some(psbt_hash_ty) => psbt_hash_ty
981 .ecdsa_hash_ty()
982 .map_err(|error| NonStandardInputSighashType { input_index, error })?,
983 None => EcdsaSighashType::All,
984 };
985
986 for (key, ecdsa_sig) in &input.partial_sigs {
987 let flag = EcdsaSighashType::from_standard(ecdsa_sig.sighash_type as u32)
988 .map_err(|error| NonStandardPartialSigsSighashType { input_index, error })?;
989 if target_ecdsa_sighash_ty != flag {
990 return Err(WrongSighashFlag {
991 input_index,
992 required: target_ecdsa_sighash_ty,
993 got: flag,
994 pubkey: *key,
995 });
996 }
997 }
998 }
999 Ok(())
1000 }
1001}
1002
1003#[derive(Debug, Clone, PartialEq, Eq)]
1005#[non_exhaustive]
1006pub enum KeyRequest {
1007 Pubkey(PublicKey),
1009 Bip32(KeySource),
1011}
1012
1013pub trait GetKey {
1015 type Error: core::fmt::Debug;
1017
1018 fn get_key<C: Signing>(
1025 &self,
1026 key_request: KeyRequest,
1027 secp: &Secp256k1<C>,
1028 ) -> Result<Option<PrivateKey>, Self::Error>;
1029}
1030
1031impl GetKey for Xpriv {
1032 type Error = GetKeyError;
1033
1034 fn get_key<C: Signing>(
1035 &self,
1036 key_request: KeyRequest,
1037 secp: &Secp256k1<C>,
1038 ) -> Result<Option<PrivateKey>, Self::Error> {
1039 match key_request {
1040 KeyRequest::Pubkey(_) => Err(GetKeyError::NotSupported),
1041 KeyRequest::Bip32((fingerprint, path)) => {
1042 let key = if self.fingerprint(secp) == fingerprint {
1043 let k = self.derive_priv(secp, &path)?;
1044 Some(k.to_priv())
1045 } else {
1046 None
1047 };
1048 Ok(key)
1049 }
1050 }
1051 }
1052}
1053
1054pub type SigningKeys = BTreeMap<usize, Vec<PublicKey>>;
1056
1057pub type SigningErrors = BTreeMap<usize, SignError>;
1059
1060#[rustfmt::skip]
1061macro_rules! impl_get_key_for_set {
1062 ($set:ident) => {
1063
1064impl GetKey for $set<Xpriv> {
1065 type Error = GetKeyError;
1066
1067 fn get_key<C: Signing>(
1068 &self,
1069 key_request: KeyRequest,
1070 secp: &Secp256k1<C>
1071 ) -> Result<Option<PrivateKey>, Self::Error> {
1072 match key_request {
1073 KeyRequest::Pubkey(_) => Err(GetKeyError::NotSupported),
1074 KeyRequest::Bip32((fingerprint, path)) => {
1075 for xpriv in self.iter() {
1076 if xpriv.parent_fingerprint == fingerprint {
1077 let k = xpriv.derive_priv(secp, &path)?;
1078 return Ok(Some(k.to_priv()));
1079 }
1080 }
1081 Ok(None)
1082 }
1083 }
1084 }
1085}}}
1086
1087impl_get_key_for_set!(BTreeSet);
1088#[cfg(feature = "std")]
1089impl_get_key_for_set!(HashSet);
1090
1091#[rustfmt::skip]
1092macro_rules! impl_get_key_for_map {
1093 ($map:ident) => {
1094
1095impl GetKey for $map<PublicKey, PrivateKey> {
1096 type Error = GetKeyError;
1097
1098 fn get_key<C: Signing>(
1099 &self,
1100 key_request: KeyRequest,
1101 _: &Secp256k1<C>,
1102 ) -> Result<Option<PrivateKey>, Self::Error> {
1103 match key_request {
1104 KeyRequest::Pubkey(pk) => Ok(self.get(&pk).cloned()),
1105 KeyRequest::Bip32(_) => Err(GetKeyError::NotSupported),
1106 }
1107 }
1108}}}
1109impl_get_key_for_map!(BTreeMap);
1110#[cfg(feature = "std")]
1111impl_get_key_for_map!(HashMap);
1112
1113#[derive(Debug, Clone, PartialEq, Eq)]
1115#[non_exhaustive]
1116pub enum GetKeyError {
1117 Bip32(bip32::Error),
1119 NotSupported,
1121}
1122
1123impl fmt::Display for GetKeyError {
1124 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1125 use GetKeyError::*;
1126
1127 match *self {
1128 Bip32(ref e) => write_err!(f, "a bip23 error"; e),
1129 NotSupported =>
1130 f.write_str("the GetKey operation is not supported for this key request"),
1131 }
1132 }
1133}
1134
1135#[cfg(feature = "std")]
1136impl std::error::Error for GetKeyError {
1137 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1138 use GetKeyError::*;
1139
1140 match *self {
1141 NotSupported => None,
1142 Bip32(ref e) => Some(e),
1143 }
1144 }
1145}
1146
1147impl From<bip32::Error> for GetKeyError {
1148 fn from(e: bip32::Error) -> Self { GetKeyError::Bip32(e) }
1149}
1150
1151#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1153#[non_exhaustive]
1154pub enum OutputType {
1155 Bare,
1157 Wpkh,
1159 Wsh,
1161 ShWpkh,
1163 ShWsh,
1165 Sh,
1167 Tr,
1169}
1170
1171impl OutputType {
1172 pub fn signing_algorithm(&self) -> SigningAlgorithm {
1174 use OutputType::*;
1175
1176 match self {
1177 Bare | Wpkh | Wsh | ShWpkh | ShWsh | Sh => SigningAlgorithm::Ecdsa,
1178 Tr => SigningAlgorithm::Schnorr,
1179 }
1180 }
1181}
1182
1183#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1185pub enum SigningAlgorithm {
1186 Ecdsa,
1190 Schnorr,
1194}
1195
1196#[derive(Debug)]
1198#[non_exhaustive]
1199pub enum DecodeError {
1200 InvalidMagic,
1203 InvalidSeparator,
1205 NoMorePairs,
1207 Global(global::DecodeError),
1209 Input(input::DecodeError),
1211 Output(output::DecodeError),
1213}
1214
1215impl fmt::Display for DecodeError {
1216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1217 use DecodeError::*;
1218
1219 match *self {
1220 InvalidMagic => f.write_str("invalid magic"),
1221 InvalidSeparator => f.write_str("invalid separator"),
1222 NoMorePairs => f.write_str("no more key-value pairs for this psbt map"),
1223 Global(ref e) => write_err!(f, "global map decode error"; e),
1224 Input(ref e) => write_err!(f, "input map decode error"; e),
1225 Output(ref e) => write_err!(f, "output map decode error"; e),
1226 }
1227 }
1228}
1229
1230#[cfg(feature = "std")]
1231impl std::error::Error for DecodeError {
1232 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1233 use DecodeError::*;
1234
1235 match *self {
1236 InvalidMagic | InvalidSeparator | NoMorePairs => None,
1237 Global(ref e) => Some(e),
1238 Input(ref e) => Some(e),
1239 Output(ref e) => Some(e),
1240 }
1241 }
1242}
1243
1244impl From<global::DecodeError> for DecodeError {
1245 fn from(e: global::DecodeError) -> Self { Self::Global(e) }
1246}
1247
1248impl From<input::DecodeError> for DecodeError {
1249 fn from(e: input::DecodeError) -> Self { Self::Input(e) }
1250}
1251
1252impl From<output::DecodeError> for DecodeError {
1253 fn from(e: output::DecodeError) -> Self { Self::Output(e) }
1254}
1255
1256#[cfg(feature = "base64")]
1258mod display_from_str {
1259 use core::fmt::{self, Display, Formatter};
1260 use core::str::FromStr;
1261
1262 use bitcoin::base64::display::Base64Display;
1263 use bitcoin::base64::prelude::{Engine as _, BASE64_STANDARD};
1264
1265 use super::*;
1266
1267 impl Display for Psbt {
1268 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1269 write!(f, "{}", Base64Display::new(&self.serialize(), &BASE64_STANDARD))
1270 }
1271 }
1272
1273 impl FromStr for Psbt {
1274 type Err = ParsePsbtError;
1275
1276 fn from_str(s: &str) -> Result<Self, Self::Err> {
1277 let data = BASE64_STANDARD.decode(s).map_err(ParsePsbtError::Base64Encoding)?;
1278 Psbt::deserialize(&data).map_err(ParsePsbtError::PsbtEncoding)
1279 }
1280 }
1281
1282 #[derive(Debug)]
1284 #[non_exhaustive]
1285 pub enum ParsePsbtError {
1286 PsbtEncoding(DeserializeError),
1288 Base64Encoding(bitcoin::base64::DecodeError),
1290 }
1291
1292 impl Display for ParsePsbtError {
1293 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1294 use self::ParsePsbtError::*;
1295
1296 match *self {
1297 PsbtEncoding(ref e) => write_err!(f, "error in internal PSBT data structure"; e),
1298 Base64Encoding(ref e) => write_err!(f, "error in PSBT base64 encoding"; e),
1299 }
1300 }
1301 }
1302
1303 #[cfg(feature = "std")]
1304 impl std::error::Error for ParsePsbtError {
1305 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1306 use self::ParsePsbtError::*;
1307
1308 match self {
1309 PsbtEncoding(e) => Some(e),
1310 Base64Encoding(e) => Some(e),
1311 }
1312 }
1313 }
1314}
1315
1316#[derive(Debug, Clone, PartialEq, Eq)]
1318#[non_exhaustive]
1319pub enum CombineError {
1320 Global(global::CombineError),
1322 Input(input::CombineError),
1324 Output(output::CombineError),
1326}
1327
1328impl fmt::Display for CombineError {
1329 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1330 use CombineError::*;
1331
1332 match *self {
1333 Global(ref e) => write_err!(f, "error while combining the global maps"; e),
1334 Input(ref e) => write_err!(f, "error while combining the input maps"; e),
1335 Output(ref e) => write_err!(f, "error while combining the output maps"; e),
1336 }
1337 }
1338}
1339
1340#[cfg(feature = "std")]
1341impl std::error::Error for CombineError {
1342 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1343 use CombineError::*;
1344
1345 match *self {
1346 Global(ref e) => Some(e),
1347 Input(ref e) => Some(e),
1348 Output(ref e) => Some(e),
1349 }
1350 }
1351}
1352
1353impl From<global::CombineError> for CombineError {
1354 fn from(e: global::CombineError) -> Self { Self::Global(e) }
1355}
1356
1357impl From<input::CombineError> for CombineError {
1358 fn from(e: input::CombineError) -> Self { Self::Input(e) }
1359}
1360
1361impl From<output::CombineError> for CombineError {
1362 fn from(e: output::CombineError) -> Self { Self::Output(e) }
1363}