1pub mod cbor_encodings;
5pub mod serialization;
6pub mod utils;
7
8#[cfg(not(feature = "used_from_wasm"))]
9use noop_proc_macro::wasm_bindgen;
10#[cfg(feature = "used_from_wasm")]
11use wasm_bindgen::prelude::wasm_bindgen;
12
13use self::cbor_encodings::{
14 LegacyRedeemerEncoding, PlutusV3ScriptEncoding, RedeemerKeyEncoding, RedeemerValEncoding,
15};
16
17use super::{Rational, SubCoin};
18use crate::utils::BigInteger;
19use cbor_encodings::{
20 CostModelsEncoding, ExUnitPricesEncoding, ExUnitsEncoding, PlutusV1ScriptEncoding,
21 PlutusV2ScriptEncoding,
22};
23
24use cml_core::ordered_hash_map::OrderedHashMap;
25use cml_core::serialization::{LenEncoding, Serialize, StringEncoding};
26use cml_crypto::{blake2b256, DatumHash};
27
28pub use utils::{ConstrPlutusData, PlutusMap, PlutusScript};
29
30#[derive(Clone, Debug, Default)]
31pub struct CostModels {
32 pub inner: OrderedHashMap<u64, Vec<i64>>,
33 pub encodings: Option<CostModelsEncoding>,
34}
35
36impl CostModels {
37 pub fn new(inner: OrderedHashMap<u64, Vec<i64>>) -> Self {
38 Self {
39 inner,
40 encodings: None,
41 }
42 }
43}
44
45impl From<OrderedHashMap<u64, Vec<i64>>> for CostModels {
46 fn from(inner: OrderedHashMap<u64, Vec<i64>>) -> Self {
47 CostModels::new(inner.clone())
48 }
49}
50
51impl From<CostModels> for OrderedHashMap<u64, Vec<i64>> {
52 fn from(wrapper: CostModels) -> Self {
53 wrapper.inner
54 }
55}
56
57impl serde::Serialize for CostModels {
58 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
59 where
60 S: serde::Serializer,
61 {
62 self.inner.serialize(serializer)
63 }
64}
65
66impl<'de> serde::de::Deserialize<'de> for CostModels {
67 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
68 where
69 D: serde::de::Deserializer<'de>,
70 {
71 let inner =
72 <OrderedHashMap<u64, Vec<i64>> as serde::de::Deserialize>::deserialize(deserializer)?;
73 Ok(Self::new(inner))
74 }
75}
76
77impl schemars::JsonSchema for CostModels {
78 fn schema_name() -> String {
79 String::from("CostModels")
80 }
81
82 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
83 OrderedHashMap::<u64, Vec<i64>>::json_schema(gen)
84 }
85
86 fn is_referenceable() -> bool {
87 OrderedHashMap::<u64, Vec<i64>>::is_referenceable()
88 }
89}
90
91#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
92pub struct ExUnitPrices {
93 pub mem_price: SubCoin,
94 pub step_price: SubCoin,
95 #[serde(skip)]
96 pub encodings: Option<ExUnitPricesEncoding>,
97}
98
99impl ExUnitPrices {
100 pub fn new(mem_price: SubCoin, step_price: SubCoin) -> Self {
101 Self {
102 mem_price,
103 step_price,
104 encodings: None,
105 }
106 }
107}
108
109#[derive(
110 Clone, Debug, derivative::Derivative, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
111)]
112#[derivative(PartialEq, Hash, Eq)]
113pub struct ExUnits {
114 pub mem: u64,
115 pub steps: u64,
116 #[serde(skip)]
117 #[derivative(PartialEq = "ignore", Hash = "ignore")]
118 pub encodings: Option<ExUnitsEncoding>,
119}
120
121impl ExUnits {
122 pub fn new(mem: u64, steps: u64) -> Self {
123 Self {
124 mem,
125 steps,
126 encodings: None,
127 }
128 }
129}
130
131#[derive(
132 Copy,
133 Eq,
134 PartialEq,
135 Ord,
136 PartialOrd,
137 Clone,
138 Debug,
139 serde::Deserialize,
140 serde::Serialize,
141 schemars::JsonSchema,
142)]
143#[wasm_bindgen]
144pub enum Language {
145 PlutusV1,
146 PlutusV2,
147 PlutusV3,
148}
149
150#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
151pub struct LegacyRedeemer {
152 pub tag: RedeemerTag,
153 pub index: u64,
154 pub data: PlutusData,
155 pub ex_units: ExUnits,
156 #[serde(skip)]
157 pub encodings: Option<LegacyRedeemerEncoding>,
158}
159
160impl LegacyRedeemer {
161 pub fn new(tag: RedeemerTag, index: u64, data: PlutusData, ex_units: ExUnits) -> Self {
162 Self {
163 tag,
164 index,
165 data,
166 ex_units,
167 encodings: None,
168 }
169 }
170}
171
172#[derive(Clone, Debug, derivative::Derivative)]
173#[derivative(
174 Eq,
175 PartialEq,
176 Ord = "feature_allow_slow_enum",
177 PartialOrd = "feature_allow_slow_enum",
178 Hash
179)]
180pub enum PlutusData {
181 ConstrPlutusData(ConstrPlutusData),
182 Map(PlutusMap),
183 List {
184 list: Vec<PlutusData>,
185 #[derivative(
186 PartialEq = "ignore",
187 Ord = "ignore",
188 PartialOrd = "ignore",
189 Hash = "ignore"
190 )]
191 list_encoding: LenEncoding,
192 },
193 Integer(BigInteger),
194 Bytes {
195 bytes: Vec<u8>,
196 #[derivative(
197 PartialEq = "ignore",
198 Ord = "ignore",
199 PartialOrd = "ignore",
200 Hash = "ignore"
201 )]
202 bytes_encoding: StringEncoding,
203 },
204}
205
206impl PlutusData {
207 pub fn new_constr_plutus_data(constr_plutus_data: ConstrPlutusData) -> Self {
208 Self::ConstrPlutusData(constr_plutus_data)
209 }
210
211 pub fn new_map(map: PlutusMap) -> Self {
212 Self::Map(map)
213 }
214
215 pub fn new_list(list: Vec<PlutusData>) -> Self {
216 Self::List {
217 list,
218 list_encoding: LenEncoding::default(),
219 }
220 }
221
222 pub fn new_integer(integer: BigInteger) -> Self {
223 Self::Integer(integer)
224 }
225
226 pub fn new_bytes(bytes: Vec<u8>) -> Self {
227 Self::Bytes {
228 bytes,
229 bytes_encoding: StringEncoding::default(),
230 }
231 }
232
233 pub fn hash(&self) -> DatumHash {
234 DatumHash::from(blake2b256(&self.to_cbor_bytes()))
235 }
236}
237
238#[derive(Clone, Debug, derivative::Derivative)]
239#[derivative(Eq, PartialEq, Ord, PartialOrd, Hash)]
240pub struct PlutusV1Script {
241 pub inner: Vec<u8>,
242 #[derivative(
243 PartialEq = "ignore",
244 Ord = "ignore",
245 PartialOrd = "ignore",
246 Hash = "ignore"
247 )]
248 pub encodings: Option<PlutusV1ScriptEncoding>,
249}
250
251impl PlutusV1Script {
252 pub fn new(inner: Vec<u8>) -> Self {
253 Self {
254 inner,
255 encodings: None,
256 }
257 }
258}
259
260impl From<Vec<u8>> for PlutusV1Script {
261 fn from(inner: Vec<u8>) -> Self {
262 PlutusV1Script::new(inner)
263 }
264}
265
266impl From<PlutusV1Script> for Vec<u8> {
267 fn from(wrapper: PlutusV1Script) -> Self {
268 wrapper.inner
269 }
270}
271
272impl serde::Serialize for PlutusV1Script {
273 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
274 where
275 S: serde::Serializer,
276 {
277 serializer.serialize_str(&hex::encode(self.inner.clone()))
278 }
279}
280
281impl<'de> serde::de::Deserialize<'de> for PlutusV1Script {
282 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
283 where
284 D: serde::de::Deserializer<'de>,
285 {
286 let s = <String as serde::de::Deserialize>::deserialize(deserializer)?;
287 hex::decode(&s).map(PlutusV1Script::new).map_err(|_e| {
288 serde::de::Error::invalid_value(serde::de::Unexpected::Str(&s), &"invalid hex bytes")
289 })
290 }
291}
292
293impl schemars::JsonSchema for PlutusV1Script {
294 fn schema_name() -> String {
295 String::from("PlutusV1Script")
296 }
297
298 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
299 String::json_schema(gen)
300 }
301
302 fn is_referenceable() -> bool {
303 String::is_referenceable()
304 }
305}
306
307#[derive(Clone, Debug, derivative::Derivative)]
308#[derivative(Eq, PartialEq, Ord, PartialOrd, Hash)]
309pub struct PlutusV2Script {
310 pub inner: Vec<u8>,
311 #[derivative(
312 PartialEq = "ignore",
313 Ord = "ignore",
314 PartialOrd = "ignore",
315 Hash = "ignore"
316 )]
317 pub encodings: Option<PlutusV2ScriptEncoding>,
318}
319
320impl PlutusV2Script {
321 pub fn new(inner: Vec<u8>) -> Self {
322 Self {
323 inner,
324 encodings: None,
325 }
326 }
327}
328
329impl From<Vec<u8>> for PlutusV2Script {
330 fn from(inner: Vec<u8>) -> Self {
331 PlutusV2Script::new(inner)
332 }
333}
334
335impl From<PlutusV2Script> for Vec<u8> {
336 fn from(wrapper: PlutusV2Script) -> Self {
337 wrapper.inner
338 }
339}
340
341impl serde::Serialize for PlutusV2Script {
342 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
343 where
344 S: serde::Serializer,
345 {
346 serializer.serialize_str(&hex::encode(self.inner.clone()))
347 }
348}
349
350impl<'de> serde::de::Deserialize<'de> for PlutusV2Script {
351 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
352 where
353 D: serde::de::Deserializer<'de>,
354 {
355 let s = <String as serde::de::Deserialize>::deserialize(deserializer)?;
356 hex::decode(&s).map(PlutusV2Script::new).map_err(|_e| {
357 serde::de::Error::invalid_value(serde::de::Unexpected::Str(&s), &"invalid hex bytes")
358 })
359 }
360}
361
362impl schemars::JsonSchema for PlutusV2Script {
363 fn schema_name() -> String {
364 String::from("PlutusV2Script")
365 }
366
367 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
368 String::json_schema(gen)
369 }
370
371 fn is_referenceable() -> bool {
372 String::is_referenceable()
373 }
374}
375
376#[derive(Clone, Debug, derivative::Derivative)]
377#[derivative(Eq, PartialEq, Ord, PartialOrd, Hash)]
378pub struct PlutusV3Script {
379 pub inner: Vec<u8>,
380 #[derivative(
381 PartialEq = "ignore",
382 Ord = "ignore",
383 PartialOrd = "ignore",
384 Hash = "ignore"
385 )]
386 pub encodings: Option<PlutusV3ScriptEncoding>,
387}
388
389impl PlutusV3Script {
390 pub fn new(inner: Vec<u8>) -> Self {
391 Self {
392 inner,
393 encodings: None,
394 }
395 }
396}
397
398impl From<Vec<u8>> for PlutusV3Script {
399 fn from(inner: Vec<u8>) -> Self {
400 PlutusV3Script::new(inner)
401 }
402}
403
404impl From<PlutusV3Script> for Vec<u8> {
405 fn from(wrapper: PlutusV3Script) -> Self {
406 wrapper.inner
407 }
408}
409
410impl serde::Serialize for PlutusV3Script {
411 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
412 where
413 S: serde::Serializer,
414 {
415 serializer.serialize_str(&hex::encode(self.inner.clone()))
416 }
417}
418
419impl<'de> serde::de::Deserialize<'de> for PlutusV3Script {
420 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
421 where
422 D: serde::de::Deserializer<'de>,
423 {
424 let s = <String as serde::de::Deserialize>::deserialize(deserializer)?;
425 hex::decode(&s).map(PlutusV3Script::new).map_err(|_e| {
426 serde::de::Error::invalid_value(serde::de::Unexpected::Str(&s), &"invalid hex bytes")
427 })
428 }
429}
430
431impl schemars::JsonSchema for PlutusV3Script {
432 fn schema_name() -> String {
433 String::from("PlutusV3Script")
434 }
435
436 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
437 String::json_schema(gen)
438 }
439
440 fn is_referenceable() -> bool {
441 String::is_referenceable()
442 }
443}
444
445#[derive(
446 Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema, derivative::Derivative,
447)]
448#[derivative(Eq, PartialEq, Ord, PartialOrd, Hash)]
449pub struct RedeemerKey {
450 pub tag: RedeemerTag,
451 pub index: u64,
452 #[derivative(
453 PartialEq = "ignore",
454 Ord = "ignore",
455 PartialOrd = "ignore",
456 Hash = "ignore"
457 )]
458 #[serde(skip)]
459 pub encodings: Option<RedeemerKeyEncoding>,
460}
461
462impl RedeemerKey {
463 pub fn new(tag: RedeemerTag, index: u64) -> Self {
464 Self {
465 tag,
466 index,
467 encodings: None,
468 }
469 }
470}
471
472#[derive(
473 Copy,
474 Eq,
475 Hash,
476 PartialEq,
477 Ord,
478 PartialOrd,
479 Clone,
480 Debug,
481 serde::Deserialize,
482 serde::Serialize,
483 schemars::JsonSchema,
484)]
485#[wasm_bindgen]
486pub enum RedeemerTag {
487 Spend,
488 Mint,
489 Cert,
490 Reward,
491 Voting,
492 Proposing,
493}
494
495#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
496pub struct RedeemerVal {
497 pub data: PlutusData,
498 pub ex_units: ExUnits,
499 #[serde(skip)]
500 pub encodings: Option<RedeemerValEncoding>,
501}
502
503impl RedeemerVal {
504 pub fn new(data: PlutusData, ex_units: ExUnits) -> Self {
505 Self {
506 data,
507 ex_units,
508 encodings: None,
509 }
510 }
511}
512
513#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
514pub enum Redeemers {
515 ArrLegacyRedeemer {
516 arr_legacy_redeemer: Vec<LegacyRedeemer>,
517 #[serde(skip)]
518 arr_legacy_redeemer_encoding: LenEncoding,
519 },
520 MapRedeemerKeyToRedeemerVal {
521 map_redeemer_key_to_redeemer_val: OrderedHashMap<RedeemerKey, RedeemerVal>,
522 #[serde(skip)]
523 map_redeemer_key_to_redeemer_val_encoding: LenEncoding,
524 },
525}
526
527impl Redeemers {
528 pub fn new_arr_legacy_redeemer(arr_legacy_redeemer: Vec<LegacyRedeemer>) -> Self {
529 Self::ArrLegacyRedeemer {
530 arr_legacy_redeemer,
531 arr_legacy_redeemer_encoding: LenEncoding::default(),
532 }
533 }
534
535 pub fn new_map_redeemer_key_to_redeemer_val(
536 map_redeemer_key_to_redeemer_val: OrderedHashMap<RedeemerKey, RedeemerVal>,
537 ) -> Self {
538 Self::MapRedeemerKeyToRedeemerVal {
539 map_redeemer_key_to_redeemer_val,
540 map_redeemer_key_to_redeemer_val_encoding: LenEncoding::default(),
541 }
542 }
543}