use core::marker::PhantomData;
use codec::{Decode, DecodeWithMemTracking, Encode, FullCodec, MaxEncodedLen};
use scale_info::TypeInfo;
use subsoil::core::ConstU32;
use subsoil::runtime::{traits::Member, BoundedVec, DispatchError, DispatchResult};
use topsoil_core::{CloneNoBound, EqNoBound, Parameter, PartialEqNoBound};
pub type PersonalId = u64;
pub type Context = [u8; 32];
pub type Alias = [u8; 32];
pub type RingIndex = u32;
pub type Data = BoundedVec<u8, ConstU32<32>>;
pub const MAX_STATEMENT_DATA_SIZE: u32 = 256;
pub type CustomStatement = BoundedVec<u8, ConstU32<MAX_STATEMENT_DATA_SIZE>>;
pub type EvidenceHash = [u8; 32];
pub const CONTEXT_SIZE: u32 = 64;
pub type JudgementContext = BoundedVec<u8, ConstU32<CONTEXT_SIZE>>;
#[derive(
Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo, DecodeWithMemTracking,
)]
pub struct ContextualAlias {
pub alias: Alias,
pub context: Context,
}
pub trait AddOnlyPeopleTrait {
type Member: Parameter + MaxEncodedLen;
fn reserve_new_id() -> PersonalId;
fn renew_id_reservation(personal_id: PersonalId) -> Result<(), DispatchError>;
fn cancel_id_reservation(personal_id: PersonalId) -> Result<(), DispatchError>;
fn recognize_personhood(
who: PersonalId,
maybe_key: Option<Self::Member>,
) -> Result<(), DispatchError>;
#[cfg(feature = "runtime-benchmarks")]
type Secret;
#[cfg(feature = "runtime-benchmarks")]
fn mock_key(who: PersonalId) -> (Self::Member, Self::Secret);
}
pub trait PeopleTrait: AddOnlyPeopleTrait {
fn suspend_personhood(suspensions: &[PersonalId]) -> DispatchResult;
fn start_people_set_mutation_session() -> DispatchResult;
fn end_people_set_mutation_session() -> DispatchResult;
}
impl AddOnlyPeopleTrait for () {
type Member = ();
fn reserve_new_id() -> PersonalId {
0
}
fn renew_id_reservation(_: PersonalId) -> Result<(), DispatchError> {
Ok(())
}
fn cancel_id_reservation(_: PersonalId) -> Result<(), DispatchError> {
Ok(())
}
fn recognize_personhood(_: PersonalId, _: Option<Self::Member>) -> Result<(), DispatchError> {
Ok(())
}
#[cfg(feature = "runtime-benchmarks")]
type Secret = PersonalId;
#[cfg(feature = "runtime-benchmarks")]
fn mock_key(who: PersonalId) -> (Self::Member, Self::Secret) {
((), who)
}
}
impl PeopleTrait for () {
fn suspend_personhood(_: &[PersonalId]) -> DispatchResult {
Ok(())
}
fn start_people_set_mutation_session() -> DispatchResult {
Ok(())
}
fn end_people_set_mutation_session() -> DispatchResult {
Ok(())
}
}
pub trait CountedMembers {
fn active_count(&self) -> u32;
}
#[derive(
Clone,
Copy,
PartialEq,
Eq,
Debug,
Encode,
Decode,
MaxEncodedLen,
TypeInfo,
DecodeWithMemTracking,
)]
pub enum Truth {
True,
False,
}
#[derive(
Clone,
Copy,
PartialEq,
Eq,
Debug,
Encode,
Decode,
MaxEncodedLen,
TypeInfo,
DecodeWithMemTracking,
)]
pub enum Judgement {
Truth(Truth),
Contempt,
}
impl Judgement {
pub fn matches_intent(&self, j: Self) -> bool {
use self::Truth::*;
use Judgement::*;
matches!(
(self, j),
(Truth(True), Truth(True)) | (Truth(False), Truth(False)) | (Contempt, Contempt)
)
}
}
pub mod identity {
use super::*;
#[derive(
Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo, DecodeWithMemTracking,
)]
pub enum Social {
Twitter { username: Data },
Github { username: Data },
}
impl Social {
pub fn eq_platform(&self, other: &Social) -> bool {
matches!(
(&self, &other),
(Social::Twitter { .. }, Social::Twitter { .. })
| (Social::Github { .. }, Social::Github { .. })
)
}
}
}
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)]
pub enum Statement {
IdentityCredential { platform: identity::Social, evidence: Data },
UsernameValid { username: Data },
Custom { id: u8, data: CustomStatement },
}
#[derive(
CloneNoBound, PartialEqNoBound, EqNoBound, Debug, Encode, Decode, MaxEncodedLen, TypeInfo,
)]
#[scale_info(skip_type_params(Params, RuntimeCall))]
#[codec(mel_bound())]
pub struct Callback<Params, RuntimeCall> {
pallet_index: u8,
call_index: u8,
phantom: PhantomData<(Params, RuntimeCall)>,
}
impl<Params: Encode, RuntimeCall: Decode> Callback<Params, RuntimeCall> {
pub const fn from_parts(pallet_index: u8, call_index: u8) -> Self {
Self { pallet_index, call_index, phantom: PhantomData }
}
pub fn curry(&self, args: Params) -> Result<RuntimeCall, codec::Error> {
(self.pallet_index, self.call_index, args).using_encoded(|mut d| Decode::decode(&mut d))
}
}
pub trait StatementOracle<RuntimeCall> {
type Ticket: Member + FullCodec + TypeInfo + MaxEncodedLen + Default;
fn judge_statement(
statement: Statement,
context: JudgementContext,
callback: Callback<(Self::Ticket, JudgementContext, Judgement), RuntimeCall>,
) -> Result<Self::Ticket, DispatchError>;
}
impl<C> StatementOracle<C> for () {
type Ticket = ();
fn judge_statement(
_: Statement,
_: JudgementContext,
_: Callback<(Self::Ticket, JudgementContext, Judgement), C>,
) -> Result<(), DispatchError> {
Err(DispatchError::Unavailable)
}
}