diff --git a/app/cli.js b/app/cli.js
index 63970ab6b910b6b6c42d525a744c73d473ca4936..330e55ffb7d75395da029a081af8cd8df57838d6 100644
--- a/app/cli.js
+++ b/app/cli.js
@@ -2,898 +2,890 @@
 
 const co = require('co');
 const logger = require('../app/lib/logger')('cli');
+const async = require('async');
+const Q = require('q');
+const _ = require('underscore');
+const program = require('commander');
+const vucoin = require('vucoin');
+const directory = require('../app/lib/system/directory');
+const wizard = require('../app/lib/wizard');
+const multicaster = require('../app/lib/streams/multicaster');
+const keyring = require('../app/lib/crypto/keyring');
+const base58 = require('../app/lib/crypto/base58');
+const pjson = require('../package.json');
+const duniter = require('../index');
+const Peer = require('../app/lib/entity/peer');
+const Block = require('../app/lib/entity/block');
+
+let currentCommand = Promise.resolve(true);
+
+let onResolve, onReject, closeCommand = () => Promise.resolve(true);
 
 module.exports = (programArgs) => {
-  return new DuniterCommand(programArgs);
-};
 
-function DuniterCommand(programArgs) {
+  currentCommand = new Promise((resolve, reject) => {
+    onResolve = resolve;
+    onReject = reject;
+  });
+  
+  return {
 
-  let that = this;
+    // Some external event can trigger the program closing function
+    closeCommand: () => closeCommand(),
 
-  // Default close process: does nothing
-  this.closeCommand = () => {};
+    // To execute the provided command
+    execute: () => co(function*() {
 
-  this.execute = () => co(function*() {
+      program.parse(programArgs);
 
-    let onResolve, onReject;
-    const commandExecution = new Promise((resolve, reject) => {
-      onResolve = resolve;
-      onReject = reject;
-    });
+      if (programArgs.length <= 2) {
 
-    function subCommand(promiseFunc) {
-      return function() {
-        let args = Array.prototype.slice.call(arguments, 0);
-        return co(function*() {
+        console.log('No command given, using default: ucoind webwait');
+        return co(function *() {
           try {
-            yield promiseFunc.apply(null, args);
-            onResolve();
+            yield webWait();
           } catch (e) {
             logger.error(e);
-            onReject();
+            throw Error("Exiting");
           }
-        })
-      };
-    }
+        });
+      }
+
+      const res = yield currentCommand;
+      if (closeCommand) {
+        yield closeCommand();
+      }
+      return res;
+    })
+  };
+};
 
-    const async = require('async');
-    const Q = require('q');
-    const _ = require('underscore');
-    const program = require('commander');
-    const vucoin = require('vucoin');
-    const directory = require('../app/lib/system/directory');
-    const wizard = require('../app/lib/wizard');
-    const multicaster = require('../app/lib/streams/multicaster');
-    const keyring = require('../app/lib/crypto/keyring');
-    const base58 = require('../app/lib/crypto/base58');
-    const pjson = require('../package.json');
-    const duniter = require('../index');
-    const Peer = require('../app/lib/entity/peer');
-    const Block = require('../app/lib/entity/block');
-
-    const ERASE_IF_ALREADY_RECORDED = true;
-    const NO_LOGS = true;
-
-    program
-      .version(pjson.version)
-      .usage('<command> [options]')
-
-      .option('--home <path>', 'Path to Duniter HOME (defaults to "$HOME/.config/duniter").')
-      .option('-d, --mdb <name>', 'Database name (defaults to "duniter_default").')
-
-      .option('--autoconf', 'With `init` command, will guess the best network and key options witout aksing for confirmation')
-      .option('--ipv4 <address>', 'IPv4 interface to listen for requests')
-      .option('--ipv6 <address>', 'IPv6 interface to listen for requests')
-      .option('--remoteh <host>', 'Remote interface others may use to contact this node')
-      .option('--remote4 <host>', 'Remote interface for IPv4 access')
-      .option('--remote6 <host>', 'Remote interface for IPv6 access')
-      .option('-p, --port <port>', 'Port to listen for requests', parseInt)
-      .option('--remotep <port>', 'Remote port others may use to contact this node')
-      .option('--upnp', 'Use UPnP to open remote port')
-      .option('--noupnp', 'Do not use UPnP to open remote port')
-
-      // Webmin options
-      .option('--webmhost <host>', 'Local network interface to connect to (IP)')
-      .option('--webmport <port>', 'Local network port to connect', parseInt)
-
-      .option('--salt <salt>', 'Key salt to generate this key\'s secret key')
-      .option('--passwd <password>', 'Password to generate this key\'s secret key')
-      .option('--participate <Y|N>', 'Participate to writing the blockchain')
-      .option('--cpu <percent>', 'Percent of CPU usage for proof-of-work computation', parsePercent)
-
-      .option('-c, --currency <name>', 'Name of the currency managed by this node.')
-      .option('--sigPeriod <timestamp>', 'Minimum delay between 2 certifications of a same issuer, in seconds.')
-      .option('--sigStock <count>', 'Maximum quantity of valid certifications per member.')
-      .option('--sigWindow <duration>', 'Maximum age of a non-written certification.')
-      .option('--idtyWindow <duration>', 'Maximum age of a non-written certification.')
-      .option('--sigValidity <timestamp>', 'Validity duration of a certification, in seconds.')
-      .option('--msValidity <timestamp>', 'Validity duration of a memberships, in seconds.')
-      .option('--sigQty <number>', 'Minimum number of required certifications to be a member/stay as a member')
-      .option('--medtblocks <number>', 'medianTimeBlocks parameter of UCP')
-      .option('--avgGenTime <number>', 'avgGenTime parameter of UCP')
-      .option('--dtdiffeval <number>', 'dtDiffEval parameter of UCP')
-      .option('--powZeroMin <number>', 'Minimum number of leading zeros for a proof-of-work')
-      .option('--powPeriod <number>', 'Number of blocks to wait to decrease proof-of-work difficulty by one')
-      .option('--powDelay <number>', 'Number of seconds to wait before starting the computation of next block')
-      .option('--growth <number>', 'Universal Dividend %growth. Aka. \'c\' parameter in RTM', parsePercent)
-      .option('--ud0 <number>', 'Universal Dividend initial value')
-      .option('--dt <number>', 'Number of seconds between two UD')
-      .option('--rootoffset <number>', 'Allow to give a time offset for first block (offset in the past)')
-      .option('--show', 'With gen-next or gen-root commands, displays the generated block')
-
-      .option('--nointeractive', 'Disable interactive sync UI')
-      .option('--nocautious', 'Do not check blocks validity during sync')
-      .option('--cautious', 'Check blocks validity during sync (overrides --nocautious option)')
-      .option('--nopeers', 'Do not retrieve peers during sync')
-
-      .option('--timeout <milliseconds>', 'Timeout to use when contacting peers', parseInt)
-      .option('--httplogs', 'Enable HTTP logs')
-      .option('--nohttplogs', 'Disable HTTP logs')
-      .option('--isolate', 'Avoid the node to send peering or status informations to the network')
-      .option('--check', 'With gen-next: just check validity of generated block')
-      .option('--forksize <size>', 'Maximum size of fork window', parseInt)
-      .option('--memory', 'Memory mode')
-    ;
-
-    program
-      .command('start')
-      .description('Start Duniter server.')
-      .action(subCommand(service(serverStart)));
-
-    program
-      .command('webwait')
-      .description('Start Duniter web admin.')
-      .action(subCommand(webWait));
-
-    program
-      .command('webstart')
-      .description('Start Duniter web admin + immediately start the server.')
-      .action(subCommand(webStart));
-
-    program
-      .command('wizard [step]')
-      .description('Launch the configuration Wizard')
-      .action(subCommand(function (step) {
-        // Only show message "Saved"
-        connect(function (step, server, conf) {
-          async.series([
-            function (next) {
-              startWizard(step, server, conf, next);
-            }
-          ], logIfErrorAndExit(server));
-        })(step, null);
-      }));
-
-    program
-      .command('sync [host] [port] [to]')
-      .description('Synchronize blockchain from a remote Duniter node')
-      .action(subCommand(service(function (host, port, to, server, conf) {
-        if (!host) {
-          throw 'Host is required.';
+function subCommand(promiseFunc) {
+  return function() {
+    let args = Array.prototype.slice.call(arguments, 0);
+    return co(function*() {
+      try {
+        let result = yield promiseFunc.apply(null, args);
+        onResolve(result);
+      } catch (e) {
+        logger.error(e);
+        onReject(e);
+      }
+    })
+  };
+}
+
+const ERASE_IF_ALREADY_RECORDED = true;
+const NO_LOGS = true;
+
+program
+  .version(pjson.version)
+  .usage('<command> [options]')
+
+  .option('--home <path>', 'Path to Duniter HOME (defaults to "$HOME/.config/duniter").')
+  .option('-d, --mdb <name>', 'Database name (defaults to "duniter_default").')
+
+  .option('--autoconf', 'With `init` command, will guess the best network and key options witout aksing for confirmation')
+  .option('--ipv4 <address>', 'IPv4 interface to listen for requests')
+  .option('--ipv6 <address>', 'IPv6 interface to listen for requests')
+  .option('--remoteh <host>', 'Remote interface others may use to contact this node')
+  .option('--remote4 <host>', 'Remote interface for IPv4 access')
+  .option('--remote6 <host>', 'Remote interface for IPv6 access')
+  .option('-p, --port <port>', 'Port to listen for requests', parseInt)
+  .option('--remotep <port>', 'Remote port others may use to contact this node')
+  .option('--upnp', 'Use UPnP to open remote port')
+  .option('--noupnp', 'Do not use UPnP to open remote port')
+
+  // Webmin options
+  .option('--webmhost <host>', 'Local network interface to connect to (IP)')
+  .option('--webmport <port>', 'Local network port to connect', parseInt)
+
+  .option('--salt <salt>', 'Key salt to generate this key\'s secret key')
+  .option('--passwd <password>', 'Password to generate this key\'s secret key')
+  .option('--participate <Y|N>', 'Participate to writing the blockchain')
+  .option('--cpu <percent>', 'Percent of CPU usage for proof-of-work computation', parsePercent)
+
+  .option('-c, --currency <name>', 'Name of the currency managed by this node.')
+  .option('--sigPeriod <timestamp>', 'Minimum delay between 2 certifications of a same issuer, in seconds.')
+  .option('--sigStock <count>', 'Maximum quantity of valid certifications per member.')
+  .option('--sigWindow <duration>', 'Maximum age of a non-written certification.')
+  .option('--idtyWindow <duration>', 'Maximum age of a non-written certification.')
+  .option('--sigValidity <timestamp>', 'Validity duration of a certification, in seconds.')
+  .option('--msValidity <timestamp>', 'Validity duration of a memberships, in seconds.')
+  .option('--sigQty <number>', 'Minimum number of required certifications to be a member/stay as a member')
+  .option('--medtblocks <number>', 'medianTimeBlocks parameter of UCP')
+  .option('--avgGenTime <number>', 'avgGenTime parameter of UCP')
+  .option('--dtdiffeval <number>', 'dtDiffEval parameter of UCP')
+  .option('--powZeroMin <number>', 'Minimum number of leading zeros for a proof-of-work')
+  .option('--powPeriod <number>', 'Number of blocks to wait to decrease proof-of-work difficulty by one')
+  .option('--powDelay <number>', 'Number of seconds to wait before starting the computation of next block')
+  .option('--growth <number>', 'Universal Dividend %growth. Aka. \'c\' parameter in RTM', parsePercent)
+  .option('--ud0 <number>', 'Universal Dividend initial value')
+  .option('--dt <number>', 'Number of seconds between two UD')
+  .option('--rootoffset <number>', 'Allow to give a time offset for first block (offset in the past)')
+  .option('--show', 'With gen-next or gen-root commands, displays the generated block')
+
+  .option('--nointeractive', 'Disable interactive sync UI')
+  .option('--nocautious', 'Do not check blocks validity during sync')
+  .option('--cautious', 'Check blocks validity during sync (overrides --nocautious option)')
+  .option('--nopeers', 'Do not retrieve peers during sync')
+
+  .option('--timeout <milliseconds>', 'Timeout to use when contacting peers', parseInt)
+  .option('--httplogs', 'Enable HTTP logs')
+  .option('--nohttplogs', 'Disable HTTP logs')
+  .option('--isolate', 'Avoid the node to send peering or status informations to the network')
+  .option('--check', 'With gen-next: just check validity of generated block')
+  .option('--forksize <size>', 'Maximum size of fork window', parseInt)
+  .option('--memory', 'Memory mode')
+;
+
+program
+  .command('start')
+  .description('Start Duniter server.')
+  .action(subCommand(service((server, conf) => new Promise((resolve, reject) => {
+    co(function*() {
+        try {
+          yield duniter.statics.startNode(server, conf);
+        } catch (e) {
+          reject(e);
+        }
+    });
+  }))));
+
+program
+  .command('webwait')
+  .description('Start Duniter web admin.')
+  .action(subCommand(webWait));
+
+program
+  .command('webstart')
+  .description('Start Duniter web admin + immediately start the server.')
+  .action(subCommand(webStart));
+
+program
+  .command('wizard [step]')
+  .description('Launch the configuration Wizard')
+  .action(subCommand(function (step) {
+    // Only show message "Saved"
+    connect(function (step, server, conf) {
+      async.series([
+        function (next) {
+          startWizard(step, server, conf, next);
         }
-        if (!port) {
-          throw 'Port is required.';
+      ], logIfErrorAndExit(server));
+    })(step, null);
+  }));
+
+program
+  .command('sync [host] [port] [to]')
+  .description('Synchronize blockchain from a remote Duniter node')
+  .action(subCommand(service(function (host, port, to, server, conf) {
+    if (!host) {
+      throw 'Host is required.';
+    }
+    if (!port) {
+      throw 'Port is required.';
+    }
+    return co(function *() {
+      try {
+        let cautious;
+        if (program.nocautious) {
+          cautious = false;
         }
-        return co(function *() {
-          try {
-            let cautious;
-            if (program.nocautious) {
-              cautious = false;
-            }
-            if (program.cautious) {
-              cautious = true;
-            }
-            yield server.synchronize(host, port, parseInt(to), 0, !program.nointeractive, cautious, program.nopeers);
-          } catch (err) {
-            logger.error(err.stack || err.message);
-          }
-          yield ((server && server.disconnect()) || Q()).catch(() => null);
+        if (program.cautious) {
+          cautious = true;
+        }
+        yield server.synchronize(host, port, parseInt(to), 0, !program.nointeractive, cautious, program.nopeers);
+      } catch (err) {
+        logger.error(err.stack || err.message);
+      }
+      yield ((server && server.disconnect()) || Q()).catch(() => null);
+    });
+  })));
+
+program
+  .command('peer [host] [port]')
+  .description('Exchange peerings with another node')
+  .action(subCommand(service(function (host, port, server) {
+    return co(function *() {
+      let node = yield Q.nfcall(vucoin, host, port);
+      logger.info('Fetching peering record at %s:%s...', host, port);
+      let peering = yield Q.nfcall(node.network.peering.get);
+      logger.info('Apply peering ...');
+      yield server.PeeringService.submitP(peering, ERASE_IF_ALREADY_RECORDED, !program.nocautious);
+      logger.info('Applied');
+      let selfPeer = yield server.dal.getPeer(server.PeeringService.pubkey);
+      if (!selfPeer) {
+        yield Q.nfcall(server.PeeringService.generateSelfPeer, server.conf, 0);
+        selfPeer = yield server.dal.getPeer(server.PeeringService.pubkey);
+      }
+      logger.info('Send self peering ...');
+      var caster = multicaster();
+      yield caster.sendPeering(Peer.statics.peerize(peering), Peer.statics.peerize(selfPeer));
+      logger.info('Sent.');
+      yield server.disconnect();
+      throw Error("Exiting");
+    })
+      .catch(function (err) {
+        logger.error(err.code || err.message || err);
+        throw Error("Exiting");
+      });
+  })));
+
+program
+  .command('init [host] [port]')
+  .description('Setup a node configuration and sync data with given node')
+  .action(subCommand(connect(bootstrapServer, true)));
+
+program
+  .command('dump [what]')
+  .description('Diverse dumps of the inner data')
+  .action(subCommand(connect(makeDump, true)));
+
+program
+  .command('forward [host] [port] [to]')
+  .description('Forward local blockchain to a remote Duniter node')
+  .action(subCommand(service(function (host, port, to, server) {
+
+    var remoteCurrent;
+    async.waterfall([
+      function (next) {
+        vucoin(host, port, next, {timeout: server.conf.timeout});
+      },
+      function (node, next) {
+        node.blockchain.current().then(_.partial(next, null)).catch(next);
+      },
+      function (current, next) {
+        remoteCurrent = current;
+        logger.info(remoteCurrent.number);
+        server.dal.getBlockFrom(remoteCurrent.number - 10).then(_.partial(next, null)).catch(next);
+      },
+      function (blocks, next) {
+        blocks = _.sortBy(blocks, 'number');
+        // Forward
+        var peer = new Peer({
+          endpoints: [['BASIC_MERKLED_API', host, port].join(' ')]
         });
-      })));
-
-    program
-      .command('peer [host] [port]')
-      .description('Exchange peerings with another node')
-      .action(subCommand(service(function (host, port, server) {
-        return co(function *() {
-          let node = yield Q.nfcall(vucoin, host, port);
-          logger.info('Fetching peering record at %s:%s...', host, port);
-          let peering = yield Q.nfcall(node.network.peering.get);
-          logger.info('Apply peering ...');
-          yield server.PeeringService.submitP(peering, ERASE_IF_ALREADY_RECORDED, !program.nocautious);
-          logger.info('Applied');
-          let selfPeer = yield server.dal.getPeer(server.PeeringService.pubkey);
-          if (!selfPeer) {
-            yield Q.nfcall(server.PeeringService.generateSelfPeer, server.conf, 0);
-            selfPeer = yield server.dal.getPeer(server.PeeringService.pubkey);
-          }
-          logger.info('Send self peering ...');
-          var caster = multicaster();
-          yield caster.sendPeering(Peer.statics.peerize(peering), Peer.statics.peerize(selfPeer));
-          logger.info('Sent.');
-          yield server.disconnect();
-          throw Error("Exiting");
-        })
-          .catch(function (err) {
-            logger.error(err.code || err.message || err);
-            throw Error("Exiting");
-          });
-      })));
-
-    program
-      .command('init [host] [port]')
-      .description('Setup a node configuration and sync data with given node')
-      .action(subCommand(connect(bootstrapServer, true)));
-
-    program
-      .command('dump [what]')
-      .description('Diverse dumps of the inner data')
-      .action(subCommand(connect(makeDump, true)));
-
-    program
-      .command('forward [host] [port] [to]')
-      .description('Forward local blockchain to a remote Duniter node')
-      .action(subCommand(service(function (host, port, to, server) {
-
-        var remoteCurrent;
-        async.waterfall([
-          function (next) {
-            vucoin(host, port, next, {timeout: server.conf.timeout});
-          },
-          function (node, next) {
-            node.blockchain.current().then(_.partial(next, null)).catch(next);
-          },
-          function (current, next) {
-            remoteCurrent = current;
-            logger.info(remoteCurrent.number);
-            server.dal.getBlockFrom(remoteCurrent.number - 10).then(_.partial(next, null)).catch(next);
-          },
-          function (blocks, next) {
-            blocks = _.sortBy(blocks, 'number');
-            // Forward
-            var peer = new Peer({
-              endpoints: [['BASIC_MERKLED_API', host, port].join(' ')]
+        async.forEachSeries(blocks, function (block, callback) {
+          logger.info("Forwarding block#" + block.number);
+          server.dal.getBlock(block.number)
+            .then(function (fullBlock) {
+              multicaster(server.conf).sendBlock(peer, new Block(fullBlock)).then(() => callback()).catch(callback);
             });
-            async.forEachSeries(blocks, function (block, callback) {
-              logger.info("Forwarding block#" + block.number);
-              server.dal.getBlock(block.number)
-                .then(function (fullBlock) {
-                  multicaster(server.conf).sendBlock(peer, new Block(fullBlock)).then(() => callback()).catch(callback);
-                });
-            }, next);
-          }
-        ], function (err) {
-          if (err) {
-            logger.error('Error during forwarding:', err);
-          }
-          server.disconnect();
+        }, next);
+      }
+    ], function (err) {
+      if (err) {
+        logger.error('Error during forwarding:', err);
+      }
+      server.disconnect();
+      throw Error("Exiting");
+    });
+  })));
+
+program
+  .command('revert [count]')
+  .description('Revert (undo + remove) the top [count] blocks from the blockchain. EXPERIMENTAL')
+  .action(subCommand(service(function (count, server) {
+    co(function *() {
+      try {
+        for (let i = 0; i < count; i++) {
+          yield server.revert();
+        }
+      } catch (err) {
+        logger.error('Error during revert:', err);
+      }
+      // Save DB
+      server.disconnect()
+        .catch(() => null)
+        .then(function () {
           throw Error("Exiting");
         });
-      })));
-
-    program
-      .command('revert [count]')
-      .description('Revert (undo + remove) the top [count] blocks from the blockchain. EXPERIMENTAL')
-      .action(subCommand(service(function (count, server) {
-        co(function *() {
-          try {
-            for (let i = 0; i < count; i++) {
-              yield server.revert();
-            }
-          } catch (err) {
-            logger.error('Error during revert:', err);
-          }
-          // Save DB
-          server.disconnect()
-            .catch(() => null)
-            .then(function () {
-              throw Error("Exiting");
-            });
+    });
+  })));
+
+program
+  .command('revert-to [number]')
+  .description('Revert (undo + remove) top blockchain blocks until block #[number] is reached. EXPERIMENTAL')
+  .action(subCommand(service(function (number, server) {
+    co(function *() {
+      try {
+        yield server.revertTo(number);
+      } catch (err) {
+        logger.error('Error during revert:', err);
+      }
+      // Save DB
+      ((server && server.disconnect()) || Q())
+        .catch(() => null)
+        .then(function () {
+          throw Error("Exiting");
         });
-      })));
+    });
+  })));
 
-    program
-      .command('revert-to [number]')
-      .description('Revert (undo + remove) top blockchain blocks until block #[number] is reached. EXPERIMENTAL')
-      .action(subCommand(service(function (number, server) {
-        co(function *() {
-          try {
-            yield server.revertTo(number);
-          } catch (err) {
-            logger.error('Error during revert:', err);
-          }
-          // Save DB
-          ((server && server.disconnect()) || Q())
-            .catch(() => null)
-            .then(function () {
-              throw Error("Exiting");
-            });
-        });
-      })));
-
-    program
-      .command('gen-next [host] [port] [diff]')
-      .description('Tries to generate the next block of the blockchain')
-      .action(subCommand(service(generateAndSend("generateNext"))));
-
-    program
-      .command('gen-root [host] [port] [diff]')
-      .description('Tries to generate root block, with choice of root members')
-      .action(subCommand(service(generateAndSend("generateManualRoot"))));
-
-    function generateAndSend(generationMethod) {
-      return function (host, port, difficulty, server, conf) {
-        return new Promise((resolve, reject) => {
-          async.waterfall([
-            function (next) {
-              var method = eval('server.BlockchainService.' + generationMethod);
-              method().then(_.partial(next, null)).catch(next);
-            },
-            function (block, next) {
-              if (program.check) {
-                block.time = block.medianTime;
-                program.show && console.log(block.getRawSigned());
-                server.doCheckBlock(block)
-                  .then(function () {
-                    logger.info('Acceptable block');
-                    next();
-                  })
-                  .catch(next);
-              }
-              else {
-                logger.debug('Block to be sent: %s', block.quickDescription());
-                var wiz = wizard(server);
-                async.waterfall([
-                  function (next) {
-                    if (!conf.salt && !conf.passwd)
-                      wiz.configKey(conf, next);
-                    else
-                      next();
-                  },
-                  function (next) {
-                    // Extract key pair
-                    keyring.scryptKeyPair(conf.salt, conf.passwd).then((pair) => next(null, pair)).catch(next);
-                  },
-                  function (pair, next) {
-                    proveAndSend(server, block, pair.publicKey, parseInt(difficulty), host, parseInt(port), next);
-                  }
-                ], next);
-              }
-            }
-          ], (err, data) => {
-            err && reject(err);
-            !err && resolve(data);
-          });
-        });
-      };
-    }
+program
+  .command('gen-next [host] [port] [diff]')
+  .description('Tries to generate the next block of the blockchain')
+  .action(subCommand(service(generateAndSend("generateNext"))));
+
+program
+  .command('gen-root [host] [port] [diff]')
+  .description('Tries to generate root block, with choice of root members')
+  .action(subCommand(service(generateAndSend("generateManualRoot"))));
 
-    function proveAndSend(server, block, issuer, difficulty, host, port, done) {
-      var BlockchainService = server.BlockchainService;
+function generateAndSend(generationMethod) {
+  return function (host, port, difficulty, server, conf) {
+    return new Promise((resolve, reject) => {
       async.waterfall([
         function (next) {
-          block.issuer = issuer;
-          program.show && console.log(block.getRawSigned());
-          BlockchainService.prove(block, difficulty).then((proven) => next(null, proven)).catch(next);
+          var method = eval('server.BlockchainService.' + generationMethod);
+          method().then(_.partial(next, null)).catch(next);
         },
         function (block, next) {
-          var peer = new Peer({
-            endpoints: [['BASIC_MERKLED_API', host, port].join(' ')]
-          });
-          program.show && console.log(block.getRawSigned());
-          logger.info('Posted block ' + block.quickDescription());
-          multicaster(server.conf).sendBlock(peer, block).then(() => next()).catch(next);
-        }
-      ], done);
-    }
-
-    program
-      .command('export-bc [upto]')
-      .description('Exports the whole blockchain as JSON array, up to [upto] block number (excluded).')
-      .action(subCommand(service(function (upto, server) {
-        return co(function *() {
-          let CHUNK_SIZE = 500;
-          let jsoned = [];
-          let current = yield server.dal.getCurrentBlockOrNull();
-          let lastNumber = current ? current.number + 1 : -1;
-          if (upto !== undefined && upto.match(/\d+/)) {
-            lastNumber = Math.min(parseInt(upto), lastNumber);
-          }
-          let chunksCount = Math.floor(lastNumber / CHUNK_SIZE);
-          let chunks = [];
-          // Max-size chunks
-          for (let i = 0, len = chunksCount; i < len; i++) {
-            chunks.push({start: i * CHUNK_SIZE, to: i * CHUNK_SIZE + CHUNK_SIZE - 1});
-          }
-          // A last chunk
-          if (lastNumber > chunksCount * CHUNK_SIZE) {
-            chunks.push({start: chunksCount * CHUNK_SIZE, to: lastNumber});
+          if (program.check) {
+            block.time = block.medianTime;
+            program.show && console.log(block.getRawSigned());
+            server.doCheckBlock(block)
+              .then(function () {
+                logger.info('Acceptable block');
+                next();
+              })
+              .catch(next);
           }
-          for (const chunk of chunks) {
-            let blocks = yield server.dal.getBlocksBetween(chunk.start, chunk.to);
-            blocks.forEach(function (block) {
-              jsoned.push(_(new Block(block).json()).omit('raw'));
-            });
+          else {
+            logger.debug('Block to be sent: %s', block.quickDescription());
+            var wiz = wizard(server);
+            async.waterfall([
+              function (next) {
+                if (!conf.salt && !conf.passwd)
+                  wiz.configKey(conf, next);
+                else
+                  next();
+              },
+              function (next) {
+                // Extract key pair
+                keyring.scryptKeyPair(conf.salt, conf.passwd).then((pair) => next(null, pair)).catch(next);
+              },
+              function (pair, next) {
+                proveAndSend(server, block, pair.publicKey, parseInt(difficulty), host, parseInt(port), next);
+              }
+            ], next);
           }
-          console.log(JSON.stringify(jsoned, null, "  "));
-          yield server.disconnect();
-          return jsoned;
-        })
-          .catch(function (err) {
-            logger.warn(err.message || err);
-            server.disconnect()
-              .catch(() => null)
-              .then(function () {
-                throw Error(err);
-              });
-          });
-      }, NO_LOGS)));
+        }
+      ], (err, data) => {
+        err && reject(err);
+        !err && resolve(data);
+      });
+    });
+  };
+}
 
-    program
-      .command('check-config')
-      .description('Checks the node\'s configuration')
-      .action(subCommand(service(function (server) {
-        server.checkConfig()
-          .then(function () {
-            logger.warn('Configuration seems correct.');
-            server.disconnect();
-            throw Error("Exiting");
-          })
-          .catch(function (err) {
-            logger.warn(err.message || err);
-            server.disconnect();
-            throw Error("Exiting");
-          });
-      })));
+function proveAndSend(server, block, issuer, difficulty, host, port, done) {
+  var BlockchainService = server.BlockchainService;
+  async.waterfall([
+    function (next) {
+      block.issuer = issuer;
+      program.show && console.log(block.getRawSigned());
+      BlockchainService.prove(block, difficulty).then((proven) => next(null, proven)).catch(next);
+    },
+    function (block, next) {
+      var peer = new Peer({
+        endpoints: [['BASIC_MERKLED_API', host, port].join(' ')]
+      });
+      program.show && console.log(block.getRawSigned());
+      logger.info('Posted block ' + block.quickDescription());
+      multicaster(server.conf).sendBlock(peer, block).then(() => next()).catch(next);
+    }
+  ], done);
+}
 
-    program
-      .command('config')
-      .description('Register configuration in database')
-      .action(subCommand(connect(function (server, conf) {
-        return co(function *() {
-          if (program.autoconf) {
-            let wiz = wizard();
-            conf.upnp = !program.noupnp;
-            yield Q.nbind(wiz.networkReconfiguration, wiz)(conf, program.autoconf, program.noupnp);
-            yield Q.nbind(wiz.keyReconfigure, wiz)(conf, program.autoconf);
-          }
-          return server.dal.saveConf(conf)
-            .then(function () {
-              logger.debug("Configuration saved.");
-              server.disconnect();
-              throw Error("Exiting");
-            })
-            .catch(function (err) {
-              logger.error("Configuration could not be saved: " + err);
-              server.disconnect();
-              throw Error("Exiting");
-            });
+program
+  .command('export-bc [upto]')
+  .description('Exports the whole blockchain as JSON array, up to [upto] block number (excluded).')
+  .action(subCommand(service(function (upto, server) {
+    return co(function *() {
+      let CHUNK_SIZE = 500;
+      let jsoned = [];
+      let current = yield server.dal.getCurrentBlockOrNull();
+      let lastNumber = current ? current.number + 1 : -1;
+      if (upto !== undefined && upto.match(/\d+/)) {
+        lastNumber = Math.min(parseInt(upto), lastNumber);
+      }
+      let chunksCount = Math.floor(lastNumber / CHUNK_SIZE);
+      let chunks = [];
+      // Max-size chunks
+      for (let i = 0, len = chunksCount; i < len; i++) {
+        chunks.push({start: i * CHUNK_SIZE, to: i * CHUNK_SIZE + CHUNK_SIZE - 1});
+      }
+      // A last chunk
+      if (lastNumber > chunksCount * CHUNK_SIZE) {
+        chunks.push({start: chunksCount * CHUNK_SIZE, to: lastNumber});
+      }
+      for (const chunk of chunks) {
+        let blocks = yield server.dal.getBlocksBetween(chunk.start, chunk.to);
+        blocks.forEach(function (block) {
+          jsoned.push(_(new Block(block).json()).omit('raw'));
         });
-      })));
-
-    program
-      .command('reset [config|data|peers|tx|stats|all]')
-      .description('Reset configuration, data, peers, transactions or everything in the database')
-      .action(subCommand((type) => {
-        let init = type == 'data' ? server : connect;
-        return init(function (server) {
-          if (!~['config', 'data', 'peers', 'stats', 'all'].indexOf(type)) {
-            throw Error('Bad command: usage `reset config`, `reset data`, `reset peers`, `reset stats` or `reset all`');
-          }
-          return co(function*() {
-            try {
-              if (type == 'data') {
-                yield server.resetData();
-                logger.warn('Data successfully reseted.');
-              }
-              if (type == 'peers') {
-                yield server.resetPeers();
-                logger.warn('Peers successfully reseted.');
-              }
-              if (type == 'stats') {
-                yield server.resetStats();
-                logger.warn('Stats successfully reseted.');
-              }
-              if (type == 'config') {
-                yield server.resetConf();
-                logger.warn('Configuration successfully reseted.');
-              }
-              if (type == 'all') {
-                yield server.resetAll();
-                logger.warn('Data & Configuration successfully reseted.');
-              }
-            } catch (e) {
-              logger.error(e);
-            }
-            return server.disconnect();
+      }
+      console.log(JSON.stringify(jsoned, null, "  "));
+      yield server.disconnect();
+      return jsoned;
+    })
+      .catch(function (err) {
+        logger.warn(err.message || err);
+        server.disconnect()
+          .catch(() => null)
+          .then(function () {
+            throw Error(err);
           });
-        }, type != 'peers')(type);
-      }));
-
-    function serverStart(server, conf) {
-
-      return co(function *() {
-        yield duniter.statics.startNode(server, conf);
+      });
+  }, NO_LOGS)));
+
+program
+  .command('check-config')
+  .description('Checks the node\'s configuration')
+  .action(subCommand(service(function (server) {
+    server.checkConfig()
+      .then(function () {
+        logger.warn('Configuration seems correct.');
+        server.disconnect();
+        throw Error("Exiting");
       })
-        .catch((err) => {
-          logger.error(err);
+      .catch(function (err) {
+        logger.warn(err.message || err);
+        server.disconnect();
+        throw Error("Exiting");
+      });
+  })));
+
+program
+  .command('config')
+  .description('Register configuration in database')
+  .action(subCommand(connect(function (server, conf) {
+    return co(function *() {
+      if (program.autoconf) {
+        let wiz = wizard();
+        conf.upnp = !program.noupnp;
+        yield Q.nbind(wiz.networkReconfiguration, wiz)(conf, program.autoconf, program.noupnp);
+        yield Q.nbind(wiz.keyReconfigure, wiz)(conf, program.autoconf);
+      }
+      return server.dal.saveConf(conf)
+        .then(function () {
+          logger.debug("Configuration saved.");
+          server.disconnect();
+          throw Error("Exiting");
+        })
+        .catch(function (err) {
+          logger.error("Configuration could not be saved: " + err);
           server.disconnect();
           throw Error("Exiting");
         });
-    }
-
-    function startWizard(step, server, conf, done) {
-      var wiz = wizard(server);
-      var task = {
-        'currency': wiz.configCurrency,
-        'basic': wiz.configBasic,
-        'pow': wiz.configPoW,
-        'network': wiz.configNetwork,
-        'network-reconfigure': wiz.configNetworkReconfigure,
-        'key': wiz.configKey,
-        'ucp': wiz.configUCP
-      };
-      var wizDo = task[step] || wiz.configAll;
-      async.waterfall([
-        function (next) {
-          wizDo(conf, next);
-        },
-        function (next) {
-          return server.dal.saveConf(conf)
-            .then(function () {
-              logger.debug("Configuration saved.");
-              next();
-            })
-            .catch(next);
-        },
-        function (next) {
-          // Check config
-          service(function (key, server, conf) {
-            next();
-          })(null, null);
-        }
-      ], done);
-    }
-
-    function makeDump(what, server, conf) {
-      return co(function *() {
+    });
+  })));
+
+program
+  .command('reset [config|data|peers|tx|stats|all]')
+  .description('Reset configuration, data, peers, transactions or everything in the database')
+  .action(subCommand((type) => {
+    let init = type == 'data' ? server : connect;
+    return init(function (server) {
+      if (!~['config', 'data', 'peers', 'stats', 'all'].indexOf(type)) {
+        throw Error('Bad command: usage `reset config`, `reset data`, `reset peers`, `reset stats` or `reset all`');
+      }
+      return co(function*() {
         try {
-          server.dal.wotb.showWoT();
+          if (type == 'data') {
+            yield server.resetData();
+            logger.warn('Data successfully reseted.');
+          }
+          if (type == 'peers') {
+            yield server.resetPeers();
+            logger.warn('Peers successfully reseted.');
+          }
+          if (type == 'stats') {
+            yield server.resetStats();
+            logger.warn('Stats successfully reseted.');
+          }
+          if (type == 'config') {
+            yield server.resetConf();
+            logger.warn('Configuration successfully reseted.');
+          }
+          if (type == 'all') {
+            yield server.resetAll();
+            logger.warn('Data & Configuration successfully reseted.');
+          }
         } catch (e) {
           logger.error(e);
         }
-        server.disconnect();
-        throw Error("Exiting");
+        return server.disconnect();
       });
+    }, type != 'peers')(type);
+  }));
+
+function startWizard(step, server, conf, done) {
+  var wiz = wizard(server);
+  var task = {
+    'currency': wiz.configCurrency,
+    'basic': wiz.configBasic,
+    'pow': wiz.configPoW,
+    'network': wiz.configNetwork,
+    'network-reconfigure': wiz.configNetworkReconfigure,
+    'key': wiz.configKey,
+    'ucp': wiz.configUCP
+  };
+  var wizDo = task[step] || wiz.configAll;
+  async.waterfall([
+    function (next) {
+      wizDo(conf, next);
+    },
+    function (next) {
+      return server.dal.saveConf(conf)
+        .then(function () {
+          logger.debug("Configuration saved.");
+          next();
+        })
+        .catch(next);
+    },
+    function (next) {
+      // Check config
+      service(function (key, server, conf) {
+        next();
+      })(null, null);
     }
+  ], done);
+}
 
-    function bootstrapServer(host, port, server, conf) {
-      async.series(getBootstrapOperations(host, port, server, conf), function (err) {
-        if (err) {
-          logger.error(err);
-        }
-        server.disconnect();
-        throw Error("Exiting");
-      });
-    }
-
-    function getBootstrapOperations(host, port, server, conf) {
-      var ops = [];
-      var wiz = wizard(server);
-      ops = ops.concat([
-        function (next) {
-          // Reset data
-          server.resetAll(next);
-        },
-        function (next) {
-          conf.upnp = !program.noupnp;
-          wiz.networkReconfiguration(conf, program.autoconf, program.noupnp, next);
-        },
-        function (next) {
-          // PublicKey
-          var keyChosen = true;
-          async.doWhilst(function (next) {
-            async.waterfall([
-              function (next) {
-                if (!conf.salt && !conf.passwd) {
-                  wiz.keyReconfigure(conf, program.autoconf, next);
-                } else {
-                  next();
-                }
-              }
-            ], next);
-          }, function () {
-            return !keyChosen;
-          }, next);
-        },
-        function (next) {
-          return server.dal.saveConf(conf).then(_.partial(next, null)).catch(next);
-        }]);
-      ops.push(function (next) {
-        logger.info('Configuration saved.');
-        next();
-      });
-      return ops;
+function makeDump(what, server, conf) {
+  return co(function *() {
+    try {
+      server.dal.wotb.showWoT();
+    } catch (e) {
+      logger.error(e);
     }
+    server.disconnect();
+    throw Error("Exiting");
+  });
+}
 
-    function commandLineConf(conf) {
-
-      conf = conf || {};
-      conf.sync = conf.sync || {};
-      var cli = {
-        currency: program.currency,
-        cpu: program.cpu,
-        server: {
-          port: program.port,
-          ipv4address: program.ipv4,
-          ipv6address: program.ipv6,
-          salt: program.salt,
-          passwd: program.passwd,
-          remote: {
-            host: program.remoteh,
-            ipv4: program.remote4,
-            ipv6: program.remote6,
-            port: program.remotep
-          }
-        },
-        db: {
-          mport: program.mport,
-          mdb: program.mdb,
-          home: program.home
-        },
-        net: {
-          upnp: program.upnp,
-          noupnp: program.noupnp
-        },
-        logs: {
-          http: program.httplogs,
-          nohttp: program.nohttplogs
-        },
-        ucp: {
-          rootoffset: program.rootoffset,
-          sigPeriod: program.sigPeriod,
-          sigStock: program.sigStock,
-          sigWindow: program.sigWindow,
-          idtyWindow: program.idtyWindow,
-          msWindow: program.msWindow,
-          sigValidity: program.sigValidity,
-          sigQty: program.sigQty,
-          msValidity: program.msValidity,
-          powZeroMin: program.powZeroMin,
-          powPeriod: program.powPeriod,
-          powDelay: program.powDelay,
-          participate: program.participate,
-          ud0: program.ud0,
-          c: program.growth,
-          dt: program.dt,
-          incDateMin: program.incDateMin,
-          medtblocks: program.medtblocks,
-          dtdiffeval: program.dtdiffeval,
-          avgGenTime: program.avgGenTime
-        },
-        isolate: program.isolate,
-        forksize: program.forksize,
-        nofork: program.nofork,
-        timeout: program.timeout
-      };
-
-      // Update conf
-      if (cli.currency)                         conf.currency = cli.currency;
-      if (cli.server.ipv4address)               conf.ipv4 = cli.server.ipv4address;
-      if (cli.server.ipv6address)               conf.ipv6 = cli.server.ipv6address;
-      if (cli.server.port)                      conf.port = cli.server.port;
-      if (cli.server.salt)                      conf.salt = cli.server.salt;
-      if (cli.server.passwd != undefined)       conf.passwd = cli.server.passwd;
-      if (cli.server.remote.host != undefined)  conf.remotehost = cli.server.remote.host;
-      if (cli.server.remote.ipv4 != undefined)  conf.remoteipv4 = cli.server.remote.ipv4;
-      if (cli.server.remote.ipv6 != undefined)  conf.remoteipv6 = cli.server.remote.ipv6;
-      if (cli.server.remote.port != undefined)  conf.remoteport = cli.server.remote.port;
-      if (cli.ucp.rootoffset)                   conf.rootoffset = cli.ucp.rootoffset;
-      if (cli.ucp.sigPeriod)                    conf.sigPeriod = cli.ucp.sigPeriod;
-      if (cli.ucp.sigStock)                     conf.sigStock = cli.ucp.sigStock;
-      if (cli.ucp.sigWindow)                    conf.sigWindow = cli.ucp.sigWindow;
-      if (cli.ucp.idtyWindow)                   conf.idtyWindow = cli.ucp.idtyWindow;
-      if (cli.ucp.msWindow)                     conf.msWindow = cli.ucp.msWindow;
-      if (cli.ucp.sigValidity)                  conf.sigValidity = cli.ucp.sigValidity;
-      if (cli.ucp.msValidity)                   conf.msValidity = cli.ucp.msValidity;
-      if (cli.ucp.sigQty)                       conf.sigQty = cli.ucp.sigQty;
-      if (cli.ucp.msValidity)                   conf.msValidity = cli.ucp.msValidity;
-      if (cli.ucp.powZeroMin)                   conf.powZeroMin = cli.ucp.powZeroMin;
-      if (cli.ucp.powPeriod)                    conf.powPeriod = cli.ucp.powPeriod;
-      if (cli.ucp.powDelay)                     conf.powDelay = cli.ucp.powDelay;
-      if (cli.ucp.participate)                  conf.participate = cli.ucp.participate == 'Y';
-      if (cli.ucp.dt)                           conf.dt = cli.ucp.dt;
-      if (cli.ucp.c)                            conf.c = cli.ucp.c;
-      if (cli.ucp.ud0)                          conf.ud0 = cli.ucp.ud0;
-      if (cli.ucp.incDateMin)                   conf.incDateMin = cli.ucp.incDateMin;
-      if (cli.ucp.medtblocks)                   conf.medianTimeBlocks = cli.ucp.medtblocks;
-      if (cli.ucp.avgGenTime)                   conf.avgGenTime = cli.ucp.avgGenTime;
-      if (cli.ucp.dtdiffeval)                   conf.dtDiffEval = cli.ucp.dtdiffeval;
-      if (cli.net.upnp)                         conf.upnp = true;
-      if (cli.net.noupnp)                       conf.upnp = false;
-      if (cli.cpu)                              conf.cpu = Math.max(0.01, Math.min(1.0, cli.cpu));
-      if (cli.logs.http)                        conf.httplogs = true;
-      if (cli.logs.nohttp)                      conf.httplogs = false;
-      if (cli.db.mport)                         conf.mport = cli.db.mport;
-      if (cli.db.home)                          conf.home = cli.db.home;
-      if (cli.db.mdb)                           conf.mdb = cli.db.mdb;
-      if (cli.isolate)                          conf.isolate = cli.isolate;
-      if (cli.timeout)                          conf.timeout = cli.timeout;
-      if (cli.forksize != null)                 conf.forksize = cli.forksize;
-
-      // Specific internal settings
-      conf.createNext = true;
-      return _(conf).extend({routing: true});
+function bootstrapServer(host, port, server, conf) {
+  async.series(getBootstrapOperations(host, port, server, conf), function (err) {
+    if (err) {
+      logger.error(err);
     }
+    server.disconnect();
+    throw Error("Exiting");
+  });
+}
 
-    function connect(callback, useDefaultConf) {
-      return function () {
-        var cbArgs = arguments;
-        var dbName = program.mdb || "duniter_default";
-        var dbHome = program.home;
-
-        var server = duniter({home: dbHome, name: dbName}, commandLineConf());
-
-        // If ever the process gets interrupted
-        let isSaving = false;
-        that.closeCommand = () => {
-          if (!isSaving) {
-            isSaving = true;
-            // Save DB
-            server.disconnect()
-              .catch(() => null)
-              .then(function () {
-                throw Error("Exiting");
-              });
+function getBootstrapOperations(host, port, server, conf) {
+  var ops = [];
+  var wiz = wizard(server);
+  ops = ops.concat([
+    function (next) {
+      // Reset data
+      server.resetAll(next);
+    },
+    function (next) {
+      conf.upnp = !program.noupnp;
+      wiz.networkReconfiguration(conf, program.autoconf, program.noupnp, next);
+    },
+    function (next) {
+      // PublicKey
+      var keyChosen = true;
+      async.doWhilst(function (next) {
+        async.waterfall([
+          function (next) {
+            if (!conf.salt && !conf.passwd) {
+              wiz.keyReconfigure(conf, program.autoconf, next);
+            } else {
+              next();
+            }
           }
-        };
-
-        // Initialize server (db connection, ...)
-        return server.plugFileSystem(useDefaultConf)
-          .then(() => server.loadConf())
-          .then(function () {
-            cbArgs.length--;
-            cbArgs[cbArgs.length++] = server;
-            cbArgs[cbArgs.length++] = server.conf;
-            return callback.apply(this, cbArgs);
-          })
-          .catch(function (err) {
-            server.disconnect();
-            throw Error(err);
-          });
-      };
-    }
+        ], next);
+      }, function () {
+        return !keyChosen;
+      }, next);
+    },
+    function (next) {
+      return server.dal.saveConf(conf).then(_.partial(next, null)).catch(next);
+    }]);
+  ops.push(function (next) {
+    logger.info('Configuration saved.');
+    next();
+  });
+  return ops;
+}
 
-    /**
-     * Super basic server with only its home path set
-     * @param callback
-     * @param useDefaultConf
-     * @returns {Function}
-     */
-    function server(callback, useDefaultConf) {
-      return function () {
-        var cbArgs = arguments;
-        var dbName = program.mdb || "duniter_default";
-        var dbHome = program.home;
+function commandLineConf(conf) {
+
+  conf = conf || {};
+  conf.sync = conf.sync || {};
+  var cli = {
+    currency: program.currency,
+    cpu: program.cpu,
+    server: {
+      port: program.port,
+      ipv4address: program.ipv4,
+      ipv6address: program.ipv6,
+      salt: program.salt,
+      passwd: program.passwd,
+      remote: {
+        host: program.remoteh,
+        ipv4: program.remote4,
+        ipv6: program.remote6,
+        port: program.remotep
+      }
+    },
+    db: {
+      mport: program.mport,
+      mdb: program.mdb,
+      home: program.home
+    },
+    net: {
+      upnp: program.upnp,
+      noupnp: program.noupnp
+    },
+    logs: {
+      http: program.httplogs,
+      nohttp: program.nohttplogs
+    },
+    ucp: {
+      rootoffset: program.rootoffset,
+      sigPeriod: program.sigPeriod,
+      sigStock: program.sigStock,
+      sigWindow: program.sigWindow,
+      idtyWindow: program.idtyWindow,
+      msWindow: program.msWindow,
+      sigValidity: program.sigValidity,
+      sigQty: program.sigQty,
+      msValidity: program.msValidity,
+      powZeroMin: program.powZeroMin,
+      powPeriod: program.powPeriod,
+      powDelay: program.powDelay,
+      participate: program.participate,
+      ud0: program.ud0,
+      c: program.growth,
+      dt: program.dt,
+      incDateMin: program.incDateMin,
+      medtblocks: program.medtblocks,
+      dtdiffeval: program.dtdiffeval,
+      avgGenTime: program.avgGenTime
+    },
+    isolate: program.isolate,
+    forksize: program.forksize,
+    nofork: program.nofork,
+    timeout: program.timeout
+  };
+
+  // Update conf
+  if (cli.currency)                         conf.currency = cli.currency;
+  if (cli.server.ipv4address)               conf.ipv4 = cli.server.ipv4address;
+  if (cli.server.ipv6address)               conf.ipv6 = cli.server.ipv6address;
+  if (cli.server.port)                      conf.port = cli.server.port;
+  if (cli.server.salt)                      conf.salt = cli.server.salt;
+  if (cli.server.passwd != undefined)       conf.passwd = cli.server.passwd;
+  if (cli.server.remote.host != undefined)  conf.remotehost = cli.server.remote.host;
+  if (cli.server.remote.ipv4 != undefined)  conf.remoteipv4 = cli.server.remote.ipv4;
+  if (cli.server.remote.ipv6 != undefined)  conf.remoteipv6 = cli.server.remote.ipv6;
+  if (cli.server.remote.port != undefined)  conf.remoteport = cli.server.remote.port;
+  if (cli.ucp.rootoffset)                   conf.rootoffset = cli.ucp.rootoffset;
+  if (cli.ucp.sigPeriod)                    conf.sigPeriod = cli.ucp.sigPeriod;
+  if (cli.ucp.sigStock)                     conf.sigStock = cli.ucp.sigStock;
+  if (cli.ucp.sigWindow)                    conf.sigWindow = cli.ucp.sigWindow;
+  if (cli.ucp.idtyWindow)                   conf.idtyWindow = cli.ucp.idtyWindow;
+  if (cli.ucp.msWindow)                     conf.msWindow = cli.ucp.msWindow;
+  if (cli.ucp.sigValidity)                  conf.sigValidity = cli.ucp.sigValidity;
+  if (cli.ucp.msValidity)                   conf.msValidity = cli.ucp.msValidity;
+  if (cli.ucp.sigQty)                       conf.sigQty = cli.ucp.sigQty;
+  if (cli.ucp.msValidity)                   conf.msValidity = cli.ucp.msValidity;
+  if (cli.ucp.powZeroMin)                   conf.powZeroMin = cli.ucp.powZeroMin;
+  if (cli.ucp.powPeriod)                    conf.powPeriod = cli.ucp.powPeriod;
+  if (cli.ucp.powDelay)                     conf.powDelay = cli.ucp.powDelay;
+  if (cli.ucp.participate)                  conf.participate = cli.ucp.participate == 'Y';
+  if (cli.ucp.dt)                           conf.dt = cli.ucp.dt;
+  if (cli.ucp.c)                            conf.c = cli.ucp.c;
+  if (cli.ucp.ud0)                          conf.ud0 = cli.ucp.ud0;
+  if (cli.ucp.incDateMin)                   conf.incDateMin = cli.ucp.incDateMin;
+  if (cli.ucp.medtblocks)                   conf.medianTimeBlocks = cli.ucp.medtblocks;
+  if (cli.ucp.avgGenTime)                   conf.avgGenTime = cli.ucp.avgGenTime;
+  if (cli.ucp.dtdiffeval)                   conf.dtDiffEval = cli.ucp.dtdiffeval;
+  if (cli.net.upnp)                         conf.upnp = true;
+  if (cli.net.noupnp)                       conf.upnp = false;
+  if (cli.cpu)                              conf.cpu = Math.max(0.01, Math.min(1.0, cli.cpu));
+  if (cli.logs.http)                        conf.httplogs = true;
+  if (cli.logs.nohttp)                      conf.httplogs = false;
+  if (cli.db.mport)                         conf.mport = cli.db.mport;
+  if (cli.db.home)                          conf.home = cli.db.home;
+  if (cli.db.mdb)                           conf.mdb = cli.db.mdb;
+  if (cli.isolate)                          conf.isolate = cli.isolate;
+  if (cli.timeout)                          conf.timeout = cli.timeout;
+  if (cli.forksize != null)                 conf.forksize = cli.forksize;
+
+  // Specific internal settings
+  conf.createNext = true;
+  return _(conf).extend({routing: true});
+}
 
-        var server = duniter({home: dbHome, name: dbName}, commandLineConf());
+function connect(callback, useDefaultConf) {
+  return function () {
+    var cbArgs = arguments;
+    var dbName = program.mdb || "duniter_default";
+    var dbHome = program.home;
+
+    var server = duniter({home: dbHome, name: dbName}, commandLineConf());
+
+    // If ever the process gets interrupted
+    let isSaving = false;
+    closeCommand = () => co(function*() {
+      if (!isSaving) {
+        isSaving = true;
+        // Save DB
+        return server.disconnect();
+      }
+    });
 
+    // Initialize server (db connection, ...)
+    return server.plugFileSystem(useDefaultConf)
+      .then(() => server.loadConf())
+      .then(function () {
         cbArgs.length--;
         cbArgs[cbArgs.length++] = server;
         cbArgs[cbArgs.length++] = server.conf;
         return callback.apply(this, cbArgs);
-      };
-    }
+      })
+      .catch(function (err) {
+        server.disconnect();
+        throw Error(err);
+      });
+  };
+}
 
-    function service(callback, nologs) {
+/**
+ * Super basic server with only its home path set
+ * @param callback
+ * @param useDefaultConf
+ * @returns {Function}
+ */
+function server(callback, useDefaultConf) {
+  return function () {
+    var cbArgs = arguments;
+    var dbName = program.mdb || "duniter_default";
+    var dbHome = program.home;
+
+    var server = duniter({home: dbHome, name: dbName}, commandLineConf());
+
+    cbArgs.length--;
+    cbArgs[cbArgs.length++] = server;
+    cbArgs[cbArgs.length++] = server.conf;
+    return callback.apply(this, cbArgs);
+  };
+}
 
-      return function () {
+function service(callback, nologs) {
 
-        if (nologs) {
-          // Disable logs
-          require('../app/lib/logger')().mute();
-        }
+  return function () {
 
-        var cbArgs = arguments;
-        var dbName = program.mdb;
-        var dbHome = program.home;
+    if (nologs) {
+      // Disable logs
+      require('../app/lib/logger')().mute();
+    }
 
-        // Add log files for this instance
-        logger.addHomeLogs(directory.getHome(dbName, dbHome));
+    var cbArgs = arguments;
+    var dbName = program.mdb;
+    var dbHome = program.home;
 
-        var server = duniter({home: dbHome, name: dbName, memory: program.memory}, commandLineConf());
+    // Add log files for this instance
+    logger.addHomeLogs(directory.getHome(dbName, dbHome));
 
-        // If ever the process gets interrupted
-        let isSaving = false;
-        that.closeCommand = () => {
-          if (!isSaving) {
-            isSaving = true;
-            // Save DB
-            server.disconnect()
-              .catch(() => null)
-              .then(function () {
-                throw Error("Exiting");
-              });
-          }
-        };
+    var server = duniter({home: dbHome, name: dbName, memory: program.memory}, commandLineConf());
 
-        // Initialize server (db connection, ...)
-        return server.initWithDAL()
-          .then(function () {
-            cbArgs.length--;
-            cbArgs[cbArgs.length++] = server;
-            cbArgs[cbArgs.length++] = server.conf;
-            return callback.apply(this, cbArgs);
-          })
-          .catch(function (err) {
-            logger.error(err);
-            server.disconnect();
-            throw Error(err);
-          });
-      };
-    }
+    // If ever the process gets interrupted
+    let isSaving = false;
+    closeCommand = () => co(function*() {
+      if (!isSaving) {
+        isSaving = true;
+        // Save DB
+        return server.disconnect();
+      }
+    });
 
-    function logIfErrorAndExit(server, prefix) {
-      return function (err) {
-        if (err && err.uerr) {
-          err = err.uerr.message;
-        }
-        err && logger.error((prefix ? prefix : "") + (err.message || err));
+    // Initialize server (db connection, ...)
+    return server.initWithDAL()
+      .then(function () {
+        cbArgs.length--;
+        cbArgs[cbArgs.length++] = server;
+        cbArgs[cbArgs.length++] = server.conf;
+        return callback.apply(this, cbArgs);
+      })
+      .catch(function (err) {
+        logger.error(err);
         server.disconnect();
-        onResolve && onResolve();
-      };
-    }
-
-    function parsePercent(s) {
-      var f = parseFloat(s);
-      return isNaN(f) ? 0 : f;
-    }
-
-    program
-      .on('*', function (cmd) {
-        console.log("Unknown command '%s'. Try --help for a listing of commands & options.", cmd);
-        throw Error("Exiting");
+        throw Error(err);
       });
+  };
+}
 
-    function webWait() {
-      return co(function *() {
-        let webminapi = yield webInit();
-        return webminapi.httpLayer.openConnections();
-      })
-        .catch(mainError);
-    }
-
-    function webStart() {
-      return co(function *() {
-        let webminapi = yield webInit();
-        yield webminapi.httpLayer.openConnections();
-        yield webminapi.webminCtrl.startHTTP();
-        yield webminapi.webminCtrl.startAllServices();
-        yield webminapi.webminCtrl.regularUPnP();
-      })
-        .catch(mainError);
+function logIfErrorAndExit(server, prefix) {
+  return function (err) {
+    if (err && err.uerr) {
+      err = err.uerr.message;
     }
+    err && logger.error((prefix ? prefix : "") + (err.message || err));
+    server.disconnect();
+    onResolve && onResolve();
+  };
+}
 
-    function webInit() {
-      return co(function *() {
-        var dbName = program.mdb;
-        var dbHome = program.home;
-        if (!program.memory) {
-          let params = yield directory.getHomeFS(program.memory, dbHome);
-          yield directory.createHomeIfNotExists(params.fs, params.home);
+function parsePercent(s) {
+  var f = parseFloat(s);
+  return isNaN(f) ? 0 : f;
+}
 
-          // Add log files for this instance
-          logger.addHomeLogs(params.home);
-        }
-        return yield duniter.statics.enableHttpAdmin({
-          home: dbHome,
-          name: dbName,
-          memory: program.memory
-        }, commandLineConf(), false, program.webmhost, program.webmport);
-      });
-    }
+program
+  .on('*', function (cmd) {
+    console.log("Unknown command '%s'. Try --help for a listing of commands & options.", cmd);
+    throw Error("Exiting");
+  });
 
-    program.parse(programArgs);
+function webWait() {
+  return co(function *() {
+    let webminapi = yield webInit();
+    return webminapi.httpLayer.openConnections();
+  })
+    .catch(mainError);
+}
 
-    if (programArgs.length <= 2) {
+function webStart() {
+  return co(function *() {
+    let webminapi = yield webInit();
+    yield webminapi.httpLayer.openConnections();
+    yield webminapi.webminCtrl.startHTTP();
+    yield webminapi.webminCtrl.startAllServices();
+    yield webminapi.webminCtrl.regularUPnP();
+  })
+    .catch(mainError);
+}
 
-      console.log('No command given, using default: ucoind webwait');
-      return co(function *() {
-        try {
-          yield webWait();
-        } catch (e) {
-          logger.error(e);
-          throw Error("Exiting");
-        }
-      });
-    }
+function webInit() {
+  return co(function *() {
+    var dbName = program.mdb;
+    var dbHome = program.home;
+    if (!program.memory) {
+      let params = yield directory.getHomeFS(program.memory, dbHome);
+      yield directory.createHomeIfNotExists(params.fs, params.home);
 
-    function mainError(err) {
-      logger.error(err.code || err.message || err);
-      throw Error("Exiting");
+      // Add log files for this instance
+      logger.addHomeLogs(params.home);
     }
-
-    return commandExecution;
+    return yield duniter.statics.enableHttpAdmin({
+      home: dbHome,
+      name: dbName,
+      memory: program.memory
+    }, commandLineConf(), false, program.webmhost, program.webmport);
   });
 }
+
+function mainError(err) {
+  logger.error(err.code || err.message || err);
+  throw Error("Exiting");
+}
diff --git a/app/lib/computation/blockGenerator.js b/app/lib/computation/blockGenerator.js
index 3e1cc112cfb1e021e48754cb620fe6d00e79ee17..9593b7a8b58929476bb6ef5d4ce409a7d63945c6 100644
--- a/app/lib/computation/blockGenerator.js
+++ b/app/lib/computation/blockGenerator.js
@@ -375,7 +375,7 @@ function BlockGenerator(mainContext, prover) {
               }
             }
           } catch (e) {
-            console.error(e.stack);
+            logger.warn(e.stack || e.message || e);
             // Go on
           }
         }
diff --git a/app/lib/dal/fileDAL.js b/app/lib/dal/fileDAL.js
index d8d9baa1ffd40fc1462963b9cd8413a297e3bda8..033abb31867e7cf1f231216864c7ef7f26c411a3 100644
--- a/app/lib/dal/fileDAL.js
+++ b/app/lib/dal/fileDAL.js
@@ -880,7 +880,18 @@ function FileDAL(params) {
 
   this.close = () => co(function *() {
     yield _.values(that.newDals).map((dal) => dal.cleanCache && dal.cleanCache());
-    return Q.nbind(sqlite.close, sqlite);
+    return new Promise((resolve, reject) => {
+      if (!sqlite.open) {
+        return resolve();
+      }
+      logger.debug('Trying to close SQLite...');
+      sqlite.on('close', () => {
+        logger.info('Database closed.');
+        resolve();
+      });
+      sqlite.on('error', (err) => reject(err));
+      sqlite.close();
+    });
   });
 
   this.resetPeers = () => co(function *() {
diff --git a/app/lib/logger/index.js b/app/lib/logger/index.js
index b47196a85cf982fd522d2b32391f264511ea1479..5c149af281e894a24e4857ca05873d60c3374578 100644
--- a/app/lib/logger/index.js
+++ b/app/lib/logger/index.js
@@ -44,7 +44,7 @@ const logger = new (winston.Logger)({
   ]
 });
 
-// Singleton
+// Singletons
 let loggerAttached = false;
 logger.addCallbackLogs = (callbackForLog) => {
   if (!loggerAttached) {
@@ -62,26 +62,35 @@ logger.addCallbackLogs = (callbackForLog) => {
   }
 };
 
+// Singletons
+let loggerHomeAttached = false;
 logger.addHomeLogs = (home) => {
-  logger.add(winston.transports.File, {
-    level: 'info',
-    levels: customLevels.levels,
-    handleExceptions: false,
-    colorize: true,
-    tailable: true,
-    maxsize: 50 * 1024 * 1024, // 50 MB
-    maxFiles: 3,
-    //zippedArchive: true,
-    json: false,
-    filename: path.join(home, 'duniter.log'),
-    timestamp: function() {
-      return moment().format();
-    }
-  });
+  if (!loggerHomeAttached) {
+    loggerHomeAttached = true;
+    logger.add(winston.transports.File, {
+      level: 'info',
+      levels: customLevels.levels,
+      handleExceptions: false,
+      colorize: true,
+      tailable: true,
+      maxsize: 50 * 1024 * 1024, // 50 MB
+      maxFiles: 3,
+      //zippedArchive: true,
+      json: false,
+      filename: path.join(home, 'duniter.log'),
+      timestamp: function () {
+        return moment().format();
+      }
+    });
+  }
 };
 
+let muted = false;
 logger.mute = () => {
-  logger.remove(winston.transports.Console);
+  if (!muted) {
+    logger.remove(winston.transports.Console);
+    muted = true;
+  }
 };
 
 /**
diff --git a/bin/ucoind b/bin/ucoind
index 617a9ec80e4e11953215c58fcb0f41a59fed30e1..0291708f8c03f7592c50953cb70acf00d9f1d3d1 100755
--- a/bin/ucoind
+++ b/bin/ucoind
@@ -19,7 +19,12 @@ return co(function*() {
     // Prepare the command
     const command = cli(process.argv);
     // If ever the process gets interrupted
-    process.on('SIGINT', command.closeCommand);
+    process.on('SIGINT', () => {
+      co(function*() {
+        yield command.closeCommand();
+        process.exit();
+      });
+    });
     // Executes the command
     yield command.execute();
     process.exit();
diff --git a/server.js b/server.js
index 684975523273f685bba3b51d3774590dedf706f9..108803c96c2e7ab550d0b60298618ae9f12c1456 100644
--- a/server.js
+++ b/server.js
@@ -345,9 +345,7 @@ function Server (dbConf, overrideConf) {
         });
   }
 
-  this.disconnect = () => {
-    return that.dal && that.dal.close();
-  };
+  this.disconnect = () => Promise.resolve(that.dal && that.dal.close());
 
   this.pullBlocks = that.PeeringService.pullBlocks;
 
diff --git a/test/integration/cli.js b/test/integration/cli.js
index 13e707851df5b19f263df1ea78f3d1e9fbc1d369..b9970785d7fb2a2e659096d2750763eb6fa4b5c1 100644
--- a/test/integration/cli.js
+++ b/test/integration/cli.js
@@ -11,23 +11,42 @@ describe("CLI", function() {
   it('reset data', () => co(function*() {
     yield execute(['reset', 'data']);
     const res = yield execute(['export-bc']);
-    JSON.parse(res).should.have.length(0);
+    res.should.have.length(0);
   }));
 
   it('sync 10 blocks', () => co(function*() {
     yield execute(['reset', 'data']);
     yield execute(['sync', 'duniter.org', '8999', '9', '--nointeractive']);
     const res = yield execute(['export-bc']);
-    JSON.parse(res).should.have.length(10);
+    res.should.have.length(10);
+  }));
+
+  it('[spawn] reset data', () => co(function*() {
+    yield executeSpawn(['reset', 'data']);
+    const res = yield executeSpawn(['export-bc']);
+    JSON.parse(res).should.have.length(0);
   }));
 });
 
+/**
+ * Executes a duniter command, as a command line utility.
+ * @param args Array of arguments.
+ * @returns {*|Promise} Returns the command output.
+ */
+function execute(args) {
+  return co(function*() {
+    const command = cli([process.argv[0], __filename].concat(args));
+    // Executes the command
+    return command.execute();
+  });
+}
+
 /**
  * Executes a duniter command, as a command line utility.
  * @param command Array of arguments.
  * @returns {*|Promise} Returns the command output.
  */
-function execute(command) {
+function executeSpawn(command) {
   return co(function*() {
     const duniter = spawn(process.argv[0], [path.join(__dirname, '../../bin/ucoind')].concat(command));
     return new Promise((resolve, reject) => {