diff --git a/Cargo.lock b/Cargo.lock
index 335797456d9a61fea4f92e07c37f298968ed9c84..6eeadc52a097c357c09b4ec4b399027fc34b6c3d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -730,6 +730,27 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "duniter-dal"
+version = "0.1.0"
+dependencies = [
+ "bincode",
+ "crossbeam-utils",
+ "dubp-common",
+ "dubp-wot",
+ "duniter-dbs",
+ "flate2",
+ "log",
+ "mockall",
+ "once_cell",
+ "rusqlite",
+ "serde",
+ "serde_json",
+ "tempdir",
+ "thiserror",
+ "unwrap",
+]
+
 [[package]]
 name = "duniter-dbex"
 version = "0.1.0"
@@ -855,6 +876,18 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
 
+[[package]]
+name = "fallible-iterator"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
+
+[[package]]
+name = "fallible-streaming-iterator"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
+
 [[package]]
 name = "fastrand"
 version = "1.4.0"
@@ -1185,6 +1218,22 @@ version = "0.2.78"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "aa7087f49d294270db4e1928fc110c976cd4b9e5a16348e0a1df09afa99e6c98"
 
+[[package]]
+name = "libsqlite3-sys"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3a245984b1b06c291f46e27ebda9f369a94a1ab8461d0e845e23f9ced01f5db"
+dependencies = [
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "linked-hash-map"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
+
 [[package]]
 name = "lock_api"
 version = "0.3.4"
@@ -1218,6 +1267,15 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3d0925aed5b12ed59857f438d25a910cf051dbcd4107907be1e7abf6c44ec903"
 
+[[package]]
+name = "lru-cache"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
+dependencies = [
+ "linked-hash-map",
+]
+
 [[package]]
 name = "maplit"
 version = "1.0.2"
@@ -1624,6 +1682,12 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
+[[package]]
+name = "pkg-config"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33"
+
 [[package]]
 name = "plotters"
 version = "0.2.15"
@@ -1850,6 +1914,22 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "rusqlite"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c78c3275d9d6eb684d2db4b2388546b32fdae0586c20a82f3905d21ea78b9ef"
+dependencies = [
+ "bitflags",
+ "fallible-iterator",
+ "fallible-streaming-iterator",
+ "libsqlite3-sys",
+ "lru-cache",
+ "memchr",
+ "serde_json",
+ "smallvec",
+]
+
 [[package]]
 name = "rust-argon2"
 version = "0.8.2"
@@ -2266,6 +2346,12 @@ version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7e33648dd74328e622c7be51f3b40a303c63f93e6fa5f08778b6203a4c25c20f"
 
+[[package]]
+name = "vcpkg"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c"
+
 [[package]]
 name = "vec-arena"
 version = "1.0.0"
diff --git a/Cargo.toml b/Cargo.toml
index 90a051b9c4c06f1dd6f307707e18fe04c1974128..c25d4cb771f81d0a2f19d58dad93aeaf4f1a3cc1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -32,6 +32,7 @@ members = [
     "rust-bins/duniter-dbex",
     "rust-bins/xtask",
     "rust-libs/dubp-wot",
+    "rust-libs/duniter-dal",
     "rust-libs/duniter-dbs",
     "rust-libs/tools/kv_typed",
     "rust-libs/tools/kv_typed_code_gen"
diff --git a/rust-libs/duniter-dal/Cargo.toml b/rust-libs/duniter-dal/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..c2aaf99cad89820b9d14801f54557a84abfae4c6
--- /dev/null
+++ b/rust-libs/duniter-dal/Cargo.toml
@@ -0,0 +1,38 @@
+[package]
+name = "duniter-dal"
+version = "0.1.0"
+authors = ["elois <elois@duniter.org>"]
+description = "Duniter Data Access Layer"
+repository = "https://git.duniter.org/nodes/typescript/duniter"
+keywords = ["duniter"]
+license = "AGPL-3.0"
+edition = "2018"
+
+[lib]
+path = "src/lib.rs"
+
+[dependencies]
+bincode = "1.2.1"
+crossbeam-utils = "0.7.2"
+dubp-common = { version = "0.25.2", features = ["crypto_scrypt"] }
+dubp-wot = { path = "../dubp-wot" }
+duniter-dbs = { path = "../duniter-dbs" }
+flate2 = "1.0.16"
+log = "0.4.8"
+mockall = { version = "0.8.0", optional = true }
+rusqlite = { version = "0.25.2", features = ["serde_json"] }
+serde = { version = "1.0.105", features = ["derive"] }
+serde_json = "1.0.53"
+thiserror = "1.0.20"
+
+[dev-dependencies]
+once_cell = "1.4.0"
+tempdir = "0.3.7"
+unwrap = "1.2.1"
+
+[features]
+default = ["mock"]
+#default = ["test_real"]
+
+mock = ["duniter-dbs/mock", "mockall"]
+test_real = []
diff --git a/rust-libs/duniter-dal/src/conf_dbs.rs b/rust-libs/duniter-dal/src/conf_dbs.rs
new file mode 100644
index 0000000000000000000000000000000000000000..09020976b2a77480a525edb2a9d9137e419bb46a
--- /dev/null
+++ b/rust-libs/duniter-dal/src/conf_dbs.rs
@@ -0,0 +1,39 @@
+use crate::*;
+
+use duniter_dbs::kv_typed::backend::sled;
+
+pub trait GenBackendConf<B: Backend> {
+    fn gen_backend_conf(db_name: &'static str, data_path_opt: Option<&Path>) -> B::Conf;
+}
+
+impl GenBackendConf<Mem> for Mem {
+    #[inline(always)]
+    fn gen_backend_conf(_db_name: &'static str, _data_path_opt: Option<&Path>) -> MemConf {
+        MemConf::default()
+    }
+}
+
+impl GenBackendConf<Sled> for Sled {
+    #[inline(always)]
+    fn gen_backend_conf(db_name: &'static str, data_path_opt: Option<&Path>) -> sled::Config {
+        if let Some(data_path) = data_path_opt {
+            sled::Config::default().path(data_path.join(format!("{}_sled", db_name)))
+        } else {
+            sled::Config::default().temporary(true)
+        }
+    }
+}
+
+impl GenBackendConf<LevelDb> for LevelDb {
+    #[inline(always)]
+    fn gen_backend_conf(_db_name: &'static str, data_path_opt: Option<&Path>) -> LevelDbConf {
+        if let Some(data_path) = data_path_opt {
+            LevelDbConf {
+                db_path: data_path.join("leveldb"),
+                ..Default::default()
+            }
+        } else {
+            panic!("LevelDb backend not supported memory mode")
+        }
+    }
+}
diff --git a/rust-libs/duniter-dal/src/databases.rs b/rust-libs/duniter-dal/src/databases.rs
new file mode 100644
index 0000000000000000000000000000000000000000..68e759ec8701af6dceb381d4da63dde932600492
--- /dev/null
+++ b/rust-libs/duniter-dal/src/databases.rs
@@ -0,0 +1,131 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Duniter databases
+
+use crate::*;
+
+/// Blockchain database
+pub type BcDb<B> = BcV1Db<B>;
+
+/// Blockchain database on read-only mode
+pub type BcDbRo<B> = BcV1DbRo<B>;
+
+#[derive(Clone)]
+pub struct DatabasesRo<B: Backend> {
+    pub(crate) bc_db: BcDbRo<B>,
+    pub(crate) peers_db: Arc<rusqlite::Connection>,
+    pub(crate) txs_mp_db: Arc<rusqlite::Connection>,
+    pub(crate) wot_mp_db: Arc<rusqlite::Connection>,
+}
+
+impl<B: Backend> Debug for DatabasesRo<B> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "DatabasesRo {{ ... }}")
+    }
+}
+
+#[derive(Clone)]
+pub struct Databases<B: Backend> {
+    pub(crate) bc_db: BcDb<B>,
+    pub(crate) peers_db: Arc<rusqlite::Connection>,
+    pub(crate) txs_mp_db: Arc<rusqlite::Connection>,
+    pub(crate) wot_mp_db: Arc<rusqlite::Connection>,
+    ro: DatabasesRo<B>,
+}
+
+impl<B: Backend> Debug for Databases<B> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "Databases {{ ... }}")
+    }
+}
+
+impl<B: Backend> Databases<B> {
+    pub(crate) fn to_ro(&self) -> &DatabasesRo<B> {
+        &self.ro
+    }
+}
+
+impl<B: Backend + GenBackendConf<B>> Databases<B> {
+    pub(crate) fn open(data_path_opt: Option<&Path>) -> DalResult<Databases<B>> {
+        let bc_db_conf = B::gen_backend_conf(BC_DB_NAME, data_path_opt);
+        let bc_db = BcV1Db::<B>::open(bc_db_conf)?;
+        let ro = DatabasesRo {
+            bc_db: bc_db.get_ro_handler(),
+            peers_db: Arc::new(open_sqlite_db(data_path_opt, PEERS_DB)?),
+            txs_mp_db: Arc::new(open_sqlite_db(data_path_opt, TX_MP_DB)?),
+            wot_mp_db: Arc::new(open_sqlite_db(data_path_opt, WOT_MP_SQLITE_DB)?),
+        };
+        Ok(Databases {
+            bc_db,
+            peers_db: ro.peers_db.clone(),
+            txs_mp_db: ro.txs_mp_db.clone(),
+            wot_mp_db: ro.wot_mp_db.clone(),
+            ro,
+        })
+    }
+}
+
+// TMP - Sqlite will be removed on the future !
+
+#[inline(always)]
+fn open_sqlite_db(
+    data_path_opt: Option<&Path>,
+    db_file_name: &str,
+) -> DalResult<rusqlite::Connection> {
+    Ok(if let Some(data_path) = data_path_opt.as_deref() {
+        let mut sqlite_db_path = data_path.to_owned();
+        sqlite_db_path.pop();
+        sqlite_db_path.push(db_file_name);
+        rusqlite::Connection::open(sqlite_db_path)?
+    } else {
+        rusqlite::Connection::open(":memory:")?
+    })
+}
+
+/// Vector of string deserialized from JSON string
+#[derive(Clone, Debug, Default, Deserialize, Serialize)]
+pub struct JsonVecStr(pub Vec<String>);
+
+impl rusqlite::types::FromSql for JsonVecStr {
+    fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
+        let json_value = serde_json::Value::column_result(value)?;
+
+        if let serde_json::Value::Array(array) = json_value {
+            let mut vec_string = Vec::with_capacity(array.len());
+            for json_value in array {
+                if let serde_json::Value::String(string) = json_value {
+                    vec_string.push(string);
+                } else {
+                    return Err(rusqlite::types::FromSqlError::InvalidType);
+                }
+            }
+            Ok(JsonVecStr(vec_string))
+        } else {
+            Err(rusqlite::types::FromSqlError::InvalidType)
+        }
+    }
+}
+
+impl rusqlite::types::ToSql for JsonVecStr {
+    fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
+        let json_string = serde_json::to_string(&self.0)
+            .map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;
+
+        Ok(rusqlite::types::ToSqlOutput::Owned(
+            rusqlite::types::Value::Text(json_string),
+        ))
+    }
+}
diff --git a/rust-libs/duniter-dal/src/entities.rs b/rust-libs/duniter-dal/src/entities.rs
new file mode 100644
index 0000000000000000000000000000000000000000..d5d5bede9f6237cd1b094e43e5f2157561e9ef5b
--- /dev/null
+++ b/rust-libs/duniter-dal/src/entities.rs
@@ -0,0 +1,23 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Duniter DAL entities
+
+pub mod peer;
+
+use crate::*;
+
+/// DUBP Block in database
+pub type BlockDb = BlockDbV1;
diff --git a/rust-libs/duniter-dal/src/entities/peer.rs b/rust-libs/duniter-dal/src/entities/peer.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ded980a4e14910dd0bc091b62a12ff6ea3346622
--- /dev/null
+++ b/rust-libs/duniter-dal/src/entities/peer.rs
@@ -0,0 +1,61 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Define peer entity
+
+use crate::*;
+
+/// DUNP Peer card in database
+#[allow(missing_docs)]
+#[derive(Debug, Default, Deserialize, Serialize)]
+pub struct PeerCardDb {
+    pub version: i64,
+    pub currency: String,
+    pub status: String,
+    pub status_ts: i64,
+    pub hash: String,
+    pub first_down: Option<i64>,
+    pub last_try: Option<i64>,
+    pub last_contact: i64,
+    pub pubkey: String,
+    pub block: String,
+    pub signature: String,
+    pub endpoints: JsonVecStr,
+    pub raw: String,
+    pub non_wot: bool,
+}
+
+impl<'stmt> TryFrom<&rusqlite::Row<'stmt>> for PeerCardDb {
+    type Error = rusqlite::Error;
+
+    fn try_from(row: &rusqlite::Row<'stmt>) -> Result<Self, Self::Error> {
+        Ok(PeerCardDb {
+            version: row.get(0)?,
+            currency: row.get(1)?,
+            status: row.get(2)?,
+            status_ts: row.get(3)?,
+            hash: row.get(4)?,
+            first_down: row.get(5)?,
+            last_try: row.get(6)?,
+            last_contact: row.get(7)?,
+            pubkey: row.get(8)?,
+            block: row.get(9)?,
+            signature: row.get(10)?,
+            endpoints: row.get(11)?,
+            raw: row.get(12)?,
+            non_wot: row.get(13)?,
+        })
+    }
+}
diff --git a/rust-libs/duniter-dal/src/errors.rs b/rust-libs/duniter-dal/src/errors.rs
new file mode 100644
index 0000000000000000000000000000000000000000..842a2b0aeeae04d804d2acfaa42b70d9ba9880fb
--- /dev/null
+++ b/rust-libs/duniter-dal/src/errors.rs
@@ -0,0 +1,71 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Define DAL errors
+
+use crate::*;
+
+/// Duniter DAL Result
+pub type DalResult<T> = Result<T, DalError>;
+
+#[derive(Debug, Error)]
+/// Dal error
+pub enum DalError {
+    /// Database error
+    #[error("{0}")]
+    DbError(ErrorDb),
+    /// Fail to create folder
+    #[error("Fail to create folder: {0}")]
+    FailToCreateFolder(std::io::Error),
+    /// Fail to open wot file
+    #[error("Fail to open wot file: {0}")]
+    FailToOpenWotFile(bincode::Error),
+    /// Fail to save wot file
+    #[error("Fail to save wot file: {0}")]
+    FailToSaveWotFile(bincode::Error),
+    /// Fail to get currency parameters from genesis block
+    #[error("Fail to get genesis parameters: {0}")]
+    GenesisParamsError(String),
+    /// No blockchain
+    #[error("No blockchain")]
+    NoBlockchain,
+    /// Sqlite error
+    #[error("Sqlite error: {0}")]
+    SqLiteError(rusqlite::Error),
+    /// Wrong backend
+    #[error("Database already exist with {exist_backend} bakend, please use them.")]
+    WrongBackend {
+        /// Existing bakend
+        exist_backend: &'static str,
+    },
+}
+
+impl From<KvError> for DalError {
+    fn from(e: KvError) -> Self {
+        Self::DbError(ErrorDb::DbError(format!("{}", e)))
+    }
+}
+
+impl From<ErrorDb> for DalError {
+    fn from(e: ErrorDb) -> Self {
+        Self::DbError(e)
+    }
+}
+
+impl From<rusqlite::Error> for DalError {
+    fn from(e: rusqlite::Error) -> Self {
+        Self::SqLiteError(e)
+    }
+}
diff --git a/rust-libs/duniter-dal/src/file_dal.rs b/rust-libs/duniter-dal/src/file_dal.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4066f949933b7a746056602d7755946f7976bf2d
--- /dev/null
+++ b/rust-libs/duniter-dal/src/file_dal.rs
@@ -0,0 +1,166 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Duniter file data access layer
+
+use crate::*;
+
+#[derive(Clone, Debug)]
+/// Duniter Data Access Layer on read-only mode that read data from filesystem
+pub struct FileDalRo<B: Backend> {
+    pub(crate) databases: DatabasesRo<B>,
+    pub(crate) currency_params: CurrencyParameters,
+    pub(crate) wot: Wot,
+}
+
+#[derive(Clone, Debug)]
+/// Duniter Data Access Layer that store data on filesystem
+pub struct FileDal<B: Backend> {
+    pub(crate) databases: Databases<B>,
+    pub(crate) currency_params: CurrencyParameters,
+    pub(crate) wot: Wot,
+}
+
+impl<B: Backend + GenBackendConf<B>> FileDal<B> {
+    #[inline(always)]
+    /// Initialise file DAL
+    pub fn init<P: AsRef<Path>>(profile_path: P) -> DalResult<Self> {
+        let data_path = profile_path.as_ref().join(DATA_DIR);
+        verify_data_path(&data_path, B::NAME)?;
+        let databases = Databases::open(Some(data_path.as_path()))?;
+        let currency_params = get_currency_params(&databases.bc_db, data_path.as_path())?;
+        let wot = Wot::open(Some(data_path.as_path()), currency_params.sig_stock)
+            .map_err(DalError::FailToOpenWotFile)?;
+
+        Ok(FileDal {
+            currency_params,
+            databases,
+            wot,
+        })
+    }
+}
+
+impl<B: Backend> ToDalRo for FileDal<B> {
+    type DalRo = FileDalRo<B>;
+
+    fn to_dal_ro(&self) -> Self::DalRo {
+        FileDalRo {
+            databases: self.databases.to_ro().clone(),
+            currency_params: self.currency_params,
+            wot: self.wot.clone(),
+        }
+    }
+}
+
+fn get_currency_params<B: Backend>(
+    bc_db: &BcDb<B>,
+    data_path: &Path,
+) -> DalResult<CurrencyParameters> {
+    Ok(if let Some(currency_params) = get_genesis_params(&bc_db)? {
+        currency_params
+    } else {
+        let mut file = fs::File::open(data_path.join(GENESIS_PARAMS_FILE))
+            .map_err(|e| DalError::GenesisParamsError(format!("{}", e)))?;
+        let mut file_contents = String::new();
+        file.read_to_string(&mut file_contents)
+            .map_err(|e| DalError::GenesisParamsError(format!("{}", e)))?;
+        serde_json::from_str::<CurrencyNameAndGenesisBlockParams>(&file_contents)
+            .map_err(|e| DalError::GenesisParamsError(format!("{}", e)))?
+            .into()
+    })
+}
+
+fn get_genesis_params<B: Backend>(bc_db: &BcDb<B>) -> DalResult<Option<CurrencyParameters>> {
+    let genesis_opt = bc_db
+        .main_blocks()
+        .get(&duniter_dbs::BlockNumberKeyV1(BlockNumber(0)))?;
+
+    Ok(if let Some(genesis) = genesis_opt {
+        Some(CurrencyParameters::from((
+            &CurrencyName(genesis.currency),
+            dubp_common::currency_params::BlockV10Parameters::from_str(&genesis.parameters)
+                .map_err(|e| DalError::GenesisParamsError(format!("{}", e)))?,
+        )))
+    } else {
+        None
+    })
+}
+
+fn verify_data_path(data_path: &PathBuf, backend_name: &'static str) -> DalResult<()> {
+    if !data_path.exists() {
+        fs::create_dir_all(data_path.as_path()).map_err(DalError::FailToCreateFolder)?;
+    } else {
+        match backend_name {
+            "leveldb" => {
+                if data_path.as_path().join("bc_v1_sled").exists() {
+                    return Err(DalError::WrongBackend {
+                        exist_backend: "sled",
+                    });
+                }
+            }
+            "sled" => {
+                if data_path.as_path().join("leveldb").exists() {
+                    return Err(DalError::WrongBackend {
+                        exist_backend: "leveldb",
+                    });
+                }
+            }
+            _ => unreachable!(),
+        }
+    }
+
+    Ok(())
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use dubp_common::currency_params::{BlockV10Parameters, GenesisBlockParams};
+    use tempdir::TempDir;
+    use unwrap::unwrap;
+
+    #[test]
+    fn test_file_dal() -> DalResult<()> {
+        let tmp_dir = unwrap!(TempDir::new("duniter_test_file_dal"));
+        let tmp_dir_path = tmp_dir.path();
+        let data_path = tmp_dir_path.join(DATA_DIR);
+        unwrap!(fs::create_dir(data_path));
+
+        /*if let Err(DalError::GenesisParamsError(_)) = FileDal::init(None, tmp_dir_path.to_owned()) {
+        } else {
+            panic!("FileDal::init must be fail with error GenesisParamsError !");
+        }*/
+
+        // Create currency params file
+        let params = CurrencyNameAndGenesisBlockParams {
+            genesis_block_params: GenesisBlockParams::V10(BlockV10Parameters {
+                sig_stock: 40,
+                ..Default::default()
+            }),
+            ..Default::default()
+        };
+        let mut file = unwrap!(fs::File::create(
+            tmp_dir_path.join(DATA_DIR).join(GENESIS_PARAMS_FILE)
+        ));
+        unwrap!(file.write_all(unwrap!(serde_json::to_string(&params)).as_bytes()));
+
+        let dal = FileDal::<Sled>::init(tmp_dir_path)?;
+
+        assert_eq!(40, dal.wot().get_max_link());
+
+        unwrap!(tmp_dir.close().map_err(DalError::FailToCreateFolder));
+        Ok(())
+    }
+}
diff --git a/rust-libs/duniter-dal/src/inner.rs b/rust-libs/duniter-dal/src/inner.rs
new file mode 100644
index 0000000000000000000000000000000000000000..998373019bcccd301221b89a7703b5d20c3a9e0a
--- /dev/null
+++ b/rust-libs/duniter-dal/src/inner.rs
@@ -0,0 +1,106 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Duniter DAL inner
+
+use crate::*;
+
+pub trait InnerDalRo: Clone {
+    type Backend: Backend;
+
+    fn currency_params(&self) -> CurrencyParameters;
+    fn databases(&self) -> &DatabasesRo<Self::Backend>;
+    fn wot(&self) -> &Wot;
+}
+
+impl InnerDalRo for MemDalRo {
+    type Backend = Mem;
+
+    #[inline(always)]
+    fn currency_params(&self) -> CurrencyParameters {
+        self.currency_params
+    }
+    #[inline(always)]
+    fn databases(&self) -> &DatabasesRo<Mem> {
+        &self.databases
+    }
+    #[inline(always)]
+    fn wot(&self) -> &Wot {
+        &self.wot
+    }
+}
+impl InnerDalRo for MemDal {
+    type Backend = Mem;
+    #[inline(always)]
+    fn currency_params(&self) -> CurrencyParameters {
+        self.currency_params
+    }
+    #[inline(always)]
+    fn databases(&self) -> &DatabasesRo<Self::Backend> {
+        self.databases.to_ro()
+    }
+    #[inline(always)]
+    fn wot(&self) -> &Wot {
+        &self.wot
+    }
+}
+impl<B: Backend> InnerDalRo for FileDalRo<B> {
+    type Backend = B;
+    #[inline(always)]
+    fn currency_params(&self) -> CurrencyParameters {
+        self.currency_params
+    }
+    #[inline(always)]
+    fn databases(&self) -> &DatabasesRo<Self::Backend> {
+        &self.databases
+    }
+    #[inline(always)]
+    fn wot(&self) -> &Wot {
+        &self.wot
+    }
+}
+impl<B: Backend> InnerDalRo for FileDal<B> {
+    type Backend = B;
+    #[inline(always)]
+    fn currency_params(&self) -> CurrencyParameters {
+        self.currency_params
+    }
+    #[inline(always)]
+    fn databases(&self) -> &DatabasesRo<Self::Backend> {
+        self.databases.to_ro()
+    }
+    #[inline(always)]
+    fn wot(&self) -> &Wot {
+        &self.wot
+    }
+}
+
+pub trait InnerDalRw: InnerDalRo + ToDalRo {
+    fn databases_rw(&self) -> &Databases<<Self as InnerDalRo>::Backend>;
+}
+
+impl<B: Backend> InnerDalRw for FileDal<B> {
+    #[inline(always)]
+    fn databases_rw(&self) -> &Databases<B> {
+        &self.databases
+    }
+}
+
+impl InnerDalRw for MemDal {
+    #[inline(always)]
+    fn databases_rw(&self) -> &Databases<Mem> {
+        &self.databases
+    }
+}
diff --git a/rust-libs/duniter-dal/src/lib.rs b/rust-libs/duniter-dal/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e87802cff343f92e19c0907dda6f94422e7795c6
--- /dev/null
+++ b/rust-libs/duniter-dal/src/lib.rs
@@ -0,0 +1,133 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Duniter Data Access Layer
+
+#![deny(
+    clippy::expect_used,
+    clippy::unwrap_used,
+    missing_docs,
+    missing_copy_implementations,
+    trivial_casts,
+    trivial_numeric_casts,
+    unstable_features,
+    unused_import_braces,
+    unused_qualifications
+)]
+
+mod conf_dbs;
+mod databases;
+mod entities;
+mod errors;
+mod file_dal;
+mod inner;
+mod mem_dal;
+#[cfg(feature = "mock")]
+mod mock_dal;
+mod read;
+mod wot;
+mod write;
+
+/// Prelude
+pub mod prelude {
+    pub use crate::databases::JsonVecStr;
+    pub use crate::databases::{BcDb, BcDbRo};
+    pub use crate::entities::peer::PeerCardDb;
+    pub use crate::entities::BlockDb;
+    pub use crate::errors::{DalError, DalResult};
+    pub use crate::file_dal::FileDal;
+    pub use crate::mem_dal::MemDal;
+    #[cfg(feature = "mock")]
+    pub use crate::mock_dal::{MockDal, MockDalRo};
+    pub use crate::read::bc_db::DalReadBc;
+    pub use crate::read::peers::DalReadPeers;
+    pub use crate::read::DalReadable;
+    pub use crate::write::peers::DalWritePeers;
+    pub use crate::write::{DalWritable, ToDalRo};
+    pub use crate::Dal;
+}
+// Technical types
+pub use duniter_dbs::kv_typed::backend::leveldb::LevelDb;
+#[cfg(feature = "mock")]
+pub use duniter_dbs::kv_typed::backend::mock::MockBackend;
+pub use duniter_dbs::kv_typed::backend::sled::Sled;
+
+// Crate imports
+pub(crate) use crate::conf_dbs::GenBackendConf;
+pub(crate) use crate::databases::{Databases, DatabasesRo};
+pub(crate) use crate::errors::{DalError, DalResult};
+pub(crate) use crate::file_dal::FileDalRo;
+pub(crate) use crate::inner::{InnerDalRo, InnerDalRw};
+pub(crate) use crate::mem_dal::MemDalRo;
+pub(crate) use crate::prelude::*;
+pub(crate) use crate::wot::Wot;
+pub(crate) use dubp_common::currency_params::{
+    CurrencyNameAndGenesisBlockParams, CurrencyParameters,
+};
+pub(crate) use dubp_common::prelude::*;
+pub(crate) use duniter_dbs::kv_typed::prelude::*;
+pub(crate) use duniter_dbs::prelude::*;
+pub(crate) use duniter_dbs::{
+    BcV1Db, BcV1DbReadable as BcDbReadable, BcV1DbRo, BcV1DbWritable as BcDbWritable, BlockDbV1,
+};
+pub(crate) use serde::{Deserialize, Serialize};
+pub(crate) use std::{
+    convert::TryFrom,
+    fmt::Debug,
+    fs::{self, File},
+    io::prelude::*,
+    path::{Path, PathBuf},
+    str::FromStr,
+    sync::Arc,
+};
+pub(crate) use thiserror::Error;
+
+// Crate internal constants
+const BC_DB_NAME: &str = "bc_v1";
+const DATA_DIR: &str = "data";
+const GENESIS_PARAMS_FILE: &str = "genesis_parameters.json";
+const WOT_FILE: &str = "wotb.bin.gz";
+const PEERS_DB: &str = "peers.db";
+const TX_MP_DB: &str = "txs.db";
+const WOT_MP_SQLITE_DB: &str = "duniter.db";
+
+/// Duniter Data Access Layer
+pub trait Dal<B: Backend>: DalWritable {
+    /// Get read only handler to blockchain database
+    fn get_bc_db_ro(&self) -> BcDbRo<B>;
+
+    /// Get read only DAL
+    fn get_dal_ro(&self) -> <Self as ToDalRo>::DalRo;
+}
+
+impl<B: Backend, T> Dal<B> for T
+where
+    T: InnerDalRo<Backend = B> + InnerDalRw + DalWritable + NotMock,
+{
+    fn get_bc_db_ro(&self) -> BcDbRo<B> {
+        self.databases_rw().bc_db.get_ro_handler()
+    }
+    fn get_dal_ro(&self) -> Self::DalRo {
+        self.to_dal_ro()
+    }
+}
+
+#[doc(hidden)]
+pub trait NotMock {}
+
+impl<B: Backend> NotMock for FileDal<B> {}
+impl<B: Backend> NotMock for FileDalRo<B> {}
+impl NotMock for MemDal {}
+impl NotMock for MemDalRo {}
diff --git a/rust-libs/duniter-dal/src/mem_dal.rs b/rust-libs/duniter-dal/src/mem_dal.rs
new file mode 100644
index 0000000000000000000000000000000000000000..6fdab11e82262fe9b736c254250115ffb6a874eb
--- /dev/null
+++ b/rust-libs/duniter-dal/src/mem_dal.rs
@@ -0,0 +1,82 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Duniter memory data access layer
+
+use crate::*;
+
+#[derive(Clone, Debug)]
+/// Duniter Data Access Layer on read-only mode that read data from memory
+pub struct MemDalRo {
+    pub(crate) databases: DatabasesRo<Mem>,
+    pub(crate) currency_params: CurrencyParameters,
+    pub(crate) wot: Wot,
+}
+
+#[derive(Clone, Debug)]
+/// Duniter Data Access Layer that store data on memory
+pub struct MemDal {
+    pub(crate) databases: Databases<Mem>,
+    pub(crate) currency_params: CurrencyParameters,
+    pub(crate) wot: Wot,
+}
+
+impl MemDal {
+    #[inline(always)]
+    /// Initialise memory DAL
+    pub fn init(currency_params_opt: Option<CurrencyParameters>) -> DalResult<Self> {
+        let currency_params = currency_params_opt.unwrap_or_default();
+        // Memory mode, force sled backend
+        let databases = Databases::open(None)?;
+        let wot =
+            Wot::open(None, currency_params.sig_stock).map_err(DalError::FailToOpenWotFile)?;
+        Ok(MemDal {
+            currency_params,
+            databases,
+            wot,
+        })
+    }
+}
+
+impl ToDalRo for MemDal {
+    type DalRo = MemDalRo;
+
+    fn to_dal_ro(&self) -> Self::DalRo {
+        MemDalRo {
+            databases: self.databases.to_ro().clone(),
+            currency_params: self.currency_params,
+            wot: self.wot.clone(),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_mem_dal() -> DalResult<()> {
+        let currency_params = CurrencyParameters {
+            sig_stock: 42,
+            ..Default::default()
+        };
+        let dal = MemDal::init(Some(currency_params))?;
+
+        assert_eq!(currency_params, dal.currency_params());
+        assert_eq!(42, dal.wot().get_max_link());
+
+        Ok(())
+    }
+}
diff --git a/rust-libs/duniter-dal/src/mock_dal.rs b/rust-libs/duniter-dal/src/mock_dal.rs
new file mode 100644
index 0000000000000000000000000000000000000000..056d8d2d8207c75c8a02b8da8e1644f57b859158
--- /dev/null
+++ b/rust-libs/duniter-dal/src/mock_dal.rs
@@ -0,0 +1,74 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Duniter mocked data access layer
+
+#![allow(clippy::ptr_arg)]
+
+use crate::*;
+
+mockall::mock! {
+    pub DalRo<B: Backend> {}
+    trait DalReadBc {
+        fn get_block(&self, number: BlockNumber) -> DalResult<Option<BlockDb>>;
+        fn get_current_block(&self) -> DalResult<Option<BlockDb>>;
+    }
+    trait DalReadPeers {
+        fn count_mirror_peers(&self) -> DalResult<u32>;
+        fn get_peer_by_pubkey(&self, pubkey: &str) -> DalResult<Option<PeerCardDb>>;
+        fn get_peers_with_endpoints_like(&self, pattern: &str) -> DalResult<Vec<PeerCardDb>>;
+        fn get_all_peers(&self) -> DalResult<Vec<PeerCardDb>>;
+        fn get_up_peers(&self) -> DalResult<Vec<PeerCardDb>>;
+    }
+    trait DalReadable {
+        fn get_currency_params(&self) -> CurrencyParameters;
+    }
+}
+
+mockall::mock! {
+    pub Dal<B: Backend> {}
+    trait DalReadBc {
+        fn get_block(&self, number: BlockNumber) -> DalResult<Option<BlockDb>>;
+        fn get_current_block(&self) -> DalResult<Option<BlockDb>>;
+    }
+    trait DalReadPeers {
+        fn count_mirror_peers(&self) -> DalResult<u32>;
+        fn get_peer_by_pubkey(&self, pubkey: &str) -> DalResult<Option<PeerCardDb>>;
+        fn get_peers_with_endpoints_like(&self, pattern: &str) -> DalResult<Vec<PeerCardDb>>;
+        fn get_all_peers(&self) -> DalResult<Vec<PeerCardDb>>;
+        fn get_up_peers(&self) -> DalResult<Vec<PeerCardDb>>;
+    }
+    trait DalReadable {
+        fn get_currency_params(&self) -> CurrencyParameters;
+    }
+    trait ToDalRo {
+        type DalRo = MockDalRo<B>;
+
+        fn to_dal_ro(&self) -> MockDalRo<B>;
+    }
+    trait DalWritePeers {
+        fn delete_mirrror_peers_whose_last_contact_is_above(&self, threshold: i64) -> DalResult<()>;
+        fn remove_all(&self) -> DalResult<()>;
+        fn remove_peer_by_pubkey(&self, pubkey: String) -> DalResult<()>;
+        fn save_peer(&self, peer: PeerCardDb) -> DalResult<()>;
+    }
+    trait DalWritable {
+        fn save_wot(&self) -> DalResult<()>;
+    }
+    trait Dal<B>: DalReadable + DalWritable<B> {
+        fn get_bc_db_ro(&self) -> BcDbRo<B>;
+        fn get_dal_ro(&self) -> MockDalRo<B>;
+    }
+}
diff --git a/rust-libs/duniter-dal/src/read.rs b/rust-libs/duniter-dal/src/read.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8c85358e194c51f55ab11443c6709634eab48dc2
--- /dev/null
+++ b/rust-libs/duniter-dal/src/read.rs
@@ -0,0 +1,38 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Duniter Data Access Layer read operations
+
+pub mod bc_db;
+pub mod peers;
+
+use crate::*;
+use bc_db::*;
+
+/// DAL read operations
+pub trait DalReadable: DalReadBc + DalReadPeers {
+    /// Get currency parameters
+    fn get_currency_params(&self) -> CurrencyParameters;
+}
+
+impl<T> DalReadable for T
+where
+    T: DalReadBc + DalReadPeers + InnerDalRo + NotMock,
+{
+    #[inline(always)]
+    fn get_currency_params(&self) -> CurrencyParameters {
+        self.currency_params()
+    }
+}
diff --git a/rust-libs/duniter-dal/src/read/bc_db.rs b/rust-libs/duniter-dal/src/read/bc_db.rs
new file mode 100644
index 0000000000000000000000000000000000000000..5f500cceba433c49ceabff74af7a95bc047d0242
--- /dev/null
+++ b/rust-libs/duniter-dal/src/read/bc_db.rs
@@ -0,0 +1,52 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Define blockchain database read operations
+
+use crate::*;
+use duniter_dbs::BlockNumberKeyV1;
+
+/// DAL read operations for blockcnain db
+pub trait DalReadBc {
+    /// Get a block by number
+    fn get_block(&self, number: BlockNumber) -> DalResult<Option<BlockDb>>;
+    /// Get the current block (=the last block)
+    fn get_current_block(&self) -> DalResult<Option<BlockDb>>;
+}
+
+impl<T> DalReadBc for T
+where
+    T: InnerDalRo + NotMock,
+{
+    fn get_current_block(&self) -> DalResult<Option<BlockDb>> {
+        Ok(self
+            .databases()
+            .bc_db
+            .main_blocks()
+            .iter(..)
+            .values()
+            .reverse()
+            .next()
+            .transpose()?)
+    }
+    #[inline(always)]
+    fn get_block(&self, number: BlockNumber) -> DalResult<Option<BlockDb>> {
+        Ok(self
+            .databases()
+            .bc_db
+            .main_blocks()
+            .get(&BlockNumberKeyV1(number))?)
+    }
+}
diff --git a/rust-libs/duniter-dal/src/read/peers.rs b/rust-libs/duniter-dal/src/read/peers.rs
new file mode 100644
index 0000000000000000000000000000000000000000..22d3eadb6e5ef35c4a90490f5b6573d73ffadca1
--- /dev/null
+++ b/rust-libs/duniter-dal/src/read/peers.rs
@@ -0,0 +1,82 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Duniter Data Access Layer read operations for peers db
+
+use crate::*;
+
+/// DAL read operations for peers db
+pub trait DalReadPeers {
+    /// Count mirror peers
+    fn count_mirror_peers(&self) -> DalResult<u32>;
+    /// Get one peer card by this pub-key
+    fn get_peer_by_pubkey(&self, pubkey: &str) -> DalResult<Option<PeerCardDb>>;
+    /// Get peers cards with endpoints like
+    fn get_peers_with_endpoints_like(&self, pattern: &str) -> DalResult<Vec<PeerCardDb>>;
+    /// Get all peer cards
+    fn get_all_peers(&self) -> DalResult<Vec<PeerCardDb>>;
+    /// Get UP peers
+    fn get_up_peers(&self) -> DalResult<Vec<PeerCardDb>>;
+}
+
+#[allow(clippy::redundant_closure)]
+impl<T> DalReadPeers for T
+where
+    T: InnerDalRo + NotMock,
+{
+    fn count_mirror_peers(&self) -> DalResult<u32> {
+        Ok(self
+            .databases()
+            .peers_db
+            .prepare("SELECT COUNT(*) as _count FROM peers WHERE nonWoT")?
+            .query_map(rusqlite::params![], |row| row.get(0))?
+            .next()
+            .transpose()?
+            .unwrap_or_default())
+    }
+    fn get_peer_by_pubkey(&self, pubkey: &str) -> DalResult<Option<PeerCardDb>> {
+        Ok(self
+            .databases()
+            .peers_db
+            .prepare("SELECT * FROM peers WHERE pubkey = ?")?
+            .query_map(&[pubkey], |row| PeerCardDb::try_from(row))?
+            .next()
+            .transpose()?)
+    }
+    fn get_peers_with_endpoints_like(&self, pattern: &str) -> DalResult<Vec<PeerCardDb>> {
+        Ok(self
+            .databases()
+            .peers_db
+            .prepare("SELECT * FROM peers WHERE endpoints LIKE ?")?
+            .query_map(&[pattern], |row| PeerCardDb::try_from(row))?
+            .collect::<Result<Vec<PeerCardDb>, rusqlite::Error>>()?)
+    }
+    fn get_all_peers(&self) -> DalResult<Vec<PeerCardDb>> {
+        Ok(self
+            .databases()
+            .peers_db
+            .prepare("SELECT * FROM peers")?
+            .query_map(rusqlite::params![], |row| PeerCardDb::try_from(row))?
+            .collect::<Result<Vec<PeerCardDb>, rusqlite::Error>>()?)
+    }
+    fn get_up_peers(&self) -> DalResult<Vec<PeerCardDb>> {
+        Ok(self
+            .databases()
+            .peers_db
+            .prepare("SELECT * FROM peers WHERE status = ?")?
+            .query_map(&["UP"], |row| PeerCardDb::try_from(row))?
+            .collect::<Result<Vec<PeerCardDb>, rusqlite::Error>>()?)
+    }
+}
diff --git a/rust-libs/duniter-dal/src/wot.rs b/rust-libs/duniter-dal/src/wot.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4ba90b9e5b4e84cf84d770a12148d61daef81b37
--- /dev/null
+++ b/rust-libs/duniter-dal/src/wot.rs
@@ -0,0 +1,80 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Duniter Data Access Layer: wot
+
+mod read_from_file;
+mod write_in_file;
+
+use crate::*;
+use crossbeam_utils::sync::ShardedLock;
+use dubp_wot::{data::rusty::RustyWebOfTrust, data::NewLinkResult, WebOfTrust, WotId};
+
+#[derive(Clone, Debug)]
+pub struct Wot {
+    pub(crate) wot: Arc<ShardedLock<RustyWebOfTrust>>,
+    file_path_opt: Option<PathBuf>,
+}
+
+#[allow(dead_code)]
+impl Wot {
+    pub(crate) fn open(
+        data_path_opt: Option<&Path>,
+        max_links: usize,
+    ) -> Result<Self, bincode::Error> {
+        Ok(if let Some(data_path) = data_path_opt {
+            let wot_file_path = data_path.join(WOT_FILE);
+            Wot {
+                wot: Arc::new(ShardedLock::new(read_from_file::wot_from_file(
+                    wot_file_path.as_path(),
+                    max_links,
+                )?)),
+                file_path_opt: Some(wot_file_path),
+            }
+        } else {
+            Wot {
+                wot: Arc::new(ShardedLock::new(RustyWebOfTrust::new(max_links))),
+                file_path_opt: None,
+            }
+        })
+    }
+    #[allow(clippy::expect_used)]
+    #[inline(always)]
+    pub(crate) fn get_max_link(&self) -> usize {
+        let wot_reader = self.wot.read().expect("poisoned");
+        wot_reader.get_max_link()
+    }
+    #[allow(clippy::expect_used)]
+    pub(crate) fn add_links(&self, links: &[(WotId, WotId)]) -> Result<(), NewLinkResult> {
+        let mut wot_writer = self.wot.write().expect("poisoned");
+        for (source, target) in links {
+            match wot_writer.add_link(*source, *target) {
+                NewLinkResult::Ok(_) => continue,
+                r => return Err(r),
+            }
+        }
+
+        Ok(())
+    }
+    #[allow(clippy::expect_used)]
+    pub(crate) fn save(&self) -> Result<(), bincode::Error> {
+        if let Some(ref wot_file_path) = self.file_path_opt {
+            let wot_reader = self.wot.read().expect("poisoned");
+            write_in_file::wot_in_file(wot_file_path.as_path(), &wot_reader)
+        } else {
+            Ok(())
+        }
+    }
+}
diff --git a/rust-libs/duniter-dal/src/wot/read_from_file.rs b/rust-libs/duniter-dal/src/wot/read_from_file.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8b9fb2acdf5c58b34f12fbb58701aedf90491e3b
--- /dev/null
+++ b/rust-libs/duniter-dal/src/wot/read_from_file.rs
@@ -0,0 +1,50 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+use super::*;
+use crate::*;
+use flate2::read::ZlibDecoder;
+
+pub(crate) fn wot_from_file(
+    file_path: &Path,
+    max_links: usize,
+) -> Result<RustyWebOfTrust, bincode::Error> {
+    let bytes = read_and_decompress_bytes_from_file(file_path)?;
+    if bytes.is_empty() {
+        Ok(RustyWebOfTrust::new(max_links))
+    } else {
+        Ok(bincode::deserialize::<RustyWebOfTrust>(&bytes)?)
+    }
+}
+
+/// Read and decompress bytes from file
+fn read_and_decompress_bytes_from_file(file_path: &Path) -> Result<Vec<u8>, std::io::Error> {
+    if !file_path.exists() {
+        if let Some(parent) = file_path.parent() {
+            std::fs::create_dir_all(parent)?
+        }
+        File::create(file_path)?;
+    }
+    if std::fs::metadata(file_path)?.len() > 0 {
+        let file = File::open(file_path)?;
+        let mut z = ZlibDecoder::new(file);
+        let mut decompressed_bytes = Vec::new();
+        z.read_to_end(&mut decompressed_bytes)?;
+
+        Ok(decompressed_bytes)
+    } else {
+        Ok(vec![])
+    }
+}
diff --git a/rust-libs/duniter-dal/src/wot/write_in_file.rs b/rust-libs/duniter-dal/src/wot/write_in_file.rs
new file mode 100644
index 0000000000000000000000000000000000000000..6b88d958a01e25a0d5cc3788b46b15514776894e
--- /dev/null
+++ b/rust-libs/duniter-dal/src/wot/write_in_file.rs
@@ -0,0 +1,40 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+use super::*;
+use crate::*;
+use flate2::write::ZlibEncoder;
+use flate2::Compression;
+
+pub(crate) fn wot_in_file(file_path: &Path, wot: &RustyWebOfTrust) -> Result<(), bincode::Error> {
+    let bytes = bincode::serialize(wot)?;
+    write_and_compress_bytes_in_file(file_path, &bytes, flate2::Compression::default())?;
+
+    Ok(())
+}
+
+/// Write and compress bytes in file
+fn write_and_compress_bytes_in_file(
+    file_path: &Path,
+    datas: &[u8],
+    compression: Compression,
+) -> Result<(), std::io::Error> {
+    let file = File::create(file_path)?;
+    let mut e = ZlibEncoder::new(file, compression);
+    e.write_all(&datas[..])?;
+    e.finish()?;
+
+    Ok(())
+}
diff --git a/rust-libs/duniter-dal/src/write.rs b/rust-libs/duniter-dal/src/write.rs
new file mode 100644
index 0000000000000000000000000000000000000000..2cf0abaeceb9842231c4ead1af465ce44c1e2c2d
--- /dev/null
+++ b/rust-libs/duniter-dal/src/write.rs
@@ -0,0 +1,46 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Duniter Data Access Layer write operations
+
+pub mod peers;
+
+use crate::*;
+
+/// To read only DAL
+pub trait ToDalRo {
+    /// Read-only DAL
+    type DalRo: DalReadable;
+
+    /// To read-only DAL
+    fn to_dal_ro(&self) -> Self::DalRo;
+}
+
+/// DAL write operations
+pub trait DalWritable: DalReadable + DalWritePeers + ToDalRo {
+    /// save web of trust
+    fn save_wot(&self) -> DalResult<()>;
+}
+
+impl<T> DalWritable for T
+where
+    T: DalWritePeers + InnerDalRw + NotMock,
+{
+    #[inline(always)]
+    fn save_wot(&self) -> DalResult<()> {
+        self.wot().save().map_err(DalError::FailToSaveWotFile)?;
+        Ok(())
+    }
+}
diff --git a/rust-libs/duniter-dal/src/write/peers.rs b/rust-libs/duniter-dal/src/write/peers.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4cbab204ad382d1684d6bc59924709437567d9a0
--- /dev/null
+++ b/rust-libs/duniter-dal/src/write/peers.rs
@@ -0,0 +1,85 @@
+//  Copyright (C) 2020 Éloïs SANCHEZ.
+//
+// This program 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, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Duniter Data Access Layer write operations for peers db
+
+use crate::*;
+
+/// DAL write operations for peers db
+pub trait DalWritePeers {
+    /// Count mirror peers
+    fn delete_mirrror_peers_whose_last_contact_is_above(&self, threshold: i64) -> DalResult<()>;
+    /// Remove all peers
+    fn remove_all(&self) -> DalResult<()>;
+    /// Remove peer by pubkey
+    fn remove_peer_by_pubkey(&self, pubkey: String) -> DalResult<()>;
+    /// Save peer
+    fn save_peer(&self, peer: PeerCardDb) -> DalResult<()>;
+}
+
+impl<T> DalWritePeers for T
+where
+    T: InnerDalRw + NotMock,
+{
+    fn delete_mirrror_peers_whose_last_contact_is_above(&self, threshold: i64) -> DalResult<()> {
+        self.databases()
+            .peers_db
+            .prepare("DELETE FROM peers WHERE (nonWoT OR nonWoT IS NULL) AND lastContact <= ?")?
+            .execute(&[threshold])?;
+        Ok(())
+    }
+
+    fn remove_all(&self) -> DalResult<()> {
+        self.databases()
+            .peers_db
+            .prepare("DELETE FROM peers")?
+            .execute(rusqlite::params![])?;
+        Ok(())
+    }
+
+    fn remove_peer_by_pubkey(&self, pubkey: String) -> DalResult<()> {
+        self.databases()
+            .peers_db
+            .prepare("DELETE FROM peers WHERE pubkey = ?")?
+            .execute(&[pubkey])?;
+        Ok(())
+    }
+
+    fn save_peer(&self, peer: PeerCardDb) -> DalResult<()> {
+        let sql = "INSERT INTO peers (version, currency, status, statusTS, hash,
+            first_down, last_try, lastContact, pubkey, block, signature, endpoints,
+            raw, nonWoT) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
+        self.databases()
+            .peers_db
+            .prepare(sql)?
+            .execute(rusqlite::params![
+                peer.version,
+                peer.currency,
+                peer.status,
+                peer.status_ts,
+                peer.hash,
+                peer.first_down,
+                peer.last_try,
+                peer.last_contact,
+                peer.pubkey,
+                peer.block,
+                peer.signature,
+                peer.endpoints,
+                peer.raw,
+                peer.non_wot
+            ])?;
+        Ok(())
+    }
+}
diff --git a/rust-libs/duniter-dal/tests/main_blocks.rs b/rust-libs/duniter-dal/tests/main_blocks.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a58de8fc58ecaf06596e1c2ea96f41eece413dfd
--- /dev/null
+++ b/rust-libs/duniter-dal/tests/main_blocks.rs
@@ -0,0 +1,53 @@
+use dubp_common::currency_params::BlockV10Parameters;
+use dubp_common::prelude::*;
+use duniter_dal::prelude::*;
+use duniter_dbs::kv_typed::prelude::*;
+use duniter_dbs::{BcV1DbWritable, BlockDbV1, BlockNumberKeyV1};
+use std::fs::create_dir;
+use tempdir::TempDir;
+use unwrap::unwrap;
+
+const DATA_DIR: &str = "data";
+
+#[test]
+fn test_dal_main_blocks() -> DalResult<()> {
+    let tmp_dir = unwrap!(TempDir::new("duniter_test_file_dal"));
+    let data_path = tmp_dir.path().join(DATA_DIR);
+    unwrap!(create_dir(data_path.as_path()));
+    let db_path = data_path.as_path().join("bc_v1_sled");
+
+    {
+        let bc_db = unwrap!(BcDb::<Sled>::open(SledConf::default().path(db_path)));
+
+        let b0 = BlockDbV1 {
+            parameters: BlockV10Parameters {
+                sig_stock: 42,
+                ..Default::default()
+            }
+            .to_string(),
+            ..Default::default()
+        };
+        let b1 = BlockDbV1 {
+            number: 1,
+            ..Default::default()
+        };
+
+        unwrap!(bc_db
+            .main_blocks_write()
+            .upsert(BlockNumberKeyV1(BlockNumber(0)), b0));
+        unwrap!(bc_db
+            .main_blocks_write()
+            .upsert(BlockNumberKeyV1(BlockNumber(1)), b1));
+    }
+
+    let dal = FileDal::<Sled>::init(tmp_dir.path().to_owned())?;
+
+    assert_eq!(42, dal.get_currency_params().sig_stock);
+
+    let current_block = unwrap!(dal.get_current_block()?);
+    assert_eq!(1, current_block.number);
+
+    unwrap!(tmp_dir.close());
+
+    Ok(())
+}
diff --git a/rust-libs/duniter-dal/tests/test_dal_mock.rs b/rust-libs/duniter-dal/tests/test_dal_mock.rs
new file mode 100644
index 0000000000000000000000000000000000000000..f349eb10ccb5f73f0ae92cd89554dcc324ede890
--- /dev/null
+++ b/rust-libs/duniter-dal/tests/test_dal_mock.rs
@@ -0,0 +1,33 @@
+#[cfg(feature = "mock")]
+mod test_mock {
+    use dubp_common::prelude::*;
+    use duniter_dal::prelude::*;
+    use duniter_dal::MockBackend;
+
+    fn get_genesis_block<DAL: DalReadable>(dal: &DAL) -> DalResult<Option<BlockDb>> {
+        dal.get_block(BlockNumber(0))
+    }
+
+    #[test]
+    fn test_mock_dal() -> DalResult<()> {
+        let mut mock_dal = MockDal::<MockBackend>::new();
+
+        mock_dal.expect_get_block().returning(|_| Ok(None));
+        mock_dal.expect_get_dal_ro().returning(MockDalRo::new);
+
+        let genesis_block_opt = get_genesis_block(&mock_dal)?;
+
+        assert_eq!(None, genesis_block_opt);
+
+        let mut mock_dal_ro = mock_dal.get_dal_ro();
+        mock_dal_ro
+            .expect_get_block()
+            .returning(|_| Ok(Some(BlockDb::default())));
+
+        let genesis_block_opt = get_genesis_block(&mock_dal_ro)?;
+
+        assert_eq!(Some(BlockDb::default()), genesis_block_opt);
+
+        Ok(())
+    }
+}
diff --git a/rust-libs/duniter-dal/tests/test_dal_real.rs b/rust-libs/duniter-dal/tests/test_dal_real.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a7d77c267837c74d68749d9b729269aa3cae0dc0
--- /dev/null
+++ b/rust-libs/duniter-dal/tests/test_dal_real.rs
@@ -0,0 +1,54 @@
+#[cfg(feature = "test_real")]
+mod tests {
+
+    use duniter_dal::prelude::*;
+    use duniter_dal::LevelDb;
+    use once_cell::sync::Lazy;
+    use std::sync::Mutex;
+    use unwrap::unwrap;
+
+    // Empty mutex used to ensure that only one test runs at a time
+    static MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
+
+    const PROFILE_PATH: &str = "/home/elois/.config/duniter/duniter_default";
+
+    #[test]
+    fn blocks() -> DalResult<()> {
+        let _lock = MUTEX.lock().expect("MUTEX poisoned");
+        let dal = FileDal::<LevelDb>::init(PROFILE_PATH)?.to_dal_ro();
+
+        let current_block = unwrap!(dal.get_current_block()?);
+
+        assert_eq!(317_499, current_block.number);
+
+        Ok(())
+    }
+
+    #[test]
+    fn peers() -> DalResult<()> {
+        let _lock = MUTEX.lock().expect("MUTEX poisoned");
+        let dal = FileDal::<LevelDb>::init(PROFILE_PATH)?;
+
+        let _bma_peers = dal.get_peers_with_endpoints_like("%BMAS%")?;
+
+        //println!("{:?}", bma_peers);
+
+        let _elois_peer = dal.get_peer_by_pubkey("D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx")?;
+
+        //println!("{:?}", elois_peer);
+
+        println!("count_mirror_peers={:?}", dal.count_mirror_peers()?);
+
+        let up_peers = dal.get_up_peers()?;
+        println!("up_peers.len()={}", up_peers.len());
+
+        let new_peer = PeerCardDb {
+            pubkey: "11111111111111111111111111111111111111111111".to_owned(),
+            ..Default::default()
+        };
+
+        dal.save_peer(new_peer)?;
+
+        Ok(())
+    }
+}