diff --git a/Cargo.lock b/Cargo.lock
index 78d354aaf1a73f5b27113cf23af82c7e1ca5859f..858903e22f2d0276c99221cc59f0d650b2ba5d6a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1069,6 +1069,7 @@ dependencies = [
  "dubp",
  "duniter-dbs",
  "duniter-dbs-write-ops",
+ "duniter-gva",
  "duniter-gva-db-writer",
  "fast-threadpool",
  "rayon",
@@ -1192,7 +1193,6 @@ dependencies = [
  "duniter-dbs",
  "duniter-dbs-read-ops",
  "duniter-dbs-write-ops",
- "duniter-gva",
  "duniter-mempools",
  "duniter-module",
  "duniter-server",
@@ -1260,7 +1260,6 @@ dependencies = [
  "duniter-dbs-read-ops",
  "duniter-dbs-write-ops",
  "duniter-gva",
- "duniter-gva-dbs-reader",
  "duniter-mempools",
  "duniter-module",
  "fast-threadpool",
diff --git a/neon/native/src/server.rs b/neon/native/src/server.rs
index 70a46f68d8ab7f64ce5414150ff6756e04a6cb20..d1804c53fe75b7ea30397839c74ddab058208d38 100644
--- a/neon/native/src/server.rs
+++ b/neon/native/src/server.rs
@@ -21,7 +21,7 @@ use dubp::documents::{
 };
 use dubp::documents_parser::prelude::*;
 use dubp::{common::crypto::hashs::Hash, crypto::keys::ed25519::Ed25519KeyPair};
-use duniter_server::{DuniterConf, DuniterServer, GvaConf, PeerCardStringified};
+use duniter_server::{DuniterConf, DuniterServer, GvaConf};
 use neon::declare_types;
 use neon::prelude::*;
 use serde::{Deserialize, Serialize};
@@ -60,7 +60,7 @@ declare_types! {
                         .downcast::<JsString>()
                         .or_throw(&mut cx)?
                         .value();
-                    if std::env::var_os("DUNITER_MEMORY_ONLY") == Some("yes".into()) {
+                    if std::env::var_os("DUNITER_JS_TESTS") == Some("yes".into()) {
                         None
                     } else {
                         Some(PathBuf::from(home_path_str))
@@ -265,11 +265,11 @@ declare_types! {
                 Ok(txs_history) => {
                     let sent: Vec<_> = txs_history.sent
                         .into_iter()
-                        .map(|db_tx| DbTx::v10(db_tx.tx.to_string_object(), db_tx.tx.get_hash(), db_tx.written_block.number.0, db_tx.written_time))
+                        .map(|(tx, wb, wt)| DbTx::v10(tx.to_string_object(), tx.get_hash(), wb.number.0, wt))
                         .collect();
                     let received: Vec<_> = txs_history.received
                         .into_iter()
-                        .map(|db_tx| DbTx::v10(db_tx.tx.to_string_object(), db_tx.tx.get_hash(), db_tx.written_block.number.0, db_tx.written_time))
+                        .map(|(tx, wb, wt)| DbTx::v10(tx.to_string_object(), tx.get_hash(), wb.number.0, wt))
                         .collect();
                     let sending: Vec<_> = txs_history.sending.into_iter().map(|tx| tx.to_string_object()).collect();
                     let pending: Vec<_> = txs_history.pending.into_iter().map(|tx| tx.to_string_object()).collect();
@@ -354,12 +354,21 @@ declare_types! {
             let peer_js = cx.argument::<JsValue>(0)?;
 
             let peer_stringified: PeerCardStringified = neon_serde::from_value(&mut cx, peer_js)?;
+            let peer = duniter_server::PeerCardDbV1 {
+                version: peer_stringified.version,
+                currency: peer_stringified.currency,
+                pubkey: peer_stringified.pubkey,
+                blockstamp: peer_stringified.blockstamp,
+                endpoints: peer_stringified.endpoints,
+                status: peer_stringified.status,
+                signature: peer_stringified.signature,
+            };
 
             let this = cx.this();
             let res = {
                 let guard = cx.lock();
                 let server = this.borrow(&guard);
-                server.server.save_peer(peer_stringified)
+                server.server.save_peer(peer)
             }.map(|()| cx.undefined().upcast());
             into_neon_res(&mut cx, res)
         }
@@ -367,12 +376,21 @@ declare_types! {
             let peer_js = cx.argument::<JsValue>(0)?;
 
             let peer_stringified: PeerCardStringified = neon_serde::from_value(&mut cx, peer_js)?;
+            let peer = duniter_server::PeerCardDbV1 {
+                version: peer_stringified.version,
+                currency: peer_stringified.currency,
+                pubkey: peer_stringified.pubkey,
+                blockstamp: peer_stringified.blockstamp,
+                endpoints: peer_stringified.endpoints,
+                status: peer_stringified.status,
+                signature: peer_stringified.signature,
+            };
 
             let this = cx.this();
             {
                 let guard = cx.lock();
                 let server = this.borrow(&guard);
-                server.server.update_self_peer(peer_stringified)
+                server.server.update_self_peer(peer)
             };
             Ok(cx.undefined().upcast())
         }
@@ -430,6 +448,18 @@ struct HeadWS2Pv1ConfStringified {
     step: Option<usize>,
 }
 
+#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PeerCardStringified {
+    pub version: u32,
+    pub currency: String,
+    pub pubkey: String,
+    pub blockstamp: String,
+    pub endpoints: Vec<String>,
+    pub status: String,
+    pub signature: String,
+}
+
 #[derive(Deserialize, Serialize)]
 #[serde(rename_all = "camelCase")]
 struct RustServerConfStringified {
diff --git a/package.json b/package.json
index 278ff64a2ee384de76530478a3c5ac12c2e586cc..2d36f39908cc120a725a48bb247d1037f4530548 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,7 @@
     "tsc": "tsc",
     "tscw": "tsc -w",
     "doc": "typedoc --out typedoc/ index.ts app/ --mode file --readme README.md --includeDeclarations --sourcefile-url-prefix \"https://git.duniter.org/nodes/typescript/duniter/blob/loki/\"",
-    "test": "DUNITER_MEMORY_ONLY=yes DUNITER_LOG_STDOUT=no nyc --reporter html mocha",
+    "test": "DUNITER_JS_TESTS=yes DUNITER_LOG_STDOUT=no nyc --reporter html mocha",
     "start": "cargo run -- start",
     "build": "./neon/build.sh && cd.. && tsc && cd \"../node_modules/duniter-ui\" && npm install && npm run build",
     "install": "./neon/build.sh",
diff --git a/rust-bins/duniter-dbex/Cargo.toml b/rust-bins/duniter-dbex/Cargo.toml
index 1413631fd3c775b35edd0e707a5fa4165a15c746..4ca70ed24751d9afb73d678624bb5451ea6e0731 100644
--- a/rust-bins/duniter-dbex/Cargo.toml
+++ b/rust-bins/duniter-dbex/Cargo.toml
@@ -25,6 +25,7 @@ dirs = "3.0.1"
 dubp = { version = "0.32.3" }
 duniter-dbs = { path = "../../rust-libs/duniter-dbs", default-features = false, features = ["explorer", "leveldb_backend", "sled_backend"] }
 duniter-dbs-write-ops = { path = "../../rust-libs/duniter-dbs-write-ops", default-features = false, features = ["explorer", "leveldb_backend", "sled_backend"] }
+duniter-gva = { path = "../../rust-libs/modules/gva" }
 duniter-gva-db-writer = { path = "../../rust-libs/modules/gva/db-writer" }
 fast-threadpool = "0.2.2"
 rayon = "1.3.1"
diff --git a/rust-bins/duniter-dbex/src/migrate.rs b/rust-bins/duniter-dbex/src/migrate.rs
index b04f307825a438dbd6ffccc1c156d9c832d958cd..aba30ba3c6db70e20d8b704fa1d77bb02a29b0c0 100644
--- a/rust-bins/duniter-dbex/src/migrate.rs
+++ b/rust-bins/duniter-dbex/src/migrate.rs
@@ -26,16 +26,17 @@ const CHUNK_SIZE: usize = 250;
 
 pub(crate) fn migrate(profile_path: PathBuf) -> anyhow::Result<()> {
     let start_time = Instant::now();
-    let (bc_db, dbs) = duniter_dbs::open_dbs(Some(profile_path.as_path()));
+    let (bc_db, shared_dbs) = duniter_dbs::open_dbs(Some(profile_path.as_path()));
+    let gva_db = duniter_gva::GvaModule::get_gva_db_rw(Some(profile_path.as_path()));
 
     // Clear bc_db and gva_db
     bc_db.clear()?;
-    dbs.gva_db.clear()?;
+    gva_db.clear()?;
 
-    if let Err(e) = migrate_inner(&bc_db, dbs.clone(), profile_path, start_time) {
+    if let Err(e) = migrate_inner(&bc_db, gva_db, profile_path, shared_dbs, start_time) {
         // Clear bc_db and gva_db
         bc_db.clear()?;
-        dbs.gva_db.clear()?;
+        gva_db.clear()?;
 
         Err(e)
     } else {
@@ -45,8 +46,9 @@ pub(crate) fn migrate(profile_path: PathBuf) -> anyhow::Result<()> {
 
 fn migrate_inner(
     bc_db: &BcV2Db<FileBackend>,
-    dbs: DuniterDbs<FileBackend>,
+    gva_db: &'static GvaV1Db<FileBackend>,
     profile_path: PathBuf,
+    shared_dbs: SharedDbs<FileBackend>,
     start_time: Instant,
 ) -> anyhow::Result<()> {
     let data_path = profile_path.join(crate::DATA_DIR);
@@ -55,15 +57,10 @@ fn migrate_inner(
         ..Default::default()
     })?;
 
-    let dbs_pool = ThreadPool::start(ThreadPoolConfig::default(), dbs).into_sync_handler();
+    let dbs_pool = ThreadPool::start(ThreadPoolConfig::default(), shared_dbs).into_sync_handler();
 
     if let Some(target) = get_target_block_number(&duniter_js_db)? {
         println!("target block: #{}", target.0);
-        /*let chunk_count = if (target.0 as usize + 1) % CHUNK_SIZE == 0 {
-            (target.0 as usize + 1) / CHUNK_SIZE
-        } else {
-            (target.0 as usize / CHUNK_SIZE) + 1
-        };*/
 
         let (s, r) = std::sync::mpsc::channel();
         let reader_handle = std::thread::spawn(move || {
@@ -114,9 +111,9 @@ fn migrate_inner(
                 let chunk = Arc::from(chunk);
                 let chunk_arc_clone = Arc::clone(&chunk);
                 let gva_handle = dbs_pool
-                    .launch(move |dbs| {
+                    .launch(move |_| {
                         for block in chunk_arc_clone.deref() {
-                            duniter_gva_db_writer::apply_block(block, &dbs.gva_db)?;
+                            duniter_gva_db_writer::apply_block(block, gva_db)?;
                         }
                         Ok::<_, KvError>(())
                     })
@@ -135,10 +132,7 @@ fn migrate_inner(
 
         println!("Flush DBs caches on disk...");
         bc_db.save()?;
-        dbs_pool.execute(|dbs| {
-            dbs.gva_db.save()?;
-            Ok::<(), KvError>(())
-        })??;
+        gva_db.save()?;
 
         if let Some(current) = current {
             if current.number != target.0 {
diff --git a/rust-libs/duniter-dbs-write-ops/src/apply_block.rs b/rust-libs/duniter-dbs-write-ops/src/apply_block.rs
index 756d07b81cf83972d133d39feb4d87e0af5fbd06..12ba380fc4f27fa317357d98cb8e302787db5e6f 100644
--- a/rust-libs/duniter-dbs-write-ops/src/apply_block.rs
+++ b/rust-libs/duniter-dbs-write-ops/src/apply_block.rs
@@ -19,7 +19,7 @@ pub fn apply_block(
     bc_db: &BcV2Db<FileBackend>,
     block: Arc<DubpBlockV10>,
     current_opt: Option<BlockMetaV2>,
-    dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
+    dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
     throw_chainability: bool,
 ) -> KvResult<BlockMetaV2> {
     if let Some(current) = current_opt {
@@ -50,7 +50,7 @@ pub fn apply_block(
 pub fn apply_chunk(
     bc_db: &BcV2Db<FileBackend>,
     current_opt: Option<BlockMetaV2>,
-    dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
+    dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
     blocks: Arc<[DubpBlockV10]>,
 ) -> KvResult<BlockMetaV2> {
     verify_chunk_chainability(current_opt, &blocks)?;
@@ -103,7 +103,7 @@ fn verify_chunk_chainability(
 
 fn apply_block_inner(
     bc_db: &BcV2Db<FileBackend>,
-    dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
+    dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
     block: Arc<DubpBlockV10>,
 ) -> KvResult<BlockMetaV2> {
     let block_arc_clone = Arc::clone(&block);
@@ -126,7 +126,7 @@ fn apply_block_inner(
 
 fn apply_chunk_inner(
     bc_db: &BcV2Db<FileBackend>,
-    dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
+    dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
     blocks: Arc<[DubpBlockV10]>,
 ) -> KvResult<BlockMetaV2> {
     let blocks_len = blocks.len();
diff --git a/rust-libs/duniter-dbs-write-ops/src/lib.rs b/rust-libs/duniter-dbs-write-ops/src/lib.rs
index 607d90124538da8673bd820c0d97659394e377cd..405a35a899dba4cabf3acff6d3d80e22a1528e4b 100644
--- a/rust-libs/duniter-dbs-write-ops/src/lib.rs
+++ b/rust-libs/duniter-dbs-write-ops/src/lib.rs
@@ -42,7 +42,7 @@ use duniter_dbs::{
         txs_mp_v2::{TxsMpV2Db, TxsMpV2DbReadable, TxsMpV2DbWritable},
     },
     kv_typed::prelude::*,
-    BlockMetaV2, DuniterDbs, FileBackend, HashKeyV2, PendingTxDbV2, PubKeyKeyV2, PubKeyValV2,
+    BlockMetaV2, FileBackend, HashKeyV2, PendingTxDbV2, PubKeyKeyV2, PubKeyValV2, SharedDbs,
     SourceAmountValV2, UtxoValV2, WalletConditionsV2,
 };
 use resiter::filter_map::FilterMap;
diff --git a/rust-libs/duniter-dbs/src/lib.rs b/rust-libs/duniter-dbs/src/lib.rs
index ade5c98f01b25029c755c29234e72584b2f4ac1f..6ac199e37260abd7cf6d6099fd38ef15b8930f90 100644
--- a/rust-libs/duniter-dbs/src/lib.rs
+++ b/rust-libs/duniter-dbs/src/lib.rs
@@ -41,7 +41,7 @@ pub use kv_typed;
 // Prelude
 pub mod prelude {
     pub use crate::open_dbs::BackendConf;
-    pub use crate::DuniterDbs;
+    pub use crate::SharedDbs;
     #[cfg(feature = "explorer")]
     pub use kv_typed::explorer::{
         DbExplorable, EntryFound, ExplorerAction, ExplorerActionResponse, ValueCaptures,
@@ -116,26 +116,23 @@ pub type FileBackend = kv_typed::backend::sled::Sled;
 pub type FileBackend = kv_typed::backend::memory::Mem;
 
 #[derive(Clone, Debug)]
-pub struct DuniterDbs<B: Backend> {
+pub struct SharedDbs<B: Backend> {
     pub bc_db_ro: databases::bc_v2::BcV2DbRo<B>,
     pub cm_db: databases::cm_v1::CmV1Db<Mem>,
     pub dunp_db: databases::dunp_v1::DunpV1Db<B>,
-    pub gva_db: databases::gva_v1::GvaV1Db<B>,
     pub txs_mp_db: databases::txs_mp_v2::TxsMpV2Db<B>,
 }
 
-impl DuniterDbs<Mem> {
+impl SharedDbs<Mem> {
     pub fn mem() -> KvResult<Self> {
         use databases::bc_v2::BcV2DbWritable as _;
         use databases::cm_v1::CmV1DbWritable as _;
         use databases::dunp_v1::DunpV1DbWritable as _;
-        use databases::gva_v1::GvaV1DbWritable as _;
         use databases::txs_mp_v2::TxsMpV2DbWritable as _;
-        Ok(DuniterDbs {
+        Ok(SharedDbs {
             bc_db_ro: databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?.get_ro_handler(),
             cm_db: databases::cm_v1::CmV1Db::<Mem>::open(MemConf::default())?,
             dunp_db: databases::dunp_v1::DunpV1Db::<Mem>::open(MemConf::default())?,
-            gva_db: databases::gva_v1::GvaV1Db::<Mem>::open(MemConf::default())?,
             txs_mp_db: databases::txs_mp_v2::TxsMpV2Db::<Mem>::open(MemConf::default())?,
         })
     }
diff --git a/rust-libs/duniter-dbs/src/open_dbs.rs b/rust-libs/duniter-dbs/src/open_dbs.rs
index cc07815fa189743f6d7992b45f7f91ad5605f5b2..04ae6264a4cf3aaffb28bfe9a4e91dc2a3e48610 100644
--- a/rust-libs/duniter-dbs/src/open_dbs.rs
+++ b/rust-libs/duniter-dbs/src/open_dbs.rs
@@ -16,35 +16,29 @@
 use crate::databases::bc_v2::BcV2DbWritable as _;
 use crate::databases::cm_v1::CmV1DbWritable as _;
 use crate::databases::dunp_v1::DunpV1DbWritable as _;
-use crate::databases::gva_v1::GvaV1DbWritable as _;
 use crate::databases::txs_mp_v2::TxsMpV2DbWritable as _;
 use crate::*;
 
 pub fn open_dbs<B: BackendConf>(
-    home_path_opt: Option<&Path>,
-) -> (crate::databases::bc_v2::BcV2Db<B>, DuniterDbs<B>) {
+    profile_path_opt: Option<&Path>,
+) -> (crate::databases::bc_v2::BcV2Db<B>, SharedDbs<B>) {
     let bc_db = crate::databases::bc_v2::BcV2Db::<B>::open(B::gen_backend_conf(
         crate::databases::bc_v2::BcV2Db::<B>::NAME,
-        home_path_opt,
+        profile_path_opt,
     ))
     .expect("fail to open BcV2 DB");
-    let dbs = DuniterDbs {
+    let dbs = SharedDbs {
         bc_db_ro: bc_db.get_ro_handler(),
         cm_db: crate::databases::cm_v1::CmV1Db::<Mem>::open(MemConf::default())
             .expect("fail to open CmV1 DB"),
         dunp_db: crate::databases::dunp_v1::DunpV1Db::<B>::open(B::gen_backend_conf(
-            crate::databases::dunp_v1::DunpV1Db::<B>::NAME,
-            home_path_opt,
+            "dunp_v1",
+            profile_path_opt,
         ))
         .expect("fail to open Dunp DB"),
-        gva_db: crate::databases::gva_v1::GvaV1Db::<B>::open(B::gen_backend_conf(
-            crate::databases::gva_v1::GvaV1Db::<B>::NAME,
-            home_path_opt,
-        ))
-        .expect("fail to open Gva DB"),
         txs_mp_db: crate::databases::txs_mp_v2::TxsMpV2Db::<B>::open(B::gen_backend_conf(
             crate::databases::txs_mp_v2::TxsMpV2Db::<B>::NAME,
-            home_path_opt,
+            profile_path_opt,
         ))
         .expect("fail to open TxsMp DB"),
     };
@@ -54,22 +48,22 @@ pub fn open_dbs<B: BackendConf>(
 pub trait BackendConf: Backend {
     fn gen_backend_conf(
         db_name: &'static str,
-        home_path_opt: Option<&Path>,
+        profile_path_opt: Option<&Path>,
     ) -> <Self as Backend>::Conf;
 }
 
 impl BackendConf for Mem {
     #[inline(always)]
-    fn gen_backend_conf(_db_name: &'static str, _home_path_opt: Option<&Path>) -> MemConf {
+    fn gen_backend_conf(_db_name: &'static str, _profile_path_opt: Option<&Path>) -> MemConf {
         MemConf::default()
     }
 }
 
 /*impl BackendConf for Lmdb {
     #[inline(always)]
-    fn gen_backend_conf(db_name: &'static str, home_path_opt: Option<&Path>) -> LmdbConf {
+    fn gen_backend_conf(db_name: &'static str, profile_path_opt: Option<&Path>) -> LmdbConf {
         let conf = LmdbConf::default();
-        if let Some(data_path) = home_path_opt {
+        if let Some(data_path) = profile_path_opt {
             conf.folder_path(data_path.join(format!("data/{}_lmdb", db_name)))
         } else {
             let random = rand::random::<u128>();
@@ -84,7 +78,7 @@ impl BackendConf for Mem {
 
 impl BackendConf for Sled {
     #[inline(always)]
-    fn gen_backend_conf(db_name: &'static str, home_path_opt: Option<&Path>) -> SledConf {
+    fn gen_backend_conf(db_name: &'static str, profile_path_opt: Option<&Path>) -> SledConf {
         let mut conf = SledConf::default().flush_every_ms(Some(10_000));
         conf = match db_name {
             "bc_v2" => {
@@ -109,7 +103,7 @@ impl BackendConf for Sled {
             }
             _ => conf.use_compression(false),
         };
-        if let Some(data_path) = home_path_opt {
+        if let Some(data_path) = profile_path_opt {
             conf.path(data_path.join(format!("data/{}_sled", db_name)))
         } else {
             conf.temporary(true)
diff --git a/rust-libs/duniter-module/src/lib.rs b/rust-libs/duniter-module/src/lib.rs
index bc804f974535c55b21c40a3531fcdf147cd63a56..fbd440c2aa557f95a5fe66577a9b46a3e78dd636 100644
--- a/rust-libs/duniter-module/src/lib.rs
+++ b/rust-libs/duniter-module/src/lib.rs
@@ -22,9 +22,14 @@
     unused_import_braces
 )]
 
-use dubp::block::DubpBlockV10;
+use dubp::{
+    block::DubpBlockV10,
+    common::prelude::{BlockNumber, Blockstamp},
+    crypto::{hashs::Hash, keys::ed25519::PublicKey},
+    documents::transaction::TransactionDocumentV10,
+};
 use duniter_conf::DuniterConf;
-use duniter_dbs::{kv_typed::prelude::*, DuniterDbs, FileBackend};
+use duniter_dbs::{kv_typed::prelude::*, FileBackend, SharedDbs};
 use duniter_mempools::Mempools;
 use fast_threadpool::{JoinHandle, ThreadPoolDisconnected};
 use std::path::Path;
@@ -38,7 +43,7 @@ pub trait DuniterModule: 'static + Sized {
     fn apply_block(
         _block: Arc<DubpBlockV10>,
         _conf: &duniter_conf::DuniterConf,
-        _dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
+        _dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
         _profile_path_opt: Option<&Path>,
     ) -> Result<Option<JoinHandle<KvResult<()>>>, ThreadPoolDisconnected> {
         Ok(None)
@@ -47,7 +52,7 @@ pub trait DuniterModule: 'static + Sized {
     fn apply_chunk_of_blocks(
         _blocks: Arc<[DubpBlockV10]>,
         _conf: &duniter_conf::DuniterConf,
-        _dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
+        _dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
         _profile_path_opt: Option<&Path>,
     ) -> Result<Option<JoinHandle<KvResult<()>>>, ThreadPoolDisconnected> {
         Ok(None)
@@ -56,7 +61,7 @@ pub trait DuniterModule: 'static + Sized {
     fn revert_block(
         _block: Arc<DubpBlockV10>,
         _conf: &duniter_conf::DuniterConf,
-        _dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
+        _dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
         _profile_path_opt: Option<&Path>,
     ) -> Result<Option<JoinHandle<KvResult<()>>>, ThreadPoolDisconnected> {
         Ok(None)
@@ -65,25 +70,54 @@ pub trait DuniterModule: 'static + Sized {
     fn init(
         conf: &DuniterConf,
         currency: &str,
-        dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<DuniterDbs<FileBackend>>,
+        dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
         mempools: Mempools,
         profile_path_opt: Option<&Path>,
         software_version: &'static str,
     ) -> anyhow::Result<(Self, Vec<Endpoint>)>;
 
     async fn start(self) -> anyhow::Result<()>;
+
+    // Needed for BMA only, will be removed when the migration is complete.
+    #[doc(hidden)]
+    fn get_transactions_history_for_bma(
+        _dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
+        _profile_path_opt: Option<&Path>,
+        _pubkey: PublicKey,
+    ) -> KvResult<Option<TxsHistoryForBma>> {
+        Ok(None)
+    }
+    // Needed for BMA only, will be removed when the migration is complete.
+    #[doc(hidden)]
+    fn get_tx_by_hash(
+        _dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
+        _hash: Hash,
+        _profile_path_opt: Option<&Path>,
+    ) -> KvResult<Option<(TransactionDocumentV10, Option<BlockNumber>)>> {
+        Ok(None)
+    }
+}
+
+// Needed for BMA only, will be removed when the migration is complete.
+#[doc(hidden)]
+#[derive(Default)]
+pub struct TxsHistoryForBma {
+    pub sent: Vec<(TransactionDocumentV10, Blockstamp, i64)>,
+    pub received: Vec<(TransactionDocumentV10, Blockstamp, i64)>,
+    pub sending: Vec<TransactionDocumentV10>,
+    pub pending: Vec<TransactionDocumentV10>,
 }
 
 #[macro_export]
 macro_rules! plug_duniter_modules {
-    ([$($M:ty),*]) => {
+    ([$($M:ty),*], $TxsHistoryForBma:ident) => {
         paste::paste! {
             use anyhow::Context as _;
             #[allow(dead_code)]
             fn apply_block_modules(
                 block: Arc<DubpBlockV10>,
                 conf: &duniter_conf::DuniterConf,
-                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
+                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
                 profile_path_opt: Option<&Path>,
             ) -> KvResult<()> {
                 $(
@@ -100,7 +134,7 @@ macro_rules! plug_duniter_modules {
             fn apply_chunk_of_blocks_modules(
                 blocks: Arc<[DubpBlockV10]>,
                 conf: &duniter_conf::DuniterConf,
-                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
+                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
                 profile_path_opt: Option<&Path>,
             ) -> KvResult<()> {
                 $(
@@ -117,7 +151,7 @@ macro_rules! plug_duniter_modules {
             fn revert_block_modules(
                 block: Arc<DubpBlockV10>,
                 conf: &duniter_conf::DuniterConf,
-                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
+                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
                 profile_path_opt: Option<&Path>,
             ) -> KvResult<()> {
                 $(
@@ -133,7 +167,7 @@ macro_rules! plug_duniter_modules {
             async fn start_duniter_modules(
                 conf: &DuniterConf,
                 currency: String,
-                dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<DuniterDbs<FileBackend>>,
+                dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
                 mempools: duniter_mempools::Mempools,
                 profile_path_opt: Option<std::path::PathBuf>,
                 software_version: &'static str,
@@ -171,6 +205,37 @@ macro_rules! plug_duniter_modules {
 
                 Ok(())
             }
+
+            // Needed for BMA only, will be removed when the migration is complete.
+            #[allow(dead_code)]
+            #[doc(hidden)]
+            fn get_transactions_history_for_bma(
+                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
+                profile_path_opt: Option<&Path>,
+                pubkey: PublicKey,
+            ) -> KvResult<TxsHistoryForBma> {
+                $(
+                    if let Some(txs_history) = <$M>::get_transactions_history_for_bma(dbs_pool, profile_path_opt, pubkey)? {
+                        return Ok(txs_history);
+                    }
+                )*
+                Ok(TxsHistoryForBma::default())
+            }
+            // Needed for BMA only, will be removed when the migration is complete.
+            #[allow(dead_code)]
+            #[doc(hidden)]
+            fn get_tx_by_hash(
+                dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
+                hash: Hash,
+                profile_path_opt: Option<&Path>,
+            ) -> KvResult<Option<(TransactionDocumentV10, Option<BlockNumber>)>> {
+                $(
+                    if let Some(tx_with_wb) = <$M>::get_tx_by_hash(dbs_pool, hash, profile_path_opt)? {
+                        return Ok(Some(tx_with_wb));
+                    }
+                )*
+                Ok(None)
+            }
         }
     };
 }
@@ -187,7 +252,7 @@ mod tests {
         fn init(
             _conf: &DuniterConf,
             _currency: &str,
-            _dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<DuniterDbs<FileBackend>>,
+            _dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
             _mempools: Mempools,
             profile_path_opt: Option<&Path>,
             _software_version: &'static str,
@@ -210,7 +275,7 @@ mod tests {
         fn init(
             _conf: &DuniterConf,
             _currency: &str,
-            _dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<DuniterDbs<FileBackend>>,
+            _dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
             _mempools: Mempools,
             _profile_path_opt: Option<&Path>,
             _software_version: &'static str,
@@ -225,9 +290,9 @@ mod tests {
 
     #[tokio::test]
     async fn test_macro_plug_duniter_modules() -> anyhow::Result<()> {
-        plug_duniter_modules!([TestMod1, TestMod2]);
+        plug_duniter_modules!([TestMod1, TestMod2], TxsHistoryForBma);
 
-        let dbs = DuniterDbs::mem()?;
+        let dbs = SharedDbs::mem()?;
         let threadpool =
             fast_threadpool::ThreadPool::start(fast_threadpool::ThreadPoolConfig::default(), dbs);
 
diff --git a/rust-libs/duniter-server/Cargo.toml b/rust-libs/duniter-server/Cargo.toml
index f3e120d72cd16e335e12c0649323463c9e85a255..6a608039f0ea2c3ef7189a408a949910e9b17113 100644
--- a/rust-libs/duniter-server/Cargo.toml
+++ b/rust-libs/duniter-server/Cargo.toml
@@ -13,8 +13,7 @@ duniter-conf = { path = "../duniter-conf" }
 duniter-dbs = { path = "../duniter-dbs" }
 duniter-dbs-read-ops = { path = "../duniter-dbs-read-ops" }
 duniter-dbs-write-ops = { path = "../duniter-dbs-write-ops" }
-duniter-gva = { path = "../modules/gva" }
-duniter-gva-dbs-reader = { path = "../modules/gva/dbs-reader" }
+duniter-gva = { path = "../modules/gva", optional = true }
 duniter-mempools = { path = "../duniter-mempools" }
 duniter-module = { path = "../duniter-module" }
 fast-threadpool = "0.2.2"
@@ -24,5 +23,10 @@ paste = "1.0.2"
 resiter = "0.4.0"
 tokio = { version = "0.2.22", features = ["io-util", "rt-threaded"] }
 
+[features]
+default = ["gva"]
+
+gva = ["duniter-gva"]
+
 [dev-dependencies]
 duniter-dbs = { path = "../duniter-dbs", features = ["mem"] }
diff --git a/rust-libs/duniter-server/src/legacy/dunp.rs b/rust-libs/duniter-server/src/legacy/dunp.rs
index 020e32e708c84dab381d57739c0bee5f08a88ec8..44c9552e3c9b889856b951b650dacfa15b8ec56e 100644
--- a/rust-libs/duniter-server/src/legacy/dunp.rs
+++ b/rust-libs/duniter-server/src/legacy/dunp.rs
@@ -43,7 +43,7 @@ impl DuniterServer {
             .execute(move |dbs| dbs.dunp_db.peers_old_write().remove(PubKeyKeyV2(pubkey)))
             .expect("dbs pool disconnected")
     }
-    pub fn save_peer(&self, new_peer_card: PeerCardStringified) -> anyhow::Result<()> {
+    pub fn save_peer(&self, new_peer_card: PeerCardDbV1) -> anyhow::Result<()> {
         use dubp::crypto::keys::PublicKey as _;
         let pubkey = PublicKey::from_base58(&new_peer_card.pubkey)?;
         use duniter_dbs::databases::dunp_v1::DunpV1DbWritable as _;
@@ -65,23 +65,12 @@ impl DuniterServer {
             .expect("dbs pool disconnected")
             .map_err(|e| e.into())
     }
-    pub fn update_self_peer(&self, new_peer_card: PeerCardStringified) {
+    pub fn update_self_peer(&self, new_peer_card: PeerCardDbV1) {
         self.dbs_pool
             .execute(move |dbs| {
                 dbs.cm_db
                     .self_peer_old_write()
-                    .upsert(
-                        (),
-                        duniter_dbs::PeerCardDbV1 {
-                            version: new_peer_card.version,
-                            currency: new_peer_card.currency,
-                            pubkey: new_peer_card.pubkey,
-                            blockstamp: new_peer_card.blockstamp,
-                            endpoints: new_peer_card.endpoints,
-                            status: new_peer_card.status,
-                            signature: new_peer_card.signature,
-                        },
-                    )
+                    .upsert((), new_peer_card)
                     .expect("fail to write on memory db")
             })
             .expect("dbs pool disconnected")
@@ -131,7 +120,7 @@ mod tests {
         use duniter_dbs::databases::dunp_v1::DunpV1DbReadable as _;
         let (server, dbs) = DuniterServer::test(DuniterConf::default())?;
 
-        let peer = PeerCardStringified {
+        let peer = PeerCardDbV1 {
             version: 0,
             currency: "test".to_owned(),
             pubkey: "82NdD9eEbXSjRJXeJdqf56xkpu6taTfTeEqtAtmtbyXY".to_owned(),
@@ -148,18 +137,7 @@ mod tests {
         assert_eq!(dbs.dunp_db.peers_old().count()?, 1);
         let peer_db = dbs.dunp_db.peers_old().get(&PubKeyKeyV2(pubkey))?;
 
-        assert_eq!(
-            peer_db,
-            Some(PeerCardDbV1 {
-                version: peer.version,
-                currency: peer.currency,
-                pubkey: peer.pubkey,
-                blockstamp: peer.blockstamp,
-                endpoints: peer.endpoints,
-                status: peer.status,
-                signature: peer.signature,
-            })
-        );
+        assert_eq!(peer_db, Some(peer));
 
         Ok(())
     }
diff --git a/rust-libs/duniter-server/src/legacy/tx_history.rs b/rust-libs/duniter-server/src/legacy/tx_history.rs
index 4c55b2fc03f01f495b4af5edffe09b5fc0fcc631..e06cf4445bde9a1f3816fa09b873803fe8a2aead 100644
--- a/rust-libs/duniter-server/src/legacy/tx_history.rs
+++ b/rust-libs/duniter-server/src/legacy/tx_history.rs
@@ -16,32 +16,14 @@
 use crate::*;
 
 impl DuniterServer {
-    pub fn get_transactions_history(&self, pubkey: PublicKey) -> KvResult<TxsHistory> {
-        self.dbs_pool
-            .execute(move |dbs| {
-                duniter_gva_dbs_reader::txs_history::get_transactions_history_for_bma(
-                    &dbs.gva_db,
-                    &dbs.txs_mp_db,
-                    pubkey,
-                )
-            })
-            .expect("dbs pool disconnected")
+    pub fn get_transactions_history(&self, pubkey: PublicKey) -> KvResult<TxsHistoryForBma> {
+        get_transactions_history_for_bma(&self.dbs_pool, self.profile_path_opt.as_deref(), pubkey)
     }
 
     pub fn get_tx_by_hash(
         &self,
         hash: Hash,
     ) -> KvResult<Option<(TransactionDocumentV10, Option<BlockNumber>)>> {
-        self.dbs_pool
-            .execute(move |dbs| {
-                if let Some(tx) = dbs.txs_mp_db.txs().get(&HashKeyV2(hash))? {
-                    Ok(Some((tx.0, None)))
-                } else if let Some(tx_db) = dbs.gva_db.txs().get(&HashKeyV2(hash))? {
-                    Ok(Some((tx_db.tx, Some(tx_db.written_block.number))))
-                } else {
-                    Ok(None)
-                }
-            })
-            .expect("dbs pool disconnected")
+        get_tx_by_hash(&self.dbs_pool, hash, self.profile_path_opt.as_deref())
     }
 }
diff --git a/rust-libs/duniter-server/src/lib.rs b/rust-libs/duniter-server/src/lib.rs
index 900ac5f02871025f61a46af69b42dca792921e13..1188466784a9db47d79ec262784189294bd8f11d 100644
--- a/rust-libs/duniter-server/src/lib.rs
+++ b/rust-libs/duniter-server/src/lib.rs
@@ -24,9 +24,12 @@
 
 mod legacy;
 
-pub use duniter_conf::DuniterConf;
-pub use duniter_dbs::{kv_typed::prelude::KvResult, smallvec, DunpHeadDbV1, DunpNodeIdV1Db};
-pub use duniter_gva::{GvaConf, GvaModule, PeerCardStringified};
+pub use duniter_conf::{gva_conf::GvaConf, DuniterConf};
+pub use duniter_dbs::{
+    kv_typed::prelude::KvResult, smallvec, DunpHeadDbV1, DunpNodeIdV1Db, PeerCardDbV1,
+};
+#[cfg(feature = "gva")]
+pub use duniter_gva::GvaModule;
 
 use anyhow::Context;
 use dubp::common::crypto::keys::ed25519::PublicKey;
@@ -39,19 +42,29 @@ use duniter_dbs::{
     databases::{
         bc_v2::BcV2Db,
         cm_v1::{CmV1DbReadable, CmV1DbWritable},
-        gva_v1::GvaV1DbReadable,
         txs_mp_v2::TxsMpV2DbReadable,
     },
     kv_typed::prelude::*,
-    HashKeyV2, PendingTxDbV2, PubKeyKeyV2,
+    PendingTxDbV2, PubKeyKeyV2,
 };
 use duniter_dbs::{prelude::*, BlockMetaV2, FileBackend};
-use duniter_gva_dbs_reader::txs_history::TxsHistory;
 use duniter_mempools::{Mempools, TxMpError, TxsMempool};
-use duniter_module::{plug_duniter_modules, DuniterModule as _, Endpoint};
+use duniter_module::{plug_duniter_modules, Endpoint, TxsHistoryForBma};
 use fast_threadpool::ThreadPoolConfig;
 use resiter::filter::Filter;
-use std::{collections::BTreeMap, path::Path};
+use std::{
+    collections::BTreeMap,
+    path::{Path, PathBuf},
+};
+
+cfg_if::cfg_if! {
+    if #[cfg(feature = "gva")] {
+        use duniter_module::DuniterModule as _;
+        plug_duniter_modules!([GvaModule], TxsHistoryForBma);
+    } else {
+        plug_duniter_modules!([], TxsHistoryForBma);
+    }
+}
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 pub enum DuniterCommand {
@@ -63,18 +76,17 @@ pub struct DuniterServer {
     bc_db: BcV2Db<FileBackend>,
     conf: DuniterConf,
     current: Option<BlockMetaV2>,
-    dbs_pool: fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
+    dbs_pool: fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
     pending_txs_subscriber:
         flume::Receiver<Arc<Events<duniter_dbs::databases::txs_mp_v2::TxsEvent>>>,
+    profile_path_opt: Option<PathBuf>,
     txs_mempool: TxsMempool,
 }
 
-plug_duniter_modules!([GvaModule]);
-
 #[cfg(not(test))]
 type DuniterServerInstance = DuniterServer;
 #[cfg(test)]
-type DuniterServerInstance = (DuniterServer, DuniterDbs<FileBackend>);
+type DuniterServerInstance = (DuniterServer, SharedDbs<FileBackend>);
 
 impl DuniterServer {
     #[cfg(test)]
@@ -91,7 +103,7 @@ impl DuniterServer {
         command_name: Option<String>,
         conf: DuniterConf,
         currency: String,
-        home_path_opt: Option<&Path>,
+        profile_path_opt: Option<&Path>,
         software_version: &'static str,
     ) -> anyhow::Result<DuniterServerInstance> {
         let command = match command_name.unwrap_or_default().as_str() {
@@ -102,7 +114,7 @@ impl DuniterServer {
         let txs_mempool = TxsMempool::new(conf.txs_mempool_size);
 
         log::info!("open duniter databases...");
-        let (bc_db, dbs) = duniter_dbs::open_dbs(home_path_opt);
+        let (bc_db, dbs) = duniter_dbs::open_dbs(profile_path_opt);
         log::info!("Databases successfully opened.");
         let current = duniter_dbs_read_ops::get_current_block_meta(&dbs.bc_db_ro)
             .context("Fail to get current")?;
@@ -118,45 +130,34 @@ impl DuniterServer {
             .subscribe(s)
             .context("Fail to subscribe to txs col")?;
 
-        let threadpool = if home_path_opt.is_some() {
-            log::info!("start dbs threadpool...");
-
-            #[cfg(test)]
-            let threadpool =
-                fast_threadpool::ThreadPool::start(ThreadPoolConfig::default(), dbs.clone());
-            #[cfg(not(test))]
-            let threadpool = fast_threadpool::ThreadPool::start(ThreadPoolConfig::default(), dbs);
-
-            if command != DuniterCommand::Sync && conf.gva.is_some() {
-                let mut runtime = tokio::runtime::Builder::new()
-                    .threaded_scheduler()
-                    .enable_all()
-                    .build()?;
-                let conf_clone = conf.clone();
-                let threadpool_async_handler = threadpool.async_handler();
-                std::thread::spawn(move || {
-                    runtime
-                        .block_on(start_duniter_modules(
-                            &conf_clone,
-                            currency,
-                            threadpool_async_handler,
-                            Mempools { txs: txs_mempool },
-                            None,
-                            software_version,
-                        ))
-                        .context("Fail to start duniter modules")
-                });
-            }
-            threadpool
-        } else {
-            cfg_if::cfg_if! {
-                if #[cfg(test)] {
-                    fast_threadpool::ThreadPool::start(ThreadPoolConfig::low(), dbs.clone())
-                } else {
-                    fast_threadpool::ThreadPool::start(ThreadPoolConfig::low(), dbs)
-                }
-            }
-        };
+        log::info!("start dbs threadpool...");
+
+        #[cfg(test)]
+        let threadpool =
+            fast_threadpool::ThreadPool::start(ThreadPoolConfig::default(), dbs.clone());
+        #[cfg(not(test))]
+        let threadpool = fast_threadpool::ThreadPool::start(ThreadPoolConfig::default(), dbs);
+
+        if command != DuniterCommand::Sync && conf.gva.is_some() {
+            let mut runtime = tokio::runtime::Builder::new()
+                .threaded_scheduler()
+                .enable_all()
+                .build()?;
+            let conf_clone = conf.clone();
+            let threadpool_async_handler = threadpool.async_handler();
+            std::thread::spawn(move || {
+                runtime
+                    .block_on(start_duniter_modules(
+                        &conf_clone,
+                        currency,
+                        threadpool_async_handler,
+                        Mempools { txs: txs_mempool },
+                        None,
+                        software_version,
+                    ))
+                    .context("Fail to start duniter modules")
+            });
+        }
 
         let duniter_server = DuniterServer {
             bc_db,
@@ -164,6 +165,7 @@ impl DuniterServer {
             current,
             dbs_pool: threadpool.into_sync_handler(),
             pending_txs_subscriber,
+            profile_path_opt: profile_path_opt.map(ToOwned::to_owned),
             txs_mempool,
         };
         cfg_if::cfg_if! {
diff --git a/rust-libs/modules/gva/src/entities.rs b/rust-libs/modules/gva/src/entities.rs
index 6aac30cd2524c60472109e77d0009ebec6230512..7eda554e30eda08e123bef2be82430788e182877 100644
--- a/rust-libs/modules/gva/src/entities.rs
+++ b/rust-libs/modules/gva/src/entities.rs
@@ -29,6 +29,31 @@ pub(crate) struct AmountWithBase {
     pub(crate) base: i32,
 }
 
+#[derive(Default, async_graphql::SimpleObject)]
+#[graphql(name = "Peer")]
+pub struct PeerCardGva {
+    pub version: u32,
+    pub currency: String,
+    pub pubkey: String,
+    pub blockstamp: String,
+    pub endpoints: Vec<String>,
+    pub status: String,
+    pub signature: String,
+}
+impl From<duniter_dbs::PeerCardDbV1> for PeerCardGva {
+    fn from(peer: duniter_dbs::PeerCardDbV1) -> Self {
+        Self {
+            version: peer.version,
+            currency: peer.currency,
+            pubkey: peer.pubkey,
+            blockstamp: peer.blockstamp,
+            endpoints: peer.endpoints,
+            status: peer.status,
+            signature: peer.signature,
+        }
+    }
+}
+
 pub(crate) enum RawTxOrChanges {
     FinalTx(String),
     Changes(Vec<String>),
diff --git a/rust-libs/modules/gva/src/lib.rs b/rust-libs/modules/gva/src/lib.rs
index 5328f9338431fc1995eb1f650e6b11d77d4093fe..ce60e01d342dcb28a06987ac4117421f56961b81 100644
--- a/rust-libs/modules/gva/src/lib.rs
+++ b/rust-libs/modules/gva/src/lib.rs
@@ -38,7 +38,7 @@ mod warp_;
 use crate::entities::{
     tx_gva::TxGva,
     ud_gva::{CurrentUdGva, RevalUdGva, UdGva},
-    AggregateSum, AmountWithBase, RawTxOrChanges, Sum, TxsHistoryGva, UtxoGva,
+    AggregateSum, AmountWithBase, PeerCardGva, RawTxOrChanges, Sum, TxsHistoryGva, UtxoGva,
 };
 use crate::inputs::{TxIssuer, TxRecipient, UdsFilter};
 use crate::inputs_validators::TxCommentValidator;
@@ -50,14 +50,17 @@ use crate::tests::create_dbs_reader;
 use crate::tests::DbsReader;
 use async_graphql::http::GraphQLPlaygroundConfig;
 use async_graphql::validators::{IntGreaterThan, ListMinLength, StringMaxLength, StringMinLength};
-use dubp::block::DubpBlockV10;
 use dubp::common::crypto::keys::{ed25519::PublicKey, KeyPair as _, PublicKey as _};
 use dubp::common::prelude::*;
 use dubp::documents::prelude::*;
 use dubp::documents::transaction::{TransactionDocumentTrait, TransactionDocumentV10};
 use dubp::documents_parser::prelude::*;
 use dubp::wallet::prelude::*;
-use duniter_dbs::databases::{gva_v1::GvaV1DbRo, txs_mp_v2::TxsMpV2DbReadable};
+use dubp::{block::DubpBlockV10, crypto::hashs::Hash};
+use duniter_dbs::databases::{
+    gva_v1::{GvaV1Db, GvaV1DbReadable, GvaV1DbRo, GvaV1DbWritable},
+    txs_mp_v2::TxsMpV2DbReadable,
+};
 use duniter_dbs::prelude::*;
 use duniter_dbs::{kv_typed::prelude::*, FileBackend, TxDbV2};
 #[cfg(not(test))]
@@ -77,18 +80,15 @@ use warp::{http::Response as HttpResponse, Filter as _, Rejection, Stream};
 
 static GVA_DB_RO: once_cell::sync::OnceCell<GvaV1DbRo<FileBackend>> =
     once_cell::sync::OnceCell::new();
-/*static GVA_DB_RW: once_cell::sync::OnceCell<GvaV1Db<FileBackend>> =
+static GVA_DB_RW: once_cell::sync::OnceCell<GvaV1Db<FileBackend>> =
     once_cell::sync::OnceCell::new();
 
-fn get_gva_db() -> &GvaV1Db<FileBackend> {
-    todo!() //ESZ
-}*/
-
 #[derive(Debug)]
 pub struct GvaModule {
     conf: Option<GvaConf>,
     currency: String,
-    dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<DuniterDbs<FileBackend>>,
+    dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
+    gva_db_ro: &'static GvaV1DbRo<FileBackend>,
     mempools: Mempools,
     self_pubkey: PublicKey,
     software_version: &'static str,
@@ -99,12 +99,13 @@ impl duniter_module::DuniterModule for GvaModule {
     fn apply_block(
         block: Arc<DubpBlockV10>,
         conf: &duniter_conf::DuniterConf,
-        dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
-        _profile_path_opt: Option<&Path>,
+        dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
+        profile_path_opt: Option<&Path>,
     ) -> Result<Option<JoinHandle<KvResult<()>>>, ThreadPoolDisconnected> {
+        let gva_db = GvaModule::get_gva_db_rw(profile_path_opt);
         if conf.gva.is_some() {
-            Ok(Some(dbs_pool.launch(move |dbs| {
-                duniter_gva_db_writer::apply_block(&block, &dbs.gva_db)
+            Ok(Some(dbs_pool.launch(move |_| {
+                duniter_gva_db_writer::apply_block(&block, gva_db)
             })?))
         } else {
             Ok(None)
@@ -113,13 +114,14 @@ impl duniter_module::DuniterModule for GvaModule {
     fn apply_chunk_of_blocks(
         blocks: Arc<[DubpBlockV10]>,
         conf: &duniter_conf::DuniterConf,
-        dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
-        _profile_path_opt: Option<&Path>,
+        dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
+        profile_path_opt: Option<&Path>,
     ) -> Result<Option<JoinHandle<KvResult<()>>>, ThreadPoolDisconnected> {
+        let gva_db = GvaModule::get_gva_db_rw(profile_path_opt);
         if conf.gva.is_some() {
-            Ok(Some(dbs_pool.launch(move |dbs| {
+            Ok(Some(dbs_pool.launch(move |_| {
                 for block in blocks.deref() {
-                    duniter_gva_db_writer::apply_block(&block, &dbs.gva_db)?;
+                    duniter_gva_db_writer::apply_block(&block, gva_db)?;
                 }
                 Ok::<_, KvError>(())
             })?))
@@ -130,12 +132,13 @@ impl duniter_module::DuniterModule for GvaModule {
     fn revert_block(
         block: Arc<DubpBlockV10>,
         conf: &duniter_conf::DuniterConf,
-        dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<DuniterDbs<FileBackend>>,
-        _profile_path_opt: Option<&Path>,
+        dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
+        profile_path_opt: Option<&Path>,
     ) -> Result<Option<JoinHandle<KvResult<()>>>, ThreadPoolDisconnected> {
+        let gva_db = GvaModule::get_gva_db_rw(profile_path_opt);
         if conf.gva.is_some() {
-            Ok(Some(dbs_pool.launch(move |dbs| {
-                duniter_gva_db_writer::revert_block(&block, &dbs.gva_db)
+            Ok(Some(dbs_pool.launch(move |_| {
+                duniter_gva_db_writer::revert_block(&block, gva_db)
             })?))
         } else {
             Ok(None)
@@ -144,9 +147,9 @@ impl duniter_module::DuniterModule for GvaModule {
     fn init(
         conf: &duniter_conf::DuniterConf,
         currency: &str,
-        dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<DuniterDbs<FileBackend>>,
+        dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
         mempools: Mempools,
-        _profile_path_opt: Option<&std::path::Path>,
+        profile_path_opt: Option<&Path>,
         software_version: &'static str,
     ) -> anyhow::Result<(Self, Vec<duniter_module::Endpoint>)> {
         let mut endpoints = Vec::new();
@@ -180,6 +183,7 @@ impl duniter_module::DuniterModule for GvaModule {
                 conf: conf.gva.to_owned(),
                 currency: currency.to_owned(),
                 dbs_pool: dbs_pool.to_owned(),
+                gva_db_ro: GvaModule::get_gva_db_ro(profile_path_opt),
                 mempools,
                 self_pubkey: conf.self_key_pair.public_key(),
                 software_version,
@@ -189,44 +193,118 @@ impl duniter_module::DuniterModule for GvaModule {
     }
 
     async fn start(self) -> anyhow::Result<()> {
-        let GvaModule {
-            conf,
-            currency,
-            dbs_pool,
-            mempools,
-            self_pubkey,
-            software_version,
-        } = self;
-
-        if let Some(conf) = conf {
-            GvaModule::start_inner(
+        // Do not start GVA server on js tests
+        if std::env::var_os("DUNITER_JS_TESTS") != Some("yes".into()) {
+            let GvaModule {
                 conf,
                 currency,
                 dbs_pool,
+                gva_db_ro,
                 mempools,
                 self_pubkey,
                 software_version,
-            )
-            .await
+            } = self;
+
+            if let Some(conf) = conf {
+                GvaModule::start_inner(
+                    conf,
+                    currency,
+                    dbs_pool,
+                    gva_db_ro,
+                    mempools,
+                    self_pubkey,
+                    software_version,
+                )
+                .await
+            }
         }
         Ok(())
     }
+    // Needed for BMA only, will be removed when the migration is complete.
+    fn get_transactions_history_for_bma(
+        dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
+        profile_path_opt: Option<&Path>,
+        pubkey: PublicKey,
+    ) -> KvResult<Option<duniter_module::TxsHistoryForBma>> {
+        let gva_db = GvaModule::get_gva_db_ro(profile_path_opt);
+        let duniter_gva_dbs_reader::txs_history::TxsHistory {
+            sent,
+            received,
+            sending,
+            pending,
+        } = dbs_pool
+            .execute(move |dbs| {
+                duniter_gva_dbs_reader::txs_history::get_transactions_history_for_bma(
+                    gva_db,
+                    &dbs.txs_mp_db,
+                    pubkey,
+                )
+            })
+            .expect("dbs pool disconnected")?;
+        Ok(Some(duniter_module::TxsHistoryForBma {
+            sent: sent
+                .into_iter()
+                .map(
+                    |TxDbV2 {
+                         tx,
+                         written_block,
+                         written_time,
+                     }| (tx, written_block, written_time),
+                )
+                .collect(),
+            received: received
+                .into_iter()
+                .map(
+                    |TxDbV2 {
+                         tx,
+                         written_block,
+                         written_time,
+                     }| (tx, written_block, written_time),
+                )
+                .collect(),
+            sending,
+            pending,
+        }))
+    }
+    // Needed for BMA only, will be removed when the migration is complete.
+    fn get_tx_by_hash(
+        dbs_pool: &fast_threadpool::ThreadPoolSyncHandler<SharedDbs<FileBackend>>,
+        hash: Hash,
+        profile_path_opt: Option<&Path>,
+    ) -> KvResult<Option<(TransactionDocumentV10, Option<BlockNumber>)>> {
+        let gva_db = GvaModule::get_gva_db_ro(profile_path_opt);
+        dbs_pool
+            .execute(move |dbs| {
+                if let Some(tx) = dbs.txs_mp_db.txs().get(&duniter_dbs::HashKeyV2(hash))? {
+                    Ok(Some((tx.0, None)))
+                } else if let Some(tx_db) = gva_db.txs().get(&duniter_dbs::HashKeyV2(hash))? {
+                    Ok(Some((tx_db.tx, Some(tx_db.written_block.number))))
+                } else {
+                    Ok(None)
+                }
+            })
+            .expect("dbs pool disconnected")
+    }
 }
 
 impl GvaModule {
-    async fn get_gva_db_ro(
-        dbs_pool: &fast_threadpool::ThreadPoolAsyncHandler<DuniterDbs<FileBackend>>,
-    ) -> &'static GvaV1DbRo<FileBackend> {
+    fn get_gva_db_ro(profile_path_opt: Option<&Path>) -> &'static GvaV1DbRo<FileBackend> {
         use duniter_dbs::databases::gva_v1::GvaV1DbWritable as _;
-        dbs_pool
-            .execute(|dbs| GVA_DB_RO.get_or_init(|| dbs.gva_db.get_ro_handler()))
-            .await
-            .expect("dbs pool disconnected")
+        GVA_DB_RO.get_or_init(|| GvaModule::get_gva_db_rw(profile_path_opt).get_ro_handler())
+    }
+    pub fn get_gva_db_rw(profile_path_opt: Option<&Path>) -> &'static GvaV1Db<FileBackend> {
+        GVA_DB_RW.get_or_init(|| {
+            duniter_dbs::databases::gva_v1::GvaV1Db::<FileBackend>::open(
+                FileBackend::gen_backend_conf("gva_v1", profile_path_opt),
+            )
+            .expect("Fail to open GVA DB")
+        })
     }
     async fn start_inner(
         conf: GvaConf,
         currency: String,
-        dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<DuniterDbs<FileBackend>>,
+        dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
+        gva_db_ro: &'static GvaV1DbRo<FileBackend>,
         mempools: Mempools,
         self_pubkey: PublicKey,
         software_version: &'static str,
@@ -238,7 +316,7 @@ impl GvaModule {
             subscriptions::SubscriptionRoot::default(),
         )
         .data(schema::SchemaData {
-            dbs_reader: create_dbs_reader(Self::get_gva_db_ro(&dbs_pool).await),
+            dbs_reader: create_dbs_reader(gva_db_ro),
             dbs_pool,
             server_meta_data: ServerMetaData {
                 currency,
@@ -323,41 +401,6 @@ pub struct ServerMetaData {
     pub software_version: &'static str,
 }
 
-#[derive(
-    async_graphql::SimpleObject,
-    Clone,
-    Debug,
-    Default,
-    Eq,
-    PartialEq,
-    serde::Deserialize,
-    serde::Serialize,
-)]
-#[serde(rename_all = "camelCase")]
-#[graphql(name = "PeerCard")]
-pub struct PeerCardStringified {
-    pub version: u32,
-    pub currency: String,
-    pub pubkey: String,
-    pub blockstamp: String,
-    pub endpoints: Vec<String>,
-    pub status: String,
-    pub signature: String,
-}
-impl From<duniter_dbs::PeerCardDbV1> for PeerCardStringified {
-    fn from(peer: duniter_dbs::PeerCardDbV1) -> Self {
-        Self {
-            version: peer.version,
-            currency: peer.currency,
-            pubkey: peer.pubkey,
-            blockstamp: peer.blockstamp,
-            endpoints: peer.endpoints,
-            status: peer.status,
-            signature: peer.signature,
-        }
-    }
-}
-
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -429,7 +472,7 @@ mod tests {
     }
 
     pub(crate) fn create_schema(dbs_ops: MockDbsReader) -> KvResult<GraphQlSchema> {
-        let dbs = DuniterDbs::mem()?;
+        let dbs = SharedDbs::mem()?;
         let threadpool = fast_threadpool::ThreadPool::start(ThreadPoolConfig::default(), dbs);
         Ok(async_graphql::Schema::build(
             queries::QueryRoot::default(),
@@ -460,7 +503,7 @@ mod tests {
     #[tokio::test]
     #[ignore]
     async fn launch_mem_gva() -> anyhow::Result<()> {
-        let dbs = unwrap!(DuniterDbs::mem());
+        let dbs = unwrap!(SharedDbs::mem());
         let threadpool = fast_threadpool::ThreadPool::start(ThreadPoolConfig::default(), dbs);
 
         GvaModule::init(
diff --git a/rust-libs/modules/gva/src/queries.rs b/rust-libs/modules/gva/src/queries.rs
index f9ffeb9e075e119a45713815543f82d0ebc52bb5..ce5ceff9e557d55a1448f255a4b5de15b2ac1bd2 100644
--- a/rust-libs/modules/gva/src/queries.rs
+++ b/rust-libs/modules/gva/src/queries.rs
@@ -46,7 +46,7 @@ impl Node {
     async fn peer(
         &self,
         ctx: &async_graphql::Context<'_>,
-    ) -> async_graphql::Result<Option<PeerCardStringified>> {
+    ) -> async_graphql::Result<Option<PeerCardGva>> {
         let data = ctx.data::<SchemaData>()?;
 
         Ok(data
diff --git a/rust-libs/modules/gva/src/queries/utxos_of_script.rs b/rust-libs/modules/gva/src/queries/utxos_of_script.rs
index cccaa81244eecaedf7a22b7f8651eb12b62d1724..d50a2f22c25754a191083ce146ad8f22434e30a0 100644
--- a/rust-libs/modules/gva/src/queries/utxos_of_script.rs
+++ b/rust-libs/modules/gva/src/queries/utxos_of_script.rs
@@ -15,7 +15,6 @@
 
 use crate::*;
 use async_graphql::connection::*;
-use duniter_dbs::databases::gva_v1::GvaV1DbReadable;
 use duniter_gva_dbs_reader::{
     utxos::{UtxoCursor, UtxosWithSum},
     PagedData,
@@ -63,12 +62,7 @@ impl UtxosQuery {
                     )?;
                     let mut times = Vec::with_capacity(paged_data.data.utxos.len());
                     for (UtxoCursor { block_number, .. }, _sa) in &paged_data.data.utxos {
-                        times.push(
-                            dbs.gva_db
-                                .blockchain_time()
-                                .get(&U32BE(block_number.0))?
-                                .unwrap_or_else(|| unreachable!()),
-                        );
+                        times.push(db_reader.get_blockchain_time(*block_number)?);
                     }
                     Ok::<_, anyhow::Error>((paged_data, times))
                 } else {
diff --git a/rust-libs/modules/gva/src/schema.rs b/rust-libs/modules/gva/src/schema.rs
index c4540e7bb64d7cc500d2aae09697c20ad5f7be87..3ea5213d24ff72788b5f1fcbeecd5f2539ecbdf9 100644
--- a/rust-libs/modules/gva/src/schema.rs
+++ b/rust-libs/modules/gva/src/schema.rs
@@ -21,7 +21,7 @@ pub(crate) type GraphQlSchema = async_graphql::Schema<
     crate::subscriptions::SubscriptionRoot,
 >;
 pub(crate) struct SchemaData {
-    pub(crate) dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<DuniterDbs<FileBackend>>,
+    pub(crate) dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
     pub(crate) dbs_reader: DbsReader,
     pub(crate) server_meta_data: ServerMetaData,
     pub(crate) txs_mempool: TxsMempool,
diff --git a/rust-libs/tests/duniter-integration-tests/Cargo.toml b/rust-libs/tests/duniter-integration-tests/Cargo.toml
index 32b78068ce82c8a002aedc5fe0c53902d8027ea8..cf913bcb60047ed426a0e6d5e74222a51f6021d8 100644
--- a/rust-libs/tests/duniter-integration-tests/Cargo.toml
+++ b/rust-libs/tests/duniter-integration-tests/Cargo.toml
@@ -12,10 +12,9 @@ duniter-conf = { path = "../../duniter-conf" }
 duniter-dbs = { path = "../../duniter-dbs" }
 duniter-dbs-read-ops = { path = "../../duniter-dbs-read-ops" }
 duniter-dbs-write-ops = { path = "../../duniter-dbs-write-ops" }
-duniter-gva = { path = "../../modules/gva" }
 duniter-mempools = { path = "../../duniter-mempools" }
 duniter-module = { path = "../../duniter-module" }
-duniter-server = { path = "../../duniter-server" }
+duniter-server = { path = "../../duniter-server", features = ["gva"] }
 fast-threadpool = "0.2.2"
 flume = "0.9.1"
 log = "0.4.11"
diff --git a/rust-libs/tests/duniter-integration-tests/src/lib.rs b/rust-libs/tests/duniter-integration-tests/src/lib.rs
index 4260a8b612d0e6fcf02500bd997dfec13a2aa6c9..ac460624c47fa944e4f92173a294238131652396 100644
--- a/rust-libs/tests/duniter-integration-tests/src/lib.rs
+++ b/rust-libs/tests/duniter-integration-tests/src/lib.rs
@@ -59,6 +59,7 @@ mod tests {
             hash: None,
         }
         .build_with_signature(smallvec![]);
+
         server.add_pending_tx_force(tx.clone())?;
 
         let txs_history = server.get_transactions_history(PublicKey::default())?;