referrerpolicy=no-referrer-when-downgrade

people_westend_runtime/
people.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// SPDX-License-Identifier: Apache-2.0
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// 	http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use super::*;
17use crate::xcm_config::LocationToAccountId;
18use codec::{Decode, Encode, MaxEncodedLen};
19use enumflags2::{bitflags, BitFlags};
20use frame_support::{
21	parameter_types, traits::ConstU32, CloneNoBound, EqNoBound, PartialEqNoBound,
22	RuntimeDebugNoBound,
23};
24use pallet_identity::{Data, IdentityInformationProvider};
25use parachains_common::{impls::ToParentTreasury, DAYS};
26use scale_info::TypeInfo;
27use sp_runtime::{
28	traits::{AccountIdConversion, Verify},
29	RuntimeDebug,
30};
31
32parameter_types! {
33	//   27 | Min encoded size of `Registration`
34	// - 10 | Min encoded size of `IdentityInfo`
35	// -----|
36	//   17 | Min size without `IdentityInfo` (accounted for in byte deposit)
37	pub const BasicDeposit: Balance = deposit(1, 17);
38	pub const ByteDeposit: Balance = deposit(0, 1);
39	pub const UsernameDeposit: Balance = deposit(0, 32);
40	pub const SubAccountDeposit: Balance = deposit(1, 53);
41	pub RelayTreasuryAccount: AccountId =
42		parachains_common::TREASURY_PALLET_ID.into_account_truncating();
43}
44
45impl pallet_identity::Config for Runtime {
46	type RuntimeEvent = RuntimeEvent;
47	type Currency = Balances;
48	type BasicDeposit = BasicDeposit;
49	type ByteDeposit = ByteDeposit;
50	type UsernameDeposit = UsernameDeposit;
51	type SubAccountDeposit = SubAccountDeposit;
52	type MaxSubAccounts = ConstU32<100>;
53	type IdentityInformation = IdentityInfo;
54	type MaxRegistrars = ConstU32<20>;
55	type Slashed = ToParentTreasury<RelayTreasuryAccount, LocationToAccountId, Runtime>;
56	type ForceOrigin = EnsureRoot<Self::AccountId>;
57	type RegistrarOrigin = EnsureRoot<Self::AccountId>;
58	type OffchainSignature = Signature;
59	type SigningPublicKey = <Signature as Verify>::Signer;
60	type UsernameAuthorityOrigin = EnsureRoot<Self::AccountId>;
61	type PendingUsernameExpiration = ConstU32<{ 7 * DAYS }>;
62	type UsernameGracePeriod = ConstU32<{ 3 * DAYS }>;
63	type MaxSuffixLength = ConstU32<7>;
64	type MaxUsernameLength = ConstU32<32>;
65	#[cfg(feature = "runtime-benchmarks")]
66	type BenchmarkHelper = ();
67	type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
68}
69
70/// The fields that we use to identify the owner of an account with. Each corresponds to a field
71/// in the `IdentityInfo` struct.
72#[bitflags]
73#[repr(u64)]
74#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)]
75pub enum IdentityField {
76	Display,
77	Legal,
78	Web,
79	Matrix,
80	Email,
81	PgpFingerprint,
82	Image,
83	Twitter,
84	GitHub,
85	Discord,
86}
87
88/// Information concerning the identity of the controller of an account.
89#[derive(
90	CloneNoBound,
91	Encode,
92	Decode,
93	DecodeWithMemTracking,
94	EqNoBound,
95	MaxEncodedLen,
96	PartialEqNoBound,
97	RuntimeDebugNoBound,
98	TypeInfo,
99)]
100#[codec(mel_bound())]
101pub struct IdentityInfo {
102	/// A reasonable display name for the controller of the account. This should be whatever it is
103	/// that it is typically known as and should not be confusable with other entities, given
104	/// reasonable context.
105	///
106	/// Stored as UTF-8.
107	pub display: Data,
108
109	/// The full legal name in the local jurisdiction of the entity. This might be a bit
110	/// long-winded.
111	///
112	/// Stored as UTF-8.
113	pub legal: Data,
114
115	/// A representative website held by the controller of the account.
116	///
117	/// NOTE: `https://` is automatically prepended.
118	///
119	/// Stored as UTF-8.
120	pub web: Data,
121
122	/// The Matrix (e.g. for Element) handle held by the controller of the account. Previously,
123	/// this was called `riot`.
124	///
125	/// Stored as UTF-8.
126	pub matrix: Data,
127
128	/// The email address of the controller of the account.
129	///
130	/// Stored as UTF-8.
131	pub email: Data,
132
133	/// The PGP/GPG public key of the controller of the account.
134	pub pgp_fingerprint: Option<[u8; 20]>,
135
136	/// A graphic image representing the controller of the account. Should be a company,
137	/// organization or project logo or a headshot in the case of a human.
138	pub image: Data,
139
140	/// The Twitter identity. The leading `@` character may be elided.
141	pub twitter: Data,
142
143	/// The GitHub username of the controller of the account.
144	pub github: Data,
145
146	/// The Discord username of the controller of the account.
147	pub discord: Data,
148}
149
150impl IdentityInformationProvider for IdentityInfo {
151	type FieldsIdentifier = u64;
152
153	fn has_identity(&self, fields: Self::FieldsIdentifier) -> bool {
154		self.fields().bits() & fields == fields
155	}
156
157	#[cfg(feature = "runtime-benchmarks")]
158	fn create_identity_info() -> Self {
159		let data = Data::Raw(alloc::vec![0; 32].try_into().unwrap());
160
161		IdentityInfo {
162			display: data.clone(),
163			legal: data.clone(),
164			web: data.clone(),
165			matrix: data.clone(),
166			email: data.clone(),
167			pgp_fingerprint: Some([0; 20]),
168			image: data.clone(),
169			twitter: data.clone(),
170			github: data.clone(),
171			discord: data,
172		}
173	}
174
175	#[cfg(feature = "runtime-benchmarks")]
176	fn all_fields() -> Self::FieldsIdentifier {
177		use enumflags2::BitFlag;
178		IdentityField::all().bits()
179	}
180}
181
182impl IdentityInfo {
183	pub(crate) fn fields(&self) -> BitFlags<IdentityField> {
184		let mut res = <BitFlags<IdentityField>>::empty();
185		if !self.display.is_none() {
186			res.insert(IdentityField::Display);
187		}
188		if !self.legal.is_none() {
189			res.insert(IdentityField::Legal);
190		}
191		if !self.web.is_none() {
192			res.insert(IdentityField::Web);
193		}
194		if !self.matrix.is_none() {
195			res.insert(IdentityField::Matrix);
196		}
197		if !self.email.is_none() {
198			res.insert(IdentityField::Email);
199		}
200		if self.pgp_fingerprint.is_some() {
201			res.insert(IdentityField::PgpFingerprint);
202		}
203		if !self.image.is_none() {
204			res.insert(IdentityField::Image);
205		}
206		if !self.twitter.is_none() {
207			res.insert(IdentityField::Twitter);
208		}
209		if !self.github.is_none() {
210			res.insert(IdentityField::GitHub);
211		}
212		if !self.discord.is_none() {
213			res.insert(IdentityField::Discord);
214		}
215		res
216	}
217}
218
219/// A `Default` identity. This is given to users who get a username but have not set an identity.
220impl Default for IdentityInfo {
221	fn default() -> Self {
222		IdentityInfo {
223			display: Data::None,
224			legal: Data::None,
225			web: Data::None,
226			matrix: Data::None,
227			email: Data::None,
228			pgp_fingerprint: None,
229			image: Data::None,
230			twitter: Data::None,
231			github: Data::None,
232			discord: Data::None,
233		}
234	}
235}