diff --git a/platforms/desktop b/platforms/desktop
index 5f53840ba382c61e7502003c05957171a3907fb7..df50262d000506dd813763b5533eb997fdc1acd6 160000
--- a/platforms/desktop
+++ b/platforms/desktop
@@ -1 +1 @@
-Subproject commit 5f53840ba382c61e7502003c05957171a3907fb7
+Subproject commit df50262d000506dd813763b5533eb997fdc1acd6
diff --git a/www/api/index.html b/www/api/index.html
index a70c78817d8a4e25aae14466f07189f2a0b621da..6a3f64ef96a6fa6249f4d8cb3aaa31615d421145 100644
--- a/www/api/index.html
+++ b/www/api/index.html
@@ -73,6 +73,7 @@
 <!-- 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/desktop-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/cache-services.js"></script>
diff --git a/www/i18n/locale-en-GB.json b/www/i18n/locale-en-GB.json
index 8a1e3590dd9da2d0f8d1f76bbece58ed2613cc99..1e682b236a1fcabec105f4e9c4b84df5384ac48e 100644
--- a/www/i18n/locale-en-GB.json
+++ b/www/i18n/locale-en-GB.json
@@ -901,7 +901,8 @@
       "LINK_DOC": "API documentation",
       "LINK_DOC_HELP": "API documentation for developers",
       "LINK_STANDARD_APP": "Standard version",
-      "LINK_STANDARD_APP_HELP": "Open standard version of {{'COMMON.APP_NAME'|translate}}"
+      "LINK_STANDARD_APP_HELP": "Open standard version of {{'COMMON.APP_NAME'|translate}}",
+      "CONNECTION_ERROR": "Peer <b>{{server}}</b> unreachable or invalid address.<br/><br/>Check your Internet connection, or contact the web site administrator."
     },
     "HOME": {
       "TITLE": "{{'COMMON.APP_NAME'|translate}} API Documentation",
@@ -917,6 +918,7 @@
       "NAME": "Name:",
       "PUBKEY": "Public key of the recipient:",
       "COMMENT": "Order reference:",
+      "NODE": "Peer address:",
       "DEMO": {
         "SALT": "demo",
         "PASSWORD": "demo",
@@ -963,6 +965,8 @@
         "PARAM_REDIRECT_URL_HELP": "URL redirection after sending payment, after the payment has been sent. Can contain the following strings, which will be replaced by the values of the transaction: \"{tx}\", \"{hash}\", \"{comment}\", \"{amount}\" and \"{pubkey}\".",
         "PARAM_CANCEL_URL": "URL if cancelled",
         "PARAM_CANCEL_URL_HELP": "URL in case of cancellation.  Can contain the following strings, which will be replaced: \"{comment}\", \"{amount}\" and \"{pubkey}\".",
+        "PARAM_PREFERRED_NODE": "Preferred Duniter peer",
+        "PARAM_PREFERRED_NODE_HELP": "Peer address (URL) to use preferably (\"g1.domain.com:443\" or \"https://g1.domain.com\")",
         "EXAMPLES_HELP": "Examples of integration:",
         "EXAMPLE_BUTTON": "HTML Button",
         "EXAMPLE_BUTTON_DEFAULT_TEXT": "Pay in {{currency|abbreviate}}",
diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json
index e9d855e7f7a290193396838a794793d7c6da3416..fe47aa82bbdba0fcdbbc4971b0b61265c60ec9c8 100644
--- a/www/i18n/locale-en.json
+++ b/www/i18n/locale-en.json
@@ -901,7 +901,8 @@
       "LINK_DOC": "API documentation",
       "LINK_DOC_HELP": "API documentation for developers",
       "LINK_STANDARD_APP": "Standard version",
-      "LINK_STANDARD_APP_HELP": "Open standard version of {{'COMMON.APP_NAME'|translate}}"
+      "LINK_STANDARD_APP_HELP": "Open standard version of {{'COMMON.APP_NAME'|translate}}",
+      "CONNECTION_ERROR": "Peer <b>{{server}}</b> unreachable or invalid address.<br/><br/>Check your Internet connection, or contact the web site administrator."
     },
     "HOME": {
       "TITLE": "{{'COMMON.APP_NAME'|translate}} API Documentation",
@@ -917,6 +918,7 @@
       "NAME": "Name:",
       "PUBKEY": "Public key of the recipient:",
       "COMMENT": "Order reference:",
+      "NODE": "Peer address:",
       "DEMO": {
         "SALT": "demo",
         "PASSWORD": "demo",
@@ -963,6 +965,8 @@
         "PARAM_REDIRECT_URL_HELP": "URL redirection after sending payment, after the payment has been sent. Can contain the following strings, which will be replaced by the values of the transaction: \"{tx}\", \"{hash}\", \"{comment}\", \"{amount}\" and \"{pubkey}\".",
         "PARAM_CANCEL_URL": "URL if cancelled",
         "PARAM_CANCEL_URL_HELP": "URL in case of cancellation.  Can contain the following strings, which will be replaced: \"{comment}\", \"{amount}\" and \"{pubkey}\".",
+        "PARAM_PREFERRED_NODE": "Preferred Duniter peer",
+        "PARAM_PREFERRED_NODE_HELP": "Peer address (URL) to use preferably (\"g1.domain.com:443\" or \"https://g1.domain.com\")",
         "EXAMPLES_HELP": "Examples of integration:",
         "EXAMPLE_BUTTON": "HTML Button",
         "EXAMPLE_BUTTON_DEFAULT_TEXT": "Pay in {{currency|abbreviate}}",
diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json
index 3b1f9ffcd6c641a7d252ccacd368cc39dba4869a..da359ee6ab9518f99a9a81c7cd595d3c6b053781 100644
--- a/www/i18n/locale-fr-FR.json
+++ b/www/i18n/locale-fr-FR.json
@@ -901,7 +901,8 @@
       "LINK_DOC": "documentation API",
       "LINK_DOC_HELP": "Documentation pour les développeurs",
       "LINK_STANDARD_APP": "version classique",
-      "LINK_STANDARD_APP_HELP": "Ouvrir la version classique de {{'COMMON.APP_NAME'|translate}}"
+      "LINK_STANDARD_APP_HELP": "Ouvrir la version classique de {{'COMMON.APP_NAME'|translate}}",
+      "CONNECTION_ERROR": "Nœud <b>{{server}}</b> injoignable ou adresse invalide.<br/><br/>Vérifiez votre connection Internet, ou contacter l'administrateur du site</a>."
     },
     "HOME": {
       "TITLE": "Documentation API {{'COMMON.APP_NAME'|translate}}",
@@ -915,8 +916,9 @@
       "SUMMARY": "Récapitulatif de la commande :",
       "AMOUNT": "Montant :",
       "NAME": "Nom :",
-      "PUBKEY": "Clé publique du destinaire :",
+      "PUBKEY": "Clé publique du destinataire :",
       "COMMENT": "Référence de la commande :",
+      "NODE": "Addresse du nœud :",
       "DEMO": {
         "SALT": "demo",
         "PASSWORD": "demo",
@@ -942,6 +944,7 @@
       "DEMO_DIVIDER": "Tester",
       "DEMO_HELP": "Pour tester ce service, cliquez sur le bouton ci-contre. Le résultat s'affichera en dessous.",
       "DEMO_RESULT": "Résultat retourné par l'appel :",
+      "DEMO_RESULT_PEER": "Nœud Duniter utilisé : ",
       "DEMO_SUCCEED": "<i class=\"icon ion-checkmark\"></i> Succès !",
       "DEMO_CANCELLED": "<i class=\"icon ion-close\"></i> Annulé par l'utilisateur",
       "INTEGRATE_DIVIDER": "Intégrer",
@@ -960,9 +963,11 @@
         "PARAM_NAME": "Nom (du destinataire ou du site web)",
         "PARAM_NAME_HELP": "Le nom du destinataire, ou du site web appellant. Cela peut-etre un nom lisible (\"Mon site en ligne\"), ou encore une pseudo-adresse web (\"MonSite.com\").",
         "PARAM_REDIRECT_URL": "Adresse web de redirection",
-        "PARAM_REDIRECT_URL_HELP": "Adresse web (URL) de redirection, appellé quand le paiement a été envoyé. Peut contenir les chaines suivantes, qui seront remplacée par les valeurs de la transaction : \"{tx}\", \"{hash}\", \"{comment}\", \"{amount}\" et {pubkey}.",
+        "PARAM_REDIRECT_URL_HELP": "Adresse web (URL) de redirection, appellé quand le paiement a été envoyé. Peut contenir les chaines suivantes, qui seront remplacée par les valeurs de la transaction : \"{tx}\", \"{hash}\", \"{comment}\", \"{amount}\", \"{pubkey}\" et \"{node}\".",
         "PARAM_CANCEL_URL": "Adresse web d'annulation",
         "PARAM_CANCEL_URL_HELP": "Adresse web (URL) en cas d'annulation du paiement, par l'utilisateur. Peut contenir les chaines suivantes, qui seront remplacée dynamiquement: \"{comment}\", \"{amount}\" et {pubkey}.",
+        "PARAM_PREFERRED_NODE": "Nœud Duniter préféré",
+        "PARAM_PREFERRED_NODE_HELP": "Adresse (URL) du nœud Duniter à utiliser de préférence (\"g1.domaine.com:443\" ou \"https://g1.domaine.com\").",
         "EXAMPLES_HELP": "Voici des exemples d'intégration :",
         "EXAMPLE_BUTTON": "Bouton HTML",
         "EXAMPLE_BUTTON_DEFAULT_TEXT": "Payer en {{currency|currencySymbol}}",
diff --git a/www/js/api/app.js b/www/js/api/app.js
index 44aa8a1af6b5bf037eed4a2d4d000d01ae5f33bc..3d2baeb296b1b4737275e1f611ba55e381862473 100644
--- a/www/js/api/app.js
+++ b/www/js/api/app.js
@@ -25,7 +25,7 @@ angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalpr
       })
 
       .state('app.home', {
-        url: "/home?result&service&cancel",
+        url: "/home?result&service&cancel&node",
         views: {
           'menuContent': {
             templateUrl: "templates/api/home.html",
@@ -43,7 +43,7 @@ angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalpr
 
       .state('api.transfer', {
         cache: false,
-        url: "/payment/:pubkey?name&amount&udAmount&comment&redirect_url&cancel_url&demo",
+        url: "/payment/:pubkey?name&amount&udAmount&comment&preferred_node&redirect_url&cancel_url&demo&error",
         views: {
           'menuContent': {
             templateUrl: "templates/api/transfer.html",
@@ -114,7 +114,8 @@ angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalpr
       amount: 100,
       comment: 'REFERENCE',
       name: 'www.domain.com',
-      redirect_url: 'http://www.domain.com/payment?ref={comment}&tx={tx}',
+      preferred_node: undefined,
+      redirect_url: 'http://www.domain.com/payment?ref={comment}&tx={tx}&node={node}',
       cancel_url: 'http://www.domain.com/payment?ref={comment}&cancel'
     };
     $scope.transferButton = {
@@ -152,7 +153,7 @@ angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalpr
     $scope.transferButton.style.icon = $scope.transferButton.icons[1/*Duniter icon*/];
     $scope.transferDemoUrl = $rootScope.rootPath + $state.href('api.transfer', angular.merge({}, $scope.transferData, {
         demo: true,
-        redirect_url: $rootScope.rootPath + '#/app/home?service=payment&result={tx}',
+        redirect_url: $rootScope.rootPath + '#/app/home?service=payment&result={tx}&node={node}',
         cancel_url: $rootScope.rootPath + '#/app/home?service=payment&cancel'
       }));
 
@@ -169,6 +170,9 @@ angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalpr
       if (state.stateParams && state.stateParams.cancel) {
         $scope.result.cancelled = true;
       }
+      if (state.stateParams && state.stateParams.node) {
+        $scope.result.node = state.stateParams.node;
+      }
 
       csCurrency.get()
         .then(function(currency) {
@@ -231,7 +235,8 @@ angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalpr
   })
 
   .controller('ApiTransferCtrl', function ($scope, $rootScope, $timeout, $controller, $state, $q, $translate, $filter,
-                                           BMA, CryptoUtils, UIUtils, csCurrency, csTx, csWallet, csDemoWallet){
+                                           $window, $ionicHistory, BMA, CryptoUtils, UIUtils, csSettings, csCurrency,
+                                           csPlatform, csTx, csWallet, csDemoWallet){
     'ngInject';
 
     // Initialize the super class and extend it.
@@ -244,10 +249,15 @@ angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalpr
       pubkey: undefined,
       name: undefined,
       redirect_url: undefined,
-      cancel_url: undefined
+      cancel_url: undefined,
+      node: undefined
     };
 
     $scope.enter = function(e, state) {
+      $rootScope.errorState = state.stateName;
+
+      if (!$scope.loading) return; // already enter
+
       if (state.stateParams && state.stateParams.amount) {
         $scope.transferData.amount  = parseFloat(state.stateParams.amount.replace(new RegExp('[.,]'), '.')).toFixed(2) * 100;
       }
@@ -269,9 +279,89 @@ angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalpr
       if (state.stateParams && state.stateParams.demo) {
         $scope.demo = true;
       }
+
+      if (state.stateParams && state.stateParams.preferred_node) {
+        var
+          isHttpsMode = $window.location.protocol === 'https:',
+          useSsl = isHttpsMode,
+          preferredNode = state.stateParams.preferred_node;
+        var matches = /^(?:(http[s]?:)\/\/)(.*)$/.exec(preferredNode);
+        if (matches) {
+          useSsl = matches[1] === 'https:';
+          preferredNode = matches[2];
+        }
+        var parts = preferredNode.split(':');
+        if (parts.length >= 1) {
+          var port = parts[1] || (useSsl ? 443 : 80);
+          $scope.node = {
+            host: parts[0],
+            port: port,
+            useSsl: useSsl || (port == 443)
+          };
+
+          // Add a fallback node that use SSL
+          if (!$scope.node.useSsl) {
+            var node = angular.copy($scope.node);
+            node.useSsl = true;
+            node.port = 443;
+            csSettings.data.fallbackNodes = csSettings.data.fallbackNodes || [];
+            csSettings.data.fallbackNodes.splice(0,0,node);
+          }
+        }
+        else {
+          console.warn("[api] Invalid preferred node address: {0}. Using default node." + state.stateParams.preferred_node);
+        }
+      }
+
+      // Start
+      return $scope.start();
     };
     $scope.$on('$ionicView.enter', $scope.enter);
 
+
+    $scope.start = function() {
+      if ($scope.starting) return;
+
+      $scope.starting = true;
+      $scope.loading = true;
+
+      // Set BMA node
+      if (!$scope.error && $scope.node && !BMA.node.same($scope.node.host, $scope.node.port)) {
+        console.debug("[api] Using preferred node: {0}:{1}".format($scope.node.host, $scope.node.port));
+        BMA.stop();
+        BMA.copy($scope.node);
+        $scope.node.server = BMA.server;
+      }
+
+      // Start platform (or restart) platform
+      // This will start the BMA node
+      return csPlatform.restart()
+        .then(csCurrency.get)
+        .then(function(currency) {
+          $scope.currency = currency;
+          $scope.node = currency.node;
+          $scope.loading = false;
+          $scope.error = false;
+          $scope.starting = false;
+          // Reset history cache
+          $ionicHistory.clearCache();
+        })
+        // Error during load (BMA not alive ?)
+        .catch(function(err) {
+          console.error(err && err.message || err);
+          $scope.error = true;
+          $scope.loading = false;
+          $scope.starting = false;
+
+          // Make sure to retry if user choose a fallback node
+          var unsubscribe = BMA.api.node.on.start($scope, function() {
+            $scope.start();
+            unsubscribe();
+          });
+        })
+        ;
+    };
+
     function onLogin(authData) {
 
       // User cancelled
@@ -285,9 +375,15 @@ angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalpr
 
       UIUtils.loading.show();
 
-      wallet.start({restore: false}/*skip restore from local storage*/)
+      wallet.start({restore: false/*skip restore from local storage*/})
         .then(function() {
-          return wallet.login({auth: true, authData: authData});
+          return wallet.login({
+            auth: true,
+            authData: authData,
+            minData: true,
+            sources: true,
+            tx: {enable: false}
+          });
         })
         .then(function(walletData) {
           $scope.login = true;
@@ -369,6 +465,7 @@ angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalpr
           url = url.replace(/\{comment\}/g, $scope.transferData.comment||'');
           url = url.replace(/\{amount\}/g, $scope.transferData.amount.toString());
           url = url.replace(/\{tx\}/g, encodeURI(txRes.tx));
+          url = url.replace(/\{node\}/g, encodeURI(BMA.host+':'+BMA.port));
 
           return $scope.redirectToUrl(url, 2500);
         });
@@ -423,9 +520,14 @@ angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalpr
 
   })
 
-  .run(function(csPlatform) {
+  .run(function(csSettings) {
     'ngInject';
 
-    csPlatform.start();
+    csSettings.data.rememberMe = false;
+    csSettings.data.useLocalStorage = false;
+    // Force auth idle to 30s
+    csSettings.data.keepAuthIdle = 30;
+
+    //csPlatform.start();
   })
 ;
diff --git a/www/js/controllers/login-controllers.js b/www/js/controllers/login-controllers.js
index 744b9cb960e7880d9479e3980a123732d7b70868..dfe8bb90889cb69bc42913f075b695ab01d31dbc 100644
--- a/www/js/controllers/login-controllers.js
+++ b/www/js/controllers/login-controllers.js
@@ -43,7 +43,7 @@ function LoginController($scope, $timeout, $controller, csWallet) {
 
 }
 
-function LoginModalController($scope, $timeout, $q, $ionicPopover, CryptoUtils, csCrypto,
+function LoginModalController($scope, $timeout, $q, $ionicPopover, CryptoUtils, csCrypto, ionicReady,
                               UIUtils, BMA, Modals, csSettings, Device, parameters) {
   'ngInject';
 
@@ -72,9 +72,12 @@ function LoginModalController($scope, $timeout, $q, $ionicPopover, CryptoUtils,
 
   // modal init
   $scope.init = function() {
-    // Should auto-compute pubkey ?
-    $scope.autoComputePubkey = ionic.Platform.grade.toLowerCase()==='a' &&
-      !UIUtils.screen.isSmall();
+
+    ionicReady().then(function(){
+      // Should auto-compute pubkey ?
+      $scope.autoComputePubkey = ionic.Platform.grade.toLowerCase()==='a' &&
+        !UIUtils.screen.isSmall();
+    });
 
     // Init remember me
     $scope.formData.rememberMe = csSettings.data.rememberMe;
diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js
index 163c1d9db39d4d4a7329b2a1775bca79ec608e2f..fdcf678801cff7bf91dffadac85a9284bae2d9c0 100644
--- a/www/js/controllers/settings-controllers.js
+++ b/www/js/controllers/settings-controllers.js
@@ -183,7 +183,7 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
           BMA.copy(nodeBMA);
           $scope.bma = BMA;
 
-          // Start platform is not already started
+          // Restart platform (or start if not already started)
           csPlatform.restart();
 
           // Reset history cache
diff --git a/www/js/filters.js b/www/js/filters.js
index 2cd8b728884a65440d5ebb24e73d2aa8e0923d59..3cf9060aecc3d0cda3b9b53604dc0d5d8c1a9635 100644
--- a/www/js/filters.js
+++ b/www/js/filters.js
@@ -2,7 +2,7 @@
 angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalprecht.translate', 'cesium.translations'
 ])
 
-  .factory('filterTranslations', function($rootScope, $q, csPlatform, csSettings, csCurrency, $translate) {
+  .factory('filterTranslations', function($rootScope, $q, csPlatform, csSettings, csCurrency, $translate, $timeout) {
     'ngInject';
 
     var
@@ -65,7 +65,10 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
     };
 
     // Default action
-    that.start();
+    // Must be started with a delay, to allow settings override, before starting platform (need by Cesium API)
+    $timeout(function() {
+      that.start();
+    });
 
     return that;
   })
diff --git a/www/js/platform.js b/www/js/platform.js
index d393e5aef6f4c74235402eae03802921c460bd34..feef681477d5ce240a5d3c01c68abc4d524ee588 100644
--- a/www/js/platform.js
+++ b/www/js/platform.js
@@ -153,7 +153,18 @@ angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services']
         .then(function(res) {
           if (!res) return checkBmaNodeAlive(); // Loop
 
-          return $translate('CONFIRM.USE_FALLBACK_NODE', {old: BMA.server, new: newServer})
+          // Force to show port/ssl, if this is the only difference
+          var messageParam = {old: BMA.server, new: newServer};
+          if (messageParam.old === messageParam.new) {
+            if (BMA.port != fallbackNode.port) {
+              messageParam.new += ':' + fallbackNode.port;
+            }
+            else if (BMA.useSsl == false && (fallbackNode.useSsl || fallbackNode.port==443)) {
+              messageParam.new += ' (SSL)';
+            }
+          }
+
+          return $translate('CONFIRM.USE_FALLBACK_NODE', messageParam)
             .then(function(msg) {
               return UIUtils.alert.confirm(msg);
             })
@@ -264,8 +275,8 @@ angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services']
         .catch(function(err) {
           startPromise = null;
           started = false;
-          if($state.current.name !== 'app.home') {
-            $state.go('app.home', {error: 'peer'});
+          if($state.current.name !== $rootScope.errorState) {
+            $state.go($rootScope.errorState, {error: 'peer'});
           }
           throw err;
         });
@@ -310,6 +321,7 @@ angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services']
     $rootScope.settings = csSettings.data;
     $rootScope.currency = csCurrency.data;
     $rootScope.device = Device;
+    $rootScope.errorState = 'app.home';
 
     // Compute the root path
     var hashIndex = $window.location.href.indexOf('#');
diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js
index 658a619ec652a8db6aebee46e4e89e2a6b2deb2b..01c7fe68561118bab71356c093a14ce004e803c0 100644
--- a/www/js/services/bma-services.js
+++ b/www/js/services/bma-services.js
@@ -129,8 +129,10 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium.
     }
 
     function closeWs() {
+      if (!that.cache) return;
+
       console.warn('[BMA] Closing all websockets...');
-      _.keys(that.cache.wsByPath).forEach(function(key) {
+      _.keys(that.cache.wsByPath||{}).forEach(function(key) {
         var sock = that.cache.wsByPath[key];
         sock.close();
       });
@@ -397,7 +399,7 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium.
       node: {
         summary: get('/node/summary', csHttp.cache.LONG),
         same: function(host2, port2) {
-          return host2 == that.host && ((!that.port && !port2) || (that.port == port2||80));
+          return host2 == that.host && ((!that.port && !port2) || (that.port == port2||80)) && (that.useSsl == (port2 && port2 === 443));
         },
         forceUseSsl: that.forceUseSsl
       },
@@ -622,9 +624,12 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium.
     };
 
     exports.copy = function(otherNode) {
-      if (that.started) that.stop();
+      var wasStarted = that.started;
+      // Stop, if need
+      if (wasStarted) that.stop();
       that.init(otherNode.host, otherNode.port, otherNode.useSsl, that.useCache/*keep original value*/);
-      return that.start();
+      // Restart (only if was already started)
+      return wasStarted ? that.start() : $q.when();
     };
 
     exports.wot.member.uids = function() {
diff --git a/www/js/services/settings-services.js b/www/js/services/settings-services.js
index e25e68a912f3b37338e45eedc1cb2c406c1685e6..e2d7c1449ec68b16de7ae58d6f14f2f33f5ecaaa 100644
--- a/www/js/services/settings-services.js
+++ b/www/js/services/settings-services.js
@@ -143,7 +143,7 @@ angular.module('cesium.settings.services', ['ngApi', 'cesium.config'])
   },
 
   emitChangedEvent = function() {
-    var hasChanged = previousData && !angular.equals(previousData, data);
+    var hasChanged = angular.isUndefined(previousData) || !angular.equals(previousData, data);
     if (hasChanged) {
       previousData = angular.copy(data);
       return api.data.raise.changed(data);
diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js
index cff0e7afc6a5fff90a34517d6e814cb30f9c2806..6cf42bfd43937991478a45ca31ec276e8d64ce9d 100644
--- a/www/js/services/wallet-services.js
+++ b/www/js/services/wallet-services.js
@@ -735,7 +735,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
 
       // If not revoked
       else {
-        if (!data.isMember && data.requirements.meta.invalid) {
+        if (!data.isMember && data.requirements.meta && data.requirements.meta.invalid) {
           addEvent({type: 'error', message: 'ERROR.WALLET_INVALID_BLOCK_HASH', context: 'requirements'});
           console.debug("Invalid membership for uid={0}: block hash changed".format(data.uid));
         }
diff --git a/www/templates/api/doc.html b/www/templates/api/doc.html
index d195f59e3e122dc8733875f84a9d8f12426d340b..4eb7c6fb6ccaa2f9074e9c3182ad016265af3ebf 100644
--- a/www/templates/api/doc.html
+++ b/www/templates/api/doc.html
@@ -47,11 +47,15 @@
         <div class="col gray" translate>API.DOC.TRANSFER.PARAM_NAME_HELP</div>
       </div>
       <div class="row">
-        <div class="col col-20 text-italic">redirect_url</div>
-        <div class="col gray" translate>API.DOC.TRANSFER.PARAM_REDIRECT_URL_HELP</div>
+        <div class="col col-20 text-italic">preferred_node</div>
+        <div class="col gray" translate>API.DOC.TRANSFER.PARAM_PREFERRED_NODE_HELP</div>
       </div>
       <div class="row stable-bg">
-        <div class="col col-20 text-italic dark">cancel_url</div>
+        <div class="col col-20 text-italic dark">redirect_url</div>
+        <div class="col gray" translate>API.DOC.TRANSFER.PARAM_REDIRECT_URL_HELP</div>
+      </div>
+      <div class="row">
+        <div class="col col-20 text-italic">cancel_url</div>
         <div class="col gray" translate>API.DOC.TRANSFER.PARAM_CANCEL_URL_HELP</div>
       </div>
     </div>
@@ -72,6 +76,8 @@
       <h2 class="text-right balanced" translate>API.DOC.DEMO_SUCCEED</h2>
       <h4 class="gray" translate>API.DOC.DEMO_RESULT</h4>
       <p class="balanced-100-bg padding dark text-keep-lines">{{result.content}}</p>
+
+      <h4 class="gray"><span translate>API.DOC.DEMO_RESULT_PEER</span> <b>{{result.node}}</b></h4>
     </div>
     <div class="item item-text-wrap" ng-if="result.type === 'payment' && result.cancelled">
       <h2 class="text-right assertive" translate>API.DOC.DEMO_CANCELLED</h2>
@@ -171,6 +177,17 @@
                        placeholder="{{'API.DOC.TRANSFER.PARAM_NAME'|translate}}">
               </label>
 
+              <p class="padding-top">
+                <i class="icon ion-key"></i>
+                {{'API.DOC.TRANSFER.PARAM_PREFERRED_NODE' | translate}} :
+              </p>
+              <label class="item item-input">
+                <input type="text"
+                       ng-model="transferData.preferred_node"
+                       ng-model-options="{ debounce: 650 }"
+                       placeholder="{{'API.DOC.TRANSFER.PARAM_PREFERRED_NODE_HELP'|translate}}">
+              </label>
+
               <p class="padding-top">
                 <i class="icon ion-arrow-return-left"></i>
                 {{'API.DOC.TRANSFER.PARAM_REDIRECT_URL' | translate}} :
diff --git a/www/templates/api/transfer.html b/www/templates/api/transfer.html
index 8643317019de7a4872e6d3e20bf7ace5d74e1c9e..1ee7deb99e5cef7f302815b1ebc9d4124852fc09 100644
--- a/www/templates/api/transfer.html
+++ b/www/templates/api/transfer.html
@@ -56,10 +56,11 @@
 
           <div class="item item-icon-left-padding item-tx no-border ">
             <h2 translate>API.TRANSFER.AMOUNT</h2>
-            <div class="badge item-note badge-calm" ng-bind-html="transferData.amount|formatAmount:{useRelative: false, currency: $root.currency.name}"></div>
-            <div class="badge badge-secondary" ng-bind-html="transferData.amount|formatAmount:{useRelative: true, currency: $root.currency.name}"></div>
+            <ion-spinner class="badge item-note" icon="android" ng-show="loading"></ion-spinner>
+            <div class="badge item-note badge-calm ng-hide" ng-show="!loading"  ng-bind-html="transferData.amount|formatAmount:{useRelative: false, currency: currency.name}"></div>
+            <div class="badge badge-secondary ng-hide" ng-show="!loading" ng-bind-html="transferData.amount|formatAmount:{useRelative: true, currency: currency.name, currentUD: currency.currentUD}"></div>
           </div>
-          <div class="item item-icon-left-padding" ng-if="transferData.name">
+          <div class="item item-icon-left-padding" >
             <h2 translate>API.TRANSFER.NAME</h2>
             <div class="badge item-note">
               {{transferData.name}}
@@ -67,7 +68,7 @@
           </div>
           <div class="item item-icon-left-padding item-text-wrap">
             <h2 translate>API.TRANSFER.PUBKEY</h2>
-            <div class="badge">
+            <div class="badge" >
               <span class="hidden-xs"><br class="visible-sm visible-md"/><i class="icon ion-key"> </i>{{transferData.pubkey}}</span>
               <span class="visible-xs" copy-on-click="{{transferData.pubkey}}"><br class="visible-xs"/><i class="icon ion-key"></i> {{transferData.pubkey|formatPubkey}}</span>
             </div>
@@ -76,10 +77,33 @@
           <div class="item item-icon-left-padding">
             <h2 translate>API.TRANSFER.COMMENT</h2>
             <div class="badge item-note">
-              <span class="hidden-xs"><br class="visible-sm visible-md"/>{{transferData.comment}}</span>
-              <span class="visible-xs" copy-on-click="{{transferData.comment}}"><br/>{{transferData.comment}}</span>
+              <span class="hidden-xs"><br class="visible-sm visible-md"/>{{::transferData.comment}}</span>
+              <span class="visible-xs" copy-on-click="{{transferData.comment}}"><br/>{{::transferData.comment}}</span>
             </div>
           </div>
+
+          <div class="item item-icon-left-padding" ng-hide="error">
+            <h2 translate>API.TRANSFER.NODE</h2>
+            <div class="badge item-note" ng-if="!loading">
+              <br class="visible-sm visible-md"/>
+              <i class="icon ion-locked" ng-if="node.useSsl"></i>&nbsp;{{node.server}}
+            </div>
+          </div>
+
+          <div class="center padding animate-fade-in animate-show-hide ng-hide" ng-show="!loading && error">
+            <div class="card card-item padding">
+              <p class="item-content item-text-wrap">
+                <i class="icon ion-android-alert assertive"></i>
+                <span class="dark" trust-as-html="'API.COMMON.CONNECTION_ERROR'|translate:node"></span>
+              </p>
+
+              <!-- Retry -->
+              <button type="button"
+                      class="button button-positive icon icon-left ion-refresh ink"
+                      ng-click="start()">{{'COMMON.BTN_REFRESH'|translate}}</button>
+            </div>
+          </div>
+
           <!-- spacer in small screen -->
           <div class="padding-bottom visible-xs">&nbsp;</div>
         </div>
diff --git a/www/templates/join/modal_choose_account_type.html b/www/templates/join/modal_choose_account_type.html
index a5a358efc708d98fe1a0ae51a2e114e728fb329a..76b439b661d9e409ffb18935197170bc8863abaa 100644
--- a/www/templates/join/modal_choose_account_type.html
+++ b/www/templates/join/modal_choose_account_type.html
@@ -39,7 +39,7 @@
             <div class="row responsive-sm">
               <div class="col">
                 <div class="item card item-icon-left padding item-text-wrap stable-bg">
-                  <i class="icon ion-android-warning  assertive"></i>
+                  <i class="icon ion-android-warning assertive"></i>
 
                   <p class="item-content item-icon-left-padding ">
                     <span class="dark" translate>ACCOUNT.NEW.INTRO_WARNING_SECURITY</span><br/>