1use crate::{
21 crypto::{CryptoType, Derive, FromEntropy, Public, Signature, UncheckedFrom},
22 hash::{H256, H512},
23};
24
25use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
26use core::marker::PhantomData;
27use scale_info::TypeInfo;
28
29#[cfg(feature = "serde")]
30use crate::crypto::Ss58Codec;
31#[cfg(feature = "serde")]
32use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
33
34#[cfg(all(not(feature = "std"), feature = "serde"))]
35use alloc::{format, string::String};
36
37pub use public_bytes::*;
38pub use signature_bytes::*;
39
40#[derive(Encode, Decode, DecodeWithMemTracking, MaxEncodedLen)]
49#[repr(transparent)]
50pub struct CryptoBytes<const N: usize, T = ()>(pub [u8; N], PhantomData<fn() -> T>);
51
52impl<const N: usize, T> Copy for CryptoBytes<N, T> {}
53
54impl<const N: usize, T> Clone for CryptoBytes<N, T> {
55 fn clone(&self) -> Self {
56 Self(self.0, PhantomData)
57 }
58}
59
60impl<const N: usize, T> TypeInfo for CryptoBytes<N, T> {
61 type Identity = [u8; N];
62
63 fn type_info() -> scale_info::Type {
64 Self::Identity::type_info()
65 }
66}
67
68impl<const N: usize, T> PartialOrd for CryptoBytes<N, T> {
69 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
70 self.0.partial_cmp(&other.0)
71 }
72}
73
74impl<const N: usize, T> Ord for CryptoBytes<N, T> {
75 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
76 self.0.cmp(&other.0)
77 }
78}
79
80impl<const N: usize, T> PartialEq for CryptoBytes<N, T> {
81 fn eq(&self, other: &Self) -> bool {
82 self.0.eq(&other.0)
83 }
84}
85
86impl<const N: usize, T> core::hash::Hash for CryptoBytes<N, T> {
87 fn hash<H: scale_info::prelude::hash::Hasher>(&self, state: &mut H) {
88 self.0.hash(state)
89 }
90}
91
92impl<const N: usize, T> Eq for CryptoBytes<N, T> {}
93
94impl<const N: usize, T> Default for CryptoBytes<N, T> {
95 fn default() -> Self {
96 Self([0_u8; N], PhantomData)
97 }
98}
99
100impl<const N: usize, T> AsRef<[u8]> for CryptoBytes<N, T> {
101 fn as_ref(&self) -> &[u8] {
102 &self.0[..]
103 }
104}
105
106impl<const N: usize, T> AsMut<[u8]> for CryptoBytes<N, T> {
107 fn as_mut(&mut self) -> &mut [u8] {
108 &mut self.0[..]
109 }
110}
111
112impl<const N: usize, T> From<CryptoBytes<N, T>> for [u8; N] {
113 fn from(v: CryptoBytes<N, T>) -> [u8; N] {
114 v.0
115 }
116}
117
118impl<const N: usize, T> AsRef<[u8; N]> for CryptoBytes<N, T> {
119 fn as_ref(&self) -> &[u8; N] {
120 &self.0
121 }
122}
123
124impl<const N: usize, T> AsMut<[u8; N]> for CryptoBytes<N, T> {
125 fn as_mut(&mut self) -> &mut [u8; N] {
126 &mut self.0
127 }
128}
129
130impl<const N: usize, T> From<[u8; N]> for CryptoBytes<N, T> {
131 fn from(value: [u8; N]) -> Self {
132 Self::from_raw(value)
133 }
134}
135
136impl<const N: usize, T> TryFrom<&[u8]> for CryptoBytes<N, T> {
137 type Error = ();
138
139 fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
140 if data.len() != N {
141 return Err(())
142 }
143 let mut r = [0u8; N];
144 r.copy_from_slice(data);
145 Ok(Self::from_raw(r))
146 }
147}
148
149impl<const N: usize, T> UncheckedFrom<[u8; N]> for CryptoBytes<N, T> {
150 fn unchecked_from(data: [u8; N]) -> Self {
151 Self::from_raw(data)
152 }
153}
154
155impl<const N: usize, T> core::ops::Deref for CryptoBytes<N, T> {
156 type Target = [u8];
157
158 fn deref(&self) -> &Self::Target {
159 &self.0
160 }
161}
162
163impl<const N: usize, T> CryptoBytes<N, T> {
164 pub fn from_raw(inner: [u8; N]) -> Self {
166 Self(inner, PhantomData)
167 }
168
169 pub fn to_raw(self) -> [u8; N] {
171 self.0
172 }
173
174 pub fn as_array_ref(&self) -> &[u8; N] {
176 &self.0
177 }
178}
179
180impl<const N: usize, T> crate::ByteArray for CryptoBytes<N, T> {
181 const LEN: usize = N;
182}
183
184impl<const N: usize, T> FromEntropy for CryptoBytes<N, T> {
185 fn from_entropy(input: &mut impl codec::Input) -> Result<Self, codec::Error> {
186 let mut result = Self::default();
187 input.read(result.as_mut())?;
188 Ok(result)
189 }
190}
191
192impl<T> From<CryptoBytes<32, T>> for H256 {
193 fn from(x: CryptoBytes<32, T>) -> H256 {
194 H256::from(x.0)
195 }
196}
197
198impl<T> From<CryptoBytes<64, T>> for H512 {
199 fn from(x: CryptoBytes<64, T>) -> H512 {
200 H512::from(x.0)
201 }
202}
203
204impl<T> UncheckedFrom<H256> for CryptoBytes<32, T> {
205 fn unchecked_from(x: H256) -> Self {
206 Self::from_h256(x)
207 }
208}
209
210impl<T> CryptoBytes<32, T> {
211 pub fn from_h256(x: H256) -> Self {
213 Self::from_raw(x.into())
214 }
215}
216
217impl<T> CryptoBytes<64, T> {
218 pub fn from_h512(x: H512) -> Self {
220 Self::from_raw(x.into())
221 }
222}
223
224mod public_bytes {
225 use super::*;
226
227 pub struct PublicTag;
229
230 pub type PublicBytes<const N: usize, SubTag> = CryptoBytes<N, (PublicTag, SubTag)>;
232
233 impl<const N: usize, SubTag> Derive for PublicBytes<N, SubTag> where Self: CryptoType {}
234
235 impl<const N: usize, SubTag> Public for PublicBytes<N, SubTag> where Self: CryptoType {}
236
237 impl<const N: usize, SubTag> core::fmt::Debug for PublicBytes<N, SubTag>
238 where
239 Self: CryptoType,
240 {
241 #[cfg(feature = "std")]
242 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
243 let s = self.to_ss58check();
244 write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.as_ref()), &s[0..8])
245 }
246
247 #[cfg(not(feature = "std"))]
248 fn fmt(&self, _: &mut core::fmt::Formatter) -> core::fmt::Result {
249 Ok(())
250 }
251 }
252
253 #[cfg(feature = "std")]
254 impl<const N: usize, SubTag> std::fmt::Display for PublicBytes<N, SubTag>
255 where
256 Self: CryptoType,
257 {
258 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
259 write!(f, "{}", self.to_ss58check())
260 }
261 }
262
263 #[cfg(feature = "std")]
264 impl<const N: usize, SubTag> std::str::FromStr for PublicBytes<N, SubTag>
265 where
266 Self: CryptoType,
267 {
268 type Err = crate::crypto::PublicError;
269
270 fn from_str(s: &str) -> Result<Self, Self::Err> {
271 Self::from_ss58check(s)
272 }
273 }
274
275 #[cfg(feature = "serde")]
276 impl<const N: usize, SubTag> Serialize for PublicBytes<N, SubTag>
277 where
278 Self: CryptoType,
279 {
280 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
281 where
282 S: Serializer,
283 {
284 serializer.serialize_str(&self.to_ss58check())
285 }
286 }
287
288 #[cfg(feature = "serde")]
289 impl<'de, const N: usize, SubTag> Deserialize<'de> for PublicBytes<N, SubTag>
290 where
291 Self: CryptoType,
292 {
293 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
294 where
295 D: Deserializer<'de>,
296 {
297 Self::from_ss58check(&String::deserialize(deserializer)?)
298 .map_err(|e| de::Error::custom(format!("{:?}", e)))
299 }
300 }
301}
302
303mod signature_bytes {
304 use super::*;
305
306 pub struct SignatureTag;
308
309 pub type SignatureBytes<const N: usize, SubTag> = CryptoBytes<N, (SignatureTag, SubTag)>;
311
312 impl<const N: usize, SubTag> Signature for SignatureBytes<N, SubTag> where Self: CryptoType {}
313
314 #[cfg(feature = "serde")]
315 impl<const N: usize, SubTag> Serialize for SignatureBytes<N, SubTag>
316 where
317 Self: CryptoType,
318 {
319 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
320 where
321 S: Serializer,
322 {
323 serializer.serialize_str(&array_bytes::bytes2hex("", self))
324 }
325 }
326
327 #[cfg(feature = "serde")]
328 impl<'de, const N: usize, SubTag> Deserialize<'de> for SignatureBytes<N, SubTag>
329 where
330 Self: CryptoType,
331 {
332 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
333 where
334 D: Deserializer<'de>,
335 {
336 let signature_hex = array_bytes::hex2bytes(&String::deserialize(deserializer)?)
337 .map_err(|e| de::Error::custom(format!("{:?}", e)))?;
338 Self::try_from(signature_hex.as_ref())
339 .map_err(|e| de::Error::custom(format!("{:?}", e)))
340 }
341 }
342
343 impl<const N: usize, SubTag> core::fmt::Debug for SignatureBytes<N, SubTag>
344 where
345 Self: CryptoType,
346 {
347 #[cfg(feature = "std")]
348 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
349 write!(f, "{}", crate::hexdisplay::HexDisplay::from(&&self.0[..]))
350 }
351
352 #[cfg(not(feature = "std"))]
353 fn fmt(&self, _: &mut core::fmt::Formatter) -> core::fmt::Result {
354 Ok(())
355 }
356 }
357}