diff --git a/Cargo.lock b/Cargo.lock
index ca9a148779ecdb2e22f08c7e9cbd2e53c9e9a6bb..45df9912b8cb879162b45ad6aaf020a4265e592d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6532,6 +6532,7 @@ dependencies = [
 name = "pallet-membership"
 version = "1.0.0"
 dependencies = [
+ "duniter-primitives",
  "frame-benchmarking",
  "frame-support",
  "frame-system",
@@ -6716,6 +6717,7 @@ dependencies = [
 name = "pallet-smith-members"
 version = "1.0.0"
 dependencies = [
+ "duniter-primitives",
  "frame-benchmarking",
  "frame-support",
  "frame-system",
@@ -6834,6 +6836,7 @@ dependencies = [
 name = "pallet-universal-dividend"
 version = "1.0.0"
 dependencies = [
+ "duniter-primitives",
  "frame-benchmarking",
  "frame-support",
  "frame-system",
diff --git a/pallets/duniter-wot/src/mock.rs b/pallets/duniter-wot/src/mock.rs
index d9ebcb1807f3a234098efe0724e176d3a8e9f4ee..f73248cc656f0dde192d15028ab5bf921260da32 100644
--- a/pallets/duniter-wot/src/mock.rs
+++ b/pallets/duniter-wot/src/mock.rs
@@ -30,15 +30,6 @@ use std::collections::BTreeMap;
 type AccountId = u64;
 type Block = frame_system::mocking::MockBlock<Test>;
 
-pub struct IdentityIndexOf<T: pallet_identity::Config>(PhantomData<T>);
-impl<T: pallet_identity::Config> sp_runtime::traits::Convert<T::AccountId, Option<T::IdtyIndex>>
-    for IdentityIndexOf<T>
-{
-    fn convert(account_id: T::AccountId) -> Option<T::IdtyIndex> {
-        pallet_identity::Pallet::<T>::identity_index_of(account_id)
-    }
-}
-
 // Configure a mock runtime to test the pallet.
 frame_support::construct_runtime!(
     pub enum Test {
@@ -145,12 +136,11 @@ parameter_types! {
 }
 
 impl pallet_membership::Config for Test {
-    type AccountIdOf = ();
     #[cfg(feature = "runtime-benchmarks")]
     type BenchmarkSetupHandler = ();
     type CheckMembershipOpAllowed = DuniterWot;
+    type IdtyAttr = Identity;
     type IdtyId = IdtyIndex;
-    type IdtyIdOf = IdentityIndexOf<Self>;
     type MembershipPeriod = MembershipPeriod;
     type MembershipRenewalPeriod = MembershipRenewalPeriod;
     type OnNewMembership = DuniterWot;
diff --git a/pallets/membership/Cargo.toml b/pallets/membership/Cargo.toml
index e33045ca98b3f71de1a1c0149e17eb3be9c215d3..b43852aa0be7ea53b58ccc63dc187292ed2f6b96 100644
--- a/pallets/membership/Cargo.toml
+++ b/pallets/membership/Cargo.toml
@@ -40,6 +40,7 @@ try-runtime = [
 targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
+duniter-primitives = { workspace = true }
 codec = { workspace = true, features = ["derive"] }
 frame-benchmarking = { workspace = true, optional = true }
 frame-support = { workspace = true }
diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs
index 92a82428c0f8730c15b09bfa36c25a92ba8f3962..4119fcb9cf47c947e3259011d8fdd75009786d08 100644
--- a/pallets/membership/src/lib.rs
+++ b/pallets/membership/src/lib.rs
@@ -69,7 +69,6 @@ pub mod pallet {
     use super::*;
     use frame_support::traits::StorageVersion;
     use frame_system::pallet_prelude::*;
-    use sp_runtime::traits::Convert;
 
     /// The current storage version.
     const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
@@ -87,10 +86,8 @@ pub mod pallet {
         type CheckMembershipOpAllowed: CheckMembershipOpAllowed<Self::IdtyId>;
         /// Something that identifies an identity
         type IdtyId: Copy + MaybeSerializeDeserialize + Parameter + Ord;
-        /// Something that gives the IdtyId of an AccountId
-        type IdtyIdOf: Convert<Self::AccountId, Option<Self::IdtyId>>;
-        /// Something that gives the AccountId of an IdtyId
-        type AccountIdOf: Convert<Self::IdtyId, Option<Self::AccountId>>;
+        /// Something that gives the IdtyId of an AccountId and reverse
+        type IdtyAttr: duniter_primitives::Idty<Self::IdtyId, Self::AccountId>;
         /// Maximum life span of a single membership (in number of blocks)
         // (this could be renamed "validity" or "duration")
         #[pallet::constant]
diff --git a/pallets/membership/src/mock.rs b/pallets/membership/src/mock.rs
index 2d27a0d79496adb355fe084d907869001ec5c71e..6269ed615639f46c57dde4fd3dc6e882d67eade1 100644
--- a/pallets/membership/src/mock.rs
+++ b/pallets/membership/src/mock.rs
@@ -22,7 +22,7 @@ use frame_support::{
 use frame_system as system;
 use sp_core::H256;
 use sp_runtime::{
-    traits::{BlakeTwo256, ConvertInto, IdentityLookup},
+    traits::{BlakeTwo256, IdentityLookup},
     BuildStorage,
 };
 
@@ -82,12 +82,11 @@ parameter_types! {
 }
 
 impl pallet_membership::Config for Test {
-    type AccountIdOf = ConvertInto;
     #[cfg(feature = "runtime-benchmarks")]
     type BenchmarkSetupHandler = ();
     type CheckMembershipOpAllowed = ();
+    type IdtyAttr = ();
     type IdtyId = IdtyId;
-    type IdtyIdOf = ConvertInto;
     type MembershipPeriod = MembershipPeriod;
     type MembershipRenewalPeriod = MembershipRenewalPeriod;
     type OnNewMembership = ();
diff --git a/pallets/smith-members/Cargo.toml b/pallets/smith-members/Cargo.toml
index 651a62a8a77f543bfaf71ee4b09128a424c30844..d18fc3cfbe1f1569203394d88dd5634100058fd0 100644
--- a/pallets/smith-members/Cargo.toml
+++ b/pallets/smith-members/Cargo.toml
@@ -13,6 +13,7 @@ version.workspace = true
 targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
+duniter-primitives = { workspace = true }
 codec = { workspace = true, features = ["derive"] }
 frame-benchmarking = { workspace = true, optional = true }
 frame-support = { workspace = true }
diff --git a/pallets/smith-members/src/benchmarking.rs b/pallets/smith-members/src/benchmarking.rs
index 3539c9ed892db0ec4011d366fcfc9395baf5cee1..0381e177c26f4c261dde4707daaf20edc7d80944 100644
--- a/pallets/smith-members/src/benchmarking.rs
+++ b/pallets/smith-members/src/benchmarking.rs
@@ -20,7 +20,6 @@ use super::*;
 
 use frame_benchmarking::v2::*;
 use frame_system::RawOrigin;
-use sp_runtime::traits::Convert;
 
 use crate::Pallet;
 
@@ -38,7 +37,7 @@ mod benchmarks {
     #[benchmark]
     fn invite_smith() {
         let issuer: T::IdtyIndex = 1.into();
-        let caller: T::AccountId = T::OwnerKeyOf::convert(issuer).unwrap();
+        let caller: T::AccountId = T::IdtyAttr::owner_key(issuer).unwrap();
         Pallet::<T>::on_smith_goes_online(1.into());
         let receiver: T::IdtyIndex = 4.into();
 
@@ -51,14 +50,14 @@ mod benchmarks {
     #[benchmark]
     fn accept_invitation() -> Result<(), BenchmarkError> {
         let issuer: T::IdtyIndex = 1.into();
-        let caller: T::AccountId = T::OwnerKeyOf::convert(issuer).unwrap();
+        let caller: T::AccountId = T::IdtyAttr::owner_key(issuer).unwrap();
         Pallet::<T>::on_smith_goes_online(1.into());
         let caller_origin: <T as frame_system::Config>::RuntimeOrigin =
             RawOrigin::Signed(caller.clone()).into();
         let receiver: T::IdtyIndex = 4.into();
         Pallet::<T>::invite_smith(caller_origin, receiver)?;
         let issuer: T::IdtyIndex = 4.into();
-        let caller: T::AccountId = T::OwnerKeyOf::convert(issuer).unwrap();
+        let caller: T::AccountId = T::IdtyAttr::owner_key(issuer).unwrap();
 
         #[extrinsic_call]
         _(RawOrigin::Signed(caller));
@@ -75,19 +74,19 @@ mod benchmarks {
     #[benchmark]
     fn certify_smith() -> Result<(), BenchmarkError> {
         let issuer: T::IdtyIndex = 1.into();
-        let caller: T::AccountId = T::OwnerKeyOf::convert(issuer).unwrap();
+        let caller: T::AccountId = T::IdtyAttr::owner_key(issuer).unwrap();
         Pallet::<T>::on_smith_goes_online(1.into());
         let caller_origin: <T as frame_system::Config>::RuntimeOrigin =
             RawOrigin::Signed(caller.clone()).into();
         let receiver: T::IdtyIndex = 4.into();
         Pallet::<T>::invite_smith(caller_origin, receiver)?;
         let issuer: T::IdtyIndex = receiver;
-        let caller: T::AccountId = T::OwnerKeyOf::convert(issuer).unwrap();
+        let caller: T::AccountId = T::IdtyAttr::owner_key(issuer).unwrap();
         let caller_origin: <T as frame_system::Config>::RuntimeOrigin =
             RawOrigin::Signed(caller.clone()).into();
         Pallet::<T>::accept_invitation(caller_origin)?;
         let issuer: T::IdtyIndex = 1.into();
-        let caller: T::AccountId = T::OwnerKeyOf::convert(issuer).unwrap();
+        let caller: T::AccountId = T::IdtyAttr::owner_key(issuer).unwrap();
 
         #[extrinsic_call]
         _(RawOrigin::Signed(caller), receiver);
diff --git a/pallets/smith-members/src/lib.rs b/pallets/smith-members/src/lib.rs
index 9b33a6b561e7a910dfa39996e08e175baf602e6c..61edcd6f6e7b741523e9450b1de869cd12ee6ab1 100644
--- a/pallets/smith-members/src/lib.rs
+++ b/pallets/smith-members/src/lib.rs
@@ -31,6 +31,7 @@ pub mod weights;
 mod benchmarking;
 
 use codec::{Codec, Decode, Encode};
+use duniter_primitives::Idty;
 use frame_support::dispatch::DispatchResultWithPostInfo;
 use frame_support::ensure;
 use frame_support::pallet_prelude::Get;
@@ -108,11 +109,9 @@ pub mod pallet {
             + MaxEncodedLen;
         /// Identifier for an authority-member
         type MemberId: Copy + Ord + MaybeSerializeDeserialize + Parameter;
-        /// Something that gives the IdtyId of an AccountId
-        type IdtyIdOf: Convert<Self::AccountId, Option<Self::IdtyIndex>>;
-        /// Something that give the owner key of an identity
-        type OwnerKeyOf: Convert<Self::IdtyIndex, Option<Self::AccountId>>;
-        /// Something that gives the IdtyId of an AccountId
+        /// Something that gives the IdtyId of an AccountId and reverse
+        type IdtyAttr: duniter_primitives::Idty<Self::IdtyIndex, Self::AccountId>;
+        // /// Something that give the owner key of an identity
         type IdtyIdOfAuthorityId: Convert<Self::MemberId, Option<Self::IdtyIndex>>;
         /// Maximum number of active certifications by issuer
         #[pallet::constant]
@@ -291,7 +290,7 @@ pub mod pallet {
         ) -> DispatchResultWithPostInfo {
             let who = ensure_signed(origin.clone())?;
             let issuer =
-                T::IdtyIdOf::convert(who.clone()).ok_or(Error::<T>::OriginMustHaveAnIdentity)?;
+                T::IdtyAttr::idty_index(who.clone()).ok_or(Error::<T>::OriginMustHaveAnIdentity)?;
             Self::check_invite_smith(issuer, receiver)?;
             Self::do_invite_smith(issuer, receiver);
             Ok(().into())
@@ -303,7 +302,7 @@ pub mod pallet {
         pub fn accept_invitation(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
             let who = ensure_signed(origin.clone())?;
             let receiver =
-                T::IdtyIdOf::convert(who.clone()).ok_or(Error::<T>::OriginMustHaveAnIdentity)?;
+                T::IdtyAttr::idty_index(who.clone()).ok_or(Error::<T>::OriginMustHaveAnIdentity)?;
             Self::check_accept_invitation(receiver)?;
             Self::do_accept_invitation(receiver)?;
             Ok(().into())
@@ -318,7 +317,7 @@ pub mod pallet {
         ) -> DispatchResultWithPostInfo {
             let who = ensure_signed(origin)?;
             let issuer =
-                T::IdtyIdOf::convert(who.clone()).ok_or(Error::<T>::OriginMustHaveAnIdentity)?;
+                T::IdtyAttr::idty_index(who.clone()).ok_or(Error::<T>::OriginMustHaveAnIdentity)?;
             Self::check_certify_smith(issuer, receiver)?;
             Self::do_certify_smith(receiver, issuer);
             Ok(().into())
diff --git a/pallets/smith-members/src/mock.rs b/pallets/smith-members/src/mock.rs
index 3669161b596f1fd1b14f36c65661aa4c00735d38..804b7d49f8f4e19833a9b9bc2771c5e13fa3e906 100644
--- a/pallets/smith-members/src/mock.rs
+++ b/pallets/smith-members/src/mock.rs
@@ -84,7 +84,7 @@ impl IsMember<u64> for EveryoneExceptIdZero {
 }
 
 impl pallet_smith_members::Config for Runtime {
-    type IdtyIdOf = ConvertInto;
+    type IdtyAttr = ();
     type IdtyIdOfAuthorityId = ConvertInto;
     type IdtyIndex = u64;
     type IsWoTMember = EveryoneExceptIdZero;
@@ -92,7 +92,6 @@ impl pallet_smith_members::Config for Runtime {
     type MemberId = u64;
     type MinCertForMembership = ConstU32<2>;
     type OnSmithDelete = ();
-    type OwnerKeyOf = ConvertInto;
     type RuntimeEvent = RuntimeEvent;
     type SmithInactivityMaxDuration = ConstU32<5>;
     type WeightInfo = ();
diff --git a/pallets/universal-dividend/Cargo.toml b/pallets/universal-dividend/Cargo.toml
index 5fdfc69f5e85236bb3ec576abc7247b3052c4fad..a859b2f97156601668f076bc65c6adbf9f30c3e8 100644
--- a/pallets/universal-dividend/Cargo.toml
+++ b/pallets/universal-dividend/Cargo.toml
@@ -49,6 +49,7 @@ default-features = false
 targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
+duniter-primitives = { workspace = true }
 codec = { workspace = true, features = ["derive", "max-encoded-len"] }
 frame-benchmarking = { workspace = true, optional = true }
 frame-support = { workspace = true }
diff --git a/pallets/universal-dividend/src/benchmarking.rs b/pallets/universal-dividend/src/benchmarking.rs
index 8614441b3a2025c50ef9518a95d5e71f7f471723..58c4302d83d5f0ccffc2850cc85f6690ebdbc92e 100644
--- a/pallets/universal-dividend/src/benchmarking.rs
+++ b/pallets/universal-dividend/src/benchmarking.rs
@@ -27,7 +27,6 @@ use frame_support::traits::StoredMap;
 use frame_system::RawOrigin;
 use pallet_balances::Pallet as Balances;
 use sp_runtime::traits::Bounded;
-use sp_runtime::traits::Convert;
 
 use crate::Pallet;
 
@@ -50,7 +49,7 @@ mod benchmarks {
         // Benchmark `transfer_ud` extrinsic with the worst possible conditions:
         // * Transfer will kill the sender account.
         // * Transfer will create the recipient account.
-        let caller: T::AccountId = T::AccountIdOf::convert(1).unwrap();
+        let caller: T::AccountId = T::IdtyAttr::owner_key(1).unwrap();
         CurrentUdIndex::<T>::put(2054u16);
         T::MembersStorage::insert(
             &caller,
@@ -135,7 +134,7 @@ mod benchmarks {
 
     #[benchmark]
     fn on_removed_member(i: Linear<1, { T::MaxPastReeval::get() }>) -> Result<(), BenchmarkError> {
-        let caller: T::AccountId = T::AccountIdOf::convert(1).unwrap();
+        let caller: T::AccountId = T::IdtyAttr::owner_key(1).unwrap();
         CurrentUdIndex::<T>::put(2054u16);
         T::MembersStorage::insert(
             &caller,
diff --git a/pallets/universal-dividend/src/lib.rs b/pallets/universal-dividend/src/lib.rs
index 9eb12eb1b4416be4400c4f2edd46fcb74c963b29..6c6f60da2c80f79d2ec3ea6d822e2aa839df0440 100644
--- a/pallets/universal-dividend/src/lib.rs
+++ b/pallets/universal-dividend/src/lib.rs
@@ -18,12 +18,16 @@
 
 mod benchmarking;
 mod compute_claim_uds;
+mod types;
+mod weights;
+
 #[cfg(test)]
 mod mock;
 #[cfg(test)]
 mod tests;
-mod types;
-mod weights;
+
+#[cfg(feature = "runtime-benchmarks")]
+use duniter_primitives::Idty;
 
 pub use pallet::*;
 pub use types::*;
@@ -86,8 +90,9 @@ pub mod pallet {
         type UnitsPerUd: Get<BalanceOf<Self>>;
         /// Pallet weights info
         type WeightInfo: WeightInfo;
+        /// Something that gives the IdtyId of an AccountId and reverse
         #[cfg(feature = "runtime-benchmarks")]
-        type AccountIdOf: Convert<u32, Option<Self::AccountId>>;
+        type IdtyAttr: duniter_primitives::Idty<u32, Self::AccountId>;
     }
 
     // STORAGE //
diff --git a/pallets/universal-dividend/src/mock.rs b/pallets/universal-dividend/src/mock.rs
index dbe776de299815ba5f3b2f63c9f82297c64631da..b1397ffe57790f6f8b624fbb69e49bb4633bf5c2 100644
--- a/pallets/universal-dividend/src/mock.rs
+++ b/pallets/universal-dividend/src/mock.rs
@@ -27,9 +27,6 @@ use sp_runtime::{
     BuildStorage,
 };
 
-#[cfg(feature = "runtime-benchmarks")]
-use sp_runtime::traits::ConvertInto;
-
 pub const BLOCK_TIME: u64 = 6_000;
 
 type Balance = u64;
@@ -142,9 +139,9 @@ impl frame_support::traits::StoredMap<u32, FirstEligibleUd> for TestMembersStora
 }
 
 impl pallet_universal_dividend::Config for Test {
-    #[cfg(feature = "runtime-benchmarks")]
-    type AccountIdOf = ConvertInto;
     type Currency = pallet_balances::Pallet<Test>;
+    #[cfg(feature = "runtime-benchmarks")]
+    type IdtyAttr = ();
     type MaxPastReeval = frame_support::traits::ConstU32<2>;
     type MembersCount = MembersCount;
     type MembersStorage = TestMembersStorage;
diff --git a/primitives/duniter/src/lib.rs b/primitives/duniter/src/lib.rs
index 44c1257daa6733ae87dc50eac5a89bf8a9a3ae66..1d71c0a590bb651a031afed211d113477b40ee12 100644
--- a/primitives/duniter/src/lib.rs
+++ b/primitives/duniter/src/lib.rs
@@ -29,6 +29,7 @@ pub fn validate_idty_name(idty_name: &[u8]) -> bool {
 }
 
 /// trait used to go from index to owner key and reverse
+// replaces less explicit "Convert" implementations
 pub trait Idty<IdtyIndex, AccountId> {
     fn owner_key(index: IdtyIndex) -> Option<AccountId>;
     fn idty_index(owner_key: AccountId) -> Option<IdtyIndex>;
diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs
index 09156ab08ed5275214187dd391492c36765a3eb2..6cbe9d6e9dd48c9f6a88a13e9bb6b5080b3b7c70 100644
--- a/runtime/common/src/pallets_config.rs
+++ b/runtime/common/src/pallets_config.rs
@@ -457,7 +457,7 @@ type RuntimeFreezeReason = ();
             type UnitsPerUd = frame_support::traits::ConstU64<1_000>;
 			type WeightInfo = common_runtime::weights::pallet_universal_dividend::WeightInfo<Runtime>;
             #[cfg(feature = "runtime-benchmarks")]
-            type AccountIdOf = common_runtime::providers::IdentityAccountIdProvider<Self>;
+            type IdtyAttr = Identity;
         }
 
         // WEB OF TRUST //
@@ -501,8 +501,7 @@ type RuntimeFreezeReason = ();
         impl pallet_membership::Config for Runtime {
             type CheckMembershipOpAllowed = Wot;
             type IdtyId = IdtyIndex;
-            type IdtyIdOf = common_runtime::providers::IdentityIndexOf<Self>;
-            type AccountIdOf = common_runtime::providers::IdentityAccountIdProvider<Self>;
+            type IdtyAttr = Identity;
             type MembershipPeriod = MembershipPeriod;
             type MembershipRenewalPeriod = MembershipRenewalPeriod;
             type OnNewMembership = OnNewMembershipHandler<Runtime>;
@@ -546,7 +545,7 @@ type RuntimeFreezeReason = ();
             type RuntimeEvent = RuntimeEvent;
             type IdtyIndex = IdtyIndex;
             type IsWoTMember = common_runtime::providers::IsWoTMemberProvider<Runtime>;
-            type IdtyIdOf = common_runtime::providers::IdentityIndexOf<Self>;
+            type IdtyAttr = Identity;
             type MinCertForMembership = SmithWotMinCertForMembership;
             type MaxByIssuer = SmithMaxByIssuer;
             type SmithInactivityMaxDuration = SmithInactivityMaxDuration;
@@ -554,8 +553,6 @@ type RuntimeFreezeReason = ();
             type IdtyIdOfAuthorityId = sp_runtime::traits::ConvertInto;
             type MemberId = IdtyIndex;
             type WeightInfo = common_runtime::weights::pallet_smith_members::WeightInfo<Runtime>;
-            // TODO: remove as it is only used for benchmarking
-            type OwnerKeyOf = Identity;
         }
 
         pub struct TechnicalCommitteeDefaultVote;