From 0b594c65ae10bf8ca20f47c99e7645059e9fde99 Mon Sep 17 00:00:00 2001
From: librelois <c@elo.tf>
Date: Thu, 20 Jan 2022 18:20:30 +0100
Subject: [PATCH] ref(runtime): simplify wot logic (remove idty right)

---
 .cargo/config                              |   1 +
 Cargo.lock                                 |   1 +
 node/src/chain_spec/gdev.rs                |  17 +-
 node/src/chain_spec/gtest.rs               |  15 +-
 pallets/certification/src/lib.rs           |  20 +-
 pallets/certification/src/mock.rs          |   4 +-
 pallets/certification/src/tests.rs         |  12 +-
 pallets/certification/src/traits.rs        |   8 +-
 pallets/certification/src/types.rs         |   2 +-
 pallets/duniter-test-parameters/src/lib.rs |   2 +-
 pallets/duniter-wot/src/lib.rs             | 224 ++++++-----------
 pallets/duniter-wot/src/mock.rs            |  38 ++-
 pallets/duniter-wot/src/tests.rs           | 149 +++++++----
 pallets/duniter-wot/src/types.rs           |  85 +++----
 pallets/identity/src/lib.rs                | 274 ++-------------------
 pallets/identity/src/mock.rs               |  44 +---
 pallets/identity/src/tests.rs              |  94 +------
 pallets/identity/src/traits.rs             |  34 ---
 pallets/identity/src/types.rs              |  29 +--
 pallets/membership/src/lib.rs              |  56 ++---
 pallets/membership/src/mock.rs             |   3 +-
 pallets/membership/src/tests.rs            |  20 +-
 primitives/membership/src/lib.rs           |   4 +-
 primitives/membership/src/traits.rs        |  24 +-
 runtime/common/Cargo.toml                  |   2 +
 runtime/common/src/handlers.rs             |  53 ++--
 runtime/common/src/pallets_config.rs       |  23 +-
 runtime/g1/src/lib.rs                      |   9 +-
 runtime/g1/src/parameters.rs               |   4 +-
 runtime/gdev/src/lib.rs                    |  14 +-
 runtime/gtest/src/lib.rs                   |   9 +-
 runtime/gtest/src/parameters.rs            |   4 +-
 32 files changed, 415 insertions(+), 863 deletions(-)

diff --git a/.cargo/config b/.cargo/config
index 14c5afe40..0c7fb81b3 100644
--- a/.cargo/config
+++ b/.cargo/config
@@ -1,2 +1,3 @@
 [alias]
 cucumber = "test -p duniter-integration-tests --test cucumber_tests --"
+tu = "test --workspace --exclude duniter-integration-tests"
diff --git a/Cargo.lock b/Cargo.lock
index f8b3ac429..58e2d61a6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -848,6 +848,7 @@ dependencies = [
  "sp-arithmetic",
  "sp-consensus-babe",
  "sp-core",
+ "sp-membership",
  "sp-runtime",
  "sp-staking",
  "sp-std",
diff --git a/node/src/chain_spec/gdev.rs b/node/src/chain_spec/gdev.rs
index 0d0dcef7f..754ee00c3 100644
--- a/node/src/chain_spec/gdev.rs
+++ b/node/src/chain_spec/gdev.rs
@@ -18,8 +18,8 @@ use super::*;
 use common_runtime::entities::IdtyName;
 use gdev_runtime::{
     AccountId, BalancesConfig, GenesisConfig, GenesisParameters, GrandpaConfig, IdentityConfig,
-    IdtyRight, IdtyValue, MembershipConfig, ParametersConfig, StrongCertConfig, SudoConfig,
-    SystemConfig, UdAccountsStorageConfig, UniversalDividendConfig, WASM_BINARY,
+    IdtyValue, MembershipConfig, ParametersConfig, StrongCertConfig, SudoConfig, SystemConfig,
+    UdAccountsStorageConfig, UniversalDividendConfig, WASM_BINARY,
 };
 use maplit::btreemap;
 use sc_service::ChainType;
@@ -113,10 +113,10 @@ fn devnet_genesis(
                 cert_period: 15,
                 cert_max_by_issuer: 10,
                 cert_renewable_period: 50,
-                cert_validity_period: 200,
+                cert_validity_period,
                 idty_confirm_period: 40,
                 idty_creation_period: 50,
-                idty_max_no_right_period: 1_000,
+                idty_max_disabled_period: 1_000,
                 membership_period,
                 membership_renewable_period,
                 pending_membership_period: 500,
@@ -126,8 +126,8 @@ fn devnet_genesis(
                 ud_reeval_period_in_blocks: 200,
                 wot_first_cert_issuable_on: 20,
                 wot_min_cert_for_ud_right: 2,
-                wot_min_cert_for_cert_right: 3,
-                wot_min_cert_for_create_idty_right: 3,
+                wot_min_cert_for_cert_right: 2,
+                wot_min_cert_for_create_idty_right: 2,
             },
         },
         balances: BalancesConfig {
@@ -149,11 +149,6 @@ fn devnet_genesis(
                     name: name.clone(),
                     next_creatable_identity_on: Default::default(),
                     removable_on: 0,
-                    rights: vec![
-                        (IdtyRight::CreateIdty, None),
-                        (IdtyRight::StrongCert, None),
-                        (IdtyRight::Ud, None),
-                    ],
                     status: gdev_runtime::IdtyStatus::Validated,
                 })
                 .collect(),
diff --git a/node/src/chain_spec/gtest.rs b/node/src/chain_spec/gtest.rs
index f601d2221..cc7b70665 100644
--- a/node/src/chain_spec/gtest.rs
+++ b/node/src/chain_spec/gtest.rs
@@ -19,8 +19,8 @@ use common_runtime::constants::*;
 use common_runtime::entities::IdtyName;
 use gtest_runtime::{
     opaque::SessionKeys, AccountId, BabeConfig, BalancesConfig, GenesisConfig, IdentityConfig,
-    IdtyRight, IdtyValue, ImOnlineId, MembershipConfig, SessionConfig, StrongCertConfig,
-    SudoConfig, SystemConfig, UdAccountsStorageConfig, UniversalDividendConfig, WASM_BINARY,
+    IdtyValue, ImOnlineId, MembershipConfig, SessionConfig, StrongCertConfig, SudoConfig,
+    SystemConfig, UdAccountsStorageConfig, UniversalDividendConfig, WASM_BINARY,
 };
 use maplit::btreemap;
 use sc_service::ChainType;
@@ -105,11 +105,6 @@ fn devnet_genesis(
                     next_creatable_identity_on: Default::default(),
                     owner_key: account.clone(),
                     removable_on: 0,
-                    rights: vec![
-                        (IdtyRight::CreateIdty, None),
-                        (IdtyRight::StrongCert, None),
-                        (IdtyRight::Ud, None),
-                    ],
                     status: gtest_runtime::IdtyStatus::Validated,
                 })
                 .collect(),
@@ -311,11 +306,7 @@ fn testnet_genesis(
                     next_creatable_identity_on: Default::default(),
                     owner_key: account.clone(),
                     removable_on: 0,
-                    rights: vec![
-                        (IdtyRight::CreateIdty, None),
-                        (IdtyRight::StrongCert, None),
-                        (IdtyRight::Ud, None),
-                    ],
+
                     status: gtest_runtime::IdtyStatus::Validated,
                 })
                 .collect(),
diff --git a/pallets/certification/src/lib.rs b/pallets/certification/src/lib.rs
index 2636ad729..4846e08d4 100644
--- a/pallets/certification/src/lib.rs
+++ b/pallets/certification/src/lib.rs
@@ -73,7 +73,10 @@ pub mod pallet {
             + MaxEncodedLen;
         #[pallet::constant]
         /// Maximum number of active certifications by issuer
-        type MaxByIssuer: Get<u8>;
+        type MaxByIssuer: Get<u32>;
+        /// Minimum number of certifications that must be received to be able to issue
+        /// certifications.
+        type MinReceivedCertToBeAbleToIssueCert: Get<u32>;
         /// Handler for NewCert event
         type OnNewcert: OnNewcert<Self::IdtyIndex>;
         /// Handler for Removed event
@@ -124,7 +127,7 @@ pub mod pallet {
                 cert_meta_by_issuer.insert(
                     *issuer,
                     IdtyCertMeta {
-                        issued_count: receivers.len() as u8,
+                        issued_count: receivers.len() as u32,
                         next_issuable_on: sp_runtime::traits::Zero::zero(),
                         received_count: 0,
                     },
@@ -238,7 +241,7 @@ pub mod pallet {
         /// [issuer, issuer_issued_count, receiver, receiver_received_count]
         NewCert {
             issuer: T::IdtyIndex,
-            issuer_issued_count: u8,
+            issuer_issued_count: u32,
             receiver: T::IdtyIndex,
             receiver_received_count: u32,
         },
@@ -246,7 +249,7 @@ pub mod pallet {
         /// [issuer, issuer_issued_count, receiver, receiver_received_count, expiration]
         RemovedCert {
             issuer: T::IdtyIndex,
-            issuer_issued_count: u8,
+            issuer_issued_count: u32,
             receiver: T::IdtyIndex,
             receiver_received_count: u32,
             expiration: bool,
@@ -265,6 +268,8 @@ pub mod pallet {
         IdtyMustReceiveCertsBeforeCanIssue,
         /// This identity has already issued the maximum number of certifications
         IssuedTooManyCert,
+        /// Not enough certifications received
+        NotEnoughCertReceived,
         /// This certification has already been issued or renewed recently
         NotRespectRenewablePeriod,
         /// This identity has already issued a certification too recently
@@ -302,7 +307,12 @@ pub mod pallet {
                     issuer,
                     receiver
                 );
-                if issuer_idty_cert_meta.next_issuable_on > block_number {
+
+                if issuer_idty_cert_meta.received_count
+                    < T::MinReceivedCertToBeAbleToIssueCert::get()
+                {
+                    return Err(Error::<T, I>::NotEnoughCertReceived.into());
+                } else if issuer_idty_cert_meta.next_issuable_on > block_number {
                     return Err(Error::<T, I>::NotRespectCertPeriod.into());
                 } else if issuer_idty_cert_meta.issued_count >= T::MaxByIssuer::get() {
                     return Err(Error::<T, I>::IssuedTooManyCert.into());
diff --git a/pallets/certification/src/mock.rs b/pallets/certification/src/mock.rs
index eac33cc0f..53cd1347a 100644
--- a/pallets/certification/src/mock.rs
+++ b/pallets/certification/src/mock.rs
@@ -92,7 +92,8 @@ impl frame_support::traits::EnsureOrigin<(Origin, IdtyIndex, IdtyIndex)> for Ens
 }
 
 parameter_types! {
-    pub const MaxByIssuer: u8 = 3;
+    pub const MaxByIssuer: u32 = 3;
+    pub const MinReceivedCertToBeAbleToIssueCert: u32 = 2;
     pub const RenewablePeriod: BlockNumber = 4;
     pub const CertPeriod: u64 = 2;
     pub const ValidityPeriod: u64 = 10;
@@ -105,6 +106,7 @@ impl pallet_certification::Config for Test {
     type Event = Event;
     type IdtyIndex = IdtyIndex;
     type MaxByIssuer = MaxByIssuer;
+    type MinReceivedCertToBeAbleToIssueCert = MinReceivedCertToBeAbleToIssueCert;
     type OnNewcert = ();
     type OnRemovedCert = ();
     type CertRenewablePeriod = RenewablePeriod;
diff --git a/pallets/certification/src/tests.rs b/pallets/certification/src/tests.rs
index 1578279e6..030a6d6d3 100644
--- a/pallets/certification/src/tests.rs
+++ b/pallets/certification/src/tests.rs
@@ -114,7 +114,11 @@ fn test_genesis_build() {
 fn test_cert_period() {
     new_test_ext(DefaultCertificationConfig {
         apply_cert_period_at_genesis: true,
-        certs_by_issuer: btreemap![0 => btreemap![1 => 10]],
+        certs_by_issuer: btreemap![
+            0 => btreemap![1 => 10],
+            2 => btreemap![0 => 10],
+            3 => btreemap![0 => 10],
+        ],
     })
     .execute_with(|| {
         assert_eq!(
@@ -137,7 +141,11 @@ fn test_cert_period() {
 fn test_renewable_period() {
     new_test_ext(DefaultCertificationConfig {
         apply_cert_period_at_genesis: true,
-        certs_by_issuer: btreemap![0 => btreemap![1 => 10]],
+        certs_by_issuer: btreemap![
+            0 => btreemap![1 => 10],
+            2 => btreemap![0 => 10],
+            3 => btreemap![0 => 10],
+        ],
     })
     .execute_with(|| {
         run_to_block(CertPeriod::get());
diff --git a/pallets/certification/src/traits.rs b/pallets/certification/src/traits.rs
index aea859b01..cde9ade86 100644
--- a/pallets/certification/src/traits.rs
+++ b/pallets/certification/src/traits.rs
@@ -17,7 +17,7 @@
 pub trait OnNewcert<IdtyIndex> {
     fn on_new_cert(
         issuer: IdtyIndex,
-        issuer_issued_count: u8,
+        issuer_issued_count: u32,
         receiver: IdtyIndex,
         receiver_received_count: u32,
     ) -> frame_support::dispatch::Weight;
@@ -25,7 +25,7 @@ pub trait OnNewcert<IdtyIndex> {
 impl<IdtyIndex> OnNewcert<IdtyIndex> for () {
     fn on_new_cert(
         _issuer: IdtyIndex,
-        _issuer_issued_count: u8,
+        _issuer_issued_count: u32,
         _receiver: IdtyIndex,
         _receiver_received_count: u32,
     ) -> frame_support::dispatch::Weight {
@@ -36,7 +36,7 @@ impl<IdtyIndex> OnNewcert<IdtyIndex> for () {
 pub trait OnRemovedCert<IdtyIndex> {
     fn on_removed_cert(
         issuer: IdtyIndex,
-        issuer_issued_count: u8,
+        issuer_issued_count: u32,
         receiver: IdtyIndex,
         receiver_received_count: u32,
         expiration: bool,
@@ -45,7 +45,7 @@ pub trait OnRemovedCert<IdtyIndex> {
 impl<IdtyIndex> OnRemovedCert<IdtyIndex> for () {
     fn on_removed_cert(
         _issuer: IdtyIndex,
-        _issuer_issued_count: u8,
+        _issuer_issued_count: u32,
         _receiver: IdtyIndex,
         _receiver_received_count: u32,
         _expiration: bool,
diff --git a/pallets/certification/src/types.rs b/pallets/certification/src/types.rs
index 464df347a..daf5d954f 100644
--- a/pallets/certification/src/types.rs
+++ b/pallets/certification/src/types.rs
@@ -28,7 +28,7 @@ pub struct CertValue<BlockNumber> {
 
 #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)]
 pub struct IdtyCertMeta<BlockNumber> {
-    pub issued_count: u8,
+    pub issued_count: u32,
     pub next_issuable_on: BlockNumber,
     pub received_count: u32,
 }
diff --git a/pallets/duniter-test-parameters/src/lib.rs b/pallets/duniter-test-parameters/src/lib.rs
index b5056f103..af7bd1acc 100644
--- a/pallets/duniter-test-parameters/src/lib.rs
+++ b/pallets/duniter-test-parameters/src/lib.rs
@@ -42,7 +42,7 @@ pub mod types {
         pub cert_validity_period: BlockNumber,
         pub idty_confirm_period: BlockNumber,
         pub idty_creation_period: BlockNumber,
-        pub idty_max_no_right_period: BlockNumber,
+        pub idty_max_disabled_period: BlockNumber,
         pub membership_period: BlockNumber,
         pub membership_renewable_period: BlockNumber,
         pub pending_membership_period: BlockNumber,
diff --git a/pallets/duniter-wot/src/lib.rs b/pallets/duniter-wot/src/lib.rs
index 1f77b043d..ede541d1f 100644
--- a/pallets/duniter-wot/src/lib.rs
+++ b/pallets/duniter-wot/src/lib.rs
@@ -32,7 +32,6 @@ mod benchmarking;*/
 pub use pallet::*;
 pub use types::*;
 
-use frame_support::instances::Instance1;
 use frame_support::pallet_prelude::*;
 use frame_system::RawOrigin;
 use pallet_certification::traits::SetNextIssuableOn;
@@ -44,6 +43,7 @@ type IdtyIndex = u32;
 #[frame_support::pallet]
 pub mod pallet {
     use super::*;
+    use frame_support::dispatch::UnfilteredDispatchable;
     use frame_support::traits::StorageVersion;
 
     /// The current storage version.
@@ -52,114 +52,82 @@ pub mod pallet {
     #[pallet::pallet]
     #[pallet::generate_store(pub(super) trait Store)]
     #[pallet::storage_version(STORAGE_VERSION)]
-    pub struct Pallet<T>(_);
+    pub struct Pallet<T, I = ()>(_);
 
     // CONFIG //
 
     #[pallet::config]
-    pub trait Config:
+    pub trait Config<I: 'static = ()>:
         frame_system::Config
-        + pallet_certification::Config<Instance1, IdtyIndex = IdtyIndex>
-        + pallet_identity::Config<IdtyIndex = IdtyIndex, IdtyRight = IdtyRight>
-        + pallet_membership::Config<Instance1, IdtyId = IdtyIndex>
+        + pallet_certification::Config<I, IdtyIndex = IdtyIndex>
+        + pallet_identity::Config<IdtyIndex = IdtyIndex>
+        + pallet_membership::Config<I, IdtyId = IdtyIndex, MetaData = ()>
     {
-        type MinCertForUdRight: Get<u8>;
-        type MinCertForCertRight: Get<u8>;
-        type MinCertForCreateIdtyRight: Get<u8>;
         type FirstIssuableOn: Get<Self::BlockNumber>;
+        type ManageIdentitiesChanges: Get<bool>;
+        type MinCertForUdRight: Get<u32>;
+        type MinCertForCreateIdtyRight: Get<u32>;
     }
 
     // INTERNAL FUNCTIONS //
 
-    impl<T: Config> Pallet<T> {
+    impl<T: Config<I>, I: 'static> Pallet<T, I> {
         pub(super) fn do_apply_first_issuable_on(idty_index: IdtyIndex) {
             let block_number = frame_system::pallet::Pallet::<T>::block_number();
-            pallet_certification::Pallet::<T, Instance1>::set_next_issuable_on(
+            pallet_certification::Pallet::<T, I>::set_next_issuable_on(
                 idty_index,
                 block_number + T::FirstIssuableOn::get(),
             );
         }
-        pub(super) fn do_add_cert_right(idty_index: IdtyIndex) {
-            match pallet_identity::Pallet::<T>::add_right(
-                RawOrigin::Root.into(),
-                idty_index,
-                IdtyRight::StrongCert,
-            ) {
-                Ok(_) => {
-                    Self::do_apply_first_issuable_on(idty_index);
-                }
-                Err(e) => {
-                    sp_std::if_std! {
-                        println!("{:?}", e)
-                    }
-                }
-            }
-        }
-        pub(super) fn do_add_rights(idty_index: IdtyIndex, received_cert_count: u32) {
-            if received_cert_count >= T::MinCertForUdRight::get() as u32 {
-                if let Err(e) = pallet_identity::Pallet::<T>::add_right(
-                    RawOrigin::Root.into(),
-                    idty_index,
-                    IdtyRight::Ud,
-                ) {
-                    sp_std::if_std! {
-                        println!("{:?}", e)
-                    }
-                }
-            }
-            if received_cert_count >= T::MinCertForCertRight::get() as u32 {
-                Self::do_add_cert_right(idty_index);
-            }
-            if received_cert_count >= T::MinCertForCreateIdtyRight::get() as u32 {
-                if let Err(e) = pallet_identity::Pallet::<T>::add_right(
-                    RawOrigin::Root.into(),
-                    idty_index,
-                    IdtyRight::CreateIdty,
-                ) {
+        pub(super) fn dispath_idty_call(idty_call: pallet_identity::Call<T>) -> bool {
+            if T::ManageIdentitiesChanges::get() {
+                if let Err(e) = idty_call.dispatch_bypass_filter(RawOrigin::Root.into()) {
                     sp_std::if_std! {
                         println!("{:?}", e)
                     }
+                    return false;
                 }
             }
+            true
         }
     }
 }
 
-impl<T: Config> pallet_identity::traits::EnsureIdtyCallAllowed<T> for Pallet<T> {
+impl<T: Config<I>, I: 'static> pallet_identity::traits::EnsureIdtyCallAllowed<T> for Pallet<T, I> {
     fn can_create_identity(creator: IdtyIndex) -> bool {
-        if let Some(cert_meta) =
-            pallet_certification::Pallet::<T, Instance1>::idty_cert_meta(creator)
-        {
-            use frame_support::traits::Get as _;
-            cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number()
+        if let Some(cert_meta) = pallet_certification::Pallet::<T, I>::idty_cert_meta(creator) {
+            cert_meta.received_count >= T::MinCertForCreateIdtyRight::get()
+                && cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number()
                 && cert_meta.issued_count < T::MaxByIssuer::get()
         } else {
-            true
+            false
         }
     }
     fn can_confirm_identity(idty_index: IdtyIndex) -> bool {
-        pallet_membership::Pallet::<T, Instance1>::request_membership(
+        pallet_membership::Pallet::<T, I>::request_membership(
             RawOrigin::Root.into(),
             idty_index,
+            (),
         )
         .is_ok()
     }
     fn can_validate_identity(idty_index: IdtyIndex) -> bool {
-        pallet_membership::Pallet::<T, Instance1>::claim_membership(
-            RawOrigin::Root.into(),
-            idty_index,
-        )
-        .is_ok()
+        pallet_membership::Pallet::<T, I>::claim_membership(RawOrigin::Root.into(), idty_index)
+            .is_ok()
     }
 }
 
-impl<T: Config> sp_membership::traits::IsIdtyAllowedToClaimMembership<IdtyIndex> for Pallet<T> {
+impl<T: Config<I>, I: 'static> sp_membership::traits::IsIdtyAllowedToClaimMembership<IdtyIndex>
+    for Pallet<T, I>
+{
     fn is_idty_allowed_to_claim_membership(_: &IdtyIndex) -> bool {
         false
     }
 }
 
-impl<T: Config> sp_membership::traits::IsIdtyAllowedToRenewMembership<IdtyIndex> for Pallet<T> {
+impl<T: Config<I>, I: 'static> sp_membership::traits::IsIdtyAllowedToRenewMembership<IdtyIndex>
+    for Pallet<T, I>
+{
     fn is_idty_allowed_to_renew_membership(idty_index: &IdtyIndex) -> bool {
         if let Some(idty_value) = pallet_identity::Pallet::<T>::identity(idty_index) {
             idty_value.status == IdtyStatus::Validated
@@ -169,18 +137,20 @@ impl<T: Config> sp_membership::traits::IsIdtyAllowedToRenewMembership<IdtyIndex>
     }
 }
 
-impl<T: Config> sp_membership::traits::IsIdtyAllowedToRequestMembership<IdtyIndex> for Pallet<T> {
+impl<T: Config<I>, I: 'static> sp_membership::traits::IsIdtyAllowedToRequestMembership<IdtyIndex>
+    for Pallet<T, I>
+{
     fn is_idty_allowed_to_request_membership(idty_index: &IdtyIndex) -> bool {
         if let Some(idty_value) = pallet_identity::Pallet::<T>::identity(idty_index) {
-            idty_value.status == IdtyStatus::Validated
+            idty_value.status == IdtyStatus::Disabled
         } else {
             false
         }
     }
 }
 
-impl<T: Config> sp_membership::traits::IsOriginAllowedToUseIdty<T::Origin, IdtyIndex>
-    for Pallet<T>
+impl<T: Config<I>, I: 'static> sp_membership::traits::IsOriginAllowedToUseIdty<T::Origin, IdtyIndex>
+    for Pallet<T, I>
 {
     fn is_origin_allowed_to_use_idty(
         origin: &T::Origin,
@@ -204,52 +174,50 @@ impl<T: Config> sp_membership::traits::IsOriginAllowedToUseIdty<T::Origin, IdtyI
     }
 }
 
-impl<T: crate::pallet::Config> sp_membership::traits::OnEvent<IdtyIndex> for Pallet<T> {
-    fn on_event(membership_event: sp_membership::Event<IdtyIndex>) -> Weight {
+impl<T: Config<I>, I: 'static> sp_membership::traits::OnEvent<IdtyIndex, ()> for Pallet<T, I> {
+    fn on_event(membership_event: &sp_membership::Event<IdtyIndex>) -> Weight {
         match membership_event {
             sp_membership::Event::<IdtyIndex>::MembershipAcquired(_) => {}
             sp_membership::Event::<IdtyIndex>::MembershipExpired(idty_index) => {
-                if let Err(e) = pallet_identity::Pallet::<T>::remove_all_rights(
-                    RawOrigin::Root.into(),
-                    idty_index,
-                ) {
-                    sp_std::if_std! {
-                        println!("{:?}", e)
-                    }
-                }
+                Self::dispath_idty_call(pallet_identity::Call::disable_identity {
+                    idty_index: *idty_index,
+                });
             }
             sp_membership::Event::<IdtyIndex>::MembershipRenewed(_) => {}
-            sp_membership::Event::<IdtyIndex>::MembershipRequested(idty_index) => {
+            sp_membership::Event::<IdtyIndex>::MembershipRequested(idty_index, _) => {
                 if let Some(idty_cert_meta) =
-                    pallet_certification::Pallet::<T, Instance1>::idty_cert_meta(idty_index)
+                    pallet_certification::Pallet::<T, I>::idty_cert_meta(idty_index)
                 {
                     let received_count = idty_cert_meta.received_count;
 
                     // TODO insert `receiver` in distance queue if received_count >= MinCertForUdRight
-                    Self::do_add_rights(idty_index, received_count);
+                    if received_count >= T::MinCertForUdRight::get() as u32 {
+                        // TODO insert `receiver` in distance queue
+                        if Self::dispath_idty_call(pallet_identity::Call::validate_identity {
+                            idty_index: *idty_index,
+                        }) && received_count == T::MinReceivedCertToBeAbleToIssueCert::get()
+                        {
+                            Self::do_apply_first_issuable_on(*idty_index);
+                        }
+                    }
                 }
             }
             sp_membership::Event::<IdtyIndex>::MembershipRevoked(_) => {}
             sp_membership::Event::<IdtyIndex>::PendingMembershipExpired(idty_index) => {
-                if let Err(e) = pallet_identity::Pallet::<T>::remove_identity(
-                    RawOrigin::Root.into(),
-                    idty_index,
-                ) {
-                    sp_std::if_std! {
-                        println!("{:?}", e)
-                    }
-                }
+                Self::dispath_idty_call(pallet_identity::Call::remove_identity {
+                    idty_index: *idty_index,
+                });
             }
         }
         0
     }
 }
 
-impl<T: Config> pallet_identity::traits::OnIdtyChange<T> for Pallet<T> {
+impl<T: Config<I>, I: 'static> pallet_identity::traits::OnIdtyChange<T> for Pallet<T, I> {
     fn on_idty_change(idty_index: IdtyIndex, idty_event: IdtyEvent<T>) -> Weight {
         match idty_event {
             IdtyEvent::Created { creator } => {
-                if let Err(e) = <pallet_certification::Pallet<T, Instance1>>::add_cert(
+                if let Err(e) = <pallet_certification::Pallet<T, I>>::add_cert(
                     frame_system::Origin::<T>::Root.into(),
                     creator,
                     idty_index,
@@ -267,40 +235,26 @@ impl<T: Config> pallet_identity::traits::OnIdtyChange<T> for Pallet<T> {
     }
 }
 
-impl<T: crate::pallet::Config> pallet_certification::traits::OnNewcert<IdtyIndex> for Pallet<T> {
+impl<T: Config<I>, I: 'static> pallet_certification::traits::OnNewcert<IdtyIndex> for Pallet<T, I> {
     fn on_new_cert(
         _issuer: IdtyIndex,
-        _issuer_issued_count: u8,
+        _issuer_issued_count: u32,
         receiver: IdtyIndex,
         receiver_received_count: u32,
     ) -> Weight {
-        if pallet_membership::Pallet::<T, Instance1>::is_member(&receiver) {
-            Self::do_add_rights(receiver, receiver_received_count);
-        } else if pallet_membership::Pallet::<T, Instance1>::pending_membership(receiver).is_some()
-            && receiver_received_count >= T::MinCertForUdRight::get() as u32
+        if pallet_membership::Pallet::<T, I>::is_member(&receiver) {
+            if receiver_received_count == T::MinReceivedCertToBeAbleToIssueCert::get() {
+                Self::do_apply_first_issuable_on(receiver);
+            }
+        } else if pallet_membership::Pallet::<T, I>::pending_membership(receiver).is_some()
+            && receiver_received_count >= T::MinCertForUdRight::get()
         {
             // TODO insert `receiver` in distance queue
-            let mut rights = sp_std::vec![IdtyRight::Ud];
-            let mut cert_right = false;
-            if receiver_received_count >= T::MinCertForCertRight::get() as u32 {
-                rights.push(IdtyRight::StrongCert);
-                cert_right = true;
-            }
-            if receiver_received_count >= T::MinCertForCreateIdtyRight::get() as u32 {
-                rights.push(IdtyRight::CreateIdty);
-            }
-            if let Err(e) = pallet_identity::Pallet::<T>::validate_identity(
-                RawOrigin::Root.into(),
-                receiver,
-                rights,
-            ) {
-                sp_std::if_std! {
-                    println!("{:?}", e)
-                }
-                return 0;
-            }
+            Self::dispath_idty_call(pallet_identity::Call::validate_identity {
+                idty_index: receiver,
+            });
 
-            if cert_right {
+            if receiver_received_count == T::MinReceivedCertToBeAbleToIssueCert::get() {
                 Self::do_apply_first_issuable_on(receiver);
             }
         }
@@ -308,47 +262,29 @@ impl<T: crate::pallet::Config> pallet_certification::traits::OnNewcert<IdtyIndex
     }
 }
 
-impl<T: crate::pallet::Config> pallet_certification::traits::OnRemovedCert<IdtyIndex>
-    for Pallet<T>
+impl<T: Config<I>, I: 'static> pallet_certification::traits::OnRemovedCert<IdtyIndex>
+    for Pallet<T, I>
 {
     fn on_removed_cert(
         _issuer: IdtyIndex,
-        _issuer_issued_count: u8,
+        _issuer_issued_count: u32,
         receiver: IdtyIndex,
         receiver_received_count: u32,
         _expiration: bool,
     ) -> Weight {
-        if receiver_received_count < T::MinCertForUdRight::get() as u32 {
-            if let Err(e) = pallet_identity::Pallet::<T>::del_right(
-                RawOrigin::Root.into(),
-                receiver,
-                IdtyRight::Ud,
-            ) {
-                sp_std::if_std! {
-                    println!("{:?}", e)
-                }
-            }
-        }
-        if receiver_received_count < T::MinCertForCertRight::get() as u32 {
-            if let Err(e) = pallet_identity::Pallet::<T>::del_right(
-                RawOrigin::Root.into(),
-                receiver,
-                IdtyRight::StrongCert,
-            ) {
-                sp_std::if_std! {
-                    println!("{:?}", e)
-                }
-            }
-        }
-        if receiver_received_count < T::MinCertForCreateIdtyRight::get() as u32 {
-            if let Err(e) = pallet_identity::Pallet::<T>::del_right(
+        if receiver_received_count < T::MinCertForUdRight::get() {
+            // Revoke receiver membership and disable his identity
+            if let Err(e) = pallet_membership::Pallet::<T, I>::revoke_membership(
                 RawOrigin::Root.into(),
                 receiver,
-                IdtyRight::CreateIdty,
             ) {
                 sp_std::if_std! {
                     println!("{:?}", e)
                 }
+            } else {
+                Self::dispath_idty_call(pallet_identity::Call::disable_identity {
+                    idty_index: receiver,
+                });
             }
         }
         0
diff --git a/pallets/duniter-wot/src/mock.rs b/pallets/duniter-wot/src/mock.rs
index ccc2ce6d0..309c3bad6 100644
--- a/pallets/duniter-wot/src/mock.rs
+++ b/pallets/duniter-wot/src/mock.rs
@@ -38,7 +38,7 @@ frame_support::construct_runtime!(
         UncheckedExtrinsic = UncheckedExtrinsic,
     {
         System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
-        DuniterWot: pallet_duniter_wot::{Pallet},
+        DuniterWot: pallet_duniter_wot::<Instance1>::{Pallet},
         Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>},
         Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>},
         Cert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>},
@@ -80,15 +80,14 @@ impl system::Config for Test {
 
 // DuniterWot
 parameter_types! {
-    pub const MinCertForUdRight: u8 = 2;
-    pub const MinCertForCertRight: u8 = 3;
-    pub const MinCertForCreateIdtyRigh: u8 = 4;
+    pub const MinCertForUdRight: u32 = 2;
+    pub const MinCertForCreateIdtyRigh: u32 = 4;
     pub const FirstIssuableOn: u64 = 2;
 }
 
-impl pallet_duniter_wot::Config for Test {
+impl pallet_duniter_wot::Config<Instance1> for Test {
+    type ManageIdentitiesChanges = frame_support::traits::ConstBool<true>;
     type MinCertForUdRight = MinCertForUdRight;
-    type MinCertForCertRight = MinCertForCertRight;
     type MinCertForCreateIdtyRight = MinCertForCreateIdtyRigh;
     type FirstIssuableOn = FirstIssuableOn;
 }
@@ -97,8 +96,7 @@ impl pallet_duniter_wot::Config for Test {
 parameter_types! {
     pub const ConfirmPeriod: u64 = 2;
     pub const IdtyCreationPeriod: u64 = 3;
-    pub const MaxInactivityPeriod: u64 = 5;
-    pub const MaxNoRightPeriod: u64 = 4;
+    pub const MaxDisabledPeriod: u64 = 4;
     pub const ValidationPeriod: u64 = 2;
 }
 
@@ -112,8 +110,6 @@ impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl {
 impl pallet_identity::Config for Test {
     type ConfirmPeriod = ConfirmPeriod;
     type Event = Event;
-    type AddRightOrigin = system::EnsureRoot<AccountId>;
-    type DelRightOrigin = system::EnsureRoot<AccountId>;
     type EnsureIdtyCallAllowed = DuniterWot;
     type IdtyCreationPeriod = IdtyCreationPeriod;
     type IdtyData = ();
@@ -121,11 +117,9 @@ impl pallet_identity::Config for Test {
     type IdtyNameValidator = IdtyNameValidatorTestImpl;
     type IdtyIndex = IdtyIndex;
     type IdtyValidationOrigin = system::EnsureRoot<AccountId>;
-    type IdtyRight = IdtyRight;
     type IsMember = Membership;
     type OnIdtyChange = DuniterWot;
-    type OnRightKeyChange = ();
-    type MaxNoRightPeriod = MaxNoRightPeriod;
+    type MaxDisabledPeriod = MaxDisabledPeriod;
 }
 
 // Membership
@@ -145,9 +139,10 @@ impl pallet_membership::Config<Instance1> for Test {
     type Event = Event;
     type ExternalizeMembershipStorage = ExternalizeMembershipStorage;
     type IdtyId = IdtyIndex;
-    type OnEvent = DuniterWot;
     type MembershipExternalStorage = sp_membership::traits::NoExternalStorage;
     type MembershipPeriod = MembershipPeriod;
+    type MetaData = ();
+    type OnEvent = DuniterWot;
     type PendingMembershipPeriod = PendingMembershipPeriod;
     type RenewablePeriod = RenewablePeriod;
     type RevocationPeriod = RevocationPeriod;
@@ -155,19 +150,21 @@ impl pallet_membership::Config<Instance1> for Test {
 
 // Cert
 parameter_types! {
-    pub const MaxByIssuer: u8 = 3;
+    pub const MaxByIssuer: u8 = 8;
+    pub const MinReceivedCertToBeAbleToIssueCert: u32 = 3;
     pub const CertRenewablePeriod: u64 = 4;
     pub const CertPeriod: u64 = 2;
     pub const ValidityPeriod: u64 = 10;
 }
 
 impl pallet_certification::Config<Instance1> for Test {
-    type AddCertOrigin = pallet_duniter_wot::AddStrongCertOrigin<Test>;
+    type AddCertOrigin = pallet_duniter_wot::AddCertOrigin<Test, Instance1>;
     type CertPeriod = CertPeriod;
-    type DelCertOrigin = pallet_duniter_wot::DelStrongCertOrigin<Test>;
+    type DelCertOrigin = pallet_duniter_wot::DelCertOrigin<Test, Instance1>;
     type Event = Event;
     type IdtyIndex = IdtyIndex;
     type MaxByIssuer = MaxByIssuer;
+    type MinReceivedCertToBeAbleToIssueCert = MinReceivedCertToBeAbleToIssueCert;
     type OnNewcert = DuniterWot;
     type OnRemovedCert = DuniterWot;
     type CertRenewablePeriod = CertRenewablePeriod;
@@ -185,14 +182,9 @@ pub fn new_test_ext(initial_identities_len: usize) -> sp_io::TestExternalities {
                 .map(|i| pallet_identity::IdtyValue {
                     data: (),
                     owner_key: i as u64,
-                    name: pallet_identity::IdtyName::from(NAMES[i]),
+                    name: pallet_identity::IdtyName::from(NAMES[i - 1]),
                     next_creatable_identity_on: 0,
                     removable_on: 0,
-                    rights: vec![
-                        (IdtyRight::CreateIdty, None),
-                        (IdtyRight::StrongCert, None),
-                        (IdtyRight::Ud, None),
-                    ],
                     status: pallet_identity::IdtyStatus::Validated,
                 })
                 .collect(),
diff --git a/pallets/duniter-wot/src/tests.rs b/pallets/duniter-wot/src/tests.rs
index 7b29034e5..a688a06d7 100644
--- a/pallets/duniter-wot/src/tests.rs
+++ b/pallets/duniter-wot/src/tests.rs
@@ -16,9 +16,9 @@
 
 use crate::mock::Identity;
 use crate::mock::*;
-use crate::IdtyRight;
 use frame_support::assert_err;
 use frame_support::assert_ok;
+use frame_support::error::BadOrigin;
 use frame_support::instances::Instance1;
 use frame_system::{EventRecord, Phase};
 use pallet_identity::{IdtyName, IdtyStatus};
@@ -55,15 +55,15 @@ fn test_creator_not_allowed_to_create_idty() {
 
 #[test]
 fn test_create_idty_ok() {
-    new_test_ext(3).execute_with(|| {
+    new_test_ext(5).execute_with(|| {
         run_to_block(2);
 
         // Alice should be able te create an identity at block #2
         assert_ok!(Identity::create_identity(
             Origin::signed(1),
             1,
-            IdtyName::from("Dave"),
-            4
+            IdtyName::from("Ferdie"),
+            6
         ));
         // 2 events should have occurred: IdtyCreated and NewCert
         let events = System::events();
@@ -73,8 +73,8 @@ fn test_create_idty_ok() {
             EventRecord {
                 phase: Phase::Initialization,
                 event: Event::Identity(pallet_identity::Event::IdtyCreated(
-                    IdtyName::from("Dave"),
-                    4
+                    IdtyName::from("Ferdie"),
+                    6
                 )),
                 topics: vec![],
             }
@@ -85,54 +85,54 @@ fn test_create_idty_ok() {
                 phase: Phase::Initialization,
                 event: Event::Cert(pallet_certification::Event::NewCert {
                     issuer: 1,
-                    issuer_issued_count: 3,
-                    receiver: 4,
+                    issuer_issued_count: 5,
+                    receiver: 6,
                     receiver_received_count: 1
                 }),
                 topics: vec![],
             }
         );
-        assert_eq!(Identity::identity(4).unwrap().status, IdtyStatus::Created);
-        assert_eq!(Identity::identity(4).unwrap().removable_on, 4);
+        assert_eq!(Identity::identity(6).unwrap().status, IdtyStatus::Created);
+        assert_eq!(Identity::identity(6).unwrap().removable_on, 4);
     });
 }
 
 #[test]
 fn test_ud_right_achievement_ok() {
-    new_test_ext(3).execute_with(|| {
-        // Alice create Dave identity
+    new_test_ext(5).execute_with(|| {
+        // Alice create Ferdie identity
         run_to_block(2);
         assert_ok!(Identity::create_identity(
             Origin::signed(1),
             1,
-            IdtyName::from("Dave"),
-            4
+            IdtyName::from("Ferdie"),
+            6
         ));
 
-        // Dave confirm it's identity
+        // Ferdie confirm it's identity
         run_to_block(3);
         assert_ok!(Identity::confirm_identity(
-            Origin::signed(4),
-            IdtyName::from("Dave"),
-            4
+            Origin::signed(6),
+            IdtyName::from("Ferdie"),
+            6
         ));
 
-        // Bob should be able to certify Dave
+        // Bob should be able to certify Ferdie
         run_to_block(4);
-        assert_ok!(Cert::add_cert(Origin::signed(2), 2, 4));
+        assert_ok!(Cert::add_cert(Origin::signed(2), 2, 6));
 
         let events = System::events();
         // 3 events should have occurred: NewCert, MembershipAcquired, IdtyValidated and IdtyAcquireRight
-        assert_eq!(events.len(), 4);
-        println!("{:?}", events[2]);
+        assert_eq!(events.len(), 3);
+        //println!("{:?}", events[2]);
         assert_eq!(
             events[0],
             EventRecord {
                 phase: Phase::Initialization,
                 event: Event::Cert(pallet_certification::Event::NewCert {
                     issuer: 2,
-                    issuer_issued_count: 3,
-                    receiver: 4,
+                    issuer_issued_count: 5,
+                    receiver: 6,
                     receiver_received_count: 2
                 }),
                 topics: vec![],
@@ -142,7 +142,7 @@ fn test_ud_right_achievement_ok() {
             events[1],
             EventRecord {
                 phase: Phase::Initialization,
-                event: Event::Membership(pallet_membership::Event::MembershipAcquired(4)),
+                event: Event::Membership(pallet_membership::Event::MembershipAcquired(6)),
                 topics: vec![],
             }
         );
@@ -151,45 +151,34 @@ fn test_ud_right_achievement_ok() {
             EventRecord {
                 phase: Phase::Initialization,
                 event: Event::Identity(pallet_identity::Event::IdtyValidated(IdtyName::from(
-                    "Dave"
+                    "Ferdie"
                 ),)),
                 topics: vec![],
             }
         );
-        assert_eq!(
-            events[3],
-            EventRecord {
-                phase: Phase::Initialization,
-                event: Event::Identity(pallet_identity::Event::IdtyAcquireRight(
-                    IdtyName::from("Dave"),
-                    IdtyRight::Ud
-                )),
-                topics: vec![],
-            }
-        );
     });
 }
 
 #[test]
 fn test_confirm_idty_ok() {
-    new_test_ext(3).execute_with(|| {
+    new_test_ext(5).execute_with(|| {
         run_to_block(2);
 
-        // Alice create Dave identity
+        // Alice create Ferdie identity
         assert_ok!(Identity::create_identity(
             Origin::signed(1),
             1,
-            IdtyName::from("Dave"),
-            4
+            IdtyName::from("Ferdie"),
+            6
         ));
 
         run_to_block(3);
 
-        // Dave should be able to confirm it's identity
+        // Ferdie should be able to confirm it's identity
         assert_ok!(Identity::confirm_identity(
-            Origin::signed(4),
-            IdtyName::from("Dave"),
-            4
+            Origin::signed(6),
+            IdtyName::from("Ferdie"),
+            6
         ));
         let events = System::events();
         // 2 events should have occurred: MembershipRequested and IdtyConfirmed
@@ -199,7 +188,7 @@ fn test_confirm_idty_ok() {
             events[0],
             EventRecord {
                 phase: Phase::Initialization,
-                event: Event::Membership(pallet_membership::Event::MembershipRequested(4)),
+                event: Event::Membership(pallet_membership::Event::MembershipRequested(6)),
                 topics: vec![],
             }
         );
@@ -208,10 +197,76 @@ fn test_confirm_idty_ok() {
             EventRecord {
                 phase: Phase::Initialization,
                 event: Event::Identity(pallet_identity::Event::IdtyConfirmed(IdtyName::from(
-                    "Dave"
+                    "Ferdie"
                 ),)),
                 topics: vec![],
             }
         );
     });
 }
+
+#[test]
+fn test_idty_membership_expire_them_requested() {
+    new_test_ext(3).execute_with(|| {
+        run_to_block(4);
+
+        // Alice renew her membership
+        assert_ok!(Membership::renew_membership(Origin::signed(1), 1));
+        // Bob renew his membership
+        assert_ok!(Membership::renew_membership(Origin::signed(2), 2));
+
+        // Charlie's membership should expire at block #5
+        run_to_block(5);
+        assert!(Membership::membership(3).is_none());
+        let events = System::events();
+        assert_eq!(events.len(), 1);
+        assert_eq!(
+            events[0],
+            EventRecord {
+                phase: Phase::Initialization,
+                event: Event::Membership(pallet_membership::Event::MembershipExpired(3)),
+                topics: vec![],
+            }
+        );
+
+        // Charlie's identity should be disabled at block #5
+        assert_eq!(Identity::identity(3).unwrap().status, IdtyStatus::Disabled);
+
+        // Alice can't renew it's cert to Charlie
+        assert_err!(Cert::add_cert(Origin::signed(1), 1, 3), BadOrigin);
+
+        // Charlie should be able to request membership
+        run_to_block(6);
+        assert_ok!(Membership::request_membership(Origin::signed(3), 3, ()));
+
+        // Charlie should re-enter in the wot immediatly
+        let events = System::events();
+        assert_eq!(events.len(), 3);
+        assert_eq!(
+            events[0],
+            EventRecord {
+                phase: Phase::Initialization,
+                event: Event::Membership(pallet_membership::Event::MembershipRequested(3)),
+                topics: vec![],
+            }
+        );
+        assert_eq!(
+            events[1],
+            EventRecord {
+                phase: Phase::Initialization,
+                event: Event::Membership(pallet_membership::Event::MembershipAcquired(3)),
+                topics: vec![],
+            }
+        );
+        assert_eq!(
+            events[2],
+            EventRecord {
+                phase: Phase::Initialization,
+                event: Event::Identity(pallet_identity::Event::IdtyValidated(IdtyName::from(
+                    "Charlie"
+                ))),
+                topics: vec![],
+            }
+        );
+    });
+}
diff --git a/pallets/duniter-wot/src/types.rs b/pallets/duniter-wot/src/types.rs
index 37ae0195b..ffac045f8 100644
--- a/pallets/duniter-wot/src/types.rs
+++ b/pallets/duniter-wot/src/types.rs
@@ -17,15 +17,13 @@
 use pallet_identity::IdtyStatus;
 
 use crate::{Config, IdtyIndex};
-use frame_support::instances::Instance1;
 use frame_support::pallet_prelude::*;
-use scale_info::TypeInfo;
-#[cfg(feature = "std")]
-use serde::{Deserialize, Serialize};
 use sp_runtime::traits::IsMember;
 
-pub struct AddStrongCertOrigin<T>(core::marker::PhantomData<T>);
-impl<T: Config> EnsureOrigin<(T::Origin, IdtyIndex, IdtyIndex)> for AddStrongCertOrigin<T> {
+pub struct AddCertOrigin<T, I>(core::marker::PhantomData<(T, I)>);
+impl<T: Config<I>, I: 'static> EnsureOrigin<(T::Origin, IdtyIndex, IdtyIndex)>
+    for AddCertOrigin<T, I>
+{
     type Success = ();
 
     fn try_origin(
@@ -35,32 +33,39 @@ impl<T: Config> EnsureOrigin<(T::Origin, IdtyIndex, IdtyIndex)> for AddStrongCer
             Ok(frame_system::RawOrigin::Root) => Ok(()),
             Ok(frame_system::RawOrigin::Signed(who)) => {
                 if let Some(issuer) = pallet_identity::Pallet::<T>::identity(o.1) {
-                    if let Some(allowed_key) = issuer.get_right_key(IdtyRight::StrongCert) {
-                        if who == allowed_key {
-                            if let Some(receiver) = pallet_identity::Pallet::<T>::identity(o.2) {
-                                match receiver.status {
-                                    IdtyStatus::ConfirmedByOwner => Ok(()),
-                                    IdtyStatus::Validated => {
-                                        if pallet_membership::Pallet::<T, Instance1>::is_member(
+                    if who == issuer.owner_key {
+                        if let Some(receiver) = pallet_identity::Pallet::<T>::identity(o.2) {
+                            match receiver.status {
+                                IdtyStatus::ConfirmedByOwner => Ok(()),
+                                IdtyStatus::Created => Err(o),
+                                IdtyStatus::Disabled => {
+                                    if pallet_membership::Pallet::<T, I>::pending_membership(&o.2)
+                                        .is_some()
+                                    {
+                                        Ok(())
+                                    } else {
+                                        Err(o)
+                                    }
+                                }
+                                IdtyStatus::Validated => {
+                                    if pallet_membership::Pallet::<T, I>::is_member(&o.2)
+                                        || pallet_membership::Pallet::<T, I>::pending_membership(
                                             &o.2,
-                                        ) || pallet_membership::Pallet::<T, Instance1>::pending_membership(&o.2).is_some() {
-                                            Ok(())
-                                        } else {
-                                            Err(o)
-                                        }
+                                        )
+                                        .is_some()
+                                    {
+                                        Ok(())
+                                    } else {
+                                        Err(o)
                                     }
-                                    IdtyStatus::Created => Err(o),
                                 }
-                            } else {
-                                // Receiver not found
-                                Err(o)
                             }
                         } else {
-                            // Bad key
+                            // Receiver not found
                             Err(o)
                         }
                     } else {
-                        // Issuer has not right StrongCert
+                        // Bad key
                         Err(o)
                     }
                 } else {
@@ -73,8 +78,10 @@ impl<T: Config> EnsureOrigin<(T::Origin, IdtyIndex, IdtyIndex)> for AddStrongCer
     }
 }
 
-pub struct DelStrongCertOrigin<T>(core::marker::PhantomData<T>);
-impl<T: Config> EnsureOrigin<(T::Origin, IdtyIndex, IdtyIndex)> for DelStrongCertOrigin<T> {
+pub struct DelCertOrigin<T, I>(core::marker::PhantomData<(T, I)>);
+impl<T: Config<I>, I: 'static> EnsureOrigin<(T::Origin, IdtyIndex, IdtyIndex)>
+    for DelCertOrigin<T, I>
+{
     type Success = ();
 
     fn try_origin(
@@ -86,29 +93,3 @@ impl<T: Config> EnsureOrigin<(T::Origin, IdtyIndex, IdtyIndex)> for DelStrongCer
         }
     }
 }
-
-#[cfg_attr(feature = "std", derive(Deserialize, Serialize))]
-#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, TypeInfo)]
-pub enum IdtyRight {
-    CreateIdty,
-    LightCert,
-    StrongCert,
-    Ud,
-}
-impl Default for IdtyRight {
-    fn default() -> Self {
-        Self::Ud
-    }
-}
-impl pallet_identity::traits::IdtyRight for IdtyRight {
-    fn allow_owner_key(self) -> bool {
-        match self {
-            Self::CreateIdty | Self::LightCert | IdtyRight::StrongCert | Self::Ud => true,
-            //IdtyRight::StrongCert => false,
-            //_ => false,
-        }
-    }
-    fn create_idty_right() -> Self {
-        Self::CreateIdty
-    }
-}
diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs
index bc596940d..e3223dd90 100644
--- a/pallets/identity/src/lib.rs
+++ b/pallets/identity/src/lib.rs
@@ -45,7 +45,6 @@ pub mod pallet {
     use frame_support::pallet_prelude::*;
     use frame_support::traits::StorageVersion;
     use frame_system::pallet_prelude::*;
-    use sp_runtime::traits::IsMember;
 
     /// The current storage version.
     const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
@@ -64,10 +63,6 @@ pub mod pallet {
         type ConfirmPeriod: Get<Self::BlockNumber>;
         /// Because this pallet emits events, it depends on the runtime's definition of an event.
         type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
-        /// Origin allowed to add a right to an identity
-        type AddRightOrigin: EnsureOrigin<Self::Origin>;
-        /// Origin allowed to delete a right to an identity
-        type DelRightOrigin: EnsureOrigin<Self::Origin>;
         /// Management of the authorizations of the different calls. (The default implementation only allows root)
         type EnsureIdtyCallAllowed: EnsureIdtyCallAllowed<Self>;
         /// Minimum duration between the creation of 2 identities by the same creator
@@ -90,23 +85,20 @@ pub mod pallet {
         type IdtyNameValidator: IdtyNameValidator;
         /// Origin allowed to validate identity
         type IdtyValidationOrigin: EnsureOrigin<Self::Origin>;
-        /// Rights that an identity can have
-        type IdtyRight: IdtyRight;
         ///
         type IsMember: sp_runtime::traits::IsMember<Self::IdtyIndex>;
         /// On identity confirmed by it's owner
         type OnIdtyChange: OnIdtyChange<Self>;
-        /// On right key change
-        type OnRightKeyChange: OnRightKeyChange<Self>;
         #[pallet::constant]
-        /// Maximum period with no rights, after this period, the identity is permanently deleted
-        type MaxNoRightPeriod: Get<Self::BlockNumber>;
+        /// Maximum period with disabled status, after this period, the identity is permanently
+        /// deleted
+        type MaxDisabledPeriod: Get<Self::BlockNumber>;
     }
 
     // GENESIS STUFF //
     #[pallet::genesis_config]
     pub struct GenesisConfig<T: Config> {
-        pub identities: Vec<IdtyValue<T::AccountId, T::BlockNumber, T::IdtyData, T::IdtyRight>>,
+        pub identities: Vec<IdtyValue<T::AccountId, T::BlockNumber, T::IdtyData>>,
     }
 
     #[cfg(feature = "std")]
@@ -128,16 +120,7 @@ pub mod pallet {
                     "Idty name {:?} is present twice",
                     &idty_value.name
                 );
-                if idty_value.status == IdtyStatus::Validated {
-                    if idty_value.rights.is_empty() {
-                        assert!(idty_value.removable_on > T::BlockNumber::zero());
-                    } else {
-                        assert!(idty_value.removable_on == T::BlockNumber::zero());
-                    }
-                } else {
-                    assert!(idty_value.removable_on > T::BlockNumber::zero());
-                    assert!(idty_value.rights.is_empty())
-                }
+                assert!(idty_value.removable_on == T::BlockNumber::zero());
                 names.insert(idty_value.name.clone());
             }
 
@@ -168,7 +151,7 @@ pub mod pallet {
         _,
         Blake2_128Concat,
         T::IdtyIndex,
-        IdtyValue<T::AccountId, T::BlockNumber, T::IdtyData, T::IdtyRight>,
+        IdtyValue<T::AccountId, T::BlockNumber, T::IdtyData>,
         OptionQuery,
     >;
 
@@ -225,20 +208,6 @@ pub mod pallet {
         /// An identity has been validated
         /// [idty]
         IdtyValidated(IdtyName),
-        /// An identity has acquired a new right
-        /// [idty, right]
-        IdtyAcquireRight(IdtyName, T::IdtyRight),
-        /// An identity lost a right
-        /// [idty, righ]
-        IdtyLostRight(IdtyName, T::IdtyRight),
-        /// An identity has modified a subkey associated with a right
-        /// [idty_name, right, old_subkey_opt, new_subkey_opt]
-        IdtySetRightSubKey(
-            IdtyName,
-            T::IdtyRight,
-            Option<T::AccountId>,
-            Option<T::AccountId>,
-        ),
     }
 
     // CALLS //
@@ -261,32 +230,20 @@ pub mod pallet {
             let creator_idty_val =
                 Identities::<T>::try_get(&creator).map_err(|_| Error::<T>::CreatorNotExist)?;
 
-            let expected_account = if let Ok(index) = creator_idty_val
-                .rights
-                .binary_search_by(|(right_, _)| right_.cmp(&T::IdtyRight::create_idty_right()))
-            {
-                creator_idty_val.rights[index]
-                    .1
-                    .clone()
-                    .unwrap_or(creator_idty_val.owner_key)
-            } else {
-                return Err(Error::<T>::CreatorNotHaveRightToCreateIdty.into());
-            };
-
-            if who != expected_account {
+            if who != creator_idty_val.owner_key {
                 return Err(Error::<T>::RequireToBeOwner.into());
             }
 
+            if !T::EnsureIdtyCallAllowed::can_create_identity(creator) {
+                return Err(Error::<T>::CreatorNotAllowedToCreateIdty.into());
+            }
+
             let block_number = frame_system::pallet::Pallet::<T>::block_number();
 
             if creator_idty_val.next_creatable_identity_on > block_number {
                 return Err(Error::<T>::NotRespectIdtyCreationPeriod.into());
             }
 
-            if !T::EnsureIdtyCallAllowed::can_create_identity(creator) {
-                return Err(Error::<T>::CreatorNotAllowedToCreateIdty.into());
-            }
-
             if !T::IdtyNameValidator::validate(&idty_name) {
                 return Err(Error::<T>::IdtyNameInvalid.into());
             }
@@ -316,7 +273,6 @@ pub mod pallet {
                     next_creatable_identity_on: T::BlockNumber::zero(),
                     owner_key: owner_key.clone(),
                     removable_on,
-                    rights: Vec::with_capacity(0),
                     status: IdtyStatus::Created,
                     data: idty_data,
                 },
@@ -365,47 +321,24 @@ pub mod pallet {
         pub fn validate_identity(
             origin: OriginFor<T>,
             idty_index: T::IdtyIndex,
-            idty_rights: Vec<T::IdtyRight>,
         ) -> DispatchResultWithPostInfo {
             T::IdtyValidationOrigin::ensure_origin(origin)?;
 
             if let Ok(mut idty_value) = <Identities<T>>::try_get(idty_index) {
                 match idty_value.status {
                     IdtyStatus::Created => Err(Error::<T>::IdtyNotConfirmedByOwner.into()),
-                    IdtyStatus::ConfirmedByOwner => {
+                    IdtyStatus::ConfirmedByOwner | IdtyStatus::Disabled => {
                         if !T::EnsureIdtyCallAllowed::can_validate_identity(idty_index) {
                             return Err(Error::<T>::NotAllowedToValidateIdty.into());
                         }
 
                         idty_value.removable_on = T::BlockNumber::zero();
-                        idty_value.rights =
-                            idty_rights.iter().map(|right| (*right, None)).collect();
                         idty_value.status = IdtyStatus::Validated;
                         let name = idty_value.name.clone();
-                        let owner_key = idty_value.owner_key.clone();
 
                         <Identities<T>>::insert(idty_index, idty_value);
-                        if idty_rights.is_empty() {
-                            let block_number = frame_system::pallet::Pallet::<T>::block_number();
-                            let removable_on = block_number + T::MaxNoRightPeriod::get();
-                            <IdentitiesRemovableOn<T>>::append(
-                                removable_on,
-                                (idty_index, IdtyStatus::Validated),
-                            );
-                        }
                         Self::deposit_event(Event::IdtyValidated(name.clone()));
                         T::OnIdtyChange::on_idty_change(idty_index, IdtyEvent::Validated);
-                        for right in idty_rights {
-                            Self::deposit_event(Event::IdtyAcquireRight(name.clone(), right));
-                            if right.allow_owner_key() {
-                                T::OnRightKeyChange::on_right_key_change(
-                                    idty_index,
-                                    right,
-                                    None,
-                                    Some(owner_key.clone()),
-                                );
-                            }
-                        }
                         Ok(().into())
                     }
                     IdtyStatus::Validated => Err(Error::<T>::IdtyAlreadyValidated.into()),
@@ -415,140 +348,28 @@ pub mod pallet {
             }
         }
         #[pallet::weight(0)]
-        pub fn add_right(
-            origin: OriginFor<T>,
-            idty_index: T::IdtyIndex,
-            right: T::IdtyRight,
-        ) -> DispatchResultWithPostInfo {
-            T::AddRightOrigin::ensure_origin(origin)?;
-
-            if let Ok(mut idty_value) = <Identities<T>>::try_get(idty_index) {
-                if idty_value.status != IdtyStatus::Validated {
-                    return Err(Error::<T>::IdtyNotValidated.into());
-                }
-
-                if !T::IsMember::is_member(&idty_index) {
-                    return Err(Error::<T>::IdtyNotMember.into());
-                }
-
-                if let Err(index) = idty_value
-                    .rights
-                    .binary_search_by(|(right_, _)| right_.cmp(&right))
-                {
-                    let name = idty_value.name.clone();
-                    let new_key = if right.allow_owner_key() {
-                        Some(idty_value.owner_key.clone())
-                    } else {
-                        None
-                    };
-
-                    idty_value.removable_on = T::BlockNumber::zero();
-                    idty_value.rights.insert(index, (right, None));
-                    <Identities<T>>::insert(idty_index, idty_value);
-                    Self::deposit_event(Event::<T>::IdtyAcquireRight(name, right));
-                    if new_key.is_some() {
-                        T::OnRightKeyChange::on_right_key_change(idty_index, right, None, new_key);
-                    }
-                    Ok(().into())
-                } else {
-                    Err(Error::<T>::RightAlreadyAdded.into())
-                }
-            } else {
-                Err(Error::<T>::IdtyNotFound.into())
-            }
-        }
-        #[pallet::weight(0)]
-        pub fn del_right(
-            origin: OriginFor<T>,
-            idty_index: T::IdtyIndex,
-            right: T::IdtyRight,
-        ) -> DispatchResultWithPostInfo {
-            T::DelRightOrigin::ensure_origin(origin)?;
-
-            if let Ok(idty_value) = <Identities<T>>::try_get(idty_index) {
-                if idty_value.status != IdtyStatus::Validated {
-                    return Err(Error::<T>::IdtyNotValidated.into());
-                }
-
-                Self::do_remove_right(idty_index, idty_value, right)
-            } else {
-                Err(Error::<T>::IdtyNotFound.into())
-            }
-        }
-        #[pallet::weight(0)]
-        pub fn set_right_subkey(
+        pub fn disable_identity(
             origin: OriginFor<T>,
             idty_index: T::IdtyIndex,
-            right: T::IdtyRight,
-            subkey_opt: Option<T::AccountId>,
         ) -> DispatchResultWithPostInfo {
-            let who = ensure_signed(origin)?;
-
-            if let Ok(mut idty_value) = <Identities<T>>::try_get(idty_index) {
-                if who == idty_value.owner_key {
-                    if idty_value.status != IdtyStatus::Validated {
-                        return Err(Error::<T>::IdtyNotValidated.into());
-                    }
-
-                    if !T::IsMember::is_member(&idty_index) {
-                        return Err(Error::<T>::IdtyNotMember.into());
-                    }
-
-                    if let Ok(index) = idty_value
-                        .rights
-                        .binary_search_by(|(right_, _)| right_.cmp(&right))
-                    {
-                        let name = idty_value.name.clone();
-                        let old_subkey_opt = idty_value.rights[index].1.clone();
-                        idty_value.rights[index].1 = subkey_opt.clone();
-                        let new_key = if let Some(ref subkey) = subkey_opt {
-                            Some(subkey.clone())
-                        } else if right.allow_owner_key() {
-                            Some(idty_value.owner_key.clone())
-                        } else {
-                            None
-                        };
+            // Verify phase
+            ensure_root(origin)?;
 
-                        <Identities<T>>::insert(idty_index, idty_value);
-                        Self::deposit_event(Event::<T>::IdtySetRightSubKey(
-                            name,
-                            right,
-                            old_subkey_opt.clone(),
-                            subkey_opt,
-                        ));
-                        T::OnRightKeyChange::on_right_key_change(
-                            idty_index,
-                            right,
-                            old_subkey_opt,
-                            new_key,
-                        );
-                        Ok(().into())
-                    } else {
-                        Err(Error::<T>::RightNotExist.into())
-                    }
-                } else {
-                    Err(Error::<T>::RequireToBeOwner.into())
-                }
-            } else {
-                Err(Error::<T>::IdtyNotFound.into())
+            if !Identities::<T>::contains_key(idty_index) {
+                return Err(Error::<T>::IdtyNotFound.into());
             }
-        }
 
-        #[pallet::weight(0)]
-        pub fn remove_all_rights(
-            origin: OriginFor<T>,
-            idty_index: T::IdtyIndex,
-        ) -> DispatchResultWithPostInfo {
-            ensure_root(origin)?;
-
-            if let Ok(idty_value) = <Identities<T>>::try_get(idty_index) {
-                for (right, _key_opt) in &idty_value.rights {
-                    Self::do_remove_right(idty_index, idty_value.clone(), *right)?;
+            // Apply phase
+            let block_number = frame_system::pallet::Pallet::<T>::block_number();
+            let removable_on = block_number + T::MaxDisabledPeriod::get();
+            Identities::<T>::mutate_exists(idty_index, |idty_value_opt| {
+                if let Some(idty_value) = idty_value_opt {
+                    idty_value.status = IdtyStatus::Disabled;
+                    idty_value.removable_on = removable_on;
                 }
-                Ok(().into())
-            } else {
-                Err(Error::<T>::IdtyNotFound.into())
-            }
+            });
+            <IdentitiesRemovableOn<T>>::append(removable_on, (idty_index, IdtyStatus::Disabled));
+            Ok(().into())
         }
 
         #[pallet::weight(0)]
@@ -572,8 +393,6 @@ pub mod pallet {
         CreatorNotExist,
         /// Creator not allowed to create identities
         CreatorNotAllowedToCreateIdty,
-        /// Creator not have right to create identities
-        CreatorNotHaveRightToCreateIdty,
         /// Identity already confirmed
         IdtyAlreadyConfirmed,
         /// Identity already validated
@@ -641,45 +460,6 @@ pub mod pallet {
 
             0
         }
-        pub(super) fn do_remove_right(
-            idty_index: T::IdtyIndex,
-            mut idty_value: IdtyValue<T::AccountId, T::BlockNumber, T::IdtyData, T::IdtyRight>,
-            right: T::IdtyRight,
-        ) -> DispatchResultWithPostInfo {
-            if let Ok(index) = idty_value
-                .rights
-                .binary_search_by(|(right_, _)| right_.cmp(&right))
-            {
-                let name = idty_value.name.clone();
-                let old_key_opt = if let Some(ref subkey) = idty_value.rights[index].1 {
-                    Some(subkey.clone())
-                } else if right.allow_owner_key() {
-                    Some(idty_value.owner_key.clone())
-                } else {
-                    None
-                };
-                idty_value.rights.remove(index);
-
-                if idty_value.rights.is_empty() {
-                    let block_number = frame_system::pallet::Pallet::<T>::block_number();
-                    let removable_on = block_number + T::MaxNoRightPeriod::get();
-                    idty_value.removable_on = removable_on;
-                    <IdentitiesRemovableOn<T>>::append(
-                        removable_on,
-                        (idty_index, IdtyStatus::Validated),
-                    );
-                }
-
-                <Identities<T>>::insert(idty_index, idty_value);
-                Self::deposit_event(Event::<T>::IdtyLostRight(name, right));
-                if old_key_opt.is_some() {
-                    T::OnRightKeyChange::on_right_key_change(idty_index, right, old_key_opt, None);
-                }
-                Ok(().into())
-            } else {
-                Err(Error::<T>::RightNotExist.into())
-            }
-        }
         fn get_next_idty_index() -> T::IdtyIndex {
             if let Ok(next_index) = <NextIdtyIndex<T>>::try_get() {
                 <NextIdtyIndex<T>>::put(next_index.saturating_add(T::IdtyIndex::one()));
diff --git a/pallets/identity/src/mock.rs b/pallets/identity/src/mock.rs
index 5985e5d53..57b7bbc2d 100644
--- a/pallets/identity/src/mock.rs
+++ b/pallets/identity/src/mock.rs
@@ -17,14 +17,10 @@
 use super::*;
 use crate::{self as pallet_identity};
 use frame_support::{
-    codec::{Decode, Encode},
     parameter_types,
     traits::{Everything, OnFinalize, OnInitialize},
-    RuntimeDebug,
 };
 use frame_system as system;
-use scale_info::TypeInfo;
-use serde::{Deserialize, Serialize};
 use sp_core::H256;
 use sp_runtime::{
     testing::Header,
@@ -36,38 +32,6 @@ type AccountId = u64;
 type Block = frame_system::mocking::MockBlock<Test>;
 type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
 
-#[derive(
-    Encode,
-    Decode,
-    Clone,
-    Copy,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    RuntimeDebug,
-    Deserialize,
-    Serialize,
-    TypeInfo,
-)]
-pub enum IdtyRight {
-    Right1,
-    Right2,
-}
-impl Default for IdtyRight {
-    fn default() -> Self {
-        IdtyRight::Right1
-    }
-}
-impl pallet_identity::traits::IdtyRight for IdtyRight {
-    fn allow_owner_key(self) -> bool {
-        self == Self::Right1
-    }
-    fn create_idty_right() -> Self {
-        Self::Right1
-    }
-}
-
 // Configure a mock runtime to test the pallet.
 frame_support::construct_runtime!(
     pub enum Test where
@@ -116,7 +80,7 @@ parameter_types! {
     pub const ConfirmPeriod: u64 = 2;
     pub const IdtyCreationPeriod: u64 = 3;
     pub const MaxInactivityPeriod: u64 = 5;
-    pub const MaxNoRightPeriod: u64 = 4;
+    pub const MaxDisabledPeriod: u64 = 4;
     pub const RenewablePeriod: u64 = 3;
     pub const ValidationPeriod: u64 = 2;
 }
@@ -138,8 +102,6 @@ impl IsMember<u64> for IsMemberTestImpl {
 impl pallet_identity::Config for Test {
     type ConfirmPeriod = ConfirmPeriod;
     type Event = Event;
-    type AddRightOrigin = system::EnsureRoot<AccountId>;
-    type DelRightOrigin = system::EnsureRoot<AccountId>;
     type EnsureIdtyCallAllowed = ();
     type IdtyCreationPeriod = IdtyCreationPeriod;
     type IdtyData = ();
@@ -147,11 +109,9 @@ impl pallet_identity::Config for Test {
     type IdtyNameValidator = IdtyNameValidatorTestImpl;
     type IdtyIndex = u64;
     type IdtyValidationOrigin = system::EnsureRoot<AccountId>;
-    type IdtyRight = IdtyRight;
     type IsMember = IsMemberTestImpl;
     type OnIdtyChange = ();
-    type OnRightKeyChange = ();
-    type MaxNoRightPeriod = MaxNoRightPeriod;
+    type MaxDisabledPeriod = MaxDisabledPeriod;
 }
 
 // Build genesis storage according to the mock runtime.
diff --git a/pallets/identity/src/tests.rs b/pallets/identity/src/tests.rs
index 264b324c2..2d59bcdd4 100644
--- a/pallets/identity/src/tests.rs
+++ b/pallets/identity/src/tests.rs
@@ -14,14 +14,13 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
 
-use crate::mock::IdtyRight as Right;
 use crate::mock::*;
 use crate::{Error, IdtyName, IdtyValue};
-use frame_support::assert_err;
+//use frame_support::assert_err;
 use frame_support::assert_ok;
 use frame_system::{EventRecord, Phase};
 
-type IdtyVal = IdtyValue<u64, u64, (), Right>;
+type IdtyVal = IdtyValue<u64, u64, ()>;
 
 fn alice() -> IdtyVal {
     IdtyVal {
@@ -30,18 +29,6 @@ fn alice() -> IdtyVal {
         name: IdtyName::from("Alice"),
         next_creatable_identity_on: 0,
         removable_on: 0,
-        rights: vec![(Right::Right1, None)],
-        status: crate::IdtyStatus::Validated,
-    }
-}
-fn bob() -> IdtyVal {
-    IdtyVal {
-        data: (),
-        owner_key: 2,
-        name: IdtyName::from("Bob"),
-        next_creatable_identity_on: 0,
-        removable_on: 0,
-        rights: vec![(Right::Right2, Some(20))],
         status: crate::IdtyStatus::Validated,
     }
 }
@@ -69,23 +56,6 @@ fn test_creator_not_exist() {
     });
 }
 
-#[test]
-fn test_creator_not_have_right_to_create_identity() {
-    new_test_ext(IdentityConfig {
-        identities: vec![bob()],
-    })
-    .execute_with(|| {
-        // We need to initialize at least one block before any call
-        run_to_block(1);
-
-        // Bob not have right to create identities
-        assert_eq!(
-            Identity::create_identity(Origin::signed(2), 1, IdtyName::from("Charlie"), 3),
-            Err(Error::<Test>::CreatorNotHaveRightToCreateIdty.into())
-        );
-    })
-}
-
 #[test]
 fn test_creator_not_owner() {
     new_test_ext(IdentityConfig {
@@ -187,63 +157,3 @@ fn test_idty_creation_period() {
         );
     });
 }
-
-#[test]
-fn test_two_identities() {
-    let identities = vec![alice(), bob()];
-
-    new_test_ext(IdentityConfig { identities }).execute_with(|| {
-        // Should have two identities
-        assert_eq!(Identity::identities_count(), 2);
-
-        // We need to initialize at least one block before any call
-        run_to_block(1);
-
-        // Add right Right1 for Alice
-        // Should fail because Alice already have this right
-        assert_err!(
-            Identity::add_right(Origin::root(), 1, Right::Right1),
-            Error::<Test>::RightAlreadyAdded
-        );
-        // Add right Right2 for alice
-        // Should succes and trigger the correct event
-        assert_ok!(Identity::add_right(Origin::root(), 1, Right::Right2));
-        let events = System::events();
-        assert_eq!(events.len(), 1);
-        assert_eq!(
-            events[0],
-            EventRecord {
-                phase: Phase::Initialization,
-                event: Event::Identity(crate::Event::IdtyAcquireRight(
-                    IdtyName::from("Alice"),
-                    Right::Right2
-                )),
-                topics: vec![],
-            }
-        );
-
-        run_to_block(3);
-
-        // Delete right Right2 for Bob
-        // Should succes and trigger the correct event
-        assert_ok!(Identity::del_right(Origin::root(), 2, Right::Right2));
-        let events = System::events();
-        assert_eq!(events.len(), 1);
-        assert_eq!(
-            events[0],
-            EventRecord {
-                phase: Phase::Initialization,
-                event: Event::Identity(crate::Event::IdtyLostRight(
-                    IdtyName::from("Bob"),
-                    Right::Right2
-                )),
-                topics: vec![],
-            }
-        );
-
-        // The Bob identity has no more rights, the inactivity period must start to run
-        let idty2 = Identity::identity(2).expect("idty not found");
-        assert!(idty2.rights.is_empty());
-        assert_eq!(idty2.removable_on, 7);
-    });
-}
diff --git a/pallets/identity/src/traits.rs b/pallets/identity/src/traits.rs
index 635944278..5ddbf29c8 100644
--- a/pallets/identity/src/traits.rs
+++ b/pallets/identity/src/traits.rs
@@ -16,8 +16,6 @@
 
 use crate::*;
 use frame_support::pallet_prelude::*;
-use sp_runtime::traits::MaybeSerializeDeserialize;
-use sp_std::fmt::Debug;
 
 pub trait EnsureIdtyCallAllowed<T: Config> {
     fn can_create_identity(creator: T::IdtyIndex) -> bool;
@@ -62,19 +60,6 @@ pub trait IdtyNameValidator {
     fn validate(idty_name: &IdtyName) -> bool;
 }
 
-pub trait IdtyRight:
-    frame_support::Parameter
-    + frame_support::pallet_prelude::Member
-    + MaybeSerializeDeserialize
-    + Debug
-    + Default
-    + Copy
-    + Ord
-{
-    fn allow_owner_key(self) -> bool;
-    fn create_idty_right() -> Self;
-}
-
 pub trait OnIdtyChange<T: Config> {
     fn on_idty_change(idty_index: T::IdtyIndex, idty_event: IdtyEvent<T>) -> Weight;
 }
@@ -83,22 +68,3 @@ impl<T: Config> OnIdtyChange<T> for () {
         0
     }
 }
-
-pub trait OnRightKeyChange<T: Config> {
-    fn on_right_key_change(
-        idty_index: T::IdtyIndex,
-        right: T::IdtyRight,
-        old_key: Option<T::AccountId>,
-        new_key: Option<T::AccountId>,
-    );
-}
-
-impl<T: Config> OnRightKeyChange<T> for () {
-    fn on_right_key_change(
-        _idty_index: T::IdtyIndex,
-        _right: T::IdtyRight,
-        _old_key: Option<T::AccountId>,
-        _new_key: Option<T::AccountId>,
-    ) {
-    }
-}
diff --git a/pallets/identity/src/types.rs b/pallets/identity/src/types.rs
index f1f2e8fcd..9418974fe 100644
--- a/pallets/identity/src/types.rs
+++ b/pallets/identity/src/types.rs
@@ -69,6 +69,7 @@ impl<'de> serde::Deserialize<'de> for IdtyName {
 pub enum IdtyStatus {
     Created,
     ConfirmedByOwner,
+    Disabled,
     Validated,
 }
 impl Default for IdtyStatus {
@@ -83,39 +84,11 @@ pub struct IdtyValue<
     AccountId: Decode + Encode + TypeInfo,
     BlockNumber: Decode + Encode + TypeInfo,
     IdtyData: Decode + Encode + TypeInfo,
-    IdtyRight: Decode + Encode + TypeInfo,
 > {
     pub data: IdtyData,
     pub owner_key: AccountId,
     pub name: IdtyName,
     pub next_creatable_identity_on: BlockNumber,
     pub removable_on: BlockNumber,
-    pub rights: Vec<(IdtyRight, Option<AccountId>)>,
     pub status: IdtyStatus,
 }
-
-impl<AccountId, BlockNumber, IdtyData, IdtyRight>
-    IdtyValue<AccountId, BlockNumber, IdtyData, IdtyRight>
-where
-    AccountId: Clone + Decode + Encode + TypeInfo,
-    BlockNumber: Decode + Encode + TypeInfo,
-    IdtyData: Decode + Encode + TypeInfo,
-    IdtyRight: crate::traits::IdtyRight + Decode + Encode + TypeInfo,
-{
-    pub fn get_right_key(&self, right: IdtyRight) -> Option<AccountId> {
-        if let Ok(index) = self
-            .rights
-            .binary_search_by(|(right_, _)| right_.cmp(&right))
-        {
-            if self.rights[index].1.is_some() {
-                self.rights[index].1.clone()
-            } else if right.allow_owner_key() {
-                Some(self.owner_key.clone())
-            } else {
-                None
-            }
-        } else {
-            None
-        }
-    }
-}
diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs
index cf4cb466d..7a7f58a5f 100644
--- a/pallets/membership/src/lib.rs
+++ b/pallets/membership/src/lib.rs
@@ -68,8 +68,8 @@ pub mod pallet {
         type ExternalizeMembershipStorage: Get<bool>;
         /// Something that identifies an identity
         type IdtyId: Copy + MaybeSerializeDeserialize + Parameter + Ord;
-        /// On event handler
-        type OnEvent: OnEvent<Self::IdtyId>;
+        /// Optional metadata
+        type MetaData: Parameter;
         /// Provide your implementation of membership storage here, if you want the pallet to
         /// handle the storage for you, specify `()` and set `ExternalizeMembershipStorage` to
         /// `false`.
@@ -77,6 +77,8 @@ pub mod pallet {
         #[pallet::constant]
         /// Maximum life span of a non-renewable membership (in number of blocks)
         type MembershipPeriod: Get<Self::BlockNumber>;
+        /// On event handler
+        type OnEvent: OnEvent<Self::IdtyId, Self::MetaData>;
         #[pallet::constant]
         /// Maximum period (in number of blocks), where an identity can remain pending subscription.
         type PendingMembershipPeriod: Get<Self::BlockNumber>;
@@ -128,7 +130,7 @@ pub mod pallet {
     #[pallet::storage]
     #[pallet::getter(fn memberships_expire_on)]
     pub type MembershipsExpireOn<T: Config<I>, I: 'static = ()> =
-        StorageMap<_, Blake2_128Concat, T::BlockNumber, Vec<T::IdtyId>, OptionQuery>;
+        StorageMap<_, Blake2_128Concat, T::BlockNumber, Vec<T::IdtyId>, ValueQuery>;
 
     #[pallet::storage]
     #[pallet::getter(fn pending_membership)]
@@ -138,7 +140,7 @@ pub mod pallet {
     #[pallet::storage]
     #[pallet::getter(fn pending_memberships_expire_on)]
     pub type PendingMembershipsExpireOn<T: Config<I>, I: 'static = ()> =
-        StorageMap<_, Blake2_128Concat, T::BlockNumber, Vec<T::IdtyId>, OptionQuery>;
+        StorageMap<_, Blake2_128Concat, T::BlockNumber, Vec<T::IdtyId>, ValueQuery>;
 
     #[pallet::storage]
     #[pallet::getter(fn revoked_membership)]
@@ -224,6 +226,7 @@ pub mod pallet {
         pub fn request_membership(
             origin: OriginFor<T>,
             idty_id: T::IdtyId,
+            metadata: T::MetaData,
         ) -> DispatchResultWithPostInfo {
             let allowed =
                 match T::IsOriginAllowedToUseIdty::is_origin_allowed_to_use_idty(&origin, &idty_id)
@@ -257,7 +260,9 @@ pub mod pallet {
             PendingMembership::<T, I>::insert(idty_id, expire_on);
             PendingMembershipsExpireOn::<T, I>::append(expire_on, idty_id);
             Self::deposit_event(Event::MembershipRequested(idty_id));
-            T::OnEvent::on_event(sp_membership::Event::MembershipRequested(idty_id));
+            T::OnEvent::on_event(&sp_membership::Event::MembershipRequested(
+                idty_id, metadata,
+            ));
 
             Ok(().into())
         }
@@ -357,13 +362,13 @@ pub mod pallet {
             PendingMembership::<T, I>::remove(&idty_id);
             total_weight += Self::do_renew_membership_inner(idty_id);
             Self::deposit_event(Event::MembershipAcquired(idty_id));
-            T::OnEvent::on_event(sp_membership::Event::MembershipAcquired(idty_id));
+            T::OnEvent::on_event(&sp_membership::Event::MembershipAcquired(idty_id));
             total_weight
         }
         pub(super) fn do_renew_membership(idty_id: T::IdtyId) -> Weight {
             let total_weight = Self::do_renew_membership_inner(idty_id);
             Self::deposit_event(Event::MembershipRenewed(idty_id));
-            T::OnEvent::on_event(sp_membership::Event::MembershipRenewed(idty_id));
+            T::OnEvent::on_event(&sp_membership::Event::MembershipRenewed(idty_id));
             total_weight
         }
         fn do_renew_membership_inner(idty_id: T::IdtyId) -> Weight {
@@ -391,26 +396,20 @@ pub mod pallet {
                 RevokedMembershipsPrunedOn::<T, I>::append(pruned_on, idty_id);
             }
             Self::deposit_event(Event::MembershipRevoked(idty_id));
-            T::OnEvent::on_event(sp_membership::Event::MembershipRevoked(idty_id));
+            T::OnEvent::on_event(&sp_membership::Event::MembershipRevoked(idty_id));
 
             0
         }
         fn expire_memberships(block_number: T::BlockNumber) -> Weight {
             let mut total_weight: Weight = 0;
 
-            use frame_support::storage::generator::StorageMap as _;
-            if let Some(identities_ids) = MembershipsExpireOn::<T, I>::from_query_to_optional_value(
-                MembershipsExpireOn::<T, I>::take(block_number),
-            ) {
-                for idty_id in identities_ids {
-                    if let Some(member_data) = Self::get_membership(&idty_id) {
-                        if member_data.expire_on == block_number {
-                            Self::remove_membership(&idty_id);
-                            Self::deposit_event(Event::MembershipExpired(idty_id));
-                            total_weight += T::OnEvent::on_event(
-                                sp_membership::Event::MembershipExpired(idty_id),
-                            );
-                        }
+            for idty_id in MembershipsExpireOn::<T, I>::take(block_number) {
+                if let Some(member_data) = Self::get_membership(&idty_id) {
+                    if member_data.expire_on == block_number {
+                        Self::remove_membership(&idty_id);
+                        Self::deposit_event(Event::MembershipExpired(idty_id));
+                        total_weight +=
+                            T::OnEvent::on_event(&sp_membership::Event::MembershipExpired(idty_id));
                     }
                 }
             }
@@ -430,7 +429,7 @@ pub mod pallet {
                     PendingMembership::<T, I>::remove(&idty_id);
                     Self::deposit_event(Event::PendingMembershipExpired(idty_id));
                     total_weight += T::OnEvent::on_event(
-                        sp_membership::Event::PendingMembershipExpired(idty_id),
+                        &sp_membership::Event::PendingMembershipExpired(idty_id),
                     );
                 }
             }
@@ -498,9 +497,6 @@ impl<T: Config<I>, I: 'static> sp_runtime::traits::IsMember<T::IdtyId> for Palle
 }
 
 impl<T: Config<I>, I: 'static> MembershipAction<T::IdtyId, T::Origin> for Pallet<T, I> {
-    fn request_membership_(origin: T::Origin, idty_id: T::IdtyId) -> DispatchResultWithPostInfo {
-        Pallet::<T, I>::request_membership(origin, idty_id)
-    }
     fn claim_membership_(origin: T::Origin, idty_id: T::IdtyId) -> DispatchResultWithPostInfo {
         Pallet::<T, I>::claim_membership(origin, idty_id)
     }
@@ -510,14 +506,4 @@ impl<T: Config<I>, I: 'static> MembershipAction<T::IdtyId, T::Origin> for Pallet
     fn revoke_membership_(origin: T::Origin, idty_id: T::IdtyId) -> DispatchResultWithPostInfo {
         Pallet::<T, I>::revoke_membership(origin, idty_id)
     }
-
-    fn force_claim_membership(idty_id: T::IdtyId) -> Weight {
-        Self::do_claim_membership(idty_id)
-    }
-    fn force_renew_membership(idty_id: T::IdtyId) -> Weight {
-        Self::do_renew_membership(idty_id)
-    }
-    fn force_revoke_membership(idty_id: T::IdtyId) -> Weight {
-        Self::do_revoke_membership(idty_id)
-    }
 }
diff --git a/pallets/membership/src/mock.rs b/pallets/membership/src/mock.rs
index 14eb7438f..27abbf1c3 100644
--- a/pallets/membership/src/mock.rs
+++ b/pallets/membership/src/mock.rs
@@ -108,9 +108,10 @@ impl pallet_membership::Config for Test {
     type Event = Event;
     type ExternalizeMembershipStorage = ExternalizeMembershipStorage;
     type IdtyId = IdtyId;
-    type OnEvent = ();
     type MembershipExternalStorage = crate::NoExternalStorage;
     type MembershipPeriod = MembershipPeriod;
+    type MetaData = ();
+    type OnEvent = ();
     type PendingMembershipPeriod = PendingMembershipPeriod;
     type RenewablePeriod = RenewablePeriod;
     type RevocationPeriod = RevocationPeriod;
diff --git a/pallets/membership/src/tests.rs b/pallets/membership/src/tests.rs
index a40782f21..6482949bd 100644
--- a/pallets/membership/src/tests.rs
+++ b/pallets/membership/src/tests.rs
@@ -128,13 +128,17 @@ fn test_membership_revocation() {
         // Membership 0 can't request membership before the end of RevokePeriod (1 + 4 = 5)
         run_to_block(2);
         assert_eq!(
-            DefaultMembership::request_membership(Origin::signed(0), 0),
+            DefaultMembership::request_membership(Origin::signed(0), 0, ()),
             Err(Error::<Test, _>::MembershipRevokedRecently.into())
         );
 
         // Membership 0 can request membership after the end of RevokePeriod (1 + 4 = 5)
         run_to_block(5);
-        assert_ok!(DefaultMembership::request_membership(Origin::signed(0), 0),);
+        assert_ok!(DefaultMembership::request_membership(
+            Origin::signed(0),
+            0,
+            ()
+        ),);
         assert_eq!(
             System::events()[0].event,
             RuntimeEvent::DefaultMembership(Event::MembershipRequested(0))
@@ -147,7 +151,11 @@ fn test_pending_membership_expiration() {
     new_test_ext(Default::default()).execute_with(|| {
         // Idty 0 request membership
         run_to_block(1);
-        assert_ok!(DefaultMembership::request_membership(Origin::signed(0), 0),);
+        assert_ok!(DefaultMembership::request_membership(
+            Origin::signed(0),
+            0,
+            ()
+        ),);
         assert_eq!(
             System::events()[0].event,
             RuntimeEvent::DefaultMembership(Event::MembershipRequested(0))
@@ -172,7 +180,11 @@ fn test_membership_workflow() {
     new_test_ext(Default::default()).execute_with(|| {
         // Idty 0 request membership
         run_to_block(1);
-        assert_ok!(DefaultMembership::request_membership(Origin::signed(0), 0),);
+        assert_ok!(DefaultMembership::request_membership(
+            Origin::signed(0),
+            0,
+            ()
+        ),);
         assert_eq!(
             System::events()[0].event,
             RuntimeEvent::DefaultMembership(Event::MembershipRequested(0))
diff --git a/primitives/membership/src/lib.rs b/primitives/membership/src/lib.rs
index bae4cf2d8..1a0914f27 100644
--- a/primitives/membership/src/lib.rs
+++ b/primitives/membership/src/lib.rs
@@ -27,7 +27,7 @@ use scale_info::TypeInfo;
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
 
-pub enum Event<IdtyId> {
+pub enum Event<IdtyId, MetaData = ()> {
     /// A membership has acquired
     MembershipAcquired(IdtyId),
     /// A membership has expired
@@ -35,7 +35,7 @@ pub enum Event<IdtyId> {
     /// A membership has renewed
     MembershipRenewed(IdtyId),
     /// An identity requested membership
-    MembershipRequested(IdtyId),
+    MembershipRequested(IdtyId, MetaData),
     /// A membership has revoked
     MembershipRevoked(IdtyId),
     /// A pending membership request has expired
diff --git a/primitives/membership/src/traits.rs b/primitives/membership/src/traits.rs
index e77c8d143..c671ba6bf 100644
--- a/primitives/membership/src/traits.rs
+++ b/primitives/membership/src/traits.rs
@@ -61,30 +61,23 @@ pub trait IsInPendingMemberships<IdtyId> {
     fn is_in_pending_memberships(idty_id: IdtyId) -> bool;
 }
 
-pub trait OnEvent<IdtyId> {
-    fn on_event(event: crate::Event<IdtyId>) -> Weight;
+pub trait OnEvent<IdtyId, MetaData> {
+    fn on_event(event: &crate::Event<IdtyId, MetaData>) -> Weight;
 }
 
-impl<IdtyId> OnEvent<IdtyId> for () {
-    fn on_event(_: crate::Event<IdtyId>) -> Weight {
+impl<IdtyId, MetaData> OnEvent<IdtyId, MetaData> for () {
+    fn on_event(_: &crate::Event<IdtyId, MetaData>) -> Weight {
         0
     }
 }
 
 pub trait MembershipAction<IdtyId, Origin> {
-    fn request_membership_(origin: Origin, idty_id: IdtyId) -> DispatchResultWithPostInfo;
     fn claim_membership_(origin: Origin, idty_id: IdtyId) -> DispatchResultWithPostInfo;
     fn renew_membership_(origin: Origin, idty_id: IdtyId) -> DispatchResultWithPostInfo;
     fn revoke_membership_(origin: Origin, idty_id: IdtyId) -> DispatchResultWithPostInfo;
-    fn force_claim_membership(idty_id: IdtyId) -> Weight;
-    fn force_renew_membership(idty_id: IdtyId) -> Weight;
-    fn force_revoke_membership(idty_id: IdtyId) -> Weight;
 }
 
 impl<IdtyId, Origin> MembershipAction<IdtyId, Origin> for () {
-    fn request_membership_(_: Origin, _: IdtyId) -> DispatchResultWithPostInfo {
-        Ok(().into())
-    }
     fn claim_membership_(_: Origin, _: IdtyId) -> DispatchResultWithPostInfo {
         Ok(().into())
     }
@@ -94,15 +87,6 @@ impl<IdtyId, Origin> MembershipAction<IdtyId, Origin> for () {
     fn revoke_membership_(_: Origin, _: IdtyId) -> DispatchResultWithPostInfo {
         Ok(().into())
     }
-    fn force_claim_membership(_: IdtyId) -> Weight {
-        0
-    }
-    fn force_renew_membership(_: IdtyId) -> Weight {
-        0
-    }
-    fn force_revoke_membership(_: IdtyId) -> Weight {
-        0
-    }
 }
 
 pub trait MembershipExternalStorage<BlockNumber: Decode + Encode + TypeInfo, IdtyId>:
diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml
index 07f972d8f..baaa300ee 100644
--- a/runtime/common/Cargo.toml
+++ b/runtime/common/Cargo.toml
@@ -29,6 +29,7 @@ std = [
     'serde',
     'sp-arithmetic/std',
     'sp-core/std',
+    'sp-membership/std',
     'sp-runtime/std',
     'sp-std/std'
 ]
@@ -39,6 +40,7 @@ pallet-duniter-wot = { path = '../../pallets/duniter-wot', default-features = fa
 pallet-identity = { path = '../../pallets/identity', default-features = false }
 pallet-membership = { path = '../../pallets/membership', default-features = false }
 pallet-ud-accounts-storage = { path = '../../pallets/ud-accounts-storage', default-features = false }
+sp-membership = { path = '../../primitives/membership', default-features = false }
 
 # Crates.io
 smallvec = "1.6.1"
diff --git a/runtime/common/src/handlers.rs b/runtime/common/src/handlers.rs
index 63b54fc81..ebfb913df 100644
--- a/runtime/common/src/handlers.rs
+++ b/runtime/common/src/handlers.rs
@@ -14,29 +14,40 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
 
-use pallet_duniter_wot::IdtyRight;
+use frame_support::pallet_prelude::Weight;
+use frame_support::Parameter;
+
+pub struct OnMembershipEventHandler<Inner, Runtime>(core::marker::PhantomData<(Inner, Runtime)>);
 
-pub struct OnRightKeyChangeHandler<Runtime>(core::marker::PhantomData<Runtime>);
 impl<
-        IdtyIndex,
-        Runtime: pallet_identity::Config<IdtyIndex = IdtyIndex, IdtyRight = IdtyRight>
-            + pallet_ud_accounts_storage::Config,
-    > pallet_identity::traits::OnRightKeyChange<Runtime> for OnRightKeyChangeHandler<Runtime>
+        IdtyIndex: Parameter,
+        Inner: sp_membership::traits::OnEvent<IdtyIndex, ()>,
+        Runtime: pallet_identity::Config<IdtyIndex = IdtyIndex> + pallet_ud_accounts_storage::Config,
+    > sp_membership::traits::OnEvent<IdtyIndex, ()> for OnMembershipEventHandler<Inner, Runtime>
 {
-    fn on_right_key_change(
-        _idty_index: IdtyIndex,
-        right: Runtime::IdtyRight,
-        old_key_opt: Option<Runtime::AccountId>,
-        new_key_opt: Option<Runtime::AccountId>,
-    ) {
-        match right {
-            IdtyRight::Ud => <pallet_ud_accounts_storage::Pallet<Runtime>>::replace_account(
-                old_key_opt,
-                new_key_opt,
-            ),
-            IdtyRight::CreateIdty => 0,
-            IdtyRight::LightCert => 0,
-            IdtyRight::StrongCert => 0,
-        };
+    fn on_event(membership_event: &sp_membership::Event<IdtyIndex>) -> Weight {
+        (match membership_event {
+            sp_membership::Event::<IdtyIndex>::MembershipAcquired(idty_index) => {
+                if let Some(idty_value) = pallet_identity::Pallet::<Runtime>::identity(idty_index) {
+                    <pallet_ud_accounts_storage::Pallet<Runtime>>::replace_account(
+                        None,
+                        Some(idty_value.owner_key),
+                    )
+                } else {
+                    0
+                }
+            }
+            sp_membership::Event::<IdtyIndex>::MembershipRevoked(idty_index) => {
+                if let Some(idty_value) = pallet_identity::Pallet::<Runtime>::identity(idty_index) {
+                    <pallet_ud_accounts_storage::Pallet<Runtime>>::replace_account(
+                        Some(idty_value.owner_key),
+                        None,
+                    )
+                } else {
+                    0
+                }
+            }
+            _ => 0,
+        }) + Inner::on_event(membership_event)
     }
 }
diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs
index ff6973eb8..cd1ead884 100644
--- a/runtime/common/src/pallets_config.rs
+++ b/runtime/common/src/pallets_config.rs
@@ -184,30 +184,27 @@ macro_rules! pallets_config {
 
 		// WEB OF TRUST //
 
-		impl pallet_duniter_wot::Config for Runtime {
+		use frame_support::instances::Instance1;
+		impl pallet_duniter_wot::Config<Instance1> for Runtime {
 			type FirstIssuableOn = WotFirstCertIssuableOn;
+			type ManageIdentitiesChanges = frame_support::traits::ConstBool<true>;
 			type MinCertForUdRight = WotMinCertForUdRight;
-			type MinCertForCertRight = WotMinCertForCertRight;
 			type MinCertForCreateIdtyRight = WotMinCertForCreateIdtyRight;
 		}
 
 		impl pallet_identity::Config for Runtime {
             type ConfirmPeriod = ConfirmPeriod;
             type Event = Event;
-            type AddRightOrigin = EnsureRoot<Self::AccountId>;
-            type DelRightOrigin = EnsureRoot<Self::AccountId>;
             type EnsureIdtyCallAllowed = DuniterWot;
 			type IdtyCreationPeriod = IdtyCreationPeriod;
 			type IdtyDataProvider = ();
             type IdtyData = ();
-            type IdtyNameValidator = IdtyNameValidatorImpl;
             type IdtyIndex = IdtyIndex;
+            type IdtyNameValidator = IdtyNameValidatorImpl;
             type IdtyValidationOrigin = EnsureRoot<Self::AccountId>;
-            type IdtyRight = IdtyRight;
 			type IsMember = Membership;
             type OnIdtyChange = DuniterWot;
-            type OnRightKeyChange = OnRightKeyChangeHandler<Runtime>;
-            type MaxNoRightPeriod = MaxNoRightPeriod;
+            type MaxDisabledPeriod = MaxDisabledPeriod;
         }
 
 		impl pallet_membership::Config<frame_support::instances::Instance1> for Runtime {
@@ -218,21 +215,23 @@ macro_rules! pallets_config {
 			type Event = Event;
 			type ExternalizeMembershipStorage = frame_support::traits::ConstBool<false>;
 			type IdtyId = IdtyIndex;
-			type OnEvent = DuniterWot;
 			type MembershipExternalStorage = sp_membership::traits::NoExternalStorage;
 			type MembershipPeriod = MembershipPeriod;
+			type MetaData = ();
+			type OnEvent = OnMembershipEventHandler<DuniterWot, Runtime>;
 			type PendingMembershipPeriod = PendingMembershipPeriod;
 			type RenewablePeriod = RenewablePeriod;
 			type RevocationPeriod = frame_support::traits::ConstU32<0>;
 		}
 
-        impl pallet_certification::Config<frame_support::instances::Instance1> for Runtime {
-            type AddCertOrigin = pallet_duniter_wot::AddStrongCertOrigin<Runtime>;
+        impl pallet_certification::Config<Instance1> for Runtime {
+            type AddCertOrigin = pallet_duniter_wot::AddCertOrigin<Runtime, Instance1>;
             type CertPeriod = CertPeriod;
-            type DelCertOrigin = pallet_duniter_wot::DelStrongCertOrigin<Runtime>;
+            type DelCertOrigin = pallet_duniter_wot::DelCertOrigin<Runtime, Instance1>;
             type Event = Event;
             type IdtyIndex = IdtyIndex;
             type MaxByIssuer = MaxByIssuer;
+			type MinReceivedCertToBeAbleToIssueCert = MinReceivedCertToBeAbleToIssueCert;
             type OnNewcert = DuniterWot;
             type OnRemovedCert = DuniterWot;
             type CertRenewablePeriod = StrongCertRenewablePeriod;
diff --git a/runtime/g1/src/lib.rs b/runtime/g1/src/lib.rs
index b5e924e44..7eb458aae 100644
--- a/runtime/g1/src/lib.rs
+++ b/runtime/g1/src/lib.rs
@@ -26,11 +26,11 @@ pub mod parameters;
 
 pub use self::parameters::*;
 pub use common_runtime::{
-    constants::*, entities::ValidatorFullIdentification, AccountId, Address, Balance, BlockNumber,
-    FullIdentificationOfImpl, Hash, Header, IdtyIndex, IdtyNameValidatorImpl, Index, Signature,
+    constants::*, entities::ValidatorFullIdentification, handlers::OnMembershipEventHandler,
+    AccountId, Address, Balance, BlockNumber, FullIdentificationOfImpl, Hash, Header, IdtyIndex,
+    IdtyNameValidatorImpl, Index, SessionManagerImpl, Signature,
 };
 pub use pallet_balances::Call as BalancesCall;
-pub use pallet_duniter_wot::IdtyRight;
 pub use pallet_identity::{IdtyStatus, IdtyValue};
 pub use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
 use pallet_session::historical as session_historical;
@@ -41,7 +41,6 @@ pub use pallet_universal_dividend;
 pub use sp_runtime::BuildStorage;
 pub use sp_runtime::{KeyTypeId, Perbill, Permill};
 
-use common_runtime::{handlers::OnRightKeyChangeHandler, SessionManagerImpl};
 use frame_system::EnsureRoot;
 use pallet_grandpa::fg_primitives;
 use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
@@ -192,7 +191,7 @@ construct_runtime!(
         UniversalDividend: pallet_universal_dividend::{Pallet, Call, Config<T>, Storage, Event<T>} = 41,
 
         // Web Of Trust
-        DuniterWot: pallet_duniter_wot::{Pallet} = 50,
+        DuniterWot: pallet_duniter_wot::<Instance1>::{Pallet} = 50,
         Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>} = 51,
         Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 52,
         StrongCert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 53,
diff --git a/runtime/g1/src/parameters.rs b/runtime/g1/src/parameters.rs
index 170b7e5b4..7dc6b2b5b 100644
--- a/runtime/g1/src/parameters.rs
+++ b/runtime/g1/src/parameters.rs
@@ -95,7 +95,7 @@ parameter_types! {
 parameter_types! {
     pub WotFirstCertIssuableOn: BlockNumber = 30* DAYS;
     pub WotMinCertForUdRight: u8 = 5;
-    pub WotMinCertForCertRight: u8 = 5;
+    pub MinReceivedCertToBeAbleToIssueCert: u8 = 5;
     pub WotMinCertForCreateIdtyRight: u8 = 5;
 }
 
@@ -104,7 +104,7 @@ pub const IDTY_CREATE_PERIOD: BlockNumber = 100;
 parameter_types! {
     pub const ConfirmPeriod: BlockNumber = 14 * DAYS;
     pub const IdtyCreationPeriod: BlockNumber = MONTHS;
-    pub const MaxNoRightPeriod: BlockNumber = YEARS;
+    pub const MaxDisabledPeriod: BlockNumber = YEARS;
     pub const ValidationPeriod: BlockNumber = YEARS;
 }
 
diff --git a/runtime/gdev/src/lib.rs b/runtime/gdev/src/lib.rs
index 96973c22e..bfe577f5a 100644
--- a/runtime/gdev/src/lib.rs
+++ b/runtime/gdev/src/lib.rs
@@ -26,19 +26,17 @@ pub mod parameters;
 
 pub use self::parameters::*;
 pub use common_runtime::{
-    constants::*, AccountId, Address, Balance, BlockNumber, Hash, Header, IdtyIndex,
-    IdtyNameValidatorImpl, Index, Signature,
+    constants::*, handlers::OnMembershipEventHandler, AccountId, Address, Balance, BlockNumber,
+    Hash, Header, IdtyIndex, IdtyNameValidatorImpl, Index, Signature,
 };
 pub use pallet_balances::Call as BalancesCall;
 pub use pallet_duniter_test_parameters::Parameters as GenesisParameters;
-pub use pallet_duniter_wot::IdtyRight;
 pub use pallet_identity::{IdtyStatus, IdtyValue};
 pub use pallet_universal_dividend;
 #[cfg(any(feature = "std", test))]
 pub use sp_runtime::BuildStorage;
 pub use sp_runtime::{Perbill, Permill};
 
-use common_runtime::handlers::OnRightKeyChangeHandler;
 use frame_system::EnsureRoot;
 use pallet_grandpa::fg_primitives;
 use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
@@ -150,8 +148,9 @@ common_runtime::pallets_config! {
     pub type ValidityPeriod = pallet_duniter_test_parameters::CertValidityPeriod<Runtime>;
     pub type ConfirmPeriod = pallet_duniter_test_parameters::IdtyConfirmPeriod<Runtime>;
     pub type IdtyCreationPeriod = pallet_duniter_test_parameters::IdtyCreationPeriod<Runtime>;
-    pub type MaxNoRightPeriod = pallet_duniter_test_parameters::IdtyMaxNoRightPeriod<Runtime>;
+    pub type MaxDisabledPeriod = pallet_duniter_test_parameters::IdtyMaxDisabledPeriod<Runtime>;
     pub type MembershipPeriod = pallet_duniter_test_parameters::MembershipPeriod<Runtime>;
+    pub type MinReceivedCertToBeAbleToIssueCert = pallet_duniter_test_parameters::WotMinCertForCertRight<Runtime>;
     pub type RenewablePeriod = pallet_duniter_test_parameters::MembershipRenewablePeriod<Runtime>;
     pub type PendingMembershipPeriod = pallet_duniter_test_parameters::PendingMembershipPeriod<Runtime>;
     pub type UdCreationPeriod = pallet_duniter_test_parameters::UdCreationPeriod<Runtime>;
@@ -160,11 +159,10 @@ common_runtime::pallets_config! {
     pub type UdReevalPeriodInBlocks = pallet_duniter_test_parameters::UdReevalPeriodInBlocks<Runtime>;
     pub type WotFirstCertIssuableOn = pallet_duniter_test_parameters::WotFirstCertIssuableOn<Runtime>;
     pub type WotMinCertForUdRight = pallet_duniter_test_parameters::WotMinCertForUdRight<Runtime>;
-    pub type WotMinCertForCertRight = pallet_duniter_test_parameters::WotMinCertForCertRight<Runtime>;
     pub type WotMinCertForCreateIdtyRight = pallet_duniter_test_parameters::WotMinCertForCreateIdtyRight<Runtime>;
 
     impl pallet_duniter_test_parameters::Config for Runtime {
-        type CertCount = u8;
+        type CertCount = u32;
         type PeriodCount = Balance;
     }
     impl pallet_sudo::Config for Runtime {
@@ -204,7 +202,7 @@ construct_runtime!(
         UniversalDividend: pallet_universal_dividend::{Pallet, Call, Config<T>, Storage, Event<T>} = 41,
 
         // Web Of Trust
-        DuniterWot: pallet_duniter_wot::{Pallet} = 50,
+        DuniterWot: pallet_duniter_wot::<Instance1>::{Pallet} = 50,
         Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>} = 51,
         Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 52,
         StrongCert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 53,
diff --git a/runtime/gtest/src/lib.rs b/runtime/gtest/src/lib.rs
index 354a96f62..80f7f0a4b 100644
--- a/runtime/gtest/src/lib.rs
+++ b/runtime/gtest/src/lib.rs
@@ -26,11 +26,11 @@ pub mod parameters;
 
 pub use self::parameters::*;
 pub use common_runtime::{
-    constants::*, entities::ValidatorFullIdentification, AccountId, Address, Balance, BlockNumber,
-    FullIdentificationOfImpl, Hash, Header, IdtyIndex, IdtyNameValidatorImpl, Index, Signature,
+    constants::*, entities::ValidatorFullIdentification, handlers::OnMembershipEventHandler,
+    AccountId, Address, Balance, BlockNumber, FullIdentificationOfImpl, Hash, Header, IdtyIndex,
+    IdtyNameValidatorImpl, Index, SessionManagerImpl, Signature,
 };
 pub use pallet_balances::Call as BalancesCall;
-pub use pallet_duniter_wot::IdtyRight;
 pub use pallet_identity::{IdtyStatus, IdtyValue};
 pub use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
 use pallet_session::historical as session_historical;
@@ -41,7 +41,6 @@ pub use pallet_universal_dividend;
 pub use sp_runtime::BuildStorage;
 pub use sp_runtime::{KeyTypeId, Perbill, Permill};
 
-use common_runtime::{handlers::OnRightKeyChangeHandler, SessionManagerImpl};
 use frame_system::EnsureRoot;
 use pallet_grandpa::fg_primitives;
 use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
@@ -192,7 +191,7 @@ construct_runtime!(
         UniversalDividend: pallet_universal_dividend::{Pallet, Call, Config<T>, Storage, Event<T>} = 41,
 
         // Web Of Trust
-        DuniterWot: pallet_duniter_wot::{Pallet} = 50,
+        DuniterWot: pallet_duniter_wot::<Instance1>::{Pallet} = 50,
         Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>} = 51,
         Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 52,
         StrongCert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 53,
diff --git a/runtime/gtest/src/parameters.rs b/runtime/gtest/src/parameters.rs
index 8dd514901..eae9849b8 100644
--- a/runtime/gtest/src/parameters.rs
+++ b/runtime/gtest/src/parameters.rs
@@ -94,7 +94,7 @@ parameter_types! {
 parameter_types! {
     pub WotFirstCertIssuableOn: BlockNumber = DAYS;
     pub WotMinCertForUdRight: u8 = 5;
-    pub WotMinCertForCertRight: u8 = 5;
+    pub MinReceivedCertToBeAbleToIssueCert: u8 = 5;
     pub WotMinCertForCreateIdtyRight: u8 = 5;
 }
 
@@ -103,7 +103,7 @@ pub const IDTY_CREATE_PERIOD: BlockNumber = 100;
 frame_support::parameter_types! {
     pub const ConfirmPeriod: BlockNumber = 8 * HOURS;
     pub const IdtyCreationPeriod: BlockNumber = DAYS;
-    pub const MaxNoRightPeriod: BlockNumber = 73 * DAYS;
+    pub const MaxDisabledPeriod: BlockNumber = 73 * DAYS;
 }
 
 // Membership
-- 
GitLab