diff --git a/.eslintignore b/.eslintignore
index 5d024870e8029a963451857cea3980fdb42ee614..d25a2f246707fc5599e607933c70bf26171f3e2e 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -18,8 +18,9 @@ app/lib/rules/*.js
 app/lib/system/*.js
 app/lib/streams/*.js
 app/lib/helpers/*.js
-app/lib/ws2p/*.js
-app/lib/ws2p/*/*.js
+app/modules/ws2p/*.js
+app/modules/ws2p/lib/*.js
+app/modules/ws2p/lib/*/*.js
 app/lib/*.js
 app/modules/wizard.js
 app/modules/router.js
diff --git a/app/lib/dto/ConfDTO.ts b/app/lib/dto/ConfDTO.ts
index 40f4ad2b6e76468844f5656be70aa26853ef2c7b..f8db265cb6db2e1f1c4385e7d6e9add1318b11b8 100644
--- a/app/lib/dto/ConfDTO.ts
+++ b/app/lib/dto/ConfDTO.ts
@@ -1,4 +1,4 @@
-import {CommonConstants} from "../common-libs/constants";
+import {CommonConstants} from "../common-libs/constants"
 const _ = require('underscore');
 const constants = require('../constants');
 
@@ -58,6 +58,16 @@ export interface NetworkConfDTO {
   httplogs:boolean
 }
 
+export interface WS2PConfDTO {
+  ws2p?: {
+    upnp?: boolean
+    remotehost?: string|null
+    remoteport?: number|null
+    port?: number
+    host?: string
+  }
+}
+
 export class ConfDTO implements CurrencyConfDTO, KeypairConfDTO, NetworkConfDTO, BranchingDTO {
 
   constructor(
diff --git a/app/lib/streams/WS2PStreamer.ts b/app/lib/streams/WS2PStreamer.ts
index e324bbbe291f10fd92940925787b085fff4cd71b..1e8685cd02d110353a21b6e2a0fc1d6d89982577 100644
--- a/app/lib/streams/WS2PStreamer.ts
+++ b/app/lib/streams/WS2PStreamer.ts
@@ -1,5 +1,5 @@
 import * as stream from "stream"
-import {WS2PConnection} from "../ws2p/WS2PConnection"
+import {WS2PConnection} from "../../modules/ws2p/lib/WS2PConnection"
 
 export class WS2PStreamer extends stream.Transform {
 
diff --git a/app/modules/ws2p/index.ts b/app/modules/ws2p/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5f25b58015297f62bea67ca422d68fff4b8018ea
--- /dev/null
+++ b/app/modules/ws2p/index.ts
@@ -0,0 +1,106 @@
+"use strict";
+import {WS2PConfDTO} from "../../lib/dto/ConfDTO"
+import {Server} from "../../../server"
+import * as stream from "stream"
+import {WS2PCluster} from "./lib/WS2PCluster"
+import {WS2PUpnp} from "./lib/ws2p-upnp"
+
+export const WS2PDependency = {
+  duniter: {
+
+    cliOptions: [
+      { value: '--ws2p-upnp',                  desc: 'Use UPnP to open remote port.' },
+      { value: '--ws2p-noupnp',                desc: 'Do not use UPnP to open remote port.' },
+      { value: '--ws2p-port <port>',           desc: 'Host to listen to' },
+      { value: '--ws2p-host <host>',           desc: 'Port to listen to', parser: (val:string) => parseInt(val) },
+      { value: '--ws2p-remote-host <address>', desc: 'Availabily host' },
+      { value: '--ws2p-remote-port <port>',    desc: 'Availabily port', parser: (val:string) => parseInt(val) },
+    ],
+
+    config: {
+
+      onLoading: async (conf:WS2PConfDTO, program:any, logger:any) => {
+
+        conf.ws2p = conf.ws2p || {}
+
+        if (program.ws2pHost !== undefined)       conf.ws2p.host = program.ws2pHost
+        if (program.ws2pPort !== undefined)       conf.ws2p.port = parseInt(program.ws2pPort)
+        if (program.ws2pRemotePort !== undefined) conf.ws2p.remoteport = program.ws2pRemotePort
+        if (program.ws2pRemoteHost !== undefined) conf.ws2p.remotehost = program.ws2pRemoteHost
+        if (program.ws2pUpnp !== undefined)       conf.ws2p.upnp = true
+        if (program.ws2pNoupnp !== undefined)     conf.ws2p.upnp = false
+
+        // Default value
+        if (conf.ws2p.upnp === undefined || conf.ws2p.upnp === null) {
+          conf.ws2p.upnp = true; // Defaults to true
+        }
+      },
+
+      beforeSave: async (conf:WS2PConfDTO) => {
+        if (conf.ws2p && !conf.ws2p.host) delete conf.ws2p.host
+        if (conf.ws2p && !conf.ws2p.port) delete conf.ws2p.port
+        if (conf.ws2p && !conf.ws2p.remoteport) delete conf.ws2p.remoteport
+        if (conf.ws2p && !conf.ws2p.remotehost) delete conf.ws2p.remotehost
+      }
+    },
+
+    service: {
+      input: (server:Server, conf:WS2PConfDTO, logger:any) => {
+        return new WS2PAPI(server, conf, logger)
+      }
+    }
+  }
+}
+
+export class WS2PAPI extends stream.Transform {
+
+  // Public http interface
+  private cluster:WS2PCluster
+  private upnpAPI:WS2PUpnp
+
+  constructor(
+    private server:Server,
+    private conf:WS2PConfDTO,
+    private logger:any) {
+    super({ objectMode: true })
+    this.cluster = new WS2PCluster(server)
+  }
+
+  startService = async () => {
+
+    /***************
+     *   MANUAL
+     **************/
+    if (this.conf.ws2p
+      && !this.conf.ws2p.upnp
+      && this.conf.ws2p.host
+      && this.conf.ws2p.port) {
+      await this.cluster.listen(this.conf.ws2p.host, this.conf.ws2p.port)
+    }
+
+    /***************
+     *    UPnP
+     **************/
+    else if (!this.conf.ws2p || this.conf.ws2p.upnp !== false) {
+      if (this.upnpAPI) {
+        this.upnpAPI.stopRegular();
+      }
+      try {
+        this.upnpAPI = await new WS2PUpnp(this.logger)
+        const { host, port } = await this.upnpAPI.startRegular()
+        await this.cluster.listen(host, port)
+      } catch (e) {
+        this.logger.warn(e);
+      }
+    }
+  }
+
+  stopService = async () => {
+    if (this.cluster) {
+      await this.cluster.close()
+    }
+    if (this.upnpAPI) {
+      this.upnpAPI.stopRegular();
+    }
+  }
+}
\ No newline at end of file
diff --git a/app/lib/ws2p/WS2PBlockPuller.ts b/app/modules/ws2p/lib/WS2PBlockPuller.ts
similarity index 90%
rename from app/lib/ws2p/WS2PBlockPuller.ts
rename to app/modules/ws2p/lib/WS2PBlockPuller.ts
index 3613257cc8630d5cc91a8bcfb6c2907a8d223f15..59ee4da09984e909c9093d7a0f0a38d0ad7364c8 100644
--- a/app/lib/ws2p/WS2PBlockPuller.ts
+++ b/app/modules/ws2p/lib/WS2PBlockPuller.ts
@@ -1,10 +1,10 @@
-import {BlockDTO} from "../dto/BlockDTO"
-import {AbstractDAO} from "../../modules/crawler/lib/pulling"
-import {Server} from "../../../server"
-import {DBBlock} from "../db/DBBlock"
-import {PeerDTO} from "../dto/PeerDTO"
-import {CrawlerConstants} from "../../modules/crawler/lib/constants"
-import {tx_cleaner} from "../../modules/crawler/lib/tx_cleaner"
+import {BlockDTO} from "../../../lib/dto/BlockDTO"
+import {AbstractDAO} from "../../crawler/lib/pulling"
+import {Server} from "../../../../server"
+import {DBBlock} from "../../../lib/db/DBBlock"
+import {PeerDTO} from "../../../lib/dto/PeerDTO"
+import {CrawlerConstants} from "../../crawler/lib/constants"
+import {tx_cleaner} from "../../crawler/lib/tx_cleaner"
 import {WS2PConnection} from "./WS2PConnection"
 import {WS2PRequester} from "./WS2PRequester"
 
diff --git a/app/lib/ws2p/WS2PClient.ts b/app/modules/ws2p/lib/WS2PClient.ts
similarity index 83%
rename from app/lib/ws2p/WS2PClient.ts
rename to app/modules/ws2p/lib/WS2PClient.ts
index f1eac48ea9e1995c33b3d4fe1eff3d4e9a3adf6a..4ebc8c4a3547753540495023f393b944848d9a60 100644
--- a/app/lib/ws2p/WS2PClient.ts
+++ b/app/modules/ws2p/lib/WS2PClient.ts
@@ -1,8 +1,8 @@
-import {Server} from "../../../server"
+import {Server} from "../../../../server"
 import {WS2PConnection, WS2PPubkeyLocalAuth, WS2PPubkeyRemoteAuth} from "./WS2PConnection"
 import {WS2PServerMessageHandler} from "./interface/WS2PServerMessageHandler"
-import {WS2PStreamer} from "../streams/WS2PStreamer"
-import {Key} from "../common-libs/crypto/keyring"
+import {WS2PStreamer} from "../../../lib/streams/WS2PStreamer"
+import {Key} from "../../../lib/common-libs/crypto/keyring"
 
 export class WS2PClient {
 
diff --git a/app/lib/ws2p/WS2PCluster.ts b/app/modules/ws2p/lib/WS2PCluster.ts
similarity index 86%
rename from app/lib/ws2p/WS2PCluster.ts
rename to app/modules/ws2p/lib/WS2PCluster.ts
index 90af4d2f57d401408682b530dd047c0cdad6388b..3b6d8257b579d558651c679f2e66e09a9a723f05 100644
--- a/app/lib/ws2p/WS2PCluster.ts
+++ b/app/modules/ws2p/lib/WS2PCluster.ts
@@ -1,9 +1,9 @@
 import {WS2PServer} from "./WS2PServer"
-import {Server} from "../../../server"
+import {Server} from "../../../../server"
 import {WS2PClient} from "./WS2PClient"
 import {WS2PConnection} from "./WS2PConnection"
-import {randomPick} from "../common-libs/randomPick"
-import {CrawlerConstants} from "../../modules/crawler/lib/constants"
+import {randomPick} from "../../../lib/common-libs/randomPick"
+import {CrawlerConstants} from "../../crawler/lib/constants"
 import {WS2PBlockPuller} from "./WS2PBlockPuller"
 import {WS2PDocpoolPuller} from "./WS2PDocpoolPuller"
 
@@ -24,6 +24,14 @@ export class WS2PCluster {
     return this.ws2pServer
   }
 
+  async close() {
+    if (this.ws2pServer) {
+      await this.ws2pServer.close()
+    }
+    const connections = await this.getAllConnections()
+    await Promise.all(connections.map(c => c.close()))
+  }
+
   clientsCount() {
     return Object.keys(this.ws2pClients).length
   }
diff --git a/app/lib/ws2p/WS2PConnection.ts b/app/modules/ws2p/lib/WS2PConnection.ts
similarity index 97%
rename from app/lib/ws2p/WS2PConnection.ts
rename to app/modules/ws2p/lib/WS2PConnection.ts
index 1a85b5242d4da9d916cec941deac413a309b95b6..a801016105d51812b405925a62a1206d37fe958b 100644
--- a/app/lib/ws2p/WS2PConnection.ts
+++ b/app/modules/ws2p/lib/WS2PConnection.ts
@@ -1,11 +1,11 @@
-import {Key, verify} from "../common-libs/crypto/keyring"
+import {Key, verify} from "../../../lib/common-libs/crypto/keyring"
 import {WS2PMessageHandler} from "./impl/WS2PMessageHandler"
-import {BlockDTO} from "../dto/BlockDTO"
-import {IdentityDTO} from "../dto/IdentityDTO"
-import {CertificationDTO} from "../dto/CertificationDTO"
-import {MembershipDTO} from "../dto/MembershipDTO"
-import {TransactionDTO} from "../dto/TransactionDTO"
-import {PeerDTO} from "../dto/PeerDTO"
+import {BlockDTO} from "../../../lib/dto/BlockDTO"
+import {IdentityDTO} from "../../../lib/dto/IdentityDTO"
+import {CertificationDTO} from "../../../lib/dto/CertificationDTO"
+import {MembershipDTO} from "../../../lib/dto/MembershipDTO"
+import {TransactionDTO} from "../../../lib/dto/TransactionDTO"
+import {PeerDTO} from "../../../lib/dto/PeerDTO"
 const ws = require('ws')
 const nuuid = require('node-uuid');
 
diff --git a/app/lib/ws2p/WS2PDocpoolPuller.ts b/app/modules/ws2p/lib/WS2PDocpoolPuller.ts
similarity index 83%
rename from app/lib/ws2p/WS2PDocpoolPuller.ts
rename to app/modules/ws2p/lib/WS2PDocpoolPuller.ts
index d95da8a5ccee2289c92429a261f442cfea9c022c..d95d55436f62cbc49f3dae7871f5b5d47498b46f 100644
--- a/app/lib/ws2p/WS2PDocpoolPuller.ts
+++ b/app/modules/ws2p/lib/WS2PDocpoolPuller.ts
@@ -1,7 +1,7 @@
-import {Server} from "../../../server"
+import {Server} from "../../../../server"
 import {WS2PConnection} from "./WS2PConnection"
 import {WS2PRequester} from "./WS2PRequester"
-import {pullSandboxToLocalServer} from "../../modules/crawler/lib/sandbox"
+import {pullSandboxToLocalServer} from "../../crawler/lib/sandbox"
 
 export class WS2PDocpoolPuller {
 
diff --git a/app/lib/ws2p/WS2PRequester.ts b/app/modules/ws2p/lib/WS2PRequester.ts
similarity index 94%
rename from app/lib/ws2p/WS2PRequester.ts
rename to app/modules/ws2p/lib/WS2PRequester.ts
index 7c3725d510f792bfceb6e60f5f977488d0427d1e..f3ed8818dac92d3634950d8df49446d449284218 100644
--- a/app/lib/ws2p/WS2PRequester.ts
+++ b/app/modules/ws2p/lib/WS2PRequester.ts
@@ -1,5 +1,5 @@
 import {WS2PConnection} from "./WS2PConnection"
-import {BlockDTO} from "../dto/BlockDTO"
+import {BlockDTO} from "../../../lib/dto/BlockDTO"
 
 export enum WS2P_REQ {
   WOT_REQUIREMENTS_OF_PENDING,
diff --git a/app/lib/ws2p/WS2PServer.ts b/app/modules/ws2p/lib/WS2PServer.ts
similarity index 90%
rename from app/lib/ws2p/WS2PServer.ts
rename to app/modules/ws2p/lib/WS2PServer.ts
index e02ee6ff4627c98b11e45f6c402526625d2ec51c..e990d5752a1b28db6a9aa95ccfc2edc3ed32f72a 100644
--- a/app/lib/ws2p/WS2PServer.ts
+++ b/app/modules/ws2p/lib/WS2PServer.ts
@@ -1,8 +1,8 @@
-import {Server} from "../../../server"
+import {Server} from "../../../../server"
 import {WS2PConnection, WS2PPubkeyLocalAuth, WS2PPubkeyRemoteAuth} from "./WS2PConnection"
 import {WS2PServerMessageHandler} from "./interface/WS2PServerMessageHandler"
-import {WS2PStreamer} from "../streams/WS2PStreamer"
-import {Key} from "../common-libs/crypto/keyring"
+import {WS2PStreamer} from "../../../lib/streams/WS2PStreamer"
+import {Key} from "../../../lib/common-libs/crypto/keyring"
 
 const WebSocketServer = require('ws').Server
 
@@ -79,6 +79,7 @@ export class WS2PServer {
   static async bindOn(server:Server, host:string, port:number) {
     const ws2ps = new WS2PServer(server, host, port)
     await ws2ps.listenToWebSocketConnections()
+    server.logger.info('WS2P server listening on %s:%s', host, port)
     return ws2ps
   }
 }
\ No newline at end of file
diff --git a/app/modules/ws2p/lib/constants.ts b/app/modules/ws2p/lib/constants.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e4fd5f3c7a31867faa8c5ae87114965b82018a58
--- /dev/null
+++ b/app/modules/ws2p/lib/constants.ts
@@ -0,0 +1,8 @@
+export const WS2PConstants = {
+
+  WS2P_UPNP_TTL: 600,
+  WS2P_PORTS_START: 20900,
+  WS2P_PORTS_END: 20999,
+  WS2P_UPNP_INTERVAL: 300
+
+}
\ No newline at end of file
diff --git a/app/lib/ws2p/impl/WS2PMessageHandler.ts b/app/modules/ws2p/lib/impl/WS2PMessageHandler.ts
similarity index 100%
rename from app/lib/ws2p/impl/WS2PMessageHandler.ts
rename to app/modules/ws2p/lib/impl/WS2PMessageHandler.ts
diff --git a/app/lib/ws2p/impl/WS2PReqMapperByServer.ts b/app/modules/ws2p/lib/impl/WS2PReqMapperByServer.ts
similarity index 91%
rename from app/lib/ws2p/impl/WS2PReqMapperByServer.ts
rename to app/modules/ws2p/lib/impl/WS2PReqMapperByServer.ts
index 8f7675233e424f83fc7e10addb8808f553016f48..368757b0b457e9ccc1e94298b33688ce6ac0d27f 100644
--- a/app/lib/ws2p/impl/WS2PReqMapperByServer.ts
+++ b/app/modules/ws2p/lib/impl/WS2PReqMapperByServer.ts
@@ -1,6 +1,6 @@
-import {Server} from "../../../../server"
+import {Server} from "../../../../../server"
 import {WS2PReqMapper} from "../interface/WS2PReqMapper"
-import {BlockDTO} from "../../dto/BlockDTO"
+import {BlockDTO} from "../../../../lib/dto/BlockDTO"
 
 export class WS2PReqMapperByServer implements WS2PReqMapper {
 
diff --git a/app/lib/ws2p/impl/WS2PResponse.ts b/app/modules/ws2p/lib/impl/WS2PResponse.ts
similarity index 100%
rename from app/lib/ws2p/impl/WS2PResponse.ts
rename to app/modules/ws2p/lib/impl/WS2PResponse.ts
diff --git a/app/lib/ws2p/interface/WS2PReqMapper.ts b/app/modules/ws2p/lib/interface/WS2PReqMapper.ts
similarity index 81%
rename from app/lib/ws2p/interface/WS2PReqMapper.ts
rename to app/modules/ws2p/lib/interface/WS2PReqMapper.ts
index ded05ead01d3c1a7c99f977045a3c54956c605e6..cdea2c5e8534ea1085e4702b0d614a906f0613c7 100644
--- a/app/lib/ws2p/interface/WS2PReqMapper.ts
+++ b/app/modules/ws2p/lib/interface/WS2PReqMapper.ts
@@ -1,4 +1,4 @@
-import {BlockDTO} from "../../dto/BlockDTO"
+import {BlockDTO} from "../../../../lib/dto/BlockDTO"
 
 export interface WS2PReqMapper {
 
diff --git a/app/lib/ws2p/interface/WS2PServerMessageHandler.ts b/app/modules/ws2p/lib/interface/WS2PServerMessageHandler.ts
similarity index 89%
rename from app/lib/ws2p/interface/WS2PServerMessageHandler.ts
rename to app/modules/ws2p/lib/interface/WS2PServerMessageHandler.ts
index 47cd0a0645c50fea24d4c7cfdfa092da6c326bc1..8033c0db50847b0ac4d6b08adfd8cce8504bc194 100644
--- a/app/lib/ws2p/interface/WS2PServerMessageHandler.ts
+++ b/app/modules/ws2p/lib/interface/WS2PServerMessageHandler.ts
@@ -1,14 +1,14 @@
 import {WS2PMessageHandler} from "../impl/WS2PMessageHandler"
 import {WS2PResponse} from "../impl/WS2PResponse"
-import {Server} from "../../../../server"
+import {Server} from "../../../../../server"
 import {WS2PReqMapperByServer} from "../impl/WS2PReqMapperByServer"
 import {WS2PReqMapper} from "./WS2PReqMapper"
-import {BlockDTO} from "../../dto/BlockDTO"
-import {IdentityDTO} from "../../dto/IdentityDTO"
-import {CertificationDTO} from "../../dto/CertificationDTO"
-import {MembershipDTO} from "../../dto/MembershipDTO"
-import {TransactionDTO} from "../../dto/TransactionDTO"
-import {PeerDTO} from "../../dto/PeerDTO"
+import {BlockDTO} from "../../../../lib/dto/BlockDTO"
+import {IdentityDTO} from "../../../../lib/dto/IdentityDTO"
+import {CertificationDTO} from "../../../../lib/dto/CertificationDTO"
+import {MembershipDTO} from "../../../../lib/dto/MembershipDTO"
+import {TransactionDTO} from "../../../../lib/dto/TransactionDTO"
+import {PeerDTO} from "../../../../lib/dto/PeerDTO"
 import {WS2P_REQ} from "../WS2PRequester"
 
 export enum WS2P_REQERROR {
diff --git a/app/modules/ws2p/lib/ws2p-upnp.ts b/app/modules/ws2p/lib/ws2p-upnp.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f91d9b2bc91e2b51b518d5077f27a128ed7f552c
--- /dev/null
+++ b/app/modules/ws2p/lib/ws2p-upnp.ts
@@ -0,0 +1,109 @@
+import {WS2PConstants} from "./constants"
+const upnp = require('nnupnp');
+const Q = require('q');
+
+export class WS2PUpnp {
+
+  private interval:NodeJS.Timer|null
+  private client = upnp.createClient()
+
+  constructor(
+    private logger:any
+  ) {}
+
+  async checkUPnPisAvailable() {
+    try {
+      await Q.nbind(this.client.externalIp, this.client)()
+      return true
+    } catch (err) {
+      return false
+    }
+  }
+
+  openPort() {
+    return Q.Promise(async (resolve:any, reject:any) => {
+      const upnpBinding = await WS2PUpnp.getAvailablePort(this.client)
+      this.logger.trace('WS2P: mapping external port %s to local %s using UPnP...', upnpBinding.host, upnpBinding.port)
+      const client = upnp.createClient()
+      client.portMapping({
+        'public': upnpBinding.port,
+        'private': upnpBinding.port,
+        'ttl': WS2PConstants.WS2P_UPNP_TTL
+      }, (err:any) => {
+        client.close()
+        if (err) {
+          this.logger.warn(err)
+          return reject(err)
+        }
+        resolve(upnpBinding)
+      })
+    })
+  }
+
+  async startRegular() {
+    this.stopRegular();
+    if (await this.checkUPnPisAvailable()) {
+      // Update UPnP IGD every INTERVAL seconds
+      this.interval = setInterval(() => this.openPort(), 1000 * WS2PConstants.WS2P_UPNP_INTERVAL)
+    }
+    return this.openPort()
+  }
+
+  stopRegular() {
+    if (this.interval) {
+      clearInterval(this.interval)
+    }
+  }
+
+  static async getLocalIP(client:any) {
+    return await new Promise((resolve:any, reject:any) => {
+      client.findGateway((err:any, res:any, localIP:any) => {
+        if (err) return reject(err)
+        resolve(localIP)
+      })
+    })
+  }
+
+  static async getAvailablePort(client:any) {
+    const localIP = await WS2PUpnp.getLocalIP(client)
+    const mappings:{
+      private: {
+        host:string
+      }
+      public: {
+        port:number
+      }
+    }[] = await WS2PUpnp.getUPnPMappings(client)
+    const ipOfPort:string[] = []
+    const externalPortsUsed = mappings.map((m) => {
+      ipOfPort.push(m.private.host)
+      return m.public.port
+    })
+    let availablePort = WS2PConstants.WS2P_PORTS_START
+    while (externalPortsUsed.indexOf(availablePort) !== -1
+      && ipOfPort[externalPortsUsed.indexOf(availablePort)] !== localIP
+      && availablePort <= WS2PConstants.WS2P_PORTS_END) {
+      availablePort++
+    }
+    if (availablePort > WS2PConstants.WS2P_PORTS_END) {
+      throw "No port available for UPnP"
+    }
+    return {
+      host: localIP,
+      port: availablePort
+    }
+  }
+
+  static async getUPnPMappings(client:any): Promise<any> {
+    return new Promise((resolve, reject) => {
+      client.getMappings((err:any, res:any) => {
+        if (err) {
+          reject(err)
+        }
+        else {
+          resolve(res)
+        }
+      })
+    })
+  }
+}
\ No newline at end of file
diff --git a/index.ts b/index.ts
index bb711b71e7c7aab7a4cd4d128d98a05c7a6cd286..ce96dcd7a489f79d0b6a3645de40bd2b473a1644 100644
--- a/index.ts
+++ b/index.ts
@@ -5,7 +5,8 @@ import {ConfDTO} from "./app/lib/dto/ConfDTO"
 import {ProverDependency} from "./app/modules/prover/index"
 import {KeypairDependency} from "./app/modules/keypair/index"
 import {CrawlerDependency} from "./app/modules/crawler/index"
-import {BmaDependency} from "./app/modules/bma/index";
+import {BmaDependency} from "./app/modules/bma/index"
+import {WS2PDependency} from "./app/modules/ws2p/index"
 
 const path = require('path');
 const _ = require('underscore');
@@ -104,7 +105,8 @@ const DEFAULT_DEPENDENCIES = MINIMAL_DEPENDENCIES.concat([
   { name: 'duniter-prover',    required: ProverDependency },
   { name: 'duniter-keypair',   required: KeypairDependency },
   { name: 'duniter-crawler',   required: CrawlerDependency },
-  { name: 'duniter-bma',       required: BmaDependency }
+  { name: 'duniter-bma',       required: BmaDependency },
+  { name: 'duniter-ws2p',      required: WS2PDependency }
 ]);
 
 const PRODUCTION_DEPENDENCIES = DEFAULT_DEPENDENCIES.concat([
diff --git a/test/integration/tools/toolbox.ts b/test/integration/tools/toolbox.ts
index cfdd28144deba0f32c6281965dcd6524700ec406..a2bea97420da54071745ad92d39adbe67c0f514f 100644
--- a/test/integration/tools/toolbox.ts
+++ b/test/integration/tools/toolbox.ts
@@ -16,11 +16,11 @@ import {FileDAL} from "../../../app/lib/dal/fileDAL"
 import {MembershipDTO} from "../../../app/lib/dto/MembershipDTO"
 import {TransactionDTO} from "../../../app/lib/dto/TransactionDTO"
 import {Key} from "../../../app/lib/common-libs/crypto/keyring"
-import {WS2PConnection, WS2PPubkeyLocalAuth, WS2PPubkeyRemoteAuth} from "../../../app/lib/ws2p/WS2PConnection"
-import {WS2PResponse} from "../../../app/lib/ws2p/impl/WS2PResponse"
-import {WS2PMessageHandler} from "../../../app/lib/ws2p/impl/WS2PMessageHandler"
-import {WS2PCluster} from "../../../app/lib/ws2p/WS2PCluster"
-import {WS2PServer} from "../../../app/lib/ws2p/WS2PServer"
+import {WS2PConnection, WS2PPubkeyLocalAuth, WS2PPubkeyRemoteAuth} from "../../../app/modules/ws2p/lib/WS2PConnection"
+import {WS2PResponse} from "../../../app/modules/ws2p/lib/impl/WS2PResponse"
+import {WS2PMessageHandler} from "../../../app/modules/ws2p/lib/impl/WS2PMessageHandler"
+import {WS2PCluster} from "../../../app/modules/ws2p/lib/WS2PCluster"
+import {WS2PServer} from "../../../app/modules/ws2p/lib/WS2PServer"
 
 const assert      = require('assert');
 const _           = require('underscore');
diff --git a/test/integration/ws2p_connection.ts b/test/integration/ws2p_connection.ts
index 777f44a11f32a837941d72841199cb93435738df..386474ff572ed5de547d9b3bd2db1f6c1ddd464e 100644
--- a/test/integration/ws2p_connection.ts
+++ b/test/integration/ws2p_connection.ts
@@ -4,11 +4,11 @@ import {
   WS2PPubkeyLocalAuth,
   WS2PPubkeyRemoteAuth,
   WS2PRemoteAuth
-} from "../../app/lib/ws2p/WS2PConnection"
+} from "../../app/modules/ws2p/lib/WS2PConnection"
 import {Key, verify} from "../../app/lib/common-libs/crypto/keyring"
 import {assertThrows} from "./tools/toolbox"
-import {WS2PMessageHandler} from "../../app/lib/ws2p/impl/WS2PMessageHandler"
-import {WS2PResponse} from "../../app/lib/ws2p/impl/WS2PResponse"
+import {WS2PMessageHandler} from "../../app/modules/ws2p/lib/impl/WS2PMessageHandler"
+import {WS2PResponse} from "../../app/modules/ws2p/lib/impl/WS2PResponse"
 const assert = require('assert');
 const WebSocketServer = require('ws').Server
 
diff --git a/test/integration/ws2p_docpool.ts b/test/integration/ws2p_docpool.ts
index e3745292034d7f816f30fd20df14e7f519cca2d2..90cc54ec508a43cbfd3615058fc5a4df62d901ad 100644
--- a/test/integration/ws2p_docpool.ts
+++ b/test/integration/ws2p_docpool.ts
@@ -1,5 +1,5 @@
 import {simpleTestingConf, simpleTestingServer, simpleUser, simpleWS2PNetwork, TestingServer} from "./tools/toolbox"
-import {WS2PCluster} from "../../app/lib/ws2p/WS2PCluster"
+import {WS2PCluster} from "../../app/modules/ws2p/lib/WS2PCluster"
 import {ProverDependency} from "../../app/modules/prover/index"
 
 const assert = require('assert')
diff --git a/test/integration/ws2p_exchange.ts b/test/integration/ws2p_exchange.ts
index 6a52b330cd17e03634bd74915771e9a9f685066d..3ab76ebbd5c0521cb65eb086888daada7bad513d 100644
--- a/test/integration/ws2p_exchange.ts
+++ b/test/integration/ws2p_exchange.ts
@@ -1,11 +1,11 @@
-import {WS2PConnection} from "../../app/lib/ws2p/WS2PConnection"
+import {WS2PConnection} from "../../app/modules/ws2p/lib/WS2PConnection"
 import {Key} from "../../app/lib/common-libs/crypto/keyring"
 import {newWS2PBidirectionnalConnection} from "./tools/toolbox"
-import {WS2PRequester} from "../../app/lib/ws2p/WS2PRequester"
-import {WS2PReqMapper} from "../../app/lib/ws2p/WS2PReqMapper"
+import {WS2PRequester} from "../../app/modules/ws2p/lib/WS2PRequester"
+import {WS2PReqMapper} from "../../app/modules/ws2p/WS2PReqMapper"
 import {BlockDTO} from "../../app/lib/dto/BlockDTO"
-import {WS2PMessageHandler} from "../../app/lib/ws2p/impl/WS2PMessageHandler"
-import {WS2PResponse} from "../../app/lib/ws2p/impl/WS2PResponse"
+import {WS2PMessageHandler} from "../../app/modules/ws2p/lib/impl/WS2PMessageHandler"
+import {WS2PResponse} from "../../app/modules/ws2p/lib/impl/WS2PResponse"
 const assert = require('assert');
 
 describe('WS2P exchange', () => {
diff --git a/test/integration/ws2p_pulling.ts b/test/integration/ws2p_pulling.ts
index df5bcff4ec7416f04e9a91433247c4e48515189d..39d8e8e3b8f175c1e9f27d25e7fd1d6a2821aa1a 100644
--- a/test/integration/ws2p_pulling.ts
+++ b/test/integration/ws2p_pulling.ts
@@ -1,5 +1,5 @@
 import {simpleTestingConf, simpleTestingServer, simpleUser, simpleWS2PNetwork, TestingServer} from "./tools/toolbox"
-import {WS2PCluster} from "../../app/lib/ws2p/WS2PCluster"
+import {WS2PCluster} from "../../app/modules/ws2p/lib/WS2PCluster"
 
 const assert = require('assert')