use core::fmt::Debug;
use std::hash::Hash;
use bitcoin::Txid;
use strict_encoding::{StrictDecode, StrictDumb, StrictEncode};
use crate::commit_verify::Conceal;
pub use crate::seals::txout::blind::{ChainBlindSeal, ParseError, SingleBlindSeal};
use crate::seals::txout::ExplicitSeal;
pub use crate::seals::txout::TxoSeal;
pub use crate::seals::SecretSeal;
use crate::txout::{BlindSeal, TxPtr};
pub type GenesisSeal = SingleBlindSeal;
pub type GraphSeal = ChainBlindSeal;
pub type OutputSeal = ExplicitSeal<Txid>;
pub trait ExposedSeal:
Debug
+ StrictDumb
+ StrictEncode
+ StrictDecode
+ Eq
+ Ord
+ Copy
+ Hash
+ TxoSeal
+ Conceal<Concealed = SecretSeal>
{
#[inline]
fn to_output_seal(self) -> Option<OutputSeal> {
let outpoint = self.outpoint()?;
Some(ExplicitSeal::new(outpoint))
}
fn to_output_seal_or_default(self, witness_id: Txid) -> OutputSeal {
self.to_output_seal()
.unwrap_or(ExplicitSeal::new(self.outpoint_or(witness_id)))
}
fn with_witness_id(self, witness_id: Option<Txid>) -> Option<BlindSeal<Txid>>;
}
impl ExposedSeal for BlindSeal<TxPtr> {
fn with_witness_id(self, witness_id: Option<Txid>) -> Option<BlindSeal<Txid>> {
let txid = self.txid().or(witness_id)?;
Some(BlindSeal::with_blinding(txid, self.vout, self.blinding))
}
}
impl ExposedSeal for BlindSeal<Txid> {
fn with_witness_id(self, _witness_id: Option<Txid>) -> Option<BlindSeal<Txid>> { Some(self) }
}
#[cfg(test)]
mod test {
use std::str::FromStr;
use super::*;
use crate::seals::txout::{BlindSeal, TxPtr};
use crate::Vout;
#[test]
fn secret_seal_is_sha256d() {
let reveal = BlindSeal {
blinding: 54683213134637,
txid: TxPtr::Txid(
Txid::from_str("646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839")
.unwrap(),
),
vout: Vout::from(2),
};
let secret = reveal.to_secret_seal();
assert_eq!(
secret.to_string(),
"utxob:nBRVm39A-ioJydHE-ug2d90m-aZyfPI0-MCc0ZNM-oMXMs2O-opKQ7"
);
assert_eq!(reveal.to_secret_seal(), reveal.conceal())
}
}