1#![cfg_attr(feature = "with-bench", feature(test))]
2#![allow(deprecated)]
3
4#[macro_use]
5extern crate cfg_if;
6
7#[cfg(test)]
8#[cfg(feature = "with-bench")]
9extern crate test;
10
11#[cfg(test)]
12extern crate quickcheck;
13#[cfg(test)]
14#[macro_use(quickcheck)]
15extern crate quickcheck_macros;
16extern crate hex;
17
18#[cfg(test)]
19mod tests;
20
21#[macro_use]
22extern crate num_derive;
23
24use std::convert::TryInto;
25use std::io::{BufRead, Seek, Write};
26
27#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
28use noop_proc_macro::wasm_bindgen;
29
30#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
31use wasm_bindgen::prelude::{wasm_bindgen, JsValue};
32
33use cbor_event::{Len, Special as CBORSpecial};
37use cbor_event::Type as CBORType;
38use cbor_event::{
39 self,
40 de::Deserializer,
41 se::{Serialize, Serializer},
42};
43
44mod builders;
45pub use builders::*;
46pub mod chain_core;
47pub mod chain_crypto;
48mod crypto;
49pub(crate) use crypto::*;
50mod emip3;
51pub use emip3::*;
52mod error;
53pub use error::*;
54mod fees;
55pub use fees::*;
56pub mod impl_mockchain;
57pub mod legacy_address;
58pub mod traits;
59mod protocol_types;
60pub use protocol_types::*;
61pub mod typed_bytes;
62#[macro_use]
63mod utils;
64pub use utils::*;
65mod serialization;
66mod rational;
67
68pub use serialization::*;
69
70use crate::traits::NoneOrEmpty;
71use schemars::JsonSchema;
72use std::cmp::Ordering;
73use std::collections::BTreeSet;
74use std::fmt;
75use std::fmt::Display;
76use hashlink::LinkedHashMap;
77
78type DeltaCoin = Int;
79
80#[wasm_bindgen]
81#[derive(
82 Clone,
83 Debug,
84 Hash,
85 Eq,
86 Ord,
87 PartialEq,
88 PartialOrd,
89 Default,
90 serde::Serialize,
91 serde::Deserialize,
92 JsonSchema,
93)]
94pub struct UnitInterval {
95 numerator: BigNum,
96 denominator: BigNum,
97}
98
99impl_to_from!(UnitInterval);
100
101#[wasm_bindgen]
102impl UnitInterval {
103 pub fn numerator(&self) -> BigNum {
104 self.numerator.clone()
105 }
106
107 pub fn denominator(&self) -> BigNum {
108 self.denominator.clone()
109 }
110
111 pub fn new(numerator: &BigNum, denominator: &BigNum) -> Self {
112 Self {
113 numerator: numerator.clone(),
114 denominator: denominator.clone(),
115 }
116 }
117}
118
119type SubCoin = UnitInterval;
120type Epoch = u32;
121type Slot32 = u32;
122type SlotBigNum = BigNum;
123
124#[wasm_bindgen]
125#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, JsonSchema)]
126pub struct Transaction {
127 body: TransactionBody,
128 witness_set: TransactionWitnessSet,
129 is_valid: bool,
130 auxiliary_data: Option<AuxiliaryData>,
131}
132
133impl_to_from!(Transaction);
134
135#[wasm_bindgen]
136impl Transaction {
137 pub fn body(&self) -> TransactionBody {
138 self.body.clone()
139 }
140
141 pub fn witness_set(&self) -> TransactionWitnessSet {
142 self.witness_set.clone()
143 }
144
145 pub fn is_valid(&self) -> bool {
146 self.is_valid.clone()
147 }
148
149 pub fn auxiliary_data(&self) -> Option<AuxiliaryData> {
150 self.auxiliary_data.clone()
151 }
152
153 pub fn set_is_valid(&mut self, valid: bool) {
154 self.is_valid = valid
155 }
156
157 pub fn new(
158 body: &TransactionBody,
159 witness_set: &TransactionWitnessSet,
160 auxiliary_data: Option<AuxiliaryData>,
161 ) -> Self {
162 Self {
163 body: body.clone(),
164 witness_set: witness_set.clone(),
165 is_valid: true,
166 auxiliary_data: auxiliary_data.clone(),
167 }
168 }
169}
170
171type TransactionIndex = u32;
173type CertificateIndex = u32;
175type GovernanceActionIndex = u32;
176
177#[wasm_bindgen]
178#[derive(Clone, Eq, PartialEq, Debug, serde::Serialize, serde::Deserialize, JsonSchema)]
179pub struct TransactionOutputs(Vec<TransactionOutput>);
180
181impl_to_from!(TransactionOutputs);
182
183#[wasm_bindgen]
184impl TransactionOutputs {
185 pub fn new() -> Self {
186 Self(Vec::new())
187 }
188
189 pub fn len(&self) -> usize {
190 self.0.len()
191 }
192
193 pub fn get(&self, index: usize) -> TransactionOutput {
194 self.0[index].clone()
195 }
196
197 pub fn add(&mut self, elem: &TransactionOutput) {
198 self.0.push(elem.clone());
199 }
200}
201
202impl<'a> IntoIterator for &'a TransactionOutputs {
203 type Item = &'a TransactionOutput;
204 type IntoIter = std::slice::Iter<'a, TransactionOutput>;
205
206 fn into_iter(self) -> std::slice::Iter<'a, TransactionOutput> {
207 self.0.iter()
208 }
209}
210
211#[wasm_bindgen]
212#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
213pub struct DataCost{
214 coins_per_byte: Coin
215}
216
217#[wasm_bindgen]
218impl DataCost {
219 pub fn new_coins_per_byte(coins_per_byte: &Coin) -> DataCost {
220 DataCost {
221 coins_per_byte: coins_per_byte.clone()
222 }
223 }
224
225 pub fn coins_per_byte(&self) -> Coin {
226 self.coins_per_byte.clone()
227 }
228}
229
230#[wasm_bindgen]
231#[derive(Debug, Clone, Eq, Ord, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema)]
232pub struct TransactionOutput {
233 address: Address,
234 amount: Value,
235 plutus_data: Option<DataOption>,
236 script_ref: Option<ScriptRef>,
237
238 #[serde(skip)]
239 serialization_format: Option<CborContainerType>,
240}
241
242impl_to_from!(TransactionOutput);
243
244#[wasm_bindgen]
245impl TransactionOutput {
246 pub fn address(&self) -> Address {
247 self.address.clone()
248 }
249
250 pub fn amount(&self) -> Value {
251 self.amount.clone()
252 }
253
254 pub fn data_hash(&self) -> Option<DataHash> {
255 match &self.plutus_data {
256 Some(DataOption::DataHash(data_hash)) => Some(data_hash.clone()),
257 _ => None,
258 }
259 }
260
261 pub fn plutus_data(&self) -> Option<PlutusData> {
262 match &self.plutus_data {
263 Some(DataOption::Data(plutus_data)) => Some(plutus_data.clone()),
264 _ => None,
265 }
266 }
267
268 pub fn script_ref(&self) -> Option<ScriptRef> {
269 self.script_ref.clone()
270 }
271
272 pub fn set_script_ref(&mut self, script_ref: &ScriptRef) {
273 self.script_ref = Some(script_ref.clone());
274 }
275
276 pub fn set_plutus_data(&mut self, data: &PlutusData) {
277 self.plutus_data = Some(DataOption::Data(data.clone()));
278 }
279
280 pub fn set_data_hash(&mut self, data_hash: &DataHash) {
281 self.plutus_data = Some(DataOption::DataHash(data_hash.clone()));
282 }
283
284 pub fn has_plutus_data(&self) -> bool {
285 match &self.plutus_data {
286 Some(DataOption::Data(_)) => true,
287 _ => false,
288 }
289 }
290
291 pub fn has_data_hash(&self) -> bool {
292 match &self.plutus_data {
293 Some(DataOption::DataHash(_)) => true,
294 _ => false,
295 }
296 }
297
298 pub fn has_script_ref(&self) -> bool {
299 self.script_ref.is_some()
300 }
301
302 pub fn new(address: &Address, amount: &Value) -> Self {
303 Self {
304 address: address.clone(),
305 amount: amount.clone(),
306 plutus_data: None,
307 script_ref: None,
308 serialization_format: None,
309 }
310 }
311
312 pub fn serialization_format(&self) -> Option<CborContainerType> {
313 self.serialization_format.clone()
314 }
315}
316
317impl PartialEq for TransactionOutput {
318 fn eq(&self, other: &Self) -> bool {
319 self.address == other.address
320 && self.amount == other.amount
321 && self.plutus_data == other.plutus_data
322 && self.script_ref == other.script_ref
323 }
324}
325
326type Port = u16;
327
328#[wasm_bindgen]
329#[derive(
330 Clone,
331 Debug,
332 Hash,
333 Eq,
334 Ord,
335 PartialEq,
336 PartialOrd,
337 serde::Serialize,
338 serde::Deserialize,
339 JsonSchema,
340)]
341pub struct Ipv4([u8; 4]);
342
343impl_to_from!(Ipv4);
344
345#[wasm_bindgen]
346impl Ipv4 {
347 pub fn new(data: Vec<u8>) -> Result<Ipv4, JsError> {
348 Self::new_impl(data).map_err(|e| JsError::from_str(&e.to_string()))
349 }
350
351 pub(crate) fn new_impl(data: Vec<u8>) -> Result<Ipv4, DeserializeError> {
352 data.as_slice().try_into().map(Self).map_err(|_e| {
353 let cbor_error = cbor_event::Error::WrongLen(
354 4,
355 cbor_event::Len::Len(data.len() as u64),
356 "Ipv4 address length",
357 );
358 DeserializeError::new("Ipv4", DeserializeFailure::CBOR(cbor_error))
359 })
360 }
361
362 pub fn ip(&self) -> Vec<u8> {
363 self.0.to_vec()
364 }
365}
366
367#[wasm_bindgen]
368#[derive(
369 Clone,
370 Debug,
371 Hash,
372 Eq,
373 Ord,
374 PartialEq,
375 PartialOrd,
376 serde::Serialize,
377 serde::Deserialize,
378 JsonSchema,
379)]
380pub struct Ipv6([u8; 16]);
381
382impl_to_from!(Ipv6);
383
384#[wasm_bindgen]
385impl Ipv6 {
386 pub fn new(data: Vec<u8>) -> Result<Ipv6, JsError> {
387 Self::new_impl(data).map_err(|e| JsError::from_str(&e.to_string()))
388 }
389
390 pub(crate) fn new_impl(data: Vec<u8>) -> Result<Ipv6, DeserializeError> {
391 data.as_slice().try_into().map(Self).map_err(|_e| {
392 let cbor_error = cbor_event::Error::WrongLen(
393 16,
394 cbor_event::Len::Len(data.len() as u64),
395 "Ipv6 address length",
396 );
397 DeserializeError::new("Ipv6", DeserializeFailure::CBOR(cbor_error))
398 })
399 }
400
401 pub fn ip(&self) -> Vec<u8> {
402 self.0.to_vec()
403 }
404}
405
406static URL_MAX_LEN: usize = 128;
407
408#[wasm_bindgen]
409#[derive(
410 Clone,
411 Debug,
412 Hash,
413 Eq,
414 Ord,
415 PartialEq,
416 PartialOrd,
417 serde::Serialize,
418 serde::Deserialize,
419 JsonSchema,
420)]
421pub struct URL(String);
422
423impl_to_from!(URL);
424
425#[wasm_bindgen]
426impl URL {
427 pub fn new(url: String) -> Result<URL, JsError> {
428 Self::new_impl(url).map_err(|e| JsError::from_str(&e.to_string()))
429 }
430
431 pub(crate) fn new_impl(url: String) -> Result<URL, DeserializeError> {
432 if url.len() <= URL_MAX_LEN {
433 Ok(Self(url))
434 } else {
435 Err(DeserializeError::new(
436 "URL",
437 DeserializeFailure::OutOfRange {
438 min: 0,
439 max: URL_MAX_LEN,
440 found: url.len(),
441 },
442 ))
443 }
444 }
445
446 pub fn url(&self) -> String {
447 self.0.clone()
448 }
449}
450
451static DNS_NAME_MAX_LEN: usize = 128;
452
453#[wasm_bindgen]
454#[derive(
455 Clone,
456 Debug,
457 Hash,
458 Eq,
459 Ord,
460 PartialEq,
461 PartialOrd,
462 serde::Serialize,
463 serde::Deserialize,
464 JsonSchema,
465)]
466pub struct DNSRecordAorAAAA(String);
467
468impl_to_from!(DNSRecordAorAAAA);
469
470#[wasm_bindgen]
471impl DNSRecordAorAAAA {
472 pub fn new(dns_name: String) -> Result<DNSRecordAorAAAA, JsError> {
473 Self::new_impl(dns_name).map_err(|e| JsError::from_str(&e.to_string()))
474 }
475
476 pub(crate) fn new_impl(dns_name: String) -> Result<DNSRecordAorAAAA, DeserializeError> {
477 if dns_name.len() <= DNS_NAME_MAX_LEN {
478 Ok(Self(dns_name))
479 } else {
480 Err(DeserializeError::new(
481 "DNSRecordAorAAAA",
482 DeserializeFailure::OutOfRange {
483 min: 0,
484 max: DNS_NAME_MAX_LEN,
485 found: dns_name.len(),
486 },
487 ))
488 }
489 }
490
491 pub fn record(&self) -> String {
492 self.0.clone()
493 }
494}
495
496#[wasm_bindgen]
497#[derive(
498 Clone,
499 Debug,
500 Hash,
501 Eq,
502 Ord,
503 PartialEq,
504 PartialOrd,
505 serde::Serialize,
506 serde::Deserialize,
507 JsonSchema,
508)]
509pub struct DNSRecordSRV(String);
510
511impl_to_from!(DNSRecordSRV);
512
513#[wasm_bindgen]
514impl DNSRecordSRV {
515 pub fn new(dns_name: String) -> Result<DNSRecordSRV, JsError> {
516 Self::new_impl(dns_name).map_err(|e| JsError::from_str(&e.to_string()))
517 }
518
519 pub(crate) fn new_impl(dns_name: String) -> Result<DNSRecordSRV, DeserializeError> {
520 if dns_name.len() <= DNS_NAME_MAX_LEN {
521 Ok(Self(dns_name))
522 } else {
523 Err(DeserializeError::new(
524 "DNSRecordSRV",
525 DeserializeFailure::OutOfRange {
526 min: 0,
527 max: DNS_NAME_MAX_LEN,
528 found: dns_name.len(),
529 },
530 ))
531 }
532 }
533
534 pub fn record(&self) -> String {
535 self.0.clone()
536 }
537}
538
539#[wasm_bindgen]
540#[derive(
541 Clone,
542 Debug,
543 Hash,
544 Eq,
545 Ord,
546 PartialEq,
547 PartialOrd,
548 serde::Serialize,
549 serde::Deserialize,
550 JsonSchema,
551)]
552pub struct SingleHostAddr {
553 port: Option<Port>,
554 ipv4: Option<Ipv4>,
555 ipv6: Option<Ipv6>,
556}
557
558impl_to_from!(SingleHostAddr);
559
560#[wasm_bindgen]
561impl SingleHostAddr {
562 pub fn port(&self) -> Option<Port> {
563 self.port.clone()
564 }
565
566 pub fn ipv4(&self) -> Option<Ipv4> {
567 self.ipv4.clone()
568 }
569
570 pub fn ipv6(&self) -> Option<Ipv6> {
571 self.ipv6.clone()
572 }
573
574 pub fn new(port: Option<Port>, ipv4: Option<Ipv4>, ipv6: Option<Ipv6>) -> Self {
575 Self {
576 port: port,
577 ipv4: ipv4.clone(),
578 ipv6: ipv6.clone(),
579 }
580 }
581}
582
583#[wasm_bindgen]
584#[derive(
585 Clone,
586 Debug,
587 Hash,
588 Eq,
589 Ord,
590 PartialEq,
591 PartialOrd,
592 serde::Serialize,
593 serde::Deserialize,
594 JsonSchema,
595)]
596pub struct SingleHostName {
597 port: Option<Port>,
598 dns_name: DNSRecordAorAAAA,
599}
600
601impl_to_from!(SingleHostName);
602
603#[wasm_bindgen]
604impl SingleHostName {
605 pub fn port(&self) -> Option<Port> {
606 self.port.clone()
607 }
608
609 pub fn dns_name(&self) -> DNSRecordAorAAAA {
610 self.dns_name.clone()
611 }
612
613 pub fn new(port: Option<Port>, dns_name: &DNSRecordAorAAAA) -> Self {
614 Self {
615 port: port,
616 dns_name: dns_name.clone(),
617 }
618 }
619}
620
621#[wasm_bindgen]
622#[derive(
623 Clone,
624 Debug,
625 Hash,
626 Eq,
627 Ord,
628 PartialEq,
629 PartialOrd,
630 serde::Serialize,
631 serde::Deserialize,
632 JsonSchema,
633)]
634pub struct MultiHostName {
635 dns_name: DNSRecordSRV,
636}
637
638impl_to_from!(MultiHostName);
639
640#[wasm_bindgen]
641impl MultiHostName {
642 pub fn dns_name(&self) -> DNSRecordSRV {
643 self.dns_name.clone()
644 }
645
646 pub fn new(dns_name: &DNSRecordSRV) -> Self {
647 Self {
648 dns_name: dns_name.clone(),
649 }
650 }
651}
652
653#[wasm_bindgen]
654#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
655pub enum RelayKind {
656 SingleHostAddr,
657 SingleHostName,
658 MultiHostName,
659}
660
661#[derive(
662 Clone,
663 Debug,
664 Hash,
665 Eq,
666 Ord,
667 PartialEq,
668 PartialOrd,
669 serde::Serialize,
670 serde::Deserialize,
671 JsonSchema,
672)]
673pub enum RelayEnum {
674 SingleHostAddr(SingleHostAddr),
675 SingleHostName(SingleHostName),
676 MultiHostName(MultiHostName),
677}
678
679#[wasm_bindgen]
680#[derive(
681 Clone,
682 Debug,
683 Hash,
684 Eq,
685 Ord,
686 PartialEq,
687 PartialOrd,
688 serde::Serialize,
689 serde::Deserialize,
690 JsonSchema,
691)]
692pub struct Relay(RelayEnum);
693
694impl_to_from!(Relay);
695
696#[wasm_bindgen]
697impl Relay {
698 pub fn new_single_host_addr(single_host_addr: &SingleHostAddr) -> Self {
699 Self(RelayEnum::SingleHostAddr(single_host_addr.clone()))
700 }
701
702 pub fn new_single_host_name(single_host_name: &SingleHostName) -> Self {
703 Self(RelayEnum::SingleHostName(single_host_name.clone()))
704 }
705
706 pub fn new_multi_host_name(multi_host_name: &MultiHostName) -> Self {
707 Self(RelayEnum::MultiHostName(multi_host_name.clone()))
708 }
709
710 pub fn kind(&self) -> RelayKind {
711 match &self.0 {
712 RelayEnum::SingleHostAddr(_) => RelayKind::SingleHostAddr,
713 RelayEnum::SingleHostName(_) => RelayKind::SingleHostName,
714 RelayEnum::MultiHostName(_) => RelayKind::MultiHostName,
715 }
716 }
717
718 pub fn as_single_host_addr(&self) -> Option<SingleHostAddr> {
719 match &self.0 {
720 RelayEnum::SingleHostAddr(x) => Some(x.clone()),
721 _ => None,
722 }
723 }
724
725 pub fn as_single_host_name(&self) -> Option<SingleHostName> {
726 match &self.0 {
727 RelayEnum::SingleHostName(x) => Some(x.clone()),
728 _ => None,
729 }
730 }
731
732 pub fn as_multi_host_name(&self) -> Option<MultiHostName> {
733 match &self.0 {
734 RelayEnum::MultiHostName(x) => Some(x.clone()),
735 _ => None,
736 }
737 }
738}
739
740#[wasm_bindgen]
741#[derive(
742 Clone,
743 Debug,
744 Hash,
745 Eq,
746 Ord,
747 PartialEq,
748 PartialOrd,
749 serde::Serialize,
750 serde::Deserialize,
751 JsonSchema,
752)]
753pub struct PoolMetadata {
754 url: URL,
755 pool_metadata_hash: PoolMetadataHash,
756}
757
758impl_to_from!(PoolMetadata);
759
760#[wasm_bindgen]
761impl PoolMetadata {
762 pub fn url(&self) -> URL {
763 self.url.clone()
764 }
765
766 pub fn pool_metadata_hash(&self) -> PoolMetadataHash {
767 self.pool_metadata_hash.clone()
768 }
769
770 pub fn new(url: &URL, pool_metadata_hash: &PoolMetadataHash) -> Self {
771 Self {
772 url: url.clone(),
773 pool_metadata_hash: pool_metadata_hash.clone(),
774 }
775 }
776}
777
778#[wasm_bindgen]
779#[derive(
780 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
781)]
782pub struct RewardAddresses(pub(crate) Vec<RewardAddress>);
783
784impl_to_from!(RewardAddresses);
785
786#[wasm_bindgen]
787impl RewardAddresses {
788 pub fn new() -> Self {
789 Self(Vec::new())
790 }
791
792 pub fn len(&self) -> usize {
793 self.0.len()
794 }
795
796 pub fn get(&self, index: usize) -> RewardAddress {
797 self.0[index].clone()
798 }
799
800 pub fn add(&mut self, elem: &RewardAddress) {
801 self.0.push(elem.clone());
802 }
803}
804
805#[wasm_bindgen]
806#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
807pub struct Withdrawals(LinkedHashMap<RewardAddress, Coin>);
808
809impl_to_from!(Withdrawals);
810
811impl NoneOrEmpty for Withdrawals {
812 fn is_none_or_empty(&self) -> bool {
813 self.0.is_empty()
814 }
815}
816
817#[wasm_bindgen]
818impl Withdrawals {
819 pub fn new() -> Self {
820 Self(LinkedHashMap::new())
821 }
822
823 pub fn len(&self) -> usize {
824 self.0.len()
825 }
826
827 pub fn insert(&mut self, key: &RewardAddress, value: &Coin) -> Option<Coin> {
828 self.0.insert(key.clone(), value.clone())
829 }
830
831 pub fn get(&self, key: &RewardAddress) -> Option<Coin> {
832 self.0.get(key).map(|v| v.clone())
833 }
834
835 pub fn keys(&self) -> RewardAddresses {
836 RewardAddresses(
837 self.0
838 .iter()
839 .map(|(k, _v)| k.clone())
840 .collect::<Vec<RewardAddress>>(),
841 )
842 }
843
844 pub(crate) fn as_vec(&self) -> Vec<(&RewardAddress, &Coin)> {
845 self.0.iter().collect()
846 }
847}
848
849impl serde::Serialize for Withdrawals {
850 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
851 where
852 S: serde::Serializer,
853 {
854 let map = self.0.iter().collect::<std::collections::BTreeMap<_, _>>();
855 map.serialize(serializer)
856 }
857}
858
859impl<'de> serde::de::Deserialize<'de> for Withdrawals {
860 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
861 where
862 D: serde::de::Deserializer<'de>,
863 {
864 let map = <std::collections::BTreeMap<_, _> as serde::de::Deserialize>::deserialize(
865 deserializer,
866 )?;
867 Ok(Self(map.into_iter().collect()))
868 }
869}
870
871impl JsonSchema for Withdrawals {
872 fn schema_name() -> String {
873 String::from("Withdrawals")
874 }
875 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
876 std::collections::BTreeMap::<RewardAddress, Coin>::json_schema(gen)
877 }
878 fn is_referenceable() -> bool {
879 std::collections::BTreeMap::<RewardAddress, Coin>::is_referenceable()
880 }
881}
882
883#[derive(
884 Debug, Clone, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
885)]
886pub enum DataOption {
887 DataHash(DataHash),
888 Data(PlutusData),
889}
890
891#[wasm_bindgen]
892#[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)]
893pub struct OutputDatum(pub(crate) DataOption);
894
895#[wasm_bindgen]
896impl OutputDatum {
897 pub fn new_data_hash(data_hash: &DataHash) -> Self {
898 Self(DataOption::DataHash(data_hash.clone()))
899 }
900
901 pub fn new_data(data: &PlutusData) -> Self {
902 Self(DataOption::Data(data.clone()))
903 }
904
905 pub fn data_hash(&self) -> Option<DataHash> {
906 match &self.0 {
907 DataOption::DataHash(data_hash) => Some(data_hash.clone()),
908 _ => None,
909 }
910 }
911
912 pub fn data(&self) -> Option<PlutusData> {
913 match &self.0 {
914 DataOption::Data(data) => Some(data.clone()),
915 _ => None,
916 }
917 }
918}
919
920#[wasm_bindgen]
925#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
926pub enum ScriptHashNamespace {
927 NativeScript = 0,
928 PlutusScript = 1,
929 PlutusScriptV2 = 2,
930 PlutusScriptV3 = 3,
931}
932
933#[wasm_bindgen]
934#[derive(
935 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
936)]
937pub struct Update {
938 proposed_protocol_parameter_updates: ProposedProtocolParameterUpdates,
939 epoch: Epoch,
940}
941
942impl_to_from!(Update);
943
944#[wasm_bindgen]
945impl Update {
946 pub fn proposed_protocol_parameter_updates(&self) -> ProposedProtocolParameterUpdates {
947 self.proposed_protocol_parameter_updates.clone()
948 }
949
950 pub fn epoch(&self) -> Epoch {
951 self.epoch.clone()
952 }
953
954 pub fn new(
955 proposed_protocol_parameter_updates: &ProposedProtocolParameterUpdates,
956 epoch: Epoch,
957 ) -> Self {
958 Self {
959 proposed_protocol_parameter_updates: proposed_protocol_parameter_updates.clone(),
960 epoch: epoch.clone(),
961 }
962 }
963}
964
965#[wasm_bindgen]
966#[derive(
967 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
968)]
969pub struct GenesisHashes(Vec<GenesisHash>);
970
971impl_to_from!(GenesisHashes);
972
973#[wasm_bindgen]
974impl GenesisHashes {
975 pub fn new() -> Self {
976 Self(Vec::new())
977 }
978
979 pub fn len(&self) -> usize {
980 self.0.len()
981 }
982
983 pub fn get(&self, index: usize) -> GenesisHash {
984 self.0[index].clone()
985 }
986
987 pub fn add(&mut self, elem: &GenesisHash) {
988 self.0.push(elem.clone());
989 }
990}
991
992#[wasm_bindgen]
993#[derive(
994 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
995)]
996pub struct ScriptHashes(pub(crate) Vec<ScriptHash>);
997
998impl_to_from!(ScriptHashes);
999
1000#[wasm_bindgen]
1001impl ScriptHashes {
1002 pub fn new() -> Self {
1003 Self(Vec::new())
1004 }
1005
1006 pub fn len(&self) -> usize {
1007 self.0.len()
1008 }
1009
1010 pub fn get(&self, index: usize) -> ScriptHash {
1011 self.0[index].clone()
1012 }
1013
1014 pub fn add(&mut self, elem: &ScriptHash) {
1015 self.0.push(elem.clone());
1016 }
1017}
1018
1019#[wasm_bindgen]
1020#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1021pub struct ProposedProtocolParameterUpdates(
1022 LinkedHashMap<GenesisHash, ProtocolParamUpdate>,
1023);
1024
1025impl serde::Serialize for ProposedProtocolParameterUpdates {
1026 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1027 where
1028 S: serde::Serializer,
1029 {
1030 let map = self.0.iter().collect::<std::collections::BTreeMap<_, _>>();
1031 map.serialize(serializer)
1032 }
1033}
1034
1035impl<'de> serde::de::Deserialize<'de> for ProposedProtocolParameterUpdates {
1036 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1037 where
1038 D: serde::de::Deserializer<'de>,
1039 {
1040 let map = <std::collections::BTreeMap<_, _> as serde::de::Deserialize>::deserialize(
1041 deserializer,
1042 )?;
1043 Ok(Self(map.into_iter().collect()))
1044 }
1045}
1046
1047impl JsonSchema for ProposedProtocolParameterUpdates {
1048 fn schema_name() -> String {
1049 String::from("ProposedProtocolParameterUpdates")
1050 }
1051 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1052 std::collections::BTreeMap::<GenesisHash, ProtocolParamUpdate>::json_schema(gen)
1053 }
1054 fn is_referenceable() -> bool {
1055 std::collections::BTreeMap::<GenesisHash, ProtocolParamUpdate>::is_referenceable()
1056 }
1057}
1058
1059impl_to_from!(ProposedProtocolParameterUpdates);
1060
1061#[wasm_bindgen]
1062impl ProposedProtocolParameterUpdates {
1063 pub fn new() -> Self {
1064 Self(LinkedHashMap::new())
1065 }
1066
1067 pub fn len(&self) -> usize {
1068 self.0.len()
1069 }
1070
1071 pub fn insert(
1072 &mut self,
1073 key: &GenesisHash,
1074 value: &ProtocolParamUpdate,
1075 ) -> Option<ProtocolParamUpdate> {
1076 self.0.insert(key.clone(), value.clone())
1077 }
1078
1079 pub fn get(&self, key: &GenesisHash) -> Option<ProtocolParamUpdate> {
1080 self.0.get(key).map(|v| v.clone())
1081 }
1082
1083 pub fn keys(&self) -> GenesisHashes {
1084 GenesisHashes(
1085 self.0
1086 .iter()
1087 .map(|(k, _v)| k.clone())
1088 .collect::<Vec<GenesisHash>>(),
1089 )
1090 }
1091}
1092
1093#[wasm_bindgen]
1094#[derive(
1095 Clone,
1096 Debug,
1097 Hash,
1098 Eq,
1099 Ord,
1100 PartialEq,
1101 PartialOrd,
1102 serde::Serialize,
1103 serde::Deserialize,
1104 JsonSchema,
1105)]
1106pub struct ProtocolVersion {
1107 major: u32,
1108 minor: u32,
1109}
1110
1111impl_to_from!(ProtocolVersion);
1112
1113#[wasm_bindgen]
1114impl ProtocolVersion {
1115 pub fn major(&self) -> u32 {
1116 self.major
1117 }
1118
1119 pub fn minor(&self) -> u32 {
1120 self.minor
1121 }
1122
1123 pub fn new(major: u32, minor: u32) -> Self {
1124 Self { major, minor }
1125 }
1126}
1127
1128#[wasm_bindgen]
1129#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1130pub struct AuxiliaryDataSet(LinkedHashMap<TransactionIndex, AuxiliaryData>);
1131
1132#[wasm_bindgen]
1133impl AuxiliaryDataSet {
1134 pub fn new() -> Self {
1135 Self(LinkedHashMap::new())
1136 }
1137
1138 pub fn len(&self) -> usize {
1139 self.0.len()
1140 }
1141
1142 pub fn insert(
1143 &mut self,
1144 tx_index: TransactionIndex,
1145 data: &AuxiliaryData,
1146 ) -> Option<AuxiliaryData> {
1147 self.0.insert(tx_index, data.clone())
1148 }
1149
1150 pub fn get(&self, tx_index: TransactionIndex) -> Option<AuxiliaryData> {
1151 self.0.get(&tx_index).map(|v| v.clone())
1152 }
1153
1154 pub fn indices(&self) -> TransactionIndexes {
1155 self.0
1156 .iter()
1157 .map(|(k, _v)| k.clone())
1158 .collect::<Vec<TransactionIndex>>()
1159 }
1160}
1161
1162impl serde::Serialize for AuxiliaryDataSet {
1163 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1164 where
1165 S: serde::Serializer,
1166 {
1167 let map = self.0.iter().collect::<std::collections::BTreeMap<_, _>>();
1168 map.serialize(serializer)
1169 }
1170}
1171
1172impl<'de> serde::de::Deserialize<'de> for AuxiliaryDataSet {
1173 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1174 where
1175 D: serde::de::Deserializer<'de>,
1176 {
1177 let map = <std::collections::BTreeMap<_, _> as serde::de::Deserialize>::deserialize(
1178 deserializer,
1179 )?;
1180 Ok(Self(map.into_iter().collect()))
1181 }
1182}
1183
1184impl JsonSchema for AuxiliaryDataSet {
1185 fn schema_name() -> String {
1186 String::from("AuxiliaryDataSet")
1187 }
1188 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1189 std::collections::BTreeMap::<TransactionIndex, AuxiliaryData>::json_schema(gen)
1190 }
1191 fn is_referenceable() -> bool {
1192 std::collections::BTreeMap::<TransactionIndex, AuxiliaryData>::is_referenceable()
1193 }
1194}
1195
1196#[wasm_bindgen]
1197#[derive(Clone, Debug, Eq, PartialEq, Hash)]
1198pub struct AssetName(Vec<u8>);
1199
1200impl Display for AssetName {
1201 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1202 write!(f, "{}", hex::encode(&self.0))
1203 }
1204}
1205
1206impl Ord for AssetName {
1207 fn cmp(&self, other: &Self) -> Ordering {
1208 return match self.0.len().cmp(&other.0.len()) {
1211 Ordering::Equal => self.0.cmp(&other.0),
1212 x => x,
1213 };
1214 }
1215}
1216
1217impl PartialOrd for AssetName {
1218 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1219 Some(self.cmp(other))
1220 }
1221}
1222
1223impl_to_from!(AssetName);
1224
1225#[wasm_bindgen]
1226impl AssetName {
1227 pub fn new(name: Vec<u8>) -> Result<AssetName, JsError> {
1228 Self::new_impl(name).map_err(|e| JsError::from_str(&e.to_string()))
1229 }
1230
1231 pub(crate) fn new_impl(name: Vec<u8>) -> Result<AssetName, DeserializeError> {
1232 if name.len() <= 32 {
1233 Ok(Self(name))
1234 } else {
1235 Err(DeserializeError::new(
1236 "AssetName",
1237 DeserializeFailure::OutOfRange {
1238 min: 0,
1239 max: 32,
1240 found: name.len(),
1241 },
1242 ))
1243 }
1244 }
1245
1246 pub fn name(&self) -> Vec<u8> {
1247 self.0.clone()
1248 }
1249}
1250
1251impl serde::Serialize for AssetName {
1252 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1253 where
1254 S: serde::Serializer,
1255 {
1256 serializer.serialize_str(&hex::encode(&self.0))
1257 }
1258}
1259
1260impl<'de> serde::de::Deserialize<'de> for AssetName {
1261 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1262 where
1263 D: serde::de::Deserializer<'de>,
1264 {
1265 let s = <String as serde::de::Deserialize>::deserialize(deserializer)?;
1266 if let Ok(bytes) = hex::decode(&s) {
1267 if let Ok(asset_name) = AssetName::new(bytes) {
1268 return Ok(asset_name);
1269 }
1270 }
1271 Err(serde::de::Error::invalid_value(
1272 serde::de::Unexpected::Str(&s),
1273 &"AssetName as hex string e.g. F8AB28C2",
1274 ))
1275 }
1276}
1277
1278impl JsonSchema for AssetName {
1279 fn schema_name() -> String {
1280 String::from("AssetName")
1281 }
1282 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1283 String::json_schema(gen)
1284 }
1285 fn is_referenceable() -> bool {
1286 String::is_referenceable()
1287 }
1288}
1289
1290#[wasm_bindgen]
1291#[derive(
1292 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
1293)]
1294pub struct AssetNames(Vec<AssetName>);
1295
1296impl_to_from!(AssetNames);
1297
1298#[wasm_bindgen]
1299impl AssetNames {
1300 pub fn new() -> Self {
1301 Self(Vec::new())
1302 }
1303
1304 pub fn len(&self) -> usize {
1305 self.0.len()
1306 }
1307
1308 pub fn get(&self, index: usize) -> AssetName {
1309 self.0[index].clone()
1310 }
1311
1312 pub fn add(&mut self, elem: &AssetName) {
1313 self.0.push(elem.clone());
1314 }
1315}
1316
1317pub type PolicyID = ScriptHash;
1318pub type PolicyIDs = ScriptHashes;
1319
1320#[wasm_bindgen]
1321#[derive(
1322 Clone,
1323 Debug,
1324 Default,
1325 Eq,
1326 Ord,
1327 PartialEq,
1328 PartialOrd,
1329 serde::Serialize,
1330 serde::Deserialize,
1331 JsonSchema,
1332)]
1333pub struct Assets(pub(crate) std::collections::BTreeMap<AssetName, BigNum>);
1334
1335impl_to_from!(Assets);
1336
1337#[wasm_bindgen]
1338impl Assets {
1339 pub fn new() -> Self {
1340 Self(std::collections::BTreeMap::new())
1341 }
1342
1343 pub fn len(&self) -> usize {
1344 self.0.len()
1345 }
1346
1347 pub fn insert(&mut self, key: &AssetName, value: &BigNum) -> Option<BigNum> {
1348 self.0.insert(key.clone(), value.clone())
1349 }
1350
1351 pub fn get(&self, key: &AssetName) -> Option<BigNum> {
1352 self.0.get(key).map(|v| v.clone())
1353 }
1354
1355 pub fn keys(&self) -> AssetNames {
1356 AssetNames(
1357 self.0
1358 .iter()
1359 .map(|(k, _v)| k.clone())
1360 .collect::<Vec<AssetName>>(),
1361 )
1362 }
1363}
1364
1365#[wasm_bindgen]
1366#[derive(Clone, Debug, Eq, Ord, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)]
1367pub struct MultiAsset(pub(crate) std::collections::BTreeMap<PolicyID, Assets>);
1368
1369impl_to_from!(MultiAsset);
1370
1371#[wasm_bindgen]
1372impl MultiAsset {
1373 pub fn new() -> Self {
1374 Self(std::collections::BTreeMap::new())
1375 }
1376
1377 pub fn len(&self) -> usize {
1379 self.0.len()
1380 }
1381
1382 pub fn insert(&mut self, policy_id: &PolicyID, assets: &Assets) -> Option<Assets> {
1384 self.0.insert(policy_id.clone(), assets.clone())
1385 }
1386
1387 pub fn get(&self, policy_id: &PolicyID) -> Option<Assets> {
1389 self.0.get(policy_id).map(|v| v.clone())
1390 }
1391
1392 pub fn set_asset(
1395 &mut self,
1396 policy_id: &PolicyID,
1397 asset_name: &AssetName,
1398 value: &BigNum,
1399 ) -> Option<BigNum> {
1400 self.0
1401 .entry(policy_id.clone())
1402 .or_default()
1403 .insert(asset_name, value)
1404 }
1405
1406 pub fn get_asset(&self, policy_id: &PolicyID, asset_name: &AssetName) -> BigNum {
1409 (|| self.0.get(policy_id)?.get(asset_name))().unwrap_or(BigNum::zero())
1410 }
1411
1412 pub fn keys(&self) -> PolicyIDs {
1414 ScriptHashes(
1415 self.0
1416 .iter()
1417 .map(|(k, _v)| k.clone())
1418 .collect::<Vec<PolicyID>>(),
1419 )
1420 }
1421
1422 pub fn sub(&self, rhs_ma: &MultiAsset) -> MultiAsset {
1425 let mut lhs_ma = self.clone();
1426 for (policy, assets) in &rhs_ma.0 {
1427 for (asset_name, amount) in &assets.0 {
1428 match lhs_ma.0.get_mut(policy) {
1429 Some(assets) => match assets.0.get_mut(asset_name) {
1430 Some(current) => match current.checked_sub(&amount) {
1431 Ok(new) => match new.compare(&BigNum(0)) {
1432 0 => {
1433 assets.0.remove(asset_name);
1434 match assets.0.len() {
1435 0 => {
1436 lhs_ma.0.remove(policy);
1437 }
1438 _ => {}
1439 }
1440 }
1441 _ => *current = new,
1442 },
1443 Err(_) => {
1444 assets.0.remove(asset_name);
1445 match assets.0.len() {
1446 0 => {
1447 lhs_ma.0.remove(policy);
1448 }
1449 _ => {}
1450 }
1451 }
1452 },
1453 None => {
1454 }
1456 },
1457 None => {
1458 }
1460 }
1461 }
1462 }
1463 lhs_ma
1464 }
1465
1466 pub(crate) fn reduce_empty_to_none(&self) -> Option<&MultiAsset> {
1467 for (_policy, assets) in self.0.iter() {
1468 if assets.len() > 0 {
1469 return Some(self);
1470 }
1471 }
1472
1473 None
1474 }
1475}
1476
1477impl PartialOrd for MultiAsset {
1484 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1485 fn amount_or_zero(ma: &MultiAsset, pid: &PolicyID, aname: &AssetName) -> Coin {
1486 ma.get(&pid)
1487 .and_then(|assets| assets.get(aname))
1488 .unwrap_or(BigNum(0u64)) }
1490
1491 fn is_all_zeros(lhs: &MultiAsset, rhs: &MultiAsset) -> bool {
1493 for (pid, assets) in lhs.0.iter() {
1494 for (aname, amount) in assets.0.iter() {
1495 match amount
1496 .clamped_sub(&amount_or_zero(&rhs, pid, aname))
1497 .cmp(&BigNum::zero())
1498 {
1499 std::cmp::Ordering::Equal => (),
1500 _ => return false,
1501 }
1502 }
1503 }
1504 true
1505 }
1506
1507 match (is_all_zeros(self, other), is_all_zeros(other, self)) {
1508 (true, true) => Some(std::cmp::Ordering::Equal),
1509 (true, false) => Some(std::cmp::Ordering::Less),
1510 (false, true) => Some(std::cmp::Ordering::Greater),
1511 (false, false) => None,
1512 }
1513 }
1514}
1515
1516#[wasm_bindgen]
1517#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema)]
1518pub struct MintsAssets(Vec<MintAssets>);
1519
1520to_from_json!(MintsAssets);
1521
1522#[wasm_bindgen]
1523impl MintsAssets {
1524 pub fn new() -> Self {
1525 Self(Vec::new())
1526 }
1527
1528 pub fn add(&mut self, mint_assets: &MintAssets) {
1529 self.0.push(mint_assets.clone())
1530 }
1531
1532 pub fn get(&self, index: usize) -> Option<MintAssets> {
1533 self.0.get(index).map(|v| v.clone())
1534 }
1535
1536 pub fn len(&self) -> usize {
1537 self.0.len()
1538 }
1539}
1540
1541#[wasm_bindgen]
1542#[derive(
1543 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
1544)]
1545pub struct MintAssets(std::collections::BTreeMap<AssetName, Int>);
1546
1547#[wasm_bindgen]
1548impl MintAssets {
1549 pub fn new() -> Self {
1550 Self(std::collections::BTreeMap::new())
1551 }
1552
1553 pub fn new_from_entry(key: &AssetName, value: &Int) -> Result<MintAssets, JsError> {
1554 if value.0 == 0 {
1555 return Err(JsError::from_str("MintAssets cannot be created with 0 value"));
1556 }
1557 let mut ma = MintAssets::new();
1558 ma.insert(key, value)?;
1559 Ok(ma)
1560 }
1561
1562 pub fn len(&self) -> usize {
1563 self.0.len()
1564 }
1565
1566 pub fn insert(&mut self, key: &AssetName, value: &Int) -> Result<Option<Int>, JsError> {
1567 if value.0 == 0 {
1568 return Err(JsError::from_str("MintAssets cannot be created with 0 value"));
1569 }
1570 Ok(self.0.insert(key.clone(), value.clone()))
1571 }
1572
1573 pub(crate) fn insert_unchecked(&mut self, key: &AssetName, value: Int) -> Option<Int> {
1574 self.0.insert(key.clone(), value)
1575 }
1576
1577 pub fn get(&self, key: &AssetName) -> Option<Int> {
1578 self.0.get(key).map(|v| v.clone())
1579 }
1580
1581 pub fn keys(&self) -> AssetNames {
1582 AssetNames(
1583 self.0
1584 .iter()
1585 .map(|(k, _v)| k.clone())
1586 .collect::<Vec<AssetName>>(),
1587 )
1588 }
1589}
1590
1591#[wasm_bindgen]
1592#[derive(
1593 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
1594)]
1595pub struct Mint(Vec<(PolicyID, MintAssets)>);
1596
1597impl_to_from!(Mint);
1598
1599impl NoneOrEmpty for Mint {
1600 fn is_none_or_empty(&self) -> bool {
1601 self.0.is_empty()
1602 }
1603}
1604
1605#[wasm_bindgen]
1606impl Mint {
1607 pub fn new() -> Self {
1608 Self(Vec::new())
1609 }
1610
1611 pub fn new_from_entry(key: &PolicyID, value: &MintAssets) -> Self {
1612 let mut m = Mint::new();
1613 m.insert(key, value);
1614 m
1615 }
1616
1617 pub fn len(&self) -> usize {
1618 self.0.len()
1619 }
1620
1621 pub fn insert(&mut self, key: &PolicyID, value: &MintAssets) -> Option<MintAssets> {
1623 self.0.push((key.clone(), value.clone()));
1624 None
1625 }
1626
1627 pub fn get(&self, key: &PolicyID) -> Option<MintsAssets> {
1628 let mints: Vec<MintAssets> = self
1629 .0
1630 .iter()
1631 .filter(|(k, _)| k.eq(key))
1632 .map(|(_k, v)| v.clone())
1633 .collect();
1634 if mints.is_empty() {
1635 None
1636 } else {
1637 Some(MintsAssets(mints))
1638 }
1639 }
1640
1641 pub fn keys(&self) -> PolicyIDs {
1642 ScriptHashes(
1643 self.0
1644 .iter()
1645 .map(|(k, _)| k.clone())
1646 .collect::<Vec<ScriptHash>>(),
1647 )
1648 }
1649
1650 fn as_multiasset(&self, is_positive: bool) -> MultiAsset {
1651 self.0
1652 .iter()
1653 .fold(MultiAsset::new(), |res, e: &(PolicyID, MintAssets)| {
1654 let assets: Assets = (e.1).0.iter().fold(Assets::new(), |res, e| {
1655 let mut assets = res;
1656 if e.1.is_positive() == is_positive {
1657 let amount = match is_positive {
1658 true => e.1.as_positive(),
1659 false => e.1.as_negative(),
1660 };
1661 assets.insert(&e.0, &amount.unwrap());
1662 }
1663 assets
1664 });
1665 let mut ma = res;
1666 if !assets.0.is_empty() {
1667 ma.insert(&e.0, &assets);
1668 }
1669 ma
1670 })
1671 }
1672
1673 pub fn as_positive_multiasset(&self) -> MultiAsset {
1675 self.as_multiasset(true)
1676 }
1677
1678 pub fn as_negative_multiasset(&self) -> MultiAsset {
1680 self.as_multiasset(false)
1681 }
1682}
1683
1684#[wasm_bindgen]
1685#[derive(
1686 Clone,
1687 Copy,
1688 Debug,
1689 Eq,
1690 Ord,
1691 PartialEq,
1692 PartialOrd,
1693 serde::Serialize,
1694 serde::Deserialize,
1695 JsonSchema,
1696)]
1697pub enum NetworkIdKind {
1698 Testnet,
1699 Mainnet,
1700}
1701
1702#[wasm_bindgen]
1703#[derive(
1704 Clone,
1705 Copy,
1706 Debug,
1707 Eq,
1708 Ord,
1709 PartialEq,
1710 PartialOrd,
1711 serde::Serialize,
1712 serde::Deserialize,
1713 JsonSchema,
1714)]
1715pub struct NetworkId(NetworkIdKind);
1716
1717impl_to_from!(NetworkId);
1718
1719#[wasm_bindgen]
1720impl NetworkId {
1721 pub fn testnet() -> Self {
1722 Self(NetworkIdKind::Testnet)
1723 }
1724
1725 pub fn mainnet() -> Self {
1726 Self(NetworkIdKind::Mainnet)
1727 }
1728
1729 pub fn kind(&self) -> NetworkIdKind {
1730 self.0
1731 }
1732}
1733
1734impl From<&NativeScript> for Ed25519KeyHashes {
1735 fn from(script: &NativeScript) -> Self {
1736 match &script.0 {
1737 NativeScriptEnum::ScriptPubkey(spk) => {
1738 let mut set = Ed25519KeyHashes::new();
1739 set.add_move(spk.addr_keyhash());
1740 set
1741 }
1742 NativeScriptEnum::ScriptAll(all) => Ed25519KeyHashes::from(&all.native_scripts),
1743 NativeScriptEnum::ScriptAny(any) => Ed25519KeyHashes::from(&any.native_scripts),
1744 NativeScriptEnum::ScriptNOfK(ofk) => Ed25519KeyHashes::from(&ofk.native_scripts),
1745 _ => Ed25519KeyHashes::new(),
1746 }
1747 }
1748}