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