1#![allow(clippy::too_many_arguments)]
2
3pub use cml_core::{
7 error::{DeserializeError, DeserializeFailure},
8 ordered_hash_map::OrderedHashMap,
9 serialization::{Deserialize, LenEncoding, Serialize, StringEncoding},
10};
11
12pub use cml_chain::{address::Address, auxdata::Metadata, NetworkId};
13
14use std::convert::From;
15
16pub mod cbor_encodings;
17pub mod error;
18pub mod serialization;
19pub mod utils;
20
21use cbor_encodings::*;
22
23extern crate derivative;
24
25pub type CIP36VotingPubKey = cml_crypto::PublicKey;
29
30pub type CIP36StakingPubKey = cml_crypto::PublicKey;
31
32pub type CIP36LegacyKeyRegistration = CIP36VotingPubKey;
33
34pub type CIP36Nonce = u64;
38
39pub type CIP36StakeCredential = CIP36StakingPubKey;
40
41pub type CIP36StakeWitness = cml_crypto::Ed25519Signature;
42
43pub type CIP36VotingPurpose = u64;
44
45pub type CIP36Weight = u32;
46
47#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
51pub struct CIP36Delegation {
52 pub voting_pub_key: CIP36VotingPubKey,
53 pub weight: CIP36Weight,
54 #[serde(skip)]
55 pub encodings: Option<CIP36DelegationEncoding>,
56}
57
58impl CIP36Delegation {
59 pub fn new(voting_pub_key: CIP36VotingPubKey, weight: CIP36Weight) -> Self {
60 Self {
61 voting_pub_key,
62 weight,
63 encodings: None,
64 }
65 }
66}
67
68#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
69pub enum CIP36DelegationDistribution {
70 Weighted {
71 delegations: Vec<CIP36Delegation>,
72 #[serde(skip)]
73 delegations_encoding: LenEncoding,
74 },
75 Legacy {
76 legacy: CIP36LegacyKeyRegistration,
77 #[serde(skip)]
78 legacy_encoding: StringEncoding,
79 },
80}
81
82impl CIP36DelegationDistribution {
83 pub fn new_weighted(delegations: Vec<CIP36Delegation>) -> Self {
86 Self::Weighted {
87 delegations,
88 delegations_encoding: LenEncoding::default(),
89 }
90 }
91
92 pub fn new_legacy(legacy: CIP36LegacyKeyRegistration) -> Self {
94 Self::Legacy {
95 legacy,
96 legacy_encoding: StringEncoding::default(),
97 }
98 }
99}
100
101#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
104pub struct CIP36DeregistrationCbor {
105 pub key_deregistration: CIP36KeyDeregistration,
106 pub deregistration_witness: CIP36DeregistrationWitness,
107}
108
109#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
110pub struct CIP36DeregistrationWitness {
111 pub stake_witness: CIP36StakeWitness,
112 #[serde(skip)]
113 pub encodings: Option<CIP36DeregistrationWitnessEncoding>,
114}
115
116impl CIP36DeregistrationWitness {
117 pub fn new(stake_witness: CIP36StakeWitness) -> Self {
118 Self {
119 stake_witness,
120 encodings: None,
121 }
122 }
123}
124
125#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
126pub struct CIP36KeyDeregistration {
127 pub stake_credential: CIP36StakeCredential,
128 pub nonce: CIP36Nonce,
129 pub voting_purpose: CIP36VotingPurpose,
130 #[serde(skip)]
131 pub encodings: Option<CIP36KeyDeregistrationEncoding>,
132}
133
134#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
135pub struct CIP36KeyRegistration {
136 pub delegation: CIP36DelegationDistribution,
137 pub stake_credential: CIP36StakeCredential,
138 pub payment_address: Address,
139 pub nonce: CIP36Nonce,
140 pub voting_purpose: CIP36VotingPurpose,
141 #[serde(skip)]
142 pub encodings: Option<CIP36KeyRegistrationEncoding>,
143}
144
145#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
148pub struct CIP36RegistrationCbor {
149 pub key_registration: CIP36KeyRegistration,
150 pub registration_witness: CIP36RegistrationWitness,
151}
152
153#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
154pub struct CIP36RegistrationWitness {
155 pub stake_witness: CIP36StakeWitness,
156 #[serde(skip)]
157 pub encodings: Option<CIP36RegistrationWitnessEncoding>,
158}
159
160impl CIP36RegistrationWitness {
161 pub fn new(stake_witness: CIP36StakeWitness) -> Self {
162 Self {
163 stake_witness,
164 encodings: None,
165 }
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use cml_chain::address::Address;
172 use cml_crypto::*;
173
174 use super::*;
175
176 #[test]
177 fn sign_data() {
178 let stake_cred = PublicKey::from_raw_bytes(&[
193 227, 205, 36, 4, 200, 77, 230, 95, 150, 145, 143, 24, 213, 180, 69, 188, 185, 51, 167,
194 205, 161, 142, 237, 237, 121, 69, 221, 25, 30, 67, 35, 105,
195 ])
196 .unwrap();
197 let nonce = 1234;
199
200 let legacy_address = Address::from_raw_bytes(&[
205 224, 114, 182, 23, 101, 120, 129, 227, 10, 209, 124, 70, 228, 1, 12, 156, 179, 235,
206 178, 68, 6, 83, 163, 77, 50, 33, 156, 131, 233,
207 ])
208 .unwrap();
209 let legacy_reg = CIP36KeyRegistration::new(
210 CIP36DelegationDistribution::new_legacy(
211 CIP36LegacyKeyRegistration::from_raw_bytes(&[
212 0, 54, 239, 62, 31, 13, 63, 89, 137, 226, 209, 85, 234, 84, 189, 178, 167, 44,
213 76, 69, 108, 203, 149, 154, 244, 201, 72, 104, 244, 115, 245, 160,
214 ])
215 .unwrap(),
216 ),
217 stake_cred.clone(),
218 legacy_address,
219 nonce,
220 );
221 let legacy_sign_data_hash = legacy_reg.hash_to_sign(false).unwrap();
222 assert_eq!(
223 "9946e71b5f6c16150cf431910a0f7dbb8084a992577847802e60d32becb3d6be",
224 hex::encode(legacy_sign_data_hash)
225 );
226
227 let new_address = Address::from_raw_bytes(&[
232 0, 71, 119, 86, 30, 125, 158, 193, 18, 236, 48, 117, 114, 250, 236, 26, 255, 97, 255,
233 12, 254, 214, 141, 244, 205, 92, 132, 127, 24, 114, 182, 23, 101, 120, 129, 227, 10,
234 209, 124, 70, 228, 1, 12, 156, 179, 235, 178, 68, 6, 83, 163, 77, 50, 33, 156, 131,
235 233,
236 ])
237 .unwrap();
238 let weighted_reg = CIP36KeyRegistration::new(
239 CIP36DelegationDistribution::new_weighted(vec![CIP36Delegation::new(
240 CIP36VotingPubKey::from_raw_bytes(&[
241 0, 54, 239, 62, 31, 13, 63, 89, 137, 226, 209, 85, 234, 84, 189, 178, 167, 44,
242 76, 69, 108, 203, 149, 154, 244, 201, 72, 104, 244, 115, 245, 160,
243 ])
244 .unwrap(),
245 1,
246 )]),
247 stake_cred,
248 new_address,
249 nonce,
250 );
251 let weighted_sign_data_hash = weighted_reg.hash_to_sign(false).unwrap();
252 assert_eq!(
253 "3110fbad72589a80de7fc174310e92dac35bbfece1690c2dce53c2235a9776fa",
254 hex::encode(weighted_sign_data_hash)
255 );
256
257 }
259}