From 109d9b458eac30534dd93492173145a3fc48b948 Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Thu, 7 Nov 2024 03:26:14 +0200
Subject: [PATCH 01/15] Cw 514 add sort functionality for addressbook 
 mywallets and contacts (#1309)

* add sort function to contact list

* fix UI

* prevent duplicate contact names

* dispose contact source subscription

* fix custom order issue

* update the address book UI

* fix saving custom order

* fix merge conflict issue

* review fixes [skip ci]

* revert to single scroll for entire page

* tabBarView address book

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 lib/entities/contact.dart                     |   9 +-
 lib/entities/contact_record.dart              |  23 +-
 lib/entities/preferences_key.dart             |   2 +
 lib/entities/wallet_list_order_types.dart     |  10 +-
 .../screens/contact/contact_list_page.dart    | 388 ++++++++++++++----
 .../dashboard/widgets/filter_list_widget.dart |  26 +-
 .../screens/wallet_list/filtered_list.dart    |  46 ++-
 .../screens/wallet_list/wallet_list_page.dart |   2 +-
 .../widgets/collapsible_standart_list.dart    |  39 --
 lib/store/settings_store.dart                 |  40 +-
 .../contact_list/contact_list_view_model.dart |  84 +++-
 .../contact_list/contact_view_model.dart      |  24 +-
 .../wallet_list/wallet_list_view_model.dart   |  14 +-
 res/values/strings_ar.arb                     |   5 +-
 res/values/strings_bg.arb                     |   5 +-
 res/values/strings_cs.arb                     |   5 +-
 res/values/strings_en.arb                     |   5 +-
 res/values/strings_es.arb                     |   3 +-
 res/values/strings_fr.arb                     |   5 +-
 res/values/strings_ha.arb                     |   5 +-
 res/values/strings_hi.arb                     |   5 +-
 res/values/strings_hr.arb                     |   5 +-
 res/values/strings_id.arb                     |   5 +-
 res/values/strings_it.arb                     |   5 +-
 res/values/strings_ja.arb                     |   5 +-
 res/values/strings_ko.arb                     |   5 +-
 res/values/strings_my.arb                     |   5 +-
 res/values/strings_nl.arb                     |   5 +-
 res/values/strings_pl.arb                     |   5 +-
 res/values/strings_pt.arb                     |   2 +-
 res/values/strings_ru.arb                     |   5 +-
 res/values/strings_th.arb                     |   5 +-
 res/values/strings_tl.arb                     |   2 +-
 res/values/strings_tr.arb                     |   5 +-
 res/values/strings_uk.arb                     |   5 +-
 res/values/strings_ur.arb                     |   5 +-
 res/values/strings_yo.arb                     |   5 +-
 res/values/strings_zh.arb                     |   5 +-
 38 files changed, 588 insertions(+), 236 deletions(-)
 delete mode 100644 lib/src/widgets/collapsible_standart_list.dart

diff --git a/lib/entities/contact.dart b/lib/entities/contact.dart
index cd4fa55a2..901993f43 100644
--- a/lib/entities/contact.dart
+++ b/lib/entities/contact.dart
@@ -7,7 +7,8 @@ part 'contact.g.dart';
 
 @HiveType(typeId: Contact.typeId)
 class Contact extends HiveObject with Keyable {
-  Contact({required this.name, required this.address, CryptoCurrency? type}) {
+  Contact({required this.name, required this.address, CryptoCurrency? type, DateTime? lastChange})
+      : lastChange = lastChange ?? DateTime.now() {
     if (type != null) {
       raw = type.raw;
     }
@@ -25,6 +26,9 @@ class Contact extends HiveObject with Keyable {
   @HiveField(2, defaultValue: 0)
   late int raw;
 
+  @HiveField(3)
+  DateTime lastChange;
+
   CryptoCurrency get type => CryptoCurrency.deserialize(raw: raw);
 
   @override
@@ -36,6 +40,5 @@ class Contact extends HiveObject with Keyable {
   @override
   int get hashCode => key.hashCode;
 
-  void updateCryptoCurrency({required CryptoCurrency currency}) =>
-      raw = currency.raw;
+  void updateCryptoCurrency({required CryptoCurrency currency}) => raw = currency.raw;
 }
diff --git a/lib/entities/contact_record.dart b/lib/entities/contact_record.dart
index 50a432727..4b0e120ba 100644
--- a/lib/entities/contact_record.dart
+++ b/lib/entities/contact_record.dart
@@ -1,22 +1,21 @@
+import 'package:cake_wallet/entities/contact.dart';
+import 'package:cake_wallet/entities/contact_base.dart';
+import 'package:cake_wallet/entities/record.dart';
+import 'package:cw_core/crypto_currency.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/entities/contact.dart';
-import 'package:cw_core/crypto_currency.dart';
-import 'package:cake_wallet/entities/record.dart';
-import 'package:cake_wallet/entities/contact_base.dart';
 
 part 'contact_record.g.dart';
 
 class ContactRecord = ContactRecordBase with _$ContactRecord;
 
-abstract class ContactRecordBase extends Record<Contact>
-    with Store
-    implements ContactBase {
+abstract class ContactRecordBase extends Record<Contact> with Store implements ContactBase {
   ContactRecordBase(Box<Contact> source, Contact original)
       : name = original.name,
         address = original.address,
         type = original.type,
-      super(source, original);
+        lastChange = original.lastChange,
+        super(source, original);
 
   @override
   @observable
@@ -30,14 +29,14 @@ abstract class ContactRecordBase extends Record<Contact>
   @observable
   CryptoCurrency type;
 
+  DateTime? lastChange;
+
   @override
   void toBind(Contact original) {
     reaction((_) => name, (String name) => original.name = name);
     reaction((_) => address, (String address) => original.address = address);
-    reaction(
-        (_) => type,
-        (CryptoCurrency currency) =>
-            original.updateCryptoCurrency(currency: currency));
+    reaction((_) => type,
+        (CryptoCurrency currency) => original.updateCryptoCurrency(currency: currency));
   }
 
   @override
diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart
index 4fbe358e5..73556452c 100644
--- a/lib/entities/preferences_key.dart
+++ b/lib/entities/preferences_key.dart
@@ -25,7 +25,9 @@ class PreferencesKey {
   static const disableBulletinKey = 'disable_bulletin';
   static const defaultBuyProvider = 'default_buy_provider';
   static const walletListOrder = 'wallet_list_order';
+  static const contactListOrder = 'contact_list_order';
   static const walletListAscending = 'wallet_list_ascending';
+  static const contactListAscending = 'contact_list_ascending';
   static const currentFiatApiModeKey = 'current_fiat_api_mode';
   static const failedTotpTokenTrials = 'failed_token_trials';
   static const disableExchangeKey = 'disable_exchange';
diff --git a/lib/entities/wallet_list_order_types.dart b/lib/entities/wallet_list_order_types.dart
index f848170f4..751569e9e 100644
--- a/lib/entities/wallet_list_order_types.dart
+++ b/lib/entities/wallet_list_order_types.dart
@@ -1,6 +1,6 @@
 import 'package:cake_wallet/generated/i18n.dart';
 
-enum WalletListOrderType {
+enum FilterListOrderType {
   CreationDate,
   Alphabetical,
   GroupByType,
@@ -9,13 +9,13 @@ enum WalletListOrderType {
   @override
   String toString() {
     switch (this) {
-      case WalletListOrderType.CreationDate:
+      case FilterListOrderType.CreationDate:
         return S.current.creation_date;
-      case WalletListOrderType.Alphabetical:
+      case FilterListOrderType.Alphabetical:
         return S.current.alphabetical;
-      case WalletListOrderType.GroupByType:
+      case FilterListOrderType.GroupByType:
         return S.current.group_by_type;
-      case WalletListOrderType.Custom:
+      case FilterListOrderType.Custom:
         return S.current.custom_drag;
     }
   }
diff --git a/lib/src/screens/contact/contact_list_page.dart b/lib/src/screens/contact/contact_list_page.dart
index 99f2aa251..130380b09 100644
--- a/lib/src/screens/contact/contact_list_page.dart
+++ b/lib/src/screens/contact/contact_list_page.dart
@@ -1,21 +1,24 @@
 import 'package:cake_wallet/core/auth_service.dart';
 import 'package:cake_wallet/entities/contact_base.dart';
 import 'package:cake_wallet/entities/contact_record.dart';
+import 'package:cake_wallet/entities/wallet_list_order_types.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/routes.dart';
+import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/screens/dashboard/widgets/filter_list_widget.dart';
+import 'package:cake_wallet/src/screens/wallet_list/filtered_list.dart';
+import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
+import 'package:cake_wallet/src/widgets/standard_list.dart';
 import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
 import 'package:cake_wallet/utils/show_bar.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter_mobx/flutter_mobx.dart';
-import 'package:flutter_slidable/flutter_slidable.dart';
-import 'package:cake_wallet/routes.dart';
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/src/screens/base_page.dart';
-import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
 import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
-import 'package:cake_wallet/src/widgets/collapsible_standart_list.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_slidable/flutter_slidable.dart';
 
 class ContactListPage extends BasePage {
   ContactListPage(this.contactListViewModel, this.authService);
@@ -74,45 +77,101 @@ class ContactListPage extends BasePage {
   }
 
   @override
-  Widget body(BuildContext context) {
-    return Container(
-        padding: EdgeInsets.all(20.0),
-        child: Observer(builder: (_) {
-          final contacts = contactListViewModel.contactsToShow;
-          final walletContacts = contactListViewModel.walletContactsToShow;
-          return CollapsibleSectionList(
-            sectionCount: 2,
-            sectionTitleBuilder: (int sectionIndex) {
-              var title = S.current.contact_list_contacts;
+  Widget body(BuildContext context) => ContactPageBody(contactListViewModel: contactListViewModel);
+}
 
-              if (sectionIndex == 0) {
-                title = S.current.contact_list_wallets;
-              }
+class ContactPageBody extends StatefulWidget {
+  const ContactPageBody({required this.contactListViewModel});
 
-              return Container(
-                  padding: EdgeInsets.only(bottom: 10),
-                  child: Text(title, style: TextStyle(fontSize: 36)));
-            },
-            itemCounter: (int sectionIndex) =>
-                sectionIndex == 0 ? walletContacts.length : contacts.length,
-            itemBuilder: (int sectionIndex, index) {
-              if (sectionIndex == 0) {
-                final walletInfo = walletContacts[index];
-                return generateRaw(context, walletInfo);
-              }
+  final ContactListViewModel contactListViewModel;
 
-              final contact = contacts[index];
-              final content = generateRaw(context, contact);
-              return contactListViewModel.isEditable
-                  ? Slidable(
-                      key: Key('${contact.key}'),
-                      endActionPane: _actionPane(context, contact),
-                      child: content,
-                    )
-                  : content;
-            },
-          );
-        }));
+  @override
+  State<ContactPageBody> createState() => _ContactPageBodyState();
+}
+
+class _ContactPageBodyState extends State<ContactPageBody> with SingleTickerProviderStateMixin {
+  late TabController _tabController;
+
+  @override
+  void initState() {
+    super.initState();
+    _tabController = TabController(length: 2, vsync: this);
+  }
+
+  @override
+  void dispose() {
+    _tabController.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.only(left: 24),
+      child: Column(
+        children: [
+          Align(
+            alignment: Alignment.centerLeft,
+            child: TabBar(
+              controller: _tabController,
+              splashFactory: NoSplash.splashFactory,
+              indicatorSize: TabBarIndicatorSize.label,
+              isScrollable: true,
+              labelStyle: TextStyle(
+                fontSize: 18,
+                fontFamily: 'Lato',
+                fontWeight: FontWeight.w600,
+                color: Theme.of(context).appBarTheme.titleTextStyle!.color,
+              ),
+              unselectedLabelStyle: TextStyle(
+                  fontSize: 18,
+                  fontFamily: 'Lato',
+                  fontWeight: FontWeight.w600,
+                  color: Theme.of(context).appBarTheme.titleTextStyle!.color?.withOpacity(0.5)),
+              labelColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
+              indicatorColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
+              indicatorPadding: EdgeInsets.zero,
+              labelPadding: EdgeInsets.only(right: 24),
+              tabAlignment: TabAlignment.center,
+              dividerColor: Colors.transparent,
+              padding: EdgeInsets.zero,
+              tabs: [
+                Tab(text: S.of(context).wallets),
+                Tab(text: S.of(context).contact_list_contacts),
+              ],
+            ),
+          ),
+          Expanded(
+            child: TabBarView(
+              controller: _tabController,
+              children: [
+                _buildWalletContacts(context),
+                ContactListBody(
+                    contactListViewModel: widget.contactListViewModel,
+                    tabController: _tabController),
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildWalletContacts(BuildContext context) {
+    final walletContacts = widget.contactListViewModel.walletContactsToShow;
+
+    return ListView.builder(
+      shrinkWrap: true,
+      itemCount: walletContacts.length * 2,
+      itemBuilder: (context, index) {
+        if (index.isOdd) {
+          return StandardListSeparator();
+        } else {
+          final walletInfo = walletContacts[index ~/ 2];
+          return generateRaw(context, walletInfo);
+        }
+      },
+    );
   }
 
   Widget generateRaw(BuildContext context, ContactBase contact) {
@@ -123,7 +182,7 @@ class ContactListPage extends BasePage {
 
     return GestureDetector(
       onTap: () async {
-        if (!contactListViewModel.isEditable) {
+        if (!widget.contactListViewModel.isEditable) {
           Navigator.of(context).pop(contact);
           return;
         }
@@ -143,8 +202,7 @@ class ContactListPage extends BasePage {
           mainAxisAlignment: MainAxisAlignment.start,
           children: <Widget>[
             currencyIcon,
-            Expanded(
-                child: Padding(
+            Padding(
               padding: EdgeInsets.only(left: 12),
               child: Text(
                 contact.name,
@@ -154,13 +212,215 @@ class ContactListPage extends BasePage {
                   color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
                 ),
               ),
-            ))
+            ),
           ],
         ),
       ),
     );
   }
 
+  Future<bool> showNameAndAddressDialog(BuildContext context, String name, String address) async {
+    return await showPopUp<bool>(
+            context: context,
+            builder: (BuildContext context) {
+              return AlertWithTwoActions(
+                  alertTitle: name,
+                  alertContent: address,
+                  rightButtonText: S.of(context).copy,
+                  leftButtonText: S.of(context).cancel,
+                  actionRightButton: () => Navigator.of(context).pop(true),
+                  actionLeftButton: () => Navigator.of(context).pop(false));
+            }) ??
+        false;
+  }
+}
+
+class ContactListBody extends StatefulWidget {
+  ContactListBody({required this.contactListViewModel, required this.tabController});
+
+  final ContactListViewModel contactListViewModel;
+  final TabController tabController;
+
+  @override
+  State<ContactListBody> createState() => _ContactListBodyState();
+}
+
+class _ContactListBodyState extends State<ContactListBody> {
+  bool _isContactsTabActive = false;
+
+  @override
+  void initState() {
+    super.initState();
+    widget.tabController.addListener(_handleTabChange);
+  }
+
+  void _handleTabChange() {
+    setState(() {
+      _isContactsTabActive = widget.tabController.index == 1;
+    });
+  }
+
+  @override
+  void dispose() {
+    widget.tabController.removeListener(_handleTabChange);
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final contacts = widget.contactListViewModel.contacts;
+    return Scaffold(
+      body: Container(
+        child: FilteredList(
+          list: contacts,
+          updateFunction: widget.contactListViewModel.reorderAccordingToContactList,
+          canReorder: widget.contactListViewModel.isEditable,
+          shrinkWrap: true,
+          itemBuilder: (context, index) {
+            final contact = contacts[index];
+            final contactContent =
+                generateContactRaw(context, contact, contacts.length == index + 1);
+            return GestureDetector(
+              key: Key('${contact.name}'),
+              onTap: () async {
+                if (!widget.contactListViewModel.isEditable) {
+                  Navigator.of(context).pop(contact);
+                  return;
+                }
+
+                final isCopied =
+                    await showNameAndAddressDialog(context, contact.name, contact.address);
+
+                if (isCopied) {
+                  await Clipboard.setData(ClipboardData(text: contact.address));
+                  await showBar<void>(context, S.of(context).copied_to_clipboard);
+                }
+              },
+              behavior: HitTestBehavior.opaque,
+              child: widget.contactListViewModel.isEditable
+                  ? Slidable(
+                      key: Key('${contact.key}'),
+                      endActionPane: _actionPane(context, contact),
+                      child: contactContent)
+                  : contactContent,
+            );
+          },
+        ),
+      ),
+      floatingActionButton:
+          _isContactsTabActive ? filterButtonWidget(context, widget.contactListViewModel) : null,
+    );
+  }
+
+  Widget generateContactRaw(BuildContext context, ContactRecord contact, bool isLast) {
+    final image = contact.type.iconPath;
+    final currencyIcon = image != null
+        ? Image.asset(image, height: 24, width: 24)
+        : const SizedBox(height: 24, width: 24);
+    return Column(
+      children: [
+        Container(
+          key: Key('${contact.name}'),
+          padding: const EdgeInsets.only(top: 16, bottom: 16, right: 24),
+          child: Row(
+            mainAxisSize: MainAxisSize.min,
+            mainAxisAlignment: MainAxisAlignment.start,
+            children: <Widget>[
+              currencyIcon,
+              Expanded(
+                  child: Padding(
+                padding: EdgeInsets.only(left: 12),
+                child: Text(
+                  contact.name,
+                  style: TextStyle(
+                    fontSize: 14,
+                    fontWeight: FontWeight.normal,
+                    color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
+                  ),
+                ),
+              ))
+            ],
+          ),
+        ),
+        StandardListSeparator()
+      ],
+    );
+  }
+
+  ActionPane _actionPane(BuildContext context, ContactRecord contact) => ActionPane(
+        motion: const ScrollMotion(),
+        extentRatio: 0.4,
+        children: [
+          SlidableAction(
+            onPressed: (_) async => await Navigator.of(context)
+                .pushNamed(Routes.addressBookAddContact, arguments: contact),
+            backgroundColor: Colors.blue,
+            foregroundColor: Colors.white,
+            icon: Icons.edit,
+            label: S.of(context).edit,
+          ),
+          SlidableAction(
+            onPressed: (_) async {
+              final isDelete = await showAlertDialog(context);
+
+              if (isDelete) {
+                await widget.contactListViewModel.delete(contact);
+              }
+            },
+            backgroundColor: Colors.red,
+            foregroundColor: Colors.white,
+            icon: CupertinoIcons.delete,
+            label: S.of(context).delete,
+          ),
+        ],
+      );
+
+  Widget filterButtonWidget(BuildContext context, ContactListViewModel contactListViewModel) {
+    final filterIcon = Image.asset('assets/images/filter_icon.png',
+        color: Theme.of(context).appBarTheme.titleTextStyle!.color);
+    return MergeSemantics(
+      child: SizedBox(
+        height: 58,
+        width: 58,
+        child: ButtonTheme(
+          minWidth: double.minPositive,
+          child: Semantics(
+            container: true,
+            child: GestureDetector(
+              onTap: () async {
+                await showPopUp<void>(
+                  context: context,
+                  builder: (context) => FilterListWidget(
+                    initalType: contactListViewModel.orderType,
+                    initalAscending: contactListViewModel.ascending,
+                    onClose: (bool ascending, FilterListOrderType type) async {
+                      contactListViewModel.setAscending(ascending);
+                      await contactListViewModel.setOrderType(type);
+                    },
+                  ),
+                );
+              },
+              child: Semantics(
+                label: 'Transaction Filter',
+                button: true,
+                enabled: true,
+                child: Container(
+                  height: 36,
+                  width: 36,
+                  decoration: BoxDecoration(
+                    shape: BoxShape.circle,
+                    color: Theme.of(context).extension<ExchangePageTheme>()!.buttonBackgroundColor,
+                  ),
+                  child: filterIcon,
+                ),
+              ),
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+
   Future<bool> showAlertDialog(BuildContext context) async {
     return await showPopUp<bool>(
             context: context,
@@ -190,32 +450,4 @@ class ContactListPage extends BasePage {
             }) ??
         false;
   }
-
-  ActionPane _actionPane(BuildContext context, ContactRecord contact) => ActionPane(
-        motion: const ScrollMotion(),
-        extentRatio: 0.4,
-        children: [
-          SlidableAction(
-            onPressed: (_) async => await Navigator.of(context)
-                .pushNamed(Routes.addressBookAddContact, arguments: contact),
-            backgroundColor: Colors.blue,
-            foregroundColor: Colors.white,
-            icon: Icons.edit,
-            label: S.of(context).edit,
-          ),
-          SlidableAction(
-            onPressed: (_) async {
-              final isDelete = await showAlertDialog(context);
-
-              if (isDelete) {
-                await contactListViewModel.delete(contact);
-              }
-            },
-            backgroundColor: Colors.red,
-            foregroundColor: Colors.white,
-            icon: CupertinoIcons.delete,
-            label: S.of(context).delete,
-          ),
-        ],
-      );
 }
diff --git a/lib/src/screens/dashboard/widgets/filter_list_widget.dart b/lib/src/screens/dashboard/widgets/filter_list_widget.dart
index cda4f5f10..8e95de2af 100644
--- a/lib/src/screens/dashboard/widgets/filter_list_widget.dart
+++ b/lib/src/screens/dashboard/widgets/filter_list_widget.dart
@@ -18,9 +18,9 @@ class FilterListWidget extends StatefulWidget {
     required this.onClose,
   });
 
-  final WalletListOrderType? initalType;
+  final FilterListOrderType? initalType;
   final bool initalAscending;
-  final Function(bool, WalletListOrderType) onClose;
+  final Function(bool, FilterListOrderType) onClose;
 
   @override
   FilterListWidgetState createState() => FilterListWidgetState();
@@ -28,7 +28,7 @@ class FilterListWidget extends StatefulWidget {
 
 class FilterListWidgetState extends State<FilterListWidget> {
   late bool ascending;
-  late WalletListOrderType? type;
+  late FilterListOrderType? type;
 
   @override
   void initState() {
@@ -37,7 +37,7 @@ class FilterListWidgetState extends State<FilterListWidget> {
     type = widget.initalType;
   }
 
-  void setSelectedOrderType(WalletListOrderType? orderType) {
+  void setSelectedOrderType(FilterListOrderType? orderType) {
     setState(() {
       type = orderType;
     });
@@ -72,7 +72,7 @@ class FilterListWidgetState extends State<FilterListWidget> {
                     ),
                   ),
                 ),
-                if (type != WalletListOrderType.Custom) ...[
+                if (type != FilterListOrderType.Custom) ...[
                   sectionDivider,
                   SettingsChoicesCell(
                     ChoicesListItem<ListOrderMode>(
@@ -89,10 +89,10 @@ class FilterListWidgetState extends State<FilterListWidget> {
                 ],
                 sectionDivider,
                 RadioListTile(
-                  value: WalletListOrderType.CreationDate,
+                  value: FilterListOrderType.CreationDate,
                   groupValue: type,
                   title: Text(
-                    WalletListOrderType.CreationDate.toString(),
+                    FilterListOrderType.CreationDate.toString(),
                     style: TextStyle(
                         color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
                         fontSize: 16,
@@ -104,10 +104,10 @@ class FilterListWidgetState extends State<FilterListWidget> {
                   activeColor: Theme.of(context).primaryColor,
                 ),
                 RadioListTile(
-                  value: WalletListOrderType.Alphabetical,
+                  value: FilterListOrderType.Alphabetical,
                   groupValue: type,
                   title: Text(
-                    WalletListOrderType.Alphabetical.toString(),
+                    FilterListOrderType.Alphabetical.toString(),
                     style: TextStyle(
                         color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
                         fontSize: 16,
@@ -119,10 +119,10 @@ class FilterListWidgetState extends State<FilterListWidget> {
                   activeColor: Theme.of(context).primaryColor,
                 ),
                 RadioListTile(
-                  value: WalletListOrderType.GroupByType,
+                  value: FilterListOrderType.GroupByType,
                   groupValue: type,
                   title: Text(
-                    WalletListOrderType.GroupByType.toString(),
+                    FilterListOrderType.GroupByType.toString(),
                     style: TextStyle(
                         color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
                         fontSize: 16,
@@ -134,10 +134,10 @@ class FilterListWidgetState extends State<FilterListWidget> {
                   activeColor: Theme.of(context).primaryColor,
                 ),
                 RadioListTile(
-                  value: WalletListOrderType.Custom,
+                  value: FilterListOrderType.Custom,
                   groupValue: type,
                   title: Text(
-                    WalletListOrderType.Custom.toString(),
+                    FilterListOrderType.Custom.toString(),
                     style: TextStyle(
                         color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
                         fontSize: 16,
diff --git a/lib/src/screens/wallet_list/filtered_list.dart b/lib/src/screens/wallet_list/filtered_list.dart
index 63a1ae392..5316c8472 100644
--- a/lib/src/screens/wallet_list/filtered_list.dart
+++ b/lib/src/screens/wallet_list/filtered_list.dart
@@ -7,13 +7,17 @@ class FilteredList extends StatefulWidget {
     required this.list,
     required this.itemBuilder,
     required this.updateFunction,
+    this.canReorder = true,
     this.shrinkWrap = false,
+    this.physics,
   });
 
   final ObservableList<dynamic> list;
   final Widget Function(BuildContext, int) itemBuilder;
   final Function updateFunction;
+  final bool canReorder;
   final bool shrinkWrap;
+  final ScrollPhysics? physics;
 
   @override
   FilteredListState createState() => FilteredListState();
@@ -22,21 +26,31 @@ class FilteredList extends StatefulWidget {
 class FilteredListState extends State<FilteredList> {
   @override
   Widget build(BuildContext context) {
-    return Observer(
-      builder: (_) => ReorderableListView.builder(
-        shrinkWrap: widget.shrinkWrap,
-        physics: const BouncingScrollPhysics(),
-        itemBuilder: widget.itemBuilder,
-        itemCount: widget.list.length,
-        onReorder: (int oldIndex, int newIndex) {
-          if (oldIndex < newIndex) {
-            newIndex -= 1;
-          }
-          final dynamic item = widget.list.removeAt(oldIndex);
-          widget.list.insert(newIndex, item);
-          widget.updateFunction();
-        },
-      ),
-    );
+    if (widget.canReorder) {
+      return Observer(
+        builder: (_) => ReorderableListView.builder(
+          shrinkWrap: widget.shrinkWrap,
+          physics: widget.physics ?? const BouncingScrollPhysics(),
+          itemBuilder: widget.itemBuilder,
+          itemCount: widget.list.length,
+          onReorder: (int oldIndex, int newIndex) {
+            if (oldIndex < newIndex) {
+              newIndex -= 1;
+            }
+            final dynamic item = widget.list.removeAt(oldIndex);
+            widget.list.insert(newIndex, item);
+            widget.updateFunction();
+          },
+        ),
+      );
+    } else {
+      return Observer(
+        builder: (_) => ListView.builder(
+          physics: widget.physics ?? const BouncingScrollPhysics(),
+          itemBuilder: widget.itemBuilder,
+          itemCount: widget.list.length,
+        ),
+      );
+    }
   }
 }
diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart
index d17534f6b..afb86cf0a 100644
--- a/lib/src/screens/wallet_list/wallet_list_page.dart
+++ b/lib/src/screens/wallet_list/wallet_list_page.dart
@@ -59,7 +59,7 @@ class WalletListPage extends BasePage {
                   builder: (context) => FilterListWidget(
                     initalType: walletListViewModel.orderType,
                     initalAscending: walletListViewModel.ascending,
-                    onClose: (bool ascending, WalletListOrderType type) async {
+                    onClose: (bool ascending, FilterListOrderType type) async {
                       walletListViewModel.setAscending(ascending);
                       await walletListViewModel.setOrderType(type);
                     },
diff --git a/lib/src/widgets/collapsible_standart_list.dart b/lib/src/widgets/collapsible_standart_list.dart
deleted file mode 100644
index 83e4daee2..000000000
--- a/lib/src/widgets/collapsible_standart_list.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-import 'package:cake_wallet/src/widgets/standard_list.dart';
-import 'package:flutter/material.dart';
-
-class CollapsibleSectionList extends SectionStandardList {
-  CollapsibleSectionList(
-      {required int sectionCount,
-      required int Function(int sectionIndex) itemCounter,
-      required Widget Function(int sectionIndex, int itemIndex) itemBuilder,
-      Widget Function(int sectionIndex)? sectionTitleBuilder,
-      bool hasTopSeparator = false})
-      : super(
-            hasTopSeparator: hasTopSeparator,
-            sectionCount: sectionCount,
-            itemCounter: itemCounter,
-            itemBuilder: itemBuilder,
-            sectionTitleBuilder: sectionTitleBuilder);
-
-  @override
-  Widget buildTitle(List<Widget> items, int sectionIndex) {
-    if (sectionTitleBuilder == null) {
-      throw Exception('Cannot to build title. sectionTitleBuilder is null');
-    }
-    return sectionTitleBuilder!.call(sectionIndex);
-  }
-
-  @override
-  List<Widget> buildSection(int itemCount, List<Widget> items, int sectionIndex) {
-    final List<Widget> section = [];
-
-    for (var itemIndex = 0; itemIndex < itemCount; itemIndex++) {
-      final item = itemBuilder(sectionIndex, itemIndex);
-
-      section.add(StandardListSeparator());
-
-      section.add(item);
-    }
-    return section;
-  }
-}
diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart
index 9f03c95c3..2eadbd8a9 100644
--- a/lib/store/settings_store.dart
+++ b/lib/store/settings_store.dart
@@ -62,9 +62,11 @@ abstract class SettingsStoreBase with Store {
       required bool initialAppSecure,
       required bool initialDisableBuy,
       required bool initialDisableSell,
+      required FilterListOrderType initialWalletListOrder,
+      required FilterListOrderType initialContactListOrder,
       required bool initialDisableBulletin,
-      required WalletListOrderType initialWalletListOrder,
       required bool initialWalletListAscending,
+      required bool initialContactListAscending,
       required FiatApiMode initialFiatMode,
       required bool initialAllowBiometricalAuthentication,
       required String initialTotpSecretKey,
@@ -149,7 +151,9 @@ abstract class SettingsStoreBase with Store {
         disableSell = initialDisableSell,
         disableBulletin = initialDisableBulletin,
         walletListOrder = initialWalletListOrder,
+        contactListOrder = initialContactListOrder,
         walletListAscending = initialWalletListAscending,
+        contactListAscending = initialContactListAscending,
         shouldShowMarketPlaceInDashboard = initialShouldShowMarketPlaceInDashboard,
         exchangeStatus = initialExchangeStatus,
         currentTheme = initialTheme,
@@ -324,14 +328,24 @@ abstract class SettingsStoreBase with Store {
 
     reaction(
         (_) => walletListOrder,
-        (WalletListOrderType walletListOrder) =>
+        (FilterListOrderType walletListOrder) =>
             sharedPreferences.setInt(PreferencesKey.walletListOrder, walletListOrder.index));
 
+    reaction(
+            (_) => contactListOrder,
+            (FilterListOrderType contactListOrder) =>
+            sharedPreferences.setInt(PreferencesKey.contactListOrder, contactListOrder.index));
+
     reaction(
         (_) => walletListAscending,
         (bool walletListAscending) =>
             sharedPreferences.setBool(PreferencesKey.walletListAscending, walletListAscending));
 
+    reaction(
+            (_) => contactListAscending,
+            (bool contactListAscending) =>
+            sharedPreferences.setBool(PreferencesKey.contactListAscending, contactListAscending));
+
     reaction(
         (_) => autoGenerateSubaddressStatus,
         (AutoGenerateSubaddressStatus autoGenerateSubaddressStatus) => sharedPreferences.setInt(
@@ -645,15 +659,21 @@ abstract class SettingsStoreBase with Store {
   @observable
   bool disableSell;
 
+  @observable
+  FilterListOrderType contactListOrder;
+
   @observable
   bool disableBulletin;
 
   @observable
-  WalletListOrderType walletListOrder;
+  FilterListOrderType walletListOrder;
 
   @observable
   bool walletListAscending;
 
+  @observable
+  bool contactListAscending;
+
   @observable
   bool allowBiometricalAuthentication;
 
@@ -907,9 +927,13 @@ abstract class SettingsStoreBase with Store {
     final disableSell = sharedPreferences.getBool(PreferencesKey.disableSellKey) ?? false;
     final disableBulletin = sharedPreferences.getBool(PreferencesKey.disableBulletinKey) ?? false;
     final walletListOrder =
-        WalletListOrderType.values[sharedPreferences.getInt(PreferencesKey.walletListOrder) ?? 0];
+        FilterListOrderType.values[sharedPreferences.getInt(PreferencesKey.walletListOrder) ?? 0];
+    final contactListOrder =
+    FilterListOrderType.values[sharedPreferences.getInt(PreferencesKey.contactListOrder) ?? 0];
     final walletListAscending =
         sharedPreferences.getBool(PreferencesKey.walletListAscending) ?? true;
+    final contactListAscending =
+        sharedPreferences.getBool(PreferencesKey.contactListAscending) ?? true;
     final currentFiatApiMode = FiatApiMode.deserialize(
         raw: sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey) ??
             FiatApiMode.enabled.raw);
@@ -1200,6 +1224,8 @@ abstract class SettingsStoreBase with Store {
       initialDisableBulletin: disableBulletin,
       initialWalletListOrder: walletListOrder,
       initialWalletListAscending: walletListAscending,
+      initialContactListOrder: contactListOrder,
+      initialContactListAscending: contactListAscending,
       initialFiatMode: currentFiatApiMode,
       initialAllowBiometricalAuthentication: allowBiometricalAuthentication,
       initialCake2FAPresetOptions: selectedCake2FAPreset,
@@ -1348,9 +1374,11 @@ abstract class SettingsStoreBase with Store {
     disableBulletin =
         sharedPreferences.getBool(PreferencesKey.disableBulletinKey) ?? disableBulletin;
     walletListOrder =
-        WalletListOrderType.values[sharedPreferences.getInt(PreferencesKey.walletListOrder) ?? 0];
+        FilterListOrderType.values[sharedPreferences.getInt(PreferencesKey.walletListOrder) ?? 0];
+    contactListOrder =
+    FilterListOrderType.values[sharedPreferences.getInt(PreferencesKey.contactListOrder) ?? 0];
     walletListAscending = sharedPreferences.getBool(PreferencesKey.walletListAscending) ?? true;
-
+    contactListAscending = sharedPreferences.getBool(PreferencesKey.contactListAscending) ?? true;
     shouldShowMarketPlaceInDashboard =
         sharedPreferences.getBool(PreferencesKey.shouldShowMarketPlaceInDashboard) ??
             shouldShowMarketPlaceInDashboard;
diff --git a/lib/view_model/contact_list/contact_list_view_model.dart b/lib/view_model/contact_list/contact_list_view_model.dart
index 89192583e..0015463a5 100644
--- a/lib/view_model/contact_list/contact_list_view_model.dart
+++ b/lib/view_model/contact_list/contact_list_view_model.dart
@@ -1,18 +1,20 @@
 import 'dart:async';
+
 import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
+import 'package:cake_wallet/entities/contact.dart';
 import 'package:cake_wallet/entities/contact_base.dart';
+import 'package:cake_wallet/entities/contact_record.dart';
 import 'package:cake_wallet/entities/wallet_contact.dart';
+import 'package:cake_wallet/entities/wallet_list_order_types.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/store/settings_store.dart';
+import 'package:cake_wallet/utils/mobx.dart';
+import 'package:collection/collection.dart';
+import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/entities/contact_record.dart';
-import 'package:cake_wallet/entities/contact.dart';
-import 'package:cake_wallet/utils/mobx.dart';
-import 'package:cw_core/crypto_currency.dart';
-import 'package:collection/collection.dart';
 
 part 'contact_list_view_model.g.dart';
 
@@ -75,6 +77,8 @@ abstract class ContactListViewModelBase with Store {
     _subscription = contactSource.bindToListWithTransform(
         contacts, (Contact contact) => ContactRecord(contactSource, contact),
         initialFire: true);
+
+    setOrderType(settingsStore.contactListOrder);
   }
 
   String _createName(String walletName, String label, {int? key = null}) {
@@ -93,6 +97,10 @@ abstract class ContactListViewModelBase with Store {
 
   bool get isEditable => _currency == null;
 
+  FilterListOrderType? get orderType => settingsStore.contactListOrder;
+
+  bool get ascending => settingsStore.contactListAscending;
+
   @computed
   bool get shouldRequireTOTP2FAForAddingContacts =>
       settingsStore.shouldRequireTOTP2FAForAddingContacts;
@@ -118,4 +126,70 @@ abstract class ContactListViewModelBase with Store {
         _currency?.toString() == element.type.tag ||
         _currency?.tag == element.type.toString();
   }
+
+  void dispose() async {
+    _subscription?.cancel();
+    final List<Contact> contactsSourceCopy = contacts.map((e) => e.original).toList();
+    await reorderContacts(contactsSourceCopy);
+  }
+
+  void reorderAccordingToContactList() =>
+      settingsStore.contactListOrder = FilterListOrderType.Custom;
+
+  Future<void> reorderContacts(List<Contact> contactCopy) async {
+    await contactSource.deleteAll(contactCopy.map((e) => e.key).toList());
+    await contactSource.addAll(contactCopy);
+  }
+
+  Future<void> sortGroupByType() async {
+    List<Contact> contactsSourceCopy = contactSource.values.toList();
+
+    contactsSourceCopy.sort((a, b) => ascending
+        ? a.type.toString().compareTo(b.type.toString())
+        : b.type.toString().compareTo(a.type.toString()));
+
+    await reorderContacts(contactsSourceCopy);
+  }
+
+  Future<void> sortAlphabetically() async {
+    List<Contact> contactsSourceCopy = contactSource.values.toList();
+
+    contactsSourceCopy
+        .sort((a, b) => ascending ? a.name.compareTo(b.name) : b.name.compareTo(a.name));
+
+    await reorderContacts(contactsSourceCopy);
+  }
+
+  Future<void> sortByCreationDate() async {
+    List<Contact> contactsSourceCopy = contactSource.values.toList();
+
+    contactsSourceCopy.sort((a, b) =>
+        ascending ? a.lastChange.compareTo(b.lastChange) : b.lastChange.compareTo(a.lastChange));
+
+    await reorderContacts(contactsSourceCopy);
+  }
+
+  void setAscending(bool ascending) => settingsStore.contactListAscending = ascending;
+
+  Future<void> setOrderType(FilterListOrderType? type) async {
+    if (type == null) return;
+
+    settingsStore.contactListOrder = type;
+
+    switch (type) {
+      case FilterListOrderType.CreationDate:
+        await sortByCreationDate();
+        break;
+      case FilterListOrderType.Alphabetical:
+        await sortAlphabetically();
+        break;
+      case FilterListOrderType.GroupByType:
+        await sortGroupByType();
+        break;
+      case FilterListOrderType.Custom:
+      default:
+        reorderAccordingToContactList();
+        break;
+    }
+  }
 }
diff --git a/lib/view_model/contact_list/contact_view_model.dart b/lib/view_model/contact_list/contact_view_model.dart
index 053cfe4c5..93abfb11c 100644
--- a/lib/view_model/contact_list/contact_view_model.dart
+++ b/lib/view_model/contact_list/contact_view_model.dart
@@ -2,7 +2,7 @@ import 'package:cake_wallet/entities/contact_record.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cake_wallet/core/execution_state.dart';
-import 'package:cw_core/wallet_base.dart';
+import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/entities/contact.dart';
 import 'package:cw_core/crypto_currency.dart';
 
@@ -17,7 +17,9 @@ abstract class ContactViewModelBase with Store {
         _contact = contact,
         name = contact?.name ?? '',
         address = contact?.address ?? '',
-        currency = contact?.type;
+        currency = contact?.type,
+        lastChange = contact?.lastChange;
+
 
   @observable
   ExecutionState state;
@@ -31,6 +33,8 @@ abstract class ContactViewModelBase with Store {
   @observable
   CryptoCurrency? currency;
 
+  DateTime? lastChange;
+
   @computed
   bool get isReady =>
       name.isNotEmpty &&
@@ -51,20 +55,32 @@ abstract class ContactViewModelBase with Store {
   Future<void> save() async {
     try {
       state = IsExecutingState();
+      final now = DateTime.now();
+
+      if (doesContactNameExist(name)) {
+        state = FailureState(S.current.contact_name_exists);
+        return;
+      }
 
       if (_contact != null && _contact!.original.isInBox) {
         _contact?.name = name;
         _contact?.address = address;
         _contact?.type = currency!;
+        _contact?.lastChange = now;
         await _contact?.save();
       } else {
         await _contacts
-            .add(Contact(name: name, address: address, type: currency!));
+            .add(Contact(name: name, address: address, type: currency!, lastChange: now));
       }
 
+            lastChange = now;
       state = ExecutedSuccessfullyState();
     } catch (e) {
       state = FailureState(e.toString());
     }
   }
-}
+
+  bool doesContactNameExist(String name) {
+    return _contacts.values.any((contact) => contact.name == name);
+  }
+}
\ No newline at end of file
diff --git a/lib/view_model/wallet_list/wallet_list_view_model.dart b/lib/view_model/wallet_list/wallet_list_view_model.dart
index 0ae6b75a5..725af843f 100644
--- a/lib/view_model/wallet_list/wallet_list_view_model.dart
+++ b/lib/view_model/wallet_list/wallet_list_view_model.dart
@@ -76,7 +76,7 @@ abstract class WalletListViewModelBase with Store {
     await _appStore.changeCurrentWallet(wallet);
   }
 
-  WalletListOrderType? get orderType => _appStore.settingsStore.walletListOrder;
+  FilterListOrderType? get orderType => _appStore.settingsStore.walletListOrder;
 
   bool get ascending => _appStore.settingsStore.walletListAscending;
 
@@ -108,7 +108,7 @@ abstract class WalletListViewModelBase with Store {
       return;
     }
 
-    _appStore.settingsStore.walletListOrder = WalletListOrderType.Custom;
+    _appStore.settingsStore.walletListOrder = FilterListOrderType.Custom;
 
     // make a copy of the walletInfoSource:
     List<WalletInfo> walletInfoSourceCopy = _walletInfoSource.values.toList();
@@ -186,22 +186,22 @@ abstract class WalletListViewModelBase with Store {
     _appStore.settingsStore.walletListAscending = ascending;
   }
 
-  Future<void> setOrderType(WalletListOrderType? type) async {
+  Future<void> setOrderType(FilterListOrderType? type) async {
     if (type == null) return;
 
     _appStore.settingsStore.walletListOrder = type;
 
     switch (type) {
-      case WalletListOrderType.CreationDate:
+      case FilterListOrderType.CreationDate:
         await sortByCreationDate();
         break;
-      case WalletListOrderType.Alphabetical:
+      case FilterListOrderType.Alphabetical:
         await sortAlphabetically();
         break;
-      case WalletListOrderType.GroupByType:
+      case FilterListOrderType.GroupByType:
         await sortGroupByType();
         break;
-      case WalletListOrderType.Custom:
+      case FilterListOrderType.Custom:
       default:
         await reorderAccordingToWalletList();
         break;
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index 81fe3cc2c..c2be1504a 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -937,5 +937,6 @@
   "you_pay": "انت تدفع",
   "you_will_get": "حول الى",
   "you_will_send": "تحويل من",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": "                   .ﻒﻠﺘﺨﻣ ﻢﺳﺍ ﺭﺎﻴﺘﺧﺍ ءﺎﺟﺮﻟﺍ .ﻞﻌﻔﻟﺎﺑ ﺓﺩﻮﺟﻮﻣ ﻢﺳﻻﺍ ﺍﺬﻬﺑ ﻝﺎﺼﺗﺍ ﺔﻬﺟ"
+}
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index 50db1610a..8b68d0d1e 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -937,5 +937,6 @@
   "you_pay": "Вие плащате",
   "you_will_get": "Обръщане в",
   "you_will_send": "Обръщане от",
-  "yy": "гг"
-}
\ No newline at end of file
+  "yy": "гг",
+  "contact_name_exists": "Вече съществува контакт с това име. Моля, изберете друго име."
+}
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index ddc91340b..9b48ebdc7 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -937,5 +937,6 @@
   "you_pay": "Zaplatíte",
   "you_will_get": "Směnit na",
   "you_will_send": "Směnit z",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": "Kontakt s tímto jménem již existuje. Vyberte prosím jiný název."
+}
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index d6a0ee9af..4f5fd23b3 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -940,5 +940,6 @@
   "you_pay": "You Pay",
   "you_will_get": "Convert to",
   "you_will_send": "Convert from",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": "A contact with that name already exists. Please choose a different name."
+}
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 25c9f95c1..fd20a8b30 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -938,5 +938,6 @@
   "you_pay": "Tú pagas",
   "you_will_get": "Convertir a",
   "you_will_send": "Convertir de",
-  "yy": "YY"
+  "yy": "YY",
+  "contact_name_exists": "Ya existe un contacto con ese nombre. Elija un nombre diferente."
 }
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index be5b48dd8..50aceb2f1 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -937,5 +937,6 @@
   "you_pay": "Vous payez",
   "you_will_get": "Convertir vers",
   "you_will_send": "Convertir depuis",
-  "yy": "AA"
-}
\ No newline at end of file
+  "yy": "AA",
+  "contact_name_exists": "Un contact portant ce nom existe déjà. Veuillez choisir un autre nom."
+}
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index 4deb0df1d..e66859531 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -939,5 +939,6 @@
   "you_pay": "Ka Bayar",
   "you_will_get": "Maida zuwa",
   "you_will_send": "Maida daga",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": "An riga an sami lamba tare da wannan sunan. Da fatan za a zaɓi suna daban."
+}
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index 5161250fc..bc8b81211 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -939,5 +939,6 @@
   "you_pay": "आप भुगतान करते हैं",
   "you_will_get": "में बदलें",
   "you_will_send": "से रूपांतरित करें",
-  "yy": "वाईवाई"
-}
\ No newline at end of file
+  "yy": "वाईवाई",
+  "contact_name_exists": "उस नाम का एक संपर्क पहले से मौजूद है. कृपया कोई भिन्न नाम चुनें."
+}
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 8ef92aaf0..9ff57707d 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -937,5 +937,6 @@
   "you_pay": "Vi plaćate",
   "you_will_get": "Razmijeni u",
   "you_will_send": "Razmijeni iz",
-  "yy": "GG"
-}
\ No newline at end of file
+  "yy": "GG",
+  "contact_name_exists": "Kontakt s tim imenom već postoji. Odaberite drugo ime."
+}
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index 5f93082ec..2858fa193 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -940,5 +940,6 @@
   "you_pay": "Anda Membayar",
   "you_will_get": "Konversi ke",
   "you_will_send": "Konversi dari",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": "Kontak dengan nama tersebut sudah ada. Silakan pilih nama lain."
+}
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index 08ae928af..034376a6c 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -940,5 +940,6 @@
   "you_pay": "Tu paghi",
   "you_will_get": "Converti a",
   "you_will_send": "Conveti da",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": "Esiste già un contatto con quel nome. Scegli un nome diverso."
+}
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index d70eca31b..7f0792063 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -938,5 +938,6 @@
   "you_pay": "あなたが支払う",
   "you_will_get": "に変換",
   "you_will_send": "から変換",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": "その名前の連絡先はすでに存在します。別の名前を選択してください。"
+}
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 133ca1838..6ba402ce3 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -939,5 +939,6 @@
   "you_will_get": "로 변환하다",
   "you_will_send": "다음에서 변환",
   "YY": "YY",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": "해당 이름을 가진 연락처가 이미 존재합니다. 다른 이름을 선택하세요."
+}
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index 1727f0d71..69b888b5a 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -937,5 +937,6 @@
   "you_pay": "သင်ပေးချေပါ။",
   "you_will_get": "သို့ပြောင်းပါ။",
   "you_will_send": "မှပြောင်းပါ။",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": "ထိုအမည်နှင့် အဆက်အသွယ်တစ်ခု ရှိနှင့်ပြီးဖြစ်သည်။ အခြားအမည်တစ်ခုကို ရွေးပါ။"
+}
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index 3f2df531b..2c259bf80 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -938,5 +938,6 @@
   "you_pay": "U betaalt",
   "you_will_get": "Converteren naar",
   "you_will_send": "Converteren van",
-  "yy": "JJ"
-}
\ No newline at end of file
+  "yy": "JJ",
+  "contact_name_exists": "Er bestaat al een contact met die naam. Kies een andere naam."
+}
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 91b265144..936339708 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -937,5 +937,6 @@
   "you_pay": "Płacisz",
   "you_will_get": "Konwertuj na",
   "you_will_send": "Konwertuj z",
-  "yy": "RR"
-}
\ No newline at end of file
+  "yy": "RR",
+  "contact_name_exists": "Kontakt o tej nazwie już istnieje. Proszę wybrać inną nazwę."
+}
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 524dbcace..0cc0cc00a 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -941,4 +941,4 @@
   "you_will_get": "Converter para",
   "you_will_send": "Converter de",
   "yy": "aa"
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index 1a8c2447f..8aeb56a86 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -938,5 +938,6 @@
   "you_pay": "Вы платите",
   "you_will_get": "Конвертировать в",
   "you_will_send": "Конвертировать из",
-  "yy": "ГГ"
-}
\ No newline at end of file
+  "yy": "ГГ",
+  "contact_name_exists": "Контакт с таким именем уже существует. Пожалуйста, выберите другое имя."
+}
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index 213f74530..736eb8762 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -937,5 +937,6 @@
   "you_pay": "คุณจ่าย",
   "you_will_get": "แปลงเป็น",
   "you_will_send": "แปลงจาก",
-  "yy": "ปี"
-}
\ No newline at end of file
+  "yy": "ปี",
+  "contact_name_exists": "มีผู้ติดต่อชื่อนั้นอยู่แล้ว โปรดเลือกชื่ออื่น"
+}
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index 0ca8ee665..e68bd0b22 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -938,4 +938,4 @@
   "you_will_get": "I-convert sa",
   "you_will_send": "I-convert mula sa",
   "yy": "YY"
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index b23f64d60..83e8f6cbc 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -937,5 +937,6 @@
   "you_pay": "Şu kadar ödeyeceksin: ",
   "you_will_get": "Biçimine dönüştür:",
   "you_will_send": "Biçiminden dönüştür:",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": "Bu isimde bir kişi zaten mevcut. Lütfen farklı bir ad seçin."
+}
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 79dc0543f..909d9c01f 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -938,5 +938,6 @@
   "you_pay": "Ви платите",
   "you_will_get": "Конвертувати в",
   "you_will_send": "Конвертувати з",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": "Контакт із такою назвою вже існує. Виберіть інше ім'я."
+}
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index 0a136d140..2dbc97102 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -939,5 +939,6 @@
   "you_pay": "تم ادا کرو",
   "you_will_get": "میں تبدیل کریں۔",
   "you_will_send": "سے تبدیل کریں۔",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": " ۔ﮟﯾﺮﮐ ﺐﺨﺘﻨﻣ ﻡﺎﻧ ﻒﻠﺘﺨﻣ ﮏﯾﺍ ﻡﺮﮐ ﮦﺍﺮﺑ ۔ﮯﮨ ﺩﻮﺟﻮﻣ ﮯﺳ ﮯﻠﮩﭘ ﮧﻄﺑﺍﺭ ﮏﯾﺍ ﮫﺗﺎﺳ ﮯﮐ ﻡﺎﻧ ﺱﺍ"
+}
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index 14270120c..03c7c95ef 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -938,5 +938,6 @@
   "you_pay": "Ẹ sàn",
   "you_will_get": "Ṣe pàṣípààrọ̀ sí",
   "you_will_send": "Ṣe pàṣípààrọ̀ láti",
-  "yy": "Ọd"
-}
\ No newline at end of file
+  "yy": "Ọd",
+  "contact_name_exists": "Olubasọrọ pẹlu orukọ yẹn ti wa tẹlẹ. Jọwọ yan orukọ ti o yatọ."
+}
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index 65047b4fe..5c8d708f4 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -937,5 +937,6 @@
   "you_pay": "你付钱",
   "you_will_get": "转换到",
   "you_will_send": "转换自",
-  "yy": "YY"
-}
\ No newline at end of file
+  "yy": "YY",
+  "contact_name_exists": "已存在具有该名称的联系人。请选择不同的名称。"
+}

From c8cfc2cff1026c4c433d0f9e683a2c4cbb4023eb Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Wed, 6 Nov 2024 18:57:36 -0800
Subject: [PATCH 02/15] Mweb enhancements 4 (#1768)

* [skip-ci] show mweb confirmations, show last mweb balance while syncing

* potential send-all fix

* [skip-ci] undo fix that didn't work

* [skip-ci] undo unnecessary changes

* [skip ci] add export mweb logs screen

* [skip ci] cleanup

* confirmation fixes

* catch electrum call errors

* [skip ci] undo some changes

* potential electrum fixes + mweb logs display only last 10000 characters

* Add question mark and link to MWEB card

* updates

* show negative unconfirmed mweb balanaces + other fixes [skip ci]

* error handling

* [skip ci] [wip] check if node supports mweb

* check fee before building tx

* [skip ci] minor

* [skip ci] minor

* mweb node setting [wip] [skip ci]

* prioritize mweb coins when selecting inputs from the pool

* potential connection edgecase fix

* translations + mweb node fixes

* don't use mweb for exchange refund address

* add peg in / out labels and make 6 confs only show up for peg in / out

* bump bitcoin_base version to v9

* [skip ci] fix logs page

* don't fetch txinfo for non-mweb addresses [skip ci]

* fix non-mweb confirmations

* rename always scan to enable mweb

* Update litecoin_wallet_addresses.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* Update cw_mweb.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* [skip ci] review updates pt.1

* [skip ci] minor code cleanup

* [skip ci] use exception handler

* exception handling [skip ci]

* [skip ci] exception handling

* trigger build

* pegout label fixes

* fix showing change transactions on peg-out

* minor code cleanup and minor peg-out fix

* final balance fixes

* non-mweb confirmations potential fix

* [skip ci] wip

* trigger build

---------

Co-authored-by: tuxpizza <tuxsudo@tux.pizza>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 cw_bitcoin/lib/electrum.dart                  |   2 +
 cw_bitcoin/lib/electrum_balance.dart          |  12 +-
 cw_bitcoin/lib/electrum_transaction_info.dart |   9 +-
 cw_bitcoin/lib/electrum_wallet.dart           | 130 +++++---
 cw_bitcoin/lib/litecoin_wallet.dart           | 310 ++++++++++++------
 cw_bitcoin/lib/litecoin_wallet_addresses.dart |  17 +-
 cw_bitcoin/lib/litecoin_wallet_service.dart   |   4 +
 .../lib/pending_bitcoin_transaction.dart      |   3 +-
 cw_bitcoin/pubspec.yaml                       |   2 +-
 cw_bitcoin_cash/pubspec.yaml                  |   2 +-
 cw_core/lib/mweb_utxo.dart                    |   4 +
 cw_core/lib/node.dart                         |   3 +
 cw_core/lib/transaction_info.dart             |   3 +-
 cw_mweb/lib/cw_mweb.dart                      |  28 +-
 lib/di.dart                                   |   6 +
 lib/entities/preferences_key.dart             |   1 +
 lib/router.dart                               |  10 +
 lib/routes.dart                               |   2 +
 .../screens/dashboard/pages/balance_page.dart |  42 ++-
 lib/src/screens/settings/mweb_logs_page.dart  | 127 +++++++
 lib/src/screens/settings/mweb_node_page.dart  |  56 ++++
 lib/src/screens/settings/mweb_settings.dart   |  10 +-
 lib/store/settings_store.dart                 |  25 +-
 .../dashboard/balance_view_model.dart         |   2 +-
 .../dashboard/transaction_list_item.dart      |  52 ++-
 .../settings/mweb_settings_view_model.dart    |  50 +++
 pubspec_base.yaml                             |   2 +-
 res/values/strings_ar.arb                     |   4 +
 res/values/strings_bg.arb                     |   4 +
 res/values/strings_cs.arb                     |   4 +
 res/values/strings_de.arb                     |   6 +-
 res/values/strings_en.arb                     |   4 +
 res/values/strings_es.arb                     |   4 +
 res/values/strings_fr.arb                     |   4 +
 res/values/strings_ha.arb                     |   4 +
 res/values/strings_hi.arb                     |   4 +
 res/values/strings_hr.arb                     |   4 +
 res/values/strings_hy.arb                     |   4 +
 res/values/strings_id.arb                     |   4 +
 res/values/strings_it.arb                     |   4 +
 res/values/strings_ja.arb                     |   4 +
 res/values/strings_ko.arb                     |   4 +
 res/values/strings_my.arb                     |   4 +
 res/values/strings_nl.arb                     |   4 +
 res/values/strings_pl.arb                     |   4 +
 res/values/strings_pt.arb                     |   4 +
 res/values/strings_ru.arb                     |   4 +
 res/values/strings_th.arb                     |   4 +
 res/values/strings_tl.arb                     |   4 +
 res/values/strings_tr.arb                     |   4 +
 res/values/strings_uk.arb                     |   4 +
 res/values/strings_ur.arb                     |   4 +
 res/values/strings_vi.arb                     |   4 +
 res/values/strings_yo.arb                     |   4 +
 res/values/strings_zh.arb                     |   4 +
 55 files changed, 821 insertions(+), 207 deletions(-)
 create mode 100644 lib/src/screens/settings/mweb_logs_page.dart
 create mode 100644 lib/src/screens/settings/mweb_node_page.dart

diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart
index a18c038fa..df8e14119 100644
--- a/cw_bitcoin/lib/electrum.dart
+++ b/cw_bitcoin/lib/electrum.dart
@@ -124,6 +124,7 @@ class ElectrumClient {
         final errorMsg = error.toString();
         print(errorMsg);
         unterminatedString = '';
+        socket = null;
       },
       onDone: () {
         print("SOCKET CLOSED!!!!!");
@@ -132,6 +133,7 @@ class ElectrumClient {
           if (host == socket?.address.host || socket == null) {
             _setConnectionStatus(ConnectionStatus.disconnected);
             socket?.destroy();
+            socket = null;
           }
         } catch (e) {
           print("onDone: $e");
diff --git a/cw_bitcoin/lib/electrum_balance.dart b/cw_bitcoin/lib/electrum_balance.dart
index 4e37f40b1..ebd2f06ae 100644
--- a/cw_bitcoin/lib/electrum_balance.dart
+++ b/cw_bitcoin/lib/electrum_balance.dart
@@ -24,9 +24,12 @@ class ElectrumBalance extends Balance {
     final decoded = json.decode(jsonSource) as Map;
 
     return ElectrumBalance(
-        confirmed: decoded['confirmed'] as int? ?? 0,
-        unconfirmed: decoded['unconfirmed'] as int? ?? 0,
-        frozen: decoded['frozen'] as int? ?? 0);
+      confirmed: decoded['confirmed'] as int? ?? 0,
+      unconfirmed: decoded['unconfirmed'] as int? ?? 0,
+      frozen: decoded['frozen'] as int? ?? 0,
+      secondConfirmed: decoded['secondConfirmed'] as int? ?? 0,
+      secondUnconfirmed: decoded['secondUnconfirmed'] as int? ?? 0,
+    );
   }
 
   int confirmed;
@@ -36,8 +39,7 @@ class ElectrumBalance extends Balance {
   int secondUnconfirmed = 0;
 
   @override
-  String get formattedAvailableBalance =>
-      bitcoinAmountToString(amount: confirmed - frozen);
+  String get formattedAvailableBalance => bitcoinAmountToString(amount: confirmed - frozen);
 
   @override
   String get formattedAdditionalBalance => bitcoinAmountToString(amount: unconfirmed);
diff --git a/cw_bitcoin/lib/electrum_transaction_info.dart b/cw_bitcoin/lib/electrum_transaction_info.dart
index 1ab7799e3..7a8b3b951 100644
--- a/cw_bitcoin/lib/electrum_transaction_info.dart
+++ b/cw_bitcoin/lib/electrum_transaction_info.dart
@@ -41,6 +41,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
     String? to,
     this.unspents,
     this.isReceivedSilentPayment = false,
+    Map<String, dynamic>? additionalInfo,
   }) {
     this.id = id;
     this.height = height;
@@ -54,6 +55,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
     this.isReplaced = isReplaced;
     this.confirmations = confirmations;
     this.to = to;
+    this.additionalInfo = additionalInfo ?? {};
   }
 
   factory ElectrumTransactionInfo.fromElectrumVerbose(Map<String, Object> obj, WalletType type,
@@ -212,6 +214,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
               BitcoinSilentPaymentsUnspent.fromJSON(null, unspent as Map<String, dynamic>))
           .toList(),
       isReceivedSilentPayment: data['isReceivedSilentPayment'] as bool? ?? false,
+      additionalInfo: data['additionalInfo'] as Map<String, dynamic>?,
     );
   }
 
@@ -246,7 +249,8 @@ class ElectrumTransactionInfo extends TransactionInfo {
         isReplaced: isReplaced ?? false,
         inputAddresses: inputAddresses,
         outputAddresses: outputAddresses,
-        confirmations: info.confirmations);
+        confirmations: info.confirmations,
+        additionalInfo: additionalInfo);
   }
 
   Map<String, dynamic> toJson() {
@@ -265,10 +269,11 @@ class ElectrumTransactionInfo extends TransactionInfo {
     m['inputAddresses'] = inputAddresses;
     m['outputAddresses'] = outputAddresses;
     m['isReceivedSilentPayment'] = isReceivedSilentPayment;
+    m['additionalInfo'] = additionalInfo;
     return m;
   }
 
   String toString() {
-    return 'ElectrumTransactionInfo(id: $id, height: $height, amount: $amount, fee: $fee, direction: $direction, date: $date, isPending: $isPending, isReplaced: $isReplaced, confirmations: $confirmations, to: $to, unspent: $unspents, inputAddresses: $inputAddresses, outputAddresses: $outputAddresses)';
+    return 'ElectrumTransactionInfo(id: $id, height: $height, amount: $amount, fee: $fee, direction: $direction, date: $date, isPending: $isPending, isReplaced: $isReplaced, confirmations: $confirmations, to: $to, unspent: $unspents, inputAddresses: $inputAddresses, outputAddresses: $outputAddresses, additionalInfo: $additionalInfo)';
   }
 }
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index c05095cf1..7988a4479 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -5,6 +5,7 @@ import 'dart:isolate';
 
 import 'package:bitcoin_base/bitcoin_base.dart';
 import 'package:cw_bitcoin/bitcoin_wallet.dart';
+import 'package:cw_bitcoin/litecoin_wallet.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:collection/collection.dart';
@@ -52,10 +53,9 @@ part 'electrum_wallet.g.dart';
 
 class ElectrumWallet = ElectrumWalletBase with _$ElectrumWallet;
 
-abstract class ElectrumWalletBase extends WalletBase<
-    ElectrumBalance,
-    ElectrumTransactionHistory,
-    ElectrumTransactionInfo> with Store, WalletKeysFile {
+abstract class ElectrumWalletBase
+    extends WalletBase<ElectrumBalance, ElectrumTransactionHistory, ElectrumTransactionInfo>
+    with Store, WalletKeysFile {
   ElectrumWalletBase({
     required String password,
     required WalletInfo walletInfo,
@@ -71,8 +71,8 @@ abstract class ElectrumWalletBase extends WalletBase<
     ElectrumBalance? initialBalance,
     CryptoCurrency? currency,
     this.alwaysScan,
-  })  : accountHD = getAccountHDWallet(
-            currency, network, seedBytes, xpub, walletInfo.derivationInfo),
+  })  : accountHD =
+            getAccountHDWallet(currency, network, seedBytes, xpub, walletInfo.derivationInfo),
         syncStatus = NotConnectedSyncStatus(),
         _password = password,
         _feeRates = <int>[],
@@ -107,12 +107,8 @@ abstract class ElectrumWalletBase extends WalletBase<
     sharedPrefs.complete(SharedPreferences.getInstance());
   }
 
-  static Bip32Slip10Secp256k1 getAccountHDWallet(
-      CryptoCurrency? currency,
-      BasedUtxoNetwork network,
-      Uint8List? seedBytes,
-      String? xpub,
-      DerivationInfo? derivationInfo) {
+  static Bip32Slip10Secp256k1 getAccountHDWallet(CryptoCurrency? currency, BasedUtxoNetwork network,
+      Uint8List? seedBytes, String? xpub, DerivationInfo? derivationInfo) {
     if (seedBytes == null && xpub == null) {
       throw Exception(
           "To create a Wallet you need either a seed or an xpub. This should not happen");
@@ -123,9 +119,8 @@ abstract class ElectrumWalletBase extends WalletBase<
         case CryptoCurrency.btc:
         case CryptoCurrency.ltc:
         case CryptoCurrency.tbtc:
-          return Bip32Slip10Secp256k1.fromSeed(seedBytes, getKeyNetVersion(network))
-                  .derivePath(_hardenedDerivationPath(
-                      derivationInfo?.derivationPath ?? electrum_path))
+          return Bip32Slip10Secp256k1.fromSeed(seedBytes, getKeyNetVersion(network)).derivePath(
+                  _hardenedDerivationPath(derivationInfo?.derivationPath ?? electrum_path))
               as Bip32Slip10Secp256k1;
         case CryptoCurrency.bch:
           return bitcoinCashHDWallet(seedBytes);
@@ -134,13 +129,11 @@ abstract class ElectrumWalletBase extends WalletBase<
       }
     }
 
-    return Bip32Slip10Secp256k1.fromExtendedKey(
-        xpub!, getKeyNetVersion(network));
+    return Bip32Slip10Secp256k1.fromExtendedKey(xpub!, getKeyNetVersion(network));
   }
 
   static Bip32Slip10Secp256k1 bitcoinCashHDWallet(Uint8List seedBytes) =>
-      Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath("m/44'/145'/0'")
-          as Bip32Slip10Secp256k1;
+      Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath("m/44'/145'/0'") as Bip32Slip10Secp256k1;
 
   static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
       inputsCount * 68 + outputsCounts * 34 + 10;
@@ -250,7 +243,7 @@ abstract class ElectrumWalletBase extends WalletBase<
       }
 
       if (tip > walletInfo.restoreHeight) {
-        _setListeners(walletInfo.restoreHeight, chainTipParam: _currentChainTip);
+        _setListeners(walletInfo.restoreHeight, chainTipParam: currentChainTip);
       }
     } else {
       alwaysScan = false;
@@ -265,23 +258,23 @@ abstract class ElectrumWalletBase extends WalletBase<
     }
   }
 
-  int? _currentChainTip;
+  int? currentChainTip;
 
   Future<int> getCurrentChainTip() async {
-    if ((_currentChainTip ?? 0) > 0) {
-      return _currentChainTip!;
+    if ((currentChainTip ?? 0) > 0) {
+      return currentChainTip!;
     }
-    _currentChainTip = await electrumClient.getCurrentBlockChainTip() ?? 0;
+    currentChainTip = await electrumClient.getCurrentBlockChainTip() ?? 0;
 
-    return _currentChainTip!;
+    return currentChainTip!;
   }
 
   Future<int> getUpdatedChainTip() async {
     final newTip = await electrumClient.getCurrentBlockChainTip();
-    if (newTip != null && newTip > (_currentChainTip ?? 0)) {
-      _currentChainTip = newTip;
+    if (newTip != null && newTip > (currentChainTip ?? 0)) {
+      currentChainTip = newTip;
     }
-    return _currentChainTip ?? 0;
+    return currentChainTip ?? 0;
   }
 
   @override
@@ -357,7 +350,7 @@ abstract class ElectrumWalletBase extends WalletBase<
           isSingleScan: doSingleScan ?? false,
         ));
 
-    _receiveStream?.cancel();
+    await _receiveStream?.cancel();
     _receiveStream = receivePort.listen((var message) async {
       if (message is Map<String, ElectrumTransactionInfo>) {
         for (final map in message.entries) {
@@ -618,7 +611,7 @@ abstract class ElectrumWalletBase extends WalletBase<
     bool spendsUnconfirmedTX = false;
 
     int leftAmount = credentialsAmount;
-    final availableInputs = unspentCoins.where((utx) {
+    var availableInputs = unspentCoins.where((utx) {
       if (!utx.isSending || utx.isFrozen) {
         return false;
       }
@@ -634,6 +627,9 @@ abstract class ElectrumWalletBase extends WalletBase<
     }).toList();
     final unconfirmedCoins = availableInputs.where((utx) => utx.confirmations == 0).toList();
 
+    // sort the unconfirmed coins so that mweb coins are first:
+    availableInputs.sort((a, b) => a.bitcoinAddressRecord.type == SegwitAddresType.mweb ? -1 : 1);
+
     for (int i = 0; i < availableInputs.length; i++) {
       final utx = availableInputs[i];
       if (!spendsUnconfirmedTX) spendsUnconfirmedTX = utx.confirmations == 0;
@@ -652,9 +648,8 @@ abstract class ElectrumWalletBase extends WalletBase<
       ECPrivate? privkey;
       bool? isSilentPayment = false;
 
-      final hd = utx.bitcoinAddressRecord.isHidden
-          ? walletAddresses.sideHd
-          : walletAddresses.mainHd;
+      final hd =
+          utx.bitcoinAddressRecord.isHidden ? walletAddresses.sideHd : walletAddresses.mainHd;
 
       if (utx.bitcoinAddressRecord is BitcoinSilentPaymentAddressRecord) {
         final unspentAddress = utx.bitcoinAddressRecord as BitcoinSilentPaymentAddressRecord;
@@ -1233,8 +1228,7 @@ abstract class ElectrumWalletBase extends WalletBase<
     }
   }
 
-  void setLedgerConnection(ledger.LedgerConnection connection) =>
-      throw UnimplementedError();
+  void setLedgerConnection(ledger.LedgerConnection connection) => throw UnimplementedError();
 
   Future<BtcTransaction> buildHardwareWalletTransaction({
     required List<BitcoinBaseOutput> outputs,
@@ -1593,9 +1587,7 @@ abstract class ElectrumWalletBase extends WalletBase<
 
         final btcAddress = RegexUtils.addressTypeFromStr(addressRecord.address, network);
         final privkey = generateECPrivate(
-            hd: addressRecord.isHidden
-                ? walletAddresses.sideHd
-                : walletAddresses.mainHd,
+            hd: addressRecord.isHidden ? walletAddresses.sideHd : walletAddresses.mainHd,
             index: addressRecord.index,
             network: network);
 
@@ -1777,8 +1769,7 @@ abstract class ElectrumWalletBase extends WalletBase<
 
     if (height != null) {
       if (time == null && height > 0) {
-        time = (getDateByBitcoinHeight(height).millisecondsSinceEpoch / 1000)
-            .round();
+        time = (getDateByBitcoinHeight(height).millisecondsSinceEpoch / 1000).round();
       }
 
       if (confirmations == null) {
@@ -1847,6 +1838,7 @@ abstract class ElectrumWalletBase extends WalletBase<
             .map((type) => fetchTransactionsForAddressType(historiesWithDetails, type)));
       } else if (type == WalletType.litecoin) {
         await Future.wait(LITECOIN_ADDRESS_TYPES
+            .where((type) => type != SegwitAddresType.mweb)
             .map((type) => fetchTransactionsForAddressType(historiesWithDetails, type)));
       }
 
@@ -1958,6 +1950,20 @@ abstract class ElectrumWalletBase extends WalletBase<
 
               // Got a new transaction fetched, add it to the transaction history
               // instead of waiting all to finish, and next time it will be faster
+
+              if (this is LitecoinWallet) {
+                // if we have a peg out transaction with the same value
+                // that matches this received transaction, mark it as being from a peg out:
+                for (final tx2 in transactionHistory.transactions.values) {
+                  final heightDiff = ((tx2.height ?? 0) - (tx.height ?? 0)).abs();
+                  // this isn't a perfect matching algorithm since we don't have the right input/output information from these transaction models (the addresses are in different formats), but this should be more than good enough for now as it's extremely unlikely a user receives the EXACT same amount from 2 different sources and one of them is a peg out and the other isn't WITHIN 5 blocks of each other
+                  if (tx2.additionalInfo["isPegOut"] == true &&
+                      tx2.amount == tx.amount &&
+                      heightDiff <= 5) {
+                    tx.additionalInfo["fromPegOut"] = true;
+                  }
+                }
+              }
               transactionHistory.addOne(tx);
               await transactionHistory.save();
             }
@@ -1984,18 +1990,28 @@ abstract class ElectrumWalletBase extends WalletBase<
       if (_isTransactionUpdating) {
         return;
       }
-      await getCurrentChainTip();
+      currentChainTip = await getUpdatedChainTip();
 
+      bool updated = false;
       transactionHistory.transactions.values.forEach((tx) {
-        if (tx.unspents != null &&
-            tx.unspents!.isNotEmpty &&
-            tx.height != null &&
-            tx.height! > 0 &&
-            (_currentChainTip ?? 0) > 0) {
-          tx.confirmations = _currentChainTip! - tx.height! + 1;
+        if ((tx.height ?? 0) > 0 && (currentChainTip ?? 0) > 0) {
+          var confirmations = currentChainTip! - tx.height! + 1;
+          if (confirmations < 0) {
+            // if our chain tip is outdated then it could lead to negative confirmations so this is just a failsafe:
+            confirmations = 0;
+          }
+          if (confirmations != tx.confirmations) {
+            updated = true;
+            tx.confirmations = confirmations;
+            transactionHistory.addOne(tx);
+          }
         }
       });
 
+      if (updated) {
+        await transactionHistory.save();
+      }
+
       _isTransactionUpdating = true;
       await fetchTransactions();
       walletAddresses.updateReceiveAddresses();
@@ -2043,6 +2059,8 @@ abstract class ElectrumWalletBase extends WalletBase<
             library: this.runtimeType.toString(),
           ));
         }
+      }, onError: (e, s) {
+        print("sub_listen error: $e $s");
       });
     }));
   }
@@ -2092,6 +2110,13 @@ abstract class ElectrumWalletBase extends WalletBase<
 
     final balances = await Future.wait(balanceFutures);
 
+    if (balances.isNotEmpty && balances.first['confirmed'] == null) {
+      // if we got null balance responses from the server, set our connection status to lost and return our last known balance:
+      print("got null balance responses from the server, setting connection status to lost");
+      syncStatus = LostConnectionSyncStatus();
+      return balance[currency] ?? ElectrumBalance(confirmed: 0, unconfirmed: 0, frozen: 0);
+    }
+
     for (var i = 0; i < balances.length; i++) {
       final addressRecord = addresses[i];
       final balance = balances[i];
@@ -2197,10 +2222,10 @@ abstract class ElectrumWalletBase extends WalletBase<
   Future<void> _setInitialHeight() async {
     if (_chainTipUpdateSubject != null) return;
 
-    _currentChainTip = await getUpdatedChainTip();
+    currentChainTip = await getUpdatedChainTip();
 
-    if ((_currentChainTip == null || _currentChainTip! == 0) && walletInfo.restoreHeight == 0) {
-      await walletInfo.updateRestoreHeight(_currentChainTip!);
+    if ((currentChainTip == null || currentChainTip! == 0) && walletInfo.restoreHeight == 0) {
+      await walletInfo.updateRestoreHeight(currentChainTip!);
     }
 
     _chainTipUpdateSubject = electrumClient.chainTipSubscribe();
@@ -2209,7 +2234,7 @@ abstract class ElectrumWalletBase extends WalletBase<
       final height = int.tryParse(event['height'].toString());
 
       if (height != null) {
-        _currentChainTip = height;
+        currentChainTip = height;
 
         if (alwaysScan == true && syncStatus is SyncedSyncStatus) {
           _setListeners(walletInfo.restoreHeight);
@@ -2223,7 +2248,6 @@ abstract class ElectrumWalletBase extends WalletBase<
 
   @action
   void _onConnectionStatusChange(ConnectionStatus status) {
-
     switch (status) {
       case ConnectionStatus.connected:
         if (syncStatus is NotConnectedSyncStatus ||
@@ -2270,8 +2294,6 @@ abstract class ElectrumWalletBase extends WalletBase<
       Timer(Duration(seconds: 5), () {
         if (this.syncStatus is NotConnectedSyncStatus ||
             this.syncStatus is LostConnectionSyncStatus) {
-          if (node == null) return;
-
           this.electrumClient.connectToUri(
                 node!.uri,
                 useSSL: node!.useSSL ?? false,
diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 1fb39c878..86228fc83 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -9,6 +9,7 @@ import 'package:crypto/crypto.dart';
 import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
 import 'package:cw_core/cake_hive.dart';
 import 'package:cw_core/mweb_utxo.dart';
+import 'package:cw_core/node.dart';
 import 'package:cw_mweb/mwebd.pbgrpc.dart';
 import 'package:fixnum/fixnum.dart';
 import 'package:bip39/bip39.dart' as bip39;
@@ -47,6 +48,7 @@ import 'package:cw_mweb/cw_mweb.dart';
 import 'package:bitcoin_base/src/crypto/keypair/sign_utils.dart';
 import 'package:pointycastle/ecc/api.dart';
 import 'package:pointycastle/ecc/curves/secp256k1.dart';
+import 'package:shared_preferences/shared_preferences.dart';
 
 part 'litecoin_wallet.g.dart';
 
@@ -85,8 +87,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
           alwaysScan: alwaysScan,
         ) {
     if (seedBytes != null) {
-      mwebHd = Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath(
-          "m/1000'") as Bip32Slip10Secp256k1;
+      mwebHd =
+          Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath("m/1000'") as Bip32Slip10Secp256k1;
       mwebEnabled = alwaysScan ?? false;
     } else {
       mwebHd = null;
@@ -287,6 +289,16 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     await (walletAddresses as LitecoinWalletAddresses).ensureMwebAddressUpToIndexExists(1020);
   }
 
+  @action
+  @override
+  Future<void> connectToNode({required Node node}) async {
+    await super.connectToNode(node: node);
+
+    final prefs = await SharedPreferences.getInstance();
+    final mwebNodeUri = prefs.getString("mwebNodeUri") ?? "ltc-electrum.cakewallet.com:9333";
+    await CwMweb.setNodeUriOverride(mwebNodeUri);
+  }
+
   @action
   @override
   Future<void> startSync() async {
@@ -349,6 +361,9 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
         return;
       }
 
+      // update the current chain tip so that confirmation calculations are accurate:
+      currentChainTip = nodeHeight;
+
       final resp = await CwMweb.status(StatusRequest());
 
       try {
@@ -361,22 +376,46 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
         } else if (resp.mwebUtxosHeight < nodeHeight) {
           mwebSyncStatus = SyncingSyncStatus(1, 0.999);
         } else {
+          bool confirmationsUpdated = false;
           if (resp.mwebUtxosHeight > walletInfo.restoreHeight) {
             await walletInfo.updateRestoreHeight(resp.mwebUtxosHeight);
             await checkMwebUtxosSpent();
             // update the confirmations for each transaction:
-            for (final transaction in transactionHistory.transactions.values) {
-              if (transaction.isPending) continue;
-              int txHeight = transaction.height ?? resp.mwebUtxosHeight;
-              final confirmations = (resp.mwebUtxosHeight - txHeight) + 1;
-              if (transaction.confirmations == confirmations) continue;
-              if (transaction.confirmations == 0) {
-                updateBalance();
+            for (final tx in transactionHistory.transactions.values) {
+              if (tx.height == null || tx.height == 0) {
+                // update with first confirmation on next block since it hasn't been confirmed yet:
+                tx.height = resp.mwebUtxosHeight;
+                continue;
               }
-              transaction.confirmations = confirmations;
-              transactionHistory.addOne(transaction);
+
+              final confirmations = (resp.mwebUtxosHeight - tx.height!) + 1;
+
+              // if the confirmations haven't changed, skip updating:
+              if (tx.confirmations == confirmations) continue;
+
+
+              // if an outgoing tx is now confirmed, delete the utxo from the box (delete the unspent coin):
+              if (confirmations >= 2 &&
+                  tx.direction == TransactionDirection.outgoing &&
+                  tx.unspents != null) {
+                for (var coin in tx.unspents!) {
+                  final utxo = mwebUtxosBox.get(coin.address);
+                  if (utxo != null) {
+                    print("deleting utxo ${coin.address} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+                    await mwebUtxosBox.delete(coin.address);
+                  }
+                }
+              }
+
+              tx.confirmations = confirmations;
+              tx.isPending = false;
+              transactionHistory.addOne(tx);
+              confirmationsUpdated = true;
+            }
+            if (confirmationsUpdated) {
+              await transactionHistory.save();
+              await updateTransactions();
             }
-            await transactionHistory.save();
           }
 
           // prevent unnecessary reaction triggers:
@@ -501,13 +540,12 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
         outputAddresses: [utxo.outputId],
         isReplaced: false,
       );
-    }
-
-    // don't update the confirmations if the tx is updated by electrum:
-    if (tx.confirmations == 0 || utxo.height != 0) {
-      tx.height = utxo.height;
-      tx.isPending = utxo.height == 0;
-      tx.confirmations = confirmations;
+    } else {
+      if (tx.confirmations != confirmations || tx.height != utxo.height) {
+        tx.height = utxo.height;
+        tx.confirmations = confirmations;
+        tx.isPending = utxo.height == 0;
+      }
     }
 
     bool isNew = transactionHistory.transactions[tx.id] == null;
@@ -557,56 +595,88 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     if (responseStream == null) {
       throw Exception("failed to get utxos stream!");
     }
-    _utxoStream = responseStream.listen((Utxo sUtxo) async {
-      // we're processing utxos, so our balance could still be innacurate:
-      if (mwebSyncStatus is! SyncronizingSyncStatus && mwebSyncStatus is! SyncingSyncStatus) {
-        mwebSyncStatus = SyncronizingSyncStatus();
-        processingUtxos = true;
-        _processingTimer?.cancel();
-        _processingTimer = Timer.periodic(const Duration(seconds: 2), (timer) async {
-          processingUtxos = false;
-          timer.cancel();
-        });
-      }
-
-      final utxo = MwebUtxo(
-        address: sUtxo.address,
-        blockTime: sUtxo.blockTime,
-        height: sUtxo.height,
-        outputId: sUtxo.outputId,
-        value: sUtxo.value.toInt(),
-      );
-
-      if (mwebUtxosBox.containsKey(utxo.outputId)) {
-        // we've already stored this utxo, skip it:
-        // but do update the utxo height if it's somehow different:
-        final existingUtxo = mwebUtxosBox.get(utxo.outputId);
-        if (existingUtxo!.height != utxo.height) {
-          print(
-              "updating utxo height for $utxo.outputId: ${existingUtxo.height} -> ${utxo.height}");
-          existingUtxo.height = utxo.height;
-          await mwebUtxosBox.put(utxo.outputId, existingUtxo);
+    _utxoStream = responseStream.listen(
+      (Utxo sUtxo) async {
+        // we're processing utxos, so our balance could still be innacurate:
+        if (mwebSyncStatus is! SyncronizingSyncStatus && mwebSyncStatus is! SyncingSyncStatus) {
+          mwebSyncStatus = SyncronizingSyncStatus();
+          processingUtxos = true;
+          _processingTimer?.cancel();
+          _processingTimer = Timer.periodic(const Duration(seconds: 2), (timer) async {
+            processingUtxos = false;
+            timer.cancel();
+          });
         }
-        return;
-      }
 
-      await updateUnspent();
-      await updateBalance();
+        final utxo = MwebUtxo(
+          address: sUtxo.address,
+          blockTime: sUtxo.blockTime,
+          height: sUtxo.height,
+          outputId: sUtxo.outputId,
+          value: sUtxo.value.toInt(),
+        );
 
-      final mwebAddrs = (walletAddresses as LitecoinWalletAddresses).mwebAddrs;
+        if (mwebUtxosBox.containsKey(utxo.outputId)) {
+          // we've already stored this utxo, skip it:
+          // but do update the utxo height if it's somehow different:
+          final existingUtxo = mwebUtxosBox.get(utxo.outputId);
+          if (existingUtxo!.height != utxo.height) {
+            print(
+                "updating utxo height for $utxo.outputId: ${existingUtxo.height} -> ${utxo.height}");
+            existingUtxo.height = utxo.height;
+            await mwebUtxosBox.put(utxo.outputId, existingUtxo);
+          }
+          return;
+        }
 
-      // don't process utxos with addresses that are not in the mwebAddrs list:
-      if (utxo.address.isNotEmpty && !mwebAddrs.contains(utxo.address)) {
-        return;
-      }
+        await updateUnspent();
+        await updateBalance();
 
-      await mwebUtxosBox.put(utxo.outputId, utxo);
+        final mwebAddrs = (walletAddresses as LitecoinWalletAddresses).mwebAddrs;
 
-      await handleIncoming(utxo);
-    });
+        // don't process utxos with addresses that are not in the mwebAddrs list:
+        if (utxo.address.isNotEmpty && !mwebAddrs.contains(utxo.address)) {
+          return;
+        }
+
+        await mwebUtxosBox.put(utxo.outputId, utxo);
+
+        await handleIncoming(utxo);
+      },
+      onError: (error) {
+        print("error in utxo stream: $error");
+        mwebSyncStatus = FailedSyncStatus(error: error.toString());
+      },
+      cancelOnError: true,
+    );
+  }
+
+  Future<void> deleteSpentUtxos() async {
+    print("deleteSpentUtxos() called!");
+    final chainHeight = await electrumClient.getCurrentBlockChainTip();
+    final status = await CwMweb.status(StatusRequest());
+    if (chainHeight == null || status.blockHeaderHeight != chainHeight) return;
+    if (status.mwebUtxosHeight != chainHeight) return; // we aren't synced
+
+    // delete any spent utxos with >= 2 confirmations:
+    final spentOutputIds = mwebUtxosBox.values
+        .where((utxo) => utxo.spent && (chainHeight - utxo.height) >= 2)
+        .map((utxo) => utxo.outputId)
+        .toList();
+
+    if (spentOutputIds.isEmpty) return;
+
+    final resp = await CwMweb.spent(SpentRequest(outputId: spentOutputIds));
+    final spent = resp.outputId;
+    if (spent.isEmpty) return;
+
+    for (final outputId in spent) {
+      await mwebUtxosBox.delete(outputId);
+    }
   }
 
   Future<void> checkMwebUtxosSpent() async {
+    print("checkMwebUtxosSpent() called!");
     if (!mwebEnabled) {
       return;
     }
@@ -620,15 +690,17 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       updatedAny = await isConfirmed(tx) || updatedAny;
     }
 
+    await deleteSpentUtxos();
+
     // get output ids of all the mweb utxos that have > 0 height:
-    final outputIds =
-        mwebUtxosBox.values.where((utxo) => utxo.height > 0).map((utxo) => utxo.outputId).toList();
+    final outputIds = mwebUtxosBox.values
+        .where((utxo) => utxo.height > 0 && !utxo.spent)
+        .map((utxo) => utxo.outputId)
+        .toList();
 
     final resp = await CwMweb.spent(SpentRequest(outputId: outputIds));
     final spent = resp.outputId;
-    if (spent.isEmpty) {
-      return;
-    }
+    if (spent.isEmpty) return;
 
     final status = await CwMweb.status(StatusRequest());
     final height = await electrumClient.getCurrentBlockChainTip();
@@ -739,7 +811,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     mwebUtxosBox.keys.forEach((dynamic oId) {
       final String outputId = oId as String;
       final utxo = mwebUtxosBox.get(outputId);
-      if (utxo == null) {
+      if (utxo == null || utxo.spent) {
         return;
       }
       if (utxo.address.isEmpty) {
@@ -789,15 +861,23 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     int unconfirmedMweb = 0;
     try {
       mwebUtxosBox.values.forEach((utxo) {
-        if (utxo.height > 0) {
+        bool isConfirmed = utxo.height > 0;
+
+        print(
+            "utxo: ${isConfirmed ? "confirmed" : "unconfirmed"} ${utxo.spent ? "spent" : "unspent"} ${utxo.outputId} ${utxo.height} ${utxo.value}");
+
+        if (isConfirmed) {
           confirmedMweb += utxo.value.toInt();
-        } else {
+        }
+
+        if (isConfirmed && utxo.spent) {
+          unconfirmedMweb -= utxo.value.toInt();
+        }
+
+        if (!isConfirmed && !utxo.spent) {
           unconfirmedMweb += utxo.value.toInt();
         }
       });
-      if (unconfirmedMweb > 0) {
-        unconfirmedMweb = -1 * (confirmedMweb - unconfirmedMweb);
-      }
     } catch (_) {}
 
     for (var addressRecord in walletAddresses.allAddresses) {
@@ -829,7 +909,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     // update the txCount for each address using the tx history, since we can't rely on mwebd
     // to have an accurate count, we should just keep it in sync with what we know from the tx history:
     for (final tx in transactionHistory.transactions.values) {
-      // if (tx.isPending) continue;
       if (tx.inputAddresses == null || tx.outputAddresses == null) {
         continue;
       }
@@ -908,7 +987,26 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     // https://github.com/ltcmweb/mwebd?tab=readme-ov-file#fee-estimation
     final preOutputSum =
         outputs.fold<BigInt>(BigInt.zero, (acc, output) => acc + output.toOutput.amount);
-    final fee = utxos.sumOfUtxosValue() - preOutputSum;
+    var fee = utxos.sumOfUtxosValue() - preOutputSum;
+
+    // determines if the fee is correct:
+    BigInt _sumOutputAmounts(List<TxOutput> outputs) {
+      BigInt sum = BigInt.zero;
+      for (final e in outputs) {
+        sum += e.amount;
+      }
+      return sum;
+    }
+
+    final sum1 = _sumOutputAmounts(outputs.map((e) => e.toOutput).toList()) + fee;
+    final sum2 = utxos.sumOfUtxosValue();
+    if (sum1 != sum2) {
+      print("@@@@@ WE HAD TO ADJUST THE FEE! @@@@@@@@");
+      final diff = sum2 - sum1;
+      // add the difference to the fee (abs value):
+      fee += diff.abs();
+    }
+
     final txb =
         BitcoinTransactionBuilder(utxos: utxos, outputs: outputs, fee: fee, network: network);
     final resp = await CwMweb.create(CreateRequest(
@@ -949,8 +1047,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
 
       if (!mwebEnabled) {
         tx.changeAddressOverride =
-            (await (walletAddresses as LitecoinWalletAddresses)
-                    .getChangeAddress(isPegIn: false))
+            (await (walletAddresses as LitecoinWalletAddresses).getChangeAddress(isPegIn: false))
                 .address;
         return tx;
       }
@@ -969,15 +1066,25 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
 
       bool hasMwebInput = false;
       bool hasMwebOutput = false;
+      bool hasRegularOutput = false;
 
       for (final output in transactionCredentials.outputs) {
-        if (output.extractedAddress?.toLowerCase().contains("mweb") ?? false) {
+        final address = output.address.toLowerCase();
+        final extractedAddress = output.extractedAddress?.toLowerCase();
+
+        if (address.contains("mweb")) {
           hasMwebOutput = true;
-          break;
         }
-        if (output.address.toLowerCase().contains("mweb")) {
-          hasMwebOutput = true;
-          break;
+        if (!address.contains("mweb")) {
+          hasRegularOutput = true;
+        }
+        if (extractedAddress != null && extractedAddress.isNotEmpty) {
+          if (extractedAddress.contains("mweb")) {
+            hasMwebOutput = true;
+          }
+          if (!extractedAddress.contains("mweb")) {
+            hasRegularOutput = true;
+          }
         }
       }
 
@@ -989,11 +1096,11 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       }
 
       bool isPegIn = !hasMwebInput && hasMwebOutput;
+      bool isPegOut = hasMwebInput && hasRegularOutput;
       bool isRegular = !hasMwebInput && !hasMwebOutput;
-      tx.changeAddressOverride =
-          (await (walletAddresses as LitecoinWalletAddresses)
-                  .getChangeAddress(isPegIn: isPegIn || isRegular))
-              .address;
+      tx.changeAddressOverride = (await (walletAddresses as LitecoinWalletAddresses)
+              .getChangeAddress(isPegIn: isPegIn || isRegular))
+          .address;
       if (!hasMwebInput && !hasMwebOutput) {
         tx.isMweb = false;
         return tx;
@@ -1046,8 +1153,11 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
           final addresses = <String>{};
           transaction.inputAddresses?.forEach((id) async {
             final utxo = mwebUtxosBox.get(id);
-            await mwebUtxosBox.delete(id); // gets deleted in checkMwebUtxosSpent
+            // await mwebUtxosBox.delete(id); // gets deleted in checkMwebUtxosSpent
             if (utxo == null) return;
+            // mark utxo as spent so we add it to the unconfirmed balance (as negative):
+            utxo.spent = true;
+            await mwebUtxosBox.put(id, utxo);
             final addressRecord = walletAddresses.allAddresses
                 .firstWhere((addressRecord) => addressRecord.address == utxo.address);
             if (!addresses.contains(utxo.address)) {
@@ -1056,7 +1166,9 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
             addressRecord.balance -= utxo.value.toInt();
           });
           transaction.inputAddresses?.addAll(addresses);
-
+          print("isPegIn: $isPegIn, isPegOut: $isPegOut");
+          transaction.additionalInfo["isPegIn"] = isPegIn;
+          transaction.additionalInfo["isPegOut"] = isPegOut;
           transactionHistory.addOne(transaction);
           await updateUnspent();
           await updateBalance();
@@ -1240,8 +1352,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   @override
   void setLedgerConnection(LedgerConnection connection) {
     _ledgerConnection = connection;
-    _litecoinLedgerApp =
-        LitecoinLedgerApp(_ledgerConnection!, derivationPath: walletInfo.derivationInfo!.derivationPath!);
+    _litecoinLedgerApp = LitecoinLedgerApp(_ledgerConnection!,
+        derivationPath: walletInfo.derivationInfo!.derivationPath!);
   }
 
   @override
@@ -1277,19 +1389,17 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       if (maybeChangePath != null) changePath ??= maybeChangePath.derivationPath;
     }
 
-
     final rawHex = await _litecoinLedgerApp!.createTransaction(
-      inputs: readyInputs,
-      outputs: outputs
-          .map((e) => TransactionOutput.fromBigInt(
-              (e as BitcoinOutput).value, Uint8List.fromList(e.address.toScriptPubKey().toBytes())))
-          .toList(),
-      changePath: changePath,
-      sigHashType: 0x01,
-      additionals: ["bech32"],
-      isSegWit: true,
-      useTrustedInputForSegwit: true
-    );
+        inputs: readyInputs,
+        outputs: outputs
+            .map((e) => TransactionOutput.fromBigInt((e as BitcoinOutput).value,
+                Uint8List.fromList(e.address.toScriptPubKey().toBytes())))
+            .toList(),
+        changePath: changePath,
+        sigHashType: 0x01,
+        additionals: ["bech32"],
+        isSegWit: true,
+        useTrustedInputForSegwit: true);
 
     return BtcTransaction.fromRaw(rawHex);
   }
diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
index c55f5fc76..062c590ba 100644
--- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
@@ -16,11 +16,9 @@ import 'package:mobx/mobx.dart';
 
 part 'litecoin_wallet_addresses.g.dart';
 
-class LitecoinWalletAddresses = LitecoinWalletAddressesBase
-    with _$LitecoinWalletAddresses;
+class LitecoinWalletAddresses = LitecoinWalletAddressesBase with _$LitecoinWalletAddresses;
 
-abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses
-    with Store {
+abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with Store {
   LitecoinWalletAddressesBase(
     WalletInfo walletInfo, {
     required super.mainHd,
@@ -46,8 +44,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses
   List<String> mwebAddrs = [];
   bool generating = false;
 
-  List<int> get scanSecret =>
-      mwebHd!.childKey(Bip32KeyIndex(0x80000000)).privateKey.privKey.raw;
+  List<int> get scanSecret => mwebHd!.childKey(Bip32KeyIndex(0x80000000)).privateKey.privKey.raw;
   List<int> get spendPubkey =>
       mwebHd!.childKey(Bip32KeyIndex(0x80000001)).publicKey.pubKey.compressed;
 
@@ -203,4 +200,12 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses
 
     return super.getChangeAddress();
   }
+
+  @override
+  String get addressForExchange {
+    // don't use mweb addresses for exchange refund address:
+    final addresses = receiveAddresses
+        .where((element) => element.type == SegwitAddresType.p2wpkh && !element.isUsed);
+    return addresses.first.address;
+  }
 }
diff --git a/cw_bitcoin/lib/litecoin_wallet_service.dart b/cw_bitcoin/lib/litecoin_wallet_service.dart
index 7cc266f5b..d519f4d0a 100644
--- a/cw_bitcoin/lib/litecoin_wallet_service.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_service.dart
@@ -112,6 +112,7 @@ class LitecoinWalletService extends WalletService<
       File neturinoDb = File('$appDirPath/neutrino.db');
       File blockHeaders = File('$appDirPath/block_headers.bin');
       File regFilterHeaders = File('$appDirPath/reg_filter_headers.bin');
+      File mwebdLogs = File('$appDirPath/logs/debug.log');
       if (neturinoDb.existsSync()) {
         neturinoDb.deleteSync();
       }
@@ -121,6 +122,9 @@ class LitecoinWalletService extends WalletService<
       if (regFilterHeaders.existsSync()) {
         regFilterHeaders.deleteSync();
       }
+      if (mwebdLogs.existsSync()) {
+        mwebdLogs.deleteSync();
+      }
     }
   }
 
diff --git a/cw_bitcoin/lib/pending_bitcoin_transaction.dart b/cw_bitcoin/lib/pending_bitcoin_transaction.dart
index 5ed84dbf4..140965655 100644
--- a/cw_bitcoin/lib/pending_bitcoin_transaction.dart
+++ b/cw_bitcoin/lib/pending_bitcoin_transaction.dart
@@ -118,8 +118,7 @@ class PendingBitcoinTransaction with PendingTransaction {
 
   Future<void> _ltcCommit() async {
     try {
-      final stub = await CwMweb.stub();
-      final resp = await stub.broadcast(BroadcastRequest(rawTx: BytesUtils.fromHexString(hex)));
+      final resp = await CwMweb.broadcast(BroadcastRequest(rawTx: BytesUtils.fromHexString(hex)));
       idOverride = resp.txid;
     } on GrpcError catch (e) {
       throw BitcoinTransactionCommitFailed(errorMessage: e.message);
diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml
index 9f1cee67d..7a1576a98 100644
--- a/cw_bitcoin/pubspec.yaml
+++ b/cw_bitcoin/pubspec.yaml
@@ -64,7 +64,7 @@ dependency_overrides:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v8
+      ref: cake-update-v9
   pointycastle: 3.7.4
   ffi: 2.1.0
 
diff --git a/cw_bitcoin_cash/pubspec.yaml b/cw_bitcoin_cash/pubspec.yaml
index cd1e52f51..14ff407e2 100644
--- a/cw_bitcoin_cash/pubspec.yaml
+++ b/cw_bitcoin_cash/pubspec.yaml
@@ -42,7 +42,7 @@ dependency_overrides:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v8
+      ref: cake-update-v9
 
 # For information on the generic Dart part of this file, see the
 # following page: https://dart.dev/tools/pub/pubspec
diff --git a/cw_core/lib/mweb_utxo.dart b/cw_core/lib/mweb_utxo.dart
index f8dfab395..5eab11734 100644
--- a/cw_core/lib/mweb_utxo.dart
+++ b/cw_core/lib/mweb_utxo.dart
@@ -11,6 +11,7 @@ class MwebUtxo extends HiveObject {
     required this.address,
     required this.outputId,
     required this.blockTime,
+    this.spent = false,
   });
 
   static const typeId = MWEB_UTXO_TYPE_ID;
@@ -30,4 +31,7 @@ class MwebUtxo extends HiveObject {
 
   @HiveField(4)
   int blockTime;
+
+  @HiveField(5, defaultValue: false)
+  bool spent;
 }
diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart
index e19d2a54b..1094b6402 100644
--- a/cw_core/lib/node.dart
+++ b/cw_core/lib/node.dart
@@ -79,6 +79,9 @@ class Node extends HiveObject with Keyable {
   @HiveField(9)
   bool? supportsSilentPayments;
 
+  @HiveField(10)
+  bool? supportsMweb;
+
   bool get isSSL => useSSL ?? false;
 
   bool get useSocksProxy => socksProxyAddress == null ? false : socksProxyAddress!.isNotEmpty;
diff --git a/cw_core/lib/transaction_info.dart b/cw_core/lib/transaction_info.dart
index 9d0c968d8..3e34af75f 100644
--- a/cw_core/lib/transaction_info.dart
+++ b/cw_core/lib/transaction_info.dart
@@ -25,6 +25,5 @@ abstract class TransactionInfo extends Object with Keyable {
   @override
   dynamic get keyIndex => id;
 
-  late Map<String, dynamic> additionalInfo;
+  Map<String, dynamic> additionalInfo = {};
 }
-
diff --git a/cw_mweb/lib/cw_mweb.dart b/cw_mweb/lib/cw_mweb.dart
index a1a592fb8..75cc0bcca 100644
--- a/cw_mweb/lib/cw_mweb.dart
+++ b/cw_mweb/lib/cw_mweb.dart
@@ -13,8 +13,18 @@ class CwMweb {
   static RpcClient? _rpcClient;
   static ClientChannel? _clientChannel;
   static int? _port;
-  static const TIMEOUT_DURATION = Duration(seconds: 5);
+  static const TIMEOUT_DURATION = Duration(seconds: 15);
   static Timer? logTimer;
+  static String? nodeUriOverride;
+
+
+  static Future<void> setNodeUriOverride(String uri) async {
+    nodeUriOverride = uri;
+    if (_rpcClient != null) {
+      await stop();
+      // will be re-started automatically when the next rpc call is made
+    }
+  }
 
   static void readFileWithTimer(String filePath) {
     final file = File(filePath);
@@ -47,7 +57,7 @@ class CwMweb {
     String debugLogPath = "${appDir.path}/logs/debug.log";
     readFileWithTimer(debugLogPath);
 
-    _port = await CwMwebPlatform.instance.start(appDir.path, ltcNodeUri);
+    _port = await CwMwebPlatform.instance.start(appDir.path, nodeUriOverride ?? ltcNodeUri);
     if (_port == null || _port == 0) {
       throw Exception("Failed to start server");
     }
@@ -197,4 +207,18 @@ class CwMweb {
     }
     return null;
   }
+
+  static Future<BroadcastResponse> broadcast(BroadcastRequest request) async {
+    log("mweb.broadcast() called");
+    try {
+      _rpcClient = await stub();
+      return await _rpcClient!.broadcast(request, options: CallOptions(timeout: TIMEOUT_DURATION));
+    } on GrpcError catch (e) {
+      log('Caught grpc error: ${e.message}');
+      throw "error from broadcast mweb: $e";
+    } catch (e) {
+      log("Error getting create: $e");
+      rethrow;
+    }
+  }
 }
diff --git a/lib/di.dart b/lib/di.dart
index 13ffd839e..14fdbd56d 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -35,6 +35,8 @@ import 'package:cake_wallet/entities/parse_address_from_domain.dart';
 import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart';
 import 'package:cake_wallet/entities/wallet_manager.dart';
 import 'package:cake_wallet/src/screens/receive/address_list_page.dart';
+import 'package:cake_wallet/src/screens/settings/mweb_logs_page.dart';
+import 'package:cake_wallet/src/screens/settings/mweb_node_page.dart';
 import 'package:cake_wallet/view_model/link_view_model.dart';
 import 'package:cake_wallet/tron/tron.dart';
 import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
@@ -945,6 +947,10 @@ Future<void> setup({
 
   getIt.registerFactory(() => MwebSettingsPage(getIt.get<MwebSettingsViewModel>()));
 
+  getIt.registerFactory(() => MwebLogsPage(getIt.get<MwebSettingsViewModel>()));
+
+  getIt.registerFactory(() => MwebNodePage(getIt.get<MwebSettingsViewModel>()));
+
   getIt.registerFactory(() => OtherSettingsPage(getIt.get<OtherSettingsViewModel>()));
 
   getIt.registerFactory(() => NanoChangeRepPage(
diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart
index 73556452c..8e8bfb6ed 100644
--- a/lib/entities/preferences_key.dart
+++ b/lib/entities/preferences_key.dart
@@ -54,6 +54,7 @@ class PreferencesKey {
   static const mwebEnabled = 'mwebEnabled';
   static const hasEnabledMwebBefore = 'hasEnabledMwebBefore';
   static const mwebAlwaysScan = 'mwebAlwaysScan';
+  static const mwebNodeUri = 'mwebNodeUri';
   static const shouldShowReceiveWarning = 'should_show_receive_warning';
   static const shouldShowYatPopup = 'should_show_yat_popup';
   static const shouldShowRepWarning = 'should_show_rep_warning';
diff --git a/lib/router.dart b/lib/router.dart
index 3b4c38546..6c234ff80 100644
--- a/lib/router.dart
+++ b/lib/router.dart
@@ -72,6 +72,8 @@ import 'package:cake_wallet/src/screens/settings/desktop_settings/desktop_settin
 import 'package:cake_wallet/src/screens/settings/display_settings_page.dart';
 import 'package:cake_wallet/src/screens/settings/domain_lookups_page.dart';
 import 'package:cake_wallet/src/screens/settings/manage_nodes_page.dart';
+import 'package:cake_wallet/src/screens/settings/mweb_logs_page.dart';
+import 'package:cake_wallet/src/screens/settings/mweb_node_page.dart';
 import 'package:cake_wallet/src/screens/settings/mweb_settings.dart';
 import 'package:cake_wallet/src/screens/settings/other_settings_page.dart';
 import 'package:cake_wallet/src/screens/settings/privacy_page.dart';
@@ -461,6 +463,14 @@ Route<dynamic> createRoute(RouteSettings settings) {
       return CupertinoPageRoute<void>(
           fullscreenDialog: true, builder: (_) => getIt.get<MwebSettingsPage>());
 
+    case Routes.mwebLogs:
+      return CupertinoPageRoute<void>(
+          fullscreenDialog: true, builder: (_) => getIt.get<MwebLogsPage>());
+
+    case Routes.mwebNode:
+      return CupertinoPageRoute<void>(
+          fullscreenDialog: true, builder: (_) => getIt.get<MwebNodePage>());
+
     case Routes.connectionSync:
       return CupertinoPageRoute<void>(
           fullscreenDialog: true, builder: (_) => getIt.get<ConnectionSyncPage>());
diff --git a/lib/routes.dart b/lib/routes.dart
index 0529d7c6f..5f11b11a3 100644
--- a/lib/routes.dart
+++ b/lib/routes.dart
@@ -74,6 +74,8 @@ class Routes {
   static const webViewPage = '/web_view_page';
   static const silentPaymentsSettings = '/silent_payments_settings';
   static const mwebSettings = '/mweb_settings';
+  static const mwebLogs = '/mweb_logs';
+  static const mwebNode = '/mweb_node';
   static const connectionSync = '/connection_sync_page';
   static const securityBackupPage = '/security_and_backup_page';
   static const privacyPage = '/privacy_page';
diff --git a/lib/src/screens/dashboard/pages/balance_page.dart b/lib/src/screens/dashboard/pages/balance_page.dart
index 028b3cfcf..b16a7b090 100644
--- a/lib/src/screens/dashboard/pages/balance_page.dart
+++ b/lib/src/screens/dashboard/pages/balance_page.dart
@@ -886,17 +886,37 @@ class BalanceRowWidget extends StatelessWidget {
                             Column(
                               crossAxisAlignment: CrossAxisAlignment.start,
                               children: [
-                                Text(
-                                  '${secondAvailableBalanceLabel}',
-                                  textAlign: TextAlign.center,
-                                  style: TextStyle(
-                                    fontSize: 12,
-                                    fontFamily: 'Lato',
-                                    fontWeight: FontWeight.w400,
-                                    color: Theme.of(context)
-                                        .extension<BalancePageTheme>()!
-                                        .labelTextColor,
-                                    height: 1,
+                                GestureDetector(
+                                  behavior: HitTestBehavior.opaque,
+                                  onTap: () => launchUrl(
+                                    Uri.parse(
+                                        "https://guides.cakewallet.com/docs/cryptos/litecoin/#mweb"),
+                                    mode: LaunchMode.externalApplication,
+                                  ),
+                                  child: Row(
+                                    children: [
+                                      Text(
+                                        '${secondAvailableBalanceLabel}',
+                                        textAlign: TextAlign.center,
+                                        style: TextStyle(
+                                          fontSize: 12,
+                                          fontFamily: 'Lato',
+                                          fontWeight: FontWeight.w400,
+                                          color: Theme.of(context)
+                                              .extension<BalancePageTheme>()!
+                                              .labelTextColor,
+                                          height: 1,
+                                        ),
+                                      ),
+                                      Padding(
+                                        padding: const EdgeInsets.symmetric(horizontal: 4),
+                                        child: Icon(Icons.help_outline,
+                                            size: 16,
+                                            color: Theme.of(context)
+                                                .extension<BalancePageTheme>()!
+                                                .labelTextColor),
+                                      )
+                                    ],
                                   ),
                                 ),
                                 SizedBox(height: 8),
diff --git a/lib/src/screens/settings/mweb_logs_page.dart b/lib/src/screens/settings/mweb_logs_page.dart
new file mode 100644
index 000000000..3c5470214
--- /dev/null
+++ b/lib/src/screens/settings/mweb_logs_page.dart
@@ -0,0 +1,127 @@
+import 'dart:io';
+import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
+import 'package:cake_wallet/src/widgets/primary_button.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/utils/exception_handler.dart';
+import 'package:cake_wallet/utils/share_util.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cake_wallet/view_model/settings/mweb_settings_view_model.dart';
+import 'package:cw_core/root_dir.dart';
+import 'package:file_picker/file_picker.dart';
+import 'package:flutter/material.dart';
+import 'package:path_provider/path_provider.dart';
+
+class MwebLogsPage extends BasePage {
+  MwebLogsPage(this.mwebSettingsViewModelBase);
+
+  final MwebSettingsViewModelBase mwebSettingsViewModelBase;
+
+  @override
+  String get title => S.current.litecoin_mweb_logs;
+
+  @override
+  Widget body(BuildContext context) {
+    return Stack(
+      fit: StackFit.expand,
+      children: [
+        FutureBuilder<String>(
+          future: mwebSettingsViewModelBase.getAbbreviatedLogs(),
+          builder: (context, snapshot) {
+            if (snapshot.connectionState == ConnectionState.waiting) {
+              return Center(child: CircularProgressIndicator());
+            } else if (snapshot.hasError || !snapshot.hasData || snapshot.data!.isEmpty) {
+              return Center(child: Text('No logs found'));
+            } else {
+              return SingleChildScrollView(
+                child: Padding(
+                  padding: EdgeInsets.all(16.0),
+                  child: Text(
+                    snapshot.data!,
+                    style: TextStyle(fontFamily: 'Monospace'),
+                  ),
+                ),
+              );
+            }
+          },
+        ),
+        Positioned(
+          child: LoadingPrimaryButton(
+            onPressed: () => onExportLogs(context),
+            text: S.of(context).export_logs,
+            color: Theme.of(context).primaryColor,
+            textColor: Colors.white,
+          ),
+          bottom: 24,
+          left: 24,
+          right: 24,
+        )
+      ],
+    );
+  }
+
+  void onExportLogs(BuildContext context) {
+    if (Platform.isAndroid) {
+      onExportAndroid(context);
+    } else if (Platform.isIOS) {
+      share(context);
+    } else {
+      _saveFile();
+    }
+  }
+
+  void onExportAndroid(BuildContext context) {
+    showPopUp<void>(
+        context: context,
+        builder: (dialogContext) {
+          return AlertWithTwoActions(
+              alertTitle: S.of(context).export_backup,
+              alertContent: S.of(context).select_destination,
+              rightButtonText: S.of(context).save_to_downloads,
+              leftButtonText: S.of(context).share,
+              actionRightButton: () async {
+                const downloadDirPath = "/storage/emulated/0/Download";
+                final filePath = downloadDirPath + "/debug.log";
+                await mwebSettingsViewModelBase.saveLogsLocally(filePath);
+                Navigator.of(dialogContext).pop();
+              },
+              actionLeftButton: () async {
+                Navigator.of(dialogContext).pop();
+                try {
+                  await share(context);
+                } catch (e, s) {
+                  ExceptionHandler.onError(FlutterErrorDetails(
+                    exception: e,
+                    stack: s,
+                    library: "Export Logs",
+                  ));
+                }
+              });
+        });
+  }
+
+  Future<void> share(BuildContext context) async {
+    final filePath = (await getAppDir()).path + "/debug.log";
+    bool success = await mwebSettingsViewModelBase.saveLogsLocally(filePath);
+    if (!success) return;
+    await ShareUtil.shareFile(filePath: filePath, fileName: "debug.log", context: context);
+    await mwebSettingsViewModelBase.removeLogsLocally(filePath);
+  }
+
+  Future<void> _saveFile() async {
+    String? outputFile = await FilePicker.platform
+        .saveFile(dialogTitle: 'Save Your File to desired location', fileName: "debug.log");
+
+    try {
+      final filePath = (await getApplicationSupportDirectory()).path + "/debug.log";
+      File debugLogFile = File(filePath);
+      await debugLogFile.copy(outputFile!);
+    } catch (exception, stackTrace) {
+      ExceptionHandler.onError(FlutterErrorDetails(
+        exception: exception,
+        stack: stackTrace,
+        library: "Export Logs",
+      ));
+    }
+  }
+}
diff --git a/lib/src/screens/settings/mweb_node_page.dart b/lib/src/screens/settings/mweb_node_page.dart
new file mode 100644
index 000000000..801ab3ac7
--- /dev/null
+++ b/lib/src/screens/settings/mweb_node_page.dart
@@ -0,0 +1,56 @@
+import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
+import 'package:cake_wallet/src/widgets/primary_button.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/view_model/settings/mweb_settings_view_model.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+
+class MwebNodePage extends BasePage {
+  MwebNodePage(this.mwebSettingsViewModelBase)
+      : _nodeUriController = TextEditingController(text: mwebSettingsViewModelBase.mwebNodeUri),
+        super();
+
+  final MwebSettingsViewModelBase mwebSettingsViewModelBase;
+  final TextEditingController _nodeUriController;
+
+  @override
+  String get title => S.current.litecoin_mweb_node;
+
+  @override
+  Widget body(BuildContext context) {
+    return Stack(
+      fit: StackFit.expand,
+      children: [
+        Container(
+          padding: EdgeInsets.symmetric(horizontal: 24),
+          child: Row(
+            children: <Widget>[
+              Expanded(
+                child: BaseTextFormField(controller: _nodeUriController),
+              )
+            ],
+          ),
+        ),
+        Positioned(
+          child: Observer(
+            builder: (_) => LoadingPrimaryButton(
+              onPressed: () => save(context),
+              text: S.of(context).save,
+              color: Theme.of(context).primaryColor,
+              textColor: Colors.white,
+            ),
+          ),
+          bottom: 24,
+          left: 24,
+          right: 24,
+        )
+      ],
+    );
+  }
+
+  void save(BuildContext context) {
+    mwebSettingsViewModelBase.setMwebNodeUri(_nodeUriController.text);
+    Navigator.pop(context);
+  }
+}
diff --git a/lib/src/screens/settings/mweb_settings.dart b/lib/src/screens/settings/mweb_settings.dart
index 722ffa9aa..e78fdf596 100644
--- a/lib/src/screens/settings/mweb_settings.dart
+++ b/lib/src/screens/settings/mweb_settings.dart
@@ -31,7 +31,7 @@ class MwebSettingsPage extends BasePage {
                 },
               ),
               SettingsSwitcherCell(
-                title: S.current.litecoin_mweb_always_scan,
+                title: S.current.litecoin_mweb_enable,
                 value: _mwebSettingsViewModel.mwebEnabled,
                 onValueChange: (_, bool value) {
                   _mwebSettingsViewModel.setMwebEnabled(value);
@@ -41,6 +41,14 @@ class MwebSettingsPage extends BasePage {
                 title: S.current.litecoin_mweb_scanning,
                 handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.rescan),
               ),
+            SettingsCellWithArrow(
+                title: S.current.litecoin_mweb_logs,
+                handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.mwebLogs),
+              ),
+              SettingsCellWithArrow(
+                title: S.current.litecoin_mweb_node,
+                handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.mwebNode),
+              ),
             ],
           ),
         );
diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart
index 2eadbd8a9..c966420db 100644
--- a/lib/store/settings_store.dart
+++ b/lib/store/settings_store.dart
@@ -120,6 +120,7 @@ abstract class SettingsStoreBase with Store {
       required this.mwebCardDisplay,
       required this.mwebEnabled,
       required this.hasEnabledMwebBefore,
+      required this.mwebNodeUri,
       TransactionPriority? initialBitcoinTransactionPriority,
       TransactionPriority? initialMoneroTransactionPriority,
       TransactionPriority? initialWowneroTransactionPriority,
@@ -358,8 +359,8 @@ abstract class SettingsStoreBase with Store {
 
     reaction(
         (_) => bitcoinSeedType,
-        (BitcoinSeedType bitcoinSeedType) => sharedPreferences.setInt(
-            PreferencesKey.bitcoinSeedType, bitcoinSeedType.raw));
+        (BitcoinSeedType bitcoinSeedType) =>
+            sharedPreferences.setInt(PreferencesKey.bitcoinSeedType, bitcoinSeedType.raw));
 
     reaction(
         (_) => nanoSeedType,
@@ -442,8 +443,10 @@ abstract class SettingsStoreBase with Store {
     reaction((_) => useTronGrid,
         (bool useTronGrid) => _sharedPreferences.setBool(PreferencesKey.useTronGrid, useTronGrid));
 
-    reaction((_) => useMempoolFeeAPI,
-        (bool useMempoolFeeAPI) => _sharedPreferences.setBool(PreferencesKey.useMempoolFeeAPI, useMempoolFeeAPI));
+    reaction(
+        (_) => useMempoolFeeAPI,
+        (bool useMempoolFeeAPI) =>
+            _sharedPreferences.setBool(PreferencesKey.useMempoolFeeAPI, useMempoolFeeAPI));
 
     reaction((_) => defaultNanoRep,
         (String nanoRep) => _sharedPreferences.setString(PreferencesKey.defaultNanoRep, nanoRep));
@@ -591,6 +594,11 @@ abstract class SettingsStoreBase with Store {
         (bool hasEnabledMwebBefore) =>
             _sharedPreferences.setBool(PreferencesKey.hasEnabledMwebBefore, hasEnabledMwebBefore));
 
+    reaction(
+        (_) => mwebNodeUri,
+        (String mwebNodeUri) =>
+            _sharedPreferences.setString(PreferencesKey.mwebNodeUri, mwebNodeUri));
+
     this.nodes.observe((change) {
       if (change.newValue != null && change.key != null) {
         _saveCurrentNode(change.newValue!, change.key!);
@@ -822,6 +830,9 @@ abstract class SettingsStoreBase with Store {
   @observable
   bool hasEnabledMwebBefore;
 
+  @observable
+  String mwebNodeUri;
+
   final SecureStorage _secureStorage;
   final SharedPreferences _sharedPreferences;
   final BackgroundTasks _backgroundTasks;
@@ -988,6 +999,8 @@ abstract class SettingsStoreBase with Store {
     final mwebEnabled = sharedPreferences.getBool(PreferencesKey.mwebEnabled) ?? false;
     final hasEnabledMwebBefore =
         sharedPreferences.getBool(PreferencesKey.hasEnabledMwebBefore) ?? false;
+    final mwebNodeUri = sharedPreferences.getString(PreferencesKey.mwebNodeUri) ??
+        "ltc-electrum.cakewallet.com:9333";
 
     // If no value
     if (pinLength == null || pinLength == 0) {
@@ -1259,6 +1272,7 @@ abstract class SettingsStoreBase with Store {
       mwebAlwaysScan: mwebAlwaysScan,
       mwebCardDisplay: mwebCardDisplay,
       mwebEnabled: mwebEnabled,
+      mwebNodeUri: mwebNodeUri,
       hasEnabledMwebBefore: hasEnabledMwebBefore,
       initialMoneroTransactionPriority: moneroTransactionPriority,
       initialWowneroTransactionPriority: wowneroTransactionPriority,
@@ -1686,7 +1700,8 @@ abstract class SettingsStoreBase with Store {
         deviceName = windowsInfo.productName;
       } catch (e) {
         print(e);
-        print('likely digitalProductId is null wait till https://github.com/fluttercommunity/plus_plugins/pull/3188 is merged');
+        print(
+            'likely digitalProductId is null wait till https://github.com/fluttercommunity/plus_plugins/pull/3188 is merged');
         deviceName = "Windows Device";
       }
     }
diff --git a/lib/view_model/dashboard/balance_view_model.dart b/lib/view_model/dashboard/balance_view_model.dart
index 56a5935c9..20dca292c 100644
--- a/lib/view_model/dashboard/balance_view_model.dart
+++ b/lib/view_model/dashboard/balance_view_model.dart
@@ -381,7 +381,7 @@ abstract class BalanceViewModelBase with Store {
 
   bool _hasSecondAdditionalBalanceForWalletType(WalletType type) {
     if (wallet.type == WalletType.litecoin) {
-      if ((wallet.balance[CryptoCurrency.ltc]?.secondAdditional ?? 0) > 0) {
+      if ((wallet.balance[CryptoCurrency.ltc]?.secondAdditional ?? 0) != 0) {
         return true;
       }
     }
diff --git a/lib/view_model/dashboard/transaction_list_item.dart b/lib/view_model/dashboard/transaction_list_item.dart
index 47fc32ab6..b218c8e9f 100644
--- a/lib/view_model/dashboard/transaction_list_item.dart
+++ b/lib/view_model/dashboard/transaction_list_item.dart
@@ -56,25 +56,53 @@ class TransactionListItem extends ActionListItem with Keyable {
   }
 
   String get formattedPendingStatus {
-    if (balanceViewModel.wallet.type == WalletType.monero ||
-        balanceViewModel.wallet.type == WalletType.haven) {
-      if (transaction.confirmations >= 0 && transaction.confirmations < 10) {
-        return ' (${transaction.confirmations}/10)';
-      }
-    } else if (balanceViewModel.wallet.type == WalletType.wownero) {
-      if (transaction.confirmations >= 0 && transaction.confirmations < 3) {
-        return ' (${transaction.confirmations}/3)';
-      }
+    switch (balanceViewModel.wallet.type) {
+      case WalletType.monero:
+      case WalletType.haven:
+        if (transaction.confirmations >= 0 && transaction.confirmations < 10) {
+          return ' (${transaction.confirmations}/10)';
+        }
+        break;
+      case WalletType.wownero:
+        if (transaction.confirmations >= 0 && transaction.confirmations < 3) {
+          return ' (${transaction.confirmations}/3)';
+        }
+        break;
+      case WalletType.litecoin:
+        bool isPegIn = (transaction.additionalInfo["isPegIn"] as bool?) ?? false;
+        bool isPegOut = (transaction.additionalInfo["isPegOut"] as bool?) ?? false;
+        bool fromPegOut = (transaction.additionalInfo["fromPegOut"] as bool?) ?? false;
+        String str = '';
+        if (transaction.confirmations <= 0) {
+          str = S.current.pending;
+        }
+        if ((isPegOut || fromPegOut) && transaction.confirmations >= 0 && transaction.confirmations < 6) {
+          str = " (${transaction.confirmations}/6)";
+        }
+        if (isPegIn) {
+          str += " (Peg In)";
+        }
+        if (isPegOut) {
+          str += " (Peg Out)";
+        }
+        return str;
+      default:
+        return '';
     }
+
     return '';
   }
 
   String get formattedStatus {
-    if (balanceViewModel.wallet.type == WalletType.monero ||
-        balanceViewModel.wallet.type == WalletType.wownero ||
-        balanceViewModel.wallet.type == WalletType.haven) {
+    if ([
+      WalletType.monero,
+      WalletType.haven,
+      WalletType.wownero,
+      WalletType.litecoin,
+    ].contains(balanceViewModel.wallet.type)) {
       return formattedPendingStatus;
     }
+
     return transaction.isPending ? S.current.pending : '';
   }
 
diff --git a/lib/view_model/settings/mweb_settings_view_model.dart b/lib/view_model/settings/mweb_settings_view_model.dart
index c6370e23f..11e4c8177 100644
--- a/lib/view_model/settings/mweb_settings_view_model.dart
+++ b/lib/view_model/settings/mweb_settings_view_model.dart
@@ -1,7 +1,12 @@
+import 'dart:io';
+
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
 import 'package:cake_wallet/store/settings_store.dart';
+import 'package:cake_wallet/utils/exception_handler.dart';
 import 'package:cw_core/wallet_base.dart';
+import 'package:flutter/widgets.dart';
 import 'package:mobx/mobx.dart';
+import 'package:path_provider/path_provider.dart';
 
 part 'mweb_settings_view_model.g.dart';
 
@@ -22,15 +27,60 @@ abstract class MwebSettingsViewModelBase with Store {
   @observable
   late bool mwebEnabled;
 
+  @computed
+  String get mwebNodeUri => _settingsStore.mwebNodeUri;
+
   @action
   void setMwebCardDisplay(bool value) {
     _settingsStore.mwebCardDisplay = value;
   }
 
+  @action
+  void setMwebNodeUri(String value) {
+    _settingsStore.mwebNodeUri = value;
+  }
+
   @action
   void setMwebEnabled(bool value) {
     mwebEnabled = value;
     bitcoin!.setMwebEnabled(_wallet, value);
     _settingsStore.mwebAlwaysScan = value;
   }
+
+  Future<bool> saveLogsLocally(String filePath) async {
+    try {
+      final appSupportPath = (await getApplicationSupportDirectory()).path;
+      final logsFile = File("$appSupportPath/logs/debug.log");
+      if (!logsFile.existsSync()) {
+        throw Exception('Logs file does not exist');
+      }
+      await logsFile.copy(filePath);
+      return true;
+    } catch (e, s) {
+      ExceptionHandler.onError(FlutterErrorDetails(
+        exception: e,
+        stack: s,
+        library: "Export Logs",
+      ));
+      return false;
+    }
+  }
+
+  Future<String> getAbbreviatedLogs() async {
+    final appSupportPath = (await getApplicationSupportDirectory()).path;
+    final logsFile = File("$appSupportPath/logs/debug.log");
+    if (!logsFile.existsSync()) {
+      return "";
+    }
+    final logs = logsFile.readAsStringSync();
+    // return last 10000 characters:
+    return logs.substring(logs.length > 10000 ? logs.length - 10000 : 0);
+  }
+
+  Future<void> removeLogsLocally(String filePath) async {
+    final logsFile = File(filePath);
+    if (logsFile.existsSync()) {
+      await logsFile.delete();
+    }
+  }
 }
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index d5fce76e9..2abd8401a 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -134,7 +134,7 @@ dependency_overrides:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v8
+      ref: cake-update-v9
   ffi: 2.1.0
 
 flutter_icons:
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index c2be1504a..0db2031dd 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -295,6 +295,7 @@
   "expiresOn": "ﻲﻓ ﻪﺘﻴﺣﻼﺻ ﻲﻬﺘﻨﺗ",
   "expiry_and_validity": "انتهاء الصلاحية والصلاحية",
   "export_backup": "تصدير نسخة احتياطية",
+  "export_logs": "سجلات التصدير",
   "extra_id": "معرف إضافي:",
   "extracted_address_content": "سوف ترسل الأموال إلى\n${recipient_name}",
   "failed_authentication": "${state_error} فشل المصادقة.",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB هو بروتوكول جديد يجلب معاملات أسرع وأرخص وأكثر خصوصية إلى Litecoin",
   "litecoin_mweb_dismiss": "رفض",
   "litecoin_mweb_display_card": "عرض بطاقة mweb",
+  "litecoin_mweb_enable": "تمكين MWEB",
   "litecoin_mweb_enable_later": "يمكنك اختيار تمكين MWEB مرة أخرى ضمن إعدادات العرض.",
+  "litecoin_mweb_logs": "سجلات MWEB",
+  "litecoin_mweb_node": "عقدة MWEB",
   "litecoin_mweb_pegin": "ربط في",
   "litecoin_mweb_pegout": "ربط",
   "litecoin_mweb_scanning": "MWEB المسح الضوئي",
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index 8b68d0d1e..7e78dd69a 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Изтича на",
   "expiry_and_validity": "Изтичане и валидност",
   "export_backup": "Експортиране на резервно копие",
+  "export_logs": "Експортни дневници",
   "extra_id": "Допълнително ID:",
   "extracted_address_content": "Ще изпратите средства на \n${recipient_name}",
   "failed_authentication": "Неуспешно удостоверяване. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWeb е нов протокол, който носи по -бърз, по -евтин и повече частни транзакции на Litecoin",
   "litecoin_mweb_dismiss": "Уволнение",
   "litecoin_mweb_display_card": "Показване на MWEB карта",
+  "litecoin_mweb_enable": "Активирайте MWeb",
   "litecoin_mweb_enable_later": "Можете да изберете да активирате MWEB отново под настройките на дисплея.",
+  "litecoin_mweb_logs": "MWeb logs",
+  "litecoin_mweb_node": "MWEB възел",
   "litecoin_mweb_pegin": "PEG в",
   "litecoin_mweb_pegout": "PEG OUT",
   "litecoin_mweb_scanning": "Сканиране на MWEB",
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index 9b48ebdc7..f17466a9f 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Vyprší dne",
   "expiry_and_validity": "Vypršení a platnost",
   "export_backup": "Exportovat zálohu",
+  "export_logs": "Vývozní protokoly",
   "extra_id": "Extra ID:",
   "extracted_address_content": "Prostředky budete posílat na\n${recipient_name}",
   "failed_authentication": "Ověřování selhalo. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB je nový protokol, který do Litecoin přináší rychlejší, levnější a více soukromých transakcí",
   "litecoin_mweb_dismiss": "Propustit",
   "litecoin_mweb_display_card": "Zobrazit kartu MWeb",
+  "litecoin_mweb_enable": "Povolit mWeb",
   "litecoin_mweb_enable_later": "V nastavení zobrazení můžete vybrat znovu povolit MWeb.",
+  "litecoin_mweb_logs": "Protokoly mWeb",
+  "litecoin_mweb_node": "Uzel mWeb",
   "litecoin_mweb_pegin": "Peg in",
   "litecoin_mweb_pegout": "Zkrachovat",
   "litecoin_mweb_scanning": "Skenování mWeb",
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 2ec59f349..cb0a59574 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Läuft aus am",
   "expiry_and_validity": "Ablauf und Gültigkeit",
   "export_backup": "Sicherung exportieren",
+  "export_logs": "Exportprotokolle",
   "extra_id": "Extra ID:",
   "extracted_address_content": "Sie senden Geld an\n${recipient_name}",
   "failed_authentication": "Authentifizierung fehlgeschlagen. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWWB ist ein neues Protokoll, das schnellere, billigere und privatere Transaktionen zu Litecoin bringt",
   "litecoin_mweb_dismiss": "Zurückweisen",
   "litecoin_mweb_display_card": "MWEB-Karte anzeigen",
+  "litecoin_mweb_enable": "Aktivieren Sie MWeb",
   "litecoin_mweb_enable_later": "Sie können MWEB unter Anzeigeeinstellungen erneut aktivieren.",
+  "litecoin_mweb_logs": "MWEB -Protokolle",
+  "litecoin_mweb_node": "MWEB -Knoten",
   "litecoin_mweb_pegin": "Peg in",
   "litecoin_mweb_pegout": "Abstecken",
   "litecoin_mweb_scanning": "MWEB Scanning",
@@ -941,4 +945,4 @@
   "you_will_get": "Konvertieren zu",
   "you_will_send": "Konvertieren von",
   "yy": "YY"
-}
+}
\ No newline at end of file
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 4f5fd23b3..40be8fd08 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Expires on",
   "expiry_and_validity": "Expiry and Validity",
   "export_backup": "Export backup",
+  "export_logs": "Export logs",
   "extra_id": "Extra ID:",
   "extracted_address_content": "You will be sending funds to\n${recipient_name}",
   "failed_authentication": "Failed authentication. ${state_error}",
@@ -373,7 +374,10 @@
   "litecoin_mweb_description": "MWEB is a new protocol that brings faster, cheaper, and more private transactions to Litecoin",
   "litecoin_mweb_dismiss": "Dismiss",
   "litecoin_mweb_display_card": "Show MWEB card",
+  "litecoin_mweb_enable": "Enable MWEB",
   "litecoin_mweb_enable_later": "You can choose to enable MWEB again under Display Settings.",
+  "litecoin_mweb_logs": "MWEB Logs",
+  "litecoin_mweb_node": "MWEB Node",
   "litecoin_mweb_pegin": "Peg In",
   "litecoin_mweb_pegout": "Peg Out",
   "litecoin_mweb_scanning": "MWEB Scanning",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index fd20a8b30..5a693cf32 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Expira el",
   "expiry_and_validity": "Vencimiento y validez",
   "export_backup": "Exportar copia de seguridad",
+  "export_logs": "Registros de exportación",
   "extra_id": "ID adicional:",
   "extracted_address_content": "Enviará fondos a\n${recipient_name}",
   "failed_authentication": "Autenticación fallida. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "Mweb es un nuevo protocolo que trae transacciones más rápidas, más baratas y más privadas a Litecoin",
   "litecoin_mweb_dismiss": "Despedir",
   "litecoin_mweb_display_card": "Mostrar tarjeta MWEB",
+  "litecoin_mweb_enable": "Habilitar mweb",
   "litecoin_mweb_enable_later": "Puede elegir habilitar MWEB nuevamente en la configuración de visualización.",
+  "litecoin_mweb_logs": "Registros de mweb",
+  "litecoin_mweb_node": "Nodo mweb",
   "litecoin_mweb_pegin": "Convertir",
   "litecoin_mweb_pegout": "Recuperar",
   "litecoin_mweb_scanning": "Escaneo mweb",
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index 50aceb2f1..1865e41f2 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Expire le",
   "expiry_and_validity": "Expiration et validité",
   "export_backup": "Exporter la sauvegarde",
+  "export_logs": "Journaux d'exportation",
   "extra_id": "ID supplémentaire :",
   "extracted_address_content": "Vous allez envoyer des fonds à\n${recipient_name}",
   "failed_authentication": "Échec d'authentification. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB est un nouveau protocole qui apporte des transactions plus rapides, moins chères et plus privées à Litecoin",
   "litecoin_mweb_dismiss": "Rejeter",
   "litecoin_mweb_display_card": "Afficher la carte MWeb",
+  "litecoin_mweb_enable": "Activer Mweb",
   "litecoin_mweb_enable_later": "Vous pouvez choisir d'activer à nouveau MWEB sous Paramètres d'affichage.",
+  "litecoin_mweb_logs": "Journaux MWEB",
+  "litecoin_mweb_node": "Node MWEB",
   "litecoin_mweb_pegin": "Entraver",
   "litecoin_mweb_pegout": "Crever",
   "litecoin_mweb_scanning": "Scann mweb",
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index e66859531..52cf14128 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Yana ƙarewa",
   "expiry_and_validity": "Karewa da inganci",
   "export_backup": "Ajiyayyen fitarwa",
+  "export_logs": "Injin fitarwa",
   "extra_id": "Karin ID:",
   "extracted_address_content": "Za ku aika da kudade zuwa\n${recipient_name}",
   "failed_authentication": "Binne wajen shiga. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "Mweb shine sabon tsarin yarjejeniya da ya kawo da sauri, mai rahusa, da kuma ma'amaloli masu zaman kansu zuwa Litecoin",
   "litecoin_mweb_dismiss": "Tuɓe \\ sallama",
   "litecoin_mweb_display_card": "Nuna katin Mweb",
+  "litecoin_mweb_enable": "Kunna Mweb",
   "litecoin_mweb_enable_later": "Kuna iya zaɓar kunna Mweb kuma a ƙarƙashin saitunan nuni.",
+  "litecoin_mweb_logs": "Jagoran Mweb",
+  "litecoin_mweb_node": "Mweb Node",
   "litecoin_mweb_pegin": "Peg in",
   "litecoin_mweb_pegout": "Peg fita",
   "litecoin_mweb_scanning": "Mweb scanning",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index bc8b81211..64f112a42 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -295,6 +295,7 @@
   "expiresOn": "पर समय सीमा समाप्त",
   "expiry_and_validity": "समाप्ति और वैधता",
   "export_backup": "निर्यात बैकअप",
+  "export_logs": "निर्यात लॉग",
   "extra_id": "अतिरिक्त आईडी:",
   "extracted_address_content": "आपको धनराशि भेजी जाएगी\n${recipient_name}",
   "failed_authentication": "प्रमाणीकरण विफल. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB एक नया प्रोटोकॉल है जो लिटकोइन के लिए तेजी से, सस्ता और अधिक निजी लेनदेन लाता है",
   "litecoin_mweb_dismiss": "नकार देना",
   "litecoin_mweb_display_card": "MWEB कार्ड दिखाएं",
+  "litecoin_mweb_enable": "MWEB सक्षम करें",
   "litecoin_mweb_enable_later": "आप प्रदर्शन सेटिंग्स के तहत फिर से MWEB को सक्षम करने के लिए चुन सकते हैं।",
+  "litecoin_mweb_logs": "MWEB लॉग",
+  "litecoin_mweb_node": "MWEB नोड",
   "litecoin_mweb_pegin": "खूंटी",
   "litecoin_mweb_pegout": "मरना",
   "litecoin_mweb_scanning": "MWEB स्कैनिंग",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 9ff57707d..4bbf4f141 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Istječe",
   "expiry_and_validity": "Istek i valjanost",
   "export_backup": "Izvezi sigurnosnu kopiju",
+  "export_logs": "Izvozni trupci",
   "extra_id": "Dodatni ID:",
   "extracted_address_content": "Poslat ćete sredstva primatelju\n${recipient_name}",
   "failed_authentication": "Autentifikacija neuspješna. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB je novi protokol koji u Litecoin donosi brže, jeftinije i privatnije transakcije",
   "litecoin_mweb_dismiss": "Odbaciti",
   "litecoin_mweb_display_card": "Prikaži MWeb karticu",
+  "litecoin_mweb_enable": "Omogući MWeb",
   "litecoin_mweb_enable_later": "Možete odabrati da MWEB ponovo omogućite pod postavkama zaslona.",
+  "litecoin_mweb_logs": "MWEB trupci",
+  "litecoin_mweb_node": "MWEB čvor",
   "litecoin_mweb_pegin": "Uvući se",
   "litecoin_mweb_pegout": "Odapeti",
   "litecoin_mweb_scanning": "MWEB skeniranje",
diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb
index 40ed1e116..cbaf3a548 100644
--- a/res/values/strings_hy.arb
+++ b/res/values/strings_hy.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Վավերականությունը լրանում է",
   "expiry_and_validity": "Վավերականություն և լրացում",
   "export_backup": "Արտահանել կրկնօրինակը",
+  "export_logs": "Արտահանման տեղեկամատյաններ",
   "extra_id": "Լրացուցիչ ID",
   "extracted_address_content": "Դուք կուղարկեք գումար ${recipient_name}",
   "failed_authentication": "Վավերացումը ձախողվեց. ${state_error}",
@@ -367,7 +368,10 @@
   "light_theme": "Լուսավոր",
   "litecoin_mweb_description": "Mweb- ը նոր արձանագրություն է, որը բերում է ավելի արագ, ավելի էժան եւ ավելի մասնավոր գործարքներ դեպի LITECOIN",
   "litecoin_mweb_dismiss": "Հեռացնել",
+  "litecoin_mweb_enable": "Միացնել Mweb- ը",
   "litecoin_mweb_enable_later": "Կարող եք ընտրել Mweb- ը կրկին միացնել ցուցադրման պարամետրերը:",
+  "litecoin_mweb_logs": "Mweb տեղեկամատյաններ",
+  "litecoin_mweb_node": "Mweb հանգույց",
   "litecoin_mweb_pegin": "Peg in",
   "litecoin_mweb_pegout": "Հափշտակել",
   "live_fee_rates": "Ապակի վարձավճարներ API- ի միջոցով",
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index 2858fa193..273087eec 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Kadaluarsa pada",
   "expiry_and_validity": "Kedaluwarsa dan validitas",
   "export_backup": "Ekspor cadangan",
+  "export_logs": "Log ekspor",
   "extra_id": "ID tambahan:",
   "extracted_address_content": "Anda akan mengirim dana ke\n${recipient_name}",
   "failed_authentication": "Otentikasi gagal. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB adalah protokol baru yang membawa transaksi yang lebih cepat, lebih murah, dan lebih pribadi ke Litecoin",
   "litecoin_mweb_dismiss": "Membubarkan",
   "litecoin_mweb_display_card": "Tunjukkan kartu mWeb",
+  "litecoin_mweb_enable": "Aktifkan MWEB",
   "litecoin_mweb_enable_later": "Anda dapat memilih untuk mengaktifkan MWEB lagi di bawah pengaturan tampilan.",
+  "litecoin_mweb_logs": "Log MWeb",
+  "litecoin_mweb_node": "Node MWEB",
   "litecoin_mweb_pegin": "Pasak masuk",
   "litecoin_mweb_pegout": "Mati",
   "litecoin_mweb_scanning": "Pemindaian MWEB",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index 034376a6c..917315aa6 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -296,6 +296,7 @@
   "expiresOn": "Scade il",
   "expiry_and_validity": "Scadenza e validità",
   "export_backup": "Esporta backup",
+  "export_logs": "Registri di esportazione",
   "extra_id": "Extra ID:",
   "extracted_address_content": "Invierai i tuoi fondi a\n${recipient_name}",
   "failed_authentication": "Autenticazione fallita. ${state_error}",
@@ -372,7 +373,10 @@
   "litecoin_mweb_description": "MWeb è un nuovo protocollo che porta transazioni più veloci, più economiche e più private a Litecoin",
   "litecoin_mweb_dismiss": "Congedare",
   "litecoin_mweb_display_card": "Mostra la scheda MWeb",
+  "litecoin_mweb_enable": "Abilita mWeb",
   "litecoin_mweb_enable_later": "È possibile scegliere di abilitare nuovamente MWeb nelle impostazioni di visualizzazione.",
+  "litecoin_mweb_logs": "Registri mWeb",
+  "litecoin_mweb_node": "Nodo MWeb",
   "litecoin_mweb_pegin": "Piolo in",
   "litecoin_mweb_pegout": "PEG OUT",
   "litecoin_mweb_scanning": "Scansione MWeb",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index 7f0792063..ae3e32ea8 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -295,6 +295,7 @@
   "expiresOn": "有効期限は次のとおりです",
   "expiry_and_validity": "有効期限と有効性",
   "export_backup": "バックアップのエクスポート",
+  "export_logs": "ログをエクスポートします",
   "extra_id": "追加ID:",
   "extracted_address_content": "に送金します\n${recipient_name}",
   "failed_authentication": "認証失敗. ${state_error}",
@@ -372,7 +373,10 @@
   "litecoin_mweb_description": "MWEBは、Litecoinにより速く、より安価で、よりプライベートなトランザクションをもたらす新しいプロトコルです",
   "litecoin_mweb_dismiss": "却下する",
   "litecoin_mweb_display_card": "MWEBカードを表示します",
+  "litecoin_mweb_enable": "MWEBを有効にします",
   "litecoin_mweb_enable_later": "表示設定の下で、MWEBを再度有効にすることを選択できます。",
+  "litecoin_mweb_logs": "MWEBログ",
+  "litecoin_mweb_node": "MWEBノード",
   "litecoin_mweb_pegin": "ペグイン",
   "litecoin_mweb_pegout": "ペグアウト",
   "litecoin_mweb_scanning": "MWEBスキャン",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 6ba402ce3..2dc1a2dfc 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -295,6 +295,7 @@
   "expiresOn": "만료 날짜",
   "expiry_and_validity": "만료와 타당성",
   "export_backup": "백업 내보내기",
+  "export_logs": "내보내기 로그",
   "extra_id": "추가 ID:",
   "extracted_address_content": "당신은에 자금을 보낼 것입니다\n${recipient_name}",
   "failed_authentication": "인증 실패. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB는 Litecoin에 더 빠르고 저렴하며 개인 거래를 제공하는 새로운 프로토콜입니다.",
   "litecoin_mweb_dismiss": "해고하다",
   "litecoin_mweb_display_card": "mweb 카드를 보여주십시오",
+  "litecoin_mweb_enable": "mweb 활성화",
   "litecoin_mweb_enable_later": "디스플레이 설정에서 MWEB를 다시 활성화하도록 선택할 수 있습니다.",
+  "litecoin_mweb_logs": "mweb 로그",
+  "litecoin_mweb_node": "mweb 노드",
   "litecoin_mweb_pegin": "페그를 입력하십시오",
   "litecoin_mweb_pegout": "죽다",
   "litecoin_mweb_scanning": "mweb 스캔",
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index 69b888b5a..f42af6863 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -295,6 +295,7 @@
   "expiresOn": "သက်တမ်းကုန်သည်။",
   "expiry_and_validity": "သက်တမ်းကုန်ဆုံးခြင်းနှင့်တရားဝင်မှု",
   "export_backup": "အရန်ကူးထုတ်ရန်",
+  "export_logs": "ပို့ကုန်မှတ်တမ်းများ",
   "extra_id": "အပို ID-",
   "extracted_address_content": "သင်သည် \n${recipient_name} သို့ ရန်ပုံငွေများ ပေးပို့ပါမည်",
   "failed_authentication": "အထောက်အထားစိစစ်ခြင်း မအောင်မြင်ပါ။. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "Mweb သည် Protocol အသစ်ဖြစ်ပြီး LitCoin သို့ပိုမိုဈေးချိုသာသော, စျေးသက်သက်သာသာသုံးခြင်းနှင့်ပိုမိုများပြားသောပုဂ္ဂလိကငွေပို့ဆောင်မှုများကိုဖြစ်ပေါ်စေသည်",
   "litecoin_mweb_dismiss": "ထုတ်ပစ်",
   "litecoin_mweb_display_card": "MweB ကဒ်ကိုပြပါ",
+  "litecoin_mweb_enable": "mweb enable",
   "litecoin_mweb_enable_later": "သင် MweB ကို display settings အောက်ရှိ ထပ်မံ. ခွင့်ပြုရန်ရွေးချယ်နိုင်သည်။",
+  "litecoin_mweb_logs": "Mweb မှတ်တမ်းများ",
+  "litecoin_mweb_node": "mweb node ကို",
   "litecoin_mweb_pegin": "တံစို့",
   "litecoin_mweb_pegout": "တံစို့",
   "litecoin_mweb_scanning": "mweb scanning",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index 2c259bf80..73e3df6b6 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Verloopt op",
   "expiry_and_validity": "Vervallen en geldigheid",
   "export_backup": "Back-up exporteren",
+  "export_logs": "Exporteer logboeken",
   "extra_id": "Extra ID:",
   "extracted_address_content": "U stuurt geld naar\n${recipient_name}",
   "failed_authentication": "Mislukte authenticatie. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB is een nieuw protocol dat snellere, goedkopere en meer privé -transacties naar Litecoin brengt",
   "litecoin_mweb_dismiss": "Afwijzen",
   "litecoin_mweb_display_card": "Toon MWEB -kaart",
+  "litecoin_mweb_enable": "MWEB inschakelen",
   "litecoin_mweb_enable_later": "U kunt ervoor kiezen om MWeb opnieuw in te schakelen onder weergave -instellingen.",
+  "litecoin_mweb_logs": "MWEB -logboeken",
+  "litecoin_mweb_node": "MWEB -knooppunt",
   "litecoin_mweb_pegin": "Vastmaken",
   "litecoin_mweb_pegout": "Uithakken",
   "litecoin_mweb_scanning": "MWEB -scanning",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 936339708..aaa82a3bf 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Upływa w dniu",
   "expiry_and_validity": "Wygaśnięcie i ważność",
   "export_backup": "Eksportuj kopię zapasową",
+  "export_logs": "Dzienniki eksportu",
   "extra_id": "Dodatkowy ID:",
   "extracted_address_content": "Wysyłasz środki na\n${recipient_name}",
   "failed_authentication": "Nieudane uwierzytelnienie. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB to nowy protokół, który przynosi szybciej, tańsze i bardziej prywatne transakcje do Litecoin",
   "litecoin_mweb_dismiss": "Odrzucać",
   "litecoin_mweb_display_card": "Pokaż kartę MWEB",
+  "litecoin_mweb_enable": "Włącz MWEB",
   "litecoin_mweb_enable_later": "Możesz ponownie włączyć MWEB w ustawieniach wyświetlania.",
+  "litecoin_mweb_logs": "Dzienniki MWEB",
+  "litecoin_mweb_node": "Węzeł MWEB",
   "litecoin_mweb_pegin": "Kołek",
   "litecoin_mweb_pegout": "Palikować",
   "litecoin_mweb_scanning": "Skanowanie MWEB",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 0cc0cc00a..194307a3d 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Expira em",
   "expiry_and_validity": "Expiração e validade",
   "export_backup": "Backup de exportação",
+  "export_logs": "Exportar logs",
   "extra_id": "ID extra:",
   "extracted_address_content": "Você enviará fundos para\n${recipient_name}",
   "failed_authentication": "Falha na autenticação. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB é um novo protocolo que traz transações mais rápidas, baratas e mais privadas para o Litecoin",
   "litecoin_mweb_dismiss": "Liberar",
   "litecoin_mweb_display_card": "Mostre o cartão MWEB",
+  "litecoin_mweb_enable": "Ativar Mweb",
   "litecoin_mweb_enable_later": "Você pode optar por ativar o MWEB novamente em Configurações de exibição.",
+  "litecoin_mweb_logs": "Logs MWeb",
+  "litecoin_mweb_node": "Nó MWeb",
   "litecoin_mweb_pegin": "Peg in",
   "litecoin_mweb_pegout": "Peg fora",
   "litecoin_mweb_scanning": "MWEB Scanning",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index 8aeb56a86..f42c28c15 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Годен до",
   "expiry_and_validity": "Истечение и достоверность",
   "export_backup": "Экспорт резервной копии",
+  "export_logs": "Экспортные журналы",
   "extra_id": "Дополнительный ID:",
   "extracted_address_content": "Вы будете отправлять средства\n${recipient_name}",
   "failed_authentication": "Ошибка аутентификации. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB - это новый протокол, который приносит быстрее, дешевле и более частные транзакции в Litecoin",
   "litecoin_mweb_dismiss": "Увольнять",
   "litecoin_mweb_display_card": "Показать карту MWEB",
+  "litecoin_mweb_enable": "Включить MWEB",
   "litecoin_mweb_enable_later": "Вы можете снова включить MWEB в настройках отображения.",
+  "litecoin_mweb_logs": "MWEB журналы",
+  "litecoin_mweb_node": "Узел MWEB",
   "litecoin_mweb_pegin": "Внедрять",
   "litecoin_mweb_pegout": "Выкрикивать",
   "litecoin_mweb_scanning": "MWEB сканирование",
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index 736eb8762..9d8fb0af2 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -295,6 +295,7 @@
   "expiresOn": "หมดอายุวันที่",
   "expiry_and_validity": "หมดอายุและถูกต้อง",
   "export_backup": "ส่งออกข้อมูลสำรอง",
+  "export_logs": "บันทึกการส่งออก",
   "extra_id": "ไอดีเพิ่มเติม:",
   "extracted_address_content": "คุณกำลังจะส่งเงินไปยัง\n${recipient_name}",
   "failed_authentication": "การยืนยันสิทธิ์ล้มเหลว ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB เป็นโปรโตคอลใหม่ที่นำการทำธุรกรรมที่เร็วกว่าราคาถูกกว่าและเป็นส่วนตัวมากขึ้นไปยัง Litecoin",
   "litecoin_mweb_dismiss": "อนุญาตให้ออกไป",
   "litecoin_mweb_display_card": "แสดงการ์ด mweb",
+  "litecoin_mweb_enable": "เปิดใช้งาน mweb",
   "litecoin_mweb_enable_later": "คุณสามารถเลือกเปิดใช้งาน MWEB อีกครั้งภายใต้การตั้งค่าการแสดงผล",
+  "litecoin_mweb_logs": "บันทึก MWEB",
+  "litecoin_mweb_node": "โหนด MWEB",
   "litecoin_mweb_pegin": "หมุด",
   "litecoin_mweb_pegout": "ตรึง",
   "litecoin_mweb_scanning": "การสแกน MWEB",
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index e68bd0b22..ca35e7997 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Mag-e-expire sa",
   "expiry_and_validity": "Pag-expire at Bisa",
   "export_backup": "I-export ang backup",
+  "export_logs": "Mga log ng pag -export",
   "extra_id": "Dagdag na ID:",
   "extracted_address_content": "Magpapadala ka ng pondo sa\n${recipient_name}",
   "failed_authentication": "Nabigo ang pagpapatunay. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "Ang MWeb ay isang bagong protocol na nagdadala ng mas mabilis, mas mura, at mas maraming pribadong mga transaksyon sa Litecoin",
   "litecoin_mweb_dismiss": "Tanggalin",
   "litecoin_mweb_display_card": "Ipakita ang MWEB Card",
+  "litecoin_mweb_enable": "Paganahin ang MWeb",
   "litecoin_mweb_enable_later": "Maaari kang pumili upang paganahin muli ang MWeb sa ilalim ng mga setting ng pagpapakita.",
+  "litecoin_mweb_logs": "MWEB log",
+  "litecoin_mweb_node": "Mweb node",
   "litecoin_mweb_pegin": "Peg in",
   "litecoin_mweb_pegout": "Peg out",
   "litecoin_mweb_scanning": "Pag -scan ng Mweb",
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index 83e8f6cbc..1fee66369 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Tarihinde sona eriyor",
   "expiry_and_validity": "Sona erme ve geçerlilik",
   "export_backup": "Yedeği dışa aktar",
+  "export_logs": "Dışa aktarma günlükleri",
   "extra_id": "Ekstra ID:",
   "extracted_address_content": "Parayı buraya gönderceksin:\n${recipient_name}",
   "failed_authentication": "Doğrulama başarısız oldu. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB, Litecoin'e daha hızlı, daha ucuz ve daha fazla özel işlem getiren yeni bir protokoldür",
   "litecoin_mweb_dismiss": "Azletmek",
   "litecoin_mweb_display_card": "MWEB kartını göster",
+  "litecoin_mweb_enable": "MWEB'i etkinleştir",
   "litecoin_mweb_enable_later": "Ekran ayarlarının altında MWEB'yi tekrar etkinleştirmeyi seçebilirsiniz.",
+  "litecoin_mweb_logs": "MWEB günlükleri",
+  "litecoin_mweb_node": "MWEB düğümü",
   "litecoin_mweb_pegin": "Takılmak",
   "litecoin_mweb_pegout": "Çiğnemek",
   "litecoin_mweb_scanning": "MWEB taraması",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 909d9c01f..5d9a56c1e 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -295,6 +295,7 @@
   "expiresOn": "Термін дії закінчується",
   "expiry_and_validity": "Закінчення та обгрунтованість",
   "export_backup": "Експортувати резервну копію",
+  "export_logs": "Експортні журнали",
   "extra_id": "Додатковий ID:",
   "extracted_address_content": "Ви будете відправляти кошти\n${recipient_name}",
   "failed_authentication": "Помилка аутентифікації. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB - це новий протокол, який приносить швидкі, дешевші та більш приватні транзакції Litecoin",
   "litecoin_mweb_dismiss": "Звільнити",
   "litecoin_mweb_display_card": "Показати карту MWeb",
+  "litecoin_mweb_enable": "Увімкнути mweb",
   "litecoin_mweb_enable_later": "Ви можете знову ввімкнути MWEB в налаштуваннях дисплея.",
+  "litecoin_mweb_logs": "Журнали MWeb",
+  "litecoin_mweb_node": "Вузол MWeb",
   "litecoin_mweb_pegin": "Подякувати",
   "litecoin_mweb_pegout": "Подякувати",
   "litecoin_mweb_scanning": "Сканування Mweb",
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index 2dbc97102..106f00f96 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -295,6 +295,7 @@
   "expiresOn": "ﺩﺎﻌﯿﻣ ﯽﻣﺎﺘﺘﺧﺍ",
   "expiry_and_validity": "میعاد ختم اور صداقت",
   "export_backup": "بیک اپ برآمد کریں۔",
+  "export_logs": "نوشتہ جات برآمد کریں",
   "extra_id": "اضافی ID:",
   "extracted_address_content": "آپ فنڈز بھیج رہے ہوں گے\n${recipient_name}",
   "failed_authentication": "ناکام تصدیق۔ ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB ایک نیا پروٹوکول ہے جو لیٹیکوئن میں تیز ، سستا اور زیادہ نجی لین دین لاتا ہے",
   "litecoin_mweb_dismiss": "خارج",
   "litecoin_mweb_display_card": "MWEB کارڈ دکھائیں",
+  "litecoin_mweb_enable": "MWEB کو فعال کریں",
   "litecoin_mweb_enable_later": "آپ ڈسپلے کی ترتیبات کے تحت MWEB کو دوبارہ فعال کرنے کا انتخاب کرسکتے ہیں۔",
+  "litecoin_mweb_logs": "MWEB لاگز",
+  "litecoin_mweb_node": "MWEB نوڈ",
   "litecoin_mweb_pegin": "پیگ میں",
   "litecoin_mweb_pegout": "پیگ آؤٹ",
   "litecoin_mweb_scanning": "MWEB اسکیننگ",
diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb
index 8d28d48a2..a95f32aaa 100644
--- a/res/values/strings_vi.arb
+++ b/res/values/strings_vi.arb
@@ -296,6 +296,7 @@
   "expiresOn": "Hết hạn vào",
   "expiry_and_validity": "Hạn và hiệu lực",
   "export_backup": "Xuất sao lưu",
+  "export_logs": "Nhật ký xuất khẩu",
   "extra_id": "ID bổ sung:",
   "extracted_address_content": "Bạn sẽ gửi tiền cho\n${recipient_name}",
   "failed_authentication": "Xác thực không thành công. ${state_error}",
@@ -368,7 +369,10 @@
   "light_theme": "Chủ đề sáng",
   "litecoin_mweb_description": "MWEB là một giao thức mới mang lại các giao dịch nhanh hơn, rẻ hơn và riêng tư hơn cho Litecoin",
   "litecoin_mweb_dismiss": "Miễn nhiệm",
+  "litecoin_mweb_enable": "Bật MWEB",
   "litecoin_mweb_enable_later": "Bạn có thể chọn bật lại MWEB trong cài đặt hiển thị.",
+  "litecoin_mweb_logs": "Nhật ký MWEB",
+  "litecoin_mweb_node": "Nút MWEB",
   "litecoin_mweb_pegin": "Chốt vào",
   "litecoin_mweb_pegout": "Chốt ra",
   "live_fee_rates": "Tỷ lệ phí hiện tại qua API",
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index 03c7c95ef..1a1583da5 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -296,6 +296,7 @@
   "expiresOn": "Ipari lori",
   "expiry_and_validity": "Ipari ati idaniloju",
   "export_backup": "Sún ẹ̀dà nípamọ́ síta",
+  "export_logs": "Wọle si okeere",
   "extra_id": "Àmì ìdánimọ̀ tó fikún:",
   "extracted_address_content": "Ẹ máa máa fi owó ránṣẹ́ sí\n${recipient_name}",
   "failed_authentication": "Ìfẹ̀rílàdí pipòfo. ${state_error}",
@@ -372,7 +373,10 @@
   "litecoin_mweb_description": "Mweb jẹ ilana ilana tuntun ti o mu iyara wa yiyara, din owo, ati awọn iṣowo ikọkọ diẹ sii si Livcoin",
   "litecoin_mweb_dismiss": "Tuka",
   "litecoin_mweb_display_card": "Fihan kaadi Mweb",
+  "litecoin_mweb_enable": "Mu mweb",
   "litecoin_mweb_enable_later": "O le yan lati ṣiṣẹ Mweb lẹẹkansi labẹ awọn eto ifihan.",
+  "litecoin_mweb_logs": "MTweb logs",
+  "litecoin_mweb_node": "Alweb joko",
   "litecoin_mweb_pegin": "Peg in",
   "litecoin_mweb_pegout": "Peg jade",
   "litecoin_mweb_scanning": "Mweb scanning",
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index 5c8d708f4..79fe8faa5 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -295,6 +295,7 @@
   "expiresOn": "到期",
   "expiry_and_validity": "到期和有效性",
   "export_backup": "导出备份",
+  "export_logs": "导出日志",
   "extra_id": "额外ID:",
   "extracted_address_content": "您将汇款至\n${recipient_name}",
   "failed_authentication": "身份验证失败. ${state_error}",
@@ -371,7 +372,10 @@
   "litecoin_mweb_description": "MWEB是一项新协议,它将更快,更便宜和更多的私人交易带给Litecoin",
   "litecoin_mweb_dismiss": "解雇",
   "litecoin_mweb_display_card": "显示MWEB卡",
+  "litecoin_mweb_enable": "启用MWEB",
   "litecoin_mweb_enable_later": "您可以选择在显示设置下再次启用MWEB。",
+  "litecoin_mweb_logs": "MWEB日志",
+  "litecoin_mweb_node": "MWEB节点",
   "litecoin_mweb_pegin": "钉进",
   "litecoin_mweb_pegout": "昏倒",
   "litecoin_mweb_scanning": "MWEB扫描",

From 48457fdd6d3b15beacdbe170117dcbc2cbce25dc Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Thu, 7 Nov 2024 07:50:48 +0200
Subject: [PATCH 03/15] cake pay country picker (#1779)

* cake pay country picker

* UI changes

* hide picker after the country is set

* Revert "hide picker after the country is set"

This reverts commit cce358b94f55c22e0807b4d3641a13ebd299106c.

* show country picker initially

* flags

* minor ui fixes

* Update lib/view_model/cake_pay/cake_pay_cards_list_view_model.dart

---------

Co-authored-by: tuxpizza <tuxsudo@tux.pizza>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 assets/images/flags/abw.png                   | Bin 0 -> 607 bytes
 assets/images/flags/afg.png                   | Bin 0 -> 1848 bytes
 assets/images/flags/ago.png                   | Bin 0 -> 1159 bytes
 assets/images/flags/aia.png                   | Bin 0 -> 1357 bytes
 assets/images/flags/and.png                   | Bin 0 -> 1966 bytes
 assets/images/flags/asm.png                   | Bin 0 -> 503 bytes
 assets/images/flags/atf.png                   | Bin 0 -> 1311 bytes
 assets/images/flags/atg.png                   | Bin 0 -> 963 bytes
 assets/images/flags/aut.png                   | Bin 0 -> 125 bytes
 assets/images/flags/aze.png                   | Bin 0 -> 717 bytes
 assets/images/flags/bel.png                   | Bin 0 -> 127 bytes
 assets/images/flags/bes.png                   | Bin 0 -> 236 bytes
 assets/images/flags/bhr.png                   | Bin 0 -> 567 bytes
 assets/images/flags/blz.png                   | Bin 0 -> 1777 bytes
 assets/images/flags/bmu.png                   | Bin 0 -> 1518 bytes
 assets/images/flags/bol.png                   | Bin 0 -> 668 bytes
 assets/images/flags/brn.png                   | Bin 0 -> 1957 bytes
 assets/images/flags/btn.png                   | Bin 0 -> 4013 bytes
 assets/images/flags/bvt.png                   | Bin 0 -> 147 bytes
 assets/images/flags/bwa.png                   | Bin 0 -> 134 bytes
 assets/images/flags/cck.png                   | Bin 0 -> 1139 bytes
 assets/images/flags/cmr.png                   | Bin 0 -> 402 bytes
 assets/images/flags/cok.png                   | Bin 0 -> 1416 bytes
 assets/images/flags/cpv.png                   | Bin 0 -> 297 bytes
 assets/images/flags/cri.png                   | Bin 0 -> 136 bytes
 assets/images/flags/cuw.png                   | Bin 0 -> 481 bytes
 assets/images/flags/cxr.png                   | Bin 0 -> 1202 bytes
 assets/images/flags/cyp.png                   | Bin 0 -> 1128 bytes
 assets/images/flags/dji.png                   | Bin 0 -> 387 bytes
 assets/images/flags/dma.png                   | Bin 0 -> 1224 bytes
 assets/images/flags/dza.png                   | Bin 0 -> 518 bytes
 assets/images/flags/ecu.png                   | Bin 0 -> 1238 bytes
 assets/images/flags/est.png                   | Bin 0 -> 130 bytes
 assets/images/flags/eth.png                   | Bin 0 -> 1584 bytes
 assets/images/flags/fin.png                   | Bin 0 -> 131 bytes
 assets/images/flags/fji.png                   | Bin 0 -> 1571 bytes
 assets/images/flags/flk.png                   | Bin 0 -> 1591 bytes
 assets/images/flags/fro.png                   | Bin 0 -> 147 bytes
 assets/images/flags/fsm.png                   | Bin 0 -> 340 bytes
 assets/images/flags/gab.png                   | Bin 0 -> 130 bytes
 assets/images/flags/geo.png                   | Bin 0 -> 187 bytes
 assets/images/flags/ggi.png                   | Bin 0 -> 892 bytes
 assets/images/flags/ggy.png                   | Bin 0 -> 192 bytes
 assets/images/flags/glp.png                   | Bin 0 -> 1820 bytes
 assets/images/flags/gmb.png                   | Bin 0 -> 278 bytes
 assets/images/flags/grc.png                   | Bin 0 -> 436 bytes
 assets/images/flags/grd.png                   | Bin 0 -> 892 bytes
 assets/images/flags/grl.png                   | Bin 0 -> 407 bytes
 assets/images/flags/guf.png                   | Bin 0 -> 581 bytes
 assets/images/flags/gum.png                   | Bin 0 -> 1259 bytes
 assets/images/flags/guy.png                   | Bin 0 -> 635 bytes
 assets/images/flags/hmd.png                   | Bin 0 -> 780 bytes
 assets/images/flags/iot.png                   | Bin 0 -> 2415 bytes
 assets/images/flags/irl.png                   | Bin 0 -> 127 bytes
 assets/images/flags/jam.png                   | Bin 0 -> 526 bytes
 assets/images/flags/jey.png                   | Bin 0 -> 914 bytes
 assets/images/flags/jor.png                   | Bin 0 -> 3131 bytes
 assets/images/flags/kaz.png                   | Bin 0 -> 1740 bytes
 assets/images/flags/ken.png                   | Bin 0 -> 2074 bytes
 assets/images/flags/kir.png                   | Bin 0 -> 2113 bytes
 assets/images/flags/kwt.png                   | Bin 0 -> 372 bytes
 assets/images/flags/lbn.png                   | Bin 0 -> 960 bytes
 assets/images/flags/lie.png                   | Bin 0 -> 844 bytes
 assets/images/flags/lka.png                   | Bin 0 -> 1757 bytes
 assets/images/flags/ltu.png                   | Bin 0 -> 130 bytes
 assets/images/flags/lux.png                   | Bin 0 -> 130 bytes
 assets/images/flags/lva.png                   | Bin 0 -> 124 bytes
 assets/images/flags/mco.png                   | Bin 0 -> 204 bytes
 assets/images/flags/mlt.png                   | Bin 0 -> 485 bytes
 assets/images/flags/mnp.png                   | Bin 0 -> 2078 bytes
 assets/images/flags/mrt.png                   | Bin 0 -> 509 bytes
 assets/images/flags/msr.png                   | Bin 0 -> 1502 bytes
 assets/images/flags/mtq.png                   | Bin 0 -> 1512 bytes
 assets/images/flags/mwi.png                   | Bin 0 -> 754 bytes
 assets/images/flags/myt.png                   | Bin 0 -> 2003 bytes
 assets/images/flags/ner.png                   | Bin 0 -> 494 bytes
 assets/images/flags/nfk.png                   | Bin 0 -> 1422 bytes
 assets/images/flags/niu.png                   | Bin 0 -> 1095 bytes
 assets/images/flags/omn.png                   | Bin 0 -> 711 bytes
 assets/images/flags/per.png                   | Bin 0 -> 123 bytes
 assets/images/flags/plw.png                   | Bin 0 -> 608 bytes
 assets/images/flags/pri.png                   | Bin 0 -> 1880 bytes
 assets/images/flags/pyf.png                   | Bin 0 -> 1256 bytes
 assets/images/flags/qat.png                   | Bin 0 -> 2021 bytes
 assets/images/flags/slb.png                   | Bin 0 -> 403 bytes
 assets/images/flags/slv.png                   | Bin 0 -> 642 bytes
 assets/images/flags/svk.png                   | Bin 0 -> 521 bytes
 assets/images/flags/svn.png                   | Bin 0 -> 1963 bytes
 assets/images/flags/tkm.png                   | Bin 0 -> 1620 bytes
 assets/images/flags/ton.png                   | Bin 0 -> 139 bytes
 assets/images/flags/tuv.png                   | Bin 0 -> 1456 bytes
 assets/images/flags/ury.png                   | Bin 0 -> 1017 bytes
 assets/images/flags/vat.png                   | Bin 0 -> 851 bytes
 assets/images/flags/vir.png                   | Bin 0 -> 1987 bytes
 assets/images/flags/vut.png                   | Bin 0 -> 1267 bytes
 lib/cake_pay/cake_pay_api.dart                |  10 +-
 lib/cake_pay/cake_pay_service.dart            |   3 +-
 lib/di.dart                                   |   3 +-
 lib/entities/country.dart                     | 386 ++++++++++++++++++
 lib/entities/preferences_key.dart             |   1 +
 .../cake_pay/cards/cake_pay_cards_page.dart   | 156 +++++--
 .../screens/cake_pay/widgets/card_item.dart   |   2 +-
 lib/store/settings_store.dart                 |  25 +-
 .../cake_pay_cards_list_view_model.dart       |  65 +--
 res/values/strings_ar.arb                     |   1 +
 res/values/strings_bg.arb                     |   1 +
 res/values/strings_cs.arb                     |   1 +
 res/values/strings_de.arb                     |   1 +
 res/values/strings_en.arb                     |   1 +
 res/values/strings_es.arb                     |   1 +
 res/values/strings_fr.arb                     |   1 +
 res/values/strings_ha.arb                     |   1 +
 res/values/strings_hi.arb                     |   1 +
 res/values/strings_hr.arb                     |   1 +
 res/values/strings_hy.arb                     |   1 +
 res/values/strings_id.arb                     |   1 +
 res/values/strings_it.arb                     |   1 +
 res/values/strings_ja.arb                     |   1 +
 res/values/strings_ko.arb                     |   1 +
 res/values/strings_my.arb                     |   1 +
 res/values/strings_nl.arb                     |   1 +
 res/values/strings_pl.arb                     |   1 +
 res/values/strings_pt.arb                     |   1 +
 res/values/strings_ru.arb                     |   1 +
 res/values/strings_th.arb                     |   1 +
 res/values/strings_tl.arb                     |   1 +
 res/values/strings_tr.arb                     |   1 +
 res/values/strings_uk.arb                     |   1 +
 res/values/strings_ur.arb                     |   1 +
 res/values/strings_vi.arb                     |   1 +
 res/values/strings_yo.arb                     |   1 +
 res/values/strings_zh.arb                     |   1 +
 132 files changed, 601 insertions(+), 78 deletions(-)
 create mode 100644 assets/images/flags/abw.png
 create mode 100644 assets/images/flags/afg.png
 create mode 100644 assets/images/flags/ago.png
 create mode 100644 assets/images/flags/aia.png
 create mode 100644 assets/images/flags/and.png
 create mode 100644 assets/images/flags/asm.png
 create mode 100644 assets/images/flags/atf.png
 create mode 100644 assets/images/flags/atg.png
 create mode 100644 assets/images/flags/aut.png
 create mode 100644 assets/images/flags/aze.png
 create mode 100644 assets/images/flags/bel.png
 create mode 100644 assets/images/flags/bes.png
 create mode 100644 assets/images/flags/bhr.png
 create mode 100644 assets/images/flags/blz.png
 create mode 100644 assets/images/flags/bmu.png
 create mode 100644 assets/images/flags/bol.png
 create mode 100644 assets/images/flags/brn.png
 create mode 100644 assets/images/flags/btn.png
 create mode 100644 assets/images/flags/bvt.png
 create mode 100644 assets/images/flags/bwa.png
 create mode 100644 assets/images/flags/cck.png
 create mode 100644 assets/images/flags/cmr.png
 create mode 100644 assets/images/flags/cok.png
 create mode 100644 assets/images/flags/cpv.png
 create mode 100644 assets/images/flags/cri.png
 create mode 100644 assets/images/flags/cuw.png
 create mode 100644 assets/images/flags/cxr.png
 create mode 100644 assets/images/flags/cyp.png
 create mode 100644 assets/images/flags/dji.png
 create mode 100644 assets/images/flags/dma.png
 create mode 100644 assets/images/flags/dza.png
 create mode 100644 assets/images/flags/ecu.png
 create mode 100644 assets/images/flags/est.png
 create mode 100644 assets/images/flags/eth.png
 create mode 100644 assets/images/flags/fin.png
 create mode 100644 assets/images/flags/fji.png
 create mode 100644 assets/images/flags/flk.png
 create mode 100644 assets/images/flags/fro.png
 create mode 100644 assets/images/flags/fsm.png
 create mode 100644 assets/images/flags/gab.png
 create mode 100644 assets/images/flags/geo.png
 create mode 100644 assets/images/flags/ggi.png
 create mode 100644 assets/images/flags/ggy.png
 create mode 100644 assets/images/flags/glp.png
 create mode 100644 assets/images/flags/gmb.png
 create mode 100644 assets/images/flags/grc.png
 create mode 100644 assets/images/flags/grd.png
 create mode 100644 assets/images/flags/grl.png
 create mode 100644 assets/images/flags/guf.png
 create mode 100644 assets/images/flags/gum.png
 create mode 100644 assets/images/flags/guy.png
 create mode 100644 assets/images/flags/hmd.png
 create mode 100644 assets/images/flags/iot.png
 create mode 100644 assets/images/flags/irl.png
 create mode 100644 assets/images/flags/jam.png
 create mode 100644 assets/images/flags/jey.png
 create mode 100644 assets/images/flags/jor.png
 create mode 100644 assets/images/flags/kaz.png
 create mode 100644 assets/images/flags/ken.png
 create mode 100644 assets/images/flags/kir.png
 create mode 100644 assets/images/flags/kwt.png
 create mode 100644 assets/images/flags/lbn.png
 create mode 100644 assets/images/flags/lie.png
 create mode 100644 assets/images/flags/lka.png
 create mode 100644 assets/images/flags/ltu.png
 create mode 100644 assets/images/flags/lux.png
 create mode 100644 assets/images/flags/lva.png
 create mode 100644 assets/images/flags/mco.png
 create mode 100644 assets/images/flags/mlt.png
 create mode 100644 assets/images/flags/mnp.png
 create mode 100644 assets/images/flags/mrt.png
 create mode 100644 assets/images/flags/msr.png
 create mode 100644 assets/images/flags/mtq.png
 create mode 100644 assets/images/flags/mwi.png
 create mode 100644 assets/images/flags/myt.png
 create mode 100644 assets/images/flags/ner.png
 create mode 100644 assets/images/flags/nfk.png
 create mode 100644 assets/images/flags/niu.png
 create mode 100644 assets/images/flags/omn.png
 create mode 100644 assets/images/flags/per.png
 create mode 100644 assets/images/flags/plw.png
 create mode 100644 assets/images/flags/pri.png
 create mode 100644 assets/images/flags/pyf.png
 create mode 100644 assets/images/flags/qat.png
 create mode 100644 assets/images/flags/slb.png
 create mode 100644 assets/images/flags/slv.png
 create mode 100644 assets/images/flags/svk.png
 create mode 100644 assets/images/flags/svn.png
 create mode 100644 assets/images/flags/tkm.png
 create mode 100644 assets/images/flags/ton.png
 create mode 100644 assets/images/flags/tuv.png
 create mode 100644 assets/images/flags/ury.png
 create mode 100644 assets/images/flags/vat.png
 create mode 100644 assets/images/flags/vir.png
 create mode 100644 assets/images/flags/vut.png
 create mode 100644 lib/entities/country.dart

diff --git a/assets/images/flags/abw.png b/assets/images/flags/abw.png
new file mode 100644
index 0000000000000000000000000000000000000000..d049d3a4348416d1826a4236ce7218e6807669b9
GIT binary patch
literal 607
zcmV-l0-*hgP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0003yP)t-sM{rE<
zC@NQhyH|j_SAe=zf4We8x>$j``PLRzf4Wb7x>|$0RDQWte!7{p*<p#mqPyE>jKX1y
z!eETUQhm8ug1qOjw|tetVvE63e!A+Xt%jGuPJ_X$nzmViy#HBMiJ-}ap2@Ys++&Nu
zRerfmg223(uWY5+R)D*=n6PD$#{X1MPJq6;oU~JZxowfd{3IdfdxA`a!svN_{Uab)
zjmYwqn2w;w+J%r#e!RED+=Q&xZIs8unyrzTzW+x<PlCWye!BBCHBWuJ@);WP8yn($
zgl3GvyO^&~gu(ADF84%4hnK)zk;+kp!l$jvU6ae2p~GU8%;|D>_fAgsl$B42#r8-@
z@F^?$ARf(;q3|6Z?<y?id4Q3w)bSi1>~3@MEG<!dx%60A|3W>(l&J43E%0P!`5PIB
zRyK|R0004WQchC<K<3zH0002eNkl<ZSi@sr7zLwX6hHwx1pw6mP6`bWm0+RB02O^D
zNs0_`wlmXWrNjWgRC{wS3JgdJ3XZfj;v~}mPBzZ~fA9DNYf~K&7BUQwbNBIx4QGr=
zOtz2}=Vv0>08VAA(3FhmG%rRM6L~Q{W+swdz@lLj7?mEu=wz&>AjC^nAnI9$#f7*U
zs>^V(k{b(-zHSD(s+6Py2Tg57HcAX&la>;uC?#?V3h+>vow+G3511)6fPK_}fir-E
t0x(Dn7>$L|SQs^cN(PLAQ7{UC0055fRc;z8VCw(?002ovPDHLkV1l;f6z%{3

literal 0
HcmV?d00001

diff --git a/assets/images/flags/afg.png b/assets/images/flags/afg.png
new file mode 100644
index 0000000000000000000000000000000000000000..f2ea25144b2c5bf758a134ae00ca05e99cc9581b
GIT binary patch
literal 1848
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
OBXmEe@8Drx!T$m5@IgcX

literal 0
HcmV?d00001

diff --git a/assets/images/flags/ago.png b/assets/images/flags/ago.png
new file mode 100644
index 0000000000000000000000000000000000000000..b04d7dfa6652e1e029f4dbeefc4db104382764af
GIT binary patch
literal 1159
zcmV;21bF+2P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0007!P)t-sM{rF4
z>=?}qCd>#Y4*>(e5F^eICIA2c&JiZk5hu+HCd~~d$^a<M3MLK!1OMw7%?>77O$hAF
z760fMzYil00R#Q&6wC%E&Jrff3Mc*O744xLy$2-w;uTm-2>ja@KsN@Lf(>X{35$FU
zLO2E>90Sj`69fYQ6A%Kpo)CU)3tLVI0RaF}Mh8|(2nq-R2?znMmJb2~06sPbUr`9#
zycEZ-5*8Bzxt|fptP-1q4%<v2zN8UzVhW~@5B=vA*TEF-p&HBwC;#mj5Do#rr4hZP
z5!_HA+)p9wnj2(M3IhcId}|Bvsu}0U6}|@~>ysN|R0;On7XIoK@T(c`s2bN-AI=XZ
z(GVw=felee2mRX?`r8)%>lFOj7X9fI&Iu>rRUzq%9LohKy`mA&1}OaI71Aao-(Vo{
ztQzBR9=-@9rH&8w%ok);3GSmBLNEvJq8iIPARHJ1<$E4^XbW&)3Xy#c2nhhYq7lIt
zBhVTp4h#XOln;@74G0GTcxMaY!W7%R6CMu)qKgh^SqaS#CjaUf8WsZGRU!Q375LE>
z>zEtfSRh?c2-GYj{N)wvmmAa>CcqOTi+BuDMhE=a7S%5#2nqo4(-q)jANJH1eQXPS
zYzuZ}3h2odGAjiC^cnx@7oLa?!5AYW9|N0(4p~hI{@WJ$*cSHK7Vy#)|JxT$LI;0t
z3$~vS=Y|}+p%J5y4(G`gI4}h^F9kI&1*47+*t!#?jSsn)5+oi2|J@eR93{{kCD=eB
z$^a+lf*sKwCD=bA=!zWFD<tQG9q*|c_RALw00Qok91;No<#`?4KqJ#AB;#=&(G(`n
z6eim{B>LPH=6@aTr5gI%752#&#U~-|ksQ7iBmEcE+5i9m0d!JMQvg8b*k%9#0i;Pp
zK~z}7V_+BsqhJ(30S5(O)PNCW02@UHu!&1DF;iebcy(`Qp*t5F*#_`VpCBcc$<4(?
zt^or3W=-tw%J;NpBF_NH!}|}2_xDHzJ2J76VSt1H&#@ys++55h_P%Vqq#Mw-_lorO
z6Ve9{aXAH~g?KQN?gH*}S7l|7ALZuYP0tkz6<{OT05+cUm#>}Sk>KD+PKwVU(gmDI
z;NpdwXD^+a6v4@vni!jv02U)?04p4bOx|$gmW<4jDiK!J?4p>sFn^FJ76aH(01F(5
zHqYF3`Xmb<ABbHL9pnXKu%N2OVgM4TXk4^u29zDe=;Mt=34R0E%lT*5bwHSr{DJJG
z8{kqYJb&i`5X;<;(Z+~$1K8{5u3ouuDv)6%Y^Fzs3xHtv_EkIP)s#6~>a&w<fJyCA
z5VdXn=4GW07CIywpl--7w0QZJt!vj!X-cs*W+&YR2Cj_ljB8dfE^H~bGu6@{-2ir7
zx4edFd*-y}u(NAxs;Q6{h=P3(T2)y{kSqfbKuKPKG6UEZ<tQ|Ooqg1RL2SS%7zLvM
Z2ml<!oxHgb?CAgi002ovPDHLkV1ik@*$)5!

literal 0
HcmV?d00001

diff --git a/assets/images/flags/aia.png b/assets/images/flags/aia.png
new file mode 100644
index 0000000000000000000000000000000000000000..193f0ff418ac5ff731ed35c4a02f26222f1194e4
GIT binary patch
literal 1357
zcmV-T1+w~yP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0007uP)t-sM{rC4
za=a%}sRK2d0CT<14-fn5>HssD|NsBY0013IrOVIO&(hiAhl<i29qy>819ZO9=JWjh
z{@hVf`TG5PmCE37asK}Q@2;+9g~9-O$TnWD*Eu=AtHL2orr6-`&=nQRr??3^oypYc
z)F&r|oz8xc!vHds0CmCLS62XZzW@IH-BeWm`1Jnz_w>G;^SG1s#isxM{^Vm304s9<
zDs}*KzXN*5(&qF7biLB&^haBQ{`~sS4i5kQ{N-g6?wV!gW)=G4()!@f{O#lImtg+(
z@%{4bcazB3MMWDqbOA?%0Y-!XcEZsZ7~S6B9659VO^N_ais9nq056OHak&68mH=_O
z0W)#T(ANPki^9gv0D8#*GI0PglmIGn0Xug9Fp*nqjubU_0X1>~Hgf<fanRG+0Cd0r
zFpvXPlL0+=0DH;9$IqUowg7a$(dP6PH+KV9l>mFnVR4abd6dP;(rkK_%+J@Pth-2D
zf=FD0%Ffo$)7k@dzWw#^(&_m5-pyupk^nK2XLgbUb-w^Hk^^?Y>x@tM*~aXTQ`7GM
z?U`f$@8I&YiwrS(tFgZQ^X<~*^7Y234KaJIv%mS<$k5*B_t3cRoM-8KHT$}e=yxyt
z@8|ya^6i#i{PF2*dzkR4eE9kK`TF{5d6wvQF7?Eu=y);ZXBYOGVEW_L_R6mEwT}Pi
z*5zm!|NZ^>+{*H|k^AP^^u3wypKS50fc^CE=XNdr`Ss^<Ci&dS^0A2Lawp_v6z6g%
z^S6=ipKR`%X6%w#^uC+#q;%|)TJyP;`r*;;ooV#Hp6!`r@1Sn;yO#93m+Od0?2uOQ
zrg!wbnCN&g>xoP2icJ3a_2gs{@vMQ5Ne83=0004WQchC<K<3zH0007TNkl<ZSi|kr
zRdd@w6b0baZhWuPKpk`(W+#q0%-p1qGBYzXGcz+YGcz;e&*_RSt92#6bw=kwqaAy{
zd)69{0s_>iQNt!%7a64mHZg&E4B{5CA)#U5Gc*vLY{WE;6i7^nkI;q705mD-LJ0w&
z#$!^P3;?v5LJ1CF#%H908~}in$Yn~ffUNNzfKY-4WRCX)_!1P*D093Rph`3w5ed*F
zb36y2C<G8i22if|751BLyHVE_+YTS!xRko<(@6k)?k{J7u6?J^EnT+#7~;`QOG@X=
z9N+P8N6-g~mN6_al3lmqKIkp^5mPh5brDT8U~G=g)QS%q%xr)6_4}_n`nHuf5SN5u
zp&^YF5EZG*O;6ECfghjT-`;=u{Bnm?0?^~*6B2_c05oZ6Ocs|Qz~)2FpC230)o^|5
z;tDT-86OM40HBqWAi%D(uiYQe;;298eFSbi@Bm0k5a5Wj%KZlM)veQ2HW9#&_XOw?
z*+Pk6JaGQfwL5Ps(02J$rCkK@<3#{hf(Q0H@b;5>*R$uYlhvy%o&Z1I3t&p{fbHN_
z#F|GB9^=h@Ys#dL@gJFw=s0oX-qY%bchS0MHR3FVz&ymV-IW*bzo<pDud^V|PzcN>
zPtICXTZdQd&J7F6VuC_o8v7TxaAxm%`eukiU~);3fy&M;YZsLm3`LWMDg;JPDJ*VH
zvU2$XaxE?#Ggu)2Bg_RY_!Nv92ucAMJ~gK$n~CFwfpTEL*nVbazu7b>%MSpudi6As
z5;>;s{d<5v06>1{4knYiOa7nV3$jY&wQHZ31^xp*-%Kj-e*<dNs3G|c5vi-dQ6`o%
P00000NkvXXu0mjfwOYRS

literal 0
HcmV?d00001

diff --git a/assets/images/flags/and.png b/assets/images/flags/and.png
new file mode 100644
index 0000000000000000000000000000000000000000..fc5d9a89be3fe0c181438caa47b8717186a2589f
GIT binary patch
literal 1966
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
A^8f$<

literal 0
HcmV?d00001

diff --git a/assets/images/flags/asm.png b/assets/images/flags/asm.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd3818eda60ec1e2727de66410c7cf1411ddfe19
GIT binary patch
literal 503
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!I14-?iy0XBj({-ZRBb+Kpx~JR
zpAc8~0-yatI^3F74BGV&w1rO*h|USBK@f*#^%+4mpcIhHrd1<s-BCSpFPCwPap(+5
z`))S<reo(HvFJD2#Lo52UKW_Q+%a)}Qq6{v?wzvEeTr`VVzyoPpS(|R-2Cv_hf6nK
zFzYt3>Nj#4HG5?)*>>obm|Yi_NlW|eLo9lY51zhf)T!UF@4BQzH=99|Pu5a-*S_+;
z-OILKlCbZVcI;`JeQ5c%%V(}W{r~^JLGW~b^EMH)=B~L%L`<8RbQ?AwxH)0z-b$dq
zcuRu(f*I=T%j@4~<iD>kfB*ja-w-yS#12mv$B>A_Z?7E{I%FWw@GxoV2{X|<UAuR`
z{=HwgmC4y+iemM{4fhp`eyYEG65y%SGC_U*{od=sMZ(*d86Pb9p}S(;l=BX{@s}RY
zU`Sald4+QUuWR*|BTQ#E8ec!%xy2*ll6>Es&~-rqoF!3rk84f4;=<J1SU7*V?HP9#
zi}UF_7&4@^HXPo2q;;p^^cf8s@5OyvF@1%6`2IM>L-%BFbl%?lzHvoY0k?+80tVK9
kDhlj^DZgx$TK2>+R;6a|2@RTk2j~X|Pgg&ebxsLQ0C#!O3jhEB

literal 0
HcmV?d00001

diff --git a/assets/images/flags/atf.png b/assets/images/flags/atf.png
new file mode 100644
index 0000000000000000000000000000000000000000..af77e45d56cffeac7204d977b30278c46b2335de
GIT binary patch
literal 1311
zcmV+)1>pLLP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00004XF*Lt006O%
z3;baP00001b5ch_0Itp)=>Px%Pf$!$MF0Q*03wtCB9#Cllu&20l$4Z|86yA_QvelR
z?PzlV6H@>plmH@?03($EBa{FmlmH@>03wqBB9#CYT>v7K02_AzB9#Cll>i)i03nh9
z9DV>Il>j1?03wnAB9s6kl>j4@02*@uAB6xSlmH`?03wwD9D4vBf&e0u03Cmll9QB^
zlQ2JT?P+uXB9xRxOHpXEi+_cbA1IS6GX)x7X>f!9BbDy%?(Hc#|NsBFz}m*n=efb!
z?ZU+dD3<{wmHz(zfRf7Y@b^AhuPjNYJXfx~#M=TTmKQgk5i*<<G@VUmwa(S*&D81}
zI-oF2sRJgKL0hor>h(HRt!#k8=IQj8rqoVmwXeF}9Xz45zTZ7pt{OU^2r8IIV6rw*
ztMT*s3@w`NYIW_<(^6@(%h2H%IG@qj?7_<AaD>A+Q>^3X^Cm>4h?&ieozLj&^>v8G
zg_g{Gj>u$rzOlUCKw7VPjK|N`>yDk!&eiLzxZF);wN`GqbB4w9_4<&X(E0lOzQ^P-
zO{vAr=fTP4yTaNWJD?djpSi-}Cq$(aG@W;e#<#)YCq<<MCYIpj@&zcDiki+cPO4OF
zxEVR0@A3GOq0$~bp;~deeU8aUVY6?8!&Pj!5HXvwz26NknxU@PJ65gs_xp&L&HerU
zQ){;xIiQuJ)AIBA4lkOEo6q|C{b+o^L|(C}wcDPn*4^Uqn5NX#+wBrEoa5&6XMDfY
z+3fA__m-v8bce<1?Dp8*?uM4k@bdV;$>sX{{dkJUc8SJsg2Oykt!I3|MqB#U0000s
zbW%=J0Qc1X`y3n`9QzZAiTL#Rnq~A8W*qnFBw;0*n_*$<>KrB1X8s%{VH_MB9R2DX
z{U07593FzAMaBRC0xU^HK~z}7V_+BsqW}(sIXF0Uv{<1)Tb~UIjEoIUO*pUuVT5jV
zX+1L_U@?aSP763Nw=%;4<Ykl~`UM#w0;C#XX2z%j(l4uOMy>&7%yJA2qC#fm8(_w#
z$-rYqi2-KZ3`~?6z{J2ynF0I^W|SFVHfq4A0mIJ#1B3y(NCvbLZ9odbfFvXX+z1$8
z0|%)H1Cnjw0AWC`H4>NuH^7__fE(cH<K*PD$kK8JkXm4m#S3_WH<Wg?v~)%hBF=yu
z*L0UQm;qbk<CmG4^_Kd&_z`VDR<>ocAItzt%k7b7X0D-@8EM3Op~SZvNG5^}*s=34
zkYU#2lS#Z6>|N~x&CEPDc|yV<dY`?SdoW0d_&@}Kb(ZVF2E^{RJYq&_EC4~cgM-6b
zkO6xv9rnhMZotYdtJgSeSY>H>X#cJQmJy^Iu-tOv<|xYqOCUPvwas!VsRk@uVu=Dm
z=aOi^?65dHJG;d|tqveYNZ2fr0}%w~2U%Lq!<C&00y`iswruExGD$a}42a#!>w%<8
zI2i``7vvY#n3)B8n#G1hG}d~NY=C{9Wn~wH*;MCH4R--A(IymCbO6anU{TWEQWXtv
zU@#GFfQOk!pPAXrNoHnV0cNnItc=viA_h!}n%X~Y0!kxGQHUfH{4Im*kehjG3=ERY
zq!=)H#>DAJ4NVQ?rY=#y-OMZi&Jh!VG?pa<#LdV63IbAy20Ir!$$)FLlQaqt001|j
VkQQ>_vPJ*^002ovPDHLkV1h&LS9<^e

literal 0
HcmV?d00001

diff --git a/assets/images/flags/atg.png b/assets/images/flags/atg.png
new file mode 100644
index 0000000000000000000000000000000000000000..d9a3d9f9e106261f8cd7e740df225aa703bf0b5d
GIT binary patch
literal 963
zcmV;!13dhRP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00009a7bBm000ie
z000ie0hKEb8vp<STu@9@MMrQ<*F8=x0|+Yv2hI^DuMQyAJWb9KCIA2c&JiX60001T
z#?BEY|NsB|(H4Wc<AS4W>z=0m{{G%#aL*Vl_0rY=H($pPBvS?thYJ`A00PxBMf~#f
zuMQw40|$pPT?%Zy0CB~~6f09og(hF8uOB@M2mt)i75mT?J23@CIR+050pYq6o`Vey
z3jwhpJ%O&*CMQLJp=<om7FS3I8WjQw2LMVv2Kdbtntu%@9|PdJ69fYQX;%p<BLm5&
z5%kIx6%he-VG05P0HcQvrHKyJu@WL20}2TM`Og*j&K10z5b?+r+O-pJTnTPl2?RS}
zE?r|@g=hpiU@cr@U4&>33jsVb1riSdIxq!oS_w!z2I|5T5e@;Mg%0b(6l_@upo9&b
zf(@L34Si<{NjwJ5s}h-i4bQ6*d}j)qfDLqD3UgozpMwpRdkx>Y6PA1pp@j|)4FREs
z4i8Tz9RL6T3UpFVQvjcpm6h+G@1LKF$KMzL00H+&L_t(o!|m2rPXa+0g<*RcKSx(U
z?1%``?O0Gj#g4uA-n;()#05cicG?1WhI6qA4D&*sD~gH=E9{@Fq$-b<s)6zrl=E83
z)j(x)?t$jYL;#uuADNyO95%skz}mq)4vni1uUCDHhnOGeu%-gg&SnVAA~Z9D&}@JW
z&<^PUuo+_O2+hqQv>syvKqf#j4Bx7cwfF*>pGOPvHTA{uFa@9uPz;Z+U&w=3f=f%m
z73@L2zzq$c4Nwddk+64h8GmE^iI*3>?~w@_fCx|wQ&IQFDo$?o%^jU$0FVI<gKNm+
zLg)pj*Msr1`tIS7iv-XGGz_PgqYqD${=e(kKRI?cdUl`#&;<yFk#OSbARhet8U7Ip
zKp!9&eE06uw<qTw^U(lQAj1&!TwI@E&Caim_V@Gvbimr*sBU{_cc7lJfvwGr#CgA!
z8vti#jdYz(;0M5Fm)*D9KokInEZ_ifpsQPazq?BkkT4Jc?0}Gg1mFZj3=S|7;4|m|
zcme3`t7ERO7mNkK)KJS<g9(fVKw$+GFdi^l==&CP76E8&)8B7vg=_*80}DVH&@(8I
zZGdE80*C_y0~<gR&@gZSWPuEW0=Wg!3_Jj7AjQB1kOz_sd;kN11cL(k1k4rzKq^pH
lEm}pf@VKn-N4>EBvLAb1mlYUv-wgl&002ovPDHLkV1lw*cfSAt

literal 0
HcmV?d00001

diff --git a/assets/images/flags/aut.png b/assets/images/flags/aut.png
new file mode 100644
index 0000000000000000000000000000000000000000..1be1ff483baf9d14483c3c5fea30ca5c21c6b406
GIT binary patch
literal 125
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSoB=)|uI>dsZ#6Cd|NsB@@7-pg
zAY)08UoeBivm0qZj*_Q~V~EA+<OB(~22&AM79MTJb)gyw2R8^wTr+G}H0WVqIQ)@=
UU2^j289>zxp00i_>zopr0P6cAp#T5?

literal 0
HcmV?d00001

diff --git a/assets/images/flags/aze.png b/assets/images/flags/aze.png
new file mode 100644
index 0000000000000000000000000000000000000000..834b1e696beb647bb499338ce6c9c8a0fa0e7aae
GIT binary patch
literal 717
zcmV;;0y6!HP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0004HP)t-sM{rE)
z0yXLbHt7H{>I66G1ULWx{{Wc7-~coLu4U>0HR%8?=>Rb4059nPH0S^=>H|0F050kR
zHt7H?>H{_D04w#5rRxqp{`dLm12p~a@#+FJ>>Ehw0W|MFX7h24>=#7q6-DU-Ht#)T
z>IFFYw8QEFH0laG?lN2a-sSUZhw2YL@J(*&05b1FY5d&e??h_p0y6lmz4xQG_^!X{
z04nJPH~;?r^^K$G04Mc?o$o_v@nM1ODpmZ~;O;wN^LUf$05R$bIp_c^>l#S$Sa<3Q
zI_dy3>?Km`6GQyc-2VCd>IppR2R7;hGU^FC>>W$;VuJa&$LRw%@m_uF6G8s=`055Z
z?m1xhp|tm)wD*~<`L)FDC{+8_-v9mm``6$0l&bZEoazTT=>RD0CsOo%m-1?e^L3H>
z!_WNU=k<)E@mziFELZxy%I-8-@m6>Gz|HPBT>RbS_^!VC%hl~CQ^!7EaR2}S0d!JM
zQvg8b*k%9#0TxL_K~z}7?b1b0LqQP0@$SCu0MCUA6fH%HyL(HK;!xb(t-$AJX-Ieh
z60)z?`Jd*n`#Vg==fg1UtAad2009JCK;h5)xz@CV-YXg9epkPq{td9th_baiH`?7;
zMc8)&08vj4VRdS(y){Ir7r?myxO5y<o3^Pf6JbC)55w^p|3{ZX?{|x{#iBsq3c~vu
zAE<VFoqb)N5CxPSI69U2Q1bWyQ2I1UMS*QN*vtVh&m34!i2{Lf*qBlIU|PYqo4uqY
zyu^_-1P5%sgZa$;%0jj95=~_g`i6THNo|o$RwsKnq>g@o&gO=iiY9M|#E3Q2)fTU<
zEQ@$MWyYeG5v$h?o&5_G<q-l1Am9Qp4C8$OOpah-4>aVl00000NkvXXu0mjfDHme4

literal 0
HcmV?d00001

diff --git a/assets/images/flags/bel.png b/assets/images/flags/bel.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c06c5fa7ddf179f6268274f97472fd677063e2f
GIT binary patch
literal 127
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSJOMr-uI>dsK<1yjj$bs)bJzm?
zfgHw?AirP+hi5m^fE-0n7sn8b)5!@EZVjd)9E-vj5B~b^@F6iIAtb?oi$|G(VfNX+
V2HlN6-GGW2JYD@<);T3K0RT*xB8UJ0

literal 0
HcmV?d00001

diff --git a/assets/images/flags/bes.png b/assets/images/flags/bes.png
new file mode 100644
index 0000000000000000000000000000000000000000..b00bfb1f57e3f511ccbc3f1ad8fff2ba78c98185
GIT binary patch
literal 236
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0J3?w7mbKU|e&H|6fVg?4jBOuH;Rhv&5C}<Gi
z6XNP#;G^i)y-r30LjM2%AHsO}?EROAkJrg+LZpD=UmiVq{QSd|RxwkcUha}0zhH*>
z^WVRJKXodQP~q;|2o(1Aba4#vIG&s!!TN>ijaP*uBlGFJJqHp)82^eCJPhB^(D+$4
z&Y-dJt6rRd!K#KjE{lJUS$TQRq<>&)4rFciV4STGH^Ct4>IGf~1~dC>r_YBR*#tC}
N!PC{xWt~$(698IAS2_Ry

literal 0
HcmV?d00001

diff --git a/assets/images/flags/bhr.png b/assets/images/flags/bhr.png
new file mode 100644
index 0000000000000000000000000000000000000000..135c254cb496638361bf40c707acac022ac8ab8f
GIT binary patch
literal 567
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!I14-?iy0XBj({-ZRBb+Kpy2ZW
zpAc8~0-tk&YM)P>{dD-m|NsC0{rd+bfg%v{ilOsW6E_I^=hNr!x9on}-1p<|gL5Jp
z->%)f<s19$>Wy3ealf9wJTIpG_s5SP_aEH}PrKzGf5pJ*l7{uu#-4LRYL6>hFKgPI
z6H@>8>-Y2SsTY;Z?#1W+`}6lsXv!5mhYNB>=Y%zWK7RJFu=ZK!<bS_@eZP74<K9E>
zH|_lM<?EXzYySQDbHgp{!>$AG)^9s6se4hy9O$IGvDu%Go&vh|`;FU=tK09Vm;U|v
z^ViGQ@78R2w|2`-_wbwU5$8p<&WUQhm^kaj#M#zeY!855<|zsC3ub8R2ZFZ#_wW1r
zb(*VPf#UZ(T^vIq4!@mtl#khv$7Q>Z-%KDVJpK3o`^<0G!fZ=SCsv*O-4K{`{zjNc
zr;8HD>Yt+B7gH}cHgey1Irn2pY3lw*Ka>sx%6t1XWNf~7UXju2j9SNmvh57}3}og`
zRQh&{_n1KAy9L)$5~QQ&TD@Ri^-VkQ47<xj0~LYq&l<&#^qpi1Xm(h~Q>rL(#%M$D
zJ|C&x;)|0%G#9FsYku`-{J@<c_|a^U+od%%O>1-%e3%~b@QLIsIp{1Z_xe`S&IN^R
z;j=rQcC9P_+9xCN=g7{NT91xTOf7n4yGcc;Q(#^LQ(g0PnUW7cpE7v5`njxgN@xNA
DZE7OE

literal 0
HcmV?d00001

diff --git a/assets/images/flags/blz.png b/assets/images/flags/blz.png
new file mode 100644
index 0000000000000000000000000000000000000000..06b23f161a3adf4e224848390dae6b9cb6ced71e
GIT binary patch
literal 1777
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
TYF3V$00000NkvXXu0mjfnM18k

literal 0
HcmV?d00001

diff --git a/assets/images/flags/bmu.png b/assets/images/flags/bmu.png
new file mode 100644
index 0000000000000000000000000000000000000000..6e253a8e64a0ccb0499c4f7a901aa0f1416afb1a
GIT binary patch
literal 1518
zcmV<K1rhp*P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00093P)t-sM{rCh
zQmGwEr2{pZ&kqm#>gw$5?92cF05h5Y|Nn+lQ~CS-{r&#_{{PY)9pZ<I?x?8TQBix9
z%HVKu(G?Z%uC8W<!Zu#7*Eu;MO{TxA!r0*N2|At1r?|<~>C`7Dgq_ZQki*?qSHu7S
zFO?&&mX^E#0LRJ8F_|Wv1Ov$c0NqqnHBS@y`T4j20EPhps09Gb&d~h-|Iq*dxT2!2
znVGbppz7`IEngRWPED@@0f$so&khbLnI^NDnLBnTER!KHj~|^xL?)gjTcuK8yxd|j
z3wNcl(b3cD)!1UV**SL@ZUO*VKPGW!Tj%TRc19$u0R^3$i*!>wjvfq+wuxt^rgxLb
zZI^*^XEfPGMWvpev!0$KejaWh2d<l&C~X>n6a~Qn0Kb}=hz<kV)zwEp4qqt-hY$ph
z4gx5WBsEqOu1ZS4006^`j3SvHQ(7@9q$wJ6Cn1w0n+gG89|x(7j8riU%$b?71qCaU
zAV51HE=DKx_4P+ZAbtb{DT*bdRaN-$@MJ?)E1D*ahJk{8ZZ=RcEMqMkX)I5kN95|}
zXq%|3V`h*cDM(pBHE<#9@$s>DcUD?gv{g&mq@}a~03>P_)0LH~9vxDMjc<8;UaZM?
z9}?yO0MgXfKan;+IyIxGq|yKYy}-J3Iwwp~5B2BfTP_c1IT^LRw@gkufp%|~j)`D?
zN|O)(m!6ucsGYvMx_p0Vjv5_=h;d&?FpPO@)XK_JI4gi{VUm`VMq3tXw$pz#7hyIV
zV5+pK4Gn`>9~3M&Za5RSwz**{9o^;IX1?K-aCz_6)h%0Xi9QgO5fPF{6LUx{RaQjK
zy1I6>rEPUeQJA)qQXE}S4t8{Acz9WQYdF-_%xRBRl8=O_sjQYuPFkIzxL83fOkaMq
zv&O`~x<p2ben?+HFTqq%FH1|Qs%TjY8Lh(0l$T+yrAnA97rCxYzA-e`y1HXoFG)ly
zT}>U5n321wR*|o_iFY}mvU+}iPSv<fc!qGoZf-(fTl?$)lf*4X00001bW%=J06^y0
zW&i*JoJmAMR9M4fU>F6XU=%=s5-Yb5GY1s#vaoY9!8l_4d;;uv0oVXx5m8P#Moa@F
zr6dGdd5AE8QC1$|2!sJ3>p7*xi7<eJSrOp~m;n&$6=XPwF@S>u=m>3yBcKLAtp`dG
zX8^(xU<2UR6K??A5g-G?;ntI40MrqjKm(%S))Qv{Ckg->fC7jxz=oZC05$-x3aIIp
zY+zuXmy>J`W<}%l0y_%|mlvYY8p5lnRMSiavrI4pQAUA>RWJ%{fT)PDA~Q-La)EW#
zI_cN@*nyd57zT(-a|-bBhl30d;%3#Bmu18>V8=l<eKjXt5HkkN0I>BEQj$y{12`Dv
z5RO1L;Nn?hW2;6Z5HlXt0EqQs92^h>IG7QRfE%#<l#!=?pq^$gXOkx{rzx@lFzY$s
z25=x80XN{}tLG1{o;!1B-;};)ZWIIH)*~ALc7zhp5pV-u{|k<|A8{${fZyaET~1Xb
z1K`%97yxqw%mAM6VLx9!dU)l8m#eEgssV88(F}k%0%m~GpI^Vfym@hY?;NjL{r)Hh
z5R+uNI6r=P_x{t5%ZC@vcAq<Q5;y4v{51}F8~N0CzgzICka^Q4+L3I)6Q9rDB5wu+
ztX#2X^?I!tW+WP5&3W(H*T>iIoIkRC?WPUewoEl4(E!Wi{<nhE?;85;Qdc+J7__9j
zj6?%`T|z@|-?(s8eZI%m&FdC)xfGCSK&i8X_ceoKyFCmSEj4iSuF6j*(Ew!~=bd_i
zdnUBDO<%Uypt{f^i9`d~bIUv1J6as=?HwEHYKqeI*hw{jU8_XLRz<}@MMa}nCsT`^
zbOV6i$gr^0(8$V8Q6{BOMFDDYu?dOFq?O8OK+}rUVx8i8VblOR888Y)!6*O%07V4R
UT)P=S+yDRo07*qoM6N<$f`F%)+yDRo

literal 0
HcmV?d00001

diff --git a/assets/images/flags/bol.png b/assets/images/flags/bol.png
new file mode 100644
index 0000000000000000000000000000000000000000..4996ddbcc30eda9b529fea925dc6f10456e3efec
GIT binary patch
literal 668
zcmV;N0%QG&P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0004TP)t-sM{rEg
z!WsDM760oL_~R7$<P-Sg6WAUF_u>=)dOi8<75L&5`s)?!-4*}p6!P5^`Rf(_>J-|e
z5&G&C_~aDs-WB=d6YAF+`05q><`eef6!z&CxvdxR-WT-X694NHw=@aIvJ}r$3I6F6
z-K-Jo*&F`n6Y|~{)WaJ6=MlxWD*ELVkAxTE)gzvt8PHM*!7T#9tPqwj2eD@k!&?lt
zH3`SD6!_{E)M5(EzZ~M&B(=F2$hj)2ZWSab8}8W^_vRzilL*uw081tn;hh5i>=eDI
z5y3J8)L99ZFbCBd0Dg%vst^I|z7|ARBQY)!sd*gAk}b4u55!>%Z;fQxp9xMW5@LW-
z;-LYjqc7Au11u~lWMC71cqE~R7|3D;oS;Rj9Rf~WRA7HgLyd5X!AYfd9g56}jM0#!
z!C)|yes_~%Ig@ixo_n&pC})gCL!*Kvm48Q$c-b}qMxT6putP?dWk;iatDG2WkVuZX
zcyyBGL;wH)0d!JMQvg8b*k%9#0NF`IK~z}7V_+BsqhJ(30Xqd?)PPX~Mh!qRfP(@+
z$N)(-4sCfp7P1YH(y(^5*OTFAA=3aBO-sKRe>)vHR`LvBQ@8SsO^Wt*(3NE)#{e-^
zn}GPVqLhR{TP<-`a$H~@lvq)oo>36zV=PUU7r26pOAAvovnstzn8-4K$s;PSq$)or
z(n()}JQrBFM`Y)gg}4|f36N!gu!^Z?SaP_tk%ABpSq89(GMc%CIvOf6^0JVbkVKT3
zxw)AISy;%<3&dq6P71)N0iy<t8h~WLC>RB!00;o`?qpIZDJ@R`0000<MNUMnLSTZd
CQy`oG

literal 0
HcmV?d00001

diff --git a/assets/images/flags/brn.png b/assets/images/flags/brn.png
new file mode 100644
index 0000000000000000000000000000000000000000..bd1d1cc9a2443c1d49897f676f7640a5daf1f7cd
GIT binary patch
literal 1957
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

literal 0
HcmV?d00001

diff --git a/assets/images/flags/btn.png b/assets/images/flags/btn.png
new file mode 100644
index 0000000000000000000000000000000000000000..962e5e5bb46e90ea42ebceaeb754a7c7ad57b26b
GIT binary patch
literal 4013
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
KreCb*6#g%F1Oa{k

literal 0
HcmV?d00001

diff --git a/assets/images/flags/bvt.png b/assets/images/flags/bvt.png
new file mode 100644
index 0000000000000000000000000000000000000000..4acde7fbf2e00cbbbd9de5ff2716f3428bfd3fe2
GIT binary patch
literal 147
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSJOMr-uI>ds|NsAIP)q)zVSa4)
zIZvQCV@Z%-FoVOh8)-m}si%u$h{fsT1PQkWpu+!&tC#(2Z{j~3-C$~BBBCL{#meZy
qQLxsDkvl`#q3y6+*co1B1_s~BH_RBfiG%<RVDNPHb6Mw<&;$U|_AFok

literal 0
HcmV?d00001

diff --git a/assets/images/flags/bwa.png b/assets/images/flags/bwa.png
new file mode 100644
index 0000000000000000000000000000000000000000..5b7eff92a31f28695c645d39181c4aecdc408f3c
GIT binary patch
literal 134
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSJOMr-uI>dsrK@fOdH?_aS1!Ha
z4rDQw1o;IsI6S+N2IOdXx;TbdoK8-VaBDCXVP)wtVEp%A;{h}CbuEz%2@6;ZWXujJ
cXGt(JaPDB{xf%0S45){})78&qol`;+0JQidng9R*

literal 0
HcmV?d00001

diff --git a/assets/images/flags/cck.png b/assets/images/flags/cck.png
new file mode 100644
index 0000000000000000000000000000000000000000..d255ab91ab79c85cdfa733e57159c80c0a231976
GIT binary patch
literal 1139
zcmYk4c{Cda0LH(F7>UHHT0vP|sbeeReAabX(0FD+>KWFiuA#0{Gu?Yc#1$E#bDu53
zv^qMp9d)1MIa+a4jBV}Owc5>E+q`+R^uPV_{eIv3{{HegKAu#vE*SuoeTwC$u*>VH
z5*4hymAR#mTH>jXlL6Z3>kvvUX?lQ?GRK?i?wRPlzX@U{l=wg*py2-sfsbb^KnB#Z
zU?|2L0t`<<MSw?3AZ3D<4SGKQ-GF%!&bPv=2Koi~uolXh(9DHL70imjD8!jYq_!ip
z8O~)0x{9Q0_(_J|agYRfCCA_ED7_77Kd9MI%>r477pw5E$K448UV%XYs=kA1A#RW1
zk2O4AMpO%A^LV)iBQe}6aOno#DnQRDI)@P<MYt5n*PxpZoqTBLVPg@TI`BKtbQeF%
zP}_^|XOMFf1C#huj_4LN_an3k^?f*$hl9BYXu$e?aO<Iw4RRLVDaPU)3cIl|3->CB
zzQx`TI9U#-QVdPv^LAKBKoR1DN=#0}@hjXM!S)(PrV!HtmkRKj@JS<rucD|MtV;OQ
zVs{;H<{<uSY^~zy3Z5+Ep$v7sh;2n*Cc09fE5eUGc&{AQKIk6BjvVbnsPV(nJhmU;
z`6?_W_-h@5lh~7^H3^QT7?{8}!+1K2y$yIvpeKS`6#6I7H;%P?u)2t2g}6S5NGY^(
zp_zlqJ5U#5c>%5!5O%`41Z2OQRK-ci7yW$vvA@3`mAaph@taBTt|36!XR}<nfg@o&
zI;oMTC03&I9yOptiMkoyh(sejo^y(Tv8!Uup7}I9yvy#qX~PIHmtb_C|3HV@^3hhp
zL`&`R*y`zn)r644VzFf`U3;#Fw`DsK#?M3JWr73Io30agT|3C?faBrNt<f-kZ&7*m
zF$W^UhIu@wxh0{$D*A=DjsFQo9>s!3Au{5|(^Le0)2n4koxfUFNen15aZseZEWlEG
zMpO1YBG!#;$F{d;pLtt1Vm^dJ5@kh{BuCOyY?*Dt+zYZrCbR8v?ia~dqRS7RF7c#h
zxk(600sf5C3$~)|p+$Qp(}63nqrB{}G1eQbkyHs{_(sO`SA11!1yjw#!_eF;*n(xE
zdCuihPKA%Mh%n=Nv^`GW#m$n^CK@O#UQm^q+B!MYrqpbrx1-E`9kg3--N`QQbfHOG
z1;w2Pzx=+!8gB~UOLOJ0RilJG$4|iJB>$hBFRd)Zy!eNjb5qkEC6=M#cH>gd#i0Y9
zpLr0+#A3O(HBCb!L_WJz=R_1{rdy1Z8Sm`m+49?!pD2_3yiC+NG&@&cdPO`bZBnsv
z^#dnWg<hARDe)M-z5xN}LX9_Y&nv<Rw$(>sdW>X9Kl^?L!%JPF!PDAoG*jmio6RY#
s^rJ`S0|#S3d6&eG=t{FAdkmTJi8!kslkBA(6{0u@*zP{88*V(of5vX4od5s;

literal 0
HcmV?d00001

diff --git a/assets/images/flags/cmr.png b/assets/images/flags/cmr.png
new file mode 100644
index 0000000000000000000000000000000000000000..2bc6ad13c4606109b4ab2a5e128aebc378c477c5
GIT binary patch
literal 402
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!I14-?iy0XBj({-ZRBb+KpkP;k
zPl&5~fzKI1HTy`PHxs4*TogMesCG_Jm7yvQ$Oe)S21Fdlc8K(OJ5~CEwCcO*QhzRr
zo)=U7eL?Jwzrr~Y)z`h!=Y&;1ERy_rOzgU)(#sZ^Tds<~&x)OwR6Q@D`m{*)X`$@%
zYT5Ims?Td=KQ5E}xK#3SmfYh^xj#S?d=&3^E5^lII{{tAQxfDC%rGAe-oKweb?Vu)
z1v7x+(>z@qLn02py=KmT$Uva&;f33hLesyvy?FcozwIVNnaTc19QUm&Hp$(brV}fm
zU^3yF_Pq*|<g@C*_m;7XMc?zQ)l|7B1T<$q)3>z(9m$FlmKhxoYyHYLsrlN@g)y)7
zK3X4q`J#ho=jN~b4!w3fX3Lr%@V(kcmtobjvV5(2h22xUrd~fI-LdF=*Lxm@1M&=y
e9EBG;eqr0w+_Y1+?$Q#V$qb&ZelF{r5}E)C5~Z^M

literal 0
HcmV?d00001

diff --git a/assets/images/flags/cok.png b/assets/images/flags/cok.png
new file mode 100644
index 0000000000000000000000000000000000000000..49386516dc346dd150a2175918135f2fd6621b29
GIT binary patch
literal 1416
zcmV;31$X+1P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00009a7bBm000ie
z000ie0hKEb8vp<TYEVp6MMrQ<03?0v;_1>OH~=4Q&lD@q6e|E9Z2%;F03>}DH;B+2
zG7v0)@YvqdWq2n>k>6%@zQNZMG=>~Ji_zET>YAkg|NrX2%KrWR)ig-iNLtO*<?ZkG
z4lso8w7ghvsdIz003?0S6f6J#|Jg@b@U^`D`}_Os?hP-4&(-D(E`wKZsRJi}8$65D
zFhmhEh6X8sI#!!{jk|)BzZN%$2`qvyO_lP)$p|Zf0wsO~D1RYAjv6|OElZRsNRoMn
zw%L%M+l-s%>hsepK<w`I@bdTDPhi|uX7tO@c!##yPG9rH%Gi*g$P_L9{{G0&;}9~1
z+1~4fmB0=#gbFNz@w~%4Sep_whD2YWafP;PfV3GoiGGm1RBfos(&QgMjU+>lCPa`n
zQkdM~?Q(^;fsDBJ)7R|p_0=^=dW^f(lcYXboQ|HwGEbM1p~nFweb(ISLtUQ~HHWpp
z*(*ttNn@g=veB`;*N~vb)7j|m@b*Vxp{%#mTyw1b{r;!3(&_B<ue#R6&Ebfc!t?d{
z5i^ByhPTnz=Vf}ZVRx?7Ph$P{_i=)>_Vo8ZTAlOe>TQ9vPG_Zyo5YEl!*7GNPiUoh
zi@MI$=G)-xb&0u?qR1FHiK4I19zKj_e6e$fxLtItvc1<>aH<F@fuF6;KwF(?eX`~0
z@|&s5Ol6}qQJ3A~?WwiX_4fL_#@)BU+I5JyY=E@E%HQGT@FPNwt+>@vYNpTD=Iq4G
z@3XquMpzv^jDnB5_xSqy>Fd}-RpaOJ?WnQt-sJb&-qnnq>6oJZ`T5N&Lgj&t-(_^*
zYI*Ibu;1hE$j#uZ;Pt2g001F$QchC<cYl9qfA4Sae}8{}e}8{}e}8{}cYp7H@9*#L
z@9*#L0fFMR0007)Nkl<ZSi@sr7zLwX6pR8G5S0)U5$1#dE+%GHZeD&UPe@RJm5+xL
zA7BI;AgL1S=W5)l2m)GaN=i!Vx?r}3r;nbOxw0Z&zyUNsAu9uHgg%M^Q0?hPgbm;@
z?SUHsGXSn#16@ZS76TL&;YRER8(@cByP={*Vnkq}wFQucY=FEr5OkhBee!6xatqji
zLnls|D=W8mfF!gL1}v$Wsa39AW?|e|fntE1DiYWUG~ghzfGSL>)x0X@SjC(mW5o{T
zh6OrE2CymN1rUWR6QdNDwZ&QmD+XJ{#w=2tA74tE0g-j};npz6=*%@)Sl0<RKuQG(
z>;h`pk1U`9Ru@v<u)+{2JeQU&uQz}hAgu`k$;!&ghtu|f15sJ|SXx^58L+q}ScA1<
z#43~+DNItdMv6v7jZ7D1Z#O-MJzxWxos>P?ogGv4VaoH1f$l~z0LUvw7y#35uK`U+
zrYR^!<OV9Y+o2^Wpjc%I!~j{icBG_?YQ$v!X&8yP+20820vWh=l+0w>1~CG}HUmO*
z01*QjAl`NSh&?pXhV=US`u5vEIHoBF_U`BcN1}lph5@!#Q;-4?KPZ~vVv8YYST#L>
zNCONaXS6K95Z$=8Aj*nJ7bwPrM`MUZ>uw<03yL-dThRTGWD{aSya5JHo0HIlB37@n
zB;Ek6?aGabC?X~6m75k5Z$LuARz*cal)_18O=3Lp1}G|;*lybtRs`kD4vVX{GeIsB
zi2(7H%0ZT;`QeKCI@LOP%5gS|BpRStGpklH$3I9hFD^zgs$z~JsRmdED+XxKP&QJW
zq+BqyRWX2M1HfS7gzV@rqioE2fmmPyih2Wm@(sXIwNYvS3p)jXWwd!T3P!;wfCB(7
W4pLx#hQQ4L0000<MNUMnLSTa3lC0?f

literal 0
HcmV?d00001

diff --git a/assets/images/flags/cpv.png b/assets/images/flags/cpv.png
new file mode 100644
index 0000000000000000000000000000000000000000..0683d931f40253e3cf325b609554383517f8224b
GIT binary patch
literal 297
zcmV+^0oMMBP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0000yP)t-sM{rCk
zP<#LP)&KCcEmC<)WN6j282|tO&JiX6IFtYO(*M*dz^5d`sUr+Oj0ruC|NZm-*+2jN
z_W#&C`WJ&Q00001bW%=J06^y0W&i*Hn@L1LR9M69l-mk`AP_`LQ@daP|6dD?5?xW$
zUSiIZEX$dNVyX%NaMNV~0R#|)1Wl7C5Ys491v*>Gs5=OO&R*(zj=6)nKxez}Sb@%V
z-(P-4_0spsfto#70)A}VUZG}Qff@#Phno2WJ7cT8Ld`5eo55cM_z%i=qS->}jTGCA
v{zfvJF{P2rW=w0OV0J(d&Mw)B0Dy}VO50DxlNzXC00000NkvXXu0mjfuugvy

literal 0
HcmV?d00001

diff --git a/assets/images/flags/cri.png b/assets/images/flags/cri.png
new file mode 100644
index 0000000000000000000000000000000000000000..029bbfc4981c51c45fa2c46419cffc3eff64a0f2
GIT binary patch
literal 136
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSJOMr-uI>ds|NsAI(5^oxsFtat
ze-S9oSQ6wH%;50sMjDW#<>}%WVsSb-LBg#eTa+upL7nkhfQW#DG~>Vj8V?SC5L@6s
ggD;>-(v5*3dclmcD_e?Wfw~wxUHx3vIVCg!02gv5{r~^~

literal 0
HcmV?d00001

diff --git a/assets/images/flags/cuw.png b/assets/images/flags/cuw.png
new file mode 100644
index 0000000000000000000000000000000000000000..92a36b728ad8bfae0f3b1e5cbcbaa61322b18f3c
GIT binary patch
literal 481
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!I14-?iy0XBj({-ZRBb+Kpx~|m
zpAc8~0-qnxMJ}FH`T0VGLA%~JHI`Ak4#)r^s7PAurBf>Z|Nr;OSW?ur!#rZvzkmM}
zT>F3i`m^ukJ!aj8_n*GA=ruM?Kfq<&a{l^rDTki$;#F)0O^iDAs$LUCZ9D6x>^pn)
zX?fo+*OY~VmhEN{v(&sM#Z;{2GjF^5=-t_?&o1435nr|L>$hK36ZSCaG?e!26t?b|
zy8PtS<)<`#Cttt&YWA8lv)7z`{NiKvq`e;Li@$#VRX=54qEpK(pf9*eg8YIR-oO7p
z_5J(#@84@2bFu)6ZufL?42d}W_L@6ivw?_fpn^lgk!9Dv+^f$2eLrlD?uQ8-7xp{z
z_x;g5y-6i7#5L%(!zu<I?h_h(9Dxr?85@5KGhQnG*0)LJ-2Ubt$8NAoJuIn}5lEQ7
z<oMnE#HM@AjqFU>(hN~^&fgV%{@6hMg6vP9EhV4&4elC==`<LBh?&oNLh;t&n`*C^
z9d;*2+Ad%6y`iCqQI@fUQNvfkl_8Dy#2;=4H-<=tC}xkvt9={-8U9>cvcl^NYti21
VoW(DSeSltI@O1TaS?83{1ORaM)>i-k

literal 0
HcmV?d00001

diff --git a/assets/images/flags/cxr.png b/assets/images/flags/cxr.png
new file mode 100644
index 0000000000000000000000000000000000000000..e644a49ea96be08fe5e2865520ecd6583398964b
GIT binary patch
literal 1202
zcmV;j1Wo&iP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00009a7bBm000ie
z000ie0hKEb8vp<TI#5hhMMrQ<8;L>>U2gy(tQ?9$034Sbib4P!mmG>h03odiJ#`z2
zLL7=h03oga#yJ#hU>k`-1~--d#W@Zwu@*G6ABsUflR$W)J{^id%D6l7!Z|FCK^}@h
zytF%Tpg#Bb`~oAbAU(G~Six$2&rO#=9Ew3BKe*k!I(DHxCX7L$tvptlKME(PP*sR?
zp+1IpZ&z7`<i9#<o<34mhm5B^Z=gPTqCWh@IU$Qd@xnRq!Z}c9#{?y=2Pd!A-0})3
zu#=(OBtf_ZC9b2bJUmsvm8v~Nlt6u>J~NO(FONaZxH?prKcukXil;qKX2!|4JHxg+
zQfbHg`~4+Bxg0sRc8AhVmq4w!<OC$HFG{?WsXcUt(lk%L5;3y1zvmJ#vJo({yv6C$
zx;kN;Kk4lFaD&nG_4|XRJ#~lD{{H@{wBuZH$_y*83@fo`ojw&av%16S8aTCEnm^pU
zI#`)MUYkGf@%p*K=wh5dUz<N!nm;*_Ky05rMwLM5w?k`w&t#oH&bc}dF0s7C>GAXW
zCyYTuTf(!kJPawP{KYv)l|U|zLF>6fU0s5hsy)ZIJJ!28Dvd$WxjIjmKZd3~zqLE}
z!#S+5JgToe<-a=GygDU}L5Ze4jeKl{r9Hj0JGHVqA8%h4LXKi!fRBA^ji^2S#W~`>
zI>oj-!nHf}!#PQnK%1*PnyWnOxkBl;LT{fwTADwXsy&vfJ@~{qIFUedpgym#JfN&R
z*t<F{jzK7mK_ZJmnX5g|WJI<A000bhQchC<e|PWiXm@Xa?`ZFU&cE{j00IU{L_t(o
z!((6=1*2dTi~<;7V&otnumKHV7UUP;Aq8kkAlNKG12}nkNi(8BwiVp~(u|OpHK`lJ
z0FsO_;hP|hX#fdE%(mj|7sX-#@kYoA@fl$?fUps@vQs9@@bFCM>%(S%0ue@Nbn?wK
zlbFHRj>Q1AjO={EMra%I@l93dYs6xJQf8VWnn$F?wY0>g(bAF0G(J8)DN#%V3JbDC
zP{Tq_iVvh#4$To=Ku7SUdzYx9he1v*YH*qgf%Gq1A!~~64Uo9HPz9D)Kn9B}B|!>T
zTCBF5h-!d1P*}*Tln1*334y{8#$vt&^CXwA-OaOgl^%+I(PE(_Uoq_I00=^Z;vkGA
zd}d%pd$tR$LDnzk9}tF?7n+0-`V~^;ed58ax$~FK5d)^09ejLy5!yYYB$Lszvs!bx
zBEp2&kYEU-7Zd_k+jw^J@onI-Fsi9iQ7LkFcJ)AZ4a9)9mNF%%ZYLzabo78s*t}~C
z-@1hYJgU`|dK!6dGN{1`^+LTeRF9*B3z7-O=0F2BZR9gI#+f?N15wz{8aX_5>p*T;
zuZuf@qZ?prV~-LeItKds20D0hD&B;I2{4Ty(Ev;%NHzf72vh?iL`XIQ#Q>4;#7I(I
zfnq>Rio74G9zpejax}?dK}H~=8bOf(AS1Ye2C%YI0Juh*N26dAi~=|S0A|UcQ9Kn$
Q#Q*>R07*qoM6N<$g2g8g?f?J)

literal 0
HcmV?d00001

diff --git a/assets/images/flags/cyp.png b/assets/images/flags/cyp.png
new file mode 100644
index 0000000000000000000000000000000000000000..ba5246809c95c86c26bf5a529ca841abdb95e69d
GIT binary patch
literal 1128
zcmV-u1eg1XP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0006;P)t-sM{rF4
z|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0|Ns53G5-Dg|Nj2{{r$1JrvCo^jhcP^(Te@g
zh5p%|{{8y>wLt#r$^EuN{`TqpvN`_u>;1Jt{{H>`;<o<Vr2V~B{^GU$yi?QI&Ai03
zS86}H!m)LQVz|Jr=<DVEu{e{UgzN3-uD7H9+M@l&ZT-%G{`TnoyHNi7_Wje3{^r2_
z&V&8MYyR-r{@9%Tx=sDhg#E~J{`c(u?9TnTNd3!s{j)s&{Q3Ugs{Zuk{@S7au{ZwN
zpZ&d7{_N2H`S1STto^`U{k~ZJxl8@dg8j5V{`v6zx=;PUUj55^{{H;^wL$*%=l<rt
z{kKN`<huUp$Nu>3{^Pj)$8Y_@WB%Qz{^!BV(Zl}k)&10x{`l_w#AyEe_5I0p{l#hi
z*P8viQU2(~{QUfnoPT$QWY5*fo2QMx#<pQ|OMi}SsIr`Bc~hjWm;KR+{@ti*d{(~2
zwC3sK{j)p$!C?K(fByUQ{QUc`xTJK1VT_r4S!_Yn+0L1zi_g`_^7HU~i)!uf>VlAQ
z`TF>Tl5$#YL&VFxgpzZLn0n*p-+GB>hLm;B)W~;-WXaINuD7CvlXUR%?zX<GQf4}o
zp@ngQUEAN*ae`iuoq)2tsJX$f`uq8(v77Gj>{e+$`}_KNiD&!!`}X(sn52r8p@w&d
zW&O!>{neEI<hk77*WKaR-s0M}zO2sF$XRScJyRjR#kFU7QvUSf(bmhBqKMw%*<El(
zg_CuXpM&IFf7Sp1019+cPE!Ec+W*gihS%Q&<L)gs0005UNkl<ZSi@sr7zLwX6bu)@
z$;!e`Heg}pWME^a2(U3QlBgpg8->fnz(I=cv}DE1XcQ3+QVd9n&yr3-6C=R@?g}oh
zSSe<54X9U8<dT==W+vVMS!V=0GCft3i>sU)i!$5>xNupD`dAC<3JV2AZ~;M0Ee|tE
z26%CyfD9Sz%5WQCg=#<)Gw}v^*c<Ab+lrzZpg^PnHayIZc3fCMXc%z@Son#VabX4S
z21FSUAc;-0gDaP$ydH635Qs&;Ff+H4C$p3YQ3eEKF+dDY3dJyhI}TmDv=BEb1~AK^
zY8Q8tz?(-f4dB_hUK66%-&D}p#E3v9!<rIzZ>Wn27x$GQCYNFwps@w&6>qdq=S?Ke
zfXzF$?F4%z1U38cbvF@b0I!a~R&5M*tCp=%n?$4m`}ZE)wFh0@ytz7a)QJtmeOd?B
z&hJ4I;9sq-wQ?!(v9M|Tx<$QxC2;;Mm4ypbmkW>(jr>d6+xS$K%L;+)jw!RJPo23~
zdj&H|B~n*z9$#reQ9d*O<cXbXGo~q%mXN?eNlB%+y1B8xWkM@2sVNZ-1ga`E2&P1Q
um1_=j1EHkMNO|>6aRXx%jDk@xTmS%+KWr^)MU)Ky0000<MNUMnLSTaO`;GPh

literal 0
HcmV?d00001

diff --git a/assets/images/flags/dji.png b/assets/images/flags/dji.png
new file mode 100644
index 0000000000000000000000000000000000000000..185c5322b4f9c75c872460a3ec00e6d3949a304e
GIT binary patch
literal 387
zcmV-}0et?6P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0000{P)t-sM{rEE
z<-B9bbD7HTcDU*D`TZueJZiG%|Ns9Itt;#J?#|}-{{R60;o<*RSO3h+%;oq0_V)ia
zHvj7C|MT<zAtC=rNdJU{|0*i~($fFc)fsTZ7XSbN0d!JMQvg8b*k%9#0N_bPK~z}7
z?a;{*f-n#SP*l{QS(IJ>|3jrLNoB?9;hH{h<8@D}s-&dkmq&eN=L?AQX(u2Ad&CN`
zM_7P6!U1?ATtJ9>y%S)J2mpLU1fU~g034A5pb<#`8Ib|#BXR(FL>?fH@PYRW9^nJi
z1dnh4Wz0Mqqp%SU(2a7**kL2Q6SR~%e9GIg*^CFY!_Wr*A1)0YP`dB6Lh1wHX+PBZ
z@C5Aoe*mR^1EAIC0b+d)AlGLAdVLZ=>Qewz9|K^01fcZ+fY<u~quvEr^$x(Rw*a?(
h1=#f~P*PH|<OBZoOMkfqd>;S+002ovPDHLkV1iqMu^RvY

literal 0
HcmV?d00001

diff --git a/assets/images/flags/dma.png b/assets/images/flags/dma.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f61af95e6fadfa4470974e4d8458453e325d924
GIT binary patch
literal 1224
zcmV;(1ULJMP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0007`P)t-sM{rEr
z886iwFx40?|NsBg8!*!xFaQ7m0Bb+|(H7SmFxeU~*c&j`8!*xtF4Y<@-x)B_6E8qV
zGwBsC(-|(%8!pomDB2k>%^EE!Pc+jOFx4C{*cvOs7%SNoG13|@!5Az1&=&sv{o5BX
z+!!w2MONMyF5O5fvK%KhN;6eUIkg}zt{f~$LNY8)G}{_59#b{g88D+IF3TG(#TF~Y
z7c0&jF3=e*)*3JXT`-U<FEUFs+7~GuQZ%9`FBVcUnqt&*H8ARcjQ6%0>vtov9W1UL
zCcqRf%^EMj5+qnYG5FKh>2D;`9WWeYJ;)j@)(|Gw882fwFeYI@dNMF~Gcd#xFZZw-
z)e|v6Q#&M5HHs}S+dwN)O*z6GEwvvlSv)b`88H3#_%mBRUP(FZi<X5hFUAoh`r6*u
z7AqlPJiZ<-sv<3xDKFnpVEfJ&C|*4F$jwbpIn)>}N>Do56e=!UJRoC0`pg$dQ99=q
zFa7%ZEnPnKts9&tF1H{q-%Vck&(qZuDdu~I-9Rh!rySB1E6y1%=W-*}7ctlrFQp_d
z))gwTA}-ArF6V`i))g_)6)NRwC9xbVv>+}mQ8la_CdL{qp(ZZc8Zf3ME~+Fhh%PVJ
z8ZN9PF47w<))**AMKX{oEQu~K(;6zeCrj5ED%Be?pHr-zD=*O<IXF#3qDhsOCn$nd
zv6M!ZmsPdQ89F&kG<RaPk6E_WASqs1p1fy6*C8#yBt)iAsvTNUh+VqEDO931b}?I9
zs8=G>9y&T-cE}zt(j6!VSuP7!I7CoeSW|D;8#1Lf5W^!Tq$V$!C@#G#Qg}sf0An)U
z8Zet6Fq$?CtRgO)Bro7WC2cqvYDX;ADk>3SFTHIOg)=J0t`THh4;frq1YR}YH;<qI
z0004WQchC<K<3zH0005gNkl<ZSi@sr7zLwX6hHw7F2Kpj$qoc8EG#&cj2bX%038g-
zukDy-YO2%USWTV*1?rtr7V~EFi}f_rkYhkmahE7BpS7Mjm+?eqEz%8$6z<lXr9XG=
zBDTailJ!+3q#EF-%vd*dhWN(42W7adgtTX>W#Kk}6AMsOmt*3Y&b@W}mJK_X@w9Vu
zDaR;cQ-{+4XE}d)CLY!u2lj7UZ!XQnlpP-tPLcsG?wUc&OsqEh4((pIREAeXC@Rbc
zrvdC(fSZS|BO|Nyl3klESFhq_<&F-O*TAL@rvVDSf%0su((_mBIcB*sk(F(x3Y!9H
z2C!b#XJchuu*Tu|1zj~(Hhyk4S&|IU5lPE6WMy4;&f&ySTTx!d5HC?zoCdI90jcQ*
zLd?9ZCvDE(w>L26DNfMybi$?%rvVvaIohmT%TFJ<bL)Zq;h9VxaRJ^W8K9I`%EirR
zc<S=)yZ5ehOK>w~sw&|$0Bag8SD86w;aPsOo7ZkwUD;$bQ!SX(%v34dYp_^=_v$67
zi!&sRgkwq1&RWcU##|!Sl6*X7ZN(|%6ewja6Quah*zt=ssV0+Gq*b&|(l9ld++3J6
mS}%+mFcb_J1*2dT0098Pi?3eDJ`{TZ0000<MNUMnLSTZh#P1vc

literal 0
HcmV?d00001

diff --git a/assets/images/flags/dza.png b/assets/images/flags/dza.png
new file mode 100644
index 0000000000000000000000000000000000000000..34228422334bbf6807ad5b7e2b68288aa1f81ec2
GIT binary patch
literal 518
zcmV+h0{Q)kP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0002SP)t-sM{rCG
zbUe%wCbk_Zc|0!%c03AoJpcdy0D3*n5hj%`EVLdeT}w0Rm7es=&;0T7;&Xrf^!5Gs
z_vVC;_0QCzCo82UD=lL<TuU<~XE_~fIu>s`{{8*@@bUin`Sr}v{rLFfd4&4u>+Pwr
z<9CD9EkNF1ZPO|}AZj`E%FaquHTBKW&lf9lKrr~*-YI1`&lD--dx!0%t<fJd_SM<<
z*xUa6{Qmp=cReubm!ac!g6f*1`sV27hmq%rl=jlr`Qzp1jFteE1i1hJ00DGTPE!Ct
z=GbNc008buL_t(o!|j#F5`r)ghDCu0HU#Xwiw%3P@BdQ9was{N++@bnekTsuZ<73*
zB@iG8;z9T;>?<T7!A}CscWrS&cNj7_t;tA8psj<(gYnkJ3koTyHDmEaA|7kju>vi9
zE009=`@&?SiWI0&-+QM}!3pwk{^%>lK4T@605)LiPr<InSQ#aN{IbwUhs&uyu#hPz
zkU$0m=NbQO^TkVqAO`~F-pW(xCTCHU5_Ft-QSb=+=Mh$dm*^Z_4}FQBF>cT?em0Va
zZ6xVdmVZpr&zbK*eGe4NmKkXs!I1{&zMG^!6AAt!AP9nU1$0JHKlNx0jsO4v07*qo
IM6N<$g1J%n$N&HU

literal 0
HcmV?d00001

diff --git a/assets/images/flags/ecu.png b/assets/images/flags/ecu.png
new file mode 100644
index 0000000000000000000000000000000000000000..efb3acb43c117fc506f992468e2cc69f46b666bc
GIT binary patch
literal 1238
zcmV;{1S$K8P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0008bP)t-sM{rC6
zO`-u!qWjta?b8bYN2&hZ00T~<|J?xX93<`24EWao1Wux{uP*>dsQudj`q=^f+yL&=
z3k*`922Y{!&;SuspdwtIo`x0xN~aH0qaItN07a}raC-tyqv*^J|K<P>P@?tK1Fw)N
z_t^q58yxJ>3aYC!07S0;?EuT3708|y@z(~~rx2`H2<E>ASU($Qd}6MzFw4Rlb(ELC
z!6q3|kif$vRV#4mG%jE)ZNXwi<i!R@GAFg3Bks=!^U?r0BPNxBFaSuZkts<4N2GKv
zS=GNO-M#{dcuF%IAkDH6F=d%=h+5LXH`>E5x0?tkVu^w-R9J#wZaZ8zYJN_AWsiF<
zx0xzbKP56{m~e?$T0<J%%@j&EGKQB)^VA1^Z&;IpN<1YV*~2RK)c`CN7x2^*oRDqS
zvjMEI4nJ^rcRX3v#~s<pC5V_v_u~R-h+O~Z0DxFf$iWFFia5%x1=7DX&%py_Q&zyL
zUoaUM>&pR@T_Uc95t(Hkes@3T%@<mPWPEx=!nie6frO}l6tZy*sFH-6ct$rKAi<>u
zc7`kfhCi=u4O=%Zo}^HMXF;k{N*8aSwU#Sghhs--a0FmyxvEu1n6<~mA3vS39dw;R
zev{rMDt2W`u2f1PGm#*Dq&k;+I)9X{a!*ZvieRNcVyaNZ!yyuMlZR<(YmlD2m=_^_
zrbCW`NtT&-P$N?^a%EkVMuC&jA1ffN);5o@XsAfDR#_jf+*Gbms*ee4$V9DHTt78>
z%NsHed7P7<qP@T-#}+U<mVQZ;d_gpORFqOrFmq<ZLg&u}yS^*8rU{{e2ac*6Pn(%v
zlWmNeorJ1fsd!9y%j<opVX>!L-t+&6$=Z92lV_qbYL=akj4rOc4RL^E!?hERsTogV
zgkP~xGloHvZfItxiBqG4X@iF%TV_sumR_j5Lz=nk_xt1kqK;>r8vp<R0d!JMQvg8b
z*k%9#0k=s+K~z}7V_+BsqhJ(30S5(O)PPX~Xl?+vcX(n(Ivc;gr<0ux8|em!N<=1C
zcXd`J#i@EZ+DZtJYyca-U`@9{e@A6nOn`@jC>!ZsNRS75V~?sqSt<vIygkWYVCLXf
z<~}WOZlg8_n+mtG00%#b1_-1mtv&zn!Tk#xCJ2;dX)C!4km`l<DQ9orz5eFf<(V^j
zN;4z;*hn=%Q0v~4M|WO7dp_G_T5pB6AnCE7Yy9%n&9^tM?%K9xy0I?4SP){t1YBHd
z`e#l)eR1p3p*2fZZ!*<a<Kn`iObBcMJ2oJvVPtA`<?+Q6%Xh3;YGrPuA%|5NZUfj^
zc@JAypE|mI@$S9W7N)$c?4%p8^0?)(gL9XyT5q|37C8o}>zEzcw`lU5bvqB3>8O)#
zfK0yT)XnoI85%Cwy0A$zUWRlR$SO3NOw?=d)0^L_q99AM3z)>DqjOst>T2uTn)70P
zrNx*?G=Nc<hc!yEupp<nC|l8ok4Ko1R4*_xic3j`h6RNL2l7dYGcl4J2JAc{Oze`b
zE^f|}>`Wp!)Ibd2qyUT>Flqqx3>XEYU=#oW066Ei|7lqACjbBd07*qoM6N<$g8Y*s
AD*ylh

literal 0
HcmV?d00001

diff --git a/assets/images/flags/est.png b/assets/images/flags/est.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2e417b93016d9acfdc636f69f9065c42e6e8dd2
GIT binary patch
literal 130
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSJOMr-uI>ds3`OVv|NjpZ&^JC0
z(!f{}<QL4~@a#q!kfY-1;uvCaIyphYt-(};m4!!}@!x-q2ZuKZJ&0;$6648lOk`p3
XzTelNGWn%GP(6dEtDnm{r-UW|?oT7%

literal 0
HcmV?d00001

diff --git a/assets/images/flags/eth.png b/assets/images/flags/eth.png
new file mode 100644
index 0000000000000000000000000000000000000000..5b4970a6779c099b5ded6d86689b13eb00674a09
GIT binary patch
literal 1584
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

literal 0
HcmV?d00001

diff --git a/assets/images/flags/fin.png b/assets/images/flags/fin.png
new file mode 100644
index 0000000000000000000000000000000000000000..b6bc2f9a9f572470302bd09888ffbe96060b5474
GIT binary patch
literal 131
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSoB=)|uI>ds3?`NT|NjqhzIPEQ
z$XF8O7tG-B>_!@pqv7e|7-DfcIYGj$A^Ym8P;ckOVU7ozCh8rK>SAJI^GYy@3t(*%
aWMHs&2+T0Q%Hj{y!{F)a=d#Wzp$PznE+jet

literal 0
HcmV?d00001

diff --git a/assets/images/flags/fji.png b/assets/images/flags/fji.png
new file mode 100644
index 0000000000000000000000000000000000000000..4700ad579f01011218eca0ade84690d701f28496
GIT binary patch
literal 1571
zcmV+;2Hg3HP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00093P)t-sM{rF0
z>gp#_sRK2d%m4t-4-Zhf=25la05h5Y|Nk9IrO*N>QnumI11bIf{?Z*C;)javsHo8h
zE!<I2`TG5PmCE37asK}Q@2;*%zv^a%!Zu#7*Eu;MO{TxA!r0*N&=nO?w&Dpooyw=U
z$<*o8Cnrvw#e|*CevrdU!0b+*#obp|NweZduiH+W#!a^5(hxM!3oz6LEz%1yQMltz
zsnJKU-un6Z+W;rsR8($UedB0;(F7~^!pheUG2KoZPq*ZIQgczH%S*fGN3Pdyr@%<E
z;9-TO&khcFQFGiuUF?yb=DGmxovh+yd$t)e+chWTS02^?AJrQ#hMu)Zw&L&q`s|pf
z?whOH03k`d=;weIhMBSCYKFQKHrYBT_OuB2$Iv{HM)<=6)e1AX5jAF>s?QEI<*caJ
zJSE#NB;lpA)fg*xlgQacMbQ`-a8`Clu;9N6EJ?fTO}pq;p~7dQy}UaqU8m7avfXT@
z#7?{CPpi~`tGCzK*`B=2Yk!{Y=;pW4*yQEpeP?OX<lpr3?1ZhBT9CB4GApJZKHEYf
z+6*X1wBggdSk=s#pC(3+yRzlRQuF-!r_#IKTyWNTfMslt@4o=rwgA>yZr<<X=DPy)
z;D~&+dE4gX-;<&1>+9j^=-!Q-(}Rxe_Vw(Qt?7`V=UNf^|Nr{<$G9Cb>)A=}*gE_6
zx7}oT-s!vWsR`dj43NIix+pKw03YUTijcX?k-g7$Rd~M(EZ<rl^S`+F(g5apj>KFc
z`^W;lK__-=huBCX@BH!Pa)<oM)rYvu(Eu^hH7EA}{o<>y=XMzFqOj_&x$Kgq-1+S9
zw!pO5zR#SVy3n+*)wtc8jf=pO4`d8Vkxa_*+ODs915*I#?&bLX^Xj#=*Nc^OQg(NB
zir`~Y;(2UfgIDJ0)nSif>FU^*v6$Xi8|I)2*$NcX7c$!^D)Phu^}hq|xC7apsmG6)
z-e`epk7|9XhSiUlM}AM`ix6y%YeIQTY?*ZMtGLzGx?!Jl^po)=00001bW%=J06^y0
zW&i*J(Md!>R9M4fU>F6XU=%=sHlv6rGY1riv$Ak<!8lR^{DSOw0oVXB1qn_SCQJil
z<z$2z`G_!pNm&))2!sJ3>pA76i7<eJSp(q+m;n&$)s;AiF@S>u=m<-QBcKLAtp`dG
zX8^(xU<2UR6K??A5g-F{;ntI40LT&f5}ces1M=Y36K4P?3IG~_0-!2Q*ie88vH>0}
z_y9zqqN$penwplLo}L;I=&70VAQ^yHzXwF2q}8st)YQ0x`?sw2_wOt(Dv-qK1r}Bm
zt~k_yoso9-uToO%f&&5r1G+67B{2h0Nu7^TI1g-qM822?GfE&v9eSMk`sdsDGYJQh
z_ihaC!D4{4Jf|SPKrYAtQ4vN<Rb?g=10Fre{P_Muazb?c;gh?gS9qcu0JdI6PL>N~
z00)x_r-TC35fFu%58q_vyvxc-Pq(+XJ0Y~Gr5M!!i1kt&91sIIm=TVEC=8AH`ziZ#
z_7@?W*o&9Xo!%4Ei);YQdJeb&90*516zZov|MTPb|L;cJ;kS~KuAkbhi(~-YdSnB@
zj?e}=0%pL|mtTK<dtk(U{_2f8H}7sYLoxtvJ&FM^M?e(19l!VN#lNt#+}sftuH3$K
zWCyYf;MSuV0C5B~3_@)0XJjPqv#~jvXnXCLZHOC^0qjHoO{*YdV`Cvh0|P@LLt~*x
zlxQT%fazO#xw*N83=D*T6mO7~CW!`Acg*s$w)XQfH1x8L-L`(JdkKjKDAu&kUO72z
zfem*!=eiA3T1^#6G=SZ#w$0pp{$d;MWvk}QoLjHUPO1S8PIa6M7x{AYE??_2qtD5K
zWCPfB${Nj=MsRa`uko2wrNd6T0X$}|&3wMxMoZ@PyB6}0VE{XiTWOQGg~haq6>dE2
z<QTxtqwnHAp{t=%pNE}11As<2>$*5AVifD_BmhMdEcF6A1z^;G;bXuk7zLvM2mss+
V--yx6DwF^K002ovPDHLkV1k_c9MS*)

literal 0
HcmV?d00001

diff --git a/assets/images/flags/flk.png b/assets/images/flags/flk.png
new file mode 100644
index 0000000000000000000000000000000000000000..66ff172c28c6efd1a7afd7396d809392bcedb848
GIT binary patch
literal 1591
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

literal 0
HcmV?d00001

diff --git a/assets/images/flags/fro.png b/assets/images/flags/fro.png
new file mode 100644
index 0000000000000000000000000000000000000000..2c3ed5f6bc5ee4851653d4286c3d2da300a1ecbe
GIT binary patch
literal 147
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSJOMr-uI>ds|NsAIC_46DTX*}y
z6|q2Z#*!evU<QY0H`0I{Q%@Ji5R22v2@-A%rY0sOU;l?M3=lBb!@47EZ4|3W1S>0d
rhromX{Y-Wj+!}b=d)Lg6c4J`ZpBJ#t;AhndpaBe?u6{1-oD!M<#Fj2C

literal 0
HcmV?d00001

diff --git a/assets/images/flags/fsm.png b/assets/images/flags/fsm.png
new file mode 100644
index 0000000000000000000000000000000000000000..b8aedd34e42d168ffc18f294864d9a2292e97a96
GIT binary patch
literal 340
zcmV-a0jvIrP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0000yP)t-sM{rD;
z#^$Nd>doWx`TPBiz~j5w?sc-=|NsBU;PL44`HH^cxYzCU`TT;p;Dx*4wAJmO%IBWR
z=lcBq=M0Rc00001bW%=J06^y0W&i*H#z{m$R9M69mdOr;AP_`VwgzPX|9>5v%w^1&
zbSw`}q>cn$=!I&gX=rHZBLnCW0Hr{H)*!$+05DrCh=jHC*&8g9y5w>`1mF6359A<i
zH%I^=hf+fZ0BbZRu7B9dhh?9c0DDmQ#c~1Cr@Twunv<7YfFMaBey_zqjRXgvwA;F;
z?zfh0)oH~Als%ww0q+pnuMi|Jge#H=ml1BHJJ~w?oO7rJG8EX-e7EHWm?~=P_+UXt
m+a<#l9`6tNBMl7=b-e%*FGCSDjgT||0000<MNUMnLSTZlubhbh

literal 0
HcmV?d00001

diff --git a/assets/images/flags/gab.png b/assets/images/flags/gab.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8e1cbd1fd83875e7a74f46db2c29f231c50d0dc
GIT binary patch
literal 130
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSJOMr-uI>dsR;5S&TohxNmyp}@
zSpX=`SQ6wH%;50sMjDW#;_2cTVsSb-LBg%!zdhFvgEcHW!WK5L9`<T56=7xJ$!|<#
ZVR-zmvo%T2z5}S9!PC{xWt~$(6980fB`p8|

literal 0
HcmV?d00001

diff --git a/assets/images/flags/geo.png b/assets/images/flags/geo.png
new file mode 100644
index 0000000000000000000000000000000000000000..46c83a5894551fe8074afe0d906b6c7bdd42c8e6
GIT binary patch
literal 187
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0J3?w7mbKU|ep#Yx{SN8&+|3JXNa86L|%Zal$
zoI}3u*%S?wWh@Eu3ubV5b|VeQ3HNky4DmRgoFKv4%+8_2tg7H3xL`5U!~pjYRs+Tz
zoX1|MNi3eB!1TmgNxOmDL9|0kTACfi6j<G`K$Jz+v&Ed<OmE7EriqIaOyYZ<ai_2@
cPT0V}V9{3c&`auB2G9xyPgg&ebxsLQ0F|^j-~a#s

literal 0
HcmV?d00001

diff --git a/assets/images/flags/ggi.png b/assets/images/flags/ggi.png
new file mode 100644
index 0000000000000000000000000000000000000000..fbc403f1616681ad5cc69721774a075166817c11
GIT binary patch
literal 892
zcmV-?1B3jDP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00009a7bBm000ie
z000ie0hKEb8vp<SfKW_SMMrQ<{{H^rIYa;d|Jncyz5ojU|Np)K3jhEA|NsBm01V<e
zLI3~&!3`I_01BM|2;bS-&unqO01B`Y8pJ3Hp#TWgl$h863&}!B*#HZ=01BP}2&n)G
zxc~}#00y)G3B^AO=hfE3ZF1nn$FB$xog*o*Y;e`6s>q$7;KatO6&;`f3E#oP{{H@-
z00^ZC63&vAwEzkc0065wKrH|QtpEwM9ww3i2!a3yK>!1l00=q&11SIkt}Qg+#m2P)
z49G%BivS0?dVa~CpsNZJ0RRBW5*#%E0?)Csh5!dY00YK^hsYBh%9WU~MogzGGR~^3
z#Day<$H%+?3akJLzyJ!>01I>g1|t9gxg83*p$e%^3AKX?$2JSVF$&WF3(NouyhaMF
zSqaD#3$7yxzCQ}q01LMr3bHQ=y)p{X0Sm8C3Df`!y*Uc9O$oO~3eExxd;kWSQV6(A
z3XMSrqDLrqKnt?~34|;SQ8fgaJtK@D2bLrVK_>$*1p+Pu0{0lA6aWAK3UpFVQvmPp
z|L<sbZ-4JS$S|A$00E3iL_t(o!|m2bQ^HUXz;O^PtjkLP4PB&&ic*vgqF6u_!4BAa
z@4f3+H#(yygh?_Em;4WTli4@F!=9c*A|@s#_ESTXfErjpArp||zk!iVE|(eM2iUuP
zgQIz~!C=mh4*I(7oPkd7(Af0c{KCTg-1OLxx05sAP7pFnn~FsfJxfT!&3y+t0ES+q
zs70Cq(D7KJZo<US`cg?xGo}eXKr%JS&;`T-%}l0}oPn<15RPYO%!uZh>^O#cyEp<J
zE)p3|Pic)t?NoX=LR=jj0jq<MAl3RE6(q!A<+=kU0I1=+uR|%T0ie~Z;UOBefLgER
z1N8L=3=l_*gCWr0#{+0XG{OMl02mRk_yH8WBYpsd*v1)f_IRjp%<}s5_F{>JDNm2{
zPe59BVpFM9evL-+c+Y<P?2oPNH7N_!HCO8Hx#GBv1?2E|mp8Z97pE02$g2RyXXhtJ
z`vL%f!-I<B>Ogx-ZGnx=Jz>Ds_OdWweRowDu(P(ZR28Ui6i~hRJQ5QV`|T6pBV05k
SBomYX0000<MNUMnLSTa6dui<e

literal 0
HcmV?d00001

diff --git a/assets/images/flags/ggy.png b/assets/images/flags/ggy.png
new file mode 100644
index 0000000000000000000000000000000000000000..a882b4a5951429aabdee7bd4c90bcc2fa96fce7f
GIT binary patch
literal 192
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0J3?w7mbKU|e{s5m4SN8&+|NsBL5Y+v7SL{Qs
za)H`x9-tIsNswPKgTu2MX+TcAr;B5V$MNI@3D#zI4kboKRfPZ-G07gTIlaBUAG87t
z&B_ktw{F~ci6eAD3sVDE0E1H_*D5A;9@bNSC%8g-3`8XsH#7!1oS4Y6x6^uoTd;^_
kWPidl*)^^gG$eF@j#4iR=bZ8{31}6Ar>mdKI;Vst0C7?}y#N3J

literal 0
HcmV?d00001

diff --git a/assets/images/flags/glp.png b/assets/images/flags/glp.png
new file mode 100644
index 0000000000000000000000000000000000000000..8bd0a69bf663de4fba86d0c6bbd02078e59f5281
GIT binary patch
literal 1820
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

literal 0
HcmV?d00001

diff --git a/assets/images/flags/gmb.png b/assets/images/flags/gmb.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa641ca1a08d685d06cf8097e9a342c6912f44f7
GIT binary patch
literal 278
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!I14-?iy0XBj({-ZRBb+KprBKL
zPl&5~fsa+W#yLT?qMBVml1HZJ-@ktl5g_^W?W2OK-9H{YJ}0CO<N{@ZYX1NKUs$#K
z*}Er&)w_N?d_3doMKz#ld?i7C!3<NUz6XN&^Fic$29NKvfiel6E{-7)hu>b?F4|xq
z;v6W=UZAx3|Ed*9jDdd_n;%#ka>8<HkBP2}aKjE^S4O5c49$#e4gUm68Gb69Vz}jb
zg<(mr2ImH*mf0GA44+mBhBBn8YB8~J{9v#bu9PiJT`C@SY<hZ|z?IcNyBIuO{an^L
HB{Ts5qQGjI

literal 0
HcmV?d00001

diff --git a/assets/images/flags/grc.png b/assets/images/flags/grc.png
new file mode 100644
index 0000000000000000000000000000000000000000..d7b37b0c70a4966b898520cd6351b21c3772442d
GIT binary patch
literal 436
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!I14-?iy0XBj({-ZRBb+KpkQNw
zPl&5~fzRK+|0Zm`_4nUD-njMu|Noar-2`Mn*!N$4*>U0d`TOq=U3<kJzg{SDgHF-T
zniZG(x7^x({`vh^U-)1ufhLHjY<lqOD^UH#2Oo~#dZP_gx%@Iv%dg*m&)s|X@b%Ys
zUw&SH^6}%hU(eos0~#WbutC3MS9sJ>psN_fN`m}?8Q#BtKXv~5`9SLZd>{bP@81io
zoz4POvE9?fF(l&f+iS=9nhkgw65X7bO85_Dcz>_@&%S19(-me9zgmXKpLvdt>=T+l
z*c?xETCx6Sh?nI|ZEYqdtL!(uhP%)7$rUef=&WLPZx#w-{;0updRJj1cmKB!X9B|n
zI;=0N|B-0tZ<%sHjH%oCG0*qAw+`=ix%nYt$-4uqogz2?Q+mjp`P*Tgz>e^;OZUnT
zJ~(bsqoBz->AvP4=g%B0mW~IKC)Ri!Xm<z^aIq2d)L?p8cSTmu&QRq3!Djg@u|O{{
Nc)I$ztaD0e0ssKr*8Tth

literal 0
HcmV?d00001

diff --git a/assets/images/flags/grd.png b/assets/images/flags/grd.png
new file mode 100644
index 0000000000000000000000000000000000000000..7138a28d7cb74b2396fa5dd130eaeb3ad4e8f2ec
GIT binary patch
literal 892
zcmV-?1B3jDP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0004HP)t-sM{rEp
zJ|f*vA?9=*(<LO<Gb7_^AN<i4&JiX6dS2yl9tM0|7=l;%#uxg?7XW!*HH=S3lS*`=
zJ?+dIaiKog#US?27}dlfN|Z_D$sO>`8Je#$$G;`Yz$5^7VCHuo@uC{sOd-w_CetV+
z?2jAQHzP8OP$Y&_!WSvBw<{-yQ(~M#i>fvce_DvCH?_Db41Qanu`r#mF#vaA&=@6~
zD>Tw0B%UfW&>AK3s2S2BCG@cw@0%OsZXWiy7+;%1T$)4xd0q#6TzPvuKaflUdR`ZU
zR|b7t6n<F%e_sH2UjTSu0Cr(`cs)=;Ngjh&0(f9FkWZ|=EfIiO0Ci#odS1f5CgaE*
zI*m^J#23rMBGSSlCx}zAw=15WF$#QK|JV`#*Af2D75dW_dwV<o*%Hn$CZ{Pd{LU8h
zrx{+FL;v3o*Tx_NdR`5GTJ_Hu+sqyF(;3`AAq{?8#1<)idOOxJBWyb6(f|Me0d!JM
zQvg8b*k%9#0mVr~K~z}7?Uq+l0x=YYL6GDMO793r#|DZbh`smTd+)vdeiuP@2eL_g
z@@3EL!=1^w-)!b2ccM}$QlzLXT&?<gc3l=3(9poHDS)~rgc|GUHT@6N2&q{$6`<2-
zbgY^R(Efb%ngDRw(H~@Y)c`<m@$j~LEPAK~02sRY`nwE*nFIhZHM85BO+QvL0HDoH
zZ+EwqjdB3!Xm`lBJK8&d1psJG$@QmNMHdACK#tVzl6t5BQl!P`Sb&UCTrWi$Y|(04
zf|cm#fYGsu#|;TWh%|ulmoNhYztPbF#>xG?yG_5u^BKZ;a1i6r1pp7=Y5VkKYk6Mu
z^o66*LLnLr_i_RJ@#nLf`@<E{ljt8PZhxRZ!3Q`v-+jA%U6%kbjvy4l_=9f?#}AiR
z*K1RfEnu7<8p>nLw*|=Tyc{jfOpBhyP&ksyMZ%$RJ^(Ddug=a@95EjX^b}Wm0>~HR
z0)SBr(cmo|q-?fykh}&SfOwQ`*6O2dwdwf*W+&+~InA7acv9{<C*vG|bSG_~bf#H=
z5!Of>rUHcMnDWUF)lzh9dC6m)5S^Tgk=6jn(aFharadr}7s@}pP!uUrB<LGsHfu0^
SMrlp}0000<MNUMnLSTY$`ig)6

literal 0
HcmV?d00001

diff --git a/assets/images/flags/grl.png b/assets/images/flags/grl.png
new file mode 100644
index 0000000000000000000000000000000000000000..53e45988b667fb6ea5727482080e46c2262b069e
GIT binary patch
literal 407
zcmV;I0cie-P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00012P)t-sM{rF0
z?C;bcL)S7>-B4`pq_X(g-_Q&*|NsB;yT;;YfaG(D(-}VV!_D7VbMUjj>zJwBNM-!;
z^xjr+(iJ-KwZZ-N_|_{;>5ic0eUka$<@)C8)g?&D<t4}f0004WQchC<K<3zH0002)
zNkl<ZSi|kpM-qcD5JXXepe=IF_dlmuxEw%3HQ3(iubEerG;$o9&GzW_MHcuUP_?7#
zo2FM|TU`L$qQtYZaL)od!$+Au2LwJg`N0_=Sg>mectHCw<ZBjiGZ@QU5-1>4a6nZ`
zKv_{h3$d00Mj03>K*@ljfL;cA3TR}YIRIW?b@I-3W_JTjGB8oV!MoEGFv!3_0ksU&
z6p*CSe40=IVhM=B0bXvN&pi@=3QhB&xZ^tj(Y&9ZBk%yC-9Lo#ya|BXoI`%_MvVZx
z`0X~+*uz<1-G_S6Q`b#;s1x7<z-NJ90XCa$?G7PANeNLSMSB1M002ovPDHLkV1mCV
Bxkms1

literal 0
HcmV?d00001

diff --git a/assets/images/flags/guf.png b/assets/images/flags/guf.png
new file mode 100644
index 0000000000000000000000000000000000000000..07a2d5070e8125cdcfefab15d566901832640fb3
GIT binary patch
literal 581
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!I14-?iy0XBj({-ZRBb+Kpy0*;
zpAc8~0-xxmN-wVQ{JG1?-f18+L1*njQ3xAIM)s;a*~<qMUuZ19YKz$KJDl_Oh_iR<
z15xohIUpCJ@|KX4VwEnCn;NXPQdj<lkd#b~Zgzm`x82<DC-UDClYHzWdRJBA=V>m%
zW<8-My{91}-w$*Dy3F~03jg<m+`lez_Sh=jmX&-KEBy03*8?-LH%$UJg`^&Pi3Y`K
zY*v?j+bnQSLRzIl=V_=&zwYu*pyNeLg8YIRe*c~N{_pSk^WXpZJN4i1`IF|qpY;BT
zAb%YL1EZv;i(^Q{;kVZ!^P3zbS`%}(cIU?4s^j6%n0<9y*7vXf|8M9MD!Adb@38F5
z;=@;MDivq8___P9SKU2x&coeP4!rfe-*A2M0ZZ9ZX(pEf7p4P(nhkCm3}OqJ0$jux
zl!_Sa7cmqlcQF_*;z@9w!ZfFY%c0Z2m&3xvXSu=zmm6kWM+DbB-l4G}E|%xaOabHI
zcYF-*=DTd#ewL|{wd%&P=lkt9<U4%%vB~=X&*TLRd*3%`GqcUB6>K{s|1I!<u%ig;
zq1F3jO%Hs!s<dfe-Rk_~{~JvE=NGU3)OD@)$Sv(tj9$tS4v{Rv8g2!RPAu{#Tp1k9
zn3%3`@B}CYDD*Zosw`p@a5rK6CU}-XvQW42ad6GzjsF6#XP^GZ(3NoZT2$z!S-?<a
N@O1TaS?83{1OTO7?fC!z

literal 0
HcmV?d00001

diff --git a/assets/images/flags/gum.png b/assets/images/flags/gum.png
new file mode 100644
index 0000000000000000000000000000000000000000..828c5f3d927602f145bc41d23c01bd52882b8a34
GIT binary patch
literal 1259
zcmV<H1Qh#;P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0008?P)t-sM{rEU
zF-gH6JH$0jv-JP9=>N6z|J68108q#`LZEjoYr;}%LOz#}CRnxP`+X~Cz-4{3@Bg*w
z{{m3Q7fQEbGkv!1|Fh=&WHfxV?Ei8tZ(TNmEJdfh>;Dc+zP^5!u^dKvEo`G8O1bU-
zN3d$dF-yE4Kf2)fUAu|Cz1YXE#X_xQ|L{z?@c*&#|F7u$SFvnGK9m_swZ9)ay&gI~
zK$<T^rnth|xWU=JfSGhIZW2qoH$R`iX@NaJnxP|7z-)xXGfT^4OP(Q2s^RXvBtWzE
z|G{8*v-khD<odbS@6BvXz+-!;BTcsJ|E%oxq^zN{?EbIF(XQn1yW{<TDrtVsxLG)c
zzU%)aN3OZr@WM@H!NAt(l}SE4no>E7h}O!$gPy+6=Dg77r{L(oNM63f+Al+;X1|uh
zAURBlIsfTXgVDc*&%AG{eUR4ByeK%!Cpf>{@~xqoV={f0B~$<FRI%**yv*dwB{$k&
zLhG1F@Tf}bo=Lgp|Ivz`zS!@vv$lrO!ld5ghttEzrn^O;RA<1He#^6;>+8fXNGC_D
zhbd#mAU8j(VZ|akE|fL6_y50qlUlihytT`Q&$_V2*I2fHfiG#i)a$zH|De<J``|^x
zTu}eeP4ntr#<R|4zLT8l>b%<Wrr+tP<M6PPjI8hZx69zWywDz-HI387!utQgh@qn0
z<_?h?#J0;Ppg=^fXG*beYr&bZ^Z$9tu8`r?VXAZg<Vr<ysKFyXy_{<3XgYazi%hLx
zxsZ_m<4L&Q^`74SHgvuJ>{6$&e|JiK0+#Tx#DQwLuey&fz`|_2*y{(7?3UU5((wP2
zyONH&ldZ9^ZL+EblIa(Y-YkW*?ezb<=K686s#9-+0EpvYevciK-$kOoYOJ77lb@bb
z1i8w6L8<P2u$Axo|6ZzSbb5cm=KKtm=Tc^33Xk4myM6EZ|DeanE1J+Xh^&3Jo;_i7
zE_S3TYLt+ab6sZ=Du%maZgjA<xA*)1`$x_^00001bW%=J06^y0W&i*IrAb6VR9M4f
zU>F6XU=%<BI|YDR25^uGMh&2k0h~&uGL#q~(Z6;QQ#knsD5|bpv~>!j6uAbJFs@j$
zY2ET^s-ol>klw4geT()s4L!|F8FCB|R+68%Wc6n4g_AoIorTFTz>ZP9MMGuP#;F}S
zA&#bG7{DvflG5C_etLUu1dAmv=>~|HScu7HG)-vBS8)+DH#Q>K03K#fR`KA3th_K;
zaUnitLy`@U;1*<+RQ3-D3iOi{66BU3*#Is9HqV%(qT<GeiZm}40WOja;CFC~YSmh>
z?10vW`eYAVev%E4@?m40dFbrrUpLhk*Ri=<k!*l;wC*hB3%c*W>FMh)El-su*#OS2
z*@w^Hc=z`Ea|46@I|?{SHb748$hjxae!u+j`qi7OyVT@JPl+>*-?@GF=Zi02KVLgF
zSCNdQ+`aqQgNN5YKK=CQ^t{SQa<X&J-lLCiUHNeD%$%xFvdRMyrhO;wU%Gg5ezk%%
zc_mVu!XBN2J9TQ9Y{)GW;|pucvSVF&$S;*SeZ8IR%|`3Sp<%#4x6($zC>RAm003O^
Vz<1{)+#3J@002ovPDHLkV1oWGr`iAj

literal 0
HcmV?d00001

diff --git a/assets/images/flags/guy.png b/assets/images/flags/guy.png
new file mode 100644
index 0000000000000000000000000000000000000000..5845c6db9c8281966eb57e50b531404cb9be61ba
GIT binary patch
literal 635
zcmV->0)+jEP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0002kP)t-sM{rCk
zu4mQn;n?uw|Ns90001YgW&F_=0G>(C5hi}lqk+$*|M%Jc^u_(?iT&k!{MR@9)hy@0
z6om^JxDO&h1q=)U0>ls`QU?zk0tJ=~9ITHI6bu4VKnSLa4igLlPdx|f>goak0GSOO
z6b}!suC5dg52&c9L%4Z7wRFMf(>1bh`270${rgF}eZJ<<iqorzaSVND3xv?8*0B=U
zvlBco1w=Im7y<-HOGrdVLkj@{biI~#zL!=|QBX@uR!&8&o?R3T1W!jg=fyIomr)Z8
z1LwmiJ@KYR00001bW%=J06^y0W&i*IQAtEWR9M69*4JXfAQ%N;Z9$q&Yxi!n)$YBQ
z)vot{qY_Av06zh|<-b4QIms2ZTD*Ai@_T-3Oobi;@WJ84bYmO<<Bt@D84Orj#dHKh
zAqE4I<rO;OGerRg2a+TkF&xYyZ=(SCh@J0wUqb+V#P$|x`WX_Ck7yAuLk7eM;$f75
z(FkWl0pt;Gh6a>II2byhjHoh9fI7lz7y*3*Yyf~^1YkgbafHc$0Y2jKo`A;fsU4sr
zUNLT869O7%mq%8h^F)Cg1F*O-$AI&b3k$HePCwz{4opv89a}%4vw`v6E|{LF+kYaf
z-)~i<VPI3QH>Dv!uLsfqpw`1_BcRk<(<Y!)UzOGYx!xhI0i$}iv;v5F=X4p!>wVHP
z!0Z3~(h`u>|Ni)<1;FaRQtxyDWcA%%Kw5g@^wW^E0J^=fbOF4)*T;M2#fuk@-ai;=
VSDSEy8L$8V002ovPDHLkV1oHp5<UO`

literal 0
HcmV?d00001

diff --git a/assets/images/flags/hmd.png b/assets/images/flags/hmd.png
new file mode 100644
index 0000000000000000000000000000000000000000..8c2931c4e5e7e9d568dfe49857235dcbabe402e1
GIT binary patch
literal 780
zcmV+n1M~ceP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0002hP)t-sM{rC7
zHJZ;45Buus9!sVC{r(R>p8zwN|NsBY000$4p)*{qCsL^$N~H-poyO7Vftt;4jK#gm
z<#mzB*x>Kthl<i29qy>8+)+{a`u%&A%4vtg;BayN{{Qc;u4aY8HeRpSIXS<p!XZtj
z&=nQRr?|<~>C`7Dgq_ZQki)dY;fkTqDpjh$&F1#_``uSp-BeWG<?_$j>@ZoZ7)GO$
zsniBIn+!dkmaEm7t=5O1&#u1T%+~Ae@%TAmu+I(-cazB3MMcpV7(8RKKV`C4dAwSC
zy^y4r%K!iX0d!JMQvg8b*k%9#0p&?VK~z}7?UmV9gD?<=MV3hcTic>m(Q2)B0g6lA
zx7PLjA4w7*Y#~kY#tZ(#4IJj1Kbgs7W208BT9Gc~{R0Ui9c?zyR{V0jv%3de5y0VD
zAC1f+V0b#{$*KUrJRc_}5&%w*tP=qMNYlhb3<%RtnjiuI2uxgtCL(}P`V=5BK>(ce
zioym^6Bw{8O|Nygx4Rk}fK7b#5efkB<*RQa)Gjzc83llhGVw-BRa-_LuxRj<b)a`T
zdcgrVev#WlO;c7Zp|P2HJrXQqpyouCd+!9$|2UjV+`zb+DZq(^_I7uc7;vyJUyjes
z^6;dZ6hP7sPKR3<0Oknw&v+(iHDf@S{um$xfW$YER5Jv`>45^EU?SVXw3-A!)29K%
z#6@f(-@>$-1VGbg0I>;n3unqm)8_!8i9!qCE6P2y54cLT@XgiL&H8{;3(v2w=j#K~
z`uqYOAUASA{47MW?dkv>Pa(&_ovl{_+|67?dVQ4?cXn5837(H;D0qCY>K@qP6tOFB
z;+v1-{kPSVgbDDT<3aZ9t(qh(fbsD7V&QP><?+D)@p~ct;RmTI`Yv4n`(8-@@q}y}
zJqaBuHo$QKTu10ou>rTi43loFp9P6rsm(tfruFns0JUn>3iJyVE?uFkcDWJ&0000<
KMNUMnLSTY}s&oth

literal 0
HcmV?d00001

diff --git a/assets/images/flags/iot.png b/assets/images/flags/iot.png
new file mode 100644
index 0000000000000000000000000000000000000000..2863320f58639484d1bce5ae2d1829c8012b5d79
GIT binary patch
literal 2415
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
Nfb<}`)!L84{s9N8KobA}

literal 0
HcmV?d00001

diff --git a/assets/images/flags/irl.png b/assets/images/flags/irl.png
new file mode 100644
index 0000000000000000000000000000000000000000..2126054d32f58c1d32626bfecece011150e4f8b3
GIT binary patch
literal 127
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSJOMr-uI>ds|NsAInC1DulHs(s
z(_f%CV@Z%-FoVOh8)-m}qNj^vh{fsT1PQl>Y*7InUe=}`{~bOgh9ra}7;y0@GcY`V
W(${cKziSszF@vY8pUXO@geCwr?<If$

literal 0
HcmV?d00001

diff --git a/assets/images/flags/jam.png b/assets/images/flags/jam.png
new file mode 100644
index 0000000000000000000000000000000000000000..97bce2de3f98a2d497b6298f66117028816b7945
GIT binary patch
literal 526
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!I14-?iy0XBj({-ZRBb+KpkRA|
zPl&5~fe*uM%X`}x{#|5%kU$1QyAi`|E1;6U7Z^NNX*#de`f!fv?OEn?o0-ifs~JvG
zzqo~IW*x(-9){Ju472JPfQmu77#RLsVEA#K@y8j4Kj#_b7aFbDCoC_?puNOEdx`$c
z-QqKVsFq<x7lXDk15o?QZU$`?hLu1yQVg6i6P^O~i<boX1vAuVl;_vK2cq}&K#&gv
z?}4B{^PVmP10$EGi(^Q{;kVb0i!~Vtv?hwW9=zAgrS<L8zw_yj7A`r%bJDJS?*C@i
z=PhBU&!0cPKIXz>Y5v>H%eT4<Uu2cxn0e#f<b2sOyLbO0Pc+Uj3}19cvfFZl&4x)9
z&+;s-b1Ver=9ymnBUbe9j~kPRP_@(9$x9e=IBlmhNFO>Qx}dY6h<5>pg*ijdfg*+m
z4jXpHxeJO|0ys78XQ~T2C|+1Txxr1rlGEm0ChwB<+m#nQVQFLt+IN343&)9{s;Ae9
zFfwH6*{O6HFc>fA<ZUSK3Sh7~&dIr;xMxMfGZ{6m1A6Tp_6hT6w=jh1?etr-diO=E
z@XifPGDR~59G0KnKI5yb`TVYRkL&yY{Q0x$FN1=_PUrF&ckhEj-qY33Wt~$(6993H
B(7ylx

literal 0
HcmV?d00001

diff --git a/assets/images/flags/jey.png b/assets/images/flags/jey.png
new file mode 100644
index 0000000000000000000000000000000000000000..e144d060e6bf143d7e77859926628ee66e1e9f99
GIT binary patch
literal 914
zcmV;D18w|?P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00009a7bBm000ie
z000ie0hKEb8vp<SYfwy7MMrQ<`rP2(7c%gYpZ@;--w`d}5iS4!|NsC0-w`eEjhpe9
zq~8=T-xV?Nlc3)dFW(d}`rYB*7&H3Y;NKTB|NsBr5iR}p_y7L>=vQm#R%+lFGy2}*
z?uM1$7&H3b;o~q!?uL~0w!h;qNA<P7@85Fv@y_wxPxbTR{QUa#>7DQAtM1-x@#dH9
z+EMZ4jq~0{=yM?ESR?Z7%<=8a_TS?2-Q4oQ$M)dk)j&7oQ)J~HIP}}z@7?0<s<86I
z$?lw|>wAjggMR0bj@~RN_1)m@tr^;J9ottf*hMAfA354yY1Xv6?XDT%Bq`M(G1`(D
z$b2B#9WL5lAnu;2+$t>Fa~;k+BI1ab)<7i3WhvzzD&3GB=zfjmh#b*ICEGkC-;^EB
zP9NWBAI3^A;;I+Ws3PB&8P{kY<(eAgcZk53Bg{-I;~gsG6)V+m9nexA)JZ18Ml0SM
zE!(0P;zA|e9WKpo8qY)_MjZ%~0000LbW%=J0PpXQkB0A$?~jj<kB^U!kMHmA?_>YS
z2><{AtVu*cR9M69mQ{PgFcgM?0i$zE=@|3j&Rm(hySuw@KYyj{S=*442H9QDRpsQ(
z_a!G{FzBI&9(f82$CVeE3o{OLSp~;gM1YkS!_kPy;dTQ*oVCezRuNE@eBc|J?W8nc
zFz6$Fx7XK6&1ytIrG(=7);0ml>Tr1jkx0PnYR7&EElsI54x<RL$*;H%PbeIXhC?2r
zdZ|lW5+Do0efSq*@px>~PgE}@{{mD{Meh90_2cu_;t)~2B=--1h(5NT?ryFwHphtS
zks3hsar<)i_WE%?iog^lfZ*fc{_ElNdv64RBGrJjl=a=qllT3#VFV5n2Eav5tR8<J
zEsYN#aH7%xSVwa!hs#razz_ofRr28U#!PP)Fv$==B{wnK-wl-+3{d*$=>!X%22l6_
z)zbm8587g<0%RYQ?dD$rIa<hd5EYdpWHF6c<z!k&gf25GWnwb>Vglu|EobV0F>EMK
z`jlyHX|%y+*i`A$t-Y;lsMk7J7}V2_Hb(W};c8@6Px4VM0!-}c(|wpUuQ(b$tf@;@
oNkKN3tm4wtB})%I^vFy60K~=CZtW2sApigX07*qoM6N<$f{GH)!vFvP

literal 0
HcmV?d00001

diff --git a/assets/images/flags/jor.png b/assets/images/flags/jor.png
new file mode 100644
index 0000000000000000000000000000000000000000..6e5d2bbb897ac0929d76c6582445690f40258eac
GIT binary patch
literal 3131
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
bv-1!XC1>BWYBYyEx<Tt`7^qjF9j^Zih?`i#

literal 0
HcmV?d00001

diff --git a/assets/images/flags/kaz.png b/assets/images/flags/kaz.png
new file mode 100644
index 0000000000000000000000000000000000000000..db52cf0788cef4aea4b92172780e36b8589f7a21
GIT binary patch
literal 1740
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

literal 0
HcmV?d00001

diff --git a/assets/images/flags/ken.png b/assets/images/flags/ken.png
new file mode 100644
index 0000000000000000000000000000000000000000..2570c185d3f427cf78fc4cc033bcb7ff7a085d99
GIT binary patch
literal 2074
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
Ef@dU`QUCw|

literal 0
HcmV?d00001

diff --git a/assets/images/flags/kir.png b/assets/images/flags/kir.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8b69d702b5f4f1a399441f6f4bcd0be6396e8fe
GIT binary patch
literal 2113
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

literal 0
HcmV?d00001

diff --git a/assets/images/flags/kwt.png b/assets/images/flags/kwt.png
new file mode 100644
index 0000000000000000000000000000000000000000..f21563b5f414f41b7fa843432667a3992114654a
GIT binary patch
literal 372
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!S^|7RT-^(N_6sOWFtOBdi8IVB
z=VxTLVCDM%|36UvoS@oLKDpxps%ad;>dfryjEtN46({mY2e9)qI2tjuW-zd_Fj#0a
zOe$p1S79iQV(83b5a4By7G-EiW?*My$O&PXQp}L-%b+385aq@YXwOg?#~>!ipdiV>
z%f&FgjKRy2frXi&FMqfE)@Y!8j3q&S!3+-1ZlnP@^E_P~Ln02pz39$&C_sQEu$l92
zLQ$XE?1KNl8wI2fi+|d&J(#^>c9+um&vw4cwqDxHILBY9;ddZQ!(S(s3AwHe63dht
zu12vK*mW=%RCh2;D;8wP3l}_)s={>RjSEAD*f~aanIFt0$zpmeA<<JB+**YuOyCN5
zAIxNB>vdp(FYAUo+>Fbr84r}b7x(aBHMswq>CN{~4xQDN2R`o!_y4um`S}M1TTP%#
O89ZJ6T-G@yGywompK)OT

literal 0
HcmV?d00001

diff --git a/assets/images/flags/lbn.png b/assets/images/flags/lbn.png
new file mode 100644
index 0000000000000000000000000000000000000000..2a9ae1dd0e14b5a158493bb2cf3a35fa918274dd
GIT binary patch
literal 960
zcmV;x13&zUP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00009a7bBm000ie
z000ie0hKEb8vp<S)KE-RMMrQ<@?&ZL|NreAB<&m|{{H^*VrcCgB>(^a?HnZXVrT%S
zQ98PK-16rGr&Id<`~Lp^F}HI4{{9B2RTHdU<n`_S{{8s;`WCHVht;hlvT7-`Z92Mn
zQ^Sgc)T`R^<ubQ(=JxLU{rnuSWO2=&4y#)Nrcx}mZ|C;zSj3GzyL(Z>hzO}xaLt~n
z;lz>Hw9W0^(N|IKVP)rEV1Lr5>G$wo$CBms?E$7z@M34%^5>`E!?@<oH@SDq?c2QP
z(W>FaGq-dIsaK!fy+*!(_51kdUSQ7d-t_zU&+gvY@#QtRbuG1Tx#rKX<H@Mt#CFf2
zIk|VT<jM}JTJZYyIk|XY$dlsr>w?p%p5482&7KFSRkh{KO230AvukS0nZfDQli9Vy
z>ee5yX20mu@A>o;tX|gf<LmhGTgHzGsaGenY&^Ppqu#*M@8I3@=!Mj*Nxy<OxpsEX
zqAj&>l-afmsaQk3eqP6sS;daq^5&e}yQtv9lG(LGy?+?4VJ^0COu&RHv~3ivUm&q(
zPr-+z-@s$Yl=l4jP{N4a^XISQ$Wp?I?D+D<>et5W*bl2)AF*cP^y<6k(T>-$J-d2+
z(WbTK%qz8S5v*KFz=IyJWxl5il>h($3UpFVQvmP(|CR6WpYQKfeRC5400DeSL_t(o
z!((6=1*2e?02X!%01MCnPG$-K=coar20#s9<iZEs@XB&A0u5kg!UH^H<nc)}u>uX?
zz$331$Q>6Gf=2-d0R#NGfj~IQm0SZPdAPaxxVf_;$uxjJLOD4%r@W*nGn^~~gu=L0
zvO#{R(8wUifCL38K?UwY9-e|S=_)b|5GbxKjg<h}ucj@`ty--_h8Oxl&QAkktxheu
z8j=m@oi>4+TQJ%updMt7a=Sc<258I>nbIc$)G8qiBm~>KI!H8Nx}M_1ncNW2)2gGR
zB1Ebe^k#E&t2YJnSa5SUwsdPYRHl+-fRHZt)LGokJl?i^U`J>wrHGPZfIz(L<Vo6U
zs$k77p+G|2mozVkCDw`P=JU&d4B!>u%}e)lG!rMufS@FhdRdSG=8%k`&r5o4^aKZh
z4cX;^mz12ngA=#3DSiWR6=|Z*lI}pt&f3bv0B@1ThNHYRwuG^a3~?5!Y@;>Pr~%Y6
ifZ~ScC>RC90ssKTcvU~5#16Co0000<MNUMnLSTaLarMmr

literal 0
HcmV?d00001

diff --git a/assets/images/flags/lie.png b/assets/images/flags/lie.png
new file mode 100644
index 0000000000000000000000000000000000000000..0b8c77442d3925650f728e78dbf6020c7081c0a6
GIT binary patch
literal 844
zcmV-S1GD^zP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0005$P)t-sM{rC4
zD1-ngg8(gs04jk1E{6aoga9jl&JiX6D}Vqkh5#vo04ak2DS-eefZ@M3v6d><wlkiF
zCIBpf0V#k0Erb9pe*i3k3o&^BAb0>Gga9Uk049MQH)H@RfJID4PD?6KT2=rYWdtgF
z6*Or86-NLaZ~zlSHb`3mC42xSgD*s002D+jJXio2R-B4A>BB7{IAH)6P$?q{02*EZ
z7D@mof{%D011x(3D|izyZviTQB|BXVFmZ`=AwfD75exth3IL;!IXX{d03?0Ywl4eE
zJG-4J8x;W$3IOxbI}i&1orEIj#5b0JBNh<=mVYBJK~w-Ifv%G%hkQRG90iVhAg+=n
z8a8F$y*1&$HuBFjPEkQ>VJ}QiJ|8(@3@vt<fh4}6EwYv?<G(h5ZXlY2C6<CEw3sTY
zktwv8EC1|6x0@_uQy03PEyATQE<aKTDSG3;HuusyRaHL!@I=h3E0ljEpNA%KWGb$c
zDX5MpMoK%jnkynYU!#a3KuuH5t}%~!AOI+ZUtBk%h##7QC9IMuxSTA`uQ98TC0a}q
zabzi>j3=p(D1UP^vX?4vT^O>KDzKF*W>y!#qb_=BB7STma$p;ZcOVoqYXBvAcxD}f
zZXbYc9}6yaYG5seaUh?EC1*?p7ytkO0d!JMQvg8b*k%9#0TD?=K~z}7V_+BsqhJ(3
z0XqeN1_rQjQf2^;tpz6~2CyW=1zK~GYXA!)WApr)0$xTo9!_!$;I@pfn>D+?p)kTm
zg^!bT1GueXn`Ta1FukWTHOx+4gp*_g%wk$6O<2@Dcgn;nfnal4CQ=RH<ZJ2bm^@Wz
z;k??MtPCGrHj-TsR8rq2FlR<zMQ&PVqMsq@E^rAcEAMRYt<Fo&PYQ6=kS5s$TF&A8
zje?~@g4xMl?)u6sBpV>7=@eaD6vZEz;_GIhC`Cp(VAHk_^>=je^!6}Tkl-c505KUg
z6C+i19aB9eNfz?*f;cl5D=RA(v#9VumIni300#wN)PPX~MhzG>V7M7D3P!;w00IDs
WWObVo)C4a80000<MNUMnLSTYZL?;LU

literal 0
HcmV?d00001

diff --git a/assets/images/flags/lka.png b/assets/images/flags/lka.png
new file mode 100644
index 0000000000000000000000000000000000000000..2b6492daa9b79a194b0a84a3eb02bd51903d9eef
GIT binary patch
literal 1757
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

literal 0
HcmV?d00001

diff --git a/assets/images/flags/ltu.png b/assets/images/flags/ltu.png
new file mode 100644
index 0000000000000000000000000000000000000000..dec6babea8788cd571a499454b5ed876cb19487f
GIT binary patch
literal 130
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSJOMr-uI>ds2i0{MvRwY|6gFyl
z!v+**ED7=pW^j0RBMrz=@pN$vu{fQaAmP^V-=6D-!5WqwVGA2r4|_G3im<Zq<Toa=
ZFg$+O*_xzh-vLz5;OXk;vd$@?2>|$LBo6=p

literal 0
HcmV?d00001

diff --git a/assets/images/flags/lux.png b/assets/images/flags/lux.png
new file mode 100644
index 0000000000000000000000000000000000000000..9cc1c65b5fda9060c2b7b60596700a01192a3a7f
GIT binary patch
literal 130
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSJOMr-uI>ds|NsAISn%MBhB^Dk
zN$Y^(j3q&S!3+-1ZlnP@DxNNmAr_~T6C~Uk{@Zi?Fj&J9;T-62V1v+us8%L1p8Uo{
a76uv9z6R0XeoKMs89ZJ6T-G@yGywqDC?<md

literal 0
HcmV?d00001

diff --git a/assets/images/flags/lva.png b/assets/images/flags/lva.png
new file mode 100644
index 0000000000000000000000000000000000000000..b3312700d81424ed2071c632ccdaf19aa462c9cf
GIT binary patch
literal 124
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSoB=)|uI>ds|NsAAY+!L}3tt&f
zkg+7lFPOpM*^M+HN72*8F~s6@a)N|gL$)Yagux}&2<JeD0}h-$$GBG=FkoVsx;Smc
Uy|Yp0fQlJBUHx3vIVCg!0GMVZM*si-

literal 0
HcmV?d00001

diff --git a/assets/images/flags/mco.png b/assets/images/flags/mco.png
new file mode 100644
index 0000000000000000000000000000000000000000..6c12bd624c047058d63686549bd829330e7a6cfc
GIT binary patch
literal 204
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0J3?w7mbKU|e&H|6fVg?4jBOuH;Rhv&5D5x0V
z6XNP#;Pe0g|8s(B$mGAjf6oc4Lj>pk5pe;TP!i-9%&>p|`}dnSzkh#hs)jF6(8kln
zF~s9|a)N|pgD<DPM?%8PPH~GKEs0PA9?^ma;TH}Z*vF->k&tj~{egs#gDaX6S2TnQ
f=yOOYe$`^g`ZJ%o=$rI6pg9blu6{1-oD!M<taM42

literal 0
HcmV?d00001

diff --git a/assets/images/flags/mlt.png b/assets/images/flags/mlt.png
new file mode 100644
index 0000000000000000000000000000000000000000..12809815f7b20a0774facd4765cc04a83335fb4d
GIT binary patch
literal 485
zcmV<B0UG{^P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0002<P)t-sM{rEZ
z!ou#t$lb5B_SV|wv%1E_#Q*>Q&lD@l$;tE0((b{>-K?_m&C=biv-8Z+-K(+YwY$Z{
z#PZA0->|mdvbX8Ezr?+~-><aiyu#nEwCA+D<hQ-VzrXY1<LS4)=eoe+vbp;0?!~>m
z#J#=4wzmBB_UXUG>Au9nx47iEzU{!q?!U(2v$^=}?a0H#%%7srqNS&#p~%F<%ATOs
zqo=sIx5&lCvaztvo}tQ~p|h^4jDUHrtg6Ju#<a4rt*E54u&mdns>jI4!@<GF$H=Xu
zpToexrJb13pQOCJyUEGPv9PYm%F3*%r;&z!mW+jMwhu@E0004WQchC<K<3zH0001>
zNkl<ZSi|kpH5S595JuqylEA~=-QC^YZU3u*f^+Cn%rq4LUBFk2ND@Nmn@KmbZa+X#
z-Ch=u%;!QZpel<B2PpK1_jZE{D5>J+@VKp7rLdg@sO7G<e7**|X52*rqS@>Ia+=Mz
zLUWJ+XQY0fjymf}+GnK>F*80cdI`=NYqE&3?jR8K_*sC(W;Cz>_A>zh000000Dl7@
bgg(6i&?iv9w}`s+00000NkvXXu0mjf1E?3O

literal 0
HcmV?d00001

diff --git a/assets/images/flags/mnp.png b/assets/images/flags/mnp.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e6c538e43fd388aefbf9c9ad5e6f170e50813ec
GIT binary patch
literal 2078
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
IM6N<$g2i$GIRF3v

literal 0
HcmV?d00001

diff --git a/assets/images/flags/mrt.png b/assets/images/flags/mrt.png
new file mode 100644
index 0000000000000000000000000000000000000000..0fd8d757ed1598b116b13ff2a14935240c2843df
GIT binary patch
literal 509
zcmV<Z0RsMsP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0001iP)t-sM{rCY
zZY}D(1kA7s`N9Flt_#4d4FF;@|HJ@4dL{;BGVQ$tRDvQocqrJl2+y(#EpsY|mKY~-
zEB3(xW{DretqekYCWMt4fs`3Db}2A)DHm%l+qMT5YA=408e@nbBycR!vkASc4I6AO
zHg_m{ks1SIGTyfbkeL>-rVx0L8+$zql>h($0d!JMQvg8b*k%9#0V+vEK~z}7?UiY7
zgD?z+3rWZu?yK}z*ZcneKXAYZ9Rh8pl_pin`vu#PA1RJ)CKDqgqek)t8Nho0;`l|t
zdi^3`w|fHc`QrvaJb3Uc;N$y~?isrP7smE!=io1ZavQ^%qSn-E0<Izf5)F{&Yn6XJ
zYu`;s0O!z}_X==t-Gf5{*hOm!+-?x9Ti7H3KWWR#aw+pnmq4C44G?K7sH>j_+K*@e
z8)~>~6lhm)z=i<~v?3-zK9rvWv}aU6cI@XLGoYZgatL_6GAIuSiL>CB-NQHC*oK!u
zpE}O<3^>6f5I9vtkoUpXu7@a`sil-lH4AIk-qII};^>L1F&n8WSy!GKx6&-p%@@|_
zo#?L~=_~)KrMj4l2#CadVg8K<@DBhZBcoDZ3e`to#GLn%00000NkvXXu0mjfyDigb

literal 0
HcmV?d00001

diff --git a/assets/images/flags/msr.png b/assets/images/flags/msr.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d2af3aef0785bc9e2d99bb772716267a512bf4f
GIT binary patch
literal 1502
zcmV<41tI#0P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0008tP)t-sM{rF0
z>goeEnguqR0HVDBp1aQv4*)Zn|NsBY001XasU1qCRj9oOH<bl9n$jH|;)javsHpt?
z{@hVf`TG5PmCE37aRfG+{{H_6IG69Pu2rbM3OSZ$g~B#ouUDwP2{@D2IXS<p!XZtj
z*x>Kb6&1>-xCuI)racGA)aleGCxo5OevrdfslEm_l>s!F-B(utqP_sA#0E5%0yLRa
zsJ#j~m<TzUraA-wrN;oN$pE9l-BeTnf*}Ytm<l?U2{e@jHk1Z6nFlqORj0jGrn~@}
zxe7X$mWh~=mauz}yqZ7}oGk#RDFCoH0HZkw0G_(f4h{f$9sqh80HM7AdLaORA^@ku
z0H?)OrnmsF&Ucf@*+oUs7#M-D#ZIWa2sD&{uEa4~tWT%ASa`Kve7hb*oj6~uPpZOF
ztHP#+d!}bbYk{_@d1QW+oTzP4eUzOSMWLEA0iG@ZT6(uKS*THSw3|K;qm!AUGXQ3R
zxlm_aqmq|5Ua6&PO{RQmrH6l<FaS+yV5DnMqACEPE&!fA4xT*^ra1?sJ`PfFW3Dy;
zP;qAftI^JSS$JC?t~v&gNfWDN4OVbwt2+mnKL-(M767EebxaM2Mhvzz0C$vLt4{~E
zSO;2jU9U?6k3s_geIXKoBmk(&pGp7~bsCFR1g(c4KyOf^R0aT@xB!J@Az~E(nwkKc
zvH+T-SEPUds>nTR63fr00Dwx5Dgd0jq(Kk?D4Lo}TuA_+yIh%50HD7Bbcl40kxg+@
zkGik`d=UVo$UItF7=(;fPfQS~#0EMHX;L0yeGLFM2p^uKK{+L#iafQflTj4_O=t*Z
ziCQ{ND;|<qMV(9lHbwxSyZ~u?BeBK^LQMcG004cGDuRMInME2<Q71Gt06$GsR8T|;
z2{~$S069Y#K1u*eR{$Fz1w~LPIXMC}3jlJ409I!lO;#g3Kf!QdOh`)5&Ao!o)Vb2l
z0G<zGXpE=;0004WQchC<K<3zH00085Nkl<ZSi@sr7zLwX6hMIiqlhRII}}K;adL3O
zII;r#g6wz!*Z?tADGp68Oaqja6onauh%kUlO$*@&gaIJyIaK6`Fo2y&2jK{q0TAo8
z)!B(LfSn!a2pfnapau|SJ(2+kM}Q3=(t2bA;En(p5RKb<ecT3s91$zU!2vWN2AB2X
zeCCqo%=+jCaG(I70Vn`THJ_P`f`W{hIJyCWocI8;0YLpg6PVErz^gwHrZmx&2LvJ`
z!IWzpPA_n>p>QQ&1|++&23SW#J$MrpVI9Eg7LOT->e@n#!ZBb2q+-Q%n9u^yg_XtV
z`jZzgpTE7i*NBBx7sCKK6%IjufoPBcq9TkoT54Pv286$U_W0rb_m6IeV;TUqUQtPz
z8)N`GmnMglDw-ptSy@8DH-36|@8g|t77PO**2}W9LkwVN!gK`C02Y>OpFh01dwG{3
zngKBD+2IDTV>&_?WI)J`r?;+bTL&~i8p!~-^~eT*9btgv2(SxSHeS87dBZB80rE%&
zz^z9y0Okmo0j6LBj_o_Qd$lDCssV88(F}k%0>ywm2acXPxWyXH1?)rtkO7BIpFMHh
zHgx@Tatz3@v|7C5;*tFq!h+ZKT3Ke2Y(PO%&%EV351%<17PMk=S9KoA26*`Tb<bb2
z_53E=&;_&nd_71sK;JpX+d{*C&dTj;Y=dS_vGA@U(E!PWv@9PD4ga~zmM#pQF~O&y
zkR$_~oh0?lQnHIRG&&|Nnl`(?rLN4$nG^$z9n5)o%~ErVDlIxEPVH-}FL8IUBgFs{
z8GA`RUcMyH{PM=u_GZsgcYA2TMr;_E@QI5{I_f#6dsWnU)k^Y-^D&bgjX*<q^&EM5
zc_q!6u-6Mj#H9%zAD_4hu8M^$FlxZ?F<=yof>8hj0CKX<%~H=me*gdg07*qoM6N<$
Eg5{WNbN~PV

literal 0
HcmV?d00001

diff --git a/assets/images/flags/mtq.png b/assets/images/flags/mtq.png
new file mode 100644
index 0000000000000000000000000000000000000000..1897c94e7fba5ea55209a8eef53a28a736083a42
GIT binary patch
literal 1512
zcmV<E1sD2>P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00009a7bBm000ie
z000ie0hKEb8vp<TUQkR_MMrQ<4J(KZD~KF8kN^Mw|NsC0|Njjuhz%=<4J(NK{r)UQ
zm;V0#^!E8GM3(mV`YcA5_xStx`THqDl`cq_|Ns9DD~KaLlN&dWDn*w5{{ApZnOSbF
z6*7z%HH{H2iV-i0!^+`zh`bLiiIkzr`uqK@x7W76+xhzZ5H5+!(&ZO4jpgX_wZ7U=
zW~uG(_SxO+4lIa1R-iLXni(~YsI$~gWT>C3&_i3I`~3YAFpFt>wPty<=<4$wIglnn
zlp#HmQfR6-P@TQS-u(Uj^7Q!X?DV9s((?28)7k0${r=wK@1Cm9Hcy;yfw<x1@GVD|
zv%J~C$>7%8>RWHFB|wyimc(6guP8&6`T6{VlfpGlo8jf~w7uGmo5yyCybmmiJXD}y
zbFh`7%WHkMEJl}^rOiZJqs`Oi#LMDJVWuufnC9v7ikQV8I+2&8%z}}@+1~6%U8Hb>
zx$Exr7c-28mBXT~(ck0mrm@p!dbIHJ_l1<hPi3e&Ql785*!ueV_V@bp^!Z$HujA+O
z+u!Zz>+{^;?fw1z!N}l1SfS6==k@pcfsw(Do5r}o+|}CZkDbU&Vy9trvC!7&yTjer
z-0R2A<H^wERcfnPZLJ$PkNy7sa)i1LD~MKWtf;coeT~0tezy4e`!Y+KKv$ukprCt<
zzM7hvRB5ZAtkCA^^Yr!kdyBqrfVbM-?eFpT$<O4ov$IiWss8@|#mwTbudn+1{F0x^
z&eY}{IFEphv^Y_nQD&+8{QO>Wuy%y9$j;=5mc+is-y=VhevZGLsm|i&@sXa%bcVap
zI(#+&000$qQchC<hL!K{kDu?KkMHmAkB^_9kDs59dw|v}0009INkl<ZSi|ksS6353
z7zSXPqJZ6ZfenEqL_!IK5`oZ*5PFj)RYU=4B3%I~f+#g~#V+>Vv7lH{{*{yDC?sY!
z7u<1pZ+4UY_Bm%}GV{g6WFs3{Co$VX&7K{bNp|m~SC|pNlKC6Qv>>L|o>_@4G_n2n
zh1}1PslC0b!g4k6^f45v^Xx4;5Yhv-dLM2Y1|06Qp-NHa+<q$Hf48eKKor>~F$~lp
zw47lo6?EV#Vk;RY(3Ju>mGBuRcpgWofKM{1m~e%NG6(8-qm*kBN!*cim=0WvLzodj
zien5ND2J<n8;C-J9S6{Y42Byh#e0SWNW?26z$9|GfKYfO*GW|U87V##;3Tq=^G3Z>
zUp#R#1gMa~V({Bo51J{!3}#qNwr9(5LI<eQKE42`{K<6$Dt*9DTTuv1dy(r;^y&c7
z0X(;?9P&P<iyBhK+91&fTwKoZa~HppkE!C~<=-+0b%3CD8F@6H?p5R-M{Zm_!}S4Y
zQMLL(;dq`fmIV$;?DghAaOXjwTyxj-BRt5^DmX863^;0Q!y=qkR>9hy8ec8oORumd
zfDP6V8v<CY1+Z8jfYn+6D*~9?QNz<#@#q!iI-BWCrtgRPSpmm(uKJWOSnzT)yq%pt
zvYPU2I`HK)K#E2T1HmuPPZy7;#dK1Evv0c!h8^-{qZA<FcpAf`u=KtV!p27t=0G9k
zL{bl}8SHiX5Y(G(nMDXkUwDQFBggt6@;J^!=NLp70b)7(f)~1-xPd?@JU9Rscp5p@
zA8L;>dS4h&w^<K55RVQnpa8ZLF254+JU~tXypbE(a<H3yR3<kBxI>CLW#&XHloUXS
zL@3fv2e;ye4&b0^+5E4-l=`$SLcc!Xujy58(ZHL0ax)C64j`^LQW9CyOMdA?Q%OtF
z3Y^jh#207%>hF2uHR966?>gtS)4ei;OF{+MzU-{UC1KyW#`v11|Aye;egz0E<%K9K
zq%lLSWnubrzz<)&z=l@gGA}~ELJgR1rDprKO(eVa(ko0i{-|$cz2py>q(XXyhR6*7
O0000<MNUMnLSTa6?Gjx8

literal 0
HcmV?d00001

diff --git a/assets/images/flags/mwi.png b/assets/images/flags/mwi.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ddfbb17be5387d81a23b5a02c7dc7aa739685a1
GIT binary patch
literal 754
zcmV<O0uB9%P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0004uP)t-sM{rD?
z4IK{w1Je;F*b*q54IPdQ8UO$Q&JiXvo;5NA35E+91ONeq3mA<I8XyA(3jqR!3mMN5
zCJX@r(h(;R0Rtri2h|cMVh9oq0RoT=8z%z?4gmv}3>=yb95e(8n++VB4INkq5J?6O
zRtFFu0tRad6kZ4s7y<>83>%3H8K4avRR<3t0|ucD9i9yxatRet2M;j>2_6CkbO{v`
z0RvnI5l{vXGXx1D0|qPv2nqoLq7EK`3m9$*6nhF6;}a^03>l9M8Y=?`mkk_M2M}Ng
z63`JQOa=}w1PCbv2vP?R+Y%_;5-GnBBU=a&<P$151q*@;7|9VO9|H!B3mViBCk_Du
z2mu0g3Keh(6;KBcoDCe93><k17JmvCehL>|2oX623&#*7zz`%H0tI9U5{e8NgbNwX
z5hf-B2a60EO9l>g3KiE9C{G3tnG76P2M{?03O)r3iVGTh3KlvA3yTXHnhYF#3KvNR
z4Lt=50{{VO2^5wL8-EKIfD0IC2osJA8j%bedQ95&00001bW%=J06^y0W&i*I6iGxu
zR9M69)5TW9P!xsXMs9A1*WDd2?(XjHP~6@1#bMCJ>WrI);rSon8|`f}K@gM+8|W`U
zOQ~u~D-`fOeY|n$H23~;WiJ3&h|2e2|JSGDc?|``fo8pcy0&tD_mD_NV#&nK^(ty_
z)CUYINIAK<ja#K>Eq)nWoDFvgdVry$khr@=W4G`a4bpgi(j^DDCUU^Of%Z4OIJ-XP
zWLf9V)C_iv%c!-M7>H1NE-yab9%U>%Z?TO`FJnhvCsjuZRC7H`L40;P$LC_$UM#fv
zJ!OPIh7yN;hX)M*o2|dwU2m=^B?GMH@|p$-O|W@&v`AHzCB?MfDU*GHHxK{-0FVb1
k83+IX0QgS;f}o$i0h%dmrr`Jm$^ZZW07*qoM6N<$f-M~1c>n+a

literal 0
HcmV?d00001

diff --git a/assets/images/flags/myt.png b/assets/images/flags/myt.png
new file mode 100644
index 0000000000000000000000000000000000000000..c149a2a7915e8f29470c49d149045f3ec42d7d58
GIT binary patch
literal 2003
zcmV;^2Q2uBP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00009a7bBm000ie
z000ie0hKEb8vp<U08mU+MMrQ<)GiXx(9r(={{R2~7Z;Y_-{1fL|NsC0|NsBb&(Gf8
z-pR?y!NI}C#>Uev5w^Cr%F4>z+}!>5_WJtz{QUgv?Cih4zuVi}{{8*9xVZQC_qw{e
z&d$!7nwrwm(yFSe>!6eo5pvDV&7z{BrlzK!pP#w8xvZ?L+1c6C)6>Vt$FHxiySuxt
zuCBtu!knC(!^6Y&_VyMQkroz|z`($yq@;_Bi=m;R%gf7=k&)u!;_B+^%*@Q!KPBE^
zOV~pyzP`S-wY8(8qp7K>yu7>;5puDyv8AP^`sd@9mzTuE#Gam>*+?+f*4Fyy<<Kk<
z`|j)7O*QenvltkK<mBY@^Yird^yuj5;Nal1v$GWyj+K>_$jHd%=H~nR`;Co_?4+3b
z>*({y!T$RC@VBk+wXF8n(%oA`?Ca~?RzTlnP}J1a+fh3C<KO9%g@uK%;^O6NYo!+#
zj2aq-y}iz`u*Jv6(;pv&*x1;HhKB9!?Sq4Ze}8}Z`T1yQm3@7Efq{WBF^bpM*OZi$
z{rdUE#l_4l5#8P0zr4Kf@9&e7ll02NzbX*AJSV|18OJOT;A&U(&ByBL>G#>x_SMhT
zHXGt~W5X^H@Vc?@v8VXm+4j`W<%4pkH4fQFF1Ich;cZ&RE)}~w5AU?9;c#8p#>2&t
zh>wr6lasY1ByU?=msM4iCMJ7@g`*xGe06oDLqm%oAbMnEm&wV`dwZBPG=SOJ+Z-Hu
zp`oy=tE}#=qvwo${rLDtN09Qrx3X47M@NUXudb+}pF%>9r(_QN^YYCs5yis7h=_=@
zP!F?Z4^dH!vS3r~sh!q5BDQW~vrawjsGYtu8@)0RmUb50(a)}d52$nwm23^fGZ4K*
z5W+1Gu!j$}IV7We7n+e)x-AvhK`6$Sjox8P+fzK(KPK|SyZ`?FtYQzlgb<%<4%}Ho
z-e5|(P7tqJ52#ZP!!{7Qc5B_%)sSx!vpp%gM-aJH5S)@wzk(3Rnv(e7+_W?v;n&v3
zqMXR2o{<Te7XSbN3UpFVQvm<}|NsC0pYN5?`$b^@00d)6L_t(o!|j%Ja2rPyhjY5U
zZE_%sZP7`pEI5HB)iKAeEnAf-jVV^;80(m2JIvfP*r3DADKob&Gc$8jX6804#q~^Q
zdXhW-r^)y?v-{rd-hR9H7H&t48qtW(5REx&7#f2BqrosV`u_-MX#sl-QqZ~?w6uX;
zJ-_w#_VgGGhC5K&{G7qi920QvdlzrtR$jip6R+%StC)~`<Vfz8)|{rhTc3VvOU|yH
zZLtBHn%gVNn|e>|`S{@e%AH36I9LhB7XgraA;{_4G=vc}b?vPv|DdaTFW5RBZ*Ir&
z&o3DS6g@OKHel<v%8HM=i*|n~-Q5k8M^AjQT{#HoY`-%mpkFCfN+<UNAXO@*=(%VD
z2>U4EKq{5?p9bqd7Ro4SKvpRDhs3C;p&%n9ivdVjyVRGGg(FWebK2}#Q>I>a>C`E+
zW>1?bKt*^~if`%iglGVcG*i%(Y7LKI1~EOEs2WRD5y{hu87Zj9TIhn5ndJBZ3UNN=
zfHdu`2B2;ZK@ek!fozTtfNC#ILkE>FR`3A=>1mus1%*pAa`XvTpmtYHLfPdgU5P$H
zu2~|4Dh-#G9^e5e*;J?z<uT#}1^|D!?X@=(#5GqVC;4^&m;^DCC(^)FR>=d9&&!0A
zU!k=zE)LMkP`m4HS$xBdi;=Ue4sb5Urd9YUm^n|*7X!8iLdxg#uAvn`dsn#Qo7BqN
zs*v-55h&<2UZ;<Ou!iM}0iz~W5JI8Dtp*?|ITFBIub&jLg#eu6b_h|mic~W^0H4Ja
z??<oDbTI(r6K4<TJfwS#02HH1fY2Xr()f4)`8sG3=}|8(EeXhH<B+fct@i*@>q4W`
zi!4x=&jTRc5?JHV7m}1mKQ3<_Y8L^7v$Ffg={*!#sCU#riJRmB$k-&U#Ga`4d#I!m
z!82Igy2l?zqj+%TO6(q6NfPDp>l5t~Z4xWvn+4pvFf-MuO%xe9ntluW`m?v+eB*_e
zUwq{;Y{P1rGl~+m&eY6>UOd`vl=a!c{8F<{xZ+*xo9}=ADz5C4cV2xB+jyT)XD*!&
z?0vGKoCg!lf(+ZY*pK^u`Dx>hFF)P)I`-s683OafA)E(vttq_o#ZE!?0TjB!;UFGH
zQQWaw;EYt5YUyZzRaSMiIsBd`Tkr$6;SlzFS=<5a(0c6oN3u0xfH|PHQc(bm5iF`l
zHr^EUeD~`g$BuXW^=IGlV}0+xL_$+Ms;FNCj7$`ONO#Iw3vfJSBW=1+D71>=I7tx4
z3#_N=bfPE#(h@Net9|f{3jXcct&)hfkWm0~l|=z?t~d|vrpRpL4Uw&jqX%_fF^2<%
zMJ10m3jrV7n6`ik1O!6!a+Ti1y4l3cbm60E@w7U?EJ$l)eSuiVdN3$g*R6nDEmcx#
zV%NIOjcy28j$({*c`zs&(vM}XExTmy`6)*3f)0hEqn^uVs89--ku~%`lki^_T~K_w
l+>!n}VAvPU5sm1K&`I417b_B9>`DLt002ovPDHLkV1neT8R-B3

literal 0
HcmV?d00001

diff --git a/assets/images/flags/ner.png b/assets/images/flags/ner.png
new file mode 100644
index 0000000000000000000000000000000000000000..87bb8211f7ac853a62d28d6b0cf4f93cf28eb1f1
GIT binary patch
literal 494
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!I14-?iy0XBj({-ZRBb+Kpy0*;
zpAc8~0-yh2aKxRJcZ2qWAT}W4Y*B!4feZ-y_uoH%|NVWEqy6vi-+%x9J;~8g+GeY~
z-43V~s2-?MahuJPY^{Gl>2IH(<{LZ+<$79V^7rSr2O*pvHuU}d`tk4A4^J{R-Y>0t
zoGkz6)0+>g+y4VqfBW<}Md5L}%DV;Szn<Ru{p#V<eElaGYESbGKdfm7TJ$(W?dScA
zzn<QFoTB(RUG?3<@(8`?Dxl*<OM?7@8Q$LyzW@HdfBbt_ugLrF-vin2?{l6he+5)<
z$kW9!B;xSf>)ZL74FnnzFID%?Wof^6sk;6@`{@QD<<rwX`0{*T&p!W1A{!6$;jWPF
zD<fSQvO+dnF>xp;u(ENVJ;r39^r>c<1P|*1mE9UY_h{6*H|B($W3+knrSQGK#DpXJ
zTU&Wp-uyfjE|9SI=>Z|8A2X-Fo5heYnNf$sp-g6jqj!(RgT{sjf9@}2w)SW@*!#bP
zWuD8Sb>i1I*{Yupe5bun^7Ar@FDwa0*K@QO*3L`|Wf5?2;3|=twe{n72JMjeFITor
Ua`K*e8|WJbPgg&ebxsLQ0Iw|U=Kufz

literal 0
HcmV?d00001

diff --git a/assets/images/flags/nfk.png b/assets/images/flags/nfk.png
new file mode 100644
index 0000000000000000000000000000000000000000..6e68aee4f51473519b3cd5c1a72425ad9eb9f7d6
GIT binary patch
literal 1422
zcmV;91#$X`P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00093P)t-sM{rC6
zdOHPtJ^*z!{{Q|1dp!_>LI8R_|NsB>`u7TdKmd3*|Ns3BfI$FyI}?OOK$>0#eLnd6
z_yKx6-R<G+_V4KO=pBhjTc~hYrfnI8MMRuqSf_Inf<p*;IskSzFp*UYd^}#NcW1AD
zD2+`okyB-@c>ezV=kn;w<I(i_^yKj7@%Ql9>)Y$}>(l7hv)8>+q;Tx@?Bej^2!23d
zt8|gWpvU3MtkbvX^XmY1IY*vk4uC!2@8bOZ`^DhN@%Zvys&pELM1Z`JCX7x>pJXYI
zQCO#NVyk&Ilv!)Ac@=|00C+Pum0c2mKOKlm41Yi$iAR0Aj0k)<e!7lKp=V{Sdpnm`
z2zx$AonHWWI%BMMDvwM-nO#YrX#j9BGn7_)xrYdSJ~x$AB8x~FghT>(IUtBgJC{==
zi%4y;fq}e<8-_qZnqXb2Yb%XTERau7qG|d3`CzDdZL)>{a4h5S;{5&j<?-hLc{mz}
zOeT(1P@{5HrD`CGQ9GAnyxYOi=hd0WrwD#N1bjcX*uOiNTeaA}Tc~m>kXEzTya01E
zYOsHe!kpFV+Eb%!c(sWsjYwv%f^oBiW375^vVw@fn8Dt~Sfp^U)wJB~-dU)21$#M`
z$f1hCo}<pLL7QV&qil-7mXO4sh`ySt(X?W$bD_<xYp-{CxR5=XVm_HvM4Mu0u6$st
zbpUxfJeXZzsdY4zQ9P7cB8yMZ=F<*+KrNA0KAB#e%BO6ve*ktkABjwbzKu|$Z+W<e
zQ=@Kzyp|e;M@*hqMV(?nmRtjOFjJ##snW8j(Xeo`ffj^EB8*I2s&ls2ym_~Ys?x7D
zlv=piy`apfE|OS#xQvX!mH=!gb+m^^ooZF3a8;pcMVePZnOSzWhEAbr&E?ZKlvr!9
zeTBS})achGhe<JxQiQ&eVXAM1zKnjlh6{Z@7=%7$t#o9pZz_#WO`>d4qhxxygBgWL
zK9y2xu6t0TVqvLwE00iQt#>DiKLB$sM4VbBi%LP7S0IQ&Xb8?z00001bW%=J06^y0
zW&i*JJV``BR9M4fU>F6XU=%<BI|kt7<iG+rIWbk@FaSxHojMYS90QEYC^LYi!JIM!
z%H4a^DKdaZT81JQY`vVTG)t5M11`LHlYDq4*#@ZdynI&>b7wybxdv!tMgGYwcze%*
zTmwWCzx>O|NN?6B(*X4kzyAxQt4Mw{CewfiU%waTseb<U>p7VQJc-SZQ~R6yGxg~S
zvJ5C+{4BpvA?=4+*4hKJ^~f+l=d7Gc_9rR+gd};zN#wX-{?X{X>{st!^D|kwO=u_G
z0PUq-+z}5Y0%c<Zxt;o*g-A9)GnkuCSVbUJYSSEcR#vA*(!CILj5#GiLDoBlQFz;`
z>0NrH8XyvKSNhg**F$XL^6PhaDooQN)qs<?!(<d>j(Df<UFWjJW8-pCy`XOYc*>)s
zcxJ{urvA*Tp=)<KkZ6F|Dd*_>;i0~)Hmk#Zx!AUEo=c(uM#_%K!SbiAW&M_gtx4P9
zwPKMFX$D-ncHUjdU+xGS6BDzKQ=-Sh#iSWve?vJaC&DB^kexSBm^H=IaKQ`<QVg&>
zcU6&>H7d$Yf}hQriIrb2ZtCP-OX3aS*?0X4TRhvD-MgoB^0o;x2}DXtI7(`h-~y3@
zH!muMgu7U=x3F_FciT*K?QpC$A|(vEb_w_e@QQOa3k%oO8|sR*Hkla|kzzpKl9lr;
zY(;eK1?zYys@g;atIH`eK*OX;i!uYaxHKp-prW!=lOh9jN{aO<YvP~)`WZlCGj9}(
cf>8hj03A)(@>(8DN&o-=07*qoM6N<$f^I;i3;+NC

literal 0
HcmV?d00001

diff --git a/assets/images/flags/niu.png b/assets/images/flags/niu.png
new file mode 100644
index 0000000000000000000000000000000000000000..acb36780d835e0a31b796d3ee1abde693b0b20d4
GIT binary patch
literal 1095
zcmV-N1i1T&P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00009a7bBm000ie
z000ie0hKEb8vp<TB2Y|JMMrQ<&lD@q6f6AE762${04QkOwiDd86a3K@{LvQr%^=}!
zauz#v-)40uNq@e=((u^b?BeIp95Ng~c>B;66F76yBRJ96<NyEv>YAkf{r&XF#?>@P
z*+^RL@bnHeaLv`>SaO{2w7heLsr=Cv04QkB6f5wxyxB)t|Ns97EoINv;#YB-`|R%i
z`}@=|L=iS}8$WmqGH(qtaPq^+2{3I9GjD>Hwea%x+D>2Cke>ej{@aY2c!{goke>0p
z!_zB3+fQKg#LDOE@!VEs^vlqCkFd}gDtU>k?C<n)h^v8)uGKY3?C<l{l%jf$u-sH%
z{r30px4hCMDdTD(`_L9~gs9+UR`$}@(<Lb)M0NDa$rCqh`|Ica{rCR)^y}^H6*z6&
zl9|;pKY@>_>6oGsHEU&kq<M{~(AeYOWpw@d`S;u2&lD=wH7DR|dF`mM(jzIz&fMKl
zBw>1?+)X6kVOHN@R@~w0_S4teL?zWPC*ECFhnl$EPbA@ABHmOZf|0T1fsN1_D%d+F
z;A2+TI40j&Bj4ogDN2AHKzaMk7W(Py>FV&}-Q(CtS=~}3I6QB_6)y!VW>qUrs+ure
zUP)anODsBY0x4%<Wk_moMadK_vlcS3pDw}`E~J(+p_DTpBwmdqJ=i)Xf`+E67d6u-
zDCvV9lZrT!ia4ehHrhrd0VihwCuj5Z`1#Kk?%w0k94h(97MG1Sk&molVZ4w4001O(
zQchC<fA4pH?`UuDe}8{}e}8{}e}8}Pe}8{}cYp8i@9*#L@9*#Cdvn_W00EmxL_t(o
z!((6=1*2dTi~<;tl#&n^W`O`6K`}-l0X`^Cl%JQ8n~M`4U<Mi>qhW7tVQ!!b0!Dgj
z&1$-aV78g9mA<8krV3ub0W?6_&j)UVkzU)17O(+O?VfIg4PZ45gBxL_w`B7gpaF30
z#;QaZpsETtqDwDw({kNTgmzUT3{cbof|8<wtkgiw^?J(|uh!kzly9P`nVAlf&>?Jq
zk~#<kfl2kPYgesXs*Wr|*Z?LqAP5c#22pdSt=zC>)_f4NFeEY;L=$O1X=pKsnly8P
z%Dl;QLCmVqb~WM*kktT!^6)Ycr7>~g?5Q*QL9CkaR<H<R0~EADph8nqGbf^_clx3!
zeVUrtl@Wm*U~z4tqEXe%-&fPgQQxjn59ny!T4zmH7Y7?}aOxz+0GM_UV_;IA08GlJ
zUI-%y8z2wY4ob=m-SwcPj4*<*0djEdAOouF@*tTBW&~jaqyv(ZQWCYmAST}3-90u6
z!b!_Wh>H#&Y=DRg1ps6K$EX3L28<doNDN?OrvR{xHjhTZC>RBB003-GJDtd6z_b7W
N002ovPDHLkV1h723KReU

literal 0
HcmV?d00001

diff --git a/assets/images/flags/omn.png b/assets/images/flags/omn.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b6cd8b3b898d8791457cf9979f55756f568e8aa
GIT binary patch
literal 711
zcmV;&0yzDNP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0004WP)t-sM{rEq
z5f<7H6xj?B+Y}kv5*OPS9RL6S+ZG!DfB@PP7}^jO+Z7ty7aQ6V7~n88*$EEX5f|JW
zAlV2F>vwtGBq-h`D(GNi*$WWpW@z3hEazHW^sB7g9U|*^dh(v2+Y=b^mzeH~i}kRv
z;4d@ZDlYcCz1a&9-6JRCMM&vwaNQpy@}Q#PJ3ibVBiRZM-6AI4Bq``&WA?tj;W<6p
z4HNUFrtzJh*$NQ;>FD4yH`oUa_rbx~0|@3+SM#T+*$ooe2oCR&lJ1F%`_$9yczW6m
z65AOb?~sw-C@lHS%;;rk?R|dXIzIf~-Tvq1``Fm)dVJn0FWC(f=1^1G4ioX4o$!{J
z?SO*&+uHin)9{j%;4CobSX=wZ$Kf?N)&Kzh<>d3KtK1kJ`o6vSzP<U&%j#@y{MFOw
zUt#4}TKwDF<xo@UW@*;|1^m|4>ThxQy1D$y$okLE<3vaDoSo}-dG@li^|G_`q^0`3
zyz6*-I-G?z00001bW%=J06^y0W&i*I0ZBwbR9M4fU>F6XU=%<B2Nu9iBtRIzBgnzQ
z&CSBb%0iw2tSY(=f)Qcvru_V@WEsGsXCEY779A>Nrpia27aRkV^0EpN!aW4Y^8!~e
zOIl88MM;#X8y7hSu!zNrWfm4^r=}-+8t{-|fWEVTWOZeJM!86Ur4BP02C$mA`o!j@
zRK<we8ENv7VE~u5xr<+7QJl9evpN$mS<%QS<m46NYa=2|W<pXB&@#5NwlGvvVqzpK
z7GxEbHJI7hn0V!7q`1g1fLmIQgPRQ$noN@7j2y%RL>Ndw{LaC{%*aNL0px;F14a!P
t<OXmO2}TVVHDJ^LY8o&KM!_fm0sxo=Wg}O5c*Xz#002ovPDHLkV1j_hPXGV_

literal 0
HcmV?d00001

diff --git a/assets/images/flags/per.png b/assets/images/flags/per.png
new file mode 100644
index 0000000000000000000000000000000000000000..490a26441ee935007fff2056dc8c2d7042ee60a9
GIT binary patch
literal 123
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSoB=)|uI>ds|NsBLB_#FOEh-l%
z$XF8O7tG-B>_!@pqu}Y{7-DfcIYGj$AzM^HhnKZULm>O$iUTVSB#213F)-)|`$*)Z
Sd(Q)^W$<+Mb6Mw<&;$T7r69Bb

literal 0
HcmV?d00001

diff --git a/assets/images/flags/plw.png b/assets/images/flags/plw.png
new file mode 100644
index 0000000000000000000000000000000000000000..6f6ff993a1377710bb411730b1bf47ece87c3571
GIT binary patch
literal 608
zcmV-m0-ybfP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00009a7bBm000ie
z000ie0hKEb8vp<R^H5AwMMrQ<|K0#ft<_7d)Hi{kK$p8pt=3Ad);EEmK$p9l!*%}M
z0B*LctjA%?&^*G;M^>=Mi@u0Vt<#*tbgjr=g}smQ+7P?TP+YRWg}ji>&^utWyRpby
z`P>HV*cOeyhRx7AO|H?*&^+eX99yx$qs44tv$}e^oci1aQm@R<(KqYZ7pKN&{oMlm
z-2%DGQjoxc#?C^6ypo>7a=pw=ugG1?&po2VZQRr-_uB~W*%M;3xZu?z*V8U%w6o>b
z9&5I)p~P-buFh+<u41#f#Lh(f+yuAERMOEjS+T@evBbN}PhGOVce$VT+X_#v&uX==
zTfOks0000AbW%=J0RR90N?HH!PhaKSQicEk0R2fsK~z}7?bcUQ!cY)~VKxZ_LrWnb
zN>QZQP*f~{GzFyl|9_2)afS)(#cp!LjOV@oo|~MUBoGjZL{7mY9|bpn8uF1UfWroK
z`{pj4yl;C1J`!X2E%N>#@qzQ$Eo?h0ae>P#aCP0~0p<zplwYubGVJvwGl0|FJ^%&-
z$Rc~_NMyiFVE{zQKos4>BN-^*z!Mp;aG*#AG#rSN0Rso-WT1}&8X1sVDDX``NHJ{x
zN<T=U<2MAza9$?lIXp`oKpySxFJ`<8W!-S^dll}LCJ$=cc_g8GxKuwUD`#GhFFjuC
u!>W~RzSvXoZTu&I684cIev?I_zkUF37e7s?&h>Es0000<MNUMnLSTZNQzPgA

literal 0
HcmV?d00001

diff --git a/assets/images/flags/pri.png b/assets/images/flags/pri.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb0c54cd634d4bc546c3dd02bf5fbf084019aaf6
GIT binary patch
literal 1880
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
SCijv60000<MNUMnLSTYByLe^*

literal 0
HcmV?d00001

diff --git a/assets/images/flags/pyf.png b/assets/images/flags/pyf.png
new file mode 100644
index 0000000000000000000000000000000000000000..66a5da6b82ffc63d15dbe66b821fd4f36a021983
GIT binary patch
literal 1256
zcmV<E1Q+{>P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00009a7bBm000ie
z000ie0hKEb8vp<T&`?ZNMMrQ<-CJq@|NqVrCe9Hi{{H^mTWZb`CjbBc&JiZvTWSBC
z5C}b-J!i51r6)FFuK&k)|G;R=YITaE(Es=B|McbW^7u4gt<&7?Pj$GyEIbK5od400
zU4Xu9jKra}+5f?5|IUhKhQa^Lg#XHc%@8I3qay#zh5wupydpEX4<Y^i{_*tr^7Q%s
z{{GI`>-hTo%+~7v_2=j8^&L&5qqo|px!b?Z<t|&R|Ns8~_UW*}-^|zQowC=`-0i$6
zIi<MUMsBtL{{GjYr@F}FVuQf!+0Osx$GQ?EzA8HZwN12dcD^e+$`B?0+NJ-;djICc
z{QLX=q96ahWB=W*|I32cs;>XrsQ<%nYl_3qf{JX5#GbR*#}Fh>bhw(Y*8lR~P<6Qf
zvqzn4hX2Zd|JtXILP^FECI85L|LDm7;<~;qJ^!pY|D6>7tvSnqiL_~Y|JkIYw%Ve$
z+W(vqk*U+5X>LAev7fZqsIbkDPgQxA$)dK|zAio?QKnUSx*<@e(TkHxakguT!DEEL
z<Id1~m&*RAF1k5Mu!4sF`0oGNrIxGH$&i+}jgZBorqQ>#PIR~jJ)HfsOb$YxbCJgX
zxmSgj!vDBc&a$-s&WSr^u+zG|yUF6cmzu*7CI727$*QcpM^*o&D79~aqoluqnaEpy
zy~WYz{;4zn!fXGrL#I1N|FlZ~)0M1AQvc74|G8HG*P#BsWAdm<|DhbjOj+^7kEA3q
z|DYPIR%*x)B>%;8|EVzlyIU$$q=Ydzs46$aqNVD(iOY?a(6X<*Au-#hk=vz<&a$=K
zteChWGTXzyP*{@x$$s0CW89i>>Zo129xwmRhu6Ww#BqB6zGVN*gYdn9@ufwz5F)pZ
zk-HBf%B!x*q?^X1r}U;n>cE$?hl|Rrul3BD>#}p%!N32!U!iJm^2Lw46eirr$+!<8
z)498!XKcrLfv)Tg>;M1&3UpFVQvmP(|CR6WpYQKfeRC5400F2;L_t(o!((6=1*2e?
z02X!%01MCnPG$-K=coar20#s9<Dvkt0S#bfq5!Z04dB2j>lC2qZ13$B;ckgj2?ss{
zL^FfDq&xz{x%2!)$uS^-FGnTV(>F}HL?)NdigW`+x;OF(WcV<r=g(NJCg3kZvH^nJ
zhu61fNij1Et=h6?GPeS$26V04d-33A!EB%bTW{=GIW5(QL<2VL6g+Wy-=<oi0oR`1
z+P;=shC~DQsA-%(rl8W=xb5omhj(sjEDj~n0L634$2HF!?Vow&@x5nSFRu%vkZ8aH
zZte@3Cl_|kdwcuQ>o*U$xsymVpm5gZQ<vuSl}$MG?*3h^C+g}UBpTpSH2duQ-m0{o
zr3YTTf3<&kjWvk|7)#2}?NE&^m^gLOZq;2Y+FW%>O-RDB{FPD3%}PqsmmFEfA1zFB
zO4Kot=8fZ#uIHUJMYfK|LYwr=q-W~L8(&)9Brn$>X=gxAcGfp@h?Fa?XsM2|H6*J%
zU}7>C=Sk$}5w~H&TcF@A(!?Yr#0V8>jFc3rjH5Nvr~%Y6fZ~ScC>RC90ssI#){;<h
S1YsZm0000<MNUMnLSTZI;k5q%

literal 0
HcmV?d00001

diff --git a/assets/images/flags/qat.png b/assets/images/flags/qat.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e8461e918b676d6b06ef7dc202530a61b7d9fcf
GIT binary patch
literal 2021
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
DVNT%K

literal 0
HcmV?d00001

diff --git a/assets/images/flags/slb.png b/assets/images/flags/slb.png
new file mode 100644
index 0000000000000000000000000000000000000000..d63061a0bdbae2d2f63096e88d2884ac3022baef
GIT binary patch
literal 403
zcmV;E0c`$>P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0000*P)t-sM{rE%
z#w5<T9Eg)8|Ns9aTr;MnP9a+}08zU9(H2m8hV;!BLTxV<T&x>o!F8e9JbKE0r`%ME
z(JgSsgsa~0_51Vp{C?QMe*gdg0d!JMQvg8b*k%9#0Q^ZrK~z}7?UTt4!ypVqyU<d)
zWo`feQ(HA9m|zCuGou_VIeIS|#k*ZgOUpkOU9NlQoF4EvI~M__DJ<!X^v)duU>L%d
z&Pabdo;+ZD8}k~MEuFFcZteO7y)nJt(;4b50d(`+`8Vhc^%U^@Jxk~e^%NlNKh`q<
z-2Yae01Evl`t%D>|BOBbfc`ms3dr`)>mvZXg^WG|fLqAw2>{(fUT-D0fb^1Efco++
z6!grmEG=IIDC;pmphp0a9sp$eEI_Ky0mOP9P@!i5HF^e6r%wTu`YoVZzX8<iBY;Lv
x0V;g}DD^8qtM>r4-UHNn0?_F_prxhdn-4c(NzPq;_HO_H002ovPDHLkV1h~uug(Af

literal 0
HcmV?d00001

diff --git a/assets/images/flags/slv.png b/assets/images/flags/slv.png
new file mode 100644
index 0000000000000000000000000000000000000000..e597e45b35c16ab3347d0ba96a8c69c1023aa335
GIT binary patch
literal 642
zcmV-|0)737P)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP00009a7bBm000ie
z000ie0hKEb8vp<SK2S_lMMrQ<(cJIQ+wTuYumAu54L+F;LZl5onGQmv4@a;6|Nqk5
z@Y3Ax|Ni~|`Q-ol=>Puy|M}x;e5?QY;{Wo%`|rB{`s)Ajy#Mvj|M=Yh?yUCfxc~g|
z|MSNF`R0$Qhwtjcw#2Rf@U_6ty8r$8|M}tZ>Aknfwg2<P`|-qyqk;eT*rT<W|M}(p
z_~ifZuvU6ea*k}Ev9n}`Vyn8l-Qmi*#ICixvsidsrLn^P`Qv4SU}%JQOms(Bd0J_T
zX#e!c;@`7mfMoyp-T(2r_w(GXxu9r(gJ5){SbJRk?5D7|vQBPb=jrWIkA(L2^pv8z
zu(!*tx6A9vw70aMT6Sfjq@3^5$XJnrLx6eE)8DhW!`r_j=-|OcgnPEU(AvN{?86S~
z&aJ1hWbyLz>&mT$mcE>(!ghk0*v_w(9@1_A000VfQchC<@9+QbXlQS5?|*P*1ONa4
z)Ja4^R9M4fU>F6XU=$1%z{WuVU;`S!$xH#@95rCnfI(vbBR4+4!-H3v5oiDl7f!&d
z?c!yn&yQOH7Ykkk1T>tvqWpOUCCN2F*VQ{EGuGE!Pl8MX9Nf~PQ<KsI%#?V^GC<Wa
zR461kJWR+*O^hr9R7`y`ViFUQJuDRX$TC1i)7mp4GS1J=P)>lnFp$-;4~h@8G*%QL
zGZ6WtwQSvO4CF=m$uxjVSW4Z*NLgGEe>z~omyqEE4!|^89*i0=d<<Y^rvR{yHW5d`
cC>S&V0B1l$f=6x+FaQ7m07*qoM6N<$g4exNn*aa+

literal 0
HcmV?d00001

diff --git a/assets/images/flags/svk.png b/assets/images/flags/svk.png
new file mode 100644
index 0000000000000000000000000000000000000000..06bed756e409718851e95508f471888f930c72bd
GIT binary patch
literal 521
zcmV+k0`~ohP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0002AP)t-sM{rF0
z#>nzjTZO05?HnWuPNDXWlI|QO|Ns9BPNMEAGWe>k?<zBer_g7S#Ti+r^l^6ZM@{*v
ztw(yf8d<1Ug}#_CQ;ITM(9qz*(&+Vngu>J3Id8PlA~gNu<k8;k{_*nq#>w@7h4NKg
z?$_RYHDg0Ug0jcrHARY}yxjV@yYATD?8?wMZ?oRa*i&1T@kdVIA1rM+YUhHCDP*l*
zJ8~vSkt$@aScbp%oS*Y!Xzw^bVs7Wy00001bW%=J06^y0W&i*I14%?dR9M69(%Ejp
zFc3gd?Ao5#VF_iYrDbiQ3v_|5|Nmcg9Ml99AY)$VDpKafCnGDR5=Bwlf-@q3fLws7
z-Ozv%F2<r{7-E6`76^WlVT1*^J@hL?Xa{4QQ~=Ov7u+3UH}T_UeY^uex{Vi5H$nyO
z<p(ImxxE7(eb@Z}mc3CQAPkjaf&Gb?ClD9kLGnW&fv^4^@Pq_DLwD?T)#$jv+#><q
zHG|FDU@oQXwC~y?s$zla`-e=MJvOm`?yWOG<<tT>!1Yz_|9oqq@jyms^_s;1*zINc
zoa}#DhLhz1P=2V?WTQI<@B{!R)7v7SKMdF{0L}w|00OW8MNzgt4R%dpI>-2;00000
LNkvXXu0mjf!>IX0

literal 0
HcmV?d00001

diff --git a/assets/images/flags/svn.png b/assets/images/flags/svn.png
new file mode 100644
index 0000000000000000000000000000000000000000..a791163bdb7a8b51b179b37b375547fd808b8496
GIT binary patch
literal 1963
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

literal 0
HcmV?d00001

diff --git a/assets/images/flags/tkm.png b/assets/images/flags/tkm.png
new file mode 100644
index 0000000000000000000000000000000000000000..0c3ff87556a0be9719ba1a55b8f806c673345076
GIT binary patch
literal 1620
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
ST*{sR0000<MNUMnLSTZ78?H$J

literal 0
HcmV?d00001

diff --git a/assets/images/flags/ton.png b/assets/images/flags/ton.png
new file mode 100644
index 0000000000000000000000000000000000000000..84cf20ef5c2f712f2c66e49bf7bbe8c0a37be123
GIT binary patch
literal 139
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSoB=)|uI>ds|Ns9#$iPsxcz!5Q
zkg+7lFPOpM*^M+H$H3FYF~s6@a)N|ggQ*BpnBxJaHB5o4SLjb*U9$XAOoN)Ax=2#Y
j>VN|)7(`jx1Q{59v1QBn&Na~j>SgeB^>bP0l+XkKsbnVU

literal 0
HcmV?d00001

diff --git a/assets/images/flags/tuv.png b/assets/images/flags/tuv.png
new file mode 100644
index 0000000000000000000000000000000000000000..15478f1914ef86b45bace3e01667bafe221e5617
GIT binary patch
literal 1456
zcmV;h1yA~kP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0006yP)t-sM{rDa
zs@%^H4|A#B%m4s%s@!y{-F2$l05h5Y|Nr~y>T#*z4nd&<HJTktr6*FUa;e~Rs@`y^
z;?f-*;)jadQBnE&{d<+lf33}Ss@ig?-|w!j?x?8z{r+Z!!r*Xm{{H{hIXS<p!XZtj
z*x>Kb6%~Z8#eJ;McB<KLsN<Bgum98t2|At1r?|<~>C`7Dgq_ZQki#}!uXCy2d#uxO
zso;65)qJecajD{+wxNEk&v&cXYp3drvAT+|ywk-~bE(~Rs@iO)>2IjykFvITtJZ3#
z>vyWy?#(K2spHJUTx_T4=F2ydvazwdg_5(eYp3bi$4HvBrvK9php)o_(+khUS7@g1
zX{YSnS6AIsRE4j^fvw7ovACGDsF1R>|JDGTwWRXTBD}wHgRaNW#a3>p<+r_R|J4J^
z!eF<(d$zrO!og~YufX}y7I>@IskxA-xRP_K-SEyOptqZ(xR&C|JDjzn_s|=+y?m*;
zk7uUv@y;fdv#q1Im*B}hqqmsv_4{{|$k|0j(HI!fVQ1i|uBNz@fv(Ez^ZGq!w1Te4
zv%G)*(h<?dPU*}s&cs;LcYVRYY^}P9mb0t)&>H>H66wq^!@+3n%`CdUcI3=5_Rk;M
z$U(QgdgseDqPLlIs^9$47j3BL+Q&%x&>C;4<Hf;c$HHUS$4c+bD4DgUpSGQ|ynt}1
z;?>4ZFkG+u(HEVzqL{R){?ZYkx196P8i=sKth$T#&>h&vNyH!~!W0_M4i0qa4c`C&
z00DGTPE!Ct=GbNc00SgRL_t(o!|m1ATiQ?<25@6MIe}CKTntBDfZ!GZaqm5G@BO&<
zXsxSi_p-Zo?`3QEu;YJg24E1Op_hGlZ+Ol{e&2hNli=p&iYu;|(!}=<@Wf3y?C!zy
zGB1LCeNIA$p@EP{886n`76=au_2Zx60C>m5?UmRA$nk-^h_f63+%sXXgc+d62gOGp
z;sW3}S)!RKVFH-(i8yW_K-s`v2^uhu#~lDztAq_$N>IR>dAtLl|H+^s4PygTi47T#
zM*{2S@pb`BQ*rCr=6!h*4e+c&0_+?=xPY)@Yhdgl05tI1!$E!>3;^Qky$50evjs=j
zd;GMyR)P|QFsnDEzcSARSZ~3@-ToE;gb0Ft|CT->MMQwWteyfM9UsK^Tc-ipMo5C^
z0XMO5Cs~l%xUjqXC2ik9B9j=w3-s|_qksT^esf%mw+*mUGif-gsQsZ<XSSgG0D63A
zShyDj;NG!3StL_}4TyA$U+Wu|mRG8m%d@NjW_&P?GXU;sDZv7SijmLi=~ex))sGFy
zR$DNS$1MPEDZvI>Qf@EK%xkB{3$0%!%Xl_GmuQNMdCz`*a$1Meq5uSdT1gQzU>R=(
zm`Yr>J_M-<^NXNF*LV_O0L%D&0A1q5zL&ssAo9iHGL=HZ9A)Ti0Kl|8MHjkD&Y@fZ
zAc6#HULZ;d6c$%^PU{HB5kTebIeBdYW<fN}RyGzJ`erseI0Kll`eNB>6QJ6jE7{J_
zC~{I;G0qLrFLhq;!ssU;T`H@qdp9aTvoREM1g3PuC66<ETBP)<p<?WVs)~J(INZeC
z;y!UHk_|+d2*TlvngzX+0C*%Pj{tG49i0%9k0eTx%^g6<odb=sDoF?Qty_08OR3Ka
zfZPE<0!h6u^F}J4r&in;xLGc=`Db!;xwK04DNTTtzEZy~%&omTc=!A%E#?FOGScfa
z(=(Jq-Nqv?#K{HnD+RgGnFiAG6{B%Zr5tT5ny)orP@(|PDF7Cv80%&m5rJqjUyo65
zF?13j-o8m0qP|~Qi2c8JM}S1T6P2%|o+kV^;BWa~09Rabh0GtgpTCXfl!Nd90000<
KMNUMnLSTZW74L8W

literal 0
HcmV?d00001

diff --git a/assets/images/flags/ury.png b/assets/images/flags/ury.png
new file mode 100644
index 0000000000000000000000000000000000000000..c41e2780a85f64e8a507342a73468d8149819e59
GIT binary patch
literal 1017
zcmV<V0|xwwP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0006~P)t-sM{rEt
z-QE2B{J6Qh{{H^h*x38~`~Uy{063`q{r&j(_lkpMiGg1I{r|_J0JxnXx|$HhxrM);
z5rl3G$E6YAx)jo`62hSn^~)9f{QdIt_4)exyu82O-rnu*@8aU(;^N-#@ACTk`sC&1
z{{R2@`1$$y`uh6&+St_H-QJ#?kKy6t?d|RU{{N4NYvkkP?(g#I>+J9D?d$62jfZKk
zu(70|li}do>gwvcx2^g4`QhT^>FVsUuA{rPpZ50n`1$*_v!=eeqW1Rns-uUkshW+3
zX_|*Ok%(jH=ik@Qs-BB7@9*%Nn2Ooez@v{g;M~aK-_)3gJF~2g>+9;?*uUlD*p`xh
z=H%Yh&$y<LGQzZSyO{{7jvT0t9Kf@9#G??soDayU9q{n*%cv5%nh(mR48x-l<>J@k
z+`7cMhTYe{y{uxup%<l*JD`q0zOj1L%%{AZ5x=l+*3h}OnH<f+kE4eTz^`Pal0u<{
z4Zffrs+dWhi!k)`^w!Oz<KND^nhn{~u)UxZ%c&OG)xzA@zoC#u;oj1<mJ#vt^u(hN
z*s~MYvlHp*==aYSwU-gKm>$KuklE6)%BK;hk~PSv6Q+$GqlXO1rxWSI6u6lY>%$er
zx{k)VgXH1Q%D;==*S)!!59Q#@!J{3gjULCR6QhO<r-}{3p8>(Nd%?1Bx|<T2e+=fn
z6vwC`xt9mIm<`aa63VC%$fyy%uWZn)62!QF$fgmyoDYg}48)%R%BKy$pAp2P5}tz$
zyq_b!of4XV4CTHQx|$Nms2kkBe&GNB00DGTPE!Ct=GbNc00C7=L_t(o!((6=1*2dT
zKmj`ifa(S?QDT6a4LhePivuesxdxbrvvYay20Oy!IEVoV16Zwj^UIQ>Lh?e{wOPqA
zz=EeFJEovCKCvN^M~8F+fd0;it4L~0NvqC@4Rh9zCe;8<*QU&3zJ#ju@*=+IdUrE9
zl3n0b)12EW(9_>5Ak>oTMS3i#+eZj?uMiTRBfNLUge*@ZB@zu_V|J_MUnU|UI!jby
z$25L#6J|D&(?OTuqP6S9c8MK6v}ax)ISFaOhV>%i+qP^HKX_p0R2NlJ1JTg8ec|er
zYnE@`zi;=}`2m))q#D3v%-*_m)siVQj~v}T-H)uKtk2!Cc=p_hlQvEc<d!GL07e7$
zwn`uWy22nUMMiQAU}tBswbRw(V%Jh2H#>7GtFXwhuuDk}Xpu&q0UQ*7Q3FsD(%`7t
nMibI#LK?~jjDk@x3V;9rg1U^iIWS=v00000NkvXXu0mjfiLp5y

literal 0
HcmV?d00001

diff --git a/assets/images/flags/vat.png b/assets/images/flags/vat.png
new file mode 100644
index 0000000000000000000000000000000000000000..d6c99cc1fa8f9c2e59007f7eea3372c248f0fb70
GIT binary patch
literal 851
zcmV-Z1FZasP)<h;3K|Lk000e1NJLTq002M$002M;0{{R3owtGP0005_P)t-sM{rE7
zt*zL#SJJdt`19@G&YA!H_W%F?|KI@q{`~&;`1<<#_2S$3?dbjY`uOe5_~WVl{r&Fj
z=l%Nd;p5`Pr-<j}=GCgI`tQ;F`0e!L;`Z$4`tZ`*wYBo*!sO=V(7%uP?c(vjIppNz
z?d|RN?9J+`0o$dbz^$;;*4F;{`t;q|@z~h)<F51R(de@z&$Vdt>eBe^-_gE@_~o(q
z`T6ta!`P-#^y99?U|_(&!0oy*w0mvnwzSUB(DK^a&8kc8#ZlP2YvRq3%yV<-)3wgF
zXt=el-=~-M=eF_Hf#<MD&Z$e~<>l<E0K==G`02d<`~U3U#LBHv-mx+M`uyk8v%0&#
z^xxjp%(K_LZN<jM%db_^t3>YJy6w0lxw4(*%#GN+ZvOuM-MypTo}Tpd_3zGY?#5Ql
zcqHVqx8KW~*S&GnwtM5sfVjH5(yK${t*yVq#=EGd@bdKKv9$B><m10=$CfSd^7YoZ
zdD6<U>FVpp$jRThlK%et;;Kmd^yL5i{_V|f*T0SY{r|_7Ec5W_>&%$@@zcDxtKg<M
z>%zwG!aUJ?d(G0(-kg-<l^@7lT+C~5^z!V{&%?5clg!Gj=g3&_(rdqQOXjyT%Er_E
z{`<_*(Co~Y{Qdj((OdZQ<NWj3)rX15c|+Ebm+i%HjTg%;00001bW%=J06^y0W&i*I
z2}wjjR9M4fU>F6XU=&~g4lIBj3m7$E)PSLEfQ$rX25=hcaZ+M{k(-Z$fg-sE2(y{7
zL@_ZrvB(K>lVyOaF>6>%L2R%qtAY?&2AH}>#^o?GCj~j{OOj)NidA?*c2!$NZeobF
z5<eLRC^JUqSGUaXD9?*`R1+Y_3%-oC?NjG0Z!XL5(<Lt&Yg*aoE}gZ2oh^X8Xbf#y
zylCOXY4fI325OOIKtx0D>=_f5P46o5*CxvV&-D7vnUg2=mn7TClVyN~7kgv(lD^_J
zc1;no43IMS&aCSxO|j7s<sr)eK4}w=tin`VbunHpva_?ji=_@_1&XZrXrVf4z=$zm
d6pVrq3;>9FVF(zeEEfO(002ovPDHLkV1io13+?~_

literal 0
HcmV?d00001

diff --git a/assets/images/flags/vir.png b/assets/images/flags/vir.png
new file mode 100644
index 0000000000000000000000000000000000000000..a57f924b23e263813f2978b22e903aaaca667425
GIT binary patch
literal 1987
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
VuPKmh{mcLW002ovPDHLkV1je&7L@=1

literal 0
HcmV?d00001

diff --git a/assets/images/flags/vut.png b/assets/images/flags/vut.png
new file mode 100644
index 0000000000000000000000000000000000000000..3c4d6e42954adcf6210e991cba9fdba76a392691
GIT binary patch
literal 1267
zcmWlZdo)xD9LIn6UNd**y7L|(gci+Y<uPSNWSA+FvPh(mOhQtT8q<TxY4gaVBebHI
zlN@S2N?}{H^pIDlBoymWvS-gk(Uw-*UHixP`~Bzh=jVJge0|olh{Xf|uoPZ0|Alq`
zKMZW4FVvsV0-#~O8w2F)4{R*^3BGngNitA9K)n<&ad^gExqv}|=ch+ds0L6wo{WVr
zkKtVl+$)Cc1mKWRl?}7^0n%Lg902FVbQ+KZxX?I9l~B#HMge)>3ibKmPZu_`Z6BAy
z<XuPz0i`ccV?t^|2xmPY#~rqd!B7`s?KFg0JI4Xobnr40qBOv<IEIl3BhKks5(v6{
zDa34nSGCZ01D=$_*d3ty1sDnj0$64S5;1^?Z*ByzT;S~rMvGvr1T0Ko^$OUg06iYq
zEdwuS2#|pe2HI90H7a!c9tLZ;C<=@CC{BYV1`rd7r^YY|2C~M17UE40_M+QZfV~Lw
zlY%}U<*|_7YL3_(lR43bZgHsr!QpU5*(uUu2^zHpH_=DW9oOx+#yK5Nr0-{PNW^0m
zgnGkV2Y>zv-(IW}xE}xTh(FQHO9*FBLjvlBz<Mc0y%C1_;39MEM=4F)#;eICsYzk&
z8CF>)IdYrpE2SsxWT<vB<W4jefsh2EQZoB*a!OKkV}lrZYC>d&ZIRP0Ofc%LFjzrv
zC}8o~2u=rA2c08ICKE^YZD;J?#-IiT4q~0hSJ`<g;&V4YIf`j(g;Bly^T&0qOtBL&
z%-XZ8@h0BL9qtNC%*GNkHAFYM(ewq#P#xDzLbEhM3y<i|_V8OTvL{-&o7`w4zj1kN
zq$-DGlZbQ`jT#qTODFdP;u0|y6@c&E%IGR*NBH8Q-gw(3wtd(=(*==`M1P;n;Qn@C
z_kwnw3Yj!uYumemi6Eh$!NUyIi^*q}sUlHrY(2kosa2-*<?!$@F<>(g$~dg5rwZ<N
z4Gmw=D>|B1J$tNZ_2k8Q7fFlDv_vWmys`D^vu01D-Wc?<vb^UPGz;i|Pxle<fJFZJ
zw33r<MJ%C{2GNVo7#pthtIg0biz{U$+j2v9T~SR1qS3A_{d#D|u?a4>E8c`y$M$kS
zI4LOW&c9WGnTaI@qQt9Nn_MCNbarV?yHk9z+r6pK?LXM4c6g^|lpf5J#U;4EZgPp*
zqb&~VIy91-ZQfyG8@(BO-V(nix<UQ={P79nC%svn-)%6p*|nLL|26)Yng|GMjNDQB
zYkP-Trme810&Nzr9iftD-hcXXz2nrE<-Zr^xtotE$+$|*NKW<K+?8?Xz4M)gA20>U
zxpFdpSDmrm`_6C7{X70>N<{i{`kEj3eUKRj(@@RirIw)P<dX-}a<#*a9Vv}#E|8_@
zinT{SkJ}&kxGPjX7?Glhx-Wx<xxc;*_TGNvV>~pqZS+-7+R&Vy#$>*7L+&N#8hNl&
zfvq}r9RqF*Hca|fco$XK2;W4@`>SkX#mQ}TiT^rAJ{87M+K@e!FR$>jGSJ=PDz)U;
z%<NF)NE5Cc*D%kPZ+dQ$GQBVKXVPpG)ApBJD`&tBT{ra&AN7p>vq}xs2%_pnl6cI<
zd3`&@bq}fP1cW_oo%#sV)8R=v%H43$)c;P2i>szYesk)hCc^8kZocT9565oIhf@>r
bAk!rUX)G!uoFj`v|9>fk+(%aB5uW-V^z7Ux

literal 0
HcmV?d00001

diff --git a/lib/cake_pay/cake_pay_api.dart b/lib/cake_pay/cake_pay_api.dart
index f403ebc63..1f91b338d 100644
--- a/lib/cake_pay/cake_pay_api.dart
+++ b/lib/cake_pay/cake_pay_api.dart
@@ -3,6 +3,7 @@ import 'dart:convert';
 import 'package:cake_wallet/cake_pay/cake_pay_order.dart';
 import 'package:cake_wallet/cake_pay/cake_pay_user_credentials.dart';
 import 'package:cake_wallet/cake_pay/cake_pay_vendor.dart';
+import 'package:cake_wallet/entities/country.dart';
 import 'package:http/http.dart' as http;
 
 class CakePayApi {
@@ -171,7 +172,7 @@ class CakePayApi {
   }
 
   /// Get Countries
-  Future<List<String>> getCountries(
+  Future<List<Country>> getCountries(
       {required String CSRFToken, required String authorization}) async {
     final uri = Uri.https(baseCakePayUri, countriesPath);
 
@@ -188,8 +189,11 @@ class CakePayApi {
     }
 
     final bodyJson = json.decode(response.body) as List;
-
-    return bodyJson.map<String>((country) => country['name'] as String).toList();
+    return bodyJson
+        .map<String>((country) => country['name'] as String)
+        .map((name) => Country.fromCakePayName(name))
+        .whereType<Country>()
+        .toList();
   }
 
   /// Get Vendors
diff --git a/lib/cake_pay/cake_pay_service.dart b/lib/cake_pay/cake_pay_service.dart
index be8e1d189..39f2ca77a 100644
--- a/lib/cake_pay/cake_pay_service.dart
+++ b/lib/cake_pay/cake_pay_service.dart
@@ -3,6 +3,7 @@ import 'package:cake_wallet/cake_pay/cake_pay_api.dart';
 import 'package:cake_wallet/cake_pay/cake_pay_order.dart';
 import 'package:cake_wallet/cake_pay/cake_pay_vendor.dart';
 import 'package:cake_wallet/core/secure_storage.dart';
+import 'package:cake_wallet/entities/country.dart';
 
 class CakePayService {
   CakePayService(this.secureStorage, this.cakePayApi);
@@ -23,7 +24,7 @@ class CakePayService {
   final CakePayApi cakePayApi;
 
   /// Get Available Countries
-  Future<List<String>> getCountries() async =>
+  Future<List<Country>> getCountries() async =>
       await cakePayApi.getCountries(CSRFToken: CSRFToken, authorization: authorization);
 
   /// Get Vendors
diff --git a/lib/di.dart b/lib/di.dart
index 14fdbd56d..540a546fd 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -1271,7 +1271,8 @@ Future<void> setup({
       () => CakePayService(getIt.get<SecureStorage>(), getIt.get<CakePayApi>()));
 
   getIt.registerFactory(
-      () => CakePayCardsListViewModel(cakePayService: getIt.get<CakePayService>()));
+      () => CakePayCardsListViewModel(cakePayService: getIt.get<CakePayService>(),
+          settingsStore: getIt.get<SettingsStore>()));
 
   getIt.registerFactory(() => CakePayAuthViewModel(cakePayService: getIt.get<CakePayService>()));
 
diff --git a/lib/entities/country.dart b/lib/entities/country.dart
new file mode 100644
index 000000000..63eee9a18
--- /dev/null
+++ b/lib/entities/country.dart
@@ -0,0 +1,386 @@
+import 'package:cw_core/enumerable_item.dart';
+import 'package:collection/collection.dart';
+
+class Country extends EnumerableItem<String> with Serializable<String> {
+  const Country({required String code, required this.fullName, required this.countryCode})
+      : super(title: fullName, raw: code);
+
+  final String fullName;
+  final String countryCode;
+
+  static List<Country> get all => _all.values.toList();
+
+  static const afghanistan = Country(code: 'afg', countryCode: 'AF', fullName: "Afghanistan");
+  static const andorra = Country(code: 'and', countryCode: 'AD', fullName: "Andorra");
+  static const angola = Country(code: 'ago', countryCode: 'AO', fullName: "Angola");
+  static const anguilla = Country(code: 'aia', countryCode: 'AI', fullName: "Anguilla");
+  static const antigua_and_barbuda =
+      Country(code: 'atg', countryCode: 'AG', fullName: "Antigua and Barbuda");
+  static const are = Country(code: 'are', countryCode: 'AE', fullName: "United Arab Emirates");
+  static const arg = Country(code: 'arg', countryCode: 'AR', fullName: "Argentina");
+  static const arm = Country(code: 'arm', countryCode: 'AM', fullName: "Armenia");
+  static const aruba = Country(code: 'abw', countryCode: 'AW', fullName: "Aruba");
+  static const aus = Country(code: 'aus', countryCode: 'AU', fullName: "Australia");
+  static const aut = Country(code: 'aut', countryCode: 'AT', fullName: "Austria");
+  static const aze = Country(code: 'aze', countryCode: 'AZ', fullName: "Azerbaijan");
+  static const belize = Country(code: 'blz', countryCode: 'BZ', fullName: "Belize");
+  static const bfa = Country(code: 'bfa', countryCode: 'BF', fullName: "Burkina Faso");
+  static const bel = Country(code: 'bel', countryCode: 'BE', fullName: "Belgium");
+  static const bgd = Country(code: 'bgd', countryCode: 'BD', fullName: "Bangladesh");
+  static const bhr = Country(code: 'bhr', countryCode: 'BH', fullName: "Bahrain");
+  static const bhs = Country(code: 'bhs', countryCode: 'BS', fullName: "Bahamas");
+  static const bhutan = Country(code: 'btn', countryCode: 'BT', fullName: "Bhutan");
+  static const bol = Country(code: 'bol', countryCode: 'BO', fullName: "Bolivia");
+  static const bra = Country(code: 'bra', countryCode: 'BR', fullName: "Brazil");
+  static const brn = Country(code: 'brn', countryCode: 'BN', fullName: "Brunei");
+  static const bwa = Country(code: 'bwa', countryCode: 'BW', fullName: "Botswana");
+  static const cad = Country(code: 'cad', countryCode: 'CA', fullName: "Canada");
+  static const che = Country(code: 'che', countryCode: 'CH', fullName: "Switzerland");
+  static const chl = Country(code: 'chl', countryCode: 'CL', fullName: "Chile");
+  static const chn = Country(code: 'chn', countryCode: 'CN', fullName: "China");
+  static const col = Country(code: 'col', countryCode: 'CO', fullName: "Colombia");
+  static const cri = Country(code: 'cri', countryCode: 'CR', fullName: "Costa Rica");
+  static const cyp = Country(code: 'cyp', countryCode: 'CY', fullName: "Cyprus");
+  static const czk = Country(code: 'czk', countryCode: 'CZ', fullName: "Czech Republic");
+  static const deu = Country(code: 'deu', countryCode: 'DE', fullName: "Germany");
+  static const dji = Country(code: 'dji', countryCode: 'DJ', fullName: "Djibouti");
+  static const dnk = Country(code: 'dnk', countryCode: 'DK', fullName: "Denmark");
+  static const dza = Country(code: 'dza', countryCode: 'DZ', fullName: "Algeria");
+  static const ecu = Country(code: 'ecu', countryCode: 'EC', fullName: "Ecuador");
+  static const egy = Country(code: 'egy', countryCode: 'EG', fullName: "Egypt");
+  static const esp = Country(code: 'esp', countryCode: 'ES', fullName: "Spain");
+  static const est = Country(code: 'est', countryCode: 'EE', fullName: "Estonia");
+  static const eur = Country(code: 'eur', countryCode: 'EU', fullName: "European Union");
+  static const fin = Country(code: 'fin', countryCode: 'FI', fullName: "Finland");
+  static const fji = Country(code: 'fji', countryCode: 'FJ', fullName: "Fiji");
+  static const flk = Country(code: 'flk', countryCode: 'FK', fullName: "Falkland Islands");
+  static const fra = Country(code: 'fra', countryCode: 'FR', fullName: "France");
+  static const fsm = Country(code: 'fsm', countryCode: 'FM', fullName: "Micronesia");
+  static const gab = Country(code: 'gab', countryCode: 'GA', fullName: "Gabon");
+  static const gbr = Country(code: 'gbr', countryCode: 'GB', fullName: "United Kingdom");
+  static const geo = Country(code: 'geo', countryCode: 'GE', fullName: "Georgia");
+  static const gha = Country(code: 'gha', countryCode: 'GH', fullName: "Ghana");
+  static const grc = Country(code: 'grc', countryCode: 'GR', fullName: "Greece");
+  static const grd = Country(code: 'grd', countryCode: 'GD', fullName: "Grenada");
+  static const grl = Country(code: 'grl', countryCode: 'GL', fullName: "Greenland");
+  static const gtm = Country(code: 'gtm', countryCode: 'GT', fullName: "Guatemala");
+  static const guy = Country(code: 'guy', countryCode: 'GY', fullName: "Guyana");
+  static const hkg = Country(code: 'hkg', countryCode: 'HK', fullName: "Hong Kong");
+  static const hrv = Country(code: 'hrv', countryCode: 'HR', fullName: "Croatia");
+  static const hun = Country(code: 'hun', countryCode: 'HU', fullName: "Hungary");
+  static const idn = Country(code: 'idn', countryCode: 'ID', fullName: "Indonesia");
+  static const ind = Country(code: 'ind', countryCode: 'IN', fullName: "India");
+  static const irl = Country(code: 'irl', countryCode: 'IE', fullName: "Ireland");
+  static const irn = Country(code: 'irn', countryCode: 'IR', fullName: "Iran");
+  static const isl = Country(code: 'isl', countryCode: 'IS', fullName: "Iceland");
+  static const isr = Country(code: 'isr', countryCode: 'IL', fullName: "Israel");
+  static const ita = Country(code: 'ita', countryCode: 'IT', fullName: "Italy");
+  static const jam = Country(code: 'jam', countryCode: 'JM', fullName: "Jamaica");
+  static const jor = Country(code: 'jor', countryCode: 'JO', fullName: "Jordan");
+  static const jpn = Country(code: 'jpn', countryCode: 'JP', fullName: "Japan");
+  static const kaz = Country(code: 'kaz', countryCode: 'KZ', fullName: "Kazakhstan");
+  static const ken = Country(code: 'ken', countryCode: 'KE', fullName: "Kenya");
+  static const kir = Country(code: 'kir', countryCode: 'KI', fullName: "Kiribati");
+  static const kor = Country(code: 'kor', countryCode: 'KR', fullName: "South Korea");
+  static const kwt = Country(code: 'kwt', countryCode: 'KW', fullName: "Kuwait");
+  static const lie = Country(code: 'lie', countryCode: 'LI', fullName: "Liechtenstein");
+  static const lka = Country(code: 'lka', countryCode: 'LK', fullName: "Sri Lanka");
+  static const ltu = Country(code: 'ltu', countryCode: 'LT', fullName: "Lithuania");
+  static const lux = Country(code: 'lux', countryCode: 'LU', fullName: "Luxembourg");
+  static const lva = Country(code: 'lva', countryCode: 'LV', fullName: "Latvia");
+  static const mar = Country(code: 'mar', countryCode: 'MA', fullName: "Morocco");
+  static const mex = Country(code: 'mex', countryCode: 'MX', fullName: "Mexico");
+  static const mlt = Country(code: 'mlt', countryCode: 'MT', fullName: "Malta");
+  static const mnp = Country(code: 'mnp', countryCode: 'MP', fullName: "Northern Mariana Islands");
+  static const mtq = Country(code: 'mtq', countryCode: 'MQ', fullName: "Martinique");
+  static const mys = Country(code: 'mys', countryCode: 'MY', fullName: "Malaysia");
+  static const mwi = Country(code: 'mwi', countryCode: 'MW', fullName: "Malawi");
+  static const nga = Country(code: 'nga', countryCode: 'NG', fullName: "Nigeria");
+  static const niu = Country(code: 'niu', countryCode: 'NU', fullName: "Niue");
+  static const nld = Country(code: 'nld', countryCode: 'NL', fullName: "Netherlands");
+  static const nor = Country(code: 'nor', countryCode: 'NO', fullName: "Norway");
+  static const nzl = Country(code: 'nzl', countryCode: 'NZ', fullName: "New Zealand");
+  static const omn = Country(code: 'omn', countryCode: 'OM', fullName: "Oman");
+  static const pak = Country(code: 'pak', countryCode: 'PK', fullName: "Pakistan");
+  static const per = Country(code: 'per', countryCode: 'PE', fullName: "Peru");
+  static const phl = Country(code: 'phl', countryCode: 'PH', fullName: "Philippines");
+  static const pol = Country(code: 'pol', countryCode: 'PL', fullName: "Poland");
+  static const pri = Country(code: 'pri', countryCode: 'PR', fullName: "Puerto Rico");
+  static const prt = Country(code: 'prt', countryCode: 'PT', fullName: "Portugal");
+  static const qat = Country(code: 'qat', countryCode: 'QA', fullName: "Qatar");
+  static const rou = Country(code: 'rou', countryCode: 'RO', fullName: "Romania");
+  static const rus = Country(code: 'rus', countryCode: 'RU', fullName: "Russia");
+  static const saf = Country(code: 'saf', countryCode: 'ZA', fullName: "South Africa");
+  static const sau = Country(code: 'sau', countryCode: 'SA', fullName: "Saudi Arabia");
+  static const sgp = Country(code: 'sgp', countryCode: 'SG', fullName: "Singapore");
+  static const slb = Country(code: 'slb', countryCode: 'SB', fullName: "Solomon Islands");
+  static const svk = Country(code: 'svk', countryCode: 'SK', fullName: "Slovakia");
+  static const svn = Country(code: 'svn', countryCode: 'SI', fullName: "Slovenia");
+  static const swe = Country(code: 'swe', countryCode: 'SE', fullName: "Sweden");
+  static const tha = Country(code: 'tha', countryCode: 'TH', fullName: "Thailand");
+  static const tkm = Country(code: 'tkm', countryCode: 'TM', fullName: "Turkmenistan");
+  static const ton = Country(code: 'ton', countryCode: 'TO', fullName: "Tonga");
+  static const tur = Country(code: 'tur', countryCode: 'TR', fullName: "Turkey");
+  static const tuv = Country(code: 'tuv', countryCode: 'TV', fullName: "Tuvalu");
+  static const twn = Country(code: 'twn', countryCode: 'TW', fullName: "Taiwan");
+  static const ukr = Country(code: 'ukr', countryCode: 'UA', fullName: "Ukraine");
+  static const ury = Country(code: 'ury', countryCode: 'UY', fullName: "Uruguay");
+  static const usa = Country(code: 'usa', countryCode: 'US', fullName: "USA");
+  static const ven = Country(code: 'ven', countryCode: 'VE', fullName: "Venezuela");
+  static const vnm = Country(code: 'vnm', countryCode: 'VN', fullName: "Vietnam");
+  static const vut = Country(code: 'vut', countryCode: 'VU', fullName: "Vanuatu");
+  static const btn = Country(code: 'btn', countryCode: 'BT', fullName: "Bhutan");
+  static const bgr = Country(code: 'bgr', countryCode: 'BG', fullName: "Bulgaria");
+  static const guf = Country(code: 'guf', countryCode: 'GF', fullName: "French Guiana");
+  static const bes = Country(code: 'bes', countryCode: 'BQ', fullName: "Caribbean Netherlands");
+  static const fro = Country(code: 'fro', countryCode: 'FO', fullName: "Faroe Islands");
+  static const cuw = Country(code: 'cuw', countryCode: 'CW', fullName: "Curacao");
+  static const msr = Country(code: 'msr', countryCode: 'MS', fullName: "Montserrat");
+  static const cpv = Country(code: 'cpv', countryCode: 'CV', fullName: "Cabo Verde");
+  static const nfk = Country(code: 'nfk', countryCode: 'NF', fullName: "Norfolk Island");
+  static const bmu = Country(code: 'bmu', countryCode: 'BM', fullName: "Bermuda");
+  static const vat = Country(code: 'vat', countryCode: 'VA', fullName: "Vatican City");
+  static const aia = Country(code: 'aia', countryCode: 'AI', fullName: "Anguilla");
+  static const gum = Country(code: 'gum', countryCode: 'GU', fullName: "Guam");
+  static const myt = Country(code: 'myt', countryCode: 'YT', fullName: "Mayotte");
+  static const mrt = Country(code: 'mrt', countryCode: 'MR', fullName: "Mauritania");
+  static const ggy = Country(code: 'ggy', countryCode: 'GG', fullName: "Guernsey");
+  static const cck = Country(code: 'cck', countryCode: 'CC', fullName: "Cocos (Keeling) Islands");
+  static const blz = Country(code: 'blz', countryCode: 'BZ', fullName: "Belize");
+  static const cxr = Country(code: 'cxr', countryCode: 'CX', fullName: "Christmas Island");
+  static const mco = Country(code: 'mco', countryCode: 'MC', fullName: "Monaco");
+  static const ner = Country(code: 'ner', countryCode: 'NE', fullName: "Niger");
+  static const jey = Country(code: 'jey', countryCode: 'JE', fullName: "Jersey");
+  static const asm = Country(code: 'asm', countryCode: 'AS', fullName: "American Samoa");
+  static const gmb = Country(code: 'gmb', countryCode: 'GM', fullName: "Gambia");
+  static const dma = Country(code: 'dma', countryCode: 'DM', fullName: "Dominica");
+  static const glp = Country(code: 'glp', countryCode: 'GP', fullName: "Guadeloupe");
+  static const ggi = Country(code: 'ggi', countryCode: 'GI', fullName: "Gibraltar");
+  static const cmr = Country(code: 'cmr', countryCode: 'CM', fullName: "Cameroon");
+  static const atg = Country(code: 'atg', countryCode: 'AG', fullName: "Antigua and Barbuda");
+  static const slv = Country(code: 'slv', countryCode: 'SV', fullName: "El Salvador");
+  static const pyf = Country(code: 'pyf', countryCode: 'PF', fullName: "French Polynesia");
+  static const iot =
+      Country(code: 'iot', countryCode: 'IO', fullName: "British Indian Ocean Territory");
+  static const vir = Country(code: 'vir', countryCode: 'VI', fullName: "Virgin Islands (U.S.)");
+  static const abw = Country(code: 'abw', countryCode: 'AW', fullName: "Aruba");
+  static const ago = Country(code: 'ago', countryCode: 'AO', fullName: "Angola");
+  static const afg = Country(code: 'afg', countryCode: 'AF', fullName: "Afghanistan");
+  static const lbn = Country(code: 'lbn', countryCode: 'LB', fullName: "Lebanon");
+  static const hmd =
+      Country(code: 'hmd', countryCode: 'HM', fullName: "Heard Island and McDonald Islands");
+  static const cok = Country(code: 'cok', countryCode: 'CK', fullName: "Cook Islands");
+  static const bvt = Country(code: 'bvt', countryCode: 'BV', fullName: "Bouvet Island");
+  static const atf =
+      Country(code: 'atf', countryCode: 'TF', fullName: "French Southern Territories");
+  static const eth = Country(code: 'eth', countryCode: 'ET', fullName: "Ethiopia");
+  static const plw = Country(code: 'plw', countryCode: 'PW', fullName: "Palau");
+  static const ata = Country(code: 'ata', countryCode: 'AQ', fullName: "Antarctica");
+
+  static final _all = {
+    Country.afghanistan.raw: Country.afghanistan,
+    Country.andorra.raw: Country.andorra,
+    Country.angola.raw: Country.angola,
+    Country.anguilla.raw: Country.anguilla,
+    Country.antigua_and_barbuda.raw: Country.antigua_and_barbuda,
+    Country.are.raw: Country.are,
+    Country.arg.raw: Country.arg,
+    Country.arm.raw: Country.arm,
+    Country.aruba.raw: Country.aruba,
+    Country.aus.raw: Country.aus,
+    Country.aut.raw: Country.aut,
+    Country.aze.raw: Country.aze,
+    Country.belize.raw: Country.belize,
+    Country.bfa.raw: Country.bfa,
+    Country.bel.raw: Country.bel,
+    Country.bgd.raw: Country.bgd,
+    Country.bhr.raw: Country.bhr,
+    Country.bhs.raw: Country.bhs,
+    Country.bhutan.raw: Country.bhutan,
+    Country.bol.raw: Country.bol,
+    Country.bra.raw: Country.bra,
+    Country.brn.raw: Country.brn,
+    Country.bwa.raw: Country.bwa,
+    Country.cad.raw: Country.cad,
+    Country.che.raw: Country.che,
+    Country.chl.raw: Country.chl,
+    Country.chn.raw: Country.chn,
+    Country.col.raw: Country.col,
+    Country.cri.raw: Country.cri,
+    Country.cyp.raw: Country.cyp,
+    Country.czk.raw: Country.czk,
+    Country.deu.raw: Country.deu,
+    Country.dji.raw: Country.dji,
+    Country.dnk.raw: Country.dnk,
+    Country.dza.raw: Country.dza,
+    Country.ecu.raw: Country.ecu,
+    Country.egy.raw: Country.egy,
+    Country.esp.raw: Country.esp,
+    Country.est.raw: Country.est,
+    Country.eur.raw: Country.eur,
+    Country.fin.raw: Country.fin,
+    Country.fji.raw: Country.fji,
+    Country.flk.raw: Country.flk,
+    Country.fra.raw: Country.fra,
+    Country.fsm.raw: Country.fsm,
+    Country.gab.raw: Country.gab,
+    Country.gbr.raw: Country.gbr,
+    Country.geo.raw: Country.geo,
+    Country.gha.raw: Country.gha,
+    Country.grc.raw: Country.grc,
+    Country.grd.raw: Country.grd,
+    Country.grl.raw: Country.grl,
+    Country.gtm.raw: Country.gtm,
+    Country.guy.raw: Country.guy,
+    Country.hkg.raw: Country.hkg,
+    Country.hrv.raw: Country.hrv,
+    Country.hun.raw: Country.hun,
+    Country.idn.raw: Country.idn,
+    Country.ind.raw: Country.ind,
+    Country.irl.raw: Country.irl,
+    Country.irn.raw: Country.irn,
+    Country.isl.raw: Country.isl,
+    Country.isr.raw: Country.isr,
+    Country.ita.raw: Country.ita,
+    Country.jam.raw: Country.jam,
+    Country.jor.raw: Country.jor,
+    Country.jpn.raw: Country.jpn,
+    Country.kaz.raw: Country.kaz,
+    Country.ken.raw: Country.ken,
+    Country.kir.raw: Country.kir,
+    Country.kor.raw: Country.kor,
+    Country.kwt.raw: Country.kwt,
+    Country.lie.raw: Country.lie,
+    Country.lka.raw: Country.lka,
+    Country.ltu.raw: Country.ltu,
+    Country.lux.raw: Country.lux,
+    Country.lva.raw: Country.lva,
+    Country.mar.raw: Country.mar,
+    Country.mex.raw: Country.mex,
+    Country.mlt.raw: Country.mlt,
+    Country.mnp.raw: Country.mnp,
+    Country.mtq.raw: Country.mtq,
+    Country.mys.raw: Country.mys,
+    Country.mwi.raw: Country.mwi,
+    Country.nga.raw: Country.nga,
+    Country.niu.raw: Country.niu,
+    Country.nld.raw: Country.nld,
+    Country.nor.raw: Country.nor,
+    Country.nzl.raw: Country.nzl,
+    Country.omn.raw: Country.omn,
+    Country.pak.raw: Country.pak,
+    Country.per.raw: Country.per,
+    Country.phl.raw: Country.phl,
+    Country.pol.raw: Country.pol,
+    Country.pri.raw: Country.pri,
+    Country.prt.raw: Country.prt,
+    Country.qat.raw: Country.qat,
+    Country.rou.raw: Country.rou,
+    Country.rus.raw: Country.rus,
+    Country.saf.raw: Country.saf,
+    Country.sau.raw: Country.sau,
+    Country.sgp.raw: Country.sgp,
+    Country.slb.raw: Country.slb,
+    Country.svk.raw: Country.svk,
+    Country.svn.raw: Country.svn,
+    Country.swe.raw: Country.swe,
+    Country.tha.raw: Country.tha,
+    Country.tkm.raw: Country.tkm,
+    Country.ton.raw: Country.ton,
+    Country.tur.raw: Country.tur,
+    Country.tuv.raw: Country.tuv,
+    Country.twn.raw: Country.twn,
+    Country.ukr.raw: Country.ukr,
+    Country.ury.raw: Country.ury,
+    Country.usa.raw: Country.usa,
+    Country.ven.raw: Country.ven,
+    Country.vnm.raw: Country.vnm,
+    Country.vut.raw: Country.vut,
+    Country.btn.raw: Country.btn,
+    Country.bgr.raw: Country.bgr,
+    Country.guf.raw: Country.guf,
+    Country.bes.raw: Country.bes,
+    Country.fro.raw: Country.fro,
+    Country.cuw.raw: Country.cuw,
+    Country.msr.raw: Country.msr,
+    Country.cpv.raw: Country.cpv,
+    Country.nfk.raw: Country.nfk,
+    Country.bmu.raw: Country.bmu,
+    Country.vat.raw: Country.vat,
+    Country.aia.raw: Country.aia,
+    Country.gum.raw: Country.gum,
+    Country.myt.raw: Country.myt,
+    Country.mrt.raw: Country.mrt,
+    Country.ggy.raw: Country.ggy,
+    Country.cck.raw: Country.cck,
+    Country.blz.raw: Country.blz,
+    Country.cxr.raw: Country.cxr,
+    Country.mco.raw: Country.mco,
+    Country.ner.raw: Country.ner,
+    Country.jey.raw: Country.jey,
+    Country.asm.raw: Country.asm,
+    Country.gmb.raw: Country.gmb,
+    Country.dma.raw: Country.dma,
+    Country.glp.raw: Country.glp,
+    Country.ggi.raw: Country.ggi,
+    Country.cmr.raw: Country.cmr,
+    Country.atg.raw: Country.atg,
+    Country.slv.raw: Country.slv,
+    Country.pyf.raw: Country.pyf,
+    Country.iot.raw: Country.iot,
+    Country.vir.raw: Country.vir,
+    Country.abw.raw: Country.abw,
+    Country.ago.raw: Country.ago,
+    Country.afg.raw: Country.afg,
+    Country.lbn.raw: Country.lbn,
+    Country.hmd.raw: Country.hmd,
+    Country.cok.raw: Country.cok,
+    Country.bvt.raw: Country.bvt,
+    Country.atf.raw: Country.atf,
+    Country.eth.raw: Country.eth,
+    Country.plw.raw: Country.plw,
+    Country.ata.raw: Country.ata,
+  };
+
+  static final Map<String, String> _cakePayNames = {
+    'Slovak Republic': 'Slovakia',
+    'Brunei Darussalam': 'Brunei',
+    'Federated States of Micronesia': 'Micronesia',
+    'Sri lanka': 'Sri Lanka',
+    'UAE': 'United Arab Emirates',
+    'UK': 'United Kingdom',
+    'Curaçao': "Curacao",
+  };
+
+  static Country deserialize({required String raw}) => _all[raw]!;
+
+  static final Map<String, Country> countryByName = {
+    for (var country in _all.values) country.fullName: country,
+  };
+
+  static Country? fromCakePayName(String name) {
+    final normalizedName = _cakePayNames[name] ?? name;
+    return countryByName[normalizedName];
+  }
+
+  static String getCakePayName(Country country) {
+    return _cakePayNames.entries
+        .firstWhere(
+          (entry) => entry.value == country.fullName,
+          orElse: () => MapEntry(country.fullName, country.fullName),
+        )
+        .key;
+  }
+
+  static Country? fromCode(String countryCode) {
+    return _all.values.firstWhereOrNull((element) => element.raw == countryCode.toLowerCase());
+  }
+
+  @override
+  bool operator ==(Object other) => other is Country && other.raw == raw;
+
+  @override
+  int get hashCode => raw.hashCode ^ title.hashCode;
+
+  String get iconPath => "assets/images/flags/$raw.png";
+}
diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart
index 8e8bfb6ed..0bb526e5d 100644
--- a/lib/entities/preferences_key.dart
+++ b/lib/entities/preferences_key.dart
@@ -12,6 +12,7 @@ class PreferencesKey {
   static const currentBananoNodeIdKey = 'current_node_id_banano';
   static const currentBananoPowNodeIdKey = 'current_node_id_banano_pow';
   static const currentFiatCurrencyKey = 'current_fiat_currency';
+  static const currentCakePayCountry = 'current_cake_pay_country';
   static const currentBitcoinCashNodeIdKey = 'current_node_id_bch';
   static const currentSolanaNodeIdKey = 'current_node_id_sol';
   static const currentTronNodeIdKey = 'current_node_id_trx';
diff --git a/lib/src/screens/cake_pay/cards/cake_pay_cards_page.dart b/lib/src/screens/cake_pay/cards/cake_pay_cards_page.dart
index 35a58ce0a..31eaa23ff 100644
--- a/lib/src/screens/cake_pay/cards/cake_pay_cards_page.dart
+++ b/lib/src/screens/cake_pay/cards/cake_pay_cards_page.dart
@@ -1,5 +1,6 @@
 import 'package:cake_wallet/cake_pay/cake_pay_states.dart';
 import 'package:cake_wallet/cake_pay/cake_pay_vendor.dart';
+import 'package:cake_wallet/entities/country.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/screens/base_page.dart';
@@ -8,6 +9,7 @@ import 'package:cake_wallet/src/screens/cake_pay/widgets/card_menu.dart';
 import 'package:cake_wallet/src/screens/dashboard/widgets/filter_widget.dart';
 import 'package:cake_wallet/src/widgets/cake_scrollbar.dart';
 import 'package:cake_wallet/src/widgets/gradient_background.dart';
+import 'package:cake_wallet/src/widgets/picker.dart';
 import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
 import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
 import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
@@ -20,6 +22,7 @@ import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:cake_wallet/view_model/cake_pay/cake_pay_cards_list_view_model.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
+import 'package:mobx/mobx.dart';
 
 class CakePayCardsPage extends BasePage {
   CakePayCardsPage(this._cardsListViewModel) : searchFocusNode = FocusNode() {
@@ -80,9 +83,25 @@ class CakePayCardsPage extends BasePage {
 
   @override
   Widget body(BuildContext context) {
+
+    if (_cardsListViewModel.settingsStore.selectedCakePayCountry == null) {
+    WidgetsBinding.instance.addPostFrameCallback((_) {
+      reaction((_) => _cardsListViewModel.shouldShowCountryPicker, (bool shouldShowCountryPicker) async {
+        if (shouldShowCountryPicker) {
+          _cardsListViewModel.storeInitialFilterStates();
+          await showCountryPicker(context, _cardsListViewModel);
+          if (_cardsListViewModel.hasFiltersChanged) {
+            _cardsListViewModel.resetLoadingNextPageState();
+            _cardsListViewModel.getVendors();
+          }
+        }
+      });
+    });
+    }
+
     final filterButton = Semantics(
       label: S.of(context).filter_by,
-      child: InkWell(
+      child: GestureDetector(
           onTap: () async {
             _cardsListViewModel.storeInitialFilterStates();
             await showFilterWidget(context);
@@ -92,50 +111,87 @@ class CakePayCardsPage extends BasePage {
             }
           },
           child: Container(
-            width: 32,
-            padding: EdgeInsets.all(8),
-            decoration: BoxDecoration(
-              color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
-              border: Border.all(
-                color: Colors.white.withOpacity(0.2),
+              width: 32,
+              padding: EdgeInsets.all(8),
+              decoration: BoxDecoration(
+                color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
+                border: Border.all(
+                  color: Colors.transparent,
+                ),
+                borderRadius: BorderRadius.circular(10),
               ),
-              borderRadius: BorderRadius.circular(10),
+              child: Image.asset(
+                'assets/images/filter.png',
+                color: Theme.of(context).extension<FilterTheme>()!.iconColor,
+              ))),
+    );
+    final _countryPicker = Semantics(
+      label: S.of(context).filter_by,
+      child: GestureDetector(
+        onTap: () async {
+          _cardsListViewModel.storeInitialFilterStates();
+          await showCountryPicker(context, _cardsListViewModel);
+          if (_cardsListViewModel.hasFiltersChanged) {
+            _cardsListViewModel.resetLoadingNextPageState();
+            _cardsListViewModel.getVendors();
+          }
+        },
+        child: Container(
+          padding: EdgeInsets.symmetric(horizontal: 6),
+          decoration: BoxDecoration(
+            color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
+            border: Border.all(color: Colors.transparent),
+            borderRadius: BorderRadius.circular(10),
+          ),
+          child: Container(
+            margin: EdgeInsets.symmetric(vertical: 2),
+            child: Row(
+              children: [
+                Image.asset(
+                  _cardsListViewModel.selectedCountry.iconPath,
+                  width: 24,
+                  height: 24,
+                  errorBuilder: (context, error, stackTrace) => Container(
+                    width: 24,
+                    height: 24,
+                  ),
+                ),
+                SizedBox(width: 6),
+                Text(
+                  _cardsListViewModel.selectedCountry.countryCode,
+                  style: TextStyle(
+                    color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
+                    fontSize: 16,
+                    fontWeight: FontWeight.w700,
+                  ),
+                ),
+              ],
             ),
-            child: Image.asset(
-              'assets/images/filter.png',
-              color: Theme.of(context).extension<FilterTheme>()!.iconColor,
-            ),
-          )),
+          ),
+        ),
+      ),
     );
 
     return Padding(
-      padding: const EdgeInsets.all(14.0),
-      child: Column(
-        children: [
+        padding: const EdgeInsets.all(14.0),
+        child: Column(children: [
           Container(
-            padding: EdgeInsets.only(left: 2, right: 22),
-            height: 32,
-            child: Row(
-              children: [
+              padding: EdgeInsets.only(left: 2, right: 22),
+              height: 32,
+              child: Row(children: [
                 Expanded(
                     child: _SearchWidget(
                   controller: _searchController,
                   focusNode: searchFocusNode,
                 )),
-                SizedBox(width: 10),
-                filterButton
-              ],
-            ),
-          ),
+                SizedBox(width: 5),
+                filterButton,
+                SizedBox(width: 5),
+                _countryPicker
+              ])),
           SizedBox(height: 8),
-          Expanded(
-            child: CakePayCardsPageBody(
-              cardsListViewModel: _cardsListViewModel,
-            ),
-          ),
-        ],
-      ),
-    );
+          Expanded(child: CakePayCardsPageBody(cardsListViewModel: _cardsListViewModel))
+        ]));
   }
 
   Future<void> showFilterWidget(BuildContext context) async {
@@ -148,6 +204,32 @@ class CakePayCardsPage extends BasePage {
   }
 }
 
+
+Future<void> showCountryPicker(BuildContext context, CakePayCardsListViewModel cardsListViewModel) async {
+  await showPopUp<void>(
+      context: context,
+      builder: (_) => Picker(
+        title: S.of(context).select_your_country,
+          items: cardsListViewModel.availableCountries,
+          images: cardsListViewModel.availableCountries
+              .map((e) => Image.asset(
+            e.iconPath,
+            errorBuilder: (context, error, stackTrace) => Container(
+              width: 58,
+              height: 58,
+            ),
+          ))
+              .toList(),
+          selectedAtIndex: cardsListViewModel.availableCountries
+              .indexOf(cardsListViewModel.selectedCountry),
+          onItemSelected: (Country country) =>
+              cardsListViewModel.setSelectedCountry(country),
+          isSeparated: false,
+          hintText: S.of(context).search,
+          matchingCriteria: (Country country, String searchText) =>
+              country.fullName.toLowerCase().contains(searchText.toLowerCase())));
+}
+
 class CakePayCardsPageBody extends StatefulWidget {
   const CakePayCardsPageBody({
     Key? key,
@@ -304,15 +386,9 @@ class _SearchWidget extends StatelessWidget {
           alignLabelWithHint: true,
           floatingLabelBehavior: FloatingLabelBehavior.never,
           suffixIcon: searchIcon,
-          border: OutlineInputBorder(
-            borderSide: BorderSide(
-              color: Colors.white.withOpacity(0.2),
-            ),
-            borderRadius: BorderRadius.circular(10),
-          ),
           enabledBorder: OutlineInputBorder(
             borderSide: BorderSide(
-              color: Colors.white.withOpacity(0.2),
+              color: Colors.transparent,
             ),
             borderRadius: BorderRadius.circular(10),
           ),
diff --git a/lib/src/screens/cake_pay/widgets/card_item.dart b/lib/src/screens/cake_pay/widgets/card_item.dart
index ce804adc2..1234c0a1f 100644
--- a/lib/src/screens/cake_pay/widgets/card_item.dart
+++ b/lib/src/screens/cake_pay/widgets/card_item.dart
@@ -9,7 +9,7 @@ class CardItem extends StatelessWidget {
     required this.backgroundColor,
     required this.titleColor,
     required this.subtitleColor,
-    this.hideBorder = false,
+    this.hideBorder = true,
     this.discount = 0.0,
     this.isAmount = false,
     this.discountBackground,
diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart
index c966420db..50d51d2ed 100644
--- a/lib/store/settings_store.dart
+++ b/lib/store/settings_store.dart
@@ -9,6 +9,7 @@ import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
 import 'package:cake_wallet/entities/background_tasks.dart';
 import 'package:cake_wallet/entities/balance_display_mode.dart';
 import 'package:cake_wallet/entities/cake_2fa_preset_options.dart';
+import 'package:cake_wallet/entities/country.dart';
 import 'package:cake_wallet/entities/exchange_api_mode.dart';
 import 'package:cake_wallet/entities/fiat_api_mode.dart';
 import 'package:cake_wallet/entities/fiat_currency.dart';
@@ -128,7 +129,8 @@ abstract class SettingsStoreBase with Store {
       TransactionPriority? initialLitecoinTransactionPriority,
       TransactionPriority? initialEthereumTransactionPriority,
       TransactionPriority? initialPolygonTransactionPriority,
-      TransactionPriority? initialBitcoinCashTransactionPriority})
+      TransactionPriority? initialBitcoinCashTransactionPriority,
+      Country? initialCakePayCountry})
       : nodes = ObservableMap<WalletType, Node>.of(nodes),
         powNodes = ObservableMap<WalletType, Node>.of(powNodes),
         _secureStorage = secureStorage,
@@ -213,6 +215,10 @@ abstract class SettingsStoreBase with Store {
       priority[WalletType.bitcoinCash] = initialBitcoinCashTransactionPriority;
     }
 
+    if (initialCakePayCountry != null) {
+      selectedCakePayCountry = initialCakePayCountry;
+    }
+
     initializeTrocadorProviderStates();
 
     WalletType.values.forEach((walletType) {
@@ -244,6 +250,15 @@ abstract class SettingsStoreBase with Store {
         (FiatCurrency fiatCurrency) => sharedPreferences.setString(
             PreferencesKey.currentFiatCurrencyKey, fiatCurrency.serialize()));
 
+    reaction(
+            (_) => selectedCakePayCountry,
+            (Country? country) {
+              if (country != null) {
+                sharedPreferences.setString(
+                    PreferencesKey.currentCakePayCountry, country.raw);
+              }
+            });
+
     reaction(
         (_) => shouldShowYatPopup,
         (bool shouldShowYatPopup) =>
@@ -625,6 +640,9 @@ abstract class SettingsStoreBase with Store {
   @observable
   FiatCurrency fiatCurrency;
 
+  @observable
+  Country? selectedCakePayCountry;
+
   @observable
   bool shouldShowYatPopup;
 
@@ -880,6 +898,10 @@ abstract class SettingsStoreBase with Store {
     final backgroundTasks = getIt.get<BackgroundTasks>();
     final currentFiatCurrency = FiatCurrency.deserialize(
         raw: sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey)!);
+    final savedCakePayCountryRaw = sharedPreferences.getString(PreferencesKey.currentCakePayCountry);
+    final currentCakePayCountry = savedCakePayCountryRaw != null
+        ? Country.deserialize(raw: savedCakePayCountryRaw)
+        : null;
 
     TransactionPriority? moneroTransactionPriority = monero?.deserializeMoneroTransactionPriority(
         raw: sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority)!);
@@ -1225,6 +1247,7 @@ abstract class SettingsStoreBase with Store {
       deviceName: deviceName,
       isBitcoinBuyEnabled: isBitcoinBuyEnabled,
       initialFiatCurrency: currentFiatCurrency,
+      initialCakePayCountry: currentCakePayCountry,
       initialBalanceDisplayMode: currentBalanceDisplayMode,
       initialSaveRecipientAddress: shouldSaveRecipientAddress,
       initialAutoGenerateSubaddressStatus: autoGenerateSubaddressStatus,
diff --git a/lib/view_model/cake_pay/cake_pay_cards_list_view_model.dart b/lib/view_model/cake_pay/cake_pay_cards_list_view_model.dart
index d0483596e..8585da9da 100644
--- a/lib/view_model/cake_pay/cake_pay_cards_list_view_model.dart
+++ b/lib/view_model/cake_pay/cake_pay_cards_list_view_model.dart
@@ -1,8 +1,10 @@
 import 'package:cake_wallet/cake_pay/cake_pay_service.dart';
 import 'package:cake_wallet/cake_pay/cake_pay_states.dart';
 import 'package:cake_wallet/cake_pay/cake_pay_vendor.dart';
+import 'package:cake_wallet/entities/country.dart';
+import 'package:cake_wallet/entities/fiat_currency.dart';
 import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/view_model/dashboard/dropdown_filter_item.dart';
+import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
 import 'package:mobx/mobx.dart';
 
@@ -13,11 +15,11 @@ class CakePayCardsListViewModel = CakePayCardsListViewModelBase with _$CakePayCa
 abstract class CakePayCardsListViewModelBase with Store {
   CakePayCardsListViewModelBase({
     required this.cakePayService,
+    required this.settingsStore,
   })  : cardState = CakePayCardsStateNoCards(),
         cakePayVendors = [],
         availableCountries = [],
         page = 1,
-        selectedCountry = 'USA',
         displayPrepaidCards = true,
         displayGiftCards = true,
         displayDenominationsCards = true,
@@ -30,13 +32,20 @@ abstract class CakePayCardsListViewModelBase with Store {
     initialization();
   }
 
+  static Country _getInitialCountry(FiatCurrency fiatCurrency) {
+    if (fiatCurrency.countryCode == 'eur') {
+      return Country.deu;
+    }
+    return Country.fromCode(fiatCurrency.countryCode) ?? Country.usa;
+  }
+
   void initialization() async {
     await getCountries();
-    selectedCountry = availableCountries.first;
     getVendors();
   }
 
   final CakePayService cakePayService;
+  final SettingsStore settingsStore;
 
   List<CakePayVendor> CakePayVendorList;
 
@@ -61,28 +70,15 @@ abstract class CakePayCardsListViewModelBase with Store {
               caption: S.current.custom_value,
               onChanged: toggleCustomValueCards),
         ],
-        S.current.countries: [
-          DropdownFilterItem(
-            items: availableCountries,
-            caption: '',
-            selectedItem: selectedCountry,
-            onItemSelected: (String value) => setSelectedCountry(value),
-          ),
-        ]
       };
 
   String searchString;
-
   int page;
 
-  late String _initialSelectedCountry;
-
+  late Country _initialSelectedCountry;
   late bool _initialDisplayPrepaidCards;
-
   late bool _initialDisplayGiftCards;
-
   late bool _initialDisplayDenominationsCards;
-
   late bool _initialDisplayCustomValueCards;
 
   @observable
@@ -107,7 +103,7 @@ abstract class CakePayCardsListViewModelBase with Store {
   List<CakePayVendor> cakePayVendors;
 
   @observable
-  List<String> availableCountries;
+  List<Country> availableCountries;
 
   @observable
   bool displayPrepaidCards;
@@ -121,15 +117,22 @@ abstract class CakePayCardsListViewModelBase with Store {
   @observable
   bool displayCustomValueCards;
 
-  @observable
-  String selectedCountry;
+  @computed
+  Country get selectedCountry =>
+      settingsStore.selectedCakePayCountry ?? _getInitialCountry(settingsStore.fiatCurrency);
+
+  @computed
+  bool get shouldShowCountryPicker => settingsStore.selectedCakePayCountry == null && availableCountries.isNotEmpty;
+
+
+  bool get hasFiltersChanged {
+    return selectedCountry != _initialSelectedCountry ||
+        displayPrepaidCards != _initialDisplayPrepaidCards ||
+        displayGiftCards != _initialDisplayGiftCards ||
+        displayDenominationsCards != _initialDisplayDenominationsCards ||
+        displayCustomValueCards != _initialDisplayCustomValueCards;
+  }
 
-  bool get hasFiltersChanged =>
-      selectedCountry != _initialSelectedCountry ||
-      displayPrepaidCards != _initialDisplayPrepaidCards ||
-      displayGiftCards != _initialDisplayGiftCards ||
-      displayDenominationsCards != _initialDisplayDenominationsCards ||
-      displayCustomValueCards != _initialDisplayCustomValueCards;
 
   Future<void> getCountries() async {
     availableCountries = await cakePayService.getCountries();
@@ -143,7 +146,7 @@ abstract class CakePayCardsListViewModelBase with Store {
     vendorsState = CakePayVendorLoadingState();
     searchString = text ?? '';
     var newVendors = await cakePayService.getVendors(
-        country: selectedCountry,
+        country: Country.getCakePayName(selectedCountry),
         page: currentPage ?? page,
         search: searchString,
         giftCards: displayGiftCards,
@@ -152,20 +155,20 @@ abstract class CakePayCardsListViewModelBase with Store {
         onDemand: displayDenominationsCards);
 
     cakePayVendors = CakePayVendorList = newVendors;
-
     vendorsState = CakePayVendorLoadedState();
   }
 
   @action
   Future<void> fetchNextPage() async {
-    if (vendorsState is CakePayVendorLoadingState || !hasMoreDataToFetch || isLoadingNextPage)
+    if (vendorsState is CakePayVendorLoadingState || !hasMoreDataToFetch || isLoadingNextPage) {
       return;
+    }
 
     isLoadingNextPage = true;
     page++;
     try {
       var newVendors = await cakePayService.getVendors(
-          country: selectedCountry,
+          country: Country.getCakePayName(selectedCountry),
           page: page,
           search: searchString,
           giftCards: displayGiftCards,
@@ -201,7 +204,7 @@ abstract class CakePayCardsListViewModelBase with Store {
   }
 
   @action
-  void setSelectedCountry(String country) => selectedCountry = country;
+  void setSelectedCountry(Country country) => settingsStore.selectedCakePayCountry = country;
 
   @action
   void togglePrepaidCards() => displayPrepaidCards = !displayPrepaidCards;
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index 0db2031dd..b8c933a2e 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -634,6 +634,7 @@
   "select_buy_provider_notice": "حدد مزود شراء أعلاه. يمكنك تخطي هذه الشاشة عن طريق تعيين مزود شراء الافتراضي في إعدادات التطبيق.",
   "select_destination": ".ﻲﻃﺎﻴﺘﺣﻻﺍ ﺦﺴﻨﻟﺍ ﻒﻠﻣ ﺔﻬﺟﻭ ﺪﻳﺪﺤﺗ ءﺎﺟﺮﻟﺍ",
   "select_sell_provider_notice": ".ﻖﻴﺒﻄﺘﻟﺍ ﺕﺍﺩﺍﺪﻋﺇ ﻲﻓ ﻚﺑ ﺹﺎﺨﻟﺍ ﻲﺿﺍﺮﺘﻓﻻﺍ ﻊﻴﺒﻟﺍ ﺩﻭﺰﻣ ﻦﻴﻴﻌﺗ ﻖﻳﺮﻃ ﻦﻋ ﺔﺷﺎﺸﻟﺍ ﻩﺬﻫ ﻲﻄﺨﺗ",
+  "select_your_country": "الرجاء تحديد بلدك",
   "sell": "بيع",
   "sell_alert_content": ".ﺎﻬﻴﻟﺇ ﻞﻳﺪﺒﺘﻟﺍ ﻭﺃ Litecoin ﻭﺃ Ethereum ﻭﺃ Bitcoin ﺔﻈﻔﺤﻣ ءﺎﺸﻧﺇ ﻰﺟﺮﻳ .Litecoin ﻭ",
   "sell_monero_com_alert_content": "بيع Monero غير مدعوم حتى الآن",
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index 7e78dd69a..2fd644d01 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -634,6 +634,7 @@
   "select_buy_provider_notice": "Изберете доставчик на покупка по -горе. Можете да пропуснете този екран, като зададете вашия доставчик по подразбиране по подразбиране в настройките на приложението.",
   "select_destination": "Моля, изберете дестинация за архивния файл.",
   "select_sell_provider_notice": "Изберете доставчик на продажба по-горе. Можете да пропуснете този екран, като зададете своя доставчик на продажба по подразбиране в настройките на приложението.",
+  "select_your_country": "Моля, изберете вашата страна",
   "sell": "Продаване",
   "sell_alert_content": "В момента поддържаме само продажбата на Bitcoin, Ethereum и Litecoin. Моля, създайте или превключете към своя портфейл Bitcoin, Ethereum или Litecoin.",
   "sell_monero_com_alert_content": "Продажбата на Monero все още не се поддържа",
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index f17466a9f..8f3b5bf28 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -634,6 +634,7 @@
   "select_buy_provider_notice": "Vyberte výše uvedeného poskytovatele nákupu. Tuto obrazovku můžete přeskočit nastavením výchozího poskytovatele nákupu v nastavení aplikace.",
   "select_destination": "Vyberte cíl pro záložní soubor.",
   "select_sell_provider_notice": "Výše vyberte poskytovatele prodeje. Tuto obrazovku můžete přeskočit nastavením výchozího poskytovatele prodeje v nastavení aplikace.",
+  "select_your_country": "Vyberte prosím svou zemi",
   "sell": "Prodat",
   "sell_alert_content": "V současné době podporujeme pouze prodej bitcoinů, etherea a litecoinů. Vytvořte nebo přepněte na svou bitcoinovou, ethereum nebo litecoinovou peněženku.",
   "sell_monero_com_alert_content": "Prodej Monero zatím není podporován",
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index cb0a59574..77a531d1b 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -635,6 +635,7 @@
   "select_buy_provider_notice": "Wählen Sie oben einen Anbieter kaufen. Sie können diese Seite überspringen, indem Sie Ihren Standard-Kaufanbieter in den App-Einstellungen festlegen.",
   "select_destination": "Bitte wählen Sie das Ziel für die Sicherungsdatei aus.",
   "select_sell_provider_notice": "Wählen Sie oben einen Verkaufsanbieter aus. Sie können diesen Bildschirm überspringen, indem Sie in den App-Einstellungen Ihren Standard-Verkaufsanbieter festlegen.",
+  "select_your_country": "Bitte wählen Sie Ihr Land aus",
   "sell": "Verkaufen",
   "sell_alert_content": "Wir unterstützen derzeit nur den Verkauf von Bitcoin, Ethereum und Litecoin. Bitte erstellen Sie Ihr Bitcoin-, Ethereum- oder Litecoin-Wallet oder wechseln Sie zu diesem.",
   "sell_monero_com_alert_content": "Der Verkauf von Monero wird noch nicht unterstützt",
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 40be8fd08..4fe375ff9 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -636,6 +636,7 @@
   "select_buy_provider_notice": "Select a buy provider above. You can skip this screen by setting your default buy provider in app settings.",
   "select_destination": "Please select destination for the backup file.",
   "select_sell_provider_notice": "Select a sell provider above. You can skip this screen by setting your default sell provider in app settings.",
+  "select_your_country": "Please select your country",
   "sell": "Sell",
   "sell_alert_content": "We currently only support the sale of Bitcoin, Ethereum and Litecoin. Please create or switch to your Bitcoin, Ethereum or Litecoin wallet.",
   "sell_monero_com_alert_content": "Selling Monero is not supported yet",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 5a693cf32..31498df2d 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -635,6 +635,7 @@
   "select_buy_provider_notice": "Selecciona un proveedor de compra arriba. Puede omitir esta pantalla configurando su proveedor de compra predeterminado en la configuración de la aplicación.",
   "select_destination": "Selecciona el destino del archivo de copia de seguridad.",
   "select_sell_provider_notice": "Selecciona un proveedor de venta arriba. Puede omitir esta pantalla configurando su proveedor de venta predeterminado en la configuración de la aplicación.",
+  "select_your_country": "Seleccione su país",
   "sell": "Vender",
   "sell_alert_content": "Actualmente solo admitimos la venta de Bitcoin, Ethereum y Litecoin. Cree o cambie a su billetera Bitcoin, Ethereum o Litecoin.",
   "sell_monero_com_alert_content": "Aún no se admite la venta de Monero",
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index 1865e41f2..f96e9e304 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -634,6 +634,7 @@
   "select_buy_provider_notice": "Sélectionnez un fournisseur d'achat ci-dessus. Vous pouvez ignorer cet écran en définissant votre fournisseur d'achat par défaut dans les paramètres de l'application.",
   "select_destination": "Veuillez sélectionner la destination du fichier de sauvegarde.",
   "select_sell_provider_notice": "Sélectionnez un fournisseur de vente ci-dessus. Vous pouvez ignorer cet écran en définissant votre fournisseur de vente par défaut dans les paramètres de l'application.",
+  "select_your_country": "Veuillez sélectionner votre pays",
   "sell": "Vendre",
   "sell_alert_content": "Nous ne prenons actuellement en charge que la vente de Bitcoin, Ethereum et Litecoin. Veuillez créer ou basculer vers votre portefeuille Bitcoin, Ethereum ou Litecoin.",
   "sell_monero_com_alert_content": "La vente de Monero n'est pas encore prise en charge",
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index 52cf14128..5fc64e0b3 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -636,6 +636,7 @@
   "select_buy_provider_notice": "Zaɓi mai ba da kyauta a sama. Zaka iya tsallake wannan allon ta hanyar saita mai ba da isasshen busasshen mai ba da isasshen busasshiyar saiti.",
   "select_destination": "Da fatan za a zaɓi wurin da za a yi wa madadin fayil ɗin.",
   "select_sell_provider_notice": "Zaɓi mai bada siyarwa a sama. Kuna iya tsallake wannan allon ta saita mai bada siyar da ku a cikin saitunan app.",
+  "select_your_country": "Da fatan za a zabi ƙasarku",
   "sell": "sayar",
   "sell_alert_content": "A halin yanzu muna tallafawa kawai siyar da Bitcoin, Ethereum da Litecoin. Da fatan za a ƙirƙiri ko canza zuwa walat ɗin ku na Bitcoin, Ethereum ko Litecoin.",
   "sell_monero_com_alert_content": "Selling Monero bai sami ƙarshen mai bukatar samun ba",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index 64f112a42..fb3b78900 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -636,6 +636,7 @@
   "select_buy_provider_notice": "ऊपर एक खरीद प्रदाता का चयन करें। आप इस स्क्रीन को ऐप सेटिंग्स में अपना डिफ़ॉल्ट बाय प्रदाता सेट करके छोड़ सकते हैं।",
   "select_destination": "कृपया बैकअप फ़ाइल के लिए गंतव्य का चयन करें।",
   "select_sell_provider_notice": "ऊपर एक विक्रय प्रदाता का चयन करें। आप ऐप सेटिंग में अपना डिफ़ॉल्ट विक्रय प्रदाता सेट करके इस स्क्रीन को छोड़ सकते हैं।",
+  "select_your_country": "कृपया अपने देश का चयन करें",
   "sell": "बेचना",
   "sell_alert_content": "हम वर्तमान में केवल बिटकॉइन, एथेरियम और लाइटकॉइन की बिक्री का समर्थन करते हैं। कृपया अपना बिटकॉइन, एथेरियम या लाइटकॉइन वॉलेट बनाएं या उसमें स्विच करें।",
   "sell_monero_com_alert_content": "मोनेरो बेचना अभी तक समर्थित नहीं है",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 4bbf4f141..230aa955b 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -634,6 +634,7 @@
   "select_buy_provider_notice": "Odaberite gornji davatelj kupnje. Ovaj zaslon možete preskočiti postavljanjem zadanog davatelja usluga kupnje u postavkama aplikacija.",
   "select_destination": "Odaberite odredište za datoteku sigurnosne kopije.",
   "select_sell_provider_notice": "Gore odaberite pružatelja usluga prodaje. Ovaj zaslon možete preskočiti postavljanjem zadanog pružatelja usluga prodaje u postavkama aplikacije.",
+  "select_your_country": "Odaberite svoju zemlju",
   "sell": "Prodavati",
   "sell_alert_content": "Trenutno podržavamo samo prodaju Bitcoina, Ethereuma i Litecoina. Izradite ili prijeđite na svoj Bitcoin, Ethereum ili Litecoin novčanik.",
   "sell_monero_com_alert_content": "Prodaja Monera još nije podržana",
diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb
index cbaf3a548..63a986103 100644
--- a/res/values/strings_hy.arb
+++ b/res/values/strings_hy.arb
@@ -626,6 +626,7 @@
   "select_buy_provider_notice": "Ընտրեք գնման մատակարարը վերևում։ Դուք կարող եք բաց թողնել այս էկրանը ձեր լռելայն գնման մատակարարը հավելվածի կարգավորումներում սահմանելով",
   "select_destination": "Խնդրում ենք ընտրել կրկնօրինակ ֆայլի նպատակակետը",
   "select_sell_provider_notice": "Ընտրեք վաճառքի մատակարարը վերևում։ Դուք կարող եք բաց թողնել այս էկրանը ձեր լռելայն վաճառքի մատակարարը հավելվածի կարգավորումներում սահմանելով",
+  "select_your_country": "Խնդրում ենք ընտրել ձեր երկիրը",
   "sell": "Ծախել",
   "sell_alert_content": "Մենք ներկայումս պաշտպանում ենք միայն Bitcoin, Ethereum և Litecoin վաճառքը։ Խնդրում ենք ստեղծել կամ միացնել ձեր Bitcoin, Ethereum կամ Litecoin դրամապանակը",
   "sell_monero_com_alert_content": "Monero-ի վաճառքը դեռ չի պաշտպանվում",
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index 273087eec..3fa3a958f 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -637,6 +637,7 @@
   "select_buy_provider_notice": "Pilih penyedia beli di atas. Anda dapat melewatkan layar ini dengan mengatur penyedia pembelian default Anda di pengaturan aplikasi.",
   "select_destination": "Silakan pilih tujuan untuk file cadangan.",
   "select_sell_provider_notice": "Pilih penyedia jual di atas. Anda dapat melewati layar ini dengan mengatur penyedia penjualan default Anda di pengaturan aplikasi.",
+  "select_your_country": "Pilih negara Anda",
   "sell": "Jual",
   "sell_alert_content": "Saat ini kami hanya mendukung penjualan Bitcoin, Ethereum, dan Litecoin. Harap buat atau alihkan ke dompet Bitcoin, Ethereum, atau Litecoin Anda.",
   "sell_monero_com_alert_content": "Menjual Monero belum didukung",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index 917315aa6..aab18d434 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -636,6 +636,7 @@
   "select_buy_provider_notice": "Seleziona un fornitore di acquisto sopra. È possibile saltare questa schermata impostando il provider di acquisto predefinito nelle impostazioni dell'app.",
   "select_destination": "Seleziona la destinazione per il file di backup.",
   "select_sell_provider_notice": "Seleziona un fornitore di vendita sopra. Puoi saltare questa schermata impostando il tuo fornitore di vendita predefinito nelle impostazioni dell'app.",
+  "select_your_country": "Seleziona il tuo paese",
   "sell": "Vendere",
   "sell_alert_content": "Al momento supportiamo solo la vendita di Bitcoin, Ethereum e Litecoin. Crea o passa al tuo portafoglio Bitcoin, Ethereum o Litecoin.",
   "sell_monero_com_alert_content": "La vendita di Monero non è ancora supportata",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index ae3e32ea8..f1fd0acd3 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -635,6 +635,7 @@
   "select_buy_provider_notice": "上記の購入プロバイダーを選択してください。デフォルトの購入プロバイダーをアプリ設定で設定して、この画面をスキップできます。",
   "select_destination": "バックアップファイルの保存先を選択してください。",
   "select_sell_provider_notice": "上記の販売プロバイダーを選択してください。アプリ設定でデフォルトの販売プロバイダーを設定することで、この画面をスキップできます。",
+  "select_your_country": "あなたの国を選択してください",
   "sell": "売る",
   "sell_alert_content": "現在、ビットコイン、イーサリアム、ライトコインの販売のみをサポートしています。ビットコイン、イーサリアム、またはライトコインのウォレットを作成するか、これらのウォレットに切り替えてください。",
   "sell_monero_com_alert_content": "モネロの販売はまだサポートされていません",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 2dc1a2dfc..7e3467cf2 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -635,6 +635,7 @@
   "select_buy_provider_notice": "위의 구매 제공자를 선택하십시오. 앱 설정에서 기본 구매 제공자를 설정 하여이 화면을 건너 뛸 수 있습니다.",
   "select_destination": "백업 파일의 대상을 선택하십시오.",
   "select_sell_provider_notice": "위에서 판매 공급자를 선택하세요. 앱 설정에서 기본 판매 공급자를 설정하면 이 화면을 건너뛸 수 있습니다.",
+  "select_your_country": "국가를 선택하십시오",
   "sell": "팔다",
   "sell_alert_content": "현재 Bitcoin, Ethereum 및 Litecoin의 판매만 지원합니다. Bitcoin, Ethereum 또는 Litecoin 지갑을 생성하거나 전환하십시오.",
   "sell_monero_com_alert_content": "지원되지 않습니다.",
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index f42af6863..10c13cfef 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -634,6 +634,7 @@
   "select_buy_provider_notice": "အပေါ်ကဝယ်သူတစ် ဦး ကိုရွေးချယ်ပါ။ သင်၏ default 0 ယ်သူအား app settings တွင် setting လုပ်ခြင်းဖြင့်ဤ screen ကိုကျော်သွားနိုင်သည်။",
   "select_destination": "အရန်ဖိုင်အတွက် ဦးတည်ရာကို ရွေးပါ။",
   "select_sell_provider_notice": "အထက်ဖော်ပြပါ အရောင်းဝန်ဆောင်မှုပေးသူကို ရွေးပါ။ အက်ပ်ဆက်တင်များတွင် သင်၏မူလရောင်းချပေးသူကို သတ်မှတ်ခြင်းဖြင့် ဤစခရင်ကို ကျော်နိုင်သည်။",
+  "select_your_country": "ကျေးဇူးပြု. သင့်နိုင်ငံကိုရွေးချယ်ပါ",
   "sell": "ရောင်း",
   "sell_alert_content": "ကျွန်ုပ်တို့သည် လက်ရှိတွင် Bitcoin၊ Ethereum နှင့် Litecoin ရောင်းချခြင်းကိုသာ ပံ့ပိုးပေးပါသည်။ သင်၏ Bitcoin၊ Ethereum သို့မဟုတ် Litecoin ပိုက်ဆံအိတ်ကို ဖန်တီးပါ သို့မဟုတ် ပြောင်းပါ။",
   "sell_monero_com_alert_content": "Monero ရောင်းချခြင်းကို မပံ့ပိုးရသေးပါ။",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index 73e3df6b6..9552f2439 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -634,6 +634,7 @@
   "select_buy_provider_notice": "Selecteer hierboven een koopprovider. U kunt dit scherm overslaan door uw standaard kopenprovider in te stellen in app -instellingen.",
   "select_destination": "Selecteer de bestemming voor het back-upbestand.",
   "select_sell_provider_notice": "Selecteer hierboven een verkoopaanbieder. U kunt dit scherm overslaan door uw standaardverkoopprovider in te stellen in de app-instellingen.",
+  "select_your_country": "Selecteer uw land",
   "sell": "Verkopen",
   "sell_alert_content": "We ondersteunen momenteel alleen de verkoop van Bitcoin, Ethereum en Litecoin. Maak of schakel over naar uw Bitcoin-, Ethereum- of Litecoin-portemonnee.",
   "sell_monero_com_alert_content": "Het verkopen van Monero wordt nog niet ondersteund",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index aaa82a3bf..f3c3e4810 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -634,6 +634,7 @@
   "select_buy_provider_notice": "Wybierz powyższe dostawcę zakupu. Możesz pominąć ten ekran, ustawiając domyślnego dostawcę zakupu w ustawieniach aplikacji.",
   "select_destination": "Wybierz miejsce docelowe dla pliku kopii zapasowej.",
   "select_sell_provider_notice": "Wybierz dostawcę sprzedaży powyżej. Możesz pominąć ten ekran, ustawiając domyślnego dostawcę sprzedaży w ustawieniach aplikacji.",
+  "select_your_country": "Wybierz swój kraj",
   "sell": "Sprzedać",
   "sell_alert_content": "Obecnie obsługujemy tylko sprzedaż Bitcoin, Ethereum i Litecoin. Utwórz lub przełącz się na swój portfel Bitcoin, Ethereum lub Litecoin.",
   "sell_monero_com_alert_content": "Sprzedaż Monero nie jest jeszcze obsługiwana",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 194307a3d..410e8cb1c 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -636,6 +636,7 @@
   "select_buy_provider_notice": "Selecione um provedor de compra acima. Você pode pular esta tela definindo seu provedor de compra padrão nas configurações de aplicativos.",
   "select_destination": "Selecione o destino para o arquivo de backup.",
   "select_sell_provider_notice": "Selecione um fornecedor de venda acima. Você pode pular esta tela definindo seu provedor de venda padrão nas configurações do aplicativo.",
+  "select_your_country": "Selecione seu país",
   "sell": "Vender",
   "sell_alert_content": "Atualmente, oferecemos suporte apenas à venda de Bitcoin, Ethereum e Litecoin. Crie ou troque para sua carteira Bitcoin, Ethereum ou Litecoin.",
   "sell_monero_com_alert_content": "A venda de Monero ainda não é suportada",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index f42c28c15..a8ee5a309 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -635,6 +635,7 @@
   "select_buy_provider_notice": "Выберите поставщика покупки выше. Вы можете пропустить этот экран, установив поставщика покупки по умолчанию в настройках приложения.",
   "select_destination": "Пожалуйста, выберите место для файла резервной копии.",
   "select_sell_provider_notice": "Выберите поставщика услуг продажи выше. Вы можете пропустить этот экран, установив поставщика услуг продаж по умолчанию в настройках приложения.",
+  "select_your_country": "Пожалуйста, выберите свою страну",
   "sell": "Продавать",
   "sell_alert_content": "В настоящее время мы поддерживаем только продажу биткойнов, эфириума и лайткойна. Пожалуйста, создайте или переключитесь на свой кошелек Bitcoin, Ethereum или Litecoin.",
   "sell_monero_com_alert_content": "Продажа Monero пока не поддерживается",
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index 9d8fb0af2..5102e150c 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -634,6 +634,7 @@
   "select_buy_provider_notice": "เลือกผู้ให้บริการซื้อด้านบน คุณสามารถข้ามหน้าจอนี้ได้โดยการตั้งค่าผู้ให้บริการซื้อเริ่มต้นในการตั้งค่าแอป",
   "select_destination": "โปรดเลือกปลายทางสำหรับไฟล์สำรอง",
   "select_sell_provider_notice": "เลือกผู้ให้บริการการขายด้านบน คุณสามารถข้ามหน้าจอนี้ได้โดยการตั้งค่าผู้ให้บริการการขายเริ่มต้นในการตั้งค่าแอป",
+  "select_your_country": "กรุณาเลือกประเทศของคุณ",
   "sell": "ขาย",
   "sell_alert_content": "ขณะนี้เรารองรับการขาย Bitcoin, Ethereum และ Litecoin เท่านั้น โปรดสร้างหรือเปลี่ยนเป็นกระเป๋าเงิน Bitcoin, Ethereum หรือ Litecoin ของคุณ",
   "sell_monero_com_alert_content": "ยังไม่รองรับการขาย Monero",
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index ca35e7997..eb78c8d3c 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -634,6 +634,7 @@
   "select_buy_provider_notice": "Pumili ng provider ng pagbili sa itaas. Maaari mong laktawan ang screen na ito sa pamamagitan ng pagtatakda ng iyong default na provider ng pagbili sa mga setting ng app.",
   "select_destination": "Mangyaring piliin ang patutunguhan para sa backup na file.",
   "select_sell_provider_notice": "Pumili ng provider ng nagbebenta sa itaas. Maaari mong laktawan ang screen na ito sa pamamagitan ng pagtatakda ng iyong default na sell provider sa mga setting ng app.",
+  "select_your_country": "Mangyaring piliin ang iyong bansa",
   "sell": "Ibenta",
   "sell_alert_content": "Kasalukuyan lamang naming sinusuportahan ang pagbebenta ng Bitcoin, Ethereum at Litecoin. Mangyaring lumikha o lumipat sa iyong Bitcoin, Ethereum o Litecoin wallet.",
   "sell_monero_com_alert_content": "Ang pagbebenta ng Monero ay hindi pa suportado",
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index 1fee66369..0b4700397 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -634,6 +634,7 @@
   "select_buy_provider_notice": "Yukarıda bir satın alma sağlayıcısı seçin. App ayarlarında varsayılan satın alma sağlayıcınızı ayarlayarak bu ekranı atlayabilirsiniz.",
   "select_destination": "Lütfen yedekleme dosyası için hedef seçin.",
   "select_sell_provider_notice": "Yukarıdan bir satış sağlayıcısı seçin. Uygulama ayarlarında varsayılan satış sağlayıcınızı ayarlayarak bu ekranı atlayabilirsiniz.",
+  "select_your_country": "Lütfen ülkenizi seçin",
   "sell": "Satış",
   "sell_alert_content": "Şu anda yalnızca Bitcoin, Ethereum ve Litecoin satışını destekliyoruz. Lütfen Bitcoin, Ethereum veya Litecoin cüzdanınızı oluşturun veya cüzdanınıza geçin.",
   "sell_monero_com_alert_content": "Monero satışı henüz desteklenmiyor",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 5d9a56c1e..c9afde7be 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -635,6 +635,7 @@
   "select_buy_provider_notice": "Виберіть постачальника купівлі вище. Ви можете пропустити цей екран, встановивши свого постачальника купівлі за замовчуванням у налаштуваннях додатків.",
   "select_destination": "Виберіть місце призначення для файлу резервної копії.",
   "select_sell_provider_notice": "Виберіть вище постачальника послуг продажу. Ви можете пропустити цей екран, встановивши постачальника послуг продажу за умовчанням у налаштуваннях програми.",
+  "select_your_country": "Будь ласка, виберіть свою країну",
   "sell": "Продати",
   "sell_alert_content": "Наразі ми підтримуємо лише продаж Bitcoin, Ethereum і Litecoin. Створіть або перейдіть на свій гаманець Bitcoin, Ethereum або Litecoin.",
   "sell_monero_com_alert_content": "Продаж Monero ще не підтримується",
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index 106f00f96..50c6f1889 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -636,6 +636,7 @@
   "select_buy_provider_notice": "اوپر خریدنے والا خریدنے والا منتخب کریں۔ آپ ایپ کی ترتیبات میں اپنے پہلے سے طے شدہ خریدنے والے کو ترتیب دے کر اس اسکرین کو چھوڑ سکتے ہیں۔",
   "select_destination": "۔ﮟﯾﺮﮐ ﺏﺎﺨﺘﻧﺍ ﺎﮐ ﻝﺰﻨﻣ ﮯﯿﻟ ﮯﮐ ﻞﺋﺎﻓ ﭖﺍ ﮏﯿﺑ ﻡﺮﮐ ﮦﺍﺮﺑ",
   "select_sell_provider_notice": "۔ﮟﯿﮨ ﮯﺘﮑﺳ ﮌﻮﮭﭼ ﻮﮐ ﻦﯾﺮﮑﺳﺍ ﺱﺍ ﺮﮐ ﮮﺩ ﺐﯿﺗﺮﺗ ﻮﮐ ﮦﺪﻨﻨﮐ ﻢﮨﺍﺮﻓ ﻞﯿﺳ ﭧﻟﺎﻔﯾﮈ ﮯﻨﭘﺍ ﮟﯿﻣ ﺕﺎﺒ",
+  "select_your_country": "براہ کرم اپنے ملک کو منتخب کریں",
   "sell": "بیچنا",
   "sell_alert_content": "۔ﮟﯾﺮﮐ ﭻﺋﻮﺳ ﺮﭘ ﺱﺍ ﺎﯾ ﮟﯿﺋﺎﻨﺑ ﭧﯿﻟﺍﻭ Litecoin ﺎﯾ Bitcoin، Ethereum ﺎﻨﭘﺍ ﻡﺮﮐ ﮦﺍﺮﺑ ۔",
   "sell_monero_com_alert_content": "Monero فروخت کرنا ابھی تک تعاون یافتہ نہیں ہے۔",
diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb
index a95f32aaa..e3ffbef3e 100644
--- a/res/values/strings_vi.arb
+++ b/res/values/strings_vi.arb
@@ -627,6 +627,7 @@
   "select_buy_provider_notice": "Chọn nhà cung cấp mua ở trên. Bạn có thể bỏ qua màn hình này bằng cách thiết lập nhà cung cấp mua mặc định trong cài đặt ứng dụng.",
   "select_destination": "Vui lòng chọn đích cho tệp sao lưu.",
   "select_sell_provider_notice": "Chọn nhà cung cấp bán ở trên. Bạn có thể bỏ qua màn hình này bằng cách thiết lập nhà cung cấp bán mặc định trong cài đặt ứng dụng.",
+  "select_your_country": "Vui lòng chọn quốc gia của bạn",
   "sell": "Bán",
   "sell_alert_content": "Hiện tại chúng tôi chỉ hỗ trợ bán Bitcoin, Ethereum và Litecoin. Vui lòng tạo hoặc chuyển sang ví Bitcoin, Ethereum hoặc Litecoin của bạn.",
   "sell_monero_com_alert_content": "Bán Monero chưa được hỗ trợ",
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index 1a1583da5..19dc9f110 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -635,6 +635,7 @@
   "select_buy_provider_notice": "Yan olupese Ra loke. O le skii iboju yii nipa ṣiṣeto olupese rẹ ni awọn eto App.",
   "select_destination": "Jọwọ yan ibi ti o nlo fun faili afẹyinti.",
   "select_sell_provider_notice": "Yan olupese ti o ta loke. O le foju iboju yii nipa tito olupese iṣẹ tita aiyipada rẹ ni awọn eto app.",
+  "select_your_country": "Jọwọ yan orilẹ-ede rẹ",
   "sell": "Tà",
   "sell_alert_content": "Lọwọlọwọ a ṣe atilẹyin tita Bitcoin, Ethereum ati Litecoin nikan. Jọwọ ṣẹda tabi yipada si Bitcoin, Ethereum tabi apamọwọ Litecoin rẹ.",
   "sell_monero_com_alert_content": "Kọ ju lọwọ Monero ko ṣe ni ibamu",
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index 79fe8faa5..009a31d86 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -634,6 +634,7 @@
   "select_buy_provider_notice": "在上面选择买入提供商。您可以通过在应用程序设置中设置默认的购买提供商来跳过此屏幕。",
   "select_destination": "请选择备份文件的目的地。",
   "select_sell_provider_notice": "选择上面的销售提供商。您可以通过在应用程序设置中设置默认销售提供商来跳过此屏幕。",
+  "select_your_country": "请选择你的国家",
   "sell": "卖",
   "sell_alert_content": "我们目前仅支持比特币、以太坊和莱特币的销售。请创建或切换到您的比特币、以太坊或莱特币钱包。",
   "sell_monero_com_alert_content": "尚不支持出售门罗币",

From 0fcfd76afd75b91665e25804859497aa46a051aa Mon Sep 17 00:00:00 2001
From: David Adegoke <64401859+Blazebrain@users.noreply.github.com>
Date: Thu, 7 Nov 2024 15:46:08 +0100
Subject: [PATCH 04/15] Automated Integration Tests Flows (#1686)

* feat: Integration tests setup and tests for Disclaimer, Welcome and Setup Pin Code pages

* feat: Integration test flow from start to restoring a wallet successfully done

* test: Dashboard view test and linking to flow

* feat: Testing the Exchange flow section, selecting sending and receiving currencies

* test: Successfully create an exchange section

* feat: Implement flow up to sending section

* test: Complete Exchange flow

* fix dependency issue

* test: Final cleanups

* feat: Add CI to run automated integration tests withan android emulator

* feat: Adjust Automated integration test CI to run on ubuntu 20.04-a

* fix: Move integration test CI into PR test build CI

* ci: Add automated test ci which is a streamlined replica of pr test build ci

* ci: Re-add step to access branch name

* ci: Add KVM

* ci: Add filepath to trigger the test run from

* ci: Add required key

* ci: Add required key

* ci: Add missing secret key

* ci: Add missing secret key

* ci: Add nano secrets to workflow

* ci: Switch step to free space on runner

* ci: Remove timeout from workflow

* ci: Confirm impact that removing copy_monero_deps would have on entire workflow time

* ci: Update CI and temporarily remove cache related to emulator

* ci: Remove dynamic java version

* ci: Temporarily switch CI

* ci: Switch to 11.x jdk

* ci: Temporarily switch CI

* ci: Revert ubuntu version

* ci: Add more api levels

* ci: Add more target options

* ci: Settled on stable emulator matrix options

* ci: Add more target options

* ci: Modify flow

* ci: Streamline api levels to 28 and 29

* ci: One more trial

* ci: Switch to flutter drive

* ci: Reduce options

* ci: Remove haven from test

* ci: Check for solana in list

* ci: Adjust amounts and currencies for exchange flow

* ci: Set write response on failure to true

* ci: Split ci to funds and non funds related tests

* test: Test for Send flow scenario and minor restructuring for test folders and files

* chore: cleanup

* ci: Pause CI for now

* ci: Pause CI for now

* ci: Pause CI for now

* test: Restore wallets integration automated tests

* Fix: Add keys back to currency amount textfield widget

* fix: Switch variable name

* fix: remove automation for now

* tests: Automated tests for Create wallets flow

* tests: Further optimize common flows

* tests: Add missing await for call

* tests: Confirm Seeds Display Properly WIP

* tests: Confirm Seeds Display Correctly Automated Tests

* fix: Add missing pubspec params for bitcoin and bitcoin_cash

* feat: Automated Tests for Transaction History Flow

* fix: Add missing pubspec parameter

* feat: Automated Integration Tests for Transaction History flow

* test: Updating send page robot and also syncing branch with main

* test: Modifying tests to flow with wallet grouping implementation

* fix: Issue with transaction history test

* fix: Modifications to the PR and add automated confirmation for checking that all wallet types are restored or created correctly

* test: Attempting automation for testing

* fix: Issue from merge conflicts

* test: Remove automation of test in this PR

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
---
 cw_bitcoin/pubspec.yaml                       |   1 +
 cw_bitcoin_cash/pubspec.yaml                  |   1 +
 cw_core/pubspec.yaml                          |   1 +
 .../components/common_test_cases.dart         | 121 ++++-
 .../components/common_test_constants.dart     |   2 +-
 .../components/common_test_flows.dart         | 291 +++++++++++-
 integration_test/funds_related_tests.dart     |   9 +-
 .../robots/dashboard_menu_widget_robot.dart   |  39 ++
 .../robots/dashboard_page_robot.dart          |  62 ++-
 .../robots/exchange_page_robot.dart           |   4 +-
 .../robots/new_wallet_page_robot.dart         |  35 ++
 .../robots/pin_code_widget_robot.dart         |  11 +-
 .../robots/pre_seed_page_robot.dart           |  20 +
 .../restore_from_seed_or_key_robot.dart       |  17 +
 .../robots/restore_options_page_robot.dart    |   6 +-
 .../security_and_backup_page_robot.dart       |  24 +
 integration_test/robots/send_page_robot.dart  |   9 +-
 .../robots/transactions_page_robot.dart       | 286 +++++++++++
 .../wallet_group_description_page_robot.dart  |  32 ++
 .../robots/wallet_keys_robot.dart             | 162 +++++++
 .../robots/wallet_list_page_robot.dart        |  27 ++
 .../robots/wallet_seed_page_robot.dart        |  57 +++
 .../test_suites/confirm_seeds_flow_test.dart  | 107 +++++
 .../test_suites/create_wallet_flow_test.dart  |  57 +++
 .../test_suites/exchange_flow_test.dart       |  61 +--
 ...estore_wallet_through_seeds_flow_test.dart |  63 +++
 .../test_suites/send_flow_test.dart           |  37 +-
 .../transaction_history_flow_test.dart        |  70 +++
 ios/Podfile.lock                              |  12 +-
 lib/src/screens/InfoPage.dart                 |  13 +-
 lib/src/screens/dashboard/dashboard_page.dart |   2 +-
 .../dashboard/pages/nft_details_page.dart     |   5 +-
 .../dashboard/pages/transactions_page.dart    | 214 +++++----
 .../widgets/anonpay_transaction_row.dart      |   1 +
 .../dashboard/widgets/date_section_raw.dart   |  41 +-
 .../screens/dashboard/widgets/header_row.dart |   3 +-
 .../dashboard/widgets/menu_widget.dart        |   3 +-
 .../screens/dashboard/widgets/order_row.dart  |  78 ++-
 .../screens/dashboard/widgets/trade_row.dart  |   1 +
 .../dashboard/widgets/transaction_raw.dart    | 103 ++--
 .../screens/new_wallet/new_wallet_page.dart   |  18 +-
 .../wallet_group_description_page.dart        |   2 +
 .../screens/restore/restore_options_page.dart |  38 +-
 .../wallet_restore_from_seed_form.dart        |   2 +
 lib/src/screens/seed/pre_seed_page.dart       |  10 +-
 lib/src/screens/seed/wallet_seed_page.dart    |  95 ++--
 .../settings/security_backup_page.dart        |  50 +-
 .../widgets/settings_cell_with_arrow.dart     |   7 +-
 .../widgets/settings_picker_cell.dart         |  24 +-
 .../widgets/settings_switcher_cell.dart       |   3 +-
 .../setup_2fa/setup_2fa_info_page.dart        |   8 +-
 .../blockexplorer_list_item.dart              |   9 +-
 .../rbf_details_list_fee_picker_item.dart     |  26 +-
 .../standart_list_item.dart                   |   7 +-
 .../textfield_list_item.dart                  |  10 +-
 .../transaction_details_list_item.dart        |   7 +-
 .../transaction_details_page.dart             |  60 +--
 .../transaction_expandable_list_item.dart     |   9 +-
 .../widgets/textfield_list_row.dart           |  14 +-
 .../screens/wallet_keys/wallet_keys_page.dart |  36 +-
 .../screens/wallet_list/wallet_list_page.dart |   2 +
 lib/src/widgets/blockchain_height_widget.dart |   3 +
 lib/src/widgets/dashboard_card_widget.dart    |   1 +
 lib/src/widgets/option_tile.dart              |  18 +-
 lib/src/widgets/picker.dart                   |   3 +
 lib/src/widgets/seed_language_selector.dart   |  11 +-
 lib/src/widgets/setting_actions.dart          |  12 +
 lib/src/widgets/standard_list.dart            |   8 +-
 .../anonpay/anonpay_transactions_store.dart   |   6 +-
 lib/store/dashboard/orders_store.dart         |  24 +-
 lib/store/dashboard/trades_store.dart         |  19 +-
 lib/utils/date_formatter.dart                 |  26 +-
 lib/utils/image_utill.dart                    |   4 +
 .../dashboard/action_list_item.dart           |   5 +
 .../anonpay_transaction_list_item.dart        |   2 +-
 .../dashboard/dashboard_view_model.dart       | 106 +++--
 .../dashboard/date_section_item.dart          |   2 +-
 .../dashboard/formatted_item_list.dart        |  15 +-
 lib/view_model/dashboard/order_list_item.dart |   4 +-
 lib/view_model/dashboard/trade_list_item.dart |   6 +-
 .../dashboard/transaction_list_item.dart      |   8 +-
 .../transaction_details_view_model.dart       | 449 ++++++++++++++----
 lib/view_model/wallet_keys_view_model.dart    | 181 ++++---
 tool/utils/secret_key.dart                    |  23 +
 84 files changed, 2716 insertions(+), 745 deletions(-)
 create mode 100644 integration_test/robots/dashboard_menu_widget_robot.dart
 create mode 100644 integration_test/robots/new_wallet_page_robot.dart
 create mode 100644 integration_test/robots/pre_seed_page_robot.dart
 create mode 100644 integration_test/robots/security_and_backup_page_robot.dart
 create mode 100644 integration_test/robots/transactions_page_robot.dart
 create mode 100644 integration_test/robots/wallet_group_description_page_robot.dart
 create mode 100644 integration_test/robots/wallet_keys_robot.dart
 create mode 100644 integration_test/robots/wallet_list_page_robot.dart
 create mode 100644 integration_test/robots/wallet_seed_page_robot.dart
 create mode 100644 integration_test/test_suites/confirm_seeds_flow_test.dart
 create mode 100644 integration_test/test_suites/create_wallet_flow_test.dart
 create mode 100644 integration_test/test_suites/restore_wallet_through_seeds_flow_test.dart
 create mode 100644 integration_test/test_suites/transaction_history_flow_test.dart

diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml
index 7a1576a98..bff6104ac 100644
--- a/cw_bitcoin/pubspec.yaml
+++ b/cw_bitcoin/pubspec.yaml
@@ -73,6 +73,7 @@ dependency_overrides:
 
 # The following section is specific to Flutter.
 flutter:
+    uses-material-design: true
 
   # To add assets to your package, add an assets section, like this:
   # assets:
diff --git a/cw_bitcoin_cash/pubspec.yaml b/cw_bitcoin_cash/pubspec.yaml
index 14ff407e2..9a5c4f14f 100644
--- a/cw_bitcoin_cash/pubspec.yaml
+++ b/cw_bitcoin_cash/pubspec.yaml
@@ -49,6 +49,7 @@ dependency_overrides:
 
 # The following section is specific to Flutter packages.
 flutter:
+    uses-material-design: true
 
 # To add assets to your package, add an assets section, like this:
 # assets:
diff --git a/cw_core/pubspec.yaml b/cw_core/pubspec.yaml
index 070779caa..6e32c2ba1 100644
--- a/cw_core/pubspec.yaml
+++ b/cw_core/pubspec.yaml
@@ -47,6 +47,7 @@ dependency_overrides:
 
 # The following section is specific to Flutter.
 flutter:
+    uses-material-design: true
 
   # To add assets to your package, add an assets section, like this:
   # assets:
diff --git a/integration_test/components/common_test_cases.dart b/integration_test/components/common_test_cases.dart
index 2e2991804..83bbb0449 100644
--- a/integration_test/components/common_test_cases.dart
+++ b/integration_test/components/common_test_cases.dart
@@ -10,10 +10,16 @@ class CommonTestCases {
     hasType<T>();
   }
 
-  Future<void> tapItemByKey(String key, {bool shouldPumpAndSettle = true}) async {
+  Future<void> tapItemByKey(
+    String key, {
+    bool shouldPumpAndSettle = true,
+    int pumpDuration = 100,
+  }) async {
     final widget = find.byKey(ValueKey(key));
     await tester.tap(widget);
-    shouldPumpAndSettle ? await tester.pumpAndSettle() : await tester.pump();
+    shouldPumpAndSettle
+        ? await tester.pumpAndSettle(Duration(milliseconds: pumpDuration))
+        : await tester.pump();
   }
 
   Future<void> tapItemByFinder(Finder finder, {bool shouldPumpAndSettle = true}) async {
@@ -31,6 +37,11 @@ class CommonTestCases {
     expect(typeWidget, findsOneWidget);
   }
 
+  bool isKeyPresent(String key) {
+    final typeWidget = find.byKey(ValueKey(key));
+    return typeWidget.tryEvaluate();
+  }
+
   void hasValueKey(String key) {
     final typeWidget = find.byKey(ValueKey(key));
     expect(typeWidget, findsOneWidget);
@@ -53,33 +64,86 @@ class CommonTestCases {
     await tester.pumpAndSettle();
   }
 
-  Future<void> scrollUntilVisible(String childKey, String parentScrollableKey,
-      {double delta = 300}) async {
-    final scrollableWidget = find.descendant(
-      of: find.byKey(Key(parentScrollableKey)),
+  Future<void> dragUntilVisible(String childKey, String parentKey) async {
+    await tester.pumpAndSettle();
+
+    final itemFinder = find.byKey(ValueKey(childKey));
+    final listFinder = find.byKey(ValueKey(parentKey));
+
+    // Check if the widget is already in the widget tree
+    if (tester.any(itemFinder)) {
+      // Widget is already built and in the tree
+      tester.printToConsole('Child is already present');
+      return;
+    }
+
+    // We can adjust this as needed
+    final maxScrolls = 200;
+
+    int scrolls = 0;
+    bool found = false;
+
+    // We start by scrolling down
+    bool scrollDown = true;
+
+    // Flag to check if we've already reversed direction
+    bool reversedDirection = false;
+
+    // Find the Scrollable associated with the Parent Ad
+    final scrollableFinder = find.descendant(
+      of: listFinder,
       matching: find.byType(Scrollable),
     );
 
-    final isAlreadyVisibile = isWidgetVisible(find.byKey(ValueKey(childKey)));
-
-    if (isAlreadyVisibile) return;
-
-    await tester.scrollUntilVisible(
-      find.byKey(ValueKey(childKey)),
-      delta,
-      scrollable: scrollableWidget,
+    // Ensure that the Scrollable is found
+    expect(
+      scrollableFinder,
+      findsOneWidget,
+      reason: 'Scrollable descendant of the Parent Widget not found.',
     );
-  }
 
-  bool isWidgetVisible(Finder finder) {
-    try {
-      final Element element = finder.evaluate().single;
-      final RenderBox renderBox = element.renderObject as RenderBox;
-      return renderBox.paintBounds
-          .shift(renderBox.localToGlobal(Offset.zero))
-          .overlaps(tester.binding.renderViews.first.paintBounds);
-    } catch (e) {
-      return false;
+    // Get the initial scroll position
+    final scrollableState = tester.state<ScrollableState>(scrollableFinder);
+    double previousScrollPosition = scrollableState.position.pixels;
+
+    while (!found && scrolls < maxScrolls) {
+      tester.printToConsole('Scrolling ${scrollDown ? 'down' : 'up'}, attempt $scrolls');
+
+      // Perform the drag in the current direction
+      await tester.drag(
+        scrollableFinder,
+        scrollDown ? const Offset(0, -100) : const Offset(0, 100),
+      );
+      await tester.pumpAndSettle();
+      scrolls++;
+
+      // Update the scroll position after the drag
+      final currentScrollPosition = scrollableState.position.pixels;
+
+      if (currentScrollPosition == previousScrollPosition) {
+        // Cannot scroll further in this direction
+        if (reversedDirection) {
+          // We've already tried both directions
+          tester.printToConsole('Cannot scroll further in both directions. Widget not found.');
+          break;
+        } else {
+          // Reverse the scroll direction
+          scrollDown = !scrollDown;
+          reversedDirection = true;
+          tester.printToConsole('Reached the end, reversing direction');
+        }
+      } else {
+        // Continue scrolling in the current direction
+        previousScrollPosition = currentScrollPosition;
+      }
+
+      // Check if the widget is now in the widget tree
+      found = tester.any(itemFinder);
+    }
+
+    if (!found) {
+      tester.printToConsole('Widget not found after scrolling in both directions.');
+      return;
     }
   }
 
@@ -91,6 +155,15 @@ class CommonTestCases {
     await tester.pumpAndSettle();
   }
 
+  void findWidgetViaDescendant({
+    required FinderBase<Element> of,
+    required FinderBase<Element> matching,
+  }) {
+    final textWidget = find.descendant(of: of, matching: matching);
+
+    expect(textWidget, findsOneWidget);
+  }
+
   Future<void> defaultSleepTime({int seconds = 2}) async =>
       await Future.delayed(Duration(seconds: seconds));
 }
diff --git a/integration_test/components/common_test_constants.dart b/integration_test/components/common_test_constants.dart
index d8381973e..302d52189 100644
--- a/integration_test/components/common_test_constants.dart
+++ b/integration_test/components/common_test_constants.dart
@@ -9,5 +9,5 @@ class CommonTestConstants {
   static final String testWalletName = 'Integrated Testing Wallet';
   static final CryptoCurrency testReceiveCurrency = CryptoCurrency.sol;
   static final CryptoCurrency testDepositCurrency = CryptoCurrency.usdtSol;
-  static final String testWalletAddress = 'An2Y2fsUYKfYvN1zF89GAqR1e6GUMBg3qA83Y5ZWDf8L';
+  static final String testWalletAddress = '5v9gTW1yWPffhnbNKuvtL2frevAf4HpBMw8oYnfqUjhm';
 }
diff --git a/integration_test/components/common_test_flows.dart b/integration_test/components/common_test_flows.dart
index 807509de9..82f714da0 100644
--- a/integration_test/components/common_test_flows.dart
+++ b/integration_test/components/common_test_flows.dart
@@ -1,41 +1,65 @@
-import 'package:flutter/foundation.dart';
+import 'package:cake_wallet/entities/seed_type.dart';
+import 'package:cake_wallet/reactions/bip39_wallet_utils.dart';
+import 'package:cake_wallet/wallet_types.g.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/material.dart';
 import 'package:flutter_test/flutter_test.dart';
 
-import 'package:cake_wallet/.secrets.g.dart' as secrets;
 import 'package:cake_wallet/main.dart' as app;
 
+import '../robots/dashboard_page_robot.dart';
 import '../robots/disclaimer_page_robot.dart';
+import '../robots/new_wallet_page_robot.dart';
 import '../robots/new_wallet_type_page_robot.dart';
+import '../robots/pre_seed_page_robot.dart';
 import '../robots/restore_from_seed_or_key_robot.dart';
 import '../robots/restore_options_page_robot.dart';
 import '../robots/setup_pin_code_robot.dart';
+import '../robots/wallet_group_description_page_robot.dart';
+import '../robots/wallet_list_page_robot.dart';
+import '../robots/wallet_seed_page_robot.dart';
 import '../robots/welcome_page_robot.dart';
 import 'common_test_cases.dart';
+import 'package:cake_wallet/.secrets.g.dart' as secrets;
+
 import 'common_test_constants.dart';
 
 class CommonTestFlows {
   CommonTestFlows(this._tester)
       : _commonTestCases = CommonTestCases(_tester),
         _welcomePageRobot = WelcomePageRobot(_tester),
+        _preSeedPageRobot = PreSeedPageRobot(_tester),
         _setupPinCodeRobot = SetupPinCodeRobot(_tester),
+        _dashboardPageRobot = DashboardPageRobot(_tester),
+        _newWalletPageRobot = NewWalletPageRobot(_tester),
         _disclaimerPageRobot = DisclaimerPageRobot(_tester),
+        _walletSeedPageRobot = WalletSeedPageRobot(_tester),
+        _walletListPageRobot = WalletListPageRobot(_tester),
         _newWalletTypePageRobot = NewWalletTypePageRobot(_tester),
         _restoreOptionsPageRobot = RestoreOptionsPageRobot(_tester),
-        _restoreFromSeedOrKeysPageRobot = RestoreFromSeedOrKeysPageRobot(_tester);
+        _restoreFromSeedOrKeysPageRobot = RestoreFromSeedOrKeysPageRobot(_tester),
+        _walletGroupDescriptionPageRobot = WalletGroupDescriptionPageRobot(_tester);
 
   final WidgetTester _tester;
   final CommonTestCases _commonTestCases;
 
   final WelcomePageRobot _welcomePageRobot;
+  final PreSeedPageRobot _preSeedPageRobot;
   final SetupPinCodeRobot _setupPinCodeRobot;
+  final NewWalletPageRobot _newWalletPageRobot;
+  final DashboardPageRobot _dashboardPageRobot;
   final DisclaimerPageRobot _disclaimerPageRobot;
+  final WalletSeedPageRobot _walletSeedPageRobot;
+  final WalletListPageRobot _walletListPageRobot;
   final NewWalletTypePageRobot _newWalletTypePageRobot;
   final RestoreOptionsPageRobot _restoreOptionsPageRobot;
   final RestoreFromSeedOrKeysPageRobot _restoreFromSeedOrKeysPageRobot;
+  final WalletGroupDescriptionPageRobot _walletGroupDescriptionPageRobot;
 
+  //* ========== Handles flow to start the app afresh and accept disclaimer =============
   Future<void> startAppFlow(Key key) async {
     await app.main(topLevelKey: ValueKey('send_flow_test_app_key'));
-    
+
     await _tester.pumpAndSettle();
 
     // --------- Disclaimer Page ------------
@@ -46,56 +70,275 @@ class CommonTestFlows {
     await _disclaimerPageRobot.tapAcceptButton();
   }
 
-  Future<void> restoreWalletThroughSeedsFlow() async {
-    await _welcomeToRestoreFromSeedsPath();
-    await _restoreFromSeeds();
+  //* ========== Handles flow from welcome to creating a new wallet ===============
+  Future<void> welcomePageToCreateNewWalletFlow(
+    WalletType walletTypeToCreate,
+    List<int> walletPin,
+  ) async {
+    await _welcomeToCreateWalletPath(walletTypeToCreate, walletPin);
+
+    await _generateNewWalletDetails();
+
+    await _confirmPreSeedInfo();
+
+    await _confirmWalletDetails();
   }
 
-  Future<void> restoreWalletThroughKeysFlow() async {
-    await _welcomeToRestoreFromSeedsPath();
+  //* ========== Handles flow from welcome to restoring wallet from seeds ===============
+  Future<void> welcomePageToRestoreWalletThroughSeedsFlow(
+    WalletType walletTypeToRestore,
+    String walletSeed,
+    List<int> walletPin,
+  ) async {
+    await _welcomeToRestoreFromSeedsOrKeysPath(walletTypeToRestore, walletPin);
+    await _restoreFromSeeds(walletTypeToRestore, walletSeed);
+  }
+
+  //* ========== Handles flow from welcome to restoring wallet from keys ===============
+  Future<void> welcomePageToRestoreWalletThroughKeysFlow(
+    WalletType walletTypeToRestore,
+    List<int> walletPin,
+  ) async {
+    await _welcomeToRestoreFromSeedsOrKeysPath(walletTypeToRestore, walletPin);
     await _restoreFromKeys();
   }
 
-  Future<void> _welcomeToRestoreFromSeedsPath() async {
-    // --------- Welcome Page ---------------
-    await _welcomePageRobot.navigateToRestoreWalletPage();
+  //* ========== Handles switching to wallet list or menu from dashboard ===============
+  Future<void> switchToWalletMenuFromDashboardPage() async {
+    _tester.printToConsole('Switching to Wallet Menu');
+    await _dashboardPageRobot.openDrawerMenu();
 
-    // ----------- Restore Options Page -----------
-    // Route to restore from seeds page to continue flow
-    await _restoreOptionsPageRobot.navigateToRestoreFromSeedsPage();
+    await _dashboardPageRobot.dashboardMenuWidgetRobot.navigateToWalletMenu();
+  }
 
+  void confirmAllAvailableWalletTypeIconsDisplayCorrectly() {
+    for (var walletType in availableWalletTypes) {
+      final imageUrl = walletTypeToCryptoCurrency(walletType).iconPath;
+
+      final walletIconFinder = find.image(
+        Image.asset(
+          imageUrl!,
+          width: 32,
+          height: 32,
+        ).image,
+      );
+
+      expect(walletIconFinder, findsAny);
+    }
+  }
+
+  //* ========== Handles creating new wallet flow from wallet list/menu ===============
+  Future<void> createNewWalletFromWalletMenu(WalletType walletTypeToCreate) async {
+    _tester.printToConsole('Creating ${walletTypeToCreate.name} Wallet');
+    await _walletListPageRobot.navigateToCreateNewWalletPage();
+    await _commonTestCases.defaultSleepTime();
+
+    await _selectWalletTypeForWallet(walletTypeToCreate);
+    await _commonTestCases.defaultSleepTime();
+
+    // ---- Wallet Group/New Seed Implementation Comes here
+    await _walletGroupDescriptionPageFlow(true, walletTypeToCreate);
+
+    await _generateNewWalletDetails();
+
+    await _confirmPreSeedInfo();
+
+    await _confirmWalletDetails();
+    await _commonTestCases.defaultSleepTime();
+  }
+
+  Future<void> _walletGroupDescriptionPageFlow(bool isNewSeed, WalletType walletType) async {
+    if (!isBIP39Wallet(walletType)) return;
+
+    await _walletGroupDescriptionPageRobot.isWalletGroupDescriptionPage();
+
+    if (isNewSeed) {
+      await _walletGroupDescriptionPageRobot.navigateToCreateNewSeedPage();
+    } else {
+      await _walletGroupDescriptionPageRobot.navigateToChooseWalletGroup();
+    }
+  }
+
+  //* ========== Handles restore wallet flow from wallet list/menu ===============
+  Future<void> restoreWalletFromWalletMenu(WalletType walletType, String walletSeed) async {
+    _tester.printToConsole('Restoring ${walletType.name} Wallet');
+    await _walletListPageRobot.navigateToRestoreWalletOptionsPage();
+    await _commonTestCases.defaultSleepTime();
+
+    await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
+    await _commonTestCases.defaultSleepTime();
+
+    await _selectWalletTypeForWallet(walletType);
+    await _commonTestCases.defaultSleepTime();
+
+    await _restoreFromSeeds(walletType, walletSeed);
+    await _commonTestCases.defaultSleepTime();
+  }
+
+  //* ========== Handles setting up pin code for wallet on first install ===============
+  Future<void> setupPinCodeForWallet(List<int> pin) async {
     // ----------- SetupPinCode Page -------------
     // Confirm initial defaults - Widgets to be displayed etc
     await _setupPinCodeRobot.isSetupPinCodePage();
 
-    await _setupPinCodeRobot.enterPinCode(CommonTestConstants.pin, true);
-    await _setupPinCodeRobot.enterPinCode(CommonTestConstants.pin, false);
+    await _setupPinCodeRobot.enterPinCode(pin);
+    await _setupPinCodeRobot.enterPinCode(pin);
     await _setupPinCodeRobot.tapSuccessButton();
+  }
 
+  Future<void> _welcomeToCreateWalletPath(
+    WalletType walletTypeToCreate,
+    List<int> pin,
+  ) async {
+    await _welcomePageRobot.navigateToCreateNewWalletPage();
+
+    await setupPinCodeForWallet(pin);
+
+    await _selectWalletTypeForWallet(walletTypeToCreate);
+  }
+
+  Future<void> _welcomeToRestoreFromSeedsOrKeysPath(
+    WalletType walletTypeToRestore,
+    List<int> pin,
+  ) async {
+    await _welcomePageRobot.navigateToRestoreWalletPage();
+
+    await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
+
+    await setupPinCodeForWallet(pin);
+
+    await _selectWalletTypeForWallet(walletTypeToRestore);
+  }
+
+  //* ============ Handles New Wallet Type Page ==================
+  Future<void> _selectWalletTypeForWallet(WalletType type) async {
     // ----------- NewWalletType Page -------------
     // Confirm scroll behaviour works properly
-    await _newWalletTypePageRobot
-        .findParticularWalletTypeInScrollableList(CommonTestConstants.testWalletType);
+    await _newWalletTypePageRobot.findParticularWalletTypeInScrollableList(type);
 
     // Select a wallet and route to next page
-    await _newWalletTypePageRobot.selectWalletType(CommonTestConstants.testWalletType);
+    await _newWalletTypePageRobot.selectWalletType(type);
     await _newWalletTypePageRobot.onNextButtonPressed();
   }
 
-  Future<void> _restoreFromSeeds() async {
+  //* ============ Handles New Wallet Page ==================
+  Future<void> _generateNewWalletDetails() async {
+    await _newWalletPageRobot.isNewWalletPage();
+
+    await _newWalletPageRobot.generateWalletName();
+
+    await _newWalletPageRobot.onNextButtonPressed();
+  }
+
+  //* ============ Handles Pre Seed Page =====================
+  Future<void> _confirmPreSeedInfo() async {
+    await _preSeedPageRobot.isPreSeedPage();
+
+    await _preSeedPageRobot.onConfirmButtonPressed();
+  }
+
+  //* ============ Handles Wallet Seed Page ==================
+  Future<void> _confirmWalletDetails() async {
+    await _walletSeedPageRobot.isWalletSeedPage();
+
+    _walletSeedPageRobot.confirmWalletDetailsDisplayCorrectly();
+
+    _walletSeedPageRobot.confirmWalletSeedReminderDisplays();
+
+    await _walletSeedPageRobot.onCopySeedsButtonPressed();
+
+    await _walletSeedPageRobot.onNextButtonPressed();
+
+    await _walletSeedPageRobot.onConfirmButtonOnSeedAlertDialogPressed();
+  }
+
+  //* Main Restore Actions - On the RestoreFromSeed/Keys Page - Restore from Seeds Action
+  Future<void> _restoreFromSeeds(WalletType type, String walletSeed) async {
     // ----------- RestoreFromSeedOrKeys Page -------------
-    await _restoreFromSeedOrKeysPageRobot.enterWalletNameText(CommonTestConstants.testWalletName);
-    await _restoreFromSeedOrKeysPageRobot.enterSeedPhraseForWalletRestore(secrets.solanaTestWalletSeeds);
+
+    await _restoreFromSeedOrKeysPageRobot.selectWalletNameFromAvailableOptions();
+    await _restoreFromSeedOrKeysPageRobot.enterSeedPhraseForWalletRestore(walletSeed);
+
+    final numberOfWords = walletSeed.split(' ').length;
+
+    if (numberOfWords == 25 && (type == WalletType.monero)) {
+      await _restoreFromSeedOrKeysPageRobot
+          .chooseSeedTypeForMoneroOrWowneroWallets(MoneroSeedType.legacy);
+
+      // Using a constant value of 2831400 for the blockheight as its the restore blockheight for our testing wallet
+      await _restoreFromSeedOrKeysPageRobot
+          .enterBlockHeightForWalletRestore(secrets.moneroTestWalletBlockHeight);
+    }
+
     await _restoreFromSeedOrKeysPageRobot.onRestoreWalletButtonPressed();
   }
 
+  //* Main Restore Actions - On the RestoreFromSeed/Keys Page - Restore from Keys Action
   Future<void> _restoreFromKeys() async {
     await _commonTestCases.swipePage();
     await _commonTestCases.defaultSleepTime();
 
-    await _restoreFromSeedOrKeysPageRobot.enterWalletNameText(CommonTestConstants.testWalletName);
+    await _restoreFromSeedOrKeysPageRobot.selectWalletNameFromAvailableOptions(
+      isSeedFormEntry: false,
+    );
 
     await _restoreFromSeedOrKeysPageRobot.enterSeedPhraseForWalletRestore('');
     await _restoreFromSeedOrKeysPageRobot.onRestoreWalletButtonPressed();
   }
+
+  //* ====== Utility Function to get test wallet seeds for each wallet type ========
+  String getWalletSeedsByWalletType(WalletType walletType) {
+    switch (walletType) {
+      case WalletType.monero:
+        return secrets.moneroTestWalletSeeds;
+      case WalletType.bitcoin:
+        return secrets.bitcoinTestWalletSeeds;
+      case WalletType.ethereum:
+        return secrets.ethereumTestWalletSeeds;
+      case WalletType.litecoin:
+        return secrets.litecoinTestWalletSeeds;
+      case WalletType.bitcoinCash:
+        return secrets.bitcoinCashTestWalletSeeds;
+      case WalletType.polygon:
+        return secrets.polygonTestWalletSeeds;
+      case WalletType.solana:
+        return secrets.solanaTestWalletSeeds;
+      case WalletType.tron:
+        return secrets.tronTestWalletSeeds;
+      case WalletType.nano:
+        return secrets.nanoTestWalletSeeds;
+      case WalletType.wownero:
+        return secrets.wowneroTestWalletSeeds;
+      default:
+        return '';
+    }
+  }
+
+  //* ====== Utility Function to get test receive address for each wallet type ========
+  String getReceiveAddressByWalletType(WalletType walletType) {
+    switch (walletType) {
+      case WalletType.monero:
+        return secrets.moneroTestWalletReceiveAddress;
+      case WalletType.bitcoin:
+        return secrets.bitcoinTestWalletReceiveAddress;
+      case WalletType.ethereum:
+        return secrets.ethereumTestWalletReceiveAddress;
+      case WalletType.litecoin:
+        return secrets.litecoinTestWalletReceiveAddress;
+      case WalletType.bitcoinCash:
+        return secrets.bitcoinCashTestWalletReceiveAddress;
+      case WalletType.polygon:
+        return secrets.polygonTestWalletReceiveAddress;
+      case WalletType.solana:
+        return secrets.solanaTestWalletReceiveAddress;
+      case WalletType.tron:
+        return secrets.tronTestWalletReceiveAddress;
+      case WalletType.nano:
+        return secrets.nanoTestWalletReceiveAddress;
+      case WalletType.wownero:
+        return secrets.wowneroTestWalletReceiveAddress;
+      default:
+        return '';
+    }
+  }
 }
diff --git a/integration_test/funds_related_tests.dart b/integration_test/funds_related_tests.dart
index 9d97d47f8..db24fbc0b 100644
--- a/integration_test/funds_related_tests.dart
+++ b/integration_test/funds_related_tests.dart
@@ -9,6 +9,7 @@ import 'robots/dashboard_page_robot.dart';
 import 'robots/exchange_confirm_page_robot.dart';
 import 'robots/exchange_page_robot.dart';
 import 'robots/exchange_trade_page_robot.dart';
+import 'package:cake_wallet/.secrets.g.dart' as secrets;
 
 void main() {
   IntegrationTestWidgetsFlutterBinding.ensureInitialized();
@@ -32,7 +33,11 @@ void main() {
 
       await commonTestFlows.startAppFlow(ValueKey('funds_exchange_test_app_key'));
 
-      await commonTestFlows.restoreWalletThroughSeedsFlow();
+      await commonTestFlows.welcomePageToRestoreWalletThroughSeedsFlow(
+        CommonTestConstants.testWalletType,
+        secrets.solanaTestWalletSeeds,
+        CommonTestConstants.pin,
+      );
 
       // ----------- RestoreFromSeedOrKeys Page -------------
       await dashboardPageRobot.navigateToExchangePage();
@@ -59,7 +64,7 @@ void main() {
 
       final onAuthPage = authPageRobot.onAuthPage();
       if (onAuthPage) {
-        await authPageRobot.enterPinCode(CommonTestConstants.pin, false);
+        await authPageRobot.enterPinCode(CommonTestConstants.pin);
       }
 
       // ----------- Exchange Confirm Page -------------
diff --git a/integration_test/robots/dashboard_menu_widget_robot.dart b/integration_test/robots/dashboard_menu_widget_robot.dart
new file mode 100644
index 000000000..f48033dda
--- /dev/null
+++ b/integration_test/robots/dashboard_menu_widget_robot.dart
@@ -0,0 +1,39 @@
+import 'package:cake_wallet/src/screens/dashboard/widgets/menu_widget.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import '../components/common_test_cases.dart';
+
+class DashboardMenuWidgetRobot {
+  DashboardMenuWidgetRobot(this.tester) : commonTestCases = CommonTestCases(tester);
+
+  final WidgetTester tester;
+  late CommonTestCases commonTestCases;
+
+  Future<void> hasMenuWidget() async {
+    commonTestCases.hasType<MenuWidget>();
+  }
+
+  void displaysTheCorrectWalletNameAndSubName() {
+    final menuWidgetState = tester.state<MenuWidgetState>(find.byType(MenuWidget));
+
+    final walletName = menuWidgetState.widget.dashboardViewModel.name;
+    commonTestCases.hasText(walletName);
+
+    final walletSubName = menuWidgetState.widget.dashboardViewModel.subname;
+    if (walletSubName.isNotEmpty) {
+      commonTestCases.hasText(walletSubName);
+    }
+  }
+
+  Future<void> navigateToWalletMenu() async {
+    await commonTestCases.tapItemByKey('dashboard_page_menu_widget_wallet_menu_button_key');
+    await commonTestCases.defaultSleepTime();
+  }
+
+  Future<void> navigateToSecurityAndBackupPage() async {
+    await commonTestCases.tapItemByKey(
+      'dashboard_page_menu_widget_security_and_backup_button_key',
+    );
+    await commonTestCases.defaultSleepTime();
+  }
+}
diff --git a/integration_test/robots/dashboard_page_robot.dart b/integration_test/robots/dashboard_page_robot.dart
index fc917c3b2..bc5f411ad 100644
--- a/integration_test/robots/dashboard_page_robot.dart
+++ b/integration_test/robots/dashboard_page_robot.dart
@@ -1,20 +1,44 @@
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/src/screens/dashboard/dashboard_page.dart';
+import 'package:cake_wallet/src/screens/dashboard/pages/balance_page.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:flutter_test/flutter_test.dart';
 
 import '../components/common_test_cases.dart';
+import 'dashboard_menu_widget_robot.dart';
 
 class DashboardPageRobot {
-  DashboardPageRobot(this.tester) : commonTestCases = CommonTestCases(tester);
+  DashboardPageRobot(this.tester)
+      : commonTestCases = CommonTestCases(tester),
+        dashboardMenuWidgetRobot = DashboardMenuWidgetRobot(tester);
 
   final WidgetTester tester;
+  final DashboardMenuWidgetRobot dashboardMenuWidgetRobot;
   late CommonTestCases commonTestCases;
 
   Future<void> isDashboardPage() async {
     await commonTestCases.isSpecificPage<DashboardPage>();
   }
 
+  Future<void> confirmWalletTypeIsDisplayedCorrectly(
+    WalletType type, {
+    bool isHaven = false,
+  }) async {
+    final cryptoBalanceWidget =
+        tester.widget<CryptoBalanceWidget>(find.byType(CryptoBalanceWidget));
+    final hasAccounts = cryptoBalanceWidget.dashboardViewModel.balanceViewModel.hasAccounts;
+
+    if (hasAccounts) {
+      final walletName = cryptoBalanceWidget.dashboardViewModel.name;
+      commonTestCases.hasText(walletName);
+    } else {
+      final walletName = walletTypeToString(type);
+      final assetName = isHaven ? '$walletName Assets' : walletName;
+      commonTestCases.hasText(assetName);
+    }
+    await commonTestCases.defaultSleepTime(seconds: 5);
+  }
+
   void confirmServiceUpdateButtonDisplays() {
     commonTestCases.hasValueKey('dashboard_page_services_update_button_key');
   }
@@ -27,30 +51,40 @@ class DashboardPageRobot {
     commonTestCases.hasValueKey('dashboard_page_wallet_menu_button_key');
   }
 
-  Future<void> confirmRightCryptoAssetTitleDisplaysPerPageView(WalletType type,
-      {bool isHaven = false}) async {
+  Future<void> confirmRightCryptoAssetTitleDisplaysPerPageView(
+    WalletType type, {
+    bool isHaven = false,
+  }) async {
     //Balance Page
-    final walletName = walletTypeToString(type);
-    final assetName = isHaven ? '$walletName Assets' : walletName;
-    commonTestCases.hasText(assetName);
+    await confirmWalletTypeIsDisplayedCorrectly(type, isHaven: isHaven);
 
     // Swipe to Cake features Page
-    await commonTestCases.swipeByPageKey(key: 'dashboard_page_view_key', swipeRight: false);
-    await commonTestCases.defaultSleepTime();
+    await swipeDashboardTab(false);
     commonTestCases.hasText('Cake ${S.current.features}');
 
     // Swipe back to balance
-    await commonTestCases.swipeByPageKey(key: 'dashboard_page_view_key');
-    await commonTestCases.defaultSleepTime();
+    await swipeDashboardTab(true);
 
     // Swipe to Transactions Page
-    await commonTestCases.swipeByPageKey(key: 'dashboard_page_view_key');
-    await commonTestCases.defaultSleepTime();
+    await swipeDashboardTab(true);
     commonTestCases.hasText(S.current.transactions);
 
     // Swipe back to balance
-    await commonTestCases.swipeByPageKey(key: 'dashboard_page_view_key', swipeRight: false);
-    await commonTestCases.defaultSleepTime(seconds: 5);
+    await swipeDashboardTab(false);
+    await commonTestCases.defaultSleepTime(seconds: 3);
+  }
+
+  Future<void> swipeDashboardTab(bool swipeRight) async {
+    await commonTestCases.swipeByPageKey(
+      key: 'dashboard_page_view_key',
+      swipeRight: swipeRight,
+    );
+    await commonTestCases.defaultSleepTime();
+  }
+
+  Future<void> openDrawerMenu() async {
+    await commonTestCases.tapItemByKey('dashboard_page_wallet_menu_button_key');
+    await commonTestCases.defaultSleepTime();
   }
 
   Future<void> navigateToBuyPage() async {
diff --git a/integration_test/robots/exchange_page_robot.dart b/integration_test/robots/exchange_page_robot.dart
index b439e4791..e01b2df9c 100644
--- a/integration_test/robots/exchange_page_robot.dart
+++ b/integration_test/robots/exchange_page_robot.dart
@@ -123,7 +123,7 @@ class ExchangePageRobot {
       return;
     }
 
-    await commonTestCases.scrollUntilVisible(
+    await commonTestCases.dragUntilVisible(
       'picker_items_index_${depositCurrency.name}_button_key',
       'picker_scrollbar_key',
     );
@@ -149,7 +149,7 @@ class ExchangePageRobot {
       return;
     }
 
-    await commonTestCases.scrollUntilVisible(
+    await commonTestCases.dragUntilVisible(
       'picker_items_index_${receiveCurrency.name}_button_key',
       'picker_scrollbar_key',
     );
diff --git a/integration_test/robots/new_wallet_page_robot.dart b/integration_test/robots/new_wallet_page_robot.dart
new file mode 100644
index 000000000..f8deb00ae
--- /dev/null
+++ b/integration_test/robots/new_wallet_page_robot.dart
@@ -0,0 +1,35 @@
+import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import '../components/common_test_cases.dart';
+
+class NewWalletPageRobot {
+  NewWalletPageRobot(this.tester) : commonTestCases = CommonTestCases(tester);
+
+  final WidgetTester tester;
+  late CommonTestCases commonTestCases;
+
+  Future<void> isNewWalletPage() async {
+    await commonTestCases.isSpecificPage<NewWalletPage>();
+  }
+
+  Future<void> enterWalletName(String walletName) async {
+    await commonTestCases.enterText(
+      walletName,
+      'new_wallet_page_wallet_name_textformfield_key',
+    );
+    await commonTestCases.defaultSleepTime();
+  }
+
+  Future<void> generateWalletName() async {
+    await commonTestCases.tapItemByKey(
+      'new_wallet_page_wallet_name_textformfield_generate_name_button_key',
+    );
+    await commonTestCases.defaultSleepTime();
+  }
+
+  Future<void> onNextButtonPressed() async {
+    await commonTestCases.tapItemByKey('new_wallet_page_confirm_button_key');
+    await commonTestCases.defaultSleepTime();
+  }
+}
diff --git a/integration_test/robots/pin_code_widget_robot.dart b/integration_test/robots/pin_code_widget_robot.dart
index b6805e9e0..18dc5fba4 100644
--- a/integration_test/robots/pin_code_widget_robot.dart
+++ b/integration_test/robots/pin_code_widget_robot.dart
@@ -24,13 +24,12 @@ class PinCodeWidgetRobot {
     commonTestCases.hasValueKey('pin_code_button_0_key');
   }
 
-  Future<void> pushPinButton(int index) async {
-    await commonTestCases.tapItemByKey('pin_code_button_${index}_key');
-  }
-
-  Future<void> enterPinCode(List<int> pinCode, bool isFirstEntry) async {
+  Future<void> enterPinCode(List<int> pinCode, {int pumpDuration = 100}) async {
     for (int pin in pinCode) {
-      await pushPinButton(pin);
+      await commonTestCases.tapItemByKey(
+        'pin_code_button_${pin}_key',
+        pumpDuration: pumpDuration,
+      );
     }
 
     await commonTestCases.defaultSleepTime();
diff --git a/integration_test/robots/pre_seed_page_robot.dart b/integration_test/robots/pre_seed_page_robot.dart
new file mode 100644
index 000000000..01be1249c
--- /dev/null
+++ b/integration_test/robots/pre_seed_page_robot.dart
@@ -0,0 +1,20 @@
+import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import '../components/common_test_cases.dart';
+
+class PreSeedPageRobot {
+  PreSeedPageRobot(this.tester) : commonTestCases = CommonTestCases(tester);
+
+  final WidgetTester tester;
+  late CommonTestCases commonTestCases;
+
+  Future<void> isPreSeedPage() async {
+    await commonTestCases.isSpecificPage<PreSeedPage>();
+  }
+
+  Future<void> onConfirmButtonPressed() async {
+    await commonTestCases.tapItemByKey('pre_seed_page_button_key');
+    await commonTestCases.defaultSleepTime();
+  }
+}
diff --git a/integration_test/robots/restore_from_seed_or_key_robot.dart b/integration_test/robots/restore_from_seed_or_key_robot.dart
index 43a65095d..9d973061b 100644
--- a/integration_test/robots/restore_from_seed_or_key_robot.dart
+++ b/integration_test/robots/restore_from_seed_or_key_robot.dart
@@ -1,3 +1,4 @@
+import 'package:cake_wallet/entities/seed_type.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
 import 'package:cake_wallet/src/widgets/validable_annotated_editable_text.dart';
@@ -70,6 +71,22 @@ class RestoreFromSeedOrKeysPageRobot {
     await tester.pumpAndSettle();
   }
 
+  Future<void> enterBlockHeightForWalletRestore(String blockHeight) async {
+    await commonTestCases.enterText(
+      blockHeight,
+      'wallet_restore_from_seed_blockheight_textfield_key',
+    );
+    await tester.pumpAndSettle();
+  }
+
+  Future<void> chooseSeedTypeForMoneroOrWowneroWallets(MoneroSeedType selectedType) async {
+    await commonTestCases.tapItemByKey('wallet_restore_from_seed_seedtype_picker_button_key');
+
+    await commonTestCases.defaultSleepTime();
+
+    await commonTestCases.tapItemByKey('picker_items_index_${selectedType.title}_button_key');
+  }
+
   Future<void> onPasteSeedPhraseButtonPressed() async {
     await commonTestCases.tapItemByKey('wallet_restore_from_seed_wallet_seeds_paste_button_key');
   }
diff --git a/integration_test/robots/restore_options_page_robot.dart b/integration_test/robots/restore_options_page_robot.dart
index b3cefc90c..cd1919609 100644
--- a/integration_test/robots/restore_options_page_robot.dart
+++ b/integration_test/robots/restore_options_page_robot.dart
@@ -14,14 +14,14 @@ class RestoreOptionsPageRobot {
   }
 
   void hasRestoreOptionsButton() {
-    commonTestCases.hasValueKey('restore_options_from_seeds_button_key');
+    commonTestCases.hasValueKey('restore_options_from_seeds_or_keys_button_key');
     commonTestCases.hasValueKey('restore_options_from_backup_button_key');
     commonTestCases.hasValueKey('restore_options_from_hardware_wallet_button_key');
     commonTestCases.hasValueKey('restore_options_from_qr_button_key');
   }
 
-  Future<void> navigateToRestoreFromSeedsPage() async {
-    await commonTestCases.tapItemByKey('restore_options_from_seeds_button_key');
+  Future<void> navigateToRestoreFromSeedsOrKeysPage() async {
+    await commonTestCases.tapItemByKey('restore_options_from_seeds_or_keys_button_key');
     await commonTestCases.defaultSleepTime();
   }
 
diff --git a/integration_test/robots/security_and_backup_page_robot.dart b/integration_test/robots/security_and_backup_page_robot.dart
new file mode 100644
index 000000000..eb7c1bc87
--- /dev/null
+++ b/integration_test/robots/security_and_backup_page_robot.dart
@@ -0,0 +1,24 @@
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/settings/security_backup_page.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import '../components/common_test_cases.dart';
+
+class SecurityAndBackupPageRobot {
+  SecurityAndBackupPageRobot(this.tester) : commonTestCases = CommonTestCases(tester);
+
+  final WidgetTester tester;
+  final CommonTestCases commonTestCases;
+
+  Future<void> isSecurityAndBackupPage() async {
+    await commonTestCases.isSpecificPage<SecurityBackupPage>();
+  }
+
+  void hasTitle() {
+    commonTestCases.hasText(S.current.security_and_backup);
+  }
+
+  Future<void> navigateToShowKeysPage() async {
+    await commonTestCases.tapItemByKey('security_backup_page_show_keys_button_key');
+  }
+}
diff --git a/integration_test/robots/send_page_robot.dart b/integration_test/robots/send_page_robot.dart
index 971556620..20cef948d 100644
--- a/integration_test/robots/send_page_robot.dart
+++ b/integration_test/robots/send_page_robot.dart
@@ -84,7 +84,7 @@ class SendPageRobot {
       return;
     }
 
-    await commonTestCases.scrollUntilVisible(
+    await commonTestCases.dragUntilVisible(
       'picker_items_index_${receiveCurrency.name}_button_key',
       'picker_scrollbar_key',
     );
@@ -117,7 +117,7 @@ class SendPageRobot {
       return;
     }
 
-    await commonTestCases.scrollUntilVisible(
+    await commonTestCases.dragUntilVisible(
       'picker_items_index_${priority.title}_button_key',
       'picker_scrollbar_key',
     );
@@ -198,7 +198,7 @@ class SendPageRobot {
       tester.printToConsole('Starting inner _handleAuth loop checks');
 
       try {
-        await authPageRobot.enterPinCode(CommonTestConstants.pin, false);
+        await authPageRobot.enterPinCode(CommonTestConstants.pin, pumpDuration: 500);
         tester.printToConsole('Auth done');
 
         await tester.pump();
@@ -213,6 +213,7 @@ class SendPageRobot {
   }
 
   Future<void> handleSendResult() async {
+    await tester.pump();
     tester.printToConsole('Inside handle function');
 
     bool hasError = false;
@@ -287,6 +288,8 @@ class SendPageRobot {
       // Loop to wait for the operation to commit transaction
       await _waitForCommitTransactionCompletion();
 
+      await tester.pump();
+
       await commonTestCases.defaultSleepTime(seconds: 4);
     } else {
       await commonTestCases.defaultSleepTime();
diff --git a/integration_test/robots/transactions_page_robot.dart b/integration_test/robots/transactions_page_robot.dart
new file mode 100644
index 000000000..40a49928f
--- /dev/null
+++ b/integration_test/robots/transactions_page_robot.dart
@@ -0,0 +1,286 @@
+import 'dart:async';
+
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
+import 'package:cake_wallet/utils/date_formatter.dart';
+import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
+import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
+import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
+import 'package:cake_wallet/view_model/dashboard/date_section_item.dart';
+import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
+import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
+import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
+import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/sync_status.dart';
+import 'package:cw_core/transaction_direction.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:intl/intl.dart';
+
+import '../components/common_test_cases.dart';
+
+class TransactionsPageRobot {
+  TransactionsPageRobot(this.tester) : commonTestCases = CommonTestCases(tester);
+
+  final WidgetTester tester;
+  late CommonTestCases commonTestCases;
+
+  Future<void> isTransactionsPage() async {
+    await commonTestCases.isSpecificPage<TransactionsPage>();
+  }
+
+  Future<void> confirmTransactionsPageConstantsDisplayProperly() async {
+    await commonTestCases.defaultSleepTime();
+
+    final transactionsPage = tester.widget<TransactionsPage>(find.byType(TransactionsPage));
+    final dashboardViewModel = transactionsPage.dashboardViewModel;
+    if (dashboardViewModel.status is SyncingSyncStatus) {
+      commonTestCases.hasValueKey('transactions_page_syncing_alert_card_key');
+      commonTestCases.hasText(S.current.syncing_wallet_alert_title);
+      commonTestCases.hasText(S.current.syncing_wallet_alert_content);
+    }
+
+    commonTestCases.hasValueKey('transactions_page_header_row_key');
+    commonTestCases.hasText(S.current.transactions);
+    commonTestCases.hasValueKey('transactions_page_header_row_transaction_filter_button_key');
+  }
+
+  Future<void> confirmTransactionHistoryListDisplaysCorrectly(bool hasTxHistoryWhileSyncing) async {
+    // Retrieve the TransactionsPage widget and its DashboardViewModel
+    final transactionsPage = tester.widget<TransactionsPage>(find.byType(TransactionsPage));
+    final dashboardViewModel = transactionsPage.dashboardViewModel;
+
+    // Define a timeout to prevent infinite loops
+    // Putting at one hour for cases like monero that takes time to sync
+    final timeout = Duration(hours: 1);
+    final pollingInterval = Duration(seconds: 2);
+    final endTime = DateTime.now().add(timeout);
+
+    while (DateTime.now().isBefore(endTime)) {
+      final isSynced = dashboardViewModel.status is SyncedSyncStatus;
+      final itemsLoaded = dashboardViewModel.items.isNotEmpty;
+
+      // Perform item checks if items are loaded
+      if (itemsLoaded) {
+        await _performItemChecks(dashboardViewModel);
+      } else {
+        // Verify placeholder when items are not loaded
+        _verifyPlaceholder();
+      }
+
+      // Determine if we should exit the loop
+      if (_shouldExitLoop(hasTxHistoryWhileSyncing, isSynced, itemsLoaded)) {
+        break;
+      }
+
+      // Pump the UI and wait for the next polling interval
+      await tester.pump(pollingInterval);
+    }
+
+    // After the loop, verify that both status is synced and items are loaded
+    if (!_isFinalStateValid(dashboardViewModel)) {
+      throw TimeoutException('Dashboard did not sync and load items within the allotted time.');
+    }
+  }
+
+  bool _shouldExitLoop(bool hasTxHistoryWhileSyncing, bool isSynced, bool itemsLoaded) {
+    if (hasTxHistoryWhileSyncing) {
+      // When hasTxHistoryWhileSyncing is true, exit when status is synced
+      return isSynced;
+    } else {
+      // When hasTxHistoryWhileSyncing is false, exit when status is synced and items are loaded
+      return isSynced && itemsLoaded;
+    }
+  }
+
+  void _verifyPlaceholder() {
+    commonTestCases.hasValueKey('transactions_page_placeholder_transactions_text_key');
+    commonTestCases.hasText(S.current.placeholder_transactions);
+  }
+
+  bool _isFinalStateValid(DashboardViewModel dashboardViewModel) {
+    final isSynced = dashboardViewModel.status is SyncedSyncStatus;
+    final itemsLoaded = dashboardViewModel.items.isNotEmpty;
+    return isSynced && itemsLoaded;
+  }
+
+  Future<void> _performItemChecks(DashboardViewModel dashboardViewModel) async {
+    List<ActionListItem> items = dashboardViewModel.items;
+    for (var item in items) {
+      final keyId = (item.key as ValueKey<String>).value;
+      tester.printToConsole('\n');
+      tester.printToConsole(keyId);
+
+      await commonTestCases.dragUntilVisible(keyId, 'transactions_page_list_view_builder_key');
+      await tester.pump();
+
+      final isWidgetVisible = tester.any(find.byKey(ValueKey(keyId)));
+      if (!isWidgetVisible) {
+        tester.printToConsole('Moving to next visible item on list');
+        continue;
+      }
+      ;
+      await tester.pump();
+
+      if (item is DateSectionItem) {
+        await _verifyDateSectionItem(item);
+      } else if (item is TransactionListItem) {
+        tester.printToConsole(item.formattedTitle);
+        tester.printToConsole(item.formattedFiatAmount);
+        tester.printToConsole('\n');
+        await _verifyTransactionListItemDisplay(item, dashboardViewModel);
+      } else if (item is AnonpayTransactionListItem) {
+        await _verifyAnonpayTransactionListItemDisplay(item);
+      } else if (item is TradeListItem) {
+        await _verifyTradeListItemDisplay(item);
+      } else if (item is OrderListItem) {
+        await _verifyOrderListItemDisplay(item);
+      }
+    }
+  }
+
+  Future<void> _verifyDateSectionItem(DateSectionItem item) async {
+    final title = DateFormatter.convertDateTimeToReadableString(item.date);
+    tester.printToConsole(title);
+    await tester.pump();
+
+    commonTestCases.findWidgetViaDescendant(
+      of: find.byKey(item.key),
+      matching: find.text(title),
+    );
+  }
+
+  Future<void> _verifyTransactionListItemDisplay(
+    TransactionListItem item,
+    DashboardViewModel dashboardViewModel,
+  ) async {
+    final keyId =
+        '${dashboardViewModel.type.name}_transaction_history_item_${item.transaction.id}_key';
+
+    if (item.hasTokens && item.assetOfTransaction == null) return;
+
+    //* ==============Confirm it has the right key for this item ========
+    commonTestCases.hasValueKey(keyId);
+
+    //* ======Confirm it displays the properly formatted amount==========
+    commonTestCases.findWidgetViaDescendant(
+      of: find.byKey(ValueKey(keyId)),
+      matching: find.text(item.formattedCryptoAmount),
+    );
+
+    //* ======Confirm it displays the properly formatted title===========
+    final transactionType = dashboardViewModel.getTransactionType(item.transaction);
+
+    final title = item.formattedTitle + item.formattedStatus + transactionType;
+
+    commonTestCases.findWidgetViaDescendant(
+      of: find.byKey(ValueKey(keyId)),
+      matching: find.text(title),
+    );
+
+    //* ======Confirm it displays the properly formatted date============
+    final formattedDate = DateFormat('HH:mm').format(item.transaction.date);
+    commonTestCases.findWidgetViaDescendant(
+      of: find.byKey(ValueKey(keyId)),
+      matching: find.text(formattedDate),
+    );
+
+    //* ======Confirm it displays the properly formatted fiat amount=====
+    final formattedFiatAmount =
+        dashboardViewModel.balanceViewModel.isFiatDisabled ? '' : item.formattedFiatAmount;
+    if (formattedFiatAmount.isNotEmpty) {
+      commonTestCases.findWidgetViaDescendant(
+        of: find.byKey(ValueKey(keyId)),
+        matching: find.text(formattedFiatAmount),
+      );
+    }
+
+    //* ======Confirm it displays the right image based on the transaction direction=====
+    final imageToUse = item.transaction.direction == TransactionDirection.incoming
+        ? 'assets/images/down_arrow.png'
+        : 'assets/images/up_arrow.png';
+
+    find.widgetWithImage(Container, AssetImage(imageToUse));
+  }
+
+  Future<void> _verifyAnonpayTransactionListItemDisplay(AnonpayTransactionListItem item) async {
+    final keyId = 'anonpay_invoice_transaction_list_item_${item.transaction.invoiceId}_key';
+
+    //* ==============Confirm it has the right key for this item ========
+    commonTestCases.hasValueKey(keyId);
+
+    //* ==============Confirm it displays the correct provider =========================
+    commonTestCases.hasText(item.transaction.provider);
+
+    //* ===========Confirm it displays the properly formatted amount with currency ========
+    final currency = item.transaction.fiatAmount != null
+        ? item.transaction.fiatEquiv ?? ''
+        : CryptoCurrency.fromFullName(item.transaction.coinTo).name.toUpperCase();
+
+    final amount =
+        item.transaction.fiatAmount?.toString() ?? (item.transaction.amountTo?.toString() ?? '');
+
+    final amountCurrencyText = amount + ' ' + currency;
+
+    commonTestCases.hasText(amountCurrencyText);
+
+    //* ======Confirm it displays the properly formatted date=================
+    final formattedDate = DateFormat('HH:mm').format(item.transaction.createdAt);
+    commonTestCases.hasText(formattedDate);
+
+    //* ===============Confirm it displays the right image====================
+    find.widgetWithImage(ClipRRect, AssetImage('assets/images/trocador.png'));
+  }
+
+  Future<void> _verifyTradeListItemDisplay(TradeListItem item) async {
+    final keyId = 'trade_list_item_${item.trade.id}_key';
+
+    //* ==============Confirm it has the right key for this item ========
+    commonTestCases.hasValueKey(keyId);
+
+    //* ==============Confirm it displays the correct provider =========================
+    final conversionFlow = '${item.trade.from.toString()} → ${item.trade.to.toString()}';
+
+    commonTestCases.hasText(conversionFlow);
+
+    //* ===========Confirm it displays the properly formatted amount with its crypto tag ========
+
+    final amountCryptoText = item.tradeFormattedAmount + ' ' + item.trade.from.toString();
+
+    commonTestCases.hasText(amountCryptoText);
+
+    //* ======Confirm it displays the properly formatted date=================
+    final createdAtFormattedDate =
+        item.trade.createdAt != null ? DateFormat('HH:mm').format(item.trade.createdAt!) : null;
+
+    if (createdAtFormattedDate != null) {
+      commonTestCases.hasText(createdAtFormattedDate);
+    }
+
+    //* ===============Confirm it displays the right image====================
+    commonTestCases.hasValueKey(item.trade.provider.image);
+  }
+
+  Future<void> _verifyOrderListItemDisplay(OrderListItem item) async {
+    final keyId = 'order_list_item_${item.order.id}_key';
+
+    //* ==============Confirm it has the right key for this item ========
+    commonTestCases.hasValueKey(keyId);
+
+    //* ==============Confirm it displays the correct provider =========================
+    final orderFlow = '${item.order.from!} → ${item.order.to}';
+
+    commonTestCases.hasText(orderFlow);
+
+    //* ===========Confirm it displays the properly formatted amount with its crypto tag ========
+
+    final amountCryptoText = item.orderFormattedAmount + ' ' + item.order.to!;
+
+    commonTestCases.hasText(amountCryptoText);
+
+    //* ======Confirm it displays the properly formatted date=================
+    final createdAtFormattedDate = DateFormat('HH:mm').format(item.order.createdAt);
+
+    commonTestCases.hasText(createdAtFormattedDate);
+  }
+}
diff --git a/integration_test/robots/wallet_group_description_page_robot.dart b/integration_test/robots/wallet_group_description_page_robot.dart
new file mode 100644
index 000000000..57500dc3c
--- /dev/null
+++ b/integration_test/robots/wallet_group_description_page_robot.dart
@@ -0,0 +1,32 @@
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/new_wallet/wallet_group_description_page.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import '../components/common_test_cases.dart';
+
+class WalletGroupDescriptionPageRobot {
+  WalletGroupDescriptionPageRobot(this.tester) : commonTestCases = CommonTestCases(tester);
+
+  final WidgetTester tester;
+  final CommonTestCases commonTestCases;
+
+  Future<void> isWalletGroupDescriptionPage() async {
+    await commonTestCases.isSpecificPage<WalletGroupDescriptionPage>();
+  }
+
+  void hasTitle() {
+    commonTestCases.hasText(S.current.wallet_group);
+  }
+
+  Future<void> navigateToCreateNewSeedPage() async {
+    await commonTestCases.tapItemByKey(
+      'wallet_group_description_page_create_new_seed_button_key',
+    );
+  }
+
+  Future<void> navigateToChooseWalletGroup() async {
+    await commonTestCases.tapItemByKey(
+      'wallet_group_description_page_choose_wallet_group_button_key',
+    );
+  }
+}
diff --git a/integration_test/robots/wallet_keys_robot.dart b/integration_test/robots/wallet_keys_robot.dart
new file mode 100644
index 000000000..f6aeb3a66
--- /dev/null
+++ b/integration_test/robots/wallet_keys_robot.dart
@@ -0,0 +1,162 @@
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/reactions/wallet_connect.dart';
+import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
+import 'package:cake_wallet/store/app_store.dart';
+import 'package:cw_core/monero_wallet_keys.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:cw_monero/monero_wallet.dart';
+import 'package:cw_wownero/wownero_wallet.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:polyseed/polyseed.dart';
+
+import '../components/common_test_cases.dart';
+
+class WalletKeysAndSeedPageRobot {
+  WalletKeysAndSeedPageRobot(this.tester) : commonTestCases = CommonTestCases(tester);
+
+  final WidgetTester tester;
+  final CommonTestCases commonTestCases;
+
+  Future<void> isWalletKeysAndSeedPage() async {
+    await commonTestCases.isSpecificPage<WalletKeysPage>();
+  }
+
+  void hasTitle() {
+    final walletKeysPage = tester.widget<WalletKeysPage>(find.byType(WalletKeysPage));
+    final walletKeysViewModel = walletKeysPage.walletKeysViewModel;
+    commonTestCases.hasText(walletKeysViewModel.title);
+  }
+
+  void hasShareWarning() {
+    commonTestCases.hasText(S.current.do_not_share_warning_text.toUpperCase());
+  }
+
+  Future<void> confirmWalletCredentials(WalletType walletType) async {
+    final walletKeysPage = tester.widget<WalletKeysPage>(find.byType(WalletKeysPage));
+    final walletKeysViewModel = walletKeysPage.walletKeysViewModel;
+
+    final appStore = walletKeysViewModel.appStore;
+    final walletName = walletType.name;
+    bool hasSeed = appStore.wallet!.seed != null;
+    bool hasHexSeed = appStore.wallet!.hexSeed != null;
+    bool hasPrivateKey = appStore.wallet!.privateKey != null;
+
+    if (walletType == WalletType.monero) {
+      final moneroWallet = appStore.wallet as MoneroWallet;
+      final lang = PolyseedLang.getByPhrase(moneroWallet.seed);
+      final legacySeed = moneroWallet.seedLegacy(lang.nameEnglish);
+
+      _confirmMoneroWalletCredentials(
+        appStore,
+        walletName,
+        moneroWallet.seed,
+        legacySeed,
+      );
+    }
+
+    if (walletType == WalletType.wownero) {
+      final wowneroWallet = appStore.wallet as WowneroWallet;
+      final lang = PolyseedLang.getByPhrase(wowneroWallet.seed);
+      final legacySeed = wowneroWallet.seedLegacy(lang.nameEnglish);
+
+      _confirmMoneroWalletCredentials(
+        appStore,
+        walletName,
+        wowneroWallet.seed,
+        legacySeed,
+      );
+    }
+
+    if (walletType == WalletType.bitcoin ||
+        walletType == WalletType.litecoin ||
+        walletType == WalletType.bitcoinCash) {
+      commonTestCases.hasText(appStore.wallet!.seed!);
+      tester.printToConsole('$walletName wallet has seeds properly displayed');
+    }
+
+    if (isEVMCompatibleChain(walletType) ||
+        walletType == WalletType.solana ||
+        walletType == WalletType.tron) {
+      if (hasSeed) {
+        commonTestCases.hasText(appStore.wallet!.seed!);
+        tester.printToConsole('$walletName wallet has seeds properly displayed');
+      }
+      if (hasPrivateKey) {
+        commonTestCases.hasText(appStore.wallet!.privateKey!);
+        tester.printToConsole('$walletName wallet has private key properly displayed');
+      }
+    }
+
+    if (walletType == WalletType.nano || walletType == WalletType.banano) {
+      if (hasSeed) {
+        commonTestCases.hasText(appStore.wallet!.seed!);
+        tester.printToConsole('$walletName wallet has seeds properly displayed');
+      }
+      if (hasHexSeed) {
+        commonTestCases.hasText(appStore.wallet!.hexSeed!);
+        tester.printToConsole('$walletName wallet has hexSeed properly displayed');
+      }
+      if (hasPrivateKey) {
+        commonTestCases.hasText(appStore.wallet!.privateKey!);
+        tester.printToConsole('$walletName wallet has private key properly displayed');
+      }
+    }
+
+    await commonTestCases.defaultSleepTime(seconds: 5);
+  }
+
+  void _confirmMoneroWalletCredentials(
+    AppStore appStore,
+    String walletName,
+    String seed,
+    String legacySeed,
+  ) {
+    final keys = appStore.wallet!.keys as MoneroWalletKeys;
+
+    final hasPublicSpendKey = commonTestCases.isKeyPresent(
+      '${walletName}_wallet_public_spend_key_item_key',
+    );
+    final hasPrivateSpendKey = commonTestCases.isKeyPresent(
+      '${walletName}_wallet_private_spend_key_item_key',
+    );
+    final hasPublicViewKey = commonTestCases.isKeyPresent(
+      '${walletName}_wallet_public_view_key_item_key',
+    );
+    final hasPrivateViewKey = commonTestCases.isKeyPresent(
+      '${walletName}_wallet_private_view_key_item_key',
+    );
+    final hasSeeds = seed.isNotEmpty;
+    final hasSeedLegacy = Polyseed.isValidSeed(seed);
+
+    if (hasPublicSpendKey) {
+      commonTestCases.hasText(keys.publicSpendKey);
+      tester.printToConsole('$walletName wallet has public spend key properly displayed');
+    }
+    if (hasPrivateSpendKey) {
+      commonTestCases.hasText(keys.privateSpendKey);
+      tester.printToConsole('$walletName wallet has private spend key properly displayed');
+    }
+    if (hasPublicViewKey) {
+      commonTestCases.hasText(keys.publicViewKey);
+      tester.printToConsole('$walletName wallet has public view key properly displayed');
+    }
+    if (hasPrivateViewKey) {
+      commonTestCases.hasText(keys.privateViewKey);
+      tester.printToConsole('$walletName wallet has private view key properly displayed');
+    }
+    if (hasSeeds) {
+      commonTestCases.hasText(seed);
+      tester.printToConsole('$walletName wallet has seeds properly displayed');
+    }
+    if (hasSeedLegacy) {
+      commonTestCases.hasText(legacySeed);
+      tester.printToConsole('$walletName wallet has legacy seeds properly displayed');
+    }
+  }
+
+  Future<void> backToDashboard() async {
+    tester.printToConsole('Going back to dashboard from credentials page');
+    await commonTestCases.goBack();
+    await commonTestCases.goBack();
+  }
+}
diff --git a/integration_test/robots/wallet_list_page_robot.dart b/integration_test/robots/wallet_list_page_robot.dart
new file mode 100644
index 000000000..b46d4ca95
--- /dev/null
+++ b/integration_test/robots/wallet_list_page_robot.dart
@@ -0,0 +1,27 @@
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import '../components/common_test_cases.dart';
+
+class WalletListPageRobot {
+  WalletListPageRobot(this.tester) : commonTestCases = CommonTestCases(tester);
+
+  final WidgetTester tester;
+  late CommonTestCases commonTestCases;
+
+  Future<void> isWalletListPage() async {
+    await commonTestCases.isSpecificPage<WalletListPageRobot>();
+  }
+
+  void displaysCorrectTitle() {
+    commonTestCases.hasText(S.current.wallets);
+  }
+
+  Future<void> navigateToCreateNewWalletPage() async {
+    commonTestCases.tapItemByKey('wallet_list_page_create_new_wallet_button_key');
+  }
+
+  Future<void> navigateToRestoreWalletOptionsPage() async {
+    commonTestCases.tapItemByKey('wallet_list_page_restore_wallet_button_key');
+  }
+}
diff --git a/integration_test/robots/wallet_seed_page_robot.dart b/integration_test/robots/wallet_seed_page_robot.dart
new file mode 100644
index 000000000..d52f3b1ec
--- /dev/null
+++ b/integration_test/robots/wallet_seed_page_robot.dart
@@ -0,0 +1,57 @@
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import '../components/common_test_cases.dart';
+
+class WalletSeedPageRobot {
+  WalletSeedPageRobot(this.tester) : commonTestCases = CommonTestCases(tester);
+
+  final WidgetTester tester;
+  late CommonTestCases commonTestCases;
+
+  Future<void> isWalletSeedPage() async {
+    await commonTestCases.isSpecificPage<WalletSeedPage>();
+  }
+
+  Future<void> onNextButtonPressed() async {
+    await commonTestCases.tapItemByKey('wallet_seed_page_next_button_key');
+    await commonTestCases.defaultSleepTime();
+  }
+
+  Future<void> onConfirmButtonOnSeedAlertDialogPressed() async {
+    await commonTestCases.tapItemByKey('wallet_seed_page_seed_alert_confirm_button_key');
+    await commonTestCases.defaultSleepTime();
+  }
+
+  Future<void> onBackButtonOnSeedAlertDialogPressed() async {
+    await commonTestCases.tapItemByKey('wallet_seed_page_seed_alert_back_button_key');
+    await commonTestCases.defaultSleepTime();
+  }
+
+  void confirmWalletDetailsDisplayCorrectly() {
+    final walletSeedPage = tester.widget<WalletSeedPage>(find.byType(WalletSeedPage));
+
+    final walletSeedViewModel = walletSeedPage.walletSeedViewModel;
+
+    final walletName = walletSeedViewModel.name;
+    final walletSeeds = walletSeedViewModel.seed;
+
+    commonTestCases.hasText(walletName);
+    commonTestCases.hasText(walletSeeds);
+  }
+
+  void confirmWalletSeedReminderDisplays() {
+    commonTestCases.hasText(S.current.seed_reminder);
+  }
+
+  Future<void> onSaveSeedsButtonPressed() async {
+    await commonTestCases.tapItemByKey('wallet_seed_page_save_seeds_button_key');
+    await commonTestCases.defaultSleepTime();
+  }
+
+  Future<void> onCopySeedsButtonPressed() async {
+    await commonTestCases.tapItemByKey('wallet_seed_page_copy_seeds_button_key');
+    await commonTestCases.defaultSleepTime();
+  }
+}
diff --git a/integration_test/test_suites/confirm_seeds_flow_test.dart b/integration_test/test_suites/confirm_seeds_flow_test.dart
new file mode 100644
index 000000000..bf6fd5a5f
--- /dev/null
+++ b/integration_test/test_suites/confirm_seeds_flow_test.dart
@@ -0,0 +1,107 @@
+import 'package:cake_wallet/wallet_types.g.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:integration_test/integration_test.dart';
+
+import '../components/common_test_constants.dart';
+import '../components/common_test_flows.dart';
+import '../robots/auth_page_robot.dart';
+import '../robots/dashboard_page_robot.dart';
+import '../robots/security_and_backup_page_robot.dart';
+import '../robots/wallet_keys_robot.dart';
+
+void main() {
+  IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+
+  AuthPageRobot authPageRobot;
+  CommonTestFlows commonTestFlows;
+  DashboardPageRobot dashboardPageRobot;
+  WalletKeysAndSeedPageRobot walletKeysAndSeedPageRobot;
+  SecurityAndBackupPageRobot securityAndBackupPageRobot;
+
+  testWidgets(
+    'Confirm if the seeds display properly',
+    (tester) async {
+      authPageRobot = AuthPageRobot(tester);
+      commonTestFlows = CommonTestFlows(tester);
+      dashboardPageRobot = DashboardPageRobot(tester);
+      walletKeysAndSeedPageRobot = WalletKeysAndSeedPageRobot(tester);
+      securityAndBackupPageRobot = SecurityAndBackupPageRobot(tester);
+
+      // Start the app
+      await commonTestFlows.startAppFlow(
+        ValueKey('confirm_creds_display_correctly_flow_app_key'),
+      );
+
+      await commonTestFlows.welcomePageToCreateNewWalletFlow(
+        WalletType.solana,
+        CommonTestConstants.pin,
+      );
+
+      await dashboardPageRobot.confirmWalletTypeIsDisplayedCorrectly(WalletType.solana);
+
+      await _confirmSeedsFlowForWalletType(
+        WalletType.solana,
+        authPageRobot,
+        dashboardPageRobot,
+        securityAndBackupPageRobot,
+        walletKeysAndSeedPageRobot,
+        tester,
+      );
+
+      // Do the same for other available wallet types
+      for (var walletType in availableWalletTypes) {
+        if (walletType == WalletType.solana) {
+          continue;
+        }
+
+        await commonTestFlows.switchToWalletMenuFromDashboardPage();
+
+        await commonTestFlows.createNewWalletFromWalletMenu(walletType);
+
+        await dashboardPageRobot.confirmWalletTypeIsDisplayedCorrectly(walletType);
+
+        await _confirmSeedsFlowForWalletType(
+          walletType,
+          authPageRobot,
+          dashboardPageRobot,
+          securityAndBackupPageRobot,
+          walletKeysAndSeedPageRobot,
+          tester,
+        );
+      }
+
+      await Future.delayed(Duration(seconds: 15));
+    },
+  );
+}
+
+Future<void> _confirmSeedsFlowForWalletType(
+  WalletType walletType,
+  AuthPageRobot authPageRobot,
+  DashboardPageRobot dashboardPageRobot,
+  SecurityAndBackupPageRobot securityAndBackupPageRobot,
+  WalletKeysAndSeedPageRobot walletKeysAndSeedPageRobot,
+  WidgetTester tester,
+) async {
+  await dashboardPageRobot.openDrawerMenu();
+  await dashboardPageRobot.dashboardMenuWidgetRobot.navigateToSecurityAndBackupPage();
+
+  await securityAndBackupPageRobot.navigateToShowKeysPage();
+
+  final onAuthPage = authPageRobot.onAuthPage();
+  if (onAuthPage) {
+    await authPageRobot.enterPinCode(CommonTestConstants.pin);
+  }
+
+  await tester.pumpAndSettle();
+
+  await walletKeysAndSeedPageRobot.isWalletKeysAndSeedPage();
+  walletKeysAndSeedPageRobot.hasTitle();
+  walletKeysAndSeedPageRobot.hasShareWarning();
+
+  walletKeysAndSeedPageRobot.confirmWalletCredentials(walletType);
+
+  await walletKeysAndSeedPageRobot.backToDashboard();
+}
diff --git a/integration_test/test_suites/create_wallet_flow_test.dart b/integration_test/test_suites/create_wallet_flow_test.dart
new file mode 100644
index 000000000..2a50dbbe8
--- /dev/null
+++ b/integration_test/test_suites/create_wallet_flow_test.dart
@@ -0,0 +1,57 @@
+import 'package:cake_wallet/wallet_types.g.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:integration_test/integration_test.dart';
+
+import '../components/common_test_constants.dart';
+import '../components/common_test_flows.dart';
+import '../robots/dashboard_page_robot.dart';
+
+void main() {
+  IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+
+  CommonTestFlows commonTestFlows;
+  DashboardPageRobot dashboardPageRobot;
+
+  testWidgets(
+    'Create Wallet Flow',
+    (tester) async {
+      commonTestFlows = CommonTestFlows(tester);
+      dashboardPageRobot = DashboardPageRobot(tester);
+
+      // Start the app
+      await commonTestFlows.startAppFlow(
+        ValueKey('create_wallets_through_seeds_test_app_key'),
+      );
+
+      await commonTestFlows.welcomePageToCreateNewWalletFlow(
+        WalletType.solana,
+        CommonTestConstants.pin,
+      );
+
+      // Confirm it actually restores a solana wallet
+      await dashboardPageRobot.confirmWalletTypeIsDisplayedCorrectly(WalletType.solana);
+
+      // Do the same for other available wallet types
+      for (var walletType in availableWalletTypes) {
+        if (walletType == WalletType.solana) {
+          continue;
+        }
+
+        await commonTestFlows.switchToWalletMenuFromDashboardPage();
+
+        await commonTestFlows.createNewWalletFromWalletMenu(walletType);
+
+        await dashboardPageRobot.confirmWalletTypeIsDisplayedCorrectly(walletType);
+      }
+
+      // Goes to the wallet menu and provides a confirmation that all the wallets were correctly restored
+      await commonTestFlows.switchToWalletMenuFromDashboardPage();
+
+      commonTestFlows.confirmAllAvailableWalletTypeIconsDisplayCorrectly();
+
+      await Future.delayed(Duration(seconds: 5));
+    },
+  );
+}
diff --git a/integration_test/test_suites/exchange_flow_test.dart b/integration_test/test_suites/exchange_flow_test.dart
index 6c993634c..c36ef9396 100644
--- a/integration_test/test_suites/exchange_flow_test.dart
+++ b/integration_test/test_suites/exchange_flow_test.dart
@@ -9,6 +9,7 @@ import '../robots/dashboard_page_robot.dart';
 import '../robots/exchange_confirm_page_robot.dart';
 import '../robots/exchange_page_robot.dart';
 import '../robots/exchange_trade_page_robot.dart';
+import 'package:cake_wallet/.secrets.g.dart' as secrets;
 
 void main() {
   IntegrationTestWidgetsFlutterBinding.ensureInitialized();
@@ -20,40 +21,42 @@ void main() {
   ExchangeTradePageRobot exchangeTradePageRobot;
   ExchangeConfirmPageRobot exchangeConfirmPageRobot;
 
-  group('Exchange Flow Tests', () {
-    testWidgets('Exchange flow', (tester) async {
-      authPageRobot = AuthPageRobot(tester);
-      commonTestFlows = CommonTestFlows(tester);
-      exchangePageRobot = ExchangePageRobot(tester);
-      dashboardPageRobot = DashboardPageRobot(tester);
-      exchangeTradePageRobot = ExchangeTradePageRobot(tester);
-      exchangeConfirmPageRobot = ExchangeConfirmPageRobot(tester);
+  testWidgets('Exchange flow', (tester) async {
+    authPageRobot = AuthPageRobot(tester);
+    commonTestFlows = CommonTestFlows(tester);
+    exchangePageRobot = ExchangePageRobot(tester);
+    dashboardPageRobot = DashboardPageRobot(tester);
+    exchangeTradePageRobot = ExchangeTradePageRobot(tester);
+    exchangeConfirmPageRobot = ExchangeConfirmPageRobot(tester);
 
-      await commonTestFlows.startAppFlow(ValueKey('exchange_app_test_key'));
-      await commonTestFlows.restoreWalletThroughSeedsFlow();
-      await dashboardPageRobot.navigateToExchangePage();
+    await commonTestFlows.startAppFlow(ValueKey('exchange_app_test_key'));
+    await commonTestFlows.welcomePageToRestoreWalletThroughSeedsFlow(
+      CommonTestConstants.testWalletType,
+      secrets.solanaTestWalletSeeds,
+      CommonTestConstants.pin,
+    );
+    await dashboardPageRobot.navigateToExchangePage();
 
-      // ----------- Exchange Page -------------
-      await exchangePageRobot.selectDepositCurrency(CommonTestConstants.testDepositCurrency);
-      await exchangePageRobot.selectReceiveCurrency(CommonTestConstants.testReceiveCurrency);
+    // ----------- Exchange Page -------------
+    await exchangePageRobot.selectDepositCurrency(CommonTestConstants.testDepositCurrency);
+    await exchangePageRobot.selectReceiveCurrency(CommonTestConstants.testReceiveCurrency);
 
-      await exchangePageRobot.enterDepositAmount(CommonTestConstants.exchangeTestAmount);
-      await exchangePageRobot.enterDepositRefundAddress(
-        depositAddress: CommonTestConstants.testWalletAddress,
-      );
-      await exchangePageRobot.enterReceiveAddress(CommonTestConstants.testWalletAddress);
-      
-      await exchangePageRobot.onExchangeButtonPressed();
+    await exchangePageRobot.enterDepositAmount(CommonTestConstants.exchangeTestAmount);
+    await exchangePageRobot.enterDepositRefundAddress(
+      depositAddress: CommonTestConstants.testWalletAddress,
+    );
+    await exchangePageRobot.enterReceiveAddress(CommonTestConstants.testWalletAddress);
 
-      await exchangePageRobot.handleErrors(CommonTestConstants.exchangeTestAmount);
+    await exchangePageRobot.onExchangeButtonPressed();
 
-      final onAuthPage = authPageRobot.onAuthPage();
-      if (onAuthPage) {
-        await authPageRobot.enterPinCode(CommonTestConstants.pin, false);
-      }
+    await exchangePageRobot.handleErrors(CommonTestConstants.exchangeTestAmount);
 
-      await exchangeConfirmPageRobot.onSavedTradeIdButtonPressed();
-      await exchangeTradePageRobot.onGotItButtonPressed();
-    });
+    final onAuthPage = authPageRobot.onAuthPage();
+    if (onAuthPage) {
+      await authPageRobot.enterPinCode(CommonTestConstants.pin);
+    }
+
+    await exchangeConfirmPageRobot.onSavedTradeIdButtonPressed();
+    await exchangeTradePageRobot.onGotItButtonPressed();
   });
 }
diff --git a/integration_test/test_suites/restore_wallet_through_seeds_flow_test.dart b/integration_test/test_suites/restore_wallet_through_seeds_flow_test.dart
new file mode 100644
index 000000000..a810aa722
--- /dev/null
+++ b/integration_test/test_suites/restore_wallet_through_seeds_flow_test.dart
@@ -0,0 +1,63 @@
+import 'package:cake_wallet/wallet_types.g.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:integration_test/integration_test.dart';
+
+import '../components/common_test_constants.dart';
+import '../components/common_test_flows.dart';
+import '../robots/dashboard_page_robot.dart';
+import 'package:cake_wallet/.secrets.g.dart' as secrets;
+
+void main() {
+  IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+
+  CommonTestFlows commonTestFlows;
+  DashboardPageRobot dashboardPageRobot;
+
+  testWidgets(
+    'Restoring Wallets Through Seeds',
+    (tester) async {
+      commonTestFlows = CommonTestFlows(tester);
+      dashboardPageRobot = DashboardPageRobot(tester);
+
+      // Start the app
+      await commonTestFlows.startAppFlow(
+        ValueKey('restore_wallets_through_seeds_test_app_key'),
+      );
+
+      // Restore the first wallet type: Solana
+      await commonTestFlows.welcomePageToRestoreWalletThroughSeedsFlow(
+        WalletType.solana,
+        secrets.solanaTestWalletSeeds,
+        CommonTestConstants.pin,
+      );
+
+      // Confirm it actually restores a solana wallet
+      await dashboardPageRobot.confirmWalletTypeIsDisplayedCorrectly(WalletType.solana);
+
+      // Do the same for other available wallet types
+      for (var walletType in availableWalletTypes) {
+        if (walletType == WalletType.solana) {
+          continue;
+        }
+
+        await commonTestFlows.switchToWalletMenuFromDashboardPage();
+
+        await commonTestFlows.restoreWalletFromWalletMenu(
+          walletType,
+          commonTestFlows.getWalletSeedsByWalletType(walletType),
+        );
+
+        await dashboardPageRobot.confirmWalletTypeIsDisplayedCorrectly(walletType);
+      }
+
+      // Goes to the wallet menu and provides a visual confirmation that all the wallets were correctly restored
+      await commonTestFlows.switchToWalletMenuFromDashboardPage();
+
+      commonTestFlows.confirmAllAvailableWalletTypeIconsDisplayCorrectly();
+
+      await Future.delayed(Duration(seconds: 5));
+    },
+  );
+}
diff --git a/integration_test/test_suites/send_flow_test.dart b/integration_test/test_suites/send_flow_test.dart
index 38ac1574f..7a46435b8 100644
--- a/integration_test/test_suites/send_flow_test.dart
+++ b/integration_test/test_suites/send_flow_test.dart
@@ -6,6 +6,7 @@ import '../components/common_test_constants.dart';
 import '../components/common_test_flows.dart';
 import '../robots/dashboard_page_robot.dart';
 import '../robots/send_page_robot.dart';
+import 'package:cake_wallet/.secrets.g.dart' as secrets;
 
 void main() {
   IntegrationTestWidgetsFlutterBinding.ensureInitialized();
@@ -14,28 +15,30 @@ void main() {
   CommonTestFlows commonTestFlows;
   DashboardPageRobot dashboardPageRobot;
 
-  group('Send Flow Tests', () {
-    testWidgets('Send flow', (tester) async {
-      commonTestFlows = CommonTestFlows(tester);
-      sendPageRobot = SendPageRobot(tester: tester);
-      dashboardPageRobot = DashboardPageRobot(tester);
+  testWidgets('Send flow', (tester) async {
+    commonTestFlows = CommonTestFlows(tester);
+    sendPageRobot = SendPageRobot(tester: tester);
+    dashboardPageRobot = DashboardPageRobot(tester);
 
-      await commonTestFlows.startAppFlow(ValueKey('send_test_app_key'));
-      await commonTestFlows.restoreWalletThroughSeedsFlow();
-      await dashboardPageRobot.navigateToSendPage();
+    await commonTestFlows.startAppFlow(ValueKey('send_test_app_key'));
+    await commonTestFlows.welcomePageToRestoreWalletThroughSeedsFlow(
+      CommonTestConstants.testWalletType,
+      secrets.solanaTestWalletSeeds,
+      CommonTestConstants.pin,
+    );
+    await dashboardPageRobot.navigateToSendPage();
 
-      await sendPageRobot.enterReceiveAddress(CommonTestConstants.testWalletAddress);
-      await sendPageRobot.selectReceiveCurrency(CommonTestConstants.testReceiveCurrency);
-      await sendPageRobot.enterAmount(CommonTestConstants.sendTestAmount);
-      await sendPageRobot.selectTransactionPriority();
+    await sendPageRobot.enterReceiveAddress(CommonTestConstants.testWalletAddress);
+    await sendPageRobot.selectReceiveCurrency(CommonTestConstants.testReceiveCurrency);
+    await sendPageRobot.enterAmount(CommonTestConstants.sendTestAmount);
+    await sendPageRobot.selectTransactionPriority();
 
-      await sendPageRobot.onSendButtonPressed();
+    await sendPageRobot.onSendButtonPressed();
 
-      await sendPageRobot.handleSendResult();
+    await sendPageRobot.handleSendResult();
 
-      await sendPageRobot.onSendButtonOnConfirmSendingDialogPressed();
+    await sendPageRobot.onSendButtonOnConfirmSendingDialogPressed();
 
-      await sendPageRobot.onSentDialogPopUp();
-    });
+    await sendPageRobot.onSentDialogPopUp();
   });
 }
diff --git a/integration_test/test_suites/transaction_history_flow_test.dart b/integration_test/test_suites/transaction_history_flow_test.dart
new file mode 100644
index 000000000..8af6d39fd
--- /dev/null
+++ b/integration_test/test_suites/transaction_history_flow_test.dart
@@ -0,0 +1,70 @@
+import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:integration_test/integration_test.dart';
+
+import '../components/common_test_constants.dart';
+import '../components/common_test_flows.dart';
+import '../robots/dashboard_page_robot.dart';
+import '../robots/transactions_page_robot.dart';
+import 'package:cake_wallet/.secrets.g.dart' as secrets;
+
+void main() {
+  IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+
+  CommonTestFlows commonTestFlows;
+  DashboardPageRobot dashboardPageRobot;
+  TransactionsPageRobot transactionsPageRobot;
+
+  /// Two Test Scenarios
+  ///  - Fully Synchronizes and display the transaction history either immediately or few seconds after fully synchronizing
+  /// - Displays the transaction history progressively as synchronizing happens
+  testWidgets('Transaction history flow', (tester) async {
+    commonTestFlows = CommonTestFlows(tester);
+    dashboardPageRobot = DashboardPageRobot(tester);
+    transactionsPageRobot = TransactionsPageRobot(tester);
+
+    await commonTestFlows.startAppFlow(
+      ValueKey('confirm_creds_display_correctly_flow_app_key'),
+    );
+
+    /// Test Scenario 1 - Displays transaction history list after fully synchronizing.
+    ///
+    /// For Solana/Tron WalletTypes.
+    await commonTestFlows.welcomePageToRestoreWalletThroughSeedsFlow(
+      WalletType.solana,
+      secrets.solanaTestWalletSeeds,
+      CommonTestConstants.pin,
+    );
+
+    await dashboardPageRobot.confirmWalletTypeIsDisplayedCorrectly(WalletType.solana);
+
+    await dashboardPageRobot.swipeDashboardTab(true);
+
+    await transactionsPageRobot.isTransactionsPage();
+
+    await transactionsPageRobot.confirmTransactionsPageConstantsDisplayProperly();
+
+    await transactionsPageRobot.confirmTransactionHistoryListDisplaysCorrectly(false);
+
+    /// Test Scenario 2 - Displays transaction history list while synchronizing.
+    ///
+    /// For bitcoin/Monero/Wownero WalletTypes.
+    await commonTestFlows.switchToWalletMenuFromDashboardPage();
+
+    await commonTestFlows.restoreWalletFromWalletMenu(
+      WalletType.bitcoin,
+      secrets.bitcoinTestWalletSeeds,
+    );
+
+    await dashboardPageRobot.confirmWalletTypeIsDisplayedCorrectly(WalletType.bitcoin);
+
+    await dashboardPageRobot.swipeDashboardTab(true);
+
+    await transactionsPageRobot.isTransactionsPage();
+
+    await transactionsPageRobot.confirmTransactionsPageConstantsDisplayProperly();
+
+    await transactionsPageRobot.confirmTransactionHistoryListDisplaysCorrectly(true);
+  });
+}
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 322ef6f86..470bdf4e7 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -109,15 +109,15 @@ PODS:
     - FlutterMacOS
   - permission_handler_apple (9.1.1):
     - Flutter
-  - Protobuf (3.27.2)
+  - Protobuf (3.28.2)
   - ReachabilitySwift (5.2.3)
   - reactive_ble_mobile (0.0.1):
     - Flutter
     - Protobuf (~> 3.5)
     - SwiftProtobuf (~> 1.0)
-  - SDWebImage (5.19.4):
-    - SDWebImage/Core (= 5.19.4)
-  - SDWebImage/Core (5.19.4)
+  - SDWebImage (5.19.7):
+    - SDWebImage/Core (= 5.19.7)
+  - SDWebImage/Core (5.19.7)
   - sensitive_clipboard (0.0.1):
     - Flutter
   - share_plus (0.0.1):
@@ -271,10 +271,10 @@ SPEC CHECKSUMS:
   package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
   path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
   permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
-  Protobuf: fb2c13674723f76ff6eede14f78847a776455fa2
+  Protobuf: 28c89b24435762f60244e691544ed80f50d82701
   ReachabilitySwift: 7f151ff156cea1481a8411701195ac6a984f4979
   reactive_ble_mobile: 9ce6723d37ccf701dbffd202d487f23f5de03b4c
-  SDWebImage: 066c47b573f408f18caa467d71deace7c0f8280d
+  SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3
   sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986
   share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
   shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
diff --git a/lib/src/screens/InfoPage.dart b/lib/src/screens/InfoPage.dart
index 5398df22c..84b9e8632 100644
--- a/lib/src/screens/InfoPage.dart
+++ b/lib/src/screens/InfoPage.dart
@@ -21,6 +21,7 @@ abstract class InfoPage extends BasePage {
   String get pageTitle;
   String get pageDescription;
   String get buttonText;
+  Key? get buttonKey;
   void Function(BuildContext) get onPressed;
 
   @override
@@ -39,15 +40,14 @@ abstract class InfoPage extends BasePage {
         alignment: Alignment.center,
         padding: EdgeInsets.all(24),
         child: ConstrainedBox(
-          constraints: BoxConstraints(
-              maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
+          constraints:
+              BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
           child: Column(
             mainAxisAlignment: MainAxisAlignment.spaceBetween,
             children: <Widget>[
               Expanded(
                 child: ConstrainedBox(
-                  constraints: BoxConstraints(
-                      maxHeight: MediaQuery.of(context).size.height * 0.3),
+                  constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.height * 0.3),
                   child: AspectRatio(aspectRatio: 1, child: image),
                 ),
               ),
@@ -61,14 +61,13 @@ abstract class InfoPage extends BasePage {
                       height: 1.7,
                       fontSize: 14,
                       fontWeight: FontWeight.normal,
-                      color: Theme.of(context)
-                          .extension<CakeTextTheme>()!
-                          .secondaryTextColor,
+                      color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
                     ),
                   ),
                 ),
               ),
               PrimaryButton(
+                key: buttonKey,
                 onPressed: () => onPressed(context),
                 text: buttonText,
                 color: Theme.of(context).primaryColor,
diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart
index 953463269..9c012d518 100644
--- a/lib/src/screens/dashboard/dashboard_page.dart
+++ b/lib/src/screens/dashboard/dashboard_page.dart
@@ -140,7 +140,7 @@ class _DashboardPageView extends BasePage {
   bool get resizeToAvoidBottomInset => false;
 
   @override
-  Widget get endDrawer => MenuWidget(dashboardViewModel);
+  Widget get endDrawer => MenuWidget(dashboardViewModel, ValueKey('dashboard_page_drawer_menu_widget_key'));
 
   @override
   Widget leading(BuildContext context) {
diff --git a/lib/src/screens/dashboard/pages/nft_details_page.dart b/lib/src/screens/dashboard/pages/nft_details_page.dart
index 15d2a2b5c..b8352a672 100644
--- a/lib/src/screens/dashboard/pages/nft_details_page.dart
+++ b/lib/src/screens/dashboard/pages/nft_details_page.dart
@@ -28,7 +28,10 @@ class NFTDetailsPage extends BasePage {
   bool get resizeToAvoidBottomInset => false;
 
   @override
-  Widget get endDrawer => MenuWidget(dashboardViewModel);
+  Widget get endDrawer => MenuWidget(
+        dashboardViewModel,
+        ValueKey('nft_details_page_menu_widget_key'),
+      );
 
   @override
   Widget trailing(BuildContext context) {
diff --git a/lib/src/screens/dashboard/pages/transactions_page.dart b/lib/src/screens/dashboard/pages/transactions_page.dart
index b6d1c286b..0db9ac35b 100644
--- a/lib/src/screens/dashboard/pages/transactions_page.dart
+++ b/lib/src/screens/dashboard/pages/transactions_page.dart
@@ -1,11 +1,13 @@
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
 import 'package:cake_wallet/src/screens/dashboard/widgets/anonpay_transaction_row.dart';
 import 'package:cake_wallet/src/screens/dashboard/widgets/order_row.dart';
+import 'package:cake_wallet/src/screens/dashboard/widgets/trade_row.dart';
 import 'package:cake_wallet/themes/extensions/placeholder_theme.dart';
 import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
 import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
 import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
+import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/sync_status.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -14,9 +16,7 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 import 'package:cake_wallet/src/screens/dashboard/widgets/header_row.dart';
 import 'package:cake_wallet/src/screens/dashboard/widgets/date_section_raw.dart';
-import 'package:cake_wallet/src/screens/dashboard/widgets/trade_row.dart';
 import 'package:cake_wallet/src/screens/dashboard/widgets/transaction_raw.dart';
-import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
 import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
 import 'package:cake_wallet/view_model/dashboard/date_section_item.dart';
 import 'package:intl/intl.dart';
@@ -49,6 +49,7 @@ class TransactionsPage extends StatelessWidget {
                 return Padding(
                   padding: const EdgeInsets.fromLTRB(24, 0, 24, 8),
                   child: DashBoardRoundedCardWidget(
+                    key: ValueKey('transactions_page_syncing_alert_card_key'),
                     onTap: () {
                       try {
                         final uri = Uri.parse(
@@ -64,82 +65,93 @@ class TransactionsPage extends StatelessWidget {
                 return Container();
               }
             }),
-            HeaderRow(dashboardViewModel: dashboardViewModel),
-            Expanded(child: Observer(builder: (_) {
-              final items = dashboardViewModel.items;
+            HeaderRow(
+              dashboardViewModel: dashboardViewModel,
+              key: ValueKey('transactions_page_header_row_key'),
+            ),
+            Expanded(
+              child: Observer(
+                builder: (_) {
+                  final items = dashboardViewModel.items;
 
-              return items.isNotEmpty
-                  ? ListView.builder(
-                      itemCount: items.length,
-                      itemBuilder: (context, index) {
-                        final item = items[index];
+                  return items.isNotEmpty
+                      ? ListView.builder(
+                          key: ValueKey('transactions_page_list_view_builder_key'),
+                          itemCount: items.length,
+                          itemBuilder: (context, index) {
+                            final item = items[index];
 
-                        if (item is DateSectionItem) {
-                          return DateSectionRaw(date: item.date);
-                        }
-
-                        if (item is TransactionListItem) {
-                          if (item.hasTokens && item.assetOfTransaction == null) {
-                            return Container();
-                          }
-
-                          final transaction = item.transaction;
-                          final transactionType = dashboardViewModel.getTransactionType(transaction);
-
-                          List<String> tags = [];
-                          if (dashboardViewModel.type == WalletType.bitcoin) {
-                            if (bitcoin!.txIsReceivedSilentPayment(transaction)) {
-                              tags.add(S.of(context).silent_payment);
+                            if (item is DateSectionItem) {
+                              return DateSectionRaw(date: item.date, key: item.key);
                             }
-                          }
-                          if (dashboardViewModel.type == WalletType.litecoin) {
-                            if (bitcoin!.txIsMweb(transaction)) {
-                              tags.add("MWEB");
+
+                            if (item is TransactionListItem) {
+                              if (item.hasTokens && item.assetOfTransaction == null) {
+                                return Container();
+                              }
+
+                              final transaction = item.transaction;
+                              final transactionType =
+                                  dashboardViewModel.getTransactionType(transaction);
+
+                              List<String> tags = [];
+                              if (dashboardViewModel.type == WalletType.bitcoin) {
+                                if (bitcoin!.txIsReceivedSilentPayment(transaction)) {
+                                  tags.add(S.of(context).silent_payment);
+                                }
+                              }
+                              if (dashboardViewModel.type == WalletType.litecoin) {
+                                if (bitcoin!.txIsMweb(transaction)) {
+                                  tags.add("MWEB");
+                                }
+                              }
+
+                              return Observer(
+                                builder: (_) => TransactionRow(
+                                  key: item.key,
+                                  onTap: () => Navigator.of(context)
+                                      .pushNamed(Routes.transactionDetails, arguments: transaction),
+                                  direction: transaction.direction,
+                                  formattedDate: DateFormat('HH:mm').format(transaction.date),
+                                  formattedAmount: item.formattedCryptoAmount,
+                                  formattedFiatAmount:
+                                      dashboardViewModel.balanceViewModel.isFiatDisabled
+                                          ? ''
+                                          : item.formattedFiatAmount,
+                                  isPending: transaction.isPending,
+                                  title:
+                                      item.formattedTitle + item.formattedStatus + transactionType,
+                                  tags: tags,
+                                ),
+                              );
                             }
-                          }
 
-                          return Observer(
-                            builder: (_) => TransactionRow(
-                              onTap: () => Navigator.of(context)
-                                  .pushNamed(Routes.transactionDetails, arguments: transaction),
-                              direction: transaction.direction,
-                              formattedDate: DateFormat('HH:mm').format(transaction.date),
-                              formattedAmount: item.formattedCryptoAmount,
-                              formattedFiatAmount:
-                                  dashboardViewModel.balanceViewModel.isFiatDisabled
-                                      ? ''
-                                      : item.formattedFiatAmount,
-                              isPending: transaction.isPending,
-                              title:
-                                  item.formattedTitle + item.formattedStatus + transactionType,
-                              tags: tags,
-                            ),
-                          );
-                        }
+                            if (item is AnonpayTransactionListItem) {
+                              final transactionInfo = item.transaction;
 
-                        if (item is AnonpayTransactionListItem) {
-                          final transactionInfo = item.transaction;
+                              return AnonpayTransactionRow(
+                                key: item.key,
+                                onTap: () => Navigator.of(context).pushNamed(
+                                    Routes.anonPayDetailsPage,
+                                    arguments: transactionInfo),
+                                currency: transactionInfo.fiatAmount != null
+                                    ? transactionInfo.fiatEquiv ?? ''
+                                    : CryptoCurrency.fromFullName(transactionInfo.coinTo)
+                                        .name
+                                        .toUpperCase(),
+                                provider: transactionInfo.provider,
+                                amount: transactionInfo.fiatAmount?.toString() ??
+                                    (transactionInfo.amountTo?.toString() ?? ''),
+                                createdAt: DateFormat('HH:mm').format(transactionInfo.createdAt),
+                              );
+                            }
 
-                          return AnonpayTransactionRow(
-                            onTap: () => Navigator.of(context)
-                                .pushNamed(Routes.anonPayDetailsPage, arguments: transactionInfo),
-                            currency: transactionInfo.fiatAmount != null
-                                ? transactionInfo.fiatEquiv ?? ''
-                                : CryptoCurrency.fromFullName(transactionInfo.coinTo)
-                                    .name
-                                    .toUpperCase(),
-                            provider: transactionInfo.provider,
-                            amount: transactionInfo.fiatAmount?.toString() ??
-                                (transactionInfo.amountTo?.toString() ?? ''),
-                            createdAt: DateFormat('HH:mm').format(transactionInfo.createdAt),
-                          );
-                        }
+                            if (item is TradeListItem) {
+                              final trade = item.trade;
 
-                        if (item is TradeListItem) {
-                          final trade = item.trade;
-
-                          return Observer(
-                              builder: (_) => TradeRow(
+                              return Observer(
+                                builder: (_) => TradeRow(
+                                  key: item.key,
                                   onTap: () => Navigator.of(context)
                                       .pushNamed(Routes.tradeDetails, arguments: trade),
                                   provider: trade.provider,
@@ -148,36 +160,44 @@ class TransactionsPage extends StatelessWidget {
                                   createdAtFormattedDate: trade.createdAt != null
                                       ? DateFormat('HH:mm').format(trade.createdAt!)
                                       : null,
-                                  formattedAmount: item.tradeFormattedAmount));
-                        }
+                                  formattedAmount: item.tradeFormattedAmount,
+                                ),
+                              );
+                            }
 
-                        if (item is OrderListItem) {
-                          final order = item.order;
+                            if (item is OrderListItem) {
+                              final order = item.order;
 
-                          return Observer(
-                              builder: (_) => OrderRow(
-                                    onTap: () => Navigator.of(context)
-                                        .pushNamed(Routes.orderDetails, arguments: order),
-                                    provider: order.provider,
-                                    from: order.from!,
-                                    to: order.to!,
-                                    createdAtFormattedDate:
-                                        DateFormat('HH:mm').format(order.createdAt),
-                                    formattedAmount: item.orderFormattedAmount,
-                                  ));
-                        }
+                              return Observer(
+                                builder: (_) => OrderRow(
+                                  key: item.key,
+                                  onTap: () => Navigator.of(context)
+                                      .pushNamed(Routes.orderDetails, arguments: order),
+                                  provider: order.provider,
+                                  from: order.from!,
+                                  to: order.to!,
+                                  createdAtFormattedDate:
+                                      DateFormat('HH:mm').format(order.createdAt),
+                                  formattedAmount: item.orderFormattedAmount,
+                                ),
+                              );
+                            }
 
-                        return Container(color: Colors.transparent, height: 1);
-                      })
-                  : Center(
-                      child: Text(
-                        S.of(context).placeholder_transactions,
-                        style: TextStyle(
-                            fontSize: 14,
-                            color: Theme.of(context).extension<PlaceholderTheme>()!.color),
-                      ),
-                    );
-            }))
+                            return Container(color: Colors.transparent, height: 1);
+                          })
+                      : Center(
+                          child: Text(
+                            key: ValueKey('transactions_page_placeholder_transactions_text_key'),
+                            S.of(context).placeholder_transactions,
+                            style: TextStyle(
+                              fontSize: 14,
+                              color: Theme.of(context).extension<PlaceholderTheme>()!.color,
+                            ),
+                          ),
+                        );
+                },
+              ),
+            )
           ],
         ),
       ),
diff --git a/lib/src/screens/dashboard/widgets/anonpay_transaction_row.dart b/lib/src/screens/dashboard/widgets/anonpay_transaction_row.dart
index cb8bef0b7..64d4bfe85 100644
--- a/lib/src/screens/dashboard/widgets/anonpay_transaction_row.dart
+++ b/lib/src/screens/dashboard/widgets/anonpay_transaction_row.dart
@@ -9,6 +9,7 @@ class AnonpayTransactionRow extends StatelessWidget {
     required this.currency,
     required this.onTap,
     required this.amount,
+    super.key,
   });
 
   final VoidCallback? onTap;
diff --git a/lib/src/screens/dashboard/widgets/date_section_raw.dart b/lib/src/screens/dashboard/widgets/date_section_raw.dart
index 73f9f03a1..02fcef7f4 100644
--- a/lib/src/screens/dashboard/widgets/date_section_raw.dart
+++ b/lib/src/screens/dashboard/widgets/date_section_raw.dart
@@ -1,42 +1,27 @@
 import 'package:flutter/material.dart';
 import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
-import 'package:intl/intl.dart';
-import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/utils/date_formatter.dart';
 
 class DateSectionRaw extends StatelessWidget {
-  DateSectionRaw({required this.date});
+  DateSectionRaw({required this.date, super.key});
 
   final DateTime date;
 
   @override
   Widget build(BuildContext context) {
-    final nowDate = DateTime.now();
-    final diffDays = date.difference(nowDate).inDays;
-    final isToday = nowDate.day == date.day &&
-        nowDate.month == date.month &&
-        nowDate.year == date.year;
-    final dateSectionDateFormat = DateFormatter.withCurrentLocal(hasTime: false);
-    var title = "";
-
-    if (isToday) {
-      title = S.of(context).today;
-    } else if (diffDays == 0) {
-      title = S.of(context).yesterday;
-    } else if (diffDays > -7 && diffDays < 0) {
-      final dateFormat = DateFormat.EEEE();
-      title = dateFormat.format(date);
-    } else {
-      title = dateSectionDateFormat.format(date);
-    }
+    final title = DateFormatter.convertDateTimeToReadableString(date);
 
     return Container(
-        height: 35,
-        alignment: Alignment.center,
-        color: Colors.transparent,
-        child: Text(title,
-            style: TextStyle(
-                fontSize: 12,
-                color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor)));
+      height: 35,
+      alignment: Alignment.center,
+      color: Colors.transparent,
+      child: Text(
+        title,
+        style: TextStyle(
+          fontSize: 12,
+          color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor,
+        ),
+      ),
+    );
   }
 }
diff --git a/lib/src/screens/dashboard/widgets/header_row.dart b/lib/src/screens/dashboard/widgets/header_row.dart
index cb4f67fc2..f1f3f0889 100644
--- a/lib/src/screens/dashboard/widgets/header_row.dart
+++ b/lib/src/screens/dashboard/widgets/header_row.dart
@@ -7,7 +7,7 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
 import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
 
 class HeaderRow extends StatelessWidget {
-  HeaderRow({required this.dashboardViewModel});
+  HeaderRow({required this.dashboardViewModel, super.key});
 
   final DashboardViewModel dashboardViewModel;
 
@@ -34,6 +34,7 @@ class HeaderRow extends StatelessWidget {
           Semantics(
             container: true,
             child: GestureDetector(
+              key: ValueKey('transactions_page_header_row_transaction_filter_button_key'),
               onTap: () {
                 showPopUp<void>(
                   context: context,
diff --git a/lib/src/screens/dashboard/widgets/menu_widget.dart b/lib/src/screens/dashboard/widgets/menu_widget.dart
index 6d8379b29..f0e330f04 100644
--- a/lib/src/screens/dashboard/widgets/menu_widget.dart
+++ b/lib/src/screens/dashboard/widgets/menu_widget.dart
@@ -9,7 +9,7 @@ import 'package:cw_core/wallet_type.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 
 class MenuWidget extends StatefulWidget {
-  MenuWidget(this.dashboardViewModel);
+  MenuWidget(this.dashboardViewModel, Key? key);
 
   final DashboardViewModel dashboardViewModel;
 
@@ -193,6 +193,7 @@ class MenuWidgetState extends State<MenuWidget> {
                   final isLastTile = index == itemCount - 1;
 
                   return SettingActionButton(
+                    key: item.key,
                     isLastTile: isLastTile,
                     tileHeight: tileHeight,
                     selectionActive: false,
diff --git a/lib/src/screens/dashboard/widgets/order_row.dart b/lib/src/screens/dashboard/widgets/order_row.dart
index 8adc6e0d5..221ea5689 100644
--- a/lib/src/screens/dashboard/widgets/order_row.dart
+++ b/lib/src/screens/dashboard/widgets/order_row.dart
@@ -12,7 +12,10 @@ class OrderRow extends StatelessWidget {
     required this.to,
     required this.createdAtFormattedDate,
     this.onTap,
-    this.formattedAmount});
+    this.formattedAmount,
+    super.key,
+  });
+  
   final VoidCallback? onTap;
   final BuyProviderDescription provider;
   final String from;
@@ -22,8 +25,7 @@ class OrderRow extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    final iconColor =
-        Theme.of(context).extension<OrderTheme>()!.iconColor;
+    final iconColor = Theme.of(context).extension<OrderTheme>()!.iconColor;
 
     final providerIcon = getBuyProviderIcon(provider, iconColor: iconColor);
 
@@ -36,46 +38,42 @@ class OrderRow extends StatelessWidget {
             mainAxisSize: MainAxisSize.max,
             crossAxisAlignment: CrossAxisAlignment.center,
             children: [
-              if (providerIcon != null) Padding(
-                padding: EdgeInsets.only(right: 12),
-                child: providerIcon,
-              ),
+              if (providerIcon != null)
+                Padding(
+                  padding: EdgeInsets.only(right: 12),
+                  child: providerIcon,
+                ),
               Expanded(
                   child: Column(
-                    mainAxisSize: MainAxisSize.min,
-                    children: [
-                      Row(
-                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                          children: <Widget>[
-                            Text('$from → $to',
-                                style: TextStyle(
-                                    fontSize: 16,
-                                    fontWeight: FontWeight.w500,
-                                    color: Theme.of(context).extension<DashboardPageTheme>()!.textColor
-                                )),
-                            formattedAmount != null
-                                ? Text(formattedAmount! + ' ' + to,
-                                style: TextStyle(
-                                    fontSize: 16,
-                                    fontWeight: FontWeight.w500,
-                                    color: Theme.of(context).extension<DashboardPageTheme>()!.textColor
-                                ))
-                                : Container()
-                          ]),
-                      SizedBox(height: 5),
-                      Row(
-                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                          children: <Widget>[
-                            Text(createdAtFormattedDate,
-                                style: TextStyle(
-                                    fontSize: 14,
-                                    color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor))
-                          ])
-                    ],
-                  )
-              )
+                mainAxisSize: MainAxisSize.min,
+                children: [
+                  Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[
+                    Text('$from → $to',
+                        style: TextStyle(
+                            fontSize: 16,
+                            fontWeight: FontWeight.w500,
+                            color: Theme.of(context).extension<DashboardPageTheme>()!.textColor)),
+                    formattedAmount != null
+                        ? Text(formattedAmount! + ' ' + to,
+                            style: TextStyle(
+                                fontSize: 16,
+                                fontWeight: FontWeight.w500,
+                                color:
+                                    Theme.of(context).extension<DashboardPageTheme>()!.textColor))
+                        : Container()
+                  ]),
+                  SizedBox(height: 5),
+                  Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[
+                    Text(createdAtFormattedDate,
+                        style: TextStyle(
+                            fontSize: 14,
+                            color:
+                                Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor))
+                  ])
+                ],
+              ))
             ],
           ),
         ));
   }
-}
\ No newline at end of file
+}
diff --git a/lib/src/screens/dashboard/widgets/trade_row.dart b/lib/src/screens/dashboard/widgets/trade_row.dart
index 7c809aa9d..84a5d2beb 100644
--- a/lib/src/screens/dashboard/widgets/trade_row.dart
+++ b/lib/src/screens/dashboard/widgets/trade_row.dart
@@ -13,6 +13,7 @@ class TradeRow extends StatelessWidget {
     required this.createdAtFormattedDate,
     this.onTap,
     this.formattedAmount,
+    super.key,
   });
 
   final VoidCallback? onTap;
diff --git a/lib/src/screens/dashboard/widgets/transaction_raw.dart b/lib/src/screens/dashboard/widgets/transaction_raw.dart
index b18131f3d..2d7cbb809 100644
--- a/lib/src/screens/dashboard/widgets/transaction_raw.dart
+++ b/lib/src/screens/dashboard/widgets/transaction_raw.dart
@@ -14,6 +14,7 @@ class TransactionRow extends StatelessWidget {
     required this.tags,
     required this.title,
     required this.onTap,
+    super.key,
   });
 
   final VoidCallback onTap;
@@ -28,33 +29,36 @@ class TransactionRow extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return InkWell(
-        onTap: onTap,
-        child: Container(
-          padding: EdgeInsets.fromLTRB(24, 8, 24, 8),
-          color: Colors.transparent,
-          child: Row(
-            mainAxisSize: MainAxisSize.max,
-            crossAxisAlignment: CrossAxisAlignment.center,
-            children: [
-              Container(
-                height: 36,
-                width: 36,
-                decoration: BoxDecoration(
-                    shape: BoxShape.circle,
-                    color: Theme.of(context).extension<TransactionTradeTheme>()!.rowsColor),
-                child: Image.asset(direction == TransactionDirection.incoming
-                    ? 'assets/images/down_arrow.png'
-                    : 'assets/images/up_arrow.png'),
-              ),
-              SizedBox(width: 12),
-              Expanded(
-                  child: Column(
+      onTap: onTap,
+      child: Container(
+        padding: EdgeInsets.fromLTRB(24, 8, 24, 8),
+        color: Colors.transparent,
+        child: Row(
+          mainAxisSize: MainAxisSize.max,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: [
+            Container(
+              height: 36,
+              width: 36,
+              decoration: BoxDecoration(
+                  shape: BoxShape.circle,
+                  color: Theme.of(context).extension<TransactionTradeTheme>()!.rowsColor),
+              child: Image.asset(direction == TransactionDirection.incoming
+                  ? 'assets/images/down_arrow.png'
+                  : 'assets/images/up_arrow.png'),
+            ),
+            SizedBox(width: 12),
+            Expanded(
+              child: Column(
                 mainAxisSize: MainAxisSize.min,
                 children: [
-                  Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[
-                    Row(
-                      children: [
-                        Text(title,
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: <Widget>[
+                      Row(
+                        children: [
+                          Text(
+                            title,
                             style: TextStyle(
                               fontSize: 16,
                               fontWeight: FontWeight.w500,
@@ -65,28 +69,39 @@ class TransactionRow extends StatelessWidget {
                     ),
                     Text(formattedAmount,
                         style: TextStyle(
-                            fontSize: 16,
-                            fontWeight: FontWeight.w500,
-                            color: Theme.of(context).extension<DashboardPageTheme>()!.textColor))
-                  ]),
+                          fontSize: 16,
+                          fontWeight: FontWeight.w500,
+                          color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
+                        ),
+                      )
+                    ],
+                  ),
                   SizedBox(height: 5),
-                  Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[
-                    Text(formattedDate,
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: <Widget>[
+                      Text(formattedDate,
+                          style: TextStyle(
+                              fontSize: 14,
+                              color: Theme.of(context)
+                                  .extension<CakeTextTheme>()!
+                                  .dateSectionRowColor)),
+                      Text(
+                        formattedFiatAmount,
                         style: TextStyle(
-                            fontSize: 14,
-                            color:
-                                Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor)),
-                    Text(formattedFiatAmount,
-                        style: TextStyle(
-                            fontSize: 14,
-                            color:
-                                Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor))
-                  ])
+                          fontSize: 14,
+                          color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor,
+                        ),
+                      )
+                    ],
+                  ),
                 ],
-              ))
-            ],
-          ),
-        ));
+              ),
+            )
+          ],
+        ),
+      ),
+    );
   }
 }
 
diff --git a/lib/src/screens/new_wallet/new_wallet_page.dart b/lib/src/screens/new_wallet/new_wallet_page.dart
index 929e3027a..387904df0 100644
--- a/lib/src/screens/new_wallet/new_wallet_page.dart
+++ b/lib/src/screens/new_wallet/new_wallet_page.dart
@@ -112,10 +112,13 @@ class _WalletNameFormState extends State<WalletNameForm> {
                 context: context,
                 builder: (_) {
                   return AlertWithOneAction(
-                      alertTitle: S.current.new_wallet,
-                      alertContent: state.error,
-                      buttonText: S.of(context).ok,
-                      buttonAction: () => Navigator.of(context).pop());
+                    key: ValueKey('new_wallet_page_failure_dialog_key'),
+                    buttonKey: ValueKey('new_wallet_page_failure_dialog_button_key'),
+                    alertTitle: S.current.new_wallet,
+                    alertContent: state.error,
+                    buttonText: S.of(context).ok,
+                    buttonAction: () => Navigator.of(context).pop(),
+                  );
                 });
           }
         });
@@ -152,6 +155,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
                       child: Column(
                         children: [
                           TextFormField(
+                            key: ValueKey('new_wallet_page_wallet_name_textformfield_key'),
                             onChanged: (value) => _walletNewVM.name = value,
                             controller: _nameController,
                             textAlign: TextAlign.center,
@@ -182,6 +186,8 @@ class _WalletNameFormState extends State<WalletNameForm> {
                               suffixIcon: Semantics(
                                 label: S.of(context).generate_name,
                                 child: IconButton(
+                                  key: ValueKey(
+                                      'new_wallet_page_wallet_name_textformfield_generate_name_button_key'),
                                   onPressed: () async {
                                     final rName = await generateName();
                                     FocusManager.instance.primaryFocus?.unfocus();
@@ -297,6 +303,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
                         builder: (BuildContext build) => Padding(
                           padding: EdgeInsets.only(top: 24),
                           child: SelectButton(
+                            key: ValueKey('new_wallet_page_monero_seed_type_button_key'),
                             text: widget._seedSettingsViewModel.moneroSeedType.title,
                             onTap: () async {
                               await showPopUp<void>(
@@ -318,6 +325,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
                         padding: EdgeInsets.only(top: 10),
                         child: SeedLanguageSelector(
                           key: _languageSelectorKey,
+                          buttonKey: ValueKey('new_wallet_page_seed_language_selector_button_key'),
                           initialSelected: defaultSeedLanguage,
                           seedType: _walletNewVM.hasSeedType
                               ? widget._seedSettingsViewModel.moneroSeedType
@@ -336,6 +344,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
               Observer(
                 builder: (context) {
                   return LoadingPrimaryButton(
+                    key: ValueKey('new_wallet_page_confirm_button_key'),
                     onPressed: _confirmForm,
                     text: S.of(context).seed_language_next,
                     color: Colors.green,
@@ -347,6 +356,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
               ),
               const SizedBox(height: 25),
               GestureDetector(
+                key: ValueKey('new_wallet_page_advanced_settings_button_key'),
                 onTap: () {
                   Navigator.of(context).pushNamed(Routes.advancedPrivacySettings, arguments: {
                     "type": _walletNewVM.type,
diff --git a/lib/src/screens/new_wallet/wallet_group_description_page.dart b/lib/src/screens/new_wallet/wallet_group_description_page.dart
index d0936b640..e892e0d49 100644
--- a/lib/src/screens/new_wallet/wallet_group_description_page.dart
+++ b/lib/src/screens/new_wallet/wallet_group_description_page.dart
@@ -66,6 +66,7 @@ class WalletGroupDescriptionPage extends BasePage {
             ),
           ),
           PrimaryButton(
+            key: ValueKey('wallet_group_description_page_create_new_seed_button_key'),
             onPressed: () => Navigator.of(context).pushNamed(
               Routes.newWallet,
               arguments: NewWalletArguments(type: selectedWalletType),
@@ -76,6 +77,7 @@ class WalletGroupDescriptionPage extends BasePage {
           ),
           SizedBox(height: 12),
           PrimaryButton(
+            key: ValueKey('wallet_group_description_page_choose_wallet_group_button_key'),
             onPressed: () => Navigator.of(context).pushNamed(
               Routes.walletGroupsDisplayPage,
               arguments: selectedWalletType,
diff --git a/lib/src/screens/restore/restore_options_page.dart b/lib/src/screens/restore/restore_options_page.dart
index 57f5ec727..299846a72 100644
--- a/lib/src/screens/restore/restore_options_page.dart
+++ b/lib/src/screens/restore/restore_options_page.dart
@@ -56,7 +56,8 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
     }
 
     if (isMoneroOnly) {
-      return DeviceConnectionType.supportedConnectionTypes(WalletType.monero, Platform.isIOS).isNotEmpty;
+      return DeviceConnectionType.supportedConnectionTypes(WalletType.monero, Platform.isIOS)
+          .isNotEmpty;
     }
 
     return true;
@@ -80,13 +81,12 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
             child: Column(
               children: <Widget>[
                 OptionTile(
-                  key: ValueKey('restore_options_from_seeds_button_key'),
-                  onPressed: () =>
-                      Navigator.pushNamed(
-                        context,
-                        Routes.restoreWalletFromSeedKeys,
-                        arguments: widget.isNewInstall,
-                      ),
+                  key: ValueKey('restore_options_from_seeds_or_keys_button_key'),
+                  onPressed: () => Navigator.pushNamed(
+                    context,
+                    Routes.restoreWalletFromSeedKeys,
+                    arguments: widget.isNewInstall,
+                  ),
                   image: imageSeedKeys,
                   title: S.of(context).restore_title_from_seed_keys,
                   description: S.of(context).restore_description_from_seed_keys,
@@ -107,7 +107,8 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
                     padding: EdgeInsets.only(top: 24),
                     child: OptionTile(
                       key: ValueKey('restore_options_from_hardware_wallet_button_key'),
-                      onPressed: () => Navigator.pushNamed(context, Routes.restoreWalletFromHardwareWallet,
+                      onPressed: () => Navigator.pushNamed(
+                          context, Routes.restoreWalletFromHardwareWallet,
                           arguments: widget.isNewInstall),
                       image: imageLedger,
                       title: S.of(context).restore_title_from_hardware_wallet,
@@ -120,9 +121,9 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
                       key: ValueKey('restore_options_from_qr_button_key'),
                       onPressed: () => _onScanQRCode(context),
                       icon: Icon(
-                          Icons.qr_code_rounded,
-                          color: imageColor,
-                          size: 50,
+                        Icons.qr_code_rounded,
+                        color: imageColor,
+                        size: 50,
                       ),
                       title: S.of(context).scan_qr_code,
                       description: S.of(context).cold_or_recover_wallet),
@@ -149,20 +150,20 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
                 buttonAction: () => Navigator.of(context).pop());
           });
     });
-
   }
 
   Future<void> _onScanQRCode(BuildContext context) async {
-    final isCameraPermissionGranted = await PermissionHandler.checkPermission(Permission.camera, context);
+    final isCameraPermissionGranted =
+        await PermissionHandler.checkPermission(Permission.camera, context);
 
     if (!isCameraPermissionGranted) return;
     bool isPinSet = false;
     if (widget.isNewInstall) {
       await Navigator.pushNamed(context, Routes.setupPin,
           arguments: (PinCodeState<PinCodeWidget> setupPinContext, String _) {
-            setupPinContext.close();
-            isPinSet = true;
-          });
+        setupPinContext.close();
+        isPinSet = true;
+      });
     }
     if (!widget.isNewInstall || isPinSet) {
       try {
@@ -174,7 +175,8 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
         });
         final restoreWallet = await WalletRestoreFromQRCode.scanQRCodeForRestoring(context);
 
-        final restoreFromQRViewModel = getIt.get<WalletRestorationFromQRVM>(param1: restoreWallet.type);
+        final restoreFromQRViewModel =
+            getIt.get<WalletRestorationFromQRVM>(param1: restoreWallet.type);
 
         await restoreFromQRViewModel.create(restoreWallet: restoreWallet);
         if (restoreFromQRViewModel.state is FailureState) {
diff --git a/lib/src/screens/restore/wallet_restore_from_seed_form.dart b/lib/src/screens/restore/wallet_restore_from_seed_form.dart
index c8a75cf40..1684f6f92 100644
--- a/lib/src/screens/restore/wallet_restore_from_seed_form.dart
+++ b/lib/src/screens/restore/wallet_restore_from_seed_form.dart
@@ -191,6 +191,7 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
           ),
           if (widget.type == WalletType.monero || widget.type == WalletType.wownero)
             GestureDetector(
+              key: ValueKey('wallet_restore_from_seed_seedtype_picker_button_key'),
               onTap: () async {
                 await showPopUp<void>(
                     context: context,
@@ -264,6 +265,7 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
             BlockchainHeightWidget(
               focusNode: widget.blockHeightFocusNode,
               key: blockchainHeightKey,
+              blockHeightTextFieldKey: ValueKey('wallet_restore_from_seed_blockheight_textfield_key'),
               onHeightOrDateEntered: widget.onHeightOrDateEntered,
               hasDatePicker: widget.type == WalletType.monero || widget.type == WalletType.wownero,
               walletType: widget.type,
diff --git a/lib/src/screens/seed/pre_seed_page.dart b/lib/src/screens/seed/pre_seed_page.dart
index 730dfa5f8..23de4564f 100644
--- a/lib/src/screens/seed/pre_seed_page.dart
+++ b/lib/src/screens/seed/pre_seed_page.dart
@@ -15,13 +15,15 @@ class PreSeedPage extends InfoPage {
   String get pageTitle => S.current.pre_seed_title;
 
   @override
-  String get pageDescription =>
-      S.current.pre_seed_description(seedPhraseLength.toString());
+  String get pageDescription => S.current.pre_seed_description(seedPhraseLength.toString());
 
   @override
   String get buttonText => S.current.pre_seed_button_text;
 
   @override
-  void Function(BuildContext) get onPressed => (BuildContext context) =>
-      Navigator.of(context).popAndPushNamed(Routes.seed, arguments: true);
+  Key? get buttonKey => ValueKey('pre_seed_page_button_key');
+
+  @override
+  void Function(BuildContext) get onPressed =>
+      (BuildContext context) => Navigator.of(context).popAndPushNamed(Routes.seed, arguments: true);
 }
diff --git a/lib/src/screens/seed/wallet_seed_page.dart b/lib/src/screens/seed/wallet_seed_page.dart
index 200b87b7d..10160839c 100644
--- a/lib/src/screens/seed/wallet_seed_page.dart
+++ b/lib/src/screens/seed/wallet_seed_page.dart
@@ -33,16 +33,22 @@ class WalletSeedPage extends BasePage {
   void onClose(BuildContext context) async {
     if (isNewWalletCreated) {
       final confirmed = await showPopUp<bool>(
-              context: context,
-              builder: (BuildContext context) {
-                return AlertWithTwoActions(
-                    alertTitle: S.of(context).seed_alert_title,
-                    alertContent: S.of(context).seed_alert_content,
-                    leftButtonText: S.of(context).seed_alert_back,
-                    rightButtonText: S.of(context).seed_alert_yes,
-                    actionLeftButton: () => Navigator.of(context).pop(false),
-                    actionRightButton: () => Navigator.of(context).pop(true));
-              }) ??
+            context: context,
+            builder: (BuildContext context) {
+              return AlertWithTwoActions(
+                alertDialogKey: ValueKey('wallet_seed_page_seed_alert_dialog_key'),
+                alertRightActionButtonKey:
+                    ValueKey('wallet_seed_page_seed_alert_confirm_button_key'),
+                alertLeftActionButtonKey: ValueKey('wallet_seed_page_seed_alert_back_button_key'),
+                alertTitle: S.of(context).seed_alert_title,
+                alertContent: S.of(context).seed_alert_content,
+                leftButtonText: S.of(context).seed_alert_back,
+                rightButtonText: S.of(context).seed_alert_yes,
+                actionLeftButton: () => Navigator.of(context).pop(false),
+                actionRightButton: () => Navigator.of(context).pop(true),
+              );
+            },
+          ) ??
           false;
 
       if (confirmed) {
@@ -62,6 +68,7 @@ class WalletSeedPage extends BasePage {
   Widget trailing(BuildContext context) {
     return isNewWalletCreated
         ? GestureDetector(
+            key: ValueKey('wallet_seed_page_next_button_key'),
             onTap: () => onClose(context),
             child: Container(
               width: 100,
@@ -74,9 +81,9 @@ class WalletSeedPage extends BasePage {
               child: Text(
                 S.of(context).seed_language_next,
                 style: TextStyle(
-                    fontSize: 14, fontWeight: FontWeight.w600, color: Theme.of(context)
-                        .extension<CakeTextTheme>()!
-                        .buttonTextColor),
+                    fontSize: 14,
+                    fontWeight: FontWeight.w600,
+                    color: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor),
               ),
             ),
           )
@@ -93,7 +100,8 @@ class WalletSeedPage extends BasePage {
           padding: EdgeInsets.all(24),
           alignment: Alignment.center,
           child: ConstrainedBox(
-            constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
+            constraints:
+                BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
             child: Column(
               mainAxisAlignment: MainAxisAlignment.spaceBetween,
               children: <Widget>[
@@ -106,6 +114,7 @@ class WalletSeedPage extends BasePage {
                     crossAxisAlignment: CrossAxisAlignment.center,
                     children: <Widget>[
                       Text(
+                        key: ValueKey('wallet_seed_page_wallet_name_text_key'),
                         walletSeedViewModel.name,
                         style: TextStyle(
                             fontSize: 20,
@@ -115,12 +124,14 @@ class WalletSeedPage extends BasePage {
                       Padding(
                         padding: EdgeInsets.only(top: 20, left: 16, right: 16),
                         child: Text(
+                          key: ValueKey('wallet_seed_page_wallet_seed_text_key'),
                           walletSeedViewModel.seed,
                           textAlign: TextAlign.center,
                           style: TextStyle(
                               fontSize: 14,
                               fontWeight: FontWeight.normal,
-                              color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor),
+                              color:
+                                  Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor),
                         ),
                       )
                     ],
@@ -132,12 +143,18 @@ class WalletSeedPage extends BasePage {
                         ? Padding(
                             padding: EdgeInsets.only(bottom: 43, left: 43, right: 43),
                             child: Text(
+                              key: ValueKey(
+                                'wallet_seed_page_wallet_seed_reminder_text_key',
+                              ),
                               S.of(context).seed_reminder,
                               textAlign: TextAlign.center,
                               style: TextStyle(
-                                  fontSize: 12,
-                                  fontWeight: FontWeight.normal,
-                                  color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor),
+                                fontSize: 12,
+                                fontWeight: FontWeight.normal,
+                                color: Theme.of(context)
+                                    .extension<TransactionTradeTheme>()!
+                                    .detailsTitlesColor,
+                              ),
                             ),
                           )
                         : Offstage(),
@@ -145,9 +162,10 @@ class WalletSeedPage extends BasePage {
                       mainAxisSize: MainAxisSize.max,
                       children: <Widget>[
                         Flexible(
-                            child: Container(
-                          padding: EdgeInsets.only(right: 8.0),
-                          child: PrimaryButton(
+                          child: Container(
+                            padding: EdgeInsets.only(right: 8.0),
+                            child: PrimaryButton(
+                              key: ValueKey('wallet_seed_page_save_seeds_button_key'),
                               onPressed: () {
                                 ShareUtil.share(
                                   text: walletSeedViewModel.seed,
@@ -156,22 +174,29 @@ class WalletSeedPage extends BasePage {
                               },
                               text: S.of(context).save,
                               color: Colors.green,
-                              textColor: Colors.white),
-                        )),
+                              textColor: Colors.white,
+                            ),
+                          ),
+                        ),
                         Flexible(
-                            child: Container(
-                          padding: EdgeInsets.only(left: 8.0),
-                          child: Builder(
+                          child: Container(
+                            padding: EdgeInsets.only(left: 8.0),
+                            child: Builder(
                               builder: (context) => PrimaryButton(
-                                  onPressed: () {
-                                    ClipboardUtil.setSensitiveDataToClipboard(
-                                        ClipboardData(text: walletSeedViewModel.seed));
-                                    showBar<void>(context, S.of(context).copied_to_clipboard);
-                                  },
-                                  text: S.of(context).copy,
-                                  color: Theme.of(context).extension<PinCodeTheme>()!.indicatorsColor,
-                                  textColor: Colors.white)),
-                        ))
+                                key: ValueKey('wallet_seed_page_copy_seeds_button_key'),
+                                onPressed: () {
+                                  ClipboardUtil.setSensitiveDataToClipboard(
+                                    ClipboardData(text: walletSeedViewModel.seed),
+                                  );
+                                  showBar<void>(context, S.of(context).copied_to_clipboard);
+                                },
+                                text: S.of(context).copy,
+                                color: Theme.of(context).extension<PinCodeTheme>()!.indicatorsColor,
+                                textColor: Colors.white,
+                              ),
+                            ),
+                          ),
+                        )
                       ],
                     )
                   ],
diff --git a/lib/src/screens/settings/security_backup_page.dart b/lib/src/screens/settings/security_backup_page.dart
index 04ae53d77..bb1c00ff5 100644
--- a/lib/src/screens/settings/security_backup_page.dart
+++ b/lib/src/screens/settings/security_backup_page.dart
@@ -16,7 +16,8 @@ import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 
 class SecurityBackupPage extends BasePage {
-  SecurityBackupPage(this._securitySettingsViewModel, this._authService, [this._isHardwareWallet = false]);
+  SecurityBackupPage(this._securitySettingsViewModel, this._authService,
+      [this._isHardwareWallet = false]);
 
   final AuthService _authService;
 
@@ -30,10 +31,13 @@ class SecurityBackupPage extends BasePage {
   @override
   Widget body(BuildContext context) {
     return Container(
-        padding: EdgeInsets.only(top: 10),
-        child: Column(mainAxisSize: MainAxisSize.min, children: [
+      padding: EdgeInsets.only(top: 10),
+      child: Column(
+        mainAxisSize: MainAxisSize.min,
+        children: [
           if (!_isHardwareWallet)
             SettingsCellWithArrow(
+              key: ValueKey('security_backup_page_show_keys_button_key'),
               title: S.current.show_keys,
               handler: (_) => _authService.authenticateAction(
                 context,
@@ -44,15 +48,17 @@ class SecurityBackupPage extends BasePage {
             ),
           if (!SettingsStoreBase.walletPasswordDirectInput)
             SettingsCellWithArrow(
+              key: ValueKey('security_backup_page_create_backup_button_key'),
               title: S.current.create_backup,
               handler: (_) => _authService.authenticateAction(
                 context,
                 route: Routes.backup,
-                conditionToDetermineIfToUse2FA: _securitySettingsViewModel
-                    .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
+                conditionToDetermineIfToUse2FA:
+                    _securitySettingsViewModel.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
               ),
             ),
           SettingsCellWithArrow(
+            key: ValueKey('security_backup_page_change_pin_button_key'),
             title: S.current.settings_change_pin,
             handler: (_) => _authService.authenticateAction(
               context,
@@ -60,28 +66,30 @@ class SecurityBackupPage extends BasePage {
               arguments: (PinCodeState<PinCodeWidget> setupPinContext, String _) {
                 setupPinContext.close();
               },
-              conditionToDetermineIfToUse2FA: _securitySettingsViewModel
-                  .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
+              conditionToDetermineIfToUse2FA:
+                  _securitySettingsViewModel.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
             ),
           ),
           if (DeviceInfo.instance.isMobile || Platform.isMacOS || Platform.isLinux)
             Observer(builder: (_) {
               return SettingsSwitcherCell(
+                  key: ValueKey('security_backup_page_allow_biometrics_button_key'),
                   title: S.current.settings_allow_biometrical_authentication,
                   value: _securitySettingsViewModel.allowBiometricalAuthentication,
                   onValueChange: (BuildContext context, bool value) {
                     if (value) {
-                      _authService.authenticateAction(context,
-                          onAuthSuccess: (isAuthenticatedSuccessfully) async {
-                        if (isAuthenticatedSuccessfully) {
-                          if (await _securitySettingsViewModel.biometricAuthenticated()) {
+                      _authService.authenticateAction(
+                        context,
+                        onAuthSuccess: (isAuthenticatedSuccessfully) async {
+                          if (isAuthenticatedSuccessfully) {
+                            if (await _securitySettingsViewModel.biometricAuthenticated()) {
+                              _securitySettingsViewModel
+                                  .setAllowBiometricalAuthentication(isAuthenticatedSuccessfully);
+                            }
+                          } else {
                             _securitySettingsViewModel
                                 .setAllowBiometricalAuthentication(isAuthenticatedSuccessfully);
                           }
-                        } else {
-                          _securitySettingsViewModel
-                              .setAllowBiometricalAuthentication(isAuthenticatedSuccessfully);
-                        }
                         },
                         conditionToDetermineIfToUse2FA: _securitySettingsViewModel
                             .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
@@ -93,6 +101,7 @@ class SecurityBackupPage extends BasePage {
             }),
           Observer(builder: (_) {
             return SettingsPickerCell<PinCodeRequiredDuration>(
+              key: ValueKey('security_backup_page_require_pin_after_button_key'),
               title: S.current.require_pin_after,
               items: PinCodeRequiredDuration.values,
               selectedItem: _securitySettingsViewModel.pinCodeRequiredDuration,
@@ -104,14 +113,15 @@ class SecurityBackupPage extends BasePage {
           Observer(
             builder: (context) {
               return SettingsCellWithArrow(
+                key: ValueKey('security_backup_page_totp_2fa_button_key'),
                 title: _securitySettingsViewModel.useTotp2FA
                     ? S.current.modify_2fa
                     : S.current.setup_2fa,
-            handler: (_) => _authService.authenticateAction(
-              context,
-              route: _securitySettingsViewModel.useTotp2FA
-                  ? Routes.modify2FAPage
-                  : Routes.setup2faInfoPage,
+                handler: (_) => _authService.authenticateAction(
+                  context,
+                  route: _securitySettingsViewModel.useTotp2FA
+                      ? Routes.modify2FAPage
+                      : Routes.setup2faInfoPage,
                   conditionToDetermineIfToUse2FA: _securitySettingsViewModel
                       .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
                 ),
diff --git a/lib/src/screens/settings/widgets/settings_cell_with_arrow.dart b/lib/src/screens/settings/widgets/settings_cell_with_arrow.dart
index f0e19a715..cb4f9dc78 100644
--- a/lib/src/screens/settings/widgets/settings_cell_with_arrow.dart
+++ b/lib/src/screens/settings/widgets/settings_cell_with_arrow.dart
@@ -3,8 +3,11 @@ import 'package:cake_wallet/src/widgets/standard_list.dart';
 import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
 
 class SettingsCellWithArrow extends StandardListRow {
-  SettingsCellWithArrow({required String title, required Function(BuildContext context)? handler})
-      : super(title: title, isSelected: false, onTap: handler);
+  SettingsCellWithArrow({
+    required String title,
+    required Function(BuildContext context)? handler,
+    Key? key,
+  }) : super(title: title, isSelected: false, onTap: handler, key: key);
 
   @override
   Widget buildTrailing(BuildContext context) => Image.asset('assets/images/select_arrow.png',
diff --git a/lib/src/screens/settings/widgets/settings_picker_cell.dart b/lib/src/screens/settings/widgets/settings_picker_cell.dart
index 8e0492330..765ac2991 100644
--- a/lib/src/screens/settings/widgets/settings_picker_cell.dart
+++ b/lib/src/screens/settings/widgets/settings_picker_cell.dart
@@ -5,19 +5,21 @@ import 'package:cake_wallet/src/widgets/picker.dart';
 import 'package:cake_wallet/src/widgets/standard_list.dart';
 
 class SettingsPickerCell<ItemType> extends StandardListRow {
-  SettingsPickerCell(
-      {required String title,
-      required this.selectedItem,
-      required this.items,
-      this.displayItem,
-      this.images,
-      this.searchHintText,
-      this.isGridView = false,
-      this.matchingCriteria,
-      this.onItemSelected})
-      : super(
+  SettingsPickerCell({
+    required String title,
+    required this.selectedItem,
+    required this.items,
+    this.displayItem,
+    this.images,
+    this.searchHintText,
+    this.isGridView = false,
+    this.matchingCriteria,
+    this.onItemSelected,
+    Key? key,
+  }) : super(
           title: title,
           isSelected: false,
+          key: key,
           onTap: (BuildContext context) async {
             final selectedAtIndex = items.indexOf(selectedItem);
 
diff --git a/lib/src/screens/settings/widgets/settings_switcher_cell.dart b/lib/src/screens/settings/widgets/settings_switcher_cell.dart
index 0e5c04524..6a3c8b4a0 100644
--- a/lib/src/screens/settings/widgets/settings_switcher_cell.dart
+++ b/lib/src/screens/settings/widgets/settings_switcher_cell.dart
@@ -10,7 +10,8 @@ class SettingsSwitcherCell extends StandardListRow {
     Decoration? decoration,
     this.leading,
     void Function(BuildContext context)? onTap,
-  }) : super(title: title, isSelected: false, decoration: decoration, onTap: onTap);
+    Key? key,
+  }) : super(title: title, isSelected: false, decoration: decoration, onTap: onTap, key: key);
 
   final bool value;
   final void Function(BuildContext context, bool value)? onValueChange;
diff --git a/lib/src/screens/setup_2fa/setup_2fa_info_page.dart b/lib/src/screens/setup_2fa/setup_2fa_info_page.dart
index ff6187665..8aa0ac3c9 100644
--- a/lib/src/screens/setup_2fa/setup_2fa_info_page.dart
+++ b/lib/src/screens/setup_2fa/setup_2fa_info_page.dart
@@ -4,7 +4,6 @@ import 'package:cake_wallet/src/screens/InfoPage.dart';
 import 'package:flutter/cupertino.dart';
 
 class Setup2FAInfoPage extends InfoPage {
-
   @override
   String get pageTitle => S.current.pre_seed_title;
 
@@ -15,6 +14,9 @@ class Setup2FAInfoPage extends InfoPage {
   String get buttonText => S.current.understand;
 
   @override
-  void Function(BuildContext) get onPressed => (BuildContext context) =>
-      Navigator.of(context).popAndPushNamed(Routes.setup_2faPage);
+  Key? get buttonKey => ValueKey('setup_2fa_info_page_button_key');
+
+  @override
+  void Function(BuildContext) get onPressed =>
+      (BuildContext context) => Navigator.of(context).popAndPushNamed(Routes.setup_2faPage);
 }
diff --git a/lib/src/screens/transaction_details/blockexplorer_list_item.dart b/lib/src/screens/transaction_details/blockexplorer_list_item.dart
index d5a70daa7..0126a147a 100644
--- a/lib/src/screens/transaction_details/blockexplorer_list_item.dart
+++ b/lib/src/screens/transaction_details/blockexplorer_list_item.dart
@@ -1,7 +1,12 @@
 import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
+import 'package:flutter/foundation.dart';
 
 class BlockExplorerListItem extends TransactionDetailsListItem {
-  BlockExplorerListItem({required String title, required String value, required this.onTap})
-      : super(title: title, value: value);
+  BlockExplorerListItem({
+    required String title,
+    required String value,
+    required this.onTap,
+    Key? key,
+  }) : super(title: title, value: value, key: key);
   final Function() onTap;
 }
diff --git a/lib/src/screens/transaction_details/rbf_details_list_fee_picker_item.dart b/lib/src/screens/transaction_details/rbf_details_list_fee_picker_item.dart
index db3d94500..96ddc94cd 100644
--- a/lib/src/screens/transaction_details/rbf_details_list_fee_picker_item.dart
+++ b/lib/src/screens/transaction_details/rbf_details_list_fee_picker_item.dart
@@ -1,18 +1,20 @@
 import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
+import 'package:flutter/widgets.dart';
 
 class StandardPickerListItem<T> extends TransactionDetailsListItem {
-  StandardPickerListItem(
-      {required String title,
-      required String value,
-      required this.items,
-      required this.displayItem,
-      required this.onSliderChanged,
-      required this.onItemSelected,
-      required this.selectedIdx,
-      required this.customItemIndex,
-      this.maxValue,
-      required this.customValue})
-      : super(title: title, value: value);
+  StandardPickerListItem({
+    required String title,
+    required String value,
+    required this.items,
+    required this.displayItem,
+    required this.onSliderChanged,
+    required this.onItemSelected,
+    required this.selectedIdx,
+    required this.customItemIndex,
+    this.maxValue,
+    required this.customValue,
+    Key? key,
+  }) : super(title: title, value: value, key: key);
 
   final List<T> items;
   final String Function(T item, double sliderValue) displayItem;
diff --git a/lib/src/screens/transaction_details/standart_list_item.dart b/lib/src/screens/transaction_details/standart_list_item.dart
index 705daf970..673eabe42 100644
--- a/lib/src/screens/transaction_details/standart_list_item.dart
+++ b/lib/src/screens/transaction_details/standart_list_item.dart
@@ -1,6 +1,9 @@
 import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
 
 class StandartListItem extends TransactionDetailsListItem {
-  StandartListItem({required String title, required String value})
-      : super(title: title, value: value);
+  StandartListItem({
+    required String super.title,
+    required String super.value,
+    super.key,
+  });
 }
diff --git a/lib/src/screens/transaction_details/textfield_list_item.dart b/lib/src/screens/transaction_details/textfield_list_item.dart
index 49ef2705e..846f9acd5 100644
--- a/lib/src/screens/transaction_details/textfield_list_item.dart
+++ b/lib/src/screens/transaction_details/textfield_list_item.dart
@@ -1,11 +1,17 @@
 import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
+import 'package:flutter/foundation.dart';
 
 class TextFieldListItem extends TransactionDetailsListItem {
   TextFieldListItem({
     required String title,
     required String value,
-    required this.onSubmitted})
-      : super(title: title, value: value);
+    required this.onSubmitted,
+    Key? key,
+  }) : super(
+          title: title,
+          value: value,
+          key: key,
+        );
 
   final Function(String value) onSubmitted;
 }
\ No newline at end of file
diff --git a/lib/src/screens/transaction_details/transaction_details_list_item.dart b/lib/src/screens/transaction_details/transaction_details_list_item.dart
index 8a8449350..446383d72 100644
--- a/lib/src/screens/transaction_details/transaction_details_list_item.dart
+++ b/lib/src/screens/transaction_details/transaction_details_list_item.dart
@@ -1,6 +1,9 @@
+import 'package:flutter/foundation.dart';
+
 abstract class TransactionDetailsListItem {
-  TransactionDetailsListItem({required this.title, required this.value});
+  TransactionDetailsListItem({required this.title, required this.value, this.key});
 
   final String title;
   final String value;
-}
\ No newline at end of file
+  final Key? key;
+}
diff --git a/lib/src/screens/transaction_details/transaction_details_page.dart b/lib/src/screens/transaction_details/transaction_details_page.dart
index 1b088fc31..9484bf4da 100644
--- a/lib/src/screens/transaction_details/transaction_details_page.dart
+++ b/lib/src/screens/transaction_details/transaction_details_page.dart
@@ -33,38 +33,42 @@ class TransactionDetailsPage extends BasePage {
       children: [
         Expanded(
           child: SectionStandardList(
-              sectionCount: 1,
-              itemCounter: (int _) => transactionDetailsViewModel.items.length,
-              itemBuilder: (__, index) {
-                final item = transactionDetailsViewModel.items[index];
+            sectionCount: 1,
+            itemCounter: (int _) => transactionDetailsViewModel.items.length,
+            itemBuilder: (__, index) {
+              final item = transactionDetailsViewModel.items[index];
 
-                if (item is StandartListItem) {
-                  return GestureDetector(
-                    onTap: () {
-                      Clipboard.setData(ClipboardData(text: item.value));
-                      showBar<void>(context, S.of(context).transaction_details_copied(item.title));
-                    },
-                    child: ListRow(title: '${item.title}:', value: item.value),
-                  );
-                }
+              if (item is StandartListItem) {
+                return GestureDetector(
+                  key: item.key,
+                  onTap: () {
+                    Clipboard.setData(ClipboardData(text: item.value));
+                    showBar<void>(context, S.of(context).transaction_details_copied(item.title));
+                  },
+                  child: ListRow(title: '${item.title}:', value: item.value),
+                );
+              }
 
-                if (item is BlockExplorerListItem) {
-                  return GestureDetector(
-                    onTap: item.onTap,
-                    child: ListRow(title: '${item.title}:', value: item.value),
-                  );
-                }
+              if (item is BlockExplorerListItem) {
+                return GestureDetector(
+                  key: item.key,
+                  onTap: item.onTap,
+                  child: ListRow(title: '${item.title}:', value: item.value),
+                );
+              }
 
-                if (item is TextFieldListItem) {
-                  return TextFieldListRow(
-                    title: item.title,
-                    value: item.value,
-                    onSubmitted: item.onSubmitted,
-                  );
-                }
+              if (item is TextFieldListItem) {
+                return TextFieldListRow(
+                  key: item.key,
+                  title: item.title,
+                  value: item.value,
+                  onSubmitted: item.onSubmitted,
+                );
+              }
 
-                return Container();
-              }),
+              return Container();
+            },
+          ),
         ),
         Observer(
           builder: (_) {
diff --git a/lib/src/screens/transaction_details/transaction_expandable_list_item.dart b/lib/src/screens/transaction_details/transaction_expandable_list_item.dart
index e87405de3..db6cf22ae 100644
--- a/lib/src/screens/transaction_details/transaction_expandable_list_item.dart
+++ b/lib/src/screens/transaction_details/transaction_expandable_list_item.dart
@@ -1,7 +1,12 @@
 import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
+import 'package:flutter/foundation.dart';
 
 class StandardExpandableListItem<T> extends TransactionDetailsListItem {
-  StandardExpandableListItem({required String title, required this.expandableItems})
-      : super(title: title, value: '');
+  StandardExpandableListItem({
+    required String title,
+    required this.expandableItems,
+    Key? key,
+  }) : super(title: title, value: '', key: key);
+  
   final List<T> expandableItems;
 }
diff --git a/lib/src/screens/transaction_details/widgets/textfield_list_row.dart b/lib/src/screens/transaction_details/widgets/textfield_list_row.dart
index a86645ecb..24016a293 100644
--- a/lib/src/screens/transaction_details/widgets/textfield_list_row.dart
+++ b/lib/src/screens/transaction_details/widgets/textfield_list_row.dart
@@ -4,12 +4,14 @@ import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
 import 'package:flutter/material.dart';
 
 class TextFieldListRow extends StatefulWidget {
-  TextFieldListRow(
-      {required this.title,
-      required this.value,
-      this.titleFontSize = 14,
-      this.valueFontSize = 16,
-      this.onSubmitted});
+  TextFieldListRow({
+    required this.title,
+    required this.value,
+    this.titleFontSize = 14,
+    this.valueFontSize = 16,
+    this.onSubmitted,
+    super.key,
+  });
 
   final String title;
   final String value;
diff --git a/lib/src/screens/wallet_keys/wallet_keys_page.dart b/lib/src/screens/wallet_keys/wallet_keys_page.dart
index 5117f152f..fac760516 100644
--- a/lib/src/screens/wallet_keys/wallet_keys_page.dart
+++ b/lib/src/screens/wallet_keys/wallet_keys_page.dart
@@ -25,23 +25,25 @@ class WalletKeysPage extends BasePage {
 
   @override
   Widget trailing(BuildContext context) => IconButton(
-      onPressed: () async {
-        final url = await walletKeysViewModel.url;
+        key: ValueKey('wallet_keys_page_fullscreen_qr_button_key'),
+        onPressed: () async {
+          final url = await walletKeysViewModel.url;
 
-        BrightnessUtil.changeBrightnessForFunction(() async {
-          await Navigator.pushNamed(
-            context,
-            Routes.fullscreenQR,
-            arguments: QrViewData(data: url.toString(), version: QrVersions.auto),
-          );
-        });
-      },
-      splashColor: Colors.transparent,
-      highlightColor: Colors.transparent,
-      hoverColor: Colors.transparent,
-      icon: Image.asset(
-        'assets/images/qr_code_icon.png',
-      ));
+          BrightnessUtil.changeBrightnessForFunction(() async {
+            await Navigator.pushNamed(
+              context,
+              Routes.fullscreenQR,
+              arguments: QrViewData(data: url.toString(), version: QrVersions.auto),
+            );
+          });
+        },
+        splashColor: Colors.transparent,
+        highlightColor: Colors.transparent,
+        hoverColor: Colors.transparent,
+        icon: Image.asset(
+          'assets/images/qr_code_icon.png',
+        ),
+      );
 
   @override
   Widget body(BuildContext context) {
@@ -60,6 +62,7 @@ class WalletKeysPage extends BasePage {
                 child: Padding(
                   padding: const EdgeInsets.all(8.0),
                   child: AutoSizeText(
+                    key: ValueKey('wallet_keys_page_share_warning_text_key'),
                     S.of(context).do_not_share_warning_text.toUpperCase(),
                     textAlign: TextAlign.center,
                     maxLines: 4,
@@ -92,6 +95,7 @@ class WalletKeysPage extends BasePage {
                     final item = walletKeysViewModel.items[index];
 
                     return GestureDetector(
+                      key: item.key,
                       onTap: () {
                         ClipboardUtil.setSensitiveDataToClipboard(ClipboardData(text: item.value));
                         showBar<void>(context, S.of(context).copied_key_to_clipboard(item.title));
diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart
index afb86cf0a..a9a9d9413 100644
--- a/lib/src/screens/wallet_list/wallet_list_page.dart
+++ b/lib/src/screens/wallet_list/wallet_list_page.dart
@@ -318,6 +318,7 @@ class WalletListBodyState extends State<WalletListBody> {
             child: Column(
               children: <Widget>[
                 PrimaryImageButton(
+                  key: ValueKey('wallet_list_page_create_new_wallet_button_key'),
                   onPressed: () {
                     //TODO(David): Find a way to optimize this
                     if (isSingleCoin) {
@@ -359,6 +360,7 @@ class WalletListBodyState extends State<WalletListBody> {
                 ),
                 SizedBox(height: 10.0),
                 PrimaryImageButton(
+                  key: ValueKey('wallet_list_page_restore_wallet_button_key'),
                   onPressed: () {
                     if (widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets) {
                       widget.authService.authenticateAction(
diff --git a/lib/src/widgets/blockchain_height_widget.dart b/lib/src/widgets/blockchain_height_widget.dart
index 9d66c1789..1c6b6da02 100644
--- a/lib/src/widgets/blockchain_height_widget.dart
+++ b/lib/src/widgets/blockchain_height_widget.dart
@@ -23,6 +23,7 @@ class BlockchainHeightWidget extends StatefulWidget {
     this.doSingleScan = false,
     this.bitcoinMempoolAPIEnabled,
     required this.walletType,
+    this.blockHeightTextFieldKey,
   }) : super(key: key);
 
   final Function(int)? onHeightChange;
@@ -35,6 +36,7 @@ class BlockchainHeightWidget extends StatefulWidget {
   final Future<bool>? bitcoinMempoolAPIEnabled;
   final Function()? toggleSingleScan;
   final WalletType walletType;
+  final Key? blockHeightTextFieldKey;
 
   @override
   State<StatefulWidget> createState() => BlockchainHeightState();
@@ -81,6 +83,7 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
                   child: Container(
                       padding: EdgeInsets.only(top: 20.0, bottom: 10.0),
                       child: BaseTextFormField(
+                        key: widget.blockHeightTextFieldKey,
                         focusNode: widget.focusNode,
                         controller: restoreHeightController,
                         keyboardType:
diff --git a/lib/src/widgets/dashboard_card_widget.dart b/lib/src/widgets/dashboard_card_widget.dart
index d9b545040..dc223eb02 100644
--- a/lib/src/widgets/dashboard_card_widget.dart
+++ b/lib/src/widgets/dashboard_card_widget.dart
@@ -15,6 +15,7 @@ class DashBoardRoundedCardWidget extends StatelessWidget {
     this.icon,
     this.onClose,
     this.customBorder,
+    super.key,
   });
 
   final VoidCallback onTap;
diff --git a/lib/src/widgets/option_tile.dart b/lib/src/widgets/option_tile.dart
index 31f958f54..c2d8b9506 100644
--- a/lib/src/widgets/option_tile.dart
+++ b/lib/src/widgets/option_tile.dart
@@ -2,14 +2,14 @@ import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
 import 'package:flutter/material.dart';
 
 class OptionTile extends StatelessWidget {
-  const OptionTile(
-      {required this.onPressed,
-       this.image,
-        this.icon,
-      required this.title,
-      required this.description,
-      super.key})
-  : assert(image!=null || icon!=null);
+  const OptionTile({
+    required this.onPressed,
+    this.image,
+    this.icon,
+    required this.title,
+    required this.description,
+    super.key,
+  }) : assert(image != null || icon != null);
 
   final VoidCallback onPressed;
   final Image? image;
@@ -34,7 +34,7 @@ class OptionTile extends StatelessWidget {
           mainAxisAlignment: MainAxisAlignment.center,
           crossAxisAlignment: CrossAxisAlignment.start,
           children: <Widget>[
-             icon ?? image!,
+            icon ?? image!,
             Expanded(
               child: Padding(
                 padding: EdgeInsets.only(left: 16),
diff --git a/lib/src/widgets/picker.dart b/lib/src/widgets/picker.dart
index 801a79595..ed5c05be6 100644
--- a/lib/src/widgets/picker.dart
+++ b/lib/src/widgets/picker.dart
@@ -2,6 +2,7 @@
 
 import 'dart:math';
 
+import 'package:cake_wallet/entities/seed_type.dart';
 import 'package:cake_wallet/src/widgets/search_bar_widget.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
 import 'package:cw_core/transaction_priority.dart';
@@ -310,6 +311,8 @@ class _PickerState<Item> extends State<Picker<Item>> {
       itemName = item.name;
     } else if (item is TransactionPriority) {
       itemName = item.title;
+    } else if (item is MoneroSeedType) {
+      itemName = item.title;
     } else {
       itemName = '';
     }
diff --git a/lib/src/widgets/seed_language_selector.dart b/lib/src/widgets/seed_language_selector.dart
index 87f3aa573..711bff390 100644
--- a/lib/src/widgets/seed_language_selector.dart
+++ b/lib/src/widgets/seed_language_selector.dart
@@ -6,12 +6,16 @@ import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:flutter/material.dart';
 
 class SeedLanguageSelector extends StatefulWidget {
-  SeedLanguageSelector(
-      {Key? key, required this.initialSelected, this.seedType = MoneroSeedType.defaultSeedType})
-      : super(key: key);
+  SeedLanguageSelector({
+    required this.initialSelected,
+    this.seedType = MoneroSeedType.defaultSeedType,
+    this.buttonKey,
+    Key? key,
+  }) : super(key: key);
 
   final String initialSelected;
   final MoneroSeedType seedType;
+  final Key? buttonKey;
 
   @override
   SeedLanguageSelectorState createState() => SeedLanguageSelectorState(selected: initialSelected);
@@ -25,6 +29,7 @@ class SeedLanguageSelectorState extends State<SeedLanguageSelector> {
   @override
   Widget build(BuildContext context) {
     return SelectButton(
+      key: widget.buttonKey,
       image: null,
       text:
           "${seedLanguages.firstWhere((e) => e.name == selected).nameLocalized} (${S.of(context).seed_language})",
diff --git a/lib/src/widgets/setting_actions.dart b/lib/src/widgets/setting_actions.dart
index b9af97f32..048d006cc 100644
--- a/lib/src/widgets/setting_actions.dart
+++ b/lib/src/widgets/setting_actions.dart
@@ -5,9 +5,11 @@ import 'package:flutter/material.dart';
 class SettingActions {
   final String Function(BuildContext) name;
   final String image;
+  final Key key;
   final void Function(BuildContext) onTap;
 
   SettingActions._({
+    required this.key,
     required this.name,
     required this.image,
     required this.onTap,
@@ -39,6 +41,7 @@ class SettingActions {
   ];
 
   static SettingActions silentPaymentsSettingAction = SettingActions._(
+    key: ValueKey('dashboard_page_menu_widget_silent_payment_settings_button_key'),
     name: (context) => S.of(context).silent_payments_settings,
     image: 'assets/images/bitcoin_menu.png',
     onTap: (BuildContext context) {
@@ -48,6 +51,7 @@ class SettingActions {
   );
 
   static SettingActions litecoinMwebSettingAction = SettingActions._(
+    key: ValueKey('dashboard_page_menu_widget_litecoin_mweb_settings_button_key'),
     name: (context) => S.of(context).litecoin_mweb_settings,
     image: 'assets/images/litecoin_menu.png',
     onTap: (BuildContext context) {
@@ -57,6 +61,7 @@ class SettingActions {
   );
 
   static SettingActions connectionSettingAction = SettingActions._(
+    key: ValueKey('dashboard_page_menu_widget_connection_and_sync_settings_button_key'),
     name: (context) => S.of(context).connection_sync,
     image: 'assets/images/nodes_menu.png',
     onTap: (BuildContext context) {
@@ -66,6 +71,7 @@ class SettingActions {
   );
 
   static SettingActions walletSettingAction = SettingActions._(
+    key: ValueKey('dashboard_page_menu_widget_wallet_menu_button_key'),
     name: (context) => S.of(context).wallets,
     image: 'assets/images/wallet_menu.png',
     onTap: (BuildContext context) {
@@ -75,6 +81,7 @@ class SettingActions {
   );
 
   static SettingActions addressBookSettingAction = SettingActions._(
+    key: ValueKey('dashboard_page_menu_widget_address_book_button_key'),
     name: (context) => S.of(context).address_book_menu,
     image: 'assets/images/open_book_menu.png',
     onTap: (BuildContext context) {
@@ -84,6 +91,7 @@ class SettingActions {
   );
 
   static SettingActions securityBackupSettingAction = SettingActions._(
+    key: ValueKey('dashboard_page_menu_widget_security_and_backup_button_key'),
     name: (context) => S.of(context).security_and_backup,
     image: 'assets/images/key_menu.png',
     onTap: (BuildContext context) {
@@ -93,6 +101,7 @@ class SettingActions {
   );
 
   static SettingActions privacySettingAction = SettingActions._(
+    key: ValueKey('dashboard_page_menu_widget_privacy_settings_button_key'),
     name: (context) => S.of(context).privacy,
     image: 'assets/images/privacy_menu.png',
     onTap: (BuildContext context) {
@@ -102,6 +111,7 @@ class SettingActions {
   );
 
   static SettingActions displaySettingAction = SettingActions._(
+    key: ValueKey('dashboard_page_menu_widget_display_settings_button_key'),
     name: (context) => S.of(context).display_settings,
     image: 'assets/images/eye_menu.png',
     onTap: (BuildContext context) {
@@ -111,6 +121,7 @@ class SettingActions {
   );
 
   static SettingActions otherSettingAction = SettingActions._(
+    key: ValueKey('dashboard_page_menu_widget_other_settings_button_key'),
     name: (context) => S.of(context).other_settings,
     image: 'assets/images/settings_menu.png',
     onTap: (BuildContext context) {
@@ -120,6 +131,7 @@ class SettingActions {
   );
 
   static SettingActions supportSettingAction = SettingActions._(
+    key: ValueKey('dashboard_page_menu_widget_support_settings_button_key'),
     name: (context) => S.of(context).settings_support,
     image: 'assets/images/question_mark.png',
     onTap: (BuildContext context) {
diff --git a/lib/src/widgets/standard_list.dart b/lib/src/widgets/standard_list.dart
index c1fcae052..0780d64cd 100644
--- a/lib/src/widgets/standard_list.dart
+++ b/lib/src/widgets/standard_list.dart
@@ -4,7 +4,13 @@ import 'package:cake_wallet/src/widgets/standard_list_status_row.dart';
 import 'package:flutter/material.dart';
 
 class StandardListRow extends StatelessWidget {
-  StandardListRow({required this.title, required this.isSelected, this.onTap, this.decoration});
+  StandardListRow({
+    required this.title,
+    required this.isSelected,
+    this.onTap,
+    this.decoration,
+    super.key,
+  });
 
   final String title;
   final bool isSelected;
diff --git a/lib/store/anonpay/anonpay_transactions_store.dart b/lib/store/anonpay/anonpay_transactions_store.dart
index c6f05b993..d0384ca5a 100644
--- a/lib/store/anonpay/anonpay_transactions_store.dart
+++ b/lib/store/anonpay/anonpay_transactions_store.dart
@@ -1,6 +1,7 @@
 import 'dart:async';
 import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
 import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
+import 'package:flutter/foundation.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 
@@ -27,7 +28,10 @@ abstract class AnonpayTransactionsStoreBase with Store {
   Future<void> updateTransactionList() async {
     transactions = anonpayInvoiceInfoSource.values
         .map(
-          (transaction) => AnonpayTransactionListItem(transaction: transaction),
+          (transaction) => AnonpayTransactionListItem(
+            transaction: transaction,
+            key: ValueKey('anonpay_invoice_transaction_list_item_${transaction.invoiceId}_key'),
+          ),
         )
         .toList();
   }
diff --git a/lib/store/dashboard/orders_store.dart b/lib/store/dashboard/orders_store.dart
index b5ec658f7..d91ad3512 100644
--- a/lib/store/dashboard/orders_store.dart
+++ b/lib/store/dashboard/orders_store.dart
@@ -1,6 +1,7 @@
 import 'dart:async';
 import 'package:cake_wallet/buy/order.dart';
 import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
+import 'package:flutter/foundation.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cake_wallet/store/settings_store.dart';
@@ -10,12 +11,10 @@ part 'orders_store.g.dart';
 class OrdersStore = OrdersStoreBase with _$OrdersStore;
 
 abstract class OrdersStoreBase with Store {
-  OrdersStoreBase({required this.ordersSource,
-    required this.settingsStore})
-    : orders = <OrderListItem>[],
-      orderId = '' {
-    _onOrdersChanged =
-        ordersSource.watch().listen((_) async => await updateOrderList());
+  OrdersStoreBase({required this.ordersSource, required this.settingsStore})
+      : orders = <OrderListItem>[],
+        orderId = '' {
+    _onOrdersChanged = ordersSource.watch().listen((_) async => await updateOrderList());
     updateOrderList();
   }
 
@@ -38,8 +37,11 @@ abstract class OrdersStoreBase with Store {
   void setOrder(Order order) => this.order = order;
 
   @action
-  Future updateOrderList() async => orders =
-      ordersSource.values.map((order) => OrderListItem(
-          order: order,
-          settingsStore: settingsStore)).toList();
-}
\ No newline at end of file
+  Future updateOrderList() async => orders = ordersSource.values
+      .map((order) => OrderListItem(
+            order: order,
+            settingsStore: settingsStore,
+            key: ValueKey('order_list_item_${order.id}_key'),
+          ))
+      .toList();
+}
diff --git a/lib/store/dashboard/trades_store.dart b/lib/store/dashboard/trades_store.dart
index 72442b46f..d0a4592e3 100644
--- a/lib/store/dashboard/trades_store.dart
+++ b/lib/store/dashboard/trades_store.dart
@@ -1,6 +1,7 @@
 import 'dart:async';
 import 'package:cake_wallet/exchange/trade.dart';
 import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
+import 'package:flutter/foundation.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cake_wallet/store/settings_store.dart';
@@ -11,9 +12,8 @@ class TradesStore = TradesStoreBase with _$TradesStore;
 
 abstract class TradesStoreBase with Store {
   TradesStoreBase({required this.tradesSource, required this.settingsStore})
-    : trades = <TradeListItem>[] {
-    _onTradesChanged =
-        tradesSource.watch().listen((_) async => await updateTradeList());
+      : trades = <TradeListItem>[] {
+    _onTradesChanged = tradesSource.watch().listen((_) async => await updateTradeList());
     updateTradeList();
   }
 
@@ -31,8 +31,11 @@ abstract class TradesStoreBase with Store {
   void setTrade(Trade trade) => this.trade = trade;
 
   @action
-  Future<void> updateTradeList() async => trades =
-      tradesSource.values.map((trade) => TradeListItem(
-          trade: trade,
-          settingsStore: settingsStore)).toList();
-}
\ No newline at end of file
+  Future<void> updateTradeList() async => trades = tradesSource.values
+      .map((trade) => TradeListItem(
+            trade: trade,
+            settingsStore: settingsStore,
+            key: ValueKey('trade_list_item_${trade.id}_key'),
+          ))
+      .toList();
+}
diff --git a/lib/utils/date_formatter.dart b/lib/utils/date_formatter.dart
index 9cff68614..58e59966a 100644
--- a/lib/utils/date_formatter.dart
+++ b/lib/utils/date_formatter.dart
@@ -1,3 +1,4 @@
+import 'package:cake_wallet/generated/i18n.dart';
 import 'package:intl/intl.dart';
 import 'package:cake_wallet/di.dart';
 import 'package:cake_wallet/store/settings_store.dart';
@@ -5,8 +6,7 @@ import 'package:cake_wallet/store/settings_store.dart';
 class DateFormatter {
   static String currentLocalFormat({bool hasTime = true, bool reverse = false}) {
     final isUSA = getIt.get<SettingsStore>().languageCode.toLowerCase() == 'en';
-    final format =
-        isUSA ? usaStyleFormat(hasTime, reverse) : regularStyleFormat(hasTime, reverse);
+    final format = isUSA ? usaStyleFormat(hasTime, reverse) : regularStyleFormat(hasTime, reverse);
 
     return format;
   }
@@ -20,4 +20,26 @@ class DateFormatter {
 
   static String regularStyleFormat(bool hasTime, bool reverse) =>
       hasTime ? (reverse ? 'HH:mm  dd.MM.yyyy' : 'dd.MM.yyyy, HH:mm') : 'dd.MM.yyyy';
+
+  static String convertDateTimeToReadableString(DateTime date) {
+    final nowDate = DateTime.now();
+    final diffDays = date.difference(nowDate).inDays;
+    final isToday =
+        nowDate.day == date.day && nowDate.month == date.month && nowDate.year == date.year;
+    final dateSectionDateFormat = withCurrentLocal(hasTime: false);
+    var title = "";
+
+    if (isToday) {
+      title = S.current.today;
+    } else if (diffDays == 0) {
+      title = S.current.yesterday;
+    } else if (diffDays > -7 && diffDays < 0) {
+      final dateFormat = DateFormat.EEEE();
+      title = dateFormat.format(date);
+    } else {
+      title = dateSectionDateFormat.format(date);
+    }
+
+    return title;
+  }
 }
diff --git a/lib/utils/image_utill.dart b/lib/utils/image_utill.dart
index ef3775e4c..746fde453 100644
--- a/lib/utils/image_utill.dart
+++ b/lib/utils/image_utill.dart
@@ -11,6 +11,7 @@ class ImageUtil {
     if (isNetworkImage) {
       return isSvg
           ? SvgPicture.network(
+              key: ValueKey(imagePath),
               imagePath,
               height: _height,
               width: _width,
@@ -23,6 +24,7 @@ class ImageUtil {
               ),
             )
           : Image.network(
+              key: ValueKey(imagePath),
               imagePath,
               height: _height,
               width: _width,
@@ -58,12 +60,14 @@ class ImageUtil {
               height: _height,
               width: _width,
               placeholderBuilder: (_) => Icon(Icons.error),
+              key: ValueKey(imagePath),
             )
           : Image.asset(
               imagePath,
               height: _height,
               width: _width,
               errorBuilder: (_, __, ___) => Icon(Icons.error),
+              key: ValueKey(imagePath),
             );
     }
   }
diff --git a/lib/view_model/dashboard/action_list_item.dart b/lib/view_model/dashboard/action_list_item.dart
index b03bd1bdc..1ee4e6a3c 100644
--- a/lib/view_model/dashboard/action_list_item.dart
+++ b/lib/view_model/dashboard/action_list_item.dart
@@ -1,3 +1,8 @@
+import 'package:flutter/foundation.dart';
+
 abstract class ActionListItem {
+  ActionListItem({required this.key});
+
   DateTime get date;
+  Key key;
 }
\ No newline at end of file
diff --git a/lib/view_model/dashboard/anonpay_transaction_list_item.dart b/lib/view_model/dashboard/anonpay_transaction_list_item.dart
index 261e49070..a54a4b334 100644
--- a/lib/view_model/dashboard/anonpay_transaction_list_item.dart
+++ b/lib/view_model/dashboard/anonpay_transaction_list_item.dart
@@ -2,7 +2,7 @@ import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
 import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
 
 class AnonpayTransactionListItem extends ActionListItem {
-  AnonpayTransactionListItem({required this.transaction});
+  AnonpayTransactionListItem({required this.transaction, required super.key});
 
   final AnonpayInvoiceInfo transaction;
 
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index 423babefc..6cf7c49d0 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -48,6 +48,7 @@ import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:eth_sig_util/util/utils.dart';
+import 'package:flutter/foundation.dart';
 import 'package:flutter/services.dart';
 import 'package:http/http.dart' as http;
 import 'package:mobx/mobx.dart';
@@ -182,10 +183,16 @@ abstract class DashboardViewModelBase with Store {
       final sortedTransactions = [..._accountTransactions];
       sortedTransactions.sort((a, b) => a.date.compareTo(b.date));
 
-      transactions = ObservableList.of(sortedTransactions.map((transaction) => TransactionListItem(
-          transaction: transaction,
-          balanceViewModel: balanceViewModel,
-          settingsStore: appStore.settingsStore)));
+      transactions = ObservableList.of(
+        sortedTransactions.map(
+          (transaction) => TransactionListItem(
+            transaction: transaction,
+            balanceViewModel: balanceViewModel,
+            settingsStore: appStore.settingsStore,
+            key: ValueKey('monero_transaction_history_item_${transaction.id}_key'),
+          ),
+        ),
+      );
     } else if (_wallet.type == WalletType.wownero) {
       subname = wow.wownero!.getCurrentAccount(_wallet).label;
 
@@ -206,18 +213,30 @@ abstract class DashboardViewModelBase with Store {
       final sortedTransactions = [..._accountTransactions];
       sortedTransactions.sort((a, b) => a.date.compareTo(b.date));
 
-      transactions = ObservableList.of(sortedTransactions.map((transaction) => TransactionListItem(
-          transaction: transaction,
-          balanceViewModel: balanceViewModel,
-          settingsStore: appStore.settingsStore)));
+      transactions = ObservableList.of(
+        sortedTransactions.map(
+          (transaction) => TransactionListItem(
+            transaction: transaction,
+            balanceViewModel: balanceViewModel,
+            settingsStore: appStore.settingsStore,
+            key: ValueKey('wownero_transaction_history_item_${transaction.id}_key'),
+          ),
+        ),
+      );
     } else {
       final sortedTransactions = [...wallet.transactionHistory.transactions.values];
       sortedTransactions.sort((a, b) => a.date.compareTo(b.date));
 
-      transactions = ObservableList.of(sortedTransactions.map((transaction) => TransactionListItem(
-          transaction: transaction,
-          balanceViewModel: balanceViewModel,
-          settingsStore: appStore.settingsStore)));
+      transactions = ObservableList.of(
+        sortedTransactions.map(
+          (transaction) => TransactionListItem(
+            transaction: transaction,
+            balanceViewModel: balanceViewModel,
+            settingsStore: appStore.settingsStore,
+            key: ValueKey('${_wallet.type.name}_transaction_history_item_${transaction.id}_key'),
+          ),
+        ),
+      );
     }
 
     // TODO: nano sub-account generation is disabled:
@@ -234,9 +253,13 @@ abstract class DashboardViewModelBase with Store {
         appStore.wallet!.transactionHistory.transactions,
         transactions,
         (TransactionInfo? transaction) => TransactionListItem(
-            transaction: transaction!,
-            balanceViewModel: balanceViewModel,
-            settingsStore: appStore.settingsStore), filter: (TransactionInfo? transaction) {
+              transaction: transaction!,
+              balanceViewModel: balanceViewModel,
+              settingsStore: appStore.settingsStore,
+              key: ValueKey(
+                '${_wallet.type.name}_transaction_history_item_${transaction.id}_key',
+              ),
+            ), filter: (TransactionInfo? transaction) {
       if (transaction == null) {
         return false;
       }
@@ -650,20 +673,29 @@ abstract class DashboardViewModelBase with Store {
 
       transactions.clear();
 
-      transactions.addAll(wallet.transactionHistory.transactions.values.map((transaction) =>
-          TransactionListItem(
-              transaction: transaction,
-              balanceViewModel: balanceViewModel,
-              settingsStore: appStore.settingsStore)));
+      transactions.addAll(
+        wallet.transactionHistory.transactions.values.map(
+          (transaction) => TransactionListItem(
+            transaction: transaction,
+            balanceViewModel: balanceViewModel,
+            settingsStore: appStore.settingsStore,
+            key: ValueKey('${wallet.type.name}_transaction_history_item_${transaction.id}_key'),
+          ),
+        ),
+      );
     }
 
     connectMapToListWithTransform(
         appStore.wallet!.transactionHistory.transactions,
         transactions,
         (TransactionInfo? transaction) => TransactionListItem(
-            transaction: transaction!,
-            balanceViewModel: balanceViewModel,
-            settingsStore: appStore.settingsStore), filter: (TransactionInfo? tx) {
+              transaction: transaction!,
+              balanceViewModel: balanceViewModel,
+              settingsStore: appStore.settingsStore,
+              key: ValueKey(
+                '${wallet.type.name}_transaction_history_item_${transaction.id}_key',
+              ),
+            ), filter: (TransactionInfo? tx) {
       if (tx == null) {
         return false;
       }
@@ -703,10 +735,16 @@ abstract class DashboardViewModelBase with Store {
               monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id)
           .toList();
 
-      transactions.addAll(_accountTransactions.map((transaction) => TransactionListItem(
-          transaction: transaction,
-          balanceViewModel: balanceViewModel,
-          settingsStore: appStore.settingsStore)));
+      transactions.addAll(
+        _accountTransactions.map(
+          (transaction) => TransactionListItem(
+            transaction: transaction,
+            balanceViewModel: balanceViewModel,
+            settingsStore: appStore.settingsStore,
+            key: ValueKey('monero_transaction_history_item_${transaction.id}_key'),
+          ),
+        ),
+      );
     } else if (wallet.type == WalletType.wownero) {
       final _accountTransactions = wow.wownero!
           .getTransactionHistory(wallet)
@@ -717,10 +755,16 @@ abstract class DashboardViewModelBase with Store {
               wow.wownero!.getCurrentAccount(wallet).id)
           .toList();
 
-      transactions.addAll(_accountTransactions.map((transaction) => TransactionListItem(
-          transaction: transaction,
-          balanceViewModel: balanceViewModel,
-          settingsStore: appStore.settingsStore)));
+      transactions.addAll(
+        _accountTransactions.map(
+          (transaction) => TransactionListItem(
+            transaction: transaction,
+            balanceViewModel: balanceViewModel,
+            settingsStore: appStore.settingsStore,
+            key: ValueKey('wownero_transaction_history_item_${transaction.id}_key'),
+          ),
+        ),
+      );
     }
   }
 
diff --git a/lib/view_model/dashboard/date_section_item.dart b/lib/view_model/dashboard/date_section_item.dart
index 0b361ecce..75250a7ea 100644
--- a/lib/view_model/dashboard/date_section_item.dart
+++ b/lib/view_model/dashboard/date_section_item.dart
@@ -1,7 +1,7 @@
 import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
 
 class DateSectionItem extends ActionListItem {
-  DateSectionItem(this.date);
+  DateSectionItem(this.date, {required super.key});
   
   @override
   final DateTime date;
diff --git a/lib/view_model/dashboard/formatted_item_list.dart b/lib/view_model/dashboard/formatted_item_list.dart
index a1cbbbf7d..04464ca89 100644
--- a/lib/view_model/dashboard/formatted_item_list.dart
+++ b/lib/view_model/dashboard/formatted_item_list.dart
@@ -1,5 +1,6 @@
 import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
 import 'package:cake_wallet/view_model/dashboard/date_section_item.dart';
+import 'package:flutter/foundation.dart';
 
 List<ActionListItem> formattedItemsList(List<ActionListItem> items) {
   final formattedList = <ActionListItem>[];
@@ -11,7 +12,12 @@ List<ActionListItem> formattedItemsList(List<ActionListItem> items) {
 
     if (lastDate == null) {
       lastDate = transaction.date;
-      formattedList.add(DateSectionItem(transaction.date));
+      formattedList.add(
+        DateSectionItem(
+          transaction.date,
+          key: ValueKey('date_section_item_${transaction.date.microsecondsSinceEpoch}_key'),
+        ),
+      );
       formattedList.add(transaction);
       continue;
     }
@@ -26,7 +32,12 @@ List<ActionListItem> formattedItemsList(List<ActionListItem> items) {
     }
 
     lastDate = transaction.date;
-    formattedList.add(DateSectionItem(transaction.date));
+    formattedList.add(
+      DateSectionItem(
+        transaction.date,
+        key: ValueKey('date_section_item_${transaction.date.microsecondsSinceEpoch}_key'),
+      ),
+    );
     formattedList.add(transaction);
   }
 
diff --git a/lib/view_model/dashboard/order_list_item.dart b/lib/view_model/dashboard/order_list_item.dart
index 9120cc1a6..52adf53a6 100644
--- a/lib/view_model/dashboard/order_list_item.dart
+++ b/lib/view_model/dashboard/order_list_item.dart
@@ -6,7 +6,9 @@ import 'package:cake_wallet/entities/balance_display_mode.dart';
 class OrderListItem extends ActionListItem {
   OrderListItem({
     required this.order,
-    required this.settingsStore});
+    required this.settingsStore,
+    required super.key,
+  });
 
   final Order order;
   final SettingsStore settingsStore;
diff --git a/lib/view_model/dashboard/trade_list_item.dart b/lib/view_model/dashboard/trade_list_item.dart
index 964ba4ffa..55ae4e99f 100644
--- a/lib/view_model/dashboard/trade_list_item.dart
+++ b/lib/view_model/dashboard/trade_list_item.dart
@@ -4,7 +4,11 @@ import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
 
 class TradeListItem extends ActionListItem {
-  TradeListItem({required this.trade, required this.settingsStore});
+  TradeListItem({
+    required this.trade,
+    required this.settingsStore,
+    required super.key,
+  });
 
   final Trade trade;
   final SettingsStore settingsStore;
diff --git a/lib/view_model/dashboard/transaction_list_item.dart b/lib/view_model/dashboard/transaction_list_item.dart
index b218c8e9f..d9b361fd2 100644
--- a/lib/view_model/dashboard/transaction_list_item.dart
+++ b/lib/view_model/dashboard/transaction_list_item.dart
@@ -22,8 +22,12 @@ import 'package:cw_core/keyable.dart';
 import 'package:cw_core/wallet_type.dart';
 
 class TransactionListItem extends ActionListItem with Keyable {
-  TransactionListItem(
-      {required this.transaction, required this.balanceViewModel, required this.settingsStore});
+  TransactionListItem({
+    required this.transaction,
+    required this.balanceViewModel,
+    required this.settingsStore,
+    required super.key,
+  });
 
   final TransactionInfo transaction;
   final BalanceViewModel balanceViewModel;
diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart
index da6699ae6..a189ebe6c 100644
--- a/lib/view_model/transaction_details_view_model.dart
+++ b/lib/view_model/transaction_details_view_model.dart
@@ -20,6 +20,7 @@ import 'package:cake_wallet/view_model/send/send_view_model.dart';
 import 'package:collection/collection.dart';
 import 'package:cw_core/transaction_direction.dart';
 import 'package:cw_core/transaction_priority.dart';
+import 'package:flutter/foundation.dart';
 import 'package:hive/hive.dart';
 import 'package:intl/src/intl/date_format.dart';
 import 'package:mobx/mobx.dart';
@@ -52,7 +53,7 @@ abstract class TransactionDetailsViewModelBase with Store {
         break;
       case WalletType.bitcoin:
         _addElectrumListItems(tx, dateFormat);
-        if(!canReplaceByFee)_checkForRBF(tx);
+        if (!canReplaceByFee) _checkForRBF(tx);
         break;
       case WalletType.litecoin:
       case WalletType.bitcoinCash:
@@ -83,8 +84,7 @@ abstract class TransactionDetailsViewModelBase with Store {
         break;
     }
 
-    final descriptionKey =
-        '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}';
+    final descriptionKey = '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}';
     final description = transactionDescriptionBox.values.firstWhere(
         (val) => val.id == descriptionKey || val.id == transactionInfo.txHash,
         orElse: () => TransactionDescription(id: descriptionKey));
@@ -93,15 +93,20 @@ abstract class TransactionDetailsViewModelBase with Store {
       final recipientAddress = description.recipientAddress;
 
       if (recipientAddress?.isNotEmpty ?? false) {
-        items.add(StandartListItem(
-          title: S.current.transaction_details_recipient_address,
-          value: recipientAddress!));
+        items.add(
+          StandartListItem(
+            title: S.current.transaction_details_recipient_address,
+            value: recipientAddress!,
+            key: ValueKey('standard_list_item_${recipientAddress}_key'),
+          ),
+        );
       }
     }
 
     final type = wallet.type;
 
-    items.add(BlockExplorerListItem(
+    items.add(
+      BlockExplorerListItem(
         title: S.current.view_in_block_explorer,
         value: _explorerDescription(type),
         onTap: () async {
@@ -109,9 +114,13 @@ abstract class TransactionDetailsViewModelBase with Store {
             final uri = Uri.parse(_explorerUrl(type, tx.txHash));
             if (await canLaunchUrl(uri)) await launchUrl(uri, mode: LaunchMode.externalApplication);
           } catch (e) {}
-        }));
+        },
+        key: ValueKey('block_explorer_list_item_${type.name}_wallet_type_key'),
+      ),
+    );
 
-    items.add(TextFieldListItem(
+    items.add(
+      TextFieldListItem(
         title: S.current.note_tap_to_change,
         value: description.note,
         onSubmitted: (value) {
@@ -122,7 +131,10 @@ abstract class TransactionDetailsViewModelBase with Store {
           } else {
             transactionDescriptionBox.add(description);
           }
-        }));
+        },
+        key: ValueKey('textfield_list_item_note_entry_key'),
+      ),
+    );
   }
 
   final TransactionInfo transactionInfo;
@@ -209,14 +221,38 @@ abstract class TransactionDetailsViewModelBase with Store {
     final addressIndex = tx.additionalInfo['addressIndex'] as int;
     final feeFormatted = tx.feeFormatted();
     final _items = [
-      StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.txHash),
       StandartListItem(
-          title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
-      StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
-      StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
+        title: S.current.transaction_details_transaction_id,
+        value: tx.txHash,
+        key: ValueKey('standard_list_item_transaction_details_id_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_date,
+        value: dateFormat.format(tx.date),
+        key: ValueKey('standard_list_item_transaction_details_date_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_height,
+        value: '${tx.height}',
+        key: ValueKey('standard_list_item_transaction_details_height_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_amount,
+        value: tx.amountFormatted(),
+        key: ValueKey('standard_list_item_transaction_details_amount_key'),
+      ),
       if (feeFormatted != null)
-        StandartListItem(title: S.current.transaction_details_fee, value: feeFormatted),
-      if (key?.isNotEmpty ?? false) StandartListItem(title: S.current.transaction_key, value: key!),
+        StandartListItem(
+          title: S.current.transaction_details_fee,
+          value: feeFormatted,
+          key: ValueKey('standard_list_item_transaction_details_fee_key'),
+        ),
+      if (key?.isNotEmpty ?? false)
+        StandartListItem(
+          title: S.current.transaction_key,
+          value: key!,
+          key: ValueKey('standard_list_item_transaction_key'),
+        ),
     ];
 
     if (tx.direction == TransactionDirection.incoming) {
@@ -226,14 +262,21 @@ abstract class TransactionDetailsViewModelBase with Store {
 
         if (address.isNotEmpty) {
           isRecipientAddressShown = true;
-          _items.add(StandartListItem(
-            title: S.current.transaction_details_recipient_address,
-            value: address,
-          ));
+          _items.add(
+            StandartListItem(
+              title: S.current.transaction_details_recipient_address,
+              value: address,
+              key: ValueKey('standard_list_item_transaction_details_recipient_address_key'),
+            ),
+          );
         }
 
         if (label.isNotEmpty) {
-          _items.add(StandartListItem(title: S.current.address_label, value: label));
+          _items.add(StandartListItem(
+            title: S.current.address_label,
+            value: label,
+            key: ValueKey('standard_list_item_address_label_key'),
+          ));
         }
       } catch (e) {
         print(e.toString());
@@ -245,14 +288,37 @@ abstract class TransactionDetailsViewModelBase with Store {
 
   void _addElectrumListItems(TransactionInfo tx, DateFormat dateFormat) {
     final _items = [
-      StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.txHash),
       StandartListItem(
-          title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
-      StandartListItem(title: S.current.confirmations, value: tx.confirmations.toString()),
-      StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
-      StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
+        title: S.current.transaction_details_transaction_id,
+        value: tx.txHash,
+        key: ValueKey('standard_list_item_transaction_details_id_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_date,
+        value: dateFormat.format(tx.date),
+        key: ValueKey('standard_list_item_transaction_details_date_key'),
+      ),
+      StandartListItem(
+        title: S.current.confirmations,
+        value: tx.confirmations.toString(),
+        key: ValueKey('standard_list_item_transaction_confirmations_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_height,
+        value: '${tx.height}',
+        key: ValueKey('standard_list_item_transaction_details_height_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_amount,
+        value: tx.amountFormatted(),
+        key: ValueKey('standard_list_item_transaction_details_amount_key'),
+      ),
       if (tx.feeFormatted()?.isNotEmpty ?? false)
-        StandartListItem(title: S.current.transaction_details_fee, value: tx.feeFormatted()!),
+        StandartListItem(
+          title: S.current.transaction_details_fee,
+          value: tx.feeFormatted()!,
+          key: ValueKey('standard_list_item_transaction_details_fee_key'),
+        ),
     ];
 
     items.addAll(_items);
@@ -260,30 +326,80 @@ abstract class TransactionDetailsViewModelBase with Store {
 
   void _addHavenListItems(TransactionInfo tx, DateFormat dateFormat) {
     items.addAll([
-      StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.txHash),
       StandartListItem(
-          title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
-      StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
-      StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
+        title: S.current.transaction_details_transaction_id,
+        value: tx.txHash,
+        key: ValueKey('standard_list_item_transaction_details_id_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_date,
+        value: dateFormat.format(tx.date),
+        key: ValueKey('standard_list_item_transaction_details_date_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_height,
+        value: '${tx.height}',
+        key: ValueKey('standard_list_item_transaction_details_height_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_amount,
+        value: tx.amountFormatted(),
+        key: ValueKey('standard_list_item_transaction_details_amount_key'),
+      ),
       if (tx.feeFormatted()?.isNotEmpty ?? false)
-        StandartListItem(title: S.current.transaction_details_fee, value: tx.feeFormatted()!),
+        StandartListItem(
+          title: S.current.transaction_details_fee,
+          value: tx.feeFormatted()!,
+          key: ValueKey('standard_list_item_transaction_details_fee_key'),
+        ),
     ]);
   }
 
   void _addEthereumListItems(TransactionInfo tx, DateFormat dateFormat) {
     final _items = [
-      StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.txHash),
       StandartListItem(
-          title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
-      StandartListItem(title: S.current.confirmations, value: tx.confirmations.toString()),
-      StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
-      StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
+        title: S.current.transaction_details_transaction_id,
+        value: tx.txHash,
+        key: ValueKey('standard_list_item_transaction_details_id_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_date,
+        value: dateFormat.format(tx.date),
+        key: ValueKey('standard_list_item_transaction_details_date_key'),
+      ),
+      StandartListItem(
+        title: S.current.confirmations,
+        value: tx.confirmations.toString(),
+        key: ValueKey('standard_list_item_transaction_confirmations_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_height,
+        value: '${tx.height}',
+        key: ValueKey('standard_list_item_transaction_details_height_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_amount,
+        value: tx.amountFormatted(),
+        key: ValueKey('standard_list_item_transaction_details_amount_key'),
+      ),
       if (tx.feeFormatted()?.isNotEmpty ?? false)
-        StandartListItem(title: S.current.transaction_details_fee, value: tx.feeFormatted()!),
+        StandartListItem(
+          title: S.current.transaction_details_fee,
+          value: tx.feeFormatted()!,
+          key: ValueKey('standard_list_item_transaction_details_fee_key'),
+        ),
       if (showRecipientAddress && tx.to != null)
-        StandartListItem(title: S.current.transaction_details_recipient_address, value: tx.to!),
+        StandartListItem(
+          title: S.current.transaction_details_recipient_address,
+          value: tx.to!,
+          key: ValueKey('standard_list_item_transaction_details_recipient_address_key'),
+        ),
       if (tx.direction == TransactionDirection.incoming && tx.from != null)
-        StandartListItem(title: S.current.transaction_details_source_address, value: tx.from!),
+        StandartListItem(
+          title: S.current.transaction_details_source_address,
+          value: tx.from!,
+          key: ValueKey('standard_list_item_transaction_details_source_address_key'),
+        ),
     ];
 
     items.addAll(_items);
@@ -291,16 +407,43 @@ abstract class TransactionDetailsViewModelBase with Store {
 
   void _addNanoListItems(TransactionInfo tx, DateFormat dateFormat) {
     final _items = [
-      StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.txHash),
-      if (showRecipientAddress && tx.to != null)
-        StandartListItem(title: S.current.transaction_details_recipient_address, value: tx.to!),
-      if (showRecipientAddress && tx.from != null)
-        StandartListItem(title: S.current.transaction_details_source_address, value: tx.from!),
-      StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
       StandartListItem(
-          title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
-      StandartListItem(title: S.current.confirmed_tx, value: (tx.confirmations > 0).toString()),
-      StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
+        title: S.current.transaction_details_transaction_id,
+        value: tx.txHash,
+        key: ValueKey('standard_list_item_transaction_details_id_key'),
+      ),
+      if (showRecipientAddress && tx.to != null)
+        StandartListItem(
+          title: S.current.transaction_details_recipient_address,
+          value: tx.to!,
+          key: ValueKey('standard_list_item_transaction_details_recipient_address_key'),
+        ),
+      if (showRecipientAddress && tx.from != null)
+        StandartListItem(
+          title: S.current.transaction_details_source_address,
+          value: tx.from!,
+          key: ValueKey('standard_list_item_transaction_details_source_address_key'),
+        ),
+      StandartListItem(
+        title: S.current.transaction_details_amount,
+        value: tx.amountFormatted(),
+        key: ValueKey('standard_list_item_transaction_details_amount_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_date,
+        value: dateFormat.format(tx.date),
+        key: ValueKey('standard_list_item_transaction_details_date_key'),
+      ),
+      StandartListItem(
+        title: S.current.confirmed_tx,
+        value: (tx.confirmations > 0).toString(),
+        key: ValueKey('standard_list_item_transaction_confirmed_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_height,
+        value: '${tx.height}',
+        key: ValueKey('standard_list_item_transaction_details_height_key'),
+      ),
     ];
 
     items.addAll(_items);
@@ -308,18 +451,49 @@ abstract class TransactionDetailsViewModelBase with Store {
 
   void _addPolygonListItems(TransactionInfo tx, DateFormat dateFormat) {
     final _items = [
-      StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.txHash),
       StandartListItem(
-          title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
-      StandartListItem(title: S.current.confirmations, value: tx.confirmations.toString()),
-      StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
-      StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
+        title: S.current.transaction_details_transaction_id,
+        value: tx.txHash,
+        key: ValueKey('standard_list_item_transaction_details_id_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_date,
+        value: dateFormat.format(tx.date),
+        key: ValueKey('standard_list_item_transaction_details_date_key'),
+      ),
+      StandartListItem(
+        title: S.current.confirmations,
+        value: tx.confirmations.toString(),
+        key: ValueKey('standard_list_item_transaction_confirmations_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_height,
+        value: '${tx.height}',
+        key: ValueKey('standard_list_item_transaction_details_height_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_amount,
+        value: tx.amountFormatted(),
+        key: ValueKey('standard_list_item_transaction_details_amount_key'),
+      ),
       if (tx.feeFormatted()?.isNotEmpty ?? false)
-        StandartListItem(title: S.current.transaction_details_fee, value: tx.feeFormatted()!),
+        StandartListItem(
+          title: S.current.transaction_details_fee,
+          value: tx.feeFormatted()!,
+          key: ValueKey('standard_list_item_transaction_details_fee_key'),
+        ),
       if (showRecipientAddress && tx.to != null && tx.direction == TransactionDirection.outgoing)
-        StandartListItem(title: S.current.transaction_details_recipient_address, value: tx.to!),
+        StandartListItem(
+          title: S.current.transaction_details_recipient_address,
+          value: tx.to!,
+          key: ValueKey('standard_list_item_transaction_details_recipient_address_key'),
+        ),
       if (tx.direction == TransactionDirection.incoming && tx.from != null)
-        StandartListItem(title: S.current.transaction_details_source_address, value: tx.from!),
+        StandartListItem(
+          title: S.current.transaction_details_source_address,
+          value: tx.from!,
+          key: ValueKey('standard_list_item_transaction_details_source_address_key'),
+        ),
     ];
 
     items.addAll(_items);
@@ -327,16 +501,39 @@ abstract class TransactionDetailsViewModelBase with Store {
 
   void _addSolanaListItems(TransactionInfo tx, DateFormat dateFormat) {
     final _items = [
-      StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.txHash),
       StandartListItem(
-          title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
-      StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
+        title: S.current.transaction_details_transaction_id,
+        value: tx.txHash,
+        key: ValueKey('standard_list_item_transaction_details_id_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_date,
+        value: dateFormat.format(tx.date),
+        key: ValueKey('standard_list_item_transaction_details_date_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_amount,
+        value: tx.amountFormatted(),
+        key: ValueKey('standard_list_item_transaction_details_amount_key'),
+      ),
       if (tx.feeFormatted()?.isNotEmpty ?? false)
-        StandartListItem(title: S.current.transaction_details_fee, value: tx.feeFormatted()!),
+        StandartListItem(
+          title: S.current.transaction_details_fee,
+          value: tx.feeFormatted()!,
+          key: ValueKey('standard_list_item_transaction_details_fee_key'),
+        ),
       if (showRecipientAddress && tx.to != null)
-        StandartListItem(title: S.current.transaction_details_recipient_address, value: tx.to!),
+        StandartListItem(
+          title: S.current.transaction_details_recipient_address,
+          value: tx.to!,
+          key: ValueKey('standard_list_item_transaction_details_recipient_address_key'),
+        ),
       if (tx.from != null)
-        StandartListItem(title: S.current.transaction_details_source_address, value: tx.from!),
+        StandartListItem(
+          title: S.current.transaction_details_source_address,
+          value: tx.from!,
+          key: ValueKey('standard_list_item_transaction_details_source_address_key'),
+        ),
     ];
 
     items.addAll(_items);
@@ -354,7 +551,13 @@ abstract class TransactionDetailsViewModelBase with Store {
     newFee = bitcoin!.getFeeAmountForPriority(
         wallet, bitcoin!.getBitcoinTransactionPriorityMedium(), inputsCount, outputsCount);
 
-    RBFListItems.add(StandartListItem(title: S.current.old_fee, value: tx.feeFormatted() ?? '0.0'));
+    RBFListItems.add(
+      StandartListItem(
+        title: S.current.old_fee,
+        value: tx.feeFormatted() ?? '0.0',
+        key: ValueKey('standard_list_item_rbf_old_fee_key'),
+      ),
+    );
 
     if (transactionInfo.fee != null && rawTransaction.isNotEmpty) {
       final size = bitcoin!.getTransactionVSize(wallet, rawTransaction);
@@ -371,7 +574,9 @@ abstract class TransactionDetailsViewModelBase with Store {
     final customItemIndex = customItem != null ? priorities.indexOf(customItem) : null;
     final maxCustomFeeRate = sendViewModel.maxCustomFeeRate?.toDouble();
 
-    RBFListItems.add(StandardPickerListItem(
+    RBFListItems.add(
+      StandardPickerListItem(
+        key: ValueKey('standard_picker_list_item_transaction_priorities_key'),
         title: S.current.estimated_new_fee,
         value: bitcoin!.formatterBitcoinAmountToString(amount: newFee) +
             ' ${walletTypeToCryptoCurrency(wallet.type)}',
@@ -387,42 +592,73 @@ abstract class TransactionDetailsViewModelBase with Store {
         onItemSelected: (dynamic item, double sliderValue) {
           transactionPriority = item as TransactionPriority;
           return setNewFee(value: sliderValue, priority: transactionPriority!);
-        }));
+        },
+      ),
+    );
 
     if (transactionInfo.inputAddresses != null && transactionInfo.inputAddresses!.isNotEmpty) {
-      RBFListItems.add(StandardExpandableListItem(
-          title: S.current.inputs, expandableItems: transactionInfo.inputAddresses!));
+      RBFListItems.add(
+        StandardExpandableListItem(
+          key: ValueKey('standard_expandable_list_item_transaction_input_addresses_key'),
+          title: S.current.inputs,
+          expandableItems: transactionInfo.inputAddresses!,
+        ),
+      );
     }
 
     if (transactionInfo.outputAddresses != null && transactionInfo.outputAddresses!.isNotEmpty) {
       final outputAddresses = transactionInfo.outputAddresses!.map((element) {
         if (element.contains('OP_RETURN:') && element.length > 40) {
-            return element.substring(0, 40) + '...';
+          return element.substring(0, 40) + '...';
         }
         return element;
       }).toList();
 
       RBFListItems.add(
-          StandardExpandableListItem(title: S.current.outputs, expandableItems: outputAddresses));
+        StandardExpandableListItem(
+          title: S.current.outputs,
+          expandableItems: outputAddresses,
+          key: ValueKey('standard_expandable_list_item_transaction_output_addresses_key'),
+        ),
+      );
     }
   }
 
   void _addTronListItems(TransactionInfo tx, DateFormat dateFormat) {
     final _items = [
-      StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.txHash),
       StandartListItem(
-          title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
-      StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
+        title: S.current.transaction_details_transaction_id,
+        value: tx.txHash,
+        key: ValueKey('standard_list_item_transaction_details_id_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_date,
+        value: dateFormat.format(tx.date),
+        key: ValueKey('standard_list_item_transaction_details_date_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_amount,
+        value: tx.amountFormatted(),
+        key: ValueKey('standard_list_item_transaction_details_amount_key'),
+      ),
       if (tx.feeFormatted()?.isNotEmpty ?? false)
-        StandartListItem(title: S.current.transaction_details_fee, value: tx.feeFormatted()!),
+        StandartListItem(
+          title: S.current.transaction_details_fee,
+          value: tx.feeFormatted()!,
+          key: ValueKey('standard_list_item_transaction_details_fee_key'),
+        ),
       if (showRecipientAddress && tx.to != null)
         StandartListItem(
-            title: S.current.transaction_details_recipient_address,
-            value: tron!.getTronBase58Address(tx.to!, wallet)),
+          title: S.current.transaction_details_recipient_address,
+          value: tron!.getTronBase58Address(tx.to!, wallet),
+          key: ValueKey('standard_list_item_transaction_details_recipient_address_key'),
+        ),
       if (tx.from != null)
         StandartListItem(
-            title: S.current.transaction_details_source_address,
-            value: tron!.getTronBase58Address(tx.from!, wallet)),
+          title: S.current.transaction_details_source_address,
+          value: tron!.getTronBase58Address(tx.from!, wallet),
+          key: ValueKey('standard_list_item_transaction_details_source_address_key'),
+        ),
     ];
 
     items.addAll(_items);
@@ -455,7 +691,7 @@ abstract class TransactionDetailsViewModelBase with Store {
     return bitcoin!.formatterBitcoinAmountToString(amount: newFee);
   }
 
-  void replaceByFee(String newFee) => sendViewModel.replaceByFee(transactionInfo, newFee,);
+  void replaceByFee(String newFee) => sendViewModel.replaceByFee(transactionInfo, newFee);
 
   @computed
   String get pendingTransactionFiatAmountValueFormatted => sendViewModel.isFiatDisabled
@@ -473,14 +709,38 @@ abstract class TransactionDetailsViewModelBase with Store {
     final addressIndex = tx.additionalInfo['addressIndex'] as int;
     final feeFormatted = tx.feeFormatted();
     final _items = [
-      StandartListItem(title: S.current.transaction_details_transaction_id, value: tx.txHash),
       StandartListItem(
-          title: S.current.transaction_details_date, value: dateFormat.format(tx.date)),
-      StandartListItem(title: S.current.transaction_details_height, value: '${tx.height}'),
-      StandartListItem(title: S.current.transaction_details_amount, value: tx.amountFormatted()),
+        title: S.current.transaction_details_transaction_id,
+        value: tx.txHash,
+        key: ValueKey('standard_list_item_transaction_details_id_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_date,
+        value: dateFormat.format(tx.date),
+        key: ValueKey('standard_list_item_transaction_details_date_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_height,
+        value: '${tx.height}',
+        key: ValueKey('standard_list_item_transaction_details_height_key'),
+      ),
+      StandartListItem(
+        title: S.current.transaction_details_amount,
+        value: tx.amountFormatted(),
+        key: ValueKey('standard_list_item_transaction_details_amount_key'),
+      ),
       if (feeFormatted != null)
-        StandartListItem(title: S.current.transaction_details_fee, value: feeFormatted),
-      if (key?.isNotEmpty ?? false) StandartListItem(title: S.current.transaction_key, value: key!),
+        StandartListItem(
+          title: S.current.transaction_details_fee,
+          value: feeFormatted,
+          key: ValueKey('standard_list_item_transaction_details_fee_key'),
+        ),
+      if (key?.isNotEmpty ?? false)
+        StandartListItem(
+          title: S.current.transaction_key,
+          value: key!,
+          key: ValueKey('standard_list_item_transaction_key'),
+        ),
     ];
 
     if (tx.direction == TransactionDirection.incoming) {
@@ -490,14 +750,23 @@ abstract class TransactionDetailsViewModelBase with Store {
 
         if (address.isNotEmpty) {
           isRecipientAddressShown = true;
-          _items.add(StandartListItem(
-            title: S.current.transaction_details_recipient_address,
-            value: address,
-          ));
+          _items.add(
+            StandartListItem(
+              title: S.current.transaction_details_recipient_address,
+              value: address,
+              key: ValueKey('standard_list_item_transaction_details_recipient_address_key'),
+            ),
+          );
         }
 
         if (label.isNotEmpty) {
-          _items.add(StandartListItem(title: S.current.address_label, value: label));
+          _items.add(
+            StandartListItem(
+              title: S.current.address_label,
+              value: label,
+              key: ValueKey('standard_list_item_address_label_key'),
+            ),
+          );
         }
       } catch (e) {
         print(e.toString());
diff --git a/lib/view_model/wallet_keys_view_model.dart b/lib/view_model/wallet_keys_view_model.dart
index 9921ae30a..6455fc0e3 100644
--- a/lib/view_model/wallet_keys_view_model.dart
+++ b/lib/view_model/wallet_keys_view_model.dart
@@ -10,6 +10,7 @@ import 'package:cw_core/transaction_info.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:cw_monero/monero_wallet.dart';
+import 'package:flutter/foundation.dart';
 import 'package:mobx/mobx.dart';
 import 'package:polyseed/polyseed.dart';
 
@@ -24,6 +25,7 @@ abstract class WalletKeysViewModelBase with Store {
                 _appStore.wallet!.type == WalletType.bitcoinCash
             ? S.current.wallet_seed
             : S.current.wallet_keys,
+        _walletName = _appStore.wallet!.type.name,
         _restoreHeight = _appStore.wallet!.walletInfo.restoreHeight,
         _restoreHeightByTransactions = 0,
         items = ObservableList<StandartListItem>() {
@@ -38,12 +40,10 @@ abstract class WalletKeysViewModelBase with Store {
         _appStore.wallet!.type == WalletType.wownero) {
       final accountTransactions = _getWalletTransactions(_appStore.wallet!);
       if (accountTransactions.isNotEmpty) {
-        final incomingAccountTransactions = accountTransactions
-            .where((tx) => tx.direction == TransactionDirection.incoming);
+        final incomingAccountTransactions =
+            accountTransactions.where((tx) => tx.direction == TransactionDirection.incoming);
         if (incomingAccountTransactions.isNotEmpty) {
-          incomingAccountTransactions
-              .toList()
-              .sort((a, b) => a.date.compareTo(b.date));
+          incomingAccountTransactions.toList().sort((a, b) => a.date.compareTo(b.date));
           _restoreHeightByTransactions = _getRestoreHeightByTransactions(
               _appStore.wallet!.type, incomingAccountTransactions.first.date);
         }
@@ -55,6 +55,10 @@ abstract class WalletKeysViewModelBase with Store {
 
   final String title;
 
+  final String _walletName;
+
+  AppStore get appStore => _appStore;
+
   final AppStore _appStore;
 
   final int _restoreHeight;
@@ -70,37 +74,56 @@ abstract class WalletKeysViewModelBase with Store {
       items.addAll([
         if (keys['publicSpendKey'] != null)
           StandartListItem(
-              title: S.current.spend_key_public,
-              value: keys['publicSpendKey']!),
+            key: ValueKey('${_walletName}_wallet_public_spend_key_item_key'),
+            title: S.current.spend_key_public,
+            value: keys['publicSpendKey']!,
+          ),
         if (keys['privateSpendKey'] != null)
           StandartListItem(
-              title: S.current.spend_key_private,
-              value: keys['privateSpendKey']!),
+            key: ValueKey('${_walletName}_wallet_private_spend_key_item_key'),
+            title: S.current.spend_key_private,
+            value: keys['privateSpendKey']!,
+          ),
         if (keys['publicViewKey'] != null)
           StandartListItem(
-              title: S.current.view_key_public, value: keys['publicViewKey']!),
+            key: ValueKey('${_walletName}_wallet_public_view_key_item_key'),
+            title: S.current.view_key_public,
+            value: keys['publicViewKey']!,
+          ),
         if (keys['privateViewKey'] != null)
           StandartListItem(
-              title: S.current.view_key_private,
-              value: keys['privateViewKey']!),
+            key: ValueKey('${_walletName}_wallet_private_view_key_item_key'),
+            title: S.current.view_key_private,
+            value: keys['privateViewKey']!,
+          ),
         if (_appStore.wallet!.seed!.isNotEmpty)
-          StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
+          StandartListItem(
+            key: ValueKey('${_walletName}_wallet_seed_item_key'),
+            title: S.current.wallet_seed,
+            value: _appStore.wallet!.seed!,
+          ),
       ]);
 
-      if (_appStore.wallet?.seed != null &&
-          Polyseed.isValidSeed(_appStore.wallet!.seed!)) {
+      if (_appStore.wallet?.seed != null && Polyseed.isValidSeed(_appStore.wallet!.seed!)) {
         final lang = PolyseedLang.getByPhrase(_appStore.wallet!.seed!);
-        items.add(StandartListItem(
+        items.add(
+          StandartListItem(
+            key: ValueKey('${_walletName}_wallet_seed_legacy_item_key'),
             title: S.current.wallet_seed_legacy,
-            value: (_appStore.wallet as MoneroWalletBase)
-                .seedLegacy(lang.nameEnglish)));
+            value: (_appStore.wallet as MoneroWalletBase).seedLegacy(lang.nameEnglish),
+          ),
+        );
       }
 
       final restoreHeight = monero!.getRestoreHeight(_appStore.wallet!);
       if (restoreHeight != null) {
-        items.add(StandartListItem(
+        items.add(
+          StandartListItem(
+            key: ValueKey('${_walletName}_wallet_restore_height_item_key'),
             title: S.current.wallet_recovery_height,
-            value: restoreHeight.toString()));
+            value: restoreHeight.toString(),
+          ),
+        );
       }
     }
 
@@ -110,21 +133,34 @@ abstract class WalletKeysViewModelBase with Store {
       items.addAll([
         if (keys['publicSpendKey'] != null)
           StandartListItem(
-              title: S.current.spend_key_public,
-              value: keys['publicSpendKey']!),
+            key: ValueKey('${_walletName}_wallet_public_spend_key_item_key'),
+            title: S.current.spend_key_public,
+            value: keys['publicSpendKey']!,
+          ),
         if (keys['privateSpendKey'] != null)
           StandartListItem(
-              title: S.current.spend_key_private,
-              value: keys['privateSpendKey']!),
+            key: ValueKey('${_walletName}_wallet_private_spend_key_item_key'),
+            title: S.current.spend_key_private,
+            value: keys['privateSpendKey']!,
+          ),
         if (keys['publicViewKey'] != null)
           StandartListItem(
-              title: S.current.view_key_public, value: keys['publicViewKey']!),
+            key: ValueKey('${_walletName}_wallet_public_view_key_item_key'),
+            title: S.current.view_key_public,
+            value: keys['publicViewKey']!,
+          ),
         if (keys['privateViewKey'] != null)
           StandartListItem(
-              title: S.current.view_key_private,
-              value: keys['privateViewKey']!),
+            key: ValueKey('${_walletName}_wallet_private_view_key_item_key'),
+            title: S.current.view_key_private,
+            value: keys['privateViewKey']!,
+          ),
         if (_appStore.wallet!.seed!.isNotEmpty)
-          StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
+          StandartListItem(
+            key: ValueKey('${_walletName}_wallet_seed_item_key'),
+            title: S.current.wallet_seed,
+            value: _appStore.wallet!.seed!,
+          ),
       ]);
     }
 
@@ -134,29 +170,45 @@ abstract class WalletKeysViewModelBase with Store {
       items.addAll([
         if (keys['publicSpendKey'] != null)
           StandartListItem(
-              title: S.current.spend_key_public,
-              value: keys['publicSpendKey']!),
+            key: ValueKey('${_walletName}_wallet_public_spend_key_item_key'),
+            title: S.current.spend_key_public,
+            value: keys['publicSpendKey']!,
+          ),
         if (keys['privateSpendKey'] != null)
           StandartListItem(
-              title: S.current.spend_key_private,
-              value: keys['privateSpendKey']!),
+            key: ValueKey('${_walletName}_wallet_private_spend_key_item_key'),
+            title: S.current.spend_key_private,
+            value: keys['privateSpendKey']!,
+          ),
         if (keys['publicViewKey'] != null)
           StandartListItem(
-              title: S.current.view_key_public, value: keys['publicViewKey']!),
+            key: ValueKey('${_walletName}_wallet_public_view_key_item_key'),
+            title: S.current.view_key_public,
+            value: keys['publicViewKey']!,
+          ),
         if (keys['privateViewKey'] != null)
           StandartListItem(
-              title: S.current.view_key_private,
-              value: keys['privateViewKey']!),
+            key: ValueKey('${_walletName}_wallet_private_view_key_item_key'),
+            title: S.current.view_key_private,
+            value: keys['privateViewKey']!,
+          ),
         if (_appStore.wallet!.seed!.isNotEmpty)
-          StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
+          StandartListItem(
+            key: ValueKey('${_walletName}_wallet_seed_item_key'),
+            title: S.current.wallet_seed,
+            value: _appStore.wallet!.seed!,
+          ),
       ]);
 
-      if (_appStore.wallet?.seed != null &&
-          Polyseed.isValidSeed(_appStore.wallet!.seed!)) {
+      if (_appStore.wallet?.seed != null && Polyseed.isValidSeed(_appStore.wallet!.seed!)) {
         final lang = PolyseedLang.getByPhrase(_appStore.wallet!.seed!);
-        items.add(StandartListItem(
+        items.add(
+          StandartListItem(
+            key: ValueKey('${_walletName}_wallet_seed_legacy_item_key'),
             title: S.current.wallet_seed_legacy,
-            value: wownero!.getLegacySeed(_appStore.wallet!, lang.nameEnglish)));
+            value: wownero!.getLegacySeed(_appStore.wallet!, lang.nameEnglish),
+          ),
+        );
       }
     }
 
@@ -173,7 +225,10 @@ abstract class WalletKeysViewModelBase with Store {
         // if (keys['publicKey'] != null)
         //   StandartListItem(title: S.current.public_key, value: keys['publicKey']!),
         StandartListItem(
-            title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
+          key: ValueKey('${_walletName}_wallet_seed_item_key'),
+          title: S.current.wallet_seed,
+          value: _appStore.wallet!.seed!,
+        ),
       ]);
     }
 
@@ -183,31 +238,43 @@ abstract class WalletKeysViewModelBase with Store {
       items.addAll([
         if (_appStore.wallet!.privateKey != null)
           StandartListItem(
-              title: S.current.private_key,
-              value: _appStore.wallet!.privateKey!),
+            key: ValueKey('${_walletName}_wallet_private_key_item_key'),
+            title: S.current.private_key,
+            value: _appStore.wallet!.privateKey!,
+          ),
         if (_appStore.wallet!.seed != null)
           StandartListItem(
-              title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
+            key: ValueKey('${_walletName}_wallet_seed_item_key'),
+            title: S.current.wallet_seed,
+            value: _appStore.wallet!.seed!,
+          ),
       ]);
     }
 
-    bool nanoBased = _appStore.wallet!.type == WalletType.nano ||
-        _appStore.wallet!.type == WalletType.banano;
+    bool nanoBased =
+        _appStore.wallet!.type == WalletType.nano || _appStore.wallet!.type == WalletType.banano;
 
     if (nanoBased) {
       // we always have the hex version of the seed and private key:
       items.addAll([
         if (_appStore.wallet!.seed != null)
           StandartListItem(
-              title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
+            key: ValueKey('${_walletName}_wallet_seed_item_key'),
+            title: S.current.wallet_seed,
+            value: _appStore.wallet!.seed!,
+          ),
         if (_appStore.wallet!.hexSeed != null)
           StandartListItem(
-              title: S.current.seed_hex_form,
-              value: _appStore.wallet!.hexSeed!),
+            key: ValueKey('${_walletName}_wallet_hex_seed_key'),
+            title: S.current.seed_hex_form,
+            value: _appStore.wallet!.hexSeed!,
+          ),
         if (_appStore.wallet!.privateKey != null)
           StandartListItem(
-              title: S.current.private_key,
-              value: _appStore.wallet!.privateKey!),
+            key: ValueKey('${_walletName}_wallet_private_key_item_key'),
+            title: S.current.private_key,
+            value: _appStore.wallet!.privateKey!,
+          ),
       ]);
     }
   }
@@ -273,8 +340,7 @@ abstract class WalletKeysViewModelBase with Store {
       if (_appStore.wallet!.seed != null) 'seed': _appStore.wallet!.seed!,
       if (_appStore.wallet!.seed == null && _appStore.wallet!.hexSeed != null)
         'hexSeed': _appStore.wallet!.hexSeed!,
-      if (_appStore.wallet!.seed == null &&
-          _appStore.wallet!.privateKey != null)
+      if (_appStore.wallet!.seed == null && _appStore.wallet!.privateKey != null)
         'private_key': _appStore.wallet!.privateKey!,
       if (restoreHeightResult != null) ...{'height': restoreHeightResult},
       if (_appStore.wallet!.passphrase != null) 'passphrase': _appStore.wallet!.passphrase!
@@ -292,11 +358,7 @@ abstract class WalletKeysViewModelBase with Store {
     } else if (wallet.type == WalletType.haven) {
       return haven!.getTransactionHistory(wallet).transactions.values.toList();
     } else if (wallet.type == WalletType.wownero) {
-      return wownero!
-          .getTransactionHistory(wallet)
-          .transactions
-          .values
-          .toList();
+      return wownero!.getTransactionHistory(wallet).transactions.values.toList();
     }
     return [];
   }
@@ -312,6 +374,5 @@ abstract class WalletKeysViewModelBase with Store {
     return 0;
   }
 
-  String getRoundedRestoreHeight(int height) =>
-      ((height / 1000).floor() * 1000).toString();
+  String getRoundedRestoreHeight(int height) => ((height / 1000).floor() * 1000).toString();
 }
diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart
index d3b652935..88cbbfce3 100644
--- a/tool/utils/secret_key.dart
+++ b/tool/utils/secret_key.dart
@@ -44,12 +44,35 @@ class SecretKey {
     SecretKey('cakePayApiKey', () => ''),
     SecretKey('CSRFToken', () => ''),
     SecretKey('authorization', () => ''),
+    SecretKey('moneroTestWalletSeeds', () => ''),
+    SecretKey('moneroLegacyTestWalletSeeds ', () => ''),
+    SecretKey('bitcoinTestWalletSeeds', () => ''),
+    SecretKey('ethereumTestWalletSeeds', () => ''),
+    SecretKey('litecoinTestWalletSeeds', () => ''),
+    SecretKey('bitcoinCashTestWalletSeeds', () => ''),
+    SecretKey('polygonTestWalletSeeds', () => ''),
+    SecretKey('solanaTestWalletSeeds', () => ''),
+    SecretKey('polygonTestWalletSeeds', () => ''),
+    SecretKey('tronTestWalletSeeds', () => ''),
+    SecretKey('nanoTestWalletSeeds', () => ''),
+    SecretKey('wowneroTestWalletSeeds', () => ''),
+    SecretKey('moneroTestWalletReceiveAddress', () => ''),
+    SecretKey('bitcoinTestWalletReceiveAddress', () => ''),
+    SecretKey('ethereumTestWalletReceiveAddress', () => ''),
+    SecretKey('litecoinTestWalletReceiveAddress', () => ''),
+    SecretKey('bitco inCashTestWalletReceiveAddress', () => ''),
+    SecretKey('polygonTestWalletReceiveAddress', () => ''),
+    SecretKey('solanaTestWalletReceiveAddress', () => ''),
+    SecretKey('tronTestWalletReceiveAddress', () => ''),
+    SecretKey('nanoTestWalletReceiveAddress', () => ''),
+    SecretKey('wowneroTestWalletReceiveAddress', () => ''),
     SecretKey('etherScanApiKey', () => ''),
     SecretKey('polygonScanApiKey', () => ''),
     SecretKey('letsExchangeBearerToken', () => ''),
     SecretKey('letsExchangeAffiliateId', () => ''),
     SecretKey('stealthExBearerToken', () => ''),
     SecretKey('stealthExAdditionalFeePercent', () => ''),
+    SecretKey('moneroTestWalletBlockHeight', () => ''),
   ];
 
   static final evmChainsSecrets = [

From 389c334f1076779a134cd037b2af5b1b1c11df2b Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Fri, 8 Nov 2024 12:50:21 +0200
Subject: [PATCH 05/15] Electrum enhancements (#1794)

* Enhance the code for sending/sending-ALL for Electrum

* remove prints [skip ci]
---
 cw_bitcoin/lib/electrum_wallet.dart | 159 +++++++++++-----------------
 cw_bitcoin/pubspec.lock             |   4 +-
 2 files changed, 63 insertions(+), 100 deletions(-)

diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 7988a4479..6245aa787 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -11,7 +11,6 @@ import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:collection/collection.dart';
 import 'package:cw_bitcoin/address_from_output.dart';
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
-import 'package:cw_bitcoin/bitcoin_amount_format.dart';
 import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
 import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
 import 'package:cw_bitcoin/bitcoin_unspent.dart';
@@ -597,8 +596,8 @@ abstract class ElectrumWalletBase
 
   UtxoDetails _createUTXOS({
     required bool sendAll,
-    required int credentialsAmount,
     required bool paysToSilentPayment,
+    int credentialsAmount = 0,
     int? inputsCount,
     UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any,
   }) {
@@ -732,13 +731,11 @@ abstract class ElectrumWalletBase
     List<BitcoinOutput> outputs,
     int feeRate, {
     String? memo,
-    int credentialsAmount = 0,
     bool hasSilentPayment = false,
     UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any,
   }) async {
     final utxoDetails = _createUTXOS(
       sendAll: true,
-      credentialsAmount: credentialsAmount,
       paysToSilentPayment: hasSilentPayment,
       coinTypeToSpendFrom: coinTypeToSpendFrom,
     );
@@ -764,23 +761,11 @@ abstract class ElectrumWalletBase
       throw BitcoinTransactionWrongBalanceException(amount: utxoDetails.allInputsAmount + fee);
     }
 
-    if (amount <= 0) {
-      throw BitcoinTransactionWrongBalanceException();
-    }
-
     // Attempting to send less than the dust limit
     if (_isBelowDust(amount)) {
       throw BitcoinTransactionNoDustException();
     }
 
-    if (credentialsAmount > 0) {
-      final amountLeftForFee = amount - credentialsAmount;
-      if (amountLeftForFee > 0 && _isBelowDust(amountLeftForFee)) {
-        amount -= amountLeftForFee;
-        fee += amountLeftForFee;
-      }
-    }
-
     if (outputs.length == 1) {
       outputs[0] = BitcoinOutput(address: outputs.last.address, value: BigInt.from(amount));
     }
@@ -810,6 +795,11 @@ abstract class ElectrumWalletBase
     bool hasSilentPayment = false,
     UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any,
   }) async {
+    // Attempting to send less than the dust limit
+    if (_isBelowDust(credentialsAmount)) {
+      throw BitcoinTransactionNoDustException();
+    }
+
     final utxoDetails = _createUTXOS(
       sendAll: false,
       credentialsAmount: credentialsAmount,
@@ -894,7 +884,43 @@ abstract class ElectrumWalletBase
     final lastOutput = updatedOutputs.last;
     final amountLeftForChange = amountLeftForChangeAndFee - fee;
 
-    if (!_isBelowDust(amountLeftForChange)) {
+    if (_isBelowDust(amountLeftForChange)) {
+      // If has change that is lower than dust, will end up with tx rejected by network rules
+      // so remove the change amount
+      updatedOutputs.removeLast();
+      outputs.removeLast();
+
+      if (amountLeftForChange < 0) {
+        if (!spendingAllCoins) {
+          return estimateTxForAmount(
+            credentialsAmount,
+            outputs,
+            updatedOutputs,
+            feeRate,
+            inputsCount: utxoDetails.utxos.length + 1,
+            memo: memo,
+            useUnconfirmed: useUnconfirmed ?? spendingAllConfirmedCoins,
+            hasSilentPayment: hasSilentPayment,
+            coinTypeToSpendFrom: coinTypeToSpendFrom,
+          );
+        } else {
+          throw BitcoinTransactionWrongBalanceException();
+        }
+      }
+
+      return EstimatedTxResult(
+        utxos: utxoDetails.utxos,
+        inputPrivKeyInfos: utxoDetails.inputPrivKeyInfos,
+        publicKeys: utxoDetails.publicKeys,
+        fee: fee,
+        amount: amount,
+        hasChange: false,
+        isSendAll: spendingAllCoins,
+        memo: memo,
+        spendsUnconfirmedTX: utxoDetails.spendsUnconfirmedTX,
+        spendsSilentPayment: utxoDetails.spendsSilentPayment,
+      );
+    } else {
       // Here, lastOutput already is change, return the amount left without the fee to the user's address.
       updatedOutputs[updatedOutputs.length - 1] = BitcoinOutput(
         address: lastOutput.address,
@@ -908,88 +934,20 @@ abstract class ElectrumWalletBase
         isSilentPayment: lastOutput.isSilentPayment,
         isChange: true,
       );
-    } else {
-      // If has change that is lower than dust, will end up with tx rejected by network rules, so estimate again without the added change
-      updatedOutputs.removeLast();
-      outputs.removeLast();
 
-      // Still has inputs to spend before failing
-      if (!spendingAllCoins) {
-        return estimateTxForAmount(
-          credentialsAmount,
-          outputs,
-          updatedOutputs,
-          feeRate,
-          inputsCount: utxoDetails.utxos.length + 1,
-          memo: memo,
-          hasSilentPayment: hasSilentPayment,
-          useUnconfirmed: useUnconfirmed ?? spendingAllConfirmedCoins,
-          coinTypeToSpendFrom: coinTypeToSpendFrom,
-        );
-      }
-
-      final estimatedSendAll = await estimateSendAllTx(
-        updatedOutputs,
-        feeRate,
+      return EstimatedTxResult(
+        utxos: utxoDetails.utxos,
+        inputPrivKeyInfos: utxoDetails.inputPrivKeyInfos,
+        publicKeys: utxoDetails.publicKeys,
+        fee: fee,
+        amount: amount,
+        hasChange: true,
+        isSendAll: spendingAllCoins,
         memo: memo,
-        coinTypeToSpendFrom: coinTypeToSpendFrom,
-      );
-
-      if (estimatedSendAll.amount == credentialsAmount) {
-        return estimatedSendAll;
-      }
-
-      // Estimate to user how much is needed to send to cover the fee
-      final maxAmountWithReturningChange = utxoDetails.allInputsAmount - _dustAmount - fee - 1;
-      throw BitcoinTransactionNoDustOnChangeException(
-        bitcoinAmountToString(amount: maxAmountWithReturningChange),
-        bitcoinAmountToString(amount: estimatedSendAll.amount),
+        spendsUnconfirmedTX: utxoDetails.spendsUnconfirmedTX,
+        spendsSilentPayment: utxoDetails.spendsSilentPayment,
       );
     }
-
-    // Attempting to send less than the dust limit
-    if (_isBelowDust(amount)) {
-      throw BitcoinTransactionNoDustException();
-    }
-
-    final totalAmount = amount + fee;
-
-    if (totalAmount > (balance[currency]!.confirmed + balance[currency]!.secondConfirmed)) {
-      throw BitcoinTransactionWrongBalanceException();
-    }
-
-    if (totalAmount > utxoDetails.allInputsAmount) {
-      if (spendingAllCoins) {
-        throw BitcoinTransactionWrongBalanceException();
-      } else {
-        updatedOutputs.removeLast();
-        outputs.removeLast();
-        return estimateTxForAmount(
-          credentialsAmount,
-          outputs,
-          updatedOutputs,
-          feeRate,
-          inputsCount: utxoDetails.utxos.length + 1,
-          memo: memo,
-          useUnconfirmed: useUnconfirmed ?? spendingAllConfirmedCoins,
-          hasSilentPayment: hasSilentPayment,
-          coinTypeToSpendFrom: coinTypeToSpendFrom,
-        );
-      }
-    }
-
-    return EstimatedTxResult(
-      utxos: utxoDetails.utxos,
-      inputPrivKeyInfos: utxoDetails.inputPrivKeyInfos,
-      publicKeys: utxoDetails.publicKeys,
-      fee: fee,
-      amount: amount,
-      hasChange: true,
-      isSendAll: false,
-      memo: memo,
-      spendsUnconfirmedTX: utxoDetails.spendsUnconfirmedTX,
-      spendsSilentPayment: utxoDetails.spendsSilentPayment,
-    );
   }
 
   Future<int> calcFee({
@@ -1080,15 +1038,20 @@ abstract class ElectrumWalletBase
           : feeRate(transactionCredentials.priority!);
 
       EstimatedTxResult estimatedTx;
-      final updatedOutputs =
-          outputs.map((e) => BitcoinOutput(address: e.address, value: e.value)).toList();
+      final updatedOutputs = outputs
+          .map((e) => BitcoinOutput(
+                address: e.address,
+                value: e.value,
+                isSilentPayment: e.isSilentPayment,
+                isChange: e.isChange,
+              ))
+          .toList();
 
       if (sendAll) {
         estimatedTx = await estimateSendAllTx(
           updatedOutputs,
           feeRateInt,
           memo: memo,
-          credentialsAmount: credentialsAmount,
           hasSilentPayment: hasSilentPayment,
           coinTypeToSpendFrom: coinTypeToSpendFrom,
         );
diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock
index 5cba9b734..0e4921a3a 100644
--- a/cw_bitcoin/pubspec.lock
+++ b/cw_bitcoin/pubspec.lock
@@ -568,10 +568,10 @@ packages:
     dependency: "direct main"
     description:
       name: ledger_flutter_plus
-      sha256: ea3ed586e1697776dacf42ac979095f1ca3bd143bf007cbe5c78e09cb6943f42
+      sha256: c7b04008553193dbca7e17b430768eecc372a72b0ff3625b5e7fc5e5c8d3231b
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.5"
+    version: "1.4.1"
   ledger_litecoin:
     dependency: "direct main"
     description:

From 8e12fb1ad9c4475abb846937946fc7c9ede6daf8 Mon Sep 17 00:00:00 2001
From: Rafael <github@rafael.saes.dev>
Date: Sat, 9 Nov 2024 02:20:06 -0300
Subject: [PATCH 06/15] fix: paymentUrls is null (#1786)

* fix: paymentUrls is null

* feat: potential secure storage error
---
 lib/cake_pay/cake_pay_order.dart                            | 1 -
 lib/cake_pay/cake_pay_service.dart                          | 6 ++++--
 .../cake_pay/cards/cake_pay_confirm_purchase_card_page.dart | 6 +++++-
 3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/lib/cake_pay/cake_pay_order.dart b/lib/cake_pay/cake_pay_order.dart
index 8cb6e784a..acdf86ea0 100644
--- a/lib/cake_pay/cake_pay_order.dart
+++ b/lib/cake_pay/cake_pay_order.dart
@@ -1,4 +1,3 @@
-
 class CakePayOrder {
   final String orderId;
   final List<OrderCard> cards;
diff --git a/lib/cake_pay/cake_pay_service.dart b/lib/cake_pay/cake_pay_service.dart
index 39f2ca77a..cf2ec254c 100644
--- a/lib/cake_pay/cake_pay_service.dart
+++ b/lib/cake_pay/cake_pay_service.dart
@@ -82,10 +82,12 @@ class CakePayService {
   }
 
   /// Logout
-  Future<void> logout(String email) async {
+  Future<void> logout([String? email]) async {
     await secureStorage.delete(key: cakePayUsernameStorageKey);
     await secureStorage.delete(key: cakePayUserTokenKey);
-    await cakePayApi.logoutUser(email: email, apiKey: cakePayApiKey);
+    if (email != null) {
+      await cakePayApi.logoutUser(email: email, apiKey: cakePayApiKey);
+    }
   }
 
   /// Purchase Gift Card
diff --git a/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart b/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart
index 81f6a354f..309c435a2 100644
--- a/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart
+++ b/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart
@@ -258,7 +258,11 @@ class CakePayBuyCardDetailPage extends BasePage {
     if (!isLogged) {
       Navigator.of(context).pushNamed(Routes.cakePayWelcomePage);
     } else {
-      await cakePayPurchaseViewModel.createOrder();
+      try {
+        await cakePayPurchaseViewModel.createOrder();
+      } catch (_) {
+        await cakePayPurchaseViewModel.cakePayService.logout();
+      }
     }
   }
 

From cea3084bb320dde27fbdbb78fba579311b58b704 Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Sat, 9 Nov 2024 19:59:47 +0100
Subject: [PATCH 07/15] WIP: CW-665 Implement AirGapped Monero Transactions
 (#1535)

* replace qr scanner with fast_scanner

* bump java version

* fix qr code scanning

* add flashlight and camera switch

* airgap work

* commitTransactionUR

* bump fast_scanner, fix configure script

* add option to restore wallet from NERO qr format

* fixes to the flow and logic
use gsed or otherwise it fails?

* remove Expanded() to fix URQR on release builds

* cache key to allow app updates

* rename cache key

* [skip ci] cache key.jks in cache_dependencies

* update fast_scanner to work on ios, with light mlkit dependency

* ui fixes

* error handling fix

* update fast_scanner to drop iOS dependency

* changes from review

* Update lib/entities/qr_scanner.dart

* changes from review

* remove useless commit

* don't set state multiple times
remove return Container() for non monero wallets

* return on fail
don't handle empty qr codes

* set node as trusted
display primary address in seed screen

* fix wow and haven

* migrate node to trusted

* - update trusted node for existing users
- update locales
- fix conflicts
- move menu item

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 .github/workflows/cache_dependencies.yml      |   3 +-
 .github/workflows/pr_test_build_android.yml   |   4 +-
 android/app/build.gradle                      |   5 +
 android/gradle.properties                     |   2 +-
 assets/node_list.yml                          |   1 +
 .../lib/pending_bitcoin_transaction.dart      |   5 +
 .../src/pending_bitcoin_cash_transaction.dart |   4 +
 cw_core/lib/monero_wallet_keys.dart           |   4 +-
 cw_core/lib/pending_transaction.dart          |   3 +
 cw_evm/lib/pending_evm_chain_transaction.dart |   5 +
 .../wallet_restore_from_keys_exception.dart   |   5 +
 cw_haven/lib/haven_wallet.dart                |   1 +
 cw_haven/lib/pending_haven_transaction.dart   |   5 +
 cw_monero/lib/api/account_list.dart           |   1 +
 cw_monero/lib/api/transaction_history.dart    |  24 +-
 cw_monero/lib/api/wallet_manager.dart         |   2 +
 cw_monero/lib/monero_wallet.dart              |  32 ++
 cw_monero/lib/pending_monero_transaction.dart |  24 +-
 cw_nano/lib/pending_nano_transaction.dart     |   5 +
 cw_shared_external/pubspec.lock               | 189 +++++++++
 cw_solana/lib/pending_solana_transaction.dart |   5 +
 cw_tron/lib/pending_tron_transaction.dart     |   5 +
 .../wallet_restore_from_keys_exception.dart   |   1 +
 .../lib/pending_wownero_transaction.dart      |   5 +
 cw_wownero/lib/wownero_wallet.dart            |   1 +
 lib/di.dart                                   |   7 +
 lib/entities/default_settings_migration.dart  |  15 +-
 lib/entities/qr_scanner.dart                  | 369 +++++++++++++++++-
 lib/main.dart                                 |   2 +-
 lib/monero/cw_monero.dart                     |  24 ++
 lib/router.dart                               |   4 +
 lib/routes.dart                               |   1 +
 .../cake_pay_confirm_purchase_card_page.dart  |   4 +-
 .../dashboard/widgets/menu_widget.dart        |   4 +-
 .../exchange_trade/exchange_trade_page.dart   |   2 +-
 lib/src/screens/send/send_page.dart           |   2 +-
 .../desktop_settings_page.dart                |   7 +-
 .../transaction_details/rbf_details_page.dart |   2 +-
 lib/src/screens/ur/animated_ur_page.dart      | 184 +++++++++
 .../wc_connections_listing_view.dart          |   2 +-
 lib/src/widgets/address_text_field.dart       |   2 +-
 lib/src/widgets/setting_actions.dart          |  11 +
 lib/view_model/animated_ur_model.dart         |  10 +
 .../dashboard/dashboard_view_model.dart       |   6 +
 .../node_create_or_edit_view_model.dart       |   2 +-
 lib/view_model/restore/restore_wallet.dart    |  14 +-
 .../restore/wallet_restore_from_qr_code.dart  |  28 +-
 lib/view_model/send/send_view_model.dart      |  18 +-
 lib/view_model/wallet_keys_view_model.dart    |  12 +
 linux/flutter/generated_plugins.cmake         |   1 -
 macos/Flutter/GeneratedPluginRegistrant.swift |   4 +-
 macos/Podfile.lock                            |   6 +
 pubspec_base.yaml                             |   6 +-
 res/values/strings_ar.arb                     |  13 +-
 res/values/strings_bg.arb                     |  13 +-
 res/values/strings_cs.arb                     |  13 +-
 res/values/strings_de.arb                     |   8 +-
 res/values/strings_en.arb                     |  10 +-
 res/values/strings_es.arb                     |  13 +-
 res/values/strings_fr.arb                     |  13 +-
 res/values/strings_ha.arb                     |  13 +-
 res/values/strings_hi.arb                     |  13 +-
 res/values/strings_hr.arb                     |  13 +-
 res/values/strings_hy.arb                     |  16 +-
 res/values/strings_id.arb                     |  13 +-
 res/values/strings_it.arb                     |  13 +-
 res/values/strings_ja.arb                     |  13 +-
 res/values/strings_ko.arb                     |  13 +-
 res/values/strings_my.arb                     |  13 +-
 res/values/strings_nl.arb                     |  13 +-
 res/values/strings_pl.arb                     |  13 +-
 res/values/strings_pt.arb                     |  10 +-
 res/values/strings_ru.arb                     |  13 +-
 res/values/strings_th.arb                     |  13 +-
 res/values/strings_tl.arb                     |  10 +-
 res/values/strings_tr.arb                     |  13 +-
 res/values/strings_uk.arb                     |  13 +-
 res/values/strings_ur.arb                     |  13 +-
 res/values/strings_vi.arb                     |  16 +-
 res/values/strings_yo.arb                     |  13 +-
 res/values/strings_zh.arb                     |  13 +-
 scripts/macos/gen_common.sh                   |   4 +-
 tool/configure.dart                           |   8 +
 windows/flutter/generated_plugins.cmake       |   1 -
 84 files changed, 1318 insertions(+), 141 deletions(-)
 create mode 100644 cw_shared_external/pubspec.lock
 create mode 100644 lib/src/screens/ur/animated_ur_page.dart
 create mode 100644 lib/view_model/animated_ur_model.dart

diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml
index c0042bf5c..0fcd5c45b 100644
--- a/.github/workflows/cache_dependencies.yml
+++ b/.github/workflows/cache_dependencies.yml
@@ -62,10 +62,9 @@ jobs:
             /opt/android/cake_wallet/cw_haven/android/.cxx
             /opt/android/cake_wallet/scripts/monero_c/release
           key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
-
       - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
         name: Generate Externals
         run: |
           cd /opt/android/cake_wallet/scripts/android/
           source ./app_env.sh cakewallet
-          ./build_monero_all.sh
+          ./build_monero_all.sh
\ No newline at end of file
diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml
index c9021fac0..6d0e541ce 100644
--- a/.github/workflows/pr_test_build_android.yml
+++ b/.github/workflows/pr_test_build_android.yml
@@ -82,7 +82,8 @@ jobs:
           path: |
             /opt/android/cake_wallet/cw_haven/android/.cxx
             /opt/android/cake_wallet/scripts/monero_c/release
-          key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
+            /opt/android/cake_wallet/android/app/key.jks
+          key: android_${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
 
       - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
         name: Generate Externals
@@ -116,6 +117,7 @@ jobs:
           ./build_mwebd.sh --dont-install
 
       - name: Generate KeyStore
+        if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
         run: |
           cd /opt/android/cake_wallet/android/app
           keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 2f5427531..5005a8bab 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -92,3 +92,8 @@ dependencies {
     androidTestImplementation 'androidx.test:runner:1.3.0'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
 }
+configurations {
+    implementation.exclude module:'proto-google-common-protos'
+    implementation.exclude module:'protolite-well-known-types'
+    implementation.exclude module:'protobuf-javalite'
+}
\ No newline at end of file
diff --git a/android/gradle.properties b/android/gradle.properties
index 38c8d4544..66dd09454 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -1,4 +1,4 @@
-org.gradle.jvmargs=-Xmx1536M
+org.gradle.jvmargs=-Xmx3072M
 android.enableR8=true
 android.useAndroidX=true
 android.enableJetifier=true
diff --git a/assets/node_list.yml b/assets/node_list.yml
index d04a9a2e8..6191129b3 100644
--- a/assets/node_list.yml
+++ b/assets/node_list.yml
@@ -1,6 +1,7 @@
 -
   uri: xmr-node.cakewallet.com:18081
   is_default: true
+  trusted: true
 -
   uri: cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081
   is_default: false
diff --git a/cw_bitcoin/lib/pending_bitcoin_transaction.dart b/cw_bitcoin/lib/pending_bitcoin_transaction.dart
index 140965655..411c7de16 100644
--- a/cw_bitcoin/lib/pending_bitcoin_transaction.dart
+++ b/cw_bitcoin/lib/pending_bitcoin_transaction.dart
@@ -153,4 +153,9 @@ class PendingBitcoinTransaction with PendingTransaction {
       inputAddresses: _tx.inputs.map((input) => input.txId).toList(),
       outputAddresses: outputAddresses,
       fee: fee);
+      
+  @override
+  Future<String?> commitUR() {
+    throw UnimplementedError();
+  }
 }
diff --git a/cw_bitcoin_cash/lib/src/pending_bitcoin_cash_transaction.dart b/cw_bitcoin_cash/lib/src/pending_bitcoin_cash_transaction.dart
index e1fa9d6e0..05483ce54 100644
--- a/cw_bitcoin_cash/lib/src/pending_bitcoin_cash_transaction.dart
+++ b/cw_bitcoin_cash/lib/src/pending_bitcoin_cash_transaction.dart
@@ -85,4 +85,8 @@ class PendingBitcoinCashTransaction with PendingTransaction {
       fee: fee, 
       isReplaced: false,
       );
+  @override
+  Future<String?> commitUR() {
+    throw UnimplementedError();
+  }
 }
diff --git a/cw_core/lib/monero_wallet_keys.dart b/cw_core/lib/monero_wallet_keys.dart
index 1435002a8..fe3784986 100644
--- a/cw_core/lib/monero_wallet_keys.dart
+++ b/cw_core/lib/monero_wallet_keys.dart
@@ -1,10 +1,12 @@
 class MoneroWalletKeys {
   const MoneroWalletKeys(
-      {required this.privateSpendKey,
+      {required this.primaryAddress,
+        required this.privateSpendKey,
         required this.privateViewKey,
         required this.publicSpendKey,
         required this.publicViewKey});
 
+  final String primaryAddress;
   final String publicViewKey;
   final String privateViewKey;
   final String publicSpendKey;
diff --git a/cw_core/lib/pending_transaction.dart b/cw_core/lib/pending_transaction.dart
index 0a6103a5f..78eba68a3 100644
--- a/cw_core/lib/pending_transaction.dart
+++ b/cw_core/lib/pending_transaction.dart
@@ -14,5 +14,8 @@ mixin PendingTransaction {
   int? get outputCount => null;
   PendingChange? change;
 
+  bool shouldCommitUR() => false;
+
   Future<void> commit();
+  Future<String?> commitUR();
 }
diff --git a/cw_evm/lib/pending_evm_chain_transaction.dart b/cw_evm/lib/pending_evm_chain_transaction.dart
index 0b367da68..6861b41f8 100644
--- a/cw_evm/lib/pending_evm_chain_transaction.dart
+++ b/cw_evm/lib/pending_evm_chain_transaction.dart
@@ -47,4 +47,9 @@ class PendingEVMChainTransaction with PendingTransaction {
 
     return '0x${Hex.HEX.encode(txid)}';
   }
+  
+  @override
+  Future<String?> commitUR() {
+    throw UnimplementedError();
+  }
 }
diff --git a/cw_haven/lib/api/exceptions/wallet_restore_from_keys_exception.dart b/cw_haven/lib/api/exceptions/wallet_restore_from_keys_exception.dart
index c6b6c6ef7..3ff5f2438 100644
--- a/cw_haven/lib/api/exceptions/wallet_restore_from_keys_exception.dart
+++ b/cw_haven/lib/api/exceptions/wallet_restore_from_keys_exception.dart
@@ -2,4 +2,9 @@ class WalletRestoreFromKeysException implements Exception {
   WalletRestoreFromKeysException({required this.message});
   
   final String message;
+
+  @override
+  String toString() {
+    return message;
+  }
 }
\ No newline at end of file
diff --git a/cw_haven/lib/haven_wallet.dart b/cw_haven/lib/haven_wallet.dart
index 06a838100..e2e598bbe 100644
--- a/cw_haven/lib/haven_wallet.dart
+++ b/cw_haven/lib/haven_wallet.dart
@@ -73,6 +73,7 @@ abstract class HavenWalletBase
 
   @override
   MoneroWalletKeys get keys => MoneroWalletKeys(
+      primaryAddress: haven_wallet.getAddress(accountIndex: 0, addressIndex: 0),
       privateSpendKey: haven_wallet.getSecretSpendKey(),
       privateViewKey: haven_wallet.getSecretViewKey(),
       publicSpendKey: haven_wallet.getPublicSpendKey(),
diff --git a/cw_haven/lib/pending_haven_transaction.dart b/cw_haven/lib/pending_haven_transaction.dart
index 1d95de08c..dbf075044 100644
--- a/cw_haven/lib/pending_haven_transaction.dart
+++ b/cw_haven/lib/pending_haven_transaction.dart
@@ -48,4 +48,9 @@ class PendingHavenTransaction with PendingTransaction {
       rethrow;
     }
   }
+  
+  @override
+  Future<String?> commitUR() {
+    throw UnimplementedError();
+  }
 }
diff --git a/cw_monero/lib/api/account_list.dart b/cw_monero/lib/api/account_list.dart
index 7cb95a507..e3bb25c97 100644
--- a/cw_monero/lib/api/account_list.dart
+++ b/cw_monero/lib/api/account_list.dart
@@ -2,6 +2,7 @@ import 'package:cw_monero/api/wallet.dart';
 import 'package:monero/monero.dart' as monero;
 
 monero.wallet? wptr = null;
+bool get isViewOnly => int.tryParse(monero.Wallet_secretSpendKey(wptr!)) == 0;
 
 int _wlptrForW = 0;
 monero.WalletListener? _wlptr = null;
diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart
index a308b682e..7748a16af 100644
--- a/cw_monero/lib/api/transaction_history.dart
+++ b/cw_monero/lib/api/transaction_history.dart
@@ -13,7 +13,13 @@ import 'package:mutex/mutex.dart';
 
 
 String getTxKey(String txId) {
-  return monero.Wallet_getTxKey(wptr!, txid: txId);
+  final txKey = monero.Wallet_getTxKey(wptr!, txid: txId);
+  final status = monero.Wallet_status(wptr!);
+  if (status != 0) {
+    final error = monero.Wallet_errorString(wptr!);
+    return txId+"_"+error;
+  }
+  return txKey;
 }
 final txHistoryMutex = Mutex();
 monero.TransactionHistory? txhistory;
@@ -178,12 +184,13 @@ PendingTransactionDescription createTransactionMultDestSync(
   );
 }
 
-void commitTransactionFromPointerAddress({required int address}) =>
-    commitTransaction(transactionPointer: monero.PendingTransaction.fromAddress(address));
+String? commitTransactionFromPointerAddress({required int address, required bool useUR}) =>
+    commitTransaction(transactionPointer: monero.PendingTransaction.fromAddress(address), useUR: useUR);
 
-void commitTransaction({required monero.PendingTransaction transactionPointer}) {
-  
-  final txCommit = monero.PendingTransaction_commit(transactionPointer, filename: '', overwrite: false);
+String? commitTransaction({required monero.PendingTransaction transactionPointer, required bool useUR}) {
+  final txCommit = useUR
+    ? monero.PendingTransaction_commitUR(transactionPointer, 120)
+    : monero.PendingTransaction_commit(transactionPointer, filename: '', overwrite: false);
 
   final String? error = (() {
     final status = monero.PendingTransaction_status(transactionPointer.cast());
@@ -196,6 +203,11 @@ void commitTransaction({required monero.PendingTransaction transactionPointer})
   if (error != null) {
     throw CreationTransactionException(message: error);
   }
+  if (useUR) {
+    return txCommit as String?;
+  } else {
+    return null;
+  }
 }
 
 Future<PendingTransactionDescription> _createTransactionSync(Map args) async {
diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart
index dca7586fb..61fd6edf0 100644
--- a/cw_monero/lib/api/wallet_manager.dart
+++ b/cw_monero/lib/api/wallet_manager.dart
@@ -425,3 +425,5 @@ Future<void> restoreFromSpendKey(
     });
 
 bool isWalletExist({required String path}) => _isWalletExist(path);
+
+bool isViewOnlyBySpendKey() => int.tryParse(monero.Wallet_secretSpendKey(wptr!)) == 0;
\ No newline at end of file
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index 0ae2202ba..bc8c3c94d 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -19,6 +19,7 @@ import 'package:cw_core/transaction_direction.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
+import 'package:cw_monero/api/account_list.dart';
 import 'package:cw_monero/api/coins_info.dart';
 import 'package:cw_monero/api/monero_output.dart';
 import 'package:cw_monero/api/structs/pending_transaction.dart';
@@ -121,6 +122,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
 
   @override
   MoneroWalletKeys get keys => MoneroWalletKeys(
+      primaryAddress: monero_wallet.getAddress(accountIndex: 0, addressIndex: 0),
       privateSpendKey: monero_wallet.getSecretSpendKey(),
       privateViewKey: monero_wallet.getSecretViewKey(),
       publicSpendKey: monero_wallet.getPublicSpendKey(),
@@ -230,6 +232,36 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
     }
   }
 
+  Future<bool> submitTransactionUR(String ur) async {
+    final retStatus = monero.Wallet_submitTransactionUR(wptr!, ur);
+    final status = monero.Wallet_status(wptr!);
+    if (status != 0) {
+      final err = monero.Wallet_errorString(wptr!);
+      throw MoneroTransactionCreationException("unable to broadcast signed transaction: $err");
+    }
+    return retStatus;
+  }
+
+  bool importKeyImagesUR(String ur) {
+    final retStatus = monero.Wallet_importKeyImagesUR(wptr!, ur);
+    final status = monero.Wallet_status(wptr!);
+    if (status != 0) {
+      final err = monero.Wallet_errorString(wptr!);
+      throw Exception("unable to import key images: $err");
+    }
+    return retStatus;
+  }
+
+  String exportOutputsUR(bool all) {
+    final str = monero.Wallet_exportOutputsUR(wptr!, all: all);
+    final status = monero.Wallet_status(wptr!);
+    if (status != 0) {
+      final err = monero.Wallet_errorString(wptr!);
+      throw MoneroTransactionCreationException("unable to export UR: $err");
+    }
+    return str;
+  }
+
   @override
   Future<PendingTransaction> createTransaction(Object credentials) async {
     final _credentials = credentials as MoneroTransactionCreationCredentials;
diff --git a/cw_monero/lib/pending_monero_transaction.dart b/cw_monero/lib/pending_monero_transaction.dart
index 2a75fc26b..eb714eeb3 100644
--- a/cw_monero/lib/pending_monero_transaction.dart
+++ b/cw_monero/lib/pending_monero_transaction.dart
@@ -1,3 +1,4 @@
+import 'package:cw_monero/api/account_list.dart';
 import 'package:cw_monero/api/structs/pending_transaction.dart';
 import 'package:cw_monero/api/transaction_history.dart'
     as monero_transaction_history;
@@ -35,11 +36,32 @@ class PendingMoneroTransaction with PendingTransaction {
   String get feeFormatted => AmountConverter.amountIntToString(
       CryptoCurrency.xmr, pendingTransactionDescription.fee);
 
+  bool shouldCommitUR() => isViewOnly;
+
   @override
   Future<void> commit() async {
     try {
       monero_transaction_history.commitTransactionFromPointerAddress(
-          address: pendingTransactionDescription.pointerAddress);
+          address: pendingTransactionDescription.pointerAddress,
+          useUR: false);
+    } catch (e) {
+      final message = e.toString();
+
+      if (message.contains('Reason: double spend')) {
+        throw DoubleSpendException();
+      }
+
+      rethrow;
+    }
+  }
+
+  @override
+  Future<String?> commitUR() async {
+    try {
+      final ret = monero_transaction_history.commitTransactionFromPointerAddress(
+          address: pendingTransactionDescription.pointerAddress,
+          useUR: true);
+      return ret;
     } catch (e) {
       final message = e.toString();
 
diff --git a/cw_nano/lib/pending_nano_transaction.dart b/cw_nano/lib/pending_nano_transaction.dart
index a027100fd..51a4ef6c1 100644
--- a/cw_nano/lib/pending_nano_transaction.dart
+++ b/cw_nano/lib/pending_nano_transaction.dart
@@ -37,4 +37,9 @@ class PendingNanoTransaction with PendingTransaction {
       await nanoClient.processBlock(block, "send");
     }
   }
+  
+  @override
+  Future<String?> commitUR() {
+    throw UnimplementedError();
+  }
 }
diff --git a/cw_shared_external/pubspec.lock b/cw_shared_external/pubspec.lock
new file mode 100644
index 000000000..203ecd5c3
--- /dev/null
+++ b/cw_shared_external/pubspec.lock
@@ -0,0 +1,189 @@
+# Generated by pub
+# See https://dart.dev/tools/pub/glossary#lockfile
+packages:
+  async:
+    dependency: transitive
+    description:
+      name: async
+      sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.11.0"
+  boolean_selector:
+    dependency: transitive
+    description:
+      name: boolean_selector
+      sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.1"
+  characters:
+    dependency: transitive
+    description:
+      name: characters
+      sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.3.0"
+  clock:
+    dependency: transitive
+    description:
+      name: clock
+      sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.1.1"
+  collection:
+    dependency: transitive
+    description:
+      name: collection
+      sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.18.0"
+  fake_async:
+    dependency: transitive
+    description:
+      name: fake_async
+      sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.3.1"
+  flutter:
+    dependency: "direct main"
+    description: flutter
+    source: sdk
+    version: "0.0.0"
+  flutter_test:
+    dependency: "direct dev"
+    description: flutter
+    source: sdk
+    version: "0.0.0"
+  leak_tracker:
+    dependency: transitive
+    description:
+      name: leak_tracker
+      sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
+      url: "https://pub.dev"
+    source: hosted
+    version: "10.0.4"
+  leak_tracker_flutter_testing:
+    dependency: transitive
+    description:
+      name: leak_tracker_flutter_testing
+      sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.0.3"
+  leak_tracker_testing:
+    dependency: transitive
+    description:
+      name: leak_tracker_testing
+      sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.0.1"
+  matcher:
+    dependency: transitive
+    description:
+      name: matcher
+      sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.12.16+1"
+  material_color_utilities:
+    dependency: transitive
+    description:
+      name: material_color_utilities
+      sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.8.0"
+  meta:
+    dependency: transitive
+    description:
+      name: meta
+      sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.12.0"
+  path:
+    dependency: transitive
+    description:
+      name: path
+      sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.9.0"
+  sky_engine:
+    dependency: transitive
+    description: flutter
+    source: sdk
+    version: "0.0.99"
+  source_span:
+    dependency: transitive
+    description:
+      name: source_span
+      sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.10.0"
+  stack_trace:
+    dependency: transitive
+    description:
+      name: stack_trace
+      sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.11.1"
+  stream_channel:
+    dependency: transitive
+    description:
+      name: stream_channel
+      sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.2"
+  string_scanner:
+    dependency: transitive
+    description:
+      name: string_scanner
+      sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.2.0"
+  term_glyph:
+    dependency: transitive
+    description:
+      name: term_glyph
+      sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.2.1"
+  test_api:
+    dependency: transitive
+    description:
+      name: test_api
+      sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.7.0"
+  vector_math:
+    dependency: transitive
+    description:
+      name: vector_math
+      sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.4"
+  vm_service:
+    dependency: transitive
+    description:
+      name: vm_service
+      sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
+      url: "https://pub.dev"
+    source: hosted
+    version: "14.2.1"
+sdks:
+  dart: ">=3.3.0 <4.0.0"
+  flutter: ">=3.18.0-18.0.pre.54"
diff --git a/cw_solana/lib/pending_solana_transaction.dart b/cw_solana/lib/pending_solana_transaction.dart
index 38347ed13..e01446000 100644
--- a/cw_solana/lib/pending_solana_transaction.dart
+++ b/cw_solana/lib/pending_solana_transaction.dart
@@ -40,4 +40,9 @@ class PendingSolanaTransaction with PendingTransaction {
 
   @override
   String get id => '';
+  
+  @override
+  Future<String?> commitUR() {
+    throw UnimplementedError();
+  }
 }
diff --git a/cw_tron/lib/pending_tron_transaction.dart b/cw_tron/lib/pending_tron_transaction.dart
index b6d064b31..2420f083b 100644
--- a/cw_tron/lib/pending_tron_transaction.dart
+++ b/cw_tron/lib/pending_tron_transaction.dart
@@ -30,4 +30,9 @@ class PendingTronTransaction with PendingTransaction {
 
   @override
   String get id => '';
+  
+  @override
+  Future<String?> commitUR() {
+    throw UnimplementedError();
+  }
 }
diff --git a/cw_wownero/lib/api/exceptions/wallet_restore_from_keys_exception.dart b/cw_wownero/lib/api/exceptions/wallet_restore_from_keys_exception.dart
index ad576faa2..6c461ee4c 100644
--- a/cw_wownero/lib/api/exceptions/wallet_restore_from_keys_exception.dart
+++ b/cw_wownero/lib/api/exceptions/wallet_restore_from_keys_exception.dart
@@ -3,5 +3,6 @@ class WalletRestoreFromKeysException implements Exception {
   
   final String message;
 
+  @override
   String toString() => message;
 }
\ No newline at end of file
diff --git a/cw_wownero/lib/pending_wownero_transaction.dart b/cw_wownero/lib/pending_wownero_transaction.dart
index 1fc1805eb..967f63756 100644
--- a/cw_wownero/lib/pending_wownero_transaction.dart
+++ b/cw_wownero/lib/pending_wownero_transaction.dart
@@ -50,4 +50,9 @@ class PendingWowneroTransaction with PendingTransaction {
       rethrow;
     }
   }
+  
+  @override
+  Future<String?> commitUR() {
+    throw UnimplementedError();
+  }
 }
diff --git a/cw_wownero/lib/wownero_wallet.dart b/cw_wownero/lib/wownero_wallet.dart
index 331957d67..5927d6434 100644
--- a/cw_wownero/lib/wownero_wallet.dart
+++ b/cw_wownero/lib/wownero_wallet.dart
@@ -120,6 +120,7 @@ abstract class WowneroWalletBase
 
   @override
   MoneroWalletKeys get keys => MoneroWalletKeys(
+      primaryAddress: wownero_wallet.getAddress(accountIndex: 0, addressIndex: 0),
       privateSpendKey: wownero_wallet.getSecretSpendKey(),
       privateViewKey: wownero_wallet.getSecretViewKey(),
       publicSpendKey: wownero_wallet.getPublicSpendKey(),
diff --git a/lib/di.dart b/lib/di.dart
index 540a546fd..9cff29798 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -125,6 +125,7 @@ import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.d
 import 'package:cake_wallet/src/screens/support/support_page.dart';
 import 'package:cake_wallet/src/screens/support_chat/support_chat_page.dart';
 import 'package:cake_wallet/src/screens/support_other_links/support_other_links_page.dart';
+import 'package:cake_wallet/src/screens/ur/animated_ur_page.dart';
 import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart';
 import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart';
 import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
@@ -134,6 +135,7 @@ import 'package:cake_wallet/utils/device_info.dart';
 import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
 import 'package:cake_wallet/utils/payment_request.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
+import 'package:cake_wallet/view_model/animated_ur_model.dart';
 import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
 import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
 import 'package:cake_wallet/view_model/anonpay_details_view_model.dart';
@@ -903,6 +905,11 @@ Future<void> setup({
   getIt.registerFactory(() => WalletKeysViewModel(getIt.get<AppStore>()));
 
   getIt.registerFactory(() => WalletKeysPage(getIt.get<WalletKeysViewModel>()));
+  
+  getIt.registerFactory(() => AnimatedURModel(getIt.get<AppStore>()));
+
+  getIt.registerFactoryParam<AnimatedURPage, String, void>((String urQr, _) =>
+    AnimatedURPage(getIt.get<AnimatedURModel>(), urQr: urQr));
 
   getIt.registerFactoryParam<ContactViewModel, ContactRecord?, void>(
       (ContactRecord? contact, _) => ContactViewModel(_contactSource, contact: contact));
diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart
index af6f1ce78..d863b136e 100644
--- a/lib/entities/default_settings_migration.dart
+++ b/lib/entities/default_settings_migration.dart
@@ -259,6 +259,10 @@ Future<void> defaultSettingsMigration(
         case 42:
           updateBtcElectrumNodeToUseSSL(nodes, sharedPreferences);
           break;
+        case 43:
+          _updateCakeXmrNode(nodes);
+          break;
+
         default:
           break;
       }
@@ -273,6 +277,15 @@ Future<void> defaultSettingsMigration(
   await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion, version);
 }
 
+void _updateCakeXmrNode(Box<Node> nodes) {
+  final node = nodes.values.firstWhereOrNull((element) => element.uriRaw == newCakeWalletMoneroUri);
+
+  if (node != null && !node.trusted) {
+    node.trusted = true;
+    node.save();
+  }
+}
+
 void updateBtcElectrumNodeToUseSSL(Box<Node> nodes, SharedPreferences sharedPreferences) {
   final btcElectrumNode = nodes.values.firstWhereOrNull((element) => element.uriRaw == newCakeWalletBitcoinUri);
 
@@ -843,7 +856,7 @@ Future<void> changeDefaultMoneroNode(
     }
   });
 
-  final newCakeWalletNode = Node(uri: newCakeWalletMoneroUri, type: WalletType.monero);
+  final newCakeWalletNode = Node(uri: newCakeWalletMoneroUri, type: WalletType.monero, trusted: true);
 
   await nodeSource.add(newCakeWalletNode);
 
diff --git a/lib/entities/qr_scanner.dart b/lib/entities/qr_scanner.dart
index c6873a5bc..2e2637566 100644
--- a/lib/entities/qr_scanner.dart
+++ b/lib/entities/qr_scanner.dart
@@ -1,15 +1,376 @@
-import 'package:barcode_scan2/barcode_scan2.dart';
+import 'dart:math';
+
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/main.dart';
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
+import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:fast_scanner/fast_scanner.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/scheduler.dart';
 
 var isQrScannerShown = false;
 
-Future<String> presentQRScanner() async {
+Future<String> presentQRScanner(BuildContext context) async {
   isQrScannerShown = true;
   try {
-    final result = await BarcodeScanner.scan();
+    final result = await Navigator.of(context).push<String>(
+      MaterialPageRoute(
+        builder:(context) {
+          return BarcodeScannerSimple();
+        },
+      ),
+    );
     isQrScannerShown = false;
-    return result.rawContent.trim();
+    return result??'';
   } catch (e) {
     isQrScannerShown = false;
     rethrow;
   }
 }
+
+// https://github.com/MrCyjaneK/fast_scanner/blob/master/example/lib/barcode_scanner_simple.dart
+class BarcodeScannerSimple extends StatefulWidget {
+  const BarcodeScannerSimple({super.key});
+
+  @override
+  State<BarcodeScannerSimple> createState() => _BarcodeScannerSimpleState();
+}
+
+class _BarcodeScannerSimpleState extends State<BarcodeScannerSimple> {
+  Barcode? _barcode;
+  bool popped = false;
+
+  List<String> urCodes = [];
+  late var ur = URQRToURQRData(urCodes);
+
+  void _handleBarcode(BarcodeCapture barcodes) {
+    try {
+      _handleBarcodeInternal(barcodes);
+    } catch (e) {
+      showPopUp<void>(
+        context: context,
+        builder: (context) {
+          return AlertWithOneAction(
+            alertTitle: S.of(context).error,
+            alertContent: S.of(context).error_dialog_content,
+            buttonText: 'ok',
+            buttonAction: () {
+              Navigator.of(context).pop();
+            },
+          );
+        },
+      );
+      print(e);
+    }
+  }
+
+  void _handleBarcodeInternal(BarcodeCapture barcodes) {
+    for (final barcode in barcodes.barcodes) {
+      // don't handle unknown QR codes
+      if (barcode.rawValue?.trim().isEmpty??false == false) continue;
+      if (barcode.rawValue!.startsWith("ur:")) {
+        if (urCodes.contains(barcode.rawValue)) continue;
+        setState(() {
+          urCodes.add(barcode.rawValue!);
+          ur = URQRToURQRData(urCodes);
+        });
+        if (ur.progress == 1) {
+          setState(() {
+            popped = true;
+          });
+          SchedulerBinding.instance.addPostFrameCallback((_) {
+            Navigator.of(context).pop(ur.inputs.join("\n"));
+          });
+        };
+      }
+    }
+    if (urCodes.isNotEmpty) return;
+    if (mounted) {
+      setState(() {
+        _barcode = barcodes.barcodes.firstOrNull;
+      });
+      if (_barcode != null && popped != true) {
+        setState(() {
+          popped = true;
+        });
+        SchedulerBinding.instance.addPostFrameCallback((_) {
+          Navigator.of(context).pop(_barcode?.rawValue ?? "");
+        });
+      }
+    }
+  }
+
+  final MobileScannerController ctrl = MobileScannerController();
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('Scan'),
+        actions: [
+          SwitchCameraButton(controller: ctrl),
+          ToggleFlashlightButton(controller: ctrl),
+        ],
+      ),
+      backgroundColor: Colors.black,
+      body: Stack(
+        children: [
+          MobileScanner(
+            onDetect: _handleBarcode,
+            controller: ctrl,
+          ),
+          if (ur.inputs.length != 0) 
+            Center(child:
+              Text(
+                "${ur.inputs.length}/${ur.count}",
+                style: Theme.of(context).textTheme.displayLarge?.copyWith(color: Colors.white)
+              ),
+            ),
+          SizedBox(
+            child: Center(
+              child: SizedBox(
+                width: 250,
+                height: 250,
+                child: CustomPaint(
+                  painter: ProgressPainter(
+                    urQrProgress: URQrProgress(
+                      expectedPartCount: ur.count - 1,
+                      processedPartsCount: ur.inputs.length,
+                      receivedPartIndexes: _urParts(),
+                      percentage: ur.progress,
+                    ),
+                  ),
+                ),
+              ),
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+
+  List<int> _urParts() {
+    List<int> l = [];
+    for (var inp in ur.inputs) {
+      try {
+        l.add(int.parse(inp.split("/")[1].split("-")[0]));
+      } catch (e) {}
+    }
+    return l;
+  }
+}
+
+
+class ToggleFlashlightButton extends StatelessWidget {
+  const ToggleFlashlightButton({required this.controller, super.key});
+
+  final MobileScannerController controller;
+
+  @override
+  Widget build(BuildContext context) {
+    return ValueListenableBuilder(
+      valueListenable: controller,
+      builder: (context, state, child) {
+        if (!state.isInitialized || !state.isRunning) {
+          return const SizedBox.shrink();
+        }
+
+        switch (state.torchState) {
+          case TorchState.auto:
+            return IconButton(
+              iconSize: 32.0,
+              icon: const Icon(Icons.flash_auto),
+              onPressed: () async {
+                await controller.toggleTorch();
+              },
+            );
+          case TorchState.off:
+            return IconButton(
+              iconSize: 32.0,
+              icon: const Icon(Icons.flash_off),
+              onPressed: () async {
+                await controller.toggleTorch();
+              },
+            );
+          case TorchState.on:
+            return IconButton(
+              iconSize: 32.0,
+              icon: const Icon(Icons.flash_on),
+              onPressed: () async {
+                await controller.toggleTorch();
+              },
+            );
+          case TorchState.unavailable:
+            return const Icon(
+              Icons.no_flash,
+              color: Colors.grey,
+            );
+        }
+      },
+    );
+  }
+}
+
+class SwitchCameraButton extends StatelessWidget {
+  const SwitchCameraButton({required this.controller, super.key});
+
+  final MobileScannerController controller;
+
+  @override
+  Widget build(BuildContext context) {
+    return ValueListenableBuilder(
+      valueListenable: controller,
+      builder: (context, state, child) {
+        if (!state.isInitialized || !state.isRunning) {
+          return const SizedBox.shrink();
+        }
+
+        final int? availableCameras = state.availableCameras;
+
+        if (availableCameras != null && availableCameras < 2) {
+          return const SizedBox.shrink();
+        }
+
+        final Widget icon;
+
+        switch (state.cameraDirection) {
+          case CameraFacing.front:
+            icon = const Icon(Icons.camera_front);
+          case CameraFacing.back:
+            icon = const Icon(Icons.camera_rear);
+        }
+
+        return IconButton(
+          iconSize: 32.0,
+          icon: icon,
+          onPressed: () async {
+            await controller.switchCamera();
+          },
+        );
+      },
+    );
+  }
+}
+
+class URQRData {
+  URQRData(
+      {required this.tag,
+      required this.str,
+      required this.progress,
+      required this.count,
+      required this.error,
+      required this.inputs});
+  final String tag;
+  final String str;
+  final double progress;
+  final int count;
+  final String error;
+  final List<String> inputs;
+  Map<String, dynamic> toJson() {
+    return {
+      "tag": tag,
+      "str": str,
+      "progress": progress,
+      "count": count,
+      "error": error,
+      "inputs": inputs,
+    };
+  }
+}
+
+URQRData URQRToURQRData(List<String> urqr_) {
+  final urqr = urqr_.toSet().toList();
+  urqr.sort((s1, s2) {
+    final s1s = s1.split("/");
+    final s1frameStr = s1s[1].split("-");
+    final s1curFrame = int.parse(s1frameStr[0]);
+    final s2s = s2.split("/");
+    final s2frameStr = s2s[1].split("-");
+    final s2curFrame = int.parse(s2frameStr[0]);
+    return s1curFrame - s2curFrame;
+  });
+
+  String tag = '';
+  int count = 0;
+  String bw = '';
+  for (var elm in urqr) {
+    final s = elm.substring(elm.indexOf(":") + 1); // strip down ur: prefix
+    final s2 = s.split("/");
+    tag = s2[0];
+    final frameStr = s2[1].split("-");
+    // final curFrame = int.parse(frameStr[0]);
+    count = int.parse(frameStr[1]);
+    final byteWords = s2[2];
+    bw += byteWords;
+  }
+  String? error;
+
+  return URQRData(
+    tag: tag,
+    str: bw,
+    progress: count == 0 ? 0 : (urqr.length / count),
+    count: count,
+    error: error ?? "",
+    inputs: urqr,
+  );
+}
+
+class ProgressPainter extends CustomPainter {
+  final URQrProgress urQrProgress;
+
+  ProgressPainter({required this.urQrProgress});
+
+  @override
+  void paint(Canvas canvas, Size size) {
+    final c = Offset(size.width / 2.0, size.height / 2.0);
+    final radius = size.width * 0.9;
+    final rect = Rect.fromCenter(center: c, width: radius, height: radius);
+    const fullAngle = 360.0;
+    var startAngle = 0.0;
+    for (int i = 0; i < urQrProgress.expectedPartCount.toInt(); i++) {
+      var sweepAngle =
+          (1 / urQrProgress.expectedPartCount) * fullAngle * pi / 180.0;
+      drawSector(canvas, urQrProgress.receivedPartIndexes.contains(i), rect,
+          startAngle, sweepAngle);
+      startAngle += sweepAngle;
+    }
+  }
+
+  void drawSector(Canvas canvas, bool isActive, Rect rect, double startAngle,
+      double sweepAngle) {
+    final paint = Paint()
+      ..style = PaintingStyle.stroke
+      ..strokeWidth = 8
+      ..strokeCap = StrokeCap.round
+      ..strokeJoin = StrokeJoin.round
+      ..color = isActive ? const Color(0xffff6600) : Colors.white70;
+    canvas.drawArc(rect, startAngle, sweepAngle, false, paint);
+  }
+
+  @override
+  bool shouldRepaint(covariant ProgressPainter oldDelegate) {
+    return urQrProgress != oldDelegate.urQrProgress;
+  }
+}
+
+class URQrProgress {
+  int expectedPartCount;
+  int processedPartsCount;
+  List<int> receivedPartIndexes;
+  double percentage;
+
+  URQrProgress({
+    required this.expectedPartCount,
+    required this.processedPartsCount,
+    required this.receivedPartIndexes,
+    required this.percentage,
+  });
+
+  bool equals(URQrProgress? progress) {
+    if (progress == null) {
+      return false;
+    }
+    return processedPartsCount == progress.processedPartsCount;
+  }
+}
diff --git a/lib/main.dart b/lib/main.dart
index 29b216b22..51fab4dd1 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -204,7 +204,7 @@ Future<void> initializeAppConfigs() async {
     transactionDescriptions: transactionDescriptions,
     secureStorage: secureStorage,
     anonpayInvoiceInfo: anonpayInvoiceInfo,
-    initialMigrationVersion: 42,
+    initialMigrationVersion: 43,
   );
 }
 
diff --git a/lib/monero/cw_monero.dart b/lib/monero/cw_monero.dart
index b1cf49482..dfda4d600 100644
--- a/lib/monero/cw_monero.dart
+++ b/lib/monero/cw_monero.dart
@@ -248,6 +248,7 @@ class CWMonero extends Monero {
     final moneroWallet = wallet as MoneroWallet;
     final keys = moneroWallet.keys;
     return <String, String>{
+      'primaryAddress': keys.primaryAddress,
       'privateSpendKey': keys.privateSpendKey,
       'privateViewKey': keys.privateViewKey,
       'publicSpendKey': keys.publicSpendKey,
@@ -357,9 +358,32 @@ class CWMonero extends Monero {
   Future<int> getCurrentHeight() async {
     return monero_wallet_api.getCurrentHeight();
   }
+  
+  @override
+  bool importKeyImagesUR(Object wallet, String ur) {
+    final moneroWallet = wallet as MoneroWallet;
+    return moneroWallet.importKeyImagesUR(ur);
+  }
+
+
+  @override
+  Future<bool> commitTransactionUR(Object wallet, String ur) {
+    final moneroWallet = wallet as MoneroWallet;
+    return moneroWallet.submitTransactionUR(ur);
+  }
+
+  @override
+  String exportOutputsUR(Object wallet, bool all) {
+    final moneroWallet = wallet as MoneroWallet;
+    return moneroWallet.exportOutputsUR(all);
+  }
 
   @override
   void monerocCheck() {
     checkIfMoneroCIsFine();
   }
+
+  bool isViewOnly() {
+    return isViewOnlyBySpendKey();
+  }
 }
diff --git a/lib/router.dart b/lib/router.dart
index 6c234ff80..4b99aabc0 100644
--- a/lib/router.dart
+++ b/lib/router.dart
@@ -96,6 +96,7 @@ import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dar
 import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart';
 import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
 import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
+import 'package:cake_wallet/src/screens/ur/animated_ur_page.dart';
 import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart';
 import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart';
 import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
@@ -732,6 +733,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
     case Routes.setup2faInfoPage:
       return MaterialPageRoute<void>(builder: (_) => getIt.get<Setup2FAInfoPage>());
 
+    case Routes.urqrAnimatedPage:
+      return MaterialPageRoute<void>(builder: (_) => getIt.get<AnimatedURPage>(param1: settings.arguments));
+
     case Routes.homeSettings:
       return CupertinoPageRoute<void>(
         builder: (_) => getIt.get<HomeSettingsPage>(param1: settings.arguments),
diff --git a/lib/routes.dart b/lib/routes.dart
index 5f11b11a3..63c41bde5 100644
--- a/lib/routes.dart
+++ b/lib/routes.dart
@@ -108,6 +108,7 @@ class Routes {
 
   static const signPage = '/sign_page';
   static const connectDevices = '/device/connect';
+  static const urqrAnimatedPage = '/urqr/animated_page';
   static const walletGroupsDisplayPage = '/wallet_groups_display_page';
   static const walletGroupDescription = '/wallet_group_description';
 }
diff --git a/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart b/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart
index 309c435a2..9357df2c3 100644
--- a/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart
+++ b/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart
@@ -347,8 +347,8 @@ class CakePayBuyCardDetailPage extends BasePage {
                 rightButtonText: S.of(popupContext).send,
                 leftButtonText: S.of(popupContext).cancel,
                 actionRightButton: () async {
-                  Navigator.of(popupContext).pop();
-                  await cakePayPurchaseViewModel.sendViewModel.commitTransaction();
+                  Navigator.of(context).pop();
+                  await cakePayPurchaseViewModel.sendViewModel.commitTransaction(context);
                 },
                 actionLeftButton: () => Navigator.of(popupContext).pop()));
       },
diff --git a/lib/src/screens/dashboard/widgets/menu_widget.dart b/lib/src/screens/dashboard/widgets/menu_widget.dart
index f0e330f04..b49a08584 100644
--- a/lib/src/screens/dashboard/widgets/menu_widget.dart
+++ b/lib/src/screens/dashboard/widgets/menu_widget.dart
@@ -101,6 +101,9 @@ class MenuWidgetState extends State<MenuWidget> {
     if (!widget.dashboardViewModel.hasSilentPayments) {
       items.removeWhere((element) => element.name(context) == S.of(context).silent_payments_settings);
     }
+    if (!widget.dashboardViewModel.isMoneroViewOnly) {
+      items.removeWhere((element) => element.name(context) == S.of(context).export_outputs);
+    }
     if (!widget.dashboardViewModel.hasMweb) {
       items.removeWhere((element) => element.name(context) == S.of(context).litecoin_mweb_settings);
     }
@@ -189,7 +192,6 @@ class MenuWidgetState extends State<MenuWidget> {
                   index--;
 
                   final item = items[index];
-
                   final isLastTile = index == itemCount - 1;
 
                   return SettingActionButton(
diff --git a/lib/src/screens/exchange_trade/exchange_trade_page.dart b/lib/src/screens/exchange_trade/exchange_trade_page.dart
index 0f3cc7bd9..130ffa6b0 100644
--- a/lib/src/screens/exchange_trade/exchange_trade_page.dart
+++ b/lib/src/screens/exchange_trade/exchange_trade_page.dart
@@ -277,7 +277,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
                     actionRightButton: () async {
                       Navigator.of(popupContext).pop();
                       await widget.exchangeTradeViewModel.sendViewModel
-                          .commitTransaction();
+                          .commitTransaction(context);
                       transactionStatePopup();
                     },
                     actionLeftButton: () => Navigator.of(popupContext).pop(),
diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart
index bce82312d..7003ceafb 100644
--- a/lib/src/screens/send/send_page.dart
+++ b/lib/src/screens/send/send_page.dart
@@ -498,7 +498,7 @@ class SendPage extends BasePage {
                           ValueKey('send_page_confirm_sending_dialog_cancel_button_key'),
                       actionRightButton: () async {
                         Navigator.of(_dialogContext).pop();
-                        sendViewModel.commitTransaction();
+                        sendViewModel.commitTransaction(context);
                         await showPopUp<void>(
                             context: context,
                             builder: (BuildContext _dialogContext) {
diff --git a/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart b/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart
index 79f74065a..6f7afe2ff 100644
--- a/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart
+++ b/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart
@@ -4,6 +4,7 @@ import 'package:cake_wallet/src/widgets/setting_action_button.dart';
 import 'package:cake_wallet/src/widgets/setting_actions.dart';
 import 'package:cake_wallet/typography.dart';
 import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
+import 'package:cw_core/wallet_type.dart';
 import 'package:flutter/material.dart';
 import 'package:cake_wallet/router.dart' as Router;
 import 'package:cake_wallet/themes/extensions/menu_theme.dart';
@@ -60,8 +61,10 @@ class _DesktopSettingsPageState extends State<DesktopSettingsPage> {
                           return Container();
                         }
 
-                        if (!widget.dashboardViewModel.hasMweb &&
-                            item.name(context) == S.of(context).litecoin_mweb_settings) {
+                        if ((!widget.dashboardViewModel.isMoneroViewOnly &&
+                            item.name(context) == S.of(context).export_outputs) ||
+                           (!widget.dashboardViewModel.hasMweb &&
+                            item.name(context) == S.of(context).litecoin_mweb_settings)) {
                           return Container();
                         }
 
diff --git a/lib/src/screens/transaction_details/rbf_details_page.dart b/lib/src/screens/transaction_details/rbf_details_page.dart
index b117a0b68..2c5edd8b4 100644
--- a/lib/src/screens/transaction_details/rbf_details_page.dart
+++ b/lib/src/screens/transaction_details/rbf_details_page.dart
@@ -168,7 +168,7 @@ class RBFDetailsPage extends BasePage {
                     leftButtonText: S.of(popupContext).cancel,
                     actionRightButton: () async {
                       Navigator.of(popupContext).pop();
-                      await transactionDetailsViewModel.sendViewModel.commitTransaction();
+                      await transactionDetailsViewModel.sendViewModel.commitTransaction(context);
                       try {
                         Navigator.of(popupContext).pop();
                       } catch (_) {}
diff --git a/lib/src/screens/ur/animated_ur_page.dart b/lib/src/screens/ur/animated_ur_page.dart
new file mode 100644
index 000000000..dc40e6a12
--- /dev/null
+++ b/lib/src/screens/ur/animated_ur_page.dart
@@ -0,0 +1,184 @@
+import 'dart:async';
+
+import 'package:cake_wallet/di.dart';
+import 'package:cake_wallet/entities/qr_scanner.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/monero/monero.dart';
+import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart';
+import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart';
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
+import 'package:cake_wallet/src/widgets/primary_button.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cake_wallet/view_model/animated_ur_model.dart';
+import 'package:cake_wallet/view_model/dashboard/wallet_balance.dart';
+import 'package:cw_core/balance.dart';
+import 'package:cw_core/transaction_history.dart';
+import 'package:cw_core/transaction_info.dart';
+import 'package:cw_core/wallet_base.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+
+// ur:xmr-txunsigned - unsigned transaction
+//     should show a scanner afterwards.
+
+class AnimatedURPage extends BasePage {
+  final bool isAll;
+  AnimatedURPage(this.animatedURmodel, {required String urQr, this.isAll = false}) {
+    if (urQr == "export-outputs") {
+      this.urQr = monero!.exportOutputsUR(animatedURmodel.wallet, false);
+    } else if (urQr == "export-outputs-all") {
+      this.urQr = monero!.exportOutputsUR(animatedURmodel.wallet, true);
+    } else {
+      this.urQr = urQr;
+    }
+  }
+
+  late String urQr;
+
+  final AnimatedURModel animatedURmodel;
+
+  String get urQrType {
+    final first = urQr.trim().split("\n")[0];
+    return first.split('/')[0];
+  }
+
+  @override
+  Widget body(BuildContext context) {
+    return Column(
+      mainAxisSize: MainAxisSize.min,
+      children: [
+        Padding(
+          padding: const EdgeInsets.only(top: 64.0),
+          child: URQR(
+            frames: urQr.trim().split("\n"),
+          ),
+        ),
+        SizedBox(height: 32),
+        if (urQrType == "ur:xmr-txunsigned" || urQrType == "ur:xmr-output")
+          Padding(
+            padding: const EdgeInsets.symmetric(horizontal: 16.0),
+            child: SizedBox(
+              width: double.maxFinite,
+              child: PrimaryButton(
+                onPressed: () => _continue(context),
+                text: "Continue",
+                color: Theme.of(context).primaryColor,
+                textColor: Colors.white,
+              ),
+            ),
+          ),
+        SizedBox(height: 32),
+        if (urQrType == "ur:xmr-output" && !isAll) Padding(
+            padding: const EdgeInsets.symmetric(horizontal: 16.0),
+            child: SizedBox(
+              width: double.maxFinite,
+              child: PrimaryButton(
+                onPressed: () => _exportAll(context),
+                text: "Export all",
+                color: Theme.of(context).colorScheme.secondary,
+                textColor: Colors.white,
+              ),
+            ),
+          ),
+      ],
+    );
+  }
+
+  void _exportAll(BuildContext context) {
+    Navigator.of(context).pushReplacement(
+      MaterialPageRoute(
+        builder: (context) {
+          return AnimatedURPage(animatedURmodel, urQr: "export-outputs-all", isAll: true);
+        },
+      ),
+    );
+  }
+
+  Future<void> _continue(BuildContext context) async {
+    try {
+    switch (urQrType) {
+      case "ur:xmr-txunsigned": // ur:xmr-txsigned
+        final ur = await presentQRScanner(context);
+        final result = await monero!.commitTransactionUR(animatedURmodel.wallet, ur);
+        if (result) {
+          Navigator.of(context).pop(true);
+        }        
+        break;
+      case "ur:xmr-output": // xmr-keyimage
+        final ur = await presentQRScanner(context);
+        final result = await monero!.importKeyImagesUR(animatedURmodel.wallet, ur);
+        if (result) {
+          Navigator.of(context).pop(true);
+        }        
+        break;
+      default:
+        throw UnimplementedError("unable to handle UR: ${urQrType}");
+    }
+  } catch (e) {
+    await showPopUp<void>(
+      context: context,
+      builder: (BuildContext context) {
+        return AlertWithOneAction(
+            alertTitle: S.of(context).error,
+            alertContent: e.toString(),
+            buttonText: S.of(context).ok,
+            buttonAction: () => Navigator.pop(context, true));
+      });
+    }
+  }
+}
+
+class URQR extends StatefulWidget {
+  URQR({super.key, required this.frames});
+
+  List<String> frames;
+
+  @override
+  // ignore: library_private_types_in_public_api
+  _URQRState createState() => _URQRState();
+}
+
+const urFrameTime = 1000 ~/ 5;
+
+class _URQRState extends State<URQR> {
+  Timer? t;
+  int frame = 0;
+  @override
+  void initState() {
+    super.initState();
+    setState(() {
+      t = Timer.periodic(const Duration(milliseconds: urFrameTime), (timer) {
+        _nextFrame();
+      });
+    });
+  }
+
+  void _nextFrame() {
+    setState(() {
+      frame++;
+    });
+  }
+
+  @override
+  void dispose() {
+    t?.cancel();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      mainAxisSize: MainAxisSize.min,
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: [
+        Center(
+          child: QrImage(
+            data: widget.frames[frame % widget.frames.length], version: -1,
+            size: 400,
+          ),
+        ),
+      ],
+    );
+  }
+}
\ No newline at end of file
diff --git a/lib/src/screens/wallet_connect/wc_connections_listing_view.dart b/lib/src/screens/wallet_connect/wc_connections_listing_view.dart
index eda2a748f..3a78f6af6 100644
--- a/lib/src/screens/wallet_connect/wc_connections_listing_view.dart
+++ b/lib/src/screens/wallet_connect/wc_connections_listing_view.dart
@@ -65,7 +65,7 @@ class WCPairingsWidget extends BasePage {
       bool isCameraPermissionGranted =
       await PermissionHandler.checkPermission(Permission.camera, context);
       if (!isCameraPermissionGranted) return;
-      uri = await presentQRScanner();
+      uri = await presentQRScanner(context);
     } else {
       uri = await _showEnterWalletConnectURIPopUp(context);
     }
diff --git a/lib/src/widgets/address_text_field.dart b/lib/src/widgets/address_text_field.dart
index 0b1ef4796..d904768f0 100644
--- a/lib/src/widgets/address_text_field.dart
+++ b/lib/src/widgets/address_text_field.dart
@@ -231,7 +231,7 @@ class AddressTextField extends StatelessWidget {
     bool isCameraPermissionGranted =
         await PermissionHandler.checkPermission(Permission.camera, context);
     if (!isCameraPermissionGranted) return;
-    final code = await presentQRScanner();
+    final code = await presentQRScanner(context);
     if (code.isEmpty) {
       return;
     }
diff --git a/lib/src/widgets/setting_actions.dart b/lib/src/widgets/setting_actions.dart
index 048d006cc..da9f26bc6 100644
--- a/lib/src/widgets/setting_actions.dart
+++ b/lib/src/widgets/setting_actions.dart
@@ -21,6 +21,7 @@ class SettingActions {
     addressBookSettingAction,
     silentPaymentsSettingAction,
     litecoinMwebSettingAction,
+    exportOutputsAction,
     securityBackupSettingAction,
     privacySettingAction,
     displaySettingAction,
@@ -50,6 +51,16 @@ class SettingActions {
     },
   );
 
+  static SettingActions exportOutputsAction = SettingActions._(
+    key: ValueKey('dashboard_page_menu_widget_export_outputs_settings_button_key'),
+    name: (context) => S.of(context).export_outputs,
+    image: 'assets/images/monero_menu.png',
+    onTap: (BuildContext context) {
+      Navigator.pop(context);
+      Navigator.of(context).pushNamed(Routes.urqrAnimatedPage, arguments: 'export-outputs');
+    },
+  );
+  
   static SettingActions litecoinMwebSettingAction = SettingActions._(
     key: ValueKey('dashboard_page_menu_widget_litecoin_mweb_settings_button_key'),
     name: (context) => S.of(context).litecoin_mweb_settings,
diff --git a/lib/view_model/animated_ur_model.dart b/lib/view_model/animated_ur_model.dart
new file mode 100644
index 000000000..f613d26be
--- /dev/null
+++ b/lib/view_model/animated_ur_model.dart
@@ -0,0 +1,10 @@
+import 'package:cake_wallet/store/app_store.dart';
+import 'package:cw_core/wallet_base.dart';
+import 'package:mobx/mobx.dart';
+
+class AnimatedURModel with Store {
+ AnimatedURModel(this.appStore)
+      : wallet = appStore.wallet!;
+  final AppStore appStore;
+  final WalletBase wallet;
+}
\ No newline at end of file
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index 6cf7c49d0..934cbdee7 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -393,6 +393,12 @@ abstract class DashboardViewModelBase with Store {
       wallet.type == WalletType.wownero ||
       wallet.type == WalletType.haven;
 
+  @computed
+  bool get isMoneroViewOnly {
+    if (wallet.type != WalletType.monero) return false;
+    return monero!.isViewOnly();
+  }
+
   @computed
   String? get getMoneroError {
     if (wallet.type != WalletType.monero) return null;
diff --git a/lib/view_model/node_list/node_create_or_edit_view_model.dart b/lib/view_model/node_list/node_create_or_edit_view_model.dart
index 86ceb654c..8b3c70c5e 100644
--- a/lib/view_model/node_list/node_create_or_edit_view_model.dart
+++ b/lib/view_model/node_list/node_create_or_edit_view_model.dart
@@ -213,7 +213,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
       bool isCameraPermissionGranted =
           await PermissionHandler.checkPermission(Permission.camera, context);
       if (!isCameraPermissionGranted) return;
-      String code = await presentQRScanner();
+      String code = await presentQRScanner(context);
 
       if (code.isEmpty) {
         throw Exception('Unexpected scan QR code value: value is empty');
diff --git a/lib/view_model/restore/restore_wallet.dart b/lib/view_model/restore/restore_wallet.dart
index 2c2a25005..cc3ad4123 100644
--- a/lib/view_model/restore/restore_wallet.dart
+++ b/lib/view_model/restore/restore_wallet.dart
@@ -1,3 +1,5 @@
+import 'dart:convert';
+
 import 'package:cake_wallet/view_model/restore/restore_mode.dart';
 import 'package:cw_core/wallet_type.dart';
 
@@ -32,6 +34,16 @@ class RestoredWallet {
   final String? privateKey;
 
   factory RestoredWallet.fromKey(Map<String, dynamic> json) {
+    try {
+    final codeParsed = jsonDecode(json['raw_qr'].toString());
+      if (codeParsed["version"] == 0) {
+        json['address'] = codeParsed["primaryAddress"];
+        json['view_key'] = codeParsed["privateViewKey"];
+        json['height'] = codeParsed["restoreHeight"].toString();
+      }
+    } catch (e) {
+      // fine, we don't care, it is only for monero anyway
+    }
     final height = json['height'] as String?;
     return RestoredWallet(
       restoreMode: json['mode'] as WalletRestoreMode,
@@ -39,7 +51,7 @@ class RestoredWallet {
       address: json['address'] as String?,
       spendKey: json['spend_key'] as String?,
       viewKey: json['view_key'] as String?,
-      height: height != null ? int.parse(height) : 0,
+      height: height != null ? int.tryParse(height)??0 : 0,
       privateKey: json['private_key'] as String?,
     );
   }
diff --git a/lib/view_model/restore/wallet_restore_from_qr_code.dart b/lib/view_model/restore/wallet_restore_from_qr_code.dart
index 23850befa..c1a19ea57 100644
--- a/lib/view_model/restore/wallet_restore_from_qr_code.dart
+++ b/lib/view_model/restore/wallet_restore_from_qr_code.dart
@@ -1,3 +1,5 @@
+import 'dart:convert';
+
 import 'package:cake_wallet/core/seed_validator.dart';
 import 'package:cake_wallet/entities/parse_address_from_domain.dart';
 import 'package:cake_wallet/entities/qr_scanner.dart';
@@ -48,6 +50,17 @@ class WalletRestoreFromQRCode {
 
     final extracted = sortedKeys.firstWhereOrNull((key) => code.toLowerCase().contains(key));
 
+    if (extracted == null) {
+      // Special case for view-only monero wallet
+      final codeParsed = json.decode(code);
+      if (codeParsed["version"] == 0 &&
+          codeParsed["primaryAddress"] != null &&
+          codeParsed["privateViewKey"] != null &&
+          codeParsed["restoreHeight"] != null) {
+        return WalletType.monero;
+      }
+    }
+
     return _walletTypeMap[extracted];
   }
 
@@ -75,7 +88,7 @@ class WalletRestoreFromQRCode {
   }
 
   static Future<RestoredWallet> scanQRCodeForRestoring(BuildContext context) async {
-    String code = await presentQRScanner();
+    String code = await presentQRScanner(context);
     if (code.isEmpty) throw Exception('Unexpected scan QR code value: value is empty');
 
     WalletType? walletType;
@@ -109,7 +122,7 @@ class WalletRestoreFromQRCode {
       queryParameters['address'] = _extractAddressFromUrl(code, walletType!);
     }
 
-    Map<String, dynamic> credentials = {'type': walletType, ...queryParameters};
+    Map<String, dynamic> credentials = {'type': walletType, ...queryParameters, 'raw_qr': code};
 
     credentials['mode'] = _determineWalletRestoreMode(credentials);
 
@@ -205,6 +218,17 @@ class WalletRestoreFromQRCode {
       return WalletRestoreMode.keys;
     }
 
+    if (type == WalletType.monero) {
+      final codeParsed = json.decode(credentials['raw_qr'].toString());
+      if (codeParsed["version"] != 0) throw UnimplementedError("Found view-only restore with unsupported version");
+      if (codeParsed["primaryAddress"] == null ||
+          codeParsed["privateViewKey"] == null ||
+          codeParsed["restoreHeight"] == null) {
+        throw UnimplementedError("Missing one or more attributes in the JSON");
+      }
+      return WalletRestoreMode.keys;
+    }
+
     throw Exception('Unexpected restore mode: restore params are invalid');
   }
 }
diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart
index 1403eb109..4621e8d16 100644
--- a/lib/view_model/send/send_view_model.dart
+++ b/lib/view_model/send/send_view_model.dart
@@ -1,3 +1,4 @@
+import 'package:cake_wallet/di.dart';
 import 'package:cake_wallet/entities/contact.dart';
 import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
 import 'package:cake_wallet/entities/transaction_description.dart';
@@ -10,7 +11,9 @@ import 'package:cake_wallet/entities/contact_record.dart';
 import 'package:cake_wallet/entities/wallet_contact.dart';
 import 'package:cake_wallet/polygon/polygon.dart';
 import 'package:cake_wallet/reactions/wallet_connect.dart';
+import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/solana/solana.dart';
+import 'package:cake_wallet/src/screens/ur/animated_ur_page.dart';
 import 'package:cake_wallet/store/app_store.dart';
 import 'package:cake_wallet/tron/tron.dart';
 import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
@@ -23,6 +26,7 @@ import 'package:cw_core/transaction_priority.dart';
 import 'package:cw_core/unspent_coin_type.dart';
 import 'package:cake_wallet/view_model/send/output.dart';
 import 'package:cake_wallet/view_model/send/send_template_view_model.dart';
+import 'package:flutter/material.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cake_wallet/entities/template.dart';
@@ -457,7 +461,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
   }
 
   @action
-  Future<void> commitTransaction() async {
+  Future<void> commitTransaction(BuildContext context) async {
     if (pendingTransaction == null) {
       throw Exception("Pending transaction doesn't exist. It should not be happened.");
     }
@@ -476,7 +480,17 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
 
     try {
       state = TransactionCommitting();
-      await pendingTransaction!.commit();
+      
+      if (pendingTransaction!.shouldCommitUR()) {
+        final urstr = await pendingTransaction!.commitUR();
+        final result = await Navigator.of(context).pushNamed(Routes.urqrAnimatedPage, arguments: urstr);
+        if (result == null) {
+          state = FailureState("Canceled by user");
+          return;
+        }
+      } else {
+        await pendingTransaction!.commit();
+      }
 
       if (walletType == WalletType.nano) {
         nano!.updateTransactions(wallet);
diff --git a/lib/view_model/wallet_keys_view_model.dart b/lib/view_model/wallet_keys_view_model.dart
index 6455fc0e3..81eda7cc8 100644
--- a/lib/view_model/wallet_keys_view_model.dart
+++ b/lib/view_model/wallet_keys_view_model.dart
@@ -72,6 +72,10 @@ abstract class WalletKeysViewModelBase with Store {
       final keys = monero!.getKeys(_appStore.wallet!);
 
       items.addAll([
+        if (keys['primaryAddress'] != null)
+          StandartListItem(
+              title: S.current.primary_address,
+              value: keys['primaryAddress']!),
         if (keys['publicSpendKey'] != null)
           StandartListItem(
             key: ValueKey('${_walletName}_wallet_public_spend_key_item_key'),
@@ -131,6 +135,10 @@ abstract class WalletKeysViewModelBase with Store {
       final keys = haven!.getKeys(_appStore.wallet!);
 
       items.addAll([
+        if (keys['primaryAddress'] != null)
+          StandartListItem(
+              title: S.current.primary_address,
+              value: keys['primaryAddress']!),
         if (keys['publicSpendKey'] != null)
           StandartListItem(
             key: ValueKey('${_walletName}_wallet_public_spend_key_item_key'),
@@ -168,6 +176,10 @@ abstract class WalletKeysViewModelBase with Store {
       final keys = wownero!.getKeys(_appStore.wallet!);
 
       items.addAll([
+        if (keys['primaryAddress'] != null)
+          StandartListItem(
+              title: S.current.primary_address,
+              value: keys['primaryAddress']!),
         if (keys['publicSpendKey'] != null)
           StandartListItem(
             key: ValueKey('${_walletName}_wallet_public_spend_key_item_key'),
diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake
index f52be7481..4b9eb3b2d 100644
--- a/linux/flutter/generated_plugins.cmake
+++ b/linux/flutter/generated_plugins.cmake
@@ -10,7 +10,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
 )
 
 list(APPEND FLUTTER_FFI_PLUGIN_LIST
-  sp_scanner
 )
 
 set(PLUGIN_BUNDLED_LIBRARIES)
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index 9895e6305..52b44e53e 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -6,9 +6,9 @@ import FlutterMacOS
 import Foundation
 
 import connectivity_plus
-import cw_mweb
 import device_info_plus
 import devicelocale
+import fast_scanner
 import flutter_inappwebview_macos
 import flutter_local_authentication
 import flutter_secure_storage_macos
@@ -23,9 +23,9 @@ import wakelock_plus
 
 func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
   ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
-  CwMwebPlugin.register(with: registry.registrar(forPlugin: "CwMwebPlugin"))
   DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
   DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin"))
+  MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin"))
   InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
   FlutterLocalAuthenticationPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalAuthenticationPlugin"))
   FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
diff --git a/macos/Podfile.lock b/macos/Podfile.lock
index d6199d028..001d75696 100644
--- a/macos/Podfile.lock
+++ b/macos/Podfile.lock
@@ -8,6 +8,8 @@ PODS:
     - FlutterMacOS
   - devicelocale (0.0.1):
     - FlutterMacOS
+  - fast_scanner (5.1.1):
+    - FlutterMacOS
   - flutter_inappwebview_macos (0.0.1):
     - FlutterMacOS
     - OrderedSet (~> 5.0)
@@ -42,6 +44,7 @@ DEPENDENCIES:
   - cw_mweb (from `Flutter/ephemeral/.symlinks/plugins/cw_mweb/macos`)
   - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
   - devicelocale (from `Flutter/ephemeral/.symlinks/plugins/devicelocale/macos`)
+  - fast_scanner (from `Flutter/ephemeral/.symlinks/plugins/fast_scanner/macos`)
   - flutter_inappwebview_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos`)
   - flutter_local_authentication (from `Flutter/ephemeral/.symlinks/plugins/flutter_local_authentication/macos`)
   - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`)
@@ -69,6 +72,8 @@ EXTERNAL SOURCES:
     :path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
   devicelocale:
     :path: Flutter/ephemeral/.symlinks/plugins/devicelocale/macos
+  fast_scanner:
+    :path: Flutter/ephemeral/.symlinks/plugins/fast_scanner/macos
   flutter_inappwebview_macos:
     :path: Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos
   flutter_local_authentication:
@@ -99,6 +104,7 @@ SPEC CHECKSUMS:
   cw_mweb: 7440b12ead811dda972a9918442ea2a458e8742c
   device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f
   devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225
+  fast_scanner: d31bae07e2653403a69dac99fb710c1722b16a97
   flutter_inappwebview_macos: 9600c9df9fdb346aaa8933812009f8d94304203d
   flutter_local_authentication: 85674893931e1c9cfa7c9e4f5973cb8c56b018b0
   flutter_secure_storage_macos: d56e2d218c1130b262bef8b4a7d64f88d7f9c9ea
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 2abd8401a..fa70b5837 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -14,8 +14,10 @@ dependencies:
   # provider: ^6.0.3
   rxdart: ^0.28.0
   yaml: ^3.1.1
-  #barcode_scan: any
-  barcode_scan2: ^4.2.1
+  fast_scanner:
+    git:
+      url: https://github.com/MrCyjaneK/fast_scanner
+      ref: c8311b46cc67dd02250970a54d2a4526168187f3
   http: ^1.1.0
   path_provider: ^2.0.11
   mobx: ^2.1.4
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index b8c933a2e..fc0ea8ea9 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "رابط Clearnet",
   "close": "يغلق",
   "coin_control": "التحكم في العملة (اختياري)",
-  "cold_or_recover_wallet": "أضف محفظة باردة أو استعد محفظة ورقية",
+  "cold_or_recover_wallet": "أضف محفظة للقراءة فقط من Cupcake أو محفظة باردة أو استعاد محفظة ورقية",
   "color_theme": "سمة اللون",
   "commit_transaction_amount_fee": "تنفيذ الصفقة\nالمبلغ: ${amount}\nالرسوم: ${fee}",
   "confirm": "تأكيد",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "جهات الاتصال",
   "contact_list_wallets": "محافظ",
   "contact_name": "اسم جهة الاتصال",
+  "contact_name_exists": "                   .ﻒﻠﺘﺨﻣ ﻢﺳﺍ ﺭﺎﻴﺘﺧﺍ ءﺎﺟﺮﻟﺍ .ﻞﻌﻔﻟﺎﺑ ﺓﺩﻮﺟﻮﻣ ﻢﺳﻻﺍ ﺍﺬﻬﺑ ﻝﺎﺼﺗﺍ ﺔﻬﺟ",
   "contact_support": "اتصل بالدعم",
   "continue_text": "التالي",
   "contract_warning": "تم وضع علامة على عنوان العقد هذا على أنه احتيالي محتمل. يرجى المعالجة بحذر.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "انتهاء الصلاحية والصلاحية",
   "export_backup": "تصدير نسخة احتياطية",
   "export_logs": "سجلات التصدير",
+  "export_outputs": "مخرجات التصدير",
   "extra_id": "معرف إضافي:",
   "extracted_address_content": "سوف ترسل الأموال إلى\n${recipient_name}",
   "failed_authentication": "${state_error} فشل المصادقة.",
@@ -336,7 +338,9 @@
   "haven_app": "Haven بواسطة Cake Wallet",
   "haven_app_wallet_text": "محفظة رائعة ل Haven",
   "help": "مساعده",
+  "hidden_addresses": "العناوين المخفية",
   "hidden_balance": "الميزان الخفي",
+  "hide": "يخفي",
   "hide_details": "أخف التفاصيل",
   "high_contrast_theme": "موضوع عالي التباين",
   "home_screen_settings": "إعدادات الشاشة الرئيسية",
@@ -500,6 +504,7 @@
   "pre_seed_title": "مهم",
   "prepaid_cards": "البطاقات المدفوعة مسبقا",
   "prevent_screenshots": "منع لقطات الشاشة وتسجيل الشاشة",
+  "primary_address": "العنوان الأساسي",
   "privacy": "خصوصية",
   "privacy_policy": "سياسة الخصوصية",
   "privacy_settings": "إعدادات الخصوصية",
@@ -696,6 +701,7 @@
   "share": "يشارك",
   "share_address": "شارك العنوان",
   "shared_seed_wallet_groups": "مجموعات محفظة البذور المشتركة",
+  "show": "يعرض",
   "show_details": "اظهر التفاصيل",
   "show_keys": "اظهار السييد / المفاتيح",
   "show_market_place": "إظهار السوق",
@@ -942,6 +948,5 @@
   "you_pay": "انت تدفع",
   "you_will_get": "حول الى",
   "you_will_send": "تحويل من",
-  "yy": "YY",
-  "contact_name_exists": "                   .ﻒﻠﺘﺨﻣ ﻢﺳﺍ ﺭﺎﻴﺘﺧﺍ ءﺎﺟﺮﻟﺍ .ﻞﻌﻔﻟﺎﺑ ﺓﺩﻮﺟﻮﻣ ﻢﺳﻻﺍ ﺍﺬﻬﺑ ﻝﺎﺼﺗﺍ ﺔﻬﺟ"
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index 2fd644d01..e66a40b36 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Clearnet връзка",
   "close": "затвори",
   "coin_control": "Управление на монетите (не е задължително)",
-  "cold_or_recover_wallet": "Добавете студен портфейл или възстановете хартиен портфейл",
+  "cold_or_recover_wallet": "Добавете портфейл само за четене от Cupcake или студен портфейл или възстановете хартиен портфейл",
   "color_theme": "Цвят",
   "commit_transaction_amount_fee": "Изпълняване на транзакция\nСума: ${amount}\nТакса: ${fee}",
   "confirm": "Потвърждаване",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Контакти",
   "contact_list_wallets": "Моите портфейли",
   "contact_name": "Име на контакт",
+  "contact_name_exists": "Вече съществува контакт с това име. Моля, изберете друго име.",
   "contact_support": "Свържи се с отдел поддръжка",
   "continue_text": "Напред",
   "contract_warning": "Този адрес на договора е маркиран като потенциално измамник. Моля, обработете с повишено внимание.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Изтичане и валидност",
   "export_backup": "Експортиране на резервно копие",
   "export_logs": "Експортни дневници",
+  "export_outputs": "Експортни резултати",
   "extra_id": "Допълнително ID:",
   "extracted_address_content": "Ще изпратите средства на \n${recipient_name}",
   "failed_authentication": "Неуспешно удостоверяване. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven от Cake Wallet",
   "haven_app_wallet_text": "Невероятен портфейл за Haven",
   "help": "Помощ",
+  "hidden_addresses": "Скрити адреси",
   "hidden_balance": "Скрит баланс",
+  "hide": "Скрий",
   "hide_details": "Скриване на подробностите",
   "high_contrast_theme": "Тема с висок контраст",
   "home_screen_settings": "Настройки на началния екран",
@@ -500,6 +504,7 @@
   "pre_seed_title": "ВАЖНО",
   "prepaid_cards": "Предплатени карти",
   "prevent_screenshots": "Предотвратете екранни снимки и запис на екрана",
+  "primary_address": "Първичен адрес",
   "privacy": "Поверителност",
   "privacy_policy": "Политика за поверителността",
   "privacy_settings": "Настройки за поверителност",
@@ -696,6 +701,7 @@
   "share": "Дял",
   "share_address": "Сподели адрес",
   "shared_seed_wallet_groups": "Споделени групи за портфейли за семена",
+  "show": "Показване",
   "show_details": "Показване на подробностите",
   "show_keys": "Покажи seed/keys",
   "show_market_place": "Покажи пазар",
@@ -942,6 +948,5 @@
   "you_pay": "Вие плащате",
   "you_will_get": "Обръщане в",
   "you_will_send": "Обръщане от",
-  "yy": "гг",
-  "contact_name_exists": "Вече съществува контакт с това име. Моля, изберете друго име."
-}
+  "yy": "гг"
+}
\ No newline at end of file
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index 8f3b5bf28..4911030b2 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Odkaz na Clearnet",
   "close": "zavřít",
   "coin_control": "Volba mincí (nepovinné)",
-  "cold_or_recover_wallet": "Přidejte studenou peněženku nebo obnovte papírovou peněženku",
+  "cold_or_recover_wallet": "Přidejte peněženku pouze pro čtení z Cupcake nebo studené peněženky nebo obnovte papírovou peněženku",
   "color_theme": "Barevný motiv",
   "commit_transaction_amount_fee": "Odeslat transakci\nČástka: ${amount}\nPoplatek: ${fee}",
   "confirm": "Potvrdit",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Kontakty",
   "contact_list_wallets": "Moje peněženky",
   "contact_name": "Jméno kontaktu",
+  "contact_name_exists": "Kontakt s tímto jménem již existuje. Vyberte prosím jiný název.",
   "contact_support": "Kontaktovat podporu",
   "continue_text": "Pokračovat",
   "contract_warning": "Tato adresa smlouvy byla označena jako potenciálně podvodná. Zpracovejte prosím opatrně.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Vypršení a platnost",
   "export_backup": "Exportovat zálohu",
   "export_logs": "Vývozní protokoly",
+  "export_outputs": "Vývozní výstupy",
   "extra_id": "Extra ID:",
   "extracted_address_content": "Prostředky budete posílat na\n${recipient_name}",
   "failed_authentication": "Ověřování selhalo. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven od Cake Wallet",
   "haven_app_wallet_text": "Úžasná peněženka pro Haven",
   "help": "pomoc",
+  "hidden_addresses": "Skryté adresy",
   "hidden_balance": "Skrytý zůstatek",
+  "hide": "Skrýt",
   "hide_details": "Skrýt detaily",
   "high_contrast_theme": "Téma s vysokým kontrastem",
   "home_screen_settings": "Nastavení domovské obrazovky",
@@ -500,6 +504,7 @@
   "pre_seed_title": "DŮLEŽITÉ",
   "prepaid_cards": "Předplacené karty",
   "prevent_screenshots": "Zabránit vytváření snímků obrazovky a nahrávání obrazovky",
+  "primary_address": "Primární adresa",
   "privacy": "Soukromí",
   "privacy_policy": "Zásady ochrany soukromí",
   "privacy_settings": "Nastavení soukromí",
@@ -696,6 +701,7 @@
   "share": "Podíl",
   "share_address": "Sdílet adresu",
   "shared_seed_wallet_groups": "Skupiny sdílených semen",
+  "show": "Show",
   "show_details": "Zobrazit detaily",
   "show_keys": "Zobrazit seed/klíče",
   "show_market_place": "Zobrazit trh",
@@ -942,6 +948,5 @@
   "you_pay": "Zaplatíte",
   "you_will_get": "Směnit na",
   "you_will_send": "Směnit z",
-  "yy": "YY",
-  "contact_name_exists": "Kontakt s tímto jménem již existuje. Vyberte prosím jiný název."
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 77a531d1b..a69174dd6 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Clearnet-Link",
   "close": "Schließen",
   "coin_control": "Coin Control (optional)",
-  "cold_or_recover_wallet": "Fügen Sie eine Cold Wallet hinzu oder stellen Sie eine Paper Wallet wieder her",
+  "cold_or_recover_wallet": "Fügen Sie eine schreibgeschützte Brieftasche von Cupcake oder eine kalte Brieftasche hinzu oder erholen Sie sich eine Brieftasche",
   "color_theme": "Farbthema",
   "commit_transaction_amount_fee": "Transaktion absenden\nBetrag: ${amount}\nGebühr: ${fee}",
   "confirm": "Bestätigen",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Kontakte",
   "contact_list_wallets": "Meine Wallets",
   "contact_name": "Name des Kontakts",
+  "contact_name_exists": "Ein Kontakt mit diesem Namen besteht bereits. Bitte wählen Sie einen anderen Namen.",
   "contact_support": "Support kontaktieren",
   "continue_text": "Weiter",
   "contract_warning": "Diese Vertragsadresse wurde als potenziell betrügerisch gekennzeichnet. Bitte verarbeiten Sie mit Vorsicht.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Ablauf und Gültigkeit",
   "export_backup": "Sicherung exportieren",
   "export_logs": "Exportprotokolle",
+  "export_outputs": "Exportausgaben",
   "extra_id": "Extra ID:",
   "extracted_address_content": "Sie senden Geld an\n${recipient_name}",
   "failed_authentication": "Authentifizierung fehlgeschlagen. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven von Cake Wallet",
   "haven_app_wallet_text": "Eine großartige Wallet für Haven",
   "help": "hilfe",
+  "hidden_addresses": "Versteckte Adressen",
   "hidden_balance": "Verstecktes Guthaben",
+  "hide": "Verstecken",
   "hide_details": "Details ausblenden",
   "high_contrast_theme": "Kontrastreiches Thema",
   "home_screen_settings": "Einstellungen für den Startbildschirm",
@@ -501,6 +505,7 @@
   "pre_seed_title": "WICHTIG",
   "prepaid_cards": "Karten mit Guthaben",
   "prevent_screenshots": "Verhindern Sie Screenshots und Bildschirmaufzeichnungen",
+  "primary_address": "Primäradresse",
   "privacy": "Datenschutz",
   "privacy_policy": "Datenschutzrichtlinie",
   "privacy_settings": "Datenschutzeinstellungen",
@@ -697,6 +702,7 @@
   "share": "Teilen",
   "share_address": "Adresse teilen ",
   "shared_seed_wallet_groups": "Gemeinsame Walletsseed Gruppen",
+  "show": "Zeigen",
   "show_details": "Details anzeigen",
   "show_keys": "Seed/Schlüssel anzeigen",
   "show_market_place": "Marktplatz anzeigen",
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 4fe375ff9..322e38b85 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Clearnet link",
   "close": "Close",
   "coin_control": "Coin control (optional)",
-  "cold_or_recover_wallet": "Add a cold wallet or recover a paper wallet",
+  "cold_or_recover_wallet": "Add a read-only wallet from Cupcake or a cold wallet or recover a paper wallet",
   "color_theme": "Color theme",
   "commit_transaction_amount_fee": "Commit transaction\nAmount: ${amount}\nFee: ${fee}",
   "confirm": "Confirm",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Contacts",
   "contact_list_wallets": "My Wallets",
   "contact_name": "Contact Name",
+  "contact_name_exists": "A contact with that name already exists. Please choose a different name.",
   "contact_support": "Contact Support",
   "continue_text": "Continue",
   "contract_warning": "This contract address has been flagged as potentially fraudulent. Please process with caution.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Expiry and Validity",
   "export_backup": "Export backup",
   "export_logs": "Export logs",
+  "export_outputs": "Export outputs",
   "extra_id": "Extra ID:",
   "extracted_address_content": "You will be sending funds to\n${recipient_name}",
   "failed_authentication": "Failed authentication. ${state_error}",
@@ -502,6 +504,7 @@
   "pre_seed_title": "IMPORTANT",
   "prepaid_cards": "Prepaid Cards",
   "prevent_screenshots": "Prevent screenshots and screen recording",
+  "primary_address": "Primary Address",
   "privacy": "Privacy",
   "privacy_policy": "Privacy Policy",
   "privacy_settings": "Privacy settings",
@@ -945,6 +948,5 @@
   "you_pay": "You Pay",
   "you_will_get": "Convert to",
   "you_will_send": "Convert from",
-  "yy": "YY",
-  "contact_name_exists": "A contact with that name already exists. Please choose a different name."
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 31498df2d..5a8ff0582 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "enlace Clearnet",
   "close": "Cerca",
   "coin_control": "Control de monedas (opcional)",
-  "cold_or_recover_wallet": "Agrega una billetera fría o recupera una billetera de papel",
+  "cold_or_recover_wallet": "Agregue una billetera de solo lectura de Cupcake o una billetera en frío o recupere una billetera de papel",
   "color_theme": "Tema de color",
   "commit_transaction_amount_fee": "Confirmar transacción\nCantidad: ${amount}\nCuota: ${fee}",
   "confirm": "Confirmar",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Contactos",
   "contact_list_wallets": "Mis billeteras",
   "contact_name": "Nombre de contacto",
+  "contact_name_exists": "Ya existe un contacto con ese nombre. Elija un nombre diferente.",
   "contact_support": "Contactar con Soporte",
   "continue_text": "Continuar",
   "contract_warning": "Esta dirección de contrato ha sido marcada como potencialmente fraudulenta. Por favor, procese con precaución.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Vencimiento y validez",
   "export_backup": "Exportar copia de seguridad",
   "export_logs": "Registros de exportación",
+  "export_outputs": "Exportaciones de exportación",
   "extra_id": "ID adicional:",
   "extracted_address_content": "Enviará fondos a\n${recipient_name}",
   "failed_authentication": "Autenticación fallida. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Increíble billetera para Haven",
   "help": "ayuda",
+  "hidden_addresses": "Direcciones ocultas",
   "hidden_balance": "Balance oculto",
+  "hide": "Esconder",
   "hide_details": "Ocultar detalles",
   "high_contrast_theme": "Tema de alto contraste",
   "home_screen_settings": "Configuración de la pantalla de inicio",
@@ -501,6 +505,7 @@
   "pre_seed_title": "IMPORTANTE",
   "prepaid_cards": "Tajetas prepagadas",
   "prevent_screenshots": "Evitar capturas de pantalla y grabación de pantalla",
+  "primary_address": "Dirección principal",
   "privacy": "Privacidad",
   "privacy_policy": "Política de privacidad",
   "privacy_settings": "Configuración de privacidad",
@@ -697,6 +702,7 @@
   "share": "Compartir",
   "share_address": "Compartir dirección",
   "shared_seed_wallet_groups": "Grupos de billetera de semillas compartidas",
+  "show": "Espectáculo",
   "show_details": "Mostrar detalles",
   "show_keys": "Mostrar semilla/claves",
   "show_market_place": "Mostrar mercado",
@@ -943,6 +949,5 @@
   "you_pay": "Tú pagas",
   "you_will_get": "Convertir a",
   "you_will_send": "Convertir de",
-  "yy": "YY",
-  "contact_name_exists": "Ya existe un contacto con ese nombre. Elija un nombre diferente."
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index f96e9e304..6abe72681 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Lien Clearnet",
   "close": "Fermer",
   "coin_control": "Contrôle optionnel des pièces (coins)",
-  "cold_or_recover_wallet": "Ajoutez un portefeuille froid (cold wallet) ou récupérez un portefeuille papier (paper wallet)",
+  "cold_or_recover_wallet": "Ajoutez un portefeuille en lecture seule de Cupcake ou d'un portefeuille froid ou récupérez un portefeuille en papier",
   "color_theme": "Thème",
   "commit_transaction_amount_fee": "Valider la transaction\nMontant : ${amount}\nFrais : ${fee}",
   "confirm": "Confirmer",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Contacts",
   "contact_list_wallets": "Mes portefeuilles (wallets)",
   "contact_name": "Nom de Contact",
+  "contact_name_exists": "Un contact portant ce nom existe déjà. Veuillez choisir un autre nom.",
   "contact_support": "Contacter l'assistance",
   "continue_text": "Continuer",
   "contract_warning": "Cette adresse contractuelle a été signalée comme potentiellement frauduleuse. Veuillez traiter avec prudence.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Expiration et validité",
   "export_backup": "Exporter la sauvegarde",
   "export_logs": "Journaux d'exportation",
+  "export_outputs": "Exportation des sorties",
   "extra_id": "ID supplémentaire :",
   "extracted_address_content": "Vous allez envoyer des fonds à\n${recipient_name}",
   "failed_authentication": "Échec d'authentification. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven par Cake Wallet",
   "haven_app_wallet_text": "Super portefeuille (wallet) pour Haven",
   "help": "aide",
+  "hidden_addresses": "Adresses cachées",
   "hidden_balance": "Solde Caché",
+  "hide": "Cacher",
   "hide_details": "Masquer les détails",
   "high_contrast_theme": "Thème à contraste élevé",
   "home_screen_settings": "Paramètres de l'écran d'accueil",
@@ -500,6 +504,7 @@
   "pre_seed_title": "IMPORTANT",
   "prepaid_cards": "Cartes prépayées",
   "prevent_screenshots": "Empêcher les captures d'écran et l'enregistrement d'écran",
+  "primary_address": "Adresse primaire",
   "privacy": "Confidentialité",
   "privacy_policy": "Politique de confidentialité",
   "privacy_settings": "Paramètres de confidentialité",
@@ -696,6 +701,7 @@
   "share": "Partager",
   "share_address": "Partager l'adresse",
   "shared_seed_wallet_groups": "Groupes de portefeuilles partagés",
+  "show": "Montrer",
   "show_details": "Afficher les détails",
   "show_keys": "Visualiser la phrase secrète (seed) et les clefs",
   "show_market_place": "Afficher la place de marché",
@@ -942,6 +948,5 @@
   "you_pay": "Vous payez",
   "you_will_get": "Convertir vers",
   "you_will_send": "Convertir depuis",
-  "yy": "AA",
-  "contact_name_exists": "Un contact portant ce nom existe déjà. Veuillez choisir un autre nom."
-}
+  "yy": "AA"
+}
\ No newline at end of file
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index 5fc64e0b3..5a53d6795 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Lambar makomar kwayoyi",
   "close": "Rufa",
   "coin_control": "Sarrafa tsabar kuɗi (na zaɓi)",
-  "cold_or_recover_wallet": "Samun kashi na baya ko samun kashi na kasa",
+  "cold_or_recover_wallet": "Aara wani walat mai karanta-kawai Cupcake ko walat ɗin mai sanyi ko murmurewa takarda takarda",
   "color_theme": "Jigon launi",
   "commit_transaction_amount_fee": "Aikata ciniki\nAdadi: ${amount}\nKuda: ${fee}",
   "confirm": "Tabbatar",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Lambobin sadarwa",
   "contact_list_wallets": "Wallets dina",
   "contact_name": "Sunan Tuntuɓi",
+  "contact_name_exists": "An riga an sami lamba tare da wannan sunan. Da fatan za a zaɓi suna daban.",
   "contact_support": "Tuntuɓi Support",
   "continue_text": "Ci gaba",
   "contract_warning": "An kafa wannan adireshin kwantaragin kwangilar yayin da yuwuwar zamba. Da fatan za a aiwatar da taka tsantsan.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Karewa da inganci",
   "export_backup": "Ajiyayyen fitarwa",
   "export_logs": "Injin fitarwa",
+  "export_outputs": "Fitarwar fitarwa",
   "extra_id": "Karin ID:",
   "extracted_address_content": "Za ku aika da kudade zuwa\n${recipient_name}",
   "failed_authentication": "Binne wajen shiga. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven da Cake Wallet",
   "haven_app_wallet_text": "Aikace-aikacen e-wallet ga Haven",
   "help": "taimako",
+  "hidden_addresses": "Adireshin ɓoye",
   "hidden_balance": "BOYE KUDI",
+  "hide": "Ɓoye",
   "hide_details": "Ɓoye cikakkun bayanai",
   "high_contrast_theme": "Babban Jigon Kwatance",
   "home_screen_settings": "Saitunan allo na gida",
@@ -502,6 +506,7 @@
   "pre_seed_title": "MUHIMMANCI",
   "prepaid_cards": "Katunan shirye-shirye",
   "prevent_screenshots": "Fada lambobi da jarrabobi na kayan lambobi",
+  "primary_address": "Adireshin farko",
   "privacy": "Keɓantawa",
   "privacy_policy": "takardar kebantawa",
   "privacy_settings": "Saitunan sirri",
@@ -698,6 +703,7 @@
   "share": "Raba",
   "share_address": "Raba adireshin",
   "shared_seed_wallet_groups": "Raba ƙungiya walat",
+  "show": "Nuna",
   "show_details": "Nuna Cikakkun bayanai",
   "show_keys": "Nuna iri/maɓallai",
   "show_market_place": "Nuna dan kasuwa",
@@ -944,6 +950,5 @@
   "you_pay": "Ka Bayar",
   "you_will_get": "Maida zuwa",
   "you_will_send": "Maida daga",
-  "yy": "YY",
-  "contact_name_exists": "An riga an sami lamba tare da wannan sunan. Da fatan za a zaɓi suna daban."
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index fb3b78900..d130c2b5f 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "क्लियरनेट लिंक",
   "close": "बंद करना",
   "coin_control": "सिक्का नियंत्रण (वैकल्पिक)",
-  "cold_or_recover_wallet": "कोल्ड वॉलेट जोड़ें या पेपर वॉलेट पुनर्प्राप्त करें",
+  "cold_or_recover_wallet": "Cupcake या एक कोल्ड वॉलेट से एक रीड-ओनली वॉलेट जोड़ें या एक पेपर वॉलेट को पुनर्प्राप्त करें",
   "color_theme": "रंग विषय",
   "commit_transaction_amount_fee": "लेन-देन करें\nरकम: ${amount}\nशुल्क: ${fee}",
   "confirm": "की पुष्टि करें",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "संपर्क",
   "contact_list_wallets": "मेरा बटुआ",
   "contact_name": "संपर्क नाम",
+  "contact_name_exists": "उस नाम का एक संपर्क पहले से मौजूद है. कृपया कोई भिन्न नाम चुनें.",
   "contact_support": "सहायता से संपर्क करें",
   "continue_text": "जारी रहना",
   "contract_warning": "इस अनुबंध के पते को संभावित रूप से धोखाधड़ी के रूप में चिह्नित किया गया है। कृपया सावधानी के साथ प्रक्रिया करें।",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "समाप्ति और वैधता",
   "export_backup": "निर्यात बैकअप",
   "export_logs": "निर्यात लॉग",
+  "export_outputs": "निर्यात आउटपुट",
   "extra_id": "अतिरिक्त आईडी:",
   "extracted_address_content": "आपको धनराशि भेजी जाएगी\n${recipient_name}",
   "failed_authentication": "प्रमाणीकरण विफल. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Awesome wallet for Haven",
   "help": "मदद करना",
+  "hidden_addresses": "छिपे हुए पते",
   "hidden_balance": "छिपा हुआ संतुलन",
+  "hide": "छिपाना",
   "hide_details": "विवरण छुपाएं",
   "high_contrast_theme": "उच्च कंट्रास्ट थीम",
   "home_screen_settings": "होम स्क्रीन सेटिंग्स",
@@ -501,6 +505,7 @@
   "pre_seed_title": "महत्वपूर्ण",
   "prepaid_cards": "पूर्वदत्त कार्ड",
   "prevent_screenshots": "स्क्रीनशॉट और स्क्रीन रिकॉर्डिंग रोकें",
+  "primary_address": "प्राथमिक पता",
   "privacy": "गोपनीयता",
   "privacy_policy": "गोपनीयता नीति",
   "privacy_settings": "गोपनीयता सेटिंग्स",
@@ -698,6 +703,7 @@
   "share": "शेयर करना",
   "share_address": "पता साझा करें",
   "shared_seed_wallet_groups": "साझा बीज बटुए समूह",
+  "show": "दिखाओ",
   "show_details": "विवरण दिखाएं",
   "show_keys": "बीज / कुंजियाँ दिखाएँ",
   "show_market_place": "बाज़ार दिखाएँ",
@@ -944,6 +950,5 @@
   "you_pay": "आप भुगतान करते हैं",
   "you_will_get": "में बदलें",
   "you_will_send": "से रूपांतरित करें",
-  "yy": "वाईवाई",
-  "contact_name_exists": "उस नाम का एक संपर्क पहले से मौजूद है. कृपया कोई भिन्न नाम चुनें."
-}
+  "yy": "वाईवाई"
+}
\ No newline at end of file
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 230aa955b..037e6e9f2 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Clearnet veza",
   "close": "Zatvoriti",
   "coin_control": "Kontrola novca (nije obavezno)",
-  "cold_or_recover_wallet": "Dodajte hladni novčanik ili povratite papirnati novčanik",
+  "cold_or_recover_wallet": "Dodajte novčanik samo za čitanje od Cupcake ili hladnog novčanika ili oporavite papirni novčanik",
   "color_theme": "Shema boja",
   "commit_transaction_amount_fee": "Izvrši transakciju \nAmount: ${amount}\nFee: ${fee}",
   "confirm": "Potvrdi",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Kontakti",
   "contact_list_wallets": "Moji novčanici",
   "contact_name": "Ime kontakta",
+  "contact_name_exists": "Kontakt s tim imenom već postoji. Odaberite drugo ime.",
   "contact_support": "Kontaktirajte podršku",
   "continue_text": "Nastavak",
   "contract_warning": "Ova adresa ugovora označena je kao potencijalno lažna. Molimo obradite s oprezom.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Istek i valjanost",
   "export_backup": "Izvezi sigurnosnu kopiju",
   "export_logs": "Izvozni trupci",
+  "export_outputs": "Izvoz izlaza",
   "extra_id": "Dodatni ID:",
   "extracted_address_content": "Poslat ćete sredstva primatelju\n${recipient_name}",
   "failed_authentication": "Autentifikacija neuspješna. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Awesome wallet for Haven",
   "help": "pomozite",
+  "hidden_addresses": "Skrivene adrese",
   "hidden_balance": "Skriven iznos",
+  "hide": "Sakriti",
   "hide_details": "Sakrij pojedinosti",
   "high_contrast_theme": "Tema visokog kontrasta",
   "home_screen_settings": "Postavke početnog zaslona",
@@ -500,6 +504,7 @@
   "pre_seed_title": "VAŽNO",
   "prepaid_cards": "Unaprijed plaćene kartice",
   "prevent_screenshots": "Spriječite snimke zaslona i snimanje zaslona",
+  "primary_address": "Primarna adresa",
   "privacy": "Privatnost",
   "privacy_policy": "Pravila privatnosti",
   "privacy_settings": "Postavke privatnosti",
@@ -696,6 +701,7 @@
   "share": "Udio",
   "share_address": "Podijeli adresu",
   "shared_seed_wallet_groups": "Zajedničke grupe za sjeme novčanika",
+  "show": "Pokazati",
   "show_details": "Prikaži pojedinosti",
   "show_keys": "Prikaži pristupni izraz/ključ",
   "show_market_place": "Prikaži tržište",
@@ -942,6 +948,5 @@
   "you_pay": "Vi plaćate",
   "you_will_get": "Razmijeni u",
   "you_will_send": "Razmijeni iz",
-  "yy": "GG",
-  "contact_name_exists": "Kontakt s tim imenom već postoji. Odaberite drugo ime."
-}
+  "yy": "GG"
+}
\ No newline at end of file
diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb
index 63a986103..04a7cddf5 100644
--- a/res/values/strings_hy.arb
+++ b/res/values/strings_hy.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Բաց ցանցի հղում",
   "close": "Փակել",
   "coin_control": "Մետաղադրամի վերահսկում (ըստ ցանկության)",
-  "cold_or_recover_wallet": "Ավելացնել սառը դրամապանակ կամ վերականգնել թղթային դրամապանակ",
+  "cold_or_recover_wallet": "Cupcake կամ ցուրտ դրամապանակից ավելացնել միայն ընթերցված դրամապանակ կամ վերականգնել թղթի դրամապանակը",
   "color_theme": "Գույների տեսք",
   "commit_transaction_amount_fee": "Հաստատել գործարքը\nՍկզբնական գումար. ${amount}\nՄիջնորդավճար. ${fee}",
   "confirm": "Հաստատել",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Կոնտակտներ",
   "contact_list_wallets": "Իմ դրամապանակներ",
   "contact_name": "Կոնտակտի անուն",
+  "contact_name_exists": "Այդ անվանման հետ կապ կա արդեն: Խնդրում ենք ընտրել այլ անուն:",
   "contact_support": "Հետադարձ կապ",
   "continue_text": "Շարունակել",
   "contract_warning": "Պայմանագրի այս հասցեն դրոշմել է որպես հնարավոր կեղծ: Խնդրում ենք զգուշությամբ մշակել:",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Վավերականություն և լրացում",
   "export_backup": "Արտահանել կրկնօրինակը",
   "export_logs": "Արտահանման տեղեկամատյաններ",
+  "export_outputs": "Արտահանման արդյունքներ",
   "extra_id": "Լրացուցիչ ID",
   "extracted_address_content": "Դուք կուղարկեք գումար ${recipient_name}",
   "failed_authentication": "Վավերացումը ձախողվեց. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven ծրագիր",
   "haven_app_wallet_text": "Հիանալի հաշվեհամար Haven համար",
   "help": "Օգնություն",
+  "hidden_addresses": "Թաքնված հասցեներ",
   "hidden_balance": "Թաքնված մնացորդ",
+  "hide": "Թաքցնել",
   "hide_details": "Թաքցնել մանրամասները",
   "high_contrast_theme": "Բարձր հակադրության տեսք",
   "home_screen_settings": "Գլխավոր էկրանի կարգավորումներ",
@@ -366,14 +370,22 @@
   "ledger_error_wrong_app": "Խնդրում ենք համոզվել, որ դուք բացել եք ճիշտ ծրագիրը ձեր Ledger-ում",
   "ledger_please_enable_bluetooth": "Խնդրում ենք միացնել Bluetooth-ը ձեր Ledger-ը հայտնաբերելու համար",
   "light_theme": "Լուսավոր",
+  "litecoin_enable_mweb_sync": "Միացնել MWEB սկան",
+  "litecoin_mweb": "Մուեբ",
+  "litecoin_mweb_always_scan": "Սահմանեք Mweb Միշտ սկանավորում",
   "litecoin_mweb_description": "Mweb- ը նոր արձանագրություն է, որը բերում է ավելի արագ, ավելի էժան եւ ավելի մասնավոր գործարքներ դեպի LITECOIN",
   "litecoin_mweb_dismiss": "Հեռացնել",
+  "litecoin_mweb_display_card": "Show ույց տալ Mweb քարտը",
   "litecoin_mweb_enable": "Միացնել Mweb- ը",
   "litecoin_mweb_enable_later": "Կարող եք ընտրել Mweb- ը կրկին միացնել ցուցադրման պարամետրերը:",
   "litecoin_mweb_logs": "Mweb տեղեկամատյաններ",
   "litecoin_mweb_node": "Mweb հանգույց",
   "litecoin_mweb_pegin": "Peg in",
   "litecoin_mweb_pegout": "Հափշտակել",
+  "litecoin_mweb_scanning": "Mweb սկանավորում",
+  "litecoin_mweb_settings": "Mweb- ի պարամետրերը",
+  "litecoin_mweb_warning": "Mweb- ի օգտագործումը սկզբում ներբեռնվի 600 ՄԲ տվյալներ եւ կարող է տեւել 30 րոպե, կախված ցանցի արագությունից: Այս նախնական տվյալները միայն մեկ անգամ ներբեռնելու են եւ հասանելի կլինեն բոլոր Litecoin դրամապանակների համար",
+  "litecoin_what_is_mweb": "Ինչ է Mweb- ը:",
   "live_fee_rates": "Ապակի վարձավճարներ API- ի միջոցով",
   "load_more": "Բեռնել ավելին",
   "loading_your_wallet": "Ձեր հաշվեհամարը բեռնում է",
@@ -492,6 +504,7 @@
   "pre_seed_title": "ԿԱՐԵՎՈՐ",
   "prepaid_cards": "Նախավճարային քարտեր",
   "prevent_screenshots": "Կանխել էկրանի պատկերները և տեսագրությունը",
+  "primary_address": "Առաջնային հասցե",
   "privacy": "Գաղտնիություն",
   "privacy_policy": "Գաղտնիության քաղաքականություն",
   "privacy_settings": "Գաղտնիության կարգավորումներ",
@@ -688,6 +701,7 @@
   "share": "Կիսվել",
   "share_address": "Կիսվել հասցեով",
   "shared_seed_wallet_groups": "Համօգտագործված սերմերի դրամապանակների խմբեր",
+  "show": "Ցուցահանդես",
   "show_details": "Ցուցադրել մանրամասներ",
   "show_keys": "Ցուցադրել բանալիներ",
   "show_market_place": "Ցուցադրել շուկան",
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index 3fa3a958f..231ac037d 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Tautan clearnet",
   "close": "Menutup",
   "coin_control": "Kontrol koin (opsional)",
-  "cold_or_recover_wallet": "Tambahkan dompet dingin atau pulihkan dompet kertas",
+  "cold_or_recover_wallet": "Tambahkan dompet hanya baca dari Cupcake atau dompet dingin atau memulihkan dompet kertas",
   "color_theme": "Tema warna",
   "commit_transaction_amount_fee": "Lakukan transaksi\nJumlah: ${amount}\nBiaya: ${fee}",
   "confirm": "Konfirmasi",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Kontak",
   "contact_list_wallets": "Dompet Saya",
   "contact_name": "Nama Kontak",
+  "contact_name_exists": "Kontak dengan nama tersebut sudah ada. Silakan pilih nama lain.",
   "contact_support": "Hubungi Dukungan",
   "continue_text": "Lanjutkan",
   "contract_warning": "Alamat kontrak ini telah ditandai sebagai berpotensi curang. Silakan memproses dengan hati -hati.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Kedaluwarsa dan validitas",
   "export_backup": "Ekspor cadangan",
   "export_logs": "Log ekspor",
+  "export_outputs": "Ekspor output",
   "extra_id": "ID tambahan:",
   "extracted_address_content": "Anda akan mengirim dana ke\n${recipient_name}",
   "failed_authentication": "Otentikasi gagal. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven Oleh Cake Wallet",
   "haven_app_wallet_text": "Dompet luar biasa untuk Haven",
   "help": "bantuan",
+  "hidden_addresses": "Alamat tersembunyi",
   "hidden_balance": "Saldo Tersembunyi",
+  "hide": "Bersembunyi",
   "hide_details": "Sembunyikan Rincian",
   "high_contrast_theme": "Tema Kontras Tinggi",
   "home_screen_settings": "Pengaturan layar awal",
@@ -502,6 +506,7 @@
   "pre_seed_title": "PENTING",
   "prepaid_cards": "Kartu prabayar",
   "prevent_screenshots": "Cegah tangkapan layar dan perekaman layar",
+  "primary_address": "Alamat utama",
   "privacy": "Privasi",
   "privacy_policy": "Kebijakan Privasi",
   "privacy_settings": "Pengaturan privasi",
@@ -699,6 +704,7 @@
   "share": "Membagikan",
   "share_address": "Bagikan alamat",
   "shared_seed_wallet_groups": "Kelompok dompet benih bersama",
+  "show": "Menunjukkan",
   "show_details": "Tampilkan Rincian",
   "show_keys": "Tampilkan seed/kunci",
   "show_market_place": "Tampilkan Pasar",
@@ -945,6 +951,5 @@
   "you_pay": "Anda Membayar",
   "you_will_get": "Konversi ke",
   "you_will_send": "Konversi dari",
-  "yy": "YY",
-  "contact_name_exists": "Kontak dengan nama tersebut sudah ada. Silakan pilih nama lain."
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index aab18d434..b06a35537 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Collegamento Clearnet",
   "close": "Chiudere",
   "coin_control": "Controllo monete (opzionale)",
-  "cold_or_recover_wallet": "Aggiungi un cold wallet o recupera un paper wallet",
+  "cold_or_recover_wallet": "Aggiungi un portafoglio di sola lettura da Cupcake o un portafoglio freddo o recupera un portafoglio di carta",
   "color_theme": "Colore tema",
   "commit_transaction_amount_fee": "Invia transazione\nAmmontare: ${amount}\nCommissione: ${fee}",
   "confirm": "Conferma",
@@ -162,6 +162,7 @@
   "contact_list_contacts": "Contatti",
   "contact_list_wallets": "I miei portafogli",
   "contact_name": "Nome Contatto",
+  "contact_name_exists": "Esiste già un contatto con quel nome. Scegli un nome diverso.",
   "contact_support": "Contatta l'assistenza",
   "continue_text": "Continua",
   "contract_warning": "Questo indirizzo del contratto è stato contrassegnato come potenzialmente fraudolento. Si prega di elaborare con cautela.",
@@ -297,6 +298,7 @@
   "expiry_and_validity": "Scadenza e validità",
   "export_backup": "Esporta backup",
   "export_logs": "Registri di esportazione",
+  "export_outputs": "Output di esportazione",
   "extra_id": "Extra ID:",
   "extracted_address_content": "Invierai i tuoi fondi a\n${recipient_name}",
   "failed_authentication": "Autenticazione fallita. ${state_error}",
@@ -337,7 +339,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Portafoglio fantastico per Haven",
   "help": "aiuto",
+  "hidden_addresses": "Indirizzi nascosti",
   "hidden_balance": "Saldo Nascosto",
+  "hide": "Nascondere",
   "hide_details": "Nascondi dettagli",
   "high_contrast_theme": "Tema ad alto contrasto",
   "home_screen_settings": "Impostazioni della schermata iniziale",
@@ -502,6 +506,7 @@
   "pre_seed_title": "IMPORTANTE",
   "prepaid_cards": "Carte prepagata",
   "prevent_screenshots": "Impedisci screenshot e registrazione dello schermo",
+  "primary_address": "Indirizzo primario",
   "privacy": "Privacy",
   "privacy_policy": "Informativa sulla privacy",
   "privacy_settings": "Impostazioni privacy",
@@ -698,6 +703,7 @@
   "share": "Condividere",
   "share_address": "Condividi indirizzo",
   "shared_seed_wallet_groups": "Gruppi di portafoglio di semi condivisi",
+  "show": "Spettacolo",
   "show_details": "Mostra dettagli",
   "show_keys": "Mostra seme/chiavi",
   "show_market_place": "Mostra mercato",
@@ -945,6 +951,5 @@
   "you_pay": "Tu paghi",
   "you_will_get": "Converti a",
   "you_will_send": "Conveti da",
-  "yy": "YY",
-  "contact_name_exists": "Esiste già un contatto con quel nome. Scegli un nome diverso."
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index f1fd0acd3..d55c4d5a1 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "クリアネット リンク",
   "close": "近い",
   "coin_control": "コインコントロール(オプション)",
-  "cold_or_recover_wallet": "コールド ウォレットを追加するか、ペーパー ウォレットを復元する",
+  "cold_or_recover_wallet": "Cupcakeまたはコールドウォレットから読み取り専用ウォレットを追加するか、紙の財布を回収する",
   "color_theme": "カラーテーマ",
   "commit_transaction_amount_fee": "トランザクションをコミット\n量: ${amount}\n費用: ${fee}",
   "confirm": "確認する",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "連絡先",
   "contact_list_wallets": "マイウォレット",
   "contact_name": "連絡先",
+  "contact_name_exists": "その名前の連絡先はすでに存在します。別の名前を選択してください。",
   "contact_support": "サポートに連絡する",
   "continue_text": "持続する",
   "contract_warning": "この契約住所は、潜在的に不正としてフラグが立てられています。注意して処理してください。",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "有効期限と有効性",
   "export_backup": "バックアップのエクスポート",
   "export_logs": "ログをエクスポートします",
+  "export_outputs": "エクスポート出力",
   "extra_id": "追加ID:",
   "extracted_address_content": "に送金します\n${recipient_name}",
   "failed_authentication": "認証失敗. ${state_error}",
@@ -337,7 +339,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Awesome wallet for Haven",
   "help": "ヘルプ",
+  "hidden_addresses": "隠されたアドレス",
   "hidden_balance": "隠れたバランス",
+  "hide": "隠れる",
   "hide_details": "詳細を非表示",
   "high_contrast_theme": "ハイコントラストテーマ",
   "home_screen_settings": "ホーム画面の設定",
@@ -501,6 +505,7 @@
   "pre_seed_title": "重要",
   "prepaid_cards": "プリペイドカード",
   "prevent_screenshots": "スクリーンショットと画面録画を防止する",
+  "primary_address": "主なアドレス",
   "privacy": "プライバシー",
   "privacy_policy": "プライバシーポリシー",
   "privacy_settings": "プライバシー設定",
@@ -697,6 +702,7 @@
   "share": "共有",
   "share_address": "住所を共有する",
   "shared_seed_wallet_groups": "共有シードウォレットグループ",
+  "show": "見せる",
   "show_details": "詳細を表示",
   "show_keys": "シード/キーを表示する",
   "show_market_place": "マーケットプレイスを表示",
@@ -943,6 +949,5 @@
   "you_pay": "あなたが支払う",
   "you_will_get": "に変換",
   "you_will_send": "から変換",
-  "yy": "YY",
-  "contact_name_exists": "その名前の連絡先はすでに存在します。別の名前を選択してください。"
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 7e3467cf2..303527fea 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "클리어넷 링크",
   "close": "닫다",
   "coin_control": "코인 제어 (옵션)",
-  "cold_or_recover_wallet": "콜드 지갑 추가 또는 종이 지갑 복구",
+  "cold_or_recover_wallet": "Cupcake 또는 차가운 지갑에서 읽기 전용 지갑을 추가하거나 종이 지갑을 복구하십시오.",
   "color_theme": "색상 테마",
   "commit_transaction_amount_fee": "커밋 거래\n양: ${amount}\n보수: ${fee}",
   "confirm": "확인",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "콘택트 렌즈",
   "contact_list_wallets": "내 지갑",
   "contact_name": "담당자 이름",
+  "contact_name_exists": "해당 이름을 가진 연락처가 이미 존재합니다. 다른 이름을 선택하세요.",
   "contact_support": "지원팀에 문의",
   "continue_text": "잇다",
   "contract_warning": "이 계약 주소는 잠재적으로 사기성으로 표시되었습니다. 주의해서 처리하십시오.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "만료와 타당성",
   "export_backup": "백업 내보내기",
   "export_logs": "내보내기 로그",
+  "export_outputs": "내보내기 출력",
   "extra_id": "추가 ID:",
   "extracted_address_content": "당신은에 자금을 보낼 것입니다\n${recipient_name}",
   "failed_authentication": "인증 실패. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Awesome wallet for Haven",
   "help": "돕다",
+  "hidden_addresses": "숨겨진 주소",
   "hidden_balance": "숨겨진 균형",
+  "hide": "숨다",
   "hide_details": "세부 정보 숨기기",
   "high_contrast_theme": "고대비 테마",
   "home_screen_settings": "홈 화면 설정",
@@ -501,6 +505,7 @@
   "pre_seed_title": "중대한",
   "prepaid_cards": "선불 카드",
   "prevent_screenshots": "스크린샷 및 화면 녹화 방지",
+  "primary_address": "기본 주소",
   "privacy": "프라이버시",
   "privacy_policy": "개인 정보 보호 정책",
   "privacy_settings": "개인정보 설정",
@@ -697,6 +702,7 @@
   "share": "공유하다",
   "share_address": "주소 공유",
   "shared_seed_wallet_groups": "공유 종자 지갑 그룹",
+  "show": "보여주다",
   "show_details": "세부정보 표시",
   "show_keys": "시드 / 키 표시",
   "show_market_place": "마켓플레이스 표시",
@@ -944,6 +950,5 @@
   "you_will_get": "로 변환하다",
   "you_will_send": "다음에서 변환",
   "YY": "YY",
-  "yy": "YY",
-  "contact_name_exists": "해당 이름을 가진 연락처가 이미 존재합니다. 다른 이름을 선택하세요."
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index 10c13cfef..9b9b44657 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Clearnet လင့်ခ်",
   "close": "အနီးကပ်",
   "coin_control": "အကြွေစေ့ထိန်းချုပ်မှု (ချန်လှပ်ထားနိုင်သည်)",
-  "cold_or_recover_wallet": "အေးသောပိုက်ဆံအိတ်ထည့်ပါ သို့မဟုတ် စက္ကူပိုက်ဆံအိတ်ကို ပြန်ယူပါ။",
+  "cold_or_recover_wallet": "Cupcake သို့မဟုတ်အအေးပိုက်ဆံအိတ်မှဖတ်ရန်သာပိုက်ဆံအိတ်တစ်ခုထည့်ပါသို့မဟုတ်စက္ကူပိုက်ဆံအိတ်ကိုပြန်လည်ရယူပါ",
   "color_theme": "အရောင်အပြင်အဆင်",
   "commit_transaction_amount_fee": "ငွေလွှဲခြင်း\nပမာဏ- ${amount}\nအခကြေးငွေ- ${fee}",
   "confirm": "အတည်ပြုပါ။",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "အဆက်အသွယ်များ",
   "contact_list_wallets": "ကျွန်ုပ်၏ ပိုက်ဆံအိတ်များ",
   "contact_name": "ဆက်သွယ်ရန်အမည်",
+  "contact_name_exists": "ထိုအမည်နှင့် အဆက်အသွယ်တစ်ခု ရှိနှင့်ပြီးဖြစ်သည်။ အခြားအမည်တစ်ခုကို ရွေးပါ။",
   "contact_support": "ပံ့ပိုးကူညီမှုထံ ဆက်သွယ်ပါ။",
   "continue_text": "ဆက်လက်",
   "contract_warning": "ဒီစာချုပ်လိပ်စာအလားအလာအလားအလာအလားအလာအလံများကိုအလံလွှင့်တင်ခဲ့သည်။ ကျေးဇူးပြုပြီးသတိဖြင့်လုပ်ငန်းစဉ်။",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "သက်တမ်းကုန်ဆုံးခြင်းနှင့်တရားဝင်မှု",
   "export_backup": "အရန်ကူးထုတ်ရန်",
   "export_logs": "ပို့ကုန်မှတ်တမ်းများ",
+  "export_outputs": "ပို့ကုန်ထုတ်ကုန်များ",
   "extra_id": "အပို ID-",
   "extracted_address_content": "သင်သည် \n${recipient_name} သို့ ရန်ပုံငွေများ ပေးပို့ပါမည်",
   "failed_authentication": "အထောက်အထားစိစစ်ခြင်း မအောင်မြင်ပါ။. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "ဟေးဗင် ကိတ် ဝေါလက်",
   "haven_app_wallet_text": "ဟေဗင်အတွက် အံ့ဩစရာကောင်းတဲ့ ပိုက်ဆံအုံး",
   "help": "ကူညီပါ",
+  "hidden_addresses": "လျှို့ဝှက်လိပ်စာများ",
   "hidden_balance": "Hidden Balance",
+  "hide": "သားရေ",
   "hide_details": "အသေးစိတ်ကို ဝှက်ပါ။",
   "high_contrast_theme": "အလင်းအမှောင် မြင့်မားသော အပြင်အဆင်",
   "home_screen_settings": "ပင်မစခရင် ဆက်တင်များ",
@@ -500,6 +504,7 @@
   "pre_seed_title": "အရေးကြီးသည်။",
   "prepaid_cards": "ကြိုတင်ငွေဖြည့်ကဒ်များ",
   "prevent_screenshots": "ဖန်သားပြင်ဓာတ်ပုံများနှင့် မျက်နှာပြင်ရိုက်ကူးခြင်းကို တားဆီးပါ။",
+  "primary_address": "အဓိကလိပ်စာ",
   "privacy": "ကိုယ်ရေးကိုယ်တာ",
   "privacy_policy": "ကိုယ်ရေးအချက်အလက်မူဝါဒ",
   "privacy_settings": "Privacy settings တွေကို",
@@ -696,6 +701,7 @@
   "share": "မျှဝေပါ။",
   "share_address": "လိပ်စာမျှဝေပါ။",
   "shared_seed_wallet_groups": "shared မျိုးစေ့ပိုက်ဆံအိတ်အုပ်စုများ",
+  "show": "ပြသ",
   "show_details": "အသေးစိတ်ပြ",
   "show_keys": "မျိုးစေ့ /သော့များကို ပြပါ။",
   "show_market_place": "စျေးကွက်ကိုပြသပါ။",
@@ -942,6 +948,5 @@
   "you_pay": "သင်ပေးချေပါ။",
   "you_will_get": "သို့ပြောင်းပါ။",
   "you_will_send": "မှပြောင်းပါ။",
-  "yy": "YY",
-  "contact_name_exists": "ထိုအမည်နှင့် အဆက်အသွယ်တစ်ခု ရှိနှင့်ပြီးဖြစ်သည်။ အခြားအမည်တစ်ခုကို ရွေးပါ။"
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index 9552f2439..657450f61 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Clearnet-link",
   "close": "Dichtbij",
   "coin_control": "Muntcontrole (optioneel)",
-  "cold_or_recover_wallet": "Voeg een cold wallet toe of herstel een paper wallet",
+  "cold_or_recover_wallet": "Voeg een alleen-lezen portemonnee toe van Cupcake of een koude portemonnee of herstel een papieren portemonnee",
   "color_theme": "Kleur thema",
   "commit_transaction_amount_fee": "Verricht transactie\nBedrag: ${amount}\nhonorarium: ${fee}",
   "confirm": "Bevestigen",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Contacten",
   "contact_list_wallets": "Mijn portefeuilles",
   "contact_name": "Contactnaam",
+  "contact_name_exists": "Er bestaat al een contact met die naam. Kies een andere naam.",
   "contact_support": "Contact opnemen met ondersteuning",
   "continue_text": "Doorgaan met",
   "contract_warning": "Dit contractadres is gemarkeerd als mogelijk frauduleus. Verwerk met voorzichtigheid.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Vervallen en geldigheid",
   "export_backup": "Back-up exporteren",
   "export_logs": "Exporteer logboeken",
+  "export_outputs": "Exportuitgangen exporteren",
   "extra_id": "Extra ID:",
   "extracted_address_content": "U stuurt geld naar\n${recipient_name}",
   "failed_authentication": "Mislukte authenticatie. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Awesome wallet for Haven",
   "help": "helpen",
+  "hidden_addresses": "Verborgen adressen",
   "hidden_balance": "Verborgen balans",
+  "hide": "Verbergen",
   "hide_details": "Details verbergen",
   "high_contrast_theme": "Thema met hoog contrast",
   "home_screen_settings": "Instellingen voor het startscherm",
@@ -500,6 +504,7 @@
   "pre_seed_title": "BELANGRIJK",
   "prepaid_cards": "Prepaid-kaarten",
   "prevent_screenshots": "Voorkom screenshots en schermopname",
+  "primary_address": "Primair adres",
   "privacy": "Privacy",
   "privacy_policy": "Privacybeleid",
   "privacy_settings": "Privacy-instellingen",
@@ -696,6 +701,7 @@
   "share": "Deel",
   "share_address": "Deel adres",
   "shared_seed_wallet_groups": "Gedeelde zaadportelgroepen",
+  "show": "Show",
   "show_details": "Toon details",
   "show_keys": "Toon zaad/sleutels",
   "show_market_place": "Toon Marktplaats",
@@ -943,6 +949,5 @@
   "you_pay": "U betaalt",
   "you_will_get": "Converteren naar",
   "you_will_send": "Converteren van",
-  "yy": "JJ",
-  "contact_name_exists": "Er bestaat al een contact met die naam. Kies een andere naam."
-}
+  "yy": "JJ"
+}
\ No newline at end of file
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index f3c3e4810..e47c93dcf 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "łącze Clearnet",
   "close": "Zamknąć",
   "coin_control": "Kontrola monet (opcjonalnie)",
-  "cold_or_recover_wallet": "Dodaj zimny portfel lub odzyskaj portfel papierowy",
+  "cold_or_recover_wallet": "Dodaj portfel tylko do odczytu od Cupcake lub zimnego portfela lub odzyskaj papierowy portfel",
   "color_theme": "Motyw kolorystyczny",
   "commit_transaction_amount_fee": "Zatwierdź transakcję\nIlość: ${amount}\nOpłata: ${fee}",
   "confirm": "Potwierdzać",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Łączność",
   "contact_list_wallets": "Moje portfele",
   "contact_name": "Nazwa Kontaktu",
+  "contact_name_exists": "Kontakt o tej nazwie już istnieje. Proszę wybrać inną nazwę.",
   "contact_support": "Skontaktuj się z pomocą techniczną",
   "continue_text": "Dalej",
   "contract_warning": "Ten adres umowy został oznaczony jako potencjalnie nieuczciwy. Prosimy o ostrożność.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Wygaśnięcie i ważność",
   "export_backup": "Eksportuj kopię zapasową",
   "export_logs": "Dzienniki eksportu",
+  "export_outputs": "Wyjścia eksportowe",
   "extra_id": "Dodatkowy ID:",
   "extracted_address_content": "Wysyłasz środki na\n${recipient_name}",
   "failed_authentication": "Nieudane uwierzytelnienie. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Awesome wallet for Haven",
   "help": "pomoc",
+  "hidden_addresses": "Ukryte adresy",
   "hidden_balance": "Ukryte saldo",
+  "hide": "Ukrywać",
   "hide_details": "Ukryj szczegóły",
   "high_contrast_theme": "Motyw o wysokim kontraście",
   "home_screen_settings": "Ustawienia ekranu głównego",
@@ -500,6 +504,7 @@
   "pre_seed_title": "WAŻNY",
   "prepaid_cards": "Karty przedpłacone",
   "prevent_screenshots": "Zapobiegaj zrzutom ekranu i nagrywaniu ekranu",
+  "primary_address": "Adres podstawowy",
   "privacy": "Prywatność",
   "privacy_policy": "Polityka prywatności",
   "privacy_settings": "Ustawienia prywatności",
@@ -696,6 +701,7 @@
   "share": "Udział",
   "share_address": "Udostępnij adres",
   "shared_seed_wallet_groups": "Wspólne grupy portfeli nasion",
+  "show": "Pokazywać",
   "show_details": "Pokaż szczegóły",
   "show_keys": "Pokaż seed/klucze",
   "show_market_place": "Pokaż rynek",
@@ -942,6 +948,5 @@
   "you_pay": "Płacisz",
   "you_will_get": "Konwertuj na",
   "you_will_send": "Konwertuj z",
-  "yy": "RR",
-  "contact_name_exists": "Kontakt o tej nazwie już istnieje. Proszę wybrać inną nazwę."
-}
+  "yy": "RR"
+}
\ No newline at end of file
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 410e8cb1c..d5aa95c16 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "link clear net",
   "close": "Fechar",
   "coin_control": "Controle de moedas (opcional)",
-  "cold_or_recover_wallet": "Adicione uma cold wallet ou recupere uma paper wallet",
+  "cold_or_recover_wallet": "Adicione uma carteira somente leitura de Cupcake ou uma carteira fria ou recupere uma carteira de papel",
   "color_theme": "Tema de cor",
   "commit_transaction_amount_fee": "Confirmar transação\nQuantia: ${amount}\nTaxa: ${fee}",
   "confirm": "Confirmar",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Contatos",
   "contact_list_wallets": "minhas carteiras",
   "contact_name": "Nome do contato",
+  "contact_name_exists": "Um contato com esse nome já existe. Escolha um nome diferente.",
   "contact_support": "Contatar Suporte",
   "continue_text": "Continuar",
   "contract_warning": "Este endereço do contrato foi sinalizado como potencialmente fraudulento. Por favor, processe com cautela.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Expiração e validade",
   "export_backup": "Backup de exportação",
   "export_logs": "Exportar logs",
+  "export_outputs": "Saídas de exportação",
   "extra_id": "ID extra:",
   "extracted_address_content": "Você enviará fundos para\n${recipient_name}",
   "failed_authentication": "Falha na autenticação. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Awesome wallet for Haven",
   "help": "ajuda",
+  "hidden_addresses": "Endereços ocultos",
   "hidden_balance": "Saldo escondido",
+  "hide": "Esconder",
   "hide_details": "Ocultar detalhes",
   "high_contrast_theme": "Tema de alto contraste",
   "home_screen_settings": "Configurações da tela inicial",
@@ -502,6 +506,7 @@
   "pre_seed_title": "IMPORTANTE",
   "prepaid_cards": "Cartões pré-pagos",
   "prevent_screenshots": "Evite capturas de tela e gravação de tela",
+  "primary_address": "Endereço primário",
   "privacy": "Privacidade",
   "privacy_policy": "Política de privacidade",
   "privacy_settings": "Configurações de privacidade",
@@ -698,6 +703,7 @@
   "share": "Compartilhar",
   "share_address": "Compartilhar endereço",
   "shared_seed_wallet_groups": "Grupos de carteira de sementes compartilhados",
+  "show": "Mostrar",
   "show_details": "Mostrar detalhes",
   "show_keys": "Mostrar semente/chaves",
   "show_market_place": "Mostrar mercado",
@@ -946,4 +952,4 @@
   "you_will_get": "Converter para",
   "you_will_send": "Converter de",
   "yy": "aa"
-}
+}
\ No newline at end of file
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index a8ee5a309..f999b4aaa 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Клирнет ссылка",
   "close": "Закрывать",
   "coin_control": "Контроль монет (необязательно)",
-  "cold_or_recover_wallet": "Добавьте холодный кошелек или восстановите бумажный кошелек",
+  "cold_or_recover_wallet": "Добавить кошелек только для чтения из Cupcake или холодный кошелек или восстановить бумажный кошелек",
   "color_theme": "Цветовая тема",
   "commit_transaction_amount_fee": "Подтвердить транзакцию \nСумма: ${amount}\nКомиссия: ${fee}",
   "confirm": "Подтвердить",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Контакты",
   "contact_list_wallets": "Мои кошельки",
   "contact_name": "Имя контакта",
+  "contact_name_exists": "Контакт с таким именем уже существует. Пожалуйста, выберите другое имя.",
   "contact_support": "Связаться со службой поддержки",
   "continue_text": "Продолжить",
   "contract_warning": "Этот адрес контракта был отмечен как потенциально мошеннический. Пожалуйста, обработайтесь с осторожностью.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Истечение и достоверность",
   "export_backup": "Экспорт резервной копии",
   "export_logs": "Экспортные журналы",
+  "export_outputs": "Экспортные выходы",
   "extra_id": "Дополнительный ID:",
   "extracted_address_content": "Вы будете отправлять средства\n${recipient_name}",
   "failed_authentication": "Ошибка аутентификации. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Awesome wallet for Haven",
   "help": "помощь",
+  "hidden_addresses": "Скрытые адреса",
   "hidden_balance": "Скрытый баланс",
+  "hide": "Скрывать",
   "hide_details": "Скрыть детали",
   "high_contrast_theme": "Высококонтрастная тема",
   "home_screen_settings": "Настройки главного экрана",
@@ -501,6 +505,7 @@
   "pre_seed_title": "ВАЖНО",
   "prepaid_cards": "Предоплаченные карты",
   "prevent_screenshots": "Предотвратить скриншоты и запись экрана",
+  "primary_address": "Первичный адрес",
   "privacy": "Конфиденциальность",
   "privacy_policy": "Политика конфиденциальности",
   "privacy_settings": "Настройки конфиденциальности",
@@ -697,6 +702,7 @@
   "share": "Делиться",
   "share_address": "Поделиться адресом",
   "shared_seed_wallet_groups": "Общие группы кошелька семян",
+  "show": "Показывать",
   "show_details": "Показать детали",
   "show_keys": "Показать мнемоническую фразу/ключи",
   "show_market_place": "Показать торговую площадку",
@@ -943,6 +949,5 @@
   "you_pay": "Вы платите",
   "you_will_get": "Конвертировать в",
   "you_will_send": "Конвертировать из",
-  "yy": "ГГ",
-  "contact_name_exists": "Контакт с таким именем уже существует. Пожалуйста, выберите другое имя."
-}
+  "yy": "ГГ"
+}
\ No newline at end of file
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index 5102e150c..a35e16a97 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "ลิงค์เคลียร์เน็ต",
   "close": "ปิด",
   "coin_control": "การควบคุมเหรียญ (ตัวเลือก)",
-  "cold_or_recover_wallet": "เพิ่มกระเป๋าเงินเย็นหรือกู้คืนกระเป๋าเงินกระดาษ",
+  "cold_or_recover_wallet": "เพิ่มกระเป๋าเงินแบบอ่านอย่างเดียวจาก Cupcake หรือกระเป๋าเงินเย็นหรือกู้คืนกระเป๋ากระดาษ",
   "color_theme": "ธีมสี",
   "commit_transaction_amount_fee": "ยืนยันธุรกรรม\nจำนวน: ${amount}\nค่าธรรมเนียม: ${fee}",
   "confirm": "ยืนยัน",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "ติดต่อ",
   "contact_list_wallets": "กระเป๋าเงินของฉัน",
   "contact_name": "ชื่อผู้ติดต่อ",
+  "contact_name_exists": "มีผู้ติดต่อชื่อนั้นอยู่แล้ว โปรดเลือกชื่ออื่น",
   "contact_support": "ติดต่อฝ่ายสนับสนุน",
   "continue_text": "ดำเนินการต่อ",
   "contract_warning": "ที่อยู่สัญญานี้ได้รับการตั้งค่าสถานะว่าเป็นการฉ้อโกง กรุณาดำเนินการด้วยความระมัดระวัง",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "หมดอายุและถูกต้อง",
   "export_backup": "ส่งออกข้อมูลสำรอง",
   "export_logs": "บันทึกการส่งออก",
+  "export_outputs": "เอาต์พุตส่งออก",
   "extra_id": "ไอดีเพิ่มเติม:",
   "extracted_address_content": "คุณกำลังจะส่งเงินไปยัง\n${recipient_name}",
   "failed_authentication": "การยืนยันสิทธิ์ล้มเหลว ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven ของ Cake Wallet",
   "haven_app_wallet_text": "กระเป๋าสตางค์ที่สวยงามสำหรับ Haven",
   "help": "ช่วยเหลือ",
+  "hidden_addresses": "ที่อยู่ที่ซ่อนอยู่",
   "hidden_balance": "ยอดคงเหลือซ่อนอยู่",
+  "hide": "ซ่อน",
   "hide_details": "ซ่อนรายละเอียด",
   "high_contrast_theme": "ธีมความคมชัดสูง",
   "home_screen_settings": "การตั้งค่าหน้าจอหลัก",
@@ -500,6 +504,7 @@
   "pre_seed_title": "สำคัญ",
   "prepaid_cards": "บัตรเติมเงิน",
   "prevent_screenshots": "ป้องกันภาพหน้าจอและการบันทึกหน้าจอ",
+  "primary_address": "ที่อยู่ปฐมภูมิ",
   "privacy": "ความเป็นส่วนตัว",
   "privacy_policy": "นโยบายความเป็นส่วนตัว",
   "privacy_settings": "การตั้งค่าความเป็นส่วนตัว",
@@ -696,6 +701,7 @@
   "share": "แบ่งปัน",
   "share_address": "แชร์ที่อยู่",
   "shared_seed_wallet_groups": "กลุ่มกระเป๋าเงินที่ใช้ร่วมกัน",
+  "show": "แสดง",
   "show_details": "แสดงรายละเอียด",
   "show_keys": "แสดงซีด/คีย์",
   "show_market_place": "แสดงตลาดกลาง",
@@ -942,6 +948,5 @@
   "you_pay": "คุณจ่าย",
   "you_will_get": "แปลงเป็น",
   "you_will_send": "แปลงจาก",
-  "yy": "ปี",
-  "contact_name_exists": "มีผู้ติดต่อชื่อนั้นอยู่แล้ว โปรดเลือกชื่ออื่น"
-}
+  "yy": "ปี"
+}
\ No newline at end of file
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index eb78c8d3c..090bdb8a7 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Link ng Clearnet",
   "close": "Isara",
   "coin_control": "Coin control (opsyonal)",
-  "cold_or_recover_wallet": "Magdagdag ng isang cold wallet o mabawi ang isang paper wallet",
+  "cold_or_recover_wallet": "Magdagdag ng isang basahin lamang na pitaka mula sa Cupcake o isang malamig na pitaka o mabawi ang isang wallet ng papel",
   "color_theme": "Color theme",
   "commit_transaction_amount_fee": "Gumawa ng transaksyon\nHalaga: ${amount}\nFee: ${fee}",
   "confirm": "Kumpirmahin",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Mga Contact",
   "contact_list_wallets": "Mga Wallet Ko",
   "contact_name": "Pangalan ng Contact",
+  "contact_name_exists": "Ang isang pakikipag -ugnay sa pangalang iyon ay mayroon na. Mangyaring pumili ng ibang pangalan.",
   "contact_support": "Makipag-ugnay sa Suporta",
   "continue_text": "Magpatuloy",
   "contract_warning": "Ang address ng kontrata na ito ay na -flag bilang potensyal na mapanlinlang. Mangyaring iproseso nang may pag -iingat.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Pag-expire at Bisa",
   "export_backup": "I-export ang backup",
   "export_logs": "Mga log ng pag -export",
+  "export_outputs": "Mga output ng pag -export",
   "extra_id": "Dagdag na ID:",
   "extracted_address_content": "Magpapadala ka ng pondo sa\n${recipient_name}",
   "failed_authentication": "Nabigo ang pagpapatunay. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Kahanga-hangang wallet para sa Haven",
   "help": "Tulong",
+  "hidden_addresses": "Nakatagong mga address",
   "hidden_balance": "Nakatagong Balanse",
+  "hide": "Itago",
   "hide_details": "Itago ang mga detalye",
   "high_contrast_theme": "High Contrast Theme",
   "home_screen_settings": "Mga setting ng home screen",
@@ -500,6 +504,7 @@
   "pre_seed_title": "Mahalaga",
   "prepaid_cards": "Mga Prepaid Card",
   "prevent_screenshots": "Maiwasan ang mga screenshot at pag -record ng screen",
+  "primary_address": "Pangunahing address",
   "privacy": "Privacy",
   "privacy_policy": "Patakaran sa Pagkapribado",
   "privacy_settings": "Settings para sa pagsasa-pribado",
@@ -696,6 +701,7 @@
   "share": "Ibahagi",
   "share_address": "Ibahagi ang address",
   "shared_seed_wallet_groups": "Ibinahaging mga pangkat ng pitaka ng binhi",
+  "show": "Ipakita",
   "show_details": "Ipakita ang mga detalye",
   "show_keys": "Ipakita ang mga seed/key",
   "show_market_place": "Ipakita ang Marketplace",
@@ -943,4 +949,4 @@
   "you_will_get": "I-convert sa",
   "you_will_send": "I-convert mula sa",
   "yy": "YY"
-}
+}
\ No newline at end of file
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index 0b4700397..3a426de9e 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Net bağlantı",
   "close": "Kapalı",
   "coin_control": "Koin kontrolü (isteğe bağlı)",
-  "cold_or_recover_wallet": "Soğuk bir cüzdan ekleyin veya bir kağıt cüzdanı kurtarın",
+  "cold_or_recover_wallet": "Cupcake veya soğuk bir cüzdandan salt okunur bir cüzdan ekleyin veya bir kağıt cüzdanı kurtar",
   "color_theme": "Renk teması",
   "commit_transaction_amount_fee": "Transferi gerçekleştir\nMiktar: ${amount}\nKomisyon: ${fee}",
   "confirm": "Onayla",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Rehberim",
   "contact_list_wallets": "Cüzdanlarım",
   "contact_name": "Kişi ismi",
+  "contact_name_exists": "Bu isimde bir kişi zaten mevcut. Lütfen farklı bir ad seçin.",
   "contact_support": "Destek ile İletişime Geç",
   "continue_text": "Devam et",
   "contract_warning": "Bu sözleşme adresi potansiyel olarak hileli olarak işaretlenmiştir. Lütfen dikkatle işleyin.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Sona erme ve geçerlilik",
   "export_backup": "Yedeği dışa aktar",
   "export_logs": "Dışa aktarma günlükleri",
+  "export_outputs": "İhracat çıktıları",
   "extra_id": "Ekstra ID:",
   "extracted_address_content": "Parayı buraya gönderceksin:\n${recipient_name}",
   "failed_authentication": "Doğrulama başarısız oldu. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Cake Wallet tarafından Haven",
   "haven_app_wallet_text": "Haven için harika cüzdan ",
   "help": "yardım",
+  "hidden_addresses": "Gizli adresler",
   "hidden_balance": "Gizli Bakiye",
+  "hide": "Saklamak",
   "hide_details": "Detayları Gizle",
   "high_contrast_theme": "Yüksek Kontrastlı Tema",
   "home_screen_settings": "Ana ekran ayarları",
@@ -500,6 +504,7 @@
   "pre_seed_title": "UYARI",
   "prepaid_cards": "Ön ödemeli kartlar",
   "prevent_screenshots": "Ekran görüntülerini ve ekran kaydını önleyin",
+  "primary_address": "Birincil adres",
   "privacy": "Gizlilik",
   "privacy_policy": "Gizlilik Politikası",
   "privacy_settings": "Gizlilik ayarları",
@@ -696,6 +701,7 @@
   "share": "Paylaşmak",
   "share_address": "Adresi paylaş",
   "shared_seed_wallet_groups": "Paylaşılan tohum cüzdan grupları",
+  "show": "Göstermek",
   "show_details": "Detayları Göster",
   "show_keys": "Tohumları/anahtarları göster",
   "show_market_place": "Pazar Yerini Göster",
@@ -942,6 +948,5 @@
   "you_pay": "Şu kadar ödeyeceksin: ",
   "you_will_get": "Biçimine dönüştür:",
   "you_will_send": "Biçiminden dönüştür:",
-  "yy": "YY",
-  "contact_name_exists": "Bu isimde bir kişi zaten mevcut. Lütfen farklı bir ad seçin."
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index c9afde7be..63665875f 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Посилання Clearnet",
   "close": "Закрити",
   "coin_control": "Контроль монет (необов’язково)",
-  "cold_or_recover_wallet": "Додайте холодний гаманець або відновіть паперовий гаманець",
+  "cold_or_recover_wallet": "Додайте гаманець лише для читання від Cupcake або холодного гаманця або відновіть паперовий гаманець",
   "color_theme": "Кольорова тема",
   "commit_transaction_amount_fee": "Підтвердити транзакцію \nСума: ${amount}\nКомісія: ${fee}",
   "confirm": "Підтвердити",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Контакти",
   "contact_list_wallets": "Мої гаманці",
   "contact_name": "Ім'я контакту",
+  "contact_name_exists": "Контакт із такою назвою вже існує. Виберіть інше ім'я.",
   "contact_support": "Звернутися до служби підтримки",
   "continue_text": "Продовжити",
   "contract_warning": "Ця адреса контракту була позначена як потенційно шахрайська. Будь ласка, обробляйте обережно.",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "Закінчення та обгрунтованість",
   "export_backup": "Експортувати резервну копію",
   "export_logs": "Експортні журнали",
+  "export_outputs": "Експортні результати",
   "extra_id": "Додатковий ID:",
   "extracted_address_content": "Ви будете відправляти кошти\n${recipient_name}",
   "failed_authentication": "Помилка аутентифікації. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Awesome wallet for Haven",
   "help": "допомога",
+  "hidden_addresses": "Приховані адреси",
   "hidden_balance": "Прихований баланс",
+  "hide": "Сховати",
   "hide_details": "Приховати деталі",
   "high_contrast_theme": "Тема високої контрастності",
   "home_screen_settings": "Налаштування головного екрана",
@@ -500,6 +504,7 @@
   "pre_seed_title": "ВАЖЛИВО",
   "prepaid_cards": "Передплачені картки",
   "prevent_screenshots": "Запобігати знімкам екрана та запису екрана",
+  "primary_address": "Первинна адреса",
   "privacy": "Конфіденційність",
   "privacy_policy": "Політика конфіденційності",
   "privacy_settings": "Налаштування конфіденційності",
@@ -697,6 +702,7 @@
   "share": "Поділіться",
   "share_address": "Поділитися адресою",
   "shared_seed_wallet_groups": "Спільні групи насіннєвих гаманців",
+  "show": "Показувати",
   "show_details": "Показати деталі",
   "show_keys": "Показати мнемонічну фразу/ключі",
   "show_market_place": "Відображати маркетплейс",
@@ -943,6 +949,5 @@
   "you_pay": "Ви платите",
   "you_will_get": "Конвертувати в",
   "you_will_send": "Конвертувати з",
-  "yy": "YY",
-  "contact_name_exists": "Контакт із такою назвою вже існує. Виберіть інше ім'я."
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index 50c6f1889..2a40fbe13 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "کلیرنیٹ لنک",
   "close": "بند کریں",
   "coin_control": "سکے کنٹرول (اختیاری)",
-  "cold_or_recover_wallet": "ٹھنڈا پرس ڈالیں یا کاغذ کا پرس بازیافت کریں",
+  "cold_or_recover_wallet": "Cupcake یا سرد بٹوے سے صرف ایک پڑھنے والا پرس شامل کریں یا کاغذ کا پرس بازیافت کریں",
   "color_theme": "رنگین تھیم",
   "commit_transaction_amount_fee": "لین دین کا ارتکاب کریں\\nرقم: ${amount}\\nفیس: ${fee}",
   "confirm": "تصدیق کریں۔",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "رابطے",
   "contact_list_wallets": "میرے بٹوے",
   "contact_name": "رابطے کا نام",
+  "contact_name_exists": " ۔ﮟﯾﺮﮐ ﺐﺨﺘﻨﻣ ﻡﺎﻧ ﻒﻠﺘﺨﻣ ﮏﯾﺍ ﻡﺮﮐ ﮦﺍﺮﺑ ۔ﮯﮨ ﺩﻮﺟﻮﻣ ﮯﺳ ﮯﻠﮩﭘ ﮧﻄﺑﺍﺭ ﮏﯾﺍ ﮫﺗﺎﺳ ﮯﮐ ﻡﺎﻧ ﺱﺍ",
   "contact_support": "سپورٹ سے رابطہ کریں۔",
   "continue_text": "جاری رہے",
   "contract_warning": "اس معاہدے کے پتے کو ممکنہ طور پر جعلی قرار دیا گیا ہے۔ براہ کرم احتیاط کے ساتھ کارروائی کریں۔",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "میعاد ختم اور صداقت",
   "export_backup": "بیک اپ برآمد کریں۔",
   "export_logs": "نوشتہ جات برآمد کریں",
+  "export_outputs": "برآمد کے نتائج",
   "extra_id": "اضافی ID:",
   "extracted_address_content": "آپ فنڈز بھیج رہے ہوں گے\n${recipient_name}",
   "failed_authentication": "ناکام تصدیق۔ ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven از Cake والیٹ",
   "haven_app_wallet_text": "Havek کے لیے زبردست پرس",
   "help": "مدد",
+  "hidden_addresses": "پوشیدہ پتے",
   "hidden_balance": "پوشیدہ بیلنس",
+  "hide": "چھپائیں",
   "hide_details": "تفصیلات چھپائیں۔",
   "high_contrast_theme": "ہائی کنٹراسٹ تھیم",
   "home_screen_settings": "ہوم اسکرین کی ترتیبات",
@@ -502,6 +506,7 @@
   "pre_seed_title": "اہم",
   "prepaid_cards": "پری پیڈ کارڈز",
   "prevent_screenshots": "اسکرین شاٹس اور اسکرین ریکارڈنگ کو روکیں۔",
+  "primary_address": "بنیادی پتہ",
   "privacy": "رازداری",
   "privacy_policy": "رازداری کی پالیسی",
   "privacy_settings": "رازداری کی ترتیبات",
@@ -698,6 +703,7 @@
   "share": "بانٹیں",
   "share_address": "پتہ شیئر کریں۔",
   "shared_seed_wallet_groups": "مشترکہ بیج پرس گروپ",
+  "show": "دکھائیں",
   "show_details": "تفصیلات دکھائیں",
   "show_keys": "بیج / چابیاں دکھائیں۔",
   "show_market_place": "بازار دکھائیں۔",
@@ -944,6 +950,5 @@
   "you_pay": "تم ادا کرو",
   "you_will_get": "میں تبدیل کریں۔",
   "you_will_send": "سے تبدیل کریں۔",
-  "yy": "YY",
-  "contact_name_exists": " ۔ﮟﯾﺮﮐ ﺐﺨﺘﻨﻣ ﻡﺎﻧ ﻒﻠﺘﺨﻣ ﮏﯾﺍ ﻡﺮﮐ ﮦﺍﺮﺑ ۔ﮯﮨ ﺩﻮﺟﻮﻣ ﮯﺳ ﮯﻠﮩﭘ ﮧﻄﺑﺍﺭ ﮏﯾﺍ ﮫﺗﺎﺳ ﮯﮐ ﻡﺎﻧ ﺱﺍ"
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb
index e3ffbef3e..9fee9f4fc 100644
--- a/res/values/strings_vi.arb
+++ b/res/values/strings_vi.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Liên kết Clearnet",
   "close": "Đóng",
   "coin_control": "Kiểm soát đồng xu (tùy chọn)",
-  "cold_or_recover_wallet": "Thêm ví lạnh hoặc khôi phục ví giấy",
+  "cold_or_recover_wallet": "Thêm ví chỉ đọc từ Cupcake hoặc ví lạnh hoặc thu hồi ví giấy",
   "color_theme": "Chủ đề màu sắc",
   "commit_transaction_amount_fee": "Cam kết giao dịch\nSố tiền: ${amount}\nPhí: ${fee}",
   "confirm": "Xác nhận",
@@ -162,6 +162,7 @@
   "contact_list_contacts": "Danh bạ",
   "contact_list_wallets": "Ví của tôi",
   "contact_name": "Tên liên hệ",
+  "contact_name_exists": "Một liên hệ với cái tên đó đã tồn tại. Vui lòng chọn một tên khác.",
   "contact_support": "Liên hệ Hỗ trợ",
   "continue_text": "Tiếp tục",
   "contract_warning": "Địa chỉ hợp đồng này đã được gắn cờ là có khả năng lừa đảo. Vui lòng xử lý một cách thận trọng.",
@@ -297,6 +298,7 @@
   "expiry_and_validity": "Hạn và hiệu lực",
   "export_backup": "Xuất sao lưu",
   "export_logs": "Nhật ký xuất khẩu",
+  "export_outputs": "Đầu ra xuất khẩu",
   "extra_id": "ID bổ sung:",
   "extracted_address_content": "Bạn sẽ gửi tiền cho\n${recipient_name}",
   "failed_authentication": "Xác thực không thành công. ${state_error}",
@@ -337,7 +339,9 @@
   "haven_app": "Haven bởi Cake Wallet",
   "haven_app_wallet_text": "Ví tuyệt vời cho Haven",
   "help": "Trợ giúp",
+  "hidden_addresses": "Địa chỉ ẩn",
   "hidden_balance": "Số dư ẩn",
+  "hide": "Trốn",
   "hide_details": "Ẩn chi tiết",
   "high_contrast_theme": "Chủ đề độ tương phản cao",
   "home_screen_settings": "Cài đặt màn hình chính",
@@ -367,14 +371,22 @@
   "ledger_error_wrong_app": "Vui lòng đảm bảo bạn đã mở đúng ứng dụng trên Ledger của mình",
   "ledger_please_enable_bluetooth": "Vui lòng bật Bluetooth để phát hiện Ledger của bạn",
   "light_theme": "Chủ đề sáng",
+  "litecoin_enable_mweb_sync": "Bật quét MWEB",
+  "litecoin_mweb": "Mweb",
+  "litecoin_mweb_always_scan": "Đặt MWEB luôn quét",
   "litecoin_mweb_description": "MWEB là một giao thức mới mang lại các giao dịch nhanh hơn, rẻ hơn và riêng tư hơn cho Litecoin",
   "litecoin_mweb_dismiss": "Miễn nhiệm",
+  "litecoin_mweb_display_card": "Hiển thị thẻ MWEB",
   "litecoin_mweb_enable": "Bật MWEB",
   "litecoin_mweb_enable_later": "Bạn có thể chọn bật lại MWEB trong cài đặt hiển thị.",
   "litecoin_mweb_logs": "Nhật ký MWEB",
   "litecoin_mweb_node": "Nút MWEB",
   "litecoin_mweb_pegin": "Chốt vào",
   "litecoin_mweb_pegout": "Chốt ra",
+  "litecoin_mweb_scanning": "Quét MWEB",
+  "litecoin_mweb_settings": "Cài đặt MWEB",
+  "litecoin_mweb_warning": "Sử dụng MWEB ban đầu sẽ tải xuống ~ 600MB dữ liệu và có thể mất tới 30 phút tùy thuộc vào tốc độ mạng. Dữ liệu ban đầu này sẽ chỉ tải xuống một lần và có sẵn cho tất cả các ví Litecoin",
+  "litecoin_what_is_mweb": "MWEB là gì?",
   "live_fee_rates": "Tỷ lệ phí hiện tại qua API",
   "load_more": "Tải thêm",
   "loading_your_wallet": "Đang tải ví của bạn",
@@ -493,6 +505,7 @@
   "pre_seed_title": "QUAN TRỌNG",
   "prepaid_cards": "Thẻ trả trước",
   "prevent_screenshots": "Ngăn chặn ảnh chụp màn hình và ghi hình màn hình",
+  "primary_address": "Địa chỉ chính",
   "privacy": "Quyền riêng tư",
   "privacy_policy": "Chính sách quyền riêng tư",
   "privacy_settings": "Cài đặt quyền riêng tư",
@@ -689,6 +702,7 @@
   "share": "Chia sẻ",
   "share_address": "Chia sẻ địa chỉ",
   "shared_seed_wallet_groups": "Nhóm ví hạt được chia sẻ",
+  "show": "Trình diễn",
   "show_details": "Hiển thị chi tiết",
   "show_keys": "Hiển thị hạt giống/khóa",
   "show_market_place": "Hiển thị Thị trường",
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index 19dc9f110..1dd6eafda 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "Kọja ilọ oke",
   "close": "sunmo",
   "coin_control": "Ìdarí owó ẹyọ (ìyàn nìyí)",
-  "cold_or_recover_wallet": "Fi owo aisan tabi yiyewo owo iwe iwe",
+  "cold_or_recover_wallet": "Ṣafikun apamọwọ kika-nikan lati Cupcake tabi apamọwọ tutu tabi gba owo apamọwọ iwe kan",
   "color_theme": "Àwọn ààtò àwọ̀",
   "commit_transaction_amount_fee": "Jẹ́rìí sí àránṣẹ́\nOwó: ${amount}\nIye àfikún: ${fee}",
   "confirm": "Jẹ́rìísí",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "Àwọn olùbásọ̀rọ̀",
   "contact_list_wallets": "Àwọn àpamọ́wọ́ mi",
   "contact_name": "Orúkọ olùbásọ̀rọ̀",
+  "contact_name_exists": "Olubasọrọ pẹlu orukọ yẹn ti wa tẹlẹ. Jọwọ yan orukọ ti o yatọ.",
   "contact_support": "Bá ìranlọ́wọ́ sọ̀rọ̀",
   "continue_text": "Tẹ̀síwájú",
   "contract_warning": "Adirẹsi adehun adehun yii ti samisi bi arekereke. Jọwọ ṣe ilana pẹlu iṣọra.",
@@ -297,6 +298,7 @@
   "expiry_and_validity": "Ipari ati idaniloju",
   "export_backup": "Sún ẹ̀dà nípamọ́ síta",
   "export_logs": "Wọle si okeere",
+  "export_outputs": "Agbohunlu okeere",
   "extra_id": "Àmì ìdánimọ̀ tó fikún:",
   "extracted_address_content": "Ẹ máa máa fi owó ránṣẹ́ sí\n${recipient_name}",
   "failed_authentication": "Ìfẹ̀rílàdí pipòfo. ${state_error}",
@@ -337,7 +339,9 @@
   "haven_app": "Haven latí ọwọ́ Cake Wallet",
   "haven_app_wallet_text": "Àpamọ́wọ́ Haven wà pa",
   "help": "ìranlọ́wọ́",
+  "hidden_addresses": "Awọn adirẹsi ti o farapamọ",
   "hidden_balance": "Ìyókù owó dídé",
+  "hide": "Pamọ",
   "hide_details": "Dé ìsọfúnni kékeré",
   "high_contrast_theme": "Akori Iyatọ giga",
   "home_screen_settings": "Awọn eto iboju ile",
@@ -501,6 +505,7 @@
   "pre_seed_title": "Ó TI ṢE PÀTÀKÌ",
   "prepaid_cards": "Awọn kaadi ti a ti sanwo",
   "prevent_screenshots": "Pese asapọ ti awọn ẹrọ eto aṣa",
+  "primary_address": "Adirẹsi akọkọ",
   "privacy": "Ìdáwà",
   "privacy_policy": "Òfin Aládàáni",
   "privacy_settings": "Ààtò àdáni",
@@ -697,6 +702,7 @@
   "share": "Pinpin",
   "share_address": "Pín àdírẹ́sì",
   "shared_seed_wallet_groups": "Awọn ẹgbẹ ti a pin irugbin",
+  "show": "Fihan",
   "show_details": "Fi ìsọfúnni kékeré hàn",
   "show_keys": "Wo hóró / àwọn kọ́kọ́rọ́",
   "show_market_place": "Wa Sopọ Pataki",
@@ -943,6 +949,5 @@
   "you_pay": "Ẹ sàn",
   "you_will_get": "Ṣe pàṣípààrọ̀ sí",
   "you_will_send": "Ṣe pàṣípààrọ̀ láti",
-  "yy": "Ọd",
-  "contact_name_exists": "Olubasọrọ pẹlu orukọ yẹn ti wa tẹlẹ. Jọwọ yan orukọ ti o yatọ."
-}
+  "yy": "Ọd"
+}
\ No newline at end of file
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index 009a31d86..92a540d19 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -136,7 +136,7 @@
   "clearnet_link": "明网链接",
   "close": "关闭",
   "coin_control": "硬幣控制(可選)",
-  "cold_or_recover_wallet": "添加冷钱包或恢复纸钱包",
+  "cold_or_recover_wallet": "从Cupcake或冷钱包中添加只读的钱包或恢复纸钱包",
   "color_theme": "主题",
   "commit_transaction_amount_fee": "提交交易\n金额: ${amount}\n手续费: ${fee}",
   "confirm": "确认",
@@ -161,6 +161,7 @@
   "contact_list_contacts": "联系人",
   "contact_list_wallets": "我的钱包",
   "contact_name": "联系人姓名",
+  "contact_name_exists": "已存在具有该名称的联系人。请选择不同的名称。",
   "contact_support": "联系支持",
   "continue_text": "继续",
   "contract_warning": "该合同地址已被标记为潜在的欺诈性。请谨慎处理。",
@@ -296,6 +297,7 @@
   "expiry_and_validity": "到期和有效性",
   "export_backup": "导出备份",
   "export_logs": "导出日志",
+  "export_outputs": "导出输出",
   "extra_id": "额外ID:",
   "extracted_address_content": "您将汇款至\n${recipient_name}",
   "failed_authentication": "身份验证失败. ${state_error}",
@@ -336,7 +338,9 @@
   "haven_app": "Haven by Cake Wallet",
   "haven_app_wallet_text": "Awesome wallet for Haven",
   "help": "帮助",
+  "hidden_addresses": "隐藏的地址",
   "hidden_balance": "隐藏余额",
+  "hide": "隐藏",
   "hide_details": "隐藏细节",
   "high_contrast_theme": "高对比度主题",
   "home_screen_settings": "主屏幕设置",
@@ -500,6 +504,7 @@
   "pre_seed_title": "重要",
   "prepaid_cards": "预付费卡",
   "prevent_screenshots": "防止截屏和录屏",
+  "primary_address": "主要地址",
   "privacy": "隐私",
   "privacy_policy": "隐私政策",
   "privacy_settings": "隐私设置",
@@ -696,6 +701,7 @@
   "share": "分享",
   "share_address": "分享地址",
   "shared_seed_wallet_groups": "共享种子钱包组",
+  "show": "展示",
   "show_details": "显示详细信息",
   "show_keys": "显示种子/密钥",
   "show_market_place": "显示市场",
@@ -942,6 +948,5 @@
   "you_pay": "你付钱",
   "you_will_get": "转换到",
   "you_will_send": "转换自",
-  "yy": "YY",
-  "contact_name_exists": "已存在具有该名称的联系人。请选择不同的名称。"
-}
+  "yy": "YY"
+}
\ No newline at end of file
diff --git a/scripts/macos/gen_common.sh b/scripts/macos/gen_common.sh
index 87fd54b43..d75ac919e 100755
--- a/scripts/macos/gen_common.sh
+++ b/scripts/macos/gen_common.sh
@@ -9,7 +9,7 @@ gen_podspec() {
 	DEFAULT_FILE_PATH="${CW_PLUGIN_DIR}/${DEFAULT_FILENAME}"
 	rm -f $DEFAULT_FILE_PATH
 	cp $BASE_FILE_PATH $DEFAULT_FILE_PATH
-	sed -i '' "s/#___VALID_ARCHS___#/${ARCH}/g" $DEFAULT_FILE_PATH
+	gsed -i "s/#___VALID_ARCHS___#/${ARCH}/g" $DEFAULT_FILE_PATH
 }
 
 gen_project() {
@@ -17,7 +17,7 @@ gen_project() {
 	CW_DIR="`pwd`/../../macos/Runner.xcodeproj"
 	DEFAULT_FILENAME="project.pbxproj"
 	DEFAULT_FILE_PATH="${CW_DIR}/${DEFAULT_FILENAME}"
-	sed -i '' "s/ARCHS =.*/ARCHS = \"${ARCH}\";/g" $DEFAULT_FILE_PATH
+	gsed -i "s/ARCHS =.*/ARCHS = \"${ARCH}\";/g" $DEFAULT_FILE_PATH
 }
 
 gen() {
diff --git a/tool/configure.dart b/tool/configure.dart
index 97541c2fa..c5d4a6863 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -276,6 +276,7 @@ import 'package:cw_core/get_height_by_date.dart';
 import 'package:cw_core/monero_amount_format.dart';
 import 'package:cw_core/monero_transaction_priority.dart';
 import 'package:cw_monero/monero_unspent.dart';
+import 'package:cw_monero/api/account_list.dart';
 import 'package:cw_monero/monero_wallet_service.dart';
 import 'package:cw_monero/api/wallet_manager.dart';
 import 'package:cw_monero/monero_wallet.dart';
@@ -379,6 +380,12 @@ abstract class Monero {
 
   Future<int> getCurrentHeight();
 
+  Future<bool> commitTransactionUR(Object wallet, String ur);
+
+  String exportOutputsUR(Object wallet, bool all);
+
+  bool importKeyImagesUR(Object wallet, String ur);
+
   WalletCredentials createMoneroRestoreWalletFromKeysCredentials({
     required String name,
     required String spendKey,
@@ -398,6 +405,7 @@ abstract class Monero {
   int formatterMoneroParseAmount({required String amount});
   Account getCurrentAccount(Object wallet);
   void monerocCheck();
+  bool isViewOnly();
   void setCurrentAccount(Object wallet, int id, String label, String? balance);
   void onStartup();
   int getTransactionInfoAccountId(TransactionInfo tx);
diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake
index 92431a6fb..26d481f85 100644
--- a/windows/flutter/generated_plugins.cmake
+++ b/windows/flutter/generated_plugins.cmake
@@ -13,7 +13,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
 )
 
 list(APPEND FLUTTER_FFI_PLUGIN_LIST
-  sp_scanner
 )
 
 set(PLUGIN_BUNDLED_LIBRARIES)

From 02f53055b1a72b5e7d33cc5bda2565412857b187 Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Sat, 9 Nov 2024 21:00:56 +0200
Subject: [PATCH 08/15] Cw 657 new buy sell flow (#1553)

* init commit

* onramper

* moonPay

* dfx provider

* meld

* dfx payment methods

* fiat buy credentials

* moonpay payment method

* payment loading state

* dfx sell quote

* onramper launch trade

* meld launch trade

* country picker

* update option tile

* buy/sell action

* meld refactor

* update pr_test_build.yml

* ui fixes

* revert country picker commit

* update the ui

* recommended providers

* payment method [skip ci]

* provider option tile

* remove buy action

* minor fixes

* update the best rate when the amount is changed

* fixes for currency title

* fix icons

* code refactoring

* null issue

* code review fixes

* Update pr_test_build_linux.yml

* Update meld_buy_provider.dart

* Update meld_buy_provider.dart

* add show wallets action

* remove default sell / buy provider setting

* localisation

* providerTypes

* icons

* remove duplicate file [skip ci]

* minor changes [skip ci]

* fixes from review

* disable dfx for non eur/chf currencies
fix providers to be fetched with the selected currency

* fix breaking from loop if one element failed

* fix minor naming issue from merging conflicts

* add fiat check for moonpay

* fix address validation

* merge conflict

* fix destination and source currency

* minor fix

* minor fix

* update the flow

* fix bch address format

* fix wallet addresses

* fix initial fetching amount.

* Update address_validator.dart

* review comments

* revert switch case to return null

* minor fix

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
---
 .github/workflows/pr_test_build_android.yml   |   2 +
 .github/workflows/pr_test_build_linux.yml     |   2 +
 assets/images/apple_pay_logo.png              | Bin 0 -> 56018 bytes
 assets/images/apple_pay_round_dark.svg        |   9 +
 assets/images/apple_pay_round_light.svg       |   9 +
 assets/images/bank.png                        | Bin 0 -> 1323 bytes
 assets/images/bank_dark.svg                   |   8 +
 assets/images/bank_light.svg                  |   8 +
 assets/images/buy_sell.png                    | Bin 0 -> 9931 bytes
 assets/images/card.svg                        |   1 +
 assets/images/card_dark.svg                   |   7 +
 assets/images/dollar_coin.svg                 |  12 +
 assets/images/google_pay_icon.png             | Bin 0 -> 12336 bytes
 assets/images/meld_logo.svg                   |  30 +
 assets/images/revolut.png                     | Bin 0 -> 11588 bytes
 assets/images/skrill.svg                      |  15 +
 assets/images/usd_round_dark.svg              |   4 +
 assets/images/usd_round_light.svg             |   2 +
 assets/images/wallet_new.png                  | Bin 0 -> 5619 bytes
 cw_core/lib/currency_for_wallet_type.dart     |  31 ++
 lib/buy/buy_provider.dart                     |  32 +-
 lib/buy/buy_quote.dart                        | 302 ++++++++++
 lib/buy/dfx/dfx_buy_provider.dart             | 273 +++++++--
 lib/buy/meld/meld_buy_provider.dart           | 266 +++++++++
 lib/buy/moonpay/moonpay_provider.dart         | 451 +++++++++------
 lib/buy/onramper/onramper_buy_provider.dart   | 359 ++++++++++--
 lib/buy/payment_method.dart                   | 287 ++++++++++
 lib/buy/robinhood/robinhood_buy_provider.dart | 102 +++-
 lib/buy/sell_buy_states.dart                  |  20 +
 lib/buy/wyre/wyre_buy_provider.dart           |   9 +-
 lib/core/backup_service.dart                  |  19 +-
 lib/core/selectable_option.dart               |  47 ++
 lib/di.dart                                   |  32 +-
 lib/entities/main_actions.dart                |  65 +--
 lib/entities/preferences_key.dart             |   4 +-
 lib/entities/provider_types.dart              |  42 +-
 lib/router.dart                               |  16 +-
 lib/routes.dart                               |   2 +
 .../screens/{InfoPage.dart => Info_page.dart} |   0
 lib/src/screens/buy/buy_options_page.dart     |  74 ---
 .../screens/buy/buy_sell_options_page.dart    |  48 ++
 lib/src/screens/buy/buy_sell_page.dart        | 469 ++++++++++++++++
 .../buy/payment_method_options_page.dart      |  47 ++
 .../desktop_dashboard_actions.dart            |  27 +-
 .../exchange/widgets/exchange_card.dart       |  58 +-
 .../mobile_exchange_cards_section.dart        |  91 ++-
 lib/src/screens/seed/pre_seed_page.dart       |   2 +-
 lib/src/screens/select_options_page.dart      | 199 +++++++
 .../screens/settings/other_settings_page.dart |  16 -
 lib/src/screens/settings/privacy_page.dart    |  12 +-
 .../setup_2fa/setup_2fa_info_page.dart        |   2 +-
 lib/src/widgets/address_text_field.dart       |   7 +-
 lib/src/widgets/provider_optoin_tile.dart     | 527 ++++++++++++++++++
 lib/store/settings_store.dart                 |  79 +--
 lib/typography.dart                           |   2 +
 lib/view_model/buy/buy_sell_view_model.dart   | 446 +++++++++++++++
 .../dashboard/dashboard_view_model.dart       |  45 +-
 .../settings/other_settings_view_model.dart   |  45 --
 .../settings/privacy_settings_view_model.dart |  10 +-
 res/values/strings_ar.arb                     |   3 +
 res/values/strings_bg.arb                     |   3 +
 res/values/strings_cs.arb                     |   3 +
 res/values/strings_de.arb                     |   3 +
 res/values/strings_en.arb                     |   3 +
 res/values/strings_es.arb                     |   3 +
 res/values/strings_fr.arb                     |   3 +
 res/values/strings_ha.arb                     |   3 +
 res/values/strings_hi.arb                     |   3 +
 res/values/strings_hr.arb                     |   3 +
 res/values/strings_hy.arb                     |   3 +
 res/values/strings_id.arb                     |   3 +
 res/values/strings_it.arb                     |   3 +
 res/values/strings_ja.arb                     |   3 +
 res/values/strings_ko.arb                     |   3 +
 res/values/strings_my.arb                     |   3 +
 res/values/strings_nl.arb                     |   3 +
 res/values/strings_pl.arb                     |   3 +
 res/values/strings_pt.arb                     |   3 +
 res/values/strings_ru.arb                     |   3 +
 res/values/strings_th.arb                     |   3 +
 res/values/strings_tl.arb                     |   3 +
 res/values/strings_tr.arb                     |   3 +
 res/values/strings_uk.arb                     |  13 +-
 res/values/strings_ur.arb                     |   3 +
 res/values/strings_vi.arb                     |   1 +
 res/values/strings_yo.arb                     |   3 +
 res/values/strings_zh.arb                     |   3 +
 tool/utils/secret_key.dart                    |   2 +
 88 files changed, 4082 insertions(+), 686 deletions(-)
 create mode 100644 assets/images/apple_pay_logo.png
 create mode 100644 assets/images/apple_pay_round_dark.svg
 create mode 100644 assets/images/apple_pay_round_light.svg
 create mode 100644 assets/images/bank.png
 create mode 100644 assets/images/bank_dark.svg
 create mode 100644 assets/images/bank_light.svg
 create mode 100644 assets/images/buy_sell.png
 create mode 100644 assets/images/card.svg
 create mode 100644 assets/images/card_dark.svg
 create mode 100644 assets/images/dollar_coin.svg
 create mode 100644 assets/images/google_pay_icon.png
 create mode 100644 assets/images/meld_logo.svg
 create mode 100644 assets/images/revolut.png
 create mode 100644 assets/images/skrill.svg
 create mode 100644 assets/images/usd_round_dark.svg
 create mode 100644 assets/images/usd_round_light.svg
 create mode 100644 assets/images/wallet_new.png
 create mode 100644 lib/buy/buy_quote.dart
 create mode 100644 lib/buy/meld/meld_buy_provider.dart
 create mode 100644 lib/buy/payment_method.dart
 create mode 100644 lib/buy/sell_buy_states.dart
 create mode 100644 lib/core/selectable_option.dart
 rename lib/src/screens/{InfoPage.dart => Info_page.dart} (100%)
 delete mode 100644 lib/src/screens/buy/buy_options_page.dart
 create mode 100644 lib/src/screens/buy/buy_sell_options_page.dart
 create mode 100644 lib/src/screens/buy/buy_sell_page.dart
 create mode 100644 lib/src/screens/buy/payment_method_options_page.dart
 create mode 100644 lib/src/screens/select_options_page.dart
 create mode 100644 lib/src/widgets/provider_optoin_tile.dart
 create mode 100644 lib/view_model/buy/buy_sell_view_model.dart

diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml
index 6d0e541ce..a12fd422f 100644
--- a/.github/workflows/pr_test_build_android.yml
+++ b/.github/workflows/pr_test_build_android.yml
@@ -194,6 +194,8 @@ jobs:
           echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
           echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
           echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
+          echo "const meldTestApiKey = '${{ secrets.MELD_TEST_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const meldTestPublicKey = '${{ secrets.MELD_TEST_PUBLIC_KEY}}';" >> lib/.secrets.g.dar
           echo "const letsExchangeBearerToken = '${{ secrets.LETS_EXCHANGE_TOKEN }}';" >> lib/.secrets.g.dart
           echo "const letsExchangeAffiliateId = '${{ secrets.LETS_EXCHANGE_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
           echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml
index 5ea0cb377..f3ce1045d 100644
--- a/.github/workflows/pr_test_build_linux.yml
+++ b/.github/workflows/pr_test_build_linux.yml
@@ -175,6 +175,8 @@ jobs:
           echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
           echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
           echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
+          echo "const meldTestApiKey = '${{ secrets.MELD_TEST_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const meldTestPublicKey = '${{ secrets.MELD_TEST_PUBLIC_KEY}}';" >> lib/.secrets.g.dar
           echo "const letsExchangeBearerToken = '${{ secrets.LETS_EXCHANGE_TOKEN }}';" >> lib/.secrets.g.dart
           echo "const letsExchangeAffiliateId = '${{ secrets.LETS_EXCHANGE_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
           echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
diff --git a/assets/images/apple_pay_logo.png b/assets/images/apple_pay_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..346007e3b164651dab29b53c8368c6d48fe3310e
GIT binary patch
literal 56018
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
Hk^KJyr@mf2

literal 0
HcmV?d00001

diff --git a/assets/images/apple_pay_round_dark.svg b/assets/images/apple_pay_round_dark.svg
new file mode 100644
index 000000000..82443bfb4
--- /dev/null
+++ b/assets/images/apple_pay_round_dark.svg
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve">
+
+<defs>
+</defs>
+    <g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
+	<path d="M 24.144 34.985 c -0.77 0.912 -2.003 1.631 -3.236 1.528 c -0.154 -1.233 0.449 -2.542 1.156 -3.351 c 0.77 -0.937 2.119 -1.605 3.21 -1.656 C 25.402 32.789 24.902 34.047 24.144 34.985 M 25.261 36.757 c -1.785 -0.103 -3.313 1.014 -4.16 1.014 c -0.86 0 -2.157 -0.963 -3.57 -0.937 c -1.836 0.026 -3.544 1.066 -4.481 2.722 c -1.926 3.313 -0.501 8.218 1.361 10.914 c 0.912 1.335 2.003 2.799 3.441 2.748 c 1.361 -0.051 1.9 -0.886 3.544 -0.886 c 1.656 0 2.131 0.886 3.57 0.86 c 1.489 -0.026 2.427 -1.335 3.338 -2.671 c 1.04 -1.515 1.464 -2.992 1.489 -3.069 c -0.026 -0.026 -2.876 -1.117 -2.902 -4.404 c -0.026 -2.748 2.247 -4.057 2.35 -4.134 C 27.958 37.014 25.954 36.808 25.261 36.757 M 35.572 33.033 v 20.018 h 3.107 v -6.844 h 4.301 c 3.929 0 6.69 -2.696 6.69 -6.6 s -2.709 -6.574 -6.587 -6.574 H 35.572 L 35.572 33.033 z M 38.679 35.652 h 3.582 c 2.696 0 4.237 1.438 4.237 3.968 c 0 2.529 -1.541 3.98 -4.25 3.98 h -3.57 V 35.652 z M 55.345 53.205 c 1.952 0 3.762 -0.989 4.584 -2.555 h 0.064 v 2.401 h 2.876 v -9.964 c 0 -2.889 -2.311 -4.751 -5.868 -4.751 c -3.3 0 -5.739 1.887 -5.829 4.481 h 2.799 c 0.231 -1.233 1.374 -2.042 2.94 -2.042 c 1.9 0 2.966 0.886 2.966 2.517 v 1.104 L 56 44.628 c -3.608 0.218 -5.56 1.695 -5.56 4.263 C 50.44 51.484 52.456 53.205 55.345 53.205 z M 56.18 50.829 c -1.656 0 -2.709 -0.796 -2.709 -2.016 c 0 -1.258 1.014 -1.99 2.953 -2.106 l 3.454 -0.218 v 1.13 C 59.878 49.494 58.286 50.829 56.18 50.829 z M 66.709 58.495 c 3.03 0 4.455 -1.156 5.701 -4.661 l 5.457 -15.305 h -3.159 l -3.659 11.826 h -0.064 l -3.659 -11.826 h -3.249 l 5.264 14.573 l -0.282 0.886 c -0.475 1.502 -1.245 2.08 -2.619 2.08 c -0.244 0 -0.719 -0.026 -0.912 -0.051 v 2.401 C 65.707 58.469 66.478 58.495 66.709 58.495 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: white; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
+        <path d="M 45 90 C 20.187 90 0 69.813 0 45 C 0 20.187 20.187 0 45 0 c 24.813 0 45 20.187 45 45 C 90 69.813 69.813 90 45 90 z M 45 3 C 21.841 3 3 21.841 3 45 c 0 23.159 18.841 42 42 42 c 23.159 0 42 -18.841 42 -42 C 87 21.841 68.159 3 45 3 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: white; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
+</g>
+</svg>
\ No newline at end of file
diff --git a/assets/images/apple_pay_round_light.svg b/assets/images/apple_pay_round_light.svg
new file mode 100644
index 000000000..2beb1248f
--- /dev/null
+++ b/assets/images/apple_pay_round_light.svg
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve">
+
+<defs>
+</defs>
+<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
+	<path d="M 24.144 34.985 c -0.77 0.912 -2.003 1.631 -3.236 1.528 c -0.154 -1.233 0.449 -2.542 1.156 -3.351 c 0.77 -0.937 2.119 -1.605 3.21 -1.656 C 25.402 32.789 24.902 34.047 24.144 34.985 M 25.261 36.757 c -1.785 -0.103 -3.313 1.014 -4.16 1.014 c -0.86 0 -2.157 -0.963 -3.57 -0.937 c -1.836 0.026 -3.544 1.066 -4.481 2.722 c -1.926 3.313 -0.501 8.218 1.361 10.914 c 0.912 1.335 2.003 2.799 3.441 2.748 c 1.361 -0.051 1.9 -0.886 3.544 -0.886 c 1.656 0 2.131 0.886 3.57 0.86 c 1.489 -0.026 2.427 -1.335 3.338 -2.671 c 1.04 -1.515 1.464 -2.992 1.489 -3.069 c -0.026 -0.026 -2.876 -1.117 -2.902 -4.404 c -0.026 -2.748 2.247 -4.057 2.35 -4.134 C 27.958 37.014 25.954 36.808 25.261 36.757 M 35.572 33.033 v 20.018 h 3.107 v -6.844 h 4.301 c 3.929 0 6.69 -2.696 6.69 -6.6 s -2.709 -6.574 -6.587 -6.574 H 35.572 L 35.572 33.033 z M 38.679 35.652 h 3.582 c 2.696 0 4.237 1.438 4.237 3.968 c 0 2.529 -1.541 3.98 -4.25 3.98 h -3.57 V 35.652 z M 55.345 53.205 c 1.952 0 3.762 -0.989 4.584 -2.555 h 0.064 v 2.401 h 2.876 v -9.964 c 0 -2.889 -2.311 -4.751 -5.868 -4.751 c -3.3 0 -5.739 1.887 -5.829 4.481 h 2.799 c 0.231 -1.233 1.374 -2.042 2.94 -2.042 c 1.9 0 2.966 0.886 2.966 2.517 v 1.104 L 56 44.628 c -3.608 0.218 -5.56 1.695 -5.56 4.263 C 50.44 51.484 52.456 53.205 55.345 53.205 z M 56.18 50.829 c -1.656 0 -2.709 -0.796 -2.709 -2.016 c 0 -1.258 1.014 -1.99 2.953 -2.106 l 3.454 -0.218 v 1.13 C 59.878 49.494 58.286 50.829 56.18 50.829 z M 66.709 58.495 c 3.03 0 4.455 -1.156 5.701 -4.661 l 5.457 -15.305 h -3.159 l -3.659 11.826 h -0.064 l -3.659 -11.826 h -3.249 l 5.264 14.573 l -0.282 0.886 c -0.475 1.502 -1.245 2.08 -2.619 2.08 c -0.244 0 -0.719 -0.026 -0.912 -0.051 v 2.401 C 65.707 58.469 66.478 58.495 66.709 58.495 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
+	<path d="M 45 90 C 20.187 90 0 69.813 0 45 C 0 20.187 20.187 0 45 0 c 24.813 0 45 20.187 45 45 C 90 69.813 69.813 90 45 90 z M 45 3 C 21.841 3 3 21.841 3 45 c 0 23.159 18.841 42 42 42 c 23.159 0 42 -18.841 42 -42 C 87 21.841 68.159 3 45 3 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
+</g>
+</svg>
\ No newline at end of file
diff --git a/assets/images/bank.png b/assets/images/bank.png
new file mode 100644
index 0000000000000000000000000000000000000000..9dc68147aad18488da6007bca88b92ba13697559
GIT binary patch
literal 1323
zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVEN?f;uumf=j~kE^`fC7ZTBNI
zG^94Nh;~MO6uz<|Tsk>DadpBM^%V=m!fHy&yw<#7RXXCQ+be(3>q^iAr-jdw^jeip
z8d~3+kT}P-*e-4EOw-quljh!;V4J@7_rCWtZ>FEyuwG=cwTi9I%T61)Q~%k7p9^{(
zSBafsvbvXhQlHl?^ODII>|fsf*SKWAbkF>&$4WitdsOi#CrR2Xb6idoeVop6P`_3R
z$k``WuKxLJb)0j)$1kgXX>OVC{Y&~Ibbi$yzaR6&Hm-7Rt@a+iZr9_-t}Ajl_O5pp
zXp)L=S70&S$LGkARU_LZaOH;;i{grpr5sKHk6#P4EI?MMUL&wbYW)kx13wnv#T5me
z%X2Q@=~sRG{{Q#(Gym3n{Hi)H>E3F~O6N<aJ@aD(wyEyD_Vv*F<UdcEKg7K}8pl<$
z-tLyv!>7Nv-%Kgte0-SY;ie_KSF`Us_ek%~(udo=9(dmBx!=>u;LdwS?IMNh8&BTu
ze04;-)l+}XEk>Sm-K_cMt0(`{_3_GP{&4o(w4;A?y{>c4V4M3-s3Fstp~?6$kHBn6
z#*VXVv>9%<a#pv!maIz3KX`lps>yYlK2^Kd>m?ZQiSMzEpIfr&>Fy^YOy^ka?*DAx
z-0pj?E@JMVKTPrJMkbuRX0JMbCb9S$ZV}_%r&Zhh#ab=nmExbxZ!Hfl|J1T@cFGBt
zW_uOen_DY9Uj7ggHrXn$%=^#c&+8SJKL2!i$@A!U!UiT$ypz)HpI-g<U#te0w!mQZ
zhlVB2lg>SP&b{vG#5z0OmkXBMW%l;zcRN3K|K#}wFLzm&hF+S;_-{X>t<*$0k)LIq
zx2M=YyX$@p$hRxJ^u>L~b6Iimn_HXYOqcZaF2C}=`o|%qxwd5&79U%ato;7lkF`^;
zHZT8@v18J{TS*zeL_Ta;QvIpI?NYk#=j}XpvKJOBwnv?*S^ac}vhMM{Uj0&w`+DbO
zRz5E;+*a^Lv+9aOY0i`DP9IBdy?=D`(8iZ(g0@*DR%Ss}HaXX2j^B&6Fx#sJ5!v-`
z&FhM)nE8FZ0u2^cvqYZpJaBiPe2C>hf1g?_XM?<~FPAWbJy1f8p{~S4(}&^Di;SQd
z3_mVjTw=iZVew+mM5aNY;l^(^!S823m*>1JG_lg#;_7pYcTIP1<Mxh)$K@<y1<Z3<
zuOHocXyg2E7bR?0<;zN2-YEL(89hUHbKzs{FDndR?YN@Wlm1yRZ1<-d8I{lP-_iI~
z2MWWOtj&j9kIx3Gczwg;){Gy!<!1dmRxmlaO6F(TNAXW_|Guoa_&OrRzfN5L)))Tl
zf6anlGEVgEdHVaB%(48Z*;iwy@m_pv@aEj^(B-_{_2<fYwtqgq{FD2Xt!sl`3PKao
zf|(`h?^>3ewyisT{DOw5hn)QMl5|rBb+-!=&e>NVM3^#!8#r8Knqjk_b$MN@^z>DX
z7IsZ-5>cz!++TMe5NY!5xp1X<$ISKrx9c(~YW!!c{2hJkt)%`Xknx_belF{r5}E)9
CLv&mK

literal 0
HcmV?d00001

diff --git a/assets/images/bank_dark.svg b/assets/images/bank_dark.svg
new file mode 100644
index 000000000..670120796
--- /dev/null
+++ b/assets/images/bank_dark.svg
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve">
+
+<defs>
+</defs>
+    <g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: white; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
+	<path d="M 84.668 38.004 v -6.27 H 90 V 20 L 45 3.034 L 0 20 v 11.734 h 5.332 v 6.27 h 4.818 v 30.892 H 5.332 v 6.271 H 0 v 11.8 h 90 v -11.8 h -5.332 v -6.271 H 79.85 V 38.004 H 84.668 z M 81.668 35.004 H 66.332 v -3.27 h 15.336 V 35.004 z M 63.332 68.896 v 6.271 h -7.664 v -6.271 H 50.85 V 38.004 h 4.818 v -6.27 h 7.664 v 6.27 h 4.818 v 30.892 H 63.332 z M 26.668 38.004 v -6.27 h 7.664 v 6.27 h 4.818 v 30.892 h -4.818 v 6.271 h -7.664 v -6.271 H 21.85 V 38.004 H 26.668 z M 42.15 68.896 V 38.004 h 5.7 v 30.892 H 42.15 z M 37.332 35.004 v -3.27 h 15.336 v 3.27 H 37.332 z M 37.332 71.896 h 15.336 v 3.271 H 37.332 V 71.896 z M 3 22.075 L 45 6.24 l 42 15.835 v 6.659 H 3 V 22.075 z M 8.332 31.734 h 15.336 v 3.27 H 8.332 V 31.734 z M 13.15 38.004 h 5.7 v 30.892 h -5.7 V 38.004 z M 8.332 71.896 h 15.336 v 3.271 H 8.332 V 71.896 z M 87 83.966 H 3 v -5.8 h 84 V 83.966 z M 81.668 75.166 H 66.332 v -3.271 h 15.336 V 75.166 z M 76.85 68.896 H 71.15 V 38.004 h 5.699 V 68.896 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: white; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
+</g>
+</svg>
\ No newline at end of file
diff --git a/assets/images/bank_light.svg b/assets/images/bank_light.svg
new file mode 100644
index 000000000..804716289
--- /dev/null
+++ b/assets/images/bank_light.svg
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve">
+
+<defs>
+</defs>
+	<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: black; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
+	<path d="M 84.668 38.004 v -6.27 H 90 V 20 L 45 3.034 L 0 20 v 11.734 h 5.332 v 6.27 h 4.818 v 30.892 H 5.332 v 6.271 H 0 v 11.8 h 90 v -11.8 h -5.332 v -6.271 H 79.85 V 38.004 H 84.668 z M 81.668 35.004 H 66.332 v -3.27 h 15.336 V 35.004 z M 63.332 68.896 v 6.271 h -7.664 v -6.271 H 50.85 V 38.004 h 4.818 v -6.27 h 7.664 v 6.27 h 4.818 v 30.892 H 63.332 z M 26.668 38.004 v -6.27 h 7.664 v 6.27 h 4.818 v 30.892 h -4.818 v 6.271 h -7.664 v -6.271 H 21.85 V 38.004 H 26.668 z M 42.15 68.896 V 38.004 h 5.7 v 30.892 H 42.15 z M 37.332 35.004 v -3.27 h 15.336 v 3.27 H 37.332 z M 37.332 71.896 h 15.336 v 3.271 H 37.332 V 71.896 z M 3 22.075 L 45 6.24 l 42 15.835 v 6.659 H 3 V 22.075 z M 8.332 31.734 h 15.336 v 3.27 H 8.332 V 31.734 z M 13.15 38.004 h 5.7 v 30.892 h -5.7 V 38.004 z M 8.332 71.896 h 15.336 v 3.271 H 8.332 V 71.896 z M 87 83.966 H 3 v -5.8 h 84 V 83.966 z M 81.668 75.166 H 66.332 v -3.271 h 15.336 V 75.166 z M 76.85 68.896 H 71.15 V 38.004 h 5.699 V 68.896 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: black; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
+</g>
+</svg>
\ No newline at end of file
diff --git a/assets/images/buy_sell.png b/assets/images/buy_sell.png
new file mode 100644
index 0000000000000000000000000000000000000000..0fbffe56fb0e74a762e0b48e79c5930d5c116498
GIT binary patch
literal 9931
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

literal 0
HcmV?d00001

diff --git a/assets/images/card.svg b/assets/images/card.svg
new file mode 100644
index 000000000..95530cdc9
--- /dev/null
+++ b/assets/images/card.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="iso-8859-1"?><!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 50 50" width="100px" height="100px"><path style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;" d="M43,40H7c-2.209,0-4-1.791-4-4V14c0-2.209,1.791-4,4-4h36c2.209,0,4,1.791,4,4v22C47,38.209,45.209,40,43,40z"/><rect x="3" y="16" width="44" height="5"/><line style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;" x1="9" y1="25" x2="25" y2="25"/></svg>
\ No newline at end of file
diff --git a/assets/images/card_dark.svg b/assets/images/card_dark.svg
new file mode 100644
index 000000000..2e5bcf986
--- /dev/null
+++ b/assets/images/card_dark.svg
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 50 50" width="100px" height="100px">
+    <path style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;" d="M43,40H7c-2.209,0-4-1.791-4-4V14c0-2.209,1.791-4,4-4h36c2.209,0,4,1.791,4,4v22C47,38.209,45.209,40,43,40z"/>
+    <rect x="3" y="16" width="44" height="5" style="fill:white;stroke:#ffffff;stroke-width:2;"/>
+    <line style="fill:none;stroke:#ffffff;stroke-width:2;stroke-miterlimit:10;" x1="9" y1="25" x2="25" y2="25"/>
+</svg>
\ No newline at end of file
diff --git a/assets/images/dollar_coin.svg b/assets/images/dollar_coin.svg
new file mode 100644
index 000000000..22218f332
--- /dev/null
+++ b/assets/images/dollar_coin.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?>
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
+<svg fill="#000000" width="800px" height="800px" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
+
<g id="Outline">
+
<g data-name="Outline" id="Outline-2">
+
<path d="M39,36.852a6.8,6.8,0,0,0-6.793-6.793h-.319A3.716,3.716,0,1,1,35.6,26.344a1,1,0,0,0,2,0,5.725,5.725,0,0,0-4.561-5.6V18.09a1,1,0,0,0-2,0V20.7a5.712,5.712,0,0,0,.846,11.361h.319a4.793,4.793,0,1,1-4.793,4.793,1,1,0,0,0-2,0A6.8,6.8,0,0,0,31.451,43.6v2.947a1,1,0,0,0,2,0v-3c0-.008,0-.014,0-.021A6.8,6.8,0,0,0,39,36.852Z"/>
+
<path d="M32,2A30,30,0,1,0,62,32,30.034,30.034,0,0,0,32,2Zm0,58A28,28,0,1,1,60,32,28.032,28.032,0,0,1,32,60Z"/>
+
<path d="M49.655,16.793a3.172,3.172,0,1,0-3.172,3.172,3.137,3.137,0,0,0,1.263-.266A19.994,19.994,0,0,1,22.692,49.707a1,1,0,0,0-.933,1.769,21.986,21.986,0,0,0,27.47-33.124A3.141,3.141,0,0,0,49.655,16.793Zm-4.344,0a1.172,1.172,0,1,1,1.172,1.172A1.172,1.172,0,0,1,45.311,16.793Z"/>
+
<path d="M16.793,44.035a3.164,3.164,0,0,0-.692.081A19.779,19.779,0,0,1,12,32,20.023,20.023,0,0,1,32,12a19.811,19.811,0,0,1,8.463,1.874,1,1,0,0,0,.848-1.812A21.989,21.989,0,0,0,14.39,45.16a3.141,3.141,0,0,0-.769,2.047,3.172,3.172,0,1,0,3.172-3.172Zm0,4.344a1.172,1.172,0,1,1,1.172-1.172A1.172,1.172,0,0,1,16.793,48.379Z"/>
+
</g>
+
</g>
+
</svg>
\ No newline at end of file
diff --git a/assets/images/google_pay_icon.png b/assets/images/google_pay_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a3ca38311cf31e5304b3fa2eb541d7e59dfe2863
GIT binary patch
literal 12336
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
O_efn=ty;x4^8W!pu>c<c

literal 0
HcmV?d00001

diff --git a/assets/images/meld_logo.svg b/assets/images/meld_logo.svg
new file mode 100644
index 000000000..1d9211d64
--- /dev/null
+++ b/assets/images/meld_logo.svg
@@ -0,0 +1,30 @@
+<svg width="40" height="42" viewBox="0 0 40 42" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path opacity="0.7" d="M19.9526 41.9076L7.3877 34.655V26.1226L19.9526 33.3751V41.9076Z" fill="url(#paint0_linear_2113_32117)"/>
+<path opacity="0.7" d="M19.9521 41.9076L32.5171 34.655V26.1226L19.9521 33.3751V41.9076Z" fill="url(#paint1_linear_2113_32117)"/>
+<path opacity="0.7" d="M39.9095 7.34521V21.8562L32.5166 26.1225V11.6114L39.9095 7.34521Z" fill="url(#paint2_linear_2113_32117)"/>
+<path d="M39.9099 7.34536L27.345 0.0927734L19.9521 4.359L32.5171 11.6116L39.9099 7.34536Z" fill="url(#paint3_linear_2113_32117)"/>
+<path d="M0 7.34536L12.5649 0.0927734L19.9519 4.359L7.387 11.6116L0 7.34536Z" fill="#F969D3"/>
+<path opacity="0.7" d="M0 7.34521V21.8562L7.387 26.1225V11.6114L0 7.34521Z" fill="url(#paint4_linear_2113_32117)"/>
+<defs>
+<linearGradient id="paint0_linear_2113_32117" x1="18.6099" y1="41.8335" x2="7.73529" y2="8.31842" gradientUnits="userSpaceOnUse">
+<stop stop-color="#E98ADA"/>
+<stop offset="1" stop-color="#7E4DBD"/>
+</linearGradient>
+<linearGradient id="paint1_linear_2113_32117" x1="26.2346" y1="26.1226" x2="26.2346" y2="41.9076" gradientUnits="userSpaceOnUse">
+<stop stop-color="#719DED"/>
+<stop offset="1" stop-color="#2545BE"/>
+</linearGradient>
+<linearGradient id="paint2_linear_2113_32117" x1="36.213" y1="7.34521" x2="36.213" y2="26.1225" gradientUnits="userSpaceOnUse">
+<stop stop-color="#93EBFF"/>
+<stop offset="1" stop-color="#197DDB"/>
+</linearGradient>
+<linearGradient id="paint3_linear_2113_32117" x1="29.931" y1="0.0927734" x2="38.2156" y2="14.8448" gradientUnits="userSpaceOnUse">
+<stop stop-color="#F969D3"/>
+<stop offset="1" stop-color="#4F51C0"/>
+</linearGradient>
+<linearGradient id="paint4_linear_2113_32117" x1="18.1251" y1="44.2539" x2="-7.06792" y2="15.2763" gradientUnits="userSpaceOnUse">
+<stop stop-color="#E98ADA"/>
+<stop offset="1" stop-color="#7E4DBD"/>
+</linearGradient>
+</defs>
+</svg>
diff --git a/assets/images/revolut.png b/assets/images/revolut.png
new file mode 100644
index 0000000000000000000000000000000000000000..bbe342592660209396ef45a6a119154437f93259
GIT binary patch
literal 11588
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
Hk754@^tnqa

literal 0
HcmV?d00001

diff --git a/assets/images/skrill.svg b/assets/images/skrill.svg
new file mode 100644
index 000000000..b264b57eb
--- /dev/null
+++ b/assets/images/skrill.svg
@@ -0,0 +1,15 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve">
+
+<defs>
+</defs>
+<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
+	<circle cx="45" cy="45" r="45" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(127,33,99); fill-rule: nonzero; opacity: 1;" transform="  matrix(1 0 0 1 0 0) "/>
+	<polygon points="69.59,36.9 69.59,54.86 74.5,54.86 74.5,36.02 " style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(249,249,249); fill-rule: nonzero; opacity: 1;" transform="  matrix(1 0 0 1 0 0) "/>
+	<polygon points="62.42,36.9 67.33,36.02 67.33,54.87 62.42,54.87 " style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(249,249,249); fill-rule: nonzero; opacity: 1;" transform="  matrix(1 0 0 1 0 0) "/>
+	<rect x="55.43" y="41.08" rx="0" ry="0" width="4.91" height="13.78" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(249,249,249); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) "/>
+	<path d="M 57.879 39.76 c 1.332 0 2.425 -1.082 2.425 -2.415 s -1.082 -2.425 -2.425 -2.425 c -1.332 0 -2.415 1.082 -2.415 2.425 C 55.465 38.677 56.547 39.76 57.879 39.76 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(249,249,249); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
+	<path d="M 52.665 40.884 c -4.538 0.146 -6.838 2.186 -6.838 6.234 v 7.754 h 4.954 v -6.328 c 0 -2.425 0.312 -3.466 3.195 -3.559 v -4.038 C 53.477 40.853 52.665 40.884 52.665 40.884 L 52.665 40.884 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(249,249,249); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
+	<path d="M 39.344 41.071 c -0.104 0.271 -0.895 2.498 -2.8 4.798 v -9.845 l -5.068 0.999 v 17.838 h 5.068 v -5.516 c 1.467 2.206 2.196 5.516 2.196 5.516 h 6.068 c -0.604 -2.498 -3.226 -7.098 -3.226 -7.098 c 2.352 -2.987 3.393 -6.172 3.559 -6.702 h -5.797 L 39.344 41.071 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(249,249,249); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
+	<path d="M 22.973 43.028 c -0.624 -0.042 -2.061 -0.135 -2.061 -1.426 c 0 -1.561 2.071 -1.561 2.841 -1.561 c 1.363 0 3.133 0.406 4.392 0.781 c 0 0 0.708 0.25 1.301 0.5 l 0.052 0.01 v -4.267 l -0.073 -0.021 c -1.488 -0.52 -3.216 -1.02 -6.432 -1.02 c -5.537 0 -7.493 3.226 -7.493 5.984 c 0 1.592 0.687 5.339 7.025 5.776 c 0.541 0.031 1.967 0.114 1.967 1.457 c 0 1.103 -1.166 1.759 -3.133 1.759 c -2.154 0 -4.236 -0.552 -5.506 -1.072 v 4.402 c 1.894 0.5 4.038 0.749 6.546 0.749 c 5.412 0 7.837 -3.049 7.837 -6.078 C 30.237 45.567 27.531 43.34 22.973 43.028 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(249,249,249); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
+</g>
+</svg>
\ No newline at end of file
diff --git a/assets/images/usd_round_dark.svg b/assets/images/usd_round_dark.svg
new file mode 100644
index 000000000..f329dd617
--- /dev/null
+++ b/assets/images/usd_round_dark.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 24 24" width="512" height="512">
+    <path d="M12,0C5.383,0,0,5.383,0,12s5.383,12,12,12,12-5.383,12-12S18.617,0,12,0Zm0,23c-6.065,0-11-4.935-11-11S5.935,1,12,1s11,4.935,11,11-4.935,11-11,11Zm4-8.626c0,1.448-1.178,2.626-2.626,2.626h-.874v1.5c0,.276-.224,.5-.5,.5s-.5-.224-.5-.5v-1.5h-.926c-.979,0-1.893-.526-2.382-1.375-.139-.239-.057-.545,.183-.683,.238-.14,.544-.057,.683,.183,.312,.54,.894,.875,1.517,.875h2.8c.896,0,1.626-.729,1.626-1.626,0-.803-.575-1.478-1.368-1.605l-3.422-.55c-1.28-.206-2.21-1.296-2.21-2.593,0-1.448,1.178-2.626,2.626-2.626h.874v-1.5c0-.276,.224-.5,.5-.5s.5,.224,.5,.5v1.5h.926c.979,0,1.892,.527,2.382,1.375,.139,.239,.057,.545-.183,.683-.236,.136-.545,.057-.683-.183-.312-.54-.894-.875-1.517-.875h-2.8c-.896,0-1.626,.729-1.626,1.626,0,.803,.575,1.478,1.368,1.605l3.422,.55c1.28,.206,2.21,1.297,2.21,2.593Z" fill="white"/>
+</svg>
\ No newline at end of file
diff --git a/assets/images/usd_round_light.svg b/assets/images/usd_round_light.svg
new file mode 100644
index 000000000..f5965c597
--- /dev/null
+++ b/assets/images/usd_round_light.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 24 24" width="512" height="512"><path d="M12,0C5.383,0,0,5.383,0,12s5.383,12,12,12,12-5.383,12-12S18.617,0,12,0Zm0,23c-6.065,0-11-4.935-11-11S5.935,1,12,1s11,4.935,11,11-4.935,11-11,11Zm4-8.626c0,1.448-1.178,2.626-2.626,2.626h-.874v1.5c0,.276-.224,.5-.5,.5s-.5-.224-.5-.5v-1.5h-.926c-.979,0-1.893-.526-2.382-1.375-.139-.239-.057-.545,.183-.683,.238-.14,.544-.057,.683,.183,.312,.54,.894,.875,1.517,.875h2.8c.896,0,1.626-.729,1.626-1.626,0-.803-.575-1.478-1.368-1.605l-3.422-.55c-1.28-.206-2.21-1.296-2.21-2.593,0-1.448,1.178-2.626,2.626-2.626h.874v-1.5c0-.276,.224-.5,.5-.5s.5,.224,.5,.5v1.5h.926c.979,0,1.892,.527,2.382,1.375,.139,.239,.057,.545-.183,.683-.236,.136-.545,.057-.683-.183-.312-.54-.894-.875-1.517-.875h-2.8c-.896,0-1.626,.729-1.626,1.626,0,.803,.575,1.478,1.368,1.605l3.422,.55c1.28,.206,2.21,1.297,2.21,2.593Z"/></svg>
diff --git a/assets/images/wallet_new.png b/assets/images/wallet_new.png
new file mode 100644
index 0000000000000000000000000000000000000000..47c43bfca99bc5cf9958e150081d4f885ed27802
GIT binary patch
literal 5619
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

literal 0
HcmV?d00001

diff --git a/cw_core/lib/currency_for_wallet_type.dart b/cw_core/lib/currency_for_wallet_type.dart
index 630078949..af6037a3b 100644
--- a/cw_core/lib/currency_for_wallet_type.dart
+++ b/cw_core/lib/currency_for_wallet_type.dart
@@ -35,3 +35,34 @@ CryptoCurrency currencyForWalletType(WalletType type, {bool? isTestnet}) {
           'Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType');
   }
 }
+
+WalletType? walletTypeForCurrency(CryptoCurrency currency) {
+  switch (currency) {
+    case CryptoCurrency.btc:
+      return WalletType.bitcoin;
+    case CryptoCurrency.xmr:
+      return WalletType.monero;
+    case CryptoCurrency.ltc:
+      return WalletType.litecoin;
+    case CryptoCurrency.xhv:
+      return WalletType.haven;
+    case CryptoCurrency.eth:
+      return WalletType.ethereum;
+    case CryptoCurrency.bch:
+      return WalletType.bitcoinCash;
+    case CryptoCurrency.nano:
+      return WalletType.nano;
+    case CryptoCurrency.banano:
+      return WalletType.banano;
+    case CryptoCurrency.maticpoly:
+      return WalletType.polygon;
+    case CryptoCurrency.sol:
+      return WalletType.solana;
+    case CryptoCurrency.trx:
+      return WalletType.tron;
+    case CryptoCurrency.wow:
+      return WalletType.wownero;
+    default:
+      return null;
+  }
+}
diff --git a/lib/buy/buy_provider.dart b/lib/buy/buy_provider.dart
index 1a37e09b3..8e79e16b8 100644
--- a/lib/buy/buy_provider.dart
+++ b/lib/buy/buy_provider.dart
@@ -1,6 +1,10 @@
 import 'package:cake_wallet/buy/buy_amount.dart';
+import 'package:cake_wallet/buy/buy_quote.dart';
 import 'package:cake_wallet/buy/order.dart';
+import 'package:cake_wallet/buy/payment_method.dart';
+import 'package:cake_wallet/entities/fiat_currency.dart';
 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
+import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:flutter/material.dart';
 
@@ -23,14 +27,38 @@ abstract class BuyProvider {
 
   String get darkIcon;
 
+  bool get isAggregator;
+
   @override
   String toString() => title;
 
-  Future<void> launchProvider(BuildContext context, bool? isBuyAction);
+  Future<void>? launchProvider(
+          {required BuildContext context,
+          required Quote quote,
+          required double amount,
+          required bool isBuyAction,
+          required String cryptoCurrencyAddress,
+          String? countryCode}) =>
+      null;
 
   Future<String> requestUrl(String amount, String sourceCurrency) => throw UnimplementedError();
 
   Future<Order> findOrderById(String id) => throw UnimplementedError();
 
-  Future<BuyAmount> calculateAmount(String amount, String sourceCurrency) => throw UnimplementedError();
+  Future<BuyAmount> calculateAmount(String amount, String sourceCurrency) =>
+      throw UnimplementedError();
+
+  Future<List<PaymentMethod>> getAvailablePaymentTypes(
+          String fiatCurrency, String cryptoCurrency, bool isBuyAction) async =>
+      [];
+
+  Future<List<Quote>?> fetchQuote(
+          {required CryptoCurrency cryptoCurrency,
+          required FiatCurrency fiatCurrency,
+          required double amount,
+          required bool isBuyAction,
+          required String walletAddress,
+          PaymentType? paymentType,
+          String? countryCode}) async =>
+      null;
 }
diff --git a/lib/buy/buy_quote.dart b/lib/buy/buy_quote.dart
new file mode 100644
index 000000000..72ab7bd7d
--- /dev/null
+++ b/lib/buy/buy_quote.dart
@@ -0,0 +1,302 @@
+import 'package:cake_wallet/buy/buy_provider.dart';
+import 'package:cake_wallet/buy/payment_method.dart';
+import 'package:cake_wallet/core/selectable_option.dart';
+import 'package:cake_wallet/entities/fiat_currency.dart';
+import 'package:cake_wallet/entities/provider_types.dart';
+import 'package:cake_wallet/exchange/limits.dart';
+import 'package:cw_core/crypto_currency.dart';
+
+enum ProviderRecommendation { bestRate, lowKyc, successRate }
+
+extension RecommendationTitle on ProviderRecommendation {
+  String get title {
+    switch (this) {
+      case ProviderRecommendation.bestRate:
+        return 'BEST RATE';
+      case ProviderRecommendation.lowKyc:
+        return 'LOW KYC';
+      case ProviderRecommendation.successRate:
+        return 'SUCCESS RATE';
+    }
+  }
+}
+
+ProviderRecommendation? getRecommendationFromString(String title) {
+  switch (title) {
+    case 'BEST RATE':
+      return ProviderRecommendation.bestRate;
+    case 'LowKyc':
+      return ProviderRecommendation.lowKyc;
+    case 'SuccessRate':
+      return ProviderRecommendation.successRate;
+    default:
+      return null;
+  }
+}
+
+class Quote extends SelectableOption {
+  Quote({
+    required this.rate,
+    required this.feeAmount,
+    required this.networkFee,
+    required this.transactionFee,
+    required this.payout,
+    required this.provider,
+    required this.paymentType,
+    required this.recommendations,
+    this.isBuyAction = true,
+    this.quoteId,
+    this.rampId,
+    this.rampName,
+    this.rampIconPath,
+    this.limits,
+  }) : super(title: provider.isAggregator ? rampName ?? '' : provider.title);
+
+  final double rate;
+  final double feeAmount;
+  final double networkFee;
+  final double transactionFee;
+  final double payout;
+  final PaymentType paymentType;
+  final BuyProvider provider;
+  final String? quoteId;
+  final List<ProviderRecommendation> recommendations;
+  String? rampId;
+  String? rampName;
+  String? rampIconPath;
+  bool _isSelected = false;
+  bool _isBestRate = false;
+  bool isBuyAction;
+  Limits? limits;
+
+  late FiatCurrency _fiatCurrency;
+  late CryptoCurrency _cryptoCurrency;
+
+
+  bool get isSelected => _isSelected;
+  bool get isBestRate => _isBestRate;
+  FiatCurrency get fiatCurrency => _fiatCurrency;
+  CryptoCurrency get cryptoCurrency => _cryptoCurrency;
+
+  @override
+  bool get isOptionSelected => this._isSelected;
+
+  @override
+  String get lightIconPath =>
+      provider.isAggregator ? rampIconPath ?? provider.lightIcon : provider.lightIcon;
+
+  @override
+  String get darkIconPath =>
+      provider.isAggregator ? rampIconPath ?? provider.darkIcon : provider.darkIcon;
+
+  @override
+  List<String> get badges => recommendations.map((e) => e.title).toList();
+
+  @override
+  String get topLeftSubTitle =>
+      this.rate > 0 ? '1 $cryptoName = ${rate.toStringAsFixed(2)} $fiatName' : '';
+
+  @override
+  String get bottomLeftSubTitle {
+    if (limits != null) {
+      final min = limits!.min;
+      final max = limits!.max;
+      return 'min: ${min} ${fiatCurrency.toString()} | max: ${max == double.infinity ? '' : '${max} ${fiatCurrency.toString()}'}';
+    }
+    return '';
+  }
+
+  String get fiatName => isBuyAction ? fiatCurrency.toString() : cryptoCurrency.toString();
+
+  String get cryptoName => isBuyAction ? cryptoCurrency.toString() : fiatCurrency.toString();
+
+  @override
+  String? get topRightSubTitle => '';
+
+  @override
+  String get topRightSubTitleLightIconPath => provider.isAggregator ? provider.lightIcon : '';
+
+  @override
+  String get topRightSubTitleDarkIconPath => provider.isAggregator ? provider.darkIcon : '';
+
+  String get quoteTitle => '${provider.title} - ${paymentType.name}';
+
+  String get formatedFee => '$feeAmount ${isBuyAction ? fiatCurrency : cryptoCurrency}';
+
+  set setIsSelected(bool isSelected) => _isSelected = isSelected;
+  set setIsBestRate(bool isBestRate) => _isBestRate = isBestRate;
+  set setFiatCurrency(FiatCurrency fiatCurrency) => _fiatCurrency = fiatCurrency;
+  set setCryptoCurrency(CryptoCurrency cryptoCurrency) => _cryptoCurrency = cryptoCurrency;
+  set setLimits(Limits limits) => this.limits = limits;
+
+  factory Quote.fromOnramperJson(Map<String, dynamic> json, bool isBuyAction,
+      Map<String, dynamic> metaData, PaymentType paymentType) {
+    final rate = _toDouble(json['rate']) ?? 0.0;
+    final networkFee = _toDouble(json['networkFee']) ?? 0.0;
+    final transactionFee = _toDouble(json['transactionFee']) ?? 0.0;
+    final feeAmount = double.parse((networkFee + transactionFee).toStringAsFixed(2));
+
+    final rampId = json['ramp'] as String? ?? '';
+    final rampData = metaData[rampId] ?? {};
+    final rampName = rampData['displayName'] as String? ?? '';
+    final rampIconPath = rampData['svg'] as String? ?? '';
+
+    final recommendations = json['recommendations'] != null
+        ? List<String>.from(json['recommendations'] as List<dynamic>)
+        : <String>[];
+
+    final enumRecommendations = recommendations
+        .map((e) => getRecommendationFromString(e))
+        .whereType<ProviderRecommendation>()
+        .toList();
+
+    final availablePaymentMethods = json['availablePaymentMethods'] as List<dynamic>? ?? [];
+    double minLimit = 0.0;
+    double maxLimit = double.infinity;
+
+    for (var paymentMethod in availablePaymentMethods) {
+      if (paymentMethod is Map<String, dynamic>) {
+        final details = paymentMethod['details'] as Map<String, dynamic>?;
+
+        if (details != null) {
+          final limits = details['limits'] as Map<String, dynamic>?;
+
+          if (limits != null && limits.isNotEmpty) {
+            final firstLimitEntry = limits.values.first as Map<String, dynamic>?;
+            if (firstLimitEntry != null) {
+              minLimit = _toDouble(firstLimitEntry['min'])?.roundToDouble() ?? 0.0;
+              maxLimit = _toDouble(firstLimitEntry['max'])?.roundToDouble() ?? double.infinity;
+              break;
+            }
+          }
+        }
+      }
+    }
+
+    return Quote(
+      rate: rate,
+      feeAmount: feeAmount,
+      networkFee: networkFee,
+      transactionFee: transactionFee,
+      payout: json['payout'] as double? ?? 0.0,
+      rampId: rampId,
+      rampName: rampName,
+      rampIconPath: rampIconPath,
+      paymentType: paymentType,
+      quoteId: json['quoteId'] as String? ?? '',
+      recommendations: enumRecommendations,
+      provider: ProvidersHelper.getProviderByType(ProviderType.onramper)!,
+      isBuyAction: isBuyAction,
+      limits: Limits(min: minLimit, max: maxLimit),
+    );
+  }
+
+  factory Quote.fromMoonPayJson(
+      Map<String, dynamic> json, bool isBuyAction, PaymentType paymentType) {
+    final rate = isBuyAction
+        ? json['quoteCurrencyPrice'] as double? ?? 0.0
+        : json['baseCurrencyPrice'] as double? ?? 0.0;
+    final fee = _toDouble(json['feeAmount']) ?? 0.0;
+    final networkFee = _toDouble(json['networkFeeAmount']) ?? 0.0;
+    final transactionFee = _toDouble(json['extraFeeAmount']) ?? 0.0;
+    final feeAmount = double.parse((fee + networkFee + transactionFee).toStringAsFixed(2));
+
+    final baseCurrency = json['baseCurrency'] as Map<String, dynamic>?;
+
+    double minLimit = 0.0;
+    double maxLimit = double.infinity;
+
+    if (baseCurrency != null) {
+      minLimit = _toDouble(baseCurrency['minAmount']) ?? minLimit;
+      maxLimit = _toDouble(baseCurrency['maxAmount']) ?? maxLimit;
+    }
+
+    return Quote(
+      rate: rate,
+      feeAmount: feeAmount,
+      networkFee: networkFee,
+      transactionFee: transactionFee,
+      payout: _toDouble(json['quoteCurrencyAmount']) ?? 0.0,
+      paymentType: paymentType,
+      recommendations: [],
+      quoteId: json['signature'] as String? ?? '',
+      provider: ProvidersHelper.getProviderByType(ProviderType.moonpay)!,
+      isBuyAction: isBuyAction,
+      limits: Limits(min: minLimit, max: maxLimit),
+    );
+  }
+
+  factory Quote.fromDFXJson(
+    Map<String, dynamic> json,
+    bool isBuyAction,
+    PaymentType paymentType,
+  ) {
+    final rate = _toDouble(json['exchangeRate']) ?? 0.0;
+    final fees = json['fees'] as Map<String, dynamic>;
+
+    final minVolume = _toDouble(json['minVolume']) ?? 0.0;
+    final maxVolume = _toDouble(json['maxVolume']) ?? double.infinity;
+
+    return Quote(
+      rate: isBuyAction ? rate : 1 / rate,
+      feeAmount: _toDouble(json['feeAmount']) ?? 0.0,
+      networkFee: _toDouble(fees['network']) ?? 0.0,
+      transactionFee: _toDouble(fees['rate']) ?? 0.0,
+      payout: _toDouble(json['payout']) ?? 0.0,
+      paymentType: paymentType,
+      recommendations: [ProviderRecommendation.lowKyc],
+      provider: ProvidersHelper.getProviderByType(ProviderType.dfx)!,
+      isBuyAction: isBuyAction,
+      limits: Limits(min: minVolume, max: maxVolume),
+    );
+  }
+
+  factory Quote.fromRobinhoodJson(
+      Map<String, dynamic> json, bool isBuyAction, PaymentType paymentType) {
+    final networkFee = json['networkFee'] as Map<String, dynamic>;
+    final processingFee = json['processingFee'] as Map<String, dynamic>;
+    final networkFeeAmount = _toDouble(networkFee['fiatAmount']) ?? 0.0;
+    final transactionFeeAmount = _toDouble(processingFee['fiatAmount']) ?? 0.0;
+    final feeAmount = double.parse((networkFeeAmount + transactionFeeAmount).toStringAsFixed(2));
+
+    return Quote(
+      rate: _toDouble(json['price']) ?? 0.0,
+      feeAmount: feeAmount,
+      networkFee: _toDouble(networkFee['fiatAmount']) ?? 0.0,
+      transactionFee: _toDouble(processingFee['fiatAmount']) ?? 0.0,
+      payout: _toDouble(json['cryptoAmount']) ?? 0.0,
+      paymentType: paymentType,
+      recommendations: [],
+      provider: ProvidersHelper.getProviderByType(ProviderType.robinhood)!,
+      isBuyAction: isBuyAction,
+      limits: Limits(min: 0.0, max: double.infinity),
+    );
+  }
+
+  factory Quote.fromMeldJson(Map<String, dynamic> json, bool isBuyAction, PaymentType paymentType) {
+    final quotes = json['quotes'][0] as Map<String, dynamic>;
+    return Quote(
+      rate: quotes['exchangeRate'] as double? ?? 0.0,
+      feeAmount: quotes['totalFee'] as double? ?? 0.0,
+      networkFee: quotes['networkFee'] as double? ?? 0.0,
+      transactionFee: quotes['transactionFee'] as double? ?? 0.0,
+      payout: quotes['payout'] as double? ?? 0.0,
+      paymentType: paymentType,
+      recommendations: [],
+      provider: ProvidersHelper.getProviderByType(ProviderType.meld)!,
+      isBuyAction: isBuyAction,
+      limits: Limits(min: 0.0, max: double.infinity),
+    );
+  }
+
+  static double? _toDouble(dynamic value) {
+    if (value is int) {
+      return value.toDouble();
+    } else if (value is double) {
+      return value;
+    } else if (value is String) {
+      return double.tryParse(value);
+    }
+    return null;
+  }
+}
diff --git a/lib/buy/dfx/dfx_buy_provider.dart b/lib/buy/dfx/dfx_buy_provider.dart
index b3ed72498..c1ed762b1 100644
--- a/lib/buy/dfx/dfx_buy_provider.dart
+++ b/lib/buy/dfx/dfx_buy_provider.dart
@@ -1,13 +1,17 @@
 import 'dart:convert';
+import 'dart:developer';
 
 import 'package:cake_wallet/buy/buy_provider.dart';
+import 'package:cake_wallet/buy/buy_quote.dart';
+import 'package:cake_wallet/buy/payment_method.dart';
+import 'package:cake_wallet/entities/fiat_currency.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart';
 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
-import 'package:cake_wallet/utils/device_info.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
+import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:flutter/material.dart';
@@ -15,10 +19,12 @@ import 'package:http/http.dart' as http;
 import 'package:url_launcher/url_launcher.dart';
 
 class DFXBuyProvider extends BuyProvider {
-  DFXBuyProvider({required WalletBase wallet, bool isTestEnvironment = false, LedgerViewModel? ledgerVM})
+  DFXBuyProvider(
+      {required WalletBase wallet, bool isTestEnvironment = false, LedgerViewModel? ledgerVM})
       : super(wallet: wallet, isTestEnvironment: isTestEnvironment, ledgerVM: ledgerVM);
 
   static const _baseUrl = 'api.dfx.swiss';
+
   // static const _signMessagePath = '/v1/auth/signMessage';
   static const _authPath = '/v1/auth';
   static const walletName = 'CakeWallet';
@@ -35,24 +41,8 @@ class DFXBuyProvider extends BuyProvider {
   @override
   String get darkIcon => 'assets/images/dfx_dark.png';
 
-  String get assetOut {
-    switch (wallet.type) {
-      case WalletType.bitcoin:
-        return 'BTC';
-      case WalletType.bitcoinCash:
-        return 'BCH';
-      case WalletType.litecoin:
-        return 'LTC';
-      case WalletType.monero:
-        return 'XMR';
-      case WalletType.ethereum:
-        return 'ETH';
-      case WalletType.polygon:
-        return 'MATIC';
-      default:
-        throw Exception("WalletType is not available for DFX ${wallet.type}");
-    }
-  }
+  @override
+  bool get isAggregator => false;
 
   String get blockchain {
     switch (wallet.type) {
@@ -60,21 +50,13 @@ class DFXBuyProvider extends BuyProvider {
       case WalletType.bitcoinCash:
       case WalletType.litecoin:
         return 'Bitcoin';
-      case WalletType.monero:
-        return 'Monero';
-      case WalletType.ethereum:
-        return 'Ethereum';
-      case WalletType.polygon:
-        return 'Polygon';
       default:
-        throw Exception("WalletType is not available for DFX ${wallet.type}");
+        return walletTypeToString(wallet.type);
     }
   }
 
-  String get walletAddress =>
-      wallet.walletAddresses.primaryAddress ?? wallet.walletAddresses.address;
 
-  Future<String> getSignMessage() async =>
+  Future<String> getSignMessage(String walletAddress) async =>
       "By_signing_this_message,_you_confirm_that_you_are_the_sole_owner_of_the_provided_Blockchain_address._Your_ID:_$walletAddress";
 
   // // Lets keep this just in case, but we can avoid this API Call
@@ -92,8 +74,9 @@ class DFXBuyProvider extends BuyProvider {
   //  }
   // }
 
-  Future<String> auth() async {
-    final signMessage = await getSignature(await getSignMessage());
+  Future<String> auth(String walletAddress) async {
+    final signMessage = await getSignature(
+        await getSignMessage(walletAddress), walletAddress);
 
     final requestBody = jsonEncode({
       'wallet': walletName,
@@ -120,7 +103,7 @@ class DFXBuyProvider extends BuyProvider {
     }
   }
 
-  Future<String> getSignature(String message) async {
+  Future<String> getSignature(String message, String walletAddress) async {
     switch (wallet.type) {
       case WalletType.ethereum:
       case WalletType.polygon:
@@ -135,8 +118,178 @@ class DFXBuyProvider extends BuyProvider {
     }
   }
 
+  Future<Map<String, dynamic>> fetchFiatCredentials(String fiatCurrency) async {
+    final url = Uri.https(_baseUrl, '/v1/fiat');
+
+    try {
+      final response = await http.get(url, headers: {'accept': 'application/json'});
+
+      if (response.statusCode == 200) {
+        final data = jsonDecode(response.body) as List<dynamic>;
+        for (final item in data) {
+          if (item['name'] == fiatCurrency) return item as Map<String, dynamic>;
+        }
+        log('DFX does not support fiat: $fiatCurrency');
+        return {};
+      } else {
+        log('DFX Failed to fetch fiat currencies: ${response.statusCode}');
+        return {};
+      }
+    } catch (e) {
+      print('DFX Error fetching fiat currencies: $e');
+      return {};
+    }
+  }
+
+  Future<Map<String, dynamic>> fetchAssetCredential(String assetsName) async {
+    final url = Uri.https(_baseUrl, '/v1/asset', {'blockchains': blockchain});
+
+    try {
+      final response = await http.get(url, headers: {'accept': 'application/json'});
+
+      if (response.statusCode == 200) {
+        final responseData = jsonDecode(response.body);
+
+        if (responseData is List && responseData.isNotEmpty) {
+          return responseData.first as Map<String, dynamic>;
+        } else if (responseData is Map<String, dynamic>) {
+          return responseData;
+        } else {
+          log('DFX: Does not support this asset name : ${blockchain}');
+        }
+      } else {
+        log('DFX: Failed to fetch assets: ${response.statusCode}');
+      }
+    } catch (e) {
+      log('DFX: Error fetching assets: $e');
+    }
+    return {};
+  }
+
+  Future<List<PaymentMethod>> getAvailablePaymentTypes(
+      String fiatCurrency, String cryptoCurrency, bool isBuyAction) async {
+    final List<PaymentMethod> paymentMethods = [];
+
+    if (isBuyAction) {
+      final fiatBuyCredentials = await fetchFiatCredentials(fiatCurrency);
+      if (fiatBuyCredentials.isNotEmpty) {
+        fiatBuyCredentials.forEach((key, value) {
+          if (key == 'limits') {
+            final limits = value as Map<String, dynamic>;
+            limits.forEach((paymentMethodKey, paymentMethodValue) {
+              final min = _toDouble(paymentMethodValue['minVolume']);
+              final max = _toDouble(paymentMethodValue['maxVolume']);
+              if (min != null && max != null && min > 0 && max > 0) {
+                final paymentMethod = PaymentMethod.fromDFX(
+                    paymentMethodKey, _getPaymentTypeByString(paymentMethodKey));
+                paymentMethods.add(paymentMethod);
+              }
+            });
+          }
+        });
+      }
+    } else {
+      final assetCredentials = await fetchAssetCredential(cryptoCurrency);
+      if (assetCredentials.isNotEmpty) {
+        if (assetCredentials['sellable'] == true) {
+          final availablePaymentTypes = [
+            PaymentType.bankTransfer,
+            PaymentType.creditCard,
+            PaymentType.sepa
+          ];
+          availablePaymentTypes.forEach((element) {
+            final paymentMethod = PaymentMethod.fromDFX(normalizePaymentMethod(element)!, element);
+            paymentMethods.add(paymentMethod);
+          });
+        }
+      }
+    }
+
+    return paymentMethods;
+  }
+
   @override
-  Future<void> launchProvider(BuildContext context, bool? isBuyAction) async {
+  Future<List<Quote>?> fetchQuote(
+      {required CryptoCurrency cryptoCurrency,
+      required FiatCurrency fiatCurrency,
+      required double amount,
+      required bool isBuyAction,
+      required String walletAddress,
+      PaymentType? paymentType,
+      String? countryCode}) async {
+    /// if buying with any currency other than eur or chf then DFX is not supported
+
+    if (isBuyAction && (fiatCurrency != FiatCurrency.eur && fiatCurrency != FiatCurrency.chf)) {
+      return null;
+    }
+
+    String? paymentMethod;
+    if (paymentType != null && paymentType != PaymentType.all) {
+      paymentMethod = normalizePaymentMethod(paymentType);
+      if (paymentMethod == null) paymentMethod = paymentType.name;
+    } else {
+      paymentMethod = 'Bank';
+    }
+
+    final action = isBuyAction ? 'buy' : 'sell';
+
+    if (isBuyAction && cryptoCurrency != wallet.currency) return null;
+
+    final fiatCredentials = await fetchFiatCredentials(fiatCurrency.name.toString());
+    if (fiatCredentials['id'] == null) return null;
+
+    final assetCredentials = await fetchAssetCredential(cryptoCurrency.title.toString());
+    if (assetCredentials['id'] == null) return null;
+
+    log('DFX: Fetching $action quote: ${isBuyAction ? cryptoCurrency : fiatCurrency} -> ${isBuyAction ? fiatCurrency : cryptoCurrency}, amount: $amount, paymentMethod: $paymentMethod');
+
+    final url = Uri.https(_baseUrl, '/v1/$action/quote');
+    final headers = {'accept': 'application/json', 'Content-Type': 'application/json'};
+    final body = jsonEncode({
+      'currency': {'id': fiatCredentials['id'] as int},
+      'asset': {'id': assetCredentials['id']},
+      'amount': amount,
+      'targetAmount': 0,
+      'paymentMethod': paymentMethod,
+      'discountCode': ''
+    });
+
+    try {
+      final response = await http.put(url, headers: headers, body: body);
+      final responseData = jsonDecode(response.body);
+
+      if (response.statusCode == 200) {
+        if (responseData is Map<String, dynamic>) {
+          final paymentType = _getPaymentTypeByString(responseData['paymentMethod'] as String?);
+          final quote = Quote.fromDFXJson(responseData, isBuyAction, paymentType);
+          quote.setFiatCurrency = fiatCurrency;
+          quote.setCryptoCurrency = cryptoCurrency;
+          return [quote];
+        } else {
+          print('DFX: Unexpected data type: ${responseData.runtimeType}');
+          return null;
+        }
+      } else {
+        if (responseData is Map<String, dynamic> && responseData.containsKey('message')) {
+          print('DFX Error: ${responseData['message']}');
+        } else {
+          print('DFX Failed to fetch buy quote: ${response.statusCode}');
+        }
+        return null;
+      }
+    } catch (e) {
+      print('DFX Error fetching buy quote: $e');
+      return null;
+    }
+  }
+
+  Future<void>? launchProvider(
+      {required BuildContext context,
+      required Quote quote,
+      required double amount,
+      required bool isBuyAction,
+      required String cryptoCurrencyAddress,
+      String? countryCode}) async {
     if (wallet.isHardwareWallet) {
       if (!ledgerVM!.isConnected) {
         await Navigator.of(context).pushNamed(Routes.connectDevices,
@@ -152,26 +305,21 @@ class DFXBuyProvider extends BuyProvider {
     }
 
     try {
-      final assetOut = this.assetOut;
-      final blockchain = this.blockchain;
-      final actionType = isBuyAction == true ? '/buy' : '/sell';
+      final actionType = isBuyAction ? '/buy' : '/sell';
 
-      final accessToken = await auth();
+      final accessToken = await auth(cryptoCurrencyAddress);
 
       final uri = Uri.https('services.dfx.swiss', actionType, {
         'session': accessToken,
         'lang': 'en',
-        'asset-out': assetOut,
+        'asset-out': isBuyAction ? quote.cryptoCurrency.toString() : quote.fiatCurrency.toString(),
         'blockchain': blockchain,
-        'asset-in': 'EUR',
+        'asset-in': isBuyAction ? quote.fiatCurrency.toString() : quote.cryptoCurrency.toString(),
+        'amount': amount.toString() //TODO: Amount does not work
       });
 
       if (await canLaunchUrl(uri)) {
-        if (DeviceInfo.instance.isMobile) {
-          Navigator.of(context).pushNamed(Routes.webViewPage, arguments: [title, uri]);
-        } else {
-          await launchUrl(uri, mode: LaunchMode.externalApplication);
-        }
+        await launchUrl(uri, mode: LaunchMode.externalApplication);
       } else {
         throw Exception('Could not launch URL');
       }
@@ -187,4 +335,39 @@ class DFXBuyProvider extends BuyProvider {
           });
     }
   }
+
+  String? normalizePaymentMethod(PaymentType paymentMethod) {
+    switch (paymentMethod) {
+      case PaymentType.bankTransfer:
+        return 'Bank';
+      case PaymentType.creditCard:
+        return 'Card';
+      case PaymentType.sepa:
+        return 'Instant';
+      default:
+        return null;
+    }
+  }
+
+  PaymentType _getPaymentTypeByString(String? paymentMethod) {
+    switch (paymentMethod) {
+      case 'Bank':
+        return PaymentType.bankTransfer;
+      case 'Card':
+        return PaymentType.creditCard;
+      case 'Instant':
+        return PaymentType.sepa;
+      default:
+        return PaymentType.all;
+    }
+  }
+
+  double? _toDouble(dynamic value) {
+    if (value is int) {
+      return value.toDouble();
+    } else if (value is double) {
+      return value;
+    }
+    return null;
+  }
 }
diff --git a/lib/buy/meld/meld_buy_provider.dart b/lib/buy/meld/meld_buy_provider.dart
new file mode 100644
index 000000000..696301f2e
--- /dev/null
+++ b/lib/buy/meld/meld_buy_provider.dart
@@ -0,0 +1,266 @@
+import 'dart:convert';
+
+import 'package:cake_wallet/.secrets.g.dart' as secrets;
+import 'package:cake_wallet/buy/buy_provider.dart';
+import 'package:cake_wallet/buy/buy_quote.dart';
+import 'package:cake_wallet/buy/payment_method.dart';
+import 'package:cake_wallet/entities/fiat_currency.dart';
+import 'package:cake_wallet/entities/provider_types.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/routes.dart';
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
+import 'package:cake_wallet/utils/device_info.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/currency.dart';
+import 'package:cw_core/wallet_base.dart';
+import 'package:flutter/material.dart';
+import 'dart:developer';
+import 'package:http/http.dart' as http;
+import 'package:url_launcher/url_launcher.dart';
+
+class MeldBuyProvider extends BuyProvider {
+  MeldBuyProvider({required WalletBase wallet, bool isTestEnvironment = false})
+      : super(wallet: wallet, isTestEnvironment: isTestEnvironment, ledgerVM: null);
+
+  static const _isProduction = false;
+
+  static const _baseUrl = _isProduction ? 'api.meld.io' : 'api-sb.meld.io';
+  static const _providersProperties = '/service-providers/properties';
+  static const _paymentMethodsPath = '/payment-methods';
+  static const _quotePath = '/payments/crypto/quote';
+
+  static const String sandboxUrl = 'sb.fluidmoney.xyz';
+  static const String productionUrl = 'fluidmoney.xyz';
+
+  static const String _baseWidgetUrl = _isProduction ? productionUrl : sandboxUrl;
+
+  static String get _testApiKey => secrets.meldTestApiKey;
+
+  static String get _testPublicKey => '' ; //secrets.meldTestPublicKey;
+
+  @override
+  String get title => 'Meld';
+
+  @override
+  String get providerDescription => 'Meld Buy Provider';
+
+  @override
+  String get lightIcon => 'assets/images/meld_logo.svg';
+
+  @override
+  String get darkIcon => 'assets/images/meld_logo.svg';
+
+  @override
+  bool get isAggregator => true;
+
+  @override
+  Future<List<PaymentMethod>> getAvailablePaymentTypes(
+      String fiatCurrency, String cryptoCurrency, bool isBuyAction) async {
+    final params = {'fiatCurrencies': fiatCurrency, 'statuses': 'LIVE,RECENTLY_ADDED,BUILDING'};
+
+    final path = '$_providersProperties$_paymentMethodsPath';
+    final url = Uri.https(_baseUrl, path, params);
+
+    try {
+      final response = await http.get(
+        url,
+        headers: {
+          'Authorization': _isProduction ? '' : _testApiKey,
+          'Meld-Version': '2023-12-19',
+          'accept': 'application/json',
+          'content-type': 'application/json',
+        },
+      );
+
+      if (response.statusCode == 200) {
+        final data = jsonDecode(response.body) as List<dynamic>;
+        final paymentMethods =
+            data.map((e) => PaymentMethod.fromMeldJson(e as Map<String, dynamic>)).toList();
+        return paymentMethods;
+      } else {
+        print('Meld: Failed to fetch payment types');
+        return List<PaymentMethod>.empty();
+      }
+    } catch (e) {
+      print('Meld: Failed to fetch payment types: $e');
+      return List<PaymentMethod>.empty();
+    }
+  }
+
+  @override
+  Future<List<Quote>?> fetchQuote(
+      {required CryptoCurrency cryptoCurrency,
+        required FiatCurrency fiatCurrency,
+        required double amount,
+        required bool isBuyAction,
+        required String walletAddress,
+        PaymentType? paymentType,
+        String? countryCode}) async {
+    String? paymentMethod;
+    if (paymentType != null && paymentType != PaymentType.all) {
+      paymentMethod = normalizePaymentMethod(paymentType);
+      if (paymentMethod == null) paymentMethod = paymentType.name;
+    }
+
+    log('Meld: Fetching buy quote: ${isBuyAction ? cryptoCurrency : fiatCurrency} -> ${isBuyAction ? fiatCurrency : cryptoCurrency}, amount: $amount');
+
+    final url = Uri.https(_baseUrl, _quotePath);
+    final headers = {
+      'Authorization': _testApiKey,
+      'Meld-Version': '2023-12-19',
+      'accept': 'application/json',
+      'content-type': 'application/json',
+    };
+    final body = jsonEncode({
+      'countryCode': countryCode,
+      'destinationCurrencyCode': isBuyAction ? fiatCurrency.name : cryptoCurrency.title,
+      'sourceAmount': amount,
+      'sourceCurrencyCode': isBuyAction ? cryptoCurrency.title : fiatCurrency.name,
+      if (paymentMethod != null) 'paymentMethod': paymentMethod,
+    });
+
+    try {
+      final response = await http.post(url, headers: headers, body: body);
+
+      if (response.statusCode == 200) {
+        final data = jsonDecode(response.body) as Map<String, dynamic>;
+        final paymentType = _getPaymentTypeByString(data['paymentMethodType'] as String?);
+        final quote = Quote.fromMeldJson(data, isBuyAction, paymentType);
+
+        quote.setFiatCurrency = fiatCurrency;
+        quote.setCryptoCurrency = cryptoCurrency;
+
+        return [quote];
+      } else {
+        return null;
+      }
+    } catch (e) {
+      print('Error fetching buy quote: $e');
+      return null;
+    }
+  }
+
+  Future<void>? launchProvider(
+      {required BuildContext context,
+      required Quote quote,
+      required double amount,
+      required bool isBuyAction,
+      required String cryptoCurrencyAddress,
+      String? countryCode}) async {
+    final actionType = isBuyAction ? 'BUY' : 'SELL';
+
+    final params = {
+      'publicKey': _isProduction ? '' : _testPublicKey,
+      'countryCode': countryCode,
+      //'paymentMethodType': normalizePaymentMethod(paymentMethod.paymentMethodType),
+      'sourceAmount': amount.toString(),
+      'sourceCurrencyCode': quote.fiatCurrency,
+      'destinationCurrencyCode': quote.cryptoCurrency,
+      'walletAddress': cryptoCurrencyAddress,
+      'transactionType': actionType
+    };
+
+    final uri = Uri.https(_baseWidgetUrl, '', params);
+
+    try {
+      if (await canLaunchUrl(uri)) {
+        await launchUrl(uri, mode: LaunchMode.externalApplication);
+      } else {
+        throw Exception('Could not launch URL');
+      }
+    } catch (e) {
+      await showPopUp<void>(
+          context: context,
+          builder: (BuildContext context) {
+            return AlertWithOneAction(
+                alertTitle: "Meld",
+                alertContent: S.of(context).buy_provider_unavailable + ': $e',
+                buttonText: S.of(context).ok,
+                buttonAction: () => Navigator.of(context).pop());
+          });
+    }
+  }
+
+  String? normalizePaymentMethod(PaymentType paymentType) {
+    switch (paymentType) {
+      case PaymentType.creditCard:
+        return 'CREDIT_DEBIT_CARD';
+      case PaymentType.applePay:
+        return 'APPLE_PAY';
+      case PaymentType.googlePay:
+        return 'GOOGLE_PAY';
+      case PaymentType.neteller:
+        return 'NETELLER';
+      case PaymentType.skrill:
+        return 'SKRILL';
+      case PaymentType.sepa:
+        return 'SEPA';
+      case PaymentType.sepaInstant:
+        return 'SEPA_INSTANT';
+      case PaymentType.ach:
+        return 'ACH';
+      case PaymentType.achInstant:
+        return 'INSTANT_ACH';
+      case PaymentType.Khipu:
+        return 'KHIPU';
+      case PaymentType.ovo:
+        return 'OVO';
+      case PaymentType.zaloPay:
+        return 'ZALOPAY';
+      case PaymentType.zaloBankTransfer:
+        return 'ZA_BANK_TRANSFER';
+      case PaymentType.gcash:
+        return 'GCASH';
+      case PaymentType.imps:
+        return 'IMPS';
+      case PaymentType.dana:
+        return 'DANA';
+      case PaymentType.ideal:
+        return 'IDEAL';
+      default:
+        return null;
+    }
+  }
+
+  PaymentType _getPaymentTypeByString(String? paymentMethod) {
+    switch (paymentMethod?.toUpperCase()) {
+      case 'CREDIT_DEBIT_CARD':
+        return PaymentType.creditCard;
+      case 'APPLE_PAY':
+        return PaymentType.applePay;
+      case 'GOOGLE_PAY':
+        return PaymentType.googlePay;
+      case 'NETELLER':
+        return PaymentType.neteller;
+      case 'SKRILL':
+        return PaymentType.skrill;
+      case 'SEPA':
+        return PaymentType.sepa;
+      case 'SEPA_INSTANT':
+        return PaymentType.sepaInstant;
+      case 'ACH':
+        return PaymentType.ach;
+      case 'INSTANT_ACH':
+        return PaymentType.achInstant;
+      case 'KHIPU':
+        return PaymentType.Khipu;
+      case 'OVO':
+        return PaymentType.ovo;
+      case 'ZALOPAY':
+        return PaymentType.zaloPay;
+      case 'ZA_BANK_TRANSFER':
+        return PaymentType.zaloBankTransfer;
+      case 'GCASH':
+        return PaymentType.gcash;
+      case 'IMPS':
+        return PaymentType.imps;
+      case 'DANA':
+        return PaymentType.dana;
+      case 'IDEAL':
+        return PaymentType.ideal;
+      default:
+        return PaymentType.all;
+    }
+  }
+}
diff --git a/lib/buy/moonpay/moonpay_provider.dart b/lib/buy/moonpay/moonpay_provider.dart
index 67ee75d7c..b93c0f02d 100644
--- a/lib/buy/moonpay/moonpay_provider.dart
+++ b/lib/buy/moonpay/moonpay_provider.dart
@@ -1,19 +1,20 @@
 import 'dart:convert';
+import 'dart:developer';
 
 import 'package:cake_wallet/.secrets.g.dart' as secrets;
-import 'package:cake_wallet/buy/buy_amount.dart';
 import 'package:cake_wallet/buy/buy_exception.dart';
 import 'package:cake_wallet/buy/buy_provider.dart';
 import 'package:cake_wallet/buy/buy_provider_description.dart';
+import 'package:cake_wallet/buy/buy_quote.dart';
 import 'package:cake_wallet/buy/order.dart';
+import 'package:cake_wallet/buy/payment_method.dart';
+import 'package:cake_wallet/entities/fiat_currency.dart';
 import 'package:cake_wallet/exchange/trade_state.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/palette.dart';
-import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
 import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/themes/theme_base.dart';
-import 'package:cake_wallet/utils/device_info.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -39,6 +40,15 @@ class MoonPayProvider extends BuyProvider {
   static const _baseBuyProductUrl = 'buy.moonpay.com';
   static const _cIdBaseUrl = 'exchange-helper.cakewallet.com';
   static const _apiUrl = 'https://api.moonpay.com';
+  static const _baseUrl = 'api.moonpay.com';
+  static const _currenciesPath = '/v3/currencies';
+  static const _buyQuote = '/buy_quote';
+  static const _sellQuote = '/sell_quote';
+
+  static const _transactionsSuffix = '/v1/transactions';
+
+  final String baseBuyUrl;
+  final String baseSellUrl;
 
   @override
   String get providerDescription =>
@@ -53,6 +63,17 @@ class MoonPayProvider extends BuyProvider {
   @override
   String get darkIcon => 'assets/images/moonpay_dark.png';
 
+  @override
+  bool get isAggregator => false;
+
+  static String get _apiKey => secrets.moonPayApiKey;
+
+  String get currencyCode => walletTypeToCryptoCurrency(wallet.type).title.toLowerCase();
+
+  String get trackUrl => baseBuyUrl + '/transaction_receipt?transactionId=';
+
+  static String get _exchangeHelperApiKey => secrets.exchangeHelperApiKey;
+
   static String themeToMoonPayTheme(ThemeBase theme) {
     switch (theme.type) {
       case ThemeType.bright:
@@ -63,28 +84,12 @@ class MoonPayProvider extends BuyProvider {
     }
   }
 
-  static String get _apiKey => secrets.moonPayApiKey;
-
-  final String baseBuyUrl;
-  final String baseSellUrl;
-
-  String get currencyCode => walletTypeToCryptoCurrency(wallet.type).title.toLowerCase();
-
-  String get trackUrl => baseBuyUrl + '/transaction_receipt?transactionId=';
-
-  static String get _exchangeHelperApiKey => secrets.exchangeHelperApiKey;
-
   Future<String> getMoonpaySignature(String query) async {
     final uri = Uri.https(_cIdBaseUrl, "/api/moonpay");
 
-    final response = await post(
-      uri,
-      headers: {
-        'Content-Type': 'application/json',
-        'x-api-key': _exchangeHelperApiKey,
-      },
-      body: json.encode({'query': query}),
-    );
+    final response = await post(uri,
+        headers: {'Content-Type': 'application/json', 'x-api-key': _exchangeHelperApiKey},
+        body: json.encode({'query': query}));
 
     if (response.statusCode == 200) {
       return (jsonDecode(response.body) as Map<String, dynamic>)['signature'] as String;
@@ -94,85 +99,195 @@ class MoonPayProvider extends BuyProvider {
     }
   }
 
-  Future<Uri> requestSellMoonPayUrl({
-    required CryptoCurrency currency,
-    required String refundWalletAddress,
-    required SettingsStore settingsStore,
-  }) async {
-    final params = {
-      'theme': themeToMoonPayTheme(settingsStore.currentTheme),
-      'language': settingsStore.languageCode,
-      'colorCode': settingsStore.currentTheme.type == ThemeType.dark
-          ? '#${Palette.blueCraiola.value.toRadixString(16).substring(2, 8)}'
-          : '#${Palette.moderateSlateBlue.value.toRadixString(16).substring(2, 8)}',
-      'defaultCurrencyCode': _normalizeCurrency(currency),
-      'refundWalletAddress': refundWalletAddress,
-    };
+  Future<Map<String, dynamic>> fetchFiatCredentials(
+      String fiatCurrency, String cryptocurrency, String? paymentMethod) async {
+    final params = {'baseCurrencyCode': fiatCurrency.toLowerCase(), 'apiKey': _apiKey};
 
-    if (_apiKey.isNotEmpty) {
-      params['apiKey'] = _apiKey;
+    if (paymentMethod != null) params['paymentMethod'] = paymentMethod;
+
+    final path = '$_currenciesPath/${cryptocurrency.toLowerCase()}/limits';
+    final url = Uri.https(_baseUrl, path, params);
+
+    try {
+      final response = await get(url, headers: {'accept': 'application/json'});
+      if (response.statusCode == 200) {
+        return jsonDecode(response.body) as Map<String, dynamic>;
+      } else {
+        print('MoonPay does not support fiat: $fiatCurrency');
+        return {};
+      }
+    } catch (e) {
+      print('MoonPay Error fetching fiat currencies: $e');
+      return {};
     }
-
-    final originalUri = Uri.https(
-      baseSellUrl,
-      '',
-      params,
-    );
-
-    if (isTestEnvironment) {
-      return originalUri;
-    }
-
-    final signature = await getMoonpaySignature('?${originalUri.query}');
-
-    final query = Map<String, dynamic>.from(originalUri.queryParameters);
-    query['signature'] = signature;
-    final signedUri = originalUri.replace(queryParameters: query);
-    return signedUri;
   }
 
-  // BUY:
-  static const _currenciesSuffix = '/v3/currencies';
-  static const _quoteSuffix = '/buy_quote';
-  static const _transactionsSuffix = '/v1/transactions';
-  static const _ipAddressSuffix = '/v4/ip_address';
+  Future<List<PaymentMethod>> getAvailablePaymentTypes(
+      String fiatCurrency, String cryptoCurrency, bool isBuyAction) async {
+    final List<PaymentMethod> paymentMethods = [];
+
+    if (isBuyAction) {
+      final fiatBuyCredentials = await fetchFiatCredentials(fiatCurrency, cryptoCurrency, null);
+      if (fiatBuyCredentials.isNotEmpty) {
+        final paymentMethod = fiatBuyCredentials['paymentMethod'] as String?;
+        paymentMethods.add(PaymentMethod.fromMoonPayJson(
+            fiatBuyCredentials, _getPaymentTypeByString(paymentMethod)));
+        return paymentMethods;
+      }
+    }
+
+    return paymentMethods;
+  }
+
+  @override
+  Future<List<Quote>?> fetchQuote(
+      {required CryptoCurrency cryptoCurrency,
+      required FiatCurrency fiatCurrency,
+      required double amount,
+      required bool isBuyAction,
+      required String walletAddress,
+      PaymentType? paymentType,
+      String? countryCode}) async {
+    String? paymentMethod;
+
+    if (paymentType != null && paymentType != PaymentType.all) {
+      paymentMethod = normalizePaymentMethod(paymentType);
+      if (paymentMethod == null) paymentMethod = paymentType.name;
+    } else {
+      paymentMethod = 'credit_debit_card';
+    }
+
+    final action = isBuyAction ? 'buy' : 'sell';
+
+    final formattedCryptoCurrency = _normalizeCurrency(cryptoCurrency);
+    final baseCurrencyCode =
+        isBuyAction ? fiatCurrency.name.toLowerCase() : cryptoCurrency.title.toLowerCase();
 
-  Future<Uri> requestBuyMoonPayUrl({
-    required CryptoCurrency currency,
-    required SettingsStore settingsStore,
-    required String walletAddress,
-    String? amount,
-  }) async {
     final params = {
-      'theme': themeToMoonPayTheme(settingsStore.currentTheme),
-      'language': settingsStore.languageCode,
-      'colorCode': settingsStore.currentTheme.type == ThemeType.dark
+      'baseCurrencyCode': baseCurrencyCode,
+      'baseCurrencyAmount': amount.toString(),
+      'amount': amount.toString(),
+      'paymentMethod': paymentMethod,
+      'areFeesIncluded': 'false',
+      'apiKey': _apiKey
+    };
+
+    log('MoonPay: Fetching $action quote: ${isBuyAction ? formattedCryptoCurrency : fiatCurrency.name.toLowerCase()} -> ${isBuyAction ? baseCurrencyCode : formattedCryptoCurrency}, amount: $amount, paymentMethod: $paymentMethod');
+
+    final quotePath = isBuyAction ? _buyQuote : _sellQuote;
+
+    final path = '$_currenciesPath/$formattedCryptoCurrency$quotePath';
+    final url = Uri.https(_baseUrl, path, params);
+    try {
+      final response = await get(url);
+
+      if (response.statusCode == 200) {
+        final data = jsonDecode(response.body) as Map<String, dynamic>;
+
+        // Check if the response is for the correct fiat currency
+        if (isBuyAction) {
+          final fiatCurrencyCode = data['baseCurrencyCode'] as String?;
+          if (fiatCurrencyCode == null || fiatCurrencyCode != fiatCurrency.name.toLowerCase())
+            return null;
+        } else {
+          final quoteCurrency = data['quoteCurrency'] as Map<String, dynamic>?;
+          if (quoteCurrency == null || quoteCurrency['code'] != fiatCurrency.name.toLowerCase())
+            return null;
+        }
+
+        final paymentMethods = data['paymentMethod'] as String?;
+        final quote =
+            Quote.fromMoonPayJson(data, isBuyAction, _getPaymentTypeByString(paymentMethods));
+
+        quote.setFiatCurrency = fiatCurrency;
+        quote.setCryptoCurrency = cryptoCurrency;
+
+        return [quote];
+      } else {
+        print('Moon Pay: Error fetching buy quote: ');
+        return null;
+      }
+    } catch (e) {
+      print('Moon Pay: Error fetching buy quote: $e');
+      return null;
+    }
+  }
+
+  @override
+  Future<void>? launchProvider(
+      {required BuildContext context,
+      required Quote quote,
+      required double amount,
+      required bool isBuyAction,
+      required String cryptoCurrencyAddress,
+      String? countryCode}) async {
+
+    final Map<String, String> params = {
+      'theme': themeToMoonPayTheme(_settingsStore.currentTheme),
+      'language': _settingsStore.languageCode,
+      'colorCode': _settingsStore.currentTheme.type == ThemeType.dark
           ? '#${Palette.blueCraiola.value.toRadixString(16).substring(2, 8)}'
           : '#${Palette.moderateSlateBlue.value.toRadixString(16).substring(2, 8)}',
-      'baseCurrencyCode': settingsStore.fiatCurrency.title,
-      'baseCurrencyAmount': amount ?? '0',
-      'currencyCode': _normalizeCurrency(currency),
-      'walletAddress': walletAddress,
+      'baseCurrencyCode': isBuyAction ? quote.fiatCurrency.name : quote.cryptoCurrency.name,
+      'baseCurrencyAmount': amount.toString(),
+      'walletAddress': cryptoCurrencyAddress,
       'lockAmount': 'false',
       'showAllCurrencies': 'false',
       'showWalletAddressForm': 'false',
-      'enabledPaymentMethods':
-          'credit_debit_card,apple_pay,google_pay,samsung_pay,sepa_bank_transfer,gbp_bank_transfer,gbp_open_banking_payment',
+      if (isBuyAction)
+        'enabledPaymentMethods': normalizePaymentMethod(quote.paymentType) ??
+            'credit_debit_card,apple_pay,google_pay,samsung_pay,sepa_bank_transfer,gbp_bank_transfer,gbp_open_banking_payment',
+      if (!isBuyAction) 'refundWalletAddress': cryptoCurrencyAddress
     };
 
-    if (_apiKey.isNotEmpty) {
-      params['apiKey'] = _apiKey;
-    }
+    if (isBuyAction) params['currencyCode'] = quote.cryptoCurrency.name;
+    if (!isBuyAction) params['quoteCurrencyCode'] = quote.cryptoCurrency.name;
 
-    final originalUri = Uri.https(
-      baseBuyUrl,
-      '',
-      params,
-    );
+    try {
+      {
+        final uri = await requestMoonPayUrl(
+            walletAddress: cryptoCurrencyAddress,
+            settingsStore: _settingsStore,
+            isBuyAction: isBuyAction,
+            amount: amount.toString(),
+            params: params);
 
-    if (isTestEnvironment) {
-      return originalUri;
+        if (await canLaunchUrl(uri)) {
+          await launchUrl(uri, mode: LaunchMode.externalApplication);
+        } else {
+          throw Exception('Could not launch URL');
+        }
+      }
+    } catch (e) {
+      if (context.mounted) {
+        await showDialog<void>(
+          context: context,
+          builder: (BuildContext context) {
+            return AlertWithOneAction(
+              alertTitle: 'MoonPay',
+              alertContent: 'The MoonPay service is currently unavailable: $e',
+              buttonText: S.of(context).ok,
+              buttonAction: () => Navigator.of(context).pop(),
+            );
+          },
+        );
+      }
     }
+  }
+
+  Future<Uri> requestMoonPayUrl({
+    required String walletAddress,
+    required SettingsStore settingsStore,
+    required bool isBuyAction,
+    required Map<String, String> params,
+    String? amount,
+  }) async {
+    if (_apiKey.isNotEmpty) params['apiKey'] = _apiKey;
+
+    final baseUrl = isBuyAction ? baseBuyUrl : baseSellUrl;
+    final originalUri = Uri.https(baseUrl, '', params);
+
+    if (isTestEnvironment) return originalUri;
 
     final signature = await getMoonpaySignature('?${originalUri.query}');
     final query = Map<String, dynamic>.from(originalUri.queryParameters);
@@ -181,33 +296,6 @@ class MoonPayProvider extends BuyProvider {
     return signedUri;
   }
 
-  Future<BuyAmount> calculateAmount(String amount, String sourceCurrency) async {
-    final url = _apiUrl +
-        _currenciesSuffix +
-        '/$currencyCode' +
-        _quoteSuffix +
-        '/?apiKey=' +
-        _apiKey +
-        '&baseCurrencyAmount=' +
-        amount +
-        '&baseCurrencyCode=' +
-        sourceCurrency.toLowerCase();
-    final uri = Uri.parse(url);
-    final response = await get(uri);
-
-    if (response.statusCode != 200) {
-      throw BuyException(title: providerDescription, content: 'Quote is not found!');
-    }
-
-    final responseJSON = json.decode(response.body) as Map<String, dynamic>;
-    final sourceAmount = responseJSON['totalAmount'] as double;
-    final destAmount = responseJSON['quoteCurrencyAmount'] as double;
-    final minSourceAmount = responseJSON['baseCurrency']['minAmount'] as int;
-
-    return BuyAmount(
-        sourceAmount: sourceAmount, destAmount: destAmount, minAmount: minSourceAmount);
-  }
-
   Future<Order> findOrderById(String id) async {
     final url = _apiUrl + _transactionsSuffix + '/$id' + '?apiKey=' + _apiKey;
     final uri = Uri.parse(url);
@@ -235,74 +323,83 @@ class MoonPayProvider extends BuyProvider {
         walletId: wallet.id);
   }
 
-  static Future<bool> onEnabled() async {
-    final url = _apiUrl + _ipAddressSuffix + '?apiKey=' + _apiKey;
-    var isBuyEnable = false;
-    final uri = Uri.parse(url);
-    final response = await get(uri);
-
-    try {
-      final responseJSON = json.decode(response.body) as Map<String, dynamic>;
-      isBuyEnable = responseJSON['isBuyAllowed'] as bool;
-    } catch (e) {
-      isBuyEnable = false;
-      print(e.toString());
-    }
-
-    return isBuyEnable;
-  }
-
-  @override
-  Future<void> launchProvider(BuildContext context, bool? isBuyAction) async {
-    try {
-      late final Uri uri;
-      if (isBuyAction ?? true) {
-        uri = await requestBuyMoonPayUrl(
-          currency: wallet.currency,
-          walletAddress: wallet.walletAddresses.address,
-          settingsStore: _settingsStore,
-        );
-      } else {
-        uri = await requestSellMoonPayUrl(
-          currency: wallet.currency,
-          refundWalletAddress: wallet.walletAddresses.address,
-          settingsStore: _settingsStore,
-        );
-      }
-
-      if (await canLaunchUrl(uri)) {
-        if (DeviceInfo.instance.isMobile) {
-          Navigator.of(context).pushNamed(Routes.webViewPage, arguments: ['MoonPay', uri]);
-        } else {
-          await launchUrl(uri, mode: LaunchMode.externalApplication);
-        }
-      } else {
-        throw Exception('Could not launch URL');
-      }
-    } catch (e) {
-      if (context.mounted) {
-        await showDialog<void>(
-          context: context,
-          builder: (BuildContext context) {
-            return AlertWithOneAction(
-              alertTitle: 'MoonPay',
-              alertContent: 'The MoonPay service is currently unavailable: $e',
-              buttonText: S.of(context).ok,
-              buttonAction: () => Navigator.of(context).pop(),
-            );
-          },
-        );
-      }
-    }
-  }
-
   String _normalizeCurrency(CryptoCurrency currency) {
-    if (currency == CryptoCurrency.maticpoly) {
-      return "POL_POLYGON";
-    } else if (currency == CryptoCurrency.matic) {
-      return "POL";
+    if (currency.tag == 'POLY') {
+      return '${currency.title.toLowerCase()}_polygon';
+    }
+
+    if (currency.tag == 'TRX') {
+      return '${currency.title.toLowerCase()}_trx';
     }
 
     return currency.toString().toLowerCase();
   }
+
+  String? normalizePaymentMethod(PaymentType paymentMethod) {
+    switch (paymentMethod) {
+      case PaymentType.creditCard:
+        return 'credit_debit_card';
+      case PaymentType.debitCard:
+        return 'credit_debit_card';
+      case PaymentType.ach:
+        return 'ach_bank_transfer';
+      case PaymentType.applePay:
+        return 'apple_pay';
+      case PaymentType.googlePay:
+        return 'google_pay';
+      case PaymentType.sepa:
+        return 'sepa_bank_transfer';
+      case PaymentType.paypal:
+        return 'paypal';
+      case PaymentType.sepaOpenBankingPayment:
+        return 'sepa_open_banking_payment';
+      case PaymentType.gbpOpenBankingPayment:
+        return 'gbp_open_banking_payment';
+      case PaymentType.lowCostAch:
+        return 'low_cost_ach';
+      case PaymentType.mobileWallet:
+        return 'mobile_wallet';
+      case PaymentType.pixInstantPayment:
+        return 'pix_instant_payment';
+      case PaymentType.yellowCardBankTransfer:
+        return 'yellow_card_bank_transfer';
+      case PaymentType.fiatBalance:
+        return 'fiat_balance';
+      default:
+        return null;
+    }
+  }
+
+  PaymentType _getPaymentTypeByString(String? paymentMethod) {
+    switch (paymentMethod) {
+      case 'ach_bank_transfer':
+        return PaymentType.ach;
+      case 'apple_pay':
+        return PaymentType.applePay;
+      case 'credit_debit_card':
+        return PaymentType.creditCard;
+      case 'fiat_balance':
+        return PaymentType.fiatBalance;
+      case 'gbp_open_banking_payment':
+        return PaymentType.gbpOpenBankingPayment;
+      case 'google_pay':
+        return PaymentType.googlePay;
+      case 'low_cost_ach':
+        return PaymentType.lowCostAch;
+      case 'mobile_wallet':
+        return PaymentType.mobileWallet;
+      case 'paypal':
+        return PaymentType.paypal;
+      case 'pix_instant_payment':
+        return PaymentType.pixInstantPayment;
+      case 'sepa_bank_transfer':
+        return PaymentType.sepa;
+      case 'sepa_open_banking_payment':
+        return PaymentType.sepaOpenBankingPayment;
+      case 'yellow_card_bank_transfer':
+        return PaymentType.yellowCardBankTransfer;
+      default:
+        return PaymentType.all;
+    }
+  }
 }
diff --git a/lib/buy/onramper/onramper_buy_provider.dart b/lib/buy/onramper/onramper_buy_provider.dart
index 1f1c86962..ee9c9bb74 100644
--- a/lib/buy/onramper/onramper_buy_provider.dart
+++ b/lib/buy/onramper/onramper_buy_provider.dart
@@ -1,13 +1,19 @@
+import 'dart:convert';
+import 'dart:developer';
+
 import 'package:cake_wallet/.secrets.g.dart' as secrets;
 import 'package:cake_wallet/buy/buy_provider.dart';
+import 'package:cake_wallet/buy/buy_quote.dart';
+import 'package:cake_wallet/buy/payment_method.dart';
+import 'package:cake_wallet/entities/fiat_currency.dart';
 import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
-import 'package:cake_wallet/utils/device_info.dart';
 import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/currency.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:flutter/material.dart';
+import 'package:http/http.dart' as http;
 import 'package:url_launcher/url_launcher.dart';
 
 class OnRamperBuyProvider extends BuyProvider {
@@ -16,9 +22,15 @@ class OnRamperBuyProvider extends BuyProvider {
       : super(wallet: wallet, isTestEnvironment: isTestEnvironment, ledgerVM: null);
 
   static const _baseUrl = 'buy.onramper.com';
+  static const _baseApiUrl = 'api.onramper.com';
+  static const quotes = '/quotes';
+  static const paymentTypes = '/payment-types';
+  static const supported = '/supported';
 
   final SettingsStore _settingsStore;
 
+  String get _apiKey => secrets.onramperApiKey;
+
   @override
   String get title => 'Onramper';
 
@@ -31,74 +43,327 @@ class OnRamperBuyProvider extends BuyProvider {
   @override
   String get darkIcon => 'assets/images/onramper_dark.png';
 
-  String get _apiKey => secrets.onramperApiKey;
+  @override
+  bool get isAggregator => true;
 
-  String get _normalizeCryptoCurrency {
-    switch (wallet.currency) {
-      case CryptoCurrency.ltc:
-        return "LTC_LITECOIN";
-      case CryptoCurrency.xmr:
-        return "XMR_MONERO";
-      case CryptoCurrency.bch:
-        return "BCH_BITCOINCASH";
-      case CryptoCurrency.nano:
-        return "XNO_NANO";
-      default:
-        return wallet.currency.title;
+  Future<List<PaymentMethod>> getAvailablePaymentTypes(
+      String fiatCurrency, String cryptoCurrency, bool isBuyAction) async {
+    final params = {
+      'fiatCurrency': fiatCurrency,
+      'type': isBuyAction ? 'buy' : 'sell',
+      'isRecurringPayment': 'false'
+    };
+
+    final url = Uri.https(_baseApiUrl, '$supported$paymentTypes/$fiatCurrency', params);
+
+    try {
+      final response =
+          await http.get(url, headers: {'Authorization': _apiKey, 'accept': 'application/json'});
+
+      if (response.statusCode == 200) {
+        final Map<String, dynamic> data = jsonDecode(response.body) as Map<String, dynamic>;
+        final List<dynamic> message = data['message'] as List<dynamic>;
+        return message
+            .map((item) => PaymentMethod.fromOnramperJson(item as Map<String, dynamic>))
+            .toList();
+      } else {
+        print('Failed to fetch available payment types');
+        return [];
+      }
+    } catch (e) {
+      print('Failed to fetch available payment types: $e');
+      return [];
     }
   }
 
-  String getColorStr(Color color) {
-    return color.value.toRadixString(16).replaceAll(RegExp(r'^ff'), "");
+  Future<Map<String, dynamic>> getOnrampMetadata() async {
+    final url = Uri.https(_baseApiUrl, '$supported/onramps/all');
+
+    try {
+      final response =
+          await http.get(url, headers: {'Authorization': _apiKey, 'accept': 'application/json'});
+
+      if (response.statusCode == 200) {
+        final Map<String, dynamic> data = jsonDecode(response.body) as Map<String, dynamic>;
+
+        final List<dynamic> onramps = data['message'] as List<dynamic>;
+
+        final Map<String, dynamic> result = {
+          for (var onramp in onramps)
+            (onramp['id'] as String): {
+              'displayName': onramp['displayName'] as String,
+              'svg': onramp['icons']['svg'] as String
+            }
+        };
+
+        return result;
+      } else {
+        print('Failed to fetch onramp metadata');
+        return {};
+      }
+    } catch (e) {
+      print('Error occurred: $e');
+      return {};
+    }
   }
 
-  Uri requestOnramperUrl(BuildContext context, bool? isBuyAction) {
-    String primaryColor,
-        secondaryColor,
-        primaryTextColor,
-        secondaryTextColor,
-        containerColor,
-        cardColor;
+  @override
+  Future<List<Quote>?> fetchQuote(
+      {required CryptoCurrency cryptoCurrency,
+      required FiatCurrency fiatCurrency,
+      required double amount,
+      required bool isBuyAction,
+      required String walletAddress,
+      PaymentType? paymentType,
+      String? countryCode}) async {
+    String? paymentMethod;
 
-    primaryColor = getColorStr(Theme.of(context).primaryColor);
-    secondaryColor = getColorStr(Theme.of(context).colorScheme.background);
-    primaryTextColor =
-        getColorStr(Theme.of(context).extension<CakeTextTheme>()!.titleColor);
-    secondaryTextColor = getColorStr(
-        Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor);
-    containerColor = getColorStr(Theme.of(context).colorScheme.background);
-    cardColor = getColorStr(Theme.of(context).cardColor);
+    if (paymentType != null && paymentType != PaymentType.all) {
+      paymentMethod = normalizePaymentMethod(paymentType);
+      if (paymentMethod == null) paymentMethod = paymentType.name;
+    }
+
+    final actionType = isBuyAction ? 'buy' : 'sell';
+
+    final normalizedCryptoCurrency = _getNormalizeCryptoCurrency(cryptoCurrency);
+
+    final params = {
+      'amount': amount.toString(),
+      if (paymentMethod != null) 'paymentMethod': paymentMethod,
+      'clientName': 'CakeWallet',
+      'type': actionType,
+      'walletAddress': walletAddress,
+      'isRecurringPayment': 'false',
+      'input': 'source',
+    };
+
+    log('Onramper: Fetching $actionType quote: ${isBuyAction ? normalizedCryptoCurrency : fiatCurrency.name} -> ${isBuyAction ? fiatCurrency.name : normalizedCryptoCurrency}, amount: $amount, paymentMethod: $paymentMethod');
+
+    final sourceCurrency = isBuyAction ? fiatCurrency.name : normalizedCryptoCurrency;
+    final destinationCurrency = isBuyAction ? normalizedCryptoCurrency : fiatCurrency.name;
+
+    final url = Uri.https(_baseApiUrl, '$quotes/${sourceCurrency}/${destinationCurrency}', params);
+    final headers = {'Authorization': _apiKey, 'accept': 'application/json'};
+
+    try {
+      final response = await http.get(url, headers: headers);
+
+      if (response.statusCode == 200) {
+        final data = jsonDecode(response.body) as List<dynamic>;
+        if (data.isEmpty) return null;
+
+        List<Quote> validQuotes = [];
+
+        final onrampMetadata = await getOnrampMetadata();
+
+        for (var item in data) {
+
+          if (item['errors'] != null) continue;
+
+          final paymentMethod = (item as Map<String, dynamic>)['paymentMethod'] as String;
+
+          final rampId = item['ramp'] as String?;
+          final rampMetaData = onrampMetadata[rampId] as Map<String, dynamic>?;
+
+          if (rampMetaData == null) continue;
+
+          final quote = Quote.fromOnramperJson(
+              item, isBuyAction, onrampMetadata, _getPaymentTypeByString(paymentMethod));
+          quote.setFiatCurrency = fiatCurrency;
+          quote.setCryptoCurrency = cryptoCurrency;
+          validQuotes.add(quote);
+        }
+
+        if (validQuotes.isEmpty) return null;
+
+        return validQuotes;
+      } else {
+        print('Onramper: Failed to fetch rate');
+        return null;
+      }
+    } catch (e) {
+      print('Onramper: Failed to fetch rate $e');
+      return null;
+    }
+  }
+
+  Future<void>? launchProvider(
+      {required BuildContext context,
+      required Quote quote,
+      required double amount,
+      required bool isBuyAction,
+      required String cryptoCurrencyAddress,
+      String? countryCode}) async {
+    final actionType = isBuyAction ? 'buy' : 'sell';
+    final prefix = actionType == 'sell' ? actionType + '_' : '';
+
+    final primaryColor = getColorStr(Theme.of(context).primaryColor);
+    final secondaryColor = getColorStr(Theme.of(context).colorScheme.background);
+    final primaryTextColor = getColorStr(Theme.of(context).extension<CakeTextTheme>()!.titleColor);
+    final secondaryTextColor =
+        getColorStr(Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor);
+    final containerColor = getColorStr(Theme.of(context).colorScheme.background);
+    var cardColor = getColorStr(Theme.of(context).cardColor);
 
     if (_settingsStore.currentTheme.title == S.current.high_contrast_theme) {
       cardColor = getColorStr(Colors.white);
     }
 
-    final networkName =
-        wallet.currency.fullName?.toUpperCase().replaceAll(" ", "");
+    final defaultCrypto = _getNormalizeCryptoCurrency(quote.cryptoCurrency);
 
-    return Uri.https(_baseUrl, '', <String, dynamic>{
+    final paymentMethod = normalizePaymentMethod(quote.paymentType);
+
+    final uri = Uri.https(_baseUrl, '', {
       'apiKey': _apiKey,
-      'defaultCrypto': _normalizeCryptoCurrency,
-      'sell_defaultCrypto': _normalizeCryptoCurrency,
-      'networkWallets': '${networkName}:${wallet.walletAddresses.address}',
+      'mode': actionType,
+      '${prefix}defaultFiat': quote.fiatCurrency.name,
+      '${prefix}defaultCrypto': quote.cryptoCurrency.name,
+      '${prefix}defaultAmount': amount.toString(),
+      if (paymentMethod != null) '${prefix}defaultPaymentMethod': paymentMethod,
+      'onlyOnramps': quote.rampId,
+      'networkWallets': '$defaultCrypto:$cryptoCurrencyAddress',
+      'walletAddress': cryptoCurrencyAddress,
       'supportSwap': "false",
       'primaryColor': primaryColor,
       'secondaryColor': secondaryColor,
+      'containerColor': containerColor,
       'primaryTextColor': primaryTextColor,
       'secondaryTextColor': secondaryTextColor,
-      'containerColor': containerColor,
       'cardColor': cardColor,
-      'mode': isBuyAction == true ? 'buy' : 'sell',
     });
-  }
 
-  Future<void> launchProvider(BuildContext context, bool? isBuyAction) async {
-    final uri = requestOnramperUrl(context, isBuyAction);
-    if (DeviceInfo.instance.isMobile) {
-      Navigator.of(context)
-          .pushNamed(Routes.webViewPage, arguments: [title, uri]);
+    if (await canLaunchUrl(uri)) {
+      await launchUrl(uri, mode: LaunchMode.externalApplication);
     } else {
-      await launchUrl(uri);
+      throw Exception('Could not launch URL');
     }
   }
+
+  List<CryptoCurrency> mainCurrency = [
+    CryptoCurrency.btc,
+    CryptoCurrency.eth,
+    CryptoCurrency.sol,
+  ];
+
+  String _tagToNetwork(String tag) {
+    switch (tag) {
+      case 'OMNI':
+        return tag;
+      case 'POL':
+        return 'POLYGON';
+      default:
+        return CryptoCurrency.fromString(tag).fullName ?? tag;
+    }
+  }
+
+  String _getNormalizeCryptoCurrency(Currency currency) {
+    if (currency is CryptoCurrency) {
+      if (!mainCurrency.contains(currency)) {
+        final network = currency.tag == null ? currency.fullName : _tagToNetwork(currency.tag!);
+        return '${currency.title}_${network?.replaceAll(' ', '')}'.toUpperCase();
+      }
+      return currency.title.toUpperCase();
+    }
+    return currency.name.toUpperCase();
+  }
+
+  String? normalizePaymentMethod(PaymentType paymentType) {
+    switch (paymentType) {
+      case PaymentType.bankTransfer:
+        return 'banktransfer';
+      case PaymentType.creditCard:
+        return 'creditcard';
+      case PaymentType.debitCard:
+        return 'debitcard';
+      case PaymentType.applePay:
+        return 'applepay';
+      case PaymentType.googlePay:
+        return 'googlepay';
+      case PaymentType.revolutPay:
+        return 'revolutpay';
+      case PaymentType.neteller:
+        return 'neteller';
+      case PaymentType.skrill:
+        return 'skrill';
+      case PaymentType.sepa:
+        return 'sepabanktransfer';
+      case PaymentType.sepaInstant:
+        return 'sepainstant';
+      case PaymentType.ach:
+        return 'ach';
+      case PaymentType.achInstant:
+        return 'iach';
+      case PaymentType.Khipu:
+        return 'khipu';
+      case PaymentType.palomaBanktTansfer:
+        return 'palomabanktransfer';
+      case PaymentType.ovo:
+        return 'ovo';
+      case PaymentType.zaloPay:
+        return 'zalopay';
+      case PaymentType.zaloBankTransfer:
+        return 'zalobanktransfer';
+      case PaymentType.gcash:
+        return 'gcash';
+      case PaymentType.imps:
+        return 'imps';
+      case PaymentType.dana:
+        return 'dana';
+      case PaymentType.ideal:
+        return 'ideal';
+      default:
+        return null;
+    }
+  }
+
+  PaymentType _getPaymentTypeByString(String paymentMethod) {
+    switch (paymentMethod.toLowerCase()) {
+      case 'banktransfer':
+        return PaymentType.bankTransfer;
+      case 'creditcard':
+        return PaymentType.creditCard;
+      case 'debitcard':
+        return PaymentType.debitCard;
+      case 'applepay':
+        return PaymentType.applePay;
+      case 'googlepay':
+        return PaymentType.googlePay;
+      case 'revolutpay':
+        return PaymentType.revolutPay;
+      case 'neteller':
+        return PaymentType.neteller;
+      case 'skrill':
+        return PaymentType.skrill;
+      case 'sepabanktransfer':
+        return PaymentType.sepa;
+      case 'sepainstant':
+        return PaymentType.sepaInstant;
+      case 'ach':
+        return PaymentType.ach;
+      case 'iach':
+        return PaymentType.achInstant;
+      case 'khipu':
+        return PaymentType.Khipu;
+      case 'palomabanktransfer':
+        return PaymentType.palomaBanktTansfer;
+      case 'ovo':
+        return PaymentType.ovo;
+      case 'zalopay':
+        return PaymentType.zaloPay;
+      case 'zalobanktransfer':
+        return PaymentType.zaloBankTransfer;
+      case 'gcash':
+        return PaymentType.gcash;
+      case 'imps':
+        return PaymentType.imps;
+      case 'dana':
+        return PaymentType.dana;
+      case 'ideal':
+        return PaymentType.ideal;
+      default:
+        return PaymentType.all;
+    }
+  }
+
+  String getColorStr(Color color) => color.value.toRadixString(16).replaceAll(RegExp(r'^ff'), "");
 }
diff --git a/lib/buy/payment_method.dart b/lib/buy/payment_method.dart
new file mode 100644
index 000000000..cf85c441b
--- /dev/null
+++ b/lib/buy/payment_method.dart
@@ -0,0 +1,287 @@
+import 'dart:ui';
+
+import 'package:cake_wallet/core/selectable_option.dart';
+
+enum PaymentType {
+  all,
+  bankTransfer,
+  creditCard,
+  debitCard,
+  applePay,
+  googlePay,
+  revolutPay,
+  neteller,
+  skrill,
+  sepa,
+  sepaInstant,
+  ach,
+  achInstant,
+  Khipu,
+  palomaBanktTansfer,
+  ovo,
+  zaloPay,
+  zaloBankTransfer,
+  gcash,
+  imps,
+  dana,
+  ideal,
+  paypal,
+  sepaOpenBankingPayment,
+  gbpOpenBankingPayment,
+  lowCostAch,
+  mobileWallet,
+  pixInstantPayment,
+  yellowCardBankTransfer,
+  fiatBalance,
+  bancontact,
+}
+
+extension PaymentTypeTitle on PaymentType {
+  String? get title {
+    switch (this) {
+      case PaymentType.all:
+        return 'All Payment Methods';
+      case PaymentType.bankTransfer:
+        return 'Bank Transfer';
+      case PaymentType.creditCard:
+        return 'Credit Card';
+      case PaymentType.debitCard:
+        return 'Debit Card';
+      case PaymentType.applePay:
+        return 'Apple Pay';
+      case PaymentType.googlePay:
+        return 'Google Pay';
+      case PaymentType.revolutPay:
+        return 'Revolut Pay';
+      case PaymentType.neteller:
+        return 'Neteller';
+      case PaymentType.skrill:
+        return 'Skrill';
+      case PaymentType.sepa:
+        return 'SEPA';
+      case PaymentType.sepaInstant:
+        return 'SEPA Instant';
+      case PaymentType.ach:
+        return 'ACH';
+      case PaymentType.achInstant:
+        return 'ACH Instant';
+      case PaymentType.Khipu:
+        return 'Khipu';
+      case PaymentType.palomaBanktTansfer:
+        return 'Paloma Bank Transfer';
+      case PaymentType.ovo:
+        return 'OVO';
+      case PaymentType.zaloPay:
+        return 'Zalo Pay';
+      case PaymentType.zaloBankTransfer:
+        return 'Zalo Bank Transfer';
+      case PaymentType.gcash:
+        return 'GCash';
+      case PaymentType.imps:
+        return 'IMPS';
+      case PaymentType.dana:
+        return 'DANA';
+      case PaymentType.ideal:
+        return 'iDEAL';
+      case PaymentType.paypal:
+        return 'PayPal';
+      case PaymentType.sepaOpenBankingPayment:
+        return 'SEPA Open Banking Payment';
+      case PaymentType.gbpOpenBankingPayment:
+        return 'GBP Open Banking Payment';
+      case PaymentType.lowCostAch:
+        return 'Low Cost ACH';
+      case PaymentType.mobileWallet:
+        return 'Mobile Wallet';
+      case PaymentType.pixInstantPayment:
+        return 'PIX Instant Payment';
+      case PaymentType.yellowCardBankTransfer:
+        return 'Yellow Card Bank Transfer';
+      case PaymentType.fiatBalance:
+        return 'Fiat Balance';
+      case PaymentType.bancontact:
+        return 'Bancontact';
+      default:
+        return null;
+    }
+  }
+
+  String? get lightIconPath {
+    switch (this) {
+      case PaymentType.all:
+        return 'assets/images/usd_round_light.svg';
+      case PaymentType.creditCard:
+      case PaymentType.debitCard:
+      case PaymentType.yellowCardBankTransfer:
+        return 'assets/images/card.svg';
+      case PaymentType.bankTransfer:
+        return 'assets/images/bank_light.svg';
+      case PaymentType.skrill:
+        return 'assets/images/skrill.svg';
+      case PaymentType.applePay:
+        return 'assets/images/apple_pay_round_light.svg';
+      default:
+        return null;
+    }
+  }
+
+  String? get darkIconPath {
+    switch (this) {
+      case PaymentType.all:
+        return 'assets/images/usd_round_dark.svg';
+      case PaymentType.creditCard:
+      case PaymentType.debitCard:
+      case PaymentType.yellowCardBankTransfer:
+        return 'assets/images/card_dark.svg';
+      case PaymentType.bankTransfer:
+        return 'assets/images/bank_dark.svg';
+      case PaymentType.skrill:
+        return 'assets/images/skrill.svg';
+      case PaymentType.applePay:
+        return 'assets/images/apple_pay_round_dark.svg';
+      default:
+        return null;
+    }
+  }
+
+  String? get description {
+    switch (this) {
+      default:
+        return null;
+    }
+  }
+}
+
+class PaymentMethod extends SelectableOption {
+  PaymentMethod({
+    required this.paymentMethodType,
+    required this.customTitle,
+    required this.customIconPath,
+    this.customDescription,
+  }) : super(title: paymentMethodType.title ?? customTitle);
+
+  final PaymentType paymentMethodType;
+  final String customTitle;
+  final String customIconPath;
+  final String? customDescription;
+  bool isSelected = false;
+
+  @override
+  String? get description => paymentMethodType.description ?? customDescription;
+
+  @override
+  String get lightIconPath => paymentMethodType.lightIconPath ?? customIconPath;
+
+  @override
+  String get darkIconPath => paymentMethodType.darkIconPath ?? customIconPath;
+
+  @override
+  bool get isOptionSelected => isSelected;
+
+  factory PaymentMethod.all() {
+    return PaymentMethod(
+        paymentMethodType: PaymentType.all,
+        customTitle: 'All Payment Methods',
+        customIconPath: 'assets/images/dollar_coin.svg');
+  }
+
+  factory PaymentMethod.fromOnramperJson(Map<String, dynamic> json) {
+    final type = PaymentMethod.getPaymentTypeId(json['paymentTypeId'] as String?);
+    return PaymentMethod(
+        paymentMethodType: type,
+        customTitle: json['name'] as String? ?? 'Unknown',
+        customIconPath: json['icon'] as String? ?? 'assets/images/card.png',
+        customDescription: json['description'] as String?);
+  }
+
+  factory PaymentMethod.fromDFX(String paymentMethod, PaymentType paymentType) {
+    return PaymentMethod(
+        paymentMethodType: paymentType,
+        customTitle: paymentMethod,
+        customIconPath: 'assets/images/card.png');
+  }
+
+  factory PaymentMethod.fromMoonPayJson(Map<String, dynamic> json, PaymentType paymentType) {
+    return PaymentMethod(
+        paymentMethodType: paymentType,
+        customTitle: json['paymentMethod'] as String,
+        customIconPath: 'assets/images/card.png');
+  }
+
+  factory PaymentMethod.fromMeldJson(Map<String, dynamic> json) {
+    final type = PaymentMethod.getPaymentTypeId(json['paymentMethod'] as String?);
+    final logos = json['logos'] as Map<String, dynamic>;
+    return PaymentMethod(
+        paymentMethodType: type,
+        customTitle: json['name'] as String? ?? 'Unknown',
+        customIconPath: logos['dark'] as String? ?? 'assets/images/card.png',
+        customDescription: json['description'] as String?);
+  }
+
+  static PaymentType getPaymentTypeId(String? type) {
+    switch (type?.toLowerCase()) {
+      case 'banktransfer':
+      case 'bank':
+      case 'yellow_card_bank_transfer':
+        return PaymentType.bankTransfer;
+      case 'creditcard':
+      case 'card':
+      case 'credit_debit_card':
+        return PaymentType.creditCard;
+      case 'debitcard':
+        return PaymentType.debitCard;
+      case 'applepay':
+      case 'apple_pay':
+        return PaymentType.applePay;
+      case 'googlepay':
+      case 'google_pay':
+        return PaymentType.googlePay;
+      case 'revolutpay':
+        return PaymentType.revolutPay;
+      case 'neteller':
+        return PaymentType.neteller;
+      case 'skrill':
+        return PaymentType.skrill;
+      case 'sepabanktransfer':
+      case 'sepa':
+      case 'sepa_bank_transfer':
+        return PaymentType.sepa;
+      case 'sepainstant':
+      case 'sepa_instant':
+        return PaymentType.sepaInstant;
+      case 'ach':
+      case 'ach_bank_transfer':
+        return PaymentType.ach;
+      case 'iach':
+      case 'instant_ach':
+        return PaymentType.achInstant;
+      case 'khipu':
+        return PaymentType.Khipu;
+      case 'palomabanktransfer':
+        return PaymentType.palomaBanktTansfer;
+      case 'ovo':
+        return PaymentType.ovo;
+      case 'zalopay':
+        return PaymentType.zaloPay;
+      case 'zalobanktransfer':
+      case 'za_bank_transfer':
+        return PaymentType.zaloBankTransfer;
+      case 'gcash':
+        return PaymentType.gcash;
+      case 'imps':
+        return PaymentType.imps;
+      case 'dana':
+        return PaymentType.dana;
+      case 'ideal':
+        return PaymentType.ideal;
+      case 'paypal':
+        return PaymentType.paypal;
+      case 'sepa_open_banking_payment':
+        return PaymentType.sepaOpenBankingPayment;
+      case 'bancontact':
+        return PaymentType.bancontact;
+      default:
+        return PaymentType.all;
+    }
+  }
+}
diff --git a/lib/buy/robinhood/robinhood_buy_provider.dart b/lib/buy/robinhood/robinhood_buy_provider.dart
index 2d809772e..e8de5a59c 100644
--- a/lib/buy/robinhood/robinhood_buy_provider.dart
+++ b/lib/buy/robinhood/robinhood_buy_provider.dart
@@ -1,13 +1,18 @@
 import 'dart:convert';
+import 'dart:developer';
 
 import 'package:cake_wallet/.secrets.g.dart' as secrets;
 import 'package:cake_wallet/buy/buy_provider.dart';
+import 'package:cake_wallet/buy/buy_quote.dart';
+import 'package:cake_wallet/buy/payment_method.dart';
+import 'package:cake_wallet/entities/fiat_currency.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart';
 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
+import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:flutter/material.dart';
@@ -15,7 +20,8 @@ import 'package:http/http.dart' as http;
 import 'package:url_launcher/url_launcher.dart';
 
 class RobinhoodBuyProvider extends BuyProvider {
-  RobinhoodBuyProvider({required WalletBase wallet, bool isTestEnvironment = false, LedgerViewModel? ledgerVM})
+  RobinhoodBuyProvider(
+      {required WalletBase wallet, bool isTestEnvironment = false, LedgerViewModel? ledgerVM})
       : super(wallet: wallet, isTestEnvironment: isTestEnvironment, ledgerVM: ledgerVM);
 
   static const _baseUrl = 'applink.robinhood.com';
@@ -33,6 +39,9 @@ class RobinhoodBuyProvider extends BuyProvider {
   @override
   String get darkIcon => 'assets/images/robinhood_dark.png';
 
+  @override
+  bool get isAggregator => false;
+
   String get _applicationId => secrets.robinhoodApplicationId;
 
   String get _apiSecret => secrets.exchangeHelperApiKey;
@@ -86,7 +95,13 @@ class RobinhoodBuyProvider extends BuyProvider {
     });
   }
 
-  Future<void> launchProvider(BuildContext context, bool? isBuyAction) async {
+  Future<void>? launchProvider(
+      {required BuildContext context,
+      required Quote quote,
+      required double amount,
+      required bool isBuyAction,
+      required String cryptoCurrencyAddress,
+      String? countryCode}) async {
     if (wallet.isHardwareWallet) {
       if (!ledgerVM!.isConnected) {
         await Navigator.of(context).pushNamed(Routes.connectDevices,
@@ -116,4 +131,87 @@ class RobinhoodBuyProvider extends BuyProvider {
           });
     }
   }
+
+  @override
+  Future<List<Quote>?> fetchQuote(
+      {required CryptoCurrency cryptoCurrency,
+      required FiatCurrency fiatCurrency,
+      required double amount,
+      required bool isBuyAction,
+      required String walletAddress,
+      PaymentType? paymentType,
+      String? countryCode}) async {
+    String? paymentMethod;
+
+    if (paymentType != null && paymentType != PaymentType.all) {
+      paymentMethod = normalizePaymentMethod(paymentType);
+      if (paymentMethod == null) paymentMethod = paymentType.name;
+    }
+
+    final action = isBuyAction ? 'buy' : 'sell';
+    log('Robinhood: Fetching $action quote: ${isBuyAction ? cryptoCurrency.title : fiatCurrency.name.toUpperCase()} -> ${isBuyAction ? fiatCurrency.name.toUpperCase() : cryptoCurrency.title}, amount: $amount paymentMethod: $paymentMethod');
+
+    final queryParams = {
+      'applicationId': _applicationId,
+      'fiatCode': fiatCurrency.name,
+      'assetCode': cryptoCurrency.title,
+      'fiatAmount': amount.toString(),
+      if (paymentMethod != null) 'paymentMethod': paymentMethod,
+    };
+
+    final uri =
+        Uri.https('api.robinhood.com', '/catpay/v1/${cryptoCurrency.title}/quote/', queryParams);
+
+    try {
+      final response = await http.get(uri, headers: {'accept': 'application/json'});
+      final responseData = jsonDecode(response.body) as Map<String, dynamic>;
+
+      if (response.statusCode == 200) {
+        final paymentType = _getPaymentTypeByString(responseData['paymentMethod'] as String?);
+        final quote = Quote.fromRobinhoodJson(responseData, isBuyAction, paymentType);
+        quote.setFiatCurrency = fiatCurrency;
+        quote.setCryptoCurrency = cryptoCurrency;
+        return [quote];
+      } else {
+        if (responseData.containsKey('message')) {
+          log('Robinhood Error: ${responseData['message']}');
+        } else {
+          print('Robinhood Failed to fetch $action quote: ${response.statusCode}');
+        }
+        return null;
+      }
+    } catch (e) {
+      log('Robinhood: Failed to fetch $action quote: $e');
+      return null;
+    }
+
+    // ● buying_power
+    // ● crypto_balance
+    // ● debit_card
+    // ● bank_transfer
+  }
+
+  String? normalizePaymentMethod(PaymentType paymentMethod) {
+    switch (paymentMethod) {
+      case PaymentType.creditCard:
+        return 'debit_card';
+      case PaymentType.debitCard:
+        return 'debit_card';
+      case PaymentType.bankTransfer:
+        return 'bank_transfer';
+      default:
+        return null;
+    }
+  }
+
+  PaymentType _getPaymentTypeByString(String? paymentMethod) {
+    switch (paymentMethod) {
+      case 'debit_card':
+        return PaymentType.debitCard;
+      case 'bank_transfer':
+        return PaymentType.bankTransfer;
+      default:
+        return PaymentType.all;
+    }
+  }
 }
diff --git a/lib/buy/sell_buy_states.dart b/lib/buy/sell_buy_states.dart
new file mode 100644
index 000000000..26ea20205
--- /dev/null
+++ b/lib/buy/sell_buy_states.dart
@@ -0,0 +1,20 @@
+abstract class PaymentMethodLoadingState {}
+
+class InitialPaymentMethod extends PaymentMethodLoadingState {}
+
+class PaymentMethodLoading extends PaymentMethodLoadingState {}
+
+class PaymentMethodLoaded extends PaymentMethodLoadingState {}
+
+class PaymentMethodFailed extends PaymentMethodLoadingState {}
+
+
+abstract class BuySellQuotLoadingState {}
+
+class InitialBuySellQuotState extends BuySellQuotLoadingState {}
+
+class BuySellQuotLoading extends BuySellQuotLoadingState {}
+
+class BuySellQuotLoaded extends BuySellQuotLoadingState {}
+
+class BuySellQuotFailed extends BuySellQuotLoadingState {}
\ No newline at end of file
diff --git a/lib/buy/wyre/wyre_buy_provider.dart b/lib/buy/wyre/wyre_buy_provider.dart
index e09186ad5..78b109ac0 100644
--- a/lib/buy/wyre/wyre_buy_provider.dart
+++ b/lib/buy/wyre/wyre_buy_provider.dart
@@ -42,6 +42,9 @@ class WyreBuyProvider extends BuyProvider {
   @override
   String get darkIcon => 'assets/images/robinhood_dark.png';
 
+  @override
+  bool get isAggregator => false;
+
   String get trackUrl => isTestEnvironment ? _trackTestUrl : _trackProductUrl;
 
   String baseApiUrl;
@@ -148,10 +151,4 @@ class WyreBuyProvider extends BuyProvider {
         receiveAddress: wallet.walletAddresses.address,
         walletId: wallet.id);
   }
-
-  @override
-  Future<void> launchProvider(BuildContext context, bool? isBuyAction) {
-    // TODO: implement launchProvider
-    throw UnimplementedError();
-  }
 }
diff --git a/lib/core/backup_service.dart b/lib/core/backup_service.dart
index d65530eb5..992ed6288 100644
--- a/lib/core/backup_service.dart
+++ b/lib/core/backup_service.dart
@@ -268,9 +268,7 @@ class BackupService {
     final currentFiatCurrency = data[PreferencesKey.currentFiatCurrencyKey] as String?;
     final shouldSaveRecipientAddress = data[PreferencesKey.shouldSaveRecipientAddressKey] as bool?;
     final isAppSecure = data[PreferencesKey.isAppSecureKey] as bool?;
-    final disableBuy = data[PreferencesKey.disableBuyKey] as bool?;
-    final disableSell = data[PreferencesKey.disableSellKey] as bool?;
-    final defaultBuyProvider = data[PreferencesKey.defaultBuyProvider] as int?;
+    final disableTradeOption = data[PreferencesKey.disableTradeOption] as bool?;
     final currentTransactionPriorityKeyLegacy =
         data[PreferencesKey.currentTransactionPriorityKeyLegacy] as int?;
     final currentBitcoinElectrumSererId =
@@ -323,14 +321,8 @@ class BackupService {
     if (isAppSecure != null)
       await _sharedPreferences.setBool(PreferencesKey.isAppSecureKey, isAppSecure);
 
-    if (disableBuy != null)
-      await _sharedPreferences.setBool(PreferencesKey.disableBuyKey, disableBuy);
-
-    if (disableSell != null)
-      await _sharedPreferences.setBool(PreferencesKey.disableSellKey, disableSell);
-
-    if (defaultBuyProvider != null)
-      await _sharedPreferences.setInt(PreferencesKey.defaultBuyProvider, defaultBuyProvider);
+    if (disableTradeOption != null)
+      await _sharedPreferences.setBool(PreferencesKey.disableTradeOption, disableTradeOption);
 
     if (currentTransactionPriorityKeyLegacy != null)
       await _sharedPreferences.setInt(
@@ -516,10 +508,7 @@ class BackupService {
           _sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey),
       PreferencesKey.shouldSaveRecipientAddressKey:
           _sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey),
-      PreferencesKey.disableBuyKey: _sharedPreferences.getBool(PreferencesKey.disableBuyKey),
-      PreferencesKey.disableSellKey: _sharedPreferences.getBool(PreferencesKey.disableSellKey),
-      PreferencesKey.defaultBuyProvider:
-          _sharedPreferences.getInt(PreferencesKey.defaultBuyProvider),
+      PreferencesKey.disableTradeOption: _sharedPreferences.getBool(PreferencesKey.disableTradeOption),
       PreferencesKey.currentPinLength: _sharedPreferences.getInt(PreferencesKey.currentPinLength),
       PreferencesKey.currentTransactionPriorityKeyLegacy:
           _sharedPreferences.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy),
diff --git a/lib/core/selectable_option.dart b/lib/core/selectable_option.dart
new file mode 100644
index 000000000..0d7511c95
--- /dev/null
+++ b/lib/core/selectable_option.dart
@@ -0,0 +1,47 @@
+abstract class SelectableItem {
+  SelectableItem({required this.title});
+  final String title;
+}
+
+class OptionTitle extends SelectableItem {
+  OptionTitle({required String title}) : super(title: title);
+
+}
+
+abstract class SelectableOption extends SelectableItem {
+  SelectableOption({required String title}) : super(title: title);
+
+  String get lightIconPath;
+
+  String get darkIconPath;
+
+  String? get description => null;
+
+  String? get topLeftSubTitle => null;
+
+  String? get topLeftSubTitleIconPath => null;
+
+  String? get topRightSubTitle => null;
+
+  String? get topRightSubTitleLightIconPath => null;
+
+  String? get topRightSubTitleDarkIconPath => null;
+
+  String? get bottomLeftSubTitle => null;
+
+  String? get bottomLeftSubTitleIconPath => null;
+
+  String? get bottomRightSubTitle => null;
+
+  String? get bottomRightSubTitleLightIconPath => null;
+
+  String? get bottomRightSubTitleDarkIconPath => null;
+
+  List<String> get badges => [];
+
+  bool get isOptionSelected => false;
+
+  set isOptionSelected(bool isSelected) => false;
+}
+
+
diff --git a/lib/di.dart b/lib/di.dart
index 9cff29798..8dd1029a9 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -19,6 +19,7 @@ import 'package:cake_wallet/core/backup_service.dart';
 import 'package:cake_wallet/core/key_service.dart';
 import 'package:cake_wallet/core/new_wallet_type_arguments.dart';
 import 'package:cake_wallet/core/secure_storage.dart';
+import 'package:cake_wallet/core/selectable_option.dart';
 import 'package:cake_wallet/core/totp_request_details.dart';
 import 'package:cake_wallet/core/wallet_connect/wallet_connect_key_service.dart';
 import 'package:cake_wallet/core/wallet_connect/wc_bottom_sheet_service.dart';
@@ -34,6 +35,8 @@ import 'package:cake_wallet/entities/exchange_api_mode.dart';
 import 'package:cake_wallet/entities/parse_address_from_domain.dart';
 import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart';
 import 'package:cake_wallet/entities/wallet_manager.dart';
+import 'package:cake_wallet/src/screens/buy/buy_sell_options_page.dart';
+import 'package:cake_wallet/src/screens/buy/payment_method_options_page.dart';
 import 'package:cake_wallet/src/screens/receive/address_list_page.dart';
 import 'package:cake_wallet/src/screens/settings/mweb_logs_page.dart';
 import 'package:cake_wallet/src/screens/settings/mweb_node_page.dart';
@@ -61,7 +64,6 @@ import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dar
 import 'package:cake_wallet/src/screens/auth/auth_page.dart';
 import 'package:cake_wallet/src/screens/backup/backup_page.dart';
 import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
-import 'package:cake_wallet/src/screens/buy/buy_options_page.dart';
 import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
 import 'package:cake_wallet/src/screens/buy/webview_page.dart';
 import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
@@ -135,6 +137,7 @@ import 'package:cake_wallet/utils/device_info.dart';
 import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
 import 'package:cake_wallet/utils/payment_request.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
+import 'package:cake_wallet/view_model/buy/buy_sell_view_model.dart';
 import 'package:cake_wallet/view_model/animated_ur_model.dart';
 import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
 import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
@@ -248,6 +251,8 @@ import 'package:get_it/get_it.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:shared_preferences/shared_preferences.dart';
+import 'buy/meld/meld_buy_provider.dart';
+import 'src/screens/buy/buy_sell_page.dart';
 import 'cake_pay/cake_pay_payment_credantials.dart';
 
 final getIt = GetIt.instance;
@@ -1004,6 +1009,10 @@ Future<void> setup({
         wallet: getIt.get<AppStore>().wallet!,
       ));
 
+  getIt.registerFactory<MeldBuyProvider>(() => MeldBuyProvider(
+    wallet: getIt.get<AppStore>().wallet!,
+  ));
+
   getIt.registerFactoryParam<WebViewPage, String, Uri>((title, uri) => WebViewPage(title, uri));
 
   getIt.registerFactory<PayfuraBuyProvider>(() => PayfuraBuyProvider(
@@ -1193,8 +1202,25 @@ Future<void> setup({
 
   getIt.registerFactory(() => BuyAmountViewModel());
 
-  getIt.registerFactoryParam<BuySellOptionsPage, bool, void>(
-      (isBuyOption, _) => BuySellOptionsPage(getIt.get<DashboardViewModel>(), isBuyOption));
+  getIt.registerFactory(() => BuySellViewModel(getIt.get<AppStore>()));
+
+  getIt.registerFactory(() => BuySellPage(getIt.get<BuySellViewModel>()));
+
+  getIt.registerFactoryParam<BuyOptionsPage, List<dynamic>, void>((List<dynamic> args, _) {
+    final items = args.first as List<SelectableItem>;
+    final pickAnOption = args[1] as void Function(SelectableOption option)?;
+    final confirmOption = args[2] as void Function(BuildContext contex)?;
+    return BuyOptionsPage(
+        items: items, pickAnOption: pickAnOption, confirmOption: confirmOption);
+  });
+
+  getIt.registerFactoryParam<PaymentMethodOptionsPage, List<dynamic>, void>((List<dynamic> args, _) {
+    final items = args.first as List<SelectableOption>;
+    final pickAnOption = args[1] as void Function(SelectableOption option)?;
+
+    return PaymentMethodOptionsPage(
+        items: items, pickAnOption: pickAnOption);
+  });
 
   getIt.registerFactory(() {
     final wallet = getIt.get<AppStore>().wallet;
diff --git a/lib/entities/main_actions.dart b/lib/entities/main_actions.dart
index c1dd71cc9..94be0d2b7 100644
--- a/lib/entities/main_actions.dart
+++ b/lib/entities/main_actions.dart
@@ -23,31 +23,18 @@ class MainActions {
   });
 
   static List<MainActions> all = [
-    buyAction,
+    showWalletsAction,
     receiveAction,
     exchangeAction,
     sendAction,
-    sellAction,
+    tradeAction,
   ];
 
-  static MainActions buyAction = MainActions._(
-    name: (context) => S.of(context).buy,
-    image: 'assets/images/buy.png',
-    isEnabled: (viewModel) => viewModel.isEnabledBuyAction,
-    canShow: (viewModel) => viewModel.hasBuyAction,
+  static MainActions showWalletsAction = MainActions._(
+    name: (context) => S.of(context).wallets,
+    image: 'assets/images/wallet_new.png',
     onTap: (BuildContext context, DashboardViewModel viewModel) async {
-      if (!viewModel.isEnabledBuyAction) {
-        return;
-      }
-
-      final defaultBuyProvider = viewModel.defaultBuyProvider;
-      try {
-        defaultBuyProvider != null
-            ? await defaultBuyProvider.launchProvider(context, true)
-            : await Navigator.of(context).pushNamed(Routes.buySellPage, arguments: true);
-      } catch (e) {
-        await _showErrorDialog(context, defaultBuyProvider.toString(), e.toString());
-      }
+      Navigator.pushNamed(context, Routes.walletList);
     },
   );
 
@@ -79,39 +66,15 @@ class MainActions {
     },
   );
 
-  static MainActions sellAction = MainActions._(
-    name: (context) => S.of(context).sell,
-    image: 'assets/images/sell.png',
-    isEnabled: (viewModel) => viewModel.isEnabledSellAction,
-    canShow: (viewModel) => viewModel.hasSellAction,
-    onTap: (BuildContext context, DashboardViewModel viewModel) async {
-      if (!viewModel.isEnabledSellAction) {
-        return;
-      }
 
-      final defaultSellProvider = viewModel.defaultSellProvider;
-      try {
-        defaultSellProvider != null
-            ? await defaultSellProvider.launchProvider(context, false)
-            : await Navigator.of(context).pushNamed(Routes.buySellPage, arguments: false);
-      } catch (e) {
-        await _showErrorDialog(context, defaultSellProvider.toString(), e.toString());
-      }
+  static MainActions tradeAction = MainActions._(
+    name: (context) => '${S.of(context).buy} / ${S.of(context).sell}',
+    image: 'assets/images/buy_sell.png',
+    isEnabled: (viewModel) => viewModel.isEnabledTradeAction,
+    canShow: (viewModel) => viewModel.hasTradeAction,
+    onTap: (BuildContext context, DashboardViewModel viewModel) async {
+      if (!viewModel.isEnabledTradeAction) return;
+      await Navigator.of(context).pushNamed(Routes.buySellPage, arguments: false);
     },
   );
-
-  static Future<void> _showErrorDialog(
-      BuildContext context, String title, String errorMessage) async {
-    await showPopUp<void>(
-      context: context,
-      builder: (BuildContext context) {
-        return AlertWithOneAction(
-          alertTitle: title,
-          alertContent: errorMessage,
-          buttonText: S.of(context).ok,
-          buttonAction: () => Navigator.of(context).pop(),
-        );
-      },
-    );
-  }
 }
\ No newline at end of file
diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart
index 0bb526e5d..5ed7a7ed6 100644
--- a/lib/entities/preferences_key.dart
+++ b/lib/entities/preferences_key.dart
@@ -21,10 +21,8 @@ class PreferencesKey {
   static const currentBalanceDisplayModeKey = 'current_balance_display_mode';
   static const shouldSaveRecipientAddressKey = 'save_recipient_address';
   static const isAppSecureKey = 'is_app_secure';
-  static const disableBuyKey = 'disable_buy';
-  static const disableSellKey = 'disable_sell';
+  static const disableTradeOption = 'disable_buy';
   static const disableBulletinKey = 'disable_bulletin';
-  static const defaultBuyProvider = 'default_buy_provider';
   static const walletListOrder = 'wallet_list_order';
   static const contactListOrder = 'contact_list_order';
   static const walletListAscending = 'wallet_list_ascending';
diff --git a/lib/entities/provider_types.dart b/lib/entities/provider_types.dart
index b9dd4ef2a..42ec74c12 100644
--- a/lib/entities/provider_types.dart
+++ b/lib/entities/provider_types.dart
@@ -1,24 +1,18 @@
 import 'package:cake_wallet/buy/buy_provider.dart';
 import 'package:cake_wallet/buy/dfx/dfx_buy_provider.dart';
+import 'package:cake_wallet/buy/meld/meld_buy_provider.dart';
 import 'package:cake_wallet/buy/moonpay/moonpay_provider.dart';
 import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
 import 'package:cake_wallet/buy/robinhood/robinhood_buy_provider.dart';
 import 'package:cake_wallet/di.dart';
 import 'package:cw_core/wallet_type.dart';
+import 'package:http/http.dart';
 
-enum ProviderType {
-  askEachTime,
-  robinhood,
-  dfx,
-  onramper,
-  moonpay,
-}
+enum ProviderType { robinhood, dfx, onramper, moonpay, meld }
 
 extension ProviderTypeName on ProviderType {
   String get title {
     switch (this) {
-      case ProviderType.askEachTime:
-        return 'Ask each time';
       case ProviderType.robinhood:
         return 'Robinhood Connect';
       case ProviderType.dfx:
@@ -27,13 +21,13 @@ extension ProviderTypeName on ProviderType {
         return 'Onramper';
       case ProviderType.moonpay:
         return 'MoonPay';
+      case ProviderType.meld:
+        return 'Meld';
     }
   }
 
   String get id {
     switch (this) {
-      case ProviderType.askEachTime:
-        return 'ask_each_time_provider';
       case ProviderType.robinhood:
         return 'robinhood_connect_provider';
       case ProviderType.dfx:
@@ -42,6 +36,8 @@ extension ProviderTypeName on ProviderType {
         return 'onramper_provider';
       case ProviderType.moonpay:
         return 'moonpay_provider';
+      case ProviderType.meld:
+        return 'meld_provider';
     }
   }
 }
@@ -52,14 +48,13 @@ class ProvidersHelper {
       case WalletType.nano:
       case WalletType.banano:
       case WalletType.wownero:
-        return [ProviderType.askEachTime, ProviderType.onramper];
+        return [ProviderType.onramper];
       case WalletType.monero:
-        return [ProviderType.askEachTime, ProviderType.onramper, ProviderType.dfx];
+        return [ProviderType.onramper, ProviderType.dfx];
       case WalletType.bitcoin:
       case WalletType.polygon:
       case WalletType.ethereum:
         return [
-          ProviderType.askEachTime,
           ProviderType.onramper,
           ProviderType.dfx,
           ProviderType.robinhood,
@@ -68,10 +63,13 @@ class ProvidersHelper {
       case WalletType.litecoin:
       case WalletType.bitcoinCash:
       case WalletType.solana:
-        return [ProviderType.askEachTime, ProviderType.onramper, ProviderType.robinhood, ProviderType.moonpay];
+        return [
+          ProviderType.onramper,
+          ProviderType.robinhood,
+          ProviderType.moonpay
+        ];
       case WalletType.tron:
         return [
-          ProviderType.askEachTime,
           ProviderType.onramper,
           ProviderType.robinhood,
           ProviderType.moonpay,
@@ -88,28 +86,24 @@ class ProvidersHelper {
       case WalletType.ethereum:
       case WalletType.polygon:
         return [
-          ProviderType.askEachTime,
           ProviderType.onramper,
           ProviderType.moonpay,
           ProviderType.dfx,
         ];
       case WalletType.litecoin:
       case WalletType.bitcoinCash:
-        return [ProviderType.askEachTime, ProviderType.moonpay];
+        return [ProviderType.moonpay];
       case WalletType.solana:
         return [
-          ProviderType.askEachTime,
           ProviderType.onramper,
-          ProviderType.robinhood,
           ProviderType.moonpay,
         ];
       case WalletType.tron:
         return [
-          ProviderType.askEachTime,
-          ProviderType.robinhood,
           ProviderType.moonpay,
         ];
       case WalletType.monero:
+        return [ProviderType.dfx];
       case WalletType.nano:
       case WalletType.banano:
       case WalletType.none:
@@ -129,7 +123,9 @@ class ProvidersHelper {
         return getIt.get<OnRamperBuyProvider>();
       case ProviderType.moonpay:
         return getIt.get<MoonPayProvider>();
-      case ProviderType.askEachTime:
+      case ProviderType.meld:
+        return getIt.get<MeldBuyProvider>();
+      default:
         return null;
     }
   }
diff --git a/lib/router.dart b/lib/router.dart
index 4b99aabc0..781a6e057 100644
--- a/lib/router.dart
+++ b/lib/router.dart
@@ -17,8 +17,9 @@ import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dar
 import 'package:cake_wallet/src/screens/auth/auth_page.dart';
 import 'package:cake_wallet/src/screens/backup/backup_page.dart';
 import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
-import 'package:cake_wallet/src/screens/buy/buy_options_page.dart';
+import 'package:cake_wallet/src/screens/buy/buy_sell_options_page.dart';
 import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
+import 'package:cake_wallet/src/screens/buy/payment_method_options_page.dart';
 import 'package:cake_wallet/src/screens/buy/webview_page.dart';
 import 'package:cake_wallet/src/screens/cake_pay/auth/cake_pay_account_page.dart';
 import 'package:cake_wallet/src/screens/cake_pay/cake_pay.dart';
@@ -129,7 +130,8 @@ import 'package:cw_core/wallet_type.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-
+import 'package:cake_wallet/src/screens/cake_pay/cake_pay.dart';
+import 'src/screens/buy/buy_sell_page.dart';
 import 'src/screens/dashboard/pages/nft_import_page.dart';
 
 late RouteSettings currentRouteSettings;
@@ -571,7 +573,15 @@ Route<dynamic> createRoute(RouteSettings settings) {
 
     case Routes.buySellPage:
       final args = settings.arguments as bool;
-      return MaterialPageRoute<void>(builder: (_) => getIt.get<BuySellOptionsPage>(param1: args));
+      return MaterialPageRoute<void>(builder: (_) => getIt.get<BuySellPage>(param1: args));
+
+    case Routes.buyOptionsPage:
+      final args = settings.arguments as List;
+      return MaterialPageRoute<void>(builder: (_) => getIt.get<BuyOptionsPage>(param1: args));
+
+    case Routes.paymentMethodOptionsPage:
+      final args = settings.arguments as List;
+      return MaterialPageRoute<void>(builder: (_) => getIt.get<PaymentMethodOptionsPage>(param1: args));
 
     case Routes.buyWebView:
       final args = settings.arguments as List;
diff --git a/lib/routes.dart b/lib/routes.dart
index 63c41bde5..0b8beb0ea 100644
--- a/lib/routes.dart
+++ b/lib/routes.dart
@@ -59,6 +59,8 @@ class Routes {
   static const supportOtherLinks = '/support/other';
   static const orderDetails = '/order_details';
   static const buySellPage = '/buy_sell_page';
+  static const buyOptionsPage = '/buy_sell_options';
+  static const paymentMethodOptionsPage = '/payment_method_options';
   static const buyWebView = '/buy_web_view';
   static const unspentCoinsList = '/unspent_coins_list';
   static const unspentCoinsDetails = '/unspent_coins_details';
diff --git a/lib/src/screens/InfoPage.dart b/lib/src/screens/Info_page.dart
similarity index 100%
rename from lib/src/screens/InfoPage.dart
rename to lib/src/screens/Info_page.dart
diff --git a/lib/src/screens/buy/buy_options_page.dart b/lib/src/screens/buy/buy_options_page.dart
deleted file mode 100644
index 38f3ed968..000000000
--- a/lib/src/screens/buy/buy_options_page.dart
+++ /dev/null
@@ -1,74 +0,0 @@
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/src/screens/base_page.dart';
-import 'package:cake_wallet/src/widgets/option_tile.dart';
-import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
-import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
-import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
-import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
-import 'package:flutter/material.dart';
-
-class BuySellOptionsPage extends BasePage {
-  BuySellOptionsPage(this.dashboardViewModel, this.isBuyAction);
-
-  final DashboardViewModel dashboardViewModel;
-  final bool isBuyAction;
-
-  @override
-  String get title => isBuyAction ? S.current.buy : S.current.sell;
-
-  @override
-  AppBarStyle get appBarStyle => AppBarStyle.regular;
-
-  @override
-  Widget body(BuildContext context) {
-    final isLightMode = Theme.of(context).extension<OptionTileTheme>()?.useDarkImage ?? false;
-    final availableProviders = isBuyAction
-        ? dashboardViewModel.availableBuyProviders
-        : dashboardViewModel.availableSellProviders;
-
-    return ScrollableWithBottomSection(
-      content: Container(
-        child: Center(
-          child: ConstrainedBox(
-            constraints: BoxConstraints(maxWidth: 330),
-            child: Column(
-              children: [
-                ...availableProviders.map((provider) {
-                  final icon = Image.asset(
-                    isLightMode ? provider.lightIcon : provider.darkIcon,
-                    height: 40,
-                    width: 40,
-                  );
-
-                  return Padding(
-                    padding: EdgeInsets.only(top: 24),
-                    child: OptionTile(
-                      image: icon,
-                      title: provider.toString(),
-                      description: provider.providerDescription,
-                      onPressed: () => provider.launchProvider(context, isBuyAction),
-                    ),
-                  );
-                }).toList(),
-              ],
-            ),
-          ),
-        ),
-      ),
-      bottomSection: Padding(
-        padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
-        child: Text(
-          isBuyAction
-              ? S.of(context).select_buy_provider_notice
-              : S.of(context).select_sell_provider_notice,
-          textAlign: TextAlign.center,
-          style: TextStyle(
-            fontSize: 14,
-            fontWeight: FontWeight.normal,
-            color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
-          ),
-        ),
-      ),
-    );
-  }
-}
diff --git a/lib/src/screens/buy/buy_sell_options_page.dart b/lib/src/screens/buy/buy_sell_options_page.dart
new file mode 100644
index 000000000..900810f68
--- /dev/null
+++ b/lib/src/screens/buy/buy_sell_options_page.dart
@@ -0,0 +1,48 @@
+import 'package:cake_wallet/core/selectable_option.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/select_options_page.dart';
+import 'package:flutter/cupertino.dart';
+
+class BuyOptionsPage extends SelectOptionsPage {
+  BuyOptionsPage({required this.items, this.pickAnOption, this.confirmOption});
+
+  final List<SelectableItem> items;
+  final Function(SelectableOption option)? pickAnOption;
+  final Function(BuildContext context)? confirmOption;
+
+  @override
+  String get pageTitle => S.current.choose_a_provider;
+
+  @override
+  EdgeInsets? get contentPadding => null;
+
+  @override
+  EdgeInsets? get tilePadding => EdgeInsets.only(top: 8);
+
+  @override
+  EdgeInsets? get innerPadding => EdgeInsets.symmetric(horizontal: 24, vertical: 8);
+
+  @override
+  double? get imageHeight => 40;
+
+  @override
+  double? get imageWidth => 40;
+
+  @override
+  Color? get selectedBackgroundColor => null;
+
+  @override
+  double? get tileBorderRadius => 30;
+
+  @override
+  String get bottomSectionText => '';
+
+  @override
+  void Function(SelectableOption option)? get onOptionTap => pickAnOption;
+
+  @override
+  String get primaryButtonText => S.current.confirm;
+
+  @override
+  void Function(BuildContext context)? get primaryButtonAction => confirmOption;
+}
diff --git a/lib/src/screens/buy/buy_sell_page.dart b/lib/src/screens/buy/buy_sell_page.dart
new file mode 100644
index 000000000..d2f16fe3c
--- /dev/null
+++ b/lib/src/screens/buy/buy_sell_page.dart
@@ -0,0 +1,469 @@
+import 'package:cake_wallet/buy/sell_buy_states.dart';
+import 'package:cake_wallet/core/address_validator.dart';
+import 'package:cake_wallet/di.dart';
+import 'package:cake_wallet/entities/fiat_currency.dart';
+import 'package:cake_wallet/entities/parse_address_from_domain.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/routes.dart';
+import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/screens/exchange/widgets/desktop_exchange_cards_section.dart';
+import 'package:cake_wallet/src/screens/exchange/widgets/exchange_card.dart';
+import 'package:cake_wallet/src/screens/exchange/widgets/mobile_exchange_cards_section.dart';
+import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
+import 'package:cake_wallet/src/widgets/primary_button.dart';
+import 'package:cake_wallet/src/widgets/provider_optoin_tile.dart';
+import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
+import 'package:cake_wallet/src/widgets/trail_button.dart';
+import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
+import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
+import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
+import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
+import 'package:cake_wallet/themes/theme_base.dart';
+import 'package:cake_wallet/typography.dart';
+import 'package:cake_wallet/src/screens/send/widgets/extract_address_from_parsed.dart';
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
+import 'package:cake_wallet/view_model/buy/buy_sell_view_model.dart';
+import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/currency.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+import 'package:keyboard_actions/keyboard_actions.dart';
+import 'package:mobx/mobx.dart';
+
+class BuySellPage extends BasePage {
+  BuySellPage(this.buySellViewModel);
+
+  final BuySellViewModel buySellViewModel;
+  final cryptoCurrencyKey = GlobalKey<ExchangeCardState>();
+  final fiatCurrencyKey = GlobalKey<ExchangeCardState>();
+  final _formKey = GlobalKey<FormState>();
+  final _fiatAmountFocus = FocusNode();
+  final _cryptoAmountFocus = FocusNode();
+  final _cryptoAddressFocus = FocusNode();
+  var _isReactionsSet = false;
+
+  final arrowBottomPurple = Image.asset(
+    'assets/images/arrow_bottom_purple_icon.png',
+    color: Colors.white,
+    height: 8,
+  );
+  final arrowBottomCakeGreen = Image.asset(
+    'assets/images/arrow_bottom_cake_green.png',
+    color: Colors.white,
+    height: 8,
+  );
+
+  late final String? depositWalletName;
+  late final String? receiveWalletName;
+
+  @override
+  String get title => S.current.buy + '/' + S.current.sell;
+
+  @override
+  bool get gradientBackground => true;
+
+  @override
+  bool get gradientAll => true;
+
+  @override
+  bool get resizeToAvoidBottomInset => false;
+
+  @override
+  bool get extendBodyBehindAppBar => true;
+
+  @override
+  AppBarStyle get appBarStyle => AppBarStyle.transparent;
+
+  @override
+  Function(BuildContext)? get pushToNextWidget => (context) {
+        FocusScopeNode currentFocus = FocusScope.of(context);
+        if (!currentFocus.hasPrimaryFocus) {
+          currentFocus.focusedChild?.unfocus();
+        }
+      };
+
+  @override
+  Widget trailing(BuildContext context) => TrailButton(
+      caption: S.of(context).clear,
+      onPressed: () {
+        _formKey.currentState?.reset();
+        buySellViewModel.reset();
+      });
+
+  @override
+  Widget? leading(BuildContext context) {
+    final _backButton = Icon(
+      Icons.arrow_back_ios,
+      color: titleColor(context),
+      size: 16,
+    );
+    final _closeButton =
+        currentTheme.type == ThemeType.dark ? closeButtonImageDarkTheme : closeButtonImage;
+
+    bool isMobileView = responsiveLayoutUtil.shouldRenderMobileUI;
+
+    return MergeSemantics(
+      child: SizedBox(
+        height: isMobileView ? 37 : 45,
+        width: isMobileView ? 37 : 45,
+        child: ButtonTheme(
+          minWidth: double.minPositive,
+          child: Semantics(
+            label: !isMobileView ? S.of(context).close : S.of(context).seed_alert_back,
+            child: TextButton(
+              style: ButtonStyle(
+                overlayColor: MaterialStateColor.resolveWith((states) => Colors.transparent),
+              ),
+              onPressed: () => onClose(context),
+              child: !isMobileView ? _closeButton : _backButton,
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+
+  @override
+  Widget body(BuildContext context) {
+    WidgetsBinding.instance.addPostFrameCallback((_) => _setReactions(context, buySellViewModel));
+
+    return KeyboardActions(
+        disableScroll: true,
+        config: KeyboardActionsConfig(
+            keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
+            keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
+            nextFocus: false,
+            actions: [
+              KeyboardActionsItem(
+                  focusNode: _fiatAmountFocus, toolbarButtons: [(_) => KeyboardDoneButton()]),
+              KeyboardActionsItem(
+                  focusNode: _cryptoAmountFocus, toolbarButtons: [(_) => KeyboardDoneButton()])
+            ]),
+        child: Container(
+          color: Theme.of(context).colorScheme.background,
+          child: Form(
+              key: _formKey,
+              child: ScrollableWithBottomSection(
+                contentPadding: EdgeInsets.only(bottom: 24),
+                content: Observer(
+                    builder: (_) => Column(children: [
+                          _exchangeCardsSection(context),
+                          Padding(
+                            padding: EdgeInsets.symmetric(horizontal: 24),
+                            child: Column(
+                              children: [
+                                SizedBox(height: 12),
+                                _buildPaymentMethodTile(context),
+                              ],
+                            ),
+                          ),
+                        ])),
+                bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
+                bottomSection: Column(children: [
+                  Observer(
+                      builder: (_) => LoadingPrimaryButton(
+                          text: S.current.choose_a_provider,
+                          onPressed: () async {
+                            if(!_formKey.currentState!.validate()) return;
+                            buySellViewModel.onTapChoseProvider(context);
+                          },
+                          color: Theme.of(context).primaryColor,
+                          textColor: Colors.white,
+                          isDisabled: false,
+                          isLoading: !buySellViewModel.isReadyToTrade)),
+                ]),
+              )),
+        ));
+  }
+
+  Widget _buildPaymentMethodTile(BuildContext context) {
+    if (buySellViewModel.paymentMethodState is PaymentMethodLoading ||
+        buySellViewModel.paymentMethodState is InitialPaymentMethod) {
+      return OptionTilePlaceholder(
+          withBadge: false,
+          withSubtitle: false,
+          borderRadius: 30,
+          padding: EdgeInsets.symmetric(horizontal: 24, vertical: 8),
+          leadingIcon: Icons.arrow_forward_ios,
+          isDarkTheme: buySellViewModel.isDarkTheme);
+    }
+    if (buySellViewModel.paymentMethodState is PaymentMethodFailed) {
+      return OptionTilePlaceholder(errorText: 'No payment methods available', borderRadius: 30);
+    }
+    if (buySellViewModel.paymentMethodState is PaymentMethodLoaded &&
+        buySellViewModel.selectedPaymentMethod != null) {
+      return Observer(builder: (_) {
+        final selectedPaymentMethod = buySellViewModel.selectedPaymentMethod!;
+        return ProviderOptionTile(
+          lightImagePath: selectedPaymentMethod.lightIconPath,
+          darkImagePath: selectedPaymentMethod.darkIconPath,
+          title: selectedPaymentMethod.title,
+          onPressed: () => _pickPaymentMethod(context),
+          leadingIcon: Icons.arrow_forward_ios,
+          isLightMode: !buySellViewModel.isDarkTheme,
+          borderRadius: 30,
+          padding: EdgeInsets.symmetric(horizontal: 24, vertical: 8),
+          titleTextStyle:
+          textLargeBold(color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
+        );
+      });
+    }
+    return OptionTilePlaceholder(errorText: 'No payment methods available', borderRadius: 30);
+  }
+
+  void _pickPaymentMethod(BuildContext context) async {
+    final currentOption = buySellViewModel.selectedPaymentMethod;
+    await Navigator.of(context).pushNamed(
+      Routes.paymentMethodOptionsPage,
+      arguments: [
+        buySellViewModel.paymentMethods,
+        buySellViewModel.changeOption,
+      ],
+    );
+
+    buySellViewModel.selectedPaymentMethod;
+    if (currentOption != null &&
+        currentOption.paymentMethodType !=
+            buySellViewModel.selectedPaymentMethod?.paymentMethodType) {
+      await buySellViewModel.calculateBestRate();
+    }
+  }
+
+  void _setReactions(BuildContext context, BuySellViewModel buySellViewModel) {
+    if (_isReactionsSet) {
+      return;
+    }
+
+    final fiatAmountController = fiatCurrencyKey.currentState!.amountController;
+    final cryptoAmountController = cryptoCurrencyKey.currentState!.amountController;
+    final cryptoAddressController = cryptoCurrencyKey.currentState!.addressController;
+
+    _onCurrencyChange(buySellViewModel.cryptoCurrency, buySellViewModel, cryptoCurrencyKey);
+    _onCurrencyChange(buySellViewModel.fiatCurrency, buySellViewModel, fiatCurrencyKey);
+
+    reaction(
+            (_) => buySellViewModel.wallet.name,
+            (String _) =>
+            _onWalletNameChange(buySellViewModel, buySellViewModel.cryptoCurrency, cryptoCurrencyKey));
+
+    reaction(
+        (_) => buySellViewModel.cryptoCurrency,
+        (CryptoCurrency currency) =>
+            _onCurrencyChange(currency, buySellViewModel, cryptoCurrencyKey));
+
+    reaction(
+        (_) => buySellViewModel.fiatCurrency,
+        (FiatCurrency currency) =>
+            _onCurrencyChange(currency, buySellViewModel, fiatCurrencyKey));
+
+    reaction((_) => buySellViewModel.fiatAmount, (String amount) {
+      if (fiatCurrencyKey.currentState!.amountController.text != amount) {
+        fiatCurrencyKey.currentState!.amountController.text = amount;
+      }
+    });
+
+    reaction((_) => buySellViewModel.isCryptoCurrencyAddressEnabled, (bool isEnabled) {
+      cryptoCurrencyKey.currentState!.isAddressEditable(isEditable: isEnabled);
+    });
+
+    reaction((_) => buySellViewModel.cryptoAmount, (String amount) {
+      if (cryptoCurrencyKey.currentState!.amountController.text != amount) {
+        cryptoCurrencyKey.currentState!.amountController.text = amount;
+      }
+    });
+
+    reaction((_) => buySellViewModel.cryptoCurrencyAddress, (String address) {
+      if (cryptoAddressController != address) {
+        cryptoCurrencyKey.currentState!.addressController.text = address;
+      }
+    });
+
+    fiatAmountController.addListener(() {
+      if (fiatAmountController.text != buySellViewModel.fiatAmount) {
+          buySellViewModel.changeFiatAmount(amount: fiatAmountController.text);
+      }
+    });
+
+    cryptoAmountController.addListener(() {
+      if (cryptoAmountController.text != buySellViewModel.cryptoAmount) {
+          buySellViewModel.changeCryptoAmount(amount: cryptoAmountController.text);
+      }
+    });
+
+    cryptoAddressController.addListener(() {
+      buySellViewModel.changeCryptoCurrencyAddress(cryptoAddressController.text);
+    });
+
+    _cryptoAddressFocus.addListener(() async {
+      if (!_cryptoAddressFocus.hasFocus && cryptoAddressController.text.isNotEmpty) {
+        final domain = cryptoAddressController.text;
+        buySellViewModel.cryptoCurrencyAddress =
+        await fetchParsedAddress(context, domain, buySellViewModel.cryptoCurrency);
+      }
+    });
+
+    reaction((_) => buySellViewModel.wallet.walletAddresses.addressForExchange, (String address) {
+      if (buySellViewModel.cryptoCurrency == CryptoCurrency.xmr) {
+        cryptoCurrencyKey.currentState!.changeAddress(address: address);
+      }
+    });
+
+    reaction((_) => buySellViewModel.isReadyToTrade, (bool isReady) {
+      if (isReady) {
+        if (cryptoAmountController.text.isNotEmpty &&
+            cryptoAmountController.text != S.current.fetching) {
+          buySellViewModel.changeCryptoAmount(amount: cryptoAmountController.text);
+        } else if (fiatAmountController.text.isNotEmpty &&
+            fiatAmountController.text != S.current.fetching) {
+          buySellViewModel.changeFiatAmount(amount: fiatAmountController.text);
+        }
+      }
+    });
+
+    _isReactionsSet = true;
+  }
+
+  void _onCurrencyChange(Currency currency, BuySellViewModel buySellViewModel,
+      GlobalKey<ExchangeCardState> key) {
+    final isCurrentTypeWallet = currency == buySellViewModel.wallet.currency;
+
+    key.currentState!.changeSelectedCurrency(currency);
+    key.currentState!.changeWalletName(isCurrentTypeWallet ? buySellViewModel.wallet.name : '');
+
+    key.currentState!.changeAddress(
+        address: isCurrentTypeWallet ? buySellViewModel.wallet.walletAddresses.addressForExchange : '');
+
+    key.currentState!.changeAmount(amount: '');
+  }
+
+  void _onWalletNameChange(BuySellViewModel buySellViewModel, CryptoCurrency currency,
+      GlobalKey<ExchangeCardState> key) {
+    final isCurrentTypeWallet = currency == buySellViewModel.wallet.currency;
+
+    if (isCurrentTypeWallet) {
+      key.currentState!.changeWalletName(buySellViewModel.wallet.name);
+      key.currentState!.addressController.text = buySellViewModel.wallet.walletAddresses.addressForExchange;
+    } else if (key.currentState!.addressController.text ==
+        buySellViewModel.wallet.walletAddresses.addressForExchange) {
+      key.currentState!.changeWalletName('');
+      key.currentState!.addressController.text = '';
+    }
+  }
+
+  void disposeBestRateSync() => {};
+
+  Widget _exchangeCardsSection(BuildContext context) {
+    final fiatExchangeCard = Observer(
+        builder: (_) => ExchangeCard(
+              cardInstanceName: 'fiat_currency_trade_card',
+              onDispose: disposeBestRateSync,
+              amountFocusNode: _fiatAmountFocus,
+              key: fiatCurrencyKey,
+              title: 'FIAT ${S.of(context).amount}',
+              initialCurrency: buySellViewModel.fiatCurrency,
+              initialWalletName: '',
+              initialAddress: '',
+              initialIsAmountEditable: true,
+              isAmountEstimated: false,
+              currencyRowPadding: EdgeInsets.zero,
+              addressRowPadding: EdgeInsets.zero,
+              isMoneroWallet: buySellViewModel.wallet == WalletType.monero,
+              showAddressField: false,
+              showLimitsField: false,
+              currencies: buySellViewModel.fiatCurrencies,
+              onCurrencySelected: (currency) =>
+                  buySellViewModel.changeFiatCurrency(currency: currency),
+              imageArrow: arrowBottomPurple,
+              currencyButtonColor: Colors.transparent,
+              addressButtonsColor:
+                  Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
+              borderColor:
+                  Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderTopPanelColor,
+              onPushPasteButton: (context) async {},
+              onPushAddressBookButton: (context) async {},
+            ));
+
+    final cryptoExchangeCard = Observer(
+        builder: (_) => ExchangeCard(
+              cardInstanceName: 'crypto_currency_trade_card',
+              onDispose: disposeBestRateSync,
+              amountFocusNode: _cryptoAmountFocus,
+              addressFocusNode: _cryptoAddressFocus,
+              key: cryptoCurrencyKey,
+              title: 'Crypto ${S.of(context).amount}',
+              initialCurrency: buySellViewModel.cryptoCurrency,
+              initialWalletName: '',
+              initialAddress: buySellViewModel.cryptoCurrency == buySellViewModel.wallet.currency
+                  ? buySellViewModel.wallet.walletAddresses.addressForExchange
+                  : buySellViewModel.cryptoCurrencyAddress,
+              initialIsAmountEditable: true,
+              isAmountEstimated: true,
+              showLimitsField: false,
+              currencyRowPadding: EdgeInsets.zero,
+              addressRowPadding: EdgeInsets.zero,
+              isMoneroWallet: buySellViewModel.wallet == WalletType.monero,
+              currencies: buySellViewModel.cryptoCurrencies,
+              onCurrencySelected: (currency) =>
+                  buySellViewModel.changeCryptoCurrency(currency: currency),
+              imageArrow: arrowBottomCakeGreen,
+              currencyButtonColor: Colors.transparent,
+              addressButtonsColor:
+                  Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
+              borderColor:
+                  Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderBottomPanelColor,
+              addressTextFieldValidator: AddressValidator(type: buySellViewModel.cryptoCurrency),
+              onPushPasteButton: (context) async {},
+              onPushAddressBookButton: (context) async {},
+            ));
+
+    if (responsiveLayoutUtil.shouldRenderMobileUI) {
+      return Observer(
+        builder: (_) {
+          if (buySellViewModel.isBuyAction) {
+            return MobileExchangeCardsSection(
+              firstExchangeCard: fiatExchangeCard,
+              secondExchangeCard: cryptoExchangeCard,
+              onBuyTap: () => null,
+              onSellTap: () =>
+                  buySellViewModel.isBuyAction ? buySellViewModel.changeBuySellAction() : null,
+              isBuySellOption: true,
+            );
+          } else {
+            return MobileExchangeCardsSection(
+              firstExchangeCard: cryptoExchangeCard,
+              secondExchangeCard: fiatExchangeCard,
+              onBuyTap: () =>
+                  !buySellViewModel.isBuyAction ? buySellViewModel.changeBuySellAction() : null,
+              onSellTap: () => null,
+              isBuySellOption: true,
+            );
+          }
+        },
+      );
+    }
+
+    return Observer(
+      builder: (_) {
+        if (buySellViewModel.isBuyAction) {
+          return DesktopExchangeCardsSection(
+            firstExchangeCard: fiatExchangeCard,
+            secondExchangeCard: cryptoExchangeCard,
+          );
+        } else {
+          return DesktopExchangeCardsSection(
+            firstExchangeCard: cryptoExchangeCard,
+            secondExchangeCard: fiatExchangeCard,
+          );
+        }
+      },
+    );
+  }
+
+  Future<String> fetchParsedAddress(
+      BuildContext context, String domain, CryptoCurrency currency) async {
+    final parsedAddress = await getIt.get<AddressResolver>().resolve(context, domain, currency);
+    final address = await extractAddressFromParsed(context, parsedAddress);
+    return address;
+  }
+}
diff --git a/lib/src/screens/buy/payment_method_options_page.dart b/lib/src/screens/buy/payment_method_options_page.dart
new file mode 100644
index 000000000..541f91ab4
--- /dev/null
+++ b/lib/src/screens/buy/payment_method_options_page.dart
@@ -0,0 +1,47 @@
+import 'package:cake_wallet/core/selectable_option.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/select_options_page.dart';
+import 'package:flutter/cupertino.dart';
+
+class PaymentMethodOptionsPage extends SelectOptionsPage {
+  PaymentMethodOptionsPage({required this.items, this.pickAnOption});
+
+  final List<SelectableItem> items;
+  final Function(SelectableOption option)? pickAnOption;
+
+  @override
+  String get pageTitle => S.current.choose_a_payment_method;
+
+  @override
+  EdgeInsets? get contentPadding => null;
+
+  @override
+  EdgeInsets? get tilePadding => EdgeInsets.only(top: 12);
+
+  @override
+  EdgeInsets? get innerPadding => EdgeInsets.symmetric(horizontal: 24, vertical: 12);
+
+  @override
+  double? get imageHeight => null;
+
+  @override
+  double? get imageWidth => null;
+
+  @override
+  Color? get selectedBackgroundColor => null;
+
+  @override
+  double? get tileBorderRadius => 30;
+
+  @override
+  String get bottomSectionText => '';
+
+  @override
+  void Function(SelectableOption option)? get onOptionTap => pickAnOption;
+
+  @override
+  String get primaryButtonText => S.current.confirm;
+
+  @override
+  void Function(BuildContext context)? get primaryButtonAction => null;
+}
diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart
index d36c06013..7bb5f77f8 100644
--- a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart
+++ b/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart
@@ -21,6 +21,14 @@ class DesktopDashboardActions extends StatelessWidget {
           return Column(
             children: [
               const SizedBox(height: 16),
+              DesktopActionButton(
+                title: MainActions.showWalletsAction.name(context),
+                image: MainActions.showWalletsAction.image,
+                canShow: MainActions.showWalletsAction.canShow?.call(dashboardViewModel),
+                isEnabled: MainActions.showWalletsAction.isEnabled?.call(dashboardViewModel),
+                onTap: () async =>
+                    await MainActions.showWalletsAction.onTap(context, dashboardViewModel),
+              ),
               DesktopActionButton(
                 title: MainActions.exchangeAction.name(context),
                 image: MainActions.exchangeAction.image,
@@ -55,20 +63,11 @@ class DesktopDashboardActions extends StatelessWidget {
                 children: [
                   Expanded(
                     child: DesktopActionButton(
-                      title: MainActions.buyAction.name(context),
-                      image: MainActions.buyAction.image,
-                      canShow: MainActions.buyAction.canShow?.call(dashboardViewModel),
-                      isEnabled: MainActions.buyAction.isEnabled?.call(dashboardViewModel),
-                      onTap: () async => await MainActions.buyAction.onTap(context, dashboardViewModel),
-                    ),
-                  ),
-                  Expanded(
-                    child: DesktopActionButton(
-                      title: MainActions.sellAction.name(context),
-                      image: MainActions.sellAction.image,
-                      canShow: MainActions.sellAction.canShow?.call(dashboardViewModel),
-                      isEnabled: MainActions.sellAction.isEnabled?.call(dashboardViewModel),
-                      onTap: () async => await MainActions.sellAction.onTap(context, dashboardViewModel),
+                      title: MainActions.tradeAction.name(context),
+                      image: MainActions.tradeAction.image,
+                      canShow: MainActions.tradeAction.canShow?.call(dashboardViewModel),
+                      isEnabled: MainActions.tradeAction.isEnabled?.call(dashboardViewModel),
+                      onTap: () async => await MainActions.tradeAction.onTap(context, dashboardViewModel),
                     ),
                   ),
                 ],
diff --git a/lib/src/screens/exchange/widgets/exchange_card.dart b/lib/src/screens/exchange/widgets/exchange_card.dart
index 75a2eadd7..7c4cc948d 100644
--- a/lib/src/screens/exchange/widgets/exchange_card.dart
+++ b/lib/src/screens/exchange/widgets/exchange_card.dart
@@ -18,7 +18,7 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
 import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
 import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
 
-class ExchangeCard extends StatefulWidget {
+class ExchangeCard<T extends Currency> extends StatefulWidget {
   ExchangeCard({
     Key? key,
     required this.initialCurrency,
@@ -40,19 +40,23 @@ class ExchangeCard extends StatefulWidget {
     this.borderColor = Colors.transparent,
     this.hasAllAmount = false,
     this.isAllAmountEnabled = false,
+    this.showAddressField = true,
+    this.showLimitsField = true,
     this.amountFocusNode,
     this.addressFocusNode,
     this.allAmount,
+    this.currencyRowPadding,
+    this.addressRowPadding,
     this.onPushPasteButton,
     this.onPushAddressBookButton,
     this.onDispose,
     required this.cardInstanceName,
   }) : super(key: key);
 
-  final List<CryptoCurrency> currencies;
-  final Function(CryptoCurrency) onCurrencySelected;
+  final List<T> currencies;
+  final Function(T) onCurrencySelected;
   final String title;
-  final CryptoCurrency initialCurrency;
+  final T initialCurrency;
   final String initialWalletName;
   final String initialAddress;
   final bool initialIsAmountEditable;
@@ -70,18 +74,22 @@ class ExchangeCard extends StatefulWidget {
   final FocusNode? amountFocusNode;
   final FocusNode? addressFocusNode;
   final bool hasAllAmount;
+  final bool showAddressField;
+  final bool showLimitsField;
   final bool isAllAmountEnabled;
   final VoidCallback? allAmount;
+  final EdgeInsets? currencyRowPadding;
+  final EdgeInsets? addressRowPadding;
   final void Function(BuildContext context)? onPushPasteButton;
   final void Function(BuildContext context)? onPushAddressBookButton;
   final Function()? onDispose;
   final String cardInstanceName;
 
   @override
-  ExchangeCardState createState() => ExchangeCardState();
+  ExchangeCardState<T> createState() => ExchangeCardState<T>();
 }
 
-class ExchangeCardState extends State<ExchangeCard> {
+class ExchangeCardState<T extends Currency> extends State<ExchangeCard<T>> {
   ExchangeCardState()
       : _title = '',
         _min = '',
@@ -89,7 +97,6 @@ class ExchangeCardState extends State<ExchangeCard> {
         _isAmountEditable = false,
         _isAddressEditable = false,
         _walletName = '',
-        _selectedCurrency = CryptoCurrency.btc,
         _isAmountEstimated = false,
         _isMoneroWallet = false,
         _cardInstanceName = '';
@@ -101,7 +108,7 @@ class ExchangeCardState extends State<ExchangeCard> {
   String _title;
   String? _min;
   String? _max;
-  CryptoCurrency _selectedCurrency;
+  late T _selectedCurrency;
   String _walletName;
   bool _isAmountEditable;
   bool _isAddressEditable;
@@ -118,7 +125,8 @@ class ExchangeCardState extends State<ExchangeCard> {
     _selectedCurrency = widget.initialCurrency;
     _isAmountEstimated = widget.isAmountEstimated;
     _isMoneroWallet = widget.isMoneroWallet;
-    addressController.text = widget.initialAddress;
+    addressController.text = _normalizeAddressFormat(widget.initialAddress);
+
     super.initState();
   }
 
@@ -136,7 +144,7 @@ class ExchangeCardState extends State<ExchangeCard> {
     });
   }
 
-  void changeSelectedCurrency(CryptoCurrency currency) {
+  void changeSelectedCurrency(T currency) {
     setState(() => _selectedCurrency = currency);
   }
 
@@ -157,7 +165,7 @@ class ExchangeCardState extends State<ExchangeCard> {
   }
 
   void changeAddress({required String address}) {
-    setState(() => addressController.text = address);
+    setState(() => addressController.text = _normalizeAddressFormat(address));
   }
 
   void changeAmount({required String amount}) {
@@ -222,7 +230,7 @@ class ExchangeCardState extends State<ExchangeCard> {
         Divider(height: 1, color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
         Padding(
           padding: EdgeInsets.only(top: 5),
-          child: Container(
+          child: widget.showLimitsField ? Container(
               height: 15,
               child: Row(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
                 _min != null
@@ -247,7 +255,7 @@ class ExchangeCardState extends State<ExchangeCard> {
                         ),
                       )
                     : Offstage(),
-              ])),
+              ])) : Offstage(),
         ),
         !_isAddressEditable && widget.hasRefundAddress
             ? Padding(
@@ -261,10 +269,11 @@ class ExchangeCardState extends State<ExchangeCard> {
                 ))
             : Offstage(),
         _isAddressEditable
+            ? widget.showAddressField
             ? FocusTraversalOrder(
                 order: NumericFocusOrder(2),
                 child: Padding(
-                  padding: EdgeInsets.only(top: 20),
+                  padding: widget.addressRowPadding ?? EdgeInsets.only(top: 20),
                   child: AddressTextField(
                       addressKey: ValueKey('${_cardInstanceName}_editable_address_textfield_key'),
                       focusNode: widget.addressFocusNode,
@@ -280,26 +289,29 @@ class ExchangeCardState extends State<ExchangeCard> {
                         widget.amountFocusNode?.requestFocus();
                         amountController.text = paymentRequest.amount;
                       },
-                      placeholder: widget.hasRefundAddress ? S.of(context).refund_address : null,
+                      placeholder:
+                      widget.hasRefundAddress ? S.of(context).refund_address : null,
                       options: [
                         AddressTextFieldOption.paste,
                         AddressTextFieldOption.qrCode,
                         AddressTextFieldOption.addressBook,
                       ],
                       isBorderExist: false,
-                      textStyle:
-                          TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
+                      textStyle: TextStyle(
+                          fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
                       hintStyle: TextStyle(
                           fontSize: 16,
                           fontWeight: FontWeight.w600,
-                          color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor),
+                          color:
+                          Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor),
                       buttonColor: widget.addressButtonsColor,
                       validator: widget.addressTextFieldValidator,
                       onPushPasteButton: widget.onPushPasteButton,
                       onPushAddressBookButton: widget.onPushAddressBookButton,
                       selectedCurrency: _selectedCurrency),
                 ),
-              )
+        )
+            : Offstage()
             : Padding(
                 padding: EdgeInsets.only(top: 10),
                 child: Builder(
@@ -402,7 +414,7 @@ class ExchangeCardState extends State<ExchangeCard> {
         hintText: S.of(context).search_currency,
         isMoneroWallet: _isMoneroWallet,
         isConvertFrom: widget.hasRefundAddress,
-        onItemSelected: (Currency item) => widget.onCurrencySelected(item as CryptoCurrency),
+        onItemSelected: (Currency item) => widget.onCurrencySelected(item as T),
       ),
     );
   }
@@ -424,4 +436,10 @@ class ExchangeCardState extends State<ExchangeCard> {
               actionLeftButton: () => Navigator.of(dialogContext).pop());
         });
   }
+
+  String _normalizeAddressFormat(String address) {
+    if (address.startsWith('bitcoincash:')) address = address.substring(12);
+    return address;
+  }
 }
+
diff --git a/lib/src/screens/exchange/widgets/mobile_exchange_cards_section.dart b/lib/src/screens/exchange/widgets/mobile_exchange_cards_section.dart
index 126bca835..d53f16339 100644
--- a/lib/src/screens/exchange/widgets/mobile_exchange_cards_section.dart
+++ b/lib/src/screens/exchange/widgets/mobile_exchange_cards_section.dart
@@ -1,20 +1,29 @@
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
 import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
+import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
 import 'package:flutter/material.dart';
 
 class MobileExchangeCardsSection extends StatelessWidget {
   final Widget firstExchangeCard;
   final Widget secondExchangeCard;
+  final bool isBuySellOption;
+  final VoidCallback? onBuyTap;
+  final VoidCallback? onSellTap;
 
   const MobileExchangeCardsSection({
     Key? key,
     required this.firstExchangeCard,
     required this.secondExchangeCard,
+    this.isBuySellOption = false,
+    this.onBuyTap,
+    this.onSellTap,
   }) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
     return Container(
-      padding: EdgeInsets.only(bottom: 32),
+      padding: EdgeInsets.only(bottom: isBuySellOption ? 8 : 32),
       decoration: BoxDecoration(
         borderRadius: BorderRadius.only(
           bottomLeft: Radius.circular(24),
@@ -45,8 +54,18 @@ class MobileExchangeCardsSection extends StatelessWidget {
                 end: Alignment.bottomRight,
               ),
             ),
-            padding: EdgeInsets.fromLTRB(24, 100, 24, 32),
-            child: firstExchangeCard,
+            padding: EdgeInsets.fromLTRB(24, 90, 24, isBuySellOption ? 8 : 32),
+            child: Column(
+              children: [
+                if (isBuySellOption) Column(
+                  children: [
+                    const SizedBox(height: 16),
+                    BuySellOptionButtons(onBuyTap: onBuyTap, onSellTap: onSellTap),
+                  ],
+                ),
+                firstExchangeCard,
+              ],
+            ),
           ),
           Padding(
             padding: EdgeInsets.only(top: 29, left: 24, right: 24),
@@ -57,3 +76,69 @@ class MobileExchangeCardsSection extends StatelessWidget {
     );
   }
 }
+
+class BuySellOptionButtons extends StatefulWidget {
+  final VoidCallback? onBuyTap;
+  final VoidCallback? onSellTap;
+
+  const BuySellOptionButtons({this.onBuyTap, this.onSellTap});
+
+  @override
+  _BuySellOptionButtonsState createState() => _BuySellOptionButtonsState();
+}
+
+class _BuySellOptionButtonsState extends State<BuySellOptionButtons> {
+  bool isBuySelected = true;
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.only(bottom: 24),
+      child: Row(
+        children: [
+          Expanded(flex: 2, child: SizedBox()),
+          Expanded(
+            flex: 5,
+            child: SelectButton(
+              height: 44,
+              text: S.of(context).buy,
+              isSelected: isBuySelected,
+              showTrailingIcon: false,
+              textColor: Colors.white,
+              image: Image.asset('assets/images/buy.png', height: 25, width: 25),
+              padding: EdgeInsets.only(left: 10, right: 30),
+              color: isBuySelected
+                  ? null
+                  : Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
+              onTap: () {
+                setState(() => isBuySelected = true);
+                if (widget.onBuyTap != null) widget.onBuyTap!();
+              },
+            ),
+          ),
+          Expanded(child: const SizedBox()),
+          Expanded(
+            flex: 5,
+            child: SelectButton(
+              height: 44,
+              text: S.of(context).sell,
+              isSelected: !isBuySelected,
+              showTrailingIcon: false,
+              textColor: Colors.white,
+              image: Image.asset('assets/images/sell.png', height: 25, width: 25),
+              padding: EdgeInsets.only(left: 10, right: 30),
+              color: !isBuySelected
+                  ? null
+                  : Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
+              onTap: () {
+                setState(() => isBuySelected = false);
+                if (widget.onSellTap != null) widget.onSellTap!();
+              },
+            ),
+          ),
+          Expanded(flex: 2, child: SizedBox()),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/src/screens/seed/pre_seed_page.dart b/lib/src/screens/seed/pre_seed_page.dart
index 23de4564f..475f45fca 100644
--- a/lib/src/screens/seed/pre_seed_page.dart
+++ b/lib/src/screens/seed/pre_seed_page.dart
@@ -1,6 +1,6 @@
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/routes.dart';
-import 'package:cake_wallet/src/screens/InfoPage.dart';
+import 'package:cake_wallet/src/screens/Info_page.dart';
 import 'package:flutter/cupertino.dart';
 
 class PreSeedPage extends InfoPage {
diff --git a/lib/src/screens/select_options_page.dart b/lib/src/screens/select_options_page.dart
new file mode 100644
index 000000000..70cb2abc1
--- /dev/null
+++ b/lib/src/screens/select_options_page.dart
@@ -0,0 +1,199 @@
+import 'package:cake_wallet/core/selectable_option.dart';
+import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/widgets/primary_button.dart';
+import 'package:cake_wallet/src/widgets/provider_optoin_tile.dart';
+import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
+import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
+import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
+import 'package:flutter/material.dart';
+
+abstract class SelectOptionsPage extends BasePage {
+  SelectOptionsPage();
+
+  String get pageTitle;
+
+  EdgeInsets? get contentPadding;
+
+  EdgeInsets? get tilePadding;
+
+  EdgeInsets? get innerPadding;
+
+  double? get imageHeight;
+
+  double? get imageWidth;
+
+  Color? get selectedBackgroundColor;
+
+  double? get tileBorderRadius;
+
+  String get bottomSectionText;
+
+  bool get primaryButtonEnabled => true;
+
+  String get primaryButtonText => '';
+
+  List<SelectableItem> get items;
+
+  void Function(SelectableOption option)? get onOptionTap;
+
+  void Function(BuildContext context)? get primaryButtonAction;
+
+  @override
+  String get title => pageTitle;
+
+  @override
+  Widget body(BuildContext context) {
+    return ScrollableWithBottomSection(
+      content: BodySelectOptionsPage(
+          items: items,
+          onOptionTap: onOptionTap,
+          tilePadding: tilePadding,
+          tileBorderRadius: tileBorderRadius,
+          imageHeight: imageHeight,
+          imageWidth: imageWidth,
+          innerPadding: innerPadding),
+      bottomSection: Padding(
+        padding: contentPadding ?? EdgeInsets.zero,
+        child: Column(
+          children: [
+            Text(
+              bottomSectionText,
+              textAlign: TextAlign.center,
+              style: TextStyle(
+                fontSize: 14,
+                fontWeight: FontWeight.normal,
+                color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
+              ),
+            ),
+            if (primaryButtonEnabled)
+              LoadingPrimaryButton(
+                  text: primaryButtonText,
+                  onPressed: () {
+                    primaryButtonAction != null
+                        ? primaryButtonAction!(context)
+                        : Navigator.pop(context);
+                  },
+                  color: Theme.of(context).primaryColor,
+                  textColor: Colors.white,
+                  isDisabled: false,
+                  isLoading: false)
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+class BodySelectOptionsPage extends StatefulWidget {
+  const BodySelectOptionsPage({
+    required this.items,
+    this.onOptionTap,
+    this.tilePadding,
+    this.tileBorderRadius,
+    this.imageHeight,
+    this.imageWidth,
+    this.innerPadding,
+  });
+
+  final List<SelectableItem> items;
+  final void Function(SelectableOption option)? onOptionTap;
+  final EdgeInsets? tilePadding;
+  final double? tileBorderRadius;
+  final double? imageHeight;
+  final double? imageWidth;
+  final EdgeInsets? innerPadding;
+
+  @override
+  _BodySelectOptionsPageState createState() => _BodySelectOptionsPageState();
+}
+
+class _BodySelectOptionsPageState extends State<BodySelectOptionsPage> {
+  late List<SelectableItem> _items;
+
+  @override
+  void initState() {
+    super.initState();
+    _items = widget.items;
+  }
+
+  void _handleOptionTap(SelectableOption option) {
+    setState(() {
+      for (var item in _items) {
+        if (item is SelectableOption) {
+          item.isOptionSelected = false;
+        }
+      }
+      option.isOptionSelected = true;
+    });
+    widget.onOptionTap?.call(option);
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final isLightMode = Theme.of(context).extension<OptionTileTheme>()?.useDarkImage ?? false;
+
+    Color titleColor =
+        isLightMode ? Theme.of(context).appBarTheme.titleTextStyle!.color! : Colors.white;
+
+    return Center(
+      child: ConstrainedBox(
+        constraints: const BoxConstraints(maxWidth: 350),
+        child: Column(
+          children: _items.map((item) {
+            if (item is OptionTitle) {
+              return Padding(
+                padding: const EdgeInsets.only(top: 18, bottom: 8),
+                child: Container(
+                  width: double.infinity,
+                  decoration: BoxDecoration(
+                    border: Border(
+                      bottom: BorderSide(
+                        color: titleColor,
+                        width: 1,
+                      ),
+                    ),
+                  ),
+                  child: Padding(
+                    padding: const EdgeInsets.only(bottom: 8.0),
+                    child: Text(
+                      item.title,
+                      style: TextStyle(
+                        fontSize: 18,
+                        fontWeight: FontWeight.w700,
+                        color: titleColor,
+                      ),
+                    ),
+                  ),
+                ),
+              );
+            } else if (item is SelectableOption) {
+              return Padding(
+                padding: widget.tilePadding ?? const EdgeInsets.only(top: 24),
+                child: ProviderOptionTile(
+                  title: item.title,
+                  lightImagePath: item.lightIconPath,
+                  darkImagePath: item.darkIconPath,
+                  imageHeight: widget.imageHeight,
+                  imageWidth: widget.imageWidth,
+                  padding: widget.innerPadding,
+                  description: item.description,
+                  topLeftSubTitle: item.topLeftSubTitle,
+                  topRightSubTitle: item.topRightSubTitle,
+                  rightSubTitleLightIconPath: item.topRightSubTitleLightIconPath,
+                  rightSubTitleDarkIconPath: item.topRightSubTitleDarkIconPath,
+                  bottomLeftSubTitle: item.bottomLeftSubTitle,
+                  badges: item.badges,
+                  isSelected: item.isOptionSelected,
+                  borderRadius: widget.tileBorderRadius,
+                  isLightMode: isLightMode,
+                  onPressed: () => _handleOptionTap(item),
+                ),
+              );
+            }
+            return const SizedBox.shrink();
+          }).toList(),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/src/screens/settings/other_settings_page.dart b/lib/src/screens/settings/other_settings_page.dart
index 137f699f5..f6a6288f5 100644
--- a/lib/src/screens/settings/other_settings_page.dart
+++ b/lib/src/screens/settings/other_settings_page.dart
@@ -57,22 +57,6 @@ class OtherSettingsPage extends BasePage {
                   handler: (BuildContext context) =>
                       Navigator.of(context).pushNamed(Routes.changeRep),
                 ),
-              if(_otherSettingsViewModel.isEnabledBuyAction)
-              SettingsPickerCell(
-                title: S.current.default_buy_provider,
-                items: _otherSettingsViewModel.availableBuyProvidersTypes,
-                displayItem: _otherSettingsViewModel.getBuyProviderType,
-                selectedItem: _otherSettingsViewModel.buyProviderType,
-                onItemSelected: _otherSettingsViewModel.onBuyProviderTypeSelected
-              ),
-              if(_otherSettingsViewModel.isEnabledSellAction)
-              SettingsPickerCell(
-                title: S.current.default_sell_provider,
-                items: _otherSettingsViewModel.availableSellProvidersTypes,
-                displayItem: _otherSettingsViewModel.getSellProviderType,
-                selectedItem: _otherSettingsViewModel.sellProviderType,
-                onItemSelected: _otherSettingsViewModel.onSellProviderTypeSelected,
-              ),
               SettingsCellWithArrow(
                 title: S.current.settings_terms_and_conditions,
                 handler: (BuildContext context) =>
diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart
index 53e7686e8..8652c4af6 100644
--- a/lib/src/screens/settings/privacy_page.dart
+++ b/lib/src/screens/settings/privacy_page.dart
@@ -73,16 +73,10 @@ class PrivacyPage extends BasePage {
                       _privacySettingsViewModel.setIsAppSecure(value);
                     }),
               SettingsSwitcherCell(
-                  title: S.current.disable_buy,
-                  value: _privacySettingsViewModel.disableBuy,
+                  title: S.current.disable_trade_option,
+                  value: _privacySettingsViewModel.disableTradeOption,
                   onValueChange: (BuildContext _, bool value) {
-                    _privacySettingsViewModel.setDisableBuy(value);
-                  }),
-              SettingsSwitcherCell(
-                  title: S.current.disable_sell,
-                  value: _privacySettingsViewModel.disableSell,
-                  onValueChange: (BuildContext _, bool value) {
-                    _privacySettingsViewModel.setDisableSell(value);
+                    _privacySettingsViewModel.setDisableTradeOption(value);
                   }),
               SettingsSwitcherCell(
                   title: S.current.disable_bulletin,
diff --git a/lib/src/screens/setup_2fa/setup_2fa_info_page.dart b/lib/src/screens/setup_2fa/setup_2fa_info_page.dart
index 8aa0ac3c9..834d01c26 100644
--- a/lib/src/screens/setup_2fa/setup_2fa_info_page.dart
+++ b/lib/src/screens/setup_2fa/setup_2fa_info_page.dart
@@ -1,6 +1,6 @@
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/routes.dart';
-import 'package:cake_wallet/src/screens/InfoPage.dart';
+import 'package:cake_wallet/src/screens/Info_page.dart';
 import 'package:flutter/cupertino.dart';
 
 class Setup2FAInfoPage extends InfoPage {
diff --git a/lib/src/widgets/address_text_field.dart b/lib/src/widgets/address_text_field.dart
index d904768f0..9b407dedb 100644
--- a/lib/src/widgets/address_text_field.dart
+++ b/lib/src/widgets/address_text_field.dart
@@ -1,20 +1,21 @@
 import 'package:cake_wallet/utils/device_info.dart';
 import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
+import 'package:cw_core/currency.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter/material.dart';
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/entities/qr_scanner.dart';
 import 'package:cake_wallet/entities/contact_base.dart';
-import 'package:cw_core/crypto_currency.dart';
 import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
 import 'package:cake_wallet/utils/permission_handler.dart';
 import 'package:permission_handler/permission_handler.dart';
 
 enum AddressTextFieldOption { paste, qrCode, addressBook, walletAddresses }
 
-class AddressTextField extends StatelessWidget {
+
+class AddressTextField<T extends Currency> extends StatelessWidget{
   AddressTextField({
     required this.controller,
     this.isActive = true,
@@ -58,7 +59,7 @@ class AddressTextField extends StatelessWidget {
   final Function(BuildContext context)? onPushAddressBookButton;
   final Function(BuildContext context)? onPushAddressPickerButton;
   final Function(ContactBase contact)? onSelectedContact;
-  final CryptoCurrency? selectedCurrency;
+  final T? selectedCurrency;
   final Key? addressKey;
 
   @override
diff --git a/lib/src/widgets/provider_optoin_tile.dart b/lib/src/widgets/provider_optoin_tile.dart
new file mode 100644
index 000000000..85396a97d
--- /dev/null
+++ b/lib/src/widgets/provider_optoin_tile.dart
@@ -0,0 +1,527 @@
+import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
+import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
+import 'package:cake_wallet/typography.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+
+class ProviderOptionTile extends StatelessWidget {
+  const ProviderOptionTile({
+    required this.onPressed,
+    required this.lightImagePath,
+    required this.darkImagePath,
+    required this.title,
+    this.topLeftSubTitle,
+    this.topRightSubTitle,
+    this.bottomLeftSubTitle,
+    this.bottomRightSubTitle,
+    this.leftSubTitleIconPath,
+    this.rightSubTitleLightIconPath,
+    this.rightSubTitleDarkIconPath,
+    this.description,
+    this.badges,
+    this.borderRadius,
+    this.imageHeight,
+    this.imageWidth,
+    this.padding,
+    this.titleTextStyle,
+    this.firstSubTitleTextStyle,
+    this.secondSubTitleTextStyle,
+    this.leadingIcon,
+    this.selectedBackgroundColor,
+    this.isSelected = false,
+    required this.isLightMode,
+  });
+
+  final VoidCallback onPressed;
+  final String lightImagePath;
+  final String darkImagePath;
+  final String title;
+  final String? topLeftSubTitle;
+  final String? topRightSubTitle;
+  final String? bottomLeftSubTitle;
+  final String? bottomRightSubTitle;
+  final String? leftSubTitleIconPath;
+  final String? rightSubTitleLightIconPath;
+  final String? rightSubTitleDarkIconPath;
+  final String? description;
+  final List<String>? badges;
+  final double? borderRadius;
+  final double? imageHeight;
+  final double? imageWidth;
+  final EdgeInsets? padding;
+  final TextStyle? titleTextStyle;
+  final TextStyle? firstSubTitleTextStyle;
+  final TextStyle? secondSubTitleTextStyle;
+  final IconData? leadingIcon;
+  final Color? selectedBackgroundColor;
+  final bool isSelected;
+  final bool isLightMode;
+
+  @override
+  Widget build(BuildContext context) {
+    final backgroundColor = isSelected
+        ? isLightMode
+            ? Theme.of(context).extension<ReceivePageTheme>()!.currentTileBackgroundColor
+            : Theme.of(context).extension<OptionTileTheme>()!.titleColor
+        : Theme.of(context).cardColor;
+
+    final textColor = isSelected
+        ? isLightMode
+            ? Colors.white
+            : Theme.of(context).cardColor
+        : Theme.of(context).extension<OptionTileTheme>()!.titleColor;
+
+    final badgeColor = isSelected
+        ? Theme.of(context).cardColor
+        : Theme.of(context).extension<OptionTileTheme>()!.titleColor;
+
+    final badgeTextColor = isSelected
+        ? Theme.of(context).extension<OptionTileTheme>()!.titleColor
+        : Theme.of(context).cardColor;
+
+    final imagePath = isSelected
+        ? isLightMode
+            ? darkImagePath
+            : lightImagePath
+        : isLightMode
+            ? lightImagePath
+            : darkImagePath;
+
+    final rightSubTitleIconPath = isSelected
+        ? isLightMode
+            ? rightSubTitleDarkIconPath
+            : rightSubTitleLightIconPath
+        : isLightMode
+            ? rightSubTitleLightIconPath
+            : rightSubTitleDarkIconPath;
+
+    return GestureDetector(
+      onTap: onPressed,
+      child: Container(
+        width: double.infinity,
+        alignment: Alignment.center,
+        decoration: BoxDecoration(
+          borderRadius: BorderRadius.all(Radius.circular(borderRadius ?? 12)),
+          border: isSelected && !isLightMode ? Border.all(color: textColor) : null,
+          color: backgroundColor,
+        ),
+        child: Padding(
+          padding: padding ?? const EdgeInsets.all(16),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              Row(
+                children: [
+                  getImage(imagePath, height: imageHeight, width: imageWidth),
+                  SizedBox(width: 8),
+                  Expanded(
+                    child: Container(
+                      child: Row(
+                        children: [
+                          Expanded(
+                              child: Text(title,
+                                  style: titleTextStyle ?? textLargeBold(color: textColor))),
+                          Row(
+                            children: [
+                              if (leadingIcon != null)
+                                Icon(leadingIcon, size: 16, color: textColor),
+                            ],
+                          )
+                        ],
+                      ),
+                    ),
+                  ),
+                ],
+              ),
+              if (topLeftSubTitle != null || topRightSubTitle != null)
+                subTitleWidget(
+                    leftSubTitle: topLeftSubTitle,
+                    subTitleIconPath: leftSubTitleIconPath,
+                    textColor: textColor,
+                    rightSubTitle: topRightSubTitle,
+                    rightSubTitleIconPath: rightSubTitleIconPath),
+              if (bottomLeftSubTitle != null || bottomRightSubTitle != null)
+                subTitleWidget(
+                    leftSubTitle: bottomLeftSubTitle,
+                    textColor: textColor,
+                    subTitleFontSize: 12),
+              if (badges != null && badges!.isNotEmpty)
+                Padding(
+                  padding: const EdgeInsets.only(top: 12),
+                  child: Row(children: [
+                    ...badges!
+                        .map((badge) => Badge(
+                            title: badge, textColor: badgeTextColor, backgroundColor: badgeColor))
+                        .toList()
+                  ]),
+                )
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}
+
+class subTitleWidget extends StatelessWidget {
+  const subTitleWidget({
+    super.key,
+    this.leftSubTitle,
+    this.subTitleIconPath,
+    required this.textColor,
+    this.rightSubTitle,
+    this.rightSubTitleIconPath,
+    this.subTitleFontSize = 16,
+  });
+
+  final String? leftSubTitle;
+  final String? subTitleIconPath;
+  final Color textColor;
+  final String? rightSubTitle;
+  final String? rightSubTitleIconPath;
+  final double subTitleFontSize;
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+      children: [
+        leftSubTitle != null || subTitleIconPath != null
+            ? Row(
+              children: [
+                if (subTitleIconPath != null && subTitleIconPath!.isNotEmpty)
+                  Padding(
+                    padding: const EdgeInsets.only(right: 6),
+                    child: getImage(subTitleIconPath!),
+                  ),
+                Text(
+                  leftSubTitle ?? '',
+                  style: TextStyle(
+                      fontSize: subTitleFontSize,
+                      fontWeight: FontWeight.w700,
+                      color: textColor),
+                ),
+              ],
+            )
+            : Offstage(),
+        rightSubTitle != null || rightSubTitleIconPath != null
+            ? Row(
+                children: [
+                  if (rightSubTitleIconPath != null && rightSubTitleIconPath!.isNotEmpty)
+                    Padding(
+                      padding: const EdgeInsets.only(right: 4),
+                      child: getImage(rightSubTitleIconPath!, imageColor: textColor),
+                    ),
+                  Text(
+                    rightSubTitle ?? '',
+                    style: TextStyle(
+                        fontSize: subTitleFontSize, fontWeight: FontWeight.w700, color: textColor),
+                  ),
+                ],
+              )
+            : Offstage(),
+      ],
+    );
+  }
+}
+
+class Badge extends StatelessWidget {
+  Badge({required this.textColor, required this.backgroundColor, required this.title});
+
+  final String title;
+  final Color textColor;
+  final Color backgroundColor;
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.only(right: 8),
+      child: FittedBox(
+        fit: BoxFit.fitHeight,
+        child: Container(
+          padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4),
+          decoration: BoxDecoration(
+              borderRadius: BorderRadius.all(Radius.circular(24)), color: backgroundColor),
+          alignment: Alignment.center,
+          child: Text(
+            title,
+            style: TextStyle(
+              color: textColor,
+              fontSize: 12,
+              fontWeight: FontWeight.w600,
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+}
+
+Widget getImage(String imagePath, {double? height, double? width, Color? imageColor}) {
+  final bool isNetworkImage = imagePath.startsWith('http') || imagePath.startsWith('https');
+  final bool isSvg = imagePath.endsWith('.svg');
+  final double imageHeight = height ?? 35;
+  final double imageWidth = width ?? 35;
+
+  if (isNetworkImage) {
+    return isSvg
+        ? SvgPicture.network(
+            imagePath,
+            height: imageHeight,
+            width: imageWidth,
+            colorFilter: imageColor != null ? ColorFilter.mode(imageColor, BlendMode.srcIn) : null,
+            placeholderBuilder: (BuildContext context) => Container(
+              height: imageHeight,
+              width: imageWidth,
+              child: Center(
+                child: CircularProgressIndicator(),
+              ),
+            ),
+          )
+        : Image.network(
+            imagePath,
+            height: imageHeight,
+            width: imageWidth,
+            loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
+              if (loadingProgress == null) {
+                return child;
+              }
+              return Container(
+                height: imageHeight,
+                width: imageWidth,
+                child: Center(
+                  child: CircularProgressIndicator(
+                    value: loadingProgress.expectedTotalBytes != null
+                        ? loadingProgress.cumulativeBytesLoaded /
+                            loadingProgress.expectedTotalBytes!
+                        : null,
+                  ),
+                ),
+              );
+            },
+            errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) {
+              return Container(
+                height: imageHeight,
+                width: imageWidth,
+              );
+            },
+          );
+  } else {
+    return isSvg
+        ? SvgPicture.asset(
+            imagePath,
+            height: imageHeight,
+            width: imageWidth,
+            colorFilter: imageColor != null ? ColorFilter.mode(imageColor, BlendMode.srcIn) : null,
+          )
+        : Image.asset(imagePath, height: imageHeight, width: imageWidth);
+  }
+}
+
+class OptionTilePlaceholder extends StatefulWidget {
+  OptionTilePlaceholder({
+    this.borderRadius,
+    this.imageHeight,
+    this.imageWidth,
+    this.padding,
+    this.leadingIcon,
+    this.withBadge = true,
+    this.withSubtitle = true,
+    this.isDarkTheme = false,
+    this.errorText,
+  });
+
+  final double? borderRadius;
+  final double? imageHeight;
+  final double? imageWidth;
+  final EdgeInsets? padding;
+  final IconData? leadingIcon;
+  final bool withBadge;
+  final bool withSubtitle;
+  final bool isDarkTheme;
+  final String? errorText;
+
+  @override
+  _OptionTilePlaceholderState createState() => _OptionTilePlaceholderState();
+}
+
+class _OptionTilePlaceholderState extends State<OptionTilePlaceholder>
+    with SingleTickerProviderStateMixin {
+  late AnimationController _controller;
+  late Animation<double> _animation;
+
+  @override
+  void initState() {
+    super.initState();
+
+    _controller = AnimationController(
+      duration: const Duration(seconds: 2),
+      vsync: this,
+    )..repeat();
+
+    _animation = CurvedAnimation(
+      parent: _controller,
+      curve: Curves.linear,
+    );
+  }
+
+  @override
+  void dispose() {
+    _controller.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final backgroundColor = Theme.of(context).cardColor;
+    final titleColor = Theme.of(context).extension<OptionTileTheme>()!.titleColor.withOpacity(0.4);
+
+    return widget.errorText != null
+        ? Container(
+            width: double.infinity,
+            padding: widget.padding ?? EdgeInsets.all(16),
+            alignment: Alignment.center,
+            decoration: BoxDecoration(
+              borderRadius: BorderRadius.all(Radius.circular(widget.borderRadius ?? 12)),
+              color: backgroundColor,
+            ),
+            child: Column(
+              children: [
+                Text(
+                  widget.errorText!,
+                  style: TextStyle(
+                    color: titleColor,
+                    fontSize: 16,
+                  ),
+                ),
+                if (widget.withSubtitle) SizedBox(height: 8),
+                Text(
+                  '',
+                  style: TextStyle(
+                    color: titleColor,
+                    fontSize: 16,
+                  ),
+                ),
+              ],
+            ),
+          )
+        : AnimatedBuilder(
+            animation: _animation,
+            builder: (context, child) {
+              return Stack(
+                children: [
+                  Container(
+                    width: double.infinity,
+                    padding: widget.padding ?? EdgeInsets.all(16),
+                    alignment: Alignment.center,
+                    decoration: BoxDecoration(
+                      borderRadius: BorderRadius.all(Radius.circular(widget.borderRadius ?? 12)),
+                      color: backgroundColor,
+                    ),
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.center,
+                      children: [
+                        Row(
+                          children: [
+                            Container(
+                              height: widget.imageHeight ?? 35,
+                              width: widget.imageWidth ?? 35,
+                              decoration: BoxDecoration(
+                                color: titleColor,
+                                shape: BoxShape.circle,
+                              ),
+                            ),
+                            SizedBox(width: 8),
+                            Expanded(
+                              child: Container(
+                                child: Row(
+                                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                                  children: [
+                                    Container(
+                                      height: 20,
+                                      width: 70,
+                                      decoration: BoxDecoration(
+                                        color: titleColor,
+                                        borderRadius: BorderRadius.all(Radius.circular(8)),
+                                      ),
+                                    ),
+                                    if (widget.leadingIcon != null)
+                                      Icon(widget.leadingIcon, size: 16, color: titleColor),
+                                  ],
+                                ),
+                              ),
+                            ),
+                          ],
+                        ),
+                        if (widget.withSubtitle)
+                          Padding(
+                            padding: EdgeInsets.symmetric(vertical: 8),
+                            child: Row(
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              children: [
+                                Container(
+                                  height: 20,
+                                  width: 170,
+                                  decoration: BoxDecoration(
+                                    color: titleColor,
+                                    borderRadius: BorderRadius.all(Radius.circular(8)),
+                                  ),
+                                ),
+                              ],
+                            ),
+                          ),
+                        if (widget.withBadge)
+                          Padding(
+                            padding: const EdgeInsets.only(top: 16.0),
+                            child: Row(
+                              children: [
+                                Container(
+                                  height: 30,
+                                  width: 70,
+                                  decoration: BoxDecoration(
+                                    color: titleColor,
+                                    borderRadius: BorderRadius.all(Radius.circular(20)),
+                                  ),
+                                ),
+                                SizedBox(width: 8),
+                                Container(
+                                  height: 30,
+                                  width: 70,
+                                  decoration: BoxDecoration(
+                                    color: titleColor,
+                                    borderRadius: BorderRadius.all(Radius.circular(20)),
+                                  ),
+                                ),
+                              ],
+                            ),
+                          ),
+                      ],
+                    ),
+                  ),
+                  Positioned.fill(
+                    child: Container(
+                      decoration: BoxDecoration(
+                        borderRadius: BorderRadius.all(Radius.circular(widget.borderRadius ?? 12)),
+                        gradient: LinearGradient(
+                          begin: Alignment(-2, -4),
+                          end: Alignment(2, 4),
+                          stops: [
+                            _animation.value - 0.2,
+                            _animation.value,
+                            _animation.value + 0.2,
+                          ],
+                          colors: [
+                            backgroundColor.withOpacity(widget.isDarkTheme ? 0.4 : 0.7),
+                            backgroundColor.withOpacity(widget.isDarkTheme ? 0.7 : 0.4),
+                            backgroundColor.withOpacity(widget.isDarkTheme ? 0.4 : 0.7),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ),
+                ],
+              );
+            },
+          );
+  }
+}
diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart
index 50d51d2ed..1ecaf50cc 100644
--- a/lib/store/settings_store.dart
+++ b/lib/store/settings_store.dart
@@ -61,8 +61,7 @@ abstract class SettingsStoreBase with Store {
       required BitcoinSeedType initialBitcoinSeedType,
       required NanoSeedType initialNanoSeedType,
       required bool initialAppSecure,
-      required bool initialDisableBuy,
-      required bool initialDisableSell,
+      required bool initialDisableTrade,
       required FilterListOrderType initialWalletListOrder,
       required FilterListOrderType initialContactListOrder,
       required bool initialDisableBulletin,
@@ -150,8 +149,7 @@ abstract class SettingsStoreBase with Store {
         useTOTP2FA = initialUseTOTP2FA,
         numberOfFailedTokenTrials = initialFailedTokenTrial,
         isAppSecure = initialAppSecure,
-        disableBuy = initialDisableBuy,
-        disableSell = initialDisableSell,
+        disableTradeOption = initialDisableTrade,
         disableBulletin = initialDisableBulletin,
         walletListOrder = initialWalletListOrder,
         contactListOrder = initialContactListOrder,
@@ -178,9 +176,7 @@ abstract class SettingsStoreBase with Store {
             initialShouldRequireTOTP2FAForAllSecurityAndBackupSettings,
         currentSyncMode = initialSyncMode,
         currentSyncAll = initialSyncAll,
-        priority = ObservableMap<WalletType, TransactionPriority>(),
-        defaultBuyProviders = ObservableMap<WalletType, ProviderType>(),
-        defaultSellProviders = ObservableMap<WalletType, ProviderType>() {
+        priority = ObservableMap<WalletType, TransactionPriority>() {
     //this.nodes = ObservableMap<WalletType, Node>.of(nodes);
 
     if (initialMoneroTransactionPriority != null) {
@@ -221,30 +217,6 @@ abstract class SettingsStoreBase with Store {
 
     initializeTrocadorProviderStates();
 
-    WalletType.values.forEach((walletType) {
-      final key = 'buyProvider_${walletType.toString()}';
-      final providerId = sharedPreferences.getString(key);
-      if (providerId != null) {
-        defaultBuyProviders[walletType] = ProviderType.values.firstWhere(
-            (provider) => provider.id == providerId,
-            orElse: () => ProviderType.askEachTime);
-      } else {
-        defaultBuyProviders[walletType] = ProviderType.askEachTime;
-      }
-    });
-
-    WalletType.values.forEach((walletType) {
-      final key = 'sellProvider_${walletType.toString()}';
-      final providerId = sharedPreferences.getString(key);
-      if (providerId != null) {
-        defaultSellProviders[walletType] = ProviderType.values.firstWhere(
-            (provider) => provider.id == providerId,
-            orElse: () => ProviderType.askEachTime);
-      } else {
-        defaultSellProviders[walletType] = ProviderType.askEachTime;
-      }
-    });
-
     reaction(
         (_) => fiatCurrency,
         (FiatCurrency fiatCurrency) => sharedPreferences.setString(
@@ -267,20 +239,6 @@ abstract class SettingsStoreBase with Store {
     reaction((_) => shouldShowRepWarning,
         (bool val) => sharedPreferences.setBool(PreferencesKey.shouldShowRepWarning, val));
 
-    defaultBuyProviders.observe((change) {
-      final String key = 'buyProvider_${change.key.toString()}';
-      if (change.newValue != null) {
-        sharedPreferences.setString(key, change.newValue!.id);
-      }
-    });
-
-    defaultSellProviders.observe((change) {
-      final String key = 'sellProvider_${change.key.toString()}';
-      if (change.newValue != null) {
-        sharedPreferences.setString(key, change.newValue!.id);
-      }
-    });
-
     priority.observe((change) {
       final String? key;
       switch (change.key) {
@@ -329,14 +287,9 @@ abstract class SettingsStoreBase with Store {
       });
     }
 
-    reaction((_) => disableBuy,
-        (bool disableBuy) => sharedPreferences.setBool(PreferencesKey.disableBuyKey, disableBuy));
-
-    reaction(
-        (_) => disableSell,
-        (bool disableSell) =>
-            sharedPreferences.setBool(PreferencesKey.disableSellKey, disableSell));
-
+    reaction((_) => disableTradeOption,
+        (bool disableTradeOption) => sharedPreferences.setBool(PreferencesKey.disableTradeOption, disableTradeOption));
+    
     reaction(
         (_) => disableBulletin,
         (bool disableBulletin) =>
@@ -680,10 +633,7 @@ abstract class SettingsStoreBase with Store {
   bool isAppSecure;
 
   @observable
-  bool disableBuy;
-
-  @observable
-  bool disableSell;
+  bool disableTradeOption;
 
   @observable
   FilterListOrderType contactListOrder;
@@ -769,12 +719,6 @@ abstract class SettingsStoreBase with Store {
   @observable
   ObservableMap<String, bool> trocadorProviderStates = ObservableMap<String, bool>();
 
-  @observable
-  ObservableMap<WalletType, ProviderType> defaultBuyProviders;
-
-  @observable
-  ObservableMap<WalletType, ProviderType> defaultSellProviders;
-
   @observable
   SortBalanceBy sortBalanceBy;
 
@@ -956,8 +900,7 @@ abstract class SettingsStoreBase with Store {
     final shouldSaveRecipientAddress =
         sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey) ?? false;
     final isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? false;
-    final disableBuy = sharedPreferences.getBool(PreferencesKey.disableBuyKey) ?? false;
-    final disableSell = sharedPreferences.getBool(PreferencesKey.disableSellKey) ?? false;
+    final disableTradeOption = sharedPreferences.getBool(PreferencesKey.disableTradeOption) ?? false;
     final disableBulletin = sharedPreferences.getBool(PreferencesKey.disableBulletinKey) ?? false;
     final walletListOrder =
         FilterListOrderType.values[sharedPreferences.getInt(PreferencesKey.walletListOrder) ?? 0];
@@ -1255,8 +1198,7 @@ abstract class SettingsStoreBase with Store {
       initialBitcoinSeedType: bitcoinSeedType,
       initialNanoSeedType: nanoSeedType,
       initialAppSecure: isAppSecure,
-      initialDisableBuy: disableBuy,
-      initialDisableSell: disableSell,
+      initialDisableTrade: disableTradeOption,
       initialDisableBulletin: disableBulletin,
       initialWalletListOrder: walletListOrder,
       initialWalletListAscending: walletListAscending,
@@ -1406,8 +1348,7 @@ abstract class SettingsStoreBase with Store {
     numberOfFailedTokenTrials =
         sharedPreferences.getInt(PreferencesKey.failedTotpTokenTrials) ?? numberOfFailedTokenTrials;
     isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? isAppSecure;
-    disableBuy = sharedPreferences.getBool(PreferencesKey.disableBuyKey) ?? disableBuy;
-    disableSell = sharedPreferences.getBool(PreferencesKey.disableSellKey) ?? disableSell;
+    disableTradeOption = sharedPreferences.getBool(PreferencesKey.disableTradeOption) ?? disableTradeOption;
     disableBulletin =
         sharedPreferences.getBool(PreferencesKey.disableBulletinKey) ?? disableBulletin;
     walletListOrder =
diff --git a/lib/typography.dart b/lib/typography.dart
index 8ae2cb4e5..816f116b4 100644
--- a/lib/typography.dart
+++ b/lib/typography.dart
@@ -22,6 +22,8 @@ TextStyle textMediumSemiBold({Color? color}) => _cakeSemiBold(22, color);
 
 TextStyle textLarge({Color? color}) => _cakeRegular(18, color);
 
+TextStyle textLargeBold({Color? color}) => _cakeBold(18, color);
+
 TextStyle textLargeSemiBold({Color? color}) => _cakeSemiBold(24, color);
 
 TextStyle textXLarge({Color? color}) => _cakeRegular(32, color);
diff --git a/lib/view_model/buy/buy_sell_view_model.dart b/lib/view_model/buy/buy_sell_view_model.dart
new file mode 100644
index 000000000..e1c53ee56
--- /dev/null
+++ b/lib/view_model/buy/buy_sell_view_model.dart
@@ -0,0 +1,446 @@
+import 'dart:async';
+
+import 'package:cake_wallet/buy/buy_provider.dart';
+import 'package:cake_wallet/buy/buy_quote.dart';
+import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
+import 'package:cake_wallet/buy/payment_method.dart';
+import 'package:cake_wallet/buy/sell_buy_states.dart';
+import 'package:cake_wallet/core/selectable_option.dart';
+import 'package:cake_wallet/core/wallet_change_listener_view_model.dart';
+import 'package:cake_wallet/entities/fiat_currency.dart';
+import 'package:cake_wallet/entities/provider_types.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/routes.dart';
+import 'package:cake_wallet/store/app_store.dart';
+import 'package:cake_wallet/store/settings_store.dart';
+import 'package:cake_wallet/themes/theme_base.dart';
+import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/currency_for_wallet_type.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:intl/intl.dart';
+import 'package:mobx/mobx.dart';
+
+part 'buy_sell_view_model.g.dart';
+
+class BuySellViewModel = BuySellViewModelBase with _$BuySellViewModel;
+
+abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with Store {
+  BuySellViewModelBase(
+    AppStore appStore,
+  )   : _cryptoNumberFormat = NumberFormat(),
+        cryptoAmount = '',
+        fiatAmount = '',
+        cryptoCurrencyAddress = '',
+        isCryptoCurrencyAddressEnabled = false,
+        cryptoCurrencies = <CryptoCurrency>[],
+        fiatCurrencies = <FiatCurrency>[],
+        paymentMethodState = InitialPaymentMethod(),
+        buySellQuotState = InitialBuySellQuotState(),
+        cryptoCurrency = appStore.wallet!.currency,
+        fiatCurrency = appStore.settingsStore.fiatCurrency,
+        providerList = [],
+        sortedRecommendedQuotes = ObservableList<Quote>(),
+        sortedQuotes = ObservableList<Quote>(),
+        paymentMethods = ObservableList<PaymentMethod>(),
+        settingsStore = appStore.settingsStore,
+        super(appStore: appStore) {
+    const excludeFiatCurrencies = [];
+    const excludeCryptoCurrencies = [];
+
+    fiatCurrencies =
+        FiatCurrency.all.where((currency) => !excludeFiatCurrencies.contains(currency)).toList();
+    cryptoCurrencies = CryptoCurrency.all
+        .where((currency) => !excludeCryptoCurrencies.contains(currency))
+        .toList();
+    _initialize();
+
+    isCryptoCurrencyAddressEnabled = !(cryptoCurrency == wallet.currency);
+  }
+
+  final NumberFormat _cryptoNumberFormat;
+  late Timer bestRateSync;
+
+  List<BuyProvider> get availableBuyProviders {
+    final providerTypes = ProvidersHelper.getAvailableBuyProviderTypes(
+        walletTypeForCurrency(cryptoCurrency) ?? wallet.type);
+    return providerTypes
+        .map((type) => ProvidersHelper.getProviderByType(type))
+        .where((provider) => provider != null)
+        .cast<BuyProvider>()
+        .toList();
+  }
+
+  List<BuyProvider> get availableSellProviders {
+    final providerTypes = ProvidersHelper.getAvailableSellProviderTypes(
+        walletTypeForCurrency(cryptoCurrency) ?? wallet.type);
+    return providerTypes
+        .map((type) => ProvidersHelper.getProviderByType(type))
+        .where((provider) => provider != null)
+        .cast<BuyProvider>()
+        .toList();
+  }
+
+  @override
+  void onWalletChange(wallet) {
+    cryptoCurrency = wallet.currency;
+  }
+
+  bool get isDarkTheme => settingsStore.currentTheme.type == ThemeType.dark;
+
+  double get amount {
+    final formattedFiatAmount = double.tryParse(fiatAmount) ?? 200.0;
+    final formattedCryptoAmount =
+        double.tryParse(cryptoAmount) ?? (cryptoCurrency == CryptoCurrency.btc ? 0.001 : 1);
+
+    return isBuyAction ? formattedFiatAmount : formattedCryptoAmount;
+  }
+
+  SettingsStore settingsStore;
+
+  Quote? bestRateQuote;
+
+  Quote? selectedQuote;
+
+  @observable
+  List<CryptoCurrency> cryptoCurrencies;
+
+  @observable
+  List<FiatCurrency> fiatCurrencies;
+
+  @observable
+  bool isBuyAction = true;
+
+  @observable
+  List<BuyProvider> providerList;
+
+  @observable
+  ObservableList<Quote> sortedRecommendedQuotes;
+
+  @observable
+  ObservableList<Quote> sortedQuotes;
+
+  @observable
+  ObservableList<PaymentMethod> paymentMethods;
+
+  @observable
+  FiatCurrency fiatCurrency;
+
+  @observable
+  CryptoCurrency cryptoCurrency;
+
+  @observable
+  String cryptoAmount;
+
+  @observable
+  String fiatAmount;
+
+  @observable
+  String cryptoCurrencyAddress;
+
+  @observable
+  bool isCryptoCurrencyAddressEnabled;
+
+  @observable
+  PaymentMethod? selectedPaymentMethod;
+
+  @observable
+  PaymentMethodLoadingState paymentMethodState;
+
+  @observable
+  BuySellQuotLoadingState buySellQuotState;
+
+  @computed
+  bool get isReadyToTrade {
+    final hasSelectedQuote = selectedQuote != null;
+    final hasSelectedPaymentMethod = selectedPaymentMethod != null;
+    final isPaymentMethodLoaded = paymentMethodState is PaymentMethodLoaded;
+    final isBuySellQuotLoaded = buySellQuotState is BuySellQuotLoaded;
+
+    return hasSelectedQuote &&
+        hasSelectedPaymentMethod &&
+        isPaymentMethodLoaded &&
+        isBuySellQuotLoaded;
+  }
+
+  @action
+  void reset() {
+    cryptoCurrency = wallet.currency;
+    fiatCurrency = settingsStore.fiatCurrency;
+    isCryptoCurrencyAddressEnabled = !(cryptoCurrency == wallet.currency);
+    _initialize();
+  }
+
+  @action
+  void changeBuySellAction() {
+    isBuyAction = !isBuyAction;
+    _initialize();
+  }
+
+  @action
+  void changeFiatCurrency({required FiatCurrency currency}) {
+    fiatCurrency = currency;
+    _onPairChange();
+  }
+
+  @action
+  void changeCryptoCurrency({required CryptoCurrency currency}) {
+    cryptoCurrency = currency;
+    _onPairChange();
+    isCryptoCurrencyAddressEnabled = !(cryptoCurrency == wallet.currency);
+  }
+
+  @action
+  void changeCryptoCurrencyAddress(String address) => cryptoCurrencyAddress = address;
+
+  @action
+  Future<void> changeFiatAmount({required String amount}) async {
+    fiatAmount = amount;
+
+    if (amount.isEmpty) {
+      fiatAmount = '';
+      cryptoAmount = '';
+      return;
+    }
+
+    final enteredAmount = double.tryParse(amount.replaceAll(',', '.')) ?? 0;
+
+    if (!isReadyToTrade) {
+      cryptoAmount = S.current.fetching;
+      return;
+    }
+
+    if (bestRateQuote != null) {
+      _cryptoNumberFormat.maximumFractionDigits = cryptoCurrency.decimals;
+      cryptoAmount = _cryptoNumberFormat
+          .format(enteredAmount / bestRateQuote!.rate)
+          .toString()
+          .replaceAll(RegExp('\\,'), '');
+    } else {
+      await calculateBestRate();
+    }
+  }
+
+  @action
+  Future<void> changeCryptoAmount({required String amount}) async {
+    cryptoAmount = amount;
+
+    if (amount.isEmpty) {
+      fiatAmount = '';
+      cryptoAmount = '';
+      return;
+    }
+
+    final enteredAmount = double.tryParse(amount.replaceAll(',', '.')) ?? 0;
+
+    if (!isReadyToTrade) {
+      fiatAmount = S.current.fetching;
+    }
+
+    if (bestRateQuote != null) {
+      fiatAmount = _cryptoNumberFormat
+          .format(enteredAmount * bestRateQuote!.rate)
+          .toString()
+          .replaceAll(RegExp('\\,'), '');
+    } else {
+      await calculateBestRate();
+    }
+  }
+
+  @action
+  void changeOption(SelectableOption option) {
+    if (option is Quote) {
+      sortedRecommendedQuotes.forEach((element) => element.setIsSelected = false);
+      sortedQuotes.forEach((element) => element.setIsSelected = false);
+      option.setIsSelected = true;
+      selectedQuote = option;
+    } else if (option is PaymentMethod) {
+      paymentMethods.forEach((element) => element.isSelected = false);
+      option.isSelected = true;
+      selectedPaymentMethod = option;
+    } else {
+      throw ArgumentError('Unknown option type');
+    }
+  }
+
+  void onTapChoseProvider(BuildContext context) async {
+    final initialQuotes = List<Quote>.from(sortedRecommendedQuotes + sortedQuotes);
+    await calculateBestRate();
+    final newQuotes = (sortedRecommendedQuotes + sortedQuotes);
+
+    for (var quote in newQuotes) quote.limits = null;
+
+    final newQuoteProviders = newQuotes
+        .map((quote) => quote.provider.isAggregator ? quote.rampName : quote.provider.title)
+        .toSet();
+
+    final outOfLimitQuotes = initialQuotes.where((initialQuote) {
+      return !newQuoteProviders.contains(
+          initialQuote.provider.isAggregator ? initialQuote.rampName : initialQuote.provider.title);
+    }).map((missingQuote) {
+      final quote = Quote(
+        rate: missingQuote.rate,
+        feeAmount: missingQuote.feeAmount,
+        networkFee: missingQuote.networkFee,
+        transactionFee: missingQuote.transactionFee,
+        payout: missingQuote.payout,
+        rampId: missingQuote.rampId,
+        rampName: missingQuote.rampName,
+        rampIconPath: missingQuote.rampIconPath,
+        paymentType: missingQuote.paymentType,
+        quoteId: missingQuote.quoteId,
+        recommendations: missingQuote.recommendations,
+        provider: missingQuote.provider,
+        isBuyAction: missingQuote.isBuyAction,
+        limits: missingQuote.limits,
+      );
+      quote.setFiatCurrency = missingQuote.fiatCurrency;
+      quote.setCryptoCurrency = missingQuote.cryptoCurrency;
+      return quote;
+    }).toList();
+
+    final updatedQuoteOptions = List<SelectableItem>.from([
+      OptionTitle(title: 'Recommended'),
+      ...sortedRecommendedQuotes,
+      if (sortedQuotes.isNotEmpty) OptionTitle(title: 'All Providers'),
+      ...sortedQuotes,
+      if (outOfLimitQuotes.isNotEmpty) OptionTitle(title: 'Out of Limits'),
+      ...outOfLimitQuotes,
+    ]);
+
+    await Navigator.of(context).pushNamed(
+      Routes.buyOptionsPage,
+      arguments: [
+        updatedQuoteOptions,
+        changeOption,
+        launchTrade,
+      ],
+    ).then((value) => calculateBestRate());
+  }
+
+  void _onPairChange() {
+    _initialize();
+  }
+
+  void _setProviders() =>
+      providerList = isBuyAction ? availableBuyProviders : availableSellProviders;
+
+  Future<void> _initialize() async {
+    _setProviders();
+    cryptoAmount = '';
+    fiatAmount = '';
+    cryptoCurrencyAddress = _getInitialCryptoCurrencyAddress();
+    paymentMethodState = InitialPaymentMethod();
+    buySellQuotState = InitialBuySellQuotState();
+    await _getAvailablePaymentTypes();
+    await calculateBestRate();
+  }
+
+  String _getInitialCryptoCurrencyAddress() {
+    return cryptoCurrency == wallet.currency ? wallet.walletAddresses.address : '';
+  }
+
+  @action
+  Future<void> _getAvailablePaymentTypes() async {
+    paymentMethodState = PaymentMethodLoading();
+    selectedPaymentMethod = null;
+    final result = await Future.wait(providerList.map((element) => element
+        .getAvailablePaymentTypes(fiatCurrency.title, cryptoCurrency.title, isBuyAction)
+        .timeout(
+          Duration(seconds: 10),
+          onTimeout: () => [],
+        )));
+
+    final Map<PaymentType, PaymentMethod> uniquePaymentMethods = {};
+    for (var methods in result) {
+      for (var method in methods) {
+        uniquePaymentMethods[method.paymentMethodType] = method;
+      }
+    }
+
+    paymentMethods = ObservableList<PaymentMethod>.of(uniquePaymentMethods.values);
+    if (paymentMethods.isNotEmpty) {
+      paymentMethods.insert(0, PaymentMethod.all());
+      selectedPaymentMethod = paymentMethods.first;
+      selectedPaymentMethod!.isSelected = true;
+      paymentMethodState = PaymentMethodLoaded();
+    } else {
+      paymentMethodState = PaymentMethodFailed();
+    }
+  }
+
+  @action
+  Future<void> calculateBestRate() async {
+    buySellQuotState = BuySellQuotLoading();
+
+    final result = await Future.wait<List<Quote>?>(providerList.map((element) => element
+        .fetchQuote(
+          cryptoCurrency: cryptoCurrency,
+          fiatCurrency: fiatCurrency,
+          amount: amount,
+          paymentType: selectedPaymentMethod?.paymentMethodType,
+          isBuyAction: isBuyAction,
+          walletAddress: wallet.walletAddresses.address,
+        )
+        .timeout(
+          Duration(seconds: 10),
+          onTimeout: () => null,
+        )));
+
+    sortedRecommendedQuotes.clear();
+    sortedQuotes.clear();
+
+    final validQuotes = result
+        .where((element) => element != null && element.isNotEmpty)
+        .expand((element) => element!)
+        .toList();
+
+    if (validQuotes.isEmpty) {
+      buySellQuotState = BuySellQuotFailed();
+      return;
+    }
+
+    validQuotes.sort((a, b) => a.rate.compareTo(b.rate));
+
+    final Set<String> addedProviders = {};
+    final List<Quote> uniqueProviderQuotes = validQuotes.where((element) {
+      if (addedProviders.contains(element.provider.title)) return false;
+      addedProviders.add(element.provider.title);
+      return true;
+    }).toList();
+
+    sortedRecommendedQuotes.addAll(uniqueProviderQuotes);
+
+    sortedQuotes = ObservableList.of(
+        validQuotes.where((element) => !uniqueProviderQuotes.contains(element)).toList());
+
+    if (sortedRecommendedQuotes.isNotEmpty) {
+      sortedRecommendedQuotes.first
+        ..setIsBestRate = true
+        ..recommendations.insert(0, ProviderRecommendation.bestRate);
+      bestRateQuote = sortedRecommendedQuotes.first;
+
+      sortedRecommendedQuotes.sort((a, b) {
+        if (a.provider is OnRamperBuyProvider) return -1;
+        if (b.provider is OnRamperBuyProvider) return 1;
+        return 0;
+      });
+
+      selectedQuote = sortedRecommendedQuotes.first;
+      sortedRecommendedQuotes.first.setIsSelected = true;
+    }
+
+    buySellQuotState = BuySellQuotLoaded();
+  }
+
+  @action
+  Future<void> launchTrade(BuildContext context) async {
+    final provider = selectedQuote!.provider;
+    await provider.launchProvider(
+      context: context,
+      quote: selectedQuote!,
+      amount: amount,
+      isBuyAction: isBuyAction,
+      cryptoCurrencyAddress: cryptoCurrencyAddress,
+    );
+  }
+}
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index 934cbdee7..a78012ae9 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -71,8 +71,7 @@ abstract class DashboardViewModelBase with Store {
       required this.anonpayTransactionsStore,
       required this.sharedPreferences,
       required this.keyService})
-      : hasSellAction = false,
-        hasBuyAction = false,
+      : hasTradeAction = false,
         hasExchangeAction = false,
         isShowFirstYatIntroduction = false,
         isShowSecondYatIntroduction = false,
@@ -521,37 +520,8 @@ abstract class DashboardViewModelBase with Store {
 
   Map<String, List<FilterItem>> filterItems;
 
-  BuyProvider? get defaultBuyProvider => ProvidersHelper.getProviderByType(
-      settingsStore.defaultBuyProviders[wallet.type] ?? ProviderType.askEachTime);
-
-  BuyProvider? get defaultSellProvider => ProvidersHelper.getProviderByType(
-      settingsStore.defaultSellProviders[wallet.type] ?? ProviderType.askEachTime);
-
   bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled;
 
-  List<BuyProvider> get availableBuyProviders {
-    final providerTypes = ProvidersHelper.getAvailableBuyProviderTypes(wallet.type);
-    return providerTypes
-        .map((type) => ProvidersHelper.getProviderByType(type))
-        .where((provider) => provider != null)
-        .cast<BuyProvider>()
-        .toList();
-  }
-
-  bool get hasBuyProviders => ProvidersHelper.getAvailableBuyProviderTypes(wallet.type).isNotEmpty;
-
-  List<BuyProvider> get availableSellProviders {
-    final providerTypes = ProvidersHelper.getAvailableSellProviderTypes(wallet.type);
-    return providerTypes
-        .map((type) => ProvidersHelper.getProviderByType(type))
-        .where((provider) => provider != null)
-        .cast<BuyProvider>()
-        .toList();
-  }
-
-  bool get hasSellProviders =>
-      ProvidersHelper.getAvailableSellProviderTypes(wallet.type).isNotEmpty;
-
   bool get shouldShowYatPopup => settingsStore.shouldShowYatPopup;
 
   @action
@@ -564,16 +534,10 @@ abstract class DashboardViewModelBase with Store {
   bool hasExchangeAction;
 
   @computed
-  bool get isEnabledBuyAction => !settingsStore.disableBuy && hasBuyProviders;
+  bool get isEnabledTradeAction => !settingsStore.disableTradeOption;
 
   @observable
-  bool hasBuyAction;
-
-  @computed
-  bool get isEnabledSellAction => !settingsStore.disableSell && hasSellProviders;
-
-  @observable
-  bool hasSellAction;
+  bool hasTradeAction;
 
   @computed
   bool get isEnabledBulletinAction => !settingsStore.disableBulletin;
@@ -776,8 +740,7 @@ abstract class DashboardViewModelBase with Store {
 
   void updateActions() {
     hasExchangeAction = !isHaven;
-    hasBuyAction = !isHaven;
-    hasSellAction = !isHaven;
+    hasTradeAction = !isHaven;
   }
 
   @computed
diff --git a/lib/view_model/settings/other_settings_view_model.dart b/lib/view_model/settings/other_settings_view_model.dart
index 9af8c67cf..3036e8ae9 100644
--- a/lib/view_model/settings/other_settings_view_model.dart
+++ b/lib/view_model/settings/other_settings_view_model.dart
@@ -65,29 +65,6 @@ abstract class OtherSettingsViewModelBase with Store {
       _wallet.type == WalletType.solana ||
       _wallet.type == WalletType.tron);
 
-  @computed
-  bool get isEnabledBuyAction =>
-      !_settingsStore.disableBuy && _wallet.type != WalletType.haven;
-
-  @computed
-  bool get isEnabledSellAction =>
-      !_settingsStore.disableSell && _wallet.type != WalletType.haven;
-
-  List<ProviderType> get availableBuyProvidersTypes {
-    return ProvidersHelper.getAvailableBuyProviderTypes(walletType);
-  }
-
-  List<ProviderType> get availableSellProvidersTypes =>
-      ProvidersHelper.getAvailableSellProviderTypes(walletType);
-
-  ProviderType get buyProviderType =>
-      _settingsStore.defaultBuyProviders[walletType] ??
-      ProviderType.askEachTime;
-
-  ProviderType get sellProviderType =>
-      _settingsStore.defaultSellProviders[walletType] ??
-      ProviderType.askEachTime;
-
   String getDisplayPriority(dynamic priority) {
     final _priority = priority as TransactionPriority;
 
@@ -115,20 +92,6 @@ abstract class OtherSettingsViewModelBase with Store {
     return priority.toString();
   }
 
-  String getBuyProviderType(dynamic buyProviderType) {
-    final _buyProviderType = buyProviderType as ProviderType;
-    return _buyProviderType == ProviderType.askEachTime
-        ? S.current.ask_each_time
-        : _buyProviderType.title;
-  }
-
-  String getSellProviderType(dynamic sellProviderType) {
-    final _sellProviderType = sellProviderType as ProviderType;
-    return _sellProviderType == ProviderType.askEachTime
-        ? S.current.ask_each_time
-        : _sellProviderType.title;
-  }
-
   void onDisplayPrioritySelected(TransactionPriority priority) =>
       _settingsStore.priority[walletType] = priority;
 
@@ -157,12 +120,4 @@ abstract class OtherSettingsViewModelBase with Store {
     }
     return null;
   }
-
-  @action
-  ProviderType onBuyProviderTypeSelected(ProviderType buyProviderType) =>
-      _settingsStore.defaultBuyProviders[walletType] = buyProviderType;
-
-  @action
-  ProviderType onSellProviderTypeSelected(ProviderType sellProviderType) =>
-      _settingsStore.defaultSellProviders[walletType] = sellProviderType;
 }
diff --git a/lib/view_model/settings/privacy_settings_view_model.dart b/lib/view_model/settings/privacy_settings_view_model.dart
index c1e0fb1ce..eaa9f9e84 100644
--- a/lib/view_model/settings/privacy_settings_view_model.dart
+++ b/lib/view_model/settings/privacy_settings_view_model.dart
@@ -59,10 +59,7 @@ abstract class PrivacySettingsViewModelBase with Store {
   bool get isAppSecure => _settingsStore.isAppSecure;
 
   @computed
-  bool get disableBuy => _settingsStore.disableBuy;
-
-  @computed
-  bool get disableSell => _settingsStore.disableSell;
+  bool get disableTradeOption => _settingsStore.disableTradeOption;
 
   @computed
   bool get disableBulletin => _settingsStore.disableBulletin;
@@ -119,10 +116,7 @@ abstract class PrivacySettingsViewModelBase with Store {
   void setIsAppSecure(bool value) => _settingsStore.isAppSecure = value;
 
   @action
-  void setDisableBuy(bool value) => _settingsStore.disableBuy = value;
-
-  @action
-  void setDisableSell(bool value) => _settingsStore.disableSell = value;
+  void setDisableTradeOption(bool value) => _settingsStore.disableTradeOption = value;
 
   @action
   void setDisableBulletin(bool value) => _settingsStore.disableBulletin = value;
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index fc0ea8ea9..9ebab6b6f 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "تم تغيير ممثل بنجاح",
   "change_wallet_alert_content": "هل تريد تغيير المحفظة الحالية إلى ${wallet_name}؟",
   "change_wallet_alert_title": "تغيير المحفظة الحالية",
+  "choose_a_payment_method": "اختر طريقة الدفع",
+  "choose_a_provider": "اختر مزودًا",
   "choose_account": "اختر حساب",
   "choose_address": "\n\nالرجاء اختيار عنوان:",
   "choose_card_value": "اختر قيمة بطاقة",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "من خلال إيقاف تشغيل هذا ، قد تكون معدلات الرسوم غير دقيقة في بعض الحالات ، لذلك قد ينتهي بك الأمر إلى دفع مبالغ زائدة أو دفع رسوم المعاملات الخاصة بك",
   "disable_fiat": "تعطيل fiat",
   "disable_sell": "قم بتعطيل إجراء البيع",
+  "disable_trade_option": "تعطيل خيار التجارة",
   "disableBatteryOptimization": "تعطيل تحسين البطارية",
   "disableBatteryOptimizationDescription": "هل تريد تعطيل تحسين البطارية من أجل جعل الخلفية مزامنة تعمل بحرية وسلاسة؟",
   "disabled": "معطلة",
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index e66a40b36..91256938d 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Успешно промени представител",
   "change_wallet_alert_content": "Искате ли да смените сегашния портфейл на ${wallet_name}?",
   "change_wallet_alert_title": "Смяна на сегашния портфейл",
+  "choose_a_payment_method": "Изберете начин на плащане",
+  "choose_a_provider": "Изберете доставчик",
   "choose_account": "Избиране на профил",
   "choose_address": "\n\nМоля, изберете адреса:",
   "choose_card_value": "Изберете стойност на картата",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Като изключите това, таксите могат да бъдат неточни в някои случаи, така че може да се препланите или да не плащате таксите за вашите транзакции",
   "disable_fiat": "Деактивиране на fiat",
   "disable_sell": "Деактивирайте действието за продажба",
+  "disable_trade_option": "Деактивирайте опцията за търговия",
   "disableBatteryOptimization": "Деактивирайте оптимизацията на батерията",
   "disableBatteryOptimizationDescription": "Искате ли да деактивирате оптимизацията на батерията, за да направите синхронизирането на фона да работи по -свободно и гладко?",
   "disabled": "Деактивирано",
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index 4911030b2..0fe38166c 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Úspěšně změnil zástupce",
   "change_wallet_alert_content": "Opravdu chcete změnit aktivní peněženku na ${wallet_name}?",
   "change_wallet_alert_title": "Přepnout peněženku",
+  "choose_a_payment_method": "Vyberte metodu platby",
+  "choose_a_provider": "Vyberte poskytovatele",
   "choose_account": "Zvolte částku",
   "choose_address": "\n\nProsím vyberte adresu:",
   "choose_card_value": "Vyberte hodnotu karty",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Tímto vypnutím by sazby poplatků mohly být v některých případech nepřesné, takže byste mohli skončit přepláváním nebo nedoplatkem poplatků za vaše transakce",
   "disable_fiat": "Zakázat fiat",
   "disable_sell": "Zakázat akci prodeje",
+  "disable_trade_option": "Zakázat možnost TRADE",
   "disableBatteryOptimization": "Zakázat optimalizaci baterie",
   "disableBatteryOptimizationDescription": "Chcete deaktivovat optimalizaci baterie, aby se synchronizovala pozadí volně a hladce?",
   "disabled": "Zakázáno",
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index a69174dd6..212ce05f7 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Vertreter erfolgreich gerändert",
   "change_wallet_alert_content": "Möchten Sie die aktuelle Wallet zu ${wallet_name} ändern?",
   "change_wallet_alert_title": "Aktuelle Wallet ändern",
+  "choose_a_payment_method": "Wählen Sie eine Zahlungsmethode",
+  "choose_a_provider": "Wählen Sie einen Anbieter",
   "choose_account": "Konto auswählen",
   "choose_address": "\n\nBitte wählen Sie die Adresse:",
   "choose_card_value": "Wählen Sie einen Kartenwert",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Wenn dies ausgeschaltet wird, sind die Gebührenquoten in einigen Fällen möglicherweise ungenau, sodass Sie die Gebühren für Ihre Transaktionen möglicherweise überbezahlt oder unterzahlt",
   "disable_fiat": "Fiat deaktivieren",
   "disable_sell": "Verkaufsaktion deaktivieren",
+  "disable_trade_option": "Handelsoption deaktivieren",
   "disableBatteryOptimization": "Batterieoptimierung deaktivieren",
   "disableBatteryOptimizationDescription": "Möchten Sie die Batterieoptimierung deaktivieren, um die Hintergrundsynchronisierung reibungsloser zu gestalten?",
   "disabled": "Deaktiviert",
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 322e38b85..15e0c04b3 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Successfully changed representative",
   "change_wallet_alert_content": "Do you want to change current wallet to ${wallet_name}?",
   "change_wallet_alert_title": "Change current wallet",
+  "choose_a_payment_method": "Choose a payment method",
+  "choose_a_provider": "Choose a provider",
   "choose_account": "Choose account",
   "choose_address": "\n\nPlease choose the address:",
   "choose_card_value": "Choose a card value",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "By turning this off, the fee rates might be inaccurate in some cases, so you might end up overpaying or underpaying the fees for your transactions",
   "disable_fiat": "Disable fiat",
   "disable_sell": "Disable sell action",
+  "disable_trade_option": "Disable trade option",
   "disableBatteryOptimization": "Disable Battery Optimization",
   "disableBatteryOptimizationDescription": "Do you want to disable battery optimization in order to make background sync run more freely and smoothly?",
   "disabled": "Disabled",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 5a8ff0582..83c0a09f0 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Representante cambiado con éxito",
   "change_wallet_alert_content": "¿Quieres cambiar la billetera actual a ${wallet_name}?",
   "change_wallet_alert_title": "Cambiar billetera actual",
+  "choose_a_payment_method": "Elija un método de pago",
+  "choose_a_provider": "Elija un proveedor",
   "choose_account": "Elegir cuenta",
   "choose_address": "\n\nPor favor elija la dirección:",
   "choose_card_value": "Elige un valor de tarjeta",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Al apagar esto, las tasas de tarifas pueden ser inexactas en algunos casos, por lo que puede terminar pagando en exceso o pagando menos las tarifas por sus transacciones",
   "disable_fiat": "Deshabilitar fiat",
   "disable_sell": "Desactivar acción de venta",
+  "disable_trade_option": "Deshabilitar la opción de comercio",
   "disableBatteryOptimization": "Deshabilitar la optimización de la batería",
   "disableBatteryOptimizationDescription": "¿Desea deshabilitar la optimización de la batería para que la sincronización de fondo se ejecute más libremente y sin problemas?",
   "disabled": "Desactivado",
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index 6abe72681..549ec5275 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Représentant changé avec succès",
   "change_wallet_alert_content": "Souhaitez-vous changer le portefeuille (wallet) actuel vers ${wallet_name} ?",
   "change_wallet_alert_title": "Changer le portefeuille (wallet) actuel",
+  "choose_a_payment_method": "Choisissez un mode de paiement",
+  "choose_a_provider": "Choisissez un fournisseur",
   "choose_account": "Choisir le compte",
   "choose_address": "\n\nMerci de choisir l'adresse :",
   "choose_card_value": "Choisissez une valeur de carte",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "En désactivant cela, les taux de frais peuvent être inexacts dans certains cas, vous pourriez donc finir par payer trop ou sous-paiement les frais pour vos transactions",
   "disable_fiat": "Désactiver les montants en fiat",
   "disable_sell": "Désactiver l'action de vente",
+  "disable_trade_option": "Désactiver l'option de commerce",
   "disableBatteryOptimization": "Désactiver l'optimisation de la batterie",
   "disableBatteryOptimizationDescription": "Voulez-vous désactiver l'optimisation de la batterie afin de faire fonctionner la synchronisation d'arrière-plan plus librement et en douceur?",
   "disabled": "Désactivé",
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index 5a53d6795..222a9cf2f 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "An samu nasarar canzawa wakilin",
   "change_wallet_alert_content": "Kana so ka canja walat yanzu zuwa ${wallet_name}?",
   "change_wallet_alert_title": "Canja walat yanzu",
+  "choose_a_payment_method": "Zabi hanyar biyan kuɗi",
+  "choose_a_provider": "Zabi mai bada",
   "choose_account": "Zaɓi asusu",
   "choose_address": "\n\n Da fatan za a zaɓi adireshin:",
   "choose_card_value": "Zabi darajar katin",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Ta hanyar juya wannan kashe, kudaden da zai iya zama ba daidai ba a wasu halaye, saboda haka zaku iya ƙare da overpaying ko a ƙarƙashin kudaden don ma'amaloli",
   "disable_fiat": "Dakatar da fiat",
   "disable_sell": "Kashe karbuwa",
+  "disable_trade_option": "Musaki zaɓi na kasuwanci",
   "disableBatteryOptimization": "Kashe ingantawa baturi",
   "disableBatteryOptimizationDescription": "Shin kana son kashe ingantawa baturi don yin setnc bankwali gudu da yar kyauta da kyau?",
   "disabled": "tsaya",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index d130c2b5f..1b2f3a1b3 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "सफलतापूर्वक बदलकर प्रतिनिधि",
   "change_wallet_alert_content": "क्या आप करंट वॉलेट को बदलना चाहते हैं ${wallet_name}?",
   "change_wallet_alert_title": "वर्तमान बटुआ बदलें",
+  "choose_a_payment_method": "एक भुगतान विधि का चयन करें",
+  "choose_a_provider": "एक प्रदाता चुनें",
   "choose_account": "खाता चुनें",
   "choose_address": "\n\nकृपया पता चुनें:",
   "choose_card_value": "एक कार्ड मूल्य चुनें",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "इसे बंद करने से, कुछ मामलों में शुल्क दरें गलत हो सकती हैं, इसलिए आप अपने लेनदेन के लिए फीस को कम कर सकते हैं या कम कर सकते हैं",
   "disable_fiat": "िएट को अक्षम करें",
   "disable_sell": "बेचने की कार्रवाई अक्षम करें",
+  "disable_trade_option": "व्यापार विकल्प अक्षम करें",
   "disableBatteryOptimization": "बैटरी अनुकूलन अक्षम करें",
   "disableBatteryOptimizationDescription": "क्या आप बैकग्राउंड सिंक को अधिक स्वतंत्र और सुचारू रूप से चलाने के लिए बैटरी ऑप्टिमाइज़ेशन को अक्षम करना चाहते हैं?",
   "disabled": "अक्षम",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 037e6e9f2..4e106fdf6 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Uspješno promijenjena reprezentativna",
   "change_wallet_alert_content": "Želite li promijeniti trenutni novčanik u ${wallet_name}?",
   "change_wallet_alert_title": "Izmijeni trenutni novčanik",
+  "choose_a_payment_method": "Odaberite način plaćanja",
+  "choose_a_provider": "Odaberite davatelja usluga",
   "choose_account": "Odaberi račun",
   "choose_address": "\n\nOdaberite adresu:",
   "choose_card_value": "Odaberite vrijednost kartice",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Isključivanjem ovoga, stope naknade u nekim bi slučajevima mogle biti netočne, tako da biste mogli preplatiti ili predati naknadu za vaše transakcije",
   "disable_fiat": "Isključi, fiat",
   "disable_sell": "Onemogući akciju prodaje",
+  "disable_trade_option": "Onemogući trgovinsku opciju",
   "disableBatteryOptimization": "Onemogući optimizaciju baterije",
   "disableBatteryOptimizationDescription": "Želite li onemogućiti optimizaciju baterije kako bi se pozadinska sinkronizacija radila slobodnije i glatko?",
   "disabled": "Onemogućeno",
diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb
index 04a7cddf5..40142ca5b 100644
--- a/res/values/strings_hy.arb
+++ b/res/values/strings_hy.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Ներկայացուցչի փոփոխությունը հաջողությամբ կատարվեց",
   "change_wallet_alert_content": "Ցանկանում եք փոխել ընթացիկ դրամապանակը ${wallet_name}?",
   "change_wallet_alert_title": "Փոխել ընթացիկ դրամապանակը",
+  "choose_a_payment_method": "Ընտրեք վճարման եղանակ",
+  "choose_a_provider": "Ընտրեք մատակարար",
   "choose_account": "Ընտրեք հաշիվը",
   "choose_address": "\n\nԽնդրում ենք ընտրեք հասցեն",
   "choose_card_value": "Ընտրեք քարտի արժեք",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Դրանից անջատելով, վճարների տեմպերը որոշ դեպքերում կարող են անճիշտ լինել, այնպես որ դուք կարող եք վերջ տալ ձեր գործարքների համար վճարների գերավճարների կամ գերավճարների վրա",
   "disable_fiat": "Անջատել ֆիատ",
   "disable_sell": "Անջատել վաճառք գործողությունը",
+  "disable_trade_option": "Անջատեք առեւտրի տարբերակը",
   "disableBatteryOptimization": "Անջատել մարտկոցի օպտիմիզացիան",
   "disableBatteryOptimizationDescription": "Դուք ցանկանում եք անջատել մարտկոցի օպտիմիզացիան ֆոնային համաժամացման ավելի ազատ և հարթ ընթացքի համար?",
   "disabled": "Անջատված",
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index 231ac037d..04336b76e 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Berhasil mengubah perwakilan",
   "change_wallet_alert_content": "Apakah Anda ingin mengganti dompet saat ini ke ${wallet_name}?",
   "change_wallet_alert_title": "Ganti dompet saat ini",
+  "choose_a_payment_method": "Pilih metode pembayaran",
+  "choose_a_provider": "Pilih penyedia",
   "choose_account": "Pilih akun",
   "choose_address": "\n\nSilakan pilih alamat:",
   "choose_card_value": "Pilih nilai kartu",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Dengan mematikan ini, tarif biaya mungkin tidak akurat dalam beberapa kasus, jadi Anda mungkin akan membayar lebih atau membayar biaya untuk transaksi Anda",
   "disable_fiat": "Nonaktifkan fiat",
   "disable_sell": "Nonaktifkan aksi jual",
+  "disable_trade_option": "Nonaktifkan opsi perdagangan",
   "disableBatteryOptimization": "Nonaktifkan optimasi baterai",
   "disableBatteryOptimizationDescription": "Apakah Anda ingin menonaktifkan optimasi baterai untuk membuat sinkronisasi latar belakang berjalan lebih bebas dan lancar?",
   "disabled": "Dinonaktifkan",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index b06a35537..ad15ab3a9 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Rappresentante modificato con successo",
   "change_wallet_alert_content": "Sei sicuro di voler cambiare il portafoglio attuale con ${wallet_name}?",
   "change_wallet_alert_title": "Cambia portafoglio attuale",
+  "choose_a_payment_method": "Scegli un metodo di pagamento",
+  "choose_a_provider": "Scegli un fornitore",
   "choose_account": "Scegli account",
   "choose_address": "\n\nSi prega di scegliere l'indirizzo:",
   "choose_card_value": "Scegli un valore della carta",
@@ -218,6 +220,7 @@
   "disable_fee_api_warning": "Disattivando questo, i tassi delle commissioni potrebbero essere inaccurati in alcuni casi, quindi potresti finire in eccesso o sostenere le commissioni per le transazioni",
   "disable_fiat": "Disabilita fiat",
   "disable_sell": "Disabilita l'azione di vendita",
+  "disable_trade_option": "Disabilita l'opzione commerciale",
   "disableBatteryOptimization": "Disabilita l'ottimizzazione della batteria",
   "disableBatteryOptimizationDescription": "Vuoi disabilitare l'ottimizzazione della batteria per far funzionare la sincronizzazione in background più libera e senza intoppi?",
   "disabled": "Disabilitato",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index d55c4d5a1..520a73ade 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "代表者の変更に成功しました",
   "change_wallet_alert_content": "現在のウォレットをに変更しますか ${wallet_name}?",
   "change_wallet_alert_title": "現在のウォレットを変更する",
+  "choose_a_payment_method": "支払い方法を選択します",
+  "choose_a_provider": "プロバイダーを選択します",
   "choose_account": "アカウントを選択",
   "choose_address": "\n\n住所を選択してください:",
   "choose_card_value": "カード値を選択します",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "これをオフにすることで、料金金利は場合によっては不正確になる可能性があるため、取引の費用が過払いまたは不足している可能性があります",
   "disable_fiat": "フィアットを無効にする",
   "disable_sell": "販売アクションを無効にする",
+  "disable_trade_option": "取引オプションを無効にします",
   "disableBatteryOptimization": "バッテリーの最適化を無効にします",
   "disableBatteryOptimizationDescription": "バックグラウンドシンクをより自由かつスムーズに実行するために、バッテリーの最適化を無効にしたいですか?",
   "disabled": "無効",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 303527fea..1d9748866 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "대리인이 성공적으로 변경되었습니다",
   "change_wallet_alert_content": "현재 지갑을 다음으로 변경 하시겠습니까 ${wallet_name}?",
   "change_wallet_alert_title": "현재 지갑 변경",
+  "choose_a_payment_method": "결제 방법을 선택하십시오",
+  "choose_a_provider": "제공자를 선택하십시오",
   "choose_account": "계정을 선택하십시오",
   "choose_address": "\n\n주소를 선택하십시오:",
   "choose_card_value": "카드 값을 선택하십시오",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "이것을 끄면 경우에 따라 수수료가 부정확 할 수 있으므로 거래 수수료를 초과 지불하거나 지불 할 수 있습니다.",
   "disable_fiat": "법정화폐 비활성화",
   "disable_sell": "판매 조치 비활성화",
+  "disable_trade_option": "거래 옵션 비활성화",
   "disableBatteryOptimization": "배터리 최적화를 비활성화합니다",
   "disableBatteryOptimizationDescription": "백그라운드 동기화를보다 자유롭고 매끄럽게 실행하기 위해 배터리 최적화를 비활성화하고 싶습니까?",
   "disabled": "장애가 있는",
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index 9b9b44657..e6be67060 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "အောင်မြင်စွာကိုယ်စားလှယ်ပြောင်းလဲသွားတယ်",
   "change_wallet_alert_content": "လက်ရှိပိုက်ဆံအိတ်ကို ${wallet_name} သို့ ပြောင်းလိုပါသလား။",
   "change_wallet_alert_title": "လက်ရှိပိုက်ဆံအိတ်ကို ပြောင်းပါ။",
+  "choose_a_payment_method": "ငွေပေးချေမှုနည်းလမ်းကိုရွေးချယ်ပါ",
+  "choose_a_provider": "ပံ့ပိုးပေးရွေးချယ်ပါ",
   "choose_account": "အကောင့်ကို ရွေးပါ။",
   "choose_address": "\n\nလိပ်စာကို ရွေးပါ-",
   "choose_card_value": "ကဒ်တန်ဖိုးတစ်ခုရွေးပါ",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "ဤအရာကိုဖွင့်ခြင်းအားဖြင့်အချို့သောကိစ္စရပ်များတွင်အခကြေးငွေနှုန်းထားများသည်တိကျမှုရှိနိုင်သည်,",
   "disable_fiat": "Fiat ကိုပိတ်ပါ။",
   "disable_sell": "ရောင်းချခြင်းလုပ်ဆောင်ချက်ကို ပိတ်ပါ။",
+  "disable_trade_option": "ကုန်သွယ်ရေး option ကိုပိတ်ပါ",
   "disableBatteryOptimization": "ဘက်ထရီ optimization ကိုပိတ်ပါ",
   "disableBatteryOptimizationDescription": "နောက်ခံထပ်တူပြုခြင်းနှင့်ချောချောမွေ့မွေ့ပြုလုပ်နိုင်ရန်ဘက်ထရီ optimization ကိုသင်ပိတ်ထားလိုပါသလား။",
   "disabled": "မသန်စွမ်း",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index 657450f61..82c3899d4 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Met succes veranderde vertegenwoordiger",
   "change_wallet_alert_content": "Wilt u de huidige portemonnee wijzigen in ${wallet_name}?",
   "change_wallet_alert_title": "Wijzig huidige portemonnee",
+  "choose_a_payment_method": "Kies een betaalmethode",
+  "choose_a_provider": "Kies een provider",
   "choose_account": "Kies account",
   "choose_address": "\n\nKies het adres:",
   "choose_card_value": "Kies een kaartwaarde",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Door dit uit te schakelen, kunnen de tarieven in sommige gevallen onnauwkeurig zijn, dus u kunt de vergoedingen voor uw transacties te veel betalen of te weinig betalen",
   "disable_fiat": "Schakel Fiat uit",
   "disable_sell": "Verkoopactie uitschakelen",
+  "disable_trade_option": "Schakel handelsoptie uit",
   "disableBatteryOptimization": "Schakel de batterijoptimalisatie uit",
   "disableBatteryOptimizationDescription": "Wilt u de optimalisatie van de batterij uitschakelen om achtergrondsynchronisatie te laten werken, vrijer en soepeler?",
   "disabled": "Gehandicapt",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index e47c93dcf..ed54624bf 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Pomyślnie zmienił przedstawiciela",
   "change_wallet_alert_content": "Czy chcesz zmienić obecny portfel na ${wallet_name}?",
   "change_wallet_alert_title": "Zmień obecny portfel",
+  "choose_a_payment_method": "Wybierz metodę płatności",
+  "choose_a_provider": "Wybierz dostawcę",
   "choose_account": "Wybierz konto",
   "choose_address": "\n\nWybierz adres:",
   "choose_card_value": "Wybierz wartość karty",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Wyłączając to, stawki opłaty mogą być w niektórych przypadkach niedokładne, więc możesz skończyć się przepłaceniem lub wynagrodzeniem opłat za transakcje",
   "disable_fiat": "Wyłącz waluty FIAT",
   "disable_sell": "Wyłącz akcję sprzedaży",
+  "disable_trade_option": "Wyłącz opcję handlu",
   "disableBatteryOptimization": "Wyłącz optymalizację baterii",
   "disableBatteryOptimizationDescription": "Czy chcesz wyłączyć optymalizację baterii, aby synchronizacja tła działała swobodniej i płynnie?",
   "disabled": "Wyłączone",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index d5aa95c16..7b43b5b12 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Mudou com sucesso o representante",
   "change_wallet_alert_content": "Quer mudar a carteira atual para ${wallet_name}?",
   "change_wallet_alert_title": "Alterar carteira atual",
+  "choose_a_payment_method": "Escolha um método de pagamento",
+  "choose_a_provider": "Escolha um provedor",
   "choose_account": "Escolha uma conta",
   "choose_address": "\n\nEscolha o endereço:",
   "choose_card_value": "Escolha um valor de cartão",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Ao desativar isso, as taxas de taxas podem ser imprecisas em alguns casos, para que você possa acabar pagando demais ou pagando as taxas por suas transações",
   "disable_fiat": "Desativar fiat",
   "disable_sell": "Desativar ação de venda",
+  "disable_trade_option": "Desativar a opção comercial",
   "disableBatteryOptimization": "Desative a otimização da bateria",
   "disableBatteryOptimizationDescription": "Deseja desativar a otimização da bateria para fazer a sincronização de fundo funcionar de forma mais livre e suave?",
   "disabled": "Desabilitado",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index f999b4aaa..2795e1ffc 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Успешно изменил представитель",
   "change_wallet_alert_content": "Вы хотите изменить текущий кошелек на ${wallet_name}?",
   "change_wallet_alert_title": "Изменить текущий кошелек",
+  "choose_a_payment_method": "Выберите способ оплаты",
+  "choose_a_provider": "Выберите поставщика",
   "choose_account": "Выберите аккаунт",
   "choose_address": "\n\nПожалуйста, выберите адрес:",
   "choose_card_value": "Выберите значение карты",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Выключив это, в некоторых случаях ставки платы могут быть неточными, так что вы можете в конечном итоге переплачивать или недоплачивать сборы за ваши транзакции",
   "disable_fiat": "Отключить фиат",
   "disable_sell": "Отключить действие продажи",
+  "disable_trade_option": "Отключить возможность торговли",
   "disableBatteryOptimization": "Отключить оптимизацию батареи",
   "disableBatteryOptimizationDescription": "Вы хотите отключить оптимизацию батареи, чтобы сделать фона синхронизации более свободно и плавно?",
   "disabled": "Отключено",
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index a35e16a97..596861646 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "เปลี่ยนตัวแทนสำเร็จ",
   "change_wallet_alert_content": "คุณต้องการเปลี่ยนกระเป๋าปัจจุบันเป็น ${wallet_name} หรือไม่?",
   "change_wallet_alert_title": "เปลี่ยนกระเป๋าปัจจุบัน",
+  "choose_a_payment_method": "เลือกวิธีการชำระเงิน",
+  "choose_a_provider": "เลือกผู้ให้บริการ",
   "choose_account": "เลือกบัญชี",
   "choose_address": "\n\nโปรดเลือกที่อยู่:",
   "choose_card_value": "เลือกค่าบัตร",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "โดยการปิดสิ่งนี้อัตราค่าธรรมเนียมอาจไม่ถูกต้องในบางกรณีดังนั้นคุณอาจจบลงด้วยการจ่ายเงินมากเกินไปหรือจ่ายค่าธรรมเนียมสำหรับการทำธุรกรรมของคุณมากเกินไป",
   "disable_fiat": "ปิดใช้งานสกุลเงินตรา",
   "disable_sell": "ปิดการใช้งานการขาย",
+  "disable_trade_option": "ปิดใช้งานตัวเลือกการค้า",
   "disableBatteryOptimization": "ปิดใช้งานการเพิ่มประสิทธิภาพแบตเตอรี่",
   "disableBatteryOptimizationDescription": "คุณต้องการปิดใช้งานการเพิ่มประสิทธิภาพแบตเตอรี่เพื่อให้การซิงค์พื้นหลังทำงานได้อย่างอิสระและราบรื่นมากขึ้นหรือไม่?",
   "disabled": "ปิดใช้งาน",
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index 090bdb8a7..f4678e00d 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Matagumpay na nagbago ng representative",
   "change_wallet_alert_content": "Gusto mo bang palitan ang kasalukuyang wallet sa ${wallet_name}?",
   "change_wallet_alert_title": "Baguhin ang kasalukuyang wallet",
+  "choose_a_payment_method": "Pumili ng isang paraan ng pagbabayad",
+  "choose_a_provider": "Pumili ng isang provider",
   "choose_account": "Pumili ng account",
   "choose_address": "Mangyaring piliin ang address:",
   "choose_card_value": "Pumili ng isang halaga ng card",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Sa pamamagitan ng pag -off nito, ang mga rate ng bayad ay maaaring hindi tumpak sa ilang mga kaso, kaya maaari mong tapusin ang labis na bayad o pagsuporta sa mga bayarin para sa iyong mga transaksyon",
   "disable_fiat": "Huwag paganahin ang fiat",
   "disable_sell": "Huwag paganahin ang pagkilos ng pagbebenta",
+  "disable_trade_option": "Huwag paganahin ang pagpipilian sa kalakalan",
   "disableBatteryOptimization": "Huwag Paganahin ang Pag-optimize ng Baterya",
   "disableBatteryOptimizationDescription": "Nais mo bang huwag paganahin ang pag-optimize ng baterya upang gawing mas malaya at maayos ang background sync?",
   "disabled": "Hindi pinagana",
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index 3a426de9e..d8b3ae3cf 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Temsilciyi başarıyla değiştirdi",
   "change_wallet_alert_content": "Şimdiki cüzdanı ${wallet_name} cüzdanı ile değiştirmek istediğinden emin misin?",
   "change_wallet_alert_title": "Şimdiki cüzdanı değiştir",
+  "choose_a_payment_method": "Bir Ödeme Yöntemi Seçin",
+  "choose_a_provider": "Bir Sağlayıcı Seçin",
   "choose_account": "Hesabı seç",
   "choose_address": "\n\nLütfen adresi seçin:",
   "choose_card_value": "Bir kart değeri seçin",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Bunu kapatarak, ücret oranları bazı durumlarda yanlış olabilir, bu nedenle işlemleriniz için ücretleri fazla ödeyebilir veya az ödeyebilirsiniz.",
   "disable_fiat": "İtibari paraları devre dışı bırak",
   "disable_sell": "Satış işlemini devre dışı bırak",
+  "disable_trade_option": "Ticaret seçeneğini devre dışı bırakın",
   "disableBatteryOptimization": "Pil optimizasyonunu devre dışı bırakın",
   "disableBatteryOptimizationDescription": "Arka plan senkronizasyonunu daha özgür ve sorunsuz bir şekilde çalıştırmak için pil optimizasyonunu devre dışı bırakmak istiyor musunuz?",
   "disabled": "Devre dışı",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 63665875f..f27300c18 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Успішно змінив представник",
   "change_wallet_alert_content": "Ви хочете змінити поточний гаманець на ${wallet_name}?",
   "change_wallet_alert_title": "Змінити поточний гаманець",
+  "choose_a_payment_method": "Виберіть метод оплати",
+  "choose_a_provider": "Виберіть постачальника",
   "choose_account": "Оберіть акаунт",
   "choose_address": "\n\nБудь ласка, оберіть адресу:",
   "choose_card_value": "Виберіть значення картки",
@@ -185,7 +187,7 @@
   "creating_new_wallet_error": "Помилка: ${description}",
   "creation_date": "Дата створення",
   "custom": "на замовлення",
-  "custom_drag": "На замовлення (утримуйте та перетягується)",
+  "custom_drag": "На замовлення (утримуйте та перетягуйте)",
   "custom_redeem_amount": "Власна сума викупу",
   "custom_value": "Спеціальне значення",
   "dark_theme": "Темна",
@@ -206,17 +208,18 @@
   "description": "опис",
   "destination_tag": "Тег призначення:",
   "dfx_option_description": "Купуйте криптовалюту з EUR & CHF. Для роздрібних та корпоративних клієнтів у Європі",
-  "didnt_get_code": "Не отримуєте код?",
+  "didnt_get_code": "Не отримали код?",
   "digit_pin": "-значний PIN",
   "digital_and_physical_card": " цифрова та фізична передплачена дебетова картка",
   "disable": "Вимкнути",
   "disable_bulletin": "Вимкнути статус послуги",
   "disable_buy": "Вимкнути дію покупки",
   "disable_cake_2fa": "Вимкнути Cake 2FA",
-  "disable_exchange": "Вимкнути exchange",
+  "disable_exchange": "Вимкнути можливість обміну",
   "disable_fee_api_warning": "Вимкнувши це, ставки плати в деяких випадках можуть бути неточними, тому ви можете переплатити або недооплатити плату за свої транзакції",
   "disable_fiat": "Вимкнути фиат",
   "disable_sell": "Вимкнути дію продажу",
+  "disable_trade_option": "Вимкнути можливість торгівлі",
   "disableBatteryOptimization": "Вимкнути оптимізацію акумулятора",
   "disableBatteryOptimizationDescription": "Ви хочете відключити оптимізацію акумулятора, щоб зробити фонову синхронізацію більш вільно та плавно?",
   "disabled": "Вимкнено",
@@ -226,14 +229,14 @@
   "do_not_have_enough_gas_asset": "У вас недостатньо ${currency}, щоб здійснити трансакцію з поточними умовами мережі блокчейн. Вам потрібно більше ${currency}, щоб сплатити комісію мережі блокчейн, навіть якщо ви надсилаєте інший актив.",
   "do_not_send": "Не надсилайте",
   "do_not_share_warning_text": "Не діліться цим нікому, включно зі службою підтримки.\n\nВаші кошти можуть і будуть вкрадені!",
-  "do_not_show_me": "Не показуй мені це знову",
+  "do_not_show_me": "Не показувати це знову",
   "domain_looks_up": "Пошук доменів",
   "donation_link_details": "Деталі посилання для пожертв",
   "e_sign_consent": "Згода електронного підпису",
   "edit": "Редагувати",
   "edit_backup_password": "Змінити пароль резервної копії",
   "edit_node": "Редагувати вузол",
-  "edit_token": "Редагувати маркер",
+  "edit_token": "Редагувати токен",
   "electrum_address_disclaimer": "Ми створюємо нові адреси щоразу, коли ви використовуєте їх, але попередні адреси продовжують працювати",
   "email_address": "Адреса електронної пошти",
   "enable": "Ввімкнути",
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index 2a40fbe13..00f336d72 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "نمائندہ کو کامیابی کے ساتھ تبدیل کیا",
   "change_wallet_alert_content": "کیا آپ موجودہ والیٹ کو ${wallet_name} میں تبدیل کرنا چاہتے ہیں؟",
   "change_wallet_alert_title": "موجودہ پرس تبدیل کریں۔",
+  "choose_a_payment_method": "ادائیگی کا طریقہ منتخب کریں",
+  "choose_a_provider": "فراہم کنندہ کا انتخاب کریں",
   "choose_account": "اکاؤنٹ کا انتخاب کریں۔",
   "choose_address": "\\n\\nبراہ کرم پتہ منتخب کریں:",
   "choose_card_value": "کارڈ کی قیمت کا انتخاب کریں",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "اس کو بند کرنے سے ، کچھ معاملات میں فیس کی شرح غلط ہوسکتی ہے ، لہذا آپ اپنے لین دین کے لئے فیسوں کو زیادہ ادائیگی یا ادائیگی ختم کرسکتے ہیں۔",
   "disable_fiat": "فیاٹ کو غیر فعال کریں۔",
   "disable_sell": "فروخت کی کارروائی کو غیر فعال کریں۔",
+  "disable_trade_option": "تجارت کے آپشن کو غیر فعال کریں",
   "disableBatteryOptimization": "بیٹری کی اصلاح کو غیر فعال کریں",
   "disableBatteryOptimizationDescription": "کیا آپ پس منظر کی مطابقت پذیری کو زیادہ آزادانہ اور آسانی سے چلانے کے لئے بیٹری کی اصلاح کو غیر فعال کرنا چاہتے ہیں؟",
   "disabled": "معذور",
diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb
index 9fee9f4fc..1291b505e 100644
--- a/res/values/strings_vi.arb
+++ b/res/values/strings_vi.arb
@@ -218,6 +218,7 @@
   "disable_fee_api_warning": "Khi tắt chức năng này, tỉ lệ phí có thể không chính xác trong một số trường hợp, dẫn đến bạn trả quá hoặc không đủ phí cho giao dịch của mình.",
   "disable_fiat": "Vô hiệu hóa tiền tệ fiat",
   "disable_sell": "Vô hiệu hóa chức năng bán",
+  "disable_trade_option": "Tắt tùy chọn thương mại",
   "disableBatteryOptimization": "Vô hiệu hóa Tối ưu hóa Pin",
   "disableBatteryOptimizationDescription": "Bạn có muốn vô hiệu hóa tối ưu hóa pin để đồng bộ hóa nền hoạt động mượt mà hơn không?",
   "disabled": "Đã vô hiệu hóa",
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index 1dd6eafda..c9275b018 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "Ni ifijišẹ yipada aṣoju",
   "change_wallet_alert_content": "Ṣe ẹ fẹ́ pààrọ̀ àpamọ́wọ́ yìí sí ${wallet_name}?",
   "change_wallet_alert_title": "Ẹ pààrọ̀ àpamọ́wọ́ yìí",
+  "choose_a_payment_method": "Yan ọna isanwo kan",
+  "choose_a_provider": "Yan olupese",
   "choose_account": "Yan àkáǹtì",
   "choose_address": "\n\nẸ jọ̀wọ́ yan àdírẹ́sì:",
   "choose_card_value": "Yan iye kaadi",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "Nipa yiyi eyi kuro, awọn oṣuwọn owo naa le jẹ aiṣe deede ni awọn ọrọ kan, nitorinaa o le pari apọju tabi awọn idiyele ti o ni agbara fun awọn iṣowo rẹ",
   "disable_fiat": "Pa owó tí ìjọba pàṣẹ wa lò",
   "disable_sell": "Ko iṣọrọ iṣọrọ",
+  "disable_trade_option": "Mu aṣayan iṣowo ṣiṣẹ",
   "disableBatteryOptimization": "Mu Ifasi batiri",
   "disableBatteryOptimizationDescription": "Ṣe o fẹ lati mu iṣapelo batiri si lati le ṣiṣe ayẹwo ẹhin ati laisiyonu?",
   "disabled": "Wọ́n tí a ti pa",
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index 92a540d19..e508d3c2c 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -123,6 +123,8 @@
   "change_rep_successful": "成功改变了代表",
   "change_wallet_alert_content": "您是否想将当前钱包改为 ${wallet_name}?",
   "change_wallet_alert_title": "更换当前钱包",
+  "choose_a_payment_method": "选择付款方式",
+  "choose_a_provider": "选择一个提供商",
   "choose_account": "选择账户",
   "choose_address": "\n\n請選擇地址:",
   "choose_card_value": "选择卡值",
@@ -217,6 +219,7 @@
   "disable_fee_api_warning": "通过将其关闭,在某些情况下,收费率可能不准确,因此您最终可能会超额付款或支付交易费用",
   "disable_fiat": "禁用法令",
   "disable_sell": "禁用卖出操作",
+  "disable_trade_option": "禁用贸易选项",
   "disableBatteryOptimization": "禁用电池优化",
   "disableBatteryOptimizationDescription": "您是否要禁用电池优化以使背景同步更加自由,平稳地运行?",
   "disabled": "禁用",
diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart
index 88cbbfce3..affe4017c 100644
--- a/tool/utils/secret_key.dart
+++ b/tool/utils/secret_key.dart
@@ -44,6 +44,8 @@ class SecretKey {
     SecretKey('cakePayApiKey', () => ''),
     SecretKey('CSRFToken', () => ''),
     SecretKey('authorization', () => ''),
+    SecretKey('meldTestApiKey', () => ''),
+    SecretKey('meldTestPublicKey', () => ''),
     SecretKey('moneroTestWalletSeeds', () => ''),
     SecretKey('moneroLegacyTestWalletSeeds ', () => ''),
     SecretKey('bitcoinTestWalletSeeds', () => ''),

From 288164603723279711dd6a894d48d7645821fb36 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Sat, 9 Nov 2024 21:07:17 +0200
Subject: [PATCH 09/15] Updatable builds (#1791)

* save and increment build number for each PR

* cd into repo path

* trial

* try generating the release build without a keystore

* cache keystore to maintain same signature for PR builds

* weird fix

* potential fix

* fix key path

* meh

* Update cache_dependencies.yml
---
 .github/workflows/cache_dependencies.yml    | 15 ++++++-
 .github/workflows/pr_test_build_android.yml | 49 ++++++++++++++++++++-
 2 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml
index 0fcd5c45b..ce098b7f1 100644
--- a/.github/workflows/cache_dependencies.yml
+++ b/.github/workflows/cache_dependencies.yml
@@ -67,4 +67,17 @@ jobs:
         run: |
           cd /opt/android/cake_wallet/scripts/android/
           source ./app_env.sh cakewallet
-          ./build_monero_all.sh
\ No newline at end of file
+          ./build_monero_all.sh
+
+      - name: Cache Keystore
+        id: cache-keystore
+        uses: actions/cache@v3
+        with:
+          path: /opt/android/cake_wallet/android/app/key.jks
+          key: $STORE_PASS
+
+      - if: ${{ steps.cache-keystore.outputs.cache-hit != 'true' }}
+        name: Generate KeyStore
+        run: |
+          cd /opt/android/cake_wallet/android/app
+          keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS
diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml
index a12fd422f..1a67ed0ec 100644
--- a/.github/workflows/pr_test_build_android.yml
+++ b/.github/workflows/pr_test_build_android.yml
@@ -116,8 +116,15 @@ jobs:
           cd /opt/android/cake_wallet/scripts/android/
           ./build_mwebd.sh --dont-install
 
-      - name: Generate KeyStore
-        if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
+      - name: Cache Keystore
+        id: cache-keystore
+        uses: actions/cache@v3
+        with:
+          path: /opt/android/cake_wallet/android/app/key.jks
+          key: $STORE_PASS
+
+      - if: ${{ steps.cache-keystore.outputs.cache-hit != 'true' }}
+        name: Generate KeyStore
         run: |
           cd /opt/android/cake_wallet/android/app
           keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS
@@ -205,6 +212,36 @@ jobs:
         run: |
           echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
 
+      # Step 3: Download previous build number
+      - name: Download previous build number
+        id: download-build-number
+        run: |
+          # Download the artifact if it exists
+          if [[ ! -f build_number.txt ]]; then
+            echo "1" > build_number.txt
+          fi
+
+      # Step 4: Read and Increment Build Number
+      - name: Increment Build Number
+        id: increment-build-number
+        run: |
+          # Read current build number from file
+          BUILD_NUMBER=$(cat build_number.txt)
+          BUILD_NUMBER=$((BUILD_NUMBER + 1))
+          echo "New build number: $BUILD_NUMBER"
+
+          # Save the incremented build number
+          echo "$BUILD_NUMBER" > build_number.txt
+
+          # Export the build number to use in later steps
+          echo "BUILD_NUMBER=$BUILD_NUMBER" >> $GITHUB_ENV
+
+      # Step 5: Update pubspec.yaml with new build number
+      - name: Update build number
+        run: |
+          cd /opt/android/cake_wallet
+          sed -i "s/^version: .*/version: 1.0.$BUILD_NUMBER/" pubspec.yaml
+
       - name: Build
         run: |
           cd /opt/android/cake_wallet
@@ -235,6 +272,13 @@ jobs:
         with:
           path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/test-apk/
 
+      # Re-upload updated build number for the next run
+      - name: Upload updated build number
+        uses: actions/upload-artifact@v3
+        with:
+          name: build_number
+          path: build_number.txt
+
       - name: Send Test APK
         continue-on-error: true
         uses: adrey/slack-file-upload-action@1.0.5
@@ -245,3 +289,4 @@ jobs:
           title: "${{ env.BRANCH_NAME }}.apk"
           filename: ${{ env.BRANCH_NAME }}.apk
           initial_comment: ${{ github.event.head_commit.message }}
+

From 5301ee4584429e57667a4f5a582b3b1538eec659 Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Sat, 9 Nov 2024 23:44:08 +0200
Subject: [PATCH 10/15] Update onramper_buy_provider.dart (#1796)

---
 lib/buy/onramper/onramper_buy_provider.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/buy/onramper/onramper_buy_provider.dart b/lib/buy/onramper/onramper_buy_provider.dart
index ee9c9bb74..dade41d43 100644
--- a/lib/buy/onramper/onramper_buy_provider.dart
+++ b/lib/buy/onramper/onramper_buy_provider.dart
@@ -217,7 +217,7 @@ class OnRamperBuyProvider extends BuyProvider {
       'apiKey': _apiKey,
       'mode': actionType,
       '${prefix}defaultFiat': quote.fiatCurrency.name,
-      '${prefix}defaultCrypto': quote.cryptoCurrency.name,
+      '${prefix}defaultCrypto': defaultCrypto,
       '${prefix}defaultAmount': amount.toString(),
       if (paymentMethod != null) '${prefix}defaultPaymentMethod': paymentMethod,
       'onlyOnramps': quote.rampId,

From ed69dc803b70d13b83b6d5445171fe99b18e9dee Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Sun, 10 Nov 2024 00:14:38 +0200
Subject: [PATCH 11/15] fix cache key

---
 .github/workflows/pr_test_build_android.yml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml
index 1a67ed0ec..1f2a9636e 100644
--- a/.github/workflows/pr_test_build_android.yml
+++ b/.github/workflows/pr_test_build_android.yml
@@ -82,8 +82,7 @@ jobs:
           path: |
             /opt/android/cake_wallet/cw_haven/android/.cxx
             /opt/android/cake_wallet/scripts/monero_c/release
-            /opt/android/cake_wallet/android/app/key.jks
-          key: android_${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
+          key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
 
       - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
         name: Generate Externals

From 89525b189732973b7e8b32f5be5157a96d0cdab1 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Sun, 10 Nov 2024 01:16:21 +0200
Subject: [PATCH 12/15] temporarily disable key caching

---
 .github/workflows/pr_test_build_android.yml | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml
index 1f2a9636e..774404e3b 100644
--- a/.github/workflows/pr_test_build_android.yml
+++ b/.github/workflows/pr_test_build_android.yml
@@ -115,15 +115,15 @@ jobs:
           cd /opt/android/cake_wallet/scripts/android/
           ./build_mwebd.sh --dont-install
 
-      - name: Cache Keystore
-        id: cache-keystore
-        uses: actions/cache@v3
-        with:
-          path: /opt/android/cake_wallet/android/app/key.jks
-          key: $STORE_PASS
-
-      - if: ${{ steps.cache-keystore.outputs.cache-hit != 'true' }}
-        name: Generate KeyStore
+#      - name: Cache Keystore
+#        id: cache-keystore
+#        uses: actions/cache@v3
+#        with:
+#          path: /opt/android/cake_wallet/android/app/key.jks
+#          key: $STORE_PASS
+#
+#      - if: ${{ steps.cache-keystore.outputs.cache-hit != 'true' }}
+      - name: Generate KeyStore
         run: |
           cd /opt/android/cake_wallet/android/app
           keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS

From e148f645086e0c6797aab2121d8e707fa8cc18c7 Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Mon, 11 Nov 2024 19:39:45 +0200
Subject: [PATCH 13/15] fix the UI issue with sending outputs (#1798)

---
 lib/view_model/send/send_view_model.dart | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart
index 4621e8d16..69011aa74 100644
--- a/lib/view_model/send/send_view_model.dart
+++ b/lib/view_model/send/send_view_model.dart
@@ -404,8 +404,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
         final updatedOutputs = bitcoin!.updateOutputs(pendingTransaction!, outputs);
 
         if (outputs.length == updatedOutputs.length) {
-          outputs.clear();
-          outputs.addAll(updatedOutputs);
+          outputs.replaceRange(0, outputs.length, updatedOutputs);
         }
       }
 

From 2c37e427e9eb7e2c882fdd7577f7ab8cfa28c558 Mon Sep 17 00:00:00 2001
From: Konstantin Ullrich <konstantinullrich12@gmail.com>
Date: Tue, 12 Nov 2024 04:26:09 +0100
Subject: [PATCH 14/15] Cw 660 add ledger monero (#1747)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Fix conflicts with main

* fix for multiple wallets

* Add tron to windows application configuration.

* Add macOS option for description message in configure_cake_wallet.sh

* Include missed monero dll for windows.

* fix conflicts with main

* Disable haven configuration for iOS as default. Add ability to configure cakewallet for iOS with  for configuration script. Remove cw_shared configuration for cw_monero.

* fix: scan fixes, add date, allow sending while scanning

* add missing nano secrets file [skip ci]

* ios library

* don't pull prebuilds android

* Add auto generation of manifest file for android project even for iOS, macOS, Windows.

* feat: sync fixes, sp settings

* feat: fix resyncing

* store crash fix

* make init async so it won't lag
disable print starts

* fix monero_c build issues

* libstdc++

* Fix MacOS saving wallet file issue
Fix Secure Storage issue (somehow)

* update pubspec.lock

* fix build script

* Use dylib as iOS framework. Use custom path for loading of iOS framework for monero.dart. Add script for generate iOS framework for monero wallet.

* fix: date from height logic, status disconnected & chain tip get

* fix: params

* feat: electrum migration if using cake electrum

* fix nodes
update versions

* re-enable tron

* update sp_scanner to work on iOS [skip ci]

* bump monero_c hash

* bump monero_c commit

* bump moneroc version

* bump monero_c commit

* Add ability to build monero wallet lib as universal lib. Update macOS build guide. Change default arch for macOS project to .

* fix: wrong socket for old electrum nodes

* Fix unchecked wallet type call

* get App Dir correctly in default_settings_migration.dart

* handle previous issue with fetching linux documents directory [skip ci]

* backup fix

* fix NTFS issues

* Close the wallet when the wallet gets changed

* fix: double balance

* feat: node domain

* fix: menu name

* bump monero_c commit

* fix: update tip on set scanning

* fix: connection switching back and forth

* feat: check if node is electrs, and supports sp

* chore: fix build

* minor enhancements

* fixes and enhancements

* solve conflicts with main

* Only stop wallet on rename and delete

* fix: status toggle

* minor enhancement

* Monero.com fixes

* bump monero_c commit

* update sp_scanner to include windows and linux

* Update macOS build guide. Change brew dependencies for build unbound locally.

* fix conflicts and update macos build guide

* remove build cache when on gh actions

* update secure storage

* free up even more storage

* free up more storage

* Add initial wownero

* fix conflicts

* fix workflow issue

* build wownero

* ios and windows changes

* macos

* complete wownero flow (app side)

* add keychain group entitlement and update script for RunnerBase on macos

* update secure_storage version to 8.1.0 in configure.dart

* add wownero framework

* update ios builds

* proper path for wownero and monero

* finalizing wownero

* finalizing wownero

* free up even more storage

* revert commenting of build gradle configs

* revert commenting of secrets [skip ci]

* free more storage

* minor fixes

* link android wownero libraries

* bump monero_c commit

* wownero fixes

* rename target

* build_single.sh using clean env

* bump monero_c commit

* minor fix

* Add wownero polyseed

* fix conflicts with main

* fix: wallet seed display
fix: wownero not refreshing

* fix: wallet seed display
fix: wownero not refreshing

* bump monero_c commit

* minor fixes

* fix: incorrectly displaying XMR instead of WOW

* fix: incorrect restore height in wownero

* bump monero_c commit

* Add Inno Setup Script for windows exe installer

* drop libc++_shared.so

* fixes from comments

* Fix CMake for windows

* Merge latest monero dart changes [skip ci]

* bump monero_c commit

* add wownero to build scripts for macos [skip ci]

* add 14 word seed support to wownero

* UI fixes for wownero seed restore

* minor fixes

* reformat code to pass lints

* Add debug ledger code

* Add Litecoin Hardware Wallet Creation

* Add Litecoin Hardware Wallet Creation

* Fix Bitcoin not sending on Ledger

* Fixes to sending LTC using Ledger

* CW-679 Fix merge conflicts

* CW-679 Fix merge conflicts

* CW-679 Minor fixes

* CW-679 Add derivation Path of change address

* Add create Monero Wallet from Ledger

* bug fix to create Monero Wallet from Ledger

* ledger flutter plus refactoring

* ledger flutter plus refactoring

* ledger flutter plus refactoring

* Ups :|

* Ups :| I forgot USB

* Handle BT Off

* Fix Issue with A14 and USB

* Small Ledger Quality of life improvements

* Small Ledger Quality of life improvements

* Small Ledger Quality of life improvements

* Small Ledger Quality of life improvements

* Small Ledger Quality of life improvements

* Small Ledger Quality of life improvements

* Small Ledger Quality of life improvements

* Pls work

* Pls work

* Pls work

* Pls work

* Fix overpopulation

* Fix ble device detection and support for Stax and Flex

* clean up pubspec

* clean up

* MWeb merge fix

* MWeb merge fix

* Migrate to Ledger Flutter Plus

* Add connect device page before loading the wallet (Only monero)

* Add connect device page before loading the wallet (Only monero)

* Fix merge error

* Fix merge error

* Fix merge error && Allow for wallet switching

* Please compile now

* Move monero/ledger.dart from monero_c to cw_monero

* Upgrade ledger_flutter_plus

* Add more popups if action on the device is needed.

* Update monero_c dependency hash

* Yay ledger monero is even more efficient and avoids memory leaks 🥳

* [skip-ci] more code

* Fix Minor Bug

* Fix Minor Bug

* Apply requested changes

* [skip ci] Apply requested changes

* Minor Cleanup

* Welp I'm dumb :/

* Implement requested changes

* Increase ledger refresh speed

* Add Monero Ledger keep connection alive

* Add Monero Ledger keep connection alive

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
Co-authored-by: m <m@cakewallet.com>
Co-authored-by: Rafael Saes <git@rafael.saes.dev>
Co-authored-by: Matthew Fosse <matt@fosse.co>
---
 build-guide-win.md                            |   38 +
 cw_bitcoin/pubspec.lock                       |    8 +-
 .../lib/hardware/device_connection_type.dart  |    1 +
 cw_core/lib/wallet_service.dart               |    4 +
 cw_monero/lib/api/wallet.dart                 |    4 +-
 cw_monero/lib/api/wallet_manager.dart         |  147 +-
 cw_monero/lib/ledger.dart                     |   88 +
 cw_monero/lib/monero_wallet.dart              |    7 +
 cw_monero/lib/monero_wallet_service.dart      |  108 +-
 cw_monero/pubspec.lock                        |  130 +-
 cw_monero/pubspec.yaml                        |    4 +-
 .../connection_to_node_exception.dart         |    5 +
 cw_wownero/lib/api/structs/account_row.dart   |   12 +
 .../lib/api/structs/coins_info_row.dart       |   73 +
 .../lib/api/structs/subaddress_row.dart       |   15 +
 .../lib/api/structs/transaction_info_row.dart |   41 +
 cw_wownero/lib/api/structs/ut8_box.dart       |    8 +
 cw_wownero/lib/cw_wownero.dart                |    8 +
 cw_wownero/lib/cw_wownero_method_channel.dart |   17 +
 .../lib/cw_wownero_platform_interface.dart    |   29 +
 cw_wownero/lib/mywownero.dart                 | 1689 +++++++++++++++++
 cw_wownero/pubspec.lock                       |   92 +-
 cw_wownero/pubspec.yaml                       |    3 +-
 lib/core/wallet_loading_service.dart          |   14 +-
 lib/di.dart                                   |   15 +-
 .../require_hardware_wallet_connection.dart   |   25 +
 lib/monero/cw_monero.dart                     |   25 +
 .../on_authentication_state_change.dart       |   57 +-
 lib/router.dart                               |    9 +-
 .../connect_device/connect_device_page.dart   |   66 +-
 .../monero_hardware_wallet_options_page.dart  |  230 +++
 .../screens/wallet_list/wallet_list_page.dart |  135 +-
 .../dashboard/dashboard_view_model.dart       |    2 +-
 .../hardware_wallet/ledger_view_model.dart    |    3 +
 .../wallet_hardware_restore_view_model.dart   |   15 +-
 .../wallet_list/wallet_list_view_model.dart   |   19 +-
 scripts/prepare_moneroc.sh                    |    4 +-
 tool/configure.dart                           |   11 +-
 38 files changed, 2912 insertions(+), 249 deletions(-)
 create mode 100644 build-guide-win.md
 create mode 100644 cw_monero/lib/ledger.dart
 create mode 100644 cw_wownero/lib/api/exceptions/connection_to_node_exception.dart
 create mode 100644 cw_wownero/lib/api/structs/account_row.dart
 create mode 100644 cw_wownero/lib/api/structs/coins_info_row.dart
 create mode 100644 cw_wownero/lib/api/structs/subaddress_row.dart
 create mode 100644 cw_wownero/lib/api/structs/transaction_info_row.dart
 create mode 100644 cw_wownero/lib/api/structs/ut8_box.dart
 create mode 100644 cw_wownero/lib/cw_wownero.dart
 create mode 100644 cw_wownero/lib/cw_wownero_method_channel.dart
 create mode 100644 cw_wownero/lib/cw_wownero_platform_interface.dart
 create mode 100644 cw_wownero/lib/mywownero.dart
 create mode 100644 lib/entities/hardware_wallet/require_hardware_wallet_connection.dart
 create mode 100644 lib/src/screens/connect_device/monero_hardware_wallet_options_page.dart

diff --git a/build-guide-win.md b/build-guide-win.md
new file mode 100644
index 000000000..6ace961af
--- /dev/null
+++ b/build-guide-win.md
@@ -0,0 +1,38 @@
+# Building CakeWallet for Windows
+
+## Requirements and Setup
+
+The following are the system requirements to build CakeWallet for your Windows PC.
+
+```
+Windows 10 or later (64-bit), x86-64 based
+Flutter 3 or above
+```
+
+## Building CakeWallet on Windows
+
+These steps will help you configure and execute a build of CakeWallet from its source code.
+
+### 1. Installing Package Dependencies
+
+For build CakeWallet windows application from sources you will be needed to have:
+> [Install Flutter]Follow installation guide (https://docs.flutter.dev/get-started/install/windows) and install do not miss to dev tools (install https://docs.flutter.dev/get-started/install/windows/desktop#development-tools) which are required for windows desktop development (need to install Git for Windows and Visual Studio 2022). Then install `Desktop development with C++` packages via GUI Visual Studio 2022, or Visual Studio Build Tools 2022 including: `C++ Build Tools core features`, `C++ 2022 Redistributable Update`, `C++ core desktop features`, `MVC v143 - VS 2022 C++ x64/x86 build tools`, `C++ CMake tools for Windwos`, `Testing tools core features - Build Tools`, `C++ AddressSanitizer`.
+> [Install WSL] for building monero dependencies need to install Windows WSL (https://learn.microsoft.com/en-us/windows/wsl/install) and required packages for WSL (Ubuntu):
+`$ sudo apt update `
+`$ sudo apt build-essential cmake gcc-mingw-w64 g++-mingw-w64 autoconf libtool pkg-config`
+
+### 2. Pull CakeWallet source code
+
+You can downlaod CakeWallet source code from our [GitHub repository](github.com/cake-tech/cake_wallet) via git by following next command:
+`$ git clone https://github.com/cake-tech/cake_wallet.git --branch MrCyjaneK-cyjan-monerodart`
+OR you can download it as [Zip archive](https://github.com/cake-tech/cake_wallet/archive/refs/heads/MrCyjaneK-cyjan-monerodart.zip)
+
+### 3. Build Monero, Monero_c and their dependencies
+
+For use monero in the application need to build Monero wrapper - Monero_C which will be used by monero.dart package. For that need to run shell (bash - typically same named utility should be available after WSL is enabled in your system) with previously installed WSL, then change current directory to the application project directory with your used shell and then change current directory to `scripts/windows`: `$ cd scripts/windows`. Run build script: `$ ./build_all.sh`.
+
+### 4. Configure and build CakeWallet application
+
+To configure the application open directory where you have downloaded or unarchived CakeWallet sources and run `cakewallet.bat`.
+Or if you used WSL and have active shell session you can run `$ ./cakewallet.sh` script in `scripts/windows` which will run `cakewallet.bat` in WSL.
+After execution of `cakewallet.bat` you should to get `Cake Wallet.zip` in project root directory which will contains `CakeWallet.exe` file and another needed files for run the application. Now you can extract files from `Cake Wallet.zip` archive and run the application.
diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock
index 0e4921a3a..8eafb2a44 100644
--- a/cw_bitcoin/pubspec.lock
+++ b/cw_bitcoin/pubspec.lock
@@ -386,10 +386,10 @@ packages:
     dependency: transitive
     description:
       name: flutter_web_bluetooth
-      sha256: "52ce64f65d7321c4bf6abfe9dac02fb888731339a5e0ad6de59fb916c20c9f02"
+      sha256: fcd03e2e5f82edcedcbc940f1b6a0635a50757374183254f447640886c53208e
       url: "https://pub.dev"
     source: hosted
-    version: "0.2.3"
+    version: "0.2.4"
   flutter_web_plugins:
     dependency: transitive
     description: flutter
@@ -560,7 +560,7 @@ packages:
     description:
       path: "packages/ledger-bitcoin"
       ref: HEAD
-      resolved-ref: dbb5c4956949dc734af3fc8febdbabed89da72aa
+      resolved-ref: "07cd61ef76a2a017b6d5ef233396740163265457"
       url: "https://github.com/cake-tech/ledger-flutter-plus-plugins"
     source: git
     version: "0.0.3"
@@ -577,7 +577,7 @@ packages:
     description:
       path: "packages/ledger-litecoin"
       ref: HEAD
-      resolved-ref: dbb5c4956949dc734af3fc8febdbabed89da72aa
+      resolved-ref: "07cd61ef76a2a017b6d5ef233396740163265457"
       url: "https://github.com/cake-tech/ledger-flutter-plus-plugins"
     source: git
     version: "0.0.2"
diff --git a/cw_core/lib/hardware/device_connection_type.dart b/cw_core/lib/hardware/device_connection_type.dart
index 9a3069552..76a501af1 100644
--- a/cw_core/lib/hardware/device_connection_type.dart
+++ b/cw_core/lib/hardware/device_connection_type.dart
@@ -7,6 +7,7 @@ enum DeviceConnectionType {
   static List<DeviceConnectionType> supportedConnectionTypes(WalletType walletType,
       [bool isIOS = false]) {
     switch (walletType) {
+      case WalletType.monero:
       case WalletType.bitcoin:
       case WalletType.litecoin:
       case WalletType.ethereum:
diff --git a/cw_core/lib/wallet_service.dart b/cw_core/lib/wallet_service.dart
index d90ae30bc..85126853e 100644
--- a/cw_core/lib/wallet_service.dart
+++ b/cw_core/lib/wallet_service.dart
@@ -61,4 +61,8 @@ abstract class WalletService<N extends WalletCredentials, RFS extends WalletCred
       return '';
     }
   }
+
+  /// Check if the Wallet requires a hardware wallet to be connected during
+  /// the opening flow. (Currently only the case for Monero)
+  bool requireHardwareWalletConnection(String name) => false;
 }
diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart
index 8e03cff3e..928fd7ef1 100644
--- a/cw_monero/lib/api/wallet.dart
+++ b/cw_monero/lib/api/wallet.dart
@@ -119,7 +119,7 @@ Future<bool> setupNodeSync(
         daemonUsername: login ?? '',
         daemonPassword: password ?? '');
   });
-  // monero.Wallet_init3(wptr!, argv0: '', defaultLogBaseName: 'moneroc', console: true);
+  // monero.Wallet_init3(wptr!, argv0: '', defaultLogBaseName: 'moneroc', console: true, logPath: '');
 
   final status = monero.Wallet_status(wptr!);
 
@@ -330,4 +330,4 @@ String signMessage(String message, {String address = ""}) {
 
 bool verifyMessage(String message, String address, String signature) {
   return monero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature);
-}
\ No newline at end of file
+}
diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart
index 61fd6edf0..7f9dbd8fa 100644
--- a/cw_monero/lib/api/wallet_manager.dart
+++ b/cw_monero/lib/api/wallet_manager.dart
@@ -7,19 +7,18 @@ import 'package:cw_monero/api/exceptions/wallet_creation_exception.dart';
 import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
 import 'package:cw_monero/api/exceptions/wallet_restore_from_keys_exception.dart';
 import 'package:cw_monero/api/exceptions/wallet_restore_from_seed_exception.dart';
-import 'package:cw_monero/api/wallet.dart';
 import 'package:cw_monero/api/transaction_history.dart';
+import 'package:cw_monero/api/wallet.dart';
+import 'package:cw_monero/ledger.dart';
 import 'package:monero/monero.dart' as monero;
 
 class MoneroCException implements Exception {
   final String message;
 
   MoneroCException(this.message);
-  
+
   @override
-  String toString() {
-    return message;
-  }
+  String toString() => message;
 }
 
 void checkIfMoneroCIsFine() {
@@ -43,7 +42,6 @@ void checkIfMoneroCIsFine() {
     throw MoneroCException("monero_c and monero.dart wrapper export list mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsExp'\ndart: '$dartCsExp'");
   }
 }
-
 monero.WalletManager? _wmPtr;
 final monero.WalletManager wmPtr = Pointer.fromAddress((() {
   try {
@@ -60,6 +58,13 @@ final monero.WalletManager wmPtr = Pointer.fromAddress((() {
   return _wmPtr!.address;
 })());
 
+void createWalletPointer() {
+  final newWptr = monero.WalletManager_createWallet(wmPtr,
+      path: "", password: "", language: "", networkType: 0);
+
+  wptr = newWptr;
+}
+
 void createWalletSync(
     {required String path,
     required String password,
@@ -124,24 +129,24 @@ void restoreWalletFromKeysSync(
     int restoreHeight = 0}) {
   txhistory = null;
   var newWptr = (spendKey != "")
-   ? monero.WalletManager_createDeterministicWalletFromSpendKey(
-    wmPtr,
-    path: path,
-    password: password,
-    language: language,
-    spendKeyString: spendKey, 
-    newWallet: true, // TODO(mrcyjanek): safe to remove
-    restoreHeight: restoreHeight)
-   : monero.WalletManager_createWalletFromKeys(
-    wmPtr,
-    path: path,
-    password: password,
-    restoreHeight: restoreHeight,
-    addressString: address,
-    viewKeyString: viewKey,
-    spendKeyString: spendKey,
-    nettype: 0,
-  );
+      ? monero.WalletManager_createDeterministicWalletFromSpendKey(wmPtr,
+          path: path,
+          password: password,
+          language: language,
+          spendKeyString: spendKey,
+          newWallet: true,
+          // TODO(mrcyjanek): safe to remove
+          restoreHeight: restoreHeight)
+      : monero.WalletManager_createWalletFromKeys(
+          wmPtr,
+          path: path,
+          password: password,
+          restoreHeight: restoreHeight,
+          addressString: address,
+          viewKeyString: viewKey,
+          spendKeyString: spendKey,
+          nettype: 0,
+        );
 
   final status = monero.Wallet_status(newWptr);
   if (status != 0) {
@@ -156,7 +161,7 @@ void restoreWalletFromKeysSync(
     if (viewKey != viewKeyRestored && viewKey != "") {
       monero.WalletManager_closeWallet(wmPtr, newWptr, false);
       File(path).deleteSync();
-      File(path+".keys").deleteSync();
+      File(path + ".keys").deleteSync();
       newWptr = monero.WalletManager_createWalletFromKeys(
         wmPtr,
         path: path,
@@ -199,7 +204,7 @@ void restoreWalletFromSpendKeySync(
   //   viewKeyString: '',
   //   nettype: 0,
   // );
-  
+
   txhistory = null;
   final newWptr = monero.WalletManager_createDeterministicWalletFromSpendKey(
     wmPtr,
@@ -230,41 +235,39 @@ void restoreWalletFromSpendKeySync(
 
 String _lastOpenedWallet = "";
 
-// void restoreMoneroWalletFromDevice(
-//     {required String path,
-//       required String password,
-//       required String deviceName,
-//       int nettype = 0,
-//       int restoreHeight = 0}) {
-//
-//   final pathPointer = path.toNativeUtf8();
-//   final passwordPointer = password.toNativeUtf8();
-//   final deviceNamePointer = deviceName.toNativeUtf8();
-//   final errorMessagePointer = ''.toNativeUtf8();
-//
-//   final isWalletRestored = restoreWalletFromDeviceNative(
-//       pathPointer,
-//       passwordPointer,
-//       deviceNamePointer,
-//       nettype,
-//       restoreHeight,
-//       errorMessagePointer) != 0;
-//
-//   calloc.free(pathPointer);
-//   calloc.free(passwordPointer);
-//
-//   storeSync();
-//
-//   if (!isWalletRestored) {
-//     throw WalletRestoreFromKeysException(
-//         message: convertUTF8ToString(pointer: errorMessagePointer));
-//   }
-// }
+Future<void> restoreWalletFromHardwareWallet(
+    {required String path,
+    required String password,
+    required String deviceName,
+    int nettype = 0,
+    int restoreHeight = 0}) async {
+  txhistory = null;
+
+  final newWptrAddr = await Isolate.run(() {
+    return monero.WalletManager_createWalletFromDevice(wmPtr,
+            path: path,
+            password: password,
+            restoreHeight: restoreHeight,
+            deviceName: deviceName)
+        .address;
+  });
+  final newWptr = Pointer<Void>.fromAddress(newWptrAddr);
+
+  final status = monero.Wallet_status(newWptr);
+
+  if (status != 0) {
+    final error = monero.Wallet_errorString(newWptr);
+    throw WalletRestoreFromSeedException(message: error);
+  }
+  wptr = newWptr;
+
+  openedWalletsByPath[path] = wptr!;
+}
 
 Map<String, monero.wallet> openedWalletsByPath = {};
 
-void loadWallet(
-    {required String path, required String password, int nettype = 0}) {
+Future<void> loadWallet(
+    {required String path, required String password, int nettype = 0}) async {
   if (openedWalletsByPath[path] != null) {
     txhistory = null;
     wptr = openedWalletsByPath[path]!;
@@ -278,8 +281,29 @@ void loadWallet(
       });
     }
     txhistory = null;
-    final newWptr = monero.WalletManager_openWallet(wmPtr,
-        path: path, password: password);
+
+    /// Get the device type
+    /// 0: Software Wallet
+    /// 1: Ledger
+    /// 2: Trezor
+    final deviceType = monero.WalletManager_queryWalletDevice(wmPtr,
+        keysFileName: "$path.keys", password: password, kdfRounds: 1);
+
+    if (deviceType == 1) {
+      final dummyWPtr = wptr ??
+          monero.WalletManager_openWallet(wmPtr, path: '', password: '');
+      enableLedgerExchange(dummyWPtr, gLedger!);
+    }
+
+    final addr = wmPtr.address;
+    final newWptrAddr = await Isolate.run(() {
+      return monero.WalletManager_openWallet(Pointer.fromAddress(addr),
+              path: path, password: password)
+          .address;
+    });
+
+    final newWptr = Pointer<Void>.fromAddress(newWptrAddr);
+
     _lastOpenedWallet = path;
     final status = monero.Wallet_status(newWptr);
     if (status != 0) {
@@ -287,6 +311,7 @@ void loadWallet(
       print(err);
       throw WalletOpeningException(message: err);
     }
+
     wptr = newWptr;
     openedWalletsByPath[path] = wptr!;
   }
@@ -351,7 +376,7 @@ Future<void> _openWallet(Map<String, String> args) async => loadWallet(
 
 bool _isWalletExist(String path) => isWalletExistSync(path: path);
 
-void openWallet(
+Future<void> openWallet(
         {required String path,
         required String password,
         int nettype = 0}) async =>
diff --git a/cw_monero/lib/ledger.dart b/cw_monero/lib/ledger.dart
new file mode 100644
index 000000000..074975df3
--- /dev/null
+++ b/cw_monero/lib/ledger.dart
@@ -0,0 +1,88 @@
+import 'dart:async';
+import 'dart:ffi';
+import 'dart:typed_data';
+
+import 'package:ffi/ffi.dart';
+import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
+import 'package:ledger_flutter_plus/ledger_flutter_plus_dart.dart';
+import 'package:monero/monero.dart' as monero;
+// import 'package:polyseed/polyseed.dart';
+
+LedgerConnection? gLedger;
+
+Timer? _ledgerExchangeTimer;
+Timer? _ledgerKeepAlive;
+
+void enableLedgerExchange(monero.wallet ptr, LedgerConnection connection) {
+  _ledgerExchangeTimer?.cancel();
+  _ledgerExchangeTimer = Timer.periodic(Duration(milliseconds: 1), (_) async {
+    final ledgerRequestLength = monero.Wallet_getSendToDeviceLength(ptr);
+    final ledgerRequest = monero.Wallet_getSendToDevice(ptr)
+        .cast<Uint8>()
+        .asTypedList(ledgerRequestLength);
+    if (ledgerRequestLength > 0) {
+      _ledgerKeepAlive?.cancel();
+
+      final Pointer<Uint8> emptyPointer = malloc<Uint8>(0);
+      monero.Wallet_setDeviceSendData(
+          ptr, emptyPointer.cast<UnsignedChar>(), 0);
+      malloc.free(emptyPointer);
+
+      // print("> ${ledgerRequest.toHexString()}");
+      final response = await exchange(connection, ledgerRequest);
+      // print("< ${response.toHexString()}");
+
+      final Pointer<Uint8> result = malloc<Uint8>(response.length);
+      for (var i = 0; i < response.length; i++) {
+        result.asTypedList(response.length)[i] = response[i];
+      }
+
+      monero.Wallet_setDeviceReceivedData(
+          ptr, result.cast<UnsignedChar>(), response.length);
+      malloc.free(result);
+      keepAlive(connection);
+    }
+  });
+}
+
+void keepAlive(LedgerConnection connection) {
+  if (connection.connectionType == ConnectionType.ble) {
+    UniversalBle.onConnectionChange = (String deviceId, bool isConnected) {
+      print("[Monero] Ledger Disconnected");
+      _ledgerKeepAlive?.cancel();
+    };
+    _ledgerKeepAlive = Timer.periodic(Duration(seconds: 10), (_) async {
+      try {
+        UniversalBle.setNotifiable(
+          connection.device.id,
+          connection.device.deviceInfo.serviceId,
+          connection.device.deviceInfo.notifyCharacteristicKey,
+          BleInputProperty.notification,
+        );
+      } catch (_){}
+    });
+  }
+}
+
+void disableLedgerExchange() {
+  _ledgerExchangeTimer?.cancel();
+  _ledgerKeepAlive?.cancel();
+  gLedger?.disconnect();
+  gLedger = null;
+}
+
+Future<Uint8List> exchange(LedgerConnection connection, Uint8List data) async =>
+    connection.sendOperation<Uint8List>(ExchangeOperation(data));
+
+class ExchangeOperation extends LedgerRawOperation<Uint8List> {
+  final Uint8List inputData;
+
+  ExchangeOperation(this.inputData);
+
+  @override
+  Future<Uint8List> read(ByteDataReader reader) async =>
+      reader.read(reader.remainingLength);
+
+  @override
+  Future<List<Uint8List>> write(ByteDataWriter writer) async => [inputData];
+}
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index bc8c3c94d..5f53b30ba 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -28,6 +28,7 @@ import 'package:cw_monero/api/wallet.dart' as monero_wallet;
 import 'package:cw_monero/api/wallet_manager.dart';
 import 'package:cw_monero/exceptions/monero_transaction_creation_exception.dart';
 import 'package:cw_monero/exceptions/monero_transaction_no_inputs_exception.dart';
+import 'package:cw_monero/ledger.dart';
 import 'package:cw_monero/monero_transaction_creation_credentials.dart';
 import 'package:cw_monero/monero_transaction_history.dart';
 import 'package:cw_monero/monero_transaction_info.dart';
@@ -36,6 +37,7 @@ import 'package:cw_monero/monero_wallet_addresses.dart';
 import 'package:cw_monero/pending_monero_transaction.dart';
 import 'package:flutter/foundation.dart';
 import 'package:hive/hive.dart';
+import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
 import 'package:mobx/mobx.dart';
 import 'package:monero/monero.dart' as monero;
 
@@ -828,4 +830,9 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
     return monero_wallet.verifyMessage(message, address, signature);
   }
 
+  void setLedgerConnection(LedgerConnection connection) {
+    final dummyWPtr = wptr ??
+        monero.WalletManager_openWallet(wmPtr, path: '', password: '');
+    enableLedgerExchange(dummyWPtr, connection);
+  }
 }
diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart
index 63ad17583..b2089dfc7 100644
--- a/cw_monero/lib/monero_wallet_service.dart
+++ b/cw_monero/lib/monero_wallet_service.dart
@@ -9,10 +9,13 @@ import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:cw_core/get_height_by_date.dart';
+import 'package:cw_monero/api/account_list.dart';
 import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
 import 'package:cw_monero/api/wallet_manager.dart';
+import 'package:cw_monero/ledger.dart';
 import 'package:cw_monero/monero_wallet.dart';
 import 'package:hive/hive.dart';
+import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
 import 'package:polyseed/polyseed.dart';
 import 'package:monero/monero.dart' as monero;
 
@@ -25,6 +28,15 @@ class MoneroNewWalletCredentials extends WalletCredentials {
   final bool isPolyseed;
 }
 
+class MoneroRestoreWalletFromHardwareCredentials extends WalletCredentials {
+  MoneroRestoreWalletFromHardwareCredentials({required String name,
+    required this.ledgerConnection,
+    int height = 0,
+    String? password})
+      : super(name: name, password: password, height: height);
+  LedgerConnection ledgerConnection;
+}
+
 class MoneroRestoreWalletFromSeedCredentials extends WalletCredentials {
   MoneroRestoreWalletFromSeedCredentials(
       {required String name, required this.mnemonic, int height = 0, String? password})
@@ -39,14 +51,13 @@ class MoneroWalletLoadingException implements Exception {
 }
 
 class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials {
-  MoneroRestoreWalletFromKeysCredentials(
-      {required String name,
-      required String password,
-      required this.language,
-      required this.address,
-      required this.viewKey,
-      required this.spendKey,
-      int height = 0})
+  MoneroRestoreWalletFromKeysCredentials({required String name,
+    required String password,
+    required this.language,
+    required this.address,
+    required this.viewKey,
+    required this.spendKey,
+    int height = 0})
       : super(name: name, password: password, height: height);
 
   final String language;
@@ -59,7 +70,7 @@ class MoneroWalletService extends WalletService<
     MoneroNewWalletCredentials,
     MoneroRestoreWalletFromSeedCredentials,
     MoneroRestoreWalletFromKeysCredentials,
-    MoneroNewWalletCredentials> {
+    MoneroRestoreWalletFromHardwareCredentials> {
   MoneroWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
 
   final Box<WalletInfo> walletInfoSource;
@@ -81,7 +92,7 @@ class MoneroWalletService extends WalletService<
         final lang = PolyseedLang.getByEnglishName(credentials.language);
 
         final heightOverride =
-            getMoneroHeigthByDate(date: DateTime.now().subtract(Duration(days: 2)));
+        getMoneroHeigthByDate(date: DateTime.now().subtract(Duration(days: 2)));
 
         return _restoreFromPolyseed(
             path, credentials.password!, polyseed, credentials.walletInfo!, lang,
@@ -91,9 +102,9 @@ class MoneroWalletService extends WalletService<
       await monero_wallet_manager.createWallet(
           path: path, password: credentials.password!, language: credentials.language);
       final wallet = MoneroWallet(
-        walletInfo: credentials.walletInfo!,
-        unspentCoinsInfo: unspentCoinsInfoSource,
-        password: credentials.password!);
+          walletInfo: credentials.walletInfo!,
+          unspentCoinsInfo: unspentCoinsInfoSource,
+          password: credentials.password!);
       await wallet.init();
 
       return wallet;
@@ -128,11 +139,11 @@ class MoneroWalletService extends WalletService<
       await monero_wallet_manager
           .openWalletAsync({'path': path, 'password': password});
       final walletInfo = walletInfoSource.values.firstWhere(
-          (info) => info.id == WalletBase.idFor(name, getType()));
+              (info) => info.id == WalletBase.idFor(name, getType()));
       final wallet = MoneroWallet(
-        walletInfo: walletInfo,
-        unspentCoinsInfo: unspentCoinsInfoSource,
-        password: password);
+          walletInfo: walletInfo,
+          unspentCoinsInfo: unspentCoinsInfoSource,
+          password: password);
       final isValid = wallet.walletAddresses.validate();
 
       if (!isValid) {
@@ -185,10 +196,9 @@ class MoneroWalletService extends WalletService<
   }
 
   @override
-  Future<void> rename(
-      String currentName, String password, String newName) async {
+  Future<void> rename(String currentName, String password, String newName) async {
     final currentWalletInfo = walletInfoSource.values.firstWhere(
-        (info) => info.id == WalletBase.idFor(currentName, getType()));
+            (info) => info.id == WalletBase.idFor(currentName, getType()));
     final currentWallet = MoneroWallet(
       walletInfo: currentWalletInfo,
       unspentCoinsInfo: unspentCoinsInfoSource,
@@ -218,9 +228,9 @@ class MoneroWalletService extends WalletService<
           viewKey: credentials.viewKey,
           spendKey: credentials.spendKey);
       final wallet = MoneroWallet(
-        walletInfo: credentials.walletInfo!,
-        unspentCoinsInfo: unspentCoinsInfoSource,
-        password: credentials.password!);
+          walletInfo: credentials.walletInfo!,
+          unspentCoinsInfo: unspentCoinsInfoSource,
+          password: credentials.password!);
       await wallet.init();
 
       return wallet;
@@ -232,9 +242,34 @@ class MoneroWalletService extends WalletService<
   }
 
   @override
-  Future<MoneroWallet> restoreFromHardwareWallet(MoneroNewWalletCredentials credentials) {
-    throw UnimplementedError(
-        "Restoring a Monero wallet from a hardware wallet is not yet supported!");
+  Future<MoneroWallet> restoreFromHardwareWallet(
+      MoneroRestoreWalletFromHardwareCredentials credentials) async {
+    try {
+      final path = await pathForWallet(name: credentials.name, type: getType());
+      final password = credentials.password;
+      final height = credentials.height;
+
+      if (wptr == null ) monero_wallet_manager.createWalletPointer();
+
+      enableLedgerExchange(wptr!, credentials.ledgerConnection);
+      await monero_wallet_manager.restoreWalletFromHardwareWallet(
+            path: path,
+            password: password!,
+            restoreHeight: height!,
+            deviceName: 'Ledger');
+
+      final wallet = MoneroWallet(
+          walletInfo: credentials.walletInfo!,
+          unspentCoinsInfo: unspentCoinsInfoSource,
+          password: credentials.password!);
+      await wallet.init();
+
+      return wallet;
+    } catch (e) {
+      // TODO: Implement Exception for wallet list service.
+      print('MoneroWalletsManager Error: $e');
+      rethrow;
+    }
   }
 
   @override
@@ -253,9 +288,9 @@ class MoneroWalletService extends WalletService<
           seed: credentials.mnemonic,
           restoreHeight: credentials.height!);
       final wallet = MoneroWallet(
-        walletInfo: credentials.walletInfo!,
-        unspentCoinsInfo: unspentCoinsInfoSource,
-        password: credentials.password!);
+          walletInfo: credentials.walletInfo!,
+          unspentCoinsInfo: unspentCoinsInfoSource,
+          password: credentials.password!);
       await wallet.init();
 
       return wallet;
@@ -283,8 +318,8 @@ class MoneroWalletService extends WalletService<
     }
   }
 
-  Future<MoneroWallet> _restoreFromPolyseed(
-      String path, String password, Polyseed polyseed, WalletInfo walletInfo, PolyseedLang lang,
+  Future<MoneroWallet> _restoreFromPolyseed(String path, String password, Polyseed polyseed,
+      WalletInfo walletInfo, PolyseedLang lang,
       {PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO, int? overrideHeight}) async {
     final height = overrideHeight ??
         getMoneroHeigthByDate(date: DateTime.fromMillisecondsSinceEpoch(polyseed.birthday * 1000));
@@ -329,7 +364,9 @@ class MoneroWalletService extends WalletService<
 
       dir.listSync().forEach((f) {
         final file = File(f.path);
-        final name = f.path.split('/').last;
+        final name = f.path
+            .split('/')
+            .last;
         final newPath = newWalletDirPath + '/$name';
         final newFile = File(newPath);
 
@@ -366,4 +403,11 @@ class MoneroWalletService extends WalletService<
       return '';
     }
   }
+
+  @override
+  bool requireHardwareWalletConnection(String name) {
+    final walletInfo = walletInfoSource.values
+        .firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
+    return walletInfo.isHardwareWallet;
+  }
 }
diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock
index ee1d48df1..a6a03dce5 100644
--- a/cw_monero/pubspec.lock
+++ b/cw_monero/pubspec.lock
@@ -29,10 +29,10 @@ packages:
     dependency: transitive
     description:
       name: asn1lib
-      sha256: "58082b3f0dca697204dbab0ef9ff208bfaea7767ea771076af9a343488428dda"
+      sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70"
       url: "https://pub.dev"
     source: hosted
-    version: "1.5.3"
+    version: "1.5.5"
   async:
     dependency: transitive
     description:
@@ -41,6 +41,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.11.0"
+  bluez:
+    dependency: transitive
+    description:
+      name: bluez
+      sha256: "203a1924e818a9dd74af2b2c7a8f375ab8e5edf0e486bba8f90a0d8a17ed9fce"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.8.2"
   boolean_selector:
     dependency: transitive
     description:
@@ -209,6 +217,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.2.4"
+  dbus:
+    dependency: transitive
+    description:
+      name: dbus
+      sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.7.10"
   encrypt:
     dependency: "direct main"
     description:
@@ -229,10 +245,10 @@ packages:
     dependency: "direct main"
     description:
       name: ffi
-      sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
+      sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.2"
+    version: "2.1.3"
   file:
     dependency: transitive
     description:
@@ -267,6 +283,14 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  flutter_web_bluetooth:
+    dependency: transitive
+    description:
+      name: flutter_web_bluetooth
+      sha256: "52ce64f65d7321c4bf6abfe9dac02fb888731339a5e0ad6de59fb916c20c9f02"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.2.3"
   frontend_server_client:
     dependency: transitive
     description:
@@ -295,18 +319,18 @@ packages:
     dependency: transitive
     description:
       name: hashlib
-      sha256: d41795742c10947930630118c6836608deeb9047cd05aee32d2baeb697afd66a
+      sha256: f572f2abce09fc7aee53f15927052b9732ea1053e540af8cae211111ee0b99b1
       url: "https://pub.dev"
     source: hosted
-    version: "1.19.2"
+    version: "1.21.0"
   hashlib_codecs:
     dependency: transitive
     description:
       name: hashlib_codecs
-      sha256: "2b570061f5a4b378425be28a576c1e11783450355ad4345a19f606ff3d96db0f"
+      sha256: "8cea9ccafcfeaa7324d2ae52c61c69f7ff71f4237507a018caab31b9e416e3b1"
       url: "https://pub.dev"
     source: hosted
-    version: "2.5.0"
+    version: "2.6.0"
   hive:
     dependency: transitive
     description:
@@ -327,10 +351,10 @@ packages:
     dependency: "direct main"
     description:
       name: http
-      sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
+      sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.1"
+    version: "1.2.2"
   http_multi_server:
     dependency: transitive
     description:
@@ -403,6 +427,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.0.1"
+  ledger_flutter_plus:
+    dependency: "direct main"
+    description:
+      name: ledger_flutter_plus
+      sha256: c7b04008553193dbca7e17b430768eecc372a72b0ff3625b5e7fc5e5c8d3231b
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.4.1"
+  ledger_usb_plus:
+    dependency: transitive
+    description:
+      name: ledger_usb_plus
+      sha256: "21cc5d976cf7edb3518bd2a0c4164139cbb0817d2e4f2054707fc4edfdf9ce87"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.4"
   logging:
     dependency: transitive
     description:
@@ -439,10 +479,10 @@ packages:
     dependency: transitive
     description:
       name: mime
-      sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2"
+      sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
       url: "https://pub.dev"
     source: hosted
-    version: "1.0.5"
+    version: "1.0.6"
   mobx:
     dependency: "direct main"
     description:
@@ -463,8 +503,8 @@ packages:
     dependency: "direct main"
     description:
       path: "impls/monero.dart"
-      ref: "6eb571ea498ed7b854934785f00fabfd0dadf75b"
-      resolved-ref: "6eb571ea498ed7b854934785f00fabfd0dadf75b"
+      ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b
+      resolved-ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b
       url: "https://github.com/mrcyjanek/monero_c"
     source: git
     version: "0.0.0"
@@ -504,10 +544,10 @@ packages:
     dependency: "direct main"
     description:
       name: path_provider
-      sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161
+      sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.3"
+    version: "2.1.4"
   path_provider_android:
     dependency: transitive
     description:
@@ -544,10 +584,18 @@ packages:
     dependency: transitive
     description:
       name: path_provider_windows
-      sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
+      sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.1"
+    version: "2.3.0"
+  petitparser:
+    dependency: transitive
+    description:
+      name: petitparser
+      sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
+      url: "https://pub.dev"
+    source: hosted
+    version: "6.0.2"
   platform:
     dependency: transitive
     description:
@@ -612,6 +660,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.3.0"
+  rxdart:
+    dependency: transitive
+    description:
+      name: rxdart
+      sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.28.0"
   shelf:
     dependency: transitive
     description:
@@ -737,6 +793,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.3.2"
+  universal_ble:
+    dependency: transitive
+    description:
+      name: universal_ble
+      sha256: "0dfbd6b64bff3ad61ed7a895c232530d9614e9b01ab261a74433a43267edb7f3"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.12.0"
+  universal_platform:
+    dependency: transitive
+    description:
+      name: universal_platform
+      sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.1.0"
   unorm_dart:
     dependency: transitive
     description:
@@ -785,22 +857,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.4.5"
-  win32:
-    dependency: transitive
-    description:
-      name: win32
-      sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
-      url: "https://pub.dev"
-    source: hosted
-    version: "5.5.0"
   xdg_directories:
     dependency: transitive
     description:
       name: xdg_directories
-      sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
+      sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
       url: "https://pub.dev"
     source: hosted
-    version: "1.0.4"
+    version: "1.1.0"
+  xml:
+    dependency: transitive
+    description:
+      name: xml
+      sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
+      url: "https://pub.dev"
+    source: hosted
+    version: "6.5.0"
   yaml:
     dependency: transitive
     description:
@@ -811,4 +883,4 @@ packages:
     version: "3.1.2"
 sdks:
   dart: ">=3.3.0 <4.0.0"
-  flutter: ">=3.16.6"
+  flutter: ">=3.19.0"
diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml
index cb1f5519f..6fa235ee4 100644
--- a/cw_monero/pubspec.yaml
+++ b/cw_monero/pubspec.yaml
@@ -25,9 +25,11 @@ dependencies:
   monero:
     git:
       url: https://github.com/mrcyjanek/monero_c
-      ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash
+      ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b
+#      ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash
       path: impls/monero.dart
   mutex: ^3.1.0
+  ledger_flutter_plus: ^1.4.1
 
 dev_dependencies:
   flutter_test:
diff --git a/cw_wownero/lib/api/exceptions/connection_to_node_exception.dart b/cw_wownero/lib/api/exceptions/connection_to_node_exception.dart
new file mode 100644
index 000000000..483b0a174
--- /dev/null
+++ b/cw_wownero/lib/api/exceptions/connection_to_node_exception.dart
@@ -0,0 +1,5 @@
+class ConnectionToNodeException implements Exception {
+  ConnectionToNodeException({required this.message});
+
+  final String message;
+}
\ No newline at end of file
diff --git a/cw_wownero/lib/api/structs/account_row.dart b/cw_wownero/lib/api/structs/account_row.dart
new file mode 100644
index 000000000..aa492ee0f
--- /dev/null
+++ b/cw_wownero/lib/api/structs/account_row.dart
@@ -0,0 +1,12 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+class AccountRow extends Struct {
+  @Int64()
+  external int id;
+  
+  external Pointer<Utf8> label;
+
+  String getLabel() => label.toDartString();
+  int getId() => id;
+}
diff --git a/cw_wownero/lib/api/structs/coins_info_row.dart b/cw_wownero/lib/api/structs/coins_info_row.dart
new file mode 100644
index 000000000..ff6f6ce73
--- /dev/null
+++ b/cw_wownero/lib/api/structs/coins_info_row.dart
@@ -0,0 +1,73 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+class CoinsInfoRow extends Struct {
+  @Int64()
+  external int blockHeight;
+
+  external Pointer<Utf8> hash;
+
+  @Uint64()
+  external int internalOutputIndex;
+
+  @Uint64()
+  external int globalOutputIndex;
+
+  @Int8()
+  external int spent;
+
+  @Int8()
+  external int frozen;
+
+  @Uint64()
+  external int spentHeight;
+
+  @Uint64()
+  external int amount;
+
+  @Int8()
+  external int rct;
+
+  @Int8()
+  external int keyImageKnown;
+
+  @Uint64()
+  external int pkIndex;
+
+  @Uint32()
+  external int subaddrIndex;
+
+  @Uint32()
+  external int subaddrAccount;
+
+  external Pointer<Utf8> address;
+
+  external Pointer<Utf8> addressLabel;
+
+  external Pointer<Utf8> keyImage;
+
+  @Uint64()
+  external int unlockTime;
+
+  @Int8()
+  external int unlocked;
+
+  external Pointer<Utf8> pubKey;
+
+  @Int8()
+  external int coinbase;
+
+  external Pointer<Utf8> description;
+
+  String getHash() => hash.toDartString();
+
+  String getAddress() => address.toDartString();
+
+  String getAddressLabel() => addressLabel.toDartString();
+
+  String getKeyImage() => keyImage.toDartString();
+
+  String getPubKey() => pubKey.toDartString();
+
+  String getDescription() => description.toDartString();
+}
diff --git a/cw_wownero/lib/api/structs/subaddress_row.dart b/cw_wownero/lib/api/structs/subaddress_row.dart
new file mode 100644
index 000000000..d593a793d
--- /dev/null
+++ b/cw_wownero/lib/api/structs/subaddress_row.dart
@@ -0,0 +1,15 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+class SubaddressRow extends Struct {
+  @Int64()
+  external int id;
+  
+  external Pointer<Utf8> address;
+  
+  external Pointer<Utf8> label;
+
+  String getLabel() => label.toDartString();
+  String getAddress() => address.toDartString();
+  int getId() => id;
+}
\ No newline at end of file
diff --git a/cw_wownero/lib/api/structs/transaction_info_row.dart b/cw_wownero/lib/api/structs/transaction_info_row.dart
new file mode 100644
index 000000000..bdcc64d3f
--- /dev/null
+++ b/cw_wownero/lib/api/structs/transaction_info_row.dart
@@ -0,0 +1,41 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+class TransactionInfoRow extends Struct {
+  @Uint64()
+  external int amount;
+
+  @Uint64()
+  external int fee;
+
+  @Uint64()
+  external int blockHeight;
+
+  @Uint64()
+  external int confirmations;
+
+  @Uint32()
+  external int subaddrAccount;
+
+  @Int8()
+  external int direction;
+
+  @Int8()
+  external int isPending;
+
+  @Uint32()
+  external int subaddrIndex;
+
+  external Pointer<Utf8> hash;
+
+  external Pointer<Utf8> paymentId;
+
+  @Int64()
+  external int datetime;
+
+  int getDatetime() => datetime;
+  int getAmount() => amount >= 0 ? amount : amount * -1;
+  bool getIsPending() => isPending != 0;
+  String getHash() => hash.toDartString();
+  String getPaymentId() => paymentId.toDartString();
+}
diff --git a/cw_wownero/lib/api/structs/ut8_box.dart b/cw_wownero/lib/api/structs/ut8_box.dart
new file mode 100644
index 000000000..53e678c88
--- /dev/null
+++ b/cw_wownero/lib/api/structs/ut8_box.dart
@@ -0,0 +1,8 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+class Utf8Box extends Struct {
+  external Pointer<Utf8> value;
+
+  String getValue() => value.toDartString();
+}
diff --git a/cw_wownero/lib/cw_wownero.dart b/cw_wownero/lib/cw_wownero.dart
new file mode 100644
index 000000000..33a55e305
--- /dev/null
+++ b/cw_wownero/lib/cw_wownero.dart
@@ -0,0 +1,8 @@
+
+import 'cw_wownero_platform_interface.dart';
+
+class CwWownero {
+  Future<String?> getPlatformVersion() {
+    return CwWowneroPlatform.instance.getPlatformVersion();
+  }
+}
diff --git a/cw_wownero/lib/cw_wownero_method_channel.dart b/cw_wownero/lib/cw_wownero_method_channel.dart
new file mode 100644
index 000000000..d797f5f81
--- /dev/null
+++ b/cw_wownero/lib/cw_wownero_method_channel.dart
@@ -0,0 +1,17 @@
+import 'package:flutter/foundation.dart';
+import 'package:flutter/services.dart';
+
+import 'cw_wownero_platform_interface.dart';
+
+/// An implementation of [CwWowneroPlatform] that uses method channels.
+class MethodChannelCwWownero extends CwWowneroPlatform {
+  /// The method channel used to interact with the native platform.
+  @visibleForTesting
+  final methodChannel = const MethodChannel('cw_wownero');
+
+  @override
+  Future<String?> getPlatformVersion() async {
+    final version = await methodChannel.invokeMethod<String>('getPlatformVersion');
+    return version;
+  }
+}
diff --git a/cw_wownero/lib/cw_wownero_platform_interface.dart b/cw_wownero/lib/cw_wownero_platform_interface.dart
new file mode 100644
index 000000000..78b21592c
--- /dev/null
+++ b/cw_wownero/lib/cw_wownero_platform_interface.dart
@@ -0,0 +1,29 @@
+import 'package:plugin_platform_interface/plugin_platform_interface.dart';
+
+import 'cw_wownero_method_channel.dart';
+
+abstract class CwWowneroPlatform extends PlatformInterface {
+  /// Constructs a CwWowneroPlatform.
+  CwWowneroPlatform() : super(token: _token);
+
+  static final Object _token = Object();
+
+  static CwWowneroPlatform _instance = MethodChannelCwWownero();
+
+  /// The default instance of [CwWowneroPlatform] to use.
+  ///
+  /// Defaults to [MethodChannelCwWownero].
+  static CwWowneroPlatform get instance => _instance;
+
+  /// Platform-specific implementations should set this with their own
+  /// platform-specific class that extends [CwWowneroPlatform] when
+  /// they register themselves.
+  static set instance(CwWowneroPlatform instance) {
+    PlatformInterface.verifyToken(instance, _token);
+    _instance = instance;
+  }
+
+  Future<String?> getPlatformVersion() {
+    throw UnimplementedError('platformVersion() has not been implemented.');
+  }
+}
diff --git a/cw_wownero/lib/mywownero.dart b/cw_wownero/lib/mywownero.dart
new file mode 100644
index 000000000..d50e48b64
--- /dev/null
+++ b/cw_wownero/lib/mywownero.dart
@@ -0,0 +1,1689 @@
+const prefixLength = 3;
+
+String swapEndianBytes(String original) {
+  if (original.length != 8) {
+    return '';
+  }
+
+  return original[6] +
+      original[7] +
+      original[4] +
+      original[5] +
+      original[2] +
+      original[3] +
+      original[0] +
+      original[1];
+}
+
+List<String> tructWords(List<String> wordSet) {
+  final start = 0;
+  final end = prefixLength;
+
+  return wordSet.map((word) => word.substring(start, end)).toList();
+}
+
+String mnemonicDecode(String seed) {
+  final n = englistWordSet.length;
+  var out = '';
+  var wlist = seed.split(' ');
+  wlist.removeLast();
+
+  for (var i = 0; i < wlist.length; i += 3) {
+    final w1 =
+        tructWords(englistWordSet).indexOf(wlist[i].substring(0, prefixLength));
+    final w2 = tructWords(englistWordSet)
+        .indexOf(wlist[i + 1].substring(0, prefixLength));
+    final w3 = tructWords(englistWordSet)
+        .indexOf(wlist[i + 2].substring(0, prefixLength));
+
+    if (w1 == -1 || w2 == -1 || w3 == -1) {
+      print("invalid word in mnemonic");
+      return '';
+    }
+
+    final x = w1 + n * (((n - w1) + w2) % n) + n * n * (((n - w2) + w3) % n);
+
+    if (x % n != w1) {
+      print("Something went wrong when decoding your private key, please try again");
+      return '';
+    }
+
+    final _res = '0000000' + x.toRadixString(16);
+    final start = _res.length - 8;
+    final end = _res.length;
+    final res = _res.substring(start, end);
+
+    out += swapEndianBytes(res);
+  }
+
+  return out;
+}
+
+final englistWordSet = [
+  "abbey",
+  "abducts",
+  "ability",
+  "ablaze",
+  "abnormal",
+  "abort",
+  "abrasive",
+  "absorb",
+  "abyss",
+  "academy",
+  "aces",
+  "aching",
+  "acidic",
+  "acoustic",
+  "acquire",
+  "across",
+  "actress",
+  "acumen",
+  "adapt",
+  "addicted",
+  "adept",
+  "adhesive",
+  "adjust",
+  "adopt",
+  "adrenalin",
+  "adult",
+  "adventure",
+  "aerial",
+  "afar",
+  "affair",
+  "afield",
+  "afloat",
+  "afoot",
+  "afraid",
+  "after",
+  "against",
+  "agenda",
+  "aggravate",
+  "agile",
+  "aglow",
+  "agnostic",
+  "agony",
+  "agreed",
+  "ahead",
+  "aided",
+  "ailments",
+  "aimless",
+  "airport",
+  "aisle",
+  "ajar",
+  "akin",
+  "alarms",
+  "album",
+  "alchemy",
+  "alerts",
+  "algebra",
+  "alkaline",
+  "alley",
+  "almost",
+  "aloof",
+  "alpine",
+  "already",
+  "also",
+  "altitude",
+  "alumni",
+  "always",
+  "amaze",
+  "ambush",
+  "amended",
+  "amidst",
+  "ammo",
+  "amnesty",
+  "among",
+  "amply",
+  "amused",
+  "anchor",
+  "android",
+  "anecdote",
+  "angled",
+  "ankle",
+  "annoyed",
+  "answers",
+  "antics",
+  "anvil",
+  "anxiety",
+  "anybody",
+  "apart",
+  "apex",
+  "aphid",
+  "aplomb",
+  "apology",
+  "apply",
+  "apricot",
+  "aptitude",
+  "aquarium",
+  "arbitrary",
+  "archer",
+  "ardent",
+  "arena",
+  "argue",
+  "arises",
+  "army",
+  "around",
+  "arrow",
+  "arsenic",
+  "artistic",
+  "ascend",
+  "ashtray",
+  "aside",
+  "asked",
+  "asleep",
+  "aspire",
+  "assorted",
+  "asylum",
+  "athlete",
+  "atlas",
+  "atom",
+  "atrium",
+  "attire",
+  "auburn",
+  "auctions",
+  "audio",
+  "august",
+  "aunt",
+  "austere",
+  "autumn",
+  "avatar",
+  "avidly",
+  "avoid",
+  "awakened",
+  "awesome",
+  "awful",
+  "awkward",
+  "awning",
+  "awoken",
+  "axes",
+  "axis",
+  "axle",
+  "aztec",
+  "azure",
+  "baby",
+  "bacon",
+  "badge",
+  "baffles",
+  "bagpipe",
+  "bailed",
+  "bakery",
+  "balding",
+  "bamboo",
+  "banjo",
+  "baptism",
+  "basin",
+  "batch",
+  "bawled",
+  "bays",
+  "because",
+  "beer",
+  "befit",
+  "begun",
+  "behind",
+  "being",
+  "below",
+  "bemused",
+  "benches",
+  "berries",
+  "bested",
+  "betting",
+  "bevel",
+  "beware",
+  "beyond",
+  "bias",
+  "bicycle",
+  "bids",
+  "bifocals",
+  "biggest",
+  "bikini",
+  "bimonthly",
+  "binocular",
+  "biology",
+  "biplane",
+  "birth",
+  "biscuit",
+  "bite",
+  "biweekly",
+  "blender",
+  "blip",
+  "bluntly",
+  "boat",
+  "bobsled",
+  "bodies",
+  "bogeys",
+  "boil",
+  "boldly",
+  "bomb",
+  "border",
+  "boss",
+  "both",
+  "bounced",
+  "bovine",
+  "bowling",
+  "boxes",
+  "boyfriend",
+  "broken",
+  "brunt",
+  "bubble",
+  "buckets",
+  "budget",
+  "buffet",
+  "bugs",
+  "building",
+  "bulb",
+  "bumper",
+  "bunch",
+  "business",
+  "butter",
+  "buying",
+  "buzzer",
+  "bygones",
+  "byline",
+  "bypass",
+  "cabin",
+  "cactus",
+  "cadets",
+  "cafe",
+  "cage",
+  "cajun",
+  "cake",
+  "calamity",
+  "camp",
+  "candy",
+  "casket",
+  "catch",
+  "cause",
+  "cavernous",
+  "cease",
+  "cedar",
+  "ceiling",
+  "cell",
+  "cement",
+  "cent",
+  "certain",
+  "chlorine",
+  "chrome",
+  "cider",
+  "cigar",
+  "cinema",
+  "circle",
+  "cistern",
+  "citadel",
+  "civilian",
+  "claim",
+  "click",
+  "clue",
+  "coal",
+  "cobra",
+  "cocoa",
+  "code",
+  "coexist",
+  "coffee",
+  "cogs",
+  "cohesive",
+  "coils",
+  "colony",
+  "comb",
+  "cool",
+  "copy",
+  "corrode",
+  "costume",
+  "cottage",
+  "cousin",
+  "cowl",
+  "criminal",
+  "cube",
+  "cucumber",
+  "cuddled",
+  "cuffs",
+  "cuisine",
+  "cunning",
+  "cupcake",
+  "custom",
+  "cycling",
+  "cylinder",
+  "cynical",
+  "dabbing",
+  "dads",
+  "daft",
+  "dagger",
+  "daily",
+  "damp",
+  "dangerous",
+  "dapper",
+  "darted",
+  "dash",
+  "dating",
+  "dauntless",
+  "dawn",
+  "daytime",
+  "dazed",
+  "debut",
+  "decay",
+  "dedicated",
+  "deepest",
+  "deftly",
+  "degrees",
+  "dehydrate",
+  "deity",
+  "dejected",
+  "delayed",
+  "demonstrate",
+  "dented",
+  "deodorant",
+  "depth",
+  "desk",
+  "devoid",
+  "dewdrop",
+  "dexterity",
+  "dialect",
+  "dice",
+  "diet",
+  "different",
+  "digit",
+  "dilute",
+  "dime",
+  "dinner",
+  "diode",
+  "diplomat",
+  "directed",
+  "distance",
+  "ditch",
+  "divers",
+  "dizzy",
+  "doctor",
+  "dodge",
+  "does",
+  "dogs",
+  "doing",
+  "dolphin",
+  "domestic",
+  "donuts",
+  "doorway",
+  "dormant",
+  "dosage",
+  "dotted",
+  "double",
+  "dove",
+  "down",
+  "dozen",
+  "dreams",
+  "drinks",
+  "drowning",
+  "drunk",
+  "drying",
+  "dual",
+  "dubbed",
+  "duckling",
+  "dude",
+  "duets",
+  "duke",
+  "dullness",
+  "dummy",
+  "dunes",
+  "duplex",
+  "duration",
+  "dusted",
+  "duties",
+  "dwarf",
+  "dwelt",
+  "dwindling",
+  "dying",
+  "dynamite",
+  "dyslexic",
+  "each",
+  "eagle",
+  "earth",
+  "easy",
+  "eating",
+  "eavesdrop",
+  "eccentric",
+  "echo",
+  "eclipse",
+  "economics",
+  "ecstatic",
+  "eden",
+  "edgy",
+  "edited",
+  "educated",
+  "eels",
+  "efficient",
+  "eggs",
+  "egotistic",
+  "eight",
+  "either",
+  "eject",
+  "elapse",
+  "elbow",
+  "eldest",
+  "eleven",
+  "elite",
+  "elope",
+  "else",
+  "eluded",
+  "emails",
+  "ember",
+  "emerge",
+  "emit",
+  "emotion",
+  "empty",
+  "emulate",
+  "energy",
+  "enforce",
+  "enhanced",
+  "enigma",
+  "enjoy",
+  "enlist",
+  "enmity",
+  "enough",
+  "enraged",
+  "ensign",
+  "entrance",
+  "envy",
+  "epoxy",
+  "equip",
+  "erase",
+  "erected",
+  "erosion",
+  "error",
+  "eskimos",
+  "espionage",
+  "essential",
+  "estate",
+  "etched",
+  "eternal",
+  "ethics",
+  "etiquette",
+  "evaluate",
+  "evenings",
+  "evicted",
+  "evolved",
+  "examine",
+  "excess",
+  "exhale",
+  "exit",
+  "exotic",
+  "exquisite",
+  "extra",
+  "exult",
+  "fabrics",
+  "factual",
+  "fading",
+  "fainted",
+  "faked",
+  "fall",
+  "family",
+  "fancy",
+  "farming",
+  "fatal",
+  "faulty",
+  "fawns",
+  "faxed",
+  "fazed",
+  "feast",
+  "february",
+  "federal",
+  "feel",
+  "feline",
+  "females",
+  "fences",
+  "ferry",
+  "festival",
+  "fetches",
+  "fever",
+  "fewest",
+  "fiat",
+  "fibula",
+  "fictional",
+  "fidget",
+  "fierce",
+  "fifteen",
+  "fight",
+  "films",
+  "firm",
+  "fishing",
+  "fitting",
+  "five",
+  "fixate",
+  "fizzle",
+  "fleet",
+  "flippant",
+  "flying",
+  "foamy",
+  "focus",
+  "foes",
+  "foggy",
+  "foiled",
+  "folding",
+  "fonts",
+  "foolish",
+  "fossil",
+  "fountain",
+  "fowls",
+  "foxes",
+  "foyer",
+  "framed",
+  "friendly",
+  "frown",
+  "fruit",
+  "frying",
+  "fudge",
+  "fuel",
+  "fugitive",
+  "fully",
+  "fuming",
+  "fungal",
+  "furnished",
+  "fuselage",
+  "future",
+  "fuzzy",
+  "gables",
+  "gadget",
+  "gags",
+  "gained",
+  "galaxy",
+  "gambit",
+  "gang",
+  "gasp",
+  "gather",
+  "gauze",
+  "gave",
+  "gawk",
+  "gaze",
+  "gearbox",
+  "gecko",
+  "geek",
+  "gels",
+  "gemstone",
+  "general",
+  "geometry",
+  "germs",
+  "gesture",
+  "getting",
+  "geyser",
+  "ghetto",
+  "ghost",
+  "giant",
+  "giddy",
+  "gifts",
+  "gigantic",
+  "gills",
+  "gimmick",
+  "ginger",
+  "girth",
+  "giving",
+  "glass",
+  "gleeful",
+  "glide",
+  "gnaw",
+  "gnome",
+  "goat",
+  "goblet",
+  "godfather",
+  "goes",
+  "goggles",
+  "going",
+  "goldfish",
+  "gone",
+  "goodbye",
+  "gopher",
+  "gorilla",
+  "gossip",
+  "gotten",
+  "gourmet",
+  "governing",
+  "gown",
+  "greater",
+  "grunt",
+  "guarded",
+  "guest",
+  "guide",
+  "gulp",
+  "gumball",
+  "guru",
+  "gusts",
+  "gutter",
+  "guys",
+  "gymnast",
+  "gypsy",
+  "gyrate",
+  "habitat",
+  "hacksaw",
+  "haggled",
+  "hairy",
+  "hamburger",
+  "happens",
+  "hashing",
+  "hatchet",
+  "haunted",
+  "having",
+  "hawk",
+  "haystack",
+  "hazard",
+  "hectare",
+  "hedgehog",
+  "heels",
+  "hefty",
+  "height",
+  "hemlock",
+  "hence",
+  "heron",
+  "hesitate",
+  "hexagon",
+  "hickory",
+  "hiding",
+  "highway",
+  "hijack",
+  "hiker",
+  "hills",
+  "himself",
+  "hinder",
+  "hippo",
+  "hire",
+  "history",
+  "hitched",
+  "hive",
+  "hoax",
+  "hobby",
+  "hockey",
+  "hoisting",
+  "hold",
+  "honked",
+  "hookup",
+  "hope",
+  "hornet",
+  "hospital",
+  "hotel",
+  "hounded",
+  "hover",
+  "howls",
+  "hubcaps",
+  "huddle",
+  "huge",
+  "hull",
+  "humid",
+  "hunter",
+  "hurried",
+  "husband",
+  "huts",
+  "hybrid",
+  "hydrogen",
+  "hyper",
+  "iceberg",
+  "icing",
+  "icon",
+  "identity",
+  "idiom",
+  "idled",
+  "idols",
+  "igloo",
+  "ignore",
+  "iguana",
+  "illness",
+  "imagine",
+  "imbalance",
+  "imitate",
+  "impel",
+  "inactive",
+  "inbound",
+  "incur",
+  "industrial",
+  "inexact",
+  "inflamed",
+  "ingested",
+  "initiate",
+  "injury",
+  "inkling",
+  "inline",
+  "inmate",
+  "innocent",
+  "inorganic",
+  "input",
+  "inquest",
+  "inroads",
+  "insult",
+  "intended",
+  "inundate",
+  "invoke",
+  "inwardly",
+  "ionic",
+  "irate",
+  "iris",
+  "irony",
+  "irritate",
+  "island",
+  "isolated",
+  "issued",
+  "italics",
+  "itches",
+  "items",
+  "itinerary",
+  "itself",
+  "ivory",
+  "jabbed",
+  "jackets",
+  "jaded",
+  "jagged",
+  "jailed",
+  "jamming",
+  "january",
+  "jargon",
+  "jaunt",
+  "javelin",
+  "jaws",
+  "jazz",
+  "jeans",
+  "jeers",
+  "jellyfish",
+  "jeopardy",
+  "jerseys",
+  "jester",
+  "jetting",
+  "jewels",
+  "jigsaw",
+  "jingle",
+  "jittery",
+  "jive",
+  "jobs",
+  "jockey",
+  "jogger",
+  "joining",
+  "joking",
+  "jolted",
+  "jostle",
+  "journal",
+  "joyous",
+  "jubilee",
+  "judge",
+  "juggled",
+  "juicy",
+  "jukebox",
+  "july",
+  "jump",
+  "junk",
+  "jury",
+  "justice",
+  "juvenile",
+  "kangaroo",
+  "karate",
+  "keep",
+  "kennel",
+  "kept",
+  "kernels",
+  "kettle",
+  "keyboard",
+  "kickoff",
+  "kidneys",
+  "king",
+  "kiosk",
+  "kisses",
+  "kitchens",
+  "kiwi",
+  "knapsack",
+  "knee",
+  "knife",
+  "knowledge",
+  "knuckle",
+  "koala",
+  "laboratory",
+  "ladder",
+  "lagoon",
+  "lair",
+  "lakes",
+  "lamb",
+  "language",
+  "laptop",
+  "large",
+  "last",
+  "later",
+  "launching",
+  "lava",
+  "lawsuit",
+  "layout",
+  "lazy",
+  "lectures",
+  "ledge",
+  "leech",
+  "left",
+  "legion",
+  "leisure",
+  "lemon",
+  "lending",
+  "leopard",
+  "lesson",
+  "lettuce",
+  "lexicon",
+  "liar",
+  "library",
+  "licks",
+  "lids",
+  "lied",
+  "lifestyle",
+  "light",
+  "likewise",
+  "lilac",
+  "limits",
+  "linen",
+  "lion",
+  "lipstick",
+  "liquid",
+  "listen",
+  "lively",
+  "loaded",
+  "lobster",
+  "locker",
+  "lodge",
+  "lofty",
+  "logic",
+  "loincloth",
+  "long",
+  "looking",
+  "lopped",
+  "lordship",
+  "losing",
+  "lottery",
+  "loudly",
+  "love",
+  "lower",
+  "loyal",
+  "lucky",
+  "luggage",
+  "lukewarm",
+  "lullaby",
+  "lumber",
+  "lunar",
+  "lurk",
+  "lush",
+  "luxury",
+  "lymph",
+  "lynx",
+  "lyrics",
+  "macro",
+  "madness",
+  "magically",
+  "mailed",
+  "major",
+  "makeup",
+  "malady",
+  "mammal",
+  "maps",
+  "masterful",
+  "match",
+  "maul",
+  "maverick",
+  "maximum",
+  "mayor",
+  "maze",
+  "meant",
+  "mechanic",
+  "medicate",
+  "meeting",
+  "megabyte",
+  "melting",
+  "memoir",
+  "menu",
+  "merger",
+  "mesh",
+  "metro",
+  "mews",
+  "mice",
+  "midst",
+  "mighty",
+  "mime",
+  "mirror",
+  "misery",
+  "mittens",
+  "mixture",
+  "moat",
+  "mobile",
+  "mocked",
+  "mohawk",
+  "moisture",
+  "molten",
+  "moment",
+  "money",
+  "moon",
+  "mops",
+  "morsel",
+  "mostly",
+  "motherly",
+  "mouth",
+  "movement",
+  "mowing",
+  "much",
+  "muddy",
+  "muffin",
+  "mugged",
+  "mullet",
+  "mumble",
+  "mundane",
+  "muppet",
+  "mural",
+  "musical",
+  "muzzle",
+  "myriad",
+  "mystery",
+  "myth",
+  "nabbing",
+  "nagged",
+  "nail",
+  "names",
+  "nanny",
+  "napkin",
+  "narrate",
+  "nasty",
+  "natural",
+  "nautical",
+  "navy",
+  "nearby",
+  "necklace",
+  "needed",
+  "negative",
+  "neither",
+  "neon",
+  "nephew",
+  "nerves",
+  "nestle",
+  "network",
+  "neutral",
+  "never",
+  "newt",
+  "nexus",
+  "nibs",
+  "niche",
+  "niece",
+  "nifty",
+  "nightly",
+  "nimbly",
+  "nineteen",
+  "nirvana",
+  "nitrogen",
+  "nobody",
+  "nocturnal",
+  "nodes",
+  "noises",
+  "nomad",
+  "noodles",
+  "northern",
+  "nostril",
+  "noted",
+  "nouns",
+  "novelty",
+  "nowhere",
+  "nozzle",
+  "nuance",
+  "nucleus",
+  "nudged",
+  "nugget",
+  "nuisance",
+  "null",
+  "number",
+  "nuns",
+  "nurse",
+  "nutshell",
+  "nylon",
+  "oaks",
+  "oars",
+  "oasis",
+  "oatmeal",
+  "obedient",
+  "object",
+  "obliged",
+  "obnoxious",
+  "observant",
+  "obtains",
+  "obvious",
+  "occur",
+  "ocean",
+  "october",
+  "odds",
+  "odometer",
+  "offend",
+  "often",
+  "oilfield",
+  "ointment",
+  "okay",
+  "older",
+  "olive",
+  "olympics",
+  "omega",
+  "omission",
+  "omnibus",
+  "onboard",
+  "oncoming",
+  "oneself",
+  "ongoing",
+  "onion",
+  "online",
+  "onslaught",
+  "onto",
+  "onward",
+  "oozed",
+  "opacity",
+  "opened",
+  "opposite",
+  "optical",
+  "opus",
+  "orange",
+  "orbit",
+  "orchid",
+  "orders",
+  "organs",
+  "origin",
+  "ornament",
+  "orphans",
+  "oscar",
+  "ostrich",
+  "otherwise",
+  "otter",
+  "ouch",
+  "ought",
+  "ounce",
+  "ourselves",
+  "oust",
+  "outbreak",
+  "oval",
+  "oven",
+  "owed",
+  "owls",
+  "owner",
+  "oxidant",
+  "oxygen",
+  "oyster",
+  "ozone",
+  "pact",
+  "paddles",
+  "pager",
+  "pairing",
+  "palace",
+  "pamphlet",
+  "pancakes",
+  "paper",
+  "paradise",
+  "pastry",
+  "patio",
+  "pause",
+  "pavements",
+  "pawnshop",
+  "payment",
+  "peaches",
+  "pebbles",
+  "peculiar",
+  "pedantic",
+  "peeled",
+  "pegs",
+  "pelican",
+  "pencil",
+  "people",
+  "pepper",
+  "perfect",
+  "pests",
+  "petals",
+  "phase",
+  "pheasants",
+  "phone",
+  "phrases",
+  "physics",
+  "piano",
+  "picked",
+  "pierce",
+  "pigment",
+  "piloted",
+  "pimple",
+  "pinched",
+  "pioneer",
+  "pipeline",
+  "pirate",
+  "pistons",
+  "pitched",
+  "pivot",
+  "pixels",
+  "pizza",
+  "playful",
+  "pledge",
+  "pliers",
+  "plotting",
+  "plus",
+  "plywood",
+  "poaching",
+  "pockets",
+  "podcast",
+  "poetry",
+  "point",
+  "poker",
+  "polar",
+  "ponies",
+  "pool",
+  "popular",
+  "portents",
+  "possible",
+  "potato",
+  "pouch",
+  "poverty",
+  "powder",
+  "pram",
+  "present",
+  "pride",
+  "problems",
+  "pruned",
+  "prying",
+  "psychic",
+  "public",
+  "puck",
+  "puddle",
+  "puffin",
+  "pulp",
+  "pumpkins",
+  "punch",
+  "puppy",
+  "purged",
+  "push",
+  "putty",
+  "puzzled",
+  "pylons",
+  "pyramid",
+  "python",
+  "queen",
+  "quick",
+  "quote",
+  "rabbits",
+  "racetrack",
+  "radar",
+  "rafts",
+  "rage",
+  "railway",
+  "raking",
+  "rally",
+  "ramped",
+  "randomly",
+  "rapid",
+  "rarest",
+  "rash",
+  "rated",
+  "ravine",
+  "rays",
+  "razor",
+  "react",
+  "rebel",
+  "recipe",
+  "reduce",
+  "reef",
+  "refer",
+  "regular",
+  "reheat",
+  "reinvest",
+  "rejoices",
+  "rekindle",
+  "relic",
+  "remedy",
+  "renting",
+  "reorder",
+  "repent",
+  "request",
+  "reruns",
+  "rest",
+  "return",
+  "reunion",
+  "revamp",
+  "rewind",
+  "rhino",
+  "rhythm",
+  "ribbon",
+  "richly",
+  "ridges",
+  "rift",
+  "rigid",
+  "rims",
+  "ringing",
+  "riots",
+  "ripped",
+  "rising",
+  "ritual",
+  "river",
+  "roared",
+  "robot",
+  "rockets",
+  "rodent",
+  "rogue",
+  "roles",
+  "romance",
+  "roomy",
+  "roped",
+  "roster",
+  "rotate",
+  "rounded",
+  "rover",
+  "rowboat",
+  "royal",
+  "ruby",
+  "rudely",
+  "ruffled",
+  "rugged",
+  "ruined",
+  "ruling",
+  "rumble",
+  "runway",
+  "rural",
+  "rustled",
+  "ruthless",
+  "sabotage",
+  "sack",
+  "sadness",
+  "safety",
+  "saga",
+  "sailor",
+  "sake",
+  "salads",
+  "sample",
+  "sanity",
+  "sapling",
+  "sarcasm",
+  "sash",
+  "satin",
+  "saucepan",
+  "saved",
+  "sawmill",
+  "saxophone",
+  "sayings",
+  "scamper",
+  "scenic",
+  "school",
+  "science",
+  "scoop",
+  "scrub",
+  "scuba",
+  "seasons",
+  "second",
+  "sedan",
+  "seeded",
+  "segments",
+  "seismic",
+  "selfish",
+  "semifinal",
+  "sensible",
+  "september",
+  "sequence",
+  "serving",
+  "session",
+  "setup",
+  "seventh",
+  "sewage",
+  "shackles",
+  "shelter",
+  "shipped",
+  "shocking",
+  "shrugged",
+  "shuffled",
+  "shyness",
+  "siblings",
+  "sickness",
+  "sidekick",
+  "sieve",
+  "sifting",
+  "sighting",
+  "silk",
+  "simplest",
+  "sincerely",
+  "sipped",
+  "siren",
+  "situated",
+  "sixteen",
+  "sizes",
+  "skater",
+  "skew",
+  "skirting",
+  "skulls",
+  "skydive",
+  "slackens",
+  "sleepless",
+  "slid",
+  "slower",
+  "slug",
+  "smash",
+  "smelting",
+  "smidgen",
+  "smog",
+  "smuggled",
+  "snake",
+  "sneeze",
+  "sniff",
+  "snout",
+  "snug",
+  "soapy",
+  "sober",
+  "soccer",
+  "soda",
+  "software",
+  "soggy",
+  "soil",
+  "solved",
+  "somewhere",
+  "sonic",
+  "soothe",
+  "soprano",
+  "sorry",
+  "southern",
+  "sovereign",
+  "sowed",
+  "soya",
+  "space",
+  "speedy",
+  "sphere",
+  "spiders",
+  "splendid",
+  "spout",
+  "sprig",
+  "spud",
+  "spying",
+  "square",
+  "stacking",
+  "stellar",
+  "stick",
+  "stockpile",
+  "strained",
+  "stunning",
+  "stylishly",
+  "subtly",
+  "succeed",
+  "suddenly",
+  "suede",
+  "suffice",
+  "sugar",
+  "suitcase",
+  "sulking",
+  "summon",
+  "sunken",
+  "superior",
+  "surfer",
+  "sushi",
+  "suture",
+  "swagger",
+  "swept",
+  "swiftly",
+  "sword",
+  "swung",
+  "syllabus",
+  "symptoms",
+  "syndrome",
+  "syringe",
+  "system",
+  "taboo",
+  "tacit",
+  "tadpoles",
+  "tagged",
+  "tail",
+  "taken",
+  "talent",
+  "tamper",
+  "tanks",
+  "tapestry",
+  "tarnished",
+  "tasked",
+  "tattoo",
+  "taunts",
+  "tavern",
+  "tawny",
+  "taxi",
+  "teardrop",
+  "technical",
+  "tedious",
+  "teeming",
+  "tell",
+  "template",
+  "tender",
+  "tepid",
+  "tequila",
+  "terminal",
+  "testing",
+  "tether",
+  "textbook",
+  "thaw",
+  "theatrics",
+  "thirsty",
+  "thorn",
+  "threaten",
+  "thumbs",
+  "thwart",
+  "ticket",
+  "tidy",
+  "tiers",
+  "tiger",
+  "tilt",
+  "timber",
+  "tinted",
+  "tipsy",
+  "tirade",
+  "tissue",
+  "titans",
+  "toaster",
+  "tobacco",
+  "today",
+  "toenail",
+  "toffee",
+  "together",
+  "toilet",
+  "token",
+  "tolerant",
+  "tomorrow",
+  "tonic",
+  "toolbox",
+  "topic",
+  "torch",
+  "tossed",
+  "total",
+  "touchy",
+  "towel",
+  "toxic",
+  "toyed",
+  "trash",
+  "trendy",
+  "tribal",
+  "trolling",
+  "truth",
+  "trying",
+  "tsunami",
+  "tubes",
+  "tucks",
+  "tudor",
+  "tuesday",
+  "tufts",
+  "tugs",
+  "tuition",
+  "tulips",
+  "tumbling",
+  "tunnel",
+  "turnip",
+  "tusks",
+  "tutor",
+  "tuxedo",
+  "twang",
+  "tweezers",
+  "twice",
+  "twofold",
+  "tycoon",
+  "typist",
+  "tyrant",
+  "ugly",
+  "ulcers",
+  "ultimate",
+  "umbrella",
+  "umpire",
+  "unafraid",
+  "unbending",
+  "uncle",
+  "under",
+  "uneven",
+  "unfit",
+  "ungainly",
+  "unhappy",
+  "union",
+  "unjustly",
+  "unknown",
+  "unlikely",
+  "unmask",
+  "unnoticed",
+  "unopened",
+  "unplugs",
+  "unquoted",
+  "unrest",
+  "unsafe",
+  "until",
+  "unusual",
+  "unveil",
+  "unwind",
+  "unzip",
+  "upbeat",
+  "upcoming",
+  "update",
+  "upgrade",
+  "uphill",
+  "upkeep",
+  "upload",
+  "upon",
+  "upper",
+  "upright",
+  "upstairs",
+  "uptight",
+  "upwards",
+  "urban",
+  "urchins",
+  "urgent",
+  "usage",
+  "useful",
+  "usher",
+  "using",
+  "usual",
+  "utensils",
+  "utility",
+  "utmost",
+  "utopia",
+  "uttered",
+  "vacation",
+  "vague",
+  "vain",
+  "value",
+  "vampire",
+  "vane",
+  "vapidly",
+  "vary",
+  "vastness",
+  "vats",
+  "vaults",
+  "vector",
+  "veered",
+  "vegan",
+  "vehicle",
+  "vein",
+  "velvet",
+  "venomous",
+  "verification",
+  "vessel",
+  "veteran",
+  "vexed",
+  "vials",
+  "vibrate",
+  "victim",
+  "video",
+  "viewpoint",
+  "vigilant",
+  "viking",
+  "village",
+  "vinegar",
+  "violin",
+  "vipers",
+  "virtual",
+  "visited",
+  "vitals",
+  "vivid",
+  "vixen",
+  "vocal",
+  "vogue",
+  "voice",
+  "volcano",
+  "vortex",
+  "voted",
+  "voucher",
+  "vowels",
+  "voyage",
+  "vulture",
+  "wade",
+  "waffle",
+  "wagtail",
+  "waist",
+  "waking",
+  "wallets",
+  "wanted",
+  "warped",
+  "washing",
+  "water",
+  "waveform",
+  "waxing",
+  "wayside",
+  "weavers",
+  "website",
+  "wedge",
+  "weekday",
+  "weird",
+  "welders",
+  "went",
+  "wept",
+  "were",
+  "western",
+  "wetsuit",
+  "whale",
+  "when",
+  "whipped",
+  "whole",
+  "wickets",
+  "width",
+  "wield",
+  "wife",
+  "wiggle",
+  "wildly",
+  "winter",
+  "wipeout",
+  "wiring",
+  "wise",
+  "withdrawn",
+  "wives",
+  "wizard",
+  "wobbly",
+  "woes",
+  "woken",
+  "wolf",
+  "womanly",
+  "wonders",
+  "woozy",
+  "worry",
+  "wounded",
+  "woven",
+  "wrap",
+  "wrist",
+  "wrong",
+  "yacht",
+  "yahoo",
+  "yanks",
+  "yard",
+  "yawning",
+  "yearbook",
+  "yellow",
+  "yesterday",
+  "yeti",
+  "yields",
+  "yodel",
+  "yoga",
+  "younger",
+  "yoyo",
+  "zapped",
+  "zeal",
+  "zebra",
+  "zero",
+  "zesty",
+  "zigzags",
+  "zinger",
+  "zippers",
+  "zodiac",
+  "zombie",
+  "zones",
+  "zoom"
+];
diff --git a/cw_wownero/pubspec.lock b/cw_wownero/pubspec.lock
index c90340800..b0347c023 100644
--- a/cw_wownero/pubspec.lock
+++ b/cw_wownero/pubspec.lock
@@ -41,6 +41,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.11.0"
+  bluez:
+    dependency: transitive
+    description:
+      name: bluez
+      sha256: "203a1924e818a9dd74af2b2c7a8f375ab8e5edf0e486bba8f90a0d8a17ed9fce"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.8.2"
   boolean_selector:
     dependency: transitive
     description:
@@ -209,6 +217,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.2.4"
+  dbus:
+    dependency: transitive
+    description:
+      name: dbus
+      sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.7.10"
   encrypt:
     dependency: "direct main"
     description:
@@ -267,6 +283,14 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  flutter_web_bluetooth:
+    dependency: transitive
+    description:
+      name: flutter_web_bluetooth
+      sha256: "52ce64f65d7321c4bf6abfe9dac02fb888731339a5e0ad6de59fb916c20c9f02"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.2.3"
   frontend_server_client:
     dependency: transitive
     description:
@@ -403,6 +427,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.0.1"
+  ledger_flutter_plus:
+    dependency: transitive
+    description:
+      name: ledger_flutter_plus
+      sha256: ea3ed586e1697776dacf42ac979095f1ca3bd143bf007cbe5c78e09cb6943f42
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.2.5"
+  ledger_usb_plus:
+    dependency: transitive
+    description:
+      name: ledger_usb_plus
+      sha256: "21cc5d976cf7edb3518bd2a0c4164139cbb0817d2e4f2054707fc4edfdf9ce87"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.4"
   logging:
     dependency: transitive
     description:
@@ -463,8 +503,8 @@ packages:
     dependency: "direct main"
     description:
       path: "impls/monero.dart"
-      ref: "6eb571ea498ed7b854934785f00fabfd0dadf75b"
-      resolved-ref: "6eb571ea498ed7b854934785f00fabfd0dadf75b"
+      ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b
+      resolved-ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b
       url: "https://github.com/mrcyjanek/monero_c"
     source: git
     version: "0.0.0"
@@ -540,6 +580,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.2.1"
+  petitparser:
+    dependency: transitive
+    description:
+      name: petitparser
+      sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
+      url: "https://pub.dev"
+    source: hosted
+    version: "6.0.2"
   platform:
     dependency: transitive
     description:
@@ -552,10 +600,10 @@ packages:
     dependency: transitive
     description:
       name: plugin_platform_interface
-      sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
+      sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.3"
+    version: "2.1.8"
   pointycastle:
     dependency: transitive
     description:
@@ -596,6 +644,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.2.1"
+  rxdart:
+    dependency: transitive
+    description:
+      name: rxdart
+      sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.28.0"
   shelf:
     dependency: transitive
     description:
@@ -721,6 +777,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.3.1"
+  universal_ble:
+    dependency: transitive
+    description:
+      name: universal_ble
+      sha256: "0dfbd6b64bff3ad61ed7a895c232530d9614e9b01ab261a74433a43267edb7f3"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.12.0"
+  universal_platform:
+    dependency: transitive
+    description:
+      name: universal_platform
+      sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.1.0"
   unorm_dart:
     dependency: transitive
     description:
@@ -777,6 +849,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.4"
+  xml:
+    dependency: transitive
+    description:
+      name: xml
+      sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
+      url: "https://pub.dev"
+    source: hosted
+    version: "6.5.0"
   yaml:
     dependency: transitive
     description:
@@ -786,5 +866,5 @@ packages:
     source: hosted
     version: "3.1.1"
 sdks:
-  dart: ">=3.2.0-0 <4.0.0"
-  flutter: ">=3.7.0"
+  dart: ">=3.3.0 <4.0.0"
+  flutter: ">=3.19.0"
diff --git a/cw_wownero/pubspec.yaml b/cw_wownero/pubspec.yaml
index 6943e60c3..582c15447 100644
--- a/cw_wownero/pubspec.yaml
+++ b/cw_wownero/pubspec.yaml
@@ -25,7 +25,8 @@ dependencies:
   monero:
     git:
       url: https://github.com/mrcyjanek/monero_c
-      ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash
+      ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b
+#      ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash
       path: impls/monero.dart
   mutex: ^3.1.0
 
diff --git a/lib/core/wallet_loading_service.dart b/lib/core/wallet_loading_service.dart
index e58e14652..10e438e0c 100644
--- a/lib/core/wallet_loading_service.dart
+++ b/lib/core/wallet_loading_service.dart
@@ -14,7 +14,11 @@ import 'package:flutter/material.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 
 class WalletLoadingService {
-  WalletLoadingService(this.sharedPreferences, this.keyService, this.walletServiceFactory);
+  WalletLoadingService(
+    this.sharedPreferences,
+    this.keyService,
+    this.walletServiceFactory,
+  );
 
   final SharedPreferences sharedPreferences;
   final KeyService keyService;
@@ -77,7 +81,8 @@ class WalletLoadingService {
             await updateMoneroWalletPassword(wallet);
           }
 
-          await sharedPreferences.setString(PreferencesKey.currentWalletName, wallet.name);
+          await sharedPreferences.setString(
+              PreferencesKey.currentWalletName, wallet.name);
           await sharedPreferences.setInt(
               PreferencesKey.currentWalletType, serializeToInt(wallet.type));
 
@@ -129,4 +134,9 @@ class WalletLoadingService {
 
     return "\n\n$type ($name): ${await walletService.getSeeds(name, password, type)}";
   }
+
+  bool requireHardwareWalletConnection(WalletType type, String name) {
+    final walletService = walletServiceFactory.call(type);
+    return walletService.requireHardwareWalletConnection(name);
+  }
 }
diff --git a/lib/di.dart b/lib/di.dart
index 8dd1029a9..facdec912 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -32,12 +32,14 @@ import 'package:cake_wallet/entities/biometric_auth.dart';
 import 'package:cake_wallet/entities/contact.dart';
 import 'package:cake_wallet/entities/contact_record.dart';
 import 'package:cake_wallet/entities/exchange_api_mode.dart';
+import 'package:cake_wallet/entities/hardware_wallet/require_hardware_wallet_connection.dart';
 import 'package:cake_wallet/entities/parse_address_from_domain.dart';
 import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart';
 import 'package:cake_wallet/entities/wallet_manager.dart';
 import 'package:cake_wallet/src/screens/buy/buy_sell_options_page.dart';
 import 'package:cake_wallet/src/screens/buy/payment_method_options_page.dart';
 import 'package:cake_wallet/src/screens/receive/address_list_page.dart';
+import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
 import 'package:cake_wallet/src/screens/settings/mweb_logs_page.dart';
 import 'package:cake_wallet/src/screens/settings/mweb_node_page.dart';
 import 'package:cake_wallet/view_model/link_view_model.dart';
@@ -184,7 +186,6 @@ import 'package:cake_wallet/src/screens/transaction_details/transaction_details_
 import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
 import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
 import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
-import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
 import 'package:cake_wallet/store/app_store.dart';
 import 'package:cake_wallet/store/authentication_store.dart';
 import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
@@ -586,7 +587,7 @@ Future<void> setup({
         );
       } else {
         // wallet is already loaded:
-        if (appStore.wallet != null) {
+        if (appStore.wallet != null || requireHardwareWalletConnection()) {
           // goes to the dashboard:
           authStore.allowed();
           // trigger any deep links:
@@ -780,10 +781,12 @@ Future<void> setup({
     );
   }
 
-  getIt.registerFactory(() => WalletListPage(
-        walletListViewModel: getIt.get<WalletListViewModel>(),
-        authService: getIt.get<AuthService>(),
-      ));
+  getIt.registerFactoryParam<WalletListPage, Function(BuildContext)?, void>(
+      (Function(BuildContext)? onWalletLoaded, _) => WalletListPage(
+            walletListViewModel: getIt.get<WalletListViewModel>(),
+            authService: getIt.get<AuthService>(),
+            onWalletLoaded: onWalletLoaded,
+          ));
 
   getIt.registerFactoryParam<WalletEditViewModel, WalletListViewModel, void>(
     (WalletListViewModel walletListViewModel, _) => WalletEditViewModel(
diff --git a/lib/entities/hardware_wallet/require_hardware_wallet_connection.dart b/lib/entities/hardware_wallet/require_hardware_wallet_connection.dart
new file mode 100644
index 000000000..a64fa5873
--- /dev/null
+++ b/lib/entities/hardware_wallet/require_hardware_wallet_connection.dart
@@ -0,0 +1,25 @@
+import 'package:cake_wallet/core/wallet_loading_service.dart';
+import 'package:cake_wallet/di.dart';
+import 'package:cake_wallet/entities/preferences_key.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:shared_preferences/shared_preferences.dart';
+
+bool requireHardwareWalletConnection() {
+  final name = getIt
+      .get<SharedPreferences>()
+      .getString(PreferencesKey.currentWalletName);
+  final typeRaw =
+      getIt.get<SharedPreferences>().getInt(PreferencesKey.currentWalletType);
+
+  if (typeRaw == null) {
+    return false;
+  }
+
+  if (name == null) {
+    throw Exception('Incorrect current wallet name: $name');
+  }
+
+  final type = deserializeFromInt(typeRaw);
+  final walletLoadingService = getIt.get<WalletLoadingService>();
+  return walletLoadingService.requireHardwareWalletConnection(type, name);
+}
diff --git a/lib/monero/cw_monero.dart b/lib/monero/cw_monero.dart
index dfda4d600..09d9889c5 100644
--- a/lib/monero/cw_monero.dart
+++ b/lib/monero/cw_monero.dart
@@ -225,6 +225,19 @@ class CWMonero extends Monero {
           language: language,
           height: height);
 
+  @override
+  WalletCredentials createMoneroRestoreWalletFromHardwareCredentials({
+    required String name,
+    required String password,
+    required int height,
+    required ledger.LedgerConnection ledgerConnection,
+  }) =>
+      MoneroRestoreWalletFromHardwareCredentials(
+          name: name,
+          password: password,
+          height: height,
+          ledgerConnection: ledgerConnection);
+
   @override
   WalletCredentials createMoneroRestoreWalletFromSeedCredentials(
           {required String name,
@@ -383,6 +396,18 @@ class CWMonero extends Monero {
     checkIfMoneroCIsFine();
   }
 
+  @override
+  void setLedgerConnection(Object wallet, ledger.LedgerConnection connection) {
+    final moneroWallet = wallet as MoneroWallet;
+    moneroWallet.setLedgerConnection(connection);
+  }
+
+  @override
+  void setGlobalLedgerConnection(ledger.LedgerConnection connection) {
+    gLedger = connection;
+    keepAlive(connection);
+  }
+
   bool isViewOnly() {
     return isViewOnlyBySpendKey();
   }
diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart
index 1aa0a12c6..b411c5a15 100644
--- a/lib/reactions/on_authentication_state_change.dart
+++ b/lib/reactions/on_authentication_state_change.dart
@@ -1,18 +1,28 @@
 import 'dart:async';
 
+import 'package:cake_wallet/core/wallet_connect/wc_bottom_sheet_service.dart';
+import 'package:cake_wallet/di.dart';
+import 'package:cake_wallet/entities/hardware_wallet/require_hardware_wallet_connection.dart';
+import 'package:cake_wallet/entities/load_current_wallet.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/monero/monero.dart';
 import 'package:cake_wallet/routes.dart';
-import 'package:cake_wallet/utils/exception_handler.dart';
+import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart';
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
+import 'package:cake_wallet/store/authentication_store.dart';
 import 'package:cake_wallet/store/settings_store.dart';
+import 'package:cake_wallet/utils/exception_handler.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cw_core/wallet_type.dart';
 import 'package:flutter/widgets.dart';
 import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/entities/load_current_wallet.dart';
-import 'package:cake_wallet/store/authentication_store.dart';
 import 'package:rxdart/subjects.dart';
 
 ReactionDisposer? _onAuthenticationStateChange;
 
 dynamic loginError;
-StreamController<dynamic> authenticatedErrorStreamController = BehaviorSubject<dynamic>();
+StreamController<dynamic> authenticatedErrorStreamController =
+    BehaviorSubject<dynamic>();
 
 void startAuthenticationStateChange(
   AuthenticationStore authenticationStore,
@@ -27,18 +37,49 @@ void startAuthenticationStateChange(
   _onAuthenticationStateChange ??= autorun((_) async {
     final state = authenticationStore.state;
 
-    if (state == AuthenticationState.installed && !SettingsStoreBase.walletPasswordDirectInput) {
+    if (state == AuthenticationState.installed &&
+        !SettingsStoreBase.walletPasswordDirectInput) {
       try {
-        await loadCurrentWallet();
+        if (!requireHardwareWalletConnection()) await loadCurrentWallet();
       } catch (error, stack) {
         loginError = error;
-        ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack));
+        ExceptionHandler.onError(
+            FlutterErrorDetails(exception: error, stack: stack));
       }
       return;
     }
 
     if (state == AuthenticationState.allowed) {
-      await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
+      if (requireHardwareWalletConnection()) {
+        await navigatorKey.currentState!.pushNamedAndRemoveUntil(
+          Routes.connectDevices,
+          (route) => false,
+          arguments: ConnectDevicePageParams(
+            walletType: WalletType.monero,
+            onConnectDevice: (context, ledgerVM) async {
+              monero!.setGlobalLedgerConnection(ledgerVM.connection);
+                showPopUp<void>(
+                  context: context,
+                  builder: (BuildContext context) => AlertWithOneAction(
+                      alertTitle: S.of(context).proceed_on_device,
+                      alertContent: S.of(context).proceed_on_device_description,
+                      buttonText: S.of(context).cancel,
+                      buttonAction: () => Navigator.of(context).pop()),
+                );
+              await loadCurrentWallet();
+              getIt.get<BottomSheetService>().resetCurrentSheet();
+              await navigatorKey.currentState!
+                  .pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
+            },
+            allowChangeWallet: true,
+          ),
+        );
+
+        // await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.connectDevices, (route) => false, arguments: ConnectDevicePageParams(walletType: walletType, onConnectDevice: onConnectDevice));
+      } else {
+        await navigatorKey.currentState!
+            .pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
+      }
       if (!(await authenticatedErrorStreamController.stream.isEmpty)) {
         ExceptionHandler.showError(
             (await authenticatedErrorStreamController.stream.first).toString());
diff --git a/lib/router.dart b/lib/router.dart
index 781a6e057..1382da28f 100644
--- a/lib/router.dart
+++ b/lib/router.dart
@@ -24,6 +24,7 @@ import 'package:cake_wallet/src/screens/buy/webview_page.dart';
 import 'package:cake_wallet/src/screens/cake_pay/auth/cake_pay_account_page.dart';
 import 'package:cake_wallet/src/screens/cake_pay/cake_pay.dart';
 import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart';
+import 'package:cake_wallet/src/screens/connect_device/monero_hardware_wallet_options_page.dart';
 import 'package:cake_wallet/src/screens/connect_device/select_hardware_wallet_account_page.dart';
 import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
 import 'package:cake_wallet/src/screens/contact/contact_page.dart';
@@ -212,6 +213,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
       final type = arguments[0] as WalletType;
       final walletVM = getIt.get<WalletHardwareRestoreViewModel>(param1: type);
 
+      if (type == WalletType.monero)
+        return CupertinoPageRoute<void>(builder: (_) => MoneroHardwareWalletOptionsPage(walletVM));
+
       return CupertinoPageRoute<void>(builder: (_) => SelectHardwareWalletAccountPage(walletVM));
 
     case Routes.setupPin:
@@ -403,8 +407,11 @@ Route<dynamic> createRoute(RouteSettings settings) {
       return CupertinoPageRoute<void>(builder: (_) => getIt.get<NanoChangeRepPage>());
 
     case Routes.walletList:
+      final onWalletLoaded = settings.arguments as Function(BuildContext)?;
       return MaterialPageRoute<void>(
-          fullscreenDialog: true, builder: (_) => getIt.get<WalletListPage>());
+        fullscreenDialog: true,
+        builder: (_) => getIt.get<WalletListPage>(param1: onWalletLoaded),
+      );
 
     case Routes.walletEdit:
       return MaterialPageRoute<void>(
diff --git a/lib/src/screens/connect_device/connect_device_page.dart b/lib/src/screens/connect_device/connect_device_page.dart
index 9e331e818..c2cc40229 100644
--- a/lib/src/screens/connect_device/connect_device_page.dart
+++ b/lib/src/screens/connect_device/connect_device_page.dart
@@ -2,9 +2,12 @@ import 'dart:async';
 import 'dart:io';
 
 import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/screens/base_page.dart';
 import 'package:cake_wallet/src/screens/connect_device/widgets/device_tile.dart';
+import 'package:cake_wallet/src/widgets/primary_button.dart';
 import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
+import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -17,35 +20,46 @@ typedef OnConnectDevice = void Function(BuildContext, LedgerViewModel);
 class ConnectDevicePageParams {
   final WalletType walletType;
   final OnConnectDevice onConnectDevice;
+  final bool allowChangeWallet;
 
-  ConnectDevicePageParams(
-      {required this.walletType, required this.onConnectDevice});
+  ConnectDevicePageParams({
+    required this.walletType,
+    required this.onConnectDevice,
+    this.allowChangeWallet = false,
+  });
 }
 
 class ConnectDevicePage extends BasePage {
   final WalletType walletType;
   final OnConnectDevice onConnectDevice;
+  final bool allowChangeWallet;
   final LedgerViewModel ledgerVM;
 
   ConnectDevicePage(ConnectDevicePageParams params, this.ledgerVM)
       : walletType = params.walletType,
-        onConnectDevice = params.onConnectDevice;
+        onConnectDevice = params.onConnectDevice,
+        allowChangeWallet = params.allowChangeWallet;
 
   @override
   String get title => S.current.restore_title_from_hardware_wallet;
 
   @override
-  Widget body(BuildContext context) =>
-      ConnectDevicePageBody(walletType, onConnectDevice, ledgerVM);
+  Widget body(BuildContext context) => ConnectDevicePageBody(
+      walletType, onConnectDevice, allowChangeWallet, ledgerVM);
 }
 
 class ConnectDevicePageBody extends StatefulWidget {
   final WalletType walletType;
   final OnConnectDevice onConnectDevice;
+  final bool allowChangeWallet;
   final LedgerViewModel ledgerVM;
 
   const ConnectDevicePageBody(
-      this.walletType, this.onConnectDevice, this.ledgerVM);
+    this.walletType,
+    this.onConnectDevice,
+    this.allowChangeWallet,
+    this.ledgerVM,
+  );
 
   @override
   ConnectDevicePageBodyState createState() => ConnectDevicePageBodyState();
@@ -102,14 +116,16 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
 
   Future<void> _refreshBleDevices() async {
     try {
-      _bleRefresh = widget.ledgerVM
-          .scanForBleDevices()
-          .listen((device) => setState(() => bleDevices.add(device)))
-        ..onError((e) {
-          throw e.toString();
-        });
-      _bleRefreshTimer?.cancel();
-      _bleRefreshTimer = null;
+      if (widget.ledgerVM.bleIsEnabled) {
+        _bleRefresh = widget.ledgerVM
+            .scanForBleDevices()
+            .listen((device) => setState(() => bleDevices.add(device)))
+          ..onError((e) {
+            throw e.toString();
+          });
+        _bleRefreshTimer?.cancel();
+        _bleRefreshTimer = null;
+      }
     } catch (e) {
       print(e);
     }
@@ -227,9 +243,7 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
                       style: TextStyle(
                         fontSize: 14,
                         fontWeight: FontWeight.w400,
-                        color: Theme.of(context)
-                            .extension<CakeTextTheme>()!
-                            .titleColor,
+                        color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
                       ),
                     ),
                   ),
@@ -247,11 +261,27 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
                       ),
                     )
                     .toList(),
-              ]
+              ],
+              if (widget.allowChangeWallet) ...[
+                PrimaryButton(
+                  text: S.of(context).wallets,
+                  color: Theme.of(context).extension<WalletListTheme>()!.createNewWalletButtonBackgroundColor,
+                  textColor: Theme.of(context).extension<WalletListTheme>()!.restoreWalletButtonTextColor,
+                  onPressed: _onChangeWallet,
+                )
+              ],
             ],
           ),
         ),
       ),
     );
   }
+
+  void _onChangeWallet() {
+    Navigator.of(context).pushNamed(
+      Routes.walletList,
+      arguments: (BuildContext context) => Navigator.of(context)
+          .pushNamedAndRemoveUntil(Routes.dashboard, (route) => false),
+    );
+  }
 }
diff --git a/lib/src/screens/connect_device/monero_hardware_wallet_options_page.dart b/lib/src/screens/connect_device/monero_hardware_wallet_options_page.dart
new file mode 100644
index 000000000..f8ace97bc
--- /dev/null
+++ b/lib/src/screens/connect_device/monero_hardware_wallet_options_page.dart
@@ -0,0 +1,230 @@
+import 'package:cake_wallet/core/wallet_name_validator.dart';
+import 'package:cake_wallet/entities/generate_name.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
+import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
+import 'package:cake_wallet/src/widgets/primary_button.dart';
+import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
+import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
+import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
+import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cake_wallet/view_model/wallet_hardware_restore_view_model.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+import 'package:mobx/mobx.dart';
+
+class MoneroHardwareWalletOptionsPage extends BasePage {
+  MoneroHardwareWalletOptionsPage(this._walletHardwareRestoreVM);
+
+  final WalletHardwareRestoreViewModel _walletHardwareRestoreVM;
+
+  @override
+  String get title => S.current.restore_title_from_hardware_wallet;
+
+  @override
+  Widget body(BuildContext context) =>
+      _MoneroHardwareWalletOptionsForm(_walletHardwareRestoreVM);
+}
+
+class _MoneroHardwareWalletOptionsForm extends StatefulWidget {
+  const _MoneroHardwareWalletOptionsForm(this._walletHardwareRestoreVM);
+
+  final WalletHardwareRestoreViewModel _walletHardwareRestoreVM;
+
+  @override
+  _MoneroHardwareWalletOptionsFormState createState() =>
+      _MoneroHardwareWalletOptionsFormState(_walletHardwareRestoreVM);
+}
+
+class _MoneroHardwareWalletOptionsFormState
+    extends State<_MoneroHardwareWalletOptionsForm> {
+  _MoneroHardwareWalletOptionsFormState(this._walletHardwareRestoreVM)
+      : _formKey = GlobalKey<FormState>(),
+        _blockchainHeightKey = GlobalKey<BlockchainHeightState>(),
+        _blockHeightFocusNode = FocusNode(),
+        _controller = TextEditingController();
+
+  final GlobalKey<FormState> _formKey;
+  final GlobalKey<BlockchainHeightState> _blockchainHeightKey;
+  final FocusNode _blockHeightFocusNode;
+  final WalletHardwareRestoreViewModel _walletHardwareRestoreVM;
+  final TextEditingController _controller;
+
+  @override
+  void initState() {
+    super.initState();
+    _setEffects(context);
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: EdgeInsets.only(top: 24),
+      child: ScrollableWithBottomSection(
+        contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
+        content: Center(
+          child: ConstrainedBox(
+            constraints: BoxConstraints(
+                maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                Padding(
+                  padding: EdgeInsets.only(top: 0),
+                  child: Form(
+                    key: _formKey,
+                    child: Stack(
+                      alignment: Alignment.centerRight,
+                      children: [
+                        TextFormField(
+                          onChanged: (value) =>
+                              _walletHardwareRestoreVM.name = value,
+                          controller: _controller,
+                          style: TextStyle(
+                            fontSize: 20.0,
+                            fontWeight: FontWeight.w600,
+                            color: Theme.of(context)
+                                .extension<CakeTextTheme>()!
+                                .titleColor,
+                          ),
+                          decoration: InputDecoration(
+                            hintStyle: TextStyle(
+                              fontSize: 18.0,
+                              fontWeight: FontWeight.w500,
+                              color: Theme.of(context)
+                                  .extension<NewWalletTheme>()!
+                                  .hintTextColor,
+                            ),
+                            hintText: S.of(context).wallet_name,
+                            focusedBorder: UnderlineInputBorder(
+                              borderSide: BorderSide(
+                                color: Theme.of(context)
+                                    .extension<NewWalletTheme>()!
+                                    .underlineColor,
+                                width: 1.0,
+                              ),
+                            ),
+                            enabledBorder: UnderlineInputBorder(
+                              borderSide: BorderSide(
+                                color: Theme.of(context)
+                                    .extension<NewWalletTheme>()!
+                                    .underlineColor,
+                                width: 1.0,
+                              ),
+                            ),
+                            suffixIcon: Semantics(
+                              label: S.of(context).generate_name,
+                              child: IconButton(
+                                onPressed: _onGenerateName,
+                                icon: Container(
+                                  padding: const EdgeInsets.all(8),
+                                  decoration: BoxDecoration(
+                                    borderRadius: BorderRadius.circular(6.0),
+                                    color: Theme.of(context).hintColor,
+                                  ),
+                                  width: 34,
+                                  height: 34,
+                                  child: Image.asset(
+                                    'assets/images/refresh_icon.png',
+                                    color: Theme.of(context)
+                                        .extension<SendPageTheme>()!
+                                        .textFieldButtonIconColor,
+                                  ),
+                                ),
+                              ),
+                            ),
+                          ),
+                          validator: WalletNameValidator(),
+                        ),
+                      ],
+                    ),
+                  ),
+                ),
+                Padding(
+                  padding: EdgeInsets.only(top: 20),
+                  child: BlockchainHeightWidget(
+                    focusNode: _blockHeightFocusNode,
+                    key: _blockchainHeightKey,
+                    hasDatePicker: true,
+                    walletType: WalletType.monero,
+                  ),
+                ),
+              ],
+            ),
+          ),
+        ),
+        bottomSectionPadding: EdgeInsets.all(24),
+        bottomSection: Observer(
+          builder: (context) => LoadingPrimaryButton(
+            onPressed: _confirmForm,
+            text: S.of(context).seed_language_next,
+            color: Colors.green,
+            textColor: Colors.white,
+            isDisabled: _walletHardwareRestoreVM.name.isEmpty,
+          ),
+        ),
+      ),
+    );
+  }
+
+  Future<void> _onGenerateName() async {
+    final rName = await generateName();
+    FocusManager.instance.primaryFocus?.unfocus();
+
+    setState(() {
+      _controller.text = rName;
+      _walletHardwareRestoreVM.name = rName;
+      _controller.selection = TextSelection.fromPosition(
+          TextPosition(offset: _controller.text.length));
+    });
+  }
+
+  Future<void> _confirmForm() async {
+    showPopUp<void>(
+      context: context,
+      builder: (BuildContext context) => AlertWithOneAction(
+        alertTitle: S.of(context).proceed_on_device,
+        alertContent: S.of(context).proceed_on_device_description,
+        buttonText: S.of(context).cancel,
+        buttonAction: () => Navigator.of(context).pop(),
+      ),
+    );
+
+    final options = {'height': _blockchainHeightKey.currentState?.height ?? -1};
+    await _walletHardwareRestoreVM.create(options: options);
+  }
+
+  bool _effectsInstalled = false;
+
+  void _setEffects(BuildContext context) {
+    if (_effectsInstalled) return;
+
+    reaction((_) => _walletHardwareRestoreVM.error, (String? error) {
+      if (error != null) {
+        if (error == S.current.ledger_connection_error)
+          Navigator.of(context).pop();
+
+        WidgetsBinding.instance.addPostFrameCallback((_) {
+          showPopUp<void>(
+            context: context,
+            builder: (BuildContext context) => AlertWithOneAction(
+              alertTitle: S.of(context).error,
+              alertContent: error,
+              buttonText: S.of(context).ok,
+              buttonAction: () {
+                _walletHardwareRestoreVM.error = null;
+                Navigator.of(context).pop();
+              },
+            ),
+          );
+        });
+      }
+    });
+
+    _effectsInstalled = true;
+  }
+}
diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart
index a9a9d9413..46eaa6143 100644
--- a/lib/src/screens/wallet_list/wallet_list_page.dart
+++ b/lib/src/screens/wallet_list/wallet_list_page.dart
@@ -1,44 +1,56 @@
+import 'package:another_flushbar/flushbar.dart';
+import 'package:cake_wallet/core/auth_service.dart';
 import 'package:cake_wallet/core/new_wallet_arguments.dart';
 import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart';
 import 'package:cake_wallet/entities/wallet_list_order_types.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/monero/monero.dart';
+import 'package:cake_wallet/routes.dart';
+import 'package:cake_wallet/src/screens/auth/auth_page.dart';
+import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart';
 import 'package:cake_wallet/src/screens/dashboard/widgets/filter_list_widget.dart';
 import 'package:cake_wallet/src/screens/new_wallet/widgets/grouped_wallet_expansion_tile.dart';
 import 'package:cake_wallet/src/screens/wallet_list/edit_wallet_button_widget.dart';
 import 'package:cake_wallet/src/screens/wallet_list/filtered_list.dart';
 import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
+import 'package:cake_wallet/src/widgets/primary_button.dart';
 import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
-import 'package:cake_wallet/src/screens/auth/auth_page.dart';
-import 'package:cake_wallet/core/auth_service.dart';
 import 'package:cake_wallet/themes/extensions/filter_theme.dart';
 import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
 import 'package:cake_wallet/utils/show_bar.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
-import 'package:another_flushbar/flushbar.dart';
+import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
+import 'package:cake_wallet/wallet_type_utils.dart';
+import 'package:cw_core/wallet_type.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
-import 'package:cake_wallet/routes.dart';
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cw_core/wallet_type.dart';
-import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
-import 'package:cake_wallet/src/widgets/primary_button.dart';
-import 'package:cake_wallet/src/screens/base_page.dart';
-import 'package:cake_wallet/wallet_type_utils.dart';
 
 class WalletListPage extends BasePage {
-  WalletListPage({required this.walletListViewModel, required this.authService});
+  WalletListPage({
+    required this.walletListViewModel,
+    required this.authService,
+    this.onWalletLoaded,
+  });
 
   final WalletListViewModel walletListViewModel;
   final AuthService authService;
+  final Function(BuildContext)? onWalletLoaded;
 
   @override
   String get title => S.current.wallets;
 
   @override
-  Widget body(BuildContext context) =>
-      WalletListBody(walletListViewModel: walletListViewModel, authService: authService);
+  Widget body(BuildContext context) => WalletListBody(
+        walletListViewModel: walletListViewModel,
+        authService: authService,
+        onWalletLoaded:
+            onWalletLoaded ?? (context) => Navigator.of(context).pop(),
+      );
 
   @override
   Widget trailing(BuildContext context) {
@@ -89,10 +101,15 @@ class WalletListPage extends BasePage {
 }
 
 class WalletListBody extends StatefulWidget {
-  WalletListBody({required this.walletListViewModel, required this.authService});
+  WalletListBody({
+    required this.walletListViewModel,
+    required this.authService,
+    required this.onWalletLoaded,
+  });
 
   final WalletListViewModel walletListViewModel;
   final AuthService authService;
+  final Function(BuildContext) onWalletLoaded;
 
   @override
   WalletListBodyState createState() => WalletListBodyState();
@@ -118,8 +135,8 @@ class WalletListBodyState extends State<WalletListBody> {
 
   @override
   Widget build(BuildContext context) {
-    final newWalletImage =
-        Image.asset('assets/images/new_wallet.png', height: 12, width: 12, color: Colors.white);
+    final newWalletImage = Image.asset('assets/images/new_wallet.png',
+        height: 12, width: 12, color: Colors.white);
     final restoreWalletImage = Image.asset('assets/images/restore_wallet.png',
         height: 12,
         width: 12,
@@ -180,8 +197,7 @@ class WalletListBodyState extends State<WalletListBody> {
                               trailingWidget: EditWalletButtonWidget(
                                 width: 74,
                                 isGroup: true,
-                                isExpanded:
-                                    widget.walletListViewModel.expansionTileStateTrack[index]!,
+                                isExpanded: widget.walletListViewModel.expansionTileStateTrack[index]!,
                                 onTap: () {
                                   final wallet = widget.walletListViewModel
                                       .convertWalletInfoToWalletListItem(group.wallets.first);
@@ -198,8 +214,7 @@ class WalletListBodyState extends State<WalletListBody> {
                                 },
                               ),
                               childWallets: group.wallets.map((walletInfo) {
-                                return widget.walletListViewModel
-                                    .convertWalletInfoToWalletListItem(walletInfo);
+                                return widget.walletListViewModel.convertWalletInfoToWalletListItem(walletInfo);
                               }).toList(),
                               isSelected: false,
                               onChildItemTapped: (wallet) =>
@@ -329,8 +344,7 @@ class WalletListBodyState extends State<WalletListBody> {
                           arguments: NewWalletArguments(
                             type: widget.walletListViewModel.currentWalletType,
                           ),
-                          conditionToDetermineIfToUse2FA:
-                              widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets,
+                          conditionToDetermineIfToUse2FA: widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets,
                         );
                       } else {
                         Navigator.of(context).pushNamed(
@@ -345,8 +359,7 @@ class WalletListBodyState extends State<WalletListBody> {
                         widget.authService.authenticateAction(
                           context,
                           route: Routes.newWalletType,
-                          conditionToDetermineIfToUse2FA:
-                              widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets,
+                          conditionToDetermineIfToUse2FA: widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets,
                         );
                       } else {
                         Navigator.of(context).pushNamed(Routes.newWalletType);
@@ -367,8 +380,7 @@ class WalletListBodyState extends State<WalletListBody> {
                         context,
                         route: Routes.restoreOptions,
                         arguments: false,
-                        conditionToDetermineIfToUse2FA:
-                            widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets,
+                        conditionToDetermineIfToUse2FA: widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets,
                       );
                     } else {
                       Navigator.of(context).pushNamed(Routes.restoreOptions, arguments: false);
@@ -387,39 +399,6 @@ class WalletListBodyState extends State<WalletListBody> {
     );
   }
 
-  Image _imageFor({required WalletType type, bool? isTestnet}) {
-    switch (type) {
-      case WalletType.bitcoin:
-        if (isTestnet == true) {
-          return tBitcoinIcon;
-        }
-        return bitcoinIcon;
-      case WalletType.monero:
-        return moneroIcon;
-      case WalletType.litecoin:
-        return litecoinIcon;
-      case WalletType.haven:
-        return havenIcon;
-      case WalletType.ethereum:
-        return ethereumIcon;
-      case WalletType.bitcoinCash:
-        return bitcoinCashIcon;
-      case WalletType.nano:
-      case WalletType.banano:
-        return nanoIcon;
-      case WalletType.polygon:
-        return polygonIcon;
-      case WalletType.solana:
-        return solanaIcon;
-      case WalletType.tron:
-        return tronIcon;
-      case WalletType.wownero:
-        return wowneroIcon;
-      case WalletType.none:
-        return nonWalletTypeIcon;
-    }
-  }
-
   Future<void> _loadWallet(WalletListItem wallet) async {
     if (SettingsStoreBase.walletPasswordDirectInput) {
       Navigator.of(context).pushNamed(Routes.walletUnlockLoadable,
@@ -438,12 +417,36 @@ class WalletListBodyState extends State<WalletListBody> {
     await widget.authService.authenticateAction(
       context,
       onAuthSuccess: (isAuthenticatedSuccessfully) async {
-        if (!isAuthenticatedSuccessfully) {
-          return;
-        }
+        if (!isAuthenticatedSuccessfully) return;
 
         try {
-          changeProcessText(S.of(context).wallet_list_loading_wallet(wallet.name));
+          if (widget.walletListViewModel
+              .requireHardwareWalletConnection(wallet)) {
+            await Navigator.of(context).pushNamed(
+              Routes.connectDevices,
+              arguments: ConnectDevicePageParams(
+                walletType: WalletType.monero,
+                onConnectDevice: (context, ledgerVM) async {
+                  monero!.setGlobalLedgerConnection(ledgerVM.connection);
+                  Navigator.of(context).pop();
+                },
+              ),
+            );
+
+            showPopUp<void>(
+              context: context,
+              builder: (BuildContext context) => AlertWithOneAction(
+                  alertTitle: S.of(context).proceed_on_device,
+                  alertContent: S.of(context).proceed_on_device_description,
+                  buttonText: S.of(context).cancel,
+                  buttonAction: () => Navigator.of(context).pop()),
+            );
+          }
+
+
+
+          changeProcessText(
+              S.of(context).wallet_list_loading_wallet(wallet.name));
           await widget.walletListViewModel.loadWallet(wallet);
           await hideProgressText();
           // only pop the wallets route in mobile as it will go back to dashboard page
@@ -451,13 +454,15 @@ class WalletListBodyState extends State<WalletListBody> {
           if (responsiveLayoutUtil.shouldRenderMobileUI) {
             WidgetsBinding.instance.addPostFrameCallback((_) {
               if (this.mounted) {
-                Navigator.of(context).pop();
+                widget.onWalletLoaded.call(context);
               }
             });
           }
         } catch (e) {
           if (this.mounted) {
-            changeProcessText(S.of(context).wallet_list_failed_to_load(wallet.name, e.toString()));
+            changeProcessText(S
+                .of(context)
+                .wallet_list_failed_to_load(wallet.name, e.toString()));
           }
         }
       },
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index a78012ae9..808657f66 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -428,7 +428,7 @@ abstract class DashboardViewModelBase with Store {
       // to not cause work duplication, this will do the job as well, it will be slightly less precise
       // about what happened - but still enough.
       // if (keys['privateSpendKey'] == List.generate(64, (index) => "0").join("")) "Private spend key is 0",
-      if (keys['privateViewKey'] == List.generate(64, (index) => "0").join(""))
+      if (keys['privateViewKey'] == List.generate(64, (index) => "0").join("") && !wallet.isHardwareWallet)
         "private view key is 0",
       // if (keys['publicSpendKey'] == List.generate(64, (index) => "0").join("")) "public spend key is 0",
       if (keys['publicViewKey'] == List.generate(64, (index) => "0").join(""))
diff --git a/lib/view_model/hardware_wallet/ledger_view_model.dart b/lib/view_model/hardware_wallet/ledger_view_model.dart
index 19b190fe3..96f5930c0 100644
--- a/lib/view_model/hardware_wallet/ledger_view_model.dart
+++ b/lib/view_model/hardware_wallet/ledger_view_model.dart
@@ -4,6 +4,7 @@ import 'dart:io';
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
 import 'package:cake_wallet/ethereum/ethereum.dart';
 import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/monero/monero.dart';
 import 'package:cake_wallet/polygon/polygon.dart';
 import 'package:cake_wallet/utils/device_info.dart';
 import 'package:cake_wallet/wallet_type_utils.dart';
@@ -114,6 +115,8 @@ abstract class LedgerViewModelBase with Store {
 
   void setLedger(WalletBase wallet) {
     switch (wallet.type) {
+      case WalletType.monero:
+        return monero!.setLedgerConnection(wallet, connection);
       case WalletType.bitcoin:
       case WalletType.litecoin:
         return bitcoin!.setLedgerConnection(wallet, connection);
diff --git a/lib/view_model/wallet_hardware_restore_view_model.dart b/lib/view_model/wallet_hardware_restore_view_model.dart
index 91e0de685..0971622a5 100644
--- a/lib/view_model/wallet_hardware_restore_view_model.dart
+++ b/lib/view_model/wallet_hardware_restore_view_model.dart
@@ -1,7 +1,9 @@
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
+import 'package:cake_wallet/core/generate_wallet_password.dart';
 import 'package:cake_wallet/core/wallet_creation_service.dart';
 import 'package:cake_wallet/ethereum/ethereum.dart';
 import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/monero/monero.dart';
 import 'package:cake_wallet/polygon/polygon.dart';
 import 'package:cake_wallet/store/app_store.dart';
 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
@@ -56,8 +58,8 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with
       List<HardwareAccountData> accounts;
       switch (type) {
         case WalletType.bitcoin:
-        accounts = await bitcoin!
-            .getHardwareWalletBitcoinAccounts(ledgerViewModel, index: _nextIndex, limit: limit);
+          accounts = await bitcoin!
+              .getHardwareWalletBitcoinAccounts(ledgerViewModel, index: _nextIndex, limit: limit);
         break;
       case WalletType.litecoin:
         accounts = await bitcoin!
@@ -104,6 +106,15 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with
       case WalletType.polygon:
         credentials = polygon!.createPolygonHardwareWalletCredentials(name: name, hwAccountData: selectedAccount!);
         break;
+      case WalletType.monero:
+        final password = walletPassword ?? generateWalletPassword();
+
+        credentials = monero!.createMoneroRestoreWalletFromHardwareCredentials(
+          name: name,
+          ledgerConnection: ledgerViewModel.connection,
+          password: password,
+          height: _options['height'] as int? ?? 0,
+        );
       default:
         throw Exception('Unexpected type: ${type.toString()}');
     }
diff --git a/lib/view_model/wallet_list/wallet_list_view_model.dart b/lib/view_model/wallet_list/wallet_list_view_model.dart
index 725af843f..c903b535f 100644
--- a/lib/view_model/wallet_list/wallet_list_view_model.dart
+++ b/lib/view_model/wallet_list/wallet_list_view_model.dart
@@ -68,6 +68,10 @@ abstract class WalletListViewModelBase with Store {
 
   WalletType get currentWalletType => _appStore.wallet!.type;
 
+  bool requireHardwareWalletConnection(WalletListItem walletItem) =>
+      _walletLoadingService.requireHardwareWalletConnection(
+          walletItem.type, walletItem.name);
+
   @action
   Future<void> loadWallet(WalletListItem walletItem) async {
     // bool switchingToSameWalletType = walletItem.type == _appStore.wallet?.type;
@@ -87,7 +91,8 @@ abstract class WalletListViewModelBase with Store {
     singleWalletsList.clear();
 
     wallets.addAll(
-      _walletInfoSource.values.map((info) => convertWalletInfoToWalletListItem(info)),
+      _walletInfoSource.values
+          .map((info) => convertWalletInfoToWalletListItem(info)),
     );
 
     //========== Split into shared seed groups and single wallets list
@@ -95,7 +100,8 @@ abstract class WalletListViewModelBase with Store {
 
     for (var group in _walletManager.walletGroups) {
       if (group.wallets.length == 1) {
-        singleWalletsList.add(convertWalletInfoToWalletListItem(group.wallets.first));
+        singleWalletsList
+            .add(convertWalletInfoToWalletListItem(group.wallets.first));
       } else {
         multiWalletGroups.add(group);
       }
@@ -148,9 +154,11 @@ abstract class WalletListViewModelBase with Store {
     List<WalletInfo> walletInfoSourceCopy = _walletInfoSource.values.toList();
     await _walletInfoSource.clear();
     if (ascending) {
-      walletInfoSourceCopy.sort((a, b) => a.type.toString().compareTo(b.type.toString()));
+      walletInfoSourceCopy
+          .sort((a, b) => a.type.toString().compareTo(b.type.toString()));
     } else {
-      walletInfoSourceCopy.sort((a, b) => b.type.toString().compareTo(a.type.toString()));
+      walletInfoSourceCopy
+          .sort((a, b) => b.type.toString().compareTo(a.type.toString()));
     }
     await _walletInfoSource.addAll(walletInfoSourceCopy);
     updateList();
@@ -213,7 +221,8 @@ abstract class WalletListViewModelBase with Store {
       name: info.name,
       type: info.type,
       key: info.key,
-      isCurrent: info.name == _appStore.wallet?.name && info.type == _appStore.wallet?.type,
+      isCurrent: info.name == _appStore.wallet?.name &&
+          info.type == _appStore.wallet?.type,
       isEnabled: availableWalletTypes.contains(info.type),
       isTestnet: info.network?.toLowerCase().contains('testnet') ?? false,
     );
diff --git a/scripts/prepare_moneroc.sh b/scripts/prepare_moneroc.sh
index 24f4d201c..0d90e431a 100755
--- a/scripts/prepare_moneroc.sh
+++ b/scripts/prepare_moneroc.sh
@@ -6,9 +6,9 @@ cd "$(dirname "$0")"
 
 if [[ ! -d "monero_c" ]];
 then
-    git clone https://github.com/mrcyjanek/monero_c --branch rewrite-wip
+    git clone https://github.com/mrcyjanek/monero_c --branch master
     cd monero_c
-    git checkout 6eb571ea498ed7b854934785f00fabfd0dadf75b
+    git checkout 1d8e0fb30b53c28756f23676d5a3e1a99a9b3051
     git reset --hard
     git submodule update --init --force --recursive
     ./apply_patches.sh monero
diff --git a/tool/configure.dart b/tool/configure.dart
index c5d4a6863..fb8291385 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -270,20 +270,22 @@ import 'package:cw_core/output_info.dart';
 import 'package:cake_wallet/view_model/send/output.dart';
 import 'package:cw_core/wallet_service.dart';
 import 'package:hive/hive.dart';
+import 'package:ledger_flutter_plus/ledger_flutter_plus.dart' as ledger;
 import 'package:polyseed/polyseed.dart';""";
   const moneroCWHeaders = """
+import 'package:cw_core/account.dart' as monero_account;
 import 'package:cw_core/get_height_by_date.dart';
 import 'package:cw_core/monero_amount_format.dart';
 import 'package:cw_core/monero_transaction_priority.dart';
+import 'package:cw_monero/api/wallet_manager.dart';
+import 'package:cw_monero/api/wallet.dart' as monero_wallet_api;
+import 'package:cw_monero/ledger.dart';
 import 'package:cw_monero/monero_unspent.dart';
 import 'package:cw_monero/api/account_list.dart';
 import 'package:cw_monero/monero_wallet_service.dart';
-import 'package:cw_monero/api/wallet_manager.dart';
 import 'package:cw_monero/monero_wallet.dart';
 import 'package:cw_monero/monero_transaction_info.dart';
 import 'package:cw_monero/monero_transaction_creation_credentials.dart';
-import 'package:cw_core/account.dart' as monero_account;
-import 'package:cw_monero/api/wallet.dart' as monero_wallet_api;
 import 'package:cw_monero/mnemonics/english.dart';
 import 'package:cw_monero/mnemonics/chinese_simplified.dart';
 import 'package:cw_monero/mnemonics/dutch.dart';
@@ -395,6 +397,7 @@ abstract class Monero {
     required String language,
     required int height});
   WalletCredentials createMoneroRestoreWalletFromSeedCredentials({required String name, required String password, required int height, required String mnemonic});
+  WalletCredentials createMoneroRestoreWalletFromHardwareCredentials({required String name, required String password, required int height, required ledger.LedgerConnection ledgerConnection});
   WalletCredentials createMoneroNewWalletCredentials({required String name, required String language, required bool isPolyseed, String? password});
   Map<String, String> getKeys(Object wallet);
   int? getRestoreHeight(Object wallet);
@@ -411,6 +414,8 @@ abstract class Monero {
   int getTransactionInfoAccountId(TransactionInfo tx);
   WalletService createMoneroWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource);
   Map<String, String> pendingTransactionInfo(Object transaction);
+  void setLedgerConnection(Object wallet, ledger.LedgerConnection connection);
+  void setGlobalLedgerConnection(ledger.LedgerConnection connection);
 }
 
 abstract class MoneroSubaddressList {

From 96db38c0aa3b2628118302e137e7b1969b5367d0 Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Tue, 12 Nov 2024 05:29:32 +0200
Subject: [PATCH 15/15] Cw 744 improve address book (#1771)

* add sort function to contact list

* fix UI

* prevent duplicate contact names

* dispose contact source subscription

* fix custom order issue

* update the address book UI

* fix saving custom order

* fix merge conflict issue

* fix the address book filter by the selected currency

* add dropdown for wallets with multiple address types

* minor fixes

* add dropdown for wallets with multiple address types

* Update lib/entities/contact.dart [skip ci]

* Update lib/src/screens/contact/contact_list_page.dart [skip ci]

* Update lib/src/screens/contact/contact_list_page.dart [skip ci]

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 .../screens/contact/contact_list_page.dart    | 62 ++++++++++++++++---
 .../contact_list/contact_list_view_model.dart | 35 +++++++----
 2 files changed, 75 insertions(+), 22 deletions(-)

diff --git a/lib/src/screens/contact/contact_list_page.dart b/lib/src/screens/contact/contact_list_page.dart
index 130380b09..f71747953 100644
--- a/lib/src/screens/contact/contact_list_page.dart
+++ b/lib/src/screens/contact/contact_list_page.dart
@@ -11,6 +11,7 @@ import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
 import 'package:cake_wallet/src/widgets/standard_list.dart';
 import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
+import 'package:cake_wallet/themes/extensions/filter_theme.dart';
 import 'package:cake_wallet/utils/show_bar.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
@@ -160,25 +161,60 @@ class _ContactPageBodyState extends State<ContactPageBody> with SingleTickerProv
   Widget _buildWalletContacts(BuildContext context) {
     final walletContacts = widget.contactListViewModel.walletContactsToShow;
 
+    final groupedContacts = <String, List<ContactBase>>{};
+    for (var contact in walletContacts) {
+      final baseName = _extractBaseName(contact.name);
+      groupedContacts.putIfAbsent(baseName, () => []).add(contact);
+    }
+
     return ListView.builder(
-      shrinkWrap: true,
-      itemCount: walletContacts.length * 2,
+      itemCount: groupedContacts.length * 2,
       itemBuilder: (context, index) {
         if (index.isOdd) {
           return StandardListSeparator();
         } else {
-          final walletInfo = walletContacts[index ~/ 2];
-          return generateRaw(context, walletInfo);
+          final groupIndex = index ~/ 2;
+          final groupName = groupedContacts.keys.elementAt(groupIndex);
+          final groupContacts = groupedContacts[groupName]!;
+
+          if (groupContacts.length == 1) {
+            final contact = groupContacts[0];
+            return generateRaw(context, contact);
+          } else {
+            final activeContact = groupContacts.firstWhere(
+              (contact) => contact.name.contains('Active'),
+              orElse: () => groupContacts[0],
+            );
+
+            return ExpansionTile(
+              title: Text(
+                groupName,
+                style: TextStyle(
+                  fontSize: 14,
+                  fontWeight: FontWeight.normal,
+                  color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
+                ),
+              ),
+              leading: _buildCurrencyIcon(activeContact),
+              tilePadding: EdgeInsets.zero,
+              childrenPadding: const EdgeInsets.only(left: 16),
+              expandedCrossAxisAlignment: CrossAxisAlignment.start,
+              expandedAlignment: Alignment.topLeft,
+              children: groupContacts.map((contact) => generateRaw(context, contact)).toList(),
+            );
+          }
         }
       },
     );
   }
 
+  String _extractBaseName(String name) {
+    final bracketIndex = name.indexOf('(');
+    return (bracketIndex != -1) ? name.substring(0, bracketIndex).trim() : name;
+  }
+
   Widget generateRaw(BuildContext context, ContactBase contact) {
-    final image = contact.type.iconPath;
-    final currencyIcon = image != null
-        ? Image.asset(image, height: 24, width: 24)
-        : const SizedBox(height: 24, width: 24);
+    final currencyIcon = _buildCurrencyIcon(contact);
 
     return GestureDetector(
       onTap: () async {
@@ -219,6 +255,13 @@ class _ContactPageBodyState extends State<ContactPageBody> with SingleTickerProv
     );
   }
 
+  Widget _buildCurrencyIcon(ContactBase contact) {
+    final image = contact.type.iconPath;
+    return image != null
+        ? Image.asset(image, height: 24, width: 24)
+        : const SizedBox(height: 24, width: 24);
+  }
+
   Future<bool> showNameAndAddressDialog(BuildContext context, String name, String address) async {
     return await showPopUp<bool>(
             context: context,
@@ -263,12 +306,13 @@ class _ContactListBodyState extends State<ContactListBody> {
   @override
   void dispose() {
     widget.tabController.removeListener(_handleTabChange);
+    widget.contactListViewModel.dispose();
     super.dispose();
   }
 
   @override
   Widget build(BuildContext context) {
-    final contacts = widget.contactListViewModel.contacts;
+    final contacts = widget.contactListViewModel.contactsToShow;
     return Scaffold(
       body: Container(
         child: FilteredList(
diff --git a/lib/view_model/contact_list/contact_list_view_model.dart b/lib/view_model/contact_list/contact_list_view_model.dart
index 0015463a5..25f222891 100644
--- a/lib/view_model/contact_list/contact_list_view_model.dart
+++ b/lib/view_model/contact_list/contact_list_view_model.dart
@@ -28,7 +28,8 @@ abstract class ContactListViewModelBase with Store {
         isAutoGenerateEnabled =
             settingsStore.autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.enabled {
     walletInfoSource.values.forEach((info) {
-      if ([WalletType.monero, WalletType.wownero, WalletType.haven].contains(info.type) && info.addressInfos != null) {
+      if ([WalletType.monero, WalletType.wownero, WalletType.haven].contains(info.type) &&
+          info.addressInfos != null) {
         for (var key in info.addressInfos!.keys) {
           final value = info.addressInfos![key];
           final address = value?.first;
@@ -60,15 +61,19 @@ abstract class ContactListViewModelBase with Store {
               address,
               name,
               walletTypeToCryptoCurrency(info.type,
-                  isTestnet:
-                      info.network == null ? false : info.network!.toLowerCase().contains("testnet")),
+                  isTestnet: info.network == null
+                      ? false
+                      : info.network!.toLowerCase().contains("testnet")),
             ));
           });
         }
       } else {
         walletContacts.add(WalletContact(
           info.address,
-          _createName(info.name, "", key: [WalletType.monero, WalletType.wownero, WalletType.haven].contains(info.type) ? 0 : null),
+          _createName(info.name, "",
+              key: [WalletType.monero, WalletType.wownero, WalletType.haven].contains(info.type)
+                  ? 0
+                  : null),
           walletTypeToCryptoCurrency(info.type),
         ));
       }
@@ -82,8 +87,11 @@ abstract class ContactListViewModelBase with Store {
   }
 
   String _createName(String walletName, String label, {int? key = null}) {
-    final actualLabel = label.replaceAll(RegExp(r'active', caseSensitive: false), S.current.active).replaceAll(RegExp(r'silent payments', caseSensitive: false), S.current.silent_payments);
-    return '$walletName${key == null ? "" : " [#${key}]"} ${actualLabel.isNotEmpty ? "($actualLabel)" : ""}'.trim();
+    final actualLabel = label
+        .replaceAll(RegExp(r'active', caseSensitive: false), S.current.active)
+        .replaceAll(RegExp(r'silent payments', caseSensitive: false), S.current.silent_payments);
+    return '$walletName${key == null ? "" : " [#${key}]"} ${actualLabel.isNotEmpty ? "($actualLabel)" : ""}'
+        .trim();
   }
 
   final bool isAutoGenerateEnabled;
@@ -108,18 +116,19 @@ abstract class ContactListViewModelBase with Store {
   Future<void> delete(ContactRecord contact) async => contact.original.delete();
 
   ObservableList<ContactRecord> get contactsToShow =>
-      ObservableList.of(contacts.where((element) => _isValidForCurrency(element)));
+      ObservableList.of(contacts.where((element) => _isValidForCurrency(element, false)));
 
   @computed
   List<WalletContact> get walletContactsToShow =>
-      walletContacts.where((element) => _isValidForCurrency(element)).toList();
+      walletContacts.where((element) => _isValidForCurrency(element, true)).toList();
 
-  bool _isValidForCurrency(ContactBase element) {
-    if (element.name.contains('Silent Payments')) return false;
-    if (element.name.contains('MWEB')) return false;
+  bool _isValidForCurrency(ContactBase element, bool isWalletContact) {
+    if (_currency == null) return true;
+    if (!element.name.contains('Active') &&
+        isWalletContact &&
+        (element.type == CryptoCurrency.btc || element.type == CryptoCurrency.ltc)) return false;
 
-    return _currency == null ||
-        element.type == _currency ||
+    return element.type == _currency ||
         (element.type.tag != null &&
             _currency?.tag != null &&
             element.type.tag == _currency?.tag) ||