cml_chain/transaction/
mod.rs

1// This file was code-generated using an experimental CDDL to rust tool:
2// https://github.com/dcSpark/cddl-codegen
3
4pub mod cbor_encodings;
5pub mod serialization;
6pub mod utils;
7
8use super::{NetworkId, Value};
9use crate::address::Address;
10use crate::assets::{Coin, Mint, PositiveCoin};
11use crate::auxdata::AuxiliaryData;
12use crate::crypto::{
13    AuxiliaryDataHash, DatumHash, Ed25519KeyHash, ScriptDataHash, TransactionHash,
14};
15use crate::governance::VotingProcedures;
16use crate::plutus::{PlutusData, Redeemers};
17use crate::{
18    NonemptySetBootstrapWitness, NonemptySetCertificate, NonemptySetNativeScript,
19    NonemptySetPlutusData, NonemptySetPlutusV1Script, NonemptySetPlutusV2Script,
20    NonemptySetPlutusV3Script, NonemptySetProposalProcedure, NonemptySetTransactionInput,
21    NonemptySetVkeywitness, RequiredSigners, Script, SetTransactionInput, Slot, Withdrawals,
22};
23use cbor_encodings::{
24    AlonzoFormatTxOutEncoding, ConwayFormatTxOutEncoding, ScriptAllEncoding, ScriptAnyEncoding,
25    ScriptInvalidBeforeEncoding, ScriptInvalidHereafterEncoding, ScriptNOfKEncoding,
26    ScriptPubkeyEncoding, TransactionBodyEncoding, TransactionEncoding, TransactionInputEncoding,
27    TransactionWitnessSetEncoding,
28};
29use cml_core::ordered_hash_map::OrderedHashMap;
30use cml_core::serialization::{LenEncoding, StringEncoding};
31use std::collections::BTreeMap;
32
33#[derive(
34    Clone, Debug, derivative::Derivative, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
35)]
36#[derivative(Hash, Eq, PartialEq)]
37pub struct AlonzoFormatTxOut {
38    pub address: Address,
39    pub amount: Value,
40    pub datum_hash: Option<DatumHash>,
41    #[serde(skip)]
42    #[derivative(PartialEq = "ignore", Hash = "ignore")]
43    pub encodings: Option<AlonzoFormatTxOutEncoding>,
44}
45
46impl AlonzoFormatTxOut {
47    pub fn new(address: Address, amount: Value) -> Self {
48        Self {
49            address,
50            amount,
51            datum_hash: None,
52            encodings: None,
53        }
54    }
55}
56
57#[derive(
58    Clone, Debug, derivative::Derivative, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
59)]
60#[derivative(Hash, Eq, PartialEq)]
61pub struct ConwayFormatTxOut {
62    pub address: Address,
63    pub amount: Value,
64    pub datum_option: Option<DatumOption>,
65    pub script_reference: Option<ScriptRef>,
66    #[serde(skip)]
67    #[derivative(PartialEq = "ignore", Hash = "ignore")]
68    pub encodings: Option<ConwayFormatTxOutEncoding>,
69}
70
71impl ConwayFormatTxOut {
72    pub fn new(address: Address, amount: Value) -> Self {
73        Self {
74            address,
75            amount,
76            datum_option: None,
77            script_reference: None,
78            encodings: None,
79        }
80    }
81}
82
83#[derive(
84    Clone, Debug, derivative::Derivative, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
85)]
86#[derivative(Eq, PartialEq, Hash)]
87pub enum DatumOption {
88    Hash {
89        datum_hash: DatumHash,
90        #[serde(skip)]
91        #[derivative(PartialEq = "ignore", Hash = "ignore")]
92        len_encoding: LenEncoding,
93        #[serde(skip)]
94        #[derivative(PartialEq = "ignore", Hash = "ignore")]
95        tag_encoding: Option<cbor_event::Sz>,
96        #[serde(skip)]
97        #[derivative(PartialEq = "ignore", Hash = "ignore")]
98        datum_hash_encoding: StringEncoding,
99    },
100    Datum {
101        datum: PlutusData,
102        #[serde(skip)]
103        #[derivative(PartialEq = "ignore", Hash = "ignore")]
104        len_encoding: LenEncoding,
105        #[serde(skip)]
106        #[derivative(PartialEq = "ignore", Hash = "ignore")]
107        tag_encoding: Option<cbor_event::Sz>,
108        #[serde(skip)]
109        #[derivative(PartialEq = "ignore", Hash = "ignore")]
110        datum_tag_encoding: Option<cbor_event::Sz>,
111        #[serde(skip)]
112        #[derivative(PartialEq = "ignore", Hash = "ignore")]
113        datum_bytes_encoding: StringEncoding,
114    },
115}
116
117impl DatumOption {
118    pub fn new_hash(datum_hash: DatumHash) -> Self {
119        Self::Hash {
120            datum_hash,
121            len_encoding: LenEncoding::default(),
122            tag_encoding: None,
123            datum_hash_encoding: StringEncoding::default(),
124        }
125    }
126
127    pub fn new_datum(datum: PlutusData) -> Self {
128        Self::Datum {
129            datum,
130            len_encoding: LenEncoding::default(),
131            tag_encoding: None,
132            datum_tag_encoding: None,
133            datum_bytes_encoding: StringEncoding::default(),
134        }
135    }
136}
137
138#[derive(
139    Clone, Debug, Hash, PartialEq, Eq, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
140)]
141pub enum NativeScript {
142    ScriptPubkey(ScriptPubkey),
143    ScriptAll(ScriptAll),
144    ScriptAny(ScriptAny),
145    ScriptNOfK(ScriptNOfK),
146    /// Timelock validity intervals are half-open intervals [a, b). This field specifies the left (included) endpoint a.
147    ScriptInvalidBefore(ScriptInvalidBefore),
148    /// Timelock validity intervals are half-open intervals [a, b). This field specifies the right (excluded) endpoint b.
149    ScriptInvalidHereafter(ScriptInvalidHereafter),
150}
151
152impl NativeScript {
153    pub fn new_script_pubkey(ed25519_key_hash: Ed25519KeyHash) -> Self {
154        Self::ScriptPubkey(ScriptPubkey::new(ed25519_key_hash))
155    }
156
157    pub fn new_script_all(native_scripts: Vec<NativeScript>) -> Self {
158        Self::ScriptAll(ScriptAll::new(native_scripts))
159    }
160
161    pub fn new_script_any(native_scripts: Vec<NativeScript>) -> Self {
162        Self::ScriptAny(ScriptAny::new(native_scripts))
163    }
164
165    pub fn new_script_n_of_k(n: u64, native_scripts: Vec<NativeScript>) -> Self {
166        Self::ScriptNOfK(ScriptNOfK::new(n, native_scripts))
167    }
168
169    /// Timelock validity intervals are half-open intervals [a, b). This field specifies the left (included) endpoint a.
170    pub fn new_script_invalid_before(before: Slot) -> Self {
171        Self::ScriptInvalidBefore(ScriptInvalidBefore::new(before))
172    }
173
174    /// Timelock validity intervals are half-open intervals [a, b). This field specifies the right (excluded) endpoint b.
175    pub fn new_script_invalid_hereafter(after: Slot) -> Self {
176        Self::ScriptInvalidHereafter(ScriptInvalidHereafter::new(after))
177    }
178}
179
180#[derive(
181    Clone, Debug, derivative::Derivative, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
182)]
183#[derivative(Hash, PartialEq, Eq)]
184pub struct ScriptAll {
185    pub native_scripts: Vec<NativeScript>,
186    #[serde(skip)]
187    #[derivative(PartialEq = "ignore", Hash = "ignore")]
188    pub encodings: Option<ScriptAllEncoding>,
189}
190
191impl ScriptAll {
192    pub fn new(native_scripts: Vec<NativeScript>) -> Self {
193        Self {
194            native_scripts,
195            encodings: None,
196        }
197    }
198}
199
200#[derive(
201    Clone, Debug, derivative::Derivative, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
202)]
203#[derivative(Hash, PartialEq, Eq)]
204pub struct ScriptAny {
205    pub native_scripts: Vec<NativeScript>,
206    #[serde(skip)]
207    #[derivative(PartialEq = "ignore", Hash = "ignore")]
208    pub encodings: Option<ScriptAnyEncoding>,
209}
210
211impl ScriptAny {
212    pub fn new(native_scripts: Vec<NativeScript>) -> Self {
213        Self {
214            native_scripts,
215            encodings: None,
216        }
217    }
218}
219
220#[derive(
221    Clone, Debug, derivative::Derivative, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
222)]
223#[derivative(Hash, PartialEq, Eq)]
224pub struct ScriptInvalidBefore {
225    pub before: Slot,
226    #[serde(skip)]
227    #[derivative(PartialEq = "ignore", Hash = "ignore")]
228    pub encodings: Option<ScriptInvalidBeforeEncoding>,
229}
230
231impl ScriptInvalidBefore {
232    pub fn new(before: Slot) -> Self {
233        Self {
234            before,
235            encodings: None,
236        }
237    }
238}
239
240#[derive(
241    Clone, Debug, derivative::Derivative, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
242)]
243#[derivative(Hash, PartialEq, Eq)]
244pub struct ScriptInvalidHereafter {
245    pub after: Slot,
246    #[serde(skip)]
247    #[derivative(PartialEq = "ignore", Hash = "ignore")]
248    pub encodings: Option<ScriptInvalidHereafterEncoding>,
249}
250
251impl ScriptInvalidHereafter {
252    pub fn new(after: Slot) -> Self {
253        Self {
254            after,
255            encodings: None,
256        }
257    }
258}
259
260#[derive(
261    Clone, Debug, derivative::Derivative, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
262)]
263#[derivative(Hash, PartialEq, Eq)]
264pub struct ScriptNOfK {
265    pub n: u64,
266    pub native_scripts: Vec<NativeScript>,
267    #[serde(skip)]
268    #[derivative(PartialEq = "ignore", Hash = "ignore")]
269    pub encodings: Option<ScriptNOfKEncoding>,
270}
271
272impl ScriptNOfK {
273    pub fn new(n: u64, native_scripts: Vec<NativeScript>) -> Self {
274        Self {
275            n,
276            native_scripts,
277            encodings: None,
278        }
279    }
280}
281
282#[derive(
283    Clone, Debug, derivative::Derivative, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
284)]
285#[derivative(Hash, PartialEq, Eq)]
286pub struct ScriptPubkey {
287    pub ed25519_key_hash: Ed25519KeyHash,
288    #[serde(skip)]
289    #[derivative(PartialEq = "ignore", Hash = "ignore")]
290    pub encodings: Option<ScriptPubkeyEncoding>,
291}
292
293impl ScriptPubkey {
294    pub fn new(ed25519_key_hash: Ed25519KeyHash) -> Self {
295        Self {
296            ed25519_key_hash,
297            encodings: None,
298        }
299    }
300}
301
302pub type ScriptRef = Script;
303
304#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
305pub struct Transaction {
306    pub body: TransactionBody,
307    pub witness_set: TransactionWitnessSet,
308    pub is_valid: bool,
309    pub auxiliary_data: Option<AuxiliaryData>,
310    #[serde(skip)]
311    pub encodings: Option<TransactionEncoding>,
312}
313
314impl Transaction {
315    pub fn new(
316        body: TransactionBody,
317        witness_set: TransactionWitnessSet,
318        is_valid: bool,
319        auxiliary_data: Option<AuxiliaryData>,
320    ) -> Self {
321        Self {
322            body,
323            witness_set,
324            is_valid,
325            auxiliary_data,
326            encodings: None,
327        }
328    }
329}
330
331#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
332pub struct TransactionBody {
333    pub inputs: SetTransactionInput,
334    pub outputs: Vec<TransactionOutput>,
335    pub fee: Coin,
336    pub ttl: Option<u64>,
337    pub certs: Option<NonemptySetCertificate>,
338    pub withdrawals: Option<Withdrawals>,
339    pub auxiliary_data_hash: Option<AuxiliaryDataHash>,
340    pub validity_interval_start: Option<u64>,
341    pub mint: Option<Mint>,
342    pub script_data_hash: Option<ScriptDataHash>,
343    pub collateral_inputs: Option<NonemptySetTransactionInput>,
344    pub required_signers: Option<RequiredSigners>,
345    pub network_id: Option<NetworkId>,
346    pub collateral_return: Option<TransactionOutput>,
347    pub total_collateral: Option<Coin>,
348    pub reference_inputs: Option<NonemptySetTransactionInput>,
349    pub voting_procedures: Option<VotingProcedures>,
350    pub proposal_procedures: Option<NonemptySetProposalProcedure>,
351    pub current_treasury_value: Option<Coin>,
352    pub donation: Option<PositiveCoin>,
353    #[serde(skip)]
354    pub encodings: Option<TransactionBodyEncoding>,
355}
356
357impl TransactionBody {
358    pub fn new(inputs: SetTransactionInput, outputs: Vec<TransactionOutput>, fee: Coin) -> Self {
359        Self {
360            inputs,
361            outputs,
362            fee,
363            ttl: None,
364            certs: None,
365            withdrawals: None,
366            auxiliary_data_hash: None,
367            validity_interval_start: None,
368            mint: None,
369            script_data_hash: None,
370            collateral_inputs: None,
371            required_signers: None,
372            network_id: None,
373            collateral_return: None,
374            total_collateral: None,
375            reference_inputs: None,
376            voting_procedures: None,
377            proposal_procedures: None,
378            current_treasury_value: None,
379            donation: None,
380            encodings: None,
381        }
382    }
383}
384
385#[derive(
386    Clone, Debug, derivative::Derivative, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
387)]
388#[derivative(Ord, PartialOrd, Eq, PartialEq, Hash)]
389pub struct TransactionInput {
390    pub transaction_id: TransactionHash,
391    pub index: u64,
392    #[serde(skip)]
393    #[derivative(
394        PartialEq = "ignore",
395        Ord = "ignore",
396        PartialOrd = "ignore",
397        Hash = "ignore"
398    )]
399    pub encodings: Option<TransactionInputEncoding>,
400}
401
402impl TransactionInput {
403    pub fn new(transaction_id: TransactionHash, index: u64) -> Self {
404        Self {
405            transaction_id,
406            index,
407            encodings: None,
408        }
409    }
410}
411
412#[derive(
413    Clone, Debug, Hash, Eq, PartialEq, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
414)]
415pub enum TransactionOutput {
416    AlonzoFormatTxOut(AlonzoFormatTxOut),
417    ConwayFormatTxOut(ConwayFormatTxOut),
418}
419
420impl TransactionOutput {
421    pub fn new_alonzo_format_tx_out(alonzo_format_tx_out: AlonzoFormatTxOut) -> Self {
422        Self::AlonzoFormatTxOut(alonzo_format_tx_out)
423    }
424
425    pub fn new_conway_format_tx_out(conway_format_tx_out: ConwayFormatTxOut) -> Self {
426        Self::ConwayFormatTxOut(conway_format_tx_out)
427    }
428}
429
430#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
431pub struct TransactionWitnessSet {
432    pub vkeywitnesses: Option<NonemptySetVkeywitness>,
433    pub native_scripts: Option<NonemptySetNativeScript>,
434    pub bootstrap_witnesses: Option<NonemptySetBootstrapWitness>,
435    pub plutus_v1_scripts: Option<NonemptySetPlutusV1Script>,
436    pub plutus_datums: Option<NonemptySetPlutusData>,
437    pub redeemers: Option<Redeemers>,
438    pub plutus_v2_scripts: Option<NonemptySetPlutusV2Script>,
439    pub plutus_v3_scripts: Option<NonemptySetPlutusV3Script>,
440    #[serde(skip)]
441    pub encodings: Option<TransactionWitnessSetEncoding>,
442}
443
444impl TransactionWitnessSet {
445    pub fn new() -> Self {
446        Self {
447            vkeywitnesses: None,
448            native_scripts: None,
449            bootstrap_witnesses: None,
450            plutus_v1_scripts: None,
451            plutus_datums: None,
452            redeemers: None,
453            plutus_v2_scripts: None,
454            plutus_v3_scripts: None,
455            encodings: None,
456        }
457    }
458}
459
460impl Default for TransactionWitnessSet {
461    fn default() -> Self {
462        Self::new()
463    }
464}