Skip to main content

smplx_sdk/transaction/
partial_input.rs

1use simplicityhl::elements::confidential::{Asset, Value};
2use simplicityhl::elements::pset::Input;
3use simplicityhl::elements::secp256k1_zkp::Tweak;
4use simplicityhl::elements::{AssetId, LockTime, OutPoint, Sequence, TxOut, TxOutSecrets, Txid};
5
6use crate::program::ProgramTrait;
7use crate::program::WitnessTrait;
8
9use super::UTXO;
10
11#[derive(Debug, Clone)]
12pub enum RequiredSignature {
13    None,
14    NativeEcdsa,
15    Witness(String),
16    WitnessWithPath(String, Vec<String>),
17}
18
19impl RequiredSignature {
20    pub fn witness_with_path<I>(name: &str, path: I) -> Self
21    where
22        I: IntoIterator,
23        I::Item: AsRef<str>,
24    {
25        RequiredSignature::WitnessWithPath(
26            name.to_string(),
27            path.into_iter().map(|s| s.as_ref().to_string()).collect(),
28        )
29    }
30}
31
32#[derive(Debug, Clone)]
33pub struct PartialInput {
34    pub witness_txid: Txid,
35    pub witness_output_index: u32,
36    pub witness_utxo: TxOut,
37    pub sequence: Sequence,
38    pub locktime: LockTime,
39    // if utxo is explicit, amount and asset are Some
40    pub amount: Option<u64>,
41    pub asset: Option<AssetId>,
42    // if utxo is confidential, secrets are Some
43    pub secrets: Option<TxOutSecrets>,
44}
45
46#[derive(Clone)]
47pub struct ProgramInput {
48    pub program: Box<dyn ProgramTrait>,
49    pub witness: Box<dyn WitnessTrait>,
50}
51
52#[derive(Clone)]
53pub struct IssuanceInput {
54    pub issuance_amount: u64,
55    pub asset_entropy: [u8; 32],
56    pub reissuance_amount: Option<u64>,
57    pub blinding_nonce: Option<Tweak>,
58}
59
60impl PartialInput {
61    pub fn new(utxo: UTXO) -> Self {
62        let amount = match utxo.txout.value {
63            Value::Explicit(value) => Some(value),
64            _ => None,
65        };
66        let asset = match utxo.txout.asset {
67            Asset::Explicit(asset) => Some(asset),
68            _ => None,
69        };
70
71        Self {
72            witness_txid: utxo.outpoint.txid,
73            witness_output_index: utxo.outpoint.vout,
74            witness_utxo: utxo.txout,
75            sequence: Sequence::default(),
76            locktime: LockTime::ZERO,
77            amount,
78            asset,
79            secrets: utxo.secrets,
80        }
81    }
82
83    pub fn with_sequence(mut self, sequence: Sequence) -> Self {
84        self.sequence = sequence;
85
86        self
87    }
88
89    pub fn with_locktime(mut self, locktime: LockTime) -> Self {
90        self.locktime = locktime;
91
92        self
93    }
94
95    pub fn outpoint(&self) -> OutPoint {
96        OutPoint {
97            txid: self.witness_txid,
98            vout: self.witness_output_index,
99        }
100    }
101
102    pub fn to_input(&self) -> Input {
103        let time_locktime = match self.locktime {
104            LockTime::Seconds(value) => Some(value),
105            _ => None,
106        };
107        // zero height locktime is essentially ignored
108        let height_locktime = match self.locktime {
109            LockTime::Blocks(value) => Some(value),
110            _ => None,
111        };
112
113        Input {
114            previous_txid: self.witness_txid,
115            previous_output_index: self.witness_output_index,
116            witness_utxo: Some(self.witness_utxo.clone()),
117            sequence: Some(self.sequence),
118            required_time_locktime: time_locktime,
119            required_height_locktime: height_locktime,
120            amount: self.amount,
121            asset: self.asset,
122            ..Default::default()
123        }
124    }
125}
126
127impl ProgramInput {
128    pub fn new(program: Box<dyn ProgramTrait>, witness: Box<dyn WitnessTrait>) -> Self {
129        Self { program, witness }
130    }
131}
132
133impl IssuanceInput {
134    pub fn new(issuance_amount: u64, asset_entropy: [u8; 32]) -> Self {
135        Self {
136            issuance_amount,
137            asset_entropy,
138            reissuance_amount: None,
139            blinding_nonce: None,
140        }
141    }
142
143    pub fn with_reissuance(mut self, reissuance_amount: u64) -> Self {
144        self.reissuance_amount = Some(reissuance_amount);
145
146        self
147    }
148
149    pub fn with_blinding_nonce(mut self, blinding_nonce: [u8; 32]) -> Self {
150        self.blinding_nonce = Some(Tweak::from_inner(blinding_nonce).expect("valid blinding_nonce"));
151
152        self
153    }
154
155    pub fn to_input(&self) -> Input {
156        Input {
157            issuance_value_amount: Some(self.issuance_amount),
158            issuance_asset_entropy: Some(self.asset_entropy),
159            issuance_inflation_keys: self.reissuance_amount,
160            issuance_blinding_nonce: self.blinding_nonce,
161            blinded_issuance: Some(0x00),
162            ..Default::default()
163        }
164    }
165}