diff --git a/ionic.config.json b/ionic.config.json
index d913a836578b69df3d02dd55390f52b847cd03cf..019c4c894379bcfb091caf82cfb0b79411a0d8af 100644
--- a/ionic.config.json
+++ b/ionic.config.json
@@ -1,13 +1,14 @@
 {
   "name": "Cesium",
-  "type": "ionic1",
   "integrations": {
     "cordova": {}
   },
+  "type": "ionic1",
   "watchPatterns": [
     "www/index.html",
     "www/api/index.html",
     "www/dist/**/*",
     "www/css/*.css"
-  ]
+  ],
+  "yarn": true
 }
diff --git a/scripts/prompts/translations.md b/scripts/prompts/translations.md
new file mode 100644
index 0000000000000000000000000000000000000000..d150ad0d42b131d3c80bf6fe2c2da3f7d17655f7
--- /dev/null
+++ b/scripts/prompts/translations.md
@@ -0,0 +1,17 @@
+## Chat GPT prompt for translations
+
+I need translations for the following messages in a web application, in these languages/locales: en, en-GB, de-DE, eo-EO, es-CT, es-ES, it-IT, nl-NL, pt-PT. Please follow these constraints: maintain the input JSON format, indentation, and message keys; preserve HTML tags and case; and keep proper nouns untranslated (e.g., "Duniter" and "Cesium"). Here is the source message in French:
+```json
+"ORIGINAL_KEY_UNCHANGED": "<your_translation>"
+```
+
+Please provide the translations for each language/locale in this format:
+
+- <language_code> (e.g., en, en-GB, ...):
+```json
+{
+"ORIGINAL_KEY_UNCHANGED": "<your_translation>"
+}
+```
+
+If you have any questions before starting, please ask for clarifications to avoid mistakes.
\ No newline at end of file
diff --git a/www/i18n/locale-de-DE.json b/www/i18n/locale-de-DE.json
index 91b081f6f1c311286193041104b44d426167ff2d..db1b67a358ed1cefe2c7fec59c82dac2be5be167 100644
--- a/www/i18n/locale-de-DE.json
+++ b/www/i18n/locale-de-DE.json
@@ -847,7 +847,8 @@
     "LOGOUT": "Sicher, dass du dich abmelden möchtest?",
     "USE_FALLBACK_NODE": "Knoten <b>{{old}}</b> ist nicht erreichbar.<br/><br/>Möchtest du temporär den Knoten <b>{{new}}</b> verwenden?",
     "ISSUE_524_SEND_LOG": "Die Transaktion wurde aufgrund eines bekannten Problems (issue #524) zurückgewiesen. Die Ursache ist bisher unbekannt.<br/>Akzeptierst du <b>die Übertragung deiner Logdaten</b> als Nachricht, um den Entwicklern bei der Korrektur zu helfen?<br/><small>(Dies beinhaltet keine vertraulichen Daten)</small><br/>",
-    "LICENCE": "Ich habe die die Lizenz des G1 gelesen und akzeptiert"
+    "LICENCE": "Ich habe die die Lizenz des G1 gelesen und akzeptiert",
+    "ENABLE_EXPERT_MODE_TO_CHANGE_NODE": "<b class=\"assertive\">Warnung:</b> Möchten Sie den Knoten <b>manuell ändern</b>?<br/><br/>Wenn Sie fortfahren:<ul><li> - Der <b>Expertenmodus</b> wird aktiviert;</li><li> - Sie können zur automatischen Knotenauswahl zurückkehren, indem Sie einfach den <b>Expertenmodus deaktivieren</b>.</li></ul>"
   },
   "MODE": {
     "DEMO": {
diff --git a/www/i18n/locale-en-GB.json b/www/i18n/locale-en-GB.json
index e072b0534d8a846569259084ba44878e03e96222..36369fa5a22c9ce91f8d4c096ff07a73eae06578 100644
--- a/www/i18n/locale-en-GB.json
+++ b/www/i18n/locale-en-GB.json
@@ -849,7 +849,8 @@
     "SAVE_BEFORE_LEAVE_TITLE": "Changes not saved",
     "LOGOUT": "Are you sure you want to logout?",
     "USE_FALLBACK_NODE": "Peer <b>{{old}}</b> unreachable or invalid address.<br/><br/>Do you want to temporarily use the <b>{{new}}</b> node?",
-    "ISSUE_524_SEND_LOG": "The transaction was rejected because of a known problem (issue #524) but not reproduced.<br/><br/>To help developers correct this error, do you accept <b>the transmission of your logs</b> per message?<br/><small>(No confidential data is sent)</small>"
+    "ISSUE_524_SEND_LOG": "The transaction was rejected because of a known problem (issue #524) but not reproduced.<br/><br/>To help developers correct this error, do you accept <b>the transmission of your logs</b> per message?<br/><small>(No confidential data is sent)</small>",
+    "ENABLE_EXPERT_MODE_TO_CHANGE_NODE": "<b class=\"assertive\">Warning:</b> Do you want to <b>manually change</b> the peer?<br/><br/>If you proceed:<ul><li> - <b>Expert mode</b> will be activated;</li><li> - You can return to automatic peer selection by simply <b>deactivating expert mode</b>.</li></ul>"
   },
   "MODE": {
     "DEMO": {
diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json
index ec5c816180e5966cd0d55ed32ffd4b0281798493..752bc04a172483eb7fcd5aa9d236c4be93e330c2 100644
--- a/www/i18n/locale-en.json
+++ b/www/i18n/locale-en.json
@@ -849,7 +849,8 @@
     "SAVE_BEFORE_LEAVE_TITLE": "Changes not saved",
     "LOGOUT": "Are you sure you want to logout?",
     "USE_FALLBACK_NODE": "Peer <b>{{old}}</b> unreachable or invalid address.<br/><br/>Do you want to temporarily use the <b>{{new}}</b> node?",
-    "ISSUE_524_SEND_LOG": "The transaction was rejected because of a known problem (issue #524) but not reproduced.<br/><br/>To help developers correct this error, do you accept <b>the transmission of your logs</b> per message?<br/><small>(No confidential data is sent)</small>"
+    "ISSUE_524_SEND_LOG": "The transaction was rejected because of a known problem (issue #524) but not reproduced.<br/><br/>To help developers correct this error, do you accept <b>the transmission of your logs</b> per message?<br/><small>(No confidential data is sent)</small>",
+    "ENABLE_EXPERT_MODE_TO_CHANGE_NODE": "<b class=\"assertive\">Warning:</b> Do you want to <b>manually change</b> the Duniter node?<br/><br/>If you continue:<ul><li> - <b>Expert mode</b> will be activated;</li><li> - You can return to automatic node selection by simply <b>deactivating expert mode</b>.</li></ul>"
   },
   "MODE": {
     "DEMO": {
diff --git a/www/i18n/locale-eo-EO.json b/www/i18n/locale-eo-EO.json
index 9dceb1e94a7fce7e8e60278f8295a95fba5b4319..c504731fc046063d6850d9ec5ce997392bfe98ea 100644
--- a/www/i18n/locale-eo-EO.json
+++ b/www/i18n/locale-eo-EO.json
@@ -830,7 +830,8 @@
     "SAVE_BEFORE_LEAVE_TITLE": "Modifoj ne registritaj",
     "LOGOUT": "Ĉu vi certas, ke vi volas malkonektiĝi?",
     "USE_FALLBACK_NODE": "Nodo <b>{{old}}</b> neatingebla aŭ adreso nevalida.<br/><br/>Ĉu vi volas provizore uzi la nodon <b>{{new}}</b> ?",
-    "ISSUE_524_SEND_LOG": "La spezo estis forĵetita, pro konata anomalio (petslipo #524) sed <b>ne ripetita</b>.<br/><br/>Por helpi la programistojn korekti tiun eraron, <b>ĉu vi akceptas la sendadon de viaj protokolaj dosieroj</b> per mesaĝo?<br/><small>(neniu konfidenca dateno estas sendita)</small>."
+    "ISSUE_524_SEND_LOG": "La spezo estis forĵetita, pro konata anomalio (petslipo #524) sed <b>ne ripetita</b>.<br/><br/>Por helpi la programistojn korekti tiun eraron, <b>ĉu vi akceptas la sendadon de viaj protokolaj dosieroj</b> per mesaĝo?<br/><small>(neniu konfidenca dateno estas sendita)</small>.",
+    "ENABLE_EXPERT_MODE_TO_CHANGE_NODE": "<b class=\"assertive\">Averto:</b> Ĉu vi volas <b>mane ŝanĝi</b> la nodon?<br/><br/>Se vi daŭrigas:<ul><li> - La <b>eksperta reĝimo</b> estos aktivigita;</li><li> - Vi povos reveni al aŭtomata nodo-selekto simple <b>malaktivigante la ekspertan reĝimon</b>.</li></ul>"
   },
   "MODE": {
     "DEMO": {
diff --git a/www/i18n/locale-es-CT.json b/www/i18n/locale-es-CT.json
index 172f338f3ff16c98364e7c7f3346698554cdc939..816c02a84d3913c8e105d2cf43054a74dbd80e27 100644
--- a/www/i18n/locale-es-CT.json
+++ b/www/i18n/locale-es-CT.json
@@ -913,7 +913,8 @@
     "SAVE_BEFORE_LEAVE": "¿Desea <b>guardar sus cambios</b> antes de abandonar la página?",
     "SAVE_BEFORE_LEAVE_TITLE": "Cambios no registrados",
     "LOGOUT": "¿Desea desconectarse?",
-    "USE_FALLBACK_NODE": "Nodo <b>{{old}}</b> inalcanzable o dirección inválida.<br/><br/>¿Desea utilizar temporalmente el nodo <b>{{new}}</b>?"
+    "USE_FALLBACK_NODE": "Nodo <b>{{old}}</b> inalcanzable o dirección inválida.<br/><br/>¿Desea utilizar temporalmente el nodo <b>{{new}}</b>?",
+    "ENABLE_EXPERT_MODE_TO_CHANGE_NODE": "<b class=\"assertive\">Advertència:</b> Vols <b>canviar manualment</b> el node Duniter?<br/><br/>Si continues:<ul><li> - S'activarà el <b>modo experto</b>;</li><li> - Podràs tornar a la selecció automàtica de nodes simplement <b>desactivant el modo experto</b>.</li></ul>"
   },
   "DOWNLOAD": {
     "POPUP_TITLE": "<b>Revocación del archivo</b>",
diff --git a/www/i18n/locale-es-ES.json b/www/i18n/locale-es-ES.json
index aabfca48b43714ed465f3832cbc37090d51cc621..1bd2ed81d1c530fb72c0591f9ccc7c9123da47cd 100644
--- a/www/i18n/locale-es-ES.json
+++ b/www/i18n/locale-es-ES.json
@@ -915,7 +915,8 @@
     "SAVE_BEFORE_LEAVE": "¿Desea <b>guardar sus cambios</b> antes de abandonar la página?",
     "SAVE_BEFORE_LEAVE_TITLE": "Cambios no registrados",
     "LOGOUT": "¿Desea desconectarse?",
-    "USE_FALLBACK_NODE": "Nodo <b>{{old}}</b> inalcanzable o dirección inválida.<br/><br/>¿Desea utilizar temporalmente el nodo <b>{{new}}</b>?"
+    "USE_FALLBACK_NODE": "Nodo <b>{{old}}</b> inalcanzable o dirección inválida.<br/><br/>¿Desea utilizar temporalmente el nodo <b>{{new}}</b>?",
+    "ENABLE_EXPERT_MODE_TO_CHANGE_NODE": "<b class=\"assertive\">Advertencia:</b> ¿Quieres <b>cambiar manualmente</b> el nodo?<br/><br/>Si continúas:<ul><li> - Se activará el <b>modo experto</b>;</li><li> - Podrás volver a la selección automática de nodos simplemente <b>desactivando el modo experto</b>.</li></ul>"
   },
   "DOWNLOAD": {
     "POPUP_TITLE": "<b>Revocación del archivo</b>",
diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json
index 8a013ebcf68d84f82c1166a5e0c2bcac7c05f1f9..141f513f440845ec3a7966fcfc186c255c9738ea 100644
--- a/www/i18n/locale-fr-FR.json
+++ b/www/i18n/locale-fr-FR.json
@@ -853,7 +853,8 @@
     "SAVE_BEFORE_LEAVE_TITLE": "Modifications non enregistrées",
     "LOGOUT": "Êtes-vous sûr de vouloir vous déconnecter ?",
     "USE_FALLBACK_NODE": "Nœud <b>{{old}}</b> injoignable ou adresse invalide.<br/><br/>Voulez-vous temporairement utiliser le nœud <b>{{new}}</b> ?",
-    "ISSUE_524_SEND_LOG": "La transaction a été rejetée, à cause d'une anomalie connue (ticket #524) mais <b>non reproduite</b>.<br/><br/>Pour aider les développeurs à corriger cette erreur, <b>acceptez-vous la transmission de vos logs</b> par message ?<br/><small>(aucune donnée confidentielle n'est envoyée)</small>."
+    "ISSUE_524_SEND_LOG": "La transaction a été rejetée, à cause d'une anomalie connue (ticket #524) mais <b>non reproduite</b>.<br/><br/>Pour aider les développeurs à corriger cette erreur, <b>acceptez-vous la transmission de vos logs</b> par message ?<br/><small>(aucune donnée confidentielle n'est envoyée)</small>.",
+    "ENABLE_EXPERT_MODE_TO_CHANGE_NODE": "<b class=\"assertive\">Avertissement :</b> Voulez-vous <b>changer manuellement</b> le nœud ?<br/><br/>Si vous continuez :<ul><li> - Le <b>mode expert</b> sera activé;</li><li> - Vous pourrez revenir à la sélection automatique du nœud, simplement <b>en désactivant le mode expert</b>.</li></ul>"
   },
   "MODE": {
     "DEMO": {
diff --git a/www/i18n/locale-it-IT.json b/www/i18n/locale-it-IT.json
index 933c7f01e1e0ad52021715f9fee7474976511356..31780da81c841d223a4a36e151a6b6cb9998253b 100644
--- a/www/i18n/locale-it-IT.json
+++ b/www/i18n/locale-it-IT.json
@@ -814,9 +814,9 @@
     "CERTIFY_RULES": "<b class=\"assertive\">Non certificare un conto</b> se credi che: <ul><li>1.) L'identità della persona potrebbe essere finta.<li>2.) La persona ha già un conto certicato.<li>3.) La persona trasgredisce la regola 1 o 2 o entrambe. (Certifica conti finti o gemelli).</ul></small><br/>Sei sicuro di voler certificare questa identità?",
     "FULLSCREEN": "Aprire l'applicazione a schermo intero?",
     "EXIT_APP": "Chiudere l'applicazione?",
-"TRANSFER": "<b>Resoconto del bonifico:</b><br/><br/><ul><li> - Inviato da: <b>{{from}}</b></li><li> - A: <b>{{to}}</b></li><li> - Importo: <b>{{amount}} {{unit}}</b></li><li> - Comemnto: <i>{{comment}}</i></li></ul><br/><b>Sei sicuro di voler procedere con questo bonifico?</b>",
-   "TRANSFER_ALL": "<b>Riepilogo del bonifico:</b><br/><br/><ul><li> - Da: <b>{{from}}</b></li><li> - A: <b>{{to}}</b></li><li> - Importo: <b>{{amount}} {{unit}}</b></li><li> - Commento: <i>{{comment}}</i></li><br/><li> - Resto : <b>{{restAmount}} {{unit}}</b> a <b>{{restTo}}</b></li></ul><br/><b>Sicuro di voler fare questo bonifico?</b>",
-   "MEMBERSHIP_OUT": "Questa operazione è <b>irreversibile</b>.<br/></br/><b>Sei sicuro di voler cancellare la tua presenza nella RdF?</b>",
+    "TRANSFER": "<b>Resoconto del bonifico:</b><br/><br/><ul><li> - Inviato da: <b>{{from}}</b></li><li> - A: <b>{{to}}</b></li><li> - Importo: <b>{{amount}} {{unit}}</b></li><li> - Comemnto: <i>{{comment}}</i></li></ul><br/><b>Sei sicuro di voler procedere con questo bonifico?</b>",
+    "TRANSFER_ALL": "<b>Riepilogo del bonifico:</b><br/><br/><ul><li> - Da: <b>{{from}}</b></li><li> - A: <b>{{to}}</b></li><li> - Importo: <b>{{amount}} {{unit}}</b></li><li> - Commento: <i>{{comment}}</i></li><br/><li> - Resto : <b>{{restAmount}} {{unit}}</b> a <b>{{restTo}}</b></li></ul><br/><b>Sicuro di voler fare questo bonifico?</b>",
+    "MEMBERSHIP_OUT": "Questa operazione è <b>irreversibile</b>.<br/></br/><b>Sei sicuro di voler cancellare la tua presenza nella RdF?</b>",
     "MEMBERSHIP_OUT_2": "Questa operazione è <b>irreversibile</b>!<br/><br/>Sei sicuro <b>di voler revocare la tua identità</b>?",
     "LOGIN_UNUSED_WALLET_TITLE": "Errore di battitura?",
     "LOGIN_UNUSED_WALLET": "Il conto sembra <b>inattivo</b>.<br/><br/>Probabilmente è un<b>errore di battitura</b> delle tue credenziali. Per favore riprova, verificando che la <b>chiave pubblica sia la tua<b/>.",
@@ -831,8 +831,9 @@
     "SAVE_BEFORE_LEAVE_TITLE": "Modifiche non salvate",
     "LOGOUT": "Sei sicuro di voler chiudere la sessione?",
     "USE_FALLBACK_NODE": "Nodo <b>{{old}}</b> indisponibile o indirizzo errato.<br/><br/>Vuoi utilizzare temporanemante il <b>{{new}}</b> nodo?",
-    "ISSUE_524_SEND_LOG": "La transazione è stata annullata a causa di un errore conosciuto (issue #524) ma non riprodotto. <br/><br/>Per aiutare gli sviluppatori a risolvere questo errore, acconsenti all'<b>invio dei tuoi logs</b> per messaggio?<br/><small>(Non viene inviato nessun dato confidenziale)</small>"
- },
+    "ISSUE_524_SEND_LOG": "La transazione è stata annullata a causa di un errore conosciuto (issue #524) ma non riprodotto. <br/><br/>Per aiutare gli sviluppatori a risolvere questo errore, acconsenti all'<b>invio dei tuoi logs</b> per messaggio?<br/><small>(Non viene inviato nessun dato confidenziale)</small>",
+    "ENABLE_EXPERT_MODE_TO_CHANGE_NODE": "<b class=\"assertive\">Avviso:</b> Vuoi <b>cambiare manualmente</b> il nodo?<br/><br/>Se continui:<ul><li> - Verrà attivata la <b>modalità esperto</b>;</li><li> - Potrai tornare alla selezione automatica del nodo semplicemente <b>disattivando la modalità esperto</b>.</li></ul>"
+  },
  "MODE": {
    "DEMO": {
      "BADGE": "Demo",
diff --git a/www/i18n/locale-nl-NL.json b/www/i18n/locale-nl-NL.json
index 71e6acd1382883b2af992fadcdf5168a881b322f..64517eb1038ee7ff0d556ce6ca5f6565f5184063 100644
--- a/www/i18n/locale-nl-NL.json
+++ b/www/i18n/locale-nl-NL.json
@@ -510,7 +510,8 @@
     "NOT_NEED_RENEW_MEMBERSHIP": "Je lidmaatschap hoeft niet verlengd te worden (het zal pas verlopen na {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Weet je zeker</b> dat je een verlengingsaanvraag wil versturen?",
     "SAVE_BEFORE_LEAVE": "Wil je <b>je wijzigingen opslaan</b> voor je de pagina verlaat?",
     "SAVE_BEFORE_LEAVE_TITLE": "Wijzigingen niet opgeslagen",
-    "LICENCE": "Ik heb gelezen en geaccepteerd de voorwaarden van de vergunning G1"
+    "LICENCE": "Ik heb gelezen en geaccepteerd de voorwaarden van de vergunning G1",
+    "ENABLE_EXPERT_MODE_TO_CHANGE_NODE": "<b class=\"assertive\">Waarschuwing:</b> Wil je het knooppunt <b>handmatig wijzigen</b>?<br/><br/>Als je doorgaat:<ul><li> - De <b>expertmodus</b> wordt geactiveerd;</li><li> - Je kunt terugkeren naar automatische knooppuntselectie door eenvoudigweg de <b>expertmodus uit te schakelen</b>.</li></ul>"
   },
   "DOWNLOAD": {
     "POPUP_TITLE": "<b>Intrekkingsdocument</b>",
diff --git a/www/i18n/locale-pt-PT.json b/www/i18n/locale-pt-PT.json
index 71ab7efc8c1f1888915af4c35f0d806288c0a796..cc360777b4bedc89d0249fc42414d9a1d6d4d5da 100644
--- a/www/i18n/locale-pt-PT.json
+++ b/www/i18n/locale-pt-PT.json
@@ -914,7 +914,8 @@
     "SAVE_BEFORE_LEAVE": "Deseja <b>guardar as alterações</b> antes de abandonar a página?",
     "SAVE_BEFORE_LEAVE_TITLE": "Alterações não guardadas",
     "LOGOUT": "Deseja desconectar-se?",
-    "USE_FALLBACK_NODE": "Nó <b>{{old}}</b> indisponível ou endereço inválido.<br/><br/>Deseja utilizar temporalmente o nó <b>{{new}}</b>?"
+    "USE_FALLBACK_NODE": "Nó <b>{{old}}</b> indisponível ou endereço inválido.<br/><br/>Deseja utilizar temporalmente o nó <b>{{new}}</b>?",
+    "ENABLE_EXPERT_MODE_TO_CHANGE_NODE": "<b class=\"assertive\">Aviso:</b> Queres <b>alterar manualmente</b> o nó Duniter?<br/><br/>Se continuares:<ul><li> - Será ativado o <b>modo perito</b>;</li><li> - Poderás voltar à seleção automática do nó, simplesmente <b>desativando o modo perito</b>.</li></ul>"
   },
   "DOWNLOAD": {
     "POPUP_TITLE": "<b>Revogação do arquivo</b>",
diff --git a/www/index.html b/www/index.html
index 2d57619a9cbb17c871060930dff5d9233535ab32..00fbb79d1740ffe1f6efa1b9fb667af4a812fcd0 100644
--- a/www/index.html
+++ b/www/index.html
@@ -279,6 +279,7 @@
     <script src="dist/dist_js/app/directives.js"></script>
     <script src="dist/dist_js/app/filters.js"></script>
     <script src="dist/dist_js/app/platform.js"></script>
+    <script src="dist/dist_js/app/functions.js"></script>
     <!-- endbuild -->
 
     <!-- build:js config.js -->
diff --git a/www/js/controllers/network-controllers.js b/www/js/controllers/network-controllers.js
index 51a53bb2825f71632cf0bafcbffce02d259a49a6..35289842cbbbdd9faeada129d8c8c9e2bd12d40e 100644
--- a/www/js/controllers/network-controllers.js
+++ b/www/js/controllers/network-controllers.js
@@ -203,7 +203,7 @@ function NetworkLookupController($scope,  $state, $location, $ionicPopover, $win
       .then(function() {
         $scope.updating = false;
       });
-  }
+  };
 
   $scope.updateView = function(data) {
     console.debug("[peers] Updating UI");
diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js
index b6e756bdec6cf0a7627e85946392ef521201812a..9292608e7ce12b01fb72ede530ae668cb61cfa5a 100644
--- a/www/js/controllers/settings-controllers.js
+++ b/www/js/controllers/settings-controllers.js
@@ -29,7 +29,11 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
   $scope.loading = true;
   $scope.nodePopup = {};
   $scope.bma = BMA;
-
+  $scope.listeners = [];
+  $scope.platform = {
+    loading: !csPlatform.isStarted(),
+    loadingMessage: 'COMMON.LOADING'
+  };
 
   $scope.keepAuthIdleLabels = {
     /*0: {
@@ -80,7 +84,9 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
   };
   $scope.blockValidityWindows = _.keys($scope.blockValidityWindowLabels);
 
-  $scope.$on('$ionicView.enter', function() {
+  $scope.enter = function() {
+    $scope.addListeners();
+
     $q.all([
       csSettings.ready(),
       csCurrency.parameters()
@@ -91,7 +97,7 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
         .then(function(parameters) {
           var avgGenTime = parameters && parameters.avgGenTime;
           if (!avgGenTime || avgGenTime < 0) {
-            console.warn("[settings] Could not not currency parameters. Using default G1 'avgGenTime' (300s)");
+            console.warn('[settings] Could not not currency parameters. Using default G1 \'avgGenTime\' (300s)');
             avgGenTime = 300; /* = G1 value = 5min */
           }
           _.each($scope.blockValidityWindows, function(blockCount) {
@@ -102,7 +108,7 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
         })
     ])
     .then($scope.load);
-  });
+  };
 
   $scope.setPopupForm = function(popupForm) {
     $scope.popupForm = popupForm;
@@ -111,6 +117,8 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
   $scope.load = function() {
     $scope.loading = true; // to avoid the call of csWallet.store()
 
+    $scope.platform.loading = !csPlatform.isStarted();
+
     // Fill locales
     $scope.locales = angular.copy(csSettings.locales);
 
@@ -130,6 +138,22 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
     }, 100);
   };
 
+
+  $scope.addListeners = function() {
+    $scope.listeners = [
+      // Listen platform start message
+      csPlatform.api.start.on.message($scope, function(message) {
+        $scope.platform.loading = !csPlatform.isStarted();
+        $scope.platform.loadingMessage = message;
+      })
+    ];
+  };
+
+  $scope.leave = function() {
+    console.debug('[settings] Leaving page');
+    $scope.removeListeners();
+  }
+
   $scope.reset = function() {
     if ($scope.actionsPopover) {
       $scope.actionsPopover.hide();
@@ -149,7 +173,30 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
   };
 
   // Change node
-  $scope.changeNode= function(node) {
+  $scope.changeNode = function(node, confirm) {
+
+    // If platform not stared yet: wait then loop
+    if (!csPlatform.isStarted()) {
+      UIUtils.loading.update({template: this.loadingMessage});
+      return csPlatform.ready()
+        .then(function() {
+          return $scope.changeNode(node, confirm); // Loop
+        });
+    }
+
+    // Ask user to confirm, before allow to change the node
+    if (!confirm && !$scope.formData.expertMode) {
+      return UIUtils.alert.confirm('CONFIRM.ENABLE_EXPERT_MODE_TO_CHANGE_NODE', 'CONFIRM.POPUP_WARNING_TITLE', {
+        cssClass: 'warning',
+        cancelText: 'COMMON.BTN_NO',
+        okText: 'COMMON.BTN_YES_CONTINUE',
+        okType: 'button-assertive'
+      })
+      .then(function(confirm) {
+        if (!confirm) return;
+        $scope.changeNode(node, true);
+      });
+    }
 
     var port = !!$scope.formData.node.port && $scope.formData.node.port != 80 && $scope.formData.node.port != 443 ? $scope.formData.node.port : undefined;
     node = node || {
@@ -166,6 +213,10 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
         newNode.useSsl === $scope.formData.node.useSsl && !$scope.formData.node.temporary) {
         return; // same node = nothing to do
       }
+
+      // Change to expert mode
+      $scope.formData.expertMode = true;
+
       UIUtils.loading.show();
 
       BMA.isAlive(newNode)
@@ -174,7 +225,7 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
             UIUtils.loading.hide();
             return UIUtils.alert.error('ERROR.INVALID_NODE_SUMMARY')
               .then(function(){
-                $scope.changeNode(newNode); // loop
+                $scope.changeNode(newNode, true); // loop
               });
           }
           UIUtils.loading.hide();
@@ -216,7 +267,7 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
         }
       })
       .then(function(newNode) {
-        $scope.changeNode(newNode);
+        $scope.changeNode(newNode, true);
       });
   };
 
@@ -284,8 +335,12 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
     }
     $scope.saving = true;
 
+    var now = Date.now();
+
     // Async - to avoid UI lock
     return $timeout(function() {
+      console.debug('[settings] Saving...');
+
       // Make sure to format helptip
       $scope.cleanupHelpTip();
 
@@ -301,7 +356,8 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
     }, 100)
     .then(function() {
       //return $timeout(function() {
-        $scope.saving = false;
+      $scope.saving = false;
+      console.debug('[settings] Saving [OK] in {0}ms'.format(Date.now() - now));
       //}, 100);
     });
   };
@@ -395,4 +451,20 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti
         csSettings.store();
       });
   };
+
+
+
+  $scope.removeListeners = function() {
+    if ($scope.listeners.length) {
+      console.debug('[settings] Closing listeners');
+      _.forEach($scope.listeners, function(remove){
+        remove();
+      });
+      $scope.listeners = [];
+    }
+  };
+
+  $scope.$on('$ionicView.enter', $scope.enter);
+  $scope.$on('$ionicView.beforeLeave', $scope.leave);
+
 }
diff --git a/www/js/functions.js b/www/js/functions.js
new file mode 100644
index 0000000000000000000000000000000000000000..b773f31f41c2f43c9a13417bbcef12d228e8146b
--- /dev/null
+++ b/www/js/functions.js
@@ -0,0 +1,37 @@
+
+// Workaround to add "".startsWith() if not present
+if (typeof String.prototype.startsWith !== 'function') {
+  console.debug("Adding String.prototype.startsWith() -> was missing on this platform");
+  String.prototype.startsWith = function(prefix, position) {
+    return this.indexOf(prefix, position) === 0;
+  };
+}
+
+// Workaround to add "".startsWith() if not present
+if (typeof String.prototype.trim !== 'function') {
+  console.debug("Adding String.prototype.trim() -> was missing on this platform");
+  // Make sure we trim BOM and NBSP
+  var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
+  String.prototype.trim = function() {
+    return this.replace(rtrim, '');
+  };
+}
+
+// Workaround to add Math.trunc() if not present - fix #144
+if (Math && typeof Math.trunc !== 'function') {
+  console.debug("Adding Math.trunc() -> was missing on this platform");
+  Math.trunc = function(number) {
+    return parseInt((number - 0.5).toFixed());
+  };
+}
+
+// Workaround to add "".format() if not present
+if (typeof String.prototype.format !== 'function') {
+  console.debug("Adding String.prototype.format() -> was missing on this platform");
+  String.prototype.format = function() {
+    var args = arguments;
+    return this.replace(/{(\d+)}/g, function(match, number) {
+      return typeof args[number] != 'undefined' ? args[number] : match;
+    });
+  };
+}
diff --git a/www/js/platform.js b/www/js/platform.js
index d1cd933c4cea62d78482e253d1ca134bcddccd3d..44720b39edda88d71b0028b41a4f1f97d820452c 100644
--- a/www/js/platform.js
+++ b/www/js/platform.js
@@ -197,8 +197,8 @@ angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services']
       var askUserConfirmation = csSettings.data.expertMode;
 
       return csNetwork.getSynchronizedBmaPeers(BMA, {
-        timeout:  Math.min(csConfig.timeout, 10000 /*10s max*/)
-      })
+          timeout:  Math.min(csConfig.timeout, 10000 /*10s max*/)
+        })
         .then(function(peers) {
 
           if (!peers.length) return; // No peer found: exit
@@ -270,7 +270,7 @@ angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services']
               csSettings.data.node.temporary = true;
 
               return BMA.copy(node);
-            })
+            });
         });
     }
 
@@ -417,10 +417,13 @@ angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services']
           addListeners();
           startPromise = null;
           started = true;
+
+          api.start.raise.message(''); // Reset message
         })
         .catch(function(err) {
           startPromise = null;
           started = false;
+          api.start.raise.message(''); // Reset message
           if($state.current.name !== $rootScope.errorState) {
             $state.go($rootScope.errorState, {error: 'peer'});
           }
@@ -560,40 +563,3 @@ angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services']
     });
   })
 ;
-
-// Workaround to add "".startsWith() if not present
-if (typeof String.prototype.startsWith !== 'function') {
-  console.debug("Adding String.prototype.startsWith() -> was missing on this platform");
-  String.prototype.startsWith = function(prefix, position) {
-    return this.indexOf(prefix, position) === 0;
-  };
-}
-
-// Workaround to add "".startsWith() if not present
-if (typeof String.prototype.trim !== 'function') {
-  console.debug("Adding String.prototype.trim() -> was missing on this platform");
-  // Make sure we trim BOM and NBSP
-  var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
-  String.prototype.trim = function() {
-    return this.replace(rtrim, '');
-  };
-}
-
-// Workaround to add Math.trunc() if not present - fix #144
-if (Math && typeof Math.trunc !== 'function') {
-  console.debug("Adding Math.trunc() -> was missing on this platform");
-  Math.trunc = function(number) {
-    return parseInt((number - 0.5).toFixed());
-  };
-}
-
-// Workaround to add "".format() if not present
-if (typeof String.prototype.format !== 'function') {
-  console.debug("Adding String.prototype.format() -> was missing on this platform");
-  String.prototype.format = function() {
-    var args = arguments;
-    return this.replace(/{(\d+)}/g, function(match, number) {
-      return typeof args[number] != 'undefined' ? args[number] : match;
-    });
-  };
-}
diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js
index 1a88a9ce5d1a75c073fbf46aa92220cb0d8bce23..a7de712bf2aa3d53a9b3af782b5a7d5612d72e9d 100644
--- a/www/js/services/bma-services.js
+++ b/www/js/services/bma-services.js
@@ -382,7 +382,9 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium.
 
     that.filterAliveNodes = function(fallbackNodes, timeout) {
       timeout = timeout || csConfig.timeout;
-      var fallbackNodes = _.filter(fallbackNodes || [], function(node) {
+
+      // Filter to exclude the current BMA node
+      fallbackNodes = _.filter(fallbackNodes || [], function(node) {
         node.server = node.server || node.host + ((!node.port && node.port != 80 && node.port != 443) ? (':' + node.port) : '');
         var same = that.node.same(node);
         if (same) console.debug('[BMA] Skipping fallback node [{0}]: same as current BMA node'.format(node.server));
@@ -399,7 +401,7 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium.
             else {
               console.error('[BMA] Unreachable (or not compatible) fallback node [{0}]: skipping'.format(node.server));
             }
-          })
+          });
         }))
         .then(function() {
           return aliveNodes;
diff --git a/www/js/services/device-services.js b/www/js/services/device-services.js
index b5d21dd7c8993902552c3dfd63c8daf4b4361222..4353a4a2b0c1847c798cee3e783e95cee0a9ef51 100644
--- a/www/js/services/device-services.js
+++ b/www/js/services/device-services.js
@@ -4,7 +4,7 @@ angular.module('cesium.device.services', ['cesium.utils.services', 'cesium.setti
 
   .factory('Device', function($rootScope, $translate, $ionicPopup, $q, Api,
       // removeIf(no-device)
-      $cordovaClipboard, $cordovaBarcodeScanner, $cordovaCamera,
+      $cordovaClipboard, $cordovaBarcodeScanner, $cordovaCamera, $cordovaNetwork,
       // endRemoveIf(no-device)
       ionicReady) {
       'ngInject';
@@ -143,6 +143,17 @@ angular.module('cesium.device.services', ['cesium.utils.services', 'cesium.setti
           cordova.plugins.Keyboard.close();
         }
       };
+      exports.network = {
+        connectionType: function() {
+          return navigator.connection.type || 'unknown';
+        },
+        isOnline: function() {
+          return navigator.connection.type !== Connection.NONE;
+        },
+        isOffline: function() {
+          return navigator.connection.type === Connection.NONE;
+        }
+      };
 
       function getLastIntent() {
         var deferred = $q.defer();
@@ -271,13 +282,15 @@ angular.module('cesium.device.services', ['cesium.utils.services', 'cesium.setti
               exports.barcode.enable = cordova && cordova.plugins && !!cordova.plugins.barcodeScanner && (!exports.isOSX() || exports.isIOS());
               exports.clipboard.enable = cordova && cordova.plugins && !!cordova.plugins.clipboard;
               exports.intent.enable = window && !!window.plugins.launchmyapp;
+              exports.clipboard.enable = cordova && cordova.plugins && !!cordova.plugins.clipboard;
+              exports.network.enable = navigator.connection && !!navigator.connection.type;
 
               if (exports.keyboard.enable) {
                 angular.extend(exports.keyboard, cordova.plugins.Keyboard);
               }
 
-              console.debug('[device] Ionic platform ready, with {camera: {0}, barcode: {1}, keyboard: {2}, clipboard: {3}, intent: {4}}'
-                .format(exports.camera.enable, exports.barcode.enable, exports.keyboard.enable, exports.clipboard.enable, exports.intent.enable));
+              console.debug('[device] Ionic platform ready, with {camera: {0}, barcode: {1}, keyboard: {2}, clipboard: {3}, intent: {4}, network: {5}}'
+                .format(exports.camera.enable, exports.barcode.enable, exports.keyboard.enable, exports.clipboard.enable, exports.intent.enable, exports.network.enable));
 
               if (cordova.InAppBrowser) {
                 console.debug('[device] Enabling InAppBrowser');
diff --git a/www/js/services/network-services.js b/www/js/services/network-services.js
index 83da91b1891114bc951b9b461b214644f2cd6441..778fd80d12918af0169412ff1cfdc99ae6eaf550 100644
--- a/www/js/services/network-services.js
+++ b/www/js/services/network-services.js
@@ -15,6 +15,7 @@ angular.module('cesium.network.services', ['ngApi', 'cesium.currency.services',
     startPromise,
 
     data = {
+      pid: 0, // Start PID
       bma: null,
       listeners: [],
       loading: true,
@@ -61,6 +62,7 @@ angular.module('cesium.network.services', ['ngApi', 'cesium.currency.services',
     },
 
     resetData = function() {
+      data.starCounter = 0;
       data.bma = null;
       data.listeners = [];
       data.peers.splice(0);
@@ -178,10 +180,11 @@ angular.module('cesium.network.services', ['ngApi', 'cesium.currency.services',
         else if (data.loading && !data.searchingPeersOnNetwork) {
           data.loading = false;
           $interval.cancel(interval);
+
           // The peer lookup end, we can make a clean final report
           sortPeers(true/*update main buid*/);
 
-          console.debug('[network] {0} peers found.'.format(data.peers.length));
+          console.debug('[network] {0} peer(s) found.'.format(data.peers.length));
         }
       }, 1000);
 
@@ -462,7 +465,6 @@ angular.module('cesium.network.services', ['ngApi', 'cesium.currency.services',
       // Apply filter
       if (!applyPeerFilter(peer)) return $q.when();
 
-      var startRefreshTime = Date.now();
       if (!data.filter.online || (!data.filter.online && peer.status === 'DOWN') || !peer.getHost() /*fix #537*/) {
         peer.online = false;
         return $q.when(peer);
@@ -512,7 +514,7 @@ angular.module('cesium.network.services', ['ngApi', 'cesium.currency.services',
         return $q.when(peer);
       }
 
-      const timeout = Math.max(500, remainingTime()); // >= 500ms
+      var timeout = Math.max(500, remainingTime()); // >= 500ms
       peer.api = peer.api || BMA.lightInstance(peer.getHost(), peer.getPort(), peer.isSsl(), timeout);
 
       // Get current block
@@ -781,16 +783,17 @@ angular.module('cesium.network.services', ['ngApi', 'cesium.currency.services',
       if (startPromise) {
         console.warn('[network-service] Waiting previous start to be closed...');
         return startPromise.then(function() {
-          return start(bma, options)
-        })
+          return start(bma, options);
+        });
       }
 
       options = options || {};
       bma = bma || BMA;
+      var pid = data.pid;
       startPromise = bma.ready()
         .then(function() {
-          close();
-
+          close(pid);
+          data.pid++;
           data.bma = bma;
           data.filter = options.filter ? angular.merge(data.filter, options.filter) : data.filter;
           data.sort = options.sort ? angular.merge(data.sort, options.sort) : data.sort;
@@ -816,18 +819,21 @@ angular.module('cesium.network.services', ['ngApi', 'cesium.currency.services',
 
           return loadPeers()
             .then(function(peers){
-              console.debug('[network] Started in {0}ms, {1} peers found'.format(Date.now() - now, peers.length));
+              if (peers) console.debug('[network] Started in {0}ms, {1} peers found'.format(Date.now() - now, peers.length));
               return data;
             });
         });
       return startPromise;
     },
 
-    close = function() {
-      if (data.bma) {
-        console.info('[network] Stopping...');
-        removeListeners();
-        resetData();
+    close = function(pid) {
+        if (data.bma) {
+          console.info('[network] Stopping...');
+          removeListeners();
+          resetData();
+        }
+      if (interval && pid === data.pid) {
+        $interval.cancel(interval);
       }
       startPromise = null;
     },
@@ -849,11 +855,17 @@ angular.module('cesium.network.services', ['ngApi', 'cesium.currency.services',
 
     getMainBlockUid = function(bma, options) {
       var wasStarted = isStarted();
+      var pid = data.pid + 1;
       return startIfNeed(bma, options)
         .then(function(data) {
           var buid = data.mainBlock && data.mainBlock.buid;
-          if (!wasStarted) close();
+          if (!wasStarted) close(pid);
           return buid;
+        })
+        .catch(function(err) {
+          console.error('[network] Failed to get main block');
+          if (!wasStarted) close(pid);
+          throw err;
         });
     },
 
@@ -865,19 +877,20 @@ angular.module('cesium.network.services', ['ngApi', 'cesium.currency.services',
       options.filter.ssl = isHttpsMode ? true : undefined;
       options.filter.online = true;
       options.filter.expertMode = false;
-      console.info('[network] Getting synchronized BMA peers...');
 
-      var wasStarted = isStarted();
       var now = Date.now();
+      console.info('[network] Getting synchronized BMA peers...');
 
+      var wasStarted = isStarted();
+      var pid = data.pid + 1;
       return startIfNeed(bma, options)
         .then(function(data){
-          var peers = _.filter(data.peers, function(peer) {
+          var peers = data && _.filter(data.peers, function(peer) {
             return peer.hasMainConsensusBlock && peer.isBma();
           });
 
           // Log
-          if (peers.length) {
+          if (peers && peers.length > 0) {
             console.info('[network] Found {0}/{1} BMA peers on main consensus block #{2} - in {3}ms'.format(
               peers.length,
               data.peers.length,
@@ -885,12 +898,19 @@ angular.module('cesium.network.services', ['ngApi', 'cesium.currency.services',
               Date.now() - now));
           }
           else {
-            console.warn('[network] No synchronized BMA peers found, in {1}ms'.format(Date.now() - now))
+            console.warn('[network] No synchronized BMA peers found, in {0}ms'.format(Date.now() - now));
           }
 
-          if (!wasStarted) close();
+          if (!wasStarted) close(pid);
 
           return peers;
+        })
+        .catch(function(err) {
+          console.error('[network] Error while getting synchronized BMA peers', err);
+
+          if (!wasStarted) close(pid);
+
+          throw err;
         });
     };
 
diff --git a/www/templates/settings/settings.html b/www/templates/settings/settings.html
index c3233d5b6cc596b8192c5afd6679775585042211..eefef17e87f972180bd616ae1ea7d69278fb4119 100644
--- a/www/templates/settings/settings.html
+++ b/www/templates/settings/settings.html
@@ -216,28 +216,40 @@
 
         <!-- Duniter node -->
         <div class="item ink item-text-wrap item-icon-right" ng-click="changeNode()">
-          <div class="input-label" translate>SETTINGS.PEER</div>
-
-          <ng-if ng-if="formData.node.temporary">
-            <!-- node temporary changed -->
-            <ng-if ng-if="formData.expertMode">
-              <h4 class="gray text-wrap assertive" >
-                <span class="ion-alert-circled"></span>
-                <span ng-bind-html="'SETTINGS.PEER_CHANGED_TEMPORARY' | translate "></span>
+          <div class="input-label" ng-class="{'gray': !formData.expertMode}" translate>SETTINGS.PEER</div>
+
+          <!-- node manually selected (expert mode) -->
+          <ng-if ng-if="formData.expertMode">
+            <h4 class="gray text-wrap assertive" ng-if="formData.node.temporary">
+              <span class="ion-alert-circled"></span>
+              <span ng-bind-html="'SETTINGS.PEER_CHANGED_TEMPORARY' | translate "></span>
+            </h4>
+            <ng-if ng-if="platform.loading">
+              <h4 class="gray text-italic">
+                <span ng-bind-html="platform.loadingMessage | translate "></span>
               </h4>
-              <div class="badge badge-assertive">{{bma.server}}</div>
             </ng-if>
-            <!-- node selected automatically -->
-            <ng-if ng-if="!formData.expertMode">
-              <h4 class="gray text-wrap " >
-                <span class="ion-info-circled positive"></span>
-                <span ng-bind-html="'SETTINGS.PEER_SELECTED_AUTOMATICALLY' | translate "></span>
-              </h4>
+            <div class="badge badge-balanced" ng-class="{'badge-assertive': formData.node.temporary}">{{bma.server}}</div>
+          </ng-if>
+
+          <!-- node selected automatically -->
+          <ng-if ng-if="!formData.expertMode">
+            <h4 class="gray text-wrap">
+              <span ng-bind-html="'SETTINGS.PEER_SELECTED_AUTOMATICALLY' | translate "></span>
+            </h4>
+            <ng-if ng-if="!platform.loading">
               <div class="badge badge-balanced">{{bma.server}}</div>
             </ng-if>
+            <ng-if ng-if="platform.loading">
+              <h4 class="gray text-italic">
+                <span ng-bind-html="platform.loadingMessage | translate "></span>
+              </h4>
+              <div class="badge badge-note">
+                <ion-spinner icon="android"></ion-spinner>
+              </div>
+            </ng-if>
           </ng-if>
 
-          <div class="badge badge-balanced" ng-if="!formData.node.temporary">{{bma.server}}</div>
           <i class="icon ion-ios-arrow-right" ng-if="formData.expertMode"></i>
         </div>
 <!--        <ion-item class="ink item-icon-right visible-xs visible-sm" ng-click="changeNode()">-->