diff --git a/.eslintignore b/.eslintignore
index 0601c0236938e190f3eac13cbc643431a4572284..2a1974b2a4d1f49d6fefa5bfd3e25d19a0f8374e 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -2,6 +2,7 @@ app/cli.js
 app/lib/blockchain/*.js
 app/lib/blockchain/interfaces/*.js
 app/lib/computation/*.js
+app/lib/common-libs/*.js
 app/lib/db/*.js
 app/lib/dto/*.js
 app/lib/indexer.js
diff --git a/app/lib/common-libs/constants.ts b/app/lib/common-libs/constants.ts
index b47770bb1d7480dd2c4f316f42b2564fcf96b8fa..9136da34b824918615385ec41c8596b497decef5 100644
--- a/app/lib/common-libs/constants.ts
+++ b/app/lib/common-libs/constants.ts
@@ -32,6 +32,31 @@ const MAXIMUM_LEN_OF_COMPACT_TX = 100
 const MAXIMUM_LEN_OF_OUTPUT = 2000
 const MAXIMUM_LEN_OF_UNLOCK = MAXIMUM_LEN_OF_OUTPUT
 
+export enum DuniterDocument {
+  ENTITY_NULL,
+  ENTITY_BLOCK,
+  ENTITY_IDENTITY,
+  ENTITY_CERTIFICATION,
+  ENTITY_MEMBERSHIP,
+  ENTITY_REVOCATION,
+  ENTITY_TRANSACTION,
+  ENTITY_PEER
+}
+
+export const duniterDocument2str = (type:DuniterDocument) => {
+  switch (type) {
+    case DuniterDocument.ENTITY_BLOCK: return "block"
+    case DuniterDocument.ENTITY_IDENTITY: return "identity"
+    case DuniterDocument.ENTITY_CERTIFICATION: return "certification"
+    case DuniterDocument.ENTITY_REVOCATION: return "revocation"
+    case DuniterDocument.ENTITY_MEMBERSHIP: return "membership"
+    case DuniterDocument.ENTITY_TRANSACTION: return "transaction"
+    case DuniterDocument.ENTITY_PEER: return "peer"
+    default:
+      return ""
+  }
+}
+
 export const CommonConstants = {
 
   FORMATS: {
diff --git a/app/lib/common-libs/parsers/GenericParser.ts b/app/lib/common-libs/parsers/GenericParser.ts
index 9ab5b437ae6e1a6e01d8249997a63dd5b11c334f..f87ddaadc66dd16c8acb32cc2e36dfd73f74b5ba 100644
--- a/app/lib/common-libs/parsers/GenericParser.ts
+++ b/app/lib/common-libs/parsers/GenericParser.ts
@@ -22,7 +22,7 @@ export abstract class GenericParser extends stream.Transform {
   }
 
   syncWrite(str:string, logger:any = null): any {
-    let error;
+    let error = ""
     const obj = {};
     this._parse(str, obj);
     this._clean(obj);
@@ -32,7 +32,7 @@ export abstract class GenericParser extends stream.Transform {
     if (!error) {
       const raw = this.rawerFunc(obj);
       if (hashf(str) !== hashf(raw))
-        error = CommonConstants.ERRORS.WRONG_DOCUMENT;
+        error = CommonConstants.ERRORS.WRONG_DOCUMENT.uerr.message;
       if (error) {
         logger && logger.trace(error);
         logger && logger.trace('-----------------');
diff --git a/app/lib/common-libs/parsers/block.ts b/app/lib/common-libs/parsers/block.ts
index 885f3a0e938e5a7b61f4cf056664446a5ef6057b..e0aef2ec6d1c642a2382c90299651f9421940187 100644
--- a/app/lib/common-libs/parsers/block.ts
+++ b/app/lib/common-libs/parsers/block.ts
@@ -39,7 +39,6 @@ export class BlockParser extends GenericParser {
   }
 
   _clean(obj:any) {
-    obj.documentType = 'block';
     obj.identities = obj.identities || [];
     obj.joiners = obj.joiners || [];
     obj.actives = obj.actives || [];
diff --git a/app/lib/common-libs/parsers/certification.ts b/app/lib/common-libs/parsers/certification.ts
index f73753942a96035f91dbf44ac1292af78dcfc80b..61e7541307dfcc4fe8adfcdf04e3edd2035e52ec 100644
--- a/app/lib/common-libs/parsers/certification.ts
+++ b/app/lib/common-libs/parsers/certification.ts
@@ -19,7 +19,6 @@ export class CertificationParser extends GenericParser {
   }
 
   _clean(obj:any) {
-    obj.documentType = 'certification';
     obj.sig = obj.signature;
     obj.block = obj.buid;
     if (obj.block) {
@@ -31,9 +30,9 @@ export class CertificationParser extends GenericParser {
     }
   }
 
-  _verify(obj:any) {
-    return ["version", "type", "currency", "issuer", "idty_issuer", "idty_sig", "idty_buid", "idty_uid", "block"].reduce(function (p, field) {
-      return p || (!obj[field] && "Wrong format for certification");
-    }, null)
+  _verify(obj:any): string {
+    return ["version", "type", "currency", "issuer", "idty_issuer", "idty_sig", "idty_buid", "idty_uid", "block"].reduce((p, field) => {
+      return p || (!obj[field] && "Wrong format for certification") || ""
+    }, "")
   }
 }
\ No newline at end of file
diff --git a/app/lib/common-libs/parsers/identity.ts b/app/lib/common-libs/parsers/identity.ts
index fc63231ee77c1adb20c17f446ad2638d0500e2a7..eed67d9098b5fba8671069e3078280f2a914c9fd 100644
--- a/app/lib/common-libs/parsers/identity.ts
+++ b/app/lib/common-libs/parsers/identity.ts
@@ -17,7 +17,6 @@ export class IdentityParser extends GenericParser {
   }
 
   _clean(obj:any) {
-    obj.documentType = 'identity';
     obj.sig = obj.signature;
     if (obj.uid && obj.buid && obj.pubkey) {
       obj.hash = hashf(obj.uid + obj.buid + obj.pubkey).toUpperCase();
diff --git a/app/lib/common-libs/parsers/membership.ts b/app/lib/common-libs/parsers/membership.ts
index 97938346a1e068387593b7c996de767d00d75920..25c3c5cc3cbc2dc16da74b1b15c11ac9b9b1b938 100644
--- a/app/lib/common-libs/parsers/membership.ts
+++ b/app/lib/common-libs/parsers/membership.ts
@@ -18,7 +18,6 @@ export class MembershipParser extends GenericParser {
   }
 
   _clean(obj:any) {
-    obj.documentType = 'membership';
     if (obj.block) {
       obj.number = obj.block.split('-')[0];
       obj.fpr = obj.block.split('-')[1];
diff --git a/app/lib/common-libs/parsers/peer.ts b/app/lib/common-libs/parsers/peer.ts
index 24715a21902754373db206bd1faa3958df1197de..485dec1d018b3ec7e23df713c593d367712f8fe7 100644
--- a/app/lib/common-libs/parsers/peer.ts
+++ b/app/lib/common-libs/parsers/peer.ts
@@ -17,7 +17,6 @@ export class PeerParser extends GenericParser {
   }
 
   _clean(obj:any) {
-    obj.documentType = 'peer';
     obj.endpoints = obj.endpoints || [];
     // Removes trailing space
     if (obj.endpoints.length > 0)
diff --git a/app/lib/common-libs/parsers/revocation.ts b/app/lib/common-libs/parsers/revocation.ts
index 777c878bc937d415393e4f0151308dbfdf2431a6..c70580237467b2ddddff9dd7c58f265c4b6e1ef1 100644
--- a/app/lib/common-libs/parsers/revocation.ts
+++ b/app/lib/common-libs/parsers/revocation.ts
@@ -18,7 +18,6 @@ export class RevocationParser extends GenericParser {
   }
 
   _clean(obj:any) {
-    obj.documentType = 'revocation';
     obj.pubkey = obj.issuer;
     obj.revocation = obj.signature;
     if (obj.uid && obj.buid && obj.pubkey) {
diff --git a/app/lib/common-libs/parsers/transaction.ts b/app/lib/common-libs/parsers/transaction.ts
index d94b58c0ef11ec60c05b487c737ced7e77f1f969..643848651dc22e6f3a4ecfc627d3ca56c0a36672 100644
--- a/app/lib/common-libs/parsers/transaction.ts
+++ b/app/lib/common-libs/parsers/transaction.ts
@@ -20,7 +20,6 @@ export class TransactionParser extends GenericParser {
   }
 
   _clean(obj:any) {
-    obj.documentType = 'transaction';
     obj.comment = obj.comment || "";
     obj.locktime = parseInt(obj.locktime) || 0;
     obj.signatures.push(obj.signature);
diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts
index 87ed408db022d86835914b3ec013f20418a5ffdb..94247cf4776f95f55fe883bc3c94f10529877e36 100644
--- a/app/lib/dal/fileDAL.ts
+++ b/app/lib/dal/fileDAL.ts
@@ -488,6 +488,9 @@ export class FileDAL {
   async isMember(pubkey:string) {
     try {
       const idty = await this.iindexDAL.getFromPubkey(pubkey);
+      if (!idty) {
+        return false
+      }
       return idty.member;
     } catch (err) {
       return false;
diff --git a/app/lib/dal/sqliteDAL/IdentityDAL.ts b/app/lib/dal/sqliteDAL/IdentityDAL.ts
index 0ee6d836255da01706af371db83fccef39c525c8..c23f6be99df73a7d0ba3a8efb07e283a2acd7cfb 100644
--- a/app/lib/dal/sqliteDAL/IdentityDAL.ts
+++ b/app/lib/dal/sqliteDAL/IdentityDAL.ts
@@ -2,9 +2,14 @@ import {AbstractSQLite} from "./AbstractSQLite"
 import {SQLiteDriver} from "../drivers/SQLiteDriver"
 import {SandBox} from "./SandBox"
 import {IdentityDTO} from "../../dto/IdentityDTO"
+import {Cloneable} from "../../dto/Cloneable";
 const constants = require('../../constants');
 
-export abstract class DBIdentity {
+export abstract class DBIdentity implements Cloneable {
+
+  clone(): any {
+    return DBIdentity.copyFromExisting(this)
+  }
 
   certs:any[] = []
   signed:any[] = []
diff --git a/app/lib/dal/sqliteDAL/PeerDAL.ts b/app/lib/dal/sqliteDAL/PeerDAL.ts
index 2fef0a5a521685a0c8dc4500a04019fbcb895713..4603303423f492508b3b8b152f63a3113ae742fd 100644
--- a/app/lib/dal/sqliteDAL/PeerDAL.ts
+++ b/app/lib/dal/sqliteDAL/PeerDAL.ts
@@ -3,8 +3,6 @@ import {AbstractSQLite} from "./AbstractSQLite"
 
 export class DBPeer {
 
-  readonly documentType = "peer"
-
   version: number
   currency: string
   status: string
diff --git a/app/lib/dto/BlockDTO.ts b/app/lib/dto/BlockDTO.ts
index 86c3ac9d820e85c6da36fb8afd0ce6d474618e85..756661ecc214ebe84c9a0ecd8b8319c80c4bd0b7 100644
--- a/app/lib/dto/BlockDTO.ts
+++ b/app/lib/dto/BlockDTO.ts
@@ -1,10 +1,15 @@
 import {TransactionDTO} from "./TransactionDTO"
 import {CurrencyConfDTO} from "./ConfDTO"
 import {hashf} from "../common"
+import {Cloneable} from "./Cloneable";
 
 const DEFAULT_DOCUMENT_VERSION = 10
 
-export class BlockDTO {
+export class BlockDTO implements Cloneable {
+
+  clone(): any {
+    return BlockDTO.fromJSONObject(this)
+  }
 
   version: number
   number: number
@@ -38,8 +43,8 @@ export class BlockDTO {
   monetaryMass: number
   UDTime: number
 
-  constructor(
-) {}
+  constructor() {
+  }
 
   json() {
     return {
diff --git a/app/lib/dto/CertificationDTO.ts b/app/lib/dto/CertificationDTO.ts
index afb437f2024134400811adab6df5d75ca979e7b2..635b9e7b5d421ecd0c5e07db2eaf77e93d027f82 100644
--- a/app/lib/dto/CertificationDTO.ts
+++ b/app/lib/dto/CertificationDTO.ts
@@ -1,5 +1,6 @@
 import {IdentityDTO} from "./IdentityDTO"
 import {Buid} from "../common-libs/buid"
+import {Cloneable} from "./Cloneable";
 
 const DEFAULT_DOCUMENT_VERSION = 10
 
@@ -25,7 +26,11 @@ export class ShortCertificationDTO {
   }
 }
 
-export class CertificationDTO extends ShortCertificationDTO {
+export class CertificationDTO extends ShortCertificationDTO implements Cloneable {
+
+  clone(): any {
+    return CertificationDTO.fromJSONObject(this)
+  }
 
   constructor(
     public version: number,
diff --git a/app/lib/dto/Cloneable.ts b/app/lib/dto/Cloneable.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f3d5165b1d18704e5cee71bf8571c2f243cbb077
--- /dev/null
+++ b/app/lib/dto/Cloneable.ts
@@ -0,0 +1,3 @@
+export interface Cloneable {
+  clone(): any
+}
\ No newline at end of file
diff --git a/app/lib/dto/Jsonable.ts b/app/lib/dto/Jsonable.ts
new file mode 100644
index 0000000000000000000000000000000000000000..17228fa53531e6a1dd47a72f9b769297c751c8b4
--- /dev/null
+++ b/app/lib/dto/Jsonable.ts
@@ -0,0 +1,3 @@
+export interface Jsonable {
+  json(): any
+}
\ No newline at end of file
diff --git a/app/lib/dto/MembershipDTO.ts b/app/lib/dto/MembershipDTO.ts
index 1c354afe4f71341f15d3783503f1a1d933439b6f..10360bfc847ed0a115dc5aeb5ccff93dd82fd3f7 100644
--- a/app/lib/dto/MembershipDTO.ts
+++ b/app/lib/dto/MembershipDTO.ts
@@ -1,9 +1,14 @@
 import {IdentityDTO} from "./IdentityDTO"
 import * as moment from "moment"
+import {Cloneable} from "./Cloneable";
 
 const DEFAULT_DOCUMENT_VERSION = 10
 
-export class MembershipDTO {
+export class MembershipDTO implements Cloneable {
+
+  clone(): any {
+    return MembershipDTO.fromJSONObject(this)
+  }
 
   sigDate?:number
   date?:number
diff --git a/app/lib/dto/PeerDTO.ts b/app/lib/dto/PeerDTO.ts
index bb10bb945b377674fc5f4f5504e9f69d3857fd67..9ddb9f5df272da171f7f02c311c052db07fe0947 100644
--- a/app/lib/dto/PeerDTO.ts
+++ b/app/lib/dto/PeerDTO.ts
@@ -1,10 +1,14 @@
 import {DBPeer} from "../dal/sqliteDAL/PeerDAL"
 import {hashf} from "../common"
 import {CommonConstants} from "../common-libs/constants"
+import {Cloneable} from "./Cloneable";
 
-export class PeerDTO {
+export class PeerDTO implements Cloneable {
+
+  clone(): any {
+    return PeerDTO.fromJSONObject(this)
+  }
 
-  readonly documentType = "peer"
   member = false
 
   constructor(
@@ -164,6 +168,10 @@ export class PeerDTO {
     return parseInt(blockstamp)
   }
 
+  static fromDBPeer(p:DBPeer) {
+    return new PeerDTO(p.version, p.currency, p.pubkey, p.block, p.endpoints, p.signature, p.status, p.statusTS, false)
+  }
+
   static fromJSONObject(obj:any) {
     return new PeerDTO(
       obj.version,
diff --git a/app/lib/dto/RevocationDTO.ts b/app/lib/dto/RevocationDTO.ts
index e7e00f5bfb93d75f31ae6c156f9114d8967514a5..73a8656d66196ab2c8eaef5b543c630ea1ebd068 100644
--- a/app/lib/dto/RevocationDTO.ts
+++ b/app/lib/dto/RevocationDTO.ts
@@ -1,3 +1,4 @@
+import {Cloneable} from "./Cloneable";
 const DEFAULT_DOCUMENT_VERSION = 10
 
 export interface ShortRevocation {
@@ -5,9 +6,11 @@ export interface ShortRevocation {
   revocation: string
 }
 
-export class RevocationDTO implements ShortRevocation {
+export class RevocationDTO implements ShortRevocation, Cloneable {
 
-  public readonly documentType = 'revocation'
+  clone(): any {
+    return RevocationDTO.fromJSONObject(this)
+  }
 
   constructor(
     public version: number,
diff --git a/app/lib/dto/TransactionDTO.ts b/app/lib/dto/TransactionDTO.ts
index 2a0fc9358bb1ce4ccaf670c0151bb1b151c60ba8..97c43cde7a590b7bc27bff8fba54d07c275664af 100644
--- a/app/lib/dto/TransactionDTO.ts
+++ b/app/lib/dto/TransactionDTO.ts
@@ -1,4 +1,5 @@
 import {hashf} from "../common"
+import {Cloneable} from "./Cloneable";
 
 export interface BaseDTO {
   base: number
@@ -24,7 +25,11 @@ export class OutputDTO implements BaseDTO {
   ) {}
 }
 
-export class TransactionDTO {
+export class TransactionDTO implements Cloneable {
+
+  clone(): any {
+    return TransactionDTO.fromJSONObject(this)
+  }
 
   constructor(
     public version: number,
@@ -58,6 +63,14 @@ export class TransactionDTO {
     return this.outputs.reduce((maxBase, output) => Math.max(maxBase, parseInt(output.split(':')[1])), 0)
   }
 
+  get blockNumber() {
+    return parseInt(this.blockstamp)
+  }
+
+  get block_hash() {
+    return this.blockstamp.split('-')[1]
+  }
+
   getLen() {
     return 2 // header + blockstamp
       + this.issuers.length * 2 // issuers + signatures
diff --git a/app/modules/bma/lib/constants.ts b/app/modules/bma/lib/constants.ts
index 18abf2eb74966a0c7e93182397ff327ad299e332..6caa2204bd605ba3eadce521da6eaea61a352c22 100644
--- a/app/modules/bma/lib/constants.ts
+++ b/app/modules/bma/lib/constants.ts
@@ -3,13 +3,6 @@ export const BMAConstants = {
   BMA_PORTS_START: 10901,
   BMA_PORTS_END: 10999,
 
-  ENTITY_BLOCK: 'block',
-  ENTITY_IDENTITY: 'identity',
-  ENTITY_CERTIFICATION: 'certification',
-  ENTITY_MEMBERSHIP: 'membership',
-  ENTITY_REVOCATION: 'revocation',
-  ENTITY_TRANSACTION: 'transaction',
-  ENTITY_PEER: 'peer',
   DEFAULT_PORT: 10901,
   IPV4_REGEXP: /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/,
   IPV6_REGEXP: /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/,
diff --git a/app/modules/bma/lib/controllers/AbstractController.ts b/app/modules/bma/lib/controllers/AbstractController.ts
index 9206e3f68e0ae3279d835da06b546ce1c2a04db9..1b3a6d2cbf8bce8a7d5a672380fae874b1ed4c9b 100644
--- a/app/modules/bma/lib/controllers/AbstractController.ts
+++ b/app/modules/bma/lib/controllers/AbstractController.ts
@@ -1,5 +1,5 @@
-import {Server} from "../../../../../server"
-import {dos2unix} from "../../../../lib/common-libs/dos2unix"
+import {Server} from "../../../../../server";
+import {dos2unix} from "../../../../lib/common-libs/dos2unix";
 
 export abstract class AbstractController {
 
@@ -30,14 +30,12 @@ export abstract class AbstractController {
     return this.server.MerkleService
   }
 
-  async pushEntity(req:any, rawer:(req:any)=>string, type:any) {
+  async pushEntity<T>(req:any, rawer:(req:any)=>string, task:(raw:string) => Promise<T>): Promise<T> {
     let rawDocument = rawer(req);
     rawDocument = dos2unix(rawDocument);
-    const written = await this.server.writeRaw(rawDocument, type);
     try {
-      return written.json();
+      return await task(rawDocument)
     } catch (e) {
-      this.logger.error('Written:', written);
       this.logger.error(e);
       throw e;
     }
diff --git a/app/modules/bma/lib/controllers/blockchain.ts b/app/modules/bma/lib/controllers/blockchain.ts
index 79fe0cdbfdbf12110f2fdefc32c9d3eabb19af83..315c816e13560f92be42765336b9a45dd524f773 100644
--- a/app/modules/bma/lib/controllers/blockchain.ts
+++ b/app/modules/bma/lib/controllers/blockchain.ts
@@ -1,9 +1,10 @@
 "use strict";
-import {Server} from "../../../../../server"
-import {AbstractController} from "./AbstractController"
-import {ParametersService} from "../parameters"
-import {BMAConstants} from "../constants"
-import {MembershipDTO} from "../../../../lib/dto/MembershipDTO"
+import {Server} from "../../../../../server";
+import {AbstractController} from "./AbstractController";
+import {ParametersService} from "../parameters";
+import {BMAConstants} from "../constants";
+import {MembershipDTO} from "../../../../lib/dto/MembershipDTO";
+import {HttpMembership} from "../dtos";
 
 const _                = require('underscore');
 const http2raw         = require('../http2raw');
@@ -29,9 +30,23 @@ export class BlockchainBinding extends AbstractController {
     }
   }
 
-  parseMembership = (req:any) => this.pushEntity(req, http2raw.membership, BMAConstants.ENTITY_MEMBERSHIP);
+  async parseMembership(req:any): Promise<HttpMembership> {
+    const res = await this.pushEntity(req, http2raw.membership, (raw:string) => this.server.writeRawMembership(raw))
+    return {
+      signature: res.signature,
+      membership: {
+        version: res.version,
+        currency: res.currency,
+        issuer: res.issuer,
+        membership: res.membership,
+        date: res.date || 0,
+        sigDate: res.sigDate || 0,
+        raw: res.getRaw()
+      }
+    }
+  }
 
-  parseBlock = (req:any) => this.pushEntity(req, http2raw.block, BMAConstants.ENTITY_BLOCK);
+  parseBlock = (req:any) => this.pushEntity(req, http2raw.block, (raw:string) => this.server.writeRawBlock(raw))
 
   parameters = () => this.server.dal.getParameters();
 
diff --git a/app/modules/bma/lib/controllers/network.ts b/app/modules/bma/lib/controllers/network.ts
index 604846d006ee943b17893d4002f0c1fef29c043c..918e4a7f4ce3de08a07f58d80566181201d46d80 100644
--- a/app/modules/bma/lib/controllers/network.ts
+++ b/app/modules/bma/lib/controllers/network.ts
@@ -1,5 +1,6 @@
-import {AbstractController} from "./AbstractController"
-import {BMAConstants} from "../constants"
+import {AbstractController} from "./AbstractController";
+import {BMAConstants} from "../constants";
+import {HttpPeer} from "../dtos";
 
 const _                = require('underscore');
 const http2raw         = require('../http2raw');
@@ -33,8 +34,17 @@ export class NetworkBinding extends AbstractController {
     })
   }
 
-  peersPost(req:any) {
-    return this.pushEntity(req, http2raw.peer, BMAConstants.ENTITY_PEER)
+  async peersPost(req:any): Promise<HttpPeer> {
+    const peerDTO = await this.pushEntity(req, http2raw.peer, (raw:string) => this.server.writeRawPeer(raw))
+    return {
+      version: peerDTO.version,
+      currency: peerDTO.currency,
+      pubkey: peerDTO.pubkey,
+      block: peerDTO.blockstamp,
+      endpoints: peerDTO.endpoints,
+      signature: peerDTO.signature,
+      raw: peerDTO.getRaw()
+    }
   }
 
   async peers() {
diff --git a/app/modules/bma/lib/controllers/transactions.ts b/app/modules/bma/lib/controllers/transactions.ts
index 1fdd85089e0539cc3f5cf87d15d67a5872550b00..cf2d1d06bb0d8206ef0df421d6731c4995421928 100644
--- a/app/modules/bma/lib/controllers/transactions.ts
+++ b/app/modules/bma/lib/controllers/transactions.ts
@@ -1,8 +1,8 @@
-import {AbstractController} from "./AbstractController"
-import {ParametersService} from "../parameters"
-import {Source} from "../entity/source"
-import {BMAConstants} from "../constants"
-import {TransactionDTO} from "../../../../lib/dto/TransactionDTO"
+import {AbstractController} from "./AbstractController";
+import {ParametersService} from "../parameters";
+import {Source} from "../entity/source";
+import {BMAConstants} from "../constants";
+import {TransactionDTO} from "../../../../lib/dto/TransactionDTO";
 
 const _                = require('underscore');
 const http2raw         = require('../http2raw');
@@ -10,7 +10,7 @@ const http2raw         = require('../http2raw');
 export class TransactionBinding extends AbstractController {
 
   parseTransaction(req:any) {
-    return this.pushEntity(req, http2raw.transaction, BMAConstants.ENTITY_TRANSACTION)
+    return this.pushEntity(req, http2raw.transaction, (raw:string) => this.server.writeRawTransaction(raw))
   }
 
   async getSources(req:any) {
diff --git a/app/modules/bma/lib/controllers/wot.ts b/app/modules/bma/lib/controllers/wot.ts
index 75140968e126c687df83d491c76a086595d3099f..68eec5f8633a258ecc2fed39deb8797a8835cf7f 100644
--- a/app/modules/bma/lib/controllers/wot.ts
+++ b/app/modules/bma/lib/controllers/wot.ts
@@ -1,6 +1,7 @@
-import {AbstractController} from "./AbstractController"
-import {BMAConstants} from "../constants"
-import {DBIdentity} from "../../../../lib/dal/sqliteDAL/IdentityDAL"
+import {AbstractController} from "./AbstractController";
+import {BMAConstants} from "../constants";
+import {DBIdentity} from "../../../../lib/dal/sqliteDAL/IdentityDAL";
+import {HttpCert, HttpCertIdentity} from "../dtos";
 
 const _        = require('underscore');
 const http2raw = require('../http2raw');
@@ -215,15 +216,27 @@ export class WOTBinding extends AbstractController {
   }
 
   add(req:any) {
-    return this.pushEntity(req, http2raw.identity, BMAConstants.ENTITY_IDENTITY)
+    return this.pushEntity(req, http2raw.identity, (raw:string) => this.server.writeRawIdentity(raw))
   }
 
-  certify(req:any) {
-    return this.pushEntity(req, http2raw.certification, BMAConstants.ENTITY_CERTIFICATION)
+  async certify(req:any): Promise<HttpCert> {
+    const res = await this.pushEntity(req, http2raw.certification, (raw:string) => this.server.writeRawCertification(raw))
+    const target:HttpCertIdentity = {
+      issuer: res.idty_issuer,
+      uid: res.idty_uid,
+      timestamp: res.idty_buid,
+      sig: res.idty_sig
+    }
+    return {
+      issuer: res.issuer,
+      timestamp: res.buid,
+      sig: res.sig,
+      target
+    }
   }
 
   revoke(req:any) {
-    return this.pushEntity(req, http2raw.revocation, BMAConstants.ENTITY_REVOCATION)
+    return this.pushEntity(req, http2raw.revocation, (raw:string) => this.server.writeRawRevocation(raw))
   }
 
   async pendingMemberships() {
diff --git a/app/modules/bma/lib/dtos.ts b/app/modules/bma/lib/dtos.ts
index 5bd20deddb447e3ba34242d3774c499ea9f25527..fd09131cc52ed27a749f0094e0eac5e9c11eb769 100644
--- a/app/modules/bma/lib/dtos.ts
+++ b/app/modules/bma/lib/dtos.ts
@@ -44,6 +44,19 @@ export const Membership = {
   }
 };
 
+export interface HttpMembership {
+  signature: string
+  membership: {
+    version: number
+    currency: string
+    issuer: string
+    membership: string
+    date: number
+    sigDate: number
+    raw: string
+  }
+}
+
 export const Memberships = {
   "pubkey": String,
   "uid": String,
@@ -295,6 +308,13 @@ export const CertIdentity = {
   "sig": String
 };
 
+export interface HttpCertIdentity {
+  issuer: string
+  uid: string
+  timestamp: string
+  sig: string
+}
+
 export const Cert = {
   "issuer": String,
   "timestamp": String,
@@ -302,6 +322,13 @@ export const Cert = {
   "target": CertIdentity
 };
 
+export interface HttpCert {
+  issuer: string
+  timestamp: string
+  sig: string
+  target: HttpCertIdentity
+}
+
 export const Identity = {
   "pubkey": String,
   "uids": [UID],
diff --git a/app/modules/crawler/lib/crawler.ts b/app/modules/crawler/lib/crawler.ts
index 9e1133d794e5a2289689a919834c32250d3b43b2..494960a47d38dff07f9f62b5db8c663c40ac7d25 100644
--- a/app/modules/crawler/lib/crawler.ts
+++ b/app/modules/crawler/lib/crawler.ts
@@ -127,7 +127,7 @@ export class PeerCrawler implements DuniterService {
       let p = found[i];
       try {
         // Try to write it
-        await server.singleWritePromise(p);
+        await server.writePeer(p)
       } catch(e) {
         // Silent error
       }
diff --git a/app/modules/crawler/lib/sandbox.ts b/app/modules/crawler/lib/sandbox.ts
index dee8367730956b87004738394a1f4418f570b798..047a3d5e1ee09075ae881dc561e681ac98221c6a 100644
--- a/app/modules/crawler/lib/sandbox.ts
+++ b/app/modules/crawler/lib/sandbox.ts
@@ -135,8 +135,7 @@ async function submitMembership(ms:any, to:any, logger:any = null) {
 async function submitIdentityToServer(idty:any, toServer:any, logger:any = null) {
   try {
     const obj = parsers.parseIdentity.syncWrite(idty)
-    obj.documentType = 'identity'
-    await toServer.singleWritePromise(obj)
+    await toServer.writeIdentity(obj)
     logger && logger.trace('Sandbox pulling: success with identity \'%s\'', idty.uid)
   } catch (e) {
     // Silent error
@@ -146,8 +145,7 @@ async function submitIdentityToServer(idty:any, toServer:any, logger:any = null)
 async function submitCertificationToServer(cert:any, toServer:any, logger:any = null) {
   try {
     const obj = parsers.parseCertification.syncWrite(cert)
-    obj.documentType = 'certification'
-    await toServer.singleWritePromise(obj)
+    await toServer.writeCertification(obj)
     logger && logger.trace('Sandbox pulling: success with cert key %s => %s', cert.from.substr(0, 6), cert.idty_uid)
   } catch (e) {
     // Silent error
@@ -157,8 +155,7 @@ async function submitCertificationToServer(cert:any, toServer:any, logger:any =
 async function submitMembershipToServer(ms:any, toServer:any, logger:any = null) {
   try {
     const obj = parsers.parseMembership.syncWrite(ms)
-    obj.documentType = 'membership'
-    await toServer.singleWritePromise(obj)
+    await toServer.writeMembership(obj)
     logger && logger.trace('Sandbox pulling: success with membership \'%s\'', ms.uid)
   } catch (e) {
     // Silent error
diff --git a/app/modules/prover/lib/permanentProver.ts b/app/modules/prover/lib/permanentProver.ts
index a5914b13e18b53c8bec8b8e71fc575e676766a9e..1903a86bd37513037d603e5855d2a3ed2fdd2a26 100644
--- a/app/modules/prover/lib/permanentProver.ts
+++ b/app/modules/prover/lib/permanentProver.ts
@@ -163,7 +163,7 @@ export class PermanentProver {
                 this.lastComputedBlock = await this.generator.makeNextBlock(null, trial2);
                 try {
                   const obj = parsers.parseBlock.syncWrite(dos2unix(this.lastComputedBlock.getRawSigned()));
-                  await this.server.singleWritePromise(obj);
+                  await this.server.writeBlock(obj)
                 } catch (err) {
                   this.logger.warn('Proof-of-work self-submission: %s', err.message || err);
                 }
diff --git a/app/service/BlockchainService.ts b/app/service/BlockchainService.ts
index 0ab223863cb10b6e3af1ca1602b9c39d7db1370d..03c16d935b82407cff12f7378b0baff57629605b 100644
--- a/app/service/BlockchainService.ts
+++ b/app/service/BlockchainService.ts
@@ -113,13 +113,13 @@ export class BlockchainService {
     return [];
   }
 
-  submitBlock(obj:any, doCheck:boolean, forkAllowed:boolean) {
+  submitBlock(obj:any, doCheck:boolean, forkAllowed:boolean): Promise<BlockDTO> {
     return GlobalFifoPromise.pushFIFO(() => {
       return this.checkAndAddBlock(obj, doCheck, forkAllowed)
     })
   }
 
-  private async checkAndAddBlock(blockToAdd:any, doCheck:boolean, forkAllowed:boolean = false) {
+  private async checkAndAddBlock(blockToAdd:any, doCheck:boolean, forkAllowed:boolean = false): Promise<BlockDTO> {
     // Check global format, notably version number
     const obj = parsers.parseBlock.syncWrite(BlockDTO.fromJSONObject(blockToAdd).getRawSigned());
     // Force usage of local currency name, do not accept other currencies documents
diff --git a/app/service/GlobalFifoPromise.ts b/app/service/GlobalFifoPromise.ts
index d44cf6b2104dd26de7a5c29823dfcf117822d1a3..8dfb3f70dc3b1023535a4079969261f129bb6371 100644
--- a/app/service/GlobalFifoPromise.ts
+++ b/app/service/GlobalFifoPromise.ts
@@ -14,9 +14,8 @@ export class GlobalFifoPromise {
   /**
    * Adds a promise to a FIFO stack of promises, so the given promise will be executed against a shared FIFO stack.
    * @param p
-   * @returns {Promise<T>} A promise wrapping the promise given in the parameter.
    */
-  static pushFIFO(p: () => Promise<any>) {
+  static pushFIFO<T>(p: () => Promise<T>): Promise<T> {
     // Return a promise that will be done after the fifo has executed the given promise
     return new Promise((resolve:any, reject:any) => {
       // Push the promise on the stack
@@ -30,7 +29,7 @@ export class GlobalFifoPromise {
           // Errored, we end the function with an error
           cb(e);
         }
-      }, (err:any, res:any) => {
+      }, (err:any, res:T) => {
         // An error occured => reject promise
         if (err) return reject(err);
         // Success => we resolve with given promise result
diff --git a/app/service/IdentityService.ts b/app/service/IdentityService.ts
index b942c2677a50e68213502592595218729052d2eb..8125a709dfbf4683fa5bb37937be08bbb739f216 100644
--- a/app/service/IdentityService.ts
+++ b/app/service/IdentityService.ts
@@ -71,13 +71,13 @@ export class IdentityService {
     return this.dal.getNonWritten(pubkey)
   }
 
-  submitIdentity(idty:BasicIdentity, byAbsorption = false): Promise<any> {
+  submitIdentity(idty:BasicIdentity, byAbsorption = false): Promise<DBIdentity> {
     const idtyObj = IdentityDTO.fromJSONObject(idty)
     const toSave = IdentityDTO.fromBasicIdentity(idty)
     // Force usage of local currency name, do not accept other currencies documents
     idtyObj.currency = this.conf.currency;
     const createIdentity = idtyObj.rawWithoutSig();
-    return GlobalFifoPromise.pushFIFO(async () => {
+    return GlobalFifoPromise.pushFIFO<DBIdentity>(async () => {
       this.logger.info('⬇ IDTY %s %s', idty.pubkey, idty.uid);
       // Check signature's validity
       let verified = verify(createIdentity, idty.sig, idty.pubkey);
@@ -124,7 +124,7 @@ export class IdentityService {
     })
   }
 
-  async submitCertification(obj:any) {
+  async submitCertification(obj:any): Promise<CertificationDTO> {
     const current = await this.dal.getCurrentBlockOrNull();
     // Prepare validator for certifications
     const potentialNext = BlockDTO.fromJSONObject({ currency: this.conf.currency, identities: [], number: current ? current.number + 1 : 0 });
@@ -144,7 +144,7 @@ export class IdentityService {
       }, BY_ABSORPTION);
     }
     let anErr:any
-    return GlobalFifoPromise.pushFIFO(async () => {
+    return GlobalFifoPromise.pushFIFO<CertificationDTO>(async () => {
       this.logger.info('⬇ CERT %s block#%s -> %s', cert.from, cert.block_number, idty.uid);
       try {
         await GLOBAL_RULES_HELPERS.checkCertificationIsValid(cert, potentialNext, () => Promise.resolve(idty), this.conf, this.dal);
@@ -207,7 +207,7 @@ export class IdentityService {
     obj.currency = this.conf.currency || obj.currency;
     const revoc = RevocationDTO.fromJSONObject(obj)
     const raw = revoc.rawWithoutSig();
-    return GlobalFifoPromise.pushFIFO(async () => {
+    return GlobalFifoPromise.pushFIFO<RevocationDTO>(async () => {
       try {
         this.logger.info('⬇ REVOCATION %s %s', revoc.pubkey, revoc.idty_uid);
         let verified = verify(raw, revoc.revocation, revoc.pubkey);
diff --git a/app/service/MembershipService.ts b/app/service/MembershipService.ts
index a64b16de3887a346db18a964e4de309c22aa5020..4a207d74e230f16d3457e958033237413c79ea78 100644
--- a/app/service/MembershipService.ts
+++ b/app/service/MembershipService.ts
@@ -25,7 +25,7 @@ export class MembershipService {
   }
 
   submitMembership(ms:any) {
-    return GlobalFifoPromise.pushFIFO(async () => {
+    return GlobalFifoPromise.pushFIFO<MembershipDTO>(async () => {
       const entry = MembershipDTO.fromJSONObject(ms)
       // Force usage of local currency name, do not accept other currencies documents
       entry.currency = this.conf.currency || entry.currency;
diff --git a/app/service/PeeringService.ts b/app/service/PeeringService.ts
index 5d289550b26a773bb8c5cd88c7ebe4723514a71a..533f148a9ddf068da76e6efeec2bcf637fa3e4d7 100644
--- a/app/service/PeeringService.ts
+++ b/app/service/PeeringService.ts
@@ -8,6 +8,7 @@ import {PeerDTO} from "../lib/dto/PeerDTO"
 import {verify} from "../lib/common-libs/crypto/keyring"
 import {dos2unix} from "../lib/common-libs/dos2unix"
 import {rawer} from "../lib/common-libs/index";
+import {Server} from "../../server";
 
 const util           = require('util');
 const _              = require('underscore');
@@ -31,7 +32,7 @@ export class PeeringService {
   peerInstance:DBPeer | null
   logger:any
 
-  constructor(private server:any) {
+  constructor(private server:Server) {
   }
 
   setConfDAL(newConf:ConfDTO, newDAL:FileDAL, newPair:Keyring) {
@@ -67,7 +68,7 @@ export class PeeringService {
     return !!signaturesMatching;
   };
 
-  submitP(peering:DBPeer, eraseIfAlreadyRecorded = false, cautious = true) {
+  submitP(peering:DBPeer, eraseIfAlreadyRecorded = false, cautious = true): Promise<PeerDTO> {
     this.logger.info('⬇ PEER %s', peering.pubkey.substr(0, 8))
     // Force usage of local currency name, do not accept other currencies documents
     peering.currency = this.conf.currency || peering.currency;
@@ -79,7 +80,7 @@ export class PeeringService {
     let sigTime = 0;
     let block:DBBlock | null;
     let makeCheckings = cautious || cautious === undefined;
-    return GlobalFifoPromise.pushFIFO(async () => {
+    return GlobalFifoPromise.pushFIFO<PeerDTO>(async () => {
       try {
         if (makeCheckings) {
           let goodSignature = this.checkPeerSignature(thePeerDTO)
@@ -165,7 +166,7 @@ export class PeeringService {
             this.peerInstance = peerEntity;
           }
         }
-        return savedPeer;
+        return PeerDTO.fromDBPeer(savedPeer)
       } catch (e) {
         this.logger.info('✘ PEER %s', peering.pubkey.substr(0, 8))
         throw e
@@ -175,7 +176,7 @@ export class PeeringService {
 
   handleNewerPeer(pretendedNewer:DBPeer) {
     logger.debug('Applying pretended newer peer document %s/%s', pretendedNewer.block);
-    return this.server.singleWritePromise(_.extend({ documentType: 'peer' }, pretendedNewer));
+    return this.server.writePeer(pretendedNewer)
   }
 
   async generateSelfPeer(theConf:ConfDTO, signalTimeInterval:number) {
@@ -243,14 +244,12 @@ export class PeeringService {
     logger.debug('Generating server\'s peering entry based on block#%s...', p2.block.split('-')[0]);
     p2.signature = await this.server.sign(raw2);
     p2.pubkey = this.selfPubkey;
-    p2.documentType = 'peer';
     // Remember this is now local peer value
     this.peerInstance = p2;
     // Submit & share with the network
-    await this.server.submitP(p2, false);
+    await this.server.writePeer(p2)
     const selfPeer = await this.dal.getPeer(this.selfPubkey);
     // Set peer's statut to UP
-    selfPeer.documentType = 'selfPeer';
     await this.peer(selfPeer);
     this.server.streamPush(selfPeer);
     logger.info("Next peering signal in %s min", signalTimeInterval / 1000 / 60);
diff --git a/app/service/TransactionsService.ts b/app/service/TransactionsService.ts
index 4d57ccf238eee80fcb246c7a99a67044a0097177..868082b90813c966904807780cd264b32a1eaf4e 100644
--- a/app/service/TransactionsService.ts
+++ b/app/service/TransactionsService.ts
@@ -23,7 +23,7 @@ export class TransactionService {
   }
 
   processTx(txObj:any) {
-    return GlobalFifoPromise.pushFIFO(async () => {
+    return GlobalFifoPromise.pushFIFO<TransactionDTO>(async () => {
       const tx = TransactionDTO.fromJSONObject(txObj, this.conf.currency)
       try {
         this.logger.info('⬇ TX %s:%s from %s', tx.output_amount, tx.output_base, tx.issuers);
diff --git a/server.ts b/server.ts
index a5525f977f0b3c0ee44f2c587ba9ac9902d3897f..8bdd0d876c2c5dd567e424a3ac48422059ed78a6 100644
--- a/server.ts
+++ b/server.ts
@@ -1,15 +1,17 @@
-import {IdentityService} from "./app/service/IdentityService"
-import {MembershipService} from "./app/service/MembershipService"
-import {PeeringService} from "./app/service/PeeringService"
-import {BlockchainService} from "./app/service/BlockchainService"
-import {TransactionService} from "./app/service/TransactionsService"
-import {ConfDTO} from "./app/lib/dto/ConfDTO"
-import {FileDAL} from "./app/lib/dal/fileDAL"
-import {DuniterBlockchain} from "./app/lib/blockchain/DuniterBlockchain"
-import {SQLBlockchain} from "./app/lib/blockchain/SqlBlockchain"
-import * as stream from "stream"
-import {KeyGen, randomKey} from "./app/lib/common-libs/crypto/keyring"
-import {parsers} from "./app/lib/common-libs/parsers/index"
+import {IdentityService} from "./app/service/IdentityService";
+import {MembershipService} from "./app/service/MembershipService";
+import {PeeringService} from "./app/service/PeeringService";
+import {BlockchainService} from "./app/service/BlockchainService";
+import {TransactionService} from "./app/service/TransactionsService";
+import {ConfDTO, NetworkConfDTO} from "./app/lib/dto/ConfDTO";
+import {FileDAL} from "./app/lib/dal/fileDAL";
+import {DuniterBlockchain} from "./app/lib/blockchain/DuniterBlockchain";
+import {SQLBlockchain} from "./app/lib/blockchain/SqlBlockchain";
+import * as stream from "stream";
+import {KeyGen, randomKey} from "./app/lib/common-libs/crypto/keyring";
+import {parsers} from "./app/lib/common-libs/parsers/index";
+import {Cloneable} from "./app/lib/dto/Cloneable";
+import {DuniterDocument, duniterDocument2str} from "./app/lib/common-libs/constants";
 
 interface HookableServer {
   getMainEndpoint: (...args:any[]) => Promise<any>
@@ -22,7 +24,6 @@ interface HookableServer {
 }
 
 const path        = require('path');
-const _           = require('underscore');
 const archiver    = require('archiver');
 const unzip       = require('unzip2');
 const fs          = require('fs');
@@ -38,7 +39,6 @@ export class Server extends stream.Duplex implements HookableServer {
   conf:ConfDTO
   dal:FileDAL
 
-  documentsMapping:any
   home:string
   version:number
   logger:any
@@ -70,24 +70,28 @@ export class Server extends stream.Duplex implements HookableServer {
     this.PeeringService      = new PeeringService(this)
     this.BlockchainService   = new BlockchainService(this)
     this.TransactionsService = new TransactionService()
-
-    // Create document mapping
-    this.documentsMapping = {
-      'identity':      { action: (obj:any) => this.IdentityService.submitIdentity(obj),                                 parser: parsers.parseIdentity },
-      'certification': { action: (obj:any) => this.IdentityService.submitCertification(obj),                            parser: parsers.parseCertification},
-      'revocation':    { action: (obj:any) => this.IdentityService.submitRevocation(obj),                               parser: parsers.parseRevocation },
-      'membership':    { action: (obj:any) => this.MembershipService.submitMembership(obj),                             parser: parsers.parseMembership },
-      'peer':          { action: (obj:any) => this.PeeringService.submitP(obj),                                         parser: parsers.parsePeer },
-      'transaction':   { action: (obj:any) => this.TransactionsService.processTx(obj),                                  parser: parsers.parseTransaction },
-      'block':         { action: (obj:any) => this.BlockchainService.submitBlock(obj, true, constants.NO_FORK_ALLOWED), parser: parsers.parseBlock }
-    }
   }
 
   // Unused, but made mandatory by Duplex interface
   _read() {}
 
-  _write(obj:any, enc:any, writeDone:any) {
-    return this.submit(obj, false, () => writeDone)
+  async _write(obj:any, enc:any, writeDone:any) {
+    try {
+      if (!obj.documentType) {
+        throw "Unknown document type"
+      }
+      switch (obj.documentType) {
+        case "block": await this.writeBlock(obj); break;
+        case "identity": await this.writeIdentity(obj); break;
+        case "certification": await this.writeCertification(obj); break;
+        case "membership": await this.writeMembership(obj); break;
+        case "transaction": await this.writeTransaction(obj); break;
+        case "peer": await this.writePeer(obj); break;
+      }
+      writeDone()
+    } catch (e) {
+      writeDone()
+    }
   }
 
   /**
@@ -171,43 +175,86 @@ export class Server extends stream.Duplex implements HookableServer {
     return this;
   }
 
-  async submit(obj:any, isInnerWrite:boolean = false, done:any|null = null) {
-    if (!obj.documentType) {
-      throw 'Document type not given';
-    }
-    try {
-      const action = this.documentsMapping[obj.documentType].action;
-      let res;
-      if (typeof action == 'function') {
-        // Handle the incoming object
-        res = await action(obj)
-      } else {
-        throw 'Unknown document type \'' + obj.documentType + '\'';
-      }
-      if (res) {
-        // Only emit valid documents
-        this.emit(obj.documentType, _.clone(res));
-        this.streamPush(_.clone(res));
-      }
-      if (done) {
-        isInnerWrite ? done(null, res) : done();
-      }
-      return res;
-    } catch (err) {
-      if (err && !err.uerr) {
-        // Unhandled error, display it
-        logger.debug('Document write error: ', err);
-      }
-      if (done) {
-        isInnerWrite ? done(err, null) : done();
-      } else {
-        throw err;
-      }
-    }
+  async writeRawBlock(raw:string) {
+    const obj = parsers.parseBlock.syncWrite(raw, logger)
+    return await this.writeBlock(obj)
+  }
+
+  async writeBlock(obj:any) {
+    const res = await this.BlockchainService.submitBlock(obj, true, constants.NO_FORK_ALLOWED)
+    this.emitDocument(res, DuniterDocument.ENTITY_BLOCK)
+    return res
+  }
+
+  async writeRawIdentity(raw:string) {
+    const obj = parsers.parseIdentity.syncWrite(raw, logger)
+    return await this.writeIdentity(obj)
+  }
+
+  async writeIdentity(obj:any) {
+    const res = await this.IdentityService.submitIdentity(obj)
+    this.emitDocument(res, DuniterDocument.ENTITY_IDENTITY)
+    return res
+  }
+
+  async writeRawCertification(raw:string) {
+    const obj = parsers.parseCertification.syncWrite(raw, logger)
+    return await this.writeCertification(obj)
   }
 
-  submitP(obj:any, isInnerWrite:boolean) {
-    return this.submit(obj, isInnerWrite)
+  async writeCertification(obj:any) {
+    const res = await this.IdentityService.submitCertification(obj)
+    this.emitDocument(res, DuniterDocument.ENTITY_CERTIFICATION)
+    return res
+  }
+
+  async writeRawMembership(raw:string) {
+    const obj = parsers.parseMembership.syncWrite(raw, logger)
+    return await this.writeMembership(obj)
+  }
+
+  async writeMembership(obj:any) {
+    const res = await this.MembershipService.submitMembership(obj)
+    this.emitDocument(res, DuniterDocument.ENTITY_MEMBERSHIP)
+    return res
+  }
+
+  async writeRawRevocation(raw:string) {
+    const obj = parsers.parseRevocation.syncWrite(raw, logger)
+    return await this.writeRevocation(obj)
+  }
+
+  async writeRevocation(obj:any) {
+    const res = await this.IdentityService.submitRevocation(obj)
+    this.emitDocument(res, DuniterDocument.ENTITY_REVOCATION)
+    return res
+  }
+
+  async writeRawTransaction(raw:string) {
+    const obj = parsers.parseTransaction.syncWrite(raw, logger)
+    return await this.writeTransaction(obj)
+  }
+
+  async writeTransaction(obj:any) {
+    const res = await this.TransactionsService.processTx(obj)
+    this.emitDocument(res, DuniterDocument.ENTITY_TRANSACTION)
+    return res
+  }
+
+  async writeRawPeer(raw:string) {
+    const obj = parsers.parsePeer.syncWrite(raw, logger)
+    return await this.writePeer(obj)
+  }
+
+  async writePeer(obj:any) {
+    const res = await this.PeeringService.submitP(obj)
+    this.emitDocument(res, DuniterDocument.ENTITY_PEER)
+    return res
+  }
+
+  private async emitDocument(res:Cloneable, type:DuniterDocument) {
+    this.emit(duniterDocument2str(type), res.clone())
+    this.streamPush(res.clone())
   }
 
   async initDAL(conf:ConfDTO|null = null) {
@@ -394,16 +441,6 @@ export class Server extends stream.Duplex implements HookableServer {
     }
   }
 
-  singleWritePromise(obj:any) {
-    return this.submit(obj)
-  }
-
-  async writeRaw(raw:string, type:string) {
-    const parser = this.documentsMapping[type] && this.documentsMapping[type].parser;
-    const obj = parser.syncWrite(raw, logger);
-    return await this.singleWritePromise(obj);
-  }
-
   /*****************
    * DAEMONIZATION
    ****************/
@@ -478,7 +515,7 @@ export class Server extends stream.Duplex implements HookableServer {
   /**
    * Default endpoint. To be overriden by a module to specify another endpoint value (for ex. BMA).
    */
-  getMainEndpoint(): Promise<any> {
+  getMainEndpoint(conf:NetworkConfDTO): Promise<any> {
     return Promise.resolve('DEFAULT_ENDPOINT')
   }
 
diff --git a/test/fast/modules/bma/module-test.js b/test/fast/modules/bma/module-test.js
index 9d9bb5063276b80aff738f16be61b54b32004dc4..88ae5ce66ccc1d4840e8d92442b54f5202874bd3 100644
--- a/test/fast/modules/bma/module-test.js
+++ b/test/fast/modules/bma/module-test.js
@@ -9,9 +9,6 @@ const duniter = require('../../../../index')
 const logger = require('../../../../app/lib/logger').NewLogger()
 const rp = require('request-promise');
 
-// Do not pollute the tests with logs
-logger.mute();
-
 const stack = duniter.statics.minimalStack();
 stack.registerDependency(duniterKeypair, 'duniter-keypair');
 stack.registerDependency(duniterBMA,     'duniter-bma');
diff --git a/test/fast/modules/keypair/module-test.js b/test/fast/modules/keypair/module-test.js
index 4e7145cac6edaa87b340ecafe90fbfc4992bb70c..55638546f12a85035e21a7660f50c01ca93afd4d 100644
--- a/test/fast/modules/keypair/module-test.js
+++ b/test/fast/modules/keypair/module-test.js
@@ -5,8 +5,6 @@ const keypair = require('../../../../app/modules/keypair/index').KeypairDependen
 const assert = require('assert');
 const duniter = require('../../../../index')
 
-duniter.statics.logger.mute()
-
 describe('Module usage', () => {
 
   it('wrong options should throw', () => co(function*() {
diff --git a/test/integration/branches2.js b/test/integration/branches2.js
index 92e50e44b01e275018f7f8d50b61cd906120c4ef..ae32d6a6f3bba57d7970f8abc8f9f000ca3c06ca 100644
--- a/test/integration/branches2.js
+++ b/test/integration/branches2.js
@@ -104,7 +104,7 @@ describe("SelfFork", function() {
     yield commitS2();
     yield commitS2();
 
-    yield s1.singleWritePromise(s2p);
+    yield s1.writePeer(s2p);
 
     // Forking S1 from S2
     return require('../../app/modules/crawler').CrawlerDependency.duniter.methods.pullBlocks(s1, s2p.pubkey);
diff --git a/test/integration/branches_revert_balance.js b/test/integration/branches_revert_balance.js
index 94d6330cb1720593f804074f01b24a5e6a9db687..fc7c448f8bc6968515b6b46020456bcbc106f6cc 100644
--- a/test/integration/branches_revert_balance.js
+++ b/test/integration/branches_revert_balance.js
@@ -47,8 +47,7 @@ describe("Revert balance", () => {
       res.sources.should.have.length(3)
     })
     const block = yield s1.dal.blockDAL.getBlock(3)
-    block.documentType = 'block'
-    // yield s1.singleWritePromise(block)
+    // yield s1.writeBlock(block)
   }))
 
   it('revert: cat and tac should have 100 units', () => co(function*() {
@@ -75,8 +74,7 @@ describe("Revert balance", () => {
       res.sources.should.have.length(3)
     })
     const block = yield s1.dal.blockDAL.getBlock(3)
-    block.documentType = 'block'
-    // yield s1.singleWritePromise(block)
+    // yield s1.writeBlock(block)
   }))
 
   after(() => {
diff --git a/test/integration/branches_switch.js b/test/integration/branches_switch.js
index 9d3fd18ec47096da06caf5f16930bcd372621717..3c859e608dc0bbd5ba2b874529a00957166b0fca 100644
--- a/test/integration/branches_switch.js
+++ b/test/integration/branches_switch.js
@@ -85,7 +85,7 @@ describe("Switch", function() {
     // So we now have:
     // S1 01234
     // S2   `3456789
-    yield s1.singleWritePromise(s2p);
+    yield s1.writePeer(s2p)
 
     // Forking S1 from S2
     yield require('../../app/modules/crawler').CrawlerDependency.duniter.methods.pullBlocks(s1, s2p.pubkey);
diff --git a/test/integration/peer-outdated.js b/test/integration/peer-outdated.js
index 260b17ec7da6036e8ef60e7e5fc6f4100346b3c4..27c5e8462503afa883e607fbe2a24a56903b5359 100644
--- a/test/integration/peer-outdated.js
+++ b/test/integration/peer-outdated.js
@@ -100,7 +100,7 @@ describe("Peer document expiry", function() {
 
   it('routing V1 peer document should inject newer peer', () => co(function*() {
     yield [
-      s2.singleWritePromise(_.extend({ documentType: 'peer' }, peer1V1)),
+      s2.writePeer(peer1V1),
       until(s2, 'peer', 2)
     ];
   }));
diff --git a/test/integration/tools/sync.js b/test/integration/tools/sync.js
index f927cff793c4e68c411d90d517bd33dd02e71d48..43c0deb2c04345c1a6a2ff5156de4382627c44c8 100644
--- a/test/integration/tools/sync.js
+++ b/test/integration/tools/sync.js
@@ -9,6 +9,6 @@ module.exports = function makeBlockAndPost(fromBlock, toBlock, fromServer, toSer
   return _.range(fromBlock, toBlock + 1).reduce((p, number) => co(function*(){
     yield p;
     const json = yield rp('http://' + fromServer.conf.ipv4 + ':' + fromServer.conf.port + '/blockchain/block/' + number, { json: true });
-    yield toServer.singleWritePromise(_.extend(json, { documentType: 'block' }));
+    yield toServer.writeBlock(json)
   }), Promise.resolve());
 };
diff --git a/test/integration/tools/toolbox.ts b/test/integration/tools/toolbox.ts
index 1205a3fbd703755000bc441796c5f75c3474345c..da415ea6e9b7a5eeb9aef2cdfd2be278e759da8c 100644
--- a/test/integration/tools/toolbox.ts
+++ b/test/integration/tools/toolbox.ts
@@ -260,10 +260,34 @@ export class TestingServer {
     return this.server.recomputeSelfPeer()
   }
 
-  singleWritePromise(obj:any) {
-    return this.server.singleWritePromise(obj)
+  async writeBlock(obj:any) {
+    return this.server.writeBlock(obj)
   }
-
+  
+  async writeIdentity(obj:any) {
+    return this.server.writeIdentity(obj)
+  }
+  
+  async writeCertification(obj:any) {
+    return this.server.writeCertification(obj)
+  }
+  
+  async writeMembership(obj:any) {
+    return this.server.writeMembership(obj)
+  }
+  
+  async writeRevocation(obj:any) {
+    return this.server.writeRevocation(obj)
+  }
+  
+  async writeTransaction(obj:any) {
+    return this.server.writeTransaction(obj)
+  }
+  
+  async writePeer(obj:any) {
+    return this.server.writePeer(obj)
+  }
+  
   exportAllDataAsZIP() {
     return this.server.exportAllDataAsZIP()
   }
diff --git a/test/mocha.opts b/test/mocha.opts
index eff29581b0431d1a8960592024616c644e78abdf..13ee986171fa0dccd4c248679eb3e32bcb7f3517 100644
--- a/test/mocha.opts
+++ b/test/mocha.opts
@@ -1,7 +1,6 @@
 --compilers ts-node/register
 --require source-map-support/register
 --full-trace
---bail
 --growl
 --timeout 20000
 --recursive