1use std::{fmt::Debug, fmt::Display, str::FromStr};
2
3use crate::{
4 convert::{decode, encode},
5 ed25519,
6 error::DecodeError,
7 version,
8};
9
10#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)]
11pub enum Strkey {
12 PublicKeyEd25519(ed25519::PublicKey),
13 PrivateKeyEd25519(ed25519::PrivateKey),
14 PreAuthTx(PreAuthTx),
15 HashX(HashX),
16 MuxedAccountEd25519(ed25519::MuxedAccount),
17 SignedPayloadEd25519(ed25519::SignedPayload),
18 Contract(Contract),
19}
20
21impl Strkey {
22 pub fn to_string(&self) -> String {
23 match self {
24 Self::PublicKeyEd25519(x) => x.to_string(),
25 Self::PrivateKeyEd25519(x) => x.to_string(),
26 Self::PreAuthTx(x) => x.to_string(),
27 Self::HashX(x) => x.to_string(),
28 Self::MuxedAccountEd25519(x) => x.to_string(),
29 Self::SignedPayloadEd25519(x) => x.to_string(),
30 Self::Contract(x) => x.to_string(),
31 }
32 }
33
34 pub fn from_string(s: &str) -> Result<Self, DecodeError> {
35 let (ver, payload) = decode(s)?;
36 match ver {
37 version::PUBLIC_KEY_ED25519 => Ok(Self::PublicKeyEd25519(
38 ed25519::PublicKey::from_payload(&payload)?,
39 )),
40 version::PRIVATE_KEY_ED25519 => Ok(Self::PrivateKeyEd25519(
41 ed25519::PrivateKey::from_payload(&payload)?,
42 )),
43 version::PRE_AUTH_TX => Ok(Self::PreAuthTx(PreAuthTx::from_payload(&payload)?)),
44 version::HASH_X => Ok(Self::HashX(HashX::from_payload(&payload)?)),
45 version::MUXED_ACCOUNT_ED25519 => Ok(Self::MuxedAccountEd25519(
46 ed25519::MuxedAccount::from_payload(&payload)?,
47 )),
48 version::SIGNED_PAYLOAD_ED25519 => Ok(Self::SignedPayloadEd25519(
49 ed25519::SignedPayload::from_payload(&payload)?,
50 )),
51 version::CONTRACT => Ok(Self::Contract(Contract::from_payload(&payload)?)),
52 _ => Err(DecodeError::Invalid),
53 }
54 }
55}
56
57impl Display for Strkey {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 write!(f, "{}", self.to_string())
60 }
61}
62
63impl FromStr for Strkey {
64 type Err = DecodeError;
65
66 fn from_str(s: &str) -> Result<Self, Self::Err> {
67 Strkey::from_string(s)
68 }
69}
70
71#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
72pub struct PreAuthTx(pub [u8; 32]);
73
74impl Debug for PreAuthTx {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 write!(f, "PreAuthTx(")?;
77 write!(
78 f,
79 "{}",
80 &self
81 .0
82 .iter()
83 .map(|b| format!("{b:02x}"))
84 .collect::<String>()
85 )?;
86 write!(f, ")")?;
87 Ok(())
88 }
89}
90
91impl PreAuthTx {
92 pub fn to_string(&self) -> String {
93 encode(version::PRE_AUTH_TX, &self.0)
94 }
95
96 fn from_payload(payload: &[u8]) -> Result<Self, DecodeError> {
97 Ok(Self(payload.try_into().map_err(|_| DecodeError::Invalid)?))
98 }
99
100 pub fn from_string(s: &str) -> Result<Self, DecodeError> {
101 let (ver, payload) = decode(s)?;
102 match ver {
103 version::PRE_AUTH_TX => Self::from_payload(&payload),
104 _ => Err(DecodeError::Invalid),
105 }
106 }
107}
108
109impl Display for PreAuthTx {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 write!(f, "{}", self.to_string())
112 }
113}
114
115impl FromStr for PreAuthTx {
116 type Err = DecodeError;
117
118 fn from_str(s: &str) -> Result<Self, Self::Err> {
119 PreAuthTx::from_string(s)
120 }
121}
122
123#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
124pub struct HashX(pub [u8; 32]);
125
126impl Debug for HashX {
127 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128 write!(f, "HashX(")?;
129 write!(
130 f,
131 "{}",
132 &self
133 .0
134 .iter()
135 .map(|b| format!("{b:02x}"))
136 .collect::<String>()
137 )?;
138 write!(f, ")")?;
139 Ok(())
140 }
141}
142
143impl HashX {
144 pub fn to_string(&self) -> String {
145 encode(version::HASH_X, &self.0)
146 }
147
148 fn from_payload(payload: &[u8]) -> Result<Self, DecodeError> {
149 Ok(Self(payload.try_into().map_err(|_| DecodeError::Invalid)?))
150 }
151
152 pub fn from_string(s: &str) -> Result<Self, DecodeError> {
153 let (ver, payload) = decode(s)?;
154 match ver {
155 version::HASH_X => Self::from_payload(&payload),
156 _ => Err(DecodeError::Invalid),
157 }
158 }
159}
160
161impl Display for HashX {
162 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163 write!(f, "{}", self.to_string())
164 }
165}
166
167impl FromStr for HashX {
168 type Err = DecodeError;
169
170 fn from_str(s: &str) -> Result<Self, Self::Err> {
171 HashX::from_string(s)
172 }
173}
174
175#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
176pub struct Contract(pub [u8; 32]);
177
178impl Debug for Contract {
179 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
180 write!(f, "Contract(")?;
181 write!(
182 f,
183 "{}",
184 &self
185 .0
186 .iter()
187 .map(|b| format!("{b:02x}"))
188 .collect::<String>()
189 )?;
190 write!(f, ")")?;
191 Ok(())
192 }
193}
194
195impl Contract {
196 pub fn to_string(&self) -> String {
197 encode(version::CONTRACT, &self.0)
198 }
199
200 fn from_payload(payload: &[u8]) -> Result<Self, DecodeError> {
201 Ok(Self(payload.try_into().map_err(|_| DecodeError::Invalid)?))
202 }
203
204 pub fn from_string(s: &str) -> Result<Self, DecodeError> {
205 let (ver, payload) = decode(s)?;
206 match ver {
207 version::CONTRACT => Self::from_payload(&payload),
208 _ => Err(DecodeError::Invalid),
209 }
210 }
211}
212
213impl Display for Contract {
214 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
215 write!(f, "{}", self.to_string())
216 }
217}
218
219impl FromStr for Contract {
220 type Err = DecodeError;
221
222 fn from_str(s: &str) -> Result<Self, Self::Err> {
223 Contract::from_string(s)
224 }
225}