diff --git a/assets/translations/ca.json b/assets/translations/ca.json
index 41d93bd08e3860744f9c4b1026d55f60e1fc653e..19f22ee8d9bda5aff3863ddd9d1f577351d7acb9 100644
--- a/assets/translations/ca.json
+++ b/assets/translations/ca.json
@@ -59,8 +59,6 @@
   "qr-scanner-title": "Escaneja el QR d'algú",
   "copy_contact_key": "Copia",
   "nothing_found": "No s'ha trobat res",
-  "using_nodes": "Usant {nodes} nodes de {type}",
-  "using_nodes_first": "El més ràpid: {node}",
   "technical_info_title": "Informació tècnica",
   "pattern_do_not_match": "Els patrons no coincideixen",
   "at_least_3": "Com a mínim calen 3 punts",
@@ -120,7 +118,6 @@
   "no_transactions": "Aquest moneder no té saldo. Comença per exemple a oferir els teus serveis als mercats Ğ1 per rebre els teus primers ingressos.",
   "reloading_nodes": "Refrescant nodes del tipus {type}",
   "language_switch_title": "Tria la teva llengua",
-  "long_press_to_refresh": "Reordenant el llistat actual de nodes. Mantingues premut per refrescar la llista.",
   "error_installing_desktop": "Error en instal·lar Ğ1nkgo al vostre escriptori (error: {error})",
   "install_desktop": "Instal·la Ğ1nkgo a l'escriptori",
   "import_failed": "La importació del moneder ha fallat",
diff --git a/assets/translations/de.json b/assets/translations/de.json
index ebb8231e972374060d02034aa01145b5e039016f..f805554bb112d4618ee6d70c2bd3f828b90d3427 100644
--- a/assets/translations/de.json
+++ b/assets/translations/de.json
@@ -41,8 +41,6 @@
     "add_contact": "Kontakt hinzufügen",
     "contact_added": "Kontakt hinzugefügt",
     "qr-scanner-title": "Scannen Sie den QR von jemanden",
-    "using_nodes": "Es werden {nodes} Knoten von {type} genutzt",
-    "using_nodes_first": "Schnellster: {node}",
     "at_least_3": "Mindestens 3 Punkte sind erforderlich",
     "intro_some_pattern_to_export": "Muster für den Import/Export Ihrer Brieftasche",
     "confirm_pattern": "Muster bestätigen",
@@ -95,6 +93,5 @@
     "intro_2_description": "Die Ğ1 ist unabhängig von jeglichen Regierungen oder Gesellschaften, ist ökologisch (durch niedrigen Energieverbrauch), ist transparent und gerecht allen Beteiligten gegenüber.",
     "intro_3_description": "Duniter ist ein dezentralisiertes Kryptowährungsnetzwerk, das die Leute ermöglicht, ihre eigene Ğ1 Währung zu schaffen.",
     "intro_4_description": "Wir helfen Ihnen, eine Ğ1-Brieftasche zu eröffnen, damit Sie Ihre Ğ1-Währung einfach und sicher auf Ihrem Gerät speichern und anderen ohne Zwischenwege überweisen können.",
-    "keys_tooltip": "Öffentliche und private Schlüssel sind in der Ğ1 und in Duniter wie ein Schlüssel-Schloss-System. Dabei schließt der öffentliche Schlüssel ab, und nur der passende private Schlüssel kann öffnen. Das ist eine sichere Weise, Transaktionen zu authentifizieren und zu überprüfen.",
-    "long_press_to_refresh": "Neues Anordnen der gegenwärtigen Knoten-Liste. Tippen und halten, um die Liste zu aktualisieren."
+    "keys_tooltip": "Öffentliche und private Schlüssel sind in der Ğ1 und in Duniter wie ein Schlüssel-Schloss-System. Dabei schließt der öffentliche Schlüssel ab, und nur der passende private Schlüssel kann öffnen. Das ist eine sichere Weise, Transaktionen zu authentifizieren und zu überprüfen."
 }
diff --git a/assets/translations/en.json b/assets/translations/en.json
index f6f5f72952858c940824aa3fe9280d9a69795de4..668f8291a181991f4eadfcf0086124f9d15e0117 100644
--- a/assets/translations/en.json
+++ b/assets/translations/en.json
@@ -60,9 +60,6 @@
   "qr-scanner-title": "Scan the QR of someone",
   "copy_contact_key": "Copy",
   "nothing_found": "Nothing found",
-  "using_nodes": "Using {nodes} nodes of {type}",
-  "using_nodes_first": "Faster: {node}",
-  "long_press_to_refresh": "Reordering the current list of nodes. Tap and hold to refresh the list.",
   "technical_info_title": "Technical info",
   "pattern_do_not_match": "Patterns do not match",
   "at_least_3": "At least 3 points required",
diff --git a/assets/translations/es.json b/assets/translations/es.json
index dcddcebae7cbdc681ba83744de0a575f6571bff8..d36c499999016e932f08d5231e098e77cb624076 100644
--- a/assets/translations/es.json
+++ b/assets/translations/es.json
@@ -60,9 +60,6 @@
   "qr-scanner-title": "Escanea el QR de alguien",
   "copy_contact_key": "Copiar",
   "nothing_found": "No se ha encontrado nada",
-  "using_nodes": "Usando {nodes} nodos de {type}",
-  "using_nodes_first": "Más rápido: {node}",
-  "long_press_to_refresh": "Reordenando la lista actual de nodos. Manten pulsado para refrescar la lista.",
   "technical_info_title": "Información técnica",
   "pattern_do_not_match": "Los patrones no coinciden",
   "at_least_3": "Se requieren al menos 3 puntos",
diff --git a/assets/translations/fr.json b/assets/translations/fr.json
index 826e06c77e193e3fdafc6a8b291e5401174a27fa..9bd9c5dc920935dcc60f8267424cd5bfe78db1b0 100644
--- a/assets/translations/fr.json
+++ b/assets/translations/fr.json
@@ -54,8 +54,6 @@
   "no_contacts": "Vous n'avez pas encore de contacts",
   "data_load_error": "Erreur de chargement des données",
   "nothing_found": "Rien trouvé",
-  "using_nodes": "Utilisation de {nodes} nœuds de type {type}",
-  "using_nodes_first": "Plus rapide : {node}",
   "technical_info_title": "Informations techniques",
   "pattern_do_not_match": "Les modèles ne correspondent pas",
   "at_least_3": "Au moins 3 points sont requis",
@@ -64,7 +62,6 @@
   "draw_pattern": "Dessiner le motif",
   "some_key_copied_to_clipboard": "La clé publique a été copiée dans le presse-papiers",
   "copy_contact_key": "Copie",
-  "long_press_to_refresh": "Réorganisation de la liste actuelle des nœuds. Tapez sur un maintien pour actualiser la liste.",
   "cancel": "ANNULER",
   "import_config_desc": "Cela remplacera votre portefeuille actuel par le portefeuille importé",
   "transaction_received": "Reçu",
diff --git a/assets/translations/gl.json b/assets/translations/gl.json
index 8d06b827bf9f3533be62bc658c1568a7ca9f1e72..99b4fae863cc80e3a7892365cf51ac69e389c814 100644
--- a/assets/translations/gl.json
+++ b/assets/translations/gl.json
@@ -59,7 +59,6 @@
   "contact_added": "Contacto engadido",
   "copy_contact_key": "Copiar",
   "nothing_found": "Non se atopou nada",
-  "using_nodes": "Usando {nodes} nodos de {type}",
   "skip": "Saltar",
   "wrong_pattern": "Patrón incorrecto",
   "cancel": "CANCELAR",
@@ -89,8 +88,6 @@
   "faq_1_title": "Podo importar a miña conta Cesium?",
   "faq_2_title": "É seguro utilizar este moedeiro?",
   "faq_3_title": "Por que non pódese agregar un contrasinal ao moedeiro?",
-  "using_nodes_first": "Máis rápido: {node}",
-  "long_press_to_refresh": "Reordenando a listaxe actual de nodos. Manter premado para refrescar a lista.",
   "technical_info_title": "Información técnica",
   "pattern_do_not_match": "Os patróns non coinciden",
   "at_least_3": "Requírense polo menos 3 puntos",
diff --git a/assets/translations/nl.json b/assets/translations/nl.json
index 629e8cdac8409fd14d8861cfbaed044c76640ac8..4452d8ddfaf121f81327be68c57d0bd7ff8ed11b 100644
--- a/assets/translations/nl.json
+++ b/assets/translations/nl.json
@@ -44,8 +44,6 @@
   "add_contact": "Contact toevoegen",
   "contact_added": "Contact toegevoegd",
   "qr-scanner-title": "Scan de QR van iemand",
-  "using_nodes": "{nodes} nodes van {type} gebruiken",
-  "using_nodes_first": "Sneller: {node}",
   "bottom_nav_frd": "Saldo",
   "bottom_nav_fifth": "Info",
   "search_user": "Zoeken (gebruiker of openbare sleutel)",
@@ -62,7 +60,6 @@
   "no_transactions": "Deze portemonnee heeft geen saldo. Begin met het aanbieden van uw diensten in Äž1 markten, bijvoorbeeld, om uw eerste inkomen te ontvangen.",
   "copy_contact_key": "kopiëren",
   "nothing_found": "Niets gevonden",
-  "long_press_to_refresh": "De huidige lijst met knooppunten wordt opnieuw geordend. Tik en houd vast om de lijst te vernieuwen.",
   "technical_info_title": "Technische informatie",
   "pattern_do_not_match": "Patronen komen niet overeen",
   "at_least_3": "Minimaal 3 punten vereist",
diff --git a/assets/translations/pt.json b/assets/translations/pt.json
index 0bb6e90b4255dcbd619a07a8fb1e8bf189c64428..f18ffc466d2fc04ee1ef87638ac54dd9d9a13681 100644
--- a/assets/translations/pt.json
+++ b/assets/translations/pt.json
@@ -77,8 +77,6 @@
   "transactions": "Transacções",
   "nothing_found": "Nada encontrado",
   "wallet_exported": "Carteira exportada correctamente",
-  "using_nodes_first": "Rápido: {node}",
-  "using_nodes": "Usando {nodes} nós de {type}",
   "intro_1_description": "Com esta carteira, pode guardar, enviar e receber moeda Ğ1 (também conhecida como 'Juna') de forma fácil e segura.",
   "intro_3_title": "A moeda Äž1 funciona na rede Duniter",
   "intro_3_description": "Duniter é uma rede descentralizada de criptomoeda que permite às pessoas criar a sua própria moeda Ğ1.",
@@ -101,7 +99,6 @@
   "no_transactions": "Esta carteira não tem saldo. Comece por oferecer os seus serviços nos mercados Ğ1, por exemplo, para receber o seu primeiro rendimento.",
   "qr-scanner-title": "Digitalizar o QR de alguém",
   "copy_contact_key": "Copiar",
-  "long_press_to_refresh": "Reordenando a lista actual de nós. Tocar e segurar para actualizar a lista.",
   "technical_info_title": "Informação técnica",
   "pattern_do_not_match": "Padrões não coincidem",
   "at_least_3": "Pelo menos 3 pontos necessários",
diff --git a/lib/data/models/node.g.dart b/lib/data/models/node.g.dart
index 6b5dca27ea887629b8136bc2dcc87b68d74aaf4d..aa005531fd331ea25a0a396fb565545cf2f5678f 100644
--- a/lib/data/models/node.g.dart
+++ b/lib/data/models/node.g.dart
@@ -10,10 +10,12 @@ Node _$NodeFromJson(Map<String, dynamic> json) => Node(
       url: json['url'] as String,
       latency: json['latency'] as int? ?? 99999,
       errors: json['errors'] as int? ?? 0,
+      currentBlock: json['currentBlock'] as int? ?? 0,
     );
 
 Map<String, dynamic> _$NodeToJson(Node instance) => <String, dynamic>{
       'url': instance.url,
       'latency': instance.latency,
       'errors': instance.errors,
+      'currentBlock': instance.currentBlock,
     };
diff --git a/lib/data/models/node_list_cubit.dart b/lib/data/models/node_list_cubit.dart
index c2434397b08cc2f67dd1806961d460cac6b76e11..96c8139973e0f7fee80cfbb83ca72f919ed3dd3a 100644
--- a/lib/data/models/node_list_cubit.dart
+++ b/lib/data/models/node_list_cubit.dart
@@ -10,6 +10,12 @@ class NodeListCubit extends HydratedCubit<NodeListState> {
   @override
   String get storagePrefix => 'NodeListCubit';
 
+  bool get isLoading => state.isLoading;
+
+  void setLoading(bool isLoading) {
+    emit(state.copyWith(isLoading: isLoading));
+  }
+
   void shuffle(NodeType type, bool withPenalty) {
     switch (type) {
       case NodeType.duniter:
@@ -23,8 +29,8 @@ class NodeListCubit extends HydratedCubit<NodeListState> {
       case NodeType.cesiumPlus:
         if (withPenalty) {
           emit(state.copyWith(
-              cesiumPlusNodes: shuffleFirstNWithPenalty(
-                  state.cesiumPlusNodes)));
+              cesiumPlusNodes:
+                  shuffleFirstNWithPenalty(state.cesiumPlusNodes)));
         } else {
           emit(state.copyWith(
               cesiumPlusNodes: shuffleFirstN(state.cesiumPlusNodes)));
diff --git a/lib/data/models/node_list_state.dart b/lib/data/models/node_list_state.dart
index 2c7d480be357b29276b6a6ea7d2afe53efdd74cf..8a023c1ce1538ed9b68096d7be8c74ceefa7049f 100644
--- a/lib/data/models/node_list_state.dart
+++ b/lib/data/models/node_list_state.dart
@@ -14,10 +14,12 @@ class NodeListState extends Equatable {
   NodeListState(
       {List<Node>? duniterNodes,
       List<Node>? cesiumPlusNodes,
-      List<Node>? gvaNodes})
+      List<Node>? gvaNodes,
+      bool? isLoading})
       : duniterNodes = duniterNodes ?? defaultDuniterNodes,
         cesiumPlusNodes = cesiumPlusNodes ?? defaultCesiumPlusNodes,
-        gvaNodes = gvaNodes ?? defaultGvaNodes;
+        gvaNodes = gvaNodes ?? defaultGvaNodes,
+        isLoading = isLoading ?? false;
 
   factory NodeListState.fromJson(Map<String, dynamic> json) =>
       _$NodeListStateFromJson(json);
@@ -25,9 +27,11 @@ class NodeListState extends Equatable {
   final List<Node> duniterNodes;
   final List<Node> cesiumPlusNodes;
   final List<Node> gvaNodes;
+  final bool isLoading;
 
   @override
-  List<Object?> get props => <Object>[duniterNodes, cesiumPlusNodes, gvaNodes];
+  List<Object?> get props =>
+      <Object>[duniterNodes, cesiumPlusNodes, gvaNodes, isLoading];
 
   Map<String, dynamic> toJson() => _$NodeListStateToJson(this);
 }
diff --git a/lib/data/models/node_list_state.g.dart b/lib/data/models/node_list_state.g.dart
index 0cc3c51959e0bac1ef0051c8b895bb540352747e..fe5c794fce98dd66831c326e2c6bf5f30ba1b464 100644
--- a/lib/data/models/node_list_state.g.dart
+++ b/lib/data/models/node_list_state.g.dart
@@ -13,6 +13,8 @@ abstract class _$NodeListStateCWProxy {
 
   NodeListState gvaNodes(List<Node>? gvaNodes);
 
+  NodeListState isLoading(bool? isLoading);
+
   /// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `NodeListState(...).copyWith.fieldName(...)` to override fields one at a time with nullification support.
   ///
   /// Usage
@@ -23,6 +25,7 @@ abstract class _$NodeListStateCWProxy {
     List<Node>? duniterNodes,
     List<Node>? cesiumPlusNodes,
     List<Node>? gvaNodes,
+    bool? isLoading,
   });
 }
 
@@ -43,6 +46,9 @@ class _$NodeListStateCWProxyImpl implements _$NodeListStateCWProxy {
   @override
   NodeListState gvaNodes(List<Node>? gvaNodes) => this(gvaNodes: gvaNodes);
 
+  @override
+  NodeListState isLoading(bool? isLoading) => this(isLoading: isLoading);
+
   @override
 
   /// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `NodeListState(...).copyWith.fieldName(...)` to override fields one at a time with nullification support.
@@ -55,6 +61,7 @@ class _$NodeListStateCWProxyImpl implements _$NodeListStateCWProxy {
     Object? duniterNodes = const $CopyWithPlaceholder(),
     Object? cesiumPlusNodes = const $CopyWithPlaceholder(),
     Object? gvaNodes = const $CopyWithPlaceholder(),
+    Object? isLoading = const $CopyWithPlaceholder(),
   }) {
     return NodeListState(
       duniterNodes: duniterNodes == const $CopyWithPlaceholder()
@@ -69,6 +76,10 @@ class _$NodeListStateCWProxyImpl implements _$NodeListStateCWProxy {
           ? _value.gvaNodes
           // ignore: cast_nullable_to_non_nullable
           : gvaNodes as List<Node>?,
+      isLoading: isLoading == const $CopyWithPlaceholder()
+          ? _value.isLoading
+          // ignore: cast_nullable_to_non_nullable
+          : isLoading as bool?,
     );
   }
 }
@@ -94,6 +105,7 @@ NodeListState _$NodeListStateFromJson(Map<String, dynamic> json) =>
       gvaNodes: (json['gvaNodes'] as List<dynamic>?)
           ?.map((e) => Node.fromJson(e as Map<String, dynamic>))
           .toList(),
+      isLoading: json['isLoading'] as bool?,
     );
 
 Map<String, dynamic> _$NodeListStateToJson(NodeListState instance) =>
@@ -101,4 +113,5 @@ Map<String, dynamic> _$NodeListStateToJson(NodeListState instance) =>
       'duniterNodes': instance.duniterNodes,
       'cesiumPlusNodes': instance.cesiumPlusNodes,
       'gvaNodes': instance.gvaNodes,
+      'isLoading': instance.isLoading,
     };
diff --git a/lib/data/models/node_manager.dart b/lib/data/models/node_manager.dart
index ce1954e6f427eb00fd337e4cc65b9a3674e207b3..17f766a35a4097e5562b7e50ec8a4295561dcb17 100644
--- a/lib/data/models/node_manager.dart
+++ b/lib/data/models/node_manager.dart
@@ -104,6 +104,12 @@ class NodeManager {
     notifyObserver();
   }
 
+  bool get loading => NodeManagerObserver.instance.cubit.isLoading;
+
+  set loading(bool isLoading) {
+    NodeManagerObserver.instance.setLoading(isLoading);
+  }
+
   void notifyObserver() {
     NodeManagerObserver.instance.update(this);
   }
@@ -116,6 +122,10 @@ class NodeManagerObserver {
 
   late NodeListCubit cubit;
 
+  void setLoading(bool isLoading) {
+    cubit.setLoading(isLoading);
+  }
+
   void update(NodeManager nodeManager) {
     cubit.setDuniterNodes(nodeManager.duniterNodes);
     cubit.setCesiumPlusNodes(nodeManager.cesiumPlusNodes);
diff --git a/lib/g1/api.dart b/lib/g1/api.dart
index 4241ffe3a04ffa686e0f9a8f951689a65e37cbc8..c4ec52b32d9230df3ce68fbd5d8fc256fafb5516 100644
--- a/lib/g1/api.dart
+++ b/lib/g1/api.dart
@@ -178,6 +178,7 @@ Future<Uint8List> getAvatar(String pubKey) async {
 
 Future<void> fetchDuniterNodes({bool force = false}) async {
   const NodeType type = NodeType.duniter;
+  NodeManager().loading = true;
   if (force || nodesWorking(type) < NodeManager.maxNodes) {
     if (force) {
       NodeManager().updateNodes(type, defaultDuniterNodes);
@@ -193,11 +194,25 @@ Future<void> fetchDuniterNodes({bool force = false}) async {
       // developer.log(StackTrace.current.toString());
     }
   }
+  NodeManager().loading = false;
+}
+
+Future<void> fetchNodes(NodeType type) async {
+  if (type == NodeType.duniter) {
+    fetchDuniterNodes(force: true);
+  } else {
+    if (type == NodeType.cesiumPlus) {
+      fetchCesiumPlusNodes(force: true);
+    } else {
+      fetchGvaNodes(force: true);
+    }
+  }
 }
 
 // https://github.com/duniter/cesium/blob/467ec68114be650cd1b306754c3142fc4020164c/www/js/config.js#L96
 // https://g1.data.le-sou.org/g1/peer/_search?pretty
 Future<void> fetchCesiumPlusNodes({bool force = false}) async {
+  NodeManager().loading = true;
   const NodeType type = NodeType.cesiumPlus;
   if (force) {
     NodeManager().updateNodes(type, defaultCesiumPlusNodes);
@@ -207,9 +222,11 @@ Future<void> fetchCesiumPlusNodes({bool force = false}) async {
   }
   final List<Node> nodes = await _fetchNodes(NodeType.cesiumPlus);
   NodeManager().updateNodes(type, nodes);
+  NodeManager().loading = false;
 }
 
 Future<void> fetchGvaNodes({bool force = false}) async {
+  NodeManager().loading = true;
   const NodeType type = NodeType.gva;
   if (force) {
     NodeManager().updateNodes(type, defaultGvaNodes);
@@ -219,6 +236,7 @@ Future<void> fetchGvaNodes({bool force = false}) async {
   }
   final List<Node> nodes = await _fetchDuniterNodesFromPeers(type);
   NodeManager().updateNodes(type, nodes);
+  NodeManager().loading = false;
 }
 
 int nodesWorking(NodeType type) => NodeManager()
@@ -361,34 +379,49 @@ Future<List<Node>> _fetchNodes(NodeType type) async {
 }
 
 Future<NodeCheck> _pingNode(String node, NodeType type) async {
+  // Decrease timout during ping
   const Duration timeout = Duration(seconds: 10);
   int currentBlock = 0;
+  Duration latency;
   try {
     final Stopwatch stopwatch = Stopwatch()..start();
-    if (type == NodeType.duniter || type == NodeType.cesiumPlus) {
+    if (type == NodeType.duniter) {
+      final Response response = await http
+          .get(Uri.parse('$node/blockchain/current'))
+          .timeout(timeout);
+      stopwatch.stop();
+      latency = stopwatch.elapsed;
+      if (response.statusCode == 200) {
+        final Map<String, dynamic> json =
+            jsonDecode(response.body) as Map<String, dynamic>;
+        currentBlock = json['number'] as int;
+      } else {
+        latency = wrongNodeDuration;
+      }
+    } else if (type == NodeType.cesiumPlus) {
+      // see: http://g1.data.e-is.pro/network/peering
       await http
-          .get(Uri.parse(type == NodeType.duniter
-              ? '$node/network/peers/self/ping'
-              : type == NodeType.cesiumPlus
-                  ?
-                  // see: http://g1.data.e-is.pro/network/peering
-                  '$node/network/peering'
-                  // gva, test for playground
-                  : '$node/playground'))
+          .get(Uri.parse('$node/network/peering'))
           // Decrease http timeout during ping
           .timeout(timeout);
+      stopwatch.stop();
+      latency = stopwatch.elapsed;
     } else {
       // Test GVA with a query
       final Gva gva = Gva(node: proxyfyNode(node));
       currentBlock = await gva.getCurrentBlock().timeout(timeout);
 //      NodeManager().updateNode(type, node.copyWith(latency: newLatency));
+      stopwatch.stop();
+      final double balance = await gva
+          .balance('EdWkzNABz7dPancFqW6JVLqv1wpGaQSxgWmMf1pmY7KG')
+          .timeout(timeout);
+      latency = balance >= 0 ? stopwatch.elapsed : wrongNodeDuration;
     }
-    stopwatch.stop();
-    return NodeCheck(latency: stopwatch.elapsed, currentBlock: currentBlock);
+    return NodeCheck(latency: latency, currentBlock: currentBlock);
   } catch (e) {
     // Handle exception when node is unavailable etc
     logger('Node $node does not respond to ping $e');
-    return NodeCheck(latency: const Duration(days: 2), currentBlock: 0);
+    return NodeCheck(latency: wrongNodeDuration, currentBlock: 0);
   }
 }
 
@@ -595,6 +628,7 @@ List<Node> _getBestGvaNodes() {
     // Fallback
     nodes.addAll(defaultGvaNodes);
   }
+  nodes.shuffle();
   return nodes;
 }
 
diff --git a/lib/g1/g1_helper.dart b/lib/g1/g1_helper.dart
index 2f18f2f65814eb6fa6174b7699bc17cf57a827ca..91ac1d144f94e0ce93d44d8bcc471c9a5e3ffa97 100644
--- a/lib/g1/g1_helper.dart
+++ b/lib/g1/g1_helper.dart
@@ -163,3 +163,5 @@ Map<String, dynamic> decryptJsonForImport(
       .decrypt64(keyEncrypted, iv: _iv);
   return jsonDecode(decrypted) as Map<String, dynamic>;
 }
+
+const Duration wrongNodeDuration = Duration(days: 2);
diff --git a/lib/ui/screens/debug_nodes_screen.dart b/lib/ui/screens/debug_nodes_screen.dart
index 1015226ce4e827e374015ab4aa9da7946f67828d..de02e3ad832a33e5f2186615682afd798c73f640 100644
--- a/lib/ui/screens/debug_nodes_screen.dart
+++ b/lib/ui/screens/debug_nodes_screen.dart
@@ -6,6 +6,8 @@ import '../../data/models/node.dart';
 import '../../data/models/node_list_cubit.dart';
 import '../../data/models/node_list_state.dart';
 import '../../data/models/node_type.dart';
+import '../../g1/api.dart';
+import '../ui_helpers.dart';
 import '../widgets/debug_nodes/debug_node_list.dart';
 
 class DebugNodesScreen extends StatelessWidget {
@@ -19,55 +21,78 @@ class DebugNodesScreen extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<NodeListCubit, NodeListState>(
-        builder: (BuildContext nodeContext, NodeListState state) {
-      final List<Node> duniterNodes =
-          filterAndSortNodesByType(state.duniterNodes, NodeType.duniter);
-      final List<Node> cesiumPlusNodes =
-          filterAndSortNodesByType(state.cesiumPlusNodes, NodeType.cesiumPlus);
-      final List<Node> gvaNodes =
-          filterAndSortNodesByType(state.gvaNodes, NodeType.gva);
-      return Scaffold(
-          appBar: AppBar(title: Text(tr('nodes_tech_info'))),
-          body: Container(
-              constraints: BoxConstraints(
-                  maxHeight: MediaQuery.of(context).size.height * 0.9),
-              child: Scrollbar(
-                child: SingleChildScrollView(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: <Widget>[
-                      const Padding(
-                        padding: EdgeInsets.all(8.0),
-                        child:
-                            Text('GVA Nodes', style: TextStyle(fontSize: 24)),
-                      ),
-                      DebugNodeList(
-                          nodes: gvaNodes,
-                          type: NodeType.gva,
-                          currentBlock: gvaNodes[0].currentBlock),
-                      const Padding(
-                        padding: EdgeInsets.all(8.0),
-                        child: Text('Duniter Nodes',
-                            style: TextStyle(fontSize: 24)),
-                      ),
-                      DebugNodeList(
-                          nodes: duniterNodes,
-                          type: NodeType.duniter,
-                          currentBlock: duniterNodes[0].currentBlock),
-                      const Padding(
-                        padding: EdgeInsets.all(8.0),
-                        child: Text('Cesium+ Nodes',
-                            style: TextStyle(fontSize: 24)),
-                      ),
-                      DebugNodeList(
-                          nodes: cesiumPlusNodes,
-                          type: NodeType.cesiumPlus,
-                          currentBlock: cesiumPlusNodes[0].currentBlock),
-                    ],
-                  ),
+    final NodeListState state = context.watch<NodeListCubit>().state;
+    final List<Node> duniterNodes =
+        filterAndSortNodesByType(state.duniterNodes, NodeType.duniter);
+    final List<Node> cesiumPlusNodes =
+        filterAndSortNodesByType(state.cesiumPlusNodes, NodeType.cesiumPlus);
+    final List<Node> gvaNodes =
+        filterAndSortNodesByType(state.gvaNodes, NodeType.gva);
+    return Scaffold(
+        appBar: AppBar(
+          title: Text(tr('nodes_tech_info')),
+          bottom: state.isLoading
+              ? const PreferredSize(
+                  preferredSize: Size.fromHeight(4.0),
+                  child: LinearProgressIndicator(),
+                )
+              : null,
+        ),
+        body: Container(
+            constraints: BoxConstraints(
+                maxHeight: MediaQuery.of(context).size.height * 0.9),
+            child: Scrollbar(
+              child: SingleChildScrollView(
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: <Widget>[
+                    const DebugNodeHeader(type: NodeType.gva),
+                    DebugNodeList(
+                        nodes: gvaNodes,
+                        type: NodeType.gva,
+                        currentBlock: gvaNodes[0].currentBlock),
+                    const DebugNodeHeader(type: NodeType.duniter),
+                    DebugNodeList(
+                        nodes: duniterNodes,
+                        type: NodeType.duniter,
+                        currentBlock: duniterNodes[0].currentBlock),
+                    const DebugNodeHeader(type: NodeType.cesiumPlus),
+                    DebugNodeList(
+                        nodes: cesiumPlusNodes,
+                        type: NodeType.cesiumPlus,
+                        currentBlock: cesiumPlusNodes[0].currentBlock),
+                  ],
                 ),
-              )));
-    });
+              ),
+            )));
+  }
+}
+
+class DebugNodeHeader extends StatelessWidget {
+  const DebugNodeHeader({super.key, required this.type});
+
+  final NodeType type;
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+        padding: const EdgeInsets.symmetric(horizontal: 10),
+        child: Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          children: <Widget>[
+            Text('${capitalize(type.name)} Nodes',
+                style: const TextStyle(fontSize: 20)),
+            IconButton(
+              icon: const Icon(Icons.refresh),
+              onPressed: () {
+                fetchNodes(type);
+                ScaffoldMessenger.of(context).showSnackBar(SnackBar(
+                  content: Text(tr('reloading_nodes',
+                      namedArgs: <String, String>{'type': type.name})),
+                ));
+              },
+            ),
+          ],
+        ));
   }
 }
diff --git a/lib/ui/screens/fifth_screen.dart b/lib/ui/screens/fifth_screen.dart
index f6799780c17b80ce85cda5307f17d14810218a74..72ca630d37da6c6c0bd4cf2203b1c703e7689e2c 100644
--- a/lib/ui/screens/fifth_screen.dart
+++ b/lib/ui/screens/fifth_screen.dart
@@ -7,7 +7,6 @@ import 'package:share_plus/share_plus.dart';
 import '../../cubit/theme_cubit.dart';
 import '../../data/models/app_cubit.dart';
 import '../../data/models/app_state.dart';
-import '../../data/models/node_type.dart';
 import '../../shared_prefs.dart';
 import '../notification_controller.dart';
 import '../ui_helpers.dart';
@@ -20,7 +19,6 @@ import '../widgets/fifth_screen/import_dialog.dart';
 import '../widgets/fifth_screen/link_card.dart';
 import '../widgets/fifth_screen/node_info.dart';
 import '../widgets/fifth_screen/text_divider.dart';
-import 'debug_nodes_screen.dart';
 
 class FifthScreen extends StatelessWidget {
   const FifthScreen({super.key});
@@ -170,26 +168,7 @@ class FifthScreen extends StatelessWidget {
                         ]),
                     if (state.expertMode)
                       const TextDivider(text: 'technical_info_title'),
-                    if (state.expertMode)
-                      const NodeInfoCard(type: NodeType.duniter),
-                    if (state.expertMode)
-                      const NodeInfoCard(type: NodeType.cesiumPlus),
-                    if (state.expertMode)
-                      const NodeInfoCard(type: NodeType.gva),
-                    if (state
-                        .expertMode) // context.read<AppState>().expertMode)
-                      ListTile(
-                        leading: const Icon(Icons.hub),
-                        title: Text(tr('nodes_tech_info')),
-                        onTap: () {
-                          Navigator.push(
-                            context,
-                            MaterialPageRoute<VoidCallback>(
-                                builder: (BuildContext context) =>
-                                    const DebugNodesScreen()),
-                          );
-                        },
-                      ),
+                    if (state.expertMode) const NodeInfoCard(),
                     if (state.expertMode) const TextDivider(text: 'info_links'),
                     if (state.expertMode)
                       LinkCard(
diff --git a/lib/ui/widgets/debug_nodes/debug_node_list.dart b/lib/ui/widgets/debug_nodes/debug_node_list.dart
index 966caa83be329ed62df5a90a774c7bd89fa12d7f..73b72e0c2f3d1942744ccda47b2eb12462e4d631 100644
--- a/lib/ui/widgets/debug_nodes/debug_node_list.dart
+++ b/lib/ui/widgets/debug_nodes/debug_node_list.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 
 import '../../../data/models/node.dart';
 import '../../../data/models/node_type.dart';
+import '../../../g1/g1_helper.dart';
 
 class DebugNodeList extends StatelessWidget {
   const DebugNodeList(
@@ -16,22 +17,31 @@ class DebugNodeList extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return ListView.builder(
-      shrinkWrap: true,
-      //physics: const AlwaysScrollableScrollPhysics(),
-      itemCount: nodes.length,
-      itemBuilder: (BuildContext context, int index) {
+    return Column(
+        children: List<Widget>.generate(
+      nodes.length,
+      (int index) {
         final Node node = nodes[index];
-        return ListTile(
-          dense: true,
-          title: Text(node.url),
-          subtitle: Text(
-              '${type != NodeType.cesiumPlus ? 'Current block: ${node.currentBlock}, ' : ''}errors: ${node.errors}, latency (ms): ${node.latency}'),
-          leading: node.currentBlock == currentBlock
-              ? const Icon(Icons.check_circle, color: Colors.green)
-              : const Icon(Icons.run_circle, color: Colors.grey),
-        );
+        final int wrongNode = wrongNodeDuration.inMicroseconds;
+        return Theme(
+            data: Theme.of(context).copyWith(
+              visualDensity: VisualDensity.compact,
+            ),
+            child: ListTile(
+              dense: true,
+              title: Text(node.url),
+              subtitle: node.latency < wrongNode
+                  ? Text(
+                      '${type != NodeType.cesiumPlus ? 'Current block: ${node.currentBlock}, ' : ''}errors: ${node.errors}, latency (ms): ${node.latency}')
+                  : null,
+              leading:
+                  node.currentBlock == currentBlock && node.latency < wrongNode
+                      ? const Icon(Icons.check_circle, color: Colors.green)
+                      : node.latency < wrongNode
+                          ? const Icon(Icons.run_circle, color: Colors.grey)
+                          : const Icon(Icons.power_off, color: Colors.grey),
+            ));
       },
-    );
+    ));
   }
 }
diff --git a/lib/ui/widgets/fifth_screen/node_info.dart b/lib/ui/widgets/fifth_screen/node_info.dart
index 0861e9ff8af03deabf46dcbf5db1ded0251b71b6..9db9f186bb934b0ed324e238350f364595bd0b7b 100644
--- a/lib/ui/widgets/fifth_screen/node_info.dart
+++ b/lib/ui/widgets/fifth_screen/node_info.dart
@@ -2,68 +2,28 @@ import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
-import '../../../data/models/node.dart';
 import '../../../data/models/node_list_cubit.dart';
 import '../../../data/models/node_list_state.dart';
-import '../../../data/models/node_type.dart';
-import '../../../g1/api.dart';
-import '../../logger.dart';
+import '../../screens/debug_nodes_screen.dart';
 import '../fifth_screen/info_card.dart';
 
 class NodeInfoCard extends StatelessWidget {
-  const NodeInfoCard({super.key, required this.type});
-
-  final NodeType type;
+  const NodeInfoCard({super.key});
 
   @override
   Widget build(BuildContext context) {
     return BlocBuilder<NodeListCubit, NodeListState>(
         builder: (BuildContext nodeContext, NodeListState state) {
-      final List<Node> nodes = type == NodeType.duniter
-          ? state.duniterNodes
-          : type == NodeType.cesiumPlus
-              ? state.cesiumPlusNodes
-              : state.gvaNodes;
       return GestureDetector(
           onTap: () {
-            context.read<NodeListCubit>().shuffle(type, true);
-            ScaffoldMessenger.of(context).showSnackBar(
-              SnackBar(
-                content: Text(tr('long_press_to_refresh')),
-              ),
+            Navigator.push(
+              context,
+              MaterialPageRoute<VoidCallback>(
+                  builder: (BuildContext context) => const DebugNodesScreen()),
             );
           },
-          onLongPress: () {
-            logger('On long press');
-            if (type == NodeType.duniter) {
-              fetchDuniterNodes(force: true);
-            } else {
-              if (type == NodeType.cesiumPlus) {
-                fetchCesiumPlusNodes(force: true);
-              } else {
-                fetchGvaNodes();
-              }
-            }
-            ScaffoldMessenger.of(context).showSnackBar(SnackBar(
-              content: Text(tr('reloading_nodes',
-                  namedArgs: <String, String>{'type': type.name})),
-            ));
-          },
           child: InfoCard(
-              title: tr('using_nodes', namedArgs: <String, String>{
-                'type': type.name,
-                'nodes': nodes.length.toString()
-              }),
-              translate: false,
-              subtitle: nodes.isNotEmpty
-                  ? tr('using_nodes_first',
-                      namedArgs: <String, String>{'node': nodes.first.url})
-                  : '',
-              icon: type == NodeType.duniter
-                  ? Icons.hub
-                  : type == NodeType.cesiumPlus
-                      ? Icons.diversity_2
-                      : Icons.g_mobiledata));
+              title: tr('nodes_tech_info'), translate: false, icon: Icons.hub));
     });
   }
 }
diff --git a/pubspec.yaml b/pubspec.yaml
index 306b8a3434ce272eacbf58fd90e9501aaea9ceed..9858c10edf745360c0db0df05de92b0b83962cb8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
 # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
 # Read more about iOS versioning at
 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
-version: 0.0.19
+version: 0.0.20-SNAPSHOT
 
 environment:
   sdk: ">=2.17.1 <3.0.0"