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 #[allow(dead_code)]
845 pub(crate) fn as_vec(&self) -> Vec<(&RewardAddress, &Coin)> {
846 self.0.iter().collect()
847 }
848}
849
850impl serde::Serialize for Withdrawals {
851 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
852 where
853 S: serde::Serializer,
854 {
855 let map = self.0.iter().collect::<std::collections::BTreeMap<_, _>>();
856 map.serialize(serializer)
857 }
858}
859
860impl<'de> serde::de::Deserialize<'de> for Withdrawals {
861 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
862 where
863 D: serde::de::Deserializer<'de>,
864 {
865 let map = <std::collections::BTreeMap<_, _> as serde::de::Deserialize>::deserialize(
866 deserializer,
867 )?;
868 Ok(Self(map.into_iter().collect()))
869 }
870}
871
872impl JsonSchema for Withdrawals {
873 fn schema_name() -> String {
874 String::from("Withdrawals")
875 }
876 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
877 std::collections::BTreeMap::<RewardAddress, Coin>::json_schema(gen)
878 }
879 fn is_referenceable() -> bool {
880 std::collections::BTreeMap::<RewardAddress, Coin>::is_referenceable()
881 }
882}
883
884#[derive(
885 Debug, Clone, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
886)]
887pub enum DataOption {
888 DataHash(DataHash),
889 Data(PlutusData),
890}
891
892#[wasm_bindgen]
893#[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)]
894pub struct OutputDatum(pub(crate) DataOption);
895
896#[wasm_bindgen]
897impl OutputDatum {
898 pub fn new_data_hash(data_hash: &DataHash) -> Self {
899 Self(DataOption::DataHash(data_hash.clone()))
900 }
901
902 pub fn new_data(data: &PlutusData) -> Self {
903 Self(DataOption::Data(data.clone()))
904 }
905
906 pub fn data_hash(&self) -> Option<DataHash> {
907 match &self.0 {
908 DataOption::DataHash(data_hash) => Some(data_hash.clone()),
909 _ => None,
910 }
911 }
912
913 pub fn data(&self) -> Option<PlutusData> {
914 match &self.0 {
915 DataOption::Data(data) => Some(data.clone()),
916 _ => None,
917 }
918 }
919}
920
921#[wasm_bindgen]
926#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
927pub enum ScriptHashNamespace {
928 NativeScript = 0,
929 PlutusScript = 1,
930 PlutusScriptV2 = 2,
931 PlutusScriptV3 = 3,
932}
933
934#[wasm_bindgen]
935#[derive(
936 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
937)]
938pub struct Update {
939 proposed_protocol_parameter_updates: ProposedProtocolParameterUpdates,
940 epoch: Epoch,
941}
942
943impl_to_from!(Update);
944
945#[wasm_bindgen]
946impl Update {
947 pub fn proposed_protocol_parameter_updates(&self) -> ProposedProtocolParameterUpdates {
948 self.proposed_protocol_parameter_updates.clone()
949 }
950
951 pub fn epoch(&self) -> Epoch {
952 self.epoch.clone()
953 }
954
955 pub fn new(
956 proposed_protocol_parameter_updates: &ProposedProtocolParameterUpdates,
957 epoch: Epoch,
958 ) -> Self {
959 Self {
960 proposed_protocol_parameter_updates: proposed_protocol_parameter_updates.clone(),
961 epoch: epoch.clone(),
962 }
963 }
964}
965
966#[wasm_bindgen]
967#[derive(
968 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
969)]
970pub struct GenesisHashes(Vec<GenesisHash>);
971
972impl_to_from!(GenesisHashes);
973
974#[wasm_bindgen]
975impl GenesisHashes {
976 pub fn new() -> Self {
977 Self(Vec::new())
978 }
979
980 pub fn len(&self) -> usize {
981 self.0.len()
982 }
983
984 pub fn get(&self, index: usize) -> GenesisHash {
985 self.0[index].clone()
986 }
987
988 pub fn add(&mut self, elem: &GenesisHash) {
989 self.0.push(elem.clone());
990 }
991}
992
993#[wasm_bindgen]
994#[derive(
995 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
996)]
997pub struct ScriptHashes(pub(crate) Vec<ScriptHash>);
998
999impl_to_from!(ScriptHashes);
1000
1001#[wasm_bindgen]
1002impl ScriptHashes {
1003 pub fn new() -> Self {
1004 Self(Vec::new())
1005 }
1006
1007 pub fn len(&self) -> usize {
1008 self.0.len()
1009 }
1010
1011 pub fn get(&self, index: usize) -> ScriptHash {
1012 self.0[index].clone()
1013 }
1014
1015 pub fn add(&mut self, elem: &ScriptHash) {
1016 self.0.push(elem.clone());
1017 }
1018}
1019
1020#[wasm_bindgen]
1021#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1022pub struct ProposedProtocolParameterUpdates(
1023 LinkedHashMap<GenesisHash, ProtocolParamUpdate>,
1024);
1025
1026impl serde::Serialize for ProposedProtocolParameterUpdates {
1027 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1028 where
1029 S: serde::Serializer,
1030 {
1031 let map = self.0.iter().collect::<std::collections::BTreeMap<_, _>>();
1032 map.serialize(serializer)
1033 }
1034}
1035
1036impl<'de> serde::de::Deserialize<'de> for ProposedProtocolParameterUpdates {
1037 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1038 where
1039 D: serde::de::Deserializer<'de>,
1040 {
1041 let map = <std::collections::BTreeMap<_, _> as serde::de::Deserialize>::deserialize(
1042 deserializer,
1043 )?;
1044 Ok(Self(map.into_iter().collect()))
1045 }
1046}
1047
1048impl JsonSchema for ProposedProtocolParameterUpdates {
1049 fn schema_name() -> String {
1050 String::from("ProposedProtocolParameterUpdates")
1051 }
1052 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1053 std::collections::BTreeMap::<GenesisHash, ProtocolParamUpdate>::json_schema(gen)
1054 }
1055 fn is_referenceable() -> bool {
1056 std::collections::BTreeMap::<GenesisHash, ProtocolParamUpdate>::is_referenceable()
1057 }
1058}
1059
1060impl_to_from!(ProposedProtocolParameterUpdates);
1061
1062#[wasm_bindgen]
1063impl ProposedProtocolParameterUpdates {
1064 pub fn new() -> Self {
1065 Self(LinkedHashMap::new())
1066 }
1067
1068 pub fn len(&self) -> usize {
1069 self.0.len()
1070 }
1071
1072 pub fn insert(
1073 &mut self,
1074 key: &GenesisHash,
1075 value: &ProtocolParamUpdate,
1076 ) -> Option<ProtocolParamUpdate> {
1077 self.0.insert(key.clone(), value.clone())
1078 }
1079
1080 pub fn get(&self, key: &GenesisHash) -> Option<ProtocolParamUpdate> {
1081 self.0.get(key).map(|v| v.clone())
1082 }
1083
1084 pub fn keys(&self) -> GenesisHashes {
1085 GenesisHashes(
1086 self.0
1087 .iter()
1088 .map(|(k, _v)| k.clone())
1089 .collect::<Vec<GenesisHash>>(),
1090 )
1091 }
1092}
1093
1094#[wasm_bindgen]
1095#[derive(
1096 Clone,
1097 Debug,
1098 Hash,
1099 Eq,
1100 Ord,
1101 PartialEq,
1102 PartialOrd,
1103 serde::Serialize,
1104 serde::Deserialize,
1105 JsonSchema,
1106)]
1107pub struct ProtocolVersion {
1108 major: u32,
1109 minor: u32,
1110}
1111
1112impl_to_from!(ProtocolVersion);
1113
1114#[wasm_bindgen]
1115impl ProtocolVersion {
1116 pub fn major(&self) -> u32 {
1117 self.major
1118 }
1119
1120 pub fn minor(&self) -> u32 {
1121 self.minor
1122 }
1123
1124 pub fn new(major: u32, minor: u32) -> Self {
1125 Self { major, minor }
1126 }
1127}
1128
1129#[wasm_bindgen]
1130#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1131pub struct AuxiliaryDataSet(LinkedHashMap<TransactionIndex, AuxiliaryData>);
1132
1133#[wasm_bindgen]
1134impl AuxiliaryDataSet {
1135 pub fn new() -> Self {
1136 Self(LinkedHashMap::new())
1137 }
1138
1139 pub fn len(&self) -> usize {
1140 self.0.len()
1141 }
1142
1143 pub fn insert(
1144 &mut self,
1145 tx_index: TransactionIndex,
1146 data: &AuxiliaryData,
1147 ) -> Option<AuxiliaryData> {
1148 self.0.insert(tx_index, data.clone())
1149 }
1150
1151 pub fn get(&self, tx_index: TransactionIndex) -> Option<AuxiliaryData> {
1152 self.0.get(&tx_index).map(|v| v.clone())
1153 }
1154
1155 pub fn indices(&self) -> TransactionIndexes {
1156 self.0
1157 .iter()
1158 .map(|(k, _v)| k.clone())
1159 .collect::<Vec<TransactionIndex>>()
1160 }
1161}
1162
1163impl serde::Serialize for AuxiliaryDataSet {
1164 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1165 where
1166 S: serde::Serializer,
1167 {
1168 let map = self.0.iter().collect::<std::collections::BTreeMap<_, _>>();
1169 map.serialize(serializer)
1170 }
1171}
1172
1173impl<'de> serde::de::Deserialize<'de> for AuxiliaryDataSet {
1174 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1175 where
1176 D: serde::de::Deserializer<'de>,
1177 {
1178 let map = <std::collections::BTreeMap<_, _> as serde::de::Deserialize>::deserialize(
1179 deserializer,
1180 )?;
1181 Ok(Self(map.into_iter().collect()))
1182 }
1183}
1184
1185impl JsonSchema for AuxiliaryDataSet {
1186 fn schema_name() -> String {
1187 String::from("AuxiliaryDataSet")
1188 }
1189 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1190 std::collections::BTreeMap::<TransactionIndex, AuxiliaryData>::json_schema(gen)
1191 }
1192 fn is_referenceable() -> bool {
1193 std::collections::BTreeMap::<TransactionIndex, AuxiliaryData>::is_referenceable()
1194 }
1195}
1196
1197#[wasm_bindgen]
1198#[derive(Clone, Debug, Eq, PartialEq, Hash)]
1199pub struct AssetName(Vec<u8>);
1200
1201impl Display for AssetName {
1202 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1203 write!(f, "{}", hex::encode(&self.0))
1204 }
1205}
1206
1207impl Ord for AssetName {
1208 fn cmp(&self, other: &Self) -> Ordering {
1209 return match self.0.len().cmp(&other.0.len()) {
1212 Ordering::Equal => self.0.cmp(&other.0),
1213 x => x,
1214 };
1215 }
1216}
1217
1218impl PartialOrd for AssetName {
1219 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1220 Some(self.cmp(other))
1221 }
1222}
1223
1224impl_to_from!(AssetName);
1225
1226#[wasm_bindgen]
1227impl AssetName {
1228 pub fn new(name: Vec<u8>) -> Result<AssetName, JsError> {
1229 Self::new_impl(name).map_err(|e| JsError::from_str(&e.to_string()))
1230 }
1231
1232 pub(crate) fn new_impl(name: Vec<u8>) -> Result<AssetName, DeserializeError> {
1233 if name.len() <= 32 {
1234 Ok(Self(name))
1235 } else {
1236 Err(DeserializeError::new(
1237 "AssetName",
1238 DeserializeFailure::OutOfRange {
1239 min: 0,
1240 max: 32,
1241 found: name.len(),
1242 },
1243 ))
1244 }
1245 }
1246
1247 pub fn name(&self) -> Vec<u8> {
1248 self.0.clone()
1249 }
1250}
1251
1252impl serde::Serialize for AssetName {
1253 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1254 where
1255 S: serde::Serializer,
1256 {
1257 serializer.serialize_str(&hex::encode(&self.0))
1258 }
1259}
1260
1261impl<'de> serde::de::Deserialize<'de> for AssetName {
1262 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1263 where
1264 D: serde::de::Deserializer<'de>,
1265 {
1266 let s = <String as serde::de::Deserialize>::deserialize(deserializer)?;
1267 if let Ok(bytes) = hex::decode(&s) {
1268 if let Ok(asset_name) = AssetName::new(bytes) {
1269 return Ok(asset_name);
1270 }
1271 }
1272 Err(serde::de::Error::invalid_value(
1273 serde::de::Unexpected::Str(&s),
1274 &"AssetName as hex string e.g. F8AB28C2",
1275 ))
1276 }
1277}
1278
1279impl JsonSchema for AssetName {
1280 fn schema_name() -> String {
1281 String::from("AssetName")
1282 }
1283 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1284 String::json_schema(gen)
1285 }
1286 fn is_referenceable() -> bool {
1287 String::is_referenceable()
1288 }
1289}
1290
1291#[wasm_bindgen]
1292#[derive(
1293 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
1294)]
1295pub struct AssetNames(Vec<AssetName>);
1296
1297impl_to_from!(AssetNames);
1298
1299#[wasm_bindgen]
1300impl AssetNames {
1301 pub fn new() -> Self {
1302 Self(Vec::new())
1303 }
1304
1305 pub fn len(&self) -> usize {
1306 self.0.len()
1307 }
1308
1309 pub fn get(&self, index: usize) -> AssetName {
1310 self.0[index].clone()
1311 }
1312
1313 pub fn add(&mut self, elem: &AssetName) {
1314 self.0.push(elem.clone());
1315 }
1316}
1317
1318pub type PolicyID = ScriptHash;
1319pub type PolicyIDs = ScriptHashes;
1320
1321#[wasm_bindgen]
1322#[derive(
1323 Clone,
1324 Debug,
1325 Default,
1326 Eq,
1327 Ord,
1328 PartialEq,
1329 PartialOrd,
1330 serde::Serialize,
1331 serde::Deserialize,
1332 JsonSchema,
1333)]
1334pub struct Assets(pub(crate) std::collections::BTreeMap<AssetName, BigNum>);
1335
1336impl_to_from!(Assets);
1337
1338#[wasm_bindgen]
1339impl Assets {
1340 pub fn new() -> Self {
1341 Self(std::collections::BTreeMap::new())
1342 }
1343
1344 pub fn len(&self) -> usize {
1345 self.0.len()
1346 }
1347
1348 pub fn insert(&mut self, key: &AssetName, value: &BigNum) -> Option<BigNum> {
1349 self.0.insert(key.clone(), value.clone())
1350 }
1351
1352 pub fn get(&self, key: &AssetName) -> Option<BigNum> {
1353 self.0.get(key).map(|v| v.clone())
1354 }
1355
1356 pub fn keys(&self) -> AssetNames {
1357 AssetNames(
1358 self.0
1359 .iter()
1360 .map(|(k, _v)| k.clone())
1361 .collect::<Vec<AssetName>>(),
1362 )
1363 }
1364}
1365
1366#[wasm_bindgen]
1367#[derive(Clone, Debug, Eq, Ord, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)]
1368pub struct MultiAsset(pub(crate) std::collections::BTreeMap<PolicyID, Assets>);
1369
1370impl_to_from!(MultiAsset);
1371
1372#[wasm_bindgen]
1373impl MultiAsset {
1374 pub fn new() -> Self {
1375 Self(std::collections::BTreeMap::new())
1376 }
1377
1378 pub fn len(&self) -> usize {
1380 self.0.len()
1381 }
1382
1383 pub fn insert(&mut self, policy_id: &PolicyID, assets: &Assets) -> Option<Assets> {
1385 self.0.insert(policy_id.clone(), assets.clone())
1386 }
1387
1388 pub fn get(&self, policy_id: &PolicyID) -> Option<Assets> {
1390 self.0.get(policy_id).map(|v| v.clone())
1391 }
1392
1393 pub fn set_asset(
1396 &mut self,
1397 policy_id: &PolicyID,
1398 asset_name: &AssetName,
1399 value: &BigNum,
1400 ) -> Option<BigNum> {
1401 self.0
1402 .entry(policy_id.clone())
1403 .or_default()
1404 .insert(asset_name, value)
1405 }
1406
1407 pub fn get_asset(&self, policy_id: &PolicyID, asset_name: &AssetName) -> BigNum {
1410 (|| self.0.get(policy_id)?.get(asset_name))().unwrap_or(BigNum::zero())
1411 }
1412
1413 pub fn keys(&self) -> PolicyIDs {
1415 ScriptHashes(
1416 self.0
1417 .iter()
1418 .map(|(k, _v)| k.clone())
1419 .collect::<Vec<PolicyID>>(),
1420 )
1421 }
1422
1423 pub fn sub(&self, rhs_ma: &MultiAsset) -> MultiAsset {
1426 let mut lhs_ma = self.clone();
1427 for (policy, assets) in &rhs_ma.0 {
1428 for (asset_name, amount) in &assets.0 {
1429 match lhs_ma.0.get_mut(policy) {
1430 Some(assets) => match assets.0.get_mut(asset_name) {
1431 Some(current) => match current.checked_sub(&amount) {
1432 Ok(new) => match new.compare(&BigNum(0)) {
1433 0 => {
1434 assets.0.remove(asset_name);
1435 match assets.0.len() {
1436 0 => {
1437 lhs_ma.0.remove(policy);
1438 }
1439 _ => {}
1440 }
1441 }
1442 _ => *current = new,
1443 },
1444 Err(_) => {
1445 assets.0.remove(asset_name);
1446 match assets.0.len() {
1447 0 => {
1448 lhs_ma.0.remove(policy);
1449 }
1450 _ => {}
1451 }
1452 }
1453 },
1454 None => {
1455 }
1457 },
1458 None => {
1459 }
1461 }
1462 }
1463 }
1464 lhs_ma
1465 }
1466
1467 pub(crate) fn reduce_empty_to_none(&self) -> Option<&MultiAsset> {
1468 for (_policy, assets) in self.0.iter() {
1469 if assets.len() > 0 {
1470 return Some(self);
1471 }
1472 }
1473
1474 None
1475 }
1476}
1477
1478impl PartialOrd for MultiAsset {
1485 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1486 fn amount_or_zero(ma: &MultiAsset, pid: &PolicyID, aname: &AssetName) -> Coin {
1487 ma.get(&pid)
1488 .and_then(|assets| assets.get(aname))
1489 .unwrap_or(BigNum(0u64)) }
1491
1492 fn is_all_zeros(lhs: &MultiAsset, rhs: &MultiAsset) -> bool {
1494 for (pid, assets) in lhs.0.iter() {
1495 for (aname, amount) in assets.0.iter() {
1496 match amount
1497 .clamped_sub(&amount_or_zero(&rhs, pid, aname))
1498 .cmp(&BigNum::zero())
1499 {
1500 std::cmp::Ordering::Equal => (),
1501 _ => return false,
1502 }
1503 }
1504 }
1505 true
1506 }
1507
1508 match (is_all_zeros(self, other), is_all_zeros(other, self)) {
1509 (true, true) => Some(std::cmp::Ordering::Equal),
1510 (true, false) => Some(std::cmp::Ordering::Less),
1511 (false, true) => Some(std::cmp::Ordering::Greater),
1512 (false, false) => None,
1513 }
1514 }
1515}
1516
1517#[wasm_bindgen]
1518#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema)]
1519pub struct MintsAssets(Vec<MintAssets>);
1520
1521to_from_json!(MintsAssets);
1522
1523#[wasm_bindgen]
1524impl MintsAssets {
1525 pub fn new() -> Self {
1526 Self(Vec::new())
1527 }
1528
1529 pub fn add(&mut self, mint_assets: &MintAssets) {
1530 self.0.push(mint_assets.clone())
1531 }
1532
1533 pub fn get(&self, index: usize) -> Option<MintAssets> {
1534 self.0.get(index).map(|v| v.clone())
1535 }
1536
1537 pub fn len(&self) -> usize {
1538 self.0.len()
1539 }
1540}
1541
1542#[wasm_bindgen]
1543#[derive(
1544 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
1545)]
1546pub struct MintAssets(std::collections::BTreeMap<AssetName, Int>);
1547
1548#[wasm_bindgen]
1549impl MintAssets {
1550 pub fn new() -> Self {
1551 Self(std::collections::BTreeMap::new())
1552 }
1553
1554 pub fn new_from_entry(key: &AssetName, value: &Int) -> Result<MintAssets, JsError> {
1555 if value.0 == 0 {
1556 return Err(JsError::from_str("MintAssets cannot be created with 0 value"));
1557 }
1558 let mut ma = MintAssets::new();
1559 ma.insert(key, value)?;
1560 Ok(ma)
1561 }
1562
1563 pub fn len(&self) -> usize {
1564 self.0.len()
1565 }
1566
1567 pub fn insert(&mut self, key: &AssetName, value: &Int) -> Result<Option<Int>, JsError> {
1568 if value.0 == 0 {
1569 return Err(JsError::from_str("MintAssets cannot be created with 0 value"));
1570 }
1571 Ok(self.0.insert(key.clone(), value.clone()))
1572 }
1573
1574 pub(crate) fn insert_unchecked(&mut self, key: &AssetName, value: Int) -> Option<Int> {
1575 self.0.insert(key.clone(), value)
1576 }
1577
1578 pub fn get(&self, key: &AssetName) -> Option<Int> {
1579 self.0.get(key).map(|v| v.clone())
1580 }
1581
1582 pub fn keys(&self) -> AssetNames {
1583 AssetNames(
1584 self.0
1585 .iter()
1586 .map(|(k, _v)| k.clone())
1587 .collect::<Vec<AssetName>>(),
1588 )
1589 }
1590}
1591
1592#[wasm_bindgen]
1593#[derive(
1594 Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema,
1595)]
1596pub struct Mint(Vec<(PolicyID, MintAssets)>);
1597
1598impl_to_from!(Mint);
1599
1600impl NoneOrEmpty for Mint {
1601 fn is_none_or_empty(&self) -> bool {
1602 self.0.is_empty()
1603 }
1604}
1605
1606#[wasm_bindgen]
1607impl Mint {
1608 pub fn new() -> Self {
1609 Self(Vec::new())
1610 }
1611
1612 pub fn new_from_entry(key: &PolicyID, value: &MintAssets) -> Self {
1613 let mut m = Mint::new();
1614 m.insert(key, value);
1615 m
1616 }
1617
1618 pub fn len(&self) -> usize {
1619 self.0.len()
1620 }
1621
1622 pub fn insert(&mut self, key: &PolicyID, value: &MintAssets) -> Option<MintAssets> {
1624 self.0.push((key.clone(), value.clone()));
1625 None
1626 }
1627
1628 pub fn get(&self, key: &PolicyID) -> Option<MintsAssets> {
1629 let mints: Vec<MintAssets> = self
1630 .0
1631 .iter()
1632 .filter(|(k, _)| k.eq(key))
1633 .map(|(_k, v)| v.clone())
1634 .collect();
1635 if mints.is_empty() {
1636 None
1637 } else {
1638 Some(MintsAssets(mints))
1639 }
1640 }
1641
1642 pub fn keys(&self) -> PolicyIDs {
1643 ScriptHashes(
1644 self.0
1645 .iter()
1646 .map(|(k, _)| k.clone())
1647 .collect::<Vec<ScriptHash>>(),
1648 )
1649 }
1650
1651 fn as_multiasset(&self, is_positive: bool) -> MultiAsset {
1652 self.0
1653 .iter()
1654 .fold(MultiAsset::new(), |res, e: &(PolicyID, MintAssets)| {
1655 let assets: Assets = (e.1).0.iter().fold(Assets::new(), |res, e| {
1656 let mut assets = res;
1657 if e.1.is_positive() == is_positive {
1658 let amount = match is_positive {
1659 true => e.1.as_positive(),
1660 false => e.1.as_negative(),
1661 };
1662 assets.insert(&e.0, &amount.unwrap());
1663 }
1664 assets
1665 });
1666 let mut ma = res;
1667 if !assets.0.is_empty() {
1668 ma.insert(&e.0, &assets);
1669 }
1670 ma
1671 })
1672 }
1673
1674 pub fn as_positive_multiasset(&self) -> MultiAsset {
1676 self.as_multiasset(true)
1677 }
1678
1679 pub fn as_negative_multiasset(&self) -> MultiAsset {
1681 self.as_multiasset(false)
1682 }
1683}
1684
1685#[wasm_bindgen]
1686#[derive(
1687 Clone,
1688 Copy,
1689 Debug,
1690 Eq,
1691 Ord,
1692 PartialEq,
1693 PartialOrd,
1694 serde::Serialize,
1695 serde::Deserialize,
1696 JsonSchema,
1697)]
1698pub enum NetworkIdKind {
1699 Testnet,
1700 Mainnet,
1701}
1702
1703#[wasm_bindgen]
1704#[derive(
1705 Clone,
1706 Copy,
1707 Debug,
1708 Eq,
1709 Ord,
1710 PartialEq,
1711 PartialOrd,
1712 serde::Serialize,
1713 serde::Deserialize,
1714 JsonSchema,
1715)]
1716pub struct NetworkId(NetworkIdKind);
1717
1718impl_to_from!(NetworkId);
1719
1720#[wasm_bindgen]
1721impl NetworkId {
1722 pub fn testnet() -> Self {
1723 Self(NetworkIdKind::Testnet)
1724 }
1725
1726 pub fn mainnet() -> Self {
1727 Self(NetworkIdKind::Mainnet)
1728 }
1729
1730 pub fn kind(&self) -> NetworkIdKind {
1731 self.0
1732 }
1733}
1734
1735impl From<&NativeScript> for Ed25519KeyHashes {
1736 fn from(script: &NativeScript) -> Self {
1737 match &script.0 {
1738 NativeScriptEnum::ScriptPubkey(spk) => {
1739 let mut set = Ed25519KeyHashes::new();
1740 set.add_move(spk.addr_keyhash());
1741 set
1742 }
1743 NativeScriptEnum::ScriptAll(all) => Ed25519KeyHashes::from(&all.native_scripts),
1744 NativeScriptEnum::ScriptAny(any) => Ed25519KeyHashes::from(&any.native_scripts),
1745 NativeScriptEnum::ScriptNOfK(ofk) => Ed25519KeyHashes::from(&ofk.native_scripts),
1746 _ => Ed25519KeyHashes::new(),
1747 }
1748 }
1749}