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