diff --git a/app/config.json b/app/config.json
index a2828157b93cf9685100fb20859373dc43ff5558..8b00dabb0849a9cd7204af33c82726387b0110d8 100644
--- a/app/config.json
+++ b/app/config.json
@@ -50,7 +50,7 @@
     "initPhase": true,
     "expertMode": false,
     "decimalCount": 4,
-    "httpsMode": "clever",
+    "httpsMode": "force",
     "helptip": {
       "enable": true,
       "installDocUrl": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md"
diff --git a/www/i18n/locale-en-GB.json b/www/i18n/locale-en-GB.json
index dda81b99799ef025c88dfdefca7937e170e05d99..0905a4b32bb5e8686bae893e05d9c294d018fa36 100644
--- a/www/i18n/locale-en-GB.json
+++ b/www/i18n/locale-en-GB.json
@@ -114,6 +114,7 @@
     "PEER": "Duniter peer address",
     "USE_LOCAL_STORAGE": "Enable local storage",
     "ENABLE_HELPTIP": "Enable contextual help tips",
+    "ENABLE_UI_EFFECTS": "Enable visual effects",
     "HISTORY_SETTINGS": "My Account",
     "DISPLAY_UD_HISTORY": "Display produced dividends?",
     "AUTHENTICATION_SETTINGS": "Authentication",
diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json
index 72d17d615ecacf6476fe8dd665c90fc51fcc04fe..9e5475167cd6d5dc6553eb5d52c52115ec93e0bf 100644
--- a/www/i18n/locale-en.json
+++ b/www/i18n/locale-en.json
@@ -114,6 +114,7 @@
     "PEER": "Duniter peer address",
     "USE_LOCAL_STORAGE": "Enable local storage",
     "ENABLE_HELPTIP": "Enable contextual help tips",
+    "ENABLE_UI_EFFECTS": "Enable visual effects",
     "HISTORY_SETTINGS": "My Account",
     "DISPLAY_UD_HISTORY": "Display produced dividends?",
     "AUTHENTICATION_SETTINGS": "Authentication",
diff --git a/www/js/config.js b/www/js/config.js
index 401aab98d70952733dda01bc8a987a4b816e1354..e6d6d502ba19e243044e7db51ac185f9beb24bcf 100644
--- a/www/js/config.js
+++ b/www/js/config.js
@@ -38,7 +38,6 @@ angular.module("cesium.config", [])
 			"askEnable": false,
 			"host": "localhost",
 			"port": 9200,
-			"wsPort": 9400,
 			"notifications": {
 				"txSent": true,
 				"txReceived": true,
@@ -52,4 +51,4 @@ angular.module("cesium.config", [])
 	"newIssueUrl": "https://github.com/duniter/cesium/issues/new?labels=bug"
 })
 
-;
\ No newline at end of file
+;
diff --git a/www/js/controllers/network-controllers.js b/www/js/controllers/network-controllers.js
index 68c5c5d93771af3e4609749e368fe270fdbc9385..dafb1d7bb7c63a2c5487ed3fe074f965567b7719 100644
--- a/www/js/controllers/network-controllers.js
+++ b/www/js/controllers/network-controllers.js
@@ -153,7 +153,9 @@ function NetworkLookupController($scope,  $state, $ionicHistory, $ionicPopover,
     $scope.search.memberPeersCount = data.memberPeersCount;
     // Always tru if network not started (e.g. after leave+renter the view)
     $scope.search.loading = !$scope.networkStarted || csNetwork.isBusy();
-    $scope.motion.show({selector: '.item-peer'});
+    if ($scope.motion && $scope.search.results && $scope.search.results.length > 0) {
+      $scope.motion.show({selector: '.item-peer'});
+    }
   };
 
   $scope.refresh = function() {
diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js
index 4c93074f0618071c80475ef8ba52d9514c9e14b3..e13027a2239b8a21c481ac55ec4ec0a0b2941983 100644
--- a/www/js/controllers/settings-controllers.js
+++ b/www/js/controllers/settings-controllers.js
@@ -76,25 +76,26 @@ function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHtt
   $scope.changeNode= function(node) {
     $scope.showNodePopup(node || $scope.formData.node)
     .then(function(newNode) {
+      console.log(newNode);
       if (newNode.host === $scope.formData.node.host &&
         newNode.port === $scope.formData.node.port) {
         return; // same node = nothing to do
       }
       UIUtils.loading.show();
       var nodeBMA = BMA.instance(newNode.host, newNode.port);
-      nodeBMA.node.summary() // ping the node
-      .then(function() {
-        UIUtils.loading.hide();
-        $scope.formData.node = newNode;
-        BMA.copy(nodeBMA);
-      })
-      .catch(function(err){
-         UIUtils.loading.hide();
-         UIUtils.alert.error('ERROR.INVALID_NODE_SUMMARY')
-         .then(function(){
-           $scope.changeNode(newNode); // loop
-         });
-      });
+      nodeBMA.isAlive()
+        .then(function(alive) {
+          if (!alive) {
+            UIUtils.loading.hide();
+            return UIUtils.alert.error('ERROR.INVALID_NODE_SUMMARY')
+              .then(function(){
+                $scope.changeNode(newNode); // loop
+              });
+          }
+          UIUtils.loading.hide();
+          $scope.formData.node = newNode;
+          BMA.copy(nodeBMA);
+        });
     });
   };
 
diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js
index 02369e476df238a91adc39749649a006bc2738db..63ab54f18b5cb9a879e9be22ee6af1c35d4195f6 100644
--- a/www/js/services/bma-services.js
+++ b/www/js/services/bma-services.js
@@ -1,15 +1,11 @@
 //var Base58, Base64, scrypt_module_factory = null, nacl_factory = null;
 
-angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'cesium.settings.services'])
+angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.services', 'cesium.settings.services'])
 
-.factory('BMA', function($q, csSettings, csHttp, csCache, $rootScope, $timeout) {
+.factory('BMA', function($q, Api, Device, csSettings, csHttp, csCache, $rootScope, $timeout) {
   'ngInject';
 
-  function factory(host, port, cacheEnable) {
-
-    function exact(regexpContent) {
-      return new RegExp("^" + regexpContent + "$");
-    }
+  function BMA(host, port, useSsl, useCache) {
 
     var
       regex = {
@@ -42,7 +38,172 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce
         LIMIT_REQUEST_COUNT: 5, // simultaneous async request to a Duniter node
         LIMIT_REQUEST_DELAY: 1000, // time (in second) to wait between to call of a rest request
         regex: regex
+      },
+      listeners,
+      that = this;
+
+    that.date = {now: csHttp.date.now};
+    that.api = new Api(this, 'BMA-' + that.server);
+
+    init(host, port, useSsl, useCache);
+
+    function init(host, port, useSsl, useCache) {
+      if (!host) {
+        throw new Error('new BMA() need mandatory argument [host]');
+      }
+      that.alive = false;
+      that.cache = _emptyCache();
+      that.host = host;
+      that.port = port || 80;
+      that.useSsl = angular.isDefined(useSsl) ? useSsl : (that.port == 443);
+      that.useCache = angular.isDefined(useCache) ? useCache : false;
+
+      that.server = csHttp.getServer(host, port);
+      that.url = csHttp.getUrl(host, port, useSsl);
+    }
+
+    function exact(regexpContent) {
+      return new RegExp("^" + regexpContent + "$");
+    }
+
+    function _emptyCache() {
+      return {
+        getByPath: {},
+        postByPath: {},
+        wsByPath: {}
       };
+    }
+
+    that.cleanCache = function() {
+      console.debug('[BMA] Cleaning requests cache...');
+      _.keys(that.cache.wsByPath).forEach(function(key) {
+        var sock = that.cache.wsByPath[key];
+        sock.close();
+      });
+      that.cache = _emptyCache();
+    };
+
+    get = function (path, cacheTime) {
+      cacheTime = that.useCache && cacheTime;
+      var cacheKey = path + (cacheTime ? ('#'+cacheTime) : '');
+      return function(params) {
+        var request = that.cache.getByPath[cacheKey];
+        if (!request) {
+          if (cacheTime) {
+            request = csHttp.getWithCache(that.host, that.port, path, that.useSsl, cacheTime);
+          }
+          else {
+            request = csHttp.get(that.host, that.port, path, that.useSsl);
+          }
+          that.cache.getByPath[cacheKey] = request;
+        }
+        return request(params);
+      };
+    };
+
+    post = function(path) {
+      return function(obj, params) {
+        var request = that.cache.postByPath[path];
+        if (!request) {
+          request =  csHttp.post(that.host, that.port, path, that.useSsl);
+          that.cache.postByPath[path] = request;
+        }
+        return request(obj, params);
+      };
+    };
+
+    ws = function(path) {
+      return function() {
+        var sock = that.cache.wsByPath[path];
+        if (!sock) {
+          sock =  csHttp.ws(that.host, that.port, path, that.useSsl);
+          that.cache.wsByPath[path] = sock;
+        }
+        return sock;
+      };
+    };
+
+    that.isAlive = function() {
+      return that.node.summary()
+        .then(function(json) {
+          var isDuniter = json && json.duniter && json.duniter.software == 'duniter' && json.duniter.version;
+          var isCompatible = isDuniter && csHttp.version.isCompatible(csSettings.data.minVersion, json.duniter.version);
+          if (isDuniter && !isCompatible) {
+            console.error('[BMA] Uncompatible version [{0}] - expected at least [{1}]'.format(json.duniter.version, csSettings.data.minVersion));
+          }
+          return isCompatible;
+        })
+        .catch(function() {
+          return false;
+        });
+    };
+
+    function removeListeners() {
+      _.forEach(listeners, function(remove){
+        remove();
+      });
+      listeners = [];
+    }
+
+    function addListeners() {
+      listeners = [
+        // Listen if node changed
+        csSettings.api.data.on.changed($rootScope, onSettingsChanged, this)
+      ];
+    }
+
+    function onSettingsChanged(settings) {
+
+      var server = csHttp.getUrl(settings.node.host, settings.node.port, '', settings.node.useSsl);
+      var hasChanged = (server != that.url);
+      if (hasChanged) {
+        init(settings.node.host, settings.node.port, settings.node.useSsl, that.useCache);
+        that.restart();
+      }
+    }
+
+    that.start = function() {
+
+      console.debug('[BMA] Starting [{0}]...'.format(that.server));
+      var now = new Date().getTime();
+
+      return that.isAlive()
+        .then(function(alive) {
+          that.alive = alive;
+          if (!alive) {
+            // TODO : alert user ?
+            console.error('[BMA] Could not start [{0}]: node unreachable'.format(that.server));
+            return false;
+          }
+
+          // Add listeners
+          if (!listeners || listeners.length === 0) {
+            addListeners();
+          }
+          console.debug('[BMA] Started in '+(new Date().getTime()-now)+'ms');
+
+          that.api.node.raise.start();
+          return true;
+        });
+    };
+
+    that.stop = function() {
+      console.debug('[BMA] Stopping...');
+      that.alive = false;
+      removeListeners();
+      that.cleanCache();
+      that.api.node.raise.stop();
+    };
+
+    that.restart = function() {
+      that.stop();
+      return $timeout(function() {
+        that.start();
+      }, 200);
+    };
+
+    that.api.registerEvent('node', 'start');
+    that.api.registerEvent('node', 'stop');
 
     var exports = {
       errorCodes: errorCodes,
@@ -57,61 +218,61 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce
         BMAS_ENDPOINT: exact(regex.BMAS_ENDPOINT)
       },
       node: {
-        server: csHttp.getServer(host, port),
-        url: csHttp.getUrl(host, port),
+        server: that.server,
+        url: that.url,
         host: host,
         port: port,
-        summary: csHttp.getWithCache(host, port, '/node/summary', csHttp.cache.LONG),
+        summary: get('/node/summary', csHttp.cache.LONG),
         same: function(host2, port2) {
           return host2 == host && ((!port && !port2) || (port == port2));
         }
       },
       network: {
         peering: {
-          self: csHttp.get(host, port, '/network/peering'),
-          peers: csHttp.get(host, port, '/network/peering/peers')
+          self: get('/network/peering'),
+          peers: get('/network/peering/peers')
         },
-        peers: csHttp.get(host, port, '/network/peers')
+        peers: get('/network/peers')
       },
       wot: {
-        lookup: csHttp.get(host, port, '/wot/lookup/:search'),
-        certifiedBy: csHttp.get(host, port, '/wot/certified-by/:pubkey'),
-        certifiersOf: csHttp.get(host, port, '/wot/certifiers-of/:pubkey'),
+        lookup: get('/wot/lookup/:search'),
+        certifiedBy: get('/wot/certified-by/:pubkey'),
+        certifiersOf: get('/wot/certifiers-of/:pubkey'),
         member: {
-          all: cacheEnable ? csHttp.getWithCache(host, port, '/wot/members') : csHttp.get(host, port, '/wot/members'),
-          pending: csHttp.get(host, port, '/wot/pending')
+          all: get('/wot/members', csHttp.cache.LONG),
+          pending: get('/wot/pending')
         },
-        requirements: csHttp.get(host, port, '/wot/requirements/:pubkey'),
-        add: csHttp.post(host, port, '/wot/add'),
-        certify: csHttp.post(host, port, '/wot/certify'),
-        revoke: csHttp.post(host, port, '/wot/revoke')
+        requirements: get('/wot/requirements/:pubkey'),
+        add: post('/wot/add'),
+        certify: post('/wot/certify'),
+        revoke: post('/wot/revoke')
       },
       blockchain: {
-        parameters: csHttp.getWithCache(host, port, '/blockchain/parameters', csHttp.cache.LONG),
-        block: cacheEnable ? csHttp.getWithCache(host, port, '/blockchain/block/:block', csHttp.cache.SHORT) : csHttp.get(host, port, '/blockchain/block/:block'),
-        blocksSlice: csHttp.get(host, port, '/blockchain/blocks/:count/:from'),
-        current: csHttp.get(host, port, '/blockchain/current'),
-        membership: csHttp.post(host, port, '/blockchain/membership'),
+        parameters: get('/blockchain/parameters', csHttp.cache.LONG),
+        block: get('/blockchain/block/:block', csHttp.cache.SHORT),
+        blocksSlice: get('/blockchain/blocks/:count/:from'),
+        current: get('/blockchain/current'),
+        membership: post('/blockchain/membership'),
         stats: {
-          ud: cacheEnable ? csHttp.getWithCache(host, port, '/blockchain/with/ud', csHttp.cache.SHORT) : csHttp.get(host, port, '/blockchain/with/ud'),
-          tx: csHttp.get(host, port, '/blockchain/with/tx'),
-          newcomers: csHttp.get(host, port, '/blockchain/with/newcomers'),
-          hardship: csHttp.get(host, port, '/blockchain/hardship/:pubkey')
+          ud: get('/blockchain/with/ud', csHttp.cache.SHORT),
+          tx: get('/blockchain/with/tx'),
+          newcomers: get('/blockchain/with/newcomers'),
+          hardship: get('/blockchain/hardship/:pubkey')
         }
       },
       tx: {
-        sources: csHttp.get(host, port, '/tx/sources/:pubkey'),
-        process: csHttp.post(host, port, '/tx/process'),
+        sources: get('/tx/sources/:pubkey'),
+        process: post('/tx/process'),
         history: {
-          all: csHttp.get(host, port, '/tx/history/:pubkey'),
-          times: cacheEnable ? csHttp.getWithCache(host, port, '/tx/history/:pubkey/times/:from/:to') : csHttp.get(host, port, '/tx/history/:pubkey/times/:from/:to'),
-          timesNoCache: csHttp.get(host, port, '/tx/history/:pubkey/times/:from/:to'),
-          blocks: cacheEnable ? csHttp.getWithCache(host, port, '/tx/history/:pubkey/blocks/:from/:to') : csHttp.get(host, port, '/tx/history/:pubkey/blocks/:from/:to'),
-          pending: csHttp.get(host, port, '/tx/history/:pubkey/pending')
+          all: get('/tx/history/:pubkey'),
+          times: get('/tx/history/:pubkey/times/:from/:to', csHttp.cache.LONG),
+          timesNoCache: get('/tx/history/:pubkey/times/:from/:to'),
+          blocks: get('/tx/history/:pubkey/blocks/:from/:to', csHttp.cache.LONG),
+          pending: get('/tx/history/:pubkey/pending')
         }
       },
       ud: {
-        history: csHttp.get(host, port, '/ud/history/:pubkey')
+        history: get('/ud/history/:pubkey')
       },
       uri: {},
       raw: {
@@ -119,26 +280,6 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce
       }
     };
 
-    exports.lightInstance = function(host, port) {
-      return {
-        node: {
-          summary: csHttp.getWithCache(host, port, '/node/summary', csHttp.cache.LONG)
-        },
-        network: {
-          peering: {
-            self: csHttp.get(host, port, '/network/peering')
-          },
-          peers: csHttp.get(host, port, '/network/peers')
-        },
-        blockchain: {
-          current: csHttp.get(host, port, '/blockchain/current'),
-          stats: {
-            hardship: csHttp.get(host, port, '/blockchain/hardship/:pubkey')
-          }
-        }
-      };
-    };
-
     exports.node.parseEndPoint = function(endpoint) {
       var matches = exports.regex.BMA_ENDPOINT.exec(endpoint);
       if (!matches) return;
@@ -151,15 +292,8 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce
     };
 
     exports.copy = function(otherNode) {
-      if (!!this.instance) { // if main service impl
-        var instance = this.instance; // keep factory
-        csCache.clearAll(); // clean all caches
-        angular.copy(otherNode, this);
-        this.instance = instance;
-      }
-      else {
-        angular.copy(otherNode, this);
-      }
+      init(otherNode.host, otherNode.port, otherNode.useSsl, that.useCache);
+      return that.restart();
     };
 
     exports.wot.member.uids = function() {
@@ -277,6 +411,8 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce
         if (exact(regex.PUBKEY).test(uri)) {
           resolve({
             pubkey: uri
+
+
           });
         }
         else if(uri.startsWith('duniter://')) {
@@ -377,31 +513,49 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce
     };
 
     exports.websocket = {
-        block: function() {
-          return csHttp.ws((exports.node.port == 443 ? 'wss' : 'ws') + '://' + exports.node.server + '/ws/block');
-        },
-        peer: function() {
-          return csHttp.ws((exports.node.port == 443 ? 'wss' : 'ws') + '://' + exports.node.server + '/ws/peer');
-        },
+        block: ws('/ws/block'),
+        peer: ws('/ws/peer'),
         close : csHttp.closeAllWs
       };
 
-    return exports;
+    angular.merge(that, exports);
   }
 
-  var service = factory(csSettings.data.node.host, csSettings.data.node.port, true /*cache*/);
-  service.instance = factory;
+  var service = new BMA(
+    csSettings.data.node.host,
+    csSettings.data.node.port,
+    csSettings.data.node.port == 443 || csSettings.data.node.useSsl,
+    true /*cache*/);
 
-  // Listen settings changes
-  csSettings.api.data.on.changed($rootScope, function(settings) {
-
-    var nodeServer = csHttp.getServer(settings.node.host, settings.node.port);
-    if (nodeServer != service.node.server) {
-      var newService = factory(settings.node.host, settings.node.port, true /*cache*/);
-      service.copy(newService); // reload service
-    }
+  service.instance = function(host, port, useSsl, useCache) {
+    return new BMA(host, port, useSsl, useCache);
+  };
 
-  });
+  service.lightInstance = function(host, port, useSsl) {
+    port = port || 80;
+    useSsl = angular.isDefined(useSsl) ? useSsl : (port == 443);
+    return {
+      node: {
+        summary: csHttp.getWithCache(host, port, '/node/summary', useSsl, csHttp.cache.LONG)
+      },
+      network: {
+        peering: {
+          self: csHttp.get(host, port, '/network/peering', useSsl)
+        },
+        peers: csHttp.get(host, port, '/network/peers', useSsl)
+      },
+      blockchain: {
+        current: csHttp.get(host, port, '/blockchain/current', useSsl),
+        stats: {
+          hardship: csHttp.get(host, port, '/blockchain/hardship/:pubkey', useSsl)
+        }
+      }
+    };
+  };
+  /*Device.ready().then(function() {
+    return service.start();
+  });*/
+  service.start();
 
   return service;
 })
diff --git a/www/js/services/http-services.js b/www/js/services/http-services.js
index 0e276ba9549ef23054611d879ce241779536f617..92948c4386101ed1ff28959795a17b3749a337bd 100644
--- a/www/js/services/http-services.js
+++ b/www/js/services/http-services.js
@@ -3,256 +3,279 @@ angular.module('cesium.http.services', ['ngResource', 'cesium.cache.services'])
 .factory('csHttp', function($http, $q, csSettings, csCache, $timeout) {
   'ngInject';
 
-  function factory(timeout) {
+  var timeout = csSettings.data.timeout;
 
-    var
-      sockets = [],
-      cachePrefix = 'csHttp'
-    ;
+  var
+    sockets = [],
+    cachePrefix = 'csHttp'
+  ;
 
-    if (!timeout) {
-      timeout=4000; // default
-    }
+  if (!timeout) {
+    timeout=4000; // default
+  }
 
-    function getServer(host, port) {
-      return  !host ? null : (host + (port ? ':' + port : ''));
-    }
+  function getServer(host, port) {
+    return  !host ? null : (host + (port ? ':' + port : ''));
+  }
 
-    function getUrl(host, port, path, useSsl) {
-      var protocol = (port == 443 || useSsl) ? 'https' : 'http';
-      return  protocol + '://' + getServer(host, port) + (path ? path : '');
-    }
+  function getUrl(host, port, path, useSsl) {
+    var protocol = (port == 443 || useSsl) ? 'https' : 'http';
+    return  protocol + '://' + getServer(host, port) + (path ? path : '');
+  }
 
-    function processError(reject, data, url, status) {
-      if (data && data.message) {
-        reject(data);
+  function getWsUrl(host, port, path, useSsl) {
+    var protocol = (port == 443 || useSsl) ? 'wss' : 'ws';
+    return  protocol + '://' + getServer(host, port) + (path ? path : '');
+  }
+
+  function processError(reject, data, url, status) {
+    if (data && data.message) {
+      reject(data);
+    }
+    else {
+      if (status == 404) {
+        reject({ucode: 404, message: 'Resource not found ' + (url ? ' ('+url+')' : '')});
+      }
+      if (url) {
+        reject('Error from node (' + url + ')');
       }
       else {
-        if (status == 404) {
-          reject({ucode: 404, message: 'Resource not found ' + (url ? ' ('+url+')' : '')});
-        }
-        if (url) {
-          reject('Error from node (' + url + ')');
-        }
-        else {
-          reject('Unknown error from node');
-        }
+        reject('Unknown error from node');
       }
     }
+  }
 
-    function prepare(url, params, config, callback) {
-      var pkeys = [], queryParams = {}, newUri = url;
-      if (typeof params == 'object') {
-        pkeys = _.keys(params);
-      }
-
-      _.forEach(pkeys, function(pkey){
-        var prevURI = newUri;
-        newUri = newUri.replace(':' + pkey, params[pkey]);
-        if (prevURI == newUri) {
-          queryParams[pkey] = params[pkey];
-        }
-      });
-      config.params = queryParams;
-      return callback(newUri, config);
+  function prepare(url, params, config, callback) {
+    var pkeys = [], queryParams = {}, newUri = url;
+    if (typeof params == 'object') {
+      pkeys = _.keys(params);
     }
 
-    function getResource(host, port, path) {
-      var url = getUrl(host, port, path);
-      return function(params) {
-        return $q(function(resolve, reject) {
-          var config = {
-            timeout: timeout
-          };
+    _.forEach(pkeys, function(pkey){
+      var prevURI = newUri;
+      newUri = newUri.replace(':' + pkey, params[pkey]);
+      if (prevURI == newUri) {
+        queryParams[pkey] = params[pkey];
+      }
+    });
+    config.params = queryParams;
+    return callback(newUri, config);
+  }
 
-          prepare(url, params, config, function(url, config) {
-              $http.get(url, config)
-              .success(function(data, status, headers, config) {
-                resolve(data);
-              })
-              .error(function(data, status, headers, config) {
-                processError(reject, data, url, status);
-              });
-          });
+  function getResource(host, port, path, useSsl) {
+    var url = getUrl(host, port, path, useSsl);
+    return function(params) {
+      return $q(function(resolve, reject) {
+        var config = {
+          timeout: timeout
+        };
+
+        prepare(url, params, config, function(url, config) {
+            $http.get(url, config)
+            .success(function(data, status, headers, config) {
+              resolve(data);
+            })
+            .error(function(data, status, headers, config) {
+              processError(reject, data, url, status);
+            });
         });
-      };
-    }
+      });
+    };
+  }
 
-    function getResourceWithCache(host, port, path, maxAge, autoRefresh) {
-      var url = getUrl(host, port, path);
-      maxAge = maxAge || csCache.constants.LONG;
-      //console.debug('[http] will cache ['+url+'] ' + maxAge + 'ms' + (autoRefresh ? ' with auto-refresh' : ''));
+  function getResourceWithCache(host, port, path, useSsl, maxAge, autoRefresh) {
+    var url = getUrl(host, port, path, useSsl);
+    maxAge = maxAge || csCache.constants.LONG;
+    //console.debug('[http] will cache ['+url+'] ' + maxAge + 'ms' + (autoRefresh ? ' with auto-refresh' : ''));
 
-      return function(params) {
-        return $q(function(resolve, reject) {
-          var config = {
-            timeout: timeout
-          };
-          if (autoRefresh) { // redo the request if need
-            config.cache = csCache.get(cachePrefix, maxAge, function (key, value) {
-                console.debug('[http] Refreshing cache for ['+key+'] ');
-                $http.get(key, config)
-                  .success(function (data) {
-                    config.cache.put(key, data);
-                });
+    return function(params) {
+      return $q(function(resolve, reject) {
+        var config = {
+          timeout: timeout
+        };
+        if (autoRefresh) { // redo the request if need
+          config.cache = csCache.get(cachePrefix, maxAge, function (key, value) {
+              console.debug('[http] Refreshing cache for ['+key+'] ');
+              $http.get(key, config)
+                .success(function (data) {
+                  config.cache.put(key, data);
               });
-          }
-          else {
-            config.cache = csCache.get(cachePrefix, maxAge);
-          }
+            });
+        }
+        else {
+          config.cache = csCache.get(cachePrefix, maxAge);
+        }
 
-          prepare(url, params, config, function(url, config) {
-            $http.get(url, config)
-              .success(function(data) {
-                resolve(data);
-              })
-              .error(function(data, status) {
-                processError(reject, data, url, status);
-              });
-          });
+        prepare(url, params, config, function(url, config) {
+          $http.get(url, config)
+            .success(function(data) {
+              resolve(data);
+            })
+            .error(function(data, status) {
+              processError(reject, data, url, status);
+            });
         });
-      };
-    }
+      });
+    };
+  }
 
-    function postResource(host, port, path) {
-      var url = getUrl(host, port, path);
-      return function(data, params) {
-        return $q(function(resolve, reject) {
-          var config = {
-            timeout: timeout,
-            headers : {'Content-Type' : 'application/json'}
-          };
+  function postResource(host, port, path) {
+    var url = getUrl(host, port, path);
+    return function(data, params) {
+      return $q(function(resolve, reject) {
+        var config = {
+          timeout: timeout,
+          headers : {'Content-Type' : 'application/json'} // TODO: test using "application/json;charset=UTF-8"
+        };
 
-          prepare(url, params, config, function(url, config) {
-              $http.post(url, data, config)
-              .success(function(data) {
-                resolve(data);
-              })
-              .error(function(data, status) {
-                processError(reject, data, status);
-              });
-          });
+        prepare(url, params, config, function(url, config) {
+            $http.post(url, data, config)
+            .success(function(data) {
+              resolve(data);
+            })
+            .error(function(data, status) {
+              processError(reject, data, status);
+            });
         });
-      };
-    }
+      });
+    };
+  }
 
-    function ws(host, port, path, useSsl) {
-      var uri = ((port == 443 || useSsl) ? 'wss' : 'ws') + '://' + getServer(host, port) + path;
-      var sock = null;
-      var callbacks = [];
+  function ws(host, port, path, useSsl) {
+    if (!path) {
+      console.error('calling csHttp.ws without path argument');
+      throw 'calling csHttp.ws without path argument';
+    }
+    var uri = getWsUrl(host, port, path, useSsl);
+    var sock = null;
+    var callbacks = [];
 
-      function _waitOpen() {
-        if (!sock) throw new Error('Websocket not opened');
-        if (sock.readyState == 1) {
-          return $q.when(sock);
-        }
-        if (sock.readyState == 3) {
-          return $q.reject('Unable to connect to Websocket ['+sock.url+']');
-        }
-        return $timeout(_waitOpen, 100);
+    function _waitOpen() {
+      if (!sock) throw new Error('Websocket not opened');
+      if (sock.readyState == 1) {
+        return $q.when(sock);
       }
-
-      function _open(self, callback, params) {
-        if (!sock) {
-          prepare(uri, params, {}, function(uri) {
-            console.debug('[http] Listening on websocket ['+path+']...');
-            sock = new WebSocket(uri);
-            sock.onerror = function(e) {
-              sock.readyState=3;
-            };
-            sock.onmessage = function(e) {
-              var obj = JSON.parse(e.data);
-              _.forEach(callbacks, function(callback) {
-                callback(obj);
-              });
-            };
-            sockets.push(self);
-          });
-        }
-        if (callback) callbacks.push(callback);
-        return _waitOpen();
+      if (sock.readyState == 3) {
+        return $q.reject('Unable to connect to Websocket ['+sock.url+']');
       }
-
-      return {
-        open: function(params) {
-          return _open(this, null, params);
-        },
-        on: function(callback, params) {
-          return _open(this, callback, params);
-        },
-        send: function(data) {
-          return _waitOpen()
-            .then(function(){
-              sock.send(data);
-            });
-        },
-        close: function() {
-          if (sock) {
-            console.debug('[http] Stopping websocket ['+path+']...');
-            sock.close();
-            sock = null;
-            callbacks = [];
-          }
-        }
-      };
+      return $timeout(_waitOpen, 100);
     }
 
-    function closeAllWs() {
-      if (sockets.length > 0) {
-        _.forEach(sockets, function(sock) {
-          sock.close();
+    function _open(self, callback, params) {
+      if (!sock) {
+        prepare(uri, params, {}, function(uri) {
+          console.debug('[http] Listening on websocket ['+path+']...');
+          sock = new WebSocket(uri);
+          sock.onerror = function(e) {
+            sock.readyState=3;
+          };
+          sock.onmessage = function(e) {
+            var obj = JSON.parse(e.data);
+            _.forEach(callbacks, function(callback) {
+              callback(obj);
+            });
+          };
+          sockets.push(self);
         });
-        sockets = []; // Reset socks list
       }
+      if (callback) callbacks.push(callback);
+      return _waitOpen();
     }
 
-    // See doc : https://gist.github.com/jlong/2428561
-    function parseUri(uri) {
-      var protocol;
-      if (uri.startsWith('duniter://')) {
-        protocol = 'duniter';
-        uri = uri.replace('duniter://', 'http://');
+    return {
+      open: function(params) {
+        return _open(this, null, params);
+      },
+      on: function(callback, params) {
+        return _open(this, callback, params);
+      },
+      send: function(data) {
+        return _waitOpen()
+          .then(function(){
+            sock.send(data);
+          });
+      },
+      close: function() {
+        if (sock) {
+          console.debug('[http] Stopping websocket ['+path+']...');
+          sock.close();
+          sock = null;
+          callbacks = [];
+        }
       }
+    };
+  }
 
-      var parser = document.createElement('a');
-      parser.href = uri;
+  function closeAllWs() {
+    if (sockets.length > 0) {
+      _.forEach(sockets, function(sock) {
+        sock.close();
+      });
+      sockets = []; // Reset socks list
+    }
+  }
 
-      var pathname = parser.pathname;
-      if (pathname && pathname.startsWith('/')) {
-        pathname = pathname.substring(1);
-      }
+  // See doc : https://gist.github.com/jlong/2428561
+  function parseUri(uri) {
+    var protocol;
+    if (uri.startsWith('duniter://')) {
+      protocol = 'duniter';
+      uri = uri.replace('duniter://', 'http://');
+    }
 
-      result = {
-        protocol: protocol ? protocol : parser.protocol,
-        hostname: parser.hostname,
-        host: parser.host,
-        port: parser.port,
-        username: parser.username,
-        password: parser.password,
-        pathname: pathname,
-        search: parser.search,
-        hash: parser.hash
-      };
-      parser.remove();
-      return result;
+    var parser = document.createElement('a');
+    parser.href = uri;
+
+    var pathname = parser.pathname;
+    if (pathname && pathname.startsWith('/')) {
+      pathname = pathname.substring(1);
     }
 
-    return {
-      get: getResource,
-      getWithCache: getResourceWithCache,
-      post: postResource,
-      ws: ws,
-      closeAllWs: closeAllWs,
-      getUrl : getUrl,
-      getServer: getServer,
-      uri: {
-        parse: parseUri
-      },
-      cache: csCache.constants
+    result = {
+      protocol: protocol ? protocol : parser.protocol,
+      hostname: parser.hostname,
+      host: parser.host,
+      port: parser.port,
+      username: parser.username,
+      password: parser.password,
+      pathname: pathname,
+      search: parser.search,
+      hash: parser.hash
     };
+    parser.remove();
+    return result;
+  }
+
+  // Get time (UTC)
+  function getDateNow() {
+    return Math.floor(moment().utc().valueOf() / 1000);
   }
 
 
-  return factory(csSettings.data.timeout);
+  function isVersionCompatible(minVersion, actualVersion) {
+    // TODO: add implementation
+    console.debug('[http] TODO: implement check version [{0}] compatible with [{1}]'.format(actualVersion, minVersion));
+    return true;
+  }
+
+  return {
+    get: getResource,
+    getWithCache: getResourceWithCache,
+    post: postResource,
+    ws: ws,
+    closeAllWs: closeAllWs,
+    getUrl : getUrl,
+    getServer: getServer,
+    uri: {
+      parse: parseUri
+    },
+    date: {
+      now: getDateNow
+    },
+    version: {
+      isCompatible: isVersionCompatible
+    },
+    cache: csCache.constants
+  };
 })
 ;
diff --git a/www/js/services/settings-services.js b/www/js/services/settings-services.js
index 6c763ba3a2d1a96fb2de4c4180396b6858bf9234..53dca121e713343731af846b91ee184f70bc704a 100644
--- a/www/js/services/settings-services.js
+++ b/www/js/services/settings-services.js
@@ -58,6 +58,7 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi
         decimalCount: 4,
         forceNetworkViewToHttp: false,
         uiEffects: true,
+        minVersion: csConfig.compatProtocol_0_80 ? '0.80.0' : '0.90.0', // TODO update this if need
         newIssueUrl: "https://github.com/duniter/cesium/issues/new?labels=bug",
         helptip: {
           enable: true,
@@ -86,8 +87,12 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi
       api = new Api(this, "csSettings"),
 
       reset = function() {
+        _.keys(data).forEach(function(key){
+          delete data[key];
+        });
         angular.merge(data, defaultSettings);
-        store();
+        api.data.raisePromise.reset(data)
+          .then(store);
       },
 
       getByPath = function(path, defaultValue) {
@@ -198,6 +203,7 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi
         });
       };
 
+    api.registerEvent('data', 'reset');
     api.registerEvent('data', 'changed');
     api.registerEvent('data', 'store');
     api.registerEvent('data', 'ready');
@@ -215,7 +221,7 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi
     };
   }
 
-  var service = Factory();
+  var service = new Factory();
 
   service.restore()
     .then(function() {
diff --git a/www/plugins/es/i18n/locale-en-GB.json b/www/plugins/es/i18n/locale-en-GB.json
index 83d3acdce5af2dbaddb0698437eafc465e5bc14f..a6871c8f34feee0c21147810b0a631b022be2bb2 100644
--- a/www/plugins/es/i18n/locale-en-GB.json
+++ b/www/plugins/es/i18n/locale-en-GB.json
@@ -31,6 +31,9 @@
     },
     "EVENT": {
       "MEMBER_WITHOUT_PROFILE": "To obtain your certification more quickly, fill in <a href=\"#/app/user/profile/edit\">your user profile</a>. Members will more easily put their trust in a verifiable identity."
+    },
+    "ERROR": {
+      "WS_CONNECTION_FAILED": "Cesium can not receive notifications because of a technical error (connection to the Cesium + data node).<br/><br/>If the problem persists, please <b>choose another data node</b> in Cesium+ settings."
     }
   },
   "COMMENTS": {
diff --git a/www/plugins/es/i18n/locale-en.json b/www/plugins/es/i18n/locale-en.json
index 83d3acdce5af2dbaddb0698437eafc465e5bc14f..a6871c8f34feee0c21147810b0a631b022be2bb2 100644
--- a/www/plugins/es/i18n/locale-en.json
+++ b/www/plugins/es/i18n/locale-en.json
@@ -31,6 +31,9 @@
     },
     "EVENT": {
       "MEMBER_WITHOUT_PROFILE": "To obtain your certification more quickly, fill in <a href=\"#/app/user/profile/edit\">your user profile</a>. Members will more easily put their trust in a verifiable identity."
+    },
+    "ERROR": {
+      "WS_CONNECTION_FAILED": "Cesium can not receive notifications because of a technical error (connection to the Cesium + data node).<br/><br/>If the problem persists, please <b>choose another data node</b> in Cesium+ settings."
     }
   },
   "COMMENTS": {
diff --git a/www/plugins/es/i18n/locale-fr-FR.json b/www/plugins/es/i18n/locale-fr-FR.json
index 9c2e50753955a154acb5c980daf19fb6cdad418c..d609686f9f1efe9890747473d23f115ef0441bdf 100644
--- a/www/plugins/es/i18n/locale-fr-FR.json
+++ b/www/plugins/es/i18n/locale-fr-FR.json
@@ -33,7 +33,7 @@
       "MEMBER_WITHOUT_PROFILE": "Pour obtenir vos certifications plus rapidement, completez <a href=\"#/app/user/profile/edit\">votre profil utilisateur</a>. Les membres accorderont plus facilement leur confiance à une identité vérifiable."
     },
     "ERROR": {
-      "WS_CONNECTION_FAILED": "Cesium ne peut plus recevoir les nouvelles notifications, à cause d'une erreur technique (connexion au noeud de noeud Cesium+).<br/><br/>Si le problème persiste, veuillez <b>changer de noeud de données</b> dans les paramètres de l'extension Cesium+."
+      "WS_CONNECTION_FAILED": "Cesium ne peut pas recevoir les notifications, à cause d'une erreur technique (connexion au noeud de données Cesium+).<br/><br/>Si le problème persiste, veuillez <b>choisir un autre noeud de données</b> dans les paramètres Cesium+."
     }
   },
   "COMMENTS": {
diff --git a/www/plugins/es/js/controllers/message-controllers.js b/www/plugins/es/js/controllers/message-controllers.js
index 4e7e04c977b3664032c3ae6829344f291fd25aa1..49d5b30b1a439133880a014d2ccf250d95f96d03 100644
--- a/www/plugins/es/js/controllers/message-controllers.js
+++ b/www/plugins/es/js/controllers/message-controllers.js
@@ -52,7 +52,7 @@ angular.module('cesium.es.message.controllers', ['cesium.es.services'])
 
 ;
 
-function ESMessageListController($scope, $rootScope, $state, $timeout, $translate, $ionicHistory, $ionicPopover,
+function ESMessageListController($scope, $rootScope, $state, $translate, $ionicHistory, $ionicPopover,
                                  esModals, UIUtils, esMessage) {
   'ngInject';
 
@@ -480,7 +480,7 @@ function ESMessageViewController($scope, $state, $timeout, $translate, $ionicHis
   };
 }
 
-function PopoverMessageController($scope, $timeout, UIUtils, $state, csWallet, esNotification, esMessage, esModals) {
+function PopoverMessageController($scope, $timeout, UIUtils, $state, csWallet, esHttp, esNotification, esMessage, esModals) {
   'ngInject';
 
   var defaultSearchLimit = 40;
@@ -493,6 +493,12 @@ function PopoverMessageController($scope, $timeout, UIUtils, $state, csWallet, e
     limit: defaultSearchLimit
   };
 
+  $scope.$on('popover.shown', function() {
+    if ($scope.search.loading) {
+      $scope.load();
+    }
+  });
+
   $scope.load = function(from, size) {
     var options = {};
     options.from = from || 0;
@@ -570,7 +576,6 @@ function PopoverMessageController($scope, $timeout, UIUtils, $state, csWallet, e
     delete $scope.search.limit;
   };
 
-  csWallet.api.data.on.logout($scope, $scope.resetData);
 
   /* -- Modals -- */
 
@@ -582,11 +587,11 @@ function PopoverMessageController($scope, $timeout, UIUtils, $state, csWallet, e
       });
   };
 
-  esNotification.api.data.on.new($scope, $scope.onNewNotification);
+  /* -- listeners -- */
 
-  /* -- default popover action -- */
-  if ($scope.search.loading) {
-    $scope.load();
-  }
+  csWallet.api.data.on.logout($scope, $scope.resetData);
+  esHttp.api.node.on.stop($scope, $scope.resetData);
+  esHttp.api.node.on.start($scope, $scope.load);
+  esNotification.api.data.on.new($scope, $scope.onNewNotification);
 
 }
diff --git a/www/plugins/es/js/controllers/notification-controllers.js b/www/plugins/es/js/controllers/notification-controllers.js
index 586b8b805b80c3424dcd00375c2271e4d5e211b8..79102d32038b2a8a9951db47aab72cd82ba616f1 100644
--- a/www/plugins/es/js/controllers/notification-controllers.js
+++ b/www/plugins/es/js/controllers/notification-controllers.js
@@ -25,7 +25,7 @@ angular.module('cesium.es.notification.controllers', ['cesium.es.services'])
 
 ;
 
-function NotificationsController($scope, $rootScope, UIUtils, $state, csWallet, esNotification) {
+function NotificationsController($scope, $rootScope, UIUtils, $state, esHttp, csWallet, esNotification) {
   'ngInject';
 
   var defaultSearchLimit = 40;
@@ -128,7 +128,6 @@ function NotificationsController($scope, $rootScope, UIUtils, $state, csWallet,
       $scope.updateView();
     }
   };
-  esNotification.api.data.on.new($scope, $scope.onNewNotification);
 
   $scope.resetData = function() {
     if ($scope.search.loading) return;
@@ -138,8 +137,14 @@ function NotificationsController($scope, $rootScope, UIUtils, $state, csWallet,
     $scope.search.loading = true;
     delete $scope.search.limit;
   };
-  // When logout: force reload
+
+  /* -- listeners -- */
+
+  esNotification.api.data.on.new($scope, $scope.onNewNotification);
   csWallet.api.data.on.logout($scope, $scope.resetData);
+  esHttp.api.node.on.stop($scope, $scope.resetData);
+  esHttp.api.node.on.start($scope, $scope.load);
+
 }
 
 function PopoverNotificationsController($scope, $timeout, $controller, UIUtils, $state, csWallet, csSettings) {
diff --git a/www/plugins/es/js/controllers/settings-controllers.js b/www/plugins/es/js/controllers/settings-controllers.js
index ff6ca7ba8601c8248a02287cdf8fd83f30f1cade..130ef5d3300cb2080794ae043dd260f0fe83d036 100644
--- a/www/plugins/es/js/controllers/settings-controllers.js
+++ b/www/plugins/es/js/controllers/settings-controllers.js
@@ -61,7 +61,8 @@ function ESPluginSettingsController ($scope, $q,  $translate, $ionicPopup, UIUti
       angular.copy(csSettings.data.plugins.es) : {
       enable: false,
       host: null,
-      port: null
+      port: null,
+      wsPort: null
     };
     $scope.loading = false;
   });
@@ -74,8 +75,9 @@ function ESPluginSettingsController ($scope, $q,  $translate, $ionicPopup, UIUti
   $scope.changeEsNode= function(node) {
     $scope.showNodePopup(node || $scope.formData)
     .then(function(newNode) {
-      if (newNode.host === $scope.formData.host &&
-        newNode.port === $scope.formData.port) {
+      if (newNode.host == $scope.formData.host &&
+        newNode.port == $scope.formData.port &&
+        newNode.wsPort == $scope.formData.wsPort) {
         UIUtils.loading.hide();
         return; // same node = nothing to do
       }
@@ -95,6 +97,7 @@ function ESPluginSettingsController ($scope, $q,  $translate, $ionicPopup, UIUti
           UIUtils.loading.hide();
           $scope.formData.host = newNode.host;
           $scope.formData.port = newNode.port;
+          $scope.formData.wsPort = newNode.wsPort;
 
           esHttp.copy(newEsNode);
         });
@@ -104,7 +107,15 @@ function ESPluginSettingsController ($scope, $q,  $translate, $ionicPopup, UIUti
   // Show node popup
   $scope.showNodePopup = function(node) {
     return $q(function(resolve, reject) {
-      $scope.popupData.newNode = node.port ? [node.host, node.port].join(':') : node.host;
+      var parts = [node.host];
+      if (node.wsPort && node.wsPort != (node.port||80)) {
+        parts.push(node.port||80);
+        parts.push(node.wsPort);
+      }
+      else if (node.port && node.port != 80) {
+        parts.push(node.port);
+      }
+      $scope.popupData.newNode = parts.join(':');
       if (!!$scope.popupForm) {
         $scope.popupForm.$setPristine();
       }
@@ -139,10 +150,10 @@ function ESPluginSettingsController ($scope, $q,  $translate, $ionicPopup, UIUti
               return;
             }
             var parts = node.split(':');
-            parts[1] = parts[1] ? parts[1] : 80;
             resolve({
               host: parts[0],
-              port: parts[1]
+              port: parts[1] || 80,
+              wsPort: parts[2] || parts[1] || 80
             });
           });
         });
@@ -198,6 +209,7 @@ function ESPluginSettingsController ($scope, $q,  $translate, $ionicPopup, UIUti
   $scope.$watch('formData', $scope.onFormChanged, true);
 
   $scope.getServer = function() {
-    return csHttp.getServer($scope.formData.host, $scope.formData.port);
+    var server = csHttp.getServer($scope.formData.host, $scope.formData.port != 80 ? $scope.formData.port : undefined);
+    return server + ($scope.formData.wsPort && $scope.formData.wsPort != $scope.formData.port ? ':' + $scope.formData.wsPort : '');
   };
 }
diff --git a/www/plugins/es/js/entities/notification.js b/www/plugins/es/js/entities/notification.js
index c7b553154be00d28f1d11d603396e7295041fdb2..54c61296bcb805eb148be0e07dacd2b118b62d38 100644
--- a/www/plugins/es/js/entities/notification.js
+++ b/www/plugins/es/js/entities/notification.js
@@ -8,7 +8,7 @@ function Notification(json, markAsReadCallback) {
 
   var that = this;
 
-  that.type = json.type.toLowerCase();
+  that.type = json.type && json.type.toLowerCase();
   that.time = json.time;
   that.hash = json.hash;
   that.read = json.read_signature ? true : false;
diff --git a/www/plugins/es/js/services/http-services.js b/www/plugins/es/js/services/http-services.js
index 6f6e4e8f6301fac80ca223aa4c4781d1f325acab..f2c6fd8052f335cf22d88b1b48193c8cf9316435 100644
--- a/www/plugins/es/js/services/http-services.js
+++ b/www/plugins/es/js/services/http-services.js
@@ -16,14 +16,13 @@ angular.module('cesium.es.http.services', ['ngResource', 'ngApi', 'cesium.servic
         USER_TAG: match('@(\\w+)')
       };
 
-    this.cache = _emptyCache();
+    that.cache = _emptyCache();
     that.alive = false;
     that.host = host;
     that.port = port || 80;
-    that.wsPort = wsPort || 80;
+    that.wsPort = wsPort || port || 80;
     that.useSsl = angular.isDefined(useSsl) ? useSsl : false;
     that.server = csHttp.getServer(host, port);
-    that.date = {};
     that.api = new Api(this, "esHttp");
 
     function exact(regexpContent) {
@@ -42,11 +41,11 @@ angular.module('cesium.es.http.services', ['ngResource', 'ngApi', 'cesium.servic
     }
 
     that.cleanCache = function() {
+      console.debug('[ES] [http] Cleaning requests cache...');
       _.keys(that.cache.wsByPath).forEach(function(key) {
         var sock = that.cache.wsByPath[key];
         sock.close();
       });
-      console.debug('[ES] [http] Cleaning requests cache');
       that.cache = _emptyCache();
     };
 
@@ -60,10 +59,7 @@ angular.module('cesium.es.http.services', ['ngResource', 'ngApi', 'cesium.servic
     };
 
     // Get time (UTC)
-    that.date.now = function() {
-       // TODO : use the block chain time
-       return Math.floor(moment().utc().valueOf() / 1000);
-    };
+    that.date = { now : csHttp.date.now };
 
     that.getUrl  = function(path) {
       return csHttp.getUrl(that.host, that.port, path, that.useSsl);
@@ -131,7 +127,7 @@ angular.module('cesium.es.http.services', ['ngResource', 'ngApi', 'cesium.servic
     };
 
     that.stop = function() {
-      console.debug('[ES] [http] Stopped');
+      console.debug('[ES] [http] Stopping...');
       that.alive = false;
       that.cleanCache();
       that.api.node.raise.stop();
@@ -429,7 +425,7 @@ angular.module('cesium.es.http.services', ['ngResource', 'ngApi', 'cesium.servic
 
   var host = csSettings.data.plugins && csSettings.data.plugins.es ? csSettings.data.plugins.es.host : null;
   var port = host ? csSettings.data.plugins.es.port : null;
-  var wsPort = host ? csSettings.data.plugins.es.wsPort : port;
+  var wsPort = host ? csSettings.data.plugins.es.wsPort : null;
 
   var service = new Factory(host, port, wsPort);
 
diff --git a/www/plugins/es/js/services/message-services.js b/www/plugins/es/js/services/message-services.js
index 9a8afcf20042c20621b4d722edefe69a959fbd2f..937ef5ac67f76e8c5b0312da13c1bd599f1d1fd6 100644
--- a/www/plugins/es/js/services/message-services.js
+++ b/www/plugins/es/js/services/message-services.js
@@ -459,24 +459,27 @@ angular.module('cesium.es.message.services', ['ngResource', 'cesium.services', '
     }
 
     function addListeners() {
-      console.debug("[ES] [message] Enable");
-
       // Extend csWallet.loadData()
       listeners = [
         csWallet.api.data.on.login($rootScope, onWalletLogin, this),
         csWallet.api.data.on.init($rootScope, onWalletInit, this),
-        csWallet.api.data.on.reset($rootScope, onWalletReset, this),
+        csWallet.api.data.on.reset($rootScope, onWalletReset, this)
       ];
     }
 
-    function refreshListeners() {
+    function refreshState() {
       var enable = esHttp.alive;
       if (!enable && listeners && listeners.length > 0) {
+        console.debug("[ES] [message] Disable");
         removeListeners();
+        if (csWallet.isLogin()) {
+          onWalletReset(csWallet.data);
+        }
       }
       else if (enable && (!listeners || listeners.length === 0)) {
+        console.debug("[ES] [message] Enable");
         addListeners();
-        if (csWallet.isLogin() && !csWallet.data.messages) {
+        if (csWallet.isLogin()) {
           onWalletLogin(csWallet.data);
         }
       }
@@ -484,9 +487,9 @@ angular.module('cesium.es.message.services', ['ngResource', 'cesium.services', '
 
     // Default action
     Device.ready().then(function() {
-      refreshListeners();
-      esHttp.api.node.on.start($rootScope, refreshListeners, this);
-      esHttp.api.node.on.stop($rootScope, refreshListeners, this);
+      esHttp.api.node.on.start($rootScope, refreshState, this);
+      esHttp.api.node.on.stop($rootScope, refreshState, this);
+      return refreshState();
     });
 
     return {
diff --git a/www/plugins/es/js/services/notification-services.js b/www/plugins/es/js/services/notification-services.js
index 9d3469a6af53c0f9db2e7ae10194fa99c6f552bd..2180ba00a6d64afc4a7c78901ead3434ac9920b3 100644
--- a/www/plugins/es/js/services/notification-services.js
+++ b/www/plugins/es/js/services/notification-services.js
@@ -159,7 +159,7 @@ angular.module('cesium.es.notification.services', ['cesium.services', 'cesium.es
       notification.read = true;
       CryptoUtils.sign(notification.hash, csWallet.data.keypair)
         .then(function(signature){
-          return postReadById(signature, {id:notification.id});
+          return that.raw.postReadById(signature, {id:notification.id});
         })
         .catch(function(err) {
           console.error('Error while trying to mark event as read:' + (err.message ? err.message : err));
@@ -242,10 +242,13 @@ angular.module('cesium.es.notification.services', ['cesium.services', 'cesium.es
       ];
     }
 
-    function refreshListeners() {
+    function refreshState() {
       var enable = esHttp.alive;
       if (!enable && listeners && listeners.length > 0) {
         removeListeners();
+        if (csWallet.isLogin()) {
+          onWalletReset(csWallet.data);
+        }
       }
       else if (enable && (!listeners || listeners.length === 0)) {
         addListeners();
@@ -260,9 +263,9 @@ angular.module('cesium.es.notification.services', ['cesium.services', 'cesium.es
 
     // Default actions
     Device.ready().then(function() {
-      esHttp.api.node.on.start($rootScope, refreshListeners, this);
-      esHttp.api.node.on.stop($rootScope, refreshListeners, this);
-      return refreshListeners();
+      esHttp.api.node.on.start($rootScope, refreshState, this);
+      esHttp.api.node.on.stop($rootScope, refreshState, this);
+      return refreshState();
     });
 
     return {
diff --git a/www/plugins/es/js/services/settings-services.js b/www/plugins/es/js/services/settings-services.js
index b835fa1e2275ca031e1bf0931e19574348f52fa8..c0c2dc81512c108699d517b2abf72103df501681 100644
--- a/www/plugins/es/js/services/settings-services.js
+++ b/www/plugins/es/js/services/settings-services.js
@@ -29,6 +29,19 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt
           excludes: ['installDocUrl']
         }
       },
+      defaultSettings = angular.merge({
+          plugins: {
+            es: {
+              askEnable: false,
+              notifications: {
+                txSent: true,
+                txReceived: true,
+                certSent: true,
+                certReceived: true
+              }
+            }
+          }
+      }, {plugins: {es: csConfig.plugins && csConfig.plugins.es || {}}}),
       that = this,
       previousRemoteData,
       listeners,
@@ -118,6 +131,13 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt
         });
     }
 
+    function onSettingsReset(data, deferred) {
+      deferred = deferred || $q.defer();
+      angular.merge(data, defaultSettings);
+      deferred.resolve(data);
+      return deferred.promise;
+    }
+
     function onWalletLogin(data, deferred) {
       deferred = deferred || $q.defer();
       if (!data || !data.pubkey || !data.keypair) {
@@ -164,7 +184,7 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt
 
       var wasEnable = listeners && listeners.length > 0;
 
-      refreshListeners();
+      refreshState();
 
       var isEnable = that.isEnable();
       if (csWallet.isLogin()) {
@@ -250,7 +270,6 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt
     }
 
     function removeListeners() {
-      console.debug("[ES] [settings] Disable");
       _.forEach(listeners, function(remove){
         remove();
       });
@@ -258,29 +277,33 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt
     }
 
     function addListeners() {
-      console.debug("[ES] [settings] Enable");
-
       // Extend csWallet.login()
       listeners = [
-        csWallet.api.data.on.login($rootScope, onWalletLogin, this),
-
+        csSettings.api.data.on.reset($rootScope, onSettingsReset, this),
+        csWallet.api.data.on.login($rootScope, onWalletLogin, this)
       ];
     }
 
-    function refreshListeners() {
+    function refreshState() {
       var enable = that.isEnable();
+
+      // Disable
       if (!enable && listeners && listeners.length > 0) {
+        console.debug("[ES] [settings] Disable");
         removeListeners();
         return esHttp.stop();
       }
+
+      // Enable
       else if (enable && (!listeners || listeners.length === 0)) {
         return esHttp.start()
           .then(function(started) {
             if (!started) {
               // TODO : alert user ?
-              console.error('ES node could not be started !!');
+              console.error('[ES] node could not be started !!');
             }
             else {
+              console.debug("[ES] [settings] Enable");
               addListeners();
               if (csWallet.isLogin()) {
                 return onWalletLogin(csWallet.data);
@@ -296,7 +319,7 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt
       esHttp.api.node.on.stop($rootScope, function() {
         previousRemoteData = null;
       }, this);
-      return refreshListeners();
+      return refreshState();
     })
 
     .then(function() {