1#![doc = include_str!("seals.md")]
23
24use std::fmt::{self, Display, Formatter};
25use std::str::FromStr;
26
27use bp::seals::txout::blind::ParseError;
28use bp::seals::txout::{CloseMethod, TxPtr};
29use bp::secp256k1::rand::{thread_rng, RngCore};
30use bp::Vout;
31use commit_verify::Conceal;
32use rgb::{ExposedSeal, GenesisSeal, GraphSeal, SecretSeal};
33
34use crate::{Outpoint, LIB_NAME_RGB_STD};
35
36#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, From)]
40#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
41#[strict_type(lib = LIB_NAME_RGB_STD)]
42#[cfg_attr(
43 feature = "serde",
44 derive(Serialize, Deserialize),
45 serde(crate = "serde_crate", rename_all = "camelCase")
46)]
47pub struct VoutSeal {
48 pub method: CloseMethod,
51
52 pub vout: Vout,
54
55 pub blinding: u64,
59}
60
61impl VoutSeal {
62 #[inline]
65 pub fn new(method: CloseMethod, vout: impl Into<Vout>) -> Self {
66 VoutSeal::with(method, vout, thread_rng().next_u64())
67 }
68
69 #[inline]
73 pub fn new_opret(vout: impl Into<Vout>) -> Self { VoutSeal::new(CloseMethod::OpretFirst, vout) }
74
75 #[inline]
79 pub fn new_tapret(vout: impl Into<Vout>) -> Self {
80 VoutSeal::new(CloseMethod::TapretFirst, vout)
81 }
82
83 #[inline]
86 pub fn with_opret(vout: impl Into<Vout>, blinding: u64) -> Self {
87 VoutSeal::with(CloseMethod::OpretFirst, vout, blinding)
88 }
89
90 #[inline]
93 pub fn with_tapret(vout: impl Into<Vout>, blinding: u64) -> Self {
94 VoutSeal::with(CloseMethod::TapretFirst, vout, blinding)
95 }
96
97 #[inline]
100 pub fn with(method: CloseMethod, vout: impl Into<Vout>, blinding: u64) -> Self {
101 VoutSeal {
102 method,
103 vout: vout.into(),
104 blinding,
105 }
106 }
107}
108
109impl From<VoutSeal> for GraphSeal {
110 fn from(seal: VoutSeal) -> Self { Self::with_vout(seal.method, seal.vout, seal.blinding) }
111}
112
113#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, From)]
124#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
125#[strict_type(lib = LIB_NAME_RGB_STD, tags = custom, dumb = Self::ConcealedUtxo(strict_dumb!()))]
126#[cfg_attr(
127 feature = "serde",
128 derive(Serialize, Deserialize),
129 serde(crate = "serde_crate", rename_all = "camelCase")
130)]
131pub enum TerminalSeal {
132 #[from]
134 #[strict_type(tag = 0)]
135 ConcealedUtxo(SecretSeal),
136
137 #[strict_type(tag = 1)]
139 WitnessVout(VoutSeal),
140}
141
142impl From<GraphSeal> for TerminalSeal {
143 fn from(seal: GraphSeal) -> Self {
144 match seal.txid {
145 TxPtr::WitnessTx => {
146 TerminalSeal::WitnessVout(VoutSeal::with(seal.method, seal.vout, seal.blinding))
147 }
148 TxPtr::Txid(_) => TerminalSeal::ConcealedUtxo(seal.conceal()),
149 }
150 }
151}
152
153impl TerminalSeal {
154 pub fn new_vout(method: CloseMethod, vout: impl Into<Vout>) -> TerminalSeal {
157 TerminalSeal::WitnessVout(VoutSeal::new(method, vout))
158 }
159
160 pub fn secret_seal(&self) -> Option<SecretSeal> {
161 match self {
162 TerminalSeal::ConcealedUtxo(seal) => Some(*seal),
163 TerminalSeal::WitnessVout(_) => None,
164 }
165 }
166}
167
168impl Conceal for TerminalSeal {
169 type Concealed = SecretSeal;
170
171 fn conceal(&self) -> Self::Concealed {
172 match *self {
173 TerminalSeal::ConcealedUtxo(hash) => hash,
174 TerminalSeal::WitnessVout(seal) => GraphSeal::from(seal).conceal(),
175 }
176 }
177}
178
179impl Display for TerminalSeal {
180 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
181 match *self {
182 TerminalSeal::ConcealedUtxo(ref seal) => Display::fmt(seal, f),
183 TerminalSeal::WitnessVout(seal) => Display::fmt(&GraphSeal::from(seal), f),
184 }
185 }
186}
187
188impl FromStr for TerminalSeal {
189 type Err = ParseError;
190
191 fn from_str(s: &str) -> Result<Self, Self::Err> {
192 SecretSeal::from_str(s)
193 .map(TerminalSeal::from)
194 .or_else(|_| GraphSeal::from_str(s).map(TerminalSeal::from))
195 }
196}
197
198#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, From)]
200pub enum BuilderSeal<Seal: ExposedSeal> {
201 Revealed(Seal),
202 #[from]
203 Concealed(SecretSeal),
204}
205
206impl<Seal: ExposedSeal> From<Outpoint> for BuilderSeal<Seal>
207where Seal: From<Outpoint>
208{
209 fn from(seal: Outpoint) -> Self { BuilderSeal::Revealed(seal.into()) }
210}
211
212impl<Seal: ExposedSeal> From<GraphSeal> for BuilderSeal<Seal>
213where Seal: From<GraphSeal>
214{
215 fn from(seal: GraphSeal) -> Self { BuilderSeal::Revealed(seal.into()) }
216}
217
218impl<Seal: ExposedSeal> From<GenesisSeal> for BuilderSeal<Seal>
219where Seal: From<GenesisSeal>
220{
221 fn from(seal: GenesisSeal) -> Self { BuilderSeal::Revealed(seal.into()) }
222}