1use crate::crypto::{Address, MultisigSignature, MultisigSubsig, Signature};
3use crate::error::TokenParsingError;
4use crate::kmd::responses::ExportKeyResponse;
5use crate::models::{
6 Ed25519PublicKey, HashDigest, MasterDerivationKey, MicroAlgos, Round, VotePK, VRFPK,
7};
8use crate::transaction::{Transaction, TransactionType};
9use data_encoding::BASE64;
10use derive_more::Display;
11use serde::de::Visitor;
12use serde::{Deserialize, Deserializer, Serialize, Serializer};
13use static_assertions::_core::ops::{Add, Sub};
14use std::fmt::{Debug, Display, Formatter};
15use std::ops::Mul;
16
17impl Serialize for Transaction {
18 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
19 where
20 S: Serializer,
21 {
22 use serde::ser::SerializeStruct;
23 let type_len = match &self.txn_type {
24 TransactionType::Payment(payment) => {
25 1 + if payment.close_remainder_to.is_some() {
26 1
27 } else {
28 0
29 } + if payment.amount.0 != 0 { 1 } else { 0 }
30 }
31 TransactionType::KeyRegistration(_) => 5,
32 };
33 let len = 6
34 + type_len
35 + if self.note.is_empty() { 0 } else { 1 }
36 + if self.genesis_id.is_empty() { 0 } else { 1 };
37 let mut state = serializer.serialize_struct("Transaction", len)?;
38 if let TransactionType::Payment(payment) = &self.txn_type {
39 if payment.amount.0 != 0 {
40 state.serialize_field("amt", &payment.amount)?;
41 }
42 }
43 if let TransactionType::Payment(payment) = &self.txn_type {
44 if payment.close_remainder_to.is_some() {
45 state.serialize_field("close", &payment.close_remainder_to)?;
46 }
47 }
48 state.serialize_field("fee", &self.fee)?;
49 state.serialize_field("fv", &self.first_valid)?;
50 if !self.genesis_id.is_empty() {
51 state.serialize_field("gen", &self.genesis_id)?;
52 }
53 state.serialize_field("gh", &self.genesis_hash)?;
54 state.serialize_field("lv", &self.last_valid)?;
55 if !self.note.is_empty() {
56 state.serialize_field("note", &serde_bytes::ByteBuf::from(self.note.clone()))?;
57 }
58 if let TransactionType::Payment(payment) = &self.txn_type {
59 state.serialize_field("rcv", &payment.receiver)?;
60 }
61 if let TransactionType::KeyRegistration(key_registration) = &self.txn_type {
62 state.serialize_field("selkey", &key_registration.selection_pk)?;
63 }
64 state.serialize_field("snd", &self.sender)?;
65 match &self.txn_type {
66 TransactionType::Payment(_payment) => {
67 state.serialize_field("type", "pay")?;
68 }
69 TransactionType::KeyRegistration(_key_registration) => {
70 state.serialize_field("type", "keyreg")?;
71 }
72 }
73 if let TransactionType::KeyRegistration(key_registration) = &self.txn_type {
74 state.serialize_field("votefst", &key_registration.vote_first)?;
75 }
76 if let TransactionType::KeyRegistration(key_registration) = &self.txn_type {
77 state.serialize_field("votekd", &key_registration.vote_key_dilution)?;
78 }
79 if let TransactionType::KeyRegistration(key_registration) = &self.txn_type {
80 state.serialize_field("votekey", &key_registration.vote_pk)?;
81 }
82 if let TransactionType::KeyRegistration(key_registration) = &self.txn_type {
83 state.serialize_field("votelst", &key_registration.vote_last)?;
84 }
85 state.end()
86 }
87}
88
89impl Serialize for HashDigest {
90 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
91 where
92 S: Serializer,
93 {
94 serializer.serialize_bytes(&self.0[..])
95 }
96}
97
98impl Serialize for VotePK {
99 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
100 where
101 S: Serializer,
102 {
103 serializer.serialize_bytes(&self.0[..])
104 }
105}
106
107impl Serialize for VRFPK {
108 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
109 where
110 S: Serializer,
111 {
112 serializer.serialize_bytes(&self.0[..])
113 }
114}
115
116impl Serialize for Ed25519PublicKey {
117 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
118 where
119 S: Serializer,
120 {
121 serializer.serialize_bytes(&self.0[..])
122 }
123}
124
125impl<'de> Deserialize<'de> for HashDigest {
126 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
127 where
128 D: Deserializer<'de>,
129 {
130 Ok(HashDigest(deserializer.deserialize_bytes(U8_32Visitor)?))
131 }
132}
133
134impl<'de> Deserialize<'de> for VotePK {
135 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
136 where
137 D: Deserializer<'de>,
138 {
139 Ok(VotePK(deserializer.deserialize_bytes(U8_32Visitor)?))
140 }
141}
142
143impl<'de> Deserialize<'de> for VRFPK {
144 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
145 where
146 D: Deserializer<'de>,
147 {
148 Ok(VRFPK(deserializer.deserialize_bytes(U8_32Visitor)?))
149 }
150}
151
152impl<'de> Deserialize<'de> for Ed25519PublicKey {
153 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
154 where
155 D: Deserializer<'de>,
156 {
157 Ok(Ed25519PublicKey(
158 deserializer.deserialize_bytes(U8_32Visitor)?,
159 ))
160 }
161}
162
163impl Serialize for MultisigSignature {
164 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
165 where
166 S: Serializer,
167 {
168 use serde::ser::SerializeMap;
170 let mut state = serializer.serialize_map(Some(3))?;
171 state.serialize_entry("subsig", &self.subsigs)?;
172 state.serialize_entry("thr", &self.threshold)?;
173 state.serialize_entry("v", &self.version)?;
174 state.end()
175 }
176}
177
178impl Serialize for MultisigSubsig {
179 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
180 where
181 S: Serializer,
182 {
183 use serde::ser::SerializeMap;
184 let len = if self.sig.is_some() { 2 } else { 1 };
185 let mut state = serializer.serialize_map(Some(len))?;
186 state.serialize_entry("pk", &self.key)?;
187 if let Some(sig) = &self.sig {
188 state.serialize_entry("s", sig)?;
189 }
190 state.end()
191 }
192}
193
194impl Serialize for Address {
195 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
196 where
197 S: Serializer,
198 {
199 serializer.serialize_bytes(&self.0[..])
200 }
201}
202
203impl<'de> Deserialize<'de> for Address {
204 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
205 where
206 D: Deserializer<'de>,
207 {
208 Ok(Address(deserializer.deserialize_bytes(U8_32Visitor)?))
209 }
210}
211
212impl Serialize for Signature {
213 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
214 where
215 S: Serializer,
216 {
217 serializer.serialize_bytes(&self.0[..])
218 }
219}
220
221impl<'de> Deserialize<'de> for Signature {
222 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
223 where
224 D: Deserializer<'de>,
225 {
226 Ok(Signature(deserializer.deserialize_bytes(SignatureVisitor)?))
227 }
228}
229
230struct SignatureVisitor;
231
232impl<'de> Visitor<'de> for SignatureVisitor {
233 type Value = [u8; 64];
234
235 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
236 formatter.write_str("a 64 byte array")
237 }
238
239 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
240 where
241 E: serde::de::Error,
242 {
243 if v.len() == 64 {
244 let mut bytes = [0; 64];
245 bytes.copy_from_slice(v);
246 Ok(bytes)
247 } else {
248 Err(E::custom(format!("Invalid signature length: {}", v.len())))
249 }
250 }
251}
252
253pub(crate) struct U8_32Visitor;
254
255impl<'de> Visitor<'de> for U8_32Visitor {
256 type Value = [u8; 32];
257
258 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
259 formatter.write_str("a 32 byte array")
260 }
261
262 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
263 where
264 E: serde::de::Error,
265 {
266 if v.len() == 32 {
267 let mut bytes = [0; 32];
268 bytes.copy_from_slice(v);
269 Ok(bytes)
270 } else {
271 Err(E::custom(format!("Invalid byte array length: {}", v.len())))
272 }
273 }
274}
275
276pub fn deserialize_hash<'de, D>(deserializer: D) -> Result<HashDigest, D::Error>
277where
278 D: Deserializer<'de>,
279{
280 Ok(HashDigest(deserialize_bytes32(deserializer)?))
281}
282
283pub fn deserialize_mdk<'de, D>(deserializer: D) -> Result<MasterDerivationKey, D::Error>
284where
285 D: Deserializer<'de>,
286{
287 Ok(MasterDerivationKey(deserialize_bytes32(deserializer)?))
288}
289
290pub fn deserialize_bytes32<'de, D>(deserializer: D) -> Result<[u8; 32], D::Error>
291where
292 D: Deserializer<'de>,
293{
294 let s = <&str>::deserialize(deserializer)?;
295 let mut decoded = [0; 32];
296 decoded.copy_from_slice(&BASE64.decode(s.as_bytes()).unwrap());
297 Ok(decoded)
298}
299
300pub fn deserialize_bytes64<'de, D>(deserializer: D) -> Result<[u8; 64], D::Error>
301where
302 D: Deserializer<'de>,
303{
304 use serde::de::Error;
305 let s = <&str>::deserialize(deserializer)?;
306 let mut decoded = [0; 64];
307 let bytes = BASE64.decode(s.as_bytes()).map_err(D::Error::custom)?;
308 decoded.copy_from_slice(&bytes);
309 Ok(decoded)
310}
311
312pub fn deserialize_bytes<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
313where
314 D: Deserializer<'de>,
315{
316 let s = <&str>::deserialize(deserializer)?;
317 Ok(BASE64.decode(s.as_bytes()).unwrap())
318}
319
320pub fn serialize_bytes<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
321where
322 S: Serializer,
323{
324 serializer.serialize_str(&BASE64.encode(bytes))
325}
326
327impl Display for MicroAlgos {
328 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
329 Display::fmt(&self.0, f)
330 }
331}
332
333impl Display for Round {
334 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
335 Display::fmt(&self.0, f)
336 }
337}
338
339impl Debug for ExportKeyResponse {
340 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
341 f.debug_struct("ExportKeyResponse")
342 .field("private_key", &self.private_key.to_vec())
343 .finish()
344 }
345}
346
347impl Debug for Signature {
348 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
349 f.debug_tuple("Signature").field(&self.0.to_vec()).finish()
350 }
351}
352
353impl Add for Round {
354 type Output = Self;
355
356 fn add(self, rhs: Self) -> Self::Output {
357 Round(self.0 + rhs.0)
358 }
359}
360
361impl Add<u64> for Round {
362 type Output = Self;
363
364 fn add(self, rhs: u64) -> Self::Output {
365 Round(self.0 + rhs)
366 }
367}
368
369impl Add for MicroAlgos {
370 type Output = Self;
371
372 fn add(self, rhs: Self) -> Self::Output {
373 MicroAlgos(self.0 + rhs.0)
374 }
375}
376
377impl Add<u64> for MicroAlgos {
378 type Output = Self;
379
380 fn add(self, rhs: u64) -> Self::Output {
381 MicroAlgos(self.0 + rhs)
382 }
383}
384
385impl Sub for Round {
386 type Output = Self;
387
388 fn sub(self, rhs: Self) -> Self::Output {
389 Round(self.0 - rhs.0)
390 }
391}
392
393impl Sub<u64> for Round {
394 type Output = Self;
395
396 fn sub(self, rhs: u64) -> Self::Output {
397 Round(self.0 - rhs)
398 }
399}
400
401impl Sub for MicroAlgos {
402 type Output = Self;
403
404 fn sub(self, rhs: Self) -> Self::Output {
405 MicroAlgos(self.0 - rhs.0)
406 }
407}
408
409impl Sub<u64> for MicroAlgos {
410 type Output = Self;
411
412 fn sub(self, rhs: u64) -> Self::Output {
413 MicroAlgos(self.0 - rhs)
414 }
415}
416
417impl Mul<u64> for Round {
421 type Output = Self;
422
423 fn mul(self, rhs: u64) -> Self::Output {
424 Round(self.0 * rhs)
425 }
426}
427
428impl Mul<u64> for MicroAlgos {
429 type Output = Self;
430
431 fn mul(self, rhs: u64) -> Self::Output {
432 MicroAlgos(self.0 * rhs)
433 }
434}
435
436impl PartialEq for Signature {
437 fn eq(&self, other: &Self) -> bool {
438 for i in 0..64 {
439 if self.0[i] != other.0[i] {
440 return false;
441 }
442 }
443 true
444 }
445}
446
447impl Eq for Signature {}
448
449#[derive(Display)]
451#[display(fmt = "{}", token)]
452pub struct ApiToken {
453 token: String,
454}
455
456const TOKEN_LENGTH: usize = 64;
457
458impl ApiToken {
459 pub fn parse(token: &str) -> Result<Self, TokenParsingError> {
461 if token.len() != TOKEN_LENGTH {
462 return Err(TokenParsingError::InvalidLength);
463 }
464
465 Ok(ApiToken {
466 token: token.to_string(),
467 })
468 }
469}