diff --git a/Cargo.lock b/Cargo.lock
index e2b6bba2a56bdd125475db9f94084b56e52c89d6..416de18697d326dcb43e3352c0ba27853c4a1554 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -377,9 +377,9 @@ checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581"
 
 [[package]]
 name = "base64"
-version = "0.13.0"
+version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
 
 [[package]]
 name = "beef"
@@ -819,6 +819,8 @@ dependencies = [
  "pallet-babe",
  "pallet-balances",
  "pallet-certification",
+ "pallet-distance",
+ "pallet-distance-rpc-runtime-api",
  "pallet-duniter-account",
  "pallet-duniter-wot",
  "pallet-grandpa",
@@ -842,6 +844,7 @@ dependencies = [
  "sp-arithmetic",
  "sp-consensus-babe",
  "sp-core",
+ "sp-distance",
  "sp-membership",
  "sp-runtime",
  "sp-staking",
@@ -1328,6 +1331,26 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "dc-distance"
+version = "1.0.0"
+dependencies = [
+ "frame-support",
+ "frame-system",
+ "pallet-distance",
+ "parity-scale-codec",
+ "sc-client-api",
+ "scale-info",
+ "sp-api",
+ "sp-blockchain",
+ "sp-core",
+ "sp-distance",
+ "sp-rpc",
+ "sp-runtime",
+ "sp-std",
+ "thiserror",
+]
+
 [[package]]
 name = "der"
 version = "0.5.1"
@@ -1459,6 +1482,7 @@ dependencies = [
  "clap",
  "clap_complete",
  "common-runtime",
+ "dc-distance",
  "frame-benchmarking",
  "frame-benchmarking-cli",
  "futures 0.3.21",
@@ -1472,6 +1496,8 @@ dependencies = [
  "maplit",
  "memmap2 0.5.0",
  "pallet-certification",
+ "pallet-distance-rpc",
+ "pallet-distance-rpc-runtime-api",
  "pallet-grandpa",
  "pallet-transaction-payment-rpc",
  "pallet-transaction-payment-rpc-runtime-api",
@@ -1502,6 +1528,7 @@ dependencies = [
  "sp-consensus",
  "sp-consensus-babe",
  "sp-core",
+ "sp-distance",
  "sp-finality-grandpa",
  "sp-inherents",
  "sp-io",
@@ -2419,6 +2446,8 @@ dependencies = [
  "pallet-balances",
  "pallet-certification",
  "pallet-collective",
+ "pallet-distance",
+ "pallet-distance-rpc-runtime-api",
  "pallet-duniter-account",
  "pallet-duniter-test-parameters",
  "pallet-duniter-wot",
@@ -2453,6 +2482,7 @@ dependencies = [
  "sp-consensus-babe",
  "sp-consensus-vrf",
  "sp-core",
+ "sp-distance",
  "sp-finality-grandpa",
  "sp-inherents",
  "sp-io",
@@ -2905,13 +2935,13 @@ dependencies = [
 
 [[package]]
 name = "http"
-version = "0.2.4"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
+checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
 dependencies = [
  "bytes",
  "fnv",
- "itoa 0.4.7",
+ "itoa 1.0.1",
 ]
 
 [[package]]
@@ -5028,6 +5058,59 @@ dependencies = [
  "sp-std",
 ]
 
+[[package]]
+name = "pallet-distance"
+version = "1.0.0"
+dependencies = [
+ "frame-support",
+ "frame-system",
+ "pallet-authority-members",
+ "pallet-authorship",
+ "pallet-certification",
+ "pallet-identity",
+ "pallet-membership",
+ "pallet-session",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-core",
+ "sp-distance",
+ "sp-inherents",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
+name = "pallet-distance-rpc"
+version = "1.0.0"
+dependencies = [
+ "base64",
+ "frame-support",
+ "frame-system",
+ "jsonrpsee 0.14.0",
+ "pallet-distance-rpc-runtime-api",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-api",
+ "sp-blockchain",
+ "sp-core",
+ "sp-distance",
+ "sp-rpc",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
+name = "pallet-distance-rpc-runtime-api"
+version = "1.0.0"
+dependencies = [
+ "frame-support",
+ "pallet-distance",
+ "parity-scale-codec",
+ "sp-api",
+ "sp-runtime",
+]
+
 [[package]]
 name = "pallet-duniter-account"
 version = "3.0.0"
@@ -8218,6 +8301,21 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "sp-distance"
+version = "3.0.0"
+dependencies = [
+ "async-trait",
+ "frame-support",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-inherents",
+ "sp-runtime",
+ "sp-std",
+ "thiserror",
+]
+
 [[package]]
 name = "sp-externalities"
 version = "0.12.0"
@@ -9374,9 +9472,9 @@ version = "1.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "digest 0.10.3",
- "rand 0.7.3",
+ "rand 0.8.4",
  "static_assertions",
 ]
 
diff --git a/Cargo.toml b/Cargo.toml
index 16e11ef4537fe2323835a5ff30f6225e77070f4e..06638309b3c7b2ffefd702315f3a4f8df15bbd02 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -55,10 +55,14 @@ sp-trie = { git = "https://github.com/duniter/substrate", branch = "duniter-subs
 [dependencies]
 # local dependencies
 common-runtime = { path = 'runtime/common' }
+dc-distance = { path = 'client/distance' }
 g1-runtime = { path = 'runtime/g1', optional = true }
 gdev-runtime = { path = 'runtime/gdev', optional = true }
 gtest-runtime = { path = 'runtime/gtest', optional = true }
 pallet-certification = { path = 'pallets/certification' }
+pallet-distance-rpc = { path = 'pallets/distance/rpc' }
+pallet-distance-rpc-runtime-api = { path = 'pallets/distance/rpc/runtime-api' }
+sp-distance = { path = 'primitives/distance' }
 sp-membership = { path = 'primitives/membership' }
 
 # crates.io dependencies
@@ -125,9 +129,13 @@ try-runtime-cli = { git = "https://github.com/duniter/substrate", branch = "duni
 resolver = "2"
 
 members = [
+    'client/distance',
     'end2end-tests',
     'live-tests',
     'pallets/certification',
+	'pallets/distance',
+	'pallets/distance/rpc',
+	'pallets/distance/rpc/runtime-api',
     'pallets/duniter-test-parameters',
     'pallets/duniter-test-parameters/macro',
     'pallets/duniter-wot',
@@ -138,6 +146,7 @@ members = [
     'pallets/universal-dividend',
     'pallets/upgrade-origin',
     'primitives/membership',
+    'primitives/distance',
     'runtime/common',
     'runtime/gdev',
     'xtask',
diff --git a/client/distance/Cargo.toml b/client/distance/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..6b29a20f43a21256634ce95a94258d4b144b709a
--- /dev/null
+++ b/client/distance/Cargo.toml
@@ -0,0 +1,65 @@
+[package]
+authors = ['tuxmain <tuxmain@zettascript.org>']
+description = 'Duniter client distance'
+edition = '2018'
+homepage = 'https://duniter.org'
+license = 'AGPL-3.0'
+name = 'dc-distance'
+readme = 'README.md'
+repository = 'https://git.duniter.org/nodes/rust/duniter-v2s'
+version = '1.0.0'
+
+[dependencies]
+
+pallet-distance = { path = "../../pallets/distance" }
+sp-distance = { path = "../../primitives/distance" }
+thiserror = "1.0.30"
+
+# substrate
+scale-info = { version = "2.1.1", features = ["derive"] }
+
+[dependencies.codec]
+features = ['derive']
+package = 'parity-scale-codec'
+version = '3.1.5'
+
+[dependencies.frame-support]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.frame-system]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sc-client-api]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-api]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-blockchain]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-core]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-rpc]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-runtime]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-std]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+### DOC ###
+
+[package.metadata.docs.rs]
+targets = ['x86_64-unknown-linux-gnu']
diff --git a/client/distance/src/lib.rs b/client/distance/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..fc7ceb499ca6fe22b25c1317be5ce1fbd2a4e455
--- /dev/null
+++ b/client/distance/src/lib.rs
@@ -0,0 +1,70 @@
+// Copyright 2022 Axiom-Team
+//
+// This file is part of Substrate-Libre-Currency.
+//
+// Substrate-Libre-Currency is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, version 3 of the License.
+//
+// Substrate-Libre-Currency is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// 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 codec::{Decode, Encode};
+use sc_client_api::{ProvideUncles, StorageKey, StorageProvider};
+use scale_info::TypeInfo;
+use sp_runtime::{generic::BlockId, traits::Block as BlockT};
+use std::path::PathBuf;
+
+#[derive(Debug, thiserror::Error)]
+pub enum Error<B: BlockT> {
+    #[error("Could not retrieve the block hash for block id: {0:?}")]
+    NoHashForBlockId(BlockId<B>),
+}
+
+/// Create a new [`sp_distance::InherentDataProvider`] at the given block.
+pub fn create_distance_inherent_data_provider<B, C, Backend, IdtyIndex>(
+    client: &C,
+    parent: B::Hash,
+    distance_dir: PathBuf,
+) -> Result<sp_distance::InherentDataProvider<IdtyIndex>, sc_client_api::blockchain::Error>
+where
+    B: BlockT,
+    C: ProvideUncles<B> + StorageProvider<B, Backend>,
+    Backend: sc_client_api::Backend<B>,
+    IdtyIndex: Decode + Encode + PartialEq + TypeInfo,
+{
+    // TODO:
+    // * dc_distance::create_distance_inherent_data_provider(client_clone, parent, distance_dir)
+    //   * est-ce qu'on a déjà publié un résultat ce round
+    //     * avec storage provider dans client_clone:
+    //        * récupérer liste des forgerons ayant publié résultat ce round
+    //        * palette session: dans KeyOwner: récupérer notre clé forgeron à partir d'une de nos session_keys
+    //   * sinon, pour quel round on veut un résultat
+    //     * current_round_index dans storage provider (ou session index)
+
+    let key_published_results = StorageKey(
+        frame_support::storage::storage_prefix(b"Distance", b"StoragePublishedResults").to_vec(),
+    );
+    // TODO: what if unwrap fails?
+    let published_results = client
+        .storage(&BlockId::Hash(parent), &key_published_results)?
+        .unwrap();
+
+    let key_owner_key =
+        StorageKey(frame_support::storage::storage_prefix(b"Session", b"OwnerKey").to_vec());
+    // TODO: what if unwrap fails?
+    let owner_key = client
+        .storage(&BlockId::Hash(parent), &key_owner_key)?
+        .unwrap();
+
+    // TODO pour trouver session key: voir keystore
+
+    Ok(sp_distance::InherentDataProvider::<IdtyIndex>::new(
+        distance_dir,
+    ))
+}
diff --git a/node/src/rpc.rs b/node/src/rpc.rs
index 36dee008a8e037c36cd0b4430a120189b878fb2d..92c6b722140cda22cea76790d56f561c5b2ce75c 100644
--- a/node/src/rpc.rs
+++ b/node/src/rpc.rs
@@ -24,13 +24,13 @@
 pub use sc_rpc_api::DenyUnsafe;
 
 use common_runtime::Block;
-use common_runtime::{AccountId, Balance, Index};
+use common_runtime::{AccountId, Balance, IdtyIndex, Index};
 use jsonrpsee::RpcModule;
 use sc_transaction_pool_api::TransactionPool;
 use sp_api::ProvideRuntimeApi;
 use sp_block_builder::BlockBuilder;
 use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
-use std::sync::Arc;
+use std::{path::PathBuf, sync::Arc};
 
 /// Full client dependencies.
 pub struct FullDeps<C, P> {
@@ -43,6 +43,7 @@ pub struct FullDeps<C, P> {
     /// Manual seal command sink
     pub command_sink_opt:
         Option<futures::channel::mpsc::Sender<manual_seal::EngineCommand<sp_core::H256>>>,
+    pub distance_dir: PathBuf,
 }
 
 /// Instantiate all full RPC extensions.
@@ -54,11 +55,13 @@ where
     C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
     C: Send + Sync + 'static,
     C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
+    C::Api: pallet_distance_rpc::DistanceRuntimeApi<Block, IdtyIndex>,
     C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
     C::Api: BlockBuilder<Block>,
     P: TransactionPool + 'static,
 {
     use manual_seal::rpc::{ManualSeal, ManualSealApiServer};
+    use pallet_distance_rpc::{Distance, DistanceApiServer};
     use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
     use substrate_frame_rpc_system::{System, SystemApiServer};
 
@@ -68,10 +71,11 @@ where
         pool,
         deny_unsafe,
         command_sink_opt,
+        distance_dir,
     } = deps;
 
     module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?;
-    module.merge(TransactionPayment::new(client).into_rpc())?;
+    module.merge(TransactionPayment::new(client.clone()).into_rpc())?;
 
     if let Some(command_sink) = command_sink_opt {
         // We provide the rpc handler with the sending end of the channel to allow the rpc
@@ -83,6 +87,13 @@ where
     // `YourRpcStruct` should have a reference to a client, which is needed
     // to call into the runtime.
     // `module.merge(YourRpcTrait::into_rpc(YourRpcStruct::new(ReferenceToClient, ...)))?;`
+    /*module.merge(DistanceApiServer::into_rpc(
+        Distance::new(
+            client,
+            distance_dir,
+        ),
+    ))?;*/
+    module.merge(Distance::new(client, distance_dir).into_rpc())?;
 
     Ok(module)
 }
diff --git a/node/src/service.rs b/node/src/service.rs
index e668b5383d927772c92e23256f971a8480f1150f..4ecbca22c2e8126d97681b51b8238e888180e8ff 100644
--- a/node/src/service.rs
+++ b/node/src/service.rs
@@ -31,7 +31,7 @@ use sc_service::{error::Error as ServiceError, Configuration, PartialComponents,
 use sc_telemetry::{Telemetry, TelemetryWorker};
 use sp_core::H256;
 use sp_runtime::traits::BlakeTwo256;
-use std::{sync::Arc, time::Duration};
+use std::{path::PathBuf, sync::Arc, time::Duration};
 
 type FullClient<RuntimeApi, Executor> =
     sc_service::TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<Executor>>;
@@ -431,6 +431,15 @@ where
     let enable_grandpa = !config.disable_grandpa;
     let prometheus_registry = config.prometheus_registry().cloned();
 
+    let distance_dir = config.base_path.as_ref().map_or_else(
+        || PathBuf::from("/tmp"),
+        |base_path| {
+            base_path
+                .config_dir(config.chain_spec.id())
+                .join("distance")
+        },
+    ); // TODO improve this
+
     let mut command_sink_opt = None;
     if role.is_authority() {
         let proposer_factory = sc_basic_authorship::ProposerFactory::new(
@@ -525,6 +534,7 @@ where
 
             let client_clone = client.clone();
             let slot_duration = babe_link.config().slot_duration();
+            let distance_dir = distance_dir.clone();
             let babe_config = babe::BabeParams {
                 keystore: keystore_container.sync_keystore(),
                 client: client.clone(),
@@ -535,6 +545,7 @@ where
                 justification_sync_link: network.clone(),
                 create_inherent_data_providers: move |parent, ()| {
                     let client_clone = client_clone.clone();
+                    let distance_dir = distance_dir.clone();
 
                     async move {
                         let uncles = sc_consensus_uncles::create_uncles_inherent_data_provider(
@@ -550,7 +561,15 @@ where
                                     slot_duration,
                                 );
 
-                        Ok((timestamp, slot, uncles))
+                        let distance =
+                            dc_distance::create_distance_inherent_data_provider::<
+                                _,
+                                _,
+                                FullBackend,
+                                u32,
+                            >(&*client_clone, parent, distance_dir)?;
+
+                        Ok((timestamp, slot, uncles, distance))
                     }
                 },
                 force_authoring,
@@ -579,6 +598,7 @@ where
         let pool = transaction_pool.clone();
         //let select_chain = select_chain.clone();
         //let chain_spec = config.chain_spec.cloned_box();
+        let distance_dir = distance_dir.clone();
 
         Box::new(move |deny_unsafe, _| {
             let deps = crate::rpc::FullDeps {
@@ -593,6 +613,7 @@ where
                     keystore: keystore.clone(),
                 },*/
                 command_sink_opt: command_sink_opt.clone(),
+                distance_dir: distance_dir.clone(),
             };
 
             crate::rpc::create_full(deps).map_err(Into::into)
diff --git a/node/src/service/client.rs b/node/src/service/client.rs
index 9c5d63ae509aaf5447f625c75c79619ba808da7c..b1deec86edd12335baaf139362d8cdd831795018 100644
--- a/node/src/service/client.rs
+++ b/node/src/service/client.rs
@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
 
-use common_runtime::{AccountId, Balance, Block, BlockNumber, Hash, Header, Index};
+use common_runtime::{AccountId, Balance, Block, BlockNumber, Hash, Header, IdtyIndex, Index};
 use sc_client_api::{AuxStore, Backend as BackendT, BlockchainEvents, KeyIterator, UsageProvider};
 use sp_api::{CallApiAt, NumberFor, ProvideRuntimeApi};
 use sp_blockchain::{HeaderBackend, HeaderMetadata};
@@ -112,6 +112,7 @@ pub trait ExecuteWithClient {
 /// that it contains.
 pub trait RuntimeApiCollection:
     pallet_grandpa::fg_primitives::GrandpaApi<Block>
+    + pallet_distance_rpc_runtime_api::DistanceApi<Block, IdtyIndex>
     + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
     + sp_api::ApiExt<Block>
     + sp_authority_discovery::AuthorityDiscoveryApi<Block>
@@ -129,6 +130,7 @@ where
 impl<Api> RuntimeApiCollection for Api
 where
     Api: pallet_grandpa::fg_primitives::GrandpaApi<Block>
+        + pallet_distance_rpc_runtime_api::DistanceApi<Block, IdtyIndex>
         + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
         + sp_api::ApiExt<Block>
         + sp_authority_discovery::AuthorityDiscoveryApi<Block>
diff --git a/pallets/authority-members/src/lib.rs b/pallets/authority-members/src/lib.rs
index 941a0af7d56e1f4be886df51bc7905436b93f900..2d052c75fadd1882893c14e2ea393b7a0ff6474f 100644
--- a/pallets/authority-members/src/lib.rs
+++ b/pallets/authority-members/src/lib.rs
@@ -29,13 +29,13 @@ mod tests;
 /*#[cfg(feature = "runtime-benchmarks")]
 mod benchmarking;*/
 
+pub use self::traits::*;
 pub use pallet::*;
+pub use sp_staking::SessionIndex;
 pub use types::*;
 
-use self::traits::*;
 use frame_support::traits::Get;
 use sp_runtime::traits::Convert;
-use sp_staking::SessionIndex;
 use sp_std::prelude::*;
 
 #[frame_support::pallet]
diff --git a/pallets/distance/Cargo.toml b/pallets/distance/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..b1c3cbf3af4edeca7e10c61b597665118c6926e9
--- /dev/null
+++ b/pallets/distance/Cargo.toml
@@ -0,0 +1,85 @@
+[package]
+authors = ['tuxmain <tuxmain@zettascript.org>']
+description = 'FRAME pallet distance.'
+edition = '2021'
+homepage = 'https://duniter.org'
+license = 'AGPL-3.0'
+name = 'pallet-distance'
+readme = 'README.md'
+repository = 'https://git.duniter.org/nodes/rust/duniter-v2s'
+version = '1.0.0'
+
+[features]
+default = ['std']
+std = [
+    'codec/std',
+    'frame-support/std',
+    'frame-system/std',
+    'pallet-session/std',
+    'sp-core/std',
+    'sp-distance/std',
+    'sp-runtime/std',
+    'sp-std/std',
+]
+
+[dependencies]
+
+pallet-authority-members = { path = "../authority-members", default-features = false }
+pallet-certification = { path = "../certification", default-features = false }
+pallet-identity = { path = "../identity", default-features = false }
+pallet-membership = { path = "../membership", default-features = false }
+sp-distance = { path = "../../primitives/distance", default-features = false }
+
+# substrate
+scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
+
+[dependencies.codec]
+default-features = false
+features = ['derive']
+package = 'parity-scale-codec'
+version = '3.1.5'
+
+[dependencies.frame-support]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.frame-system]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.pallet-authorship]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.pallet-session]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-core]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-inherents]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-runtime]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-std]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+### DOC ###
+
+[package.metadata.docs.rs]
+targets = ['x86_64-unknown-linux-gnu']
diff --git a/pallets/distance/rpc/Cargo.toml b/pallets/distance/rpc/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..1feabb3b3a0c422cac77c4eccd661a545b5bb9ef
--- /dev/null
+++ b/pallets/distance/rpc/Cargo.toml
@@ -0,0 +1,64 @@
+[package]
+authors = ['tuxmain <tuxmain@zettascript.org>']
+description = 'FRAME pallet distance RPC.'
+edition = '2018'
+homepage = 'https://duniter.org'
+license = 'AGPL-3.0'
+name = 'pallet-distance-rpc'
+readme = 'README.md'
+repository = 'https://git.duniter.org/nodes/rust/duniter-v2s'
+version = '1.0.0'
+
+[dependencies]
+
+pallet-distance-rpc-runtime-api = { path = "./runtime-api" }
+sp-distance = { path = "../../../primitives/distance" }
+
+base64 = "0.13.1"
+serde = { version = "1.0", features = ["derive"] }
+
+# substrate
+jsonrpsee = { version = "0.14.0", features = ["server", "macros"] }
+scale-info = { version = "2.1.1", features = ["derive"] }
+
+[dependencies.codec]
+features = ['derive']
+package = 'parity-scale-codec'
+version = '3.1.5'
+
+[dependencies.frame-support]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.frame-system]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-api]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-blockchain]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-core]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-rpc]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-runtime]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-std]
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+### DOC ###
+
+[package.metadata.docs.rs]
+targets = ['x86_64-unknown-linux-gnu']
diff --git a/pallets/distance/rpc/runtime-api/Cargo.toml b/pallets/distance/rpc/runtime-api/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..c27fbca9855c011ac31e67c6b2b2f22dfff5a434
--- /dev/null
+++ b/pallets/distance/rpc/runtime-api/Cargo.toml
@@ -0,0 +1,32 @@
+[package]
+authors = ['tuxmain <tuxmain@zettascript.org>']
+description = 'FRAME pallet distance RPC runtime API.'
+edition = '2018'
+homepage = 'https://duniter.org'
+license = 'AGPL-3.0'
+name = 'pallet-distance-rpc-runtime-api'
+readme = 'README.md'
+repository = 'https://git.duniter.org/nodes/rust/duniter-v2s'
+version = '1.0.0'
+
+[dependencies]
+pallet-distance = { path = "../../", default-features = false }
+sp-api = { git = "https://github.com/duniter/substrate", branch = "duniter-substrate-v0.9.26", default-features = false }
+sp-runtime = { git = "https://github.com/duniter/substrate", branch = "duniter-substrate-v0.9.26", default-features = false }
+
+[dependencies.codec]
+default-features = false
+features = ['derive']
+package = 'parity-scale-codec'
+version = '3.1.5'
+
+[dependencies.frame-support]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[features]
+default = ["std"]
+std = [
+	"sp-api/std",
+]
diff --git a/pallets/distance/rpc/runtime-api/src/lib.rs b/pallets/distance/rpc/runtime-api/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..71aa3f9221239263840b66df242d9cf6df75ced8
--- /dev/null
+++ b/pallets/distance/rpc/runtime-api/src/lib.rs
@@ -0,0 +1,31 @@
+// Copyright 2022 Axiom-Team
+//
+// This file is part of Substrate-Libre-Currency.
+//
+// Substrate-Libre-Currency is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, version 3 of the License.
+//
+// Substrate-Libre-Currency is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// 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/>.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+pub use pallet_distance::{ComputationMetadata, ComputationResult};
+
+use codec::{Decode, Encode};
+use frame_support::pallet_prelude::*;
+
+// Here we declare the runtime API. It is implemented it the `impl` block in
+// runtime amalgamator file (the `runtime/src/lib.rs`)
+sp_api::decl_runtime_apis! {
+    pub trait DistanceApi<IdtyIndex: Decode + Encode + PartialEq + TypeInfo> {
+        fn get_computation_metadata() -> Option<ComputationMetadata>;
+        //fn publish_computation_result(computation_result: ComputationResult<IdtyIndex>);
+    }
+}
diff --git a/pallets/distance/rpc/src/lib.rs b/pallets/distance/rpc/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..31e1a74ff5de53cb7ae13a4c2aa665708dab6663
--- /dev/null
+++ b/pallets/distance/rpc/src/lib.rs
@@ -0,0 +1,177 @@
+// Copyright 2022 Axiom-Team
+//
+// This file is part of Substrate-Libre-Currency.
+//
+// Substrate-Libre-Currency is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, version 3 of the License.
+//
+// Substrate-Libre-Currency is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// 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 std::sync::Arc;
+
+use codec::{Decode, Encode};
+use frame_support::pallet_prelude::*;
+use jsonrpsee::{
+    core::{async_trait, RpcResult},
+    proc_macros::rpc,
+    types::error::{CallError, ErrorObject},
+};
+use serde::{Deserialize, Serialize};
+use sp_api::ProvideRuntimeApi;
+use sp_blockchain::HeaderBackend;
+use sp_runtime::{generic::BlockId, traits::Block as BlockT};
+use std::{io::Write, path::PathBuf};
+
+pub use pallet_distance_rpc_runtime_api::{ComputationResult, DistanceApi as DistanceRuntimeApi};
+
+#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct ComputationMetadata /*<Hash>*/ {
+    //pub block_hash: Hash,
+}
+
+impl From<pallet_distance_rpc_runtime_api::ComputationMetadata> for ComputationMetadata {
+    fn from(_val: pallet_distance_rpc_runtime_api::ComputationMetadata) -> Self {
+        Self {}
+    }
+}
+
+/*#[derive(Clone, Serialize, Deserialize)]
+pub struct ComputationResult {
+
+}
+
+impl Into<pallet_distance_rpc_runtime_api::ComputationResult> for ComputationResult {
+    fn into(self) -> pallet_distance_rpc_runtime_api::ComputationResult {
+        pallet_distance_rpc_runtime_api::ComputationResult{}
+    }
+}*/
+
+#[rpc(client, server)]
+pub trait DistanceApi<BlockHash, ResponseType> {
+    #[method(name = "distance_getComputationMetadata")]
+    fn get_computation_metadata(
+        &self,
+        at: Option<BlockHash>,
+    ) -> RpcResult<Option<ComputationMetadata>>;
+    #[method(name = "distance_publishComputationResult")]
+    fn publish_computation_result(
+        &self,
+        encoded_computation_result: String, //Bytes,
+                                            /*at: Option<BlockHash>,*/
+    ) -> RpcResult<ResponseType>;
+}
+
+/// Provides RPC methods to query a dispatchable's class, weight and fee.
+pub struct Distance<C, P> {
+    /// Shared reference to the client.
+    client: Arc<C>,
+    computation_result_dir: PathBuf,
+    _marker: std::marker::PhantomData<P>,
+}
+
+impl<C, P> Distance<C, P> {
+    /// Creates a new instance of the Distance Rpc helper.
+    pub fn new(client: Arc<C>, computation_result_dir: PathBuf) -> Self {
+        Self {
+            client,
+            computation_result_dir,
+            _marker: Default::default(),
+        }
+    }
+}
+
+/// Error type of this RPC api.
+pub enum Error {
+    /// The transaction was not decodable.
+    DecodeError,
+    /// The call to runtime failed.
+    RuntimeError,
+}
+
+impl From<Error> for i32 {
+    fn from(e: Error) -> i32 {
+        match e {
+            Error::RuntimeError => 1,
+            Error::DecodeError => 2,
+        }
+    }
+}
+
+#[async_trait]
+impl<C, Block, IdtyIndex: 'static + Decode + Encode + PartialEq + Send + Sync + TypeInfo>
+    DistanceApiServer<<Block as BlockT>::Hash, ()> for Distance<C, (Block, IdtyIndex)>
+where
+    Block: BlockT,
+    C: ProvideRuntimeApi<Block> + HeaderBackend<Block> + Send + Sync + 'static,
+    C::Api: DistanceRuntimeApi<Block, IdtyIndex>,
+{
+    fn get_computation_metadata(
+        &self,
+        at: Option<Block::Hash>,
+    ) -> RpcResult<Option<ComputationMetadata>> {
+        let api = self.client.runtime_api();
+        let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));
+
+        api.get_computation_metadata(&at).map_or_else(
+            |e| {
+                Err(CallError::Custom(ErrorObject::owned(
+                    Error::RuntimeError.into(),
+                    "Unable to query dispatch info.",
+                    Some(e.to_string()),
+                ))
+                .into())
+            },
+            |v| Ok(v.map(Into::into)),
+        )
+    }
+    fn publish_computation_result(
+        &self,
+        encoded_computation_result: String, //Bytes,
+                                            /*at: Option<Block::Hash>,*/
+    ) -> RpcResult<()> {
+        //let api = self.client.runtime_api();
+        //let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));
+
+        let encoded_computation_result =
+            base64::decode(encoded_computation_result).map_err(|e| {
+                CallError::Custom(ErrorObject::owned(
+                    Error::DecodeError.into(),
+                    "Bad encoding.",
+                    Some(format!("{:?}", e)),
+                ))
+            })?;
+
+        let computation_result: ComputationResult =
+            Decode::decode(&mut &*encoded_computation_result).map_err(|e| {
+                CallError::Custom(ErrorObject::owned(
+                    Error::DecodeError.into(),
+                    "Unable to query dispatch info.",
+                    Some(format!("{:?}", e)),
+                ))
+            })?;
+        /*api.publish_computation_result(&at, computation_result)
+        .map_err(|e| {
+            CallError::Custom(ErrorObject::owned(
+                Error::RuntimeError.into(),
+                "Unable to query dispatch info.",
+                Some(e.to_string()),
+            ))
+            .into()
+        })?;*/
+        std::fs::create_dir_all(&self.computation_result_dir)?;
+        let mut file = std::fs::File::create(self.computation_result_dir.join("result"))?;
+        file.write(&Encode::encode(&computation_result))?;
+
+        Ok(())
+
+        //sp_distance::InherentDataProvider::from_computation_result(computation_result);
+        //todo!()
+    }
+}
diff --git a/pallets/distance/src/lib.rs b/pallets/distance/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e57056d98ccc488fcf4ea1f668e4cc11ec7ebd0f
--- /dev/null
+++ b/pallets/distance/src/lib.rs
@@ -0,0 +1,353 @@
+// Copyright 2022 Axiom-Team
+//
+// This file is part of Duniter-v2S.
+//
+// Duniter-v2S is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, version 3 of the License.
+//
+// Duniter-v2S is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+mod median;
+mod types;
+
+use median::*;
+pub use pallet::*;
+pub use types::*;
+
+use frame_support::traits::StorageVersion;
+use pallet_authority_members::SessionIndex;
+use sp_distance::{InherentError, INHERENT_IDENTIFIER};
+use sp_inherents::{InherentData, InherentIdentifier};
+use sp_std::convert::TryInto;
+
+type IdtyIndex = u32;
+
+#[frame_support::pallet]
+pub mod pallet {
+    use super::*;
+    use frame_support::pallet_prelude::*;
+    use frame_system::pallet_prelude::*;
+    use sp_runtime::Perbill;
+
+    /// The current storage version.
+    const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
+
+    #[pallet::pallet]
+    #[pallet::generate_store(pub(super) trait Store)]
+    #[pallet::storage_version(STORAGE_VERSION)]
+    #[pallet::without_storage_info]
+    pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);
+    #[pallet::config]
+    pub trait Config<I: 'static = ()>:
+        frame_system::Config
+        + pallet_authorship::Config
+        + pallet_certification::Config<I, IdtyIndex = IdtyIndex>
+        + pallet_identity::Config<IdtyIndex = IdtyIndex>
+        + pallet_session::Config
+    {
+        /// Number of sessions before starting a new computation
+        type FinalityLag: Get<u32>;
+        /// Duration of a computation (in sessions)
+        type ComputationMaxDelay: Get<u32>;
+        // /// Maximum number of identities in the evaluation queue
+        //type QueueSize: Get<Option<u32>>;
+        /// Maximum number of identities to be evaluated in a session
+        type MaxEvaluationsPerSession: Get<u32>;
+        /// Maximum number of evaluators in a session
+        type MaxEvaluatorsPerSession: Get<u32>;
+        /// Minimum ratio of accessible referees
+        type MinAccessibleReferees: Get<Perbill>;
+    }
+
+    // STORAGE //
+
+    /*#[pallet::storage]
+    pub type NextComputationMetadata<T: Config<I>, I: 'static = ()> = StorageValue<
+        _,
+        ComputationMetadata,
+        OptionQuery,
+        GetDefault,
+    >;*/
+
+    /*/// Identities to be evaluated in next sessions
+    #[pallet::storage]
+    pub type EvaluationQueue<T: Config<I>, I: 'static = ()> = StorageValue<
+        _,
+        BoundedVec<<T as pallet_certification::Config<I>>::IdtyIndex, T::MaxEvaluationsPerSession>,
+        ValueQuery,
+    >;*/
+
+    /*#[pallet::storage]
+    pub type IdentitiesBeingEvaluated<T: Config<I>, I: 'static = ()> =
+        StorageValue<_, Vec<<T as pallet_certification::Config<I>>::IdtyIndex>, OptionQuery>;*/
+
+    // /// Number of evaluators coming up with some value.
+    // /// Indexed by identity index, then by value.
+    //#[pallet::storage]
+    /*pub type EvaluatedIdentities<T: Config<I>, I: 'static = ()> = StorageMap<
+        _,
+        Twox64Concat,
+        <T as pallet_certification::Config<I>>::IdtyIndex,
+        MedianAcc<Perbill>,
+        OptionQuery,
+        GetDefault,
+    >;*/
+    /*pub type StoragePublishedResults<T: Config<I>, I: 'static = ()> = StorageValue<
+        _,
+        //PublishedResults<<T as pallet_certification::Config<I>>::IdtyIndex, T::MaxEvaluationsPerSession, T::MaxEvaluatorsPerSession>,
+        (
+            BoundedVec<
+                (
+                    <T as pallet_certification::Config<I>>::IdtyIndex,
+                    MedianAcc<Perbill>,
+                ),
+                T::MaxEvaluationsPerSession,
+            >,
+            BoundedVec<T::AccountId, T::MaxEvaluatorsPerSession>,
+        ),
+        ValueQuery,
+    >;*/
+    // TODO 3 storages qu'on lit en fonction de session index % 3
+
+    /*/// Number of evaluators coming up with some referee count, indexed by referee count.
+    #[pallet::storage]
+    pub type Referees<T: Config<I>, I: 'static = ()> = StorageValue<_, MedianAcc<u32>, OptionQuery>;*/
+
+    #[pallet::storage]
+    pub type EvaluationPool0<T: Config<I>, I: 'static = ()> = StorageValue<
+        _,
+        (
+            BoundedVec<
+                (
+                    <T as pallet_certification::Config<I>>::IdtyIndex,
+                    MedianAcc<Perbill>,
+                ),
+                T::MaxEvaluationsPerSession,
+            >,
+            BoundedVec<T::AccountId, T::MaxEvaluatorsPerSession>,
+        ),
+        ValueQuery,
+    >;
+    #[pallet::storage]
+    pub type EvaluationPool1<T: Config<I>, I: 'static = ()> = StorageValue<
+        _,
+        (
+            BoundedVec<
+                (
+                    <T as pallet_certification::Config<I>>::IdtyIndex,
+                    MedianAcc<Perbill>,
+                ),
+                T::MaxEvaluationsPerSession,
+            >,
+            BoundedVec<T::AccountId, T::MaxEvaluatorsPerSession>,
+        ),
+        ValueQuery,
+    >;
+    #[pallet::storage]
+    pub type EvaluationPool2<T: Config<I>, I: 'static = ()> = StorageValue<
+        _,
+        (
+            BoundedVec<
+                (
+                    <T as pallet_certification::Config<I>>::IdtyIndex,
+                    MedianAcc<Perbill>,
+                ),
+                T::MaxEvaluationsPerSession,
+            >,
+            BoundedVec<T::AccountId, T::MaxEvaluatorsPerSession>,
+        ),
+        ValueQuery,
+    >;
+
+    // session_index % 3:
+    // 0 =>
+    // 1 =>
+    // 2 =>
+
+    #[pallet::error]
+    pub enum Error<T, I = ()> {
+        IdentityNotInEvaluation,
+        IdtyNotFound,
+        NonEligibleForEvaluation,
+        QueueFull,
+        TooManyEvaluators,
+        UnauthorizedIdentity,
+        WrongResultLength,
+    }
+
+    #[pallet::hooks]
+    impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {}
+
+    // CALLS //
+
+    #[pallet::call]
+    impl<T: Config<I>, I: 'static> Pallet<T, I> {
+        #[pallet::weight(1_000_000_000)]
+        pub fn evaluate_distance(
+            origin: OriginFor<T>,
+            idty_index: <T as pallet_certification::Config<I>>::IdtyIndex,
+        ) -> DispatchResultWithPostInfo {
+            let _who = ensure_signed(origin)?;
+            // TODO check whether origin is authorized to request evaluation
+            // TODO (maybe) check whether identity is already in queue
+            // TODO sort queue chronologically
+
+            /*if let Some(queue_size) = <T as Config<I>>::QueueSize::get() {
+                ensure!(
+                    EvaluationQueue::<T, I>::count() < queue_size,
+                    Error::<T, I>::QueueFull
+                );
+            }*/
+            ensure!(
+                EvaluationQueue::<T, I>::get().len()
+                    < <T as Config<I>>::MaxEvaluationsPerSession::get() as usize,
+                Error::<T, I>::QueueFull
+            );
+
+            ensure!(
+                pallet_identity::Identities::<T>::contains_key(idty_index),
+                Error::<T, I>::IdtyNotFound
+            );
+
+            EvaluationQueue::<T, I>::get()
+                .try_push(idty_index)
+                .map_err(|_| Error::<T, I>::QueueFull)?;
+
+            Ok(().into())
+        }
+
+        #[pallet::weight(1_000_000_000)]
+        pub fn update_evaluation(
+            origin: OriginFor<T>,
+            computation_result: ComputationResult, /*<<T as pallet_identity::Config>::IdtyIndex>*/
+        ) -> DispatchResult {
+            ensure_none(origin)?;
+            //assert!(!DidUpdate::<T>::exists(), "At most one distance computation result can be submitted per block");
+
+            ensure!(
+                computation_result.distances.len()
+                    == StoragePublishedResults::<T, I>::get().0.len(),
+                Error::<T, I>::WrongResultLength
+            );
+
+            StoragePublishedResults::<T, I>::get()
+                .1
+                .try_push(
+                    pallet_authorship::Pallet::<T>::author()
+                        .expect("Block author is needed to update distance evaluation"),
+                )
+                .map_err(|_| Error::<T, I>::TooManyEvaluators)?;
+
+            for (distance_value, (_identity, median_acc)) in computation_result
+                .distances
+                .into_iter()
+                .zip(StoragePublishedResults::<T, I>::get().0.iter_mut())
+            {
+                median_acc.push(distance_value);
+                /*try_mutate::<_, _, Error<T, I>, _>(
+                    identity,
+                    |median_acc| {
+                        median_acc
+                            .as_mut()
+                            .ok_or(Error::<T, I>::IdentityNotInEvaluation)?
+                            .push(result);
+                        Ok(())
+                    },
+                )?;*/
+            }
+
+            Ok(())
+        }
+    }
+
+    // PUBLIC FUNCTIONS //
+
+    impl<T: Config<I>, I: 'static> Pallet<T, I> {
+        pub fn get_computation_metadata(
+        ) -> Option<ComputationMetadata /*<<T as frame_system::Config>::Hash>*/> {
+            None
+        }
+        /*pub fn publish_computation_result(
+            _computation_result: ComputationResult<<T as pallet_identity::Config>::IdtyIndex>,
+        ) {
+        }*/
+    }
+
+    // INTERNAL FUNCTIONS //
+
+    impl<T: Config<I>, I: 'static> Pallet<T, I> {}
+
+    impl<T: Config<I>, I: 'static> pallet_authority_members::OnNewSession for Pallet<T, I> {
+        fn on_new_session(index: SessionIndex) -> Weight {
+            // TODO roll between the 3 states simultaneously
+            match index % 3 {
+                0 => {
+                    /*EvaluationQueue::<T, I>::drain()
+                    .zip(0..<T as Config<I>>::MaxEvaluationsPerSession::get())
+                    .map(|((identity, _), _)| identity)
+                    .for_each(|identity| {
+                        EvaluatedIdentities::<T, I>::insert(identity, MedianAcc::new())
+                    });*/
+                    EvaluationQueue::<T, I>::get()
+                        .into_iter()
+                        .for_each(|identity| {
+                            StoragePublishedResults::<T, I>::get()
+                                .0
+                                .try_push((identity, MedianAcc::new()))
+                                .expect("unreachable")
+                        });
+                }
+                1 => {}
+                2 => {
+                    for (_identity, median_acc) in
+                        StoragePublishedResults::<T, I>::get().0.into_iter()
+                    {
+                        if let Some(median_result) = median_acc.get_median() {
+                            let median = match median_result {
+                                MedianResult::One(m) => m,
+                                MedianResult::Two(m1, m2) => m1 + (m2 - m1) / 2, // Avoid overflow (since max is 1)
+                            };
+                            if median >= T::MinAccessibleReferees::get() {
+                                todo!();
+                            } else {
+                                todo!();
+                            }
+                        }
+                    }
+                }
+                _ => unreachable!("index % 3 < 3"),
+            }
+            0
+        }
+    }
+
+    #[pallet::inherent]
+    impl<T: Config<I>, I: 'static> ProvideInherent for Pallet<T, I> {
+        type Call = Call<T, I>;
+        type Error = InherentError;
+
+        const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
+
+        fn create_inherent(data: &InherentData) -> Option<Self::Call> {
+            data.get_data::<ComputationResult/*<<T as pallet_identity::Config>::IdtyIndex>*/>(
+                &INHERENT_IDENTIFIER,
+            )
+            .expect("Distance inherent data not correctly encoded")
+            .map(|inherent_data| Call::update_evaluation {
+                computation_result: inherent_data,
+            })
+        }
+        fn is_inherent(call: &Self::Call) -> bool {
+            matches!(call, Self::Call::update_evaluation { .. })
+        }
+    }
+}
diff --git a/pallets/distance/src/median.rs b/pallets/distance/src/median.rs
new file mode 100644
index 0000000000000000000000000000000000000000..065efb3119377cea4906e86c45e176f56f1b1941
--- /dev/null
+++ b/pallets/distance/src/median.rs
@@ -0,0 +1,143 @@
+// Copyright 2022 Axiom-Team
+//
+// This file is part of Duniter-v2S.
+//
+// Duniter-v2S is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, version 3 of the License.
+//
+// Duniter-v2S is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
+
+use frame_support::pallet_prelude::*;
+use sp_std::{cmp::Ordering, vec::Vec};
+
+#[derive(Clone, Debug, Decode, Default, Encode, TypeInfo)]
+pub struct MedianAcc<T: Clone + Decode + Encode + Ord + TypeInfo> {
+    samples: Vec<(T, u32)>,
+    median_index: Option<u32>,
+    median_subindex: u32,
+}
+
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum MedianResult<T: Clone + Ord> {
+    One(T),
+    Two(T, T),
+}
+
+impl<T: Clone + Decode + Encode + Ord + TypeInfo> MedianAcc<T> {
+    pub fn new() -> Self {
+        Self {
+            samples: Vec::new(),
+            median_index: None,
+            median_subindex: 0,
+        }
+    }
+
+    pub fn push(&mut self, sample: T) {
+        if let Some(median_index) = &mut self.median_index {
+            match self
+                .samples
+                .binary_search_by_key(&sample, |(s, _n)| s.clone())
+            {
+                Ok(sample_index) => {
+                    self.samples.get_mut(sample_index).expect("unreachable").1 += 1;
+                    match (sample_index as u32).cmp(median_index) {
+                        Ordering::Greater => {
+                            if self.median_subindex
+                                == self
+                                    .samples
+                                    .get(*median_index as usize)
+                                    .expect("unreachable")
+                                    .1
+                                    * 2
+                                    - 1
+                            {
+                                self.median_subindex = 0;
+                                *median_index += 1;
+                            } else {
+                                self.median_subindex += 1;
+                            }
+                        }
+                        Ordering::Equal => {
+                            self.median_subindex += 1;
+                        }
+                        Ordering::Less => {
+                            if self.median_subindex == 0 {
+                                *median_index -= 1;
+                                self.median_subindex = self
+                                    .samples
+                                    .get(*median_index as usize)
+                                    .expect("unreachable")
+                                    .1
+                                    * 2
+                                    - 1;
+                            } else {
+                                self.median_subindex -= 1;
+                            }
+                        }
+                    }
+                }
+                Err(sample_index) => {
+                    self.samples.insert(sample_index, (sample, 1));
+                    if *median_index as usize >= sample_index {
+                        if self.median_subindex == 0 {
+                            self.median_subindex = self
+                                .samples
+                                .get(*median_index as usize)
+                                .expect("unreachable")
+                                .1
+                                * 2
+                                - 1;
+                        } else {
+                            self.median_subindex -= 1;
+                            *median_index += 1;
+                        }
+                    } else if self.median_subindex
+                        == self
+                            .samples
+                            .get(*median_index as usize)
+                            .expect("unreachable")
+                            .1
+                            * 2
+                            - 1
+                    {
+                        self.median_subindex = 0;
+                        *median_index += 1;
+                    } else {
+                        self.median_subindex += 1;
+                    }
+                }
+            }
+        } else {
+            self.samples.push((sample, 1));
+            self.median_index = Some(0);
+        }
+    }
+
+    pub fn get_median(&self) -> Option<MedianResult<T>> {
+        self.median_index.map(|median_index| {
+            let (median_sample, median_n) = self
+                .samples
+                .get(median_index as usize)
+                .expect("unreachable");
+            if self.median_subindex == median_n * 2 - 1 {
+                MedianResult::Two(
+                    median_sample.clone(),
+                    self.samples
+                        .get(median_index as usize + 1)
+                        .expect("unreachable")
+                        .0
+                        .clone(),
+                )
+            } else {
+                MedianResult::One(median_sample.clone())
+            }
+        })
+    }
+}
diff --git a/pallets/distance/src/types.rs b/pallets/distance/src/types.rs
new file mode 100644
index 0000000000000000000000000000000000000000..6eecd2513b6a6549ac2185d17bc3672ade37ade0
--- /dev/null
+++ b/pallets/distance/src/types.rs
@@ -0,0 +1,63 @@
+// Copyright 2022 Axiom-Team
+//
+// This file is part of Duniter-v2S.
+//
+// Duniter-v2S is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, version 3 of the License.
+//
+// Duniter-v2S is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
+
+//use crate::median::MedianAcc;
+
+pub use sp_distance::ComputationResult;
+
+use codec::{Decode, Encode};
+use frame_support::pallet_prelude::*;
+use sp_inherents::IsFatalError;
+//use sp_runtime::Perbill;
+//use sp_std::vec::Vec;
+
+#[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug, TypeInfo)]
+pub struct ComputationMetadata /*<Hash>*/ {
+    //pub block_hash: Hash,
+}
+
+// TODO solve this! -> MaxEncodedLen
+/*#[derive(Encode, Decode, TypeInfo)]
+pub struct PublishedResults<IdtyIndex, MaxEvaluationsPerSession, MaxEvaluatorsPerSession> {
+    pub distances: BoundedVec<
+        (
+            IdtyIndex,
+            MedianAcc<Perbill>,
+        ),
+        MaxEvaluationsPerSession,
+    >,
+    pub evaluators: BoundedVec<IdtyIndex, MaxEvaluatorsPerSession>,
+}
+
+impl<IdtyIndex, MaxEvaluationsPerSession, MaxEvaluatorsPerSession> Default for PublishedResults<IdtyIndex, MaxEvaluationsPerSession, MaxEvaluatorsPerSession> {
+    fn default() -> Self {
+        Self {
+            distances: Default::default(),
+            evaluators: Default::default(),
+        }
+    }
+}*/
+
+#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
+pub enum InherentError {
+    Foo,
+}
+
+impl IsFatalError for InherentError {
+    fn is_fatal_error(&self) -> bool {
+        false
+    }
+}
diff --git a/primitives/distance/Cargo.toml b/primitives/distance/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..87f11de280e47377de47fb04c52c172f1a73965a
--- /dev/null
+++ b/primitives/distance/Cargo.toml
@@ -0,0 +1,67 @@
+[package]
+authors = ['librelois <c@elo.tf>']
+description = 'primitives for pallet distance.'
+edition = "2021"
+homepage = 'https://duniter.org'
+license = 'AGPL-3.0'
+name = 'sp-distance'
+readme = 'README.md'
+repository = 'https://git.duniter.org/nodes/rust/duniter-v2s'
+version = '3.0.0'
+
+[features]
+default = ['std']
+std = [
+    'async-trait',
+    'codec/std',
+    'frame-support/std',
+    'serde',
+    'sp-inherents/std',
+    'sp-runtime/std',
+    'sp-std/std',
+    'thiserror'
+]
+try-runtime = ['frame-support/try-runtime']
+
+[dependencies]
+async-trait = { version = "0.1.50", optional = true }
+thiserror = { version = "1.0.30", optional = true }
+
+# substrate
+scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
+
+[dependencies.codec]
+default-features = false
+features = ['derive']
+package = 'parity-scale-codec'
+version = "3.1.5"
+
+[dependencies.frame-support]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.serde]
+version = "1.0.101"
+optional = true
+features = ["derive"]
+
+[dependencies.sp-inherents]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-runtime]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+[dependencies.sp-std]
+default-features = false
+git = 'https://github.com/duniter/substrate'
+branch = 'duniter-substrate-v0.9.26'
+
+### DOC ###
+
+[package.metadata.docs.rs]
+targets = ['x86_64-unknown-linux-gnu']
diff --git a/primitives/distance/src/lib.rs b/primitives/distance/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8feeec3a0bfc9ecba6924450b4a6248060734338
--- /dev/null
+++ b/primitives/distance/src/lib.rs
@@ -0,0 +1,126 @@
+// Copyright 2022 Axiom-Team
+//
+// This file is part of Duniter-v2S.
+//
+// Duniter-v2S is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, version 3 of the License.
+//
+// Duniter-v2S is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
+
+//! Defines types and traits for users of pallet distance.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(clippy::type_complexity)]
+
+use codec::{Decode, Encode};
+use frame_support::RuntimeDebug;
+use scale_info::TypeInfo;
+//#[cfg(feature = "std")]
+//use serde::{Deserialize, Serialize};
+use sp_inherents::{InherentData, InherentIdentifier, IsFatalError};
+use sp_runtime::Perbill;
+use sp_std::vec::Vec;
+#[cfg(feature = "std")]
+use std::{marker::PhantomData, path::PathBuf};
+
+pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"distanc0";
+
+#[derive(Clone, Decode, Encode, PartialEq, RuntimeDebug, TypeInfo)]
+pub struct ComputationResult /*<IdtyIndex: Decode + Encode + PartialEq + TypeInfo>*/ {
+    pub distances: Vec<Perbill>,
+}
+
+/*pub enum Event<IdtyId, MetaData = ()> {
+}*/
+
+#[derive(Encode, sp_runtime::RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Decode, thiserror::Error))]
+pub enum InherentError {
+    #[cfg_attr(feature = "std", error("InvalidComputationResultFile"))]
+    InvalidComputationResultFile,
+}
+
+impl IsFatalError for InherentError {
+    fn is_fatal_error(&self) -> bool {
+        match self {
+            InherentError::InvalidComputationResultFile => false,
+        }
+    }
+}
+
+impl InherentError {
+    #[cfg(feature = "std")]
+    pub fn try_from(id: &InherentIdentifier, mut data: &[u8]) -> Option<Self> {
+        if id == &INHERENT_IDENTIFIER {
+            <InherentError as codec::Decode>::decode(&mut data).ok()
+        } else {
+            None
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+pub struct InherentDataProvider<IdtyIndex: Decode + Encode + PartialEq + TypeInfo> {
+    //computation_result: ComputationResult<IdtyIndex>,
+    computation_result_dir: PathBuf,
+    //result_expected_for_round: Option<u32>, // TODO (None => soit 2 premiers rounds, soit déjà publié)
+    _p: PhantomData<IdtyIndex>,
+}
+
+#[cfg(feature = "std")]
+impl<IdtyIndex: Decode + Encode + PartialEq + TypeInfo> InherentDataProvider<IdtyIndex> {
+    /*pub fn from_computation_result(computation_result: ComputationResult<IdtyIndex>, computation_result_dir: PathBuf) -> Self {
+        Self { computation_result, computation_result_dir }
+    }*/
+    pub fn new(computation_result_dir: PathBuf) -> Self {
+        Self {
+            computation_result_dir,
+            _p: PhantomData,
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+#[async_trait::async_trait]
+impl<IdtyIndex: Decode + Encode + PartialEq + TypeInfo + Send + Sync>
+    sp_inherents::InherentDataProvider for InherentDataProvider<IdtyIndex>
+{
+    fn provide_inherent_data(
+        &self,
+        inherent_data: &mut InherentData,
+    ) -> Result<(), sp_inherents::Error> {
+        // TODO check whether to do something: check if round corresponds between file and self.expected_round
+
+        // TODO match error
+        if let Ok(file) = std::fs::File::open(self.computation_result_dir.join("result")) {
+            let mut reader = codec::IoReader(file);
+            // TODO remove unwrap
+            inherent_data.put_data(
+                INHERENT_IDENTIFIER,
+                &ComputationResult::decode(&mut reader).unwrap(),
+            )?;
+        }
+        Ok(())
+    }
+
+    async fn try_handle_error(
+        &self,
+        identifier: &InherentIdentifier,
+        error: &[u8],
+    ) -> Option<Result<(), sp_inherents::Error>> {
+        if *identifier != INHERENT_IDENTIFIER {
+            return None;
+        }
+
+        match InherentError::try_from(&INHERENT_IDENTIFIER, error)? {
+            o => Some(Err(sp_inherents::Error::Application(Box::from(o)))),
+        }
+    }
+}
diff --git a/resources/metadata.scale b/resources/metadata.scale
index ff4c1c40a4d58bf8b3d8dc74373830583ef1ddbb..0b6f620736c233764ab5453fc420a8f6b522b4d5 100644
Binary files a/resources/metadata.scale and b/resources/metadata.scale differ
diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml
index a4685b21bdeb8eefd696b83106d3ad4beb53afd9..2adb84d554483e5ff406f0aa344b4ce79274e6fb 100644
--- a/runtime/common/Cargo.toml
+++ b/runtime/common/Cargo.toml
@@ -33,6 +33,8 @@ std = [
     'pallet-babe/std',
     'pallet-balances/std',
     'pallet-certification/std',
+    'pallet-distance/std',
+    'pallet-distance-rpc-runtime-api/std',
     'pallet-duniter-account/std',
     'pallet-duniter-wot/std',
     'pallet-grandpa/std',
@@ -50,6 +52,7 @@ std = [
 	"serde_derive",
     'sp-arithmetic/std',
     'sp-core/std',
+    'sp-distance/std',
     'sp-membership/std',
     'sp-runtime/std',
     'sp-std/std',
@@ -65,6 +68,8 @@ try-runtime = [
 duniter-primitives = { path = '../../primitives/duniter', default-features = false }
 pallet-authority-members = { path = '../../pallets/authority-members', default-features = false }
 pallet-certification = { path = '../../pallets/certification', default-features = false }
+pallet-distance = { path = "../../pallets/distance", default-features = false }
+pallet-distance-rpc-runtime-api = { path = "../../pallets/distance/rpc/runtime-api", default-features = false }
 pallet-duniter-account = { path = '../../pallets/duniter-account', default-features = false }
 pallet-duniter-wot = { path = '../../pallets/duniter-wot', default-features = false }
 pallet-identity = { path = '../../pallets/identity', default-features = false }
@@ -73,6 +78,7 @@ pallet-oneshot-account = { path = '../../pallets/oneshot-account', default-featu
 pallet-provide-randomness = { path = '../../pallets/provide-randomness', default-features = false }
 pallet-upgrade-origin = { path = '../../pallets/upgrade-origin', default-features = false }
 pallet-universal-dividend = { path = '../../pallets/universal-dividend', default-features = false }
+sp-distance = { path = '../../primitives/distance', default-features = false }
 sp-membership = { path = '../../primitives/membership', default-features = false }
 
 # Crates.io
diff --git a/runtime/common/src/apis.rs b/runtime/common/src/apis.rs
index dcd38e6e10ea4dccbea315532a2763c162757144..de510f739b751ba2313f26a837f9802a807f1d5c 100644
--- a/runtime/common/src/apis.rs
+++ b/runtime/common/src/apis.rs
@@ -208,6 +208,14 @@ macro_rules! runtime_apis {
                     TransactionPayment::query_fee_details(uxt, len)
                 }
             }
+            impl pallet_distance_rpc_runtime_api::DistanceApi<Block, u32> for Runtime {
+                fn get_computation_metadata() -> Option<pallet_distance_rpc_runtime_api::ComputationMetadata/*<<T as frame_system::Config>::Hash>*/> {
+                    Distance::get_computation_metadata()
+                }
+                /*fn publish_computation_result(computation_result: pallet_distance_rpc_runtime_api::ComputationResult<u32>) {
+                    //Distance::publish_computation_result(computation_result)
+                }*/
+            }
 
             #[cfg(feature = "try-runtime")]
             impl frame_try_runtime::TryRuntime<Block> for Runtime {
diff --git a/runtime/common/src/handlers.rs b/runtime/common/src/handlers.rs
index e09b1d30fd008f604e4834e9f4b8a0c3531be31a..edf25c2943f4c2037572e45cd95c1334bc535f08 100644
--- a/runtime/common/src/handlers.rs
+++ b/runtime/common/src/handlers.rs
@@ -27,11 +27,11 @@ use sp_runtime::traits::IsMember;
 pub struct OnNewSessionHandler<Runtime>(core::marker::PhantomData<Runtime>);
 impl<Runtime> pallet_authority_members::traits::OnNewSession for OnNewSessionHandler<Runtime>
 where
-    Runtime: pallet_provide_randomness::Config,
+    Runtime: pallet_provide_randomness::Config + pallet_distance::Config<Instance1>,
 {
-    fn on_new_session(_index: sp_staking::SessionIndex) -> Weight {
+    fn on_new_session(index: sp_staking::SessionIndex) -> Weight {
         pallet_provide_randomness::Pallet::<Runtime>::on_new_epoch();
-        0
+        pallet_distance::Pallet::<Runtime, Instance1>::on_new_session(index)
     }
 }
 
diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs
index 974db7fa974d19b6e7eed3bec498457852222a02..eb3fb4222825c149375d412ef6f91e426a743aed 100644
--- a/runtime/common/src/pallets_config.rs
+++ b/runtime/common/src/pallets_config.rs
@@ -466,6 +466,18 @@ macro_rules! pallets_config {
             type OnRemovedCert = Wot;
             type ValidityPeriod = ValidityPeriod;
         }
+        parameter_types! {
+            pub const MinAccessibleReferees: Perbill = Perbill::from_percent(80);
+        }
+        impl pallet_distance::Config<Instance1> for Runtime {
+            //type IdtyIndex: IdtyIndex;
+            type FinalityLag = frame_support::traits::ConstU32<1>;
+            type ComputationMaxDelay = frame_support::traits::ConstU32<1>;
+            //type QueueSize = frame_support::traits::ConstU32<800>;
+            type MaxEvaluationsPerSession = frame_support::traits::ConstU32<100>;
+            type MaxEvaluatorsPerSession = frame_support::traits::ConstU32<100>;// TODO <= number of blocks per session
+            type MinAccessibleReferees = MinAccessibleReferees;
+        }
 
         // SMITHS SUB-WOT //
 
diff --git a/runtime/gdev/Cargo.toml b/runtime/gdev/Cargo.toml
index 65d3ec9afbf49d90c96ddf69b9189a25d293207c..d01c15dd7f667fbafdc54596ff20d1be2d56c9c4 100644
--- a/runtime/gdev/Cargo.toml
+++ b/runtime/gdev/Cargo.toml
@@ -63,6 +63,8 @@ std = [
     'pallet-balances/std',
     'pallet-certification/std',
     'pallet-collective/std',
+    'pallet-distance/std',
+    'pallet-distance-rpc-runtime-api/std',
     'pallet-duniter-test-parameters/std',
     'pallet-duniter-account/std',
     'pallet-duniter-wot/std',
@@ -94,6 +96,7 @@ std = [
     'sp-block-builder/std',
     'sp-consensus-babe/std',
     'sp-core/std',
+    'sp-distance/std',
     'sp-inherents/std',
     'sp-offchain/std',
     'sp-membership/std',
@@ -136,6 +139,8 @@ sp-keyring = { git = 'https://github.com/duniter/substrate', branch = 'duniter-s
 common-runtime = { path = "../common", default-features = false }
 pallet-authority-members = { path = '../../pallets/authority-members', default-features = false }
 pallet-certification = { path = '../../pallets/certification', default-features = false }
+pallet-distance = { path = "../../pallets/distance", default-features = false }
+pallet-distance-rpc-runtime-api = { path = "../../pallets/distance/rpc/runtime-api", default-features = false }
 pallet-duniter-test-parameters = { path = '../../pallets/duniter-test-parameters', default-features = false }
 pallet-duniter-account = { path = '../../pallets/duniter-account', default-features = false }
 pallet-duniter-wot = { path = '../../pallets/duniter-wot', default-features = false }
@@ -145,6 +150,7 @@ pallet-oneshot-account = { path = '../../pallets/oneshot-account', default-featu
 pallet-provide-randomness = { path = '../../pallets/provide-randomness', default-features = false }
 pallet-universal-dividend = { path = '../../pallets/universal-dividend', default-features = false }
 pallet-upgrade-origin = { path = '../../pallets/upgrade-origin', default-features = false }
+sp-distance = { path = '../../primitives/distance', default-features = false }
 sp-membership = { path = '../../primitives/membership', default-features = false }
 
 # crates.io
diff --git a/runtime/gdev/src/lib.rs b/runtime/gdev/src/lib.rs
index 33e172eb2b0e88afb816ec25a07d95d32ff5dbb1..8e927c407ba0dd97db81113348fe009201fe01d5 100644
--- a/runtime/gdev/src/lib.rs
+++ b/runtime/gdev/src/lib.rs
@@ -313,6 +313,7 @@ construct_runtime!(
         Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>} = 41,
         Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 42,
         Cert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 43,
+        Distance: pallet_distance::<Instance1>::{Pallet, Call, Storage} = 44,
 
         // Smiths Sub-Wot
         SmithsSubWot: pallet_duniter_wot::<Instance2>::{Pallet} = 50,