use did::KeyIdOf;
use frame_system::pallet_prelude::BlockNumberFor;
use kilt_dip_primitives::DidMerkleProof;
use pallet_did_lookup::linkable_account::LinkableAccountId;
use pallet_dip_provider::{
traits::{IdentityCommitmentGenerator, IdentityProvider},
IdentityCommitmentVersion, IdentityOf,
};
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_runtime::RuntimeDebug;
use sp_std::marker::PhantomData;
use crate::dip::did::LinkedDidInfoOf;
pub mod v0;
#[cfg(test)]
mod tests;
pub type DidMerkleProofOf<T> = DidMerkleProof<
KeyIdOf<T>,
<T as frame_system::Config>::AccountId,
BlockNumberFor<T>,
<T as pallet_web3_names::Config>::Web3Name,
LinkableAccountId,
>;
#[derive(Encode, Decode, RuntimeDebug, PartialEq, Eq, TypeInfo)]
pub struct CompleteMerkleProof<Root, Proof> {
pub root: Root,
pub proof: Proof,
}
#[derive(Clone, RuntimeDebug, Encode, Decode, TypeInfo, PartialEq)]
pub enum DidMerkleProofError {
UnsupportedVersion,
KeyNotFound,
LinkedAccountNotFound,
Web3NameNotFound,
TooManyLeaves,
Internal,
}
impl From<DidMerkleProofError> for u16 {
fn from(value: DidMerkleProofError) -> Self {
match value {
DidMerkleProofError::UnsupportedVersion => 1,
DidMerkleProofError::KeyNotFound => 2,
DidMerkleProofError::LinkedAccountNotFound => 3,
DidMerkleProofError::Web3NameNotFound => 4,
DidMerkleProofError::TooManyLeaves => 5,
DidMerkleProofError::Internal => u16::MAX,
}
}
}
pub struct DidMerkleRootGenerator<T>(PhantomData<T>);
impl<Runtime, const MAX_LINKED_ACCOUNT: u32> IdentityCommitmentGenerator<Runtime> for DidMerkleRootGenerator<Runtime>
where
Runtime: did::Config + pallet_did_lookup::Config + pallet_web3_names::Config + pallet_dip_provider::Config,
Runtime::IdentityProvider: IdentityProvider<Runtime, Success = LinkedDidInfoOf<Runtime, MAX_LINKED_ACCOUNT>>,
{
type Error = DidMerkleProofError;
type Output = Runtime::Hash;
fn generate_commitment(
_identifier: &Runtime::Identifier,
identity: &IdentityOf<Runtime>,
version: IdentityCommitmentVersion,
) -> Result<Self::Output, Self::Error> {
match version {
0 => v0::generate_commitment::<Runtime, MAX_LINKED_ACCOUNT>(identity),
_ => Err(DidMerkleProofError::UnsupportedVersion),
}
}
}
impl<Runtime> DidMerkleRootGenerator<Runtime>
where
Runtime: did::Config + pallet_did_lookup::Config + pallet_web3_names::Config,
{
pub fn generate_proof<'a, K, A, const MAX_LINKED_ACCOUNT: u32>(
identity: &LinkedDidInfoOf<Runtime, MAX_LINKED_ACCOUNT>,
version: IdentityCommitmentVersion,
key_ids: K,
should_include_web3_name: bool,
account_ids: A,
) -> Result<CompleteMerkleProof<Runtime::Hash, DidMerkleProofOf<Runtime>>, DidMerkleProofError>
where
K: Iterator<Item = &'a KeyIdOf<Runtime>>,
A: Iterator<Item = &'a LinkableAccountId>,
{
match version {
0 => v0::generate_proof(identity, key_ids, should_include_web3_name, account_ids),
_ => Err(DidMerkleProofError::UnsupportedVersion),
}
}
}