snapshot before rebranding

This commit is contained in:
2025-12-14 07:37:21 +03:00
parent 5520d491a5
commit 09735eb97a
1752 changed files with 58116 additions and 15986 deletions
+130
View File
@@ -0,0 +1,130 @@
// Copyright (C) 2021-2022 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use super::*;
/// A custom address format. See also [`Ss58AddressFormatRegistry`]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Ss58AddressFormat {
prefix: u16,
}
/// An enumeration of unique networks.
/// Some are reserved.
impl Ss58AddressFormat {
/// Custom constructor
#[inline]
pub fn custom(prefix: u16) -> Self {
Ss58AddressFormat { prefix }
}
/// Address prefix used on the network
pub const fn prefix(&self) -> u16 {
self.prefix
}
/// names of all address formats
pub fn all_names() -> &'static [&'static str] {
&ALL_SS58_ADDRESS_FORMAT_NAMES
}
/// All known address formats.
pub fn all() -> &'static [Ss58AddressFormatRegistry] {
&ALL_SS58_ADDRESS_FORMATS
}
}
/// Display the name of the address format (not the description).
#[cfg(feature = "std")]
impl std::fmt::Display for Ss58AddressFormat {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
if let Ok(lookup) =
PREFIX_TO_INDEX.binary_search_by_key(&self.prefix, |(prefix, _)| *prefix)
{
let (_, idx) = PREFIX_TO_INDEX[lookup];
write!(f, "{}", ALL_SS58_ADDRESS_FORMAT_NAMES[idx])
} else {
write!(f, "{}", self.prefix)
}
}
}
/// const function to convert [`Ss58AddressFormat`] to u16
pub const fn from_address_format(x: Ss58AddressFormat) -> u16 {
x.prefix
}
impl From<Ss58AddressFormatRegistry> for Ss58AddressFormat {
fn from(x: Ss58AddressFormatRegistry) -> Ss58AddressFormat {
Ss58AddressFormat { prefix: x as u16 }
}
}
impl From<u8> for Ss58AddressFormat {
#[inline]
fn from(x: u8) -> Ss58AddressFormat {
Ss58AddressFormat::from(u16::from(x))
}
}
impl From<Ss58AddressFormat> for u16 {
#[inline]
fn from(x: Ss58AddressFormat) -> u16 {
from_address_format(x)
}
}
impl From<u16> for Ss58AddressFormat {
#[inline]
fn from(prefix: u16) -> Ss58AddressFormat {
Ss58AddressFormat { prefix }
}
}
impl<'a> TryFrom<&'a str> for Ss58AddressFormat {
type Error = ParseError;
fn try_from(x: &'a str) -> Result<Ss58AddressFormat, Self::Error> {
Ss58AddressFormatRegistry::try_from(x).map(|a| a.into())
}
}
impl<'a> TryFrom<&'a str> for Ss58AddressFormatRegistry {
type Error = ParseError;
fn try_from(x: &'a str) -> Result<Ss58AddressFormatRegistry, Self::Error> {
ALL_SS58_ADDRESS_FORMAT_NAMES
.into_iter()
.position(|n| n.eq_ignore_ascii_case(x))
.map(|lookup| ALL_SS58_ADDRESS_FORMATS[lookup])
.ok_or(ParseError)
}
}
#[cfg(feature = "std")]
impl From<Ss58AddressFormat> for String {
fn from(x: Ss58AddressFormat) -> String {
x.to_string()
}
}
#[cfg(feature = "std")]
impl std::str::FromStr for Ss58AddressFormatRegistry {
type Err = ParseError;
fn from_str(data: &str) -> Result<Self, Self::Err> {
TryFrom::try_from(data)
}
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright (C) 2021-2022 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Error encountered while parsing `Ss58AddressFormat` from &'_ str
/// unit struct for now.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct ParseError;
#[cfg(feature = "std")]
impl std::fmt::Display for ParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "failed to parse network value as u16")
}
}
#[cfg(feature = "std")]
impl std::error::Error for ParseError {}
+35
View File
@@ -0,0 +1,35 @@
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs)]
#![deny(unsafe_code)]
//! Enumerations of well-known SS58 account types and tokens used in the Polkadot ecosystem.
use core::convert::TryFrom;
mod address_format;
mod error;
mod registry;
#[cfg(test)]
mod tests;
mod token;
pub use address_format::{from_address_format, Ss58AddressFormat};
pub use error::ParseError;
pub use registry::{from_known_address_format, Ss58AddressFormatRegistry, TokenRegistry};
pub use token::{Token, TokenAmount};
#[cfg(feature = "std")]
use registry::PREFIX_TO_INDEX;
use registry::{ALL_SS58_ADDRESS_FORMATS, ALL_SS58_ADDRESS_FORMAT_NAMES};
+58
View File
@@ -0,0 +1,58 @@
// Copyright (C) 2021-2022 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use super::*;
include!(concat!(env!("OUT_DIR"), "/registry_gen.rs"));
#[cfg(feature = "std")]
impl std::fmt::Display for Ss58AddressFormatRegistry {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let lookup = PREFIX_TO_INDEX
.binary_search_by_key(&from_known_address_format(*self), |(prefix, _)| *prefix)
.expect("always be found");
let (_, idx) = PREFIX_TO_INDEX[lookup];
write!(f, "{}", ALL_SS58_ADDRESS_FORMAT_NAMES[idx])
}
}
impl TryFrom<Ss58AddressFormat> for Ss58AddressFormatRegistry {
type Error = ParseError;
fn try_from(x: Ss58AddressFormat) -> Result<Ss58AddressFormatRegistry, ParseError> {
PREFIX_TO_INDEX
.binary_search_by_key(&x.prefix(), |(prefix, _)| *prefix)
.map(|lookup| {
let (_, idx) = PREFIX_TO_INDEX[lookup];
ALL_SS58_ADDRESS_FORMATS[idx]
})
.map_err(|_| ParseError)
}
}
/// const function to convert [`Ss58AddressFormat`] to u16
pub const fn from_known_address_format(x: Ss58AddressFormatRegistry) -> u16 {
x as u16
}
impl core::fmt::Debug for TokenRegistry {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let token: Token = (*self).into();
f.debug_struct("TokenRegistry")
.field("name", &token.name)
.field("decimals", &token.decimals)
.finish()
}
}
+73
View File
@@ -0,0 +1,73 @@
// Copyright (C) 2021-2022 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use super::{Ss58AddressFormat, Ss58AddressFormatRegistry, TokenRegistry};
#[test]
fn is_reserved() {
let reserved: Ss58AddressFormat = Ss58AddressFormatRegistry::Reserved46Account.into();
assert!(reserved.is_reserved());
let not_reserved: Ss58AddressFormat = Ss58AddressFormatRegistry::PolkadexAccount.into();
assert!(!not_reserved.is_reserved());
assert!(!Ss58AddressFormat::custom(100).is_reserved());
}
#[test]
fn is_custom() {
assert!(Ss58AddressFormat::custom(432).is_custom());
let reserved: Ss58AddressFormat = Ss58AddressFormatRegistry::Reserved46Account.into();
assert!(!reserved.is_custom());
let not_reserved: Ss58AddressFormat = Ss58AddressFormatRegistry::PolkadexAccount.into();
assert!(!not_reserved.is_custom());
}
#[cfg(feature = "std")]
#[test]
fn enum_to_name_and_back() {
use std::convert::TryInto;
for name in Ss58AddressFormat::all_names() {
let val: Ss58AddressFormatRegistry = (*name).try_into().expect(name);
assert_eq!(name, &val.to_string());
let val: Ss58AddressFormatRegistry = name.to_lowercase().as_str().try_into().expect(name);
assert_eq!(name, &val.to_string());
let val: Ss58AddressFormatRegistry =
name.to_ascii_uppercase().as_str().try_into().expect(name);
assert_eq!(name, &val.to_string());
}
}
#[test]
fn prefix() {
let dot: Ss58AddressFormat = Ss58AddressFormatRegistry::PolkadotAccount.into();
assert_eq!(dot.prefix(), 0);
let ksm: Ss58AddressFormat = Ss58AddressFormatRegistry::KusamaAccount.into();
assert_eq!(ksm.prefix(), 2);
}
#[test]
fn tokens() {
let polka = Ss58AddressFormatRegistry::PolkadotAccount;
assert_eq!(polka.tokens(), &[TokenRegistry::Dot]);
let kusama = Ss58AddressFormatRegistry::KusamaAccount;
assert_eq!(kusama.tokens(), &[TokenRegistry::Ksm]);
let n46 = Ss58AddressFormatRegistry::Reserved46Account;
assert_eq!(n46.tokens(), &[]);
}
+110
View File
@@ -0,0 +1,110 @@
// Copyright (C) 2021-2022 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#[cfg(feature = "std")]
use num_format::{Locale, ToFormattedString};
/// Name and decimals of a given token.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Token {
/// The short name (ticker) of the token
pub name: &'static str,
/// The number of decimals the token has (smallest granularity of the token)
pub decimals: u8,
}
impl core::fmt::Debug for Token {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Token")
.field("name", &self.name)
.field("decimals", &self.decimals)
.finish()
}
}
impl Token {
/// Creates the specified amount of [`Token`] with its name and decimals filled from the
/// [`TokenRegistry`] variant.
///
/// ```
/// # use ss58_registry::{Token, TokenRegistry};
/// # #[cfg(feature = "std")]
/// # fn x() {
/// let token: Token = TokenRegistry::Dot.into();
/// let my_amount = token.amount(100_000_000);
/// assert_eq!(format!("{}", my_amount), "0.010 DOT");
/// assert_eq!(format!("{:?}", my_amount), "0.010 DOT (100,000,000)");
/// # }
/// # #[cfg(not(feature = "std"))]
/// # fn x() {}
/// # x();
/// ```
pub fn amount(&self, amount: u128) -> TokenAmount {
TokenAmount { token: self.clone(), amount }
}
}
/// A given amount of token. Can be used for nicely formatted output and token-aware comparison of
/// different amounts.
///
/// ```
/// # use ss58_registry::{Token, TokenAmount};
/// # #[cfg(feature = "std")]
/// # fn x() {
/// let token = Token { name: "I❤U", decimals: 8 };
/// let my_amount = token.amount(100_000_000_000);
/// assert_eq!(format!("{}", my_amount), "1,000.000 I❤U");
/// assert_eq!(format!("{:?}", my_amount), "1000.000 I❤U (100,000,000,000)");
/// # }
/// # #[cfg(not(feature = "std"))]
/// # fn x() {}
/// # x();
/// ```
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TokenAmount {
/// The token this amount is from.
pub token: Token,
/// The amount in the smallest granularity of the token.
pub amount: u128,
}
#[cfg(feature = "std")]
impl std::fmt::Display for TokenAmount {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let multiplier = u128::pow(10, self.token.decimals as u32);
write!(
f,
"{}.{:0>3} {}",
(self.amount / multiplier).to_formatted_string(&Locale::en),
self.amount % multiplier / (multiplier / 1000),
self.token.name
)
}
}
#[cfg(feature = "std")]
impl std::fmt::Debug for TokenAmount {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let multiplier = u128::pow(10, self.token.decimals as u32);
write!(
f,
"{}.{:0>3} {} ({})",
self.amount / multiplier,
self.amount % multiplier / (multiplier / 1000),
self.token.name,
self.amount.to_formatted_string(&Locale::en),
)
}
}