// Copyright (C) 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::*; use crate::xcm_config::LocationToAccountId; use codec::{Decode, Encode, MaxEncodedLen}; use enumflags2::{bitflags, BitFlags}; use pezframe_support::{ parameter_types, traits::ConstU32, CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, }; use pezpallet_identity::{Data, IdentityInformationProvider}; use pezsp_runtime::{ traits::{AccountIdConversion, Verify}, RuntimeDebug, }; use scale_info::TypeInfo; use teyrchains_common::{impls::ToParentTreasury, DAYS}; parameter_types! { // 27 | Min encoded size of `Registration` // - 10 | Min encoded size of `IdentityInfo` // -----| // 17 | Min size without `IdentityInfo` (accounted for in byte deposit) pub const BasicDeposit: Balance = deposit(1, 17); pub const ByteDeposit: Balance = deposit(0, 1); pub const UsernameDeposit: Balance = deposit(0, 32); pub const SubAccountDeposit: Balance = deposit(1, 53); pub RelayTreasuryAccount: AccountId = teyrchains_common::TREASURY_PALLET_ID.into_account_truncating(); } impl pezpallet_identity::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type BasicDeposit = BasicDeposit; type ByteDeposit = ByteDeposit; type UsernameDeposit = UsernameDeposit; type SubAccountDeposit = SubAccountDeposit; type MaxSubAccounts = ConstU32<100>; type IdentityInformation = IdentityInfo; type MaxRegistrars = ConstU32<20>; type Slashed = ToParentTreasury; type ForceOrigin = EnsureRoot; type RegistrarOrigin = EnsureRoot; type OffchainSignature = Signature; type SigningPublicKey = ::Signer; type UsernameAuthorityOrigin = EnsureRoot; type PendingUsernameExpiration = ConstU32<{ 7 * DAYS }>; type UsernameGracePeriod = ConstU32<{ 3 * DAYS }>; type MaxSuffixLength = ConstU32<7>; type MaxUsernameLength = ConstU32<32>; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = (); type WeightInfo = weights::pezpallet_identity::WeightInfo; } /// The fields that we use to identify the owner of an account with. Each corresponds to a field /// in the `IdentityInfo` struct. #[bitflags] #[repr(u64)] #[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)] pub enum IdentityField { Display, Legal, Web, Matrix, Email, PgpFingerprint, Image, Twitter, GitHub, Discord, } /// Information concerning the identity of the controller of an account. #[derive( CloneNoBound, Encode, Decode, DecodeWithMemTracking, EqNoBound, MaxEncodedLen, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, )] #[codec(mel_bound())] pub struct IdentityInfo { /// A reasonable display name for the controller of the account. This should be whatever it is /// that it is typically known as and should not be confusable with other entities, given /// reasonable context. /// /// Stored as UTF-8. pub display: Data, /// The full legal name in the local jurisdiction of the entity. This might be a bit /// long-winded. /// /// Stored as UTF-8. pub legal: Data, /// A representative website held by the controller of the account. /// /// NOTE: `https://` is automatically prepended. /// /// Stored as UTF-8. pub web: Data, /// The Matrix (e.g. for Element) handle held by the controller of the account. Previously, /// this was called `riot`. /// /// Stored as UTF-8. pub matrix: Data, /// The email address of the controller of the account. /// /// Stored as UTF-8. pub email: Data, /// The PGP/GPG public key of the controller of the account. pub pgp_fingerprint: Option<[u8; 20]>, /// A graphic image representing the controller of the account. Should be a company, /// organization or project logo or a headshot in the case of a human. pub image: Data, /// The Twitter identity. The leading `@` character may be elided. pub twitter: Data, /// The GitHub username of the controller of the account. pub github: Data, /// The Discord username of the controller of the account. pub discord: Data, } impl IdentityInformationProvider for IdentityInfo { type FieldsIdentifier = u64; fn has_identity(&self, fields: Self::FieldsIdentifier) -> bool { self.fields().bits() & fields == fields } #[cfg(feature = "runtime-benchmarks")] fn create_identity_info() -> Self { let data = Data::Raw(alloc::vec![0; 32].try_into().unwrap()); IdentityInfo { display: data.clone(), legal: data.clone(), web: data.clone(), matrix: data.clone(), email: data.clone(), pgp_fingerprint: Some([0; 20]), image: data.clone(), twitter: data.clone(), github: data.clone(), discord: data, } } #[cfg(feature = "runtime-benchmarks")] fn all_fields() -> Self::FieldsIdentifier { use enumflags2::BitFlag; IdentityField::all().bits() } } impl IdentityInfo { pub(crate) fn fields(&self) -> BitFlags { let mut res = >::empty(); if !self.display.is_none() { res.insert(IdentityField::Display); } if !self.legal.is_none() { res.insert(IdentityField::Legal); } if !self.web.is_none() { res.insert(IdentityField::Web); } if !self.matrix.is_none() { res.insert(IdentityField::Matrix); } if !self.email.is_none() { res.insert(IdentityField::Email); } if self.pgp_fingerprint.is_some() { res.insert(IdentityField::PgpFingerprint); } if !self.image.is_none() { res.insert(IdentityField::Image); } if !self.twitter.is_none() { res.insert(IdentityField::Twitter); } if !self.github.is_none() { res.insert(IdentityField::GitHub); } if !self.discord.is_none() { res.insert(IdentityField::Discord); } res } } /// A `Default` identity. This is given to users who get a username but have not set an identity. impl Default for IdentityInfo { fn default() -> Self { IdentityInfo { display: Data::None, legal: Data::None, web: Data::None, matrix: Data::None, email: Data::None, pgp_fingerprint: None, image: Data::None, twitter: Data::None, github: Data::None, discord: Data::None, } } }