diff --git a/lib/data/models/transaction_cubit.dart b/lib/data/models/transaction_cubit.dart
index 7d0405cf5e4fd85cc5d444016cb5ab0622b54f85..4222bbb1a5e5ed716b2f3c137b2d402f9562122b 100644
--- a/lib/data/models/transaction_cubit.dart
+++ b/lib/data/models/transaction_cubit.dart
@@ -1,5 +1,6 @@
 import 'package:flutter/foundation.dart';
 import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:tuple/tuple.dart';
 
 import '../../../g1/api.dart';
 import '../../../g1/transaction_parser.dart';
@@ -8,7 +9,9 @@ import '../../ui/contacts_cache.dart';
 import '../../ui/logger.dart';
 import '../../ui/notification_controller.dart';
 import 'contact.dart';
+import 'node.dart';
 import 'node_list_cubit.dart';
+import 'node_type.dart';
 import 'transaction.dart';
 import 'transaction_balance_state.dart';
 import 'transaction_type.dart';
@@ -38,46 +41,67 @@ class TransactionsCubit extends HydratedCubit<TransactionsAndBalanceState> {
     emit(state.copyWith(transactions: newTransactions, balance: newBalance));
   }
 
-  Future<void> fetchTransactions(NodeListCubit cubit) async {
-    logger('Loading transactions --------------------');
-    final Map<String, dynamic>? txData =
-        await gvaHistoryAndBalance(SharedPreferencesHelper().getPubKey());
-    if (txData == null) {
-      logger('Failed to get transactions');
-      return;
-    }
-    final TransactionsAndBalanceState newState =
-        transactionsGvaParser(txData, state);
-    // Notify
-    //logger(
-    //  'Last received: ${lastReceived.toIso8601String()}, last received notification: ${lastReceivedNotification.toIso8601String()}, compared ${lastReceived.compareTo(lastReceivedNotification)}');
-    logger(
-        'Last received notification: ${newState.latestReceivedNotification.toIso8601String()})}');
-    logger(
-        'Last sent notification: ${newState.latestSentNotification.toIso8601String()})}');
-    emit(newState);
-    for (final Transaction tx in newState.transactions.reversed) {
-      if (tx.type == TransactionType.received &&
-          newState.latestReceivedNotification.isBefore(tx.time)) {
-        // Future
-        final Contact from = await ContactsCache().getContact(tx.from);
-        NotificationController.createNewNotification(
-            tx.time.millisecondsSinceEpoch.toString(),
-            amount: tx.amount / 100,
-            from: from.title);
-        emit(newState.copyWith(latestReceivedNotification: tx.time));
+  Future<void> fetchTransactions(NodeListCubit cubit, {int retries = 5}) async {
+    Tuple2<Map<String, dynamic>?, Node> txDataResult;
+    bool success = false;
+
+    for (int attempt = 0; attempt < retries; attempt++) {
+      txDataResult =
+          await gvaHistoryAndBalance(SharedPreferencesHelper().getPubKey());
+      final Node node = txDataResult.item2;
+      logger('Loading transactions using $node --------------------');
+
+      if (txDataResult.item1 == null) {
+        logger(
+            'Failed to get transactions, attempt ${attempt + 1} of $retries');
+        await Future<void>.delayed(const Duration(seconds: 1));
+        increaseNodeErrors(NodeType.gva, node);
+        continue;
+      }
+
+      final Map<String, dynamic> txData = txDataResult.item1!;
+      final TransactionsAndBalanceState newState =
+          transactionsGvaParser(txData, state);
+
+      if (newState.balance < 0) {
+        logger('Warning: Negative balance in node ${txDataResult.item2}');
+        increaseNodeErrors(NodeType.gva, node);
+        continue;
       }
-      if (tx.type == TransactionType.sent &&
-          newState.latestSentNotification.isBefore(tx.time)) {
-        // Future
-        final Contact to = await ContactsCache().getContact(tx.from);
-        NotificationController.createNewNotification(
-            tx.time.millisecondsSinceEpoch.toString(),
-            amount: -tx.amount / 100,
-            to: to.title);
-        emit(newState.copyWith(latestSentNotification: tx.time));
+      success = true;
+
+      logger(
+          'Last received notification: ${newState.latestReceivedNotification.toIso8601String()})}');
+      logger(
+          'Last sent notification: ${newState.latestSentNotification.toIso8601String()})}');
+      emit(newState);
+      for (final Transaction tx in newState.transactions.reversed) {
+        if (tx.type == TransactionType.received &&
+            newState.latestReceivedNotification.isBefore(tx.time)) {
+          // Future
+          final Contact from = await ContactsCache().getContact(tx.from);
+          NotificationController.createNewNotification(
+              tx.time.millisecondsSinceEpoch.toString(),
+              amount: tx.amount / 100,
+              from: from.title);
+          emit(newState.copyWith(latestReceivedNotification: tx.time));
+        }
+        if (tx.type == TransactionType.sent &&
+            newState.latestSentNotification.isBefore(tx.time)) {
+          // Future
+          final Contact to = await ContactsCache().getContact(tx.from);
+          NotificationController.createNewNotification(
+              tx.time.millisecondsSinceEpoch.toString(),
+              amount: -tx.amount / 100,
+              to: to.title);
+          emit(newState.copyWith(latestSentNotification: tx.time));
+        }
       }
     }
+    if (!success) {
+      logger('Failed to get transactions after $retries attempts');
+      return;
+    }
   }
 
   @override
diff --git a/lib/g1/api.dart b/lib/g1/api.dart
index c4ec52b32d9230df3ce68fbd5d8fc256fafb5516..1f09ddc492e6ad79288bac46e5bd64cc1b72a858 100644
--- a/lib/g1/api.dart
+++ b/lib/g1/api.dart
@@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart';
 import 'package:http/http.dart' as http;
 import 'package:http/http.dart';
 import 'package:sentry_flutter/sentry_flutter.dart';
+import 'package:tuple/tuple.dart';
 import 'package:universal_html/html.dart' show window;
 
 import '../data/models/contact.dart';
@@ -496,8 +497,7 @@ Future<http.Response> _requestWithRetry(
     } catch (e) {
       logger('Error trying ${node.url} $e');
       if (!dontRecord) {
-        logger('Increasing node errors of ${node.url} (${node.errors})');
-        NodeManager().updateNode(type, node.copyWith(errors: node.errors + 1));
+        increaseNodeErrors(type, node);
       }
       continue;
     }
@@ -574,37 +574,36 @@ String proxyfyNode(String nodeUrl) {
   return url;
 }
 
-Future<Map<String, dynamic>?> gvaHistoryAndBalance(String pubKey) async {
+Future<Tuple2<Map<String, dynamic>?, Node>> gvaHistoryAndBalance(
+    String pubKey) async {
   return gvaFunctionWrapper<Map<String, dynamic>>(
       pubKey, (Gva gva) => gva.history(pubKey));
 }
 
-Future<double?> gvaBalance(String pubKey) async {
+Future<Tuple2<double?, Node>> gvaBalance(String pubKey) async {
   return gvaFunctionWrapper<double>(pubKey, (Gva gva) => gva.balance(pubKey));
 }
 
-Future<String?> gvaNick(String pubKey) async {
+Future<Tuple2<String?, Node>> gvaNick(String pubKey) async {
   return gvaFunctionWrapper<String>(
       pubKey, (Gva gva) => gva.getUsername(pubKey));
 }
 
-Future<T?> gvaFunctionWrapper<T>(
+Future<Tuple2<T?, Node>> gvaFunctionWrapper<T>(
     String pubKey, Future<T?> Function(Gva) specificFunction) async {
   final List<Node> nodes = _getBestGvaNodes();
   for (int i = 0; i < nodes.length; i++) {
     final Node node = nodes[i];
     try {
       final Gva gva = Gva(node: proxyfyNode(node.url));
-      logger('Trying use gva ${node.url}');
+      logger('Trying to use gva ${node.url}');
       final T? result = await specificFunction(gva);
-      return result;
+      return Tuple2<T?, Node>(result, node);
     } catch (e) {
       // await Sentry.captureMessage(
       //     'Error trying to use gva node ${node.url} $e');
       logger('Error trying ${node.url} $e');
-      logger('Increasing node errors of ${node.url} (${node.errors})');
-      NodeManager()
-          .updateNode(NodeType.gva, node.copyWith(errors: node.errors + 1));
+      increaseNodeErrors(NodeType.gva, node);
       continue;
     }
   }
@@ -638,3 +637,8 @@ class NodeCheck {
   final Duration latency;
   final int currentBlock;
 }
+
+void increaseNodeErrors(NodeType type, Node node) {
+  logger('Increasing node errors of ${node.url} (${node.errors})');
+  NodeManager().updateNode(type, node.copyWith(errors: node.errors + 1));
+}
diff --git a/lib/g1/transaction_parser.dart b/lib/g1/transaction_parser.dart
index 556570c41c75ceb04b5eade2a1237b1f7ca6c88d..d5c5ab9747a95d799509e5eb828fc5e236378625 100644
--- a/lib/g1/transaction_parser.dart
+++ b/lib/g1/transaction_parser.dart
@@ -57,13 +57,9 @@ TransactionsAndBalanceState transactionsGvaParser(
     Map<String, dynamic> txData, TransactionsAndBalanceState state) {
   // Balance
   final dynamic rawBalance = txData['balance'];
-  final double? amount;
-  if (rawBalance != null) {
-    final Map<String, dynamic> balance = rawBalance as Map<String, dynamic>;
-    amount = (balance['amount'] as int) / 1.0;
-  } else {
-    amount = 0;
-  }
+  final double amount = rawBalance != null
+      ? ((rawBalance as Map<String, dynamic>)['amount'] as int) / 1.0
+      : 0;
   // Transactions
   final Map<String, dynamic> txsHistoryBc =
       txData['txsHistoryBc'] as Map<String, dynamic>;
diff --git a/lib/ui/widgets/fourth_screen/transaction_page.dart b/lib/ui/widgets/fourth_screen/transaction_page.dart
index da9ff95d21372d1e4e319016ef74aeee445635b9..87c711ef2a1d143267a0557fe176d1987d870949 100644
--- a/lib/ui/widgets/fourth_screen/transaction_page.dart
+++ b/lib/ui/widgets/fourth_screen/transaction_page.dart
@@ -34,7 +34,7 @@ class _TransactionsAndBalanceWidgetState
   void initState() {
     super.initState();
     _transScrollController.addListener(_scrollListener);
-// Remove in the future
+    // Remove in the future
     transCubit = context.read<TransactionsCubit>();
     nodeListCubit = context.read<NodeListCubit>();
     transCubit.fetchTransactions(nodeListCubit);
diff --git a/pubspec.lock b/pubspec.lock
index f0a252e135d1c42cebcbe9911f6a285eeb392b6b..696e5e73ada37cf3b3e66a7bc370e345d3452d72 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1337,6 +1337,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.1"
+  tuple:
+    dependency: "direct main"
+    description:
+      name: tuple
+      sha256: "0ea99cd2f9352b2586583ab2ce6489d1f95a5f6de6fb9492faaf97ae2060f0aa"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.1"
   typed_data:
     dependency: transitive
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 9858c10edf745360c0db0df05de92b0b83962cb8..2b9baaec7883fd65b03c176876556bcc13ca0853 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -75,6 +75,7 @@ dependencies:
   barcode_scan2: ^4.2.4
   jsqr: ^0.1.4
   web_browser_detect: ^2.0.3
+  tuple: ^2.0.1
 
 dev_dependencies:
   flutter_test: