From 978431f524b1b9548031dac69f8f09ed461cb378 Mon Sep 17 00:00:00 2001
From: blavenie <benoit.lavenier@e-is.pro>
Date: Fri, 19 Aug 2016 20:02:31 +0200
Subject: [PATCH] - Simplify configuration syntax - New Settings service - new
 csNetwork service, to manage network and peers access - TX in protocole v0.3

---
 app/config.json                               |  62 ++--
 ...o.large.blue.sand-dune-250\303\227250.png" | Bin 30885 -> 0 bytes
 gulpfile.js                                   |   8 +-
 package.json                                  |  19 +
 www/i18n/locale-en.json                       |   6 +-
 www/i18n/locale-fr-FR.json                    |  10 +-
 www/index.html                                |   2 +
 www/js/app.js                                 |   8 +-
 www/js/config.js                              |  29 +-
 www/js/controllers/app-controllers.js         |  16 +-
 www/js/controllers/currency-controllers.js    | 154 ++-------
 www/js/controllers/login-controllers.js       |   4 +-
 www/js/controllers/peer-controllers.js        |  11 +-
 www/js/controllers/settings-controllers.js    |  40 ++-
 www/js/controllers/transfer-controllers.js    |   9 +-
 www/js/controllers/wallet-controllers.js      |  20 +-
 www/js/controllers/wot-controllers.js         |   7 +-
 www/js/services.js                            |   2 +
 www/js/services/bma-services.js               |  91 +++--
 www/js/services/http-services.js              |   4 +-
 www/js/services/network-services.js           | 148 ++++++++
 www/js/services/settings-services.js          |  96 ++++++
 www/js/services/utils-services.js             |   2 +-
 www/js/services/wallet-services.js            | 326 ++++++++----------
 www/js/services/wot-services.js               |  13 +-
 .../es/js/controllers/common-controllers.js   |   8 +-
 .../es/js/controllers/settings-controllers.js |  14 +-
 www/plugins/es/js/services/http-services.js   |   4 +-
 www/plugins/es/js/services/user-services.js   |   4 +-
 www/templates/currency/tabs/view_network.html |   4 +-
 www/templates/currency/view_currency.html     |  21 +-
 www/templates/currency/view_currency_lg.html  |   2 -
 www/templates/settings/settings.html          |   2 +-
 www/templates/wallet/view_wallet.html         |  20 +-
 .../wallet/view_wallet_tx_error.html          |  16 +-
 www/templates/wot/view_certifications.html    |   4 +-
 36 files changed, 675 insertions(+), 511 deletions(-)
 delete mode 100644 "cesium-logo.large.blue.sand-dune-250\303\227250.png"
 create mode 100644 www/js/services/network-services.js
 create mode 100644 www/js/services/settings-services.js

diff --git a/app/config.json b/app/config.json
index 0ff11f63..25bd48bc 100644
--- a/app/config.json
+++ b/app/config.json
@@ -1,37 +1,43 @@
 {
   "default": {
-    "APP_CONFIG": {
-      "DUNITER_NODE": "test-net.duniter.fr:9201",
-      "DUNITER_NODE_ES": "test-net.duniter.fr:9203",
-      "NEW_ISSUE_LINK": "https://github.com/duniter/cesium/issues/new?labels=bug",
-      "TIMEOUT": 4000,
-      "DEBUG": false
-    }
-  },
-
-  "simple": {
-    "APP_CONFIG": {
-      "DUNITER_NODE": "test-net.duniter.fr:9201",
-      "NEW_ISSUE_LINK": "https://github.com/duniter/cesium/issues/new?labels=bug",
-      "TIMEOUT": 6000,
-      "DEBUG": false
+    "timeout": 4000,
+    "useRelative": true,
+    "timeWarningExpireMembership": 5184000,
+    "timeWarningExpire": 7776000,
+    "useLocalStorage": false,
+    "rememberMe": false,
+    "showUDHistory": false,
+    "node": {
+      "host": "test-net.duniter.fr",
+      "port": "9201"
+    },
+    "plugins":{
+      "es": {
+        "enable": "false",
+        "host": "test-net.duniter.fr",
+        "port": "9203"
+      }
     }
   },
 
   "dev": {
-    "APP_CONFIG": {
-      "DUNITER_NODE": "localhost:9201",
-      "TIMEOUT": 6000,
-      "DEBUG": true
-    }
-  },
-
-  "dev-es": {
-    "APP_CONFIG": {
-      "DUNITER_NODE": "test-net.duniter.fr:9201",
-      "DUNITER_NODE_ES": "192.168.0.28:9200",
-      "TIMEOUT": 6000,
-      "DEBUG": true
+    "timeout": 6000,
+    "useRelative": true,
+    "timeWarningExpireMembership": 5184000,
+    "timeWarningExpire": 7776000,
+    "useLocalStorage": true,
+    "rememberMe": true,
+    "showUDHistory": false,
+    "node": {
+      "host": "test-net.duniter.fr",
+      "port": "9201"
+    },
+    "plugins":{
+      "es": {
+        "enable": "true",
+        "host": "test-net.duniter.fr",
+        "port": "9203"
+      }
     }
   }
 }
diff --git "a/cesium-logo.large.blue.sand-dune-250\303\227250.png" "b/cesium-logo.large.blue.sand-dune-250\303\227250.png"
deleted file mode 100644
index 68fe13e1b3916829585550000d6bc4f1f0dadb42..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 30885
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
b2=M;_E-t)@6aTf~00000NkvXXu0mjf<H7PQ

diff --git a/gulpfile.js b/gulpfile.js
index 6a22c5ea..9a839a42 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -117,14 +117,14 @@ gulp.task('config', function (done) {
   gutil.log(gutil.colors.green("Building `www/js/config.js` for `" + env + "` environment..."));
 
   var version = JSON.parse(fs.readFileSync('./package.json', 'utf8')).version;
-  config['APP_CONFIG']['VERSION'] = version;
-  config['APP_CONFIG']['BUILD_DATE'] = (new Date()).toJSON();
+  config['version'] = version;
+  config['build'] = (new Date()).toJSON();
 
-  // TODO : change version config.xml file
+  // TODO : change version in config.xml file
 
   return ngConstant({
       name: 'cesium.config',
-      constants: config,
+      constants: {"csConfig": config},
       stream: true,
       dest: 'config.js'
     })
diff --git a/package.json b/package.json
index e9a56de3..cfd8a19e 100644
--- a/package.json
+++ b/package.json
@@ -2,6 +2,25 @@
   "name": "cesium",
   "version": "0.1.28",
   "description": "Unhosted webapp client for Duniter network",
+  "repository": {
+    "type": "git",
+    "url": "git@github.com:duniter/cesium.git"
+  },
+  "keywords": [
+    "duniter",
+    "cesium",
+    "ionic",
+    "angular",
+    "cordova",
+    "crypto-currency"
+  ],
+  "author": "Duniter team",
+  "license": "GPLv3",
+  "readmeFilename": "README.md",
+  "bugs": {
+    "url": "https://github.com/duniter/cesium/issues",
+    "new": "https://github.com/duniter/cesium/issues/new?labels=bug"
+  },
   "dependencies": {
     "delete-empty": "^0.1.3",
     "gulp": "^3.9.1",
diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json
index d1c23bdc..82d35fc4 100644
--- a/www/i18n/locale-en.json
+++ b/www/i18n/locale-en.json
@@ -224,6 +224,9 @@
     "PASSWORD_NOT_CONFIRMED": "Must match previous password.",
     "SEND_IDENTITY_FAILED": "Error while trying to register.",
     "SEND_CERTIFICATION_FAILED": "Could not certify identity.",
+    "NEED_MEMBER_ACCOUNT_TO_CERTIFY": "You could not send certification, because your account is <b>not</b> a member account.",
+    "NEED_MEMBER_ACCOUNT_TO_CERTIFY_HAS_SELF": "You could not send certification now, because your are a member yet.<br/>Be patient ! ;-)",
+    "NOT_MEMBER_FOR_CERTIFICATION": "Votre compte n'est pas encore membre.",
     "LOGIN_FAILED": "Error while sign in.",
     "LOAD_IDENTITY_FAILED": "Could not load identity.",
     "LOAD_REQUIREMENTS_FAILED": "Could not load identity requirements.",
@@ -252,7 +255,8 @@
     "INVALID_NODE_SUMMARY": "Unreachable node or invalid address",
     "INVALID_USER_ID": "Field 'pseudonym' must not contains spaces or special caracters.",
     "INVALID_COMMENT": "Field 'reference' has a bad format.",
-    "INVALID_PUBKEY": "Public key has a bad format."
+    "INVALID_PUBKEY": "Public key has a bad format.",
+    "IDENTITY_SANDBOX_FULL": "Duniter node could not received new identity, beacause it's sandbox is full.<br/><br/>Please retry later or change your node (in <b>Settings</b>)."
   },
   "INFO": {
     "POPUP_TITLE": "Information",
diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json
index 110ff1b7..fc48e267 100644
--- a/www/i18n/locale-fr-FR.json
+++ b/www/i18n/locale-fr-FR.json
@@ -222,8 +222,11 @@
     "FIELD_TOO_LONG": "Valeur trop longue",
     "FIELD_ACCENT": "Caractères accentués et virgules non autorisés",
     "PASSWORD_NOT_CONFIRMED": "Ne correspond pas au mot de passe.",
-    "SEND_IDENTITY_FAILED": "Erreur pendant l'inscription.",
-    "SEND_CERTIFICATION_FAILED": "Erreur lors de la certification de l'identité.",
+    "SEND_IDENTITY_FAILED": "Echec de l'inscription.",
+    "SEND_CERTIFICATION_FAILED": "Echec de la certification.",
+    "NEED_MEMBER_ACCOUNT_TO_CERTIFY": "Vous ne pouvez pas effectuer de certification, car votre compte n'est <b>pas membre</b>.",
+    "NEED_MEMBER_ACCOUNT_TO_CERTIFY_HAS_SELF": "Vous ne pouvez pas certifier quelqu'un, car vous n'etes pas encore devenu membre.<br/>Patience ! ;-)",
+    "NOT_MEMBER_FOR_CERTIFICATION": "Votre compte n'est pas encore membre.",
     "LOGIN_FAILED": "Erreur lors de l'authentification.",
     "LOAD_IDENTITY_FAILED": "Erreur de chargement de l'identité.",
     "LOAD_REQUIREMENTS_FAILED": "Erreur de chargement des prérequis de l'ientité.",
@@ -252,7 +255,8 @@
     "INVALID_NODE_SUMMARY": "Noeud injoignable ou adresse invalide.",
     "INVALID_USER_ID": "Le champ 'pseudonyme' ne doit contenir ni espace ni caractère spécial ou accentué.",
     "INVALID_COMMENT": "Le champ 'référence' ne doit pas contenir de caractères accentués.",
-    "INVALID_PUBKEY": "La clé publique n'a pas le format attendu."
+    "INVALID_PUBKEY": "La clé publique n'a pas le format attendu.",
+    "IDENTITY_SANDBOX_FULL": "Le noeud Duniter utilisé par Cesium ne peut plus recevoir de nouvelles identités, car sa file d'attente est pleine.<br/><br/>Veuillez réessayer ultérieurement ou changer de noeud (via le menu <b>Paramètres</b>)."
   },
   "INFO": {
     "POPUP_TITLE": "Information",
diff --git a/www/index.html b/www/index.html
index 752c2b4e..bae90aeb 100644
--- a/www/index.html
+++ b/www/index.html
@@ -51,6 +51,8 @@
     <!-- endbuild -->
     <!-- build:js dist_js/cesium.js -->
       <!-- services -->
+      <script src="dist/dist_js/app/services/settings-services.js"></script>
+      <script src="dist/dist_js/app/services/network-services.js"></script>
       <script src="dist/dist_js/app/services/crypto-services.js"></script>
       <script src="dist/dist_js/app/services/utils-services.js"></script>
       <script src="dist/dist_js/app/services/modal-services.js"></script>
diff --git a/www/js/app.js b/www/js/app.js
index fe544df6..9c9922cb 100644
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -119,10 +119,10 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'ngAnimate',
     .useLoaderCache(true);
   })
 
-  .config(function($httpProvider, APP_CONFIG) {
+  .config(function($httpProvider, csConfig) {
     'ngInject';
     // Set default timeout
-    $httpProvider.defaults.timeout = !!APP_CONFIG.TIMEOUT ? APP_CONFIG.TIMEOUT : 4000 /* default timeout */;
+    $httpProvider.defaults.timeout = !!csConfig.TIMEOUT ? csConfig.TIMEOUT : 4000 /* default timeout */;
 
     //Enable cross domain calls
     $httpProvider.defaults.useXDomain = true;
@@ -131,10 +131,10 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'ngAnimate',
     delete $httpProvider.defaults.headers.common['X-Requested-With'];
   })
 
-  .config(function($compileProvider, APP_CONFIG) {
+  .config(function($compileProvider, csConfig) {
     'ngInject';
 
-    $compileProvider.debugInfoEnabled(!!APP_CONFIG.DEBUG);
+    $compileProvider.debugInfoEnabled(!!csConfig.DEBUG);
   })
 
   .config(function($animateProvider) {
diff --git a/www/js/config.js b/www/js/config.js
index cc193730..29394a2c 100644
--- a/www/js/config.js
+++ b/www/js/config.js
@@ -8,14 +8,27 @@
 
 angular.module("cesium.config", [])
 
-.constant("APP_CONFIG", {
-	"DUNITER_NODE": "test-net.duniter.fr:9201",
-	"DUNITER_NODE_ES": "test-net.duniter.fr:9203",
-	"NEW_ISSUE_LINK": "https://github.com/duniter/cesium/issues/new?labels=bug",
-	"TIMEOUT": 4000,
-	"DEBUG": false,
-	"VERSION": "0.1.28",
-	"BUILD_DATE": "2016-08-18T22:15:59.099Z"
+.constant("csConfig", {
+	"timeout": 6000,
+	"useRelative": true,
+	"timeWarningExpireMembership": 5184000,
+	"timeWarningExpire": 7776000,
+	"useLocalStorage": true,
+	"rememberMe": true,
+	"showUDHistory": false,
+	"node": {
+		"host": "test-net.duniter.fr",
+		"port": "9201"
+	},
+	"plugins": {
+		"es": {
+			"enable": "true",
+			"host": "test-net.duniter.fr",
+			"port": "9203"
+		}
+	},
+	"version": "0.1.28",
+	"build": "2016-08-19T10:52:06.309Z"
 })
 
 ;
\ No newline at end of file
diff --git a/www/js/controllers/app-controllers.js b/www/js/controllers/app-controllers.js
index a4da9715..ed46950a 100644
--- a/www/js/controllers/app-controllers.js
+++ b/www/js/controllers/app-controllers.js
@@ -53,17 +53,19 @@ function PluginExtensionPointController($scope, PluginService) {
 /**
  * Abstract controller (inherited by other controllers)
  */
-function AppController($scope, $rootScope, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout,
-  CryptoUtils, BMA, Wallet, APP_CONFIG, $ionicHistory, Device, $ionicPopover, $translate, $filter,
-  Modals
+function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout,
+  BMA, Wallet, csConfig, $ionicHistory, Device, Modals, csSettings
   ) {
   'ngInject';
 
   $scope.search = { text: '', results: {} };
-  $scope.config = APP_CONFIG;
+  $scope.config = csConfig;
   if (!$rootScope.walletData) {
     $rootScope.walletData = Wallet.data;
   }
+  if (!$rootScope.settings) {
+    $rootScope.settings = csSettings.data;
+  }
 
   ////////////////////////////////////////
   // Load currencies
@@ -195,9 +197,9 @@ function AppController($scope, $rootScope, $ionicModal, $state, $ionicSideMenuDe
     return Modals.showLogin()
     .then(function(formData){
       if (!formData) return;
-      Wallet.data.settings.rememberMe = formData.rememberMe;
-      if (Wallet.data.settings.rememberMe) {
-        Wallet.data.settings.useLocalStorage = true;
+      var rememberMeChanged = (csSettings.data.rememberMe !== formData.rememberMe);
+      if (rememberMeChanged) {
+        csSettings.data.useLocalStorage = csSettings.data.rememberMe ? true : csSettings.data.useLocalStorage;
         Wallet.store();
       }
       return Wallet.login(formData.username, formData.password);
diff --git a/www/js/controllers/currency-controllers.js b/www/js/controllers/currency-controllers.js
index 6c1880f1..18a33685 100644
--- a/www/js/controllers/currency-controllers.js
+++ b/www/js/controllers/currency-controllers.js
@@ -59,14 +59,14 @@ angular.module('cesium.currency.controllers', ['cesium.services'])
 
 ;
 
-function CurrencyLookupController($scope, $state, $q, $timeout, UIUtils, APP_CONFIG, BMA) {
+function CurrencyLookupController($scope, $state, UIUtils) {
   'ngInject';
 
   $scope.selectedCurrency = '';
   $scope.knownCurrencies = [];
   $scope.search.looking = true;
 
-  $scope.$on('$ionicView.enter', function(e, $state) {
+  $scope.$on('$ionicView.enter', function() {
     $scope.loadCurrencies()
     .then(function (res) {
       $scope.knownCurrencies = res;
@@ -91,15 +91,13 @@ function CurrencyLookupController($scope, $state, $q, $timeout, UIUtils, APP_CON
   };
 }
 
-function CurrencyViewController($scope, $rootScope, $state, BMA, $q, UIUtils, $interval, $timeout, Wallet, $translate) {
-
-  PeersController.call(this, $scope, $rootScope, BMA, UIUtils, $q, $interval, $timeout);
+function CurrencyViewController($scope, $q, $translate, $timeout, BMA, UIUtils, csSettings, csNetwork) {
 
-  $scope.search = {};
+  $scope.loadingPeers = true;
+  $scope.peers = csNetwork.data.peers;
   $scope.formData = {
-    useRelative: Wallet.data.settings.useRelative
+    useRelative: csSettings.data.useRelative
   };
-  $scope.knownBlocks = [];
   $scope.node = null;
   $scope.loading = true;
 
@@ -158,11 +156,11 @@ function CurrencyViewController($scope, $rootScope, $state, BMA, $q, UIUtils, $i
     }
 
     $scope.node.websocket.block().on('block', function(block) {
-      var theFPR = fpr(block);
-      if ($scope.knownBlocks.indexOf(theFPR) === -1) {
-        $scope.knownBlocks.push(theFPR);
+      var buid = csNetwork.buid(block);
+      if (csNetwork.data.knownBlocks.indexOf(buid) === -1) {
+        csNetwork.data.knownBlocks.push(buid);
         // We wait 2s when a new block is received, just to wait for network propagation
-        var wait = $scope.knownBlocks.length === 1 ? 0 : 2000;
+        var wait = csNetwork.data.knownBlocks.length === 1 ? 0 : 2000;
         $timeout(function() {
           $scope.refresh();
         }, wait);
@@ -266,128 +264,16 @@ function CurrencyViewController($scope, $rootScope, $state, BMA, $q, UIUtils, $i
     })
     .then(function(){
       // Network
-      $scope.searchPeers();
-    });
-  };
-}
-
-
-function PeersController($scope, $rootScope, BMA, UIUtils, $q, $interval, $timeout) {
-
-  var newPeers = [], interval, lookingForPeers;
-  $scope.search.lookingForPeers = false;
-  $scope.search.peers = [];
-
-  $scope.overviewPeers = function() {
-    var currents = {}, block;
-    for (var i = 0, len = $scope.search.peers.length; i < len; i++) {
-      block = $scope.search.peers[i].current;
-      if (block) {
-        var bid = fpr(block);
-        currents[bid] = currents[bid] || 0;
-        currents[bid]++;
-      }
-    }
-    var fprs = _.keys(currents).map(function(key) {
-      return { fpr: key, qty: currents[key] };
-    });
-    var best = _.max(fprs, function(obj) {
-      return obj.qty;
-    });
-    var p;
-    for (var j = 0, len2 = $scope.search.peers.length; j < len2; j++) {
-      p = $scope.search.peers[j];
-      p.hasMainConsensusBlock = fpr(p.current) == best.fpr;
-      p.hasConsensusBlock = !p.hasMainConsensusBlock && currents[fpr(p.current)] > 1;
-    }
-    $scope.search.peers = _.uniq($scope.search.peers, false, function(peer) {
-      return peer.pubkey;
-    });
-    $scope.search.peers = _.sortBy($scope.search.peers, function(p) {
-      var score = 1;
-      score += (10000 * (p.online ? 1 : 0));
-      score += (1000  * (p.hasMainConsensusBlock ? 1 : 0));
-      score += (100   * (p.uid ? 1 : 0));
-      return -score;
+      $scope.loadingPeers = true;
+      csNetwork.getPeers()
+        .then(function(peers) {
+          $scope.peers = peers;
+          $scope.loadingPeers = false;
+        })
+        .catch(function(err) {
+          $scope.peers = [];
+          $scope.loadingPeers = false;
+        })
     });
   };
-
-  $scope.searchPeers = function() {
-
-    if (interval) {
-      $interval.cancel(interval);
-    }
-
-    interval = $interval(function() {
-      if (newPeers.length) {
-        $scope.search.peers = $scope.search.peers.concat(newPeers.splice(0));
-        $scope.overviewPeers();
-      } else if (lookingForPeers && !$scope.search.lookingForPeers) {
-        // The peer lookup endend, we can make a clean final report
-        $timeout(function(){
-          lookingForPeers = false;
-          $scope.overviewPeers();
-        }, 1000);
-      }
-    }, 1000);
-
-    var known = {};
-    $rootScope.memberUidsByPubkeys = {};
-    $scope.search.peers = [];
-    $scope.search.lookingForPeers = true;
-    lookingForPeers = true;
-    return BMA.network.peering.peers({ leaves: true })
-      .then(function(res){
-        return BMA.wot.member.uids(true/*cache*/)
-          .then(function(uids){
-            $rootScope.memberUidsByPubkeys = uids;
-            return res;
-          });
-      })
-      .then(function(res){
-        return $q.all(res.leaves.map(function(leaf) {
-          return BMA.network.peering.peers({ leaf: leaf })
-            .then(function(subres){
-              var peer = subres.leaf.value;
-              if (peer) {
-                peer = new Peer(peer);
-                // Test each peer only once
-                if (!known[peer.getURL()]) {
-                  peer.dns = peer.getDns();
-                  peer.blockNumber = peer.block.replace(/-.+$/, '');
-                  peer.uid = $rootScope.memberUidsByPubkeys[peer.pubkey];
-                  newPeers.push(peer);
-                  var node = BMA.instance(peer.getURL());
-                  return node.blockchain.current()
-                    .then(function(block){
-                      peer.current = block;
-                      peer.online = true;
-                      peer.server = peer.getURL();
-                      if ($scope.knownBlocks.indexOf(fpr(block)) === -1) {
-                        $scope.knownBlocks.push(fpr(block));
-                      }
-                    })
-                    .catch(function(err) {
-                    });
-                }
-              }
-            });
-        }))
-        .then(function(){
-          $scope.search.lookingForPeers = false;
-        });
-      })
-      .catch(function(err) {
-        //console.log(err);
-        $scope.search.lookingForPeers = false;
-      });
-  };
-
-  $scope.viewPeer = function() {
-
-  };
-}
-
-function fpr(block) {
-  return block && [block.number, block.hash].join('-');
 }
diff --git a/www/js/controllers/login-controllers.js b/www/js/controllers/login-controllers.js
index e7c8357f..dc4c03fe 100644
--- a/www/js/controllers/login-controllers.js
+++ b/www/js/controllers/login-controllers.js
@@ -4,13 +4,13 @@ angular.module('cesium.login.controllers', ['cesium.services'])
   .controller('LoginModalCtrl', LoginModalController)
 ;
 
-function LoginModalController($scope, $rootScope, $ionicModal, Wallet, CryptoUtils, UIUtils, $q, $state, $timeout, $ionicSideMenuDelegate, $ionicHistory, Modals) {
+function LoginModalController($scope, $timeout, CryptoUtils, UIUtils, Modals, csSettings) {
   'ngInject';
 
   $scope.computing = false;
   $scope.pubkey = null;
   $scope.formData = {
-    rememberMe: Wallet.data.settings.rememberMe
+    rememberMe: csSettings.data.rememberMe
   };
 
   // Login form submit
diff --git a/www/js/controllers/peer-controllers.js b/www/js/controllers/peer-controllers.js
index ee129522..fd423f2b 100644
--- a/www/js/controllers/peer-controllers.js
+++ b/www/js/controllers/peer-controllers.js
@@ -3,7 +3,16 @@ function PeerController($scope, $rootScope, $ionicSlideBoxDelegate, $ionicModal,
   'ngInject';
 
   $scope.$on('$ionicView.enter', function(e, $state) {
-    $scope.showPeer($state.stateParams.server);
+    if (!$rootScope.memberUidsByPubkeys) {
+      BMA.wot.member.uids(true/*cache*/)
+      .then(function(uids){
+        $rootScope.memberUidsByPubkeys = uids;
+        $scope.showPeer($state.stateParams.server);
+      });
+    }
+    else {
+      $scope.showPeer($state.stateParams.server);
+    }
   });
 
   $scope.showPeer = function(server) {
diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js
index b01b86b5..5ddf4b8b 100644
--- a/www/js/controllers/settings-controllers.js
+++ b/www/js/controllers/settings-controllers.js
@@ -20,19 +20,19 @@ angular.module('cesium.settings.controllers', ['cesium.services', 'cesium.curren
   .controller('SettingsCtrl', SettingsController)
 ;
 
-function SettingsController($scope, $state, UIUtils, Wallet, $translate, BMA, $q, $ionicPopup, $timeout, localStorage) {
+function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, UIUtils, BMA, csSettings) {
   'ngInject';
 
-  $scope.formData = angular.copy(Wallet.defaultSettings);
+  $scope.formData = angular.copy(csSettings.data);
   $scope.loading = true;
 
   $scope.$on('$ionicView.enter', function(e, $state) {
     $scope.loading = true; // to avoid the call of Wallet.store()
     $scope.locales = UIUtils.locales;
     $scope.formData.locale = _.findWhere($scope.locales, {id: $translate.use()});
-    angular.merge($scope.formData, Wallet.data.settings);
-    if (Wallet.data.settings.locale && Wallet.data.settings.locale.id) {
-      $scope.formData.locale = _.findWhere($scope.locales, {id: Wallet.data.settings.locale.id});
+    angular.merge($scope.formData, csSettings.data);
+    if (csSettings.data.locale && csSettings.data.locale.id) {
+      $scope.formData.locale = _.findWhere($scope.locales, {id: csSettings.data.locale.id});
     }
     UIUtils.loading.hide();
     $scope.loading = false;
@@ -54,27 +54,26 @@ function SettingsController($scope, $state, UIUtils, Wallet, $translate, BMA, $q
 
   // Change node
   $scope.changeNode= function(node) {
-    if (!node) {
-      node = $scope.formData.node;
-    }
-    $scope.showNodePopup(node)
-    .then(function(node) {
-      if (node == $scope.formData.node) {
+    $scope.showNodePopup(node || $scope.formData.node)
+    .then(function(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(node);
+      var nodeBMA = BMA.instance(newNode.host, newNode.port);
       nodeBMA.node.summary() // ping the node
       .then(function() {
         UIUtils.loading.hide();
-        $scope.formData.node = node;
+        $scope.formData.node = newNode;
         BMA.copy(nodeBMA);
       })
       .catch(function(err){
          UIUtils.loading.hide();
          UIUtils.alert.error('ERROR.INVALID_NODE_SUMMARY')
          .then(function(){
-           $scope.changeNode(node); // loop
+           $scope.changeNode(newNode); // loop
          });
       });
     });
@@ -83,7 +82,7 @@ function SettingsController($scope, $state, UIUtils, Wallet, $translate, BMA, $q
   // Show node popup
   $scope.showNodePopup = function(node) {
     return $q(function(resolve, reject) {
-      $scope.formData.newNode = node;
+      $scope.formData.newNode = [node.host, node.port].join(':');
       if (!!$scope.settingsForm) {
         $scope.settingsForm.$setPristine();
       }
@@ -113,12 +112,15 @@ function SettingsController($scope, $state, UIUtils, Wallet, $translate, BMA, $q
             ]
           })
           .then(function(node) {
-            delete $scope.formData.newNode;
             if (!node) { // user cancel
               UIUtils.loading.hide();
               return;
             }
-            resolve(node);
+            var parts = node.split(':');
+            resolve({
+              host: parts[0],
+              port: parts[1] || 80
+            });
           });
         });
       });
@@ -127,8 +129,8 @@ function SettingsController($scope, $state, UIUtils, Wallet, $translate, BMA, $q
   $scope.onSettingsChanged = function() {
     if (!$scope.loading) {
       $scope.loading = true;
-      angular.merge(Wallet.data.settings, $scope.formData);
-      Wallet.store();
+      angular.merge(csSettings.data, $scope.formData);
+      csSettings.store();
       $scope.loading = false;
     }
   };
diff --git a/www/js/controllers/transfer-controllers.js b/www/js/controllers/transfer-controllers.js
index 62b265f2..151d343b 100644
--- a/www/js/controllers/transfer-controllers.js
+++ b/www/js/controllers/transfer-controllers.js
@@ -44,7 +44,7 @@ angular.module('cesium.transfer.controllers', ['cesium.services', 'cesium.curren
 function TransferController($scope, $rootScope, $state, BMA, Wallet, UIUtils, $timeout, Device, $ionicPopover, $translate, $filter, $q, Modals, $ionicHistory) {
   'ngInject';
 
-  TransferModalController.call(this, $scope, $rootScope, $state, BMA, Wallet, UIUtils, $timeout, Device, $ionicPopover, $translate, $filter, $q, Modals);
+  TransferModalController.call(this, $scope, $rootScope, $state, BMA, Wallet, UIUtils, $timeout, Device, $ionicPopover, $translate, $filter, $q, Modals, csSettings);
 
   $scope.$on('$ionicView.enter', function(e, $state) {
     if (!!$state.stateParams && !!$state.stateParams.pubkey) {
@@ -62,7 +62,7 @@ function TransferController($scope, $rootScope, $state, BMA, Wallet, UIUtils, $t
     $scope.loadWallet()
     .then(function(walletData) {
       $scope.walletData = walletData;
-      $scope.formData.useRelative = walletData.settings.useRelative;
+      $scope.formData.useRelative = csSettings.data.useRelative;
       $scope.onUseRelativeChanged();
       UIUtils.loading.hide();
     });
@@ -78,7 +78,8 @@ function TransferController($scope, $rootScope, $state, BMA, Wallet, UIUtils, $t
 
 }
 
-function TransferModalController($scope, $rootScope, $state, BMA, Wallet, UIUtils, $timeout, Device, $ionicPopover, $translate, $filter, $q, Modals, parameters) {
+function TransferModalController($scope, $rootScope, $ionicPopover, $translate, $filter, $q, BMA, Wallet, UIUtils, Modals,
+                                 csSettings, parameters) {
   'ngInject';
 
   $scope.walletData = $rootScope.walletData;
@@ -87,7 +88,7 @@ function TransferModalController($scope, $rootScope, $state, BMA, Wallet, UIUtil
     destPub: null,
     amount: null,
     comment: null,
-    useRelative: Wallet.defaultSettings.useRelative,
+    useRelative: csSettings.data.useRelative,
     useComment: false
   };
   $scope.udAmount = null;
diff --git a/www/js/controllers/wallet-controllers.js b/www/js/controllers/wallet-controllers.js
index c455fd6b..1396eb18 100644
--- a/www/js/controllers/wallet-controllers.js
+++ b/www/js/controllers/wallet-controllers.js
@@ -32,8 +32,8 @@ angular.module('cesium.wallet.controllers', ['cesium.services', 'cesium.currency
   .controller('WalletTxErrorCtrl', WalletTxErrorController)
 ;
 
-function WalletController($scope, $rootScope, $state, $q, $ionicPopup, $ionicActionSheet, $timeout,
-  UIUtils, Wallet, BMA, $translate, Device, $ionicPopover, Modals) {
+function WalletController($scope, $q, $ionicPopup, $timeout,
+  UIUtils, Wallet, BMA, $translate, $ionicPopover, Modals, csSettings) {
   'ngInject';
 
   $scope.walletData = null;
@@ -73,7 +73,7 @@ function WalletController($scope, $rootScope, $state, $q, $ionicPopup, $ionicAct
     if (!$scope.walletData) {
       return;
     }
-    if ($scope.walletData.settings.useRelative) {
+    if (csSettings.data.useRelative) {
       $scope.convertedBalance = $scope.walletData.balance ? ($scope.walletData.balance / $scope.walletData.currentUD) : 0;
     } else {
       var balance = $scope.walletData.balance;
@@ -83,7 +83,7 @@ function WalletController($scope, $rootScope, $state, $q, $ionicPopup, $ionicAct
       $scope.convertedBalance = balance;
     }
   };
-  $scope.$watch('walletData.settings.useRelative', $scope.refreshConvertedBalance, true);
+  csSettings.api.data.on.changed($scope, $scope.refreshConvertedBalance);
   $scope.$watch('walletData.balance', $scope.refreshConvertedBalance, true);
 
   // Update view
@@ -241,8 +241,10 @@ function WalletController($scope, $rootScope, $state, $q, $ionicPopup, $ionicAct
       })
       .catch(function(err){
          UIUtils.loading.hide();
-         UIUtils.alert.info(err);
-         $scope.self(); // loop
+         UIUtils.onError('ERROR.SEND_IDENTITY_FAILED')(err)
+         .then(function() {
+           $scope.self(); // loop
+         });
       });
     });
   };
@@ -251,9 +253,6 @@ function WalletController($scope, $rootScope, $state, $q, $ionicPopup, $ionicAct
   $scope.membershipIn= function() {
     var doMembershipIn = function(retryCount) {
       Wallet.membership.inside()
-      .then(function() {
-        $scope.doUpdate();
-      })
       .catch(function(err) {
         if (!retryCount || retryCount <= 2) {
           $timeout(function() {
@@ -295,9 +294,6 @@ function WalletController($scope, $rootScope, $state, $q, $ionicPopup, $ionicAct
   $scope.membershipOut = function() {
     UIUtils.loading.show();
     Wallet.membership.out()
-    .then(function() {
-      $scope.doUpdate();
-    })
     .catch(UIUtils.onError('ERROR.SEND_MEMBERSHIP_OUT_FAILED'));
   };
 
diff --git a/www/js/controllers/wot-controllers.js b/www/js/controllers/wot-controllers.js
index 1b6cd124..0acf6dc1 100644
--- a/www/js/controllers/wot-controllers.js
+++ b/www/js/controllers/wot-controllers.js
@@ -234,7 +234,7 @@ function WotCertificationsViewController($scope, $state, BMA, Wallet, UIUtils, $
     WotService.load(pubkey)
     .then(function(identity){
       $scope.formData = identity;
-      $scope.canCertify = Wallet.isLogin() && !Wallet.isUserPubkey(pubkey) && Wallet.data.isMember;
+      $scope.canCertify = $scope.formData.hasSelf && (!Wallet.isLogin() || (!Wallet.isUserPubkey(pubkey)));
       $scope.alreadyCertified = $scope.canCertify ? !!_.findWhere(identity.certifications, { uid: Wallet.data.uid, valid: true }) : false;
 
       $scope.loading = false;
@@ -254,6 +254,11 @@ function WotCertificationsViewController($scope, $state, BMA, Wallet, UIUtils, $
   $scope.certify = function() {
     $scope.loadWallet()
     .then(function(walletData) {
+      if (!walletData.isMember) {
+        UIUtils.alert.error(walletData.requirements.needSelf ?
+          'ERROR.NEED_MEMBER_ACCOUNT_TO_CERTIFY' : 'ERROR.NEED_MEMBER_ACCOUNT_TO_CERTIFY_HAS_SELF');
+        return;
+      }
       UIUtils.loading.hide();
       UIUtils.alert.confirm('CONFIRM.CERTIFY_RULES')
       .then(function(confirm){
diff --git a/www/js/services.js b/www/js/services.js
index 2f85d603..fa593fda 100644
--- a/www/js/services.js
+++ b/www/js/services.js
@@ -1,6 +1,8 @@
 angular.module('cesium.services', [
     'cesium.config',
+    'cesium.settings.services',
     'cesium.http.services',
+    'cesium.network.services',
     'cesium.bma.services',
     'cesium.crypto.services',
     'cesium.utils.services',
diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js
index 08867c85..9bc368d5 100644
--- a/www/js/services/bma-services.js
+++ b/www/js/services/bma-services.js
@@ -1,12 +1,11 @@
 //var Base58, Base64, scrypt_module_factory = null, nacl_factory = null;
 
-angular.module('cesium.bma.services', ['cesium.http.services', 'ngResource',
-    'cesium.config'])
+angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'cesium.settings.services'])
 
-.factory('BMA', function($q, APP_CONFIG, HttpUtils) {
+.factory('BMA', function($q, csSettings, HttpUtils, $rootScope) {
   'ngInject';
 
-  function BMA(server) {
+  function BMA(host, port) {
 
     var
     instance = this,
@@ -15,7 +14,8 @@ angular.module('cesium.bma.services', ['cesium.http.services', 'ngResource',
         UID_ALREADY_USED: 2003,
         NO_MATCHING_MEMBER: 2004,
         NO_IDTY_MATCHING_PUB_OR_UID: 2021,
-        MEMBERSHRIP_ALREADY_SEND: 2007
+        MEMBERSHIP_ALREADY_SEND: 2007,
+        IDENTITY_SANDBOX_FULL: 1007
       },
     regex = {
       USER_ID: "[A-Za-z0-9_-]+",
@@ -29,7 +29,13 @@ angular.module('cesium.bma.services', ['cesium.http.services', 'ngResource',
     constants = {
       CACHE_TIME_MS: 60000
     },
+    protocol = (port === 443 ? 'https' : 'http'),
+    server = protocol + '://' + host + (port ? ':' + port : ''),
     data = {
+      node: {
+        host: host,
+        port: port
+      },
       blockchain: {
         current: null
       },
@@ -57,7 +63,7 @@ angular.module('cesium.bma.services', ['cesium.http.services', 'ngResource',
 
 
     function getBlockchainCurrent(cache) {
-      var getBlockchainCurrentNoCache = HttpUtils.get('http://' + server + '/blockchain/current');
+      var getBlockchainCurrentNoCache = HttpUtils.get(server + '/blockchain/current');
       return $q(function(resolve, reject) {
         var now = new Date();
         if (cache && data.blockchain.current !== null &&
@@ -72,13 +78,14 @@ angular.module('cesium.bma.services', ['cesium.http.services', 'ngResource',
             timestamp: now.getTime()
           };
           resolve(block);
-        });
+        })
+        .catch(function(err){reject(err);});
       });
     }
 
 
     function getMembers(cache) {
-      var getMembersNoCache = HttpUtils.get('http://' + server + '/wot/members');
+      var getMembersNoCache = HttpUtils.get(server + '/wot/members');
       return $q(function(resolve, reject) {
         var now = new Date();
         if (cache && data.wot && data.wot.members && data.wot.members.length > 0 &&
@@ -146,8 +153,8 @@ angular.module('cesium.bma.services', ['cesium.http.services', 'ngResource',
     }
 
     function getBlockchainLastUd(cache) {
-      var getBlockchainWithUd = HttpUtils.get('http://' + server + '/blockchain/with/ud');
-      var getBlockchainBlock = HttpUtils.get('http://' + server + '/blockchain/block/:block');
+      var getBlockchainWithUd = HttpUtils.get(server + '/blockchain/with/ud');
+      var getBlockchainBlock = HttpUtils.get(server + '/blockchain/block/:block');
       return $q(function(resolve, reject) {
         var now = new Date();
         if (cache && data.blockchain && data.blockchain.lastUd && (now.getTime() - data.blockchain.lastUdTimestamp) <= constants.CACHE_TIME_MS){
@@ -216,7 +223,7 @@ angular.module('cesium.bma.services', ['cesium.http.services', 'ngResource',
 
           if (!currency){
             if (host) {
-              HttpUtils.get('http://' + host + '/blockchain/parameters')()
+              HttpUtils.get(host + '/blockchain/parameters')()
               .then(function(parameters){
                 resolve({
                   uid: uid,
@@ -242,7 +249,7 @@ angular.module('cesium.bma.services', ['cesium.http.services', 'ngResource',
             }
 
             // Check if currency are the same (between node and uri)
-            return HttpUtils.get('http://' + host + '/blockchain/parameters')()
+            return HttpUtils.get(host + '/blockchain/parameters')()
             .then(function(parameters){
               if (parameters.currency !== currency) {
                 throw {message: "Node's currency ["+parameters.currency+"] does not matched URI's currency ["+currency+"]."};
@@ -286,55 +293,57 @@ angular.module('cesium.bma.services', ['cesium.http.services', 'ngResource',
 
     return {
       node: {
-        summary: HttpUtils.get('http://' + server + '/node/summary'),
-        url: server
+        summary: HttpUtils.get(server + '/node/summary'),
+        url: server,
+        host: host,
+        port: port
       },
       wot: {
-        lookup: HttpUtils.get('http://' + server + '/wot/lookup/:search'),
+        lookup: HttpUtils.get(server + '/wot/lookup/:search'),
         member: {
           all: getMembers,
           uids: getMemberUidsByPubkey,
           get: getMemberByPubkey
         },
-        requirements: HttpUtils.get('http://' + server + '/wot/requirements/:pubkey'),
-        add: HttpUtils.post('http://' + server + '/wot/add'),
-        certify: HttpUtils.post('http://' + server + '/wot/certify')
+        requirements: HttpUtils.get(server + '/wot/requirements/:pubkey'),
+        add: HttpUtils.post(server + '/wot/add'),
+        certify: HttpUtils.post(server + '/wot/certify')
       },
       network: {
         peering: {
-          peers: HttpUtils.get('http://' + server + '/network/peering/peers')
+          peers: HttpUtils.get(server + '/network/peering/peers')
         },
-        peers: HttpUtils.get('http://' + server + '/network/peers')
+        peers: HttpUtils.get(server + '/network/peers')
       },
       blockchain: {
-        parameters: HttpUtils.get('http://' + server + '/blockchain/parameters'),
+        parameters: HttpUtils.get(server + '/blockchain/parameters'),
         current: getBlockchainCurrent,
-        block: HttpUtils.get('http://' + server + '/blockchain/block/:block'),
-        membership: HttpUtils.post('http://' + server + '/blockchain/membership'),
+        block: HttpUtils.get(server + '/blockchain/block/:block'),
+        membership: HttpUtils.post(server + '/blockchain/membership'),
         stats: {
-          ud: HttpUtils.get('http://' + server + '/blockchain/with/ud'),
-          tx: HttpUtils.get('http://' + server + '/blockchain/with/tx')
+          ud: HttpUtils.get(server + '/blockchain/with/ud'),
+          tx: HttpUtils.get(server + '/blockchain/with/tx')
         },
         lastUd: getBlockchainLastUd
       },
       tx: {
-        sources: HttpUtils.get('http://' + server + '/tx/sources/:pubkey'),
-        process: HttpUtils.post('http://' + server + '/tx/process'),
+        sources: HttpUtils.get(server + '/tx/sources/:pubkey'),
+        process: HttpUtils.post(server + '/tx/process'),
         history: {
-          all: HttpUtils.get('http://' + server + '/tx/history/:pubkey'),
-          times: HttpUtils.get('http://' + server + '/tx/history/:pubkey/times/:from/:to'),
-          blocks: HttpUtils.get('http://' + server + '/tx/history/:pubkey/blocks/:from/:to')
+          all: HttpUtils.get(server + '/tx/history/:pubkey'),
+          times: HttpUtils.get(server + '/tx/history/:pubkey/times/:from/:to'),
+          blocks: HttpUtils.get(server + '/tx/history/:pubkey/blocks/:from/:to')
         }
       },
       ud: {
-        history: HttpUtils.get('http://' + server + '/ud/history/:pubkey')
+        history: HttpUtils.get(server + '/ud/history/:pubkey')
       },
       websocket: {
         block: function() {
-          return HttpUtils.ws('ws://' + server + '/ws/block');
+          return HttpUtils.ws('ws://' + host + ':' + port + '/ws/block');
         },
         peer: function() {
-          return HttpUtils.ws('ws://' + server + '/ws/peer');
+          return HttpUtils.ws('ws://' + host + ':' + port + '/ws/peer');
         },
         close : HttpUtils.closeAllWs
       },
@@ -361,8 +370,22 @@ angular.module('cesium.bma.services', ['cesium.http.services', 'ngResource',
     };
   }
 
-  var service = BMA(APP_CONFIG.DUNITER_NODE, APP_CONFIG.TIMEOUT);
+  var service = BMA(csSettings.data.node.host, csSettings.data.node.port);
   service.instance = BMA;
+
+  // Listen settings changes
+  csSettings.api.data.on.changed($rootScope, function(settings) {
+
+    var nodeChanged =
+      (settings.node.host && settings.node.host != service.node.host) ||
+      (settings.node.port && settings.node.port != service.node.port);
+
+    if (nodeChanged) {
+      service.copy(BMA(settings.node.host, settings.node.port)); // reload BMA
+    }
+
+  });
+
   return service;
 })
 ;
diff --git a/www/js/services/http-services.js b/www/js/services/http-services.js
index 0c91f95e..0fe2275c 100644
--- a/www/js/services/http-services.js
+++ b/www/js/services/http-services.js
@@ -1,6 +1,6 @@
 angular.module('cesium.http.services', ['ngResource'])
 
-.factory('HttpUtils', function($http, $q, APP_CONFIG) {
+.factory('HttpUtils', function($http, $q, csSettings) {
   'ngInject';
 
   function HttpUtils(timeout) {
@@ -165,7 +165,7 @@ angular.module('cesium.http.services', ['ngResource'])
     };
   }
 
-  var service = HttpUtils(APP_CONFIG.TIMEOUT);
+  var service = HttpUtils(csSettings.data.timeout);
   service.instance = HttpUtils;
   return service;
 })
diff --git a/www/js/services/network-services.js b/www/js/services/network-services.js
new file mode 100644
index 00000000..3c399d84
--- /dev/null
+++ b/www/js/services/network-services.js
@@ -0,0 +1,148 @@
+
+angular.module('cesium.network.services', ['ngResource', 'ngApi', 'cesium.bma.services'])
+
+.factory('csNetwork', function($rootScope, $q, $interval, $timeout, BMA, Api) {
+  'ngInject';
+
+  CSNetwork = function(id) {
+
+    var
+    data = {
+      peers: [],
+      newPeers: [],
+      knownBlocks: []
+    },
+    interval,
+    updatingPeers = false,
+    searchingPeersOnNetwork = false,
+    api = new Api(this, "csNetwork-" + id),
+
+    buid = function(block) {
+      return block && [block.number, block.hash].join('-');
+    },
+
+    processPeers = function() {
+      // Count peer by current block uid
+      var currents = {}, block;
+      _.forEach(data.peers, function(peer){
+        if (peer.buid) {
+          currents[peer.buid] = currents[peer.buid] || 0;
+          currents[peer.buid]++;
+        }
+      });
+      var buids = _.keys(currents).map(function(key) {
+        return { buid: key, count: currents[key] };
+      });
+      var mainBuid = _.max(buids, function(obj) {
+        return obj.count;
+      }).buid;
+      var p;
+      _.forEach(data.peers, function(peer){
+        peer.hasMainConsensusBlock = peer.buid == mainBuid;
+        peer.hasConsensusBlock = !peer.hasMainConsensusBlock && currents[peer.buid] > 1;
+      });
+      data.peers = _.uniq(data.peers, false, function(peer) {
+        return peer.pubkey;
+      });
+      data.peers = _.sortBy(data.peers, function(peer) {
+        var score = 1;
+        score += (10000000 * (peer.online ? 1 : 0));
+        score += (1000000  * (peer.hasMainConsensusBlock ? 1 : 0));
+        score += (100      * (peer.hasConsensusBlock ? currents[peer.buid] : 0));
+        score += (10       * (peer.uid ? 1 : 0));
+        return -score;
+      });
+    },
+
+    getPeers = function() {
+      return $q(function(resolve, reject){
+
+        if (interval) {
+          $interval.cancel(interval);
+        }
+
+        interval = $interval(function() {
+          if (data.newPeers.length) {
+            data.peers = data.peers.concat(data.newPeers.splice(0));
+            processPeers();
+          } else if (updatingPeers && !searchingPeersOnNetwork) {
+            // The peer lookup endend, we can make a clean final report
+            $timeout(function(){
+              updatingPeers = false;
+              processPeers();
+              resolve(data.peers);
+              $interval.cancel(interval);
+            }, 1000);
+          }
+        }, 1000);
+
+        var known = {};
+        data.peers = [];
+        searchingPeersOnNetwork = true;
+        updatingPeers = true;
+        var uidsByPubkeys;
+        return BMA.wot.member.uids(true/*cache*/)
+          .then(function(uids){
+            uidsByPubkeys = uids;
+            return BMA.network.peering.peers({ leaves: true })
+          })
+          .then(function(res){
+            return $q.all(res.leaves.map(function(leaf) {
+              return BMA.network.peering.peers({ leaf: leaf })
+                .then(function(subres){
+                  var peer = subres.leaf.value;
+                  if (peer) {
+                    peer = new Peer(peer);
+                    // Test each peer only once
+                    if (!known[peer.getURL()]) {
+                      peer.dns = peer.getDns();
+                      peer.blockNumber = peer.block.replace(/-.+$/, '');
+                      data.newPeers.push(peer);
+                      var node = BMA.instance(peer.getHost(), peer.getPort());
+                      return node.blockchain.current()
+                        .then(function(block){
+                          peer.current = block;
+                          peer.online = true;
+                          peer.server = peer.getURL();
+                          peer.buid = buid(block);
+                          peer.uid = uidsByPubkeys[peer.pubkey];
+                          if (data.knownBlocks.indexOf(peer.buid) === -1) {
+                            data.knownBlocks.push(peer.buid);
+                          }
+                        })
+                        .catch(function(err) {
+                          // nothing to do (node is DOWN ?)
+                        });
+                    }
+                  }
+                });
+            }))
+              .then(function(){
+                searchingPeersOnNetwork = false;
+              });
+          })
+          .catch(function(err) {
+            //console.log(err);
+            searchingPeersOnNetwork = false;
+          });
+      });
+    };
+
+    // Register extension points
+    //api.registerEvent('data', 'load');
+
+    return {
+      id: id,
+      buid: buid,
+      data: data,
+      getPeers: getPeers,
+      // api extension
+      api: api
+    };
+  };
+
+  var service = CSNetwork('default');
+
+  service.instance = CSNetwork;
+  return service;
+});
diff --git a/www/js/services/settings-services.js b/www/js/services/settings-services.js
new file mode 100644
index 00000000..56568ba6
--- /dev/null
+++ b/www/js/services/settings-services.js
@@ -0,0 +1,96 @@
+
+angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.config'])
+
+.factory('csSettings', function($q, csConfig, Api, localStorage, $translate) {
+  'ngInject';
+
+  CSSettings = function(id) {
+
+    var
+      constants = {
+        STORAGE_KEY: 'CESIUM_SETTINGS'
+      },
+
+      defaultSettings = angular.merge({
+        useRelative: true,
+        timeWarningExpireMembership: 2592000 * 2 /*=2 mois*/,
+        timeWarningExpire: 2592000 * 3 /*=3 mois*/,
+        useLocalStorage: false,
+        rememberMe: false,
+        showUDHistory: true,
+        locale: {
+          id: $translate.use()
+        }
+      }, csConfig),
+
+      data = angular.copy(defaultSettings),
+
+      api = new Api(this, "csSettings-" + id),
+
+      reset = function() {
+        angular.merge(data, defaultSettings);
+      },
+
+      store = function(options) {
+        if (data.useLocalStorage) {
+          localStorage.setObject(constants.STORAGE_KEY, data);
+        }
+        else {
+          localStorage.setObject(constants.STORAGE_KEY, null);
+        }
+
+        // Emit event on changed
+        api.data.raise.changed(data);
+
+      },
+
+      restore = function() {
+        return $q(function(resolve, reject){
+          var storedData = localStorage.getObject(constants.STORAGE_KEY);
+          if (!storedData) {
+            resolve();
+            return;
+          }
+
+          var localeChanged = storedData.locale && storedData.locale.id && (data.locale.id !== storedData.locale.id);
+          angular.merge(data, storedData);
+
+          // Always force the usage of deffault settings
+          // This is a workaround for DEV (TODO: implement edition in settings)
+          data.timeWarningExpire = defaultSettings.timeWarningExpire;
+          data.timeWarningExpireMembership = defaultSettings.timeWarningExpireMembership;
+          delete data.DUNITER_NODE;
+          delete data.DUNITER_NODE_ES;
+
+          if (localeChanged) {
+            $translate.use(data.locale.id);
+          }
+
+
+          // Emit event on changed
+          api.data.raisePromise.changed(data);
+          //resolve();
+        });
+      };
+
+    api.registerEvent('data', 'changed');
+
+    return {
+      id: id,
+      data: data,
+      reset: reset,
+      store: store,
+      restore: restore,
+      defaultSettings: defaultSettings,
+      // api extension
+      api: api
+    };
+  };
+
+  var service = CSSettings('default');
+
+  service.restore();
+
+  service.instance = CSSettings;
+  return service;
+});
diff --git a/www/js/services/utils-services.js b/www/js/services/utils-services.js
index b3897e57..6ce78ee2 100644
--- a/www/js/services/utils-services.js
+++ b/www/js/services/utils-services.js
@@ -146,7 +146,7 @@ angular.module('cesium.utils.services', ['ngResource'])
       else {
         console.error(err);
         hideLoading(10); // timeout, to avoid bug on transfer (when error on reference)
-        alertError(fullMsg, subtitle);
+        return alertError(fullMsg, subtitle);
       }
     };
   }
diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js
index 3f2859be..d76d5b57 100644
--- a/www/js/services/wallet-services.js
+++ b/www/js/services/wallet-services.js
@@ -1,27 +1,17 @@
 
-angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.services', 'cesium.crypto.services', 'cesium.utils.services'])
+angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.services', 'cesium.crypto.services', 'cesium.utils.services',
+  'cesium.settings.services'])
 
 
-.factory('Wallet', function($q, $rootScope, CryptoUtils, BMA, $translate, localStorage, $filter, Api, UIUtils) {
+.factory('Wallet', function($q, $rootScope, CryptoUtils, BMA, $translate, localStorage, $filter, Api, csSettings) {
   'ngInject';
 
   Wallet = function(id) {
 
     var
-    events = {
-      SETTINGS: 'wallet-settings-changed'
-    },
-
-    defaultSettings = {
-      useRelative: true,
-      timeWarningExpireMembership: 2592000 * 2 /*=2 mois*/,
-      timeWarningExpire: 2592000 * 3 /*=3 mois*/,
-      useLocalStorage: false,
-      rememberMe: false,
-      node: BMA.node.url,
-      showUDHistory: true
-    },
-
+    constants = {
+      STORAGE_KEY: "CESIUM_DATA"
+    }
     data = {
         pubkey: null,
         keypair: {
@@ -46,16 +36,6 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
         loaded: false,
         blockUid: null,
         avatar: null,
-        settings: {
-          useRelative: defaultSettings.useRelative,
-          timeWarningExpireMembership: defaultSettings.timeWarningExpireMembership,
-          timeWarningExpire: defaultSettings.timeWarningExpire,
-          locale: {id: $translate.use()},
-          useLocalStorage: defaultSettings.useLocalStorage,
-          rememberMe: defaultSettings.rememberMe,
-          node: defaultSettings.node,
-          showUDHistory: defaultSettings.showUDHistory
-        }
     },
 
     api = new Api(this, 'WalletService-' + id),
@@ -84,17 +64,8 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
       data.loaded = false;
       data.blockUid = null;
       data.avatar = null;
-      if (!data.settings.useLocalStorage) {
-        data.settings = {
-          useRelative: defaultSettings.useRelative,
-          timeWarningExpireMembership: defaultSettings.timeWarningExpireMembership,
-          timeWarningExpire: defaultSettings.timeWarningExpire,
-          locale: {id: $translate.use()},
-          useLocalStorage: defaultSettings.useLocalStorage,
-          rememberMe: defaultSettings.rememberMe,
-          node: BMA.node.url, // If changed, use the updated url
-          showUDHistory: defaultSettings.showUDHistory
-        };
+      if (!csSettings.data.useLocalStorage) {
+        csSettings.reset();
       }
     },
 
@@ -177,7 +148,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
                     // Copy result to properties
                     data.pubkey = CryptoUtils.util.encode_base58(keypair.signPk);
                     data.keypair = keypair;
-                    if (data.settings.useLocalStorage) {
+                    if (csSettings.data.useLocalStorage) {
                       store();
                     }
                     resolve(data);
@@ -204,99 +175,64 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
       return isLogin() && data.pubkey === pubkey;
     },
 
-    store = function(options) {
-      if (data.settings.useLocalStorage) {
-
-        if (!options || options.settings) {
-          localStorage.setObject('CESIUM_SETTINGS', data.settings);
-          // Send event when settings changed
-          $rootScope.$broadcast(events.SETTINGS);
-        }
+    store = function() {
+      if (csSettings.data.useLocalStorage) {
 
-        if (!options || options.data) {
-          if (isLogin() && data.settings.rememberMe) {
-            var dataToStore = {
-              keypair: data.keypair,
-              pubkey: data.pubkey
-            };
+        if (isLogin() && csSettings.data.rememberMe) {
+          var dataToStore = {
+            keypair: data.keypair,
+            pubkey: data.pubkey
+          };
 
-            if (data.tx && data.tx.pendings && data.tx.pendings.length>0) {
-              var pendings = data.tx.pendings.reduce(function(res, tx){
-                return tx.time ? res.concat({
-                  amount: tx.amount,
-                  time: tx.time,
-                  hash: tx.hash
-                }) : res;
-              }, []);
-              if (pendings.length) {
-                dataToStore.tx = {
-                  pendings: pendings
-                };
-              }
+          if (data.tx && data.tx.pendings && data.tx.pendings.length>0) {
+            var pendings = data.tx.pendings.reduce(function(res, tx){
+              return tx.time ? res.concat({
+                amount: tx.amount,
+                time: tx.time,
+                hash: tx.hash
+              }) : res;
+            }, []);
+            if (pendings.length) {
+              dataToStore.tx = {
+                pendings: pendings
+              };
             }
-
-            localStorage.setObject('CESIUM_DATA', dataToStore);
-          }
-          else {
-            localStorage.setObject('CESIUM_DATA', null);
           }
+
+          localStorage.setObject(constants.STORAGE_KEY, dataToStore);
+        }
+        else {
+          localStorage.setObject(constants.STORAGE_KEY, null);
         }
       }
       else {
-        localStorage.setObject('CESIUM_SETTINGS', null);
-        localStorage.setObject('CESIUM_DATA', null);
-        // Send event when settings changed
-        $rootScope.$broadcast(events.SETTINGS);
+        localStorage.setObject(constants.STORAGE_KEY, null);
       }
-
     },
 
     restore = function() {
       return $q(function(resolve, reject){
-        var settings = localStorage.getObject('CESIUM_SETTINGS');
-        var dataStr = localStorage.get('CESIUM_DATA');
-        if (!settings && !dataStr) {
+        var dataStr = localStorage.get(constants.STORAGE_KEY);
+        if (!dataStr) {
           resolve();
           return;
         }
-        var nodeChanged = (settings && settings.node) && (data.settings.node != settings.node);
-        if (nodeChanged) {
-          BMA.copy(BMA.instance(settings.node)); // reload BMA
-          data.loaded = false;
-        }
-        if (settings) {
-          var refreshLocale = settings.locale && settings.locale.id && (data.settings.locale.id !== settings.locale.id);
-          data.settings = settings;
-
-          // TODO : This is a workaround for DEV (Need to implement edition in settings)
-          data.settings.timeWarningExpire = defaultSettings.timeWarningExpire;
-          data.settings.timeWarningExpireMembership = defaultSettings.timeWarningExpireMembership;
-
-          if (refreshLocale) {
-            $translate.use(data.settings.locale.id);
-          }
-        }
-        if (dataStr) {
-          fromJson(dataStr, false)
-          .then(function(storedData){
-            if (storedData && storedData.keypair && storedData.pubkey) {
-              data.keypair = storedData.keypair;
-              data.pubkey = storedData.pubkey;
-              if (storedData.tx && storedData.tx.pendings) {
-                data.tx.pendings = storedData.tx.pendings;
-              }
-              data.loaded = false;
+        fromJson(dataStr, false)
+        .then(function(storedData){
+          if (storedData && storedData.keypair && storedData.pubkey) {
+            data.keypair = storedData.keypair;
+            data.pubkey = storedData.pubkey;
+            if (storedData.tx && storedData.tx.pendings) {
+              data.tx.pendings = storedData.tx.pendings;
             }
+            data.loaded = false;
+          }
 
-            // Load parameters
-            // This prevent timeout error, when loading a market record after a browser refresh (e.g. F5)
-            return loadParameters();
-          })
-          .catch(function(err){reject(err);});
-        }
-        else {
-          resolve();
-        }
+          // Load parameters
+          // This prevent timeout error, when loading a market record after a browser refresh (e.g. F5)
+          return loadParameters();
+        })
+        .catch(function(err){reject(err);});
       });
     },
 
@@ -356,13 +292,13 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
           data.requirements.needMembership = (data.requirements.membershipExpiresIn === 0 &&
                                               data.requirements.membershipPendingExpiresIn <= 0 );
           data.requirements.needRenew = (!data.requirements.needMembership &&
-                                         data.requirements.membershipExpiresIn <= data.settings.timeWarningExpireMembership &&
+                                         data.requirements.membershipExpiresIn <= csSettings.data.timeWarningExpireMembership &&
                                          data.requirements.membershipPendingExpiresIn <= 0);
           data.requirements.canMembershipOut = (data.requirements.membershipExpiresIn > 0);
           data.requirements.pendingMembership = (data.requirements.membershipPendingExpiresIn > 0);
           data.requirements.certificationCount = (idty.certifications) ? idty.certifications.length : 0;
           data.requirements.willExpireCertificationCount = idty.certifications ? idty.certifications.reduce(function(count, cert){
-            if (cert.expiresIn <= data.settings.timeWarningExpire) {
+            if (cert.expiresIn <= csSettings.data.timeWarningExpire) {
               return count + 1;
             }
             return count;
@@ -435,7 +371,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
             reduceTxAndPush(res.history.pending, txPendings, processedTxMap, false/*exclude pending*/);
           }));
         // get UD history
-        if (data.settings.showUDHistory) {
+        if (csSettings.data.showUDHistory) {
           jobs.push(
             BMA.ud.history({pubkey: data.pubkey})
             .then(function(res){
@@ -529,21 +465,23 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
     },
 
     loadParameters = function() {
-      if (!data.parameters || !data.currency) {
-        return $q(function(resolve, reject) {
-          BMA.blockchain.parameters()
-          .then(function(json){
-            data.currency = json.currency;
-            data.parameters = json;
-            resolve();
-          })
-          .catch(function(err) {
-            data.currency = null;
-            data.parameters = null;
-            reject(err);
-          });
+      return $q(function(resolve, reject) {
+        if (data.parameters && data.currency) {
+          resolve();
+          return;
+        }
+        BMA.blockchain.parameters()
+        .then(function(json){
+          data.currency = json.currency;
+          data.parameters = json;
+          resolve();
+        })
+        .catch(function(err) {
+          data.currency = null;
+          data.parameters = null;
+          reject(err);
         });
-      }
+      });
     },
 
     loadUDs = function() {
@@ -627,25 +565,40 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
       });
     },
 
-    refreshData = function() {
+    refreshData = function(options) {
+      if (!options) {
+        options = {
+          uds: true,
+          requirements: true,
+          sources: true,
+          tx: true
+        }
+      }
       return $q(function(resolve, reject){
-        $q.all([
-
-          // Get UDs
-          loadUDs(),
-
-          // Get requirements
-          loadRequirements()
-          .then(function() {
-            finishLoadRequirements();
-          }),
-
-          // Get sources
-          loadSources(),
+        var jobs = [];
+        // Get UDs
+        if (options.uds) {
+          jobs.push(loadUDs());
+        }
+        // Get requirements
+        if (options.uds) {
+          jobs.push(loadRequirements()
+            .then(function() {
+              finishLoadRequirements();
+            }));
+        }
+        // Get sources
+        if (options.source) {
+          jobs.push(loadSources());
+        }
+        // Get transactions
+        if (options.tx) {
+          jobs.push(loadTransactions());
+        }
+        // API extension
+        jobs.push(api.data.raisePromise.load(data));
 
-          // Get transactions
-          loadTransactions()
-        ])
+        $q.all(jobs)
         .then(function() {
           // Process transactions and sources
           processTransactionsAndSources()
@@ -794,18 +747,19 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
             return;
           }
 
-          var tx = "Version: 2\n";
-          tx += "Type: Transaction\n";
-          tx += "Currency: " + data.currency + "\n";
-          tx += "Locktime: 0" + "\n"; // no lock
-          tx += "Issuers:\n";
-          tx += data.pubkey + "\n";
-          tx += "Inputs:\n";
+          var tx = 'Version: 3\n' +
+            'Type: Transaction\n' +
+            'Currency: ' + data.currency + '\n' +
+            'Blockstamp: ' + block.number + '-' + block.hash + '\n' +
+            'Locktime: 0\n' + // no lock
+            'Issuers:\n' +
+             data.pubkey + '\n' +
+             'Inputs:\n';
 
           _.forEach(inputs.sources, function(source) {
-              // if D : D:PUBLIC_KEY:BLOCK_ID
-              // if T : T:T_HASH:T_INDEX
-              tx += source.type+":"+source.identifier+":"+source.noffset+"\n";
+              // if D : AMOUNT:BASE:D:PUBLIC_KEY:BLOCK_ID
+              // if T : AMOUNT:BASE:T:T_HASH:T_INDEX
+              tx += [source.amount, source.base, source.type, source.identifier,source.noffset].join(':')+"\n";
           });
 
           tx += 'Unlocks:\n';
@@ -899,22 +853,27 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
                   var signedIdentity = identity + signature + '\n';
                   // Send signed identity
                   BMA.wot.add({identity: signedIdentity})
-                    .then(function (result) {
-                      if (!!requirements) {
-                        // Refresh membership data
-                        loadRequirements()
-                          .then(function () {
-                            resolve();
-                          }).catch(function (err) {
-                          reject(err);
-                        });
-                      }
-                      else {
-                        data.uid = uid;
-                        data.blockUid = block.number + '-' + block.hash;
-                        resolve();
-                      }
-                    }).catch(function (err) {
+                  .then(function (result) {
+                    if (!!requirements) {
+                      // Refresh membership data
+                      loadRequirements()
+                        .then(function () {
+                          resolve();
+                        }).catch(function (err) {
+                        reject(err);
+                      });
+                    }
+                    else {
+                      data.uid = uid;
+                      data.blockUid = block.number + '-' + block.hash;
+                      resolve();
+                    }
+                  })
+                  .catch(function (err) {
+                    if (err && err.ucode === BMA.errorCodes.IDENTITY_SANDBOX_FULL) {
+                      reject({ucode: BMA.errorCodes.IDENTITY_SANDBOX_FULL, message: 'ERROR.IDENTITY_SANDBOX_FULL'});
+                      return;
+                    }
                     reject(err);
                   });
                 }).catch(function (err) {
@@ -953,11 +912,14 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
               // Send signed membership
               BMA.blockchain.membership({membership: signedMembership})
               .then(function(result) {
-                // Refresh membership data
-                loadRequirements()
-                .then(function() {
-                  resolve();
-                }).catch(function(err){reject(err);});
+                $timeout(function() {
+                  loadRequirements()
+                    .then(function() {
+                      finishLoadRequirements();
+                      resolve();
+                    })
+                    .catch(function(err){reject(err);});
+                }, 200);
               }).catch(function(err){reject(err);});
             }).catch(function(err){reject(err);});
           }).catch(function(err){reject(err);});
@@ -1047,6 +1009,8 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
     // Register extension points
     api.registerEvent('data', 'load');
 
+    csSettings.api.data.on.changed($rootScope, store);
+
     return {
       id: id,
       data: data,
@@ -1071,9 +1035,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
       // serialization
       toJson: toJson,
       fromJson: fromJson,
-      defaultSettings: defaultSettings,
-      api: api,
-      events: events
+      api: api
     };
   };
 
diff --git a/www/js/services/wot-services.js b/www/js/services/wot-services.js
index 68f303e6..19f11b9c 100644
--- a/www/js/services/wot-services.js
+++ b/www/js/services/wot-services.js
@@ -1,7 +1,8 @@
 
-angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.services', 'cesium.crypto.services', 'cesium.utils.services'])
+angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.services', 'cesium.crypto.services', 'cesium.utils.services',
+  'cesium.settings.services'])
 
-.factory('WotService', function($q, BMA, Api, Wallet) {
+.factory('WotService', function($q, BMA, Api, csSettings) {
   'ngInject';
 
   WotService = function(id) {
@@ -28,19 +29,18 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic
                   return -score;
                 });
           }
-          var timeWarningExpire = Wallet.isLogin() ? Wallet.data.settings.timeWarningExpire : Wallet.defaultSettings.timeWarningExpire;
           var requirements = res.identities[0];
           // Add useful custom fields
           requirements.hasSelf = true;
           requirements.needMembership = (requirements.membershipExpiresIn === 0 &&
                                               requirements.membershipPendingExpiresIn <= 0 );
-          requirements.needRenew = !requirements.needMembership && (requirements.membershipExpiresIn <= timeWarningExpire &&
+          requirements.needRenew = !requirements.needMembership && (requirements.membershipExpiresIn <= csSettings.data.timeWarningExpire &&
                                         requirements.membershipPendingExpiresIn <= 0 );
           requirements.canMembershipOut = (requirements.membershipExpiresIn > 0);
           requirements.pendingMembership = (requirements.membershipPendingExpiresIn > 0);
           requirements.certificationCount = (requirements.certifications) ? requirements.certifications.length : 0;
           requirements.willExpireCertificationCount = requirements.certifications ? requirements.certifications.reduce(function(count, cert){
-            if (cert.expiresIn <= timeWarningExpire) {
+            if (cert.expiresIn <= csSettings.data.timeWarningExpire) {
               return count + 1;
             }
             return count;
@@ -95,7 +95,6 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic
           identity.hasSelf = !!(identity.uid && identity.timestamp && identity.sig);
 
           // Retrieve certifications
-          var timeWarningExpire = Wallet.isLogin() ? Wallet.data.settings.timeWarningExpire : Wallet.defaultSettings.timeWarningExpire;
           var expiresInByPub = requirements.certifications.reduce(function(map, cert){
             map[cert.from]=cert.expiresIn;
             return map;
@@ -112,7 +111,7 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic
                     uid: cert.uids[0],
                     block: (cert.meta && cert.meta.block_number) ? cert.meta.block_number : 0,
                     expiresIn: expiresIn,
-                    willExpire: (expiresIn && expiresIn <= timeWarningExpire),
+                    willExpire: (expiresIn && expiresIn <= csSettings.data.timeWarningExpire),
                     valid: (expiresIn && expiresIn > 0),
                     isMember: cert.isMember
                   });
diff --git a/www/plugins/es/js/controllers/common-controllers.js b/www/plugins/es/js/controllers/common-controllers.js
index f6b76222..33f42e71 100644
--- a/www/plugins/es/js/controllers/common-controllers.js
+++ b/www/plugins/es/js/controllers/common-controllers.js
@@ -1,10 +1,10 @@
 angular.module('cesium.es.common.controllers', ['ngResource', 'cesium.es.services'])
 
   // Configure menu items
-  .config(function(PluginServiceProvider, APP_CONFIG) {
+  .config(function(PluginServiceProvider, csConfig) {
     'ngInject';
 
-    var enable = !!APP_CONFIG.DUNITER_NODE_ES;
+    var enable = !!csConfig.DUNITER_NODE_ES;
     if (enable) {
       // Menu extension points
       PluginServiceProvider.extendState('app', {
@@ -36,14 +36,14 @@ angular.module('cesium.es.common.controllers', ['ngResource', 'cesium.es.service
 /**
  * Control menu extension
  */
-function ESMenuExtendController($scope, $rootScope, PluginService, Wallet, APP_CONFIG) {
+function ESMenuExtendController($scope, $rootScope, PluginService, Wallet, csConfig) {
   'ngInject';
   $scope.extensionPoint = PluginService.extensions.points.current.get();
 
   $scope.refreshEnable = function() {
     $scope.enable = Wallet.data && Wallet.data.settings.plugins && Wallet.data.settings.plugins.es ?
         Wallet.data.settings.plugins.es.enable :
-        !!APP_CONFIG.DUNITER_NODE_ES;
+        !!csConfig.DUNITER_NODE_ES;
   };
 
   $rootScope.$on(Wallet.events.SETTINGS, $scope.refreshEnable);
diff --git a/www/plugins/es/js/controllers/settings-controllers.js b/www/plugins/es/js/controllers/settings-controllers.js
index 954188b8..1f9a6f6c 100644
--- a/www/plugins/es/js/controllers/settings-controllers.js
+++ b/www/plugins/es/js/controllers/settings-controllers.js
@@ -1,10 +1,10 @@
 angular.module('cesium.es.settings.controllers', ['cesium.es.services'])
 
   // Configure menu items
-  .config(function(PluginServiceProvider, $stateProvider, APP_CONFIG) {
+  .config(function(PluginServiceProvider, $stateProvider, csConfig) {
     'ngInject';
 
-    var enable = !!APP_CONFIG.DUNITER_NODE_ES;
+    var enable = !!csConfig.DUNITER_NODE_ES;
     if (enable) {
       // Extend settings via extension points
       PluginServiceProvider.extendState('app.settings', {
@@ -38,7 +38,7 @@ angular.module('cesium.es.settings.controllers', ['cesium.es.services'])
 /*
  * Settings extend controller
  */
-function ESExtendSettingsController ($scope, $rootScope, Wallet, PluginService, APP_CONFIG) {
+function ESExtendSettingsController ($scope, $rootScope, Wallet, PluginService, csConfig) {
   'ngInject';
 
   $scope.extensionPoint = PluginService.extensions.points.current.get();
@@ -47,7 +47,7 @@ function ESExtendSettingsController ($scope, $rootScope, Wallet, PluginService,
   // Update settings if need
   $scope.onSettingsLoaded = function() {
     if ($scope.loading) {
-      var enable = !!APP_CONFIG.DUNITER_NODE_ES;
+      var enable = !!csConfig.DUNITER_NODE_ES;
       if (enable && Wallet.data.settings && Wallet.data.settings.plugins && Wallet.data.settings.plugins.es) {
         enable = Wallet.data.settings.plugins.es.enable;
       }
@@ -60,7 +60,7 @@ function ESExtendSettingsController ($scope, $rootScope, Wallet, PluginService,
 /*
  * Settings extend controller
  */
-function ESPluginSettingsController ($scope, $rootScope, $q,  $translate, $ionicPopup, $ionicHistory, UIUtils, APP_CONFIG, esHttp, esMarket,
+function ESPluginSettingsController ($scope, $rootScope, $q,  $translate, $ionicPopup, $ionicHistory, UIUtils, csConfig, esHttp, esMarket,
   esRegistry, esUser, Wallet) {
   'ngInject';
 
@@ -73,11 +73,11 @@ function ESPluginSettingsController ($scope, $rootScope, $q,  $translate, $ionic
         angular.merge($scope.formData, Wallet.data.settings.plugins.es);
       }
       else {
-        $scope.formData.enable = !!APP_CONFIG.DUNITER_NODE_ES;
+        $scope.formData.enable = !!csConfig.DUNITER_NODE_ES;
 
       }
       if (!$scope.formData.node) {
-        $scope.formData.node = APP_CONFIG.DUNITER_NODE_ES;
+        $scope.formData.node = csConfig.DUNITER_NODE_ES;
       }
     }
     $scope.loading = false;
diff --git a/www/plugins/es/js/services/http-services.js b/www/plugins/es/js/services/http-services.js
index acbcfef3..b8bd39df 100644
--- a/www/plugins/es/js/services/http-services.js
+++ b/www/plugins/es/js/services/http-services.js
@@ -3,7 +3,7 @@ angular.module('cesium.es.http.services', ['ngResource', 'cesium.services', 'ces
 /**
  * Elastic Search Http
  */
-.factory('esHttp', function($q, CryptoUtils, HttpUtils, $rootScope, APP_CONFIG, Wallet) {
+.factory('esHttp', function($q, CryptoUtils, HttpUtils, $rootScope, csConfig, Wallet) {
   'ngInject';
 
   function esHttp(server) {
@@ -203,7 +203,7 @@ angular.module('cesium.es.http.services', ['ngResource', 'cesium.services', 'ces
     };
   }
 
-  var service = esHttp(APP_CONFIG.DUNITER_NODE_ES);
+  var service = esHttp(csConfig.DUNITER_NODE_ES);
   service.instance = esHttp;
   return service;
 })
diff --git a/www/plugins/es/js/services/user-services.js b/www/plugins/es/js/services/user-services.js
index 57cef594..9cd82e7b 100644
--- a/www/plugins/es/js/services/user-services.js
+++ b/www/plugins/es/js/services/user-services.js
@@ -1,8 +1,8 @@
 angular.module('cesium.es.user.services', ['cesium.services', 'cesium.es.http.services'])
-.config(function(PluginServiceProvider, APP_CONFIG) {
+.config(function(PluginServiceProvider, csConfig) {
     'ngInject';
 
-    var enable = !!APP_CONFIG.DUNITER_NODE_ES;
+    var enable = !!csConfig.DUNITER_NODE_ES;
     if (enable) {
       // Will force to load this service
       PluginServiceProvider.registerEagerLoadingService('esUser');
diff --git a/www/templates/currency/tabs/view_network.html b/www/templates/currency/tabs/view_network.html
index ee491a9e..c0c34cee 100644
--- a/www/templates/currency/tabs/view_network.html
+++ b/www/templates/currency/tabs/view_network.html
@@ -3,11 +3,11 @@
 
         <div class="item item-divider item-icon-right">
             {{'PEER.PEERS'|translate}}
-            <ion-spinner class="icon" icon="android" ng-if="search.lookingForPeers"></ion-spinner>
+            <ion-spinner class="icon" icon="android" ng-if="loadingPeers"></ion-spinner>
         </div>
 
         <a class="peer-item item item-icon-left"
-           collection-repeat="peer in search.peers"
+           collection-repeat="peer in peers"
            ng-class="{ assertive: !peer.online, balanced: (peer.online && peer.hasMainConsensusBlock), energized: (peer.online && !peer.hasMainConsensusBlock) }"
            ui-sref="app.view_peer(peer)">
             <i class="icon ion-android-globe"></i>
diff --git a/www/templates/currency/view_currency.html b/www/templates/currency/view_currency.html
index c0bae04c..5288c7d7 100644
--- a/www/templates/currency/view_currency.html
+++ b/www/templates/currency/view_currency.html
@@ -3,17 +3,15 @@
     cache-view="false"
     >
   <ion-nav-title>
-    {{id}}
+    {{currency}}
   </ion-nav-title>
 
     <ion-nav-buttons side="secondary">
         <button class="button button-icon button-clear icon ion-loop" ng-click="refresh()">
         </button>
     </ion-nav-buttons>
-    <!--
-      TODO : use a ng-if to show/hide when small/large
-    <div class="scroll visible-xs">-->
-    <div class="scroll">
+
+    <ion-content scroll="false">
         <ion-tabs class="tabs-icon-top tabs-positive has-header">
 
             <ion-tab title="{{'CURRENCY.VIEW.TAB_CURRENCY'|translate}}" icon="ion-stats-bars">
@@ -32,17 +30,6 @@
 
             </ion-tab>
         </ion-tabs>
-    </div>
+    </ion-content>
 
-    <!--<ion-content class="has-header hidden-xs">
-        <div class="row scroll">
-            <div class="col-50 ">
-                <ng-include src="'templates/explore/tabs/explore_tab_currency.html'"/>
-            </div>
-            <div class="col-50 ">
-                <ng-include src="'templates/explore/tabs/explore_tab_network.html'"/>
-            </div>
-        </div>
-        <div class="scroll-bar scroll-bar-v"></div>
-    </ion-content>-->
 </ion-view>
diff --git a/www/templates/currency/view_currency_lg.html b/www/templates/currency/view_currency_lg.html
index 033bec7e..5c128098 100644
--- a/www/templates/currency/view_currency_lg.html
+++ b/www/templates/currency/view_currency_lg.html
@@ -11,8 +11,6 @@
 
     <ion-content>
       <div class="row">
-        </div>
-      </div>
         <div class="row responsive-sm">
             <div class="col col-50 ">
               <ng-include src="'templates/currency/tabs/view_parameters.html'"></ng-include>
diff --git a/www/templates/settings/settings.html b/www/templates/settings/settings.html
index a26847a4..ea8f2e47 100644
--- a/www/templates/settings/settings.html
+++ b/www/templates/settings/settings.html
@@ -79,7 +79,7 @@
       <div class="input-label">
       {{'SETTINGS.NODE' | translate}}
       </div>
-      <span class="item-note dark">{{formData.node}}</span>
+      <span class="item-note dark">{{formData.node.host}}<ng-if ng-if="formData.node.port && formData.node.port !== 80">:{{formData.node.port}}</ng-if></span>
     </div>
     <!-- Allow extension here -->
     <cs-extension-point name="network"></cs-extension-point>
diff --git a/www/templates/wallet/view_wallet.html b/www/templates/wallet/view_wallet.html
index e9224854..2f89e958 100644
--- a/www/templates/wallet/view_wallet.html
+++ b/www/templates/wallet/view_wallet.html
@@ -26,8 +26,8 @@
         <h3 class="light" ng-if="!walletData.name && walletData.isMember">{{walletData.uid}}</h3>
         <h3 class="light" ng-if="!walletData.name && !walletData.isMember">{{::walletData.pubkey | formatPubkey}}</h3>
         <h4 class="light">
-            <span ng-if="!walletData.settings.useRelative">{{convertedBalance | formatInteger}} {{walletData.parameters.currency | abbreviate}}</span>
-            <span ng-if="walletData.settings.useRelative">{{convertedBalance | formatDecimal}} {{'COMMON.UD' | translate}}<sub>{{walletData.parameters.currency | abbreviate}}</sub></span>
+            <span ng-if="!$root.settings.useRelative">{{convertedBalance | formatInteger}} {{walletData.parameters.currency | abbreviate}}</span>
+            <span ng-if="$root.settings.useRelative">{{convertedBalance | formatDecimal}} {{'COMMON.UD' | translate}}<sub>{{walletData.parameters.currency | abbreviate}}</sub></span>
         </h4>
       </div>
       <h4 class="content light" ng-if="loading">
@@ -123,8 +123,8 @@
         <span class="item item-pending item-divider" ng-if="walletData.tx.pendings && walletData.tx.pendings.length">
           <span translate>ACCOUNT.PENDING_TX</span>
           <div class="badge item-note">
-            <span ng-if="!walletData.settings.useRelative">({{walletData.parameters.currency | abbreviate}})</span>
-            <span ng-if="walletData.settings.useRelative">({{'COMMON.UD' | translate}}<sub>{{walletData.parameters.currency | abbreviate}}</sub>)</span>
+            <span ng-if="!$root.settings.useRelative">({{walletData.parameters.currency | abbreviate}})</span>
+            <span ng-if="$root.settings.useRelative">({{'COMMON.UD' | translate}}<sub>{{walletData.parameters.currency | abbreviate}}</sub>)</span>
           </div>
         </span>
 
@@ -158,8 +158,8 @@
           </h3>
           <div class="badge badge-pending item-note"
                ng-class="{'badge-balanced': tx.amount > 0}">
-            <span ng-if="!walletData.settings.useRelative">{{::tx.amount | formatInteger}}</span>
-            <span ng-if="walletData.settings.useRelative">{{::tx.amount/walletData.currentUD | formatDecimal}}</span>
+            <span ng-if="!$root.settings.useRelative">{{::tx.amount | formatInteger}}</span>
+            <span ng-if="$root.settings.useRelative">{{::tx.amount/walletData.currentUD | formatDecimal}}</span>
           </div >
         </span>
 
@@ -167,8 +167,8 @@
         <span class="item item-divider" ng-if="!loading">
           <span translate>ACCOUNT.LAST_TX</span>
           <div class="badge item-note">
-            <span ng-if="!walletData.settings.useRelative">({{walletData.parameters.currency | abbreviate}})</span>
-            <span ng-if="walletData.settings.useRelative">({{'COMMON.UD' | translate}}<sub>{{walletData.parameters.currency | abbreviate}}</sub>)</span>
+            <span ng-if="!$root.settings.useRelative">({{walletData.parameters.currency | abbreviate}})</span>
+            <span ng-if="$root.settings.useRelative">({{'COMMON.UD' | translate}}<sub>{{walletData.parameters.currency | abbreviate}}</sub>)</span>
           </div>
         </span>
 
@@ -217,8 +217,8 @@
           </h3>
           <div class="badge item-note"
                ng-class="{'badge-balanced': tx.amount > 0}">
-            <span ng-if="!walletData.settings.useRelative">{{::tx.amount | formatInteger}}</span>
-            <span ng-if="walletData.settings.useRelative">{{::tx.amount/walletData.currentUD | formatDecimal}}</span>
+            <span ng-if="!$root.settings.useRelative">{{::tx.amount | formatInteger}}</span>
+            <span ng-if="$root.settings.useRelative">{{::tx.amount/walletData.currentUD | formatDecimal}}</span>
           </div >
         </span>
       </div>
diff --git a/www/templates/wallet/view_wallet_tx_error.html b/www/templates/wallet/view_wallet_tx_error.html
index 4d0d76c6..c02db0fd 100644
--- a/www/templates/wallet/view_wallet_tx_error.html
+++ b/www/templates/wallet/view_wallet_tx_error.html
@@ -34,8 +34,8 @@
         <span class="item item-divider">
           <span translate>ACCOUNT.ERROR_TX_SENDED</span>
           <div class="badge item-note">
-            <span ng-if="!walletData.settings.useRelative">({{walletData.currency | abbreviate}})</span>
-            <span ng-if="walletData.settings.useRelative">({{'COMMON.UD' | translate}}<sub>{{walletData.currency | abbreviate}}</sub>)</span>
+            <span ng-if="!$root.settings.useRelative">({{walletData.currency | abbreviate}})</span>
+            <span ng-if="$root.settings.useRelative">({{'COMMON.UD' | translate}}<sub>{{walletData.currency | abbreviate}}</sub>)</span>
           </div>
         </span>
 
@@ -66,8 +66,8 @@
             {{::tx.comment}}<br/>
           </h3>
           <div class="badge item-note assertive">
-            <span ng-if="!walletData.settings.useRelative">{{::tx.amount | formatInteger}}</span>
-            <span ng-if="walletData.settings.useRelative">{{::tx.amount/walletData.currentUD | formatDecimal}}</span>
+            <span ng-if="!$root.settings.useRelative">{{::tx.amount | formatInteger}}</span>
+            <span ng-if="$root.settings.useRelative">{{::tx.amount/walletData.currentUD | formatDecimal}}</span>
           </div >
         </span>
 
@@ -75,8 +75,8 @@
         <span class="item item-divider">
           <span translate>ACCOUNT.ERROR_TX_RECEIVED</span>
           <div class="badge item-note">
-            <span ng-if="!walletData.settings.useRelative">({{walletData.currency | abbreviate}})</span>
-            <span ng-if="walletData.settings.useRelative">({{'COMMON.UD' | translate}}<sub>{{walletData.currency | abbreviate}}</sub>)</span>
+            <span ng-if="!$root.settings.useRelative">({{walletData.currency | abbreviate}})</span>
+            <span ng-if="$root.settings.useRelative">({{'COMMON.UD' | translate}}<sub>{{walletData.currency | abbreviate}}</sub>)</span>
           </div>
         </span>
 
@@ -107,8 +107,8 @@
             {{::tx.comment}}<br/>
           </h3>
           <div class="badge badge-assertive item-note">
-            <span ng-if="!walletData.settings.useRelative">{{::tx.amount | formatInteger}}</span>
-            <span ng-if="walletData.settings.useRelative">{{::tx.amount/walletData.currentUD | formatDecimal}}</span>
+            <span ng-if="!$root.settings.useRelative">{{::tx.amount | formatInteger}}</span>
+            <span ng-if="$root.settings.useRelative">{{::tx.amount/walletData.currentUD | formatDecimal}}</span>
           </div >
         </span>
       </div>
diff --git a/www/templates/wot/view_certifications.html b/www/templates/wot/view_certifications.html
index 1b8667be..e013f73c 100644
--- a/www/templates/wot/view_certifications.html
+++ b/www/templates/wot/view_certifications.html
@@ -82,8 +82,8 @@
   <!-- fab button -->
   <div class="visible-xs visible-sm">
     <button id="fab-certify" class="button button-fab button-fab-bottom-right button-energized-900 spin"
-            ng-click="certifyIdentity()"
-            ng-if="canCertify && !alreadyCertified">
+            ng-click="certify()"
+            ng-if="formData.hasSelf && canCertify && !alreadyCertified">
       <i class="icon ion-ribbon-b"></i></button>
   </div>
 
-- 
GitLab