1use codec::{Compact, CompactAs, Decode, Encode};
2
3use core::{fmt, str::FromStr};
4
5#[cfg(feature = "serde")]
6use serde::{de::DeserializeOwned, ser, Deserialize, Serialize};
7
8#[cfg(all(feature = "std", feature = "type_info"))]
9use scale_info::TypeInfo;
10
11#[cfg(not(feature = "std"))]
12use alloc::{format, string::String};
13use sp_core::crypto::Ss58Codec;
14use sp_std::prelude::*;
15
16pub use frame_metadata;
18
19pub use sp_core;
20
21pub use sp_core::hashing;
22
23pub use sp_weights;
24
25pub use sp_runtime::MultiSignature;
26
27#[derive(
29 Clone, Copy, Debug, Encode, Decode, CompactAs, Default, PartialEq, Eq, PartialOrd, Ord,
30)]
31#[cfg_attr(all(feature = "std", feature = "type_info"), derive(TypeInfo))]
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33#[cfg_attr(feature = "serde", serde(transparent))]
34pub struct OldWeight(pub u64);
35
36pub mod per_things {
38 use super::*;
39
40 #[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord)]
41 #[cfg_attr(feature = "std", derive(Hash))]
42 #[cfg_attr(all(feature = "std", feature = "type_info"), derive(TypeInfo))]
43 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
44 pub struct Perbill(pub u32);
45
46 impl CompactAs for Perbill {
47 type As = u32;
48
49 fn encode_as(&self) -> &Self::As {
50 &self.0
51 }
52
53 fn decode_from(v: Self::As) -> Result<Self, codec::Error> {
54 Ok(Self(v))
55 }
56 }
57
58 impl From<Compact<Self>> for Perbill {
59 fn from(c: Compact<Self>) -> Self {
60 c.0
61 }
62 }
63
64 impl From<sp_arithmetic::per_things::Perbill> for Perbill {
65 fn from(p: sp_arithmetic::per_things::Perbill) -> Self {
66 Self(p.deconstruct())
67 }
68 }
69
70 #[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord)]
71 #[cfg_attr(feature = "std", derive(Hash))]
72 #[cfg_attr(all(feature = "std", feature = "type_info"), derive(TypeInfo))]
73 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
74 pub struct PerU16(pub u16);
75
76 impl CompactAs for PerU16 {
77 type As = u16;
78
79 fn encode_as(&self) -> &Self::As {
80 &self.0
81 }
82
83 fn decode_from(v: Self::As) -> Result<Self, codec::Error> {
84 Ok(Self(v))
85 }
86 }
87
88 impl From<Compact<Self>> for PerU16 {
89 fn from(c: Compact<Self>) -> Self {
90 c.0
91 }
92 }
93
94 impl From<sp_arithmetic::per_things::PerU16> for PerU16 {
95 fn from(p: sp_arithmetic::per_things::PerU16) -> Self {
96 Self(p.deconstruct())
97 }
98 }
99
100 #[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord)]
101 #[cfg_attr(feature = "std", derive(Hash))]
102 #[cfg_attr(all(feature = "std", feature = "type_info"), derive(TypeInfo))]
103 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
104 pub struct Permill(pub u32);
105
106 impl CompactAs for Permill {
107 type As = u32;
108
109 fn encode_as(&self) -> &Self::As {
110 &self.0
111 }
112
113 fn decode_from(v: Self::As) -> Result<Self, codec::Error> {
114 Ok(Self(v))
115 }
116 }
117
118 impl From<Compact<Self>> for Permill {
119 fn from(c: Compact<Self>) -> Self {
120 c.0
121 }
122 }
123
124 impl From<sp_arithmetic::per_things::Permill> for Permill {
125 fn from(p: sp_arithmetic::per_things::Permill) -> Self {
126 Self(p.deconstruct())
127 }
128 }
129
130 #[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord)]
131 #[cfg_attr(feature = "std", derive(Hash))]
132 #[cfg_attr(all(feature = "std", feature = "type_info"), derive(TypeInfo))]
133 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
134 pub struct Percent(pub u8);
135
136 impl CompactAs for Percent {
137 type As = u8;
138
139 fn encode_as(&self) -> &Self::As {
140 &self.0
141 }
142
143 fn decode_from(v: Self::As) -> Result<Self, codec::Error> {
144 Ok(Self(v))
145 }
146 }
147
148 impl From<Compact<Self>> for Percent {
149 fn from(c: Compact<Self>) -> Self {
150 c.0
151 }
152 }
153
154 impl From<sp_arithmetic::per_things::Percent> for Percent {
155 fn from(p: sp_arithmetic::per_things::Percent) -> Self {
156 Self(p.deconstruct())
157 }
158 }
159}
160
161#[cfg(not(feature = "serde"))]
162pub trait AccountTraits: Clone + Encode + Decode + Default + FromStr {}
163
164#[cfg(not(feature = "serde"))]
165impl<T> AccountTraits for T where T: Clone + Encode + Decode + Default + FromStr {}
166
167#[cfg(feature = "serde")]
168pub trait AccountTraits:
169 Clone + Encode + Decode + Default + FromStr + ser::Serialize + DeserializeOwned
170{
171}
172
173#[cfg(feature = "serde")]
174impl<T> AccountTraits for T where
175 T: Clone + Encode + Decode + Default + FromStr + ser::Serialize + DeserializeOwned
176{
177}
178
179#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord)]
181#[cfg_attr(feature = "std", derive(Hash))]
182#[cfg_attr(all(feature = "std", feature = "type_info"), derive(TypeInfo))]
183pub enum MultiAddress<AccountId: AccountTraits, AccountIndex: AccountTraits> {
184 Id(AccountId),
186 Index(#[codec(compact)] AccountIndex),
188 Raw(Vec<u8>),
190 Address32([u8; 32]),
192 Address20([u8; 20]),
194}
195
196impl<AccountId: AccountTraits, AccountIndex: AccountTraits> From<&AccountId>
197 for MultiAddress<AccountId, AccountIndex>
198{
199 fn from(other: &AccountId) -> Self {
200 Self::Id(other.clone())
201 }
202}
203
204impl<AccountId: AccountTraits, AccountIndex: AccountTraits> From<AccountId>
205 for MultiAddress<AccountId, AccountIndex>
206{
207 fn from(other: AccountId) -> Self {
208 Self::Id(other)
209 }
210}
211
212impl<AccountIndex: AccountTraits> From<sp_runtime::AccountId32>
213 for MultiAddress<AccountId, AccountIndex>
214{
215 fn from(other: sp_runtime::AccountId32) -> Self {
216 Self::Id(other.into())
217 }
218}
219
220impl<AccountId: AccountTraits, AccountIndex: AccountTraits>
221 From<sp_runtime::MultiAddress<AccountId, AccountIndex>>
222 for MultiAddress<AccountId, AccountIndex>
223{
224 fn from(other: sp_runtime::MultiAddress<AccountId, AccountIndex>) -> Self {
225 match other {
226 sp_runtime::MultiAddress::Id(v) => Self::Id(v),
227 sp_runtime::MultiAddress::Index(v) => Self::Index(v),
228 sp_runtime::MultiAddress::Raw(v) => Self::Raw(v),
229 sp_runtime::MultiAddress::Address32(v) => Self::Address32(v),
230 sp_runtime::MultiAddress::Address20(v) => Self::Address20(v),
231 }
232 }
233}
234
235impl<AccountId: AccountTraits, AccountIndex: AccountTraits>
236 From<&sp_runtime::MultiAddress<AccountId, AccountIndex>>
237 for MultiAddress<AccountId, AccountIndex>
238{
239 fn from(other: &sp_runtime::MultiAddress<AccountId, AccountIndex>) -> Self {
240 Self::from(other.clone())
241 }
242}
243
244#[derive(Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Encode, Decode)]
245#[cfg_attr(all(feature = "std", feature = "type_info"), derive(TypeInfo))]
246pub struct AccountId(pub [u8; 32]);
247
248impl AccountId {
249 pub fn to_hex(&self) -> String {
250 format!("0x{}", hex::encode(&self.0))
251 }
252}
253
254impl FromStr for AccountId {
255 type Err = crate::Error;
256
257 fn from_str(s: &str) -> Result<Self, Self::Err> {
258 match s.len() {
259 66 if s.starts_with("0x") => {
260 let mut id = AccountId::default();
261 hex::decode_to_slice(&s[2..], &mut id.0)?;
262 Ok(id)
263 }
264 64 => {
265 let mut id = AccountId::default();
266 hex::decode_to_slice(&s[0..], &mut id.0)?;
267 Ok(id)
268 }
269 _ => Ok(AccountId::from_ss58check(s)?),
270 }
271 }
272}
273
274#[cfg(not(feature = "serde"))]
275impl AccountId {
276 pub fn to_ss58check(&self) -> String {
277 format!("0x{}", hex::encode(&self.0))
278 }
279}
280
281impl Ss58Codec for AccountId {}
282
283impl fmt::Display for AccountId {
284 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
285 write!(f, "{}", self.to_ss58check())
286 }
287}
288
289impl fmt::Debug for AccountId {
290 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
291 let ss58 = self.to_ss58check();
292 let h = hex::encode(&self.0);
293 write!(f, "0x{} ({}...)", h, &ss58[0..8])
294 }
295}
296
297impl<'a> TryFrom<&'a [u8]> for AccountId {
298 type Error = ();
299
300 fn try_from(x: &'a [u8]) -> Result<Self, ()> {
301 Ok(AccountId(x.try_into().map_err(|_| ())?))
302 }
303}
304
305impl AsMut<[u8; 32]> for AccountId {
306 fn as_mut(&mut self) -> &mut [u8; 32] {
307 &mut self.0
308 }
309}
310
311impl AsMut<[u8]> for AccountId {
312 fn as_mut(&mut self) -> &mut [u8] {
313 &mut self.0[..]
314 }
315}
316
317impl AsRef<[u8; 32]> for AccountId {
318 fn as_ref(&self) -> &[u8; 32] {
319 &self.0
320 }
321}
322
323impl AsRef<[u8]> for AccountId {
324 fn as_ref(&self) -> &[u8] {
325 &self.0[..]
326 }
327}
328
329impl sp_core::ByteArray for AccountId {
330 const LEN: usize = 32;
331}
332
333impl From<[u8; 32]> for AccountId {
334 fn from(p: [u8; 32]) -> Self {
335 Self(p)
336 }
337}
338
339impl From<sp_core::sr25519::Public> for AccountId {
340 fn from(p: sp_core::sr25519::Public) -> Self {
341 p.0.into()
342 }
343}
344
345impl From<sp_core::ed25519::Public> for AccountId {
346 fn from(p: sp_core::ed25519::Public) -> Self {
347 p.0.into()
348 }
349}
350
351impl From<sp_runtime::AccountId32> for AccountId {
352 fn from(id: sp_runtime::AccountId32) -> Self {
353 Self(*id.as_ref())
354 }
355}
356
357impl From<&sp_runtime::AccountId32> for AccountId {
358 fn from(id: &sp_runtime::AccountId32) -> Self {
359 Self(*id.as_ref())
360 }
361}
362
363impl From<AccountId> for sp_runtime::AccountId32 {
364 fn from(id: AccountId) -> Self {
365 Self::new(id.0)
366 }
367}
368
369impl From<&AccountId> for sp_runtime::AccountId32 {
370 fn from(id: &AccountId) -> Self {
371 Self::new(id.0)
372 }
373}
374
375pub type GenericAddress = MultiAddress<AccountId, u32>;
376
377#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Encode, Decode)]
378#[cfg_attr(all(feature = "std", feature = "type_info"), derive(TypeInfo))]
379#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
380#[cfg_attr(
381 feature = "utoipa",
382 schema(value_type = String, format = Binary, example = "0x0600000000000000000000000000000000000000000000000000000000000000")
383)]
384pub struct IdentityId(pub [u8; 32]);
385
386impl fmt::Display for IdentityId {
387 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
388 let h = hex::encode(&self.0);
389 write!(f, "0x{}", h)
390 }
391}
392
393impl fmt::Debug for IdentityId {
394 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
395 let h = hex::encode(&self.0);
396 write!(f, "0x{}", h)
397 }
398}
399
400#[derive(Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Encode, Decode)]
401#[cfg_attr(all(feature = "std", feature = "type_info"), derive(TypeInfo))]
402#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
403#[cfg_attr(
404 feature = "utoipa",
405 schema(value_type = String, format = Binary, example = "67e55044-10b1-426f-9247-bb680e5fe0c8")
406)]
407pub struct AssetId(pub [u8; 16]);
408
409impl AssetId {
410 pub fn as_uuid(&self) -> uuid::Uuid {
411 uuid::Uuid::from_bytes(self.0)
412 }
413}
414
415impl fmt::Display for AssetId {
416 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
417 self.as_uuid().fmt(f)
418 }
419}
420
421impl fmt::Debug for AssetId {
422 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
423 self.as_uuid().fmt(f)
424 }
425}
426
427impl From<uuid::Uuid> for AssetId {
428 fn from(uuid: uuid::Uuid) -> Self {
429 Self(uuid.into_bytes())
430 }
431}
432
433impl FromStr for AssetId {
434 type Err = uuid::Error;
435
436 fn from_str(uuid_str: &str) -> Result<Self, Self::Err> {
437 let uuid = uuid::Uuid::parse_str(uuid_str)?;
438 Ok(uuid.into())
439 }
440}
441
442impl TryFrom<&'_ str> for AssetId {
443 type Error = uuid::Error;
444
445 fn try_from(uuid_str: &'_ str) -> Result<Self, Self::Error> {
446 let uuid = uuid::Uuid::parse_str(uuid_str)?;
447 Ok(uuid.into())
448 }
449}
450
451#[cfg(test)]
452mod tests {
453 use super::*;
454 use serde_json::json;
455
456 #[test]
457 fn account_id_deserialize() {
458 let json_hex = json!("0x788b804aeea9afcf7042c6ee45ddc2a394f4e225918e3261a9b5ed5069037d09");
459 let json_ss58 = json!("5Enm3VfZioxHVBpZgJcACv7pZPZZeYWymvrZ9cxkXhNHJWe5");
460 let expected = AccountId::from_ss58check("5Enm3VfZioxHVBpZgJcACv7pZPZZeYWymvrZ9cxkXhNHJWe5")
461 .expect("AccountId");
462
463 let decoded: AccountId = serde_json::from_str(&json_hex.to_string()).expect("decode as json");
464 assert_eq!(decoded, expected);
465 let decoded: AccountId = serde_json::from_str(&json_ss58.to_string()).expect("decode as json");
466 assert_eq!(decoded, expected);
467 }
468
469 #[test]
470 fn account_id_roundtrip() {
471 let account = AccountId::from_ss58check("5Enm3VfZioxHVBpZgJcACv7pZPZZeYWymvrZ9cxkXhNHJWe5")
472 .expect("AccountId");
473 let data = serde_json::to_string(&account).expect("encode json");
474 let decoded: AccountId = serde_json::from_str(&data).expect("decode as json");
475 assert_eq!(decoded, account);
476 }
477
478 #[test]
479 fn asset_id_roundtrip() {
480 let asset: AssetId = "67e55044-10b1-426f-9247-bb680e5fe0c8"
481 .parse()
482 .expect("AssetId");
483 let data = serde_json::to_string(&asset).expect("encode json");
484 let decoded: AssetId = serde_json::from_str(&data).expect("decode as json");
485 assert_eq!(decoded, asset);
486 }
487
488 #[test]
489 fn asset_id_display() {
490 let str_id = "67e55044-10b1-426f-9247-bb680e5fe0c8";
491 let asset: AssetId = str_id.parse().expect("AssetId");
492 let display_id = format!("{asset}");
493 assert_eq!(display_id, str_id);
494 }
495
496 #[test]
497 fn multi_address_roundtrip() {
498 let account = AccountId::from_ss58check("5Enm3VfZioxHVBpZgJcACv7pZPZZeYWymvrZ9cxkXhNHJWe5")
499 .expect("AccountId");
500 let address = GenericAddress::Id(account);
502 let data = serde_json::to_string(&address).expect("encode json");
503 eprintln!("MultiAddress::Id = {data}");
504 let decoded: GenericAddress = serde_json::from_str(&data).expect("decode as json");
505 assert_eq!(decoded, address);
506 let address = GenericAddress::Index(1234);
508 let data = serde_json::to_string(&address).expect("encode json");
509 eprintln!("MultiAddress::Index = {data}");
510 let decoded: GenericAddress = serde_json::from_str(&data).expect("decode as json");
511 assert_eq!(decoded, address);
512 let address = GenericAddress::Raw(vec![0, 1, 2, 3, 4, 5]);
514 let data = serde_json::to_string(&address).expect("encode json");
515 eprintln!("MultiAddress::Raw = {data}");
516 let decoded: GenericAddress = serde_json::from_str(&data).expect("decode as json");
517 assert_eq!(decoded, address);
518 let address = GenericAddress::Address32([1; 32]);
520 let data = serde_json::to_string(&address).expect("encode json");
521 eprintln!("MultiAddress::Address32 = {data}");
522 let decoded: GenericAddress = serde_json::from_str(&data).expect("decode as json");
523 assert_eq!(decoded, address);
524 let address = GenericAddress::Address20([2; 20]);
526 let data = serde_json::to_string(&address).expect("encode json");
527 eprintln!("MultiAddress::Address20 = {data}");
528 let decoded: GenericAddress = serde_json::from_str(&data).expect("decode as json");
529 assert_eq!(decoded, address);
530 }
531}