diff --git a/Cargo.lock b/Cargo.lock
index 6aaa53b4a3f149b50199f4402d00354e29381baf..a1bb5e00f6673d11ae1ad07dc71a151e605919a9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -217,6 +217,7 @@ dependencies = [
  "duniter-crypto 0.1.2",
  "duniter-message 0.1.0",
  "duniter-module 0.1.0",
+ "duniter-network 0.1.0",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -224,6 +225,7 @@ dependencies = [
  "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "simplelog 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "sqlite 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -369,7 +371,6 @@ dependencies = [
 name = "durs"
 version = "0.1.0"
 dependencies = [
- "duniter-conf 0.1.0",
  "duniter-core 0.1.0",
  "duniter-tui 0.1.0",
  "duniter-ws2p 0.1.0",
@@ -484,6 +485,17 @@ name = "libc"
 version = "0.2.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "libz-sys"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "linked-hash-map"
 version = "0.5.1"
@@ -1064,6 +1076,8 @@ dependencies = [
  "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1125,6 +1139,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
 "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
 "checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
+"checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16"
 "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e"
 "checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
 "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
diff --git a/Cargo.toml b/Cargo.toml
index 9674d5b625837386d3be78a46382d5f93dd7227c..3eecdcaed45e67aa65b3fbca4941d536e73be393 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,7 +6,6 @@ description = "DUniter-RS (durs) is a new implementation of Duniter protocol and
 license = "AGPL-3.0"
 
 [dependencies]
-duniter-conf = { path = "./conf" }
 duniter-core = { path = "./core" }
 duniter-tui = { path = "./tui", optional = true }
 duniter-ws2p = { path = "./ws2p" }
diff --git a/blockchain/dbex.rs b/blockchain/dbex.rs
index ebb8d5965553c17ec3f8beb66c8cb1180a104b50..8833738f3993a2946c23cfdf4551410098acbeda 100644
--- a/blockchain/dbex.rs
+++ b/blockchain/dbex.rs
@@ -28,7 +28,7 @@ pub enum DBExWotQuery {
     /// Ask distance of all members
     AllDistances(bool),
     /// Show members expire date
-    ExpireMembers(bool, bool),
+    ExpireMembers(bool),
     /// Show members list
     ListMembers(bool),
     /// Ask member datas
@@ -51,14 +51,14 @@ pub enum DBExQuery {
     TxQuery(DBExTxQuery),
 }
 
-pub fn dbex<DC: DuniterConf>(profile: &str, conf: &DC, query: &DBExQuery) {
+pub fn dbex<DC: DuniterConf>(profile: &str, conf: &DC, csv: bool, query: &DBExQuery) {
     match *query {
-        DBExQuery::WotQuery(ref wot_query) => dbex_wot(profile, conf, wot_query),
-        DBExQuery::TxQuery(ref tx_query) => dbex_tx(profile, conf, tx_query),
+        DBExQuery::WotQuery(ref wot_query) => dbex_wot(profile, conf, csv, wot_query),
+        DBExQuery::TxQuery(ref tx_query) => dbex_tx(profile, conf, csv, tx_query),
     }
 }
 
-pub fn dbex_tx<DC: DuniterConf>(profile: &str, conf: &DC, query: &DBExTxQuery) {
+pub fn dbex_tx<DC: DuniterConf>(profile: &str, conf: &DC, _csv: bool, query: &DBExTxQuery) {
     // Get db path
     let db_path = duniter_conf::get_blockchain_db_path(profile, &conf.currency());
 
@@ -114,7 +114,7 @@ pub fn dbex_tx<DC: DuniterConf>(profile: &str, conf: &DC, query: &DBExTxQuery) {
     );
 }
 
-pub fn dbex_wot<DC: DuniterConf>(profile: &str, conf: &DC, query: &DBExWotQuery) {
+pub fn dbex_wot<DC: DuniterConf>(profile: &str, conf: &DC, csv: bool, query: &DBExWotQuery) {
     // Get db path
     let db_path = duniter_conf::get_blockchain_db_path(profile, &conf.currency());
 
@@ -204,13 +204,17 @@ pub fn dbex_wot<DC: DuniterConf>(profile: &str, conf: &DC, query: &DBExWotQuery)
             for (wot_id, distance_datas) in distances_datas {
                 let distance_percent: f64 =
                     f64::from(distance_datas.success) / f64::from(distance_datas.sentries) * 100.0;
-                println!(
-                    "{} -> distance: {:.2}% ({}/{})",
-                    wot_uid_index[&wot_id],
-                    distance_percent,
-                    distance_datas.success,
-                    distance_datas.sentries
-                );
+                if csv {
+                    println!("{}, {}", wot_uid_index[&wot_id], distance_percent,);
+                } else {
+                    println!(
+                        "{} -> distance: {:.2}% ({}/{})",
+                        wot_uid_index[&wot_id],
+                        distance_percent,
+                        distance_datas.success,
+                        distance_datas.sentries
+                    );
+                }
             }
             println!(
                 "compute_distances_duration = {},{:03}.",
@@ -218,7 +222,7 @@ pub fn dbex_wot<DC: DuniterConf>(profile: &str, conf: &DC, query: &DBExWotQuery)
                 compute_distances_duration.subsec_nanos() / 1_000_000
             );
         }
-        DBExWotQuery::ExpireMembers(ref reverse, ref _csv) => {
+        DBExWotQuery::ExpireMembers(ref reverse) => {
             // Open blockchain database
             let blockchain_db = open_db::<LocalBlockchainV10Datas>(&db_path, "blockchain.db")
                 .expect("Fail to open blockchain db");
diff --git a/blockchain/lib.rs b/blockchain/lib.rs
index 49bb2e27088b9c6941a063b1773228b370163de6..a52ce9d8dbcc9f622503b52dfd9b429065b7f973 100644
--- a/blockchain/lib.rs
+++ b/blockchain/lib.rs
@@ -192,8 +192,8 @@ impl BlockchainModule {
         }
     }
     /// Databases explorer
-    pub fn dbex<DC: DuniterConf>(profile: &str, conf: &DC, req: &DBExQuery) {
-        dbex::dbex(profile, conf, req);
+    pub fn dbex<DC: DuniterConf>(profile: &str, conf: &DC, csv: bool, req: &DBExQuery) {
+        dbex::dbex(profile, conf, csv, req);
     }
     /// Synchronize blockchain from a duniter-ts database
     pub fn sync_ts<DC: DuniterConf>(
diff --git a/core/Cargo.toml b/core/Cargo.toml
index a748b2c0c33057fd6c478ef8b601f81ce2c3a8cb..1cfd1489f5cfb3774b4b2b4f5358c79bf592f58a 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -15,6 +15,7 @@ duniter-conf = { path = "../conf" }
 duniter-crypto = { path = "../crypto" }
 duniter-message =  { path = "../message" }
 duniter-module = { path = "../module" }
+duniter-network = { path = "../network" }
 lazy_static = "1.0.0"
 log = "0.4.1"
 rand = "0.4.2"
@@ -22,6 +23,7 @@ regex = "1.0.0"
 rust-crypto = "0.2.36"
 serde = "1.0.57"
 serde_derive = "1.0.57"
+serde_json = "1.0.20"
 simplelog = "0.5.2"
 sqlite = "0.23.9"
 threadpool = "1.7.1"
diff --git a/core/cli/en.yml b/core/cli/en.yml
index f48ad39c470a09614e91eb64a45e998c9a675193..56657e63a56d771b255a543f46bf2f10572e2e8d 100644
--- a/core/cli/en.yml
+++ b/core/cli/en.yml
@@ -27,6 +27,30 @@ subcommands:
         about: start duniter server
         version: "0.1.0"
         author: Elois L. <elois@duniter.org>
+    - sync:
+        about: synchronization from network
+        version: "0.1.0"
+        author: Elois L. <elois@duniter.org>
+        args:
+            - DOMAIN_OR_IP:
+                help: The domain name or ip address of the node from which to synchronize.
+                index: 1
+                required: true
+            - PORT:
+                help: The port number of the node from which to synchronize.
+                index: 2
+                required: true
+            - PATH:
+                help: The endpoint path of the node from which to synchronize.
+                index: 3
+            - cautious:
+                short: c
+                long: cautious
+                help: cautious mode (check all protocol rules, very slow)
+            - unsafe:
+                short: u
+                long: unsafe
+                help: unsafe mode (not check blocks inner hashs, very dangerous)
     - sync_ts:
         about: synchronization via a duniter-ts database
         version: "0.1.0"
diff --git a/core/lib.rs b/core/lib.rs
index f61af82f94a1c4a177467e160b68e951ae55009c..50cf7b326b3c8524dc915637e000b862ef2e6ed1 100644
--- a/core/lib.rs
+++ b/core/lib.rs
@@ -33,15 +33,18 @@ extern crate duniter_conf;
 extern crate duniter_crypto;
 extern crate duniter_message;
 extern crate duniter_module;
+extern crate duniter_network;
+extern crate serde_json;
 extern crate simplelog;
 extern crate sqlite;
 extern crate threadpool;
 
 use clap::{App, ArgMatches};
 use duniter_blockchain::{BlockchainModule, DBExQuery, DBExTxQuery, DBExWotQuery};
-use duniter_conf::{DuRsConf, DuniterKeyPairs};
+pub use duniter_conf::{DuRsConf, DuniterKeyPairs};
 use duniter_message::DuniterMessage;
 use duniter_module::*;
+use duniter_network::{NetworkModule, SyncEndpoint};
 use log::Level;
 use simplelog::*;
 use std::env;
@@ -52,27 +55,34 @@ use std::thread;
 use std::time::Duration;
 use threadpool::ThreadPool;
 
+#[derive(Debug, Clone)]
+/// User command
+pub enum UserCommand {
+    /// Start
+    Start(),
+    /// Sync (SyncEndpoint)
+    Sync(SyncEndpoint),
+    /// Other command
+    Other(),
+}
+
 #[derive(Debug)]
 /// Duniter Core Datas
 pub struct DuniterCore<DC: DuniterConf> {
     /// Does the entered command require to launch server ?
-    pub start: bool,
-    /// Software name
-    pub soft_name: &'static str,
-    /// Soft version
-    pub soft_version: &'static str,
-    /// User profile
-    pub profile: String,
+    pub user_command: UserCommand,
+    /// Software meta datas
+    pub soft_meta_datas: SoftwareMetaDatas<DC>,
     /// Keypairs
     pub keypairs: DuniterKeyPairs,
-    /// Duniter configuration
-    pub conf: DC,
     /// Run duration. Zero = infinite duration.
     pub run_duration_in_secs: u64,
     /// Sender channel of rooter thread
     pub rooter_sender: mpsc::Sender<RooterThreadMessage<DuniterMessage>>,
     ///  Count the number of plugged modules
     pub modules_count: usize,
+    ///  Count the number of plugged network modules
+    pub network_modules_count: usize,
     /// ThreadPool that execute plugged modules
     pub thread_pool: ThreadPool,
 }
@@ -115,16 +125,49 @@ impl DuniterCore<DuRsConf> {
         let (conf, keypairs) = duniter_conf::load_conf(profile.as_str());
         info!("Success to load global conf.");
 
+        // Define SoftwareMetaDatas
+        let soft_meta_datas = SoftwareMetaDatas {
+            soft_name,
+            soft_version,
+            profile: profile.clone(),
+            conf: conf.clone(),
+        };
+
         if let Some(_matches) = cli_args.subcommand_matches("start") {
             Some(start(
-                soft_name,
-                soft_version,
-                &profile,
+                soft_meta_datas,
                 keypairs,
-                conf,
                 run_duration_in_secs,
                 external_followers,
             ))
+        } else if let Some(matches) = cli_args.subcommand_matches("sync") {
+            let domain_or_ip = matches
+                .value_of("DOMAIN_OR_IP")
+                .expect("sync: you must enter a domain name or ip address !")
+                .to_string();
+            let port: u16 = matches
+                .value_of("PORT")
+                .expect("sync: you must enter a port number !")
+                .parse()
+                .expect("sync: port : you must enter an integer value !");
+            let path = if let Some(path) = matches.value_of("PATH") {
+                Some(path.to_string())
+            } else {
+                None
+            };
+            let sync_endpoint = SyncEndpoint {
+                domain_or_ip,
+                port,
+                path,
+                tls: false,
+            };
+            Some(sync(
+                soft_meta_datas,
+                keypairs,
+                sync_endpoint,
+                matches.is_present("cautious"),
+                !matches.is_present("unsafe"),
+            ))
         } else if let Some(matches) = cli_args.subcommand_matches("sync_ts") {
             let ts_profile = matches.value_of("TS_PROFILE").unwrap_or("duniter_default");
             sync_ts(
@@ -141,6 +184,7 @@ impl DuniterCore<DuRsConf> {
                 dbex(
                     profile.as_str(),
                     &conf,
+                    csv,
                     &DBExQuery::WotQuery(DBExWotQuery::AllDistances(
                         distances_matches.is_present("reverse"),
                     )),
@@ -150,6 +194,7 @@ impl DuniterCore<DuRsConf> {
                 dbex(
                     profile.as_str(),
                     &conf,
+                    csv,
                     &DBExQuery::WotQuery(DBExWotQuery::MemberDatas(String::from(uid))),
                 );
             } else if let Some(members_matches) = matches.subcommand_matches("members") {
@@ -157,15 +202,16 @@ impl DuniterCore<DuRsConf> {
                     dbex(
                         profile.as_str(),
                         &conf,
+                        csv,
                         &DBExQuery::WotQuery(DBExWotQuery::ExpireMembers(
                             members_matches.is_present("reverse"),
-                            csv,
                         )),
                     );
                 } else {
                     dbex(
                         profile.as_str(),
                         &conf,
+                        csv,
                         &DBExQuery::WotQuery(DBExWotQuery::ListMembers(
                             members_matches.is_present("reverse"),
                         )),
@@ -176,6 +222,7 @@ impl DuniterCore<DuRsConf> {
                 dbex(
                     &profile,
                     &conf,
+                    csv,
                     &DBExQuery::TxQuery(DBExTxQuery::Balance(String::from(address))),
                 );
             }
@@ -226,7 +273,10 @@ impl DuniterCore<DuRsConf> {
     }
     /// Start blockchain module
     pub fn start_blockchain(&self) {
-        if self.start {
+        if self.network_modules_count == 0 {
+            panic!("You must plug at least one network layer !");
+        }
+        if let UserCommand::Start() = self.user_command {
             thread::sleep(Duration::from_secs(2));
             // Create blockchain module channel
             let (blockchain_sender, blockchain_receiver): (
@@ -246,8 +296,8 @@ impl DuniterCore<DuRsConf> {
 
             // Instantiate blockchain module and load is conf
             let mut blockchain_module = BlockchainModule::load_blockchain_conf(
-                &self.profile,
-                &self.conf,
+                &self.soft_meta_datas.profile,
+                &self.soft_meta_datas.conf,
                 RequiredKeysContent::MemberKeyPair(None),
             );
             info!("Success to load Blockchain module.");
@@ -256,34 +306,67 @@ impl DuniterCore<DuRsConf> {
             blockchain_module.start_blockchain(&blockchain_receiver);
         }
     }
+    /// Plug a network module
+    pub fn plug_network<NM: NetworkModule<DuRsConf, DuniterMessage>>(&mut self) {
+        if let UserCommand::Start() = self.user_command {
+            self.network_modules_count += 1;
+            self.plug::<NM>();
+        } else if let UserCommand::Sync(ref sync_endpoint) = self.user_command {
+            self.network_modules_count += 1;
+            // Load module conf and keys
+            let (module_conf, required_keys) = self.load_module_conf_and_keys::<NM>();
+            // Start module in a new thread
+            let rooter_sender = self.rooter_sender.clone();
+            let soft_meta_datas = self.soft_meta_datas.clone();
+            let sync_endpoint = sync_endpoint.clone();
+            self.thread_pool.execute(move || {
+                NM::sync(
+                    &soft_meta_datas,
+                    required_keys,
+                    &module_conf,
+                    rooter_sender,
+                    sync_endpoint,
+                ).expect(&format!(
+                    "Fatal error : fail to load {} Module !",
+                    NM::id().to_string()
+                ));
+            });
+            self.modules_count += 1;
+            info!("Success to load {} module.", NM::id().to_string());
+        }
+    }
+    /// Load module conf and keys
+    pub fn load_module_conf_and_keys<M: DuniterModule<DuRsConf, DuniterMessage>>(
+        &self,
+    ) -> (serde_json::value::Value, RequiredKeysContent) {
+        let module_conf = if let Some(module_conf_) = self
+            .soft_meta_datas
+            .conf
+            .clone()
+            .modules()
+            .get(&M::id().to_string().as_str())
+        {
+            module_conf_.clone()
+        } else {
+            M::default_conf()
+        };
+        let required_keys =
+            DuniterKeyPairs::get_required_keys_content(M::ask_required_keys(), self.keypairs);
+
+        (module_conf, required_keys)
+    }
     /// Plug a module
     pub fn plug<M: DuniterModule<DuRsConf, DuniterMessage>>(&mut self) {
-        if self.start {
+        if let UserCommand::Start() = self.user_command {
+            // Load module conf and keys
+            let (module_conf, required_keys) = self.load_module_conf_and_keys::<M>();
             // Start module in a new thread
-            let soft_name_clone = &(*self.soft_name);
-            let soft_version_clone = &(*self.soft_version);
-            let required_keys =
-                DuniterKeyPairs::get_required_keys_content(M::ask_required_keys(), self.keypairs);
-            let module_conf = if let Some(module_conf_) = self
-                .conf
-                .clone()
-                .modules()
-                .get(&M::id().to_string().as_str())
-            {
-                module_conf_.clone()
-            } else {
-                M::default_conf()
-            };
             let rooter_sender_clone = self.rooter_sender.clone();
-            let conf_clone = self.conf.clone();
-            let profile_copy = self.profile.clone();
+            let soft_meta_datas = self.soft_meta_datas.clone();
             self.thread_pool.execute(move || {
                 M::start(
-                    soft_name_clone,
-                    soft_version_clone,
-                    &profile_copy,
+                    &soft_meta_datas,
                     required_keys,
-                    &conf_clone,
                     &module_conf,
                     rooter_sender_clone,
                     false,
@@ -303,18 +386,11 @@ pub fn match_profile(cli_args: &ArgMatches) -> String {
     String::from(cli_args.value_of("profile").unwrap_or("default"))
 }
 
-/// Launch duniter server
-pub fn start<DC: DuniterConf>(
-    soft_name: &'static str,
-    soft_version: &'static str,
-    profile: &str,
-    keypairs: DuniterKeyPairs,
-    conf: DC,
+/// Start rooter thread
+pub fn start_rooter<DC: DuniterConf>(
     run_duration_in_secs: u64,
     external_followers: Vec<mpsc::Sender<DuniterMessage>>,
-) -> DuniterCore<DC> {
-    info!("Starting Duniter-rs...");
-
+) -> mpsc::Sender<RooterThreadMessage<DuniterMessage>> {
     // Create senders channel
     let (rooter_sender, main_receiver): (
         mpsc::Sender<RooterThreadMessage<DuniterMessage>>,
@@ -408,17 +484,54 @@ pub fn start<DC: DuniterConf>(
         }
     });
 
+    rooter_sender
+}
+
+/// Launch duniter server
+pub fn start<DC: DuniterConf>(
+    soft_meta_datas: SoftwareMetaDatas<DC>,
+    keypairs: DuniterKeyPairs,
+    run_duration_in_secs: u64,
+    external_followers: Vec<mpsc::Sender<DuniterMessage>>,
+) -> DuniterCore<DC> {
+    info!("Starting Duniter-rs...");
+
+    // Start rooter thread
+    let rooter_sender = start_rooter::<DC>(run_duration_in_secs, external_followers);
+
     // Instanciate DuniterCore
     DuniterCore {
-        start: true,
-        soft_name,
-        soft_version,
-        profile: profile.to_string(),
+        user_command: UserCommand::Start(),
+        soft_meta_datas,
         keypairs,
-        conf,
         run_duration_in_secs,
         rooter_sender,
         modules_count: 0,
+        network_modules_count: 0,
+        thread_pool: ThreadPool::new(2),
+    }
+}
+
+/// Launch synchronisation from network
+pub fn sync<DC: DuniterConf>(
+    soft_meta_datas: SoftwareMetaDatas<DC>,
+    keypairs: DuniterKeyPairs,
+    sync_endpoint: SyncEndpoint,
+    _cautious: bool,
+    _verif_hashs: bool,
+) -> DuniterCore<DC> {
+    // Start rooter thread
+    let rooter_sender = start_rooter::<DC>(0, vec![]);
+
+    // Instanciate DuniterCore
+    DuniterCore {
+        user_command: UserCommand::Sync(sync_endpoint),
+        soft_meta_datas,
+        keypairs,
+        run_duration_in_secs: 0,
+        rooter_sender,
+        modules_count: 0,
+        network_modules_count: 0,
         thread_pool: ThreadPool::new(2),
     }
 }
@@ -436,9 +549,9 @@ pub fn sync_ts<DC: DuniterConf>(
 }
 
 /// Launch databases explorer
-pub fn dbex<DC: DuniterConf>(profile: &str, conf: &DC, query: &DBExQuery) {
+pub fn dbex<DC: DuniterConf>(profile: &str, conf: &DC, csv: bool, query: &DBExQuery) {
     // Launch databases explorer
-    BlockchainModule::dbex(profile, conf, query);
+    BlockchainModule::dbex(profile, conf, csv, query);
 }
 
 /// Initialize logger
diff --git a/module/lib.rs b/module/lib.rs
index 7707d3127cebf2484cedd1e1ee2e03599caf5be6..1bc026b423fd9d7c0b948d341044ac065bd1c932 100644
--- a/module/lib.rs
+++ b/module/lib.rs
@@ -128,6 +128,19 @@ pub trait DuniterConf: Clone + Debug + Default + PartialEq + Serialize + Deseria
     fn modules(&self) -> serde_json::Value;
 }
 
+/// Sofware meta datas
+#[derive(Debug, Clone)]
+pub struct SoftwareMetaDatas<DC: DuniterConf> {
+    /// Software name
+    pub soft_name: &'static str,
+    /// Software version
+    pub soft_version: &'static str,
+    /// User profile
+    pub profile: String,
+    /// User configuration
+    pub conf: DC,
+}
+
 /// The different modules of Duniter-rs can exchange messages with the type of their choice,
 /// provided that this type implements the ModuleMessage trait.
 pub trait ModuleMessage: Clone + Debug {}
@@ -203,11 +216,8 @@ pub trait DuniterModule<DC: DuniterConf, M: ModuleMessage> {
     fn default_conf() -> serde_json::Value;
     /// Launch the module
     fn start(
-        soft_name: &str,
-        soft_version: &str,
-        profile: &str,
+        soft_meta_datas: &SoftwareMetaDatas<DC>,
         keys: RequiredKeysContent,
-        conf: &DC,
         module_conf: &serde_json::Value,
         main_sender: mpsc::Sender<RooterThreadMessage<M>>,
         load_conf_only: bool,
diff --git a/network/lib.rs b/network/lib.rs
index 60478a07f67c1d716d5ab809a98484600791cf0b..a25307910c632fc655b52004d6b610258933e2e2 100644
--- a/network/lib.rs
+++ b/network/lib.rs
@@ -45,11 +45,37 @@ use duniter_documents::blockchain::v10::documents::{
 };
 use duniter_documents::blockchain::Document;
 use duniter_documents::{BlockHash, BlockId, Blockstamp, Hash};
-use duniter_module::{ModuleReqFullId, ModuleReqId};
+use duniter_module::*;
 use network_head::NetworkHead;
 use network_peer::NetworkPeer;
 use std::fmt::{Debug, Display, Error, Formatter};
 use std::ops::Deref;
+use std::sync::mpsc;
+
+/// NetworkModule
+pub trait NetworkModule<DC: DuniterConf, M: ModuleMessage>: DuniterModule<DC, M> {
+    /// Launch synchronisation
+    fn sync(
+        soft_meta_datas: &SoftwareMetaDatas<DC>,
+        keys: RequiredKeysContent,
+        module_conf: &serde_json::Value,
+        main_sender: mpsc::Sender<RooterThreadMessage<M>>,
+        sync_endpoint: SyncEndpoint,
+    ) -> Result<(), ModuleInitError>;
+}
+
+#[derive(Debug, Clone)]
+/// Synchronisation endpoint
+pub struct SyncEndpoint {
+    /// Domaine name or IP
+    pub domain_or_ip: String,
+    /// Port number
+    pub port: u16,
+    /// Optionnal path
+    pub path: Option<String>,
+    /// Use TLS
+    pub tls: bool,
+}
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 /// Random identifier with which several Duniter nodes with the same network keypair can be differentiated
diff --git a/src/main.rs b/src/main.rs
index 2c9748b753cca19bed36b90d3c2a173191380309..eacbede7127d6d3001943d637eac47312c4f8c02 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -21,13 +21,13 @@
     trivial_numeric_casts, unsafe_code, unstable_features, unused_import_braces,
     unused_qualifications
 )]
-extern crate duniter_conf;
+
 extern crate duniter_core;
 #[cfg(feature = "tui")]
 extern crate duniter_tui;
 extern crate duniter_ws2p;
 
-pub use duniter_conf::DuRsConf;
+pub use duniter_core::DuRsConf;
 pub use duniter_core::DuniterCore;
 #[cfg(feature = "tui")]
 pub use duniter_tui::TuiModule;
@@ -47,7 +47,7 @@ fn main() {
         //duniter_core.plug::<PoolModule>();
         //duniter_core.plug::<PowModule>();
         plug_tui_module(&mut duniter_core);
-        duniter_core.plug::<WS2PModule>();
+        duniter_core.plug_network::<WS2PModule>();
         duniter_core.start_blockchain();
     };
 }
diff --git a/tui/lib.rs b/tui/lib.rs
index 55028786e5443704466389bbab4b07d6b0506fce..3e877a8af94ebd3f586bab9df07b64db81b3466f 100644
--- a/tui/lib.rs
+++ b/tui/lib.rs
@@ -362,11 +362,8 @@ impl DuniterModule<DuRsConf, DuniterMessage> for TuiModule {
         serde_json::Value::default()
     }
     fn start(
-        _soft_name: &str,
-        _soft_version: &str,
-        _profile: &str,
+        _soft_meta_datas: &SoftwareMetaDatas<DuRsConf>,
         _keys: RequiredKeysContent,
-        _conf: &DuRsConf,
         module_conf: &serde_json::Value,
         main_sender: mpsc::Sender<RooterThreadMessage<DuniterMessage>>,
         load_conf_only: bool,
diff --git a/ws2p/Cargo.toml b/ws2p/Cargo.toml
index 2b4b0f4debae043a864f4cab75c1652ddbc8ce63..89d3ace4289a8c9dc78deb4d03639a25bb60f26f 100644
--- a/ws2p/Cargo.toml
+++ b/ws2p/Cargo.toml
@@ -26,7 +26,7 @@ sqlite = "0.23.9"
 serde = "1.0.24"
 serde_derive = "1.0.24"
 serde_json = "1.0.20"
-ws = "0.7.6"
+ws = { version = "0.7.6", features = ["permessage-deflate"] }
 
 [features]
 ssl = ["ws/ssl"]
diff --git a/ws2p/lib.rs b/ws2p/lib.rs
index 5a25d52b0e902eb6aed2987d246e87d22c84ff56..277934e848a7c82fa127f2a7b3ee8ba110a6e9c4 100644
--- a/ws2p/lib.rs
+++ b/ws2p/lib.rs
@@ -147,6 +147,20 @@ impl Default for WS2PModule {
     }
 }
 
+impl NetworkModule<DuRsConf, DuniterMessage> for WS2PModule {
+    fn sync(
+        _soft_meta_datas: &SoftwareMetaDatas<DuRsConf>,
+        _keys: RequiredKeysContent,
+        _module_conf: &serde_json::Value,
+        _main_sender: mpsc::Sender<RooterThreadMessage<DuniterMessage>>,
+        _sync_endpoint: SyncEndpoint,
+    ) -> Result<(), ModuleInitError> {
+        println!("Downlaod blockchain from network...");
+        println!("Error : not yet implemented !");
+        Ok(())
+    }
+}
+
 impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
     fn id() -> ModuleId {
         ModuleId(String::from("ws2p"))
@@ -169,11 +183,8 @@ impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
         })
     }
     fn start(
-        soft_name: &str,
-        soft_version: &str,
-        profile: &str,
+        soft_meta_datas: &SoftwareMetaDatas<DuRsConf>,
         keys: RequiredKeysContent,
-        duniter_conf: &DuRsConf,
         module_conf: &serde_json::Value,
         rooter_sender: mpsc::Sender<RooterThreadMessage<DuniterMessage>>,
         load_conf_only: bool,
@@ -198,7 +209,7 @@ impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
             RequiredKeysContent::NetworkKeyPair(key_pair) => key_pair,
             _ => panic!("WS2PModule fatal error at load_conf() : keys != NetworkKeyPair"),
         };
-        let conf = WS2PModuleDatas::parse_ws2p_conf(duniter_conf, module_conf);
+        let conf = WS2PModuleDatas::parse_ws2p_conf(&soft_meta_datas.conf, module_conf);
         let mut ws2p_endpoints = HashMap::new();
         for ep in conf.sync_endpoints.clone() {
             ws2p_endpoints.insert(
@@ -209,7 +220,7 @@ impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
             info!("Load sync endpoint {}", ep.raw());
         }
         ws2p_module.key_pair = Some(key_pair);
-        ws2p_module.currency = Some(duniter_conf.currency().to_string());
+        ws2p_module.currency = Some(soft_meta_datas.conf.currency().to_string());
         ws2p_module.conf = Some(conf.clone());
         ws2p_module.ws2p_endpoints = ws2p_endpoints;
 
@@ -248,7 +259,8 @@ impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
         });
 
         // open ws2p bdd
-        let mut db_path = duniter_conf::datas_path(profile, &duniter_conf.currency());
+        let mut db_path =
+            duniter_conf::datas_path(&soft_meta_datas.profile, &soft_meta_datas.conf.currency());
         db_path.push("ws2p.db");
         let db = WS2PModuleDatas::open_db(&db_path).expect("Fatal error : fail to open WS2P DB !");
 
@@ -315,8 +327,8 @@ impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
                                             ws2p_module.my_head = Some(heads::generate_my_head(
                                                 &key_pair,
                                                 &conf.clone(),
-                                                soft_name,
-                                                soft_version,
+                                                soft_meta_datas.soft_name,
+                                                soft_meta_datas.soft_version,
                                                 &current_blockstamp,
                                                 None,
                                             ));
@@ -401,8 +413,8 @@ impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
                                     ws2p_module.my_head = Some(heads::generate_my_head(
                                         &key_pair,
                                         &conf.clone(),
-                                        soft_name,
-                                        soft_version,
+                                        soft_meta_datas.soft_name,
+                                        soft_meta_datas.soft_version,
                                         &current_blockstamp,
                                         None,
                                     ));
@@ -454,8 +466,8 @@ impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
                                                     Some(heads::generate_my_head(
                                                         &key_pair,
                                                         &conf.clone(),
-                                                        soft_name,
-                                                        soft_version,
+                                                        soft_meta_datas.soft_name,
+                                                        soft_meta_datas.soft_version,
                                                         &current_blockstamp,
                                                         None,
                                                     ));
@@ -630,7 +642,10 @@ impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
                         WS2PSignal::ReqResponse(req_id, req, recipient_full_id, response) => {
                             match req {
                                 NetworkRequest::GetCurrent(ref _req_id, _receiver) => {
-                                    info!("WS2PSignal::ReceiveCurrent({}, {:?})", req_id.0, req);
+                                    info!(
+                                        "WS2PSignal::ReceiveCurrent({}, {:?}, {:#?})",
+                                        req_id.0, req, response
+                                    );
                                     if let Some(block) = parse_json_block(&response) {
                                         ws2p_module.send_network_event(&NetworkEvent::ReqResponse(
                                             Box::new(NetworkResponse::CurrentBlock(
diff --git a/ws2p/ws2p_connection.rs b/ws2p/ws2p_connection.rs
index 214ef3290051b81a56f39d3cc5cb787fc6ead58e..5c1be57d031e136b4a053ee8f4479d134e3ead45 100644
--- a/ws2p/ws2p_connection.rs
+++ b/ws2p/ws2p_connection.rs
@@ -6,6 +6,7 @@ use duniter_network::{NetworkDocument, NodeUUID};
 use parsers::blocks::parse_json_block;
 use rand::Rng;
 use std::sync::mpsc;
+use ws::deflate::DeflateBuilder;
 #[allow(deprecated)]
 use ws::util::{Timeout, Token};
 use ws::{connect, CloseCode, Frame, Handler, Handshake, Message, Sender};
@@ -617,17 +618,19 @@ pub fn connect_to_ws2p_endpoint(
     info!("Try connection to {} ...", ws_url);
 
     // Connect to websocket
-    connect(ws_url, |ws| Client {
-        ws,
-        conductor_sender: conductor_sender.clone(),
-        currency: String::from(currency),
-        key_pair,
-        connect_message: connect_message.clone(),
-        conn_meta_datas: conn_meta_datas.clone(),
-        last_mess_time: SystemTime::now(),
-        spam_interval: false,
-        spam_counter: 0,
-        timeout: None,
+    connect(ws_url, |ws| {
+        DeflateBuilder::new().build(Client {
+            ws,
+            conductor_sender: conductor_sender.clone(),
+            currency: String::from(currency),
+            key_pair,
+            connect_message: connect_message.clone(),
+            conn_meta_datas: conn_meta_datas.clone(),
+            last_mess_time: SystemTime::now(),
+            spam_interval: false,
+            spam_counter: 0,
+            timeout: None,
+        })
     })
 }