cml_cip36_wasm/utils.rs
1pub use cml_core::{
2 error::{DeserializeError, DeserializeFailure},
3 ordered_hash_map::OrderedHashMap,
4 serialization::{Deserialize, LenEncoding, Serialize, StringEncoding},
5};
6
7pub use cml_chain_wasm::auxdata::{Metadata, TransactionMetadatum};
8
9pub use cml_chain_wasm::{address::Address, NetworkId};
10use wasm_bindgen::JsError;
11
12use std::convert::{TryFrom, TryInto};
13
14use super::{
15 CIP36DelegationDistribution, CIP36DeregistrationCbor, CIP36KeyDeregistration,
16 CIP36KeyRegistration, CIP36Nonce, CIP36RegistrationCbor, CIP36StakeCredential,
17};
18
19impl CIP36DeregistrationCbor {
20 /// Add to an existing metadata (could be empty) the full CIP36 deregistration metadata
21 pub fn add_to_metadata(&self, metadata: &mut Metadata) -> Result<(), JsError> {
22 self.0
23 .add_to_metadata(metadata.as_mut())
24 .map_err(Into::into)
25 }
26
27 // these are not implementing Serialize/Deserialize as we do not keep track of the rest of the encoding metadata
28 // so it would be disingenuous to implement them if users called to_cbor_bytes() and we skip the rest of
29 // the metadata, as well as when creating from a Metadata object its outer encoding (e.g. map len, key encodings)
30 // is not present as that is simply an OrderedHashMap<TransactionMetadatumLabel, TransactionMetadatum>
31
32 /// Serializes to bytes compatable with Metadata, but containing ONLY the relevant fields for CIP36.
33 /// If this was created from bytes or from a Metadata that was created from bytes, it will preserve
34 /// the encodings but only from the metadatums themselves within the keys 61285 and 61286
35 pub fn to_metadata_bytes(&self) -> Vec<u8> {
36 self.0.to_metadata_bytes()
37 }
38
39 /// Create a CIP36 view from the bytes of a Metadata.
40 /// The resulting CIP36DeregistrationCbor will contain ONLY the relevant fields for CIP36 from the Metadata
41 pub fn from_metadata_bytes(metadata_cbor_bytes: &[u8]) -> Result<Self, DeserializeError> {
42 cml_cip36::CIP36DeregistrationCbor::from_metadata_bytes(metadata_cbor_bytes)
43 .map(Into::into)
44 .map_err(Into::into)
45 }
46
47 pub fn try_from_metadata(metadata: &Metadata) -> Result<CIP36DeregistrationCbor, JsError> {
48 cml_cip36::CIP36DeregistrationCbor::try_from(metadata.as_ref())
49 .map(Into::into)
50 .map_err(Into::into)
51 }
52
53 pub fn try_into_metadata(&self) -> Result<Metadata, JsError> {
54 TryInto::<cml_chain::auxdata::Metadata>::try_into(&self.0)
55 .map(Into::into)
56 .map_err(Into::into)
57 }
58}
59
60impl CIP36KeyDeregistration {
61 /// Creates a new CIP36KeyDeregistration. You must then sign self.hash_to_sign() to make a `DeregistrationWitness`.
62 ///
63 /// # Arguments
64 ///
65 /// * `stake_credential` - stake address for the network that this transaction is submitted to (to point to the Ada that was being delegated).
66 /// * `nonce` - Monotonically rising across all transactions with the same staking key. Recommended to just use the slot of this tx.
67 pub fn new(stake_credential: &CIP36StakeCredential, nonce: CIP36Nonce) -> Self {
68 Self(cml_cip36::CIP36KeyDeregistration::new(
69 stake_credential.clone().into(),
70 nonce,
71 ))
72 }
73
74 /// Create bytes to sign to make a `DeregistrationWitness` from.
75 ///
76 /// # Arguments
77 ///
78 /// * `force_canonical` - Whether to encode the inner registration canonically. Should be true for hardware wallets and false otherwise.
79 pub fn hash_to_sign(&self, force_canonical: bool) -> Vec<u8> {
80 self.0.hash_to_sign(force_canonical).unwrap()
81 }
82}
83
84impl CIP36KeyRegistration {
85 /// Creates a new CIP36KeyRegistration. You must then sign self.hash_to_sign() to make a `RegistrationWitness`.
86 ///
87 /// # Arguments
88 ///
89 /// * `delegation` - Delegation
90 /// * `stake_credential` - stake address for the network that this transaction is submitted to (to point to the Ada that is being delegated).
91 /// * `payment_address` - Shelley oayment address discriminated for the same network this transaction is submitted to for receiving awairds.
92 /// * `nonce` - Monotonically rising across all transactions with the same staking key. Recommended to just use the slot of this tx.
93 pub fn new(
94 delegation: &CIP36DelegationDistribution,
95 stake_credential: &CIP36StakeCredential,
96 payment_address: &Address,
97 nonce: CIP36Nonce,
98 ) -> Self {
99 Self(cml_cip36::CIP36KeyRegistration::new(
100 delegation.clone().into(),
101 stake_credential.clone().into(),
102 payment_address.clone().into(),
103 nonce,
104 ))
105 }
106
107 /// Create bytes to sign to make a `RegistrationWitness` from.
108 ///
109 /// # Arguments
110 ///
111 /// * `force_canonical` - Whether to encode the inner registration canonically. Should be true for hardware wallets and false otherwise.
112 pub fn hash_to_sign(&self, force_canonical: bool) -> Vec<u8> {
113 self.0.hash_to_sign(force_canonical).unwrap()
114 }
115}
116
117impl CIP36RegistrationCbor {
118 /// Add to an existing metadata (could be empty) the full CIP36 registration metadata
119 pub fn add_to_metadata(&self, metadata: &mut Metadata) -> Result<(), JsError> {
120 self.0
121 .add_to_metadata(metadata.as_mut())
122 .map_err(Into::into)
123 }
124
125 /// Verifies invariants in CIP36.
126 pub fn verify(&self) -> Result<(), JsError> {
127 self.0.verify().map_err(Into::into)
128 }
129
130 // these are not implementing Serialize/Deserialize as we do not keep track of the rest of the encoding metadata
131 // so it would be disingenuous to implement them if users called to_cbor_bytes() and we skip the rest of
132 // the metadata, as well as when creating from a Metadata object its outer encoding (e.g. map len, key encodings)
133 // is not present as that is simply an OrderedHashMap<TransactionMetadatumLabel, TransactionMetadatum>
134
135 /// Serializes to bytes compatable with Metadata, but containing ONLY the relevant fields for CIP36.
136 /// If this was created from bytes or from a Metadata that was created from bytes, it will preserve
137 /// the encodings but only from the metadatums themselves within the keys 61284 and 61285
138 pub fn to_metadata_bytes(&self) -> Vec<u8> {
139 self.0.to_metadata_bytes()
140 }
141
142 /// Create a CIP36 view from the bytes of a Metadata.
143 /// The resulting CIP36RegistrationCbor will contain ONLY the relevant fields for CIP36 from the Metadata
144 pub fn from_metadata_bytes(metadata_cbor_bytes: &[u8]) -> Result<Self, JsError> {
145 cml_cip36::CIP36RegistrationCbor::from_metadata_bytes(metadata_cbor_bytes)
146 .map(Into::into)
147 .map_err(Into::into)
148 }
149
150 pub fn try_from_metadata(metadata: &Metadata) -> Result<CIP36RegistrationCbor, JsError> {
151 cml_cip36::CIP36RegistrationCbor::try_from(metadata.as_ref())
152 .map(Into::into)
153 .map_err(Into::into)
154 }
155
156 pub fn try_into_metadata(&self) -> Result<Metadata, JsError> {
157 TryInto::<cml_chain::auxdata::Metadata>::try_into(&self.0)
158 .map(Into::into)
159 .map_err(Into::into)
160 }
161}