use bitcoin::{Amount, ScriptBuf, TxOut};
use miniscript::bitcoin;
use crate::DefiniteDescriptor;
#[derive(Debug, Clone)]
pub enum ScriptSource {
Script(ScriptBuf),
Descriptor(DefiniteDescriptor),
}
impl From<ScriptBuf> for ScriptSource {
fn from(script: ScriptBuf) -> Self {
Self::from_script(script)
}
}
impl From<DefiniteDescriptor> for ScriptSource {
fn from(descriptor: DefiniteDescriptor) -> Self {
Self::from_descriptor(descriptor)
}
}
impl ScriptSource {
pub fn from_script(script: ScriptBuf) -> Self {
Self::Script(script)
}
pub fn from_descriptor(descriptor: DefiniteDescriptor) -> Self {
Self::Descriptor(descriptor)
}
pub fn script(&self) -> ScriptBuf {
match self {
ScriptSource::Script(spk) => spk.clone(),
ScriptSource::Descriptor(descriptor) => descriptor.script_pubkey(),
}
}
pub fn descriptor(&self) -> Option<&DefiniteDescriptor> {
match self {
ScriptSource::Script(_) => None,
ScriptSource::Descriptor(descriptor) => Some(descriptor),
}
}
}
#[derive(Debug, Clone)]
pub struct Output {
pub value: Amount,
pub script_pubkey_source: ScriptSource,
}
impl From<(ScriptBuf, Amount)> for Output {
fn from((script, value): (ScriptBuf, Amount)) -> Self {
Self::with_script(script, value)
}
}
impl From<(DefiniteDescriptor, Amount)> for Output {
fn from((descriptor, value): (DefiniteDescriptor, Amount)) -> Self {
Self::with_descriptor(descriptor, value)
}
}
impl Output {
pub fn with_script(script: ScriptBuf, value: Amount) -> Self {
Self {
value,
script_pubkey_source: script.into(),
}
}
pub fn with_descriptor(descriptor: DefiniteDescriptor, value: Amount) -> Self {
Self {
value,
script_pubkey_source: descriptor.into(),
}
}
pub fn script_pubkey(&self) -> ScriptBuf {
self.script_pubkey_source.script()
}
pub fn descriptor(&self) -> Option<&DefiniteDescriptor> {
self.script_pubkey_source.descriptor()
}
pub fn txout(&self) -> TxOut {
TxOut {
value: self.value,
script_pubkey: self.script_pubkey_source.script(),
}
}
}