bitcoin/psbt/map/
output.rs1use secp256k1::XOnlyPublicKey;
4
5use crate::bip32::KeySource;
6use crate::blockdata::script::ScriptBuf;
7use crate::prelude::*;
8use crate::psbt::map::Map;
9use crate::psbt::{raw, Error};
10use crate::taproot::{TapLeafHash, TapTree};
11
12const PSBT_OUT_REDEEM_SCRIPT: u8 = 0x00;
14const PSBT_OUT_WITNESS_SCRIPT: u8 = 0x01;
16const PSBT_OUT_BIP32_DERIVATION: u8 = 0x02;
18const PSBT_OUT_TAP_INTERNAL_KEY: u8 = 0x05;
20const PSBT_OUT_TAP_TREE: u8 = 0x06;
22const PSBT_OUT_TAP_BIP32_DERIVATION: u8 = 0x07;
24const PSBT_OUT_PROPRIETARY: u8 = 0xFC;
26
27#[derive(Clone, Default, Debug, PartialEq, Eq, Hash)]
30#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
31#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
32pub struct Output {
33 pub redeem_script: Option<ScriptBuf>,
35 pub witness_script: Option<ScriptBuf>,
37 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
40 pub bip32_derivation: BTreeMap<secp256k1::PublicKey, KeySource>,
41 pub tap_internal_key: Option<XOnlyPublicKey>,
43 pub tap_tree: Option<TapTree>,
45 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
47 pub tap_key_origins: BTreeMap<XOnlyPublicKey, (Vec<TapLeafHash>, KeySource)>,
48 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
50 pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
51 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
53 pub unknown: BTreeMap<raw::Key, Vec<u8>>,
54}
55
56impl Output {
57 pub(super) fn insert_pair(&mut self, pair: raw::Pair) -> Result<(), Error> {
58 let raw::Pair { key: raw_key, value: raw_value } = pair;
59
60 match raw_key.type_value {
61 PSBT_OUT_REDEEM_SCRIPT => {
62 impl_psbt_insert_pair! {
63 self.redeem_script <= <raw_key: _>|<raw_value: ScriptBuf>
64 }
65 }
66 PSBT_OUT_WITNESS_SCRIPT => {
67 impl_psbt_insert_pair! {
68 self.witness_script <= <raw_key: _>|<raw_value: ScriptBuf>
69 }
70 }
71 PSBT_OUT_BIP32_DERIVATION => {
72 impl_psbt_insert_pair! {
73 self.bip32_derivation <= <raw_key: secp256k1::PublicKey>|<raw_value: KeySource>
74 }
75 }
76 PSBT_OUT_PROPRIETARY => {
77 let key = raw::ProprietaryKey::try_from(raw_key.clone())?;
78 match self.proprietary.entry(key) {
79 btree_map::Entry::Vacant(empty_key) => {
80 empty_key.insert(raw_value);
81 }
82 btree_map::Entry::Occupied(_) => return Err(Error::DuplicateKey(raw_key)),
83 }
84 }
85 PSBT_OUT_TAP_INTERNAL_KEY => {
86 impl_psbt_insert_pair! {
87 self.tap_internal_key <= <raw_key: _>|<raw_value: XOnlyPublicKey>
88 }
89 }
90 PSBT_OUT_TAP_TREE => {
91 impl_psbt_insert_pair! {
92 self.tap_tree <= <raw_key: _>|<raw_value: TapTree>
93 }
94 }
95 PSBT_OUT_TAP_BIP32_DERIVATION => {
96 impl_psbt_insert_pair! {
97 self.tap_key_origins <= <raw_key: XOnlyPublicKey>|< raw_value: (Vec<TapLeafHash>, KeySource)>
98 }
99 }
100 _ => match self.unknown.entry(raw_key) {
101 btree_map::Entry::Vacant(empty_key) => {
102 empty_key.insert(raw_value);
103 }
104 btree_map::Entry::Occupied(k) => return Err(Error::DuplicateKey(k.key().clone())),
105 },
106 }
107
108 Ok(())
109 }
110
111 pub fn combine(&mut self, other: Self) {
113 self.bip32_derivation.extend(other.bip32_derivation);
114 self.proprietary.extend(other.proprietary);
115 self.unknown.extend(other.unknown);
116 self.tap_key_origins.extend(other.tap_key_origins);
117
118 combine!(redeem_script, self, other);
119 combine!(witness_script, self, other);
120 combine!(tap_internal_key, self, other);
121 combine!(tap_tree, self, other);
122 }
123}
124
125impl Map for Output {
126 fn get_pairs(&self) -> Vec<raw::Pair> {
127 let mut rv: Vec<raw::Pair> = Default::default();
128
129 impl_psbt_get_pair! {
130 rv.push(self.redeem_script, PSBT_OUT_REDEEM_SCRIPT)
131 }
132
133 impl_psbt_get_pair! {
134 rv.push(self.witness_script, PSBT_OUT_WITNESS_SCRIPT)
135 }
136
137 impl_psbt_get_pair! {
138 rv.push_map(self.bip32_derivation, PSBT_OUT_BIP32_DERIVATION)
139 }
140
141 impl_psbt_get_pair! {
142 rv.push(self.tap_internal_key, PSBT_OUT_TAP_INTERNAL_KEY)
143 }
144
145 impl_psbt_get_pair! {
146 rv.push(self.tap_tree, PSBT_OUT_TAP_TREE)
147 }
148
149 impl_psbt_get_pair! {
150 rv.push_map(self.tap_key_origins, PSBT_OUT_TAP_BIP32_DERIVATION)
151 }
152
153 for (key, value) in self.proprietary.iter() {
154 rv.push(raw::Pair { key: key.to_key(), value: value.clone() });
155 }
156
157 for (key, value) in self.unknown.iter() {
158 rv.push(raw::Pair { key: key.clone(), value: value.clone() });
159 }
160
161 rv
162 }
163}
164
165impl_psbtmap_ser_de_serialize!(Output);