1use crate::{
2 convert::{binary_len, decode, encode, encode_len},
3 error::DecodeError,
4 version,
5};
6
7use core::{
8 fmt::{Debug, Display},
9 str::FromStr,
10};
11use heapless::{String, Vec};
12
13#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
14#[cfg_attr(
15 feature = "serde",
16 derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr)
17)]
18pub struct PrivateKey(pub [u8; 32]);
19
20impl Debug for PrivateKey {
21 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22 write!(f, "PrivateKey(")?;
23 for b in &self.0 {
24 write!(f, "{b:02x}")?;
25 }
26 write!(f, ")")
27 }
28}
29
30impl PrivateKey {
31 pub(crate) const PAYLOAD_LEN: usize = 32;
32 pub(crate) const BINARY_LEN: usize = binary_len(Self::PAYLOAD_LEN);
33 pub(crate) const ENCODED_LEN: usize = encode_len(Self::BINARY_LEN);
34 const _ASSERTS: () = {
35 assert!(Self::BINARY_LEN == 35);
36 assert!(Self::ENCODED_LEN == 56);
37 };
38
39 pub fn to_string(&self) -> String<{ Self::ENCODED_LEN }> {
40 encode::<{ Self::PAYLOAD_LEN }, { Self::BINARY_LEN }, { Self::ENCODED_LEN }>(
41 version::PRIVATE_KEY_ED25519,
42 &self.0,
43 )
44 }
45
46 pub fn from_payload(payload: &[u8]) -> Result<Self, DecodeError> {
47 match payload.try_into() {
48 Ok(ed25519) => Ok(Self(ed25519)),
49 Err(_) => Err(DecodeError::Invalid),
50 }
51 }
52
53 pub fn from_string(s: &str) -> Result<Self, DecodeError> {
54 Self::from_slice(s.as_bytes())
55 }
56
57 pub fn from_slice(s: &[u8]) -> Result<Self, DecodeError> {
58 let (ver, payload) = decode::<{ Self::PAYLOAD_LEN }, { Self::BINARY_LEN }>(s)?;
59 match ver {
60 version::PRIVATE_KEY_ED25519 => Self::from_payload(&payload),
61 _ => Err(DecodeError::Invalid),
62 }
63 }
64}
65
66impl Display for PrivateKey {
67 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
68 write!(f, "{}", self.to_string())
69 }
70}
71
72impl FromStr for PrivateKey {
73 type Err = DecodeError;
74
75 fn from_str(s: &str) -> Result<Self, Self::Err> {
76 PrivateKey::from_string(s)
77 }
78}
79
80#[cfg(feature = "serde-decoded")]
81mod private_key_decoded_serde_impl {
82 use super::*;
83 use crate::decoded_json_format::Decoded;
84 use serde::{Deserialize, Deserializer, Serialize, Serializer};
85 use serde_with::serde_as;
86
87 #[serde_as]
88 #[derive(Serialize)]
89 #[serde(transparent)]
90 struct DecodedBorrowed<'a>(#[serde_as(as = "serde_with::hex::Hex")] &'a [u8; 32]);
91
92 #[serde_as]
93 #[derive(Deserialize)]
94 #[serde(transparent)]
95 struct DecodedOwned(#[serde_as(as = "serde_with::hex::Hex")] [u8; 32]);
96
97 impl Serialize for Decoded<&PrivateKey> {
98 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
99 let Self(PrivateKey(bytes)) = self;
100 DecodedBorrowed(bytes).serialize(serializer)
101 }
102 }
103
104 impl<'de> Deserialize<'de> for Decoded<PrivateKey> {
105 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
106 let DecodedOwned(bytes) = DecodedOwned::deserialize(deserializer)?;
107 Ok(Decoded(PrivateKey(bytes)))
108 }
109 }
110}
111
112#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
113#[cfg_attr(
114 feature = "serde",
115 derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr)
116)]
117pub struct PublicKey(pub [u8; 32]);
118
119impl Debug for PublicKey {
120 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
121 write!(f, "PublicKey(")?;
122 for b in &self.0 {
123 write!(f, "{b:02x}")?;
124 }
125 write!(f, ")")
126 }
127}
128
129impl PublicKey {
130 pub(crate) const PAYLOAD_LEN: usize = 32;
131 pub(crate) const BINARY_LEN: usize = binary_len(Self::PAYLOAD_LEN);
132 pub(crate) const ENCODED_LEN: usize = encode_len(Self::BINARY_LEN);
133 const _ASSERTS: () = {
134 assert!(Self::BINARY_LEN == 35);
135 assert!(Self::ENCODED_LEN == 56);
136 };
137
138 pub fn to_string(&self) -> String<{ Self::ENCODED_LEN }> {
139 encode::<{ Self::PAYLOAD_LEN }, { Self::BINARY_LEN }, { Self::ENCODED_LEN }>(
140 version::PUBLIC_KEY_ED25519,
141 &self.0,
142 )
143 }
144
145 pub fn from_payload(payload: &[u8]) -> Result<Self, DecodeError> {
146 match payload.try_into() {
147 Ok(ed25519) => Ok(Self(ed25519)),
148 Err(_) => Err(DecodeError::Invalid),
149 }
150 }
151
152 pub fn from_string(s: &str) -> Result<Self, DecodeError> {
153 Self::from_slice(s.as_bytes())
154 }
155
156 pub fn from_slice(s: &[u8]) -> Result<Self, DecodeError> {
157 let (ver, payload) = decode::<{ Self::PAYLOAD_LEN }, { Self::BINARY_LEN }>(s)?;
158 match ver {
159 version::PUBLIC_KEY_ED25519 => Self::from_payload(&payload),
160 _ => Err(DecodeError::Invalid),
161 }
162 }
163}
164
165impl Display for PublicKey {
166 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
167 write!(f, "{}", self.to_string())
168 }
169}
170
171impl FromStr for PublicKey {
172 type Err = DecodeError;
173
174 fn from_str(s: &str) -> Result<Self, Self::Err> {
175 PublicKey::from_string(s)
176 }
177}
178
179#[cfg(feature = "serde-decoded")]
180mod public_key_decoded_serde_impl {
181 use super::*;
182 use crate::decoded_json_format::Decoded;
183 use serde::{Deserialize, Deserializer, Serialize, Serializer};
184 use serde_with::serde_as;
185
186 #[serde_as]
187 #[derive(Serialize)]
188 #[serde(transparent)]
189 struct DecodedBorrowed<'a>(#[serde_as(as = "serde_with::hex::Hex")] &'a [u8; 32]);
190
191 #[serde_as]
192 #[derive(Deserialize)]
193 #[serde(transparent)]
194 struct DecodedOwned(#[serde_as(as = "serde_with::hex::Hex")] [u8; 32]);
195
196 impl Serialize for Decoded<&PublicKey> {
197 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
198 let Self(PublicKey(bytes)) = self;
199 DecodedBorrowed(bytes).serialize(serializer)
200 }
201 }
202
203 impl<'de> Deserialize<'de> for Decoded<PublicKey> {
204 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
205 let DecodedOwned(bytes) = DecodedOwned::deserialize(deserializer)?;
206 Ok(Decoded(PublicKey(bytes)))
207 }
208 }
209}
210
211#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
212#[cfg_attr(
213 feature = "serde",
214 derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr)
215)]
216pub struct MuxedAccount {
217 pub ed25519: [u8; 32],
218 pub id: u64,
219}
220
221impl Debug for MuxedAccount {
222 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
223 write!(f, "MuxedAccount(")?;
224 for b in &self.ed25519 {
225 write!(f, "{b:02x}")?;
226 }
227 write!(f, ", {}", self.id)?;
228 write!(f, ")")
229 }
230}
231
232impl MuxedAccount {
233 pub(crate) const PAYLOAD_LEN: usize = 32 + 8; pub(crate) const BINARY_LEN: usize = binary_len(Self::PAYLOAD_LEN);
235 pub(crate) const ENCODED_LEN: usize = encode_len(Self::BINARY_LEN);
236 const _ASSERTS: () = {
237 assert!(Self::BINARY_LEN == 43);
238 assert!(Self::ENCODED_LEN == 69);
239 };
240
241 pub fn to_string(&self) -> String<{ Self::ENCODED_LEN }> {
242 let mut payload: [u8; Self::PAYLOAD_LEN] = [0; Self::PAYLOAD_LEN];
243 let (ed25519, id) = payload.split_at_mut(32);
244 ed25519.copy_from_slice(&self.ed25519);
245 id.copy_from_slice(&self.id.to_be_bytes());
246 encode::<{ Self::PAYLOAD_LEN }, { Self::BINARY_LEN }, { Self::ENCODED_LEN }>(
247 version::MUXED_ACCOUNT_ED25519,
248 &payload,
249 )
250 }
251
252 pub fn from_payload(payload: &[u8]) -> Result<Self, DecodeError> {
253 if payload.len() < 40 {
254 return Err(DecodeError::Invalid);
255 }
256 let (ed25519, id) = payload.split_at(32);
257 Ok(Self {
258 ed25519: ed25519.try_into().map_err(|_| DecodeError::Invalid)?,
259 id: u64::from_be_bytes(id.try_into().map_err(|_| DecodeError::Invalid)?),
260 })
261 }
262
263 pub fn from_string(s: &str) -> Result<Self, DecodeError> {
264 Self::from_slice(s.as_bytes())
265 }
266
267 pub fn from_slice(s: &[u8]) -> Result<Self, DecodeError> {
268 let (ver, payload) = decode::<{ Self::PAYLOAD_LEN }, { Self::BINARY_LEN }>(s)?;
269 match ver {
270 version::MUXED_ACCOUNT_ED25519 => Self::from_payload(&payload),
271 _ => Err(DecodeError::Invalid),
272 }
273 }
274}
275
276impl Display for MuxedAccount {
277 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
278 write!(f, "{}", self.to_string())
279 }
280}
281
282impl FromStr for MuxedAccount {
283 type Err = DecodeError;
284
285 fn from_str(s: &str) -> Result<Self, Self::Err> {
286 MuxedAccount::from_string(s)
287 }
288}
289
290#[cfg(feature = "serde-decoded")]
291mod muxed_account_decoded_serde_impl {
292 use super::*;
293 use crate::decoded_json_format::Decoded;
294 use serde::{Deserialize, Deserializer, Serialize, Serializer};
295 use serde_with::serde_as;
296
297 #[serde_as]
298 #[derive(Serialize)]
299 struct DecodedBorrowed<'a> {
300 #[serde_as(as = "serde_with::hex::Hex")]
301 ed25519: &'a [u8; 32],
302 id: u64,
303 }
304
305 #[serde_as]
306 #[derive(Deserialize)]
307 struct DecodedOwned {
308 #[serde_as(as = "serde_with::hex::Hex")]
309 ed25519: [u8; 32],
310 id: u64,
311 }
312
313 impl Serialize for Decoded<&MuxedAccount> {
314 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
315 let Self(MuxedAccount { ed25519, id }) = self;
316 DecodedBorrowed { ed25519, id: *id }.serialize(serializer)
317 }
318 }
319
320 impl<'de> Deserialize<'de> for Decoded<MuxedAccount> {
321 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
322 let DecodedOwned { ed25519, id } = DecodedOwned::deserialize(deserializer)?;
323 Ok(Decoded(MuxedAccount { ed25519, id }))
324 }
325 }
326}
327
328#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
332#[cfg_attr(
333 feature = "serde",
334 derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr)
335)]
336pub struct SignedPayload {
337 pub ed25519: [u8; 32],
338 pub payload: Vec<u8, 64>,
339}
340
341impl Debug for SignedPayload {
342 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
343 write!(f, "SignedPayload(")?;
344 for b in &self.ed25519 {
345 write!(f, "{b:02x}")?;
346 }
347 write!(f, ", ")?;
348 for b in &self.payload {
349 write!(f, "{b:02x}")?;
350 }
351 write!(f, ")")
352 }
353}
354
355impl SignedPayload {
356 pub(crate) const MAX_PAYLOAD_LEN: usize = 32 + 4 + 64;
358 pub(crate) const MAX_BINARY_LEN: usize = binary_len(Self::MAX_PAYLOAD_LEN);
359 pub(crate) const MAX_ENCODED_LEN: usize = encode_len(Self::MAX_BINARY_LEN);
360 const _ASSERTS: () = {
361 assert!(Self::MAX_PAYLOAD_LEN == 100);
362 assert!(Self::MAX_BINARY_LEN == 103);
363 assert!(Self::MAX_ENCODED_LEN == 165);
364 };
365
366 pub fn to_string(&self) -> String<{ Self::MAX_ENCODED_LEN }> {
368 let inner_payload_len = self.payload.len();
369 let payload_len = 32 + 4 + inner_payload_len + (4 - inner_payload_len % 4) % 4;
370
371 let inner_payload_len_u32: u32 = inner_payload_len as u32;
372
373 let mut payload = [0u8; Self::MAX_PAYLOAD_LEN];
375 payload[..32].copy_from_slice(&self.ed25519);
376 payload[32..32 + 4].copy_from_slice(&(inner_payload_len_u32).to_be_bytes());
377 payload[32 + 4..32 + 4 + inner_payload_len].copy_from_slice(&self.payload);
378
379 encode::<{ Self::MAX_PAYLOAD_LEN }, { Self::MAX_BINARY_LEN }, { Self::MAX_ENCODED_LEN }>(
380 version::SIGNED_PAYLOAD_ED25519,
381 &payload[..payload_len],
382 )
383 }
384
385 pub fn from_payload(payload: &[u8]) -> Result<Self, DecodeError> {
391 const MAX_INNER_PAYLOAD_LENGTH: u32 = 64;
394 const MIN_LENGTH: usize = 32 + 4 + 4;
395 const MAX_LENGTH: usize = 32 + 4 + (MAX_INNER_PAYLOAD_LENGTH as usize);
396 let payload_len = payload.len();
397 if !(MIN_LENGTH..=MAX_LENGTH).contains(&payload_len) {
398 return Err(DecodeError::Invalid);
399 }
400
401 let mut offset = 0;
403 let ed25519: [u8; 32] = payload
404 .get(offset..offset + 32)
405 .ok_or(DecodeError::Invalid)?
406 .try_into()
407 .map_err(|_| DecodeError::Invalid)?;
408 offset += 32;
409
410 let inner_payload_len = u32::from_be_bytes(
412 payload
413 .get(offset..offset + 4)
414 .ok_or(DecodeError::Invalid)?
415 .try_into()
416 .map_err(|_| DecodeError::Invalid)?,
417 );
418 offset += 4;
419
420 if inner_payload_len > MAX_INNER_PAYLOAD_LENGTH {
422 return Err(DecodeError::Invalid);
423 }
424
425 let inner_payload = payload
427 .get(offset..offset + inner_payload_len as usize)
428 .ok_or(DecodeError::Invalid)?;
429 offset += inner_payload_len as usize;
430
431 let padding_len = (4 - inner_payload_len % 4) % 4;
433
434 let padding = payload
436 .get(offset..offset + padding_len as usize)
437 .ok_or(DecodeError::Invalid)?;
438 offset += padding_len as usize;
439
440 if padding.iter().any(|b| *b != 0) {
442 return Err(DecodeError::Invalid);
443 }
444
445 if offset != payload_len {
447 return Err(DecodeError::Invalid);
448 }
449
450 let mut payload = Vec::new();
451 payload
452 .extend_from_slice(inner_payload)
453 .map_err(|_| DecodeError::Invalid)?;
454 Ok(Self { ed25519, payload })
455 }
456
457 pub fn from_string(s: &str) -> Result<Self, DecodeError> {
458 Self::from_slice(s.as_bytes())
459 }
460
461 pub fn from_slice(s: &[u8]) -> Result<Self, DecodeError> {
462 let (ver, payload) = decode::<{ Self::MAX_PAYLOAD_LEN }, { Self::MAX_BINARY_LEN }>(s)?;
463 match ver {
464 version::SIGNED_PAYLOAD_ED25519 => Self::from_payload(&payload),
465 _ => Err(DecodeError::Invalid),
466 }
467 }
468}
469
470impl Display for SignedPayload {
471 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
472 write!(f, "{}", self.to_string())
473 }
474}
475
476impl FromStr for SignedPayload {
477 type Err = DecodeError;
478
479 fn from_str(s: &str) -> Result<Self, Self::Err> {
480 SignedPayload::from_string(s)
481 }
482}
483
484#[cfg(feature = "serde-decoded")]
485mod signed_payload_decoded_serde_impl {
486 use super::SignedPayload;
487 use crate::decoded_json_format::Decoded;
488 use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
489 use serde_with::serde_as;
490
491 #[serde_as]
492 #[derive(Serialize)]
493 struct DecodedBorrowed<'a> {
494 #[serde_as(as = "serde_with::hex::Hex")]
495 ed25519: &'a [u8; 32],
496 #[serde_as(as = "serde_with::hex::Hex")]
497 payload: &'a [u8],
498 }
499
500 #[serde_as]
501 #[derive(Deserialize)]
502 struct DecodedOwned {
503 #[serde_as(as = "serde_with::hex::Hex")]
504 ed25519: [u8; 32],
505 #[serde_as(as = "serde_with::hex::Hex")]
506 payload: alloc::vec::Vec<u8>,
507 }
508
509 impl Serialize for Decoded<&SignedPayload> {
510 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
511 let Self(SignedPayload { ed25519, payload }) = self;
512 DecodedBorrowed { ed25519, payload }.serialize(serializer)
513 }
514 }
515
516 impl<'de> Deserialize<'de> for Decoded<SignedPayload> {
517 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
518 let DecodedOwned { ed25519, payload } = DecodedOwned::deserialize(deserializer)?;
519 Ok(Decoded(SignedPayload {
520 ed25519,
521 payload: payload
522 .as_slice()
523 .try_into()
524 .map_err(|_| de::Error::custom("payload too large"))?,
525 }))
526 }
527 }
528}