use super::*;
use crate::xcm_config::LocationToAccountId;
use codec::{Decode, Encode, MaxEncodedLen};
use enumflags2::{bitflags, BitFlags};
use frame_support::{
parameter_types, traits::ConstU32, CloneNoBound, EqNoBound, PartialEqNoBound,
RuntimeDebugNoBound,
};
use pallet_identity::{Data, IdentityInformationProvider};
use parachains_common::{impls::ToParentTreasury, DAYS};
use scale_info::TypeInfo;
use sp_runtime::{
traits::{AccountIdConversion, Verify},
RuntimeDebug,
};
parameter_types! {
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 =
parachains_common::TREASURY_PALLET_ID.into_account_truncating();
}
impl pallet_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<RelayTreasuryAccount, LocationToAccountId, Runtime>;
type ForceOrigin = EnsureRoot<Self::AccountId>;
type RegistrarOrigin = EnsureRoot<Self::AccountId>;
type OffchainSignature = Signature;
type SigningPublicKey = <Signature as Verify>::Signer;
type UsernameAuthorityOrigin = EnsureRoot<Self::AccountId>;
type PendingUsernameExpiration = ConstU32<{ 7 * DAYS }>;
type UsernameGracePeriod = ConstU32<{ 3 * DAYS }>;
type MaxSuffixLength = ConstU32<7>;
type MaxUsernameLength = ConstU32<32>;
type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
}
#[bitflags]
#[repr(u64)]
#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)]
pub enum IdentityField {
Display,
Legal,
Web,
Matrix,
Email,
PgpFingerprint,
Image,
Twitter,
GitHub,
Discord,
}
#[derive(
CloneNoBound,
Encode,
Decode,
EqNoBound,
MaxEncodedLen,
PartialEqNoBound,
RuntimeDebugNoBound,
TypeInfo,
)]
#[codec(mel_bound())]
pub struct IdentityInfo {
pub display: Data,
pub legal: Data,
pub web: Data,
pub matrix: Data,
pub email: Data,
pub pgp_fingerprint: Option<[u8; 20]>,
pub image: Data,
pub twitter: Data,
pub github: Data,
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<IdentityField> {
let mut res = <BitFlags<IdentityField>>::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
}
}
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,
}
}
}