diff --git a/assets/translations/en.json b/assets/translations/en.json
index 7cc29e7f8b92a9ff9c1ed7267270e25e5a033d77..1ff918b203e92b3ba6e677157e5f3dd3bde93705 100644
--- a/assets/translations/en.json
+++ b/assets/translations/en.json
@@ -94,5 +94,6 @@
   "transaction_sending": "Sending",
   "transaction_receiving": "Receiving",
   "transaction_sent": "Sent",
-  "transaction_received": "Received"
+  "transaction_received": "Received",
+  "valid_comment": "The comment cannot have accents or commas"
 }
diff --git a/assets/translations/es.json b/assets/translations/es.json
index cb7388144c32bd2e3735b209f090d133915f7f7d..2c00c5a4f0616030b86b3e646d8f0352503c726f 100644
--- a/assets/translations/es.json
+++ b/assets/translations/es.json
@@ -93,5 +93,6 @@
   "transaction_sending": "Enviando",
   "transaction_receiving": "Recibiendo",
   "transaction_sent": "Enviado",
-  "transaction_received": "Recibido"
+  "transaction_received": "Recibido",
+  "valid_comment": "El comentario no puede tener tildes o comas"
 }
diff --git a/lib/data/models/transaction.dart b/lib/data/models/transaction.dart
index 57eaccea013139d5805ee417586bdf611b3d836d..1a4bbfb2293d1f2d434869e5844b8e0c57071417 100644
--- a/lib/data/models/transaction.dart
+++ b/lib/data/models/transaction.dart
@@ -41,6 +41,12 @@ class Transaction extends Equatable {
   final Uint8List? fromAvatar;
   final String? fromNick;
 
+  bool get isOutgoing =>
+      type == TransactionType.sending || type == TransactionType.sent;
+
+  bool get isIncoming =>
+      type == TransactionType.receiving || type == TransactionType.received;
+
   Map<String, dynamic> toJson() => _$TransactionToJson(this);
 
   @override
diff --git a/lib/g1/transaction_parser.dart b/lib/g1/transaction_parser.dart
index 831b624aac733a75e42f8ac7f2bc521f827899d0..660397144c236c704af6a561d34bb54260448678 100644
--- a/lib/g1/transaction_parser.dart
+++ b/lib/g1/transaction_parser.dart
@@ -82,12 +82,12 @@ TransactionsAndBalanceState transactionsGvaParser(Map<String, dynamic> txData) {
   for (final dynamic receiveRaw in receiving) {
     final Transaction tx = _txGvaParse(
         receiveRaw as Map<String, dynamic>, TransactionType.receiving);
-    txs.add(tx);
+    txs.insert(0, tx);
   }
   for (final dynamic sendingRaw in sending) {
     final Transaction tx = _txGvaParse(
         sendingRaw as Map<String, dynamic>, TransactionType.sending);
-    txs.add(tx);
+    txs.insert(0, tx);
   }
   return TransactionsAndBalanceState(
       transactions: txs, balance: amount, lastChecked: DateTime.now());
diff --git a/lib/main.dart b/lib/main.dart
index 9b7ec5b32b04fd4fc10629af83440d1f2a3fb8b2..dbe44ab793489160f45cebf5905abf563f252a47 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -215,6 +215,7 @@ class _GinkgoAppState extends State<GinkgoApp> {
     await fetchDuniterNodes(NodeType.duniter);
     await fetchCesiumPlusNodes();
     await fetchDuniterNodes(NodeType.gva);
+
     _printNodeStatus(prefix: 'Continuing');
   }
 
@@ -248,6 +249,10 @@ class _GinkgoAppState extends State<GinkgoApp> {
       Once.runCustom('clear_errors', callback: () {
         NodeManager().cleanErrorStats();
       }, duration: const Duration(minutes: 90));
+      Once.runCustom('fetch_transactions', callback: () {
+        fetchTransactions(context);
+      }, duration: const Duration(minutes: 10));
+      fetchTransactions(context);
       return ConnectivityAppWrapper(
           app: MaterialApp(
         /// Localization is not available for the title.
diff --git a/lib/ui/screens/g1_textfield.dart b/lib/ui/screens/g1_textfield.dart
index 4fa30a23665a41300fd0e73f17ffa0e7a4ee90c9..c9bddc0df29528e121a318c350737bb64a5094ca 100644
--- a/lib/ui/screens/g1_textfield.dart
+++ b/lib/ui/screens/g1_textfield.dart
@@ -21,8 +21,6 @@ class _G1PayAmountFieldState extends State<G1PayAmountField> {
   @override
   Widget build(BuildContext context) => BlocBuilder<PaymentCubit, PaymentState>(
           builder: (BuildContext context, PaymentState state) {
-        final NumberFormat format =
-            NumberFormat.decimalPattern(context.locale.toString());
         if (state.amount != null) {
           final String amountFormatted = localizeNumber(context, state.amount!);
           if (_controller.text != amountFormatted) {
@@ -45,10 +43,13 @@ class _G1PayAmountFieldState extends State<G1PayAmountField> {
               onEditingComplete: () {},
               onChanged: (String? value) {
                 final bool? validate = _formKey.currentState?.validate();
-                if (validate != null && validate) {
-                  context
-                      .read<PaymentCubit>()
-                      .selectAmount(format.parse(value!).toDouble());
+                if (validate != null &&
+                    value != null &&
+                    value.isNotEmpty &&
+                    validate) {
+                  context.read<PaymentCubit>().selectAmount(
+                      parseToDoubleLocalized(
+                          context.locale.toLanguageTag(), value));
                 }
               },
               decoration: InputDecoration(
diff --git a/lib/ui/screens/pay_form.dart b/lib/ui/screens/pay_form.dart
index 42b00a81fd0bbb75004a09cba352c760dc43cdf2..e1f334f54a511a2c24f746abf651ecd6c6dbf5f6 100644
--- a/lib/ui/screens/pay_form.dart
+++ b/lib/ui/screens/pay_form.dart
@@ -1,12 +1,12 @@
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
 import '../../data/models/payment_cubit.dart';
 import '../../data/models/payment_state.dart';
 import '../../data/models/transaction_cubit.dart';
 import '../../g1/api.dart';
+import '../logger.dart';
 import '../ui_helpers.dart';
 import 'g1_textfield.dart';
 
@@ -21,112 +21,123 @@ class _PayFormState extends State<PayForm> {
   final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
   final TextEditingController _commentController = TextEditingController();
 
+//  static final RegExp _englishRegExp = RegExp('^[\u0000-\u007F]*\$');
+  // static final RegExp _englishRegExp = RegExp(r'^[a-zA-Z0-9\s.,;:!?()\-]*$');
+
   @override
   Widget build(BuildContext context) {
     return BlocBuilder<PaymentCubit, PaymentState>(
         builder: (BuildContext context, PaymentState state) {
-          if (state.comment != null &&
-              _commentController.text != state.comment) {
-            _commentController.text = state.comment;
-          }
-          return Form(
-            key: _formKey,
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.stretch,
-              children: <Widget>[
-                const G1PayAmountField(),
-                const SizedBox(height: 10.0),
-                TextField(
-                  controller: _commentController,
-                  inputFormatters: <TextInputFormatter>[
-                    Iso88591TextInputFormatter()
-                  ],
-                  onChanged: (String? value) {
-                    if (value != null) {
-                      context.read<PaymentCubit>().setComment(value);
-                    }
-                  },
-                  decoration: InputDecoration(
-                    labelText: tr('g1_form_pay_desc'),
-                    hintText: tr('g1_form_pay_hint'),
-                    border: const OutlineInputBorder(),
-                  ),
-                  maxLines: null,
-                ),
-                const SizedBox(height: 10.0),
-                ElevatedButton(
-                  onPressed: !state.canBeSent() ||
+      if (state.comment != null && _commentController.text != state.comment) {
+        _commentController.text = state.comment;
+      }
+      return Form(
+        key: _formKey,
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          children: <Widget>[
+            const G1PayAmountField(),
+            const SizedBox(height: 10.0),
+            TextFormField(
+              controller: _commentController,
+              onChanged: (String? value) {
+                final bool? validate = _commentValidate();
+                if (validate != null &&
+                    value != null &&
+                    value.isNotEmpty &&
+                    validate) {
+                  context.read<PaymentCubit>().setComment(value);
+                }
+              },
+              decoration: InputDecoration(
+                labelText: tr('g1_form_pay_desc'),
+                hintText: tr('g1_form_pay_hint'),
+                border: const OutlineInputBorder(),
+              ),
+              validator: (String? value) {
+                if (value != null && !basicEnglishCharsRegExp.hasMatch(value)) {
+                  return tr('valid_comment');
+                }
+                return null;
+              },
+              maxLines: null,
+            ),
+            const SizedBox(height: 10.0),
+            ElevatedButton(
+              onPressed: !state.canBeSent() ||
+                      _commentValidate() == false ||
                       state.amount == null ||
                       !_weHaveBalance(context, state.amount!)
-                      ? null
-                      : () async {
-                    // We disable the number, anyway
-                    context.read<PaymentCubit>().sending();
-                    final bool? confirmed = await _confirmSend(
-                        context,
-                        state.amount!.toString(),
-                        humanizePubKey(state.publicKey));
-                    if (!mounted) {
-                      return;
-                    }
-                    if (confirmed == null || !confirmed) {
-                      context.read<PaymentCubit>().sentFailed();
-                    } else {
-                      final String response = await pay(
-                          to: state.publicKey,
-                          comment: state.comment,
-                          amount: state.amount!);
+                  ? null
+                  : () async {
+                      // We disable the number, anyway
+                      context.read<PaymentCubit>().sending();
+                      final bool? confirmed = await _confirmSend(
+                          context,
+                          state.amount!.toString(),
+                          humanizePubKey(state.publicKey));
                       if (!mounted) {
-                        // Cannot show a tooltip if the widget is not now visible
                         return;
                       }
-                      if (response == 'success') {
-                        context.read<PaymentCubit>().sent();
-                        showTooltip(context, '', tr('payment_successful'));
-                      } else {
+                      if (confirmed == null || !confirmed) {
                         context.read<PaymentCubit>().sentFailed();
-                        showTooltip(context, '', tr(response));
+                      } else {
+                        final String response = await pay(
+                            to: state.publicKey,
+                            comment: state.comment,
+                            amount: state.amount!);
+                        if (!mounted) {
+                          // Cannot show a tooltip if the widget is not now visible
+                          return;
+                        }
+                        if (response == 'success') {
+                          context.read<PaymentCubit>().sent();
+                          showTooltip(context, '', tr('payment_successful'));
+                        } else {
+                          context.read<PaymentCubit>().sentFailed();
+                          showTooltip(context, '', tr(response));
+                        }
                       }
-                    }
-                  },
-                  style: ElevatedButton.styleFrom(
-                    padding:
+                    },
+              style: ElevatedButton.styleFrom(
+                padding:
                     const EdgeInsets.symmetric(horizontal: 20, vertical: 25),
-                    shape: RoundedRectangleBorder(
-                      borderRadius: BorderRadius.circular(30.0),
-                    ),
-                    foregroundColor: Colors.white,
-                    backgroundColor: Theme
-                        .of(context)
-                        .colorScheme
-                        .primary,
-                    textStyle: const TextStyle(
-                      fontWeight: FontWeight.bold,
-                      fontSize: 16,
-                    ),
-                  ),
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.center,
-                    children: <Widget>[
-                      const Icon(Icons.send),
-                      const SizedBox(width: 10),
-                      Text(tr('g1_form_pay_send')),
-                    ],
-                  ),
-                )
-              ],
-            ),
-          );
-        });
+                shape: RoundedRectangleBorder(
+                  borderRadius: BorderRadius.circular(30.0),
+                ),
+                foregroundColor: Colors.white,
+                backgroundColor: Theme.of(context).colorScheme.primary,
+                textStyle: const TextStyle(
+                  fontWeight: FontWeight.bold,
+                  fontSize: 16,
+                ),
+              ),
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.center,
+                children: <Widget>[
+                  const Icon(Icons.send),
+                  const SizedBox(width: 10),
+                  Text(tr('g1_form_pay_send')),
+                ],
+              ),
+            )
+          ],
+        ),
+      );
+    });
+  }
+
+  bool _commentValidate() {
+    final bool? val = _formKey.currentState?.validate();
+    logger('Validating comment: $val');
+    return val ?? false;
   }
 
   bool _weHaveBalance(BuildContext context, double amount) =>
-      context
-          .read<TransactionsCubit>()
-          .balance >= amount * 100;
+      context.read<TransactionsCubit>().balance >= amount * 100;
 
-  Future<bool?> _confirmSend(BuildContext context, String amount,
-      String to) async {
+  Future<bool?> _confirmSend(
+      BuildContext context, String amount, String to) async {
     return showDialog<bool>(
       context: context,
       builder: (BuildContext context) {
@@ -149,18 +160,3 @@ class _PayFormState extends State<PayForm> {
     );
   }
 }
-
-class Iso88591TextInputFormatter extends TextInputFormatter {
-  // static final RegExp _iso88591RegExp = RegExp('^[\u0000-\u00FF]*\$');
-  static final RegExp _englishRegExp = RegExp('^[\u0000-\u007F]*\$');
-
-  @override
-  TextEditingValue formatEditUpdate(TextEditingValue oldValue,
-      TextEditingValue newValue) {
-    if (_englishRegExp.hasMatch(newValue.text)) {
-      return newValue;
-    } else {
-      return oldValue;
-    }
-  }
-}
diff --git a/lib/ui/ui_helpers.dart b/lib/ui/ui_helpers.dart
index 0115eda8aae525103e6e540f831f7d4607c4cad1..53fd3714dfcf4aa219844aa3749c23578a50f4a1 100644
--- a/lib/ui/ui_helpers.dart
+++ b/lib/ui/ui_helpers.dart
@@ -3,10 +3,12 @@ import 'dart:typed_data';
 import 'package:clipboard/clipboard.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:timeago/timeago.dart' as timeago;
 
 import '../data/models/contact.dart';
-import '../data/models/transaction_type.dart';
+import '../data/models/node_list_cubit.dart';
+import '../data/models/transaction_cubit.dart';
 import '../g1/api.dart';
 import '../shared_prefs.dart';
 import 'widgets/first_screen/circular_icon.dart';
@@ -41,10 +43,12 @@ const Color defAvatarBgColor = Colors.grey;
 const Color defAvatarColor = Colors.white;
 
 Widget avatar(Uint8List? rawAvatar,
-    {Color color = defAvatarColor, Color bgColor = defAvatarBgColor}) {
+    {Color color = defAvatarColor,
+    Color bgColor = defAvatarBgColor,
+    double avatarSize = 24}) {
   return rawAvatar != null && rawAvatar.isNotEmpty
       ? CircleAvatar(
-          radius: 24,
+          radius: avatarSize,
           child: ClipOval(
               child: Image.memory(
             rawAvatar,
@@ -62,6 +66,24 @@ String humanizeFromToPubKey(String publicAddress, String address) {
   }
 }
 
+String humanizeContact(String publicAddress, Contact contact) {
+  final bool hasName = contact.name?.isNotEmpty ?? false;
+  final bool hasNick = contact.nick?.isNotEmpty ?? false;
+
+  if (contact.pubKey == publicAddress) {
+    return tr('your_wallet');
+  } else {
+    if (hasName && hasNick)
+      return '${contact.name} (${contact.nick})';
+    else if (hasNick)
+      return contact.nick!;
+    else if (hasName)
+      return contact.name!;
+    else
+      return humanizePubKey(contact.pubKey);
+  }
+}
+
 String humanizePubKey(String address) => '\u{1F511} ${simplifyPubKey(address)}';
 
 String simplifyPubKey(String address) => address.substring(0, 8);
@@ -82,8 +104,9 @@ Color tileColor(int index, BuildContext context, [bool inverse = false]) {
       : unselectedColor;
 }
 
+// https://github.com/andresaraujo/timeago.dart/pull/142#issuecomment-859661123
 String? humanizeTime(DateTime time, String locale) =>
-    timeago.format(time, locale: locale, clock: DateTime.now());
+    timeago.format(time.toUtc(), locale: locale, clock: DateTime.now().toUtc());
 
 const bool txDebugging = false;
 
@@ -107,19 +130,14 @@ String formatAmount(BuildContext context, double amount) {
 String formatKAmount(BuildContext context, double amount) =>
     formatAmount(context, amount / 100);
 
+double parseToDoubleLocalized(String locale, String double) =>
+    NumberFormat.decimalPattern(locale).parse(double).toDouble();
+
 String getAppVersion() => '0.0.8';
 
 String localizeNumber(BuildContext context, double amount) =>
     NumberFormat.decimalPattern(context.locale.toString()).format(amount);
 
-bool isOutgoing(TransactionType type) {
-  return type == TransactionType.sending || type == TransactionType.sent;
-}
-
-bool isIncoming(TransactionType type) {
-  return type == TransactionType.receiving || type == TransactionType.received;
-}
-
 Contact contactFromResultSearch(Map<String, dynamic> record) {
   final Map<String, dynamic> source = record['_source'] as Map<String, dynamic>;
   final Uint8List? avatarBase64 = _getAvatarFromResults(source);
@@ -147,3 +165,13 @@ Uint8List? _getAvatarFromResults(Map<String, dynamic> source) {
   }
   return avatarBase64;
 }
+
+final RegExp basicEnglishCharsRegExp =
+    RegExp(r'^[ A-Za-z0-9\s.;:!?()\-_;!@&<>%]*$');
+// RegExp(r'^[a-zA-Z0-9-_:/;*\[\]()?!^\\+=@&~#{}|\<>%.]*$');
+
+void fetchTransactions(BuildContext context) {
+  final TransactionsCubit transCubit = context.read<TransactionsCubit>();
+  final NodeListCubit nodeListCubit = context.read<NodeListCubit>();
+  transCubit.fetchTransactions(nodeListCubit);
+}
diff --git a/lib/ui/widgets/fifth_screen/import_dialog.dart b/lib/ui/widgets/fifth_screen/import_dialog.dart
index 9d4bdc89a0110dae5bda6cc7c959204f4cb16ece..060623729605d3836958e6be4d1cc85b2a0e4b0c 100644
--- a/lib/ui/widgets/fifth_screen/import_dialog.dart
+++ b/lib/ui/widgets/fifth_screen/import_dialog.dart
@@ -12,6 +12,7 @@ import '../../../data/models/transaction_cubit.dart';
 import '../../../g1/g1_helper.dart';
 import '../../../shared_prefs.dart';
 import '../../logger.dart';
+import '../../ui_helpers.dart';
 import '../custom_error_widget.dart';
 import '../loading_box.dart';
 import 'pattern_util.dart';
@@ -78,6 +79,8 @@ class _ImportDialogState extends State<ImportDialog> {
                                 style: const TextStyle(color: Colors.white),
                               ),
                             );
+                            // ok, fetch the transactions & balance
+                            fetchTransactions(context);
                           }
                           if (!mounted) {
                             return;
diff --git a/lib/ui/widgets/fourth_screen/transaction_item.dart b/lib/ui/widgets/fourth_screen/transaction_item.dart
index 3d7aefc244eb02ec5c25b2bb7d2462c261138eea..298a497c19acb72b61b2aea5d156ebce6461cd3f 100644
--- a/lib/ui/widgets/fourth_screen/transaction_item.dart
+++ b/lib/ui/widgets/fourth_screen/transaction_item.dart
@@ -26,33 +26,31 @@ class TransactionListItem extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) =>
-      BlocBuilder<TransactionsCubit,
-          TransactionsAndBalanceState>(
+      BlocBuilder<TransactionsCubit, TransactionsAndBalanceState>(
           builder: (BuildContext context,
-              TransactionsAndBalanceState transBalanceState) =>
-              FutureBuilder<Contact>(
+                  TransactionsAndBalanceState transBalanceState) =>
+              FutureBuilder<List<Contact>>(
                   future: _fetchContact(pubKey, transaction),
                   builder: (BuildContext context,
-                      AsyncSnapshot<Contact> snapshot) {
+                      AsyncSnapshot<List<Contact>> snapshot) {
                     if (snapshot.hasData) {
                       return _buildTransactionItem(context, snapshot.data!);
                     } else if (snapshot.hasError) {
                       return Text('Error ${snapshot.error}');
                     } else {
-                      return _buildTransactionItem(context, Contact(
-                          pubKey: isIncoming(transaction.type) ? transaction
-                              .from : transaction.to));
+                      return _buildTransactionItem(context, <Contact>[
+                        Contact(pubKey: transaction.from),
+                        Contact(pubKey: transaction.to)
+                      ]);
                     }
                   }));
 
-  Slidable _buildTransactionItem(BuildContext context,
-      Contact contact) {
+  Slidable _buildTransactionItem(BuildContext context, List<Contact> contacts) {
     IconData? icon;
     Color? iconColor;
     String statusText;
     final String amountS =
-        '${transaction.amount < 0 ? "" : "+"}${formatKAmount(
-        context, transaction.amount)}';
+        '${transaction.amount < 0 ? "" : "+"}${formatKAmount(context, transaction.amount)}';
     statusText = tr('transaction_${transaction.type.name}');
     switch (transaction.type) {
       case TransactionType.pending:
@@ -73,10 +71,10 @@ class TransactionListItem extends StatelessWidget {
         break;
     }
     final String myPubKey = SharedPreferencesHelper().getPubKey();
-    final ContactsCubit contactsCubit =
-    context.read<ContactsCubit>();
+
+    final ContactsCubit contactsCubit = context.read<ContactsCubit>();
     return Slidable(
-      // Specify a key if the Slidable is dismissible.
+        // Specify a key if the Slidable is dismissible.
         key: const ValueKey<int>(0),
         // The end action pane is the one at the right or the bottom side.
         endActionPane: ActionPane(
@@ -84,16 +82,15 @@ class TransactionListItem extends StatelessWidget {
           children: <SlidableAction>[
             SlidableAction(
               onPressed: (BuildContext c) {
-                contactsCubit.addContact(contact);
+                contactsCubit.addContact(
+                    transaction.isIncoming ? contacts[0] : contacts[1]);
                 ScaffoldMessenger.of(context).showSnackBar(
                   SnackBar(
                     content: Text(tr('contact_added')),
                   ),
                 );
               },
-              backgroundColor: Theme
-                  .of(context)
-                  .primaryColor,
+              backgroundColor: Theme.of(context).primaryColor,
               foregroundColor: Colors.white,
               icon: Icons.contacts,
               label: tr('add_contact'),
@@ -103,14 +100,13 @@ class TransactionListItem extends StatelessWidget {
         child: ListTile(
           leading: (icon != null)
               ? Icon(
-            icon,
-            color: iconColor,
-          )
+                  icon,
+                  color: iconColor,
+                )
               : null,
           tileColor: tileColor(index, context),
           title: Row(
             children: <Widget>[
-              // if (avatar != null) avatar,
               const SizedBox(width: 8.0),
               Expanded(
                 child: Column(
@@ -145,11 +141,9 @@ class TransactionListItem extends StatelessWidget {
                             child: Text(
                               tr('transaction_from_to',
                                   namedArgs: <String, String>{
-                                    'from': humanizeFromToPubKey(
-                                        myPubKey,
-                                        transaction.from),
-                                    'to': humanizeFromToPubKey(
-                                        myPubKey, transaction.to)
+                                    'from':
+                                        humanizeContact(myPubKey, contacts[0]),
+                                    'to': humanizeContact(myPubKey, contacts[1])
                                   }),
                               style: const TextStyle(
                                 fontSize: 14.0,
@@ -181,18 +175,15 @@ class TransactionListItem extends StatelessWidget {
                 amountS,
                 style: TextStyle(
                   // fontWeight: FontWeight.bold,
-                  color: transaction.type ==
-                      TransactionType.received ||
-                      transaction.type ==
-                          TransactionType.receiving
+                  color: transaction.type == TransactionType.received ||
+                          transaction.type == TransactionType.receiving
                       ? Colors.blue
                       : Colors.red,
                 ),
               ),
               const SizedBox(height: 4.0),
               Text(
-                humanizeTime(
-                    transaction.time, context.locale.toString())!,
+                humanizeTime(transaction.time, context.locale.toString())!,
                 style: const TextStyle(
                   fontSize: 12.0,
                   color: Colors.grey,
@@ -203,12 +194,15 @@ class TransactionListItem extends StatelessWidget {
         ));
   }
 
-  Future<Contact> _fetchContact(String pubKey, Transaction transaction) async {
-    // return Contact(pubKey: pubKey);
+  Future<List<Contact>> _fetchContact(
+      String pubKey, Transaction transaction) async {
+    final Contact myContact = await ContactsCache().getContact(pubKey);
     if (pubKey == transaction.from) {
-      return ContactsCache().getContact(transaction.to);
+      final Contact to = await ContactsCache().getContact(transaction.to);
+      return <Contact>[myContact, to];
     } else {
-      return ContactsCache().getContact(transaction.from);
+      final Contact from = await ContactsCache().getContact(transaction.from);
+      return <Contact>[from, myContact];
     }
   }
 }
diff --git a/lib/ui/widgets/fourth_screen/transaction_page.dart b/lib/ui/widgets/fourth_screen/transaction_page.dart
index 6691dea6aeb80902789b446e3abd4535c6f34633..1086ec4c0f6e222b4e0bd09f228a2752d812c77c 100644
--- a/lib/ui/widgets/fourth_screen/transaction_page.dart
+++ b/lib/ui/widgets/fourth_screen/transaction_page.dart
@@ -33,6 +33,7 @@ class _TransactionsAndBalanceWidgetState
   void initState() {
     super.initState();
     _transScrollController.addListener(_scrollListener);
+// Remove in the future
     transCubit = context.read<TransactionsCubit>();
     nodeListCubit = context.read<NodeListCubit>();
     transCubit.fetchTransactions(nodeListCubit);
@@ -56,7 +57,7 @@ class _TransactionsAndBalanceWidgetState
   }
 
   final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
-      GlobalKey<RefreshIndicatorState>();
+  GlobalKey<RefreshIndicatorState>();
 
   @override
   Widget build(BuildContext context) {
@@ -67,7 +68,10 @@ class _TransactionsAndBalanceWidgetState
       final double balance = transBalanceState.balance;
       return BackdropScaffold(
           appBar: BackdropAppBar(
-            backgroundColor: Theme.of(context).colorScheme.inversePrimary,
+            backgroundColor: Theme
+                .of(context)
+                .colorScheme
+                .inversePrimary,
             title: Text(tr('balance')),
             actions: <Widget>[
               IconButton(
@@ -78,49 +82,59 @@ class _TransactionsAndBalanceWidgetState
                 },
               ),
               const BackdropToggleButton(
-                  // The default
-                  // icon: AnimatedIcons.close_menu,
-                  )
+                // The default
+                // icon: AnimatedIcons.close_menu,
+              )
             ],
           ),
           backLayer: Center(
               child: Container(
-            decoration: BoxDecoration(
-              color: Theme.of(context).colorScheme.inversePrimary,
-              border: Border.all(
-                  color: Theme.of(context).colorScheme.inversePrimary,
-                  width: 3),
-              /* borderRadius: const BorderRadius.only(
+                decoration: BoxDecoration(
+                  color: Theme
+                      .of(context)
+                      .colorScheme
+                      .inversePrimary,
+                  border: Border.all(
+                      color: Theme
+                          .of(context)
+                          .colorScheme
+                          .inversePrimary,
+                      width: 3),
+                  /* borderRadius: const BorderRadius.only(
               topLeft: Radius.circular(8),
               topRight: Radius.circular(8),
             ), */
-            ),
-            child: Scrollbar(
-                child: ListView(
-              //   controller: scrollController,
-              children: <Widget>[
-                Padding(
-                  padding: const EdgeInsets.symmetric(vertical: 10.0),
-                  child: Center(
-                      child: Text(
-                    formatKAmount(context, balance),
-                    style: TextStyle(
-                        fontSize: 36.0,
-                        color:
-                            balance == 0 ? Colors.lightBlue : Colors.lightBlue,
-                        fontWeight: FontWeight.bold),
-                  )),
                 ),
-                if (!kReleaseMode) TransactionChart()
-                /*BalanceChart(
+                child: Scrollbar(
+                    child: ListView(
+                      //   controller: scrollController,
+                      children: <Widget>[
+                        Padding(
+                          padding: const EdgeInsets.symmetric(vertical: 10.0),
+                          child: Center(
+                              child: Text(
+                                formatKAmount(context, balance),
+                                style: TextStyle(
+                                    fontSize: 36.0,
+                                    color:
+                                    balance == 0 ? Colors.lightBlue : Colors
+                                        .lightBlue,
+                                    fontWeight: FontWeight.bold),
+                              )),
+                        ),
+                        if (!kReleaseMode) TransactionChart()
+                        /*BalanceChart(
                                     transactions: .transactions),*/
-              ],
-            )),
-          )),
+                      ],
+                    )),
+              )),
           subHeader: BackdropSubHeader(
             title: Text(tr('transactions')),
             divider: Divider(
-              color: Theme.of(context).colorScheme.surfaceVariant,
+              color: Theme
+                  .of(context)
+                  .colorScheme
+                  .surfaceVariant,
               height: 0,
             ),
           ),
@@ -140,16 +154,19 @@ class _TransactionsAndBalanceWidgetState
                           child: Header(text: 'transactions'))), */
                   Expanded(
                       child: Padding(
-                    padding: const EdgeInsets.fromLTRB(0, 0, 0, 50),
-                    child: transactions.isEmpty
-                        ? Padding(
+                        padding: const EdgeInsets.fromLTRB(0, 0, 0, 50),
+                        child: transactions.isEmpty
+                            ? Padding(
                             padding: const EdgeInsets.symmetric(horizontal: 20),
                             child: Center(child: Text(tr('no_transactions'))))
-                        : RefreshIndicator(
+                            : RefreshIndicator(
                             key: _refreshIndicatorKey,
                             color: Colors.white,
                             backgroundColor:
-                                Theme.of(context).colorScheme.primary,
+                            Theme
+                                .of(context)
+                                .colorScheme
+                                .primary,
                             strokeWidth: 4.0,
                             onRefresh: () async {
                               return _refreshTransactions();
@@ -238,7 +255,7 @@ class _TransactionsAndBalanceWidgetState
                                       */
                               },
                             )),
-                  ))
+                      ))
                 ]),
           ));
     });
diff --git a/lib/ui/widgets/transaction_contact_widget.dart b/lib/ui/widgets/transaction_contact_widget.dart
new file mode 100644
index 0000000000000000000000000000000000000000..c2a42b4bd23a5155e2de42fe9a14e0c5b9825115
--- /dev/null
+++ b/lib/ui/widgets/transaction_contact_widget.dart
@@ -0,0 +1,44 @@
+import 'package:flutter/material.dart';
+
+import '../../data/models/contact.dart';
+import '../ui_helpers.dart';
+
+class TransactionContactWidget extends StatelessWidget {
+  const TransactionContactWidget(
+      {super.key, required this.contact, this.avatarSize = 10.0});
+
+  final Contact contact;
+  final double avatarSize;
+
+  @override
+  Widget build(BuildContext context) {
+    final bool hasName = contact.name?.isNotEmpty ?? false;
+    final bool hasNick = contact.nick?.isNotEmpty ?? false;
+
+    return Row(
+      children: <Widget>[
+        avatar(contact.avatar, avatarSize: avatarSize),
+        const SizedBox(width: 8.0),
+        Expanded(
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: <Widget>[
+              if (hasName && hasNick)
+                Text('${contact.name} (${contact.nick})',
+                    style: Theme.of(context).textTheme.titleMedium)
+              else if (hasNick)
+                Text(contact.nick!,
+                    style: Theme.of(context).textTheme.titleMedium)
+              else if (hasName)
+                Text(contact.name!,
+                    style: Theme.of(context).textTheme.titleMedium)
+              else
+                Text(contact.pubKey,
+                    style: Theme.of(context).textTheme.titleMedium)
+            ],
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/test/ui_test.dart b/test/ui_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..c4543f13c5a20943ea11b1cedf4ebe48959841c2
--- /dev/null
+++ b/test/ui_test.dart
@@ -0,0 +1,30 @@
+import 'package:flutter_test/flutter_test.dart';
+import 'package:ginkgo/ui/ui_helpers.dart';
+
+void main() {
+  test('localizedParseToDouble parses a localized double string correctly', () {
+    const String doubleString = '1.234,56';
+    final double parsedDouble = parseToDoubleLocalized('es', doubleString);
+    expect(parsedDouble, equals(1234.56));
+  });
+
+  test('valid and invalid comments', () {
+    const List<String> invalidText = <String>['á', '`e', 'ç', 'ñ', ','];
+    const List<String> validText = <String>[
+      'ab c de',
+      'a b c d e',
+      'a-b',
+      'a_b',
+      'a%',
+      'a & b'
+    ];
+    for (final String text in invalidText) {
+      expect(basicEnglishCharsRegExp.hasMatch(text), equals(false),
+          reason: 'Failed $text');
+    }
+    for (final String text in validText) {
+      expect(basicEnglishCharsRegExp.hasMatch(text), equals(true),
+          reason: 'Failed $text');
+    }
+  });
+}