From cb9f69074563e0e81199413f54ab9f279dc16033 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Fri, 7 Oct 2022 15:25:20 +0200
Subject: [PATCH 01/61] Add Native setTrustedDaemon and trustedDaemon functions
 and integrate them with their wallets

---
 cw_haven/ios/Classes/haven_api.cpp                 | 10 ++++++++++
 cw_haven/lib/api/signatures.dart                   |  6 +++++-
 cw_haven/lib/api/types.dart                        |  6 +++++-
 cw_haven/lib/api/wallet.dart                       | 12 ++++++++++++
 cw_haven/lib/haven_wallet.dart                     |  4 ++++
 cw_monero/ios/Classes/monero_api.cpp               | 10 ++++++++++
 cw_monero/ios/Classes/monero_api.h                 |  3 +++
 cw_monero/lib/api/signatures.dart                  |  6 +++++-
 cw_monero/lib/api/types.dart                       |  6 +++++-
 cw_monero/lib/api/wallet.dart                      | 14 +++++++++++++-
 cw_monero/lib/monero_wallet.dart                   |  4 ++++
 .../node_list/node_create_or_edit_view_model.dart  |  7 +++++++
 12 files changed, 83 insertions(+), 5 deletions(-)

diff --git a/cw_haven/ios/Classes/haven_api.cpp b/cw_haven/ios/Classes/haven_api.cpp
index c1013bf87..aecaf0016 100644
--- a/cw_haven/ios/Classes/haven_api.cpp
+++ b/cw_haven/ios/Classes/haven_api.cpp
@@ -927,6 +927,16 @@ extern "C"
         return static_cast<int32_t>(rates.size());
     }
 
+    void set_trusted_daemon(bool arg)
+    {
+        m_wallet->setTrustedDaemon(arg);
+    }
+
+    bool trusted_daemon()
+    {
+        return m_wallet->trustedDaemon();
+    }
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cw_haven/lib/api/signatures.dart b/cw_haven/lib/api/signatures.dart
index 9dd1c8dac..c98926c51 100644
--- a/cw_haven/lib/api/signatures.dart
+++ b/cw_haven/lib/api/signatures.dart
@@ -137,4 +137,8 @@ typedef get_rate = Pointer<Int64> Function();
 
 typedef size_of_rate = Int32 Function();
 
-typedef update_rate = Void Function();
\ No newline at end of file
+typedef update_rate = Void Function();
+
+typedef set_trusted_daemon = Void Function(Int8 trusted);
+
+typedef trusted_daemon = Int8 Function();
\ No newline at end of file
diff --git a/cw_haven/lib/api/types.dart b/cw_haven/lib/api/types.dart
index 878297501..81661afc2 100644
--- a/cw_haven/lib/api/types.dart
+++ b/cw_haven/lib/api/types.dart
@@ -135,4 +135,8 @@ typedef GetRate = Pointer<Int64> Function();
 
 typedef SizeOfRate = int Function();
 
-typedef UpdateRate = void Function();
\ No newline at end of file
+typedef UpdateRate = void Function();
+
+typedef SetTrustedDaemon = void Function(int);
+
+typedef TrustedDaemon = int Function();
\ No newline at end of file
diff --git a/cw_haven/lib/api/wallet.dart b/cw_haven/lib/api/wallet.dart
index 3370fd3e0..96e6e80a6 100644
--- a/cw_haven/lib/api/wallet.dart
+++ b/cw_haven/lib/api/wallet.dart
@@ -116,6 +116,14 @@ final rescanBlockchainAsyncNative = havenApi
     .lookup<NativeFunction<rescan_blockchain>>('rescan_blockchain')
     .asFunction<RescanBlockchainAsync>();
 
+final setTrustedDaemonNative = havenApi
+    .lookup<NativeFunction<set_trusted_daemon>>('set_trusted_daemon')
+    .asFunction<SetTrustedDaemon>();
+
+final trustedDaemonNative = havenApi
+    .lookup<NativeFunction<trusted_daemon>>('trusted_daemon')
+    .asFunction<TrustedDaemon>();
+
 int getSyncingHeight() => getSyncingHeightNative();
 
 bool isNeededToRefresh() => isNeededToRefreshNative() != 0;
@@ -346,3 +354,7 @@ Future<bool> isConnected() => compute(_isConnected, 0);
 Future<int> getNodeHeight() => compute(_getNodeHeight, 0);
 
 void rescanBlockchainAsync() => rescanBlockchainAsyncNative();
+
+Future setTrustedDaemon(bool trusted) async => setTrustedDaemonNative(_boolToInt(trusted));
+
+Future<bool> trustedDaemon() async => trustedDaemonNative() != 0;
diff --git a/cw_haven/lib/haven_wallet.dart b/cw_haven/lib/haven_wallet.dart
index c107d2f52..4a08a183a 100644
--- a/cw_haven/lib/haven_wallet.dart
+++ b/cw_haven/lib/haven_wallet.dart
@@ -390,4 +390,8 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
       print(e.toString());
     }
   }
+
+  void setTrustedDaemon(bool arg) => haven_wallet.setTrustedDaemon(arg);
+
+  Future<bool> trustedDaemon() async => haven_wallet.trustedDaemon();
 }
diff --git a/cw_monero/ios/Classes/monero_api.cpp b/cw_monero/ios/Classes/monero_api.cpp
index 6bb251dcf..117214295 100644
--- a/cw_monero/ios/Classes/monero_api.cpp
+++ b/cw_monero/ios/Classes/monero_api.cpp
@@ -783,6 +783,16 @@ extern "C"
         return strdup(get_current_wallet()->getSubaddressLabel(accountIndex, addressIndex).c_str());
     }
 
+    void set_trusted_daemon(bool arg)
+    {
+        m_wallet->setTrustedDaemon(arg);
+    }
+
+    bool trusted_daemon()
+    {
+        return m_wallet->trustedDaemon();
+    }
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cw_monero/ios/Classes/monero_api.h b/cw_monero/ios/Classes/monero_api.h
index 3e2ebcff2..74258ba4c 100644
--- a/cw_monero/ios/Classes/monero_api.h
+++ b/cw_monero/ios/Classes/monero_api.h
@@ -30,6 +30,9 @@ void set_refresh_from_block_height(uint64_t height);
 void set_recovering_from_seed(bool is_recovery);
 void store(char *path);
 
+void set_trusted_daemon(bool arg);
+bool trusted_daemon();
+
 #ifdef __cplusplus
 }
 #endif
\ No newline at end of file
diff --git a/cw_monero/lib/api/signatures.dart b/cw_monero/lib/api/signatures.dart
index 16f983480..3de4fd1a5 100644
--- a/cw_monero/lib/api/signatures.dart
+++ b/cw_monero/lib/api/signatures.dart
@@ -125,4 +125,8 @@ typedef rescan_blockchain = Void Function();
 
 typedef get_subaddress_label = Pointer<Utf8> Function(
     Int32 accountIndex,
-    Int32 addressIndex);
\ No newline at end of file
+    Int32 addressIndex);
+
+typedef set_trusted_daemon = Void Function(Int8 trusted);
+
+typedef trusted_daemon = Int8 Function();
\ No newline at end of file
diff --git a/cw_monero/lib/api/types.dart b/cw_monero/lib/api/types.dart
index 3438b89fc..e328b776a 100644
--- a/cw_monero/lib/api/types.dart
+++ b/cw_monero/lib/api/types.dart
@@ -123,4 +123,8 @@ typedef RescanBlockchainAsync = void Function();
 
 typedef GetSubaddressLabel = Pointer<Utf8> Function(
     int accountIndex,
-    int addressIndex);
\ No newline at end of file
+    int addressIndex);
+
+typedef SetTrustedDaemon = void Function(int);
+
+typedef TrustedDaemon = int Function();
\ No newline at end of file
diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart
index 9e84d7865..aeda971d8 100644
--- a/cw_monero/lib/api/wallet.dart
+++ b/cw_monero/lib/api/wallet.dart
@@ -120,6 +120,14 @@ final getSubaddressLabelNative = moneroApi
     .lookup<NativeFunction<get_subaddress_label>>('get_subaddress_label')
     .asFunction<GetSubaddressLabel>();
 
+final setTrustedDaemonNative = moneroApi
+    .lookup<NativeFunction<set_trusted_daemon>>('set_trusted_daemon')
+    .asFunction<SetTrustedDaemon>();
+
+final trustedDaemonNative = moneroApi
+    .lookup<NativeFunction<trusted_daemon>>('trusted_daemon')
+    .asFunction<TrustedDaemon>();
+
 int getSyncingHeight() => getSyncingHeightNative();
 
 bool isNeededToRefresh() => isNeededToRefreshNative() != 0;
@@ -353,4 +361,8 @@ void rescanBlockchainAsync() => rescanBlockchainAsyncNative();
 
 String getSubaddressLabel(int accountIndex, int addressIndex) {
   return convertUTF8ToString(pointer: getSubaddressLabelNative(accountIndex, addressIndex));
-}
\ No newline at end of file
+}
+
+Future setTrustedDaemon(bool trusted) async => setTrustedDaemonNative(_boolToInt(trusted));
+
+Future<bool> trustedDaemon() async => trustedDaemonNative() != 0;
\ No newline at end of file
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index 175bd96f5..772df420c 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -427,4 +427,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
       print(e.toString());
     }
   }
+
+  void setTrustedDaemon(bool arg) => monero_wallet.setTrustedDaemon(arg);
+
+  Future<bool> trustedDaemon() async => monero_wallet.trustedDaemon();
 }
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 c14bdda5e..4b7e0ddc9 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
@@ -1,4 +1,6 @@
 import 'package:cake_wallet/core/execution_state.dart';
+import 'package:cw_haven/haven_wallet.dart';
+import 'package:cw_monero/monero_wallet.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cw_core/wallet_base.dart';
@@ -78,6 +80,11 @@ abstract class NodeCreateOrEditViewModelBase with Store {
       final node =
           Node(uri: uri, type: _wallet.type, login: login, password: password,
               useSSL: useSSL, trusted: trusted);
+      if (_wallet.type == WalletType.monero) {
+        (_wallet as MoneroWallet).setTrustedDaemon(trusted);
+      } else if (_wallet.type == WalletType.haven) {
+        (_wallet as HavenWallet).setTrustedDaemon(trusted);
+      }
       await _nodeSource.add(node);
       state = ExecutedSuccessfullyState();
     } catch (e) {

From b0e188c0bd154ca9b95658a74d9369b0274bcc31 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Fri, 7 Oct 2022 20:06:33 +0200
Subject: [PATCH 02/61] Remove unused getter

---
 cw_core/lib/node.dart | 2 --
 1 file changed, 2 deletions(-)

diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart
index dd5969b99..dca429482 100644
--- a/cw_core/lib/node.dart
+++ b/cw_core/lib/node.dart
@@ -57,8 +57,6 @@ class Node extends HiveObject with Keyable {
 
   bool get isSSL => useSSL ?? false;
 
-  bool get isTrusted => trusted ?? false;
-
   Uri get uri {
     switch (type) {
       case WalletType.monero:

From 1eb9e65617e85ef2d70d7c324865c8cde8137565 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Thu, 20 Oct 2022 20:24:01 +0200
Subject: [PATCH 03/61] Set trusted daemon after node connection

---
 cw_haven/lib/haven_wallet.dart                             | 6 ++----
 cw_monero/lib/monero_wallet.dart                           | 6 ++----
 .../node_list/node_create_or_edit_view_model.dart          | 7 -------
 3 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/cw_haven/lib/haven_wallet.dart b/cw_haven/lib/haven_wallet.dart
index 00d37ee08..14ff2f88e 100644
--- a/cw_haven/lib/haven_wallet.dart
+++ b/cw_haven/lib/haven_wallet.dart
@@ -121,6 +121,8 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
           password: node.password,
           useSSL: node.useSSL ?? false,
           isLightWallet: false); // FIXME: hardcoded value
+
+      haven_wallet.setTrustedDaemon(node.trusted);
       syncStatus = ConnectedSyncStatus();
     } catch (e) {
       syncStatus = FailedSyncStatus();
@@ -394,8 +396,4 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
       print(e.toString());
     }
   }
-
-  void setTrustedDaemon(bool arg) => haven_wallet.setTrustedDaemon(arg);
-
-  Future<bool> trustedDaemon() async => haven_wallet.trustedDaemon();
 }
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index ff0104015..86a0358f0 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -136,6 +136,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
           password: node.password,
           useSSL: node.isSSL,
           isLightWallet: false); // FIXME: hardcoded value
+
+      monero_wallet.setTrustedDaemon(node.trusted);
       syncStatus = ConnectedSyncStatus();
     } catch (e) {
       syncStatus = FailedSyncStatus();
@@ -432,8 +434,4 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
       print(e.toString());
     }
   }
-
-  void setTrustedDaemon(bool arg) => monero_wallet.setTrustedDaemon(arg);
-
-  Future<bool> trustedDaemon() async => monero_wallet.trustedDaemon();
 }
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 7b481f356..e24692059 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
@@ -1,6 +1,4 @@
 import 'package:cake_wallet/core/execution_state.dart';
-import 'package:cw_haven/haven_wallet.dart';
-import 'package:cw_monero/monero_wallet.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cw_core/wallet_base.dart';
@@ -84,11 +82,6 @@ abstract class NodeCreateOrEditViewModelBase with Store {
       final node =
           Node(uri: uri, type: _wallet.type, login: login, password: password,
               useSSL: useSSL, trusted: trusted);
-      if (_wallet.type == WalletType.monero) {
-        (_wallet as MoneroWallet).setTrustedDaemon(trusted);
-      } else if (_wallet.type == WalletType.haven) {
-        (_wallet as HavenWallet).setTrustedDaemon(trusted);
-      }
       await _nodeSource.add(node);
       state = ExecutedSuccessfullyState();
     } catch (e) {

From 7d92a964c7b8dc369249a9507790b4f30b538099 Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Wed, 9 Nov 2022 12:14:21 +0200
Subject: [PATCH 04/61] Change synchronization status text

 changed the status from "Starting sync" to "Attempting sync".
---
 cw_bitcoin/lib/electrum_wallet.dart | 2 +-
 cw_core/lib/sync_status.dart        | 2 +-
 cw_haven/lib/haven_wallet.dart      | 2 +-
 cw_monero/lib/monero_wallet.dart    | 2 +-
 lib/core/sync_status_title.dart     | 4 ++--
 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_hi.arb           | 1 +
 res/values/strings_hr.arb           | 1 +
 res/values/strings_it.arb           | 1 +
 res/values/strings_ja.arb           | 1 +
 res/values/strings_ko.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_uk.arb           | 1 +
 res/values/strings_zh.arb           | 1 +
 20 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 7abed8c07..fad546d90 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -129,7 +129,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
   @override
   Future<void> startSync() async {
     try {
-      syncStatus = StartingSyncStatus();
+      syncStatus = AttemptingSyncStatus();
       await walletAddresses.discoverAddresses();
       await updateTransactions();
       _subscribeForUpdates();
diff --git a/cw_core/lib/sync_status.dart b/cw_core/lib/sync_status.dart
index fabec67c8..4983967d0 100644
--- a/cw_core/lib/sync_status.dart
+++ b/cw_core/lib/sync_status.dart
@@ -28,7 +28,7 @@ class NotConnectedSyncStatus extends SyncStatus {
   double progress() => 0.0;
 }
 
-class StartingSyncStatus extends SyncStatus {
+class AttemptingSyncStatus extends SyncStatus {
   @override
   double progress() => 0.0;
 }
diff --git a/cw_haven/lib/haven_wallet.dart b/cw_haven/lib/haven_wallet.dart
index 4f360bdff..cf7c9dcdd 100644
--- a/cw_haven/lib/haven_wallet.dart
+++ b/cw_haven/lib/haven_wallet.dart
@@ -135,7 +135,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
     } catch (_) {}
 
     try {
-      syncStatus = StartingSyncStatus();
+      syncStatus = AttemptingSyncStatus();
       haven_wallet.startRefresh();
       _setListeners();
       _listener?.start();
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index 404d8bad0..69c61b83a 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -150,7 +150,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
     } catch (_) {}
 
     try {
-      syncStatus = StartingSyncStatus();
+      syncStatus = AttemptingSyncStatus();
       monero_wallet.startRefresh();
       _setListeners();
       _listener?.start();
diff --git a/lib/core/sync_status_title.dart b/lib/core/sync_status_title.dart
index e46ec2490..66094de2b 100644
--- a/lib/core/sync_status_title.dart
+++ b/lib/core/sync_status_title.dart
@@ -14,8 +14,8 @@ String syncStatusTitle(SyncStatus syncStatus) {
     return S.current.sync_status_not_connected;
   }
 
-  if (syncStatus is StartingSyncStatus) {
-    return S.current.sync_status_starting_sync;
+  if (syncStatus is AttemptingSyncStatus) {
+    return S.current.sync_status_attempting_sync;
   }
 
   if (syncStatus is FailedSyncStatus) {
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 685d817d5..15ab8f02a 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "GETRENNT",
   "sync_status_connecting" : "VERBINDEN",
   "sync_status_connected" : "VERBUNDEN",
+  "sync_status_attempting_sync" : "SYNC VERSUCHEN",
 
 
   "transaction_priority_slow" : "Langsam",
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 877d09231..7dd18dee6 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "DISCONNECTED",
   "sync_status_connecting" : "CONNECTING",
   "sync_status_connected" : "CONNECTED",
+  "sync_status_attempting_sync" : "ATTEMPTING SYNC",
 
 
   "transaction_priority_slow" : "Slow",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 505f3ffa8..ee368c75f 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "DESCONECTADO",
   "sync_status_connecting" : "CONECTANDO",
   "sync_status_connected" : "CONECTADO",
+  "sync_status_attempting_sync" : "INTENTAR SINCRONIZAR",
 
 
   "transaction_priority_slow" : "Lento",
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index 941016c0b..c99e7c552 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -354,6 +354,7 @@
   "sync_status_failed_connect" : "DÉCONNECTÉ",
   "sync_status_connecting" : "CONNEXION EN COURS",
   "sync_status_connected" : "CONNECTÉ",
+  "sync_status_attempting_sync" : "TENTATIVE DE SYNCHRONISATION",
 
 
   "transaction_priority_slow" : "Lent",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index 7faa06f7f..15dc9d1ed 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "डिस्कनेक्ट किया गया",
   "sync_status_connecting" : "कनेक्ट",
   "sync_status_connected" : "जुड़े हुए",
+  "sync_status_attempting_sync" : "सिंक करने का प्रयास",
 
 
   "transaction_priority_slow" : "धीरे",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 4fa77948a..76c67b965 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "ISKLJUČENO",
   "sync_status_connecting" : "SPAJANJE",
   "sync_status_connected" : "SPOJENO",
+  "sync_status_attempting_sync" : "POKUŠAJ SINKRONIZACIJE",
 
 
   "transaction_priority_slow" : "Sporo",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index 9a42a588b..b62f799d5 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "DISCONNESSO",
   "sync_status_connecting" : "CONNESSIONE",
   "sync_status_connected" : "CONNESSO",
+  "sync_status_attempting_sync" : "TENTATIVO DI SINCRONIZZAZIONE",
 
 
   "transaction_priority_slow" : "Bassa",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index c1d0de4e3..9f480a49f 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "切断されました",
   "sync_status_connecting" : "接続中",
   "sync_status_connected" : "接続済み",
+  "sync_status_attempting_sync" : "同期を試みています",
 
 
   "transaction_priority_slow" : "スロー",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 127aa949e..ae8fe8c23 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "연결 해제",
   "sync_status_connecting" : "연결 중",
   "sync_status_connected" : "연결됨",
+  "sync_status_attempting_sync" : "동기화 시도 중",
 
 
   "transaction_priority_slow" : "느린",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index fa748b552..5253f8b24 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "LOSGEKOPPELD",
   "sync_status_connecting" : "AANSLUITING",
   "sync_status_connected" : "VERBONDEN",
+  "sync_status_attempting_sync" : "SYNCHRONISATIE PROBEREN",
 
 
   "transaction_priority_slow" : "Langzaam",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 454fe9717..ada641aac 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "NIEPOWIĄZANY",
   "sync_status_connecting" : "ZŁĄCZONY",
   "sync_status_connected" : "POŁĄCZONY",
+  "sync_status_attempting_sync" : "PRÓBA SYNCHRONIZACJI",
 
 
   "transaction_priority_slow" : "Powolny",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 04a0a3ff2..edd75e704 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "DESCONECTADO",
   "sync_status_connecting" : "CONECTANDO",
   "sync_status_connected" : "CONECTADO",
+  "sync_status_attempting_sync" : "TENTANDO SINCRONIZAR",
 
 
   "transaction_priority_slow" : "Lenta",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index 632b0990c..64d27a197 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "ОТКЛЮЧЕНО",
   "sync_status_connecting" : "ПОДКЛЮЧЕНИЕ",
   "sync_status_connected" : "ПОДКЛЮЧЕНО",
+  "sync_status_attempting_sync" : "ПОПЫТКА СИНХРОНИЗАЦИИ",
 
 
   "transaction_priority_slow" : "Медленный",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 5e0f0d18a..637cc779e 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -355,6 +355,7 @@
   "sync_status_failed_connect" : "ВІДКЛЮЧЕНО",
   "sync_status_connecting" : "ПІДКЛЮЧЕННЯ",
   "sync_status_connected" : "ПІДКЛЮЧЕНО",
+  "sync_status_attempting_sync" : "СПРОБА СИНХРОНІЗАЦІЇ",
 
 
   "transaction_priority_slow" : "Повільний",
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index c46d07d59..07e800466 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -356,6 +356,7 @@
   "sync_status_failed_connect" : "断线",
   "sync_status_connecting" : "连接中",
   "sync_status_connected" : "已连接",
+  "sync_status_attempting_sync" : "嘗試同步",
 
 
   "transaction_priority_slow" : "慢速",

From 7d49dc47616559b8e94f72c54abd50a6eb9ea341 Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Thu, 10 Nov 2022 20:08:52 +0200
Subject: [PATCH 05/61] rework confirm sending screen for cake pay (#603)

* rework confirm sending allert

* remove confirm_modal.dart

* fix  text color and buttons size
---
 lib/di.dart                                   |   1 +
 .../cards/ionia_buy_card_detail_page.dart     |  84 +++-------
 .../screens/ionia/widgets/confirm_modal.dart  | 149 ------------------
 .../send/widgets/confirm_sending_alert.dart   |  86 +++++++++-
 lib/src/widgets/base_alert_dialog.dart        |  98 +++++++-----
 .../ionia_purchase_merch_view_model.dart      |   4 +
 6 files changed, 169 insertions(+), 253 deletions(-)
 delete mode 100644 lib/src/screens/ionia/widgets/confirm_modal.dart

diff --git a/lib/di.dart b/lib/di.dart
index 7ce2ff6d9..90549cf6f 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -701,6 +701,7 @@ Future setup(
       ioniaAnyPayService: getIt.get<IoniaAnyPay>(), 
       amount: amount,
       ioniaMerchant: merchant,
+      sendViewModel: getIt.get<SendViewModel>()
     );
   });
 
diff --git a/lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart b/lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart
index f3b12e65b..4b9f0a220 100644
--- a/lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart
+++ b/lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart
@@ -3,7 +3,6 @@ import 'package:cake_wallet/ionia/ionia_merchant.dart';
 import 'package:cake_wallet/ionia/ionia_tip.dart';
 import 'package:cake_wallet/palette.dart';
 import 'package:cake_wallet/routes.dart';
-import 'package:cake_wallet/src/screens/ionia/widgets/confirm_modal.dart';
 import 'package:cake_wallet/src/screens/ionia/widgets/ionia_alert_model.dart';
 import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart';
 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
@@ -18,6 +17,7 @@ import 'package:cake_wallet/generated/i18n.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart';
 
 class IoniaBuyGiftCardDetailPage extends BasePage {
   IoniaBuyGiftCardDetailPage(this.ioniaPurchaseViewModel);
@@ -295,73 +295,35 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
     
     final amount = ioniaPurchaseViewModel.invoice!.totalAmount;
     final addresses = ioniaPurchaseViewModel.invoice!.outAddresses;
+    ioniaPurchaseViewModel.sendViewModel.outputs.first.setCryptoAmount(amount);
+    ioniaPurchaseViewModel.sendViewModel.outputs.first.address = addresses.first;
 
     await showPopUp<void>(
       context: context,
       builder: (_) {
-        return IoniaConfirmModal(
+        return ConfirmSendingAlert(
             alertTitle: S.of(context).confirm_sending,
-            alertContent: Container(
-                height: 200,
-                padding: EdgeInsets.all(15),
-                child: Column(children: [
-                  Row(children: [
-                    Text(S.of(context).payment_id,
-                        textAlign: TextAlign.center,
-                        style: TextStyle(
-                            fontSize: 16,
-                            fontWeight: FontWeight.w400,
-                            color: PaletteDark.pigeonBlue,
-                            decoration: TextDecoration.none)),
-                    Text(ioniaPurchaseViewModel.invoice!.paymentId,
-                        style: TextStyle(
-                            fontSize: 16,
-                            fontWeight: FontWeight.w400,
-                            color: PaletteDark.pigeonBlue,
-                            decoration: TextDecoration.none))
-                  ], mainAxisAlignment: MainAxisAlignment.spaceBetween),
-                  SizedBox(height: 10),
-                  Row(children: [
-                    Text(S.of(context).amount,
-                        textAlign: TextAlign.center,
-                        style: TextStyle(
-                            fontSize: 16,
-                            fontWeight: FontWeight.w400,
-                            color: PaletteDark.pigeonBlue,
-                            decoration: TextDecoration.none)),
-                    Text('$amount ${ioniaPurchaseViewModel.invoice!.chain}',
-                        style: TextStyle(
-                            fontSize: 16,
-                            fontWeight: FontWeight.w400,
-                            color: PaletteDark.pigeonBlue,
-                            decoration: TextDecoration.none))
-                  ], mainAxisAlignment: MainAxisAlignment.spaceBetween),
-                  SizedBox(height: 25),
-                  Row(children: [
-                    Text(S.of(context).recipient_address,
-                        style: TextStyle(
-                            fontSize: 16,
-                            fontWeight: FontWeight.w400,
-                            color: PaletteDark.pigeonBlue,
-                            decoration: TextDecoration.none))
-                  ], mainAxisAlignment: MainAxisAlignment.center),
-                  Expanded(
-                      child: ListView.builder(
-                          itemBuilder: (_, int index) {
-                            return Text(addresses[index],
-                                style: TextStyle(
-                                    fontSize: 14,
-                                    fontWeight: FontWeight.w400,
-                                    color: PaletteDark.pigeonBlue,
-                                    decoration: TextDecoration.none));
-                          },
-                          itemCount: addresses.length,
-                          physics: NeverScrollableScrollPhysics()))
-                ])),
+            paymentId: S.of(context).payment_id,
+            paymentIdValue: ioniaPurchaseViewModel.invoice!.paymentId,
+            amount: S.of(context).send_amount,
+            amountValue: '$amount ${ioniaPurchaseViewModel.invoice!.chain}',
+            fiatAmountValue:
+            '~ ${ioniaPurchaseViewModel.sendViewModel.outputs.first.fiatAmount} '
+                '${ioniaPurchaseViewModel.sendViewModel.fiat.title}',
+            fee: S.of(context).send_fee,
+            feeValue:
+            '${ioniaPurchaseViewModel.sendViewModel.outputs.first.estimatedFee} '
+                '${ioniaPurchaseViewModel.invoice!.chain}',
+            feeFiatAmount:
+            '${ioniaPurchaseViewModel.sendViewModel.outputs.first.estimatedFeeFiatAmount} '
+                '${ioniaPurchaseViewModel.sendViewModel.fiat.title}',
+            outputs: ioniaPurchaseViewModel.sendViewModel.outputs,
             rightButtonText: S.of(context).ok,
             leftButtonText: S.of(context).cancel,
-            leftActionColor: Color(0xffFF6600),
-            rightActionColor: Theme.of(context).accentTextTheme!.bodyText1!.color!,
+            alertLeftActionButtonTextColor: Colors.white,
+            alertRightActionButtonTextColor: Colors.white,
+            alertLeftActionButtonColor: Palette.brightOrange,
+            alertRightActionButtonColor: Theme.of(context).textTheme!.subtitle2!.color,
             actionRightButton: () async {
               Navigator.of(context).pop();
               await ioniaPurchaseViewModel.commitPaymentInvoice();
diff --git a/lib/src/screens/ionia/widgets/confirm_modal.dart b/lib/src/screens/ionia/widgets/confirm_modal.dart
deleted file mode 100644
index cfc9a1cf1..000000000
--- a/lib/src/screens/ionia/widgets/confirm_modal.dart
+++ /dev/null
@@ -1,149 +0,0 @@
-import 'dart:ui';
-
-import 'package:cake_wallet/palette.dart';
-import 'package:flutter/material.dart';
-
-class IoniaConfirmModal extends StatelessWidget {
-  IoniaConfirmModal({
-    required this.alertTitle,
-    required this.alertContent,
-    required this.leftButtonText,
-    required this.rightButtonText,
-    required this.actionLeftButton,
-    required this.actionRightButton,
-    required this.leftActionColor,
-    required this.rightActionColor,
-    this.hideActions = false,
-  });
-
-  final String alertTitle;
-  final Widget alertContent;
-  final String leftButtonText;
-  final String rightButtonText;
-  final VoidCallback actionLeftButton;
-  final VoidCallback actionRightButton;
-  final Color leftActionColor;
-  final Color rightActionColor;
-  final bool hideActions;
-
-  Widget actionButtons(BuildContext context) {
-    return Row(
-      mainAxisSize: MainAxisSize.max,
-      children: <Widget>[
-        IoniaActionButton(
-          buttonText: leftButtonText,
-          action: actionLeftButton,
-          backgoundColor: leftActionColor,
-        ),
-        Container(
-          width: 1,
-          height: 52,
-          color: Theme.of(context).dividerColor,
-        ),
-        IoniaActionButton(
-          buttonText: rightButtonText,
-          action: actionRightButton,
-          backgoundColor: rightActionColor,
-        ),
-      ],
-    );
-  }
-
-  Widget title(BuildContext context) {
-    return Text(
-      alertTitle,
-      textAlign: TextAlign.center,
-      style: TextStyle(
-        fontSize: 20,
-        fontFamily: 'Lato',
-        fontWeight: FontWeight.w600,
-        color: Theme.of(context).primaryTextTheme!.headline6!.color!,
-        decoration: TextDecoration.none,
-      ),
-    );
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return Container(
-      color: Colors.transparent,
-      child: BackdropFilter(
-        filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
-        child: Container(
-          decoration: BoxDecoration(color: PaletteDark.darkNightBlue.withOpacity(0.75)),
-          child: Center(
-            child: GestureDetector(
-              onTap: () => null,
-              child: ClipRRect(
-                borderRadius: BorderRadius.all(Radius.circular(30)),
-                child: Container(
-                  width: 327,
-                  color: Theme.of(context).accentTextTheme!.headline6!.decorationColor!,
-                  child: Column(
-                    mainAxisSize: MainAxisSize.min,
-                    children: [
-                      Padding(
-                        padding: EdgeInsets.fromLTRB(24, 20, 24, 0),
-                        child: title(context),
-                      ),
-                      Padding(
-                        padding: EdgeInsets.only(top: 16, bottom: 8),
-                        child: Container(
-                          height: 1,
-                          color: Theme.of(context).dividerColor,
-                        ),
-                      ),
-                      alertContent,
-                      actionButtons(context),
-                    ],
-                  ),
-                ),
-              ),
-            ),
-          ),
-        ),
-      ),
-    );
-  }
-}
-
-class IoniaActionButton extends StatelessWidget {
-  const IoniaActionButton({
-    required this.buttonText,
-    required this.action,
-    required this.backgoundColor,
-  });
-
-  final String buttonText;
-  final VoidCallback action;
-  final Color backgoundColor;
-
-  @override
-  Widget build(BuildContext context) {
-    return Flexible(
-        child: Container(
-      height: 52,
-      padding: EdgeInsets.only(left: 6, right: 6),
-      color: backgoundColor,
-      child: ButtonTheme(
-        minWidth: double.infinity,
-        child: TextButton(
-            onPressed: action,
-            // FIX-ME: ignored highlightColor and splashColor
-            //highlightColor: Colors.transparent,
-            //splashColor: Colors.transparent,
-            child: Text(
-              buttonText,
-              textAlign: TextAlign.center,
-              style: TextStyle(
-                fontSize: 15,
-                fontFamily: 'Lato',
-                fontWeight: FontWeight.w600,
-                color: backgoundColor != null ? Colors.white : Theme.of(context).primaryTextTheme!.bodyText2!.backgroundColor!,
-                decoration: TextDecoration.none,
-              ),
-            )),
-      ),
-    ));
-  }
-}
diff --git a/lib/src/screens/send/widgets/confirm_sending_alert.dart b/lib/src/screens/send/widgets/confirm_sending_alert.dart
index 317303442..a034d801e 100644
--- a/lib/src/screens/send/widgets/confirm_sending_alert.dart
+++ b/lib/src/screens/send/widgets/confirm_sending_alert.dart
@@ -4,10 +4,13 @@ import 'package:flutter/material.dart';
 import 'package:cake_wallet/src/widgets/base_alert_dialog.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/src/widgets/cake_scrollbar.dart';
+import 'package:flutter/scheduler.dart';
 
 class ConfirmSendingAlert extends BaseAlertDialog {
   ConfirmSendingAlert({
     required this.alertTitle,
+    this.paymentId,
+    this.paymentIdValue,
     required this.amount,
     required this.amountValue,
     required this.fiatAmountValue,
@@ -19,9 +22,15 @@ class ConfirmSendingAlert extends BaseAlertDialog {
     required this.rightButtonText,
     required this.actionLeftButton,
     required this.actionRightButton,
-    this.alertBarrierDismissible = true});
+    this.alertBarrierDismissible = true,
+    this.alertLeftActionButtonTextColor,
+    this.alertRightActionButtonTextColor,
+    this.alertLeftActionButtonColor,
+    this.alertRightActionButtonColor});
 
   final String alertTitle;
+  final String? paymentId;
+  final String? paymentIdValue;
   final String amount;
   final String amountValue;
   final String fiatAmountValue;
@@ -34,6 +43,10 @@ class ConfirmSendingAlert extends BaseAlertDialog {
   final VoidCallback actionLeftButton;
   final VoidCallback actionRightButton;
   final bool alertBarrierDismissible;
+  final Color? alertLeftActionButtonTextColor;
+  final Color? alertRightActionButtonTextColor;
+  final Color? alertLeftActionButtonColor;
+  final Color? alertRightActionButtonColor;
 
   @override
   String get titleText => alertTitle;
@@ -56,8 +69,22 @@ class ConfirmSendingAlert extends BaseAlertDialog {
   @override
   bool get barrierDismissible => alertBarrierDismissible;
 
+  @override
+  Color? get leftActionButtonTextColor => alertLeftActionButtonTextColor;
+
+  @override
+  Color? get rightActionButtonTextColor => alertRightActionButtonTextColor;
+
+  @override
+  Color? get leftActionButtonColor => alertLeftActionButtonColor;
+
+  @override
+  Color? get rightActionButtonColor => alertRightActionButtonColor;
+
   @override
   Widget content(BuildContext context) => ConfirmSendingAlertContent(
+      paymentId: paymentId,
+      paymentIdValue: paymentIdValue,
       amount: amount,
       amountValue: amountValue,
       fiatAmountValue: fiatAmountValue,
@@ -70,6 +97,8 @@ class ConfirmSendingAlert extends BaseAlertDialog {
 
 class ConfirmSendingAlertContent extends StatefulWidget {
   ConfirmSendingAlertContent({
+    this.paymentId,
+    this.paymentIdValue,
     required this.amount,
     required this.amountValue,
     required this.fiatAmountValue,
@@ -78,6 +107,8 @@ class ConfirmSendingAlertContent extends StatefulWidget {
     required this.feeFiatAmount,
     required this.outputs});
 
+  final String? paymentId;
+  final String? paymentIdValue;
   final String amount;
   final String amountValue;
   final String fiatAmountValue;
@@ -88,6 +119,8 @@ class ConfirmSendingAlertContent extends StatefulWidget {
 
   @override
   ConfirmSendingAlertContentState createState() => ConfirmSendingAlertContentState(
+    paymentId: paymentId,
+    paymentIdValue: paymentIdValue,
     amount: amount,
     amountValue: amountValue,
     fiatAmountValue: fiatAmountValue,
@@ -100,6 +133,8 @@ class ConfirmSendingAlertContent extends StatefulWidget {
 
 class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent> {
   ConfirmSendingAlertContentState({
+    this.paymentId,
+    this.paymentIdValue,
     required this.amount,
     required this.amountValue,
     required this.fiatAmountValue,
@@ -115,6 +150,8 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
         : S.current.recipient_address;
   }
 
+  final String? paymentId;
+  final String? paymentIdValue;
   final String amount;
   final String amountValue;
   final String fiatAmountValue;
@@ -129,6 +166,7 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
   double fromTop = 0;
   String recipientTitle;
   int itemCount;
+  bool showScrollbar = false;
 
   @override
   Widget build(BuildContext context) {
@@ -140,6 +178,12 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
       setState(() {});
     });
 
+    SchedulerBinding.instance.addPostFrameCallback((_) {
+      setState(() {
+        showScrollbar = controller.position.maxScrollExtent > 0;
+      });
+    });
+
     return Stack(
       alignment: Alignment.center,
       clipBehavior: Clip.none,
@@ -150,6 +194,44 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
                 controller: controller,
                 child: Column(
                   children: <Widget>[
+                    if (paymentIdValue != null && paymentId != null)
+                      Padding(
+                        padding: EdgeInsets.only(bottom: 32),
+                        child: Row(
+                          mainAxisSize: MainAxisSize.max,
+                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: <Widget>[
+                            Text(
+                              paymentId!,
+                              style: TextStyle(
+                                fontSize: 16,
+                                fontWeight: FontWeight.normal,
+                                fontFamily: 'Lato',
+                                color: Theme.of(context).primaryTextTheme!
+                                    .headline6!.color!,
+                                decoration: TextDecoration.none,
+                              ),
+                            ),
+                            Column(
+                              crossAxisAlignment: CrossAxisAlignment.end,
+                              children: [
+                                Text(
+                                  paymentIdValue!,
+                                  style: TextStyle(
+                                    fontSize: 18,
+                                    fontWeight: FontWeight.w600,
+                                    fontFamily: 'Lato',
+                                    color: Theme.of(context).primaryTextTheme!
+                                        .headline6!.color!,
+                                    decoration: TextDecoration.none,
+                                  ),
+                                ),
+                              ],
+                            )
+                          ],
+                        ),
+                      ),
                     Row(
                       mainAxisSize: MainAxisSize.max,
                       mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -365,7 +447,7 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
                 )
             )
         ),
-        if (itemCount > 1) CakeScrollbar(
+        if (showScrollbar) CakeScrollbar(
               backgroundHeight: backgroundHeight,
               thumbHeight: thumbHeight,
               fromTop: fromTop,
diff --git a/lib/src/widgets/base_alert_dialog.dart b/lib/src/widgets/base_alert_dialog.dart
index 7713284f2..70370e227 100644
--- a/lib/src/widgets/base_alert_dialog.dart
+++ b/lib/src/widgets/base_alert_dialog.dart
@@ -11,6 +11,10 @@ class BaseAlertDialog extends StatelessWidget {
   VoidCallback get actionLeft => () {};
   VoidCallback get actionRight => () {};
   bool get barrierDismissible => true;
+  Color? get leftActionButtonTextColor => null;
+  Color? get rightActionButtonTextColor => null;
+  Color? get leftActionButtonColor => null;
+  Color? get rightActionButtonColor => null;
 
   Widget title(BuildContext context) {
     return Text(
@@ -45,52 +49,64 @@ class BaseAlertDialog extends StatelessWidget {
       height: 52,
       child: Row(
       mainAxisSize: MainAxisSize.max,
-      mainAxisAlignment: MainAxisAlignment.center,
+      crossAxisAlignment: CrossAxisAlignment.stretch,
       children: <Widget>[
-        Flexible(
-          child: Container(
-            width: double.infinity,
-            color: Theme.of(context).accentTextTheme!.bodyText1!.decorationColor!,
-            child: TextButton(
-                onPressed: actionLeft,
-                child: Text(
-                  leftActionButtonText,
-                  textAlign: TextAlign.center,
-                  style: TextStyle(
-                    fontSize: 15,
-                    fontFamily: 'Lato',
-                    fontWeight: FontWeight.w600,
-                    color: Theme.of(context).primaryTextTheme!.bodyText1!.backgroundColor!,
-                    decoration: TextDecoration.none,
-                  ),
-                )),
-          ),
-        ),
+            Expanded(
+              child: TextButton(
+                  onPressed: actionLeft,
+                  style: TextButton.styleFrom(
+                      backgroundColor: leftActionButtonColor ??
+                          Theme.of(context)
+                              .accentTextTheme!
+                              .bodyText1!
+                              .decorationColor!,
+                      shape: const RoundedRectangleBorder(
+                          borderRadius: BorderRadius.all(Radius.zero))),
+                  child: Text(
+                    leftActionButtonText,
+                    textAlign: TextAlign.center,
+                    style: TextStyle(
+                      fontSize: 15,
+                      fontFamily: 'Lato',
+                      fontWeight: FontWeight.w600,
+                      color: leftActionButtonTextColor ??
+                          Theme.of(context).primaryTextTheme!
+                              .bodyText1!.backgroundColor!,
+                      decoration: TextDecoration.none,
+                    ),
+                  )),
+            ),
         Container(
           width: 1,
           color: Theme.of(context).dividerColor,
         ),
-        Flexible(
-          child: Container(
-            width: double.infinity,
-            color: Theme.of(context).accentTextTheme!.bodyText2!.backgroundColor!,
-            child: TextButton(
-                onPressed: actionRight,
-                child: Text(
-                  rightActionButtonText,
-                  textAlign: TextAlign.center,
-                  style: TextStyle(
-                    fontSize: 15,
-                    fontFamily: 'Lato',
-                    fontWeight: FontWeight.w600,
-                    color: Theme.of(context).primaryTextTheme!.bodyText2!.backgroundColor!,
-                    decoration: TextDecoration.none,
-                  ),
-                )),
-          ),
-        ),
-      ],
-    ));
+            Expanded(
+              child: TextButton(
+                  onPressed: actionRight,
+                  style: TextButton.styleFrom(
+                      backgroundColor: rightActionButtonColor ??
+                          Theme.of(context).accentTextTheme!
+                              .bodyText2!.backgroundColor!,
+                      shape: const RoundedRectangleBorder(
+                          borderRadius: BorderRadius.all(Radius.zero))),
+                  child: Text(
+                    rightActionButtonText,
+                    textAlign: TextAlign.center,
+                    style: TextStyle(
+                      fontSize: 15,
+                      fontFamily: 'Lato',
+                      fontWeight: FontWeight.w600,
+                      color: rightActionButtonTextColor ??
+                          Theme.of(context)
+                              .primaryTextTheme!
+                              .bodyText2!
+                              .backgroundColor!,
+                      decoration: TextDecoration.none,
+                    ),
+                  )),
+            ),
+          ],
+        ));
   }
 
   @override
diff --git a/lib/view_model/ionia/ionia_purchase_merch_view_model.dart b/lib/view_model/ionia/ionia_purchase_merch_view_model.dart
index da71f31fa..df6a23718 100644
--- a/lib/view_model/ionia/ionia_purchase_merch_view_model.dart
+++ b/lib/view_model/ionia/ionia_purchase_merch_view_model.dart
@@ -7,6 +7,7 @@ import 'package:cake_wallet/ionia/ionia_anypay.dart';
 import 'package:cake_wallet/ionia/ionia_merchant.dart';
 import 'package:cake_wallet/ionia/ionia_tip.dart';
 import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
+import 'package:cake_wallet/view_model/send/send_view_model.dart';
 
 part 'ionia_purchase_merch_view_model.g.dart';
 
@@ -17,6 +18,7 @@ abstract class IoniaMerchPurchaseViewModelBase with Store {
     required this.ioniaAnyPayService,
     required this.amount,
     required this.ioniaMerchant,
+    required this.sendViewModel,
   }) : tipAmount = 0.0,
         percentage = 0.0,
         invoiceCreationState = InitialExecutionState(),
@@ -40,6 +42,8 @@ abstract class IoniaMerchPurchaseViewModelBase with Store {
 
   final IoniaMerchant ioniaMerchant;
 
+  final SendViewModel sendViewModel;
+
   final IoniaAnyPay ioniaAnyPayService;
 
   IoniaAnyPayPaymentInfo? paymentInfo;

From 1efced7607dea0679971ec95877cfdd7847121a4 Mon Sep 17 00:00:00 2001
From: M <m@cakewallet.com>
Date: Thu, 10 Nov 2022 13:11:10 -0500
Subject: [PATCH 06/61] Update build version for cake wallet to 132; monero.com
 28

---
 scripts/android/app_env.sh | 4 ++--
 scripts/ios/app_env.sh     | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index b9ca9f98b..54ad0b4d4 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -15,13 +15,13 @@ APP_ANDROID_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
 MONERO_COM_VERSION="1.2.0"
-MONERO_COM_BUILD_NUMBER=26
+MONERO_COM_BUILD_NUMBER=28
 MONERO_COM_BUNDLE_ID="com.monero.app"
 MONERO_COM_PACKAGE="com.monero.app"
 
 CAKEWALLET_NAME="Cake Wallet"
 CAKEWALLET_VERSION="4.5.0"
-CAKEWALLET_BUILD_NUMBER=130
+CAKEWALLET_BUILD_NUMBER=132
 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
 
diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh
index bab932345..c7ecaa60b 100644
--- a/scripts/ios/app_env.sh
+++ b/scripts/ios/app_env.sh
@@ -14,12 +14,12 @@ APP_IOS_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
 MONERO_COM_VERSION="1.2.0"
-MONERO_COM_BUILD_NUMBER=26
+MONERO_COM_BUILD_NUMBER=28
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
 CAKEWALLET_VERSION="4.5.0"
-CAKEWALLET_BUILD_NUMBER=130
+CAKEWALLET_BUILD_NUMBER=132
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 HAVEN_NAME="Haven"

From 549975ecc17316141ab22b20892fd5d7fe24140a Mon Sep 17 00:00:00 2001
From: Godwin Asuquo <godilite@gmail.com>
Date: Wed, 16 Nov 2022 09:29:14 +0200
Subject: [PATCH 07/61] Reorganize settings

---
 lib/di.dart                                   |  18 +-
 lib/router.dart                               |  29 ++-
 lib/routes.dart                               |   5 +
 lib/src/screens/dashboard/wallet_menu.dart    | 136 +++++-------
 .../screens/nodes/widgets/node_list_row.dart  |   7 +-
 .../settings/connection_sync_page.dart        | 155 +++++++++++++
 .../settings/display_settings_page.dart       |  80 +++++++
 .../screens/settings/other_settings_page.dart |  45 ++++
 lib/src/screens/settings/privacy_page.dart    |  30 +++
 .../settings/security_backup_page.dart        |  84 +++++++
 lib/src/screens/settings/settings.dart        |  98 ---------
 lib/src/widgets/standard_list.dart            |   4 +-
 .../settings/settings_view_model.dart         | 207 ++++--------------
 res/values/strings_de.arb                     |   6 +-
 res/values/strings_en.arb                     |   9 +-
 res/values/strings_es.arb                     |   6 +-
 res/values/strings_fr.arb                     |   6 +-
 res/values/strings_hi.arb                     |   6 +-
 res/values/strings_hr.arb                     |   6 +-
 res/values/strings_it.arb                     |   6 +-
 res/values/strings_ja.arb                     |   6 +-
 res/values/strings_ko.arb                     |   6 +-
 res/values/strings_nl.arb                     |   6 +-
 res/values/strings_pl.arb                     |   6 +-
 res/values/strings_pt.arb                     |   6 +-
 res/values/strings_ru.arb                     |   6 +-
 res/values/strings_uk.arb                     |   7 +-
 res/values/strings_zh.arb                     |   6 +-
 28 files changed, 619 insertions(+), 373 deletions(-)
 create mode 100644 lib/src/screens/settings/connection_sync_page.dart
 create mode 100644 lib/src/screens/settings/display_settings_page.dart
 create mode 100644 lib/src/screens/settings/other_settings_page.dart
 create mode 100644 lib/src/screens/settings/privacy_page.dart
 create mode 100644 lib/src/screens/settings/security_backup_page.dart
 delete mode 100644 lib/src/screens/settings/settings.dart

diff --git a/lib/di.dart b/lib/di.dart
index 90549cf6f..265a5036b 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -5,9 +5,14 @@ import 'package:cake_wallet/ionia/ionia_anypay.dart';
 import 'package:cake_wallet/ionia/ionia_gift_card.dart';
 import 'package:cake_wallet/ionia/ionia_tip.dart';
 import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
+import 'package:cake_wallet/src/screens/setting/display_settings_page.dart';
+import 'package:cake_wallet/src/screens/setting/other_settings_page.dart';
+import 'package:cake_wallet/src/screens/setting/privacy_page.dart';
+import 'package:cake_wallet/src/screens/setting/security_backup_page.dart';
 import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dart';
 import 'package:cake_wallet/src/screens/ionia/cards/ionia_gift_card_detail_page.dart';
 import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart';
+import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart';
 import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart';
 import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart';
 import 'package:cake_wallet/view_model/ionia/ionia_custom_tip_view_model.dart';
@@ -59,7 +64,6 @@ import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
 import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
 import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart';
 import 'package:cake_wallet/src/screens/send/send_template_page.dart';
-import 'package:cake_wallet/src/screens/settings/settings.dart';
 import 'package:cake_wallet/src/screens/setup_pin_code/setup_pin_code.dart';
 import 'package:cake_wallet/src/screens/support/support_page.dart';
 import 'package:cake_wallet/src/screens/trade_details/trade_details_page.dart';
@@ -439,8 +443,6 @@ Future setup(
     return SettingsViewModel(appStore.settingsStore, yatStore, appStore.wallet!);
   });
 
-  getIt.registerFactory(() => SettingsPage(getIt.get<SettingsViewModel>()));
-
   getIt
       .registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
 
@@ -477,6 +479,16 @@ Future setup(
 
   getIt.registerFactory(() => NodeListPage(getIt.get<NodeListViewModel>()));
 
+  getIt.registerFactory(() => ConnectionSyncPage(getIt.get<NodeListViewModel>(), getIt.get<DashboardViewModel>()));
+
+  getIt.registerFactory(() => SecurityBackupPage(getIt.get<SettingsViewModel>()));
+
+  getIt.registerFactory(() => PrivacyPage(getIt.get<SettingsViewModel>()));
+
+  getIt.registerFactory(() => DisplaySettingsPage(getIt.get<SettingsViewModel>()));
+
+  getIt.registerFactory(() => OtherSettingsPage(getIt.get<SettingsViewModel>()));
+
   getIt.registerFactory(() =>
       NodeCreateOrEditViewModel(_nodeSource, getIt.get<AppStore>().wallet!));
 
diff --git a/lib/router.dart b/lib/router.dart
index b255ce8b9..e35ba19ef 100644
--- a/lib/router.dart
+++ b/lib/router.dart
@@ -5,6 +5,10 @@ import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
 import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
 import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
 import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
+import 'package:cake_wallet/src/screens/setting/display_settings_page.dart';
+import 'package:cake_wallet/src/screens/setting/other_settings_page.dart';
+import 'package:cake_wallet/src/screens/setting/privacy_page.dart';
+import 'package:cake_wallet/src/screens/setting/security_backup_page.dart';
 import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_cards_page.dart';
 import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_page.dart';
 import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dart';
@@ -16,6 +20,7 @@ import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
 import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
 import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
 import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
+import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart';
 import 'package:cake_wallet/src/screens/support/support_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';
@@ -56,7 +61,6 @@ import 'package:cake_wallet/src/screens/contact/contact_page.dart';
 import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
 import 'package:cake_wallet/src/screens/restore/restore_wallet_from_seed_details.dart';
 import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
-import 'package:cake_wallet/src/screens/settings/settings.dart';
 import 'package:cake_wallet/src/screens/rescan/rescan_page.dart';
 import 'package:cake_wallet/src/screens/faq/faq_page.dart';
 import 'package:cake_wallet/src/screens/trade_details/trade_details_page.dart';
@@ -278,6 +282,26 @@ Route<dynamic> createRoute(RouteSettings settings) {
       return CupertinoPageRoute<void>(
           builder: (_) => getIt.get<NodeListPage>());
 
+    case Routes.connectionSync:
+      return CupertinoPageRoute<void>(
+          builder: (_) => getIt.get<ConnectionSyncPage>());
+
+    case Routes.securityBackupPage:
+      return CupertinoPageRoute<void>(
+          builder: (_) => getIt.get<SecurityBackupPage>());
+    
+     case Routes.privacyPage:
+      return CupertinoPageRoute<void>(
+          builder: (_) => getIt.get<PrivacyPage>());
+
+     case Routes.displaySettingsPage:
+      return CupertinoPageRoute<void>(
+          builder: (_) => getIt.get<DisplaySettingsPage>());
+
+    case Routes.otherSettingsPage:
+      return CupertinoPageRoute<void>(
+          builder: (_) => getIt.get<OtherSettingsPage>());
+    
     case Routes.newNode:
       return CupertinoPageRoute<void>(
           builder: (_) => getIt.get<NodeCreateOrEditPage>());
@@ -360,9 +384,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
       return CupertinoPageRoute<void>(
           builder: (_) => getIt.get<ExchangeTemplatePage>());
 
-    case Routes.settings:
-      return MaterialPageRoute<void>(builder: (_) => getIt.get<SettingsPage>());
-
     case Routes.rescan:
       return MaterialPageRoute<void>(builder: (_) => getIt.get<RescanPage>());
 
diff --git a/lib/routes.dart b/lib/routes.dart
index 3a781ac3a..04642ba34 100644
--- a/lib/routes.dart
+++ b/lib/routes.dart
@@ -77,4 +77,9 @@ class Routes {
   static const ioniaMoreOptionsPage = '/ionia_more_options_page';
   static const ioniaCustomRedeemPage = '/ionia_custom_redeem_page';
   static const onramperPage = '/onramper';
+  static const connectionSync = '/connection_sync_page';
+  static const securityBackupPage = '/security_and_backup_page';
+  static const privacyPage = '/privacy_page';
+  static const displaySettingsPage = '/display_settings_page';
+  static const otherSettingsPage = '/other_settings_page';
 }
diff --git a/lib/src/screens/dashboard/wallet_menu.dart b/lib/src/screens/dashboard/wallet_menu.dart
index 68e7cc76d..bc1f20a5d 100644
--- a/lib/src/screens/dashboard/wallet_menu.dart
+++ b/lib/src/screens/dashboard/wallet_menu.dart
@@ -1,81 +1,64 @@
 import 'package:cake_wallet/palette.dart';
 import 'package:cake_wallet/src/screens/dashboard/wallet_menu_item.dart';
-import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:flutter/material.dart';
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/src/screens/auth/auth_page.dart';
-import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
-import 'package:cake_wallet/wallet_type_utils.dart';
 
 // FIXME: terrible design
 
 class WalletMenu {
   WalletMenu(this.context, this.reconnect, this.hasRescan) : items = [] {
     items.addAll([
-      WalletMenuItem(
-          title: S.current.reconnect,
-          image: Image.asset('assets/images/reconnect_menu.png',
-              height: 16, width: 16),
-	  handler: () => _presentReconnectAlert(context)),
-      if (hasRescan)
-        WalletMenuItem(
-            title: S.current.rescan,
-            image: Image.asset('assets/images/filter_icon.png',
-                height: 16, width: 16, color: Palette.darkBlue),
-	    handler: () => Navigator.of(context).pushNamed(Routes.rescan)),
-      WalletMenuItem(
-          title: S.current.wallets,
-          image: Image.asset('assets/images/wallet_menu.png',
-              height: 16, width: 16),
-	  handler: () => Navigator.of(context).pushNamed(Routes.walletList)),
-      WalletMenuItem(
-          title: S.current.nodes,
-          image: Image.asset('assets/images/nodes_menu.png',
-              height: 16, width: 16),
-	  handler: () => Navigator.of(context).pushNamed(Routes.nodeList)),
-      WalletMenuItem(
-          title: S.current.show_keys,
-          image:
-              Image.asset('assets/images/key_menu.png', height: 16, width: 16),
-	  handler: () {
-	  Navigator.of(context).pushNamed(Routes.auth,
-            arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
-            if (isAuthenticatedSuccessfully) {
-              auth.close(route: Routes.showKeys);
-            }
-          });
-	}),
-      WalletMenuItem(
-          title: S.current.address_book_menu,
-          image: Image.asset('assets/images/open_book_menu.png',
-              height: 16, width: 16),
-	  handler: () => Navigator.of(context).pushNamed(Routes.addressBook)),
-      WalletMenuItem(
-        title: S.current.backup,
-        image: Image.asset('assets/images/restore_wallet.png',
-          height: 16,
-          width: 16,
-          color: Palette.darkBlue),
-        handler: () {
-          Navigator.of(context).pushNamed(
-            Routes.auth,
-            arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
-              if (isAuthenticatedSuccessfully) {
-                auth.close(route:Routes.backup);
-              }
-            });
-        }),
-      WalletMenuItem(
-          title: S.current.settings_title,
-          image: Image.asset('assets/images/settings_menu.png',
-              height: 16, width: 16),
-	  handler: () => Navigator.of(context).pushNamed(Routes.settings)),
-      WalletMenuItem(
-          title: S.current.settings_support,
-          image: Image.asset('assets/images/question_mark.png',
-              height: 16, width: 16, color: Palette.darkBlue),
-	  handler: () => Navigator.of(context).pushNamed(Routes.support)),
+    WalletMenuItem(
+      title: S.current.connection_sync,
+      image: Image.asset('assets/images/nodes_menu.png',
+          height: 16, width: 16),
+      handler: () => Navigator.of(context).pushNamed(Routes.connectionSync),
+    ),
+    WalletMenuItem(
+      title: S.current.wallets,
+      image: Image.asset('assets/images/wallet_menu.png',
+          height: 16, width: 16),
+      handler: () => Navigator.of(context).pushNamed(Routes.walletList),
+    ),
+    WalletMenuItem(
+      title: S.current.security_and_backup,
+      image:
+          Image.asset('assets/images/key_menu.png', height: 16, width: 16),
+      handler: () {
+      Navigator.of(context).pushNamed(Routes.securityBackupPage);
+	  }),
+    WalletMenuItem(
+      title: S.current.privacy,
+      image:
+          Image.asset('assets/images/eye_menu.png', height: 16, width: 16),
+      handler: () {
+      Navigator.of(context).pushNamed(Routes.privacyPage);
+	  }),
+    WalletMenuItem(
+      title: S.current.address_book_menu,
+      image: Image.asset('assets/images/open_book_menu.png',
+      height: 16, width: 16),
+      handler: () => Navigator.of(context).pushNamed(Routes.addressBook),
+    ),
+    WalletMenuItem(
+      title: S.current.display_settings,
+      image: Image.asset('assets/images/eye_menu.png',
+      height: 16, width: 16),
+      handler: () => Navigator.of(context).pushNamed(Routes.displaySettingsPage),
+    ),
+    WalletMenuItem(
+      title: S.current.other_settings,
+      image: Image.asset('assets/images/settings_menu.png',
+      height: 16, width: 16),
+      handler: () => Navigator.of(context).pushNamed(Routes.otherSettingsPage),
+    ),
+    WalletMenuItem(
+      title: S.current.settings_support,
+      image: Image.asset('assets/images/question_mark.png',
+      height: 16, width: 16, color: Palette.darkBlue),
+      handler: () => Navigator.of(context).pushNamed(Routes.support),
+    ),
     ]);
   }
 
@@ -86,23 +69,6 @@ class WalletMenu {
 
   void action(int index) {
     final item = items[index];
-    item?.handler();
-  }
-
-  Future<void> _presentReconnectAlert(BuildContext context) async {
-    await showPopUp<void>(
-        context: context,
-        builder: (BuildContext context) {
-          return AlertWithTwoActions(
-              alertTitle: S.of(context).reconnection,
-              alertContent: S.of(context).reconnect_alert_text,
-              rightButtonText: S.of(context).ok,
-              leftButtonText: S.of(context).cancel,
-              actionRightButton: () async {
-                Navigator.of(context).pop();
-                await reconnect?.call();
-              },
-              actionLeftButton: () => Navigator.of(context).pop());
-        });
+    item.handler();
   }
 }
diff --git a/lib/src/screens/nodes/widgets/node_list_row.dart b/lib/src/screens/nodes/widgets/node_list_row.dart
index 3008d450c..580aba170 100644
--- a/lib/src/screens/nodes/widgets/node_list_row.dart
+++ b/lib/src/screens/nodes/widgets/node_list_row.dart
@@ -37,7 +37,10 @@ class NodeHeaderListRow extends StandardListRow {
 
   @override
   Widget buildTrailing(BuildContext context) {
-    return Icon(Icons.add,
-        color: Theme.of(context).accentTextTheme!.subtitle1!.color!, size: 24.0);
+    return SizedBox(
+      width: 20,
+      child: Icon(Icons.add,
+          color: Theme.of(context).accentTextTheme!.subtitle1!.color!, size: 24.0),
+    );
   }
 }
diff --git a/lib/src/screens/settings/connection_sync_page.dart b/lib/src/screens/settings/connection_sync_page.dart
new file mode 100644
index 000000000..0e56d6e58
--- /dev/null
+++ b/lib/src/screens/settings/connection_sync_page.dart
@@ -0,0 +1,155 @@
+import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
+import 'package:cw_core/node.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter_mobx/flutter_mobx.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/screens/nodes/widgets/node_list_row.dart';
+import 'package:cake_wallet/src/widgets/standard_list.dart';
+import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
+import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
+import 'package:flutter_slidable/flutter_slidable.dart';
+
+class ConnectionSyncPage extends BasePage {
+  ConnectionSyncPage(this.nodeListViewModel, this.dashboardViewModel);
+
+  @override
+  String get title => S.current.connection_sync;
+
+  final NodeListViewModel nodeListViewModel;
+  final DashboardViewModel dashboardViewModel;
+
+  @override
+  Widget body(BuildContext context) {
+    return Container(
+      padding: EdgeInsets.only(top: 10),
+      child: Column(
+        mainAxisSize: MainAxisSize.min,
+        children: [
+          SettingsCellWithArrow(
+            title: S.current.reconnect,
+            handler: (context) => _presentReconnectAlert(context),
+          ),
+          StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
+          SettingsCellWithArrow(
+            title: S.current.rescan,
+            handler: (context) => Navigator.of(context).pushNamed(Routes.rescan),
+          ),
+          StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
+          NodeHeaderListRow(
+            title: S.of(context).add_new_node,
+            onTap: (_) async => await Navigator.of(context).pushNamed(Routes.newNode),
+          ),
+          StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
+          SizedBox(height: 100),
+          Observer(
+            builder: (BuildContext context) {
+              return Flexible(
+                child: SectionStandardList(
+                  sectionCount: 1,
+                  context: context,
+                  dividerPadding: EdgeInsets.symmetric(horizontal: 24),
+                  itemCounter: (int sectionIndex) {
+                    return nodeListViewModel.nodes.length;
+                  },
+                  itemBuilder: (_, sectionIndex, index) {
+                    final node = nodeListViewModel.nodes[index];
+                    final isSelected = node.keyIndex == nodeListViewModel.currentNode.keyIndex;
+                    final nodeListRow = NodeListRow(
+                      title: node.uriRaw,
+                      isSelected: isSelected,
+                      isAlive: node.requestNode(),
+                      onTap: (_) async {
+                        if (isSelected) {
+                          return;
+                        }
+
+                        await showPopUp<void>(
+                            context: context,
+                            builder: (BuildContext context) {
+                              return AlertWithTwoActions(
+                                alertTitle: S.of(context).change_current_node_title,
+                                alertContent: S.of(context).change_current_node(node.uriRaw),
+                                leftButtonText: S.of(context).cancel,
+                                rightButtonText: S.of(context).change,
+                                actionLeftButton: () => Navigator.of(context).pop(),
+                                actionRightButton: () async {
+                                  await nodeListViewModel.setAsCurrent(node);
+                                  Navigator.of(context).pop();
+                                },
+                              );
+                            });
+                      },
+                    );
+
+                    final dismissibleRow = Slidable(
+                      key: Key('${node.keyIndex}'),
+                      startActionPane: _actionPane(context, node),
+                      endActionPane: _actionPane(context, node),
+                      child: nodeListRow,
+                    );
+
+                    return isSelected ? nodeListRow : dismissibleRow;
+                  },
+                ),
+              );
+            },
+          ),
+        ],
+      ),
+    );
+  }
+
+  Future<void> _presentReconnectAlert(BuildContext context) async {
+    await showPopUp<void>(
+      context: context,
+      builder: (BuildContext context) {
+        return AlertWithTwoActions(
+            alertTitle: S.of(context).reconnection,
+            alertContent: S.of(context).reconnect_alert_text,
+            rightButtonText: S.of(context).ok,
+            leftButtonText: S.of(context).cancel,
+            actionRightButton: () async {
+              Navigator.of(context).pop();
+              await dashboardViewModel.reconnect();
+            },
+            actionLeftButton: () => Navigator.of(context).pop());
+      },
+    );
+  }
+
+  ActionPane _actionPane(BuildContext context, Node node) => ActionPane(
+        motion: const ScrollMotion(),
+        extentRatio: 0.3,
+        children: [
+          SlidableAction(
+            onPressed: (context) async {
+              final confirmed = await showPopUp<bool>(
+                      context: context,
+                      builder: (BuildContext context) {
+                        return AlertWithTwoActions(
+                            alertTitle: S.of(context).remove_node,
+                            alertContent: S.of(context).remove_node_message,
+                            rightButtonText: S.of(context).remove,
+                            leftButtonText: S.of(context).cancel,
+                            actionRightButton: () => Navigator.pop(context, true),
+                            actionLeftButton: () => Navigator.pop(context, false));
+                      }) ??
+                  false;
+
+              if (confirmed) {
+                await nodeListViewModel.delete(node);
+              }
+            },
+            backgroundColor: Colors.red,
+            foregroundColor: Colors.white,
+            icon: CupertinoIcons.delete,
+            label: S.of(context).delete,
+          ),
+        ],
+      );
+}
diff --git a/lib/src/screens/settings/display_settings_page.dart b/lib/src/screens/settings/display_settings_page.dart
new file mode 100644
index 000000000..a5a855b59
--- /dev/null
+++ b/lib/src/screens/settings/display_settings_page.dart
@@ -0,0 +1,80 @@
+import 'package:cake_wallet/entities/fiat_currency.dart';
+import 'package:cake_wallet/entities/language_service.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart';
+import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
+import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
+import 'package:cake_wallet/themes/theme_base.dart';
+import 'package:cake_wallet/themes/theme_list.dart';
+import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
+import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
+import 'package:cake_wallet/wallet_type_utils.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+
+class DisplaySettingsPage extends BasePage {
+  DisplaySettingsPage(this.settingsViewModel);
+
+  @override
+  String get title => S.current.display_settings;
+
+  final SettingsViewModel settingsViewModel;
+
+  @override
+  Widget body(BuildContext context) {
+    return Observer(builder: (_) {
+      return Container(
+        padding: EdgeInsets.only(top: 10),
+        child: Column(
+          children: [
+            SettingsSwitcherCell(
+                title: S.current.settings_save_recipient_address,
+                value: settingsViewModel.shouldSaveRecipientAddress,
+                onValueChange: (BuildContext _, bool value) {
+                  settingsViewModel.setShouldSaveRecipientAddress(value);
+                }),
+            if (!isHaven)
+              SettingsPickerCell<FiatCurrency>(
+                title: S.current.settings_currency,
+                searchHintText: S.current.search_currency,
+                items: FiatCurrency.all,
+                selectedItem: settingsViewModel.fiatCurrency,
+                onItemSelected: (FiatCurrency currency) => settingsViewModel.setFiatCurrency(currency),
+                images: FiatCurrency.all.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png")).toList(),
+                isGridView: true,
+                matchingCriteria: (FiatCurrency currency, String searchText) {
+                  return currency.title.toLowerCase().contains(searchText) ||
+                      currency.fullName.toLowerCase().contains(searchText);
+                },
+              ),
+            SettingsPickerCell<String>(
+              title: S.current.settings_change_language,
+              searchHintText: S.current.search_language,
+              items: LanguageService.list.keys.toList(),
+              displayItem: (dynamic code) {
+                return LanguageService.list[code] ?? '';
+              },
+              selectedItem: settingsViewModel.languageCode,
+              onItemSelected: settingsViewModel.onLanguageSelected,
+              images: LanguageService.list.keys
+                  .map((e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
+                  .toList(),
+              matchingCriteria: (String code, String searchText) {
+                return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
+              },
+            ),
+            SettingsChoicesCell(
+              ChoicesListItem<ThemeBase>(
+                title: S.current.color_theme,
+                items: ThemeList.all,
+                selectedItem: settingsViewModel.theme,
+                onItemSelected: (ThemeBase theme) => settingsViewModel.setTheme(theme),
+              ),
+            ),
+          ],
+        ),
+      );
+    });
+  }
+}
diff --git a/lib/src/screens/settings/other_settings_page.dart b/lib/src/screens/settings/other_settings_page.dart
new file mode 100644
index 000000000..7d1ec311d
--- /dev/null
+++ b/lib/src/screens/settings/other_settings_page.dart
@@ -0,0 +1,45 @@
+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/settings/widgets/settings_cell_with_arrow.dart';
+import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
+import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.dart';
+import 'package:cake_wallet/src/widgets/standard_list.dart';
+import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
+import 'package:cw_core/transaction_priority.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+
+class OtherSettingsPage extends BasePage {
+  OtherSettingsPage(this._settingsViewModel);
+
+  @override
+  String get title => S.current.other_settings;
+
+  final SettingsViewModel _settingsViewModel;
+
+  @override
+  Widget body(BuildContext context) {
+    return Observer(builder: (_) {
+      return Container(
+        padding: EdgeInsets.only(top: 10),
+        child: Column(children: [
+          SettingsPickerCell<TransactionPriority>(
+            title: S.current.settings_fee_priority,
+            items: priorityForWalletType(_settingsViewModel.walletType),
+            displayItem: _settingsViewModel.getDisplayPriority,
+            selectedItem: _settingsViewModel.transactionPriority,
+            onItemSelected: _settingsViewModel.onDisplayPrioritySelected,
+          ),
+          SettingsCellWithArrow(
+            title: S.current.settings_terms_and_conditions,
+            handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.readDisclaimer),
+          ),
+          StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
+          Spacer(),
+          SettingsVersionCell(title: S.of(context).version(_settingsViewModel.currentVersion))
+        ]),
+      );
+    });
+  }
+}
diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart
new file mode 100644
index 000000000..d8518ce3b
--- /dev/null
+++ b/lib/src/screens/settings/privacy_page.dart
@@ -0,0 +1,30 @@
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
+import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+
+class PrivacyPage extends BasePage {
+  PrivacyPage(this.settingsViewModel);
+
+  @override
+  String get title => S.current.privacy_settings;
+
+  final SettingsViewModel settingsViewModel;
+
+  @override
+  Widget body(BuildContext context) {
+    return Container(
+      padding: EdgeInsets.only(top: 10),
+      child: Observer(builder: (_) {
+        return SettingsSwitcherCell(
+            title: S.current.settings_save_recipient_address,
+            value: settingsViewModel.shouldSaveRecipientAddress,
+            onValueChange: (BuildContext _, bool value) {
+              settingsViewModel.setShouldSaveRecipientAddress(value);
+            });
+      }),
+    );
+  }
+}
diff --git a/lib/src/screens/settings/security_backup_page.dart b/lib/src/screens/settings/security_backup_page.dart
new file mode 100644
index 000000000..d950597f0
--- /dev/null
+++ b/lib/src/screens/settings/security_backup_page.dart
@@ -0,0 +1,84 @@
+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/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
+import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
+import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
+import 'package:cake_wallet/src/widgets/standard_list.dart';
+import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+
+class SecurityBackupPage extends BasePage {
+  SecurityBackupPage(this.settingsViewModel);
+
+  @override
+  String get title => S.current.security_and_backup;
+
+  final SettingsViewModel settingsViewModel;
+
+  @override
+  Widget body(BuildContext context) {
+    return Container(
+      padding: EdgeInsets.only(top: 10),
+      child: Column(mainAxisSize: MainAxisSize.min, children: [
+        SettingsCellWithArrow(
+          title: S.current.show_keys,
+          handler: (_) => Navigator.of(context).pushNamed(Routes.auth,
+              arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
+            if (isAuthenticatedSuccessfully) {
+              auth.close(route: Routes.showKeys);
+            }
+          }),
+        ),
+        StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
+        SettingsCellWithArrow(
+          title: S.current.create_backup,
+          handler: (_) => Navigator.of(context).pushNamed(Routes.auth,
+              arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
+            if (isAuthenticatedSuccessfully) {
+              auth.close(route: Routes.backup);
+            }
+          }),
+        ),
+        StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
+        SettingsCellWithArrow(
+            title: S.current.settings_change_pin,
+            handler: (_) => Navigator.of(context).pushNamed(Routes.auth,
+                    arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
+                  auth.close(
+                    route: isAuthenticatedSuccessfully ? Routes.setupPin : null,
+                    arguments: (PinCodeState<PinCodeWidget> setupPinContext, String _) {
+                      setupPinContext.close();
+                    },
+                  );
+                })),
+        StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
+        Observer(builder: (_) {
+          return SettingsSwitcherCell(
+              title: S.current.settings_allow_biometrical_authentication,
+              value: settingsViewModel.allowBiometricalAuthentication,
+              onValueChange: (BuildContext context, bool value) {
+                if (value) {
+                  Navigator.of(context).pushNamed(Routes.auth,
+                      arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
+                    if (isAuthenticatedSuccessfully) {
+                      if (await settingsViewModel.biometricAuthenticated()) {
+                        settingsViewModel.setAllowBiometricalAuthentication(isAuthenticatedSuccessfully);
+                      }
+                    } else {
+                      settingsViewModel.setAllowBiometricalAuthentication(isAuthenticatedSuccessfully);
+                    }
+
+                    auth.close();
+                  });
+                } else {
+                  settingsViewModel.setAllowBiometricalAuthentication(value);
+                }
+              });
+        }),
+      ]),
+    );
+  }
+}
diff --git a/lib/src/screens/settings/settings.dart b/lib/src/screens/settings/settings.dart
deleted file mode 100644
index 3f6f41e7b..000000000
--- a/lib/src/screens/settings/settings.dart
+++ /dev/null
@@ -1,98 +0,0 @@
-import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.dart';
-import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
-import 'package:cake_wallet/view_model/settings/version_list_item.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:flutter_mobx/flutter_mobx.dart';
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
-import 'package:cake_wallet/view_model/settings/link_list_item.dart';
-import 'package:cake_wallet/view_model/settings/picker_list_item.dart';
-import 'package:cake_wallet/view_model/settings/regular_list_item.dart';
-import 'package:cake_wallet/view_model/settings/switcher_list_item.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_link_provider_cell.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
-import 'package:cake_wallet/src/widgets/standard_list.dart';
-import 'package:cake_wallet/src/screens/base_page.dart';
-
-class SettingsPage extends BasePage {
-  SettingsPage(this.settingsViewModel);
-
-  final SettingsViewModel settingsViewModel;
-
-  @override
-  String get title => S.current.settings_title;
-
-  @override
-  Widget body(BuildContext context) {
-    // FIX-ME: Added `context` it was not used here before, maby bug ?
-    return SectionStandardList(
-        context: context,
-        sectionCount: settingsViewModel.sections.length,
-        itemCounter: (int sectionIndex) {
-          if (sectionIndex < settingsViewModel.sections.length) {
-            return settingsViewModel.sections[sectionIndex].length;
-          }
-
-          return 0;
-        },
-        itemBuilder: (_, sectionIndex, itemIndex) {
-          final item = settingsViewModel.sections[sectionIndex][itemIndex];
-
-          if (item is PickerListItem) {
-            return Observer(builder: (_) {
-              return SettingsPickerCell<Object>(
-                displayItem: item.displayItem,
-                title: item.title,
-                selectedItem: item.selectedItem(),
-                items: item.items,
-                onItemSelected: (dynamic value) => item.onItemSelected(value),
-                images: item.images,
-                searchHintText: item.searchHintText,
-                isGridView: item.isGridView,
-                matchingCriteria: (dynamic value, String searchText) => item.matchingCriteria(value, searchText),
-              );
-            });
-          }
-
-          if (item is SwitcherListItem) {
-            return Observer(builder: (_) {
-              return SettingsSwitcherCell(
-                  title: item.title,
-                  value: item.value(),
-                  onValueChange: item.onValueChange);
-            });
-          }
-
-          if (item is RegularListItem) {
-            return SettingsCellWithArrow(
-                title: item.title, handler: item.handler);
-          }
-
-          if (item is LinkListItem) {
-            return SettingsLinkProviderCell(
-                title: item.title,
-                icon: item.icon,
-                link: item.link,
-                linkTitle: item.linkTitle);
-          }
-
-          if (item is VersionListItem) {
-            return Observer(builder: (_) {
-              return SettingsVersionCell(
-                  title:
-                      S.of(context).version(settingsViewModel.currentVersion));
-            });
-          }
-
-          if (item is ChoicesListItem) {
-            return SettingsChoicesCell(item);
-          }
-
-          return Container();
-        });
-  }
-}
diff --git a/lib/src/widgets/standard_list.dart b/lib/src/widgets/standard_list.dart
index ae8978eb4..f5abdd900 100644
--- a/lib/src/widgets/standard_list.dart
+++ b/lib/src/widgets/standard_list.dart
@@ -123,6 +123,7 @@ class SectionStandardList extends StatelessWidget {
       required this.itemBuilder,
       required this.sectionCount,
       required BuildContext context,
+      this.dividerPadding = const EdgeInsets.only(left: 24),
       this.themeColor,
       this.dividerThemeColor,
       this.sectionTitleBuilder,
@@ -149,6 +150,7 @@ class SectionStandardList extends StatelessWidget {
   final List<Widget> totalRows;
   final Color? themeColor;
   final Color? dividerThemeColor;
+  final EdgeInsets dividerPadding;
 
   List<Widget> transform(
       bool hasTopSeparator,
@@ -178,7 +180,7 @@ class SectionStandardList extends StatelessWidget {
 
       items.add(sectionIndex + 1 != sectionCount
           ? SectionHeaderListRow()
-          : StandardListSeparator(padding: EdgeInsets.only(left: 24)));
+          : StandardListSeparator(padding: dividerPadding));
     }
 
     return items;
diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart
index aabe51ef1..bf870af2e 100644
--- a/lib/view_model/settings/settings_view_model.dart
+++ b/lib/view_model/settings/settings_view_model.dart
@@ -1,11 +1,6 @@
-import 'package:cake_wallet/entities/language_service.dart';
 import 'package:cake_wallet/store/yat/yat_store.dart';
-import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
-import 'package:flutter/cupertino.dart';
 import 'package:mobx/mobx.dart';
 import 'package:package_info/package_info.dart';
-import 'package:cake_wallet/routes.dart';
-import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/entities/biometric_auth.dart';
@@ -16,21 +11,12 @@ import 'package:cw_core/node.dart';
 import 'package:cake_wallet/monero/monero.dart';
 import 'package:cake_wallet/haven/haven.dart';
 import 'package:cake_wallet/entities/action_list_display_mode.dart';
-import 'package:cake_wallet/view_model/settings/version_list_item.dart';
-import 'package:cake_wallet/view_model/settings/picker_list_item.dart';
-import 'package:cake_wallet/view_model/settings/regular_list_item.dart';
-import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
-import 'package:cake_wallet/view_model/settings/switcher_list_item.dart';
-import 'package:cake_wallet/src/screens/auth/auth_page.dart';
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
 import 'package:cw_core/transaction_history.dart';
 import 'package:cw_core/balance.dart';
 import 'package:cw_core/transaction_info.dart';
 import 'package:cw_core/transaction_priority.dart';
 import 'package:cake_wallet/themes/theme_base.dart';
-import 'package:cake_wallet/themes/theme_list.dart';
-import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
-import 'package:cake_wallet/wallet_type_utils.dart';
 
 part 'settings_view_model.g.dart';
 
@@ -59,9 +45,9 @@ abstract class SettingsViewModelBase with Store {
               TransactionInfo>
           wallet)
       : itemHeaders = {},
-        _walletType = wallet.type,
+        walletType = wallet.type,
+        _wallet = wallet,
         _biometricAuth = BiometricAuth(),
-        sections = <List<SettingsListItem>>[],
         currentVersion = '' {
     PackageInfo.fromPlatform().then(
         (PackageInfo packageInfo) => currentVersion = packageInfo.version);
@@ -97,171 +83,30 @@ abstract class SettingsViewModelBase with Store {
     //  createNewYatUrl += '?sub1=' + createNewYatUrlParameters;
     //}
 
-
-    sections = [
-      [
-        SwitcherListItem(
-            title: S.current.settings_display_balance,
-            value: () => balanceDisplayMode == BalanceDisplayMode.displayableBalance,
-            onValueChange: (_, bool value) {
-              if (value) {
-                _settingsStore.balanceDisplayMode = BalanceDisplayMode.displayableBalance;
-              } else {
-                _settingsStore.balanceDisplayMode = BalanceDisplayMode.hiddenBalance;
-              }
-            },
-        ),
-        if (!isHaven)
-          PickerListItem(
-              title: S.current.settings_currency,
-              searchHintText: S.current.search_currency,
-              items: FiatCurrency.all,
-              selectedItem: () => fiatCurrency,
-              onItemSelected: (FiatCurrency currency) =>
-                  setFiatCurrency(currency),
-              images: FiatCurrency.all.map(
-                    (e) => Image.asset("assets/images/flags/${e.countryCode}.png"))
-                .toList(),
-              isGridView: true,
-              matchingCriteria: (FiatCurrency currency, String searchText) {
-                return currency.title.toLowerCase().contains(searchText) || currency.fullName.toLowerCase().contains(searchText);
-              },
-          ),
-        PickerListItem(
-            title: S.current.settings_fee_priority,
-            items: priorityForWalletType(wallet.type),
-            displayItem: (dynamic priority) {
-              final _priority = priority as TransactionPriority;
-
-              if (wallet.type == WalletType.bitcoin
-                  || wallet.type == WalletType.litecoin) {
-                final rate = bitcoin!.getFeeRate(wallet, _priority);
-                return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate);
-              }
-
-              return priority.toString();
-            },
-            selectedItem: () => transactionPriority,
-            onItemSelected: (TransactionPriority priority) =>
-                _settingsStore.priority[wallet.type] = priority),
-        SwitcherListItem(
-            title: S.current.settings_save_recipient_address,
-            value: () => shouldSaveRecipientAddress,
-            onValueChange: (_, bool value) =>
-                setShouldSaveRecipientAddress(value))
-      ],
-      [
-        RegularListItem(
-            title: S.current.settings_change_pin,
-            handler: (BuildContext context) {
-              Navigator.of(context).pushNamed(Routes.auth, arguments:
-                  (bool isAuthenticatedSuccessfully, AuthPageState auth) {
-                auth.close(
-                  route: isAuthenticatedSuccessfully ? Routes.setupPin : null,
-                  arguments: (PinCodeState<PinCodeWidget> setupPinContext,
-                      String _) {
-                    setupPinContext.close();
-                  },
-                );
-              });
-            }),
-        PickerListItem(
-            title: S.current.settings_change_language,
-            searchHintText: S.current.search_language,
-            items: LanguageService.list.keys.toList(),
-            displayItem: (dynamic code) {
-              return LanguageService.list[code] ?? '';
-            },
-            selectedItem: () => _settingsStore.languageCode,
-            onItemSelected: (String code) {
-              _settingsStore.languageCode = code;
-            },
-            images: LanguageService.list.keys.map(
-              (e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
-              .toList(),
-            matchingCriteria: (String code, String searchText) {
-              return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
-            },
-        ),
-        SwitcherListItem(
-            title: S.current.settings_allow_biometrical_authentication,
-            value: () => allowBiometricalAuthentication,
-            onValueChange: (BuildContext context, bool value) {
-              if (value) {
-                Navigator.of(context).pushNamed(Routes.auth, arguments:
-                    (bool isAuthenticatedSuccessfully,
-                        AuthPageState auth) async {
-                  if (isAuthenticatedSuccessfully) {
-                    if (await _biometricAuth.canCheckBiometrics() &&
-                        await _biometricAuth.isAuthenticated()) {
-                      setAllowBiometricalAuthentication(
-                          isAuthenticatedSuccessfully);
-                    }
-                  } else {
-                    setAllowBiometricalAuthentication(
-                        isAuthenticatedSuccessfully);
-                  }
-
-                  auth.close();
-                });
-              } else {
-                setAllowBiometricalAuthentication(value);
-              }
-            }),
-        ChoicesListItem(
-          title: S.current.color_theme,
-          items: ThemeList.all,
-          selectedItem: theme,
-          onItemSelected: (ThemeBase theme) => _settingsStore.currentTheme = theme,
-        ),
-      ],
-      //[
-        //if (_yatStore.emoji.isNotEmpty) ...[
-        //  LinkListItem(
-        //      title: S.current.manage_yats,
-        //      link: manageYatUrl,
-        //      linkTitle: ''),
-        //] else ...[
-        //LinkListItem(
-        //  title: S.current.connect_yats,
-        //  link: connectYatUrl,
-        //  linkTitle: ''),
-        //LinkListItem(
-        //  title: 'Create new Yats',
-        //  link: createNewYatUrl,
-        //  linkTitle: '')
-        //]
-      //],
-      [
-        RegularListItem(
-          title: S.current.settings_terms_and_conditions,
-          handler: (BuildContext context) =>
-              Navigator.of(context).pushNamed(Routes.readDisclaimer),
-        )
-      ],
-      [VersionListItem(title: currentVersion)]
-    ];
   }
 
   @observable
   String currentVersion;
 
   @computed
-  Node get node => _settingsStore.getCurrentNode(_walletType);
+  Node get node => _settingsStore.getCurrentNode(walletType);
 
   @computed
   FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency;
 
+  @computed
+  String get languageCode => _settingsStore.languageCode;
+
   @computed
   ObservableList<ActionListDisplayMode> get actionlistDisplayMode =>
       _settingsStore.actionlistDisplayMode;
 
   @computed
   TransactionPriority get transactionPriority {
-    final priority = _settingsStore.priority[_walletType];
+    final priority = _settingsStore.priority[walletType];
 
     if (priority == null) {
-      throw Exception('Unexpected type ${_walletType.toString()}');
+      throw Exception('Unexpected type ${walletType.toString()}');
     }
 
     return priority;
@@ -285,11 +130,12 @@ abstract class SettingsViewModelBase with Store {
   bool get isBitcoinBuyEnabled => _settingsStore.isBitcoinBuyEnabled;
 
   final Map<String, String> itemHeaders;
-  List<List<SettingsListItem>> sections;
   final SettingsStore _settingsStore;
   final YatStore _yatStore;
-  final WalletType _walletType;
+  final WalletType walletType;
   final BiometricAuth _biometricAuth;
+  final  WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
+              TransactionInfo> _wallet;
 
   @action
   void setBalanceDisplayMode(BalanceDisplayMode value) =>
@@ -333,4 +179,35 @@ abstract class SettingsViewModelBase with Store {
 
   @action
   void _showTrades() => actionlistDisplayMode.add(ActionListDisplayMode.trades);
+
+  @action 
+  Future<bool> biometricAuthenticated()async{
+   return await _biometricAuth.canCheckBiometrics() && await _biometricAuth.isAuthenticated();
+  }
+
+  @action
+  void onLanguageSelected (String code) {
+    _settingsStore.languageCode = code;
+  }
+
+  @action
+  void setTheme(ThemeBase newTheme){
+     _settingsStore.currentTheme = newTheme;
+  }
+
+  String getDisplayPriority(TransactionPriority priority) {
+              final _priority = priority;
+
+              if (_wallet.type == WalletType.bitcoin
+                  || _wallet.type == WalletType.litecoin) {
+                final rate = bitcoin!.getFeeRate(_wallet, _priority);
+                return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate);
+              }
+
+              return priority.toString();
+  }
+
+  void onDisplayPrioritySelected(TransactionPriority priority) =>
+                _settingsStore.priority[_wallet.type] = priority;
+
 }
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 685d817d5..cea889b15 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -651,5 +651,9 @@
   "ignor": "Ignorieren",
   "use_suggested": "Vorgeschlagen verwenden",
   "do_not_share_warning_text" : "Teilen Sie diese nicht mit anderen, einschließlich des Supports.\n\nSie werden Ihr Geld stehlen!",
-  "help": "hilfe"
+  "help": "hilfe",
+  "privacy_settings": "Datenschutzeinstellungen",
+  "privacy": "Datenschutz",
+  "display_settings": "Anzeigeeinstellungen",
+  "other_settings": "Andere Einstellungen"
 }
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 877d09231..e764a0b90 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -651,5 +651,12 @@
   "ignor": "Ignore",
   "use_suggested": "Use Suggested",
   "do_not_share_warning_text" : "Do not share these with anyone else, including support.\n\nThey will steal your money!",
-  "help": "help"
+  "help": "help",
+  "connection_sync": "Connection and sync",
+  "security_and_backup": "Security and backup",
+  "create_backup": "Create backup",
+  "privacy_settings": "Privacy settings",
+  "privacy": "Privacy",
+  "display_settings": "Display settings",
+  "other_settings": "Other settings"
 }
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 505f3ffa8..bd43abe58 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -651,5 +651,9 @@
   "ignor": "Pasar por alto",
   "use_suggested": "Usar sugerido",
   "do_not_share_warning_text" : "No comparta estos con nadie más, incluido el soporte.\n\n¡Te robarán tu dinero!",
-  "help": "ayuda"
+  "help": "ayuda",
+  "privacy_settings": "Configuración de privacidad",
+  "privacy": "Privacidad",
+  "display_settings": "Configuración de pantalla",
+  "other_settings": "Otras configuraciones"
 }
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index 941016c0b..df43f41a6 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -649,5 +649,9 @@
   "ignor": "Ignorer",
   "use_suggested": "Utilisation suggérée",
   "do_not_share_warning_text" : "Ne les partagez avec personne d'autre, y compris avec l'assistance.\n\nIls vont voler votre argent!",
-  "help": "aider"
+  "help": "aider",
+  "privacy_settings": "Paramètres de confidentialité",
+  "privacy": "Confidentialité",
+  "display_settings": "Paramètres d'affichage",
+  "other_settings": "Autres paramètres"
 }
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index 7faa06f7f..06d95d3b2 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -651,5 +651,9 @@
   "ignor": "नज़रअंदाज़ करना",
   "use_suggested": "सुझाए गए का प्रयोग करें",
   "do_not_share_warning_text" : "इन्हें समर्थन सहित किसी और के साथ साझा न करें।\n\nवे आपका पैसा चुरा लेंगे!",
-  "help": "मदद करना"
+  "help": "मदद करना",
+  "privacy_settings": "गोपनीयता सेटिंग्स",
+  "privacy": "गोपनीयता",
+  "display_settings": "प्रदर्शन सेटिंग्स",
+  "other_settings": "अन्य सेटिंग्स"
 }
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 4fa77948a..7c25928e5 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -651,5 +651,9 @@
   "ignor": "Zanemariti",
   "use_suggested": "Koristite predloženo",
   "do_not_share_warning_text" : "Nemojte ih dijeliti ni s kim, uključujući podršku.\n\nUkrast će vam novac!",
-  "help": "pomozite"
+  "help": "pomozite",
+  "privacy_settings": "Postavke privatnosti",
+  "privacy": "Privatnost",
+  "display_settings": "Postavke zaslona",
+  "other_settings": "Ostale postavke"
 }
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index 9a42a588b..45d9d8164 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -651,5 +651,9 @@
   "ignor": "Ignorare",
   "use_suggested": "Usa suggerito",
   "do_not_share_warning_text" : "Non condividerli con nessun altro, incluso il supporto.\n\nTi ruberanno i soldi!",
-  "help": "aiuto"
+  "help": "aiuto",
+  "privacy_settings": "Impostazioni privacy",
+  "privacy": "Privacy",
+  "display_settings": "Impostazioni di visualizzazione",
+  "other_settings": "Altre impostazioni"
 }
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index c1d0de4e3..ffb2cbb71 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -651,5 +651,9 @@
   "ignor": "無視",
   "use_suggested": "推奨を使用",
   "do_not_share_warning_text" : "サポートを含め、これらを他の誰とも共有しないでください。\n\n彼らはあなたのお金を盗みます!",
-  "help": "ヘルプ"
+  "help": "ヘルプ",
+  "privacy_settings": "プライバシー設定",
+  "privacy": "プライバシー",
+  "display_settings": "表示設定",
+  "other_settings": "その他の設定"
 }
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 127aa949e..598fe2f56 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -651,5 +651,9 @@
   "ignor": "무시하다",
   "use_suggested": "추천 사용",
   "do_not_share_warning_text" : "지원을 포함하여 다른 사람과 이러한 정보를 공유하지 마십시오.\n\n그들은 당신의 돈을 훔칠 것입니다!",
-  "help": "돕다"
+  "help": "돕다",
+  "privacy_settings": "개인정보 설정",
+  "privacy": "프라이버시",
+  "display_settings": "디스플레이 설정",
+  "other_settings": "기타 설정"
 }
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index fa748b552..12e2f5569 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -651,5 +651,9 @@
   "ignor": "Negeren",
   "use_suggested": "Gebruik aanbevolen",
   "do_not_share_warning_text" : "Deel deze met niemand anders, ook niet met support.\n\nZe zullen je geld stelen!",
-  "help": "helpen"
+  "help": "helpen",
+  "privacy_settings": "Privacy-instellingen",
+  "privacy": "Privacy",
+  "display_settings": "Weergave-instellingen",
+  "other_settings": "Andere instellingen"
 }
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 454fe9717..fd092d332 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -651,5 +651,9 @@
   "ignor": "Ignorować",
   "use_suggested": "Użyj sugerowane",
   "do_not_share_warning_text" : "Nie udostępniaj ich nikomu innemu, w tym wsparcia.\n\nUkradną twoje pieniądze!",
-  "help": "pomoc"
+  "help": "pomoc",
+  "privacy_settings": "Ustawienia prywatności",
+  "privacy": "Prywatność",
+  "display_settings": "Ustawienia wyświetlania",
+  "other_settings": "Inne ustawienia"
 }
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 04a0a3ff2..e4d7ef647 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -651,5 +651,9 @@
   "ignor": "Ignorar",
   "use_suggested": "Uso sugerido",
   "do_not_share_warning_text" : "Não os compartilhe com mais ninguém, incluindo suporte.\n\nEles vão roubar seu dinheiro!",
-  "help": "ajuda"
+  "help": "ajuda",
+  "privacy_settings": "Configurações de privacidade",
+  "privacy": "Privacidade",
+  "display_settings": "Configurações de exibição",
+  "other_settings": "Outras configurações"
 }
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index 632b0990c..786f11e36 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -651,5 +651,9 @@
   "ignor": "Игнорировать",
   "use_suggested": "Использовать предложенный",
   "do_not_share_warning_text" : "Не делитесь ими с кем-либо еще, в том числе со службой поддержки.\n\nОни украдут ваши деньги!",
-  "help": "помощь"
+  "help": "помощь",
+  "privacy_settings": "Настройки конфиденциальности",
+  "privacy": "Конфиденциальность",
+  "display_settings": "Настройки отображения",
+  "other_settings": "Другие настройки"
 }
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 5e0f0d18a..48951e806 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -650,5 +650,10 @@
   "ignor": "Ігнорувати",
   "use_suggested": "Використати запропоноване",
   "do_not_share_warning_text" : "Не повідомляйте їх нікому, включно зі службою підтримки.\n\nВони вкрадуть ваші гроші!",
-  "help": "допомога"
+  "help": "допомога",
+  "privacy_settings": "Налаштування конфіденційності",
+  "privacy": "Конфіденційність",
+  "display_settings": "Налаштування дисплея",
+  "other_settings": "Інші налаштування"
+
 }
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index c46d07d59..29d7351d5 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -649,5 +649,9 @@
   "ignor": "忽视",
   "use_suggested": "使用建议",
   "do_not_share_warning_text" : "不要與其他任何人分享這些內容,包括支持。\n\n他們會偷你的錢!",
-  "help": "帮助"
+  "help": "帮助",
+  "privacy_settings": "隐私设置",
+  "privacy":"隐私",
+  "display_settings": "显示设置",
+  "other_settings": "其他设置"
 }

From 91d7e87334d9374904c0bf3098510a8c5c20d1a2 Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Wed, 16 Nov 2022 23:31:42 +0200
Subject: [PATCH 08/61] fix gift card filter colors

---
 lib/src/screens/ionia/cards/ionia_manage_cards_page.dart | 2 +-
 lib/src/screens/ionia/widgets/ionia_filter_modal.dart    | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart b/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart
index 2fbb1d57d..1c13f7a88 100644
--- a/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart
+++ b/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart
@@ -118,7 +118,7 @@ class IoniaManageCardsPage extends BasePage {
           width: 32,
           padding: EdgeInsets.all(8),
           decoration: BoxDecoration(
-            color: Colors.white.withOpacity(0.15),
+            color: Theme.of(context).textTheme!.headline6!.backgroundColor!,
             border: Border.all(
               color: Colors.white.withOpacity(0.2),
             ),
diff --git a/lib/src/screens/ionia/widgets/ionia_filter_modal.dart b/lib/src/screens/ionia/widgets/ionia_filter_modal.dart
index ec6e84cc0..2b885f736 100644
--- a/lib/src/screens/ionia/widgets/ionia_filter_modal.dart
+++ b/lib/src/screens/ionia/widgets/ionia_filter_modal.dart
@@ -20,7 +20,7 @@ class IoniaFilterModal extends StatelessWidget {
       padding: EdgeInsets.all(10),
       child: Image.asset(
         'assets/images/mini_search_icon.png',
-        color: Theme.of(context).accentColor,
+        color: Theme.of(context).textTheme.subtitle2!.color!,
       ),
     );
     return Scaffold(
@@ -53,7 +53,7 @@ class IoniaFilterModal extends StatelessWidget {
                           prefixIcon: searchIcon,
                           hintText: S.of(context).search_category,
                           contentPadding: EdgeInsets.only(bottom: 5),
-                          fillColor: Theme.of(context).textTheme!.subtitle1!.backgroundColor!,
+                          fillColor: Theme.of(context).primaryTextTheme!.caption!.decorationColor!.withOpacity(0.5),
                           border: OutlineInputBorder(
                             borderSide: BorderSide.none,
                             borderRadius: BorderRadius.circular(8),

From ab305e22a23c9f2930a538a1110ca1c9eb3ee24a Mon Sep 17 00:00:00 2001
From: mkyq <53115730+mkyq@users.noreply.github.com>
Date: Wed, 16 Nov 2022 18:30:35 -0500
Subject: [PATCH 09/61] Remove duplication for qr codes. (#628)

---
 lib/src/screens/receive/widgets/qr_painter.dart | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/src/screens/receive/widgets/qr_painter.dart b/lib/src/screens/receive/widgets/qr_painter.dart
index 90dba73ac..e4af59f1a 100644
--- a/lib/src/screens/receive/widgets/qr_painter.dart
+++ b/lib/src/screens/receive/widgets/qr_painter.dart
@@ -9,7 +9,6 @@ class QrPainter extends CustomPainter {
     this.errorCorrectionLevel,
   ) : this._qr = QrCode(version, errorCorrectionLevel)..addData(data) {
     _p.color = this.color;
-    _qr.addData(data);
     _qrImage = QrImage(_qr);
   }
 

From 35007fcf3ecc3dbac44ae8b2e9e3bb904bef653e Mon Sep 17 00:00:00 2001
From: mkyq <53115730+mkyq@users.noreply.github.com>
Date: Wed, 16 Nov 2022 18:33:12 -0500
Subject: [PATCH 10/61] Update version to 4.5.1 for cakewallet; 1.2.1 for
 monero.com. (#629)

---
 scripts/android/app_env.sh | 8 ++++----
 scripts/ios/app_env.sh     | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index 54ad0b4d4..e57d3a97c 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -14,14 +14,14 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
 APP_ANDROID_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.2.0"
-MONERO_COM_BUILD_NUMBER=28
+MONERO_COM_VERSION="1.2.1"
+MONERO_COM_BUILD_NUMBER=29
 MONERO_COM_BUNDLE_ID="com.monero.app"
 MONERO_COM_PACKAGE="com.monero.app"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.5.0"
-CAKEWALLET_BUILD_NUMBER=132
+CAKEWALLET_VERSION="4.5.1"
+CAKEWALLET_BUILD_NUMBER=133
 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
 
diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh
index c7ecaa60b..8bb945680 100644
--- a/scripts/ios/app_env.sh
+++ b/scripts/ios/app_env.sh
@@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
 APP_IOS_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.2.0"
-MONERO_COM_BUILD_NUMBER=28
+MONERO_COM_VERSION="1.2.1"
+MONERO_COM_BUILD_NUMBER=29
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.5.0"
-CAKEWALLET_BUILD_NUMBER=132
+CAKEWALLET_VERSION="4.5.1"
+CAKEWALLET_BUILD_NUMBER=133
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 HAVEN_NAME="Haven"

From 3dbdb8fceaa77c33dbc0ff58484c411ee5ee4a77 Mon Sep 17 00:00:00 2001
From: mkyq <53115730+mkyq@users.noreply.github.com>
Date: Wed, 16 Nov 2022 20:15:30 -0500
Subject: [PATCH 11/61] Update targetSdkVersion to 31. (#630)

---
 android/app/build.gradle | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/app/build.gradle b/android/app/build.gradle
index 74cd0f8f7..00cef6393 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -46,7 +46,7 @@ android {
     defaultConfig {
         applicationId appProperties['id']
         minSdkVersion 21
-        targetSdkVersion 30
+        targetSdkVersion 31
         versionCode flutterVersionCode.toInteger()
         versionName flutterVersionName
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

From 91941e7c80fc01141b7215afe3f918ed92cfdaf4 Mon Sep 17 00:00:00 2001
From: mkyq <53115730+mkyq@users.noreply.github.com>
Date: Wed, 16 Nov 2022 20:19:23 -0500
Subject: [PATCH 12/61] Update build number for android cakewallet to 134;
 monero.com to 30. (#631)

---
 scripts/android/app_env.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index e57d3a97c..1cb3084cf 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -15,13 +15,13 @@ APP_ANDROID_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
 MONERO_COM_VERSION="1.2.1"
-MONERO_COM_BUILD_NUMBER=29
+MONERO_COM_BUILD_NUMBER=30
 MONERO_COM_BUNDLE_ID="com.monero.app"
 MONERO_COM_PACKAGE="com.monero.app"
 
 CAKEWALLET_NAME="Cake Wallet"
 CAKEWALLET_VERSION="4.5.1"
-CAKEWALLET_BUILD_NUMBER=133
+CAKEWALLET_BUILD_NUMBER=134
 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
 

From 841b69aef743b8d984ff81de817735072104de31 Mon Sep 17 00:00:00 2001
From: mkyq <53115730+mkyq@users.noreply.github.com>
Date: Wed, 16 Nov 2022 21:55:26 -0500
Subject: [PATCH 13/61] Android exported (#632)

* Add android:exported="true" to android activity.

* Update build version for android for cakewallet to 135; monero.com 31.
---
 android/app/src/main/AndroidManifestBase.xml | 3 ++-
 scripts/android/app_env.sh                   | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml
index f43b0369b..22278d5f1 100644
--- a/android/app/src/main/AndroidManifestBase.xml
+++ b/android/app/src/main/AndroidManifestBase.xml
@@ -21,7 +21,8 @@
             android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
             android:hardwareAccelerated="true"
             android:windowSoftInputMode="adjustResize"
-            android:screenOrientation="portrait">
+            android:screenOrientation="portrait"
+            android:exported="true">
             <meta-data
                     android:name="io.flutter.embedding.android.SplashScreenDrawable"
                     android:resource="@drawable/launch_background"
diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index 1cb3084cf..51e9fcdec 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -15,13 +15,13 @@ APP_ANDROID_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
 MONERO_COM_VERSION="1.2.1"
-MONERO_COM_BUILD_NUMBER=30
+MONERO_COM_BUILD_NUMBER=31
 MONERO_COM_BUNDLE_ID="com.monero.app"
 MONERO_COM_PACKAGE="com.monero.app"
 
 CAKEWALLET_NAME="Cake Wallet"
 CAKEWALLET_VERSION="4.5.1"
-CAKEWALLET_BUILD_NUMBER=134
+CAKEWALLET_BUILD_NUMBER=135
 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
 

From 3d836d5dce6bda9102b783539f24addcd06abeda Mon Sep 17 00:00:00 2001
From: mkyq <53115730+mkyq@users.noreply.github.com>
Date: Wed, 16 Nov 2022 22:00:59 -0500
Subject: [PATCH 14/61] Update android build version for cakewallet to 136;
 monero.com 32. (#633)

---
 scripts/android/app_env.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index 51e9fcdec..d361c8dfa 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -15,13 +15,13 @@ APP_ANDROID_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
 MONERO_COM_VERSION="1.2.1"
-MONERO_COM_BUILD_NUMBER=31
+MONERO_COM_BUILD_NUMBER=32
 MONERO_COM_BUNDLE_ID="com.monero.app"
 MONERO_COM_PACKAGE="com.monero.app"
 
 CAKEWALLET_NAME="Cake Wallet"
 CAKEWALLET_VERSION="4.5.1"
-CAKEWALLET_BUILD_NUMBER=135
+CAKEWALLET_BUILD_NUMBER=136
 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
 

From a82803de3ae6902cd94b0ec0348d5726404cb62a Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Fri, 18 Nov 2022 20:32:52 +0200
Subject: [PATCH 15/61] Fix Casting issue

---
 lib/view_model/settings/settings_view_model.dart | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart
index bf870af2e..359ebfaf5 100644
--- a/lib/view_model/settings/settings_view_model.dart
+++ b/lib/view_model/settings/settings_view_model.dart
@@ -180,7 +180,7 @@ abstract class SettingsViewModelBase with Store {
   @action
   void _showTrades() => actionlistDisplayMode.add(ActionListDisplayMode.trades);
 
-  @action 
+  @action
   Future<bool> biometricAuthenticated()async{
    return await _biometricAuth.canCheckBiometrics() && await _biometricAuth.isAuthenticated();
   }
@@ -195,8 +195,8 @@ abstract class SettingsViewModelBase with Store {
      _settingsStore.currentTheme = newTheme;
   }
 
-  String getDisplayPriority(TransactionPriority priority) {
-              final _priority = priority;
+  String getDisplayPriority(dynamic priority) {
+              final _priority = priority as TransactionPriority;
 
               if (_wallet.type == WalletType.bitcoin
                   || _wallet.type == WalletType.litecoin) {

From c67e8c5037e4aafea5da830db30dd68a5dd85b89 Mon Sep 17 00:00:00 2001
From: Godwin Asuquo <godilite@gmail.com>
Date: Fri, 18 Nov 2022 20:53:35 +0200
Subject: [PATCH 16/61] [CW-233] Fix missing display balance setting

---
 lib/di.dart                                         |  8 ++++----
 lib/router.dart                                     |  8 ++++----
 lib/src/screens/dashboard/dashboard_page.dart       |  2 +-
 lib/src/screens/settings/display_settings_page.dart | 10 +++++-----
 lib/src/screens/settings/other_settings_page.dart   |  2 +-
 lib/view_model/settings/settings_view_model.dart    | 12 ++++++++++++
 6 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/lib/di.dart b/lib/di.dart
index 265a5036b..815a3740e 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -5,10 +5,10 @@ import 'package:cake_wallet/ionia/ionia_anypay.dart';
 import 'package:cake_wallet/ionia/ionia_gift_card.dart';
 import 'package:cake_wallet/ionia/ionia_tip.dart';
 import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
-import 'package:cake_wallet/src/screens/setting/display_settings_page.dart';
-import 'package:cake_wallet/src/screens/setting/other_settings_page.dart';
-import 'package:cake_wallet/src/screens/setting/privacy_page.dart';
-import 'package:cake_wallet/src/screens/setting/security_backup_page.dart';
+import 'package:cake_wallet/src/screens/settings/display_settings_page.dart';
+import 'package:cake_wallet/src/screens/settings/other_settings_page.dart';
+import 'package:cake_wallet/src/screens/settings/privacy_page.dart';
+import 'package:cake_wallet/src/screens/settings/security_backup_page.dart';
 import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dart';
 import 'package:cake_wallet/src/screens/ionia/cards/ionia_gift_card_detail_page.dart';
 import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart';
diff --git a/lib/router.dart b/lib/router.dart
index e35ba19ef..7818cc52f 100644
--- a/lib/router.dart
+++ b/lib/router.dart
@@ -5,10 +5,10 @@ import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
 import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
 import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
 import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
-import 'package:cake_wallet/src/screens/setting/display_settings_page.dart';
-import 'package:cake_wallet/src/screens/setting/other_settings_page.dart';
-import 'package:cake_wallet/src/screens/setting/privacy_page.dart';
-import 'package:cake_wallet/src/screens/setting/security_backup_page.dart';
+import 'package:cake_wallet/src/screens/settings/display_settings_page.dart';
+import 'package:cake_wallet/src/screens/settings/other_settings_page.dart';
+import 'package:cake_wallet/src/screens/settings/privacy_page.dart';
+import 'package:cake_wallet/src/screens/settings/security_backup_page.dart';
 import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_cards_page.dart';
 import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_page.dart';
 import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dart';
diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart
index f3d5a21fb..cb90bb8e0 100644
--- a/lib/src/screens/dashboard/dashboard_page.dart
+++ b/lib/src/screens/dashboard/dashboard_page.dart
@@ -60,7 +60,7 @@ class DashboardPage extends BasePage {
   Widget middle(BuildContext context) {
     return SyncIndicator(dashboardViewModel: walletViewModel,
         onTap: () => Navigator.of(context, rootNavigator: true)
-            .pushNamed(Routes.nodeList));
+            .pushNamed(Routes.connectionSync));
   }
 
   @override
diff --git a/lib/src/screens/settings/display_settings_page.dart b/lib/src/screens/settings/display_settings_page.dart
index a5a855b59..0c18ce09a 100644
--- a/lib/src/screens/settings/display_settings_page.dart
+++ b/lib/src/screens/settings/display_settings_page.dart
@@ -29,11 +29,11 @@ class DisplaySettingsPage extends BasePage {
         child: Column(
           children: [
             SettingsSwitcherCell(
-                title: S.current.settings_save_recipient_address,
-                value: settingsViewModel.shouldSaveRecipientAddress,
-                onValueChange: (BuildContext _, bool value) {
-                  settingsViewModel.setShouldSaveRecipientAddress(value);
-                }),
+            title: S.current.settings_display_balance,
+            value:  settingsViewModel.shouldDisplayBalance,
+            onValueChange: (_, bool value) {
+               settingsViewModel.setShouldDisplayBalance(value);          
+            }),
             if (!isHaven)
               SettingsPickerCell<FiatCurrency>(
                 title: S.current.settings_currency,
diff --git a/lib/src/screens/settings/other_settings_page.dart b/lib/src/screens/settings/other_settings_page.dart
index 7d1ec311d..65d976708 100644
--- a/lib/src/screens/settings/other_settings_page.dart
+++ b/lib/src/screens/settings/other_settings_page.dart
@@ -24,7 +24,7 @@ class OtherSettingsPage extends BasePage {
       return Container(
         padding: EdgeInsets.only(top: 10),
         child: Column(children: [
-          SettingsPickerCell<TransactionPriority>(
+          SettingsPickerCell(
             title: S.current.settings_fee_priority,
             items: priorityForWalletType(_settingsViewModel.walletType),
             displayItem: _settingsViewModel.getDisplayPriority,
diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart
index 359ebfaf5..9caacb211 100644
--- a/lib/view_model/settings/settings_view_model.dart
+++ b/lib/view_model/settings/settings_view_model.dart
@@ -116,6 +116,9 @@ abstract class SettingsViewModelBase with Store {
   BalanceDisplayMode get balanceDisplayMode =>
       _settingsStore.balanceDisplayMode;
 
+  @computed
+  bool get shouldDisplayBalance => balanceDisplayMode == BalanceDisplayMode.displayableBalance;
+
   @computed
   bool get shouldSaveRecipientAddress =>
       _settingsStore.shouldSaveRecipientAddress;
@@ -195,6 +198,15 @@ abstract class SettingsViewModelBase with Store {
      _settingsStore.currentTheme = newTheme;
   }
 
+  @action
+  void setShouldDisplayBalance(bool value){
+  if (value) {
+    _settingsStore.balanceDisplayMode = BalanceDisplayMode.displayableBalance;
+    } else {
+    _settingsStore.balanceDisplayMode = BalanceDisplayMode.hiddenBalance;
+    }
+  }
+
   String getDisplayPriority(dynamic priority) {
               final _priority = priority as TransactionPriority;
 

From bcf09b048c635206e978ea1628ecb23201228c99 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Tue, 22 Nov 2022 03:52:03 +0200
Subject: [PATCH 17/61] Cw 220 fix grey exchange screen (#641)

* Fix nullability issue for ChangeNow rateId

* Handle concurrent modification error from Splay Tree
---
 .../exchange/exchange_view_model.dart         | 158 +++++++++---------
 1 file changed, 83 insertions(+), 75 deletions(-)

diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart
index e7e73855b..725208324 100644
--- a/lib/view_model/exchange/exchange_view_model.dart
+++ b/lib/view_model/exchange/exchange_view_model.dart
@@ -7,7 +7,6 @@ import 'package:cake_wallet/exchange/sideshift/sideshift_exchange_provider.dart'
 import 'package:cake_wallet/exchange/sideshift/sideshift_request.dart';
 import 'package:cake_wallet/exchange/simpleswap/simpleswap_exchange_provider.dart';
 import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
-import 'package:cw_core/transaction_priority.dart';
 import 'package:cake_wallet/exchange/simpleswap/simpleswap_request.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/crypto_currency.dart';
@@ -375,96 +374,105 @@ abstract class ExchangeViewModelBase with Store {
     TradeRequest? request;
     String amount = '';
 
-    for (var provider in _sortedAvailableProviders.values) {
-      if (!(await provider.checkIsAvailable())) {
-        continue;
-      }
+    try {
+      for (var provider in _sortedAvailableProviders.values) {
+        if (!(await provider.checkIsAvailable())) {
+          continue;
+        }
 
-      if (provider is SideShiftExchangeProvider) {
-        request = SideShiftRequest(
-          depositMethod: depositCurrency,
-          settleMethod: receiveCurrency,
-          depositAmount: depositAmount.replaceAll(',', '.'),
-          settleAddress: receiveAddress,
-          refundAddress: depositAddress,
-        );
-        amount = depositAmount;
-      }
+        if (provider is SideShiftExchangeProvider) {
+          request = SideShiftRequest(
+            depositMethod: depositCurrency,
+            settleMethod: receiveCurrency,
+            depositAmount: depositAmount.replaceAll(',', '.'),
+            settleAddress: receiveAddress,
+            refundAddress: depositAddress,
+          );
+          amount = depositAmount;
+        }
 
-      if (provider is SimpleSwapExchangeProvider) {
-        request = SimpleSwapRequest(
-          from: depositCurrency,
-          to: receiveCurrency,
-          amount: depositAmount.replaceAll(',', '.'),
-          address: receiveAddress,
-          refundAddress: depositAddress,
-        );
-        amount = depositAmount;
-      }
-
-      if (provider is XMRTOExchangeProvider) {
-        request = XMRTOTradeRequest(
+        if (provider is SimpleSwapExchangeProvider) {
+          request = SimpleSwapRequest(
             from: depositCurrency,
             to: receiveCurrency,
             amount: depositAmount.replaceAll(',', '.'),
-            receiveAmount: receiveAmount.replaceAll(',', '.'),
             address: receiveAddress,
             refundAddress: depositAddress,
-            isBTCRequest: isReceiveAmountEntered);
-        amount = depositAmount;
-      }
+          );
+          amount = depositAmount;
+        }
 
-      if (provider is ChangeNowExchangeProvider) {
-        request = ChangeNowRequest(
-            from: depositCurrency,
-            to: receiveCurrency,
-            fromAmount: depositAmount.replaceAll(',', '.'),
-            toAmount: receiveAmount.replaceAll(',', '.'),
-            refundAddress: depositAddress,
-            address: receiveAddress,
-            isReverse: isReverse);
-        amount = isReverse ? receiveAmount : depositAmount;
-      }
+        if (provider is XMRTOExchangeProvider) {
+          request = XMRTOTradeRequest(
+              from: depositCurrency,
+              to: receiveCurrency,
+              amount: depositAmount.replaceAll(',', '.'),
+              receiveAmount: receiveAmount.replaceAll(',', '.'),
+              address: receiveAddress,
+              refundAddress: depositAddress,
+              isBTCRequest: isReceiveAmountEntered);
+          amount = depositAmount;
+        }
 
-      if (provider is MorphTokenExchangeProvider) {
-        request = MorphTokenRequest(
-            from: depositCurrency,
-            to: receiveCurrency,
-            amount: depositAmount.replaceAll(',', '.'),
-            refundAddress: depositAddress,
-            address: receiveAddress);
-        amount = depositAmount;
-      }
+        if (provider is ChangeNowExchangeProvider) {
+          request = ChangeNowRequest(
+              from: depositCurrency,
+              to: receiveCurrency,
+              fromAmount: depositAmount.replaceAll(',', '.'),
+              toAmount: receiveAmount.replaceAll(',', '.'),
+              refundAddress: depositAddress,
+              address: receiveAddress,
+              isReverse: isReverse);
+          amount = isReverse ? receiveAmount : depositAmount;
+        }
 
-      amount = amount.replaceAll(',', '.');
+        if (provider is MorphTokenExchangeProvider) {
+          request = MorphTokenRequest(
+              from: depositCurrency,
+              to: receiveCurrency,
+              amount: depositAmount.replaceAll(',', '.'),
+              refundAddress: depositAddress,
+              address: receiveAddress);
+          amount = depositAmount;
+        }
 
-      if (limitsState is LimitsLoadedSuccessfully) {
-        if (double.parse(amount) < limits.min!) {
-          continue;
-        } else if (limits.max != null && double.parse(amount) > limits.max!) {
-          continue;
-        } else {
-          try {
-            tradeState = TradeIsCreating();
-            final trade = await provider.createTrade(
-                request: request!, isFixedRateMode: isFixedRateMode);
-            trade.walletId = wallet.id;
-            tradesStore.setTrade(trade);
-            await trades.add(trade);
-            tradeState = TradeIsCreatedSuccessfully(trade: trade);
-            /// return after the first successful trade
-            return;
-          } catch (e) {
+        amount = amount.replaceAll(',', '.');
+
+        if (limitsState is LimitsLoadedSuccessfully) {
+          if (double.parse(amount) < limits.min!) {
             continue;
+          } else if (limits.max != null && double.parse(amount) > limits.max!) {
+            continue;
+          } else {
+            try {
+              tradeState = TradeIsCreating();
+              final trade = await provider.createTrade(
+                  request: request!, isFixedRateMode: isFixedRateMode);
+              trade.walletId = wallet.id;
+              tradesStore.setTrade(trade);
+              await trades.add(trade);
+              tradeState = TradeIsCreatedSuccessfully(trade: trade);
+              /// return after the first successful trade
+              return;
+            } catch (e) {
+              continue;
+            }
           }
         }
       }
-    }
 
-    /// if the code reached here then none of the providers succeeded
-    tradeState = TradeIsCreatedFailure(
-        title: S.current.trade_not_created,
-        error: S.current.none_of_selected_providers_can_exchange);
+      /// if the code reached here then none of the providers succeeded
+      tradeState = TradeIsCreatedFailure(
+          title: S.current.trade_not_created,
+          error: S.current.none_of_selected_providers_can_exchange);
+    } on ConcurrentModificationError {
+      /// if create trade happened at the exact same time of the scheduled rate update
+      /// then delay the create trade a bit and try again
+      ///
+      /// this is because the limitation of the SplayTreeMap that
+      /// you can't modify it while iterating through it
+      Future.delayed(Duration(milliseconds: 500), createTrade);
+    }
   }
 
   @action

From 9b32c9c95666093841621b4753b0de40e8a19f37 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Tue, 22 Nov 2022 04:18:18 +0200
Subject: [PATCH 18/61] CW-227 Add Disable Exchange option to settings (#642)

* Add Disable Exchange option to settings
---
 lib/entities/preferences_key.dart                  | 1 +
 lib/src/screens/dashboard/dashboard_page.dart      | 4 +++-
 lib/store/settings_store.dart                      | 8 ++++++++
 lib/view_model/dashboard/dashboard_view_model.dart | 6 ++----
 lib/view_model/settings/settings_view_model.dart   | 6 ++++++
 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_hi.arb                          | 3 ++-
 res/values/strings_hr.arb                          | 3 ++-
 res/values/strings_it.arb                          | 3 ++-
 res/values/strings_ja.arb                          | 3 ++-
 res/values/strings_ko.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_uk.arb                          | 3 ++-
 res/values/strings_zh.arb                          | 3 ++-
 20 files changed, 50 insertions(+), 20 deletions(-)

diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart
index 6cf7e5608..a28410192 100644
--- a/lib/entities/preferences_key.dart
+++ b/lib/entities/preferences_key.dart
@@ -11,6 +11,7 @@ class PreferencesKey {
   static const shouldSaveRecipientAddressKey = 'save_recipient_address';
   static const allowBiometricalAuthenticationKey =
       'allow_biometrical_authentication';
+  static const disableExchangeKey = 'disable_exchange';
   static const currentTheme = 'current_theme';
   static const isDarkThemeLegacy = 'dark_theme';
   static const displayActionListModeKey = 'display_list_mode';
diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart
index f3d5a21fb..fe8414134 100644
--- a/lib/src/screens/dashboard/dashboard_page.dart
+++ b/lib/src/screens/dashboard/dashboard_page.dart
@@ -315,6 +315,8 @@ class DashboardPage extends BasePage {
   }
 
   Future<void> _onClickExchangeButton(BuildContext context) async {
-    await Navigator.of(context).pushNamed(Routes.exchange);
+    if (walletViewModel.isEnabledExchangeAction) {
+      await Navigator.of(context).pushNamed(Routes.exchange);
+    }
   }
 }
diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart
index 2b3105a34..534ea67e9 100644
--- a/lib/store/settings_store.dart
+++ b/lib/store/settings_store.dart
@@ -30,6 +30,7 @@ abstract class SettingsStoreBase with Store {
       required BalanceDisplayMode initialBalanceDisplayMode,
       required bool initialSaveRecipientAddress,
       required bool initialAllowBiometricalAuthentication,
+      required bool initialExchangeEnabled,
       required ThemeBase initialTheme,
       required int initialPinLength,
       required String initialLanguageCode,
@@ -47,6 +48,7 @@ abstract class SettingsStoreBase with Store {
     balanceDisplayMode = initialBalanceDisplayMode,
     shouldSaveRecipientAddress = initialSaveRecipientAddress,
     allowBiometricalAuthentication = initialAllowBiometricalAuthentication,
+    disableExchange = initialExchangeEnabled,
     currentTheme = initialTheme,
     pinCodeLength = initialPinLength,
     languageCode = initialLanguageCode,
@@ -143,6 +145,9 @@ abstract class SettingsStoreBase with Store {
   @observable
   bool allowBiometricalAuthentication;
 
+  @observable
+  bool disableExchange;
+
   @observable
   ThemeBase currentTheme;
 
@@ -221,6 +226,8 @@ abstract class SettingsStoreBase with Store {
     final allowBiometricalAuthentication = sharedPreferences
             .getBool(PreferencesKey.allowBiometricalAuthenticationKey) ??
         false;
+    final disableExchange = sharedPreferences
+            .getBool(PreferencesKey.disableExchangeKey) ?? false;
     final legacyTheme =
         (sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy) ?? false)
             ? ThemeType.dark.index
@@ -284,6 +291,7 @@ abstract class SettingsStoreBase with Store {
         initialBalanceDisplayMode: currentBalanceDisplayMode,
         initialSaveRecipientAddress: shouldSaveRecipientAddress,
         initialAllowBiometricalAuthentication: allowBiometricalAuthentication,
+        initialExchangeEnabled: disableExchange,
         initialTheme: savedTheme,
         actionlistDisplayMode: actionListDisplayMode,
         initialPinLength: pinLength,
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index 49dd2437a..7f11b0c2f 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -53,7 +53,6 @@ abstract class DashboardViewModelBase with Store {
     hasBuyAction = false,
     isEnabledBuyAction = false,
     hasExchangeAction = false,
-    isEnabledExchangeAction = false,
     isShowFirstYatIntroduction = false,
     isShowSecondYatIntroduction = false,
     isShowThirdYatIntroduction = false,
@@ -249,8 +248,8 @@ abstract class DashboardViewModelBase with Store {
   void furtherShowYatPopup(bool shouldShow) =>
       settingsStore.shouldShowYatPopup = shouldShow;
 
-  @observable
-  bool isEnabledExchangeAction;
+  @computed
+  bool get isEnabledExchangeAction => !settingsStore.disableExchange;
 
   @observable
   bool hasExchangeAction;
@@ -365,7 +364,6 @@ abstract class DashboardViewModelBase with Store {
   }
 
   void updateActions() {
-    isEnabledExchangeAction = true;
     hasExchangeAction = !isHaven;
     isEnabledBuyAction = wallet.type != WalletType.haven
       && wallet.type != WalletType.monero;
diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart
index aabe51ef1..f85d2c459 100644
--- a/lib/view_model/settings/settings_view_model.dart
+++ b/lib/view_model/settings/settings_view_model.dart
@@ -208,6 +208,12 @@ abstract class SettingsViewModelBase with Store {
                 setAllowBiometricalAuthentication(value);
               }
             }),
+        SwitcherListItem(
+            title: S.current.disable_exchange,
+            value: () => _settingsStore.disableExchange,
+            onValueChange: (BuildContext context, bool value) {
+              _settingsStore.disableExchange = value;
+            }),
         ChoicesListItem(
           title: S.current.color_theme,
           items: ThemeList.all,
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 685d817d5..f5170b84e 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -651,5 +651,6 @@
   "ignor": "Ignorieren",
   "use_suggested": "Vorgeschlagen verwenden",
   "do_not_share_warning_text" : "Teilen Sie diese nicht mit anderen, einschließlich des Supports.\n\nSie werden Ihr Geld stehlen!",
-  "help": "hilfe"
+  "help": "hilfe",
+  "disable_exchange": "Exchange deaktivieren"
 }
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 877d09231..b62dbd984 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -651,5 +651,6 @@
   "ignor": "Ignore",
   "use_suggested": "Use Suggested",
   "do_not_share_warning_text" : "Do not share these with anyone else, including support.\n\nThey will steal your money!",
-  "help": "help"
+  "help": "help",
+  "disable_exchange": "Disable exchange"
 }
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 505f3ffa8..beff1af8d 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -651,5 +651,6 @@
   "ignor": "Pasar por alto",
   "use_suggested": "Usar sugerido",
   "do_not_share_warning_text" : "No comparta estos con nadie más, incluido el soporte.\n\n¡Te robarán tu dinero!",
-  "help": "ayuda"
+  "help": "ayuda",
+  "disable_exchange": "Deshabilitar intercambio"
 }
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index 941016c0b..fa1d01e22 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -649,5 +649,6 @@
   "ignor": "Ignorer",
   "use_suggested": "Utilisation suggérée",
   "do_not_share_warning_text" : "Ne les partagez avec personne d'autre, y compris avec l'assistance.\n\nIls vont voler votre argent!",
-  "help": "aider"
+  "help": "aider",
+  "disable_exchange": "Désactiver l'échange"
 }
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index 7faa06f7f..c7b6ece40 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -651,5 +651,6 @@
   "ignor": "नज़रअंदाज़ करना",
   "use_suggested": "सुझाए गए का प्रयोग करें",
   "do_not_share_warning_text" : "इन्हें समर्थन सहित किसी और के साथ साझा न करें।\n\nवे आपका पैसा चुरा लेंगे!",
-  "help": "मदद करना"
+  "help": "मदद करना",
+  "disable_exchange": "एक्सचेंज अक्षम करें"
 }
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 4fa77948a..532a4d63a 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -651,5 +651,6 @@
   "ignor": "Zanemariti",
   "use_suggested": "Koristite predloženo",
   "do_not_share_warning_text" : "Nemojte ih dijeliti ni s kim, uključujući podršku.\n\nUkrast će vam novac!",
-  "help": "pomozite"
+  "help": "pomozite",
+  "disable_exchange": "Onemogući exchange"
 }
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index 9a42a588b..cb5209fc3 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -651,5 +651,6 @@
   "ignor": "Ignorare",
   "use_suggested": "Usa suggerito",
   "do_not_share_warning_text" : "Non condividerli con nessun altro, incluso il supporto.\n\nTi ruberanno i soldi!",
-  "help": "aiuto"
+  "help": "aiuto",
+  "disable_exchange": "Disabilita scambio"
 }
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index c1d0de4e3..2d1c291ce 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -651,5 +651,6 @@
   "ignor": "無視",
   "use_suggested": "推奨を使用",
   "do_not_share_warning_text" : "サポートを含め、これらを他の誰とも共有しないでください。\n\n彼らはあなたのお金を盗みます!",
-  "help": "ヘルプ"
+  "help": "ヘルプ",
+  "disable_exchange": "交換を無効にする"
 }
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 127aa949e..f24e736cb 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -651,5 +651,6 @@
   "ignor": "무시하다",
   "use_suggested": "추천 사용",
   "do_not_share_warning_text" : "지원을 포함하여 다른 사람과 이러한 정보를 공유하지 마십시오.\n\n그들은 당신의 돈을 훔칠 것입니다!",
-  "help": "돕다"
+  "help": "돕다",
+  "disable_exchange": "교환 비활성화"
 }
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index fa748b552..5663b0357 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -651,5 +651,6 @@
   "ignor": "Negeren",
   "use_suggested": "Gebruik aanbevolen",
   "do_not_share_warning_text" : "Deel deze met niemand anders, ook niet met support.\n\nZe zullen je geld stelen!",
-  "help": "helpen"
+  "help": "helpen",
+  "disable_exchange": "Uitwisseling uitschakelen"
 }
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 454fe9717..f2a414ae2 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -651,5 +651,6 @@
   "ignor": "Ignorować",
   "use_suggested": "Użyj sugerowane",
   "do_not_share_warning_text" : "Nie udostępniaj ich nikomu innemu, w tym wsparcia.\n\nUkradną twoje pieniądze!",
-  "help": "pomoc"
+  "help": "pomoc",
+  "disable_exchange": "Wyłącz wymianę"
 }
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 04a0a3ff2..25318dc2d 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -651,5 +651,6 @@
   "ignor": "Ignorar",
   "use_suggested": "Uso sugerido",
   "do_not_share_warning_text" : "Não os compartilhe com mais ninguém, incluindo suporte.\n\nEles vão roubar seu dinheiro!",
-  "help": "ajuda"
+  "help": "ajuda",
+  "disable_exchange": "Desativar troca"
 }
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index 632b0990c..a907e5765 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -651,5 +651,6 @@
   "ignor": "Игнорировать",
   "use_suggested": "Использовать предложенный",
   "do_not_share_warning_text" : "Не делитесь ими с кем-либо еще, в том числе со службой поддержки.\n\nОни украдут ваши деньги!",
-  "help": "помощь"
+  "help": "помощь",
+  "disable_exchange": "Отключить обмен"
 }
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 5e0f0d18a..91042e91b 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -650,5 +650,6 @@
   "ignor": "Ігнорувати",
   "use_suggested": "Використати запропоноване",
   "do_not_share_warning_text" : "Не повідомляйте їх нікому, включно зі службою підтримки.\n\nВони вкрадуть ваші гроші!",
-  "help": "допомога"
+  "help": "допомога",
+  "disable_exchange": "Вимкнути exchange"
 }
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index c46d07d59..958e80d14 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -649,5 +649,6 @@
   "ignor": "忽视",
   "use_suggested": "使用建议",
   "do_not_share_warning_text" : "不要與其他任何人分享這些內容,包括支持。\n\n他們會偷你的錢!",
-  "help": "帮助"
+  "help": "帮助",
+  "disable_exchange": "禁用交换"
 }

From 0fcd72f82136ba3695da14054a750da3a275ed65 Mon Sep 17 00:00:00 2001
From: Godwin Asuquo <godilite@gmail.com>
Date: Wed, 23 Nov 2022 09:05:47 +0200
Subject: [PATCH 19/61] format indent code

---
 lib/view_model/settings/settings_view_model.dart | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart
index 9caacb211..7783cd200 100644
--- a/lib/view_model/settings/settings_view_model.dart
+++ b/lib/view_model/settings/settings_view_model.dart
@@ -208,18 +208,18 @@ abstract class SettingsViewModelBase with Store {
   }
 
   String getDisplayPriority(dynamic priority) {
-              final _priority = priority as TransactionPriority;
+    final _priority = priority as TransactionPriority;
 
-              if (_wallet.type == WalletType.bitcoin
-                  || _wallet.type == WalletType.litecoin) {
-                final rate = bitcoin!.getFeeRate(_wallet, _priority);
-                return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate);
-              }
+    if (_wallet.type == WalletType.bitcoin
+        || _wallet.type == WalletType.litecoin) {
+      final rate = bitcoin!.getFeeRate(_wallet, _priority);
+      return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate);
+    }
 
-              return priority.toString();
+    return priority.toString();
   }
 
   void onDisplayPrioritySelected(TransactionPriority priority) =>
-                _settingsStore.priority[_wallet.type] = priority;
+    _settingsStore.priority[_wallet.type] = priority;
 
 }

From 5462836b8d62227c3d1ec00fdaa4a66f42b6a802 Mon Sep 17 00:00:00 2001
From: Godwin Asuquo <godilite@gmail.com>
Date: Wed, 23 Nov 2022 19:06:41 +0200
Subject: [PATCH 20/61] seperate settings view model

---
 lib/di.dart                                   |  32 +++++-
 lib/entities/priority_for_wallet_type.dart    |  21 ++++
 lib/src/screens/send/widgets/send_card.dart   |   3 +-
 .../settings/display_settings_page.dart       |   4 +-
 .../screens/settings/other_settings_page.dart |   6 +-
 lib/src/screens/settings/privacy_page.dart    |   4 +-
 .../settings/security_backup_page.dart        |   3 +-
 lib/view_model/send/send_view_model.dart      |   2 +-
 .../settings/display_settings_view_model.dart |  63 +++++++++++
 .../settings/other_settings_view_model.dart   |  72 +++++++++++++
 .../settings/privacy_settings_view_model.dart |  21 ++++
 .../security_settings_view_model.dart         |  29 +++++
 .../settings/settings_view_model.dart         | 101 +-----------------
 13 files changed, 248 insertions(+), 113 deletions(-)
 create mode 100644 lib/entities/priority_for_wallet_type.dart
 create mode 100644 lib/view_model/settings/display_settings_view_model.dart
 create mode 100644 lib/view_model/settings/other_settings_view_model.dart
 create mode 100644 lib/view_model/settings/privacy_settings_view_model.dart
 create mode 100644 lib/view_model/settings/security_settings_view_model.dart

diff --git a/lib/di.dart b/lib/di.dart
index 815a3740e..2edb9057e 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -31,6 +31,10 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart';
 import 'package:cake_wallet/view_model/ionia/ionia_account_view_model.dart';
 import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
 import 'package:cake_wallet/view_model/ionia/ionia_purchase_merch_view_model.dart';
+import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
+import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart';
+import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart';
+import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cake_wallet/core/backup_service.dart';
 import 'package:cw_core/wallet_service.dart';
@@ -443,6 +447,26 @@ Future setup(
     return SettingsViewModel(appStore.settingsStore, yatStore, appStore.wallet!);
   });
 
+  getIt.registerFactory(() {
+    final appStore = getIt.get<AppStore>();
+    return DisplaySettingsViewModel(appStore.settingsStore);
+  });
+
+  getIt.registerFactory(() {
+    final appStore = getIt.get<AppStore>();
+    return PrivacySettingsViewModel(appStore.settingsStore);
+  });
+
+  getIt.registerFactory(() {
+    final appStore = getIt.get<AppStore>();
+    return OtherSettingsViewModel(appStore.settingsStore, appStore.wallet!);
+  });
+
+  getIt.registerFactory(() {
+    final appStore = getIt.get<AppStore>();
+    return SecuritySettingsViewModel(appStore.settingsStore);
+  });
+
   getIt
       .registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
 
@@ -481,13 +505,13 @@ Future setup(
 
   getIt.registerFactory(() => ConnectionSyncPage(getIt.get<NodeListViewModel>(), getIt.get<DashboardViewModel>()));
 
-  getIt.registerFactory(() => SecurityBackupPage(getIt.get<SettingsViewModel>()));
+  getIt.registerFactory(() => SecurityBackupPage(getIt.get<SecuritySettingsViewModel>()));
 
-  getIt.registerFactory(() => PrivacyPage(getIt.get<SettingsViewModel>()));
+  getIt.registerFactory(() => PrivacyPage(getIt.get<PrivacySettingsViewModel>()));
 
-  getIt.registerFactory(() => DisplaySettingsPage(getIt.get<SettingsViewModel>()));
+  getIt.registerFactory(() => DisplaySettingsPage(getIt.get<DisplaySettingsViewModel>()));
 
-  getIt.registerFactory(() => OtherSettingsPage(getIt.get<SettingsViewModel>()));
+  getIt.registerFactory(() => OtherSettingsPage(getIt.get<OtherSettingsViewModel>()));
 
   getIt.registerFactory(() =>
       NodeCreateOrEditViewModel(_nodeSource, getIt.get<AppStore>().wallet!));
diff --git a/lib/entities/priority_for_wallet_type.dart b/lib/entities/priority_for_wallet_type.dart
new file mode 100644
index 000000000..927ab8803
--- /dev/null
+++ b/lib/entities/priority_for_wallet_type.dart
@@ -0,0 +1,21 @@
+import 'package:cake_wallet/bitcoin/bitcoin.dart';
+import 'package:cake_wallet/haven/haven.dart';
+import 'package:cake_wallet/monero/monero.dart';
+import 'package:cw_core/transaction_priority.dart';
+import 'package:cw_core/wallet_type.dart';
+
+List<TransactionPriority> priorityForWalletType(WalletType type) {
+  switch (type) {
+    case WalletType.monero:
+      return monero!.getTransactionPriorities();
+    case WalletType.bitcoin:
+      return bitcoin!.getTransactionPriorities();
+    case WalletType.litecoin:
+      return bitcoin!.getLitecoinTransactionPriorities();
+    case WalletType.haven:
+      return haven!.getTransactionPriorities();
+    default:
+      return [];
+  }
+}
+
diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart
index dc589923f..d5775e2b5 100644
--- a/lib/src/screens/send/widgets/send_card.dart
+++ b/lib/src/screens/send/widgets/send_card.dart
@@ -1,11 +1,10 @@
-import 'dart:ui';
+import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
 import 'package:cake_wallet/utils/payment_request.dart';
 import 'package:cw_core/transaction_priority.dart';
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
 import 'package:cake_wallet/src/widgets/picker.dart';
 import 'package:cake_wallet/view_model/send/output.dart';
-import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
diff --git a/lib/src/screens/settings/display_settings_page.dart b/lib/src/screens/settings/display_settings_page.dart
index 0c18ce09a..fd26da1c4 100644
--- a/lib/src/screens/settings/display_settings_page.dart
+++ b/lib/src/screens/settings/display_settings_page.dart
@@ -8,7 +8,7 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.
 import 'package:cake_wallet/themes/theme_base.dart';
 import 'package:cake_wallet/themes/theme_list.dart';
 import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
-import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
+import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
 import 'package:cake_wallet/wallet_type_utils.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
@@ -19,7 +19,7 @@ class DisplaySettingsPage extends BasePage {
   @override
   String get title => S.current.display_settings;
 
-  final SettingsViewModel settingsViewModel;
+  final DisplaySettingsViewModel settingsViewModel;
 
   @override
   Widget body(BuildContext context) {
diff --git a/lib/src/screens/settings/other_settings_page.dart b/lib/src/screens/settings/other_settings_page.dart
index 65d976708..01bd861b1 100644
--- a/lib/src/screens/settings/other_settings_page.dart
+++ b/lib/src/screens/settings/other_settings_page.dart
@@ -1,3 +1,4 @@
+import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/screens/base_page.dart';
@@ -5,8 +6,7 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arro
 import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
 import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.dart';
 import 'package:cake_wallet/src/widgets/standard_list.dart';
-import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
-import 'package:cw_core/transaction_priority.dart';
+import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 
@@ -16,7 +16,7 @@ class OtherSettingsPage extends BasePage {
   @override
   String get title => S.current.other_settings;
 
-  final SettingsViewModel _settingsViewModel;
+  final OtherSettingsViewModel _settingsViewModel;
 
   @override
   Widget body(BuildContext context) {
diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart
index d8518ce3b..08ab945cc 100644
--- a/lib/src/screens/settings/privacy_page.dart
+++ b/lib/src/screens/settings/privacy_page.dart
@@ -1,7 +1,7 @@
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/src/screens/base_page.dart';
 import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
-import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
+import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 
@@ -11,7 +11,7 @@ class PrivacyPage extends BasePage {
   @override
   String get title => S.current.privacy_settings;
 
-  final SettingsViewModel settingsViewModel;
+  final PrivacySettingsViewModel settingsViewModel;
 
   @override
   Widget body(BuildContext context) {
diff --git a/lib/src/screens/settings/security_backup_page.dart b/lib/src/screens/settings/security_backup_page.dart
index d950597f0..633450313 100644
--- a/lib/src/screens/settings/security_backup_page.dart
+++ b/lib/src/screens/settings/security_backup_page.dart
@@ -6,6 +6,7 @@ import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
 import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
 import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
 import 'package:cake_wallet/src/widgets/standard_list.dart';
+import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart';
 import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
@@ -16,7 +17,7 @@ class SecurityBackupPage extends BasePage {
   @override
   String get title => S.current.security_and_backup;
 
-  final SettingsViewModel settingsViewModel;
+  final SecuritySettingsViewModel settingsViewModel;
 
   @override
   Widget body(BuildContext context) {
diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart
index cdef6faba..c673c452d 100644
--- a/lib/view_model/send/send_view_model.dart
+++ b/lib/view_model/send/send_view_model.dart
@@ -1,10 +1,10 @@
 import 'package:cake_wallet/entities/balance_display_mode.dart';
+import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
 import 'package:cake_wallet/entities/transaction_description.dart';
 import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
 import 'package:cw_core/transaction_priority.dart';
 import 'package:cake_wallet/view_model/send/output.dart';
 import 'package:cake_wallet/view_model/send/send_template_view_model.dart';
-import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cake_wallet/entities/template.dart';
diff --git a/lib/view_model/settings/display_settings_view_model.dart b/lib/view_model/settings/display_settings_view_model.dart
new file mode 100644
index 000000000..3537dfa6e
--- /dev/null
+++ b/lib/view_model/settings/display_settings_view_model.dart
@@ -0,0 +1,63 @@
+import 'package:cake_wallet/entities/balance_display_mode.dart';
+import 'package:cake_wallet/entities/fiat_currency.dart';
+import 'package:cake_wallet/store/settings_store.dart';
+import 'package:cake_wallet/themes/theme_base.dart';
+import 'package:mobx/mobx.dart';
+
+part 'display_settings_view_model.g.dart';
+
+class DisplaySettingsViewModel = DisplaySettingsViewModelBase with _$DisplaySettingsViewModel;
+
+
+abstract class DisplaySettingsViewModelBase with Store {
+  DisplaySettingsViewModelBase(
+      this._settingsStore,
+  );
+
+  final SettingsStore _settingsStore;
+
+  @computed
+  FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency;
+
+  @computed
+  String get languageCode => _settingsStore.languageCode;
+
+
+  @computed
+  BalanceDisplayMode get balanceDisplayMode =>
+      _settingsStore.balanceDisplayMode;
+
+  @computed
+  bool get shouldDisplayBalance => balanceDisplayMode == BalanceDisplayMode.displayableBalance;
+
+  @computed
+  ThemeBase get theme => _settingsStore.currentTheme;
+
+  @action
+  void setBalanceDisplayMode(BalanceDisplayMode value) =>
+      _settingsStore.balanceDisplayMode = value;
+
+  @action
+  void setShouldDisplayBalance(bool value){
+  if (value) {
+    _settingsStore.balanceDisplayMode = BalanceDisplayMode.displayableBalance;
+    } else {
+    _settingsStore.balanceDisplayMode = BalanceDisplayMode.hiddenBalance;
+    }
+  }
+
+  @action
+  void onLanguageSelected (String code) {
+    _settingsStore.languageCode = code;
+  }
+
+  @action
+  void setTheme(ThemeBase newTheme){
+     _settingsStore.currentTheme = newTheme;
+  }
+
+  @action
+  void setFiatCurrency(FiatCurrency value) =>
+      _settingsStore.fiatCurrency = value;
+
+}
\ No newline at end of file
diff --git a/lib/view_model/settings/other_settings_view_model.dart b/lib/view_model/settings/other_settings_view_model.dart
new file mode 100644
index 000000000..b0ba4c9b5
--- /dev/null
+++ b/lib/view_model/settings/other_settings_view_model.dart
@@ -0,0 +1,72 @@
+import 'package:cake_wallet/bitcoin/bitcoin.dart';
+import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
+import 'package:cake_wallet/store/settings_store.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/transaction_priority.dart';
+import 'package:cw_core/wallet_base.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:mobx/mobx.dart';
+import 'package:package_info/package_info.dart';
+
+part 'other_settings_view_model.g.dart';
+
+class OtherSettingsViewModel = OtherSettingsViewModelBase
+    with _$OtherSettingsViewModel;
+
+
+abstract class OtherSettingsViewModelBase with Store {
+  OtherSettingsViewModelBase(this._settingsStore,  WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
+              TransactionInfo>
+          wallet):
+  walletType = wallet.type,
+  _wallet = wallet,
+  currentVersion = ''{
+     PackageInfo.fromPlatform().then(
+        (PackageInfo packageInfo) => currentVersion = packageInfo.version);
+
+    final priority = _settingsStore.priority[wallet.type];
+    final priorities = priorityForWalletType(wallet.type);
+
+    if (!priorities.contains(priority)) {
+      _settingsStore.priority[wallet.type] = priorities.first;
+  }
+
+   }
+
+     final WalletType walletType;
+  final  WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
+              TransactionInfo> _wallet;
+
+  @observable
+  String currentVersion;
+
+  final SettingsStore _settingsStore;
+
+  @computed
+  TransactionPriority get transactionPriority {
+    final priority = _settingsStore.priority[walletType];
+
+    if (priority == null) {
+      throw Exception('Unexpected type ${walletType.toString()}');
+    }
+
+    return priority;
+  }
+
+   String getDisplayPriority(dynamic priority) {
+    final _priority = priority as TransactionPriority;
+
+    if (_wallet.type == WalletType.bitcoin
+        || _wallet.type == WalletType.litecoin) {
+      final rate = bitcoin!.getFeeRate(_wallet, _priority);
+      return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate);
+    }
+
+    return priority.toString();
+  }
+
+  void onDisplayPrioritySelected(TransactionPriority priority) =>
+    _settingsStore.priority[_wallet.type] = priority;
+}
\ No newline at end of file
diff --git a/lib/view_model/settings/privacy_settings_view_model.dart b/lib/view_model/settings/privacy_settings_view_model.dart
new file mode 100644
index 000000000..2ea816724
--- /dev/null
+++ b/lib/view_model/settings/privacy_settings_view_model.dart
@@ -0,0 +1,21 @@
+import 'package:cake_wallet/store/settings_store.dart';
+import 'package:mobx/mobx.dart';
+
+part 'privacy_settings_view_model.g.dart';
+
+class PrivacySettingsViewModel = PrivacySettingsViewModelBase
+    with _$PrivacySettingsViewModel;
+
+abstract class PrivacySettingsViewModelBase with Store {
+  PrivacySettingsViewModelBase(this._settingsStore);
+
+  final SettingsStore _settingsStore;
+
+  @computed
+  bool get shouldSaveRecipientAddress =>
+      _settingsStore.shouldSaveRecipientAddress;
+
+  @action
+  void setShouldSaveRecipientAddress(bool value) =>
+      _settingsStore.shouldSaveRecipientAddress = value;
+}
\ No newline at end of file
diff --git a/lib/view_model/settings/security_settings_view_model.dart b/lib/view_model/settings/security_settings_view_model.dart
new file mode 100644
index 000000000..9bf2fb6eb
--- /dev/null
+++ b/lib/view_model/settings/security_settings_view_model.dart
@@ -0,0 +1,29 @@
+import 'package:cake_wallet/entities/biometric_auth.dart';
+import 'package:cake_wallet/store/settings_store.dart';
+import 'package:mobx/mobx.dart';
+
+part 'security_settings_view_model.g.dart';
+
+class SecuritySettingsViewModel = SecuritySettingsViewModelBase
+    with _$SecuritySettingsViewModel;
+
+abstract class SecuritySettingsViewModelBase with Store {
+  SecuritySettingsViewModelBase(this._settingsStore): _biometricAuth = BiometricAuth();
+
+  final BiometricAuth _biometricAuth;
+  final SettingsStore _settingsStore;
+  
+  @computed
+  bool get allowBiometricalAuthentication =>
+      _settingsStore.allowBiometricalAuthentication;
+
+  @action
+  Future<bool> biometricAuthenticated()async{
+   return await _biometricAuth.canCheckBiometrics() && await _biometricAuth.isAuthenticated();
+  }
+
+  @action
+  void setAllowBiometricalAuthentication(bool value) =>
+      _settingsStore.allowBiometricalAuthentication = value;
+
+}
\ No newline at end of file
diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart
index 7783cd200..1f34d5374 100644
--- a/lib/view_model/settings/settings_view_model.dart
+++ b/lib/view_model/settings/settings_view_model.dart
@@ -1,6 +1,6 @@
+import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
 import 'package:cake_wallet/store/yat/yat_store.dart';
 import 'package:mobx/mobx.dart';
-import 'package:package_info/package_info.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/entities/biometric_auth.dart';
@@ -22,21 +22,6 @@ part 'settings_view_model.g.dart';
 
 class SettingsViewModel = SettingsViewModelBase with _$SettingsViewModel;
 
-List<TransactionPriority> priorityForWalletType(WalletType type) {
-  switch (type) {
-    case WalletType.monero:
-      return monero!.getTransactionPriorities();
-    case WalletType.bitcoin:
-      return bitcoin!.getTransactionPriorities();
-    case WalletType.litecoin:
-      return bitcoin!.getLitecoinTransactionPriorities();
-    case WalletType.haven:
-      return haven!.getTransactionPriorities();
-    default:
-      return [];
-  }
-}
-
 abstract class SettingsViewModelBase with Store {
   SettingsViewModelBase(
       this._settingsStore,
@@ -46,12 +31,8 @@ abstract class SettingsViewModelBase with Store {
           wallet)
       : itemHeaders = {},
         walletType = wallet.type,
-        _wallet = wallet,
-        _biometricAuth = BiometricAuth(),
-        currentVersion = '' {
-    PackageInfo.fromPlatform().then(
-        (PackageInfo packageInfo) => currentVersion = packageInfo.version);
-
+        _wallet = wallet{
+  
     final priority = _settingsStore.priority[wallet.type];
     final priorities = priorityForWalletType(wallet.type);
 
@@ -85,18 +66,9 @@ abstract class SettingsViewModelBase with Store {
 
   }
 
-  @observable
-  String currentVersion;
-
-  @computed
-  Node get node => _settingsStore.getCurrentNode(walletType);
-
   @computed
   FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency;
 
-  @computed
-  String get languageCode => _settingsStore.languageCode;
-
   @computed
   ObservableList<ActionListDisplayMode> get actionlistDisplayMode =>
       _settingsStore.actionlistDisplayMode;
@@ -112,21 +84,6 @@ abstract class SettingsViewModelBase with Store {
     return priority;
   }
 
-  @computed
-  BalanceDisplayMode get balanceDisplayMode =>
-      _settingsStore.balanceDisplayMode;
-
-  @computed
-  bool get shouldDisplayBalance => balanceDisplayMode == BalanceDisplayMode.displayableBalance;
-
-  @computed
-  bool get shouldSaveRecipientAddress =>
-      _settingsStore.shouldSaveRecipientAddress;
-
-  @computed
-  bool get allowBiometricalAuthentication =>
-      _settingsStore.allowBiometricalAuthentication;
-
   @computed
   ThemeBase get theme => _settingsStore.currentTheme;
 
@@ -136,26 +93,13 @@ abstract class SettingsViewModelBase with Store {
   final SettingsStore _settingsStore;
   final YatStore _yatStore;
   final WalletType walletType;
-  final BiometricAuth _biometricAuth;
   final  WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
               TransactionInfo> _wallet;
 
-  @action
-  void setBalanceDisplayMode(BalanceDisplayMode value) =>
-      _settingsStore.balanceDisplayMode = value;
-
   @action
   void setFiatCurrency(FiatCurrency value) =>
       _settingsStore.fiatCurrency = value;
 
-  @action
-  void setShouldSaveRecipientAddress(bool value) =>
-      _settingsStore.shouldSaveRecipientAddress = value;
-
-  @action
-  void setAllowBiometricalAuthentication(bool value) =>
-      _settingsStore.allowBiometricalAuthentication = value;
-
   @action
   void toggleTransactionsDisplay() =>
       actionlistDisplayMode.contains(ActionListDisplayMode.transactions)
@@ -183,43 +127,4 @@ abstract class SettingsViewModelBase with Store {
   @action
   void _showTrades() => actionlistDisplayMode.add(ActionListDisplayMode.trades);
 
-  @action
-  Future<bool> biometricAuthenticated()async{
-   return await _biometricAuth.canCheckBiometrics() && await _biometricAuth.isAuthenticated();
-  }
-
-  @action
-  void onLanguageSelected (String code) {
-    _settingsStore.languageCode = code;
-  }
-
-  @action
-  void setTheme(ThemeBase newTheme){
-     _settingsStore.currentTheme = newTheme;
-  }
-
-  @action
-  void setShouldDisplayBalance(bool value){
-  if (value) {
-    _settingsStore.balanceDisplayMode = BalanceDisplayMode.displayableBalance;
-    } else {
-    _settingsStore.balanceDisplayMode = BalanceDisplayMode.hiddenBalance;
-    }
-  }
-
-  String getDisplayPriority(dynamic priority) {
-    final _priority = priority as TransactionPriority;
-
-    if (_wallet.type == WalletType.bitcoin
-        || _wallet.type == WalletType.litecoin) {
-      final rate = bitcoin!.getFeeRate(_wallet, _priority);
-      return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate);
-    }
-
-    return priority.toString();
-  }
-
-  void onDisplayPrioritySelected(TransactionPriority priority) =>
-    _settingsStore.priority[_wallet.type] = priority;
-
 }

From 3acbfbae796e16aa5a613a55f19dfe4815277665 Mon Sep 17 00:00:00 2001
From: Godwin Asuquo <godilite@gmail.com>
Date: Fri, 25 Nov 2022 22:51:07 +0200
Subject: [PATCH 21/61] Fix issues from code review

---
 lib/di.dart                                   |  23 +---
 lib/src/screens/send/send_page.dart           |  11 +-
 .../settings/display_settings_page.dart       |  20 +--
 .../screens/settings/other_settings_page.dart |  14 +-
 lib/src/screens/settings/privacy_page.dart    |  25 +++-
 .../settings/security_backup_page.dart        |  15 +--
 .../exchange/exchange_view_model.dart         |  25 +++-
 lib/view_model/send/send_view_model.dart      |  22 +++-
 .../settings/privacy_settings_view_model.dart |   7 +
 .../settings/settings_view_model.dart         | 124 ------------------
 10 files changed, 94 insertions(+), 192 deletions(-)
 delete mode 100644 lib/view_model/settings/settings_view_model.dart

diff --git a/lib/di.dart b/lib/di.dart
index 2edb9057e..ce2e2a7d8 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -123,7 +123,6 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_v
 import 'package:cake_wallet/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart';
 import 'package:cake_wallet/view_model/monero_account_list/monero_account_list_view_model.dart';
 import 'package:cake_wallet/view_model/send/send_view_model.dart';
-import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
 import 'package:cake_wallet/view_model/wallet_keys_view_model.dart';
 import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
 import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
@@ -385,8 +384,7 @@ Future setup(
       _transactionDescriptionBox));
 
   getIt.registerFactory(
-      () => SendPage(sendViewModel: getIt.get<SendViewModel>(),
-          settingsViewModel: getIt.get<SettingsViewModel>()));
+      () => SendPage(sendViewModel: getIt.get<SendViewModel>()));
 
   getIt.registerFactory(() => SendTemplatePage(
       sendTemplateViewModel: getIt.get<SendTemplateViewModel>()));
@@ -442,29 +440,19 @@ Future setup(
               getIt.get<MoneroAccountEditOrCreateViewModel>(param1: account)));
 
   getIt.registerFactory(() {
-    final appStore = getIt.get<AppStore>();
-    final yatStore = getIt.get<YatStore>();
-    return SettingsViewModel(appStore.settingsStore, yatStore, appStore.wallet!);
+    return DisplaySettingsViewModel(getIt.get<SettingsStore>());
   });
 
   getIt.registerFactory(() {
-    final appStore = getIt.get<AppStore>();
-    return DisplaySettingsViewModel(appStore.settingsStore);
+    return PrivacySettingsViewModel(getIt.get<SettingsStore>());
   });
 
   getIt.registerFactory(() {
-    final appStore = getIt.get<AppStore>();
-    return PrivacySettingsViewModel(appStore.settingsStore);
+    return OtherSettingsViewModel(getIt(), getIt());
   });
 
   getIt.registerFactory(() {
-    final appStore = getIt.get<AppStore>();
-    return OtherSettingsViewModel(appStore.settingsStore, appStore.wallet!);
-  });
-
-  getIt.registerFactory(() {
-    final appStore = getIt.get<AppStore>();
-    return SecuritySettingsViewModel(appStore.settingsStore);
+    return SecuritySettingsViewModel(getIt.get<SettingsStore>());
   });
 
   getIt
@@ -530,7 +518,6 @@ Future setup(
       getIt.get<TradesStore>(),
       getIt.get<AppStore>().settingsStore,
       getIt.get<SharedPreferences>(),
-      getIt.get<SettingsViewModel>(),
   ));
 
   getIt.registerFactory(() => ExchangeTradeViewModel(
diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart
index e0cfff517..b051a3afb 100644
--- a/lib/src/screens/send/send_page.dart
+++ b/lib/src/screens/send/send_page.dart
@@ -1,4 +1,3 @@
-import 'dart:ui';
 import 'package:cake_wallet/entities/fiat_currency.dart';
 import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart';
 import 'package:cake_wallet/src/screens/send/widgets/send_card.dart';
@@ -6,8 +5,6 @@ import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
 import 'package:cake_wallet/src/widgets/picker.dart';
 import 'package:cake_wallet/src/widgets/template_tile.dart';
 import 'package:cake_wallet/view_model/send/output.dart';
-import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
-import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 import 'package:mobx/mobx.dart';
@@ -28,13 +25,11 @@ import 'package:smooth_page_indicator/smooth_page_indicator.dart';
 import 'package:cw_core/crypto_currency.dart';
 
 class SendPage extends BasePage {
-  SendPage({required this.sendViewModel,required this.settingsViewModel }) : _formKey = GlobalKey<FormState>(),fiatFromSettings = settingsViewModel.fiatCurrency;
+  SendPage({required this.sendViewModel}) : _formKey = GlobalKey<FormState>();
 
   final SendViewModel sendViewModel;
-  final SettingsViewModel settingsViewModel;
   final GlobalKey<FormState> _formKey;
   final controller = PageController(initialPage: 0);
-  final FiatCurrency fiatFromSettings ;
 
   bool _effectsInstalled = false;
 
@@ -55,7 +50,7 @@ class SendPage extends BasePage {
 
   @override
   void onClose(BuildContext context) {
-    settingsViewModel.setFiatCurrency(fiatFromSettings);
+    sendViewModel.onClose();
     Navigator.of(context).pop();
   }
 
@@ -236,7 +231,7 @@ class SendPage extends BasePage {
                                   if(template.isCurrencySelected){
                                     output.setCryptoAmount(template.amount);
                                   }else{
-                                    settingsViewModel.setFiatCurrency(fiatFromTemplate);
+                                    sendViewModel.setFiatCurrency(fiatFromTemplate);
                                     output.setFiatAmount(template.amountFiat);
                                   }
                                   output.resetParsedAddress();
diff --git a/lib/src/screens/settings/display_settings_page.dart b/lib/src/screens/settings/display_settings_page.dart
index fd26da1c4..cd413ff45 100644
--- a/lib/src/screens/settings/display_settings_page.dart
+++ b/lib/src/screens/settings/display_settings_page.dart
@@ -14,12 +14,12 @@ import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 
 class DisplaySettingsPage extends BasePage {
-  DisplaySettingsPage(this.settingsViewModel);
+  DisplaySettingsPage(this._displaySettingsViewModel);
 
   @override
   String get title => S.current.display_settings;
 
-  final DisplaySettingsViewModel settingsViewModel;
+  final DisplaySettingsViewModel _displaySettingsViewModel;
 
   @override
   Widget body(BuildContext context) {
@@ -30,17 +30,17 @@ class DisplaySettingsPage extends BasePage {
           children: [
             SettingsSwitcherCell(
             title: S.current.settings_display_balance,
-            value:  settingsViewModel.shouldDisplayBalance,
+            value:  _displaySettingsViewModel.shouldDisplayBalance,
             onValueChange: (_, bool value) {
-               settingsViewModel.setShouldDisplayBalance(value);          
+               _displaySettingsViewModel.setShouldDisplayBalance(value);          
             }),
             if (!isHaven)
               SettingsPickerCell<FiatCurrency>(
                 title: S.current.settings_currency,
                 searchHintText: S.current.search_currency,
                 items: FiatCurrency.all,
-                selectedItem: settingsViewModel.fiatCurrency,
-                onItemSelected: (FiatCurrency currency) => settingsViewModel.setFiatCurrency(currency),
+                selectedItem: _displaySettingsViewModel.fiatCurrency,
+                onItemSelected: (FiatCurrency currency) => _displaySettingsViewModel.setFiatCurrency(currency),
                 images: FiatCurrency.all.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png")).toList(),
                 isGridView: true,
                 matchingCriteria: (FiatCurrency currency, String searchText) {
@@ -55,8 +55,8 @@ class DisplaySettingsPage extends BasePage {
               displayItem: (dynamic code) {
                 return LanguageService.list[code] ?? '';
               },
-              selectedItem: settingsViewModel.languageCode,
-              onItemSelected: settingsViewModel.onLanguageSelected,
+              selectedItem: _displaySettingsViewModel.languageCode,
+              onItemSelected: _displaySettingsViewModel.onLanguageSelected,
               images: LanguageService.list.keys
                   .map((e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
                   .toList(),
@@ -68,8 +68,8 @@ class DisplaySettingsPage extends BasePage {
               ChoicesListItem<ThemeBase>(
                 title: S.current.color_theme,
                 items: ThemeList.all,
-                selectedItem: settingsViewModel.theme,
-                onItemSelected: (ThemeBase theme) => settingsViewModel.setTheme(theme),
+                selectedItem: _displaySettingsViewModel.theme,
+                onItemSelected: (ThemeBase theme) => _displaySettingsViewModel.setTheme(theme),
               ),
             ),
           ],
diff --git a/lib/src/screens/settings/other_settings_page.dart b/lib/src/screens/settings/other_settings_page.dart
index 01bd861b1..e055e2e8e 100644
--- a/lib/src/screens/settings/other_settings_page.dart
+++ b/lib/src/screens/settings/other_settings_page.dart
@@ -11,12 +11,12 @@ import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 
 class OtherSettingsPage extends BasePage {
-  OtherSettingsPage(this._settingsViewModel);
+  OtherSettingsPage(this._otherSettingsViewModel);
 
   @override
   String get title => S.current.other_settings;
 
-  final OtherSettingsViewModel _settingsViewModel;
+  final OtherSettingsViewModel _otherSettingsViewModel;
 
   @override
   Widget body(BuildContext context) {
@@ -26,10 +26,10 @@ class OtherSettingsPage extends BasePage {
         child: Column(children: [
           SettingsPickerCell(
             title: S.current.settings_fee_priority,
-            items: priorityForWalletType(_settingsViewModel.walletType),
-            displayItem: _settingsViewModel.getDisplayPriority,
-            selectedItem: _settingsViewModel.transactionPriority,
-            onItemSelected: _settingsViewModel.onDisplayPrioritySelected,
+            items: priorityForWalletType(_otherSettingsViewModel.walletType),
+            displayItem: _otherSettingsViewModel.getDisplayPriority,
+            selectedItem: _otherSettingsViewModel.transactionPriority,
+            onItemSelected: _otherSettingsViewModel.onDisplayPrioritySelected,
           ),
           SettingsCellWithArrow(
             title: S.current.settings_terms_and_conditions,
@@ -37,7 +37,7 @@ class OtherSettingsPage extends BasePage {
           ),
           StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
           Spacer(),
-          SettingsVersionCell(title: S.of(context).version(_settingsViewModel.currentVersion))
+          SettingsVersionCell(title: S.of(context).version(_otherSettingsViewModel.currentVersion))
         ]),
       );
     });
diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart
index 08ab945cc..47041b4fb 100644
--- a/lib/src/screens/settings/privacy_page.dart
+++ b/lib/src/screens/settings/privacy_page.dart
@@ -6,24 +6,37 @@ import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 
 class PrivacyPage extends BasePage {
-  PrivacyPage(this.settingsViewModel);
+  PrivacyPage(this._privacySettingsViewModel);
 
   @override
   String get title => S.current.privacy_settings;
 
-  final PrivacySettingsViewModel settingsViewModel;
+  final PrivacySettingsViewModel _privacySettingsViewModel;
 
   @override
   Widget body(BuildContext context) {
     return Container(
       padding: EdgeInsets.only(top: 10),
       child: Observer(builder: (_) {
-        return SettingsSwitcherCell(
+        return Observer(builder: (_) {
+        return Column(
+          mainAxisSize: MainAxisSize.min, 
+          children: [
+             SettingsSwitcherCell(
+              title: S.current.disable_exchange,
+              value: _privacySettingsViewModel.disableExchange,
+              onValueChange: (BuildContext context, bool value) {
+                _privacySettingsViewModel.setEnableExchange(value);
+            }),
+            SettingsSwitcherCell(
             title: S.current.settings_save_recipient_address,
-            value: settingsViewModel.shouldSaveRecipientAddress,
+            value: _privacySettingsViewModel.shouldSaveRecipientAddress,
             onValueChange: (BuildContext _, bool value) {
-              settingsViewModel.setShouldSaveRecipientAddress(value);
-            });
+              _privacySettingsViewModel.setShouldSaveRecipientAddress(value);
+            })         
+          ],
+        );
+      });
       }),
     );
   }
diff --git a/lib/src/screens/settings/security_backup_page.dart b/lib/src/screens/settings/security_backup_page.dart
index 633450313..224c941ee 100644
--- a/lib/src/screens/settings/security_backup_page.dart
+++ b/lib/src/screens/settings/security_backup_page.dart
@@ -7,17 +7,16 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arro
 import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
 import 'package:cake_wallet/src/widgets/standard_list.dart';
 import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart';
-import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 
 class SecurityBackupPage extends BasePage {
-  SecurityBackupPage(this.settingsViewModel);
+  SecurityBackupPage(this._securitySettingsViewModel);
 
   @override
   String get title => S.current.security_and_backup;
 
-  final SecuritySettingsViewModel settingsViewModel;
+  final SecuritySettingsViewModel _securitySettingsViewModel;
 
   @override
   Widget body(BuildContext context) {
@@ -59,23 +58,23 @@ class SecurityBackupPage extends BasePage {
         Observer(builder: (_) {
           return SettingsSwitcherCell(
               title: S.current.settings_allow_biometrical_authentication,
-              value: settingsViewModel.allowBiometricalAuthentication,
+              value: _securitySettingsViewModel.allowBiometricalAuthentication,
               onValueChange: (BuildContext context, bool value) {
                 if (value) {
                   Navigator.of(context).pushNamed(Routes.auth,
                       arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
                     if (isAuthenticatedSuccessfully) {
-                      if (await settingsViewModel.biometricAuthenticated()) {
-                        settingsViewModel.setAllowBiometricalAuthentication(isAuthenticatedSuccessfully);
+                      if (await _securitySettingsViewModel.biometricAuthenticated()) {
+                        _securitySettingsViewModel.setAllowBiometricalAuthentication(isAuthenticatedSuccessfully);
                       }
                     } else {
-                      settingsViewModel.setAllowBiometricalAuthentication(isAuthenticatedSuccessfully);
+                      _securitySettingsViewModel.setAllowBiometricalAuthentication(isAuthenticatedSuccessfully);
                     }
 
                     auth.close();
                   });
                 } else {
-                  settingsViewModel.setAllowBiometricalAuthentication(value);
+                  _securitySettingsViewModel.setAllowBiometricalAuthentication(value);
                 }
               });
         }),
diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart
index 725208324..68947d170 100644
--- a/lib/view_model/exchange/exchange_view_model.dart
+++ b/lib/view_model/exchange/exchange_view_model.dart
@@ -6,8 +6,8 @@ import 'package:cake_wallet/entities/preferences_key.dart';
 import 'package:cake_wallet/exchange/sideshift/sideshift_exchange_provider.dart';
 import 'package:cake_wallet/exchange/sideshift/sideshift_request.dart';
 import 'package:cake_wallet/exchange/simpleswap/simpleswap_exchange_provider.dart';
-import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
 import 'package:cake_wallet/exchange/simpleswap/simpleswap_request.dart';
+import 'package:cw_core/transaction_priority.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/sync_status.dart';
@@ -42,7 +42,7 @@ class ExchangeViewModel = ExchangeViewModelBase with _$ExchangeViewModel;
 
 abstract class ExchangeViewModelBase with Store {
   ExchangeViewModelBase(this.wallet, this.trades, this._exchangeTemplateStore,
-      this.tradesStore, this._settingsStore, this.sharedPreferences, this._settingsViewModel)
+      this.tradesStore, this._settingsStore, this.sharedPreferences)
     : _cryptoNumberFormat = NumberFormat(),
       isReverse = false,
       isFixedRateMode = false,
@@ -189,6 +189,19 @@ abstract class ExchangeViewModelBase with Store {
   ObservableList<ExchangeTemplate> get templates =>
       _exchangeTemplateStore.templates;
 
+  
+  @computed
+  TransactionPriority get transactionPriority {
+    final priority = _settingsStore.priority[wallet.type];
+
+    if (priority == null) {
+      throw Exception('Unexpected type ${wallet.type.toString()}');
+    }
+
+    return priority;
+  }
+
+
   bool get hasAllAmount =>
       wallet.type == WalletType.bitcoin && depositCurrency == wallet.currency;
 
@@ -198,11 +211,11 @@ abstract class ExchangeViewModelBase with Store {
     switch (wallet.type) {
       case WalletType.monero:
       case WalletType.haven:
-        return _settingsViewModel.transactionPriority == monero!.getMoneroTransactionPrioritySlow();
+        return transactionPriority == monero!.getMoneroTransactionPrioritySlow();
       case WalletType.bitcoin:
-        return _settingsViewModel.transactionPriority == bitcoin!.getBitcoinTransactionPrioritySlow();
+        return transactionPriority == bitcoin!.getBitcoinTransactionPrioritySlow();
       case WalletType.litecoin:
-        return _settingsViewModel.transactionPriority == bitcoin!.getLitecoinTransactionPrioritySlow();
+        return transactionPriority == bitcoin!.getLitecoinTransactionPrioritySlow();
       default:
         return false;
     }
@@ -220,8 +233,6 @@ abstract class ExchangeViewModelBase with Store {
 
   final SettingsStore _settingsStore;
 
-  final SettingsViewModel _settingsViewModel;
-
   double _bestRate = 0.0;
 
   late Timer bestRateSync;
diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart
index c673c452d..25a5cc7ee 100644
--- a/lib/view_model/send/send_view_model.dart
+++ b/lib/view_model/send/send_view_model.dart
@@ -42,7 +42,8 @@ abstract class SendViewModelBase with Store {
       : state = InitialExecutionState(),
         currencies = _wallet.balance.keys.toList(),
         selectedCryptoCurrency = _wallet.currency,
-        outputs = ObservableList<Output>() {
+        outputs = ObservableList<Output>(),
+        fiatFromSettings = _settingsStore.fiatCurrency {
     final priority = _settingsStore.priority[_wallet.type];
     final priorities = priorityForWalletType(_wallet.type);
 
@@ -52,7 +53,7 @@ abstract class SendViewModelBase with Store {
     
     outputs.add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
   }
-
+  
   @observable
   ExecutionState state;
 
@@ -133,11 +134,13 @@ abstract class SendViewModelBase with Store {
 
   Validator get textValidator => TextValidator();
 
+  final FiatCurrency fiatFromSettings;
+
   @observable
   PendingTransaction? pendingTransaction;
 
   @computed
-  String get balance => balanceViewModel.availableBalance ?? '0.0';
+  String get balance => balanceViewModel.availableBalance;
 
   @computed
   bool get isReadyForSend => _wallet.syncStatus is SyncedSyncStatus;
@@ -166,6 +169,9 @@ abstract class SendViewModelBase with Store {
 
   bool get hasCurrecyChanger => walletType == WalletType.haven;
 
+  @computed
+  FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency;
+
   final WalletBase _wallet;
   final SettingsStore _settingsStore;
   final SendTemplateViewModel sendTemplateViewModel;
@@ -208,7 +214,7 @@ abstract class SendViewModelBase with Store {
       state = TransactionCommitting();
       await pendingTransaction!.commit();
 
-      if (pendingTransaction!.id?.isNotEmpty ?? false) {
+      if (pendingTransaction!.id.isNotEmpty) {
         _settingsStore.shouldSaveRecipientAddress
             ? await transactionDescriptionBox.add(TransactionDescription(
                 id: pendingTransaction!.id,
@@ -283,4 +289,12 @@ abstract class SendViewModelBase with Store {
 
   bool _isEqualCurrency(String currency) => 
       currency.toLowerCase() == _wallet.currency.title.toLowerCase();
+
+  @action
+  void onClose() =>
+      _settingsStore.fiatCurrency = fiatFromSettings;
+  
+  @action
+  void setFiatCurrency(FiatCurrency fiat) =>
+      _settingsStore.fiatCurrency = fiat;
 }
diff --git a/lib/view_model/settings/privacy_settings_view_model.dart b/lib/view_model/settings/privacy_settings_view_model.dart
index 2ea816724..8433e673a 100644
--- a/lib/view_model/settings/privacy_settings_view_model.dart
+++ b/lib/view_model/settings/privacy_settings_view_model.dart
@@ -11,6 +11,9 @@ abstract class PrivacySettingsViewModelBase with Store {
 
   final SettingsStore _settingsStore;
 
+  @computed
+  bool get disableExchange => _settingsStore.disableExchange;
+
   @computed
   bool get shouldSaveRecipientAddress =>
       _settingsStore.shouldSaveRecipientAddress;
@@ -18,4 +21,8 @@ abstract class PrivacySettingsViewModelBase with Store {
   @action
   void setShouldSaveRecipientAddress(bool value) =>
       _settingsStore.shouldSaveRecipientAddress = value;
+  
+  @action
+  void setEnableExchange(bool value) =>
+      _settingsStore.disableExchange = value;
 }
\ No newline at end of file
diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart
deleted file mode 100644
index d5de8be67..000000000
--- a/lib/view_model/settings/settings_view_model.dart
+++ /dev/null
@@ -1,124 +0,0 @@
-import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
-import 'package:cake_wallet/store/yat/yat_store.dart';
-import 'package:mobx/mobx.dart';
-import 'package:cw_core/wallet_base.dart';
-import 'package:cake_wallet/store/settings_store.dart';
-import 'package:cw_core/wallet_type.dart';
-import 'package:cake_wallet/entities/fiat_currency.dart';
-import 'package:cake_wallet/entities/action_list_display_mode.dart';
-import 'package:cw_core/transaction_history.dart';
-import 'package:cw_core/balance.dart';
-import 'package:cw_core/transaction_info.dart';
-import 'package:cw_core/transaction_priority.dart';
-import 'package:cake_wallet/themes/theme_base.dart';
-
-part 'settings_view_model.g.dart';
-
-class SettingsViewModel = SettingsViewModelBase with _$SettingsViewModel;
-
-abstract class SettingsViewModelBase with Store {
-  SettingsViewModelBase(
-      this._settingsStore,
-      this._yatStore,
-      WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
-              TransactionInfo>
-          wallet)
-      : itemHeaders = {},
-        walletType = wallet.type,
-        _wallet = wallet{
-  
-    final priority = _settingsStore.priority[wallet.type];
-    final priorities = priorityForWalletType(wallet.type);
-
-    if (!priorities.contains(priority)) {
-      _settingsStore.priority[wallet.type] = priorities.first;
-    }
-
-    //var connectYatUrl = YatLink.baseUrl + YatLink.signInSuffix;
-    //final connectYatUrlParameters =
-    //    _yatStore.defineQueryParameters();
-
-    //if (connectYatUrlParameters.isNotEmpty) {
-    //  connectYatUrl += YatLink.queryParameter + connectYatUrlParameters;
-    //}
-
-    //var manageYatUrl = YatLink.baseUrl + YatLink.managePath;
-    //final manageYatUrlParameters =
-    //    _yatStore.defineQueryParameters();
-
-    //if (manageYatUrlParameters.isNotEmpty) {
-    //  manageYatUrl += YatLink.queryParameter + manageYatUrlParameters;
-    //}
-
-    //var createNewYatUrl = YatLink.startFlowUrl;
-    //final createNewYatUrlParameters =
-    //    _yatStore.defineQueryParameters();
-
-    //if (createNewYatUrlParameters.isNotEmpty) {
-    //  createNewYatUrl += '?sub1=' + createNewYatUrlParameters;
-    //}
-
-  }
-
-  @computed
-  FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency;
-
-  @computed
-  ObservableList<ActionListDisplayMode> get actionlistDisplayMode =>
-      _settingsStore.actionlistDisplayMode;
-
-  @computed
-  TransactionPriority get transactionPriority {
-    final priority = _settingsStore.priority[walletType];
-
-    if (priority == null) {
-      throw Exception('Unexpected type ${walletType.toString()}');
-    }
-
-    return priority;
-  }
-
-  @computed
-  ThemeBase get theme => _settingsStore.currentTheme;
-
-  bool get isBitcoinBuyEnabled => _settingsStore.isBitcoinBuyEnabled;
-
-  final Map<String, String> itemHeaders;
-  final SettingsStore _settingsStore;
-  final YatStore _yatStore;
-  final WalletType walletType;
-  final  WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
-              TransactionInfo> _wallet;
-
-  @action
-  void setFiatCurrency(FiatCurrency value) =>
-      _settingsStore.fiatCurrency = value;
-
-  @action
-  void toggleTransactionsDisplay() =>
-      actionlistDisplayMode.contains(ActionListDisplayMode.transactions)
-          ? _hideTransaction()
-          : _showTransaction();
-
-  @action
-  void toggleTradesDisplay() =>
-      actionlistDisplayMode.contains(ActionListDisplayMode.trades)
-          ? _hideTrades()
-          : _showTrades();
-
-  @action
-  void _hideTransaction() =>
-      actionlistDisplayMode.remove(ActionListDisplayMode.transactions);
-
-  @action
-  void _hideTrades() =>
-      actionlistDisplayMode.remove(ActionListDisplayMode.trades);
-
-  @action
-  void _showTransaction() =>
-      actionlistDisplayMode.add(ActionListDisplayMode.transactions);
-
-  @action
-  void _showTrades() => actionlistDisplayMode.add(ActionListDisplayMode.trades);
-
-}

From 08edd4d8fff65ba368317f78109d68fbd94f4c8a Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Sat, 26 Nov 2022 02:33:37 +0200
Subject: [PATCH 22/61] Add types for OtherSettingsViewModel dependencies

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

diff --git a/lib/di.dart b/lib/di.dart
index ce2e2a7d8..6248a2c1a 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -448,7 +448,7 @@ Future setup(
   });
 
   getIt.registerFactory(() {
-    return OtherSettingsViewModel(getIt(), getIt());
+    return OtherSettingsViewModel(getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!);
   });
 
   getIt.registerFactory(() {

From 0188089bd8d3656ea262200681dfbc404fee6851 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Sat, 26 Nov 2022 14:07:01 +0200
Subject: [PATCH 23/61] Remove unused nodes list page route

---
 lib/di.dart                                | 2 --
 lib/router.dart                            | 4 ----
 lib/routes.dart                            | 1 -
 lib/src/screens/nodes/nodes_list_page.dart | 2 ++
 4 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/lib/di.dart b/lib/di.dart
index 6248a2c1a..9245e58ca 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -489,8 +489,6 @@ Future setup(
         _nodeSource, appStore.wallet!, appStore.settingsStore);
   });
 
-  getIt.registerFactory(() => NodeListPage(getIt.get<NodeListViewModel>()));
-
   getIt.registerFactory(() => ConnectionSyncPage(getIt.get<NodeListViewModel>(), getIt.get<DashboardViewModel>()));
 
   getIt.registerFactory(() => SecurityBackupPage(getIt.get<SecuritySettingsViewModel>()));
diff --git a/lib/router.dart b/lib/router.dart
index 7818cc52f..f9aa37a02 100644
--- a/lib/router.dart
+++ b/lib/router.dart
@@ -278,10 +278,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
                   param2: false),
               onWillPop: () async => false));
 
-    case Routes.nodeList:
-      return CupertinoPageRoute<void>(
-          builder: (_) => getIt.get<NodeListPage>());
-
     case Routes.connectionSync:
       return CupertinoPageRoute<void>(
           builder: (_) => getIt.get<ConnectionSyncPage>());
diff --git a/lib/routes.dart b/lib/routes.dart
index 04642ba34..d738b13e8 100644
--- a/lib/routes.dart
+++ b/lib/routes.dart
@@ -21,7 +21,6 @@ class Routes {
   static const seedLanguage = '/seed_language';
   static const walletList = '/view_model.wallet_list';
   static const auth = '/auth';
-  static const nodeList = '/node_list';
   static const newNode = '/new_node_list';
   static const login = '/login';
   static const splash = '/splash';
diff --git a/lib/src/screens/nodes/nodes_list_page.dart b/lib/src/screens/nodes/nodes_list_page.dart
index 556a0fd06..4e72c511e 100644
--- a/lib/src/screens/nodes/nodes_list_page.dart
+++ b/lib/src/screens/nodes/nodes_list_page.dart
@@ -23,6 +23,8 @@ class NodeListPage extends BasePage {
 
   @override
   Widget trailing(context) {
+    // TODO: check if this will be used in the new design and then delete the whole page
+    // as it's not used anymore
     return Container(
       height: 32,
       decoration: BoxDecoration(

From 79fb1b91d4b661cba9e1e668f59c9fcf152dc76b Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Sat, 26 Nov 2022 16:13:54 +0200
Subject: [PATCH 24/61] Check for Nodes if exists before adding them in nodes
 Fix nullability issue due to early access Fix Nodes_list,yml file structure

---
 assets/node_list.yml                          |  4 ++--
 lib/entities/default_settings_migration.dart  | 22 +++++++++++++++----
 .../on_authentication_state_change.dart       |  4 ++--
 3 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/assets/node_list.yml b/assets/node_list.yml
index 09fb72383..7962ea18c 100644
--- a/assets/node_list.yml
+++ b/assets/node_list.yml
@@ -22,10 +22,10 @@
 -
   uri: node.imonero.org:18081
   is_default: false
-
+-
   uri: node.c3pool.com:18081
   is_default: false
-  
+-
   uri: xmr.prprpr.icu:18081
   is_default: false
 
diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart
index b2036c3f6..fb404cd88 100644
--- a/lib/entities/default_settings_migration.dart
+++ b/lib/entities/default_settings_migration.dart
@@ -69,6 +69,8 @@ Future defaultSettingsMigration(
               sharedPreferences: sharedPreferences, nodes: nodes);
           await changeLitecoinCurrentElectrumServerToDefault(
               sharedPreferences: sharedPreferences, nodes: nodes);
+          await changeHavenCurrentNodeToDefault(
+              sharedPreferences: sharedPreferences, nodes: nodes);
 
           break;
         case 2:
@@ -277,17 +279,29 @@ Future<void> updateNodeTypes({required Box<Node> nodes}) async {
 
 Future<void> addBitcoinElectrumServerList({required Box<Node> nodes}) async {
   final serverList = await loadBitcoinElectrumServerList();
-  await nodes.addAll(serverList);
+  for (var node in serverList) {
+    if (nodes.values.firstWhereOrNull((element) => element.uriRaw == node.uriRaw) == null) {
+      await nodes.add(node);
+    }
+  }
 }
 
 Future<void> addLitecoinElectrumServerList({required Box<Node> nodes}) async {
   final serverList = await loadLitecoinElectrumServerList();
-  await nodes.addAll(serverList);
+  for (var node in serverList) {
+    if (nodes.values.firstWhereOrNull((element) => element.uriRaw == node.uriRaw) == null) {
+      await nodes.add(node);
+    }
+  }
 }
 
 Future<void> addHavenNodeList({required Box<Node> nodes}) async {
   final nodeList = await loadDefaultHavenNodes();
-  await nodes.addAll(nodeList);
+  for (var node in nodeList) {
+    if (nodes.values.firstWhereOrNull((element) => element.uriRaw == node.uriRaw) == null) {
+      await nodes.add(node);
+    }
+  }
 }
 
 Future<void> addAddressesForMoneroWallets(
@@ -431,7 +445,7 @@ Future<void> resetBitcoinElectrumServer(
   final oldElectrumServer = nodeSource.values.firstWhereOrNull(
       (node) => node.uri.toString().contains('electrumx.cakewallet.com'));
   var cakeWalletNode = nodeSource.values.firstWhereOrNull(
-      (node) => node.uri.toString() == cakeWalletBitcoinElectrumUri);
+      (node) => node.uriRaw.toString() == cakeWalletBitcoinElectrumUri);
 
   if (cakeWalletNode == null) {
     cakeWalletNode =
diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart
index c91f5277e..560326cb5 100644
--- a/lib/reactions/on_authentication_state_change.dart
+++ b/lib/reactions/on_authentication_state_change.dart
@@ -23,12 +23,12 @@ void startAuthenticationStateChange(AuthenticationStore authenticationStore,
     }
 
     if (state == AuthenticationState.allowed) {
-      await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
+      await navigatorKey.currentState?.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
       return;
     }
 
     if (state == AuthenticationState.denied) {
-      await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.welcome, (_) => false);
+      await navigatorKey.currentState?.pushNamedAndRemoveUntil(Routes.welcome, (_) => false);
       return;
     }
   });

From 4d91ef6af8b554f66f68239b8fde46a7be59d7f2 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Sun, 27 Nov 2022 22:10:21 +0200
Subject: [PATCH 25/61] App Center Integration with CI/CD workflow (#644)

Add Ionia client id to secrets
Update how to build android instructions
Change devicelocale version as it caused issues when building
Add trigger for send test build to transfer.sh and notify slack channel
---
 .github/workflows/pr_test_build.yml | 116 ++++++++++++++++++++++++++++
 howto-build-android.md              |   8 +-
 pubspec_base.yaml                   |   2 +-
 tool/utils/secret_key.dart          |   1 +
 4 files changed, 124 insertions(+), 3 deletions(-)
 create mode 100644 .github/workflows/pr_test_build.yml

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
new file mode 100644
index 000000000..dd2f1edeb
--- /dev/null
+++ b/.github/workflows/pr_test_build.yml
@@ -0,0 +1,116 @@
+name: PR Test Build
+
+on:
+  pull_request:
+    branches: [ main ]
+
+jobs:
+  test:
+
+    runs-on: ubuntu-18.04
+
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-java@v1
+        with:
+          java-version: '8.x'
+
+      - name: Flutter action
+        uses: subosito/flutter-action@v1
+        with:
+          flutter-version: '3.3.x'
+          channel: stable
+
+      - name: Install package dependencies
+        run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
+
+      - name: Execute Build and Setup Commands
+        run: |
+          sudo mkdir -p /opt/android
+          sudo chown $USER /opt/android
+          cd /opt/android
+          git clone https://github.com/cake-tech/cake_wallet.git --branch $GITHUB_HEAD_REF
+          cd cake_wallet/scripts/android/
+          ./install_ndk.sh
+          source ./app_env.sh cakewallet
+          ./app_config.sh
+          ./build_all.sh
+          ./copy_monero_deps.sh
+
+      - name: Install Flutter dependencies
+        run: |
+          cd /opt/android/cake_wallet
+          flutter pub get
+
+      - 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 ${{ secrets.STORE_PASS }} -keypass ${{ secrets.KEY_PASS }}
+
+      - name: Generate key properties
+        run: |
+          cd /opt/android/cake_wallet
+          flutter packages pub run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=${{ secrets.STORE_PASS }} keyPassword=${{ secrets.KEY_PASS }}
+
+      - name: Generate localization
+        run: |
+          cd /opt/android/cake_wallet
+          flutter packages pub run tool/generate_localization.dart
+
+      - name: Build generated code
+        run: |
+          cd /opt/android/cake_wallet
+          cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+          cd cw_monero && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+          cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+          cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+          flutter packages pub run build_runner build --delete-conflicting-outputs
+
+      - name: Add secrets
+        run: |
+          cd /opt/android/cake_wallet
+          touch lib/.secrets.g.dart
+          echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
+          echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
+          echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
+          echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
+          echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
+          echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
+          echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
+          echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
+          echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart
+          echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart
+          echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
+          echo "const sideShiftApiKey = '${{ secrets.SIDE_SHIFT_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart
+          echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart
+
+      - name: Build
+        run: |
+          cd /opt/android/cake_wallet
+          flutter build apk --release
+
+#      - name: Push to App Center
+#        run: |
+#          echo 'Installing App Center CLI tools'
+#          npm install -g appcenter-cli
+#          echo "Publishing test to App Center"
+#          appcenter distribute release \
+#              --group "Testers" \
+#              --file "/opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk" \
+#              --release-notes ${GITHUB_HEAD_REF} \
+#              --app Cake-Labs/Cake-Wallet \
+#              --token ${{ secrets.APP_CENTER_TOKEN }} \
+#              --quiet
+
+      - name: Send Test APK
+        run: |
+          cd /opt/android/cake_wallet
+          var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/app-release.apk)
+          curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}'
+
diff --git a/howto-build-android.md b/howto-build-android.md
index 28478cdd1..4ef385b9f 100644
--- a/howto-build-android.md
+++ b/howto-build-android.md
@@ -55,7 +55,7 @@ You may download and install the latest version of Android Studio [here](https:/
 
 ### 3. Installing Flutter
 
-Need to install flutter with version `2.0.4`. For this please check section [Install Flutter manually](https://docs.flutter.dev/get-started/install/linux#install-flutter-manually). When flutter repository is downloaded please open it with `cd <flutter-path>` and checkout version 2.0.4 by `git checkout 2.0.4`.
+Need to install flutter with version `3.x.x`. For this please check section [Install Flutter manually](https://docs.flutter.dev/get-started/install/linux#install-flutter-manually).
 
 ### 4. Verify Installations
 
@@ -66,7 +66,7 @@ Verify that the Android toolchain, Flutter, and Android Studio have been correct
 The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding.
 ```
 Doctor summary (to see all details, run flutter doctor -v):
-[✓] Flutter (Channel stable, 2.0.4, on Linux, locale en_US.UTF-8)
+[✓] Flutter (Channel stable, 3.x.x, on Linux, locale en_US.UTF-8)
 [✓] Android toolchain - develop for Android devices (Android SDK version 28)
 [✓] Android Studio (version 4.0)
 ```
@@ -156,6 +156,10 @@ Generate mobx models for `cw_bitcoin`:
 
 `cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..`
 
+Generate mobx models for `cw_haven`:
+
+`cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..`
+
 Finally build mobx models for the app:
 
 `$ flutter packages pub run build_runner build --delete-conflicting-outputs`
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 248a06de0..00e1a39b1 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -34,7 +34,7 @@ dependencies:
   local_auth: ^2.1.0
   package_info: ^2.0.0
   #package_info_plus: ^1.4.2
-  devicelocale: ^0.5.4
+  devicelocale: ^0.4.3
   auto_size_text: ^3.0.0
   dotted_border: ^2.0.0+2
   smooth_page_indicator: ^1.0.0+2
diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart
index 64c7beefd..e5202a829 100644
--- a/tool/utils/secret_key.dart
+++ b/tool/utils/secret_key.dart
@@ -28,6 +28,7 @@ class SecretKey {
     SecretKey('simpleSwapApiKey', () => ''),
     SecretKey('anypayToken', () => ''),
     SecretKey('onramperApiKey', () => ''),
+    SecretKey('ioniaClientId', () => ''),
   ];
 
   final String name;

From a51384bd067fb4ab17aa469782f38fc044ad00af Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Mon, 28 Nov 2022 14:04:03 +0200
Subject: [PATCH 26/61] Remove unused nodes_list_page.dart

---
 lib/di.dart                                |   1 -
 lib/router.dart                            |   1 -
 lib/src/screens/nodes/nodes_list_page.dart | 168 ---------------------
 3 files changed, 170 deletions(-)
 delete mode 100644 lib/src/screens/nodes/nodes_list_page.dart

diff --git a/lib/di.dart b/lib/di.dart
index 9245e58ca..c62dc9790 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -58,7 +58,6 @@ import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart'
 import 'package:cake_wallet/src/screens/faq/faq_page.dart';
 import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart';
 import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart';
-import 'package:cake_wallet/src/screens/nodes/nodes_list_page.dart';
 import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
 import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
 import 'package:cake_wallet/src/screens/rescan/rescan_page.dart';
diff --git a/lib/router.dart b/lib/router.dart
index f9aa37a02..4d3d61f5f 100644
--- a/lib/router.dart
+++ b/lib/router.dart
@@ -41,7 +41,6 @@ import 'package:cake_wallet/src/screens/dashboard/dashboard_page.dart';
 import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart';
 import 'package:cake_wallet/src/screens/auth/auth_page.dart';
 import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart';
-import 'package:cake_wallet/src/screens/nodes/nodes_list_page.dart';
 import 'package:cake_wallet/src/screens/receive/receive_page.dart';
 import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.dart';
 import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
diff --git a/lib/src/screens/nodes/nodes_list_page.dart b/lib/src/screens/nodes/nodes_list_page.dart
deleted file mode 100644
index 4e72c511e..000000000
--- a/lib/src/screens/nodes/nodes_list_page.dart
+++ /dev/null
@@ -1,168 +0,0 @@
-import 'package:cake_wallet/utils/show_pop_up.dart';
-import 'package:cw_core/node.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:flutter_mobx/flutter_mobx.dart';
-import 'package:cake_wallet/routes.dart';
-import 'package:cake_wallet/palette.dart';
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/src/screens/base_page.dart';
-import 'package:cake_wallet/src/screens/nodes/widgets/node_list_row.dart';
-import 'package:cake_wallet/src/widgets/standard_list.dart';
-import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
-import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
-import 'package:flutter_slidable/flutter_slidable.dart';
-
-class NodeListPage extends BasePage {
-  NodeListPage(this.nodeListViewModel);
-
-  @override
-  String get title => S.current.nodes;
-
-  final NodeListViewModel nodeListViewModel;
-
-  @override
-  Widget trailing(context) {
-    // TODO: check if this will be used in the new design and then delete the whole page
-    // as it's not used anymore
-    return Container(
-      height: 32,
-      decoration: BoxDecoration(
-          borderRadius: BorderRadius.all(Radius.circular(16)),
-          color: Theme.of(context).accentTextTheme.caption!.color!),
-      child: ButtonTheme(
-        minWidth: double.minPositive,
-        child: TextButton(
-            onPressed: () async {
-              await showPopUp<void>(
-                  context: context,
-                  builder: (BuildContext context) {
-                    return AlertWithTwoActions(
-                        alertTitle: S.of(context).node_reset_settings_title,
-                        alertContent:
-                            S.of(context).nodes_list_reset_to_default_message,
-                        rightButtonText: S.of(context).reset,
-                        leftButtonText: S.of(context).cancel,
-                        actionRightButton: () async {
-                          Navigator.of(context).pop();
-                          await nodeListViewModel.reset();
-                        },
-                        actionLeftButton: () => Navigator.of(context).pop());
-                  });
-            },
-            child: Text(
-              S.of(context).reset,
-              textAlign: TextAlign.center,
-              style: TextStyle(
-                  fontSize: 14.0,
-                  fontWeight: FontWeight.w600,
-                  color: Palette.blueCraiola),
-            )),
-      ),
-    );
-  }
-
-  @override
-  Widget body(BuildContext context) {
-    return Container(
-      padding: EdgeInsets.only(top: 10),
-      child: Observer(
-        builder: (BuildContext context) {
-          return SectionStandardList(
-              sectionCount: 2,
-              context: context,
-              itemCounter: (int sectionIndex) {
-                if (sectionIndex == 0) {
-                  return 1;
-                }
-
-                return nodeListViewModel.nodes.length;
-              },
-              itemBuilder: (_, sectionIndex, index) {
-                if (sectionIndex == 0) {
-                  return NodeHeaderListRow(
-                      title: S.of(context).add_new_node,
-                      onTap: (_) async => await Navigator.of(context)
-                          .pushNamed(Routes.newNode));
-                }
-
-                final node = nodeListViewModel.nodes[index];
-                final isSelected =
-                    node.keyIndex == nodeListViewModel.currentNode.keyIndex;
-                final nodeListRow = NodeListRow(
-                    title: node.uriRaw,
-                    isSelected: isSelected,
-                    isAlive: node.requestNode(),
-                    onTap: (_) async {
-                      if (isSelected) {
-                        return;
-                      }
-
-                      await showPopUp<void>(
-                          context: context,
-                          builder: (BuildContext context) {
-                            return AlertWithTwoActions(
-                                alertTitle:
-                                    S.of(context).change_current_node_title,
-                                alertContent: S
-                                    .of(context)
-                                    .change_current_node(node.uriRaw),
-                                leftButtonText: S.of(context).cancel,
-                                rightButtonText: S.of(context).change,
-                                actionLeftButton: () =>
-                                    Navigator.of(context).pop(),
-                                actionRightButton: () async {
-                                  await nodeListViewModel.setAsCurrent(node);
-                                  Navigator.of(context).pop();
-                                });
-                          });
-                    });
-
-                final dismissibleRow = Slidable(
-                  key: Key('${node.keyIndex}'),
-                  startActionPane: _actionPane(context, node),
-                  endActionPane: _actionPane(context, node),
-                  child: nodeListRow,
-                );
-                
-                return isSelected ? nodeListRow : dismissibleRow;
-              });
-        },
-      ),
-    );
-  }
-
-  ActionPane _actionPane(BuildContext context, Node node) => ActionPane(
-    motion: const ScrollMotion(),
-    extentRatio: 0.3,
-    children: [
-      SlidableAction(
-        onPressed: (context) async {
-          final confirmed = await showPopUp<bool>(
-              context: context,
-              builder: (BuildContext context) {
-                return AlertWithTwoActions(
-                    alertTitle: S.of(context).remove_node,
-                    alertContent:
-                    S.of(context).remove_node_message,
-                    rightButtonText: S.of(context).remove,
-                    leftButtonText: S.of(context).cancel,
-                    actionRightButton: () =>
-                        Navigator.pop(context, true),
-                    actionLeftButton: () =>
-                        Navigator.pop(context, false));
-              }) ??
-              false;
-
-          if (confirmed) {
-            await nodeListViewModel.delete(node);
-          }
-        },
-        backgroundColor: Colors.red,
-        foregroundColor: Colors.white,
-        icon: CupertinoIcons.delete,
-        label: S.of(context).delete,
-      ),
-    ],
-  );
-}

From c8a9c1f53f1a60c93e557f7a10462d2f490d298c Mon Sep 17 00:00:00 2001
From: Justin Ehrenhofer <justin.ehrenhofer@gmail.com>
Date: Mon, 28 Nov 2022 09:45:18 -0600
Subject: [PATCH 27/61] Update Monero nodes

---
 assets/node_list.yml | 30 ++++++++++--------------------
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/assets/node_list.yml b/assets/node_list.yml
index 7962ea18c..39b440c9f 100644
--- a/assets/node_list.yml
+++ b/assets/node_list.yml
@@ -1,31 +1,21 @@
 -
-  uri: xmr-node-uk.cakewallet.com:18081
+  uri: xmr-node.cakewallet.com:18081
   is_default: true
 -
-  uri: xmr-node-eu.cakewallet.com:18081
+  uri: node.sethforprivacy.com:18089
   is_default: false
 -
-  uri: xmr-node-usa-east.cakewallet.com:18081
-  is_default: false
--
-  uri: node.moneroworld.com:18089
-  is_default: false
--
-  uri: node.xmr.pt:18081
-  is_default: false
--
-  uri: node.monero.net:18081
-  is_default: false
--
-  uri: opennode.xmr-tw.org:18089
-  is_default: false
--
-  uri: node.imonero.org:18081
+  uri: nodes.hashvault.pro:18081
   is_default: false
 -
   uri: node.c3pool.com:18081
   is_default: false
 -
-  uri: xmr.prprpr.icu:18081
+  uri: node.supportxmr.com:18081
+  is_default: false
+-
+  uri: node.community.rino.io:18081
+  is_default: false
+-
+  uri: node.moneroworld.com:18089
   is_default: false
-

From 1dd94c96058cdd153a748b9e6cbad430adc0f75f Mon Sep 17 00:00:00 2001
From: Justin Ehrenhofer <justin.ehrenhofer@gmail.com>
Date: Mon, 28 Nov 2022 10:11:52 -0600
Subject: [PATCH 28/61] Add onion node

Apologies for forgetting this a few minutes ago, despite me adding this to the guides.cakewallet.com website this morning! Related to CW-252 (no notice is added in this commit)
---
 assets/node_list.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/assets/node_list.yml b/assets/node_list.yml
index 39b440c9f..fccc968cf 100644
--- a/assets/node_list.yml
+++ b/assets/node_list.yml
@@ -1,6 +1,9 @@
 -
   uri: xmr-node.cakewallet.com:18081
   is_default: true
+-
+  uri: cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081
+  is_default: false
 -
   uri: node.sethforprivacy.com:18089
   is_default: false

From bd65fd8782fede5e01d1399b449448eb06edaba9 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:14:31 +0200
Subject: [PATCH 29/61] Upload APK to github artifacts Rename apk

---
 .github/workflows/pr_test_build.yml | 187 +++++++++++++++-------------
 1 file changed, 102 insertions(+), 85 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index dd2f1edeb..398f1edd5 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -11,89 +11,89 @@ jobs:
 
     steps:
       - uses: actions/checkout@v2
-      - uses: actions/setup-java@v1
-        with:
-          java-version: '8.x'
-
-      - name: Flutter action
-        uses: subosito/flutter-action@v1
-        with:
-          flutter-version: '3.3.x'
-          channel: stable
-
-      - name: Install package dependencies
-        run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
-
-      - name: Execute Build and Setup Commands
-        run: |
-          sudo mkdir -p /opt/android
-          sudo chown $USER /opt/android
-          cd /opt/android
-          git clone https://github.com/cake-tech/cake_wallet.git --branch $GITHUB_HEAD_REF
-          cd cake_wallet/scripts/android/
-          ./install_ndk.sh
-          source ./app_env.sh cakewallet
-          ./app_config.sh
-          ./build_all.sh
-          ./copy_monero_deps.sh
-
-      - name: Install Flutter dependencies
-        run: |
-          cd /opt/android/cake_wallet
-          flutter pub get
-
-      - 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 ${{ secrets.STORE_PASS }} -keypass ${{ secrets.KEY_PASS }}
-
-      - name: Generate key properties
-        run: |
-          cd /opt/android/cake_wallet
-          flutter packages pub run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=${{ secrets.STORE_PASS }} keyPassword=${{ secrets.KEY_PASS }}
-
-      - name: Generate localization
-        run: |
-          cd /opt/android/cake_wallet
-          flutter packages pub run tool/generate_localization.dart
-
-      - name: Build generated code
-        run: |
-          cd /opt/android/cake_wallet
-          cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
-          cd cw_monero && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
-          cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
-          cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
-          flutter packages pub run build_runner build --delete-conflicting-outputs
-
-      - name: Add secrets
-        run: |
-          cd /opt/android/cake_wallet
-          touch lib/.secrets.g.dart
-          echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
-          echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
-          echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
-          echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
-          echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
-          echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
-          echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
-          echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
-          echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
-          echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart
-          echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart
-          echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart
-          echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart
-          echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
-          echo "const sideShiftApiKey = '${{ secrets.SIDE_SHIFT_API_KEY }}';" >> lib/.secrets.g.dart
-          echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
-          echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart
-          echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart
-          echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart
-
-      - name: Build
-        run: |
-          cd /opt/android/cake_wallet
-          flutter build apk --release
+#      - uses: actions/setup-java@v1
+#        with:
+#          java-version: '8.x'
+#
+#      - name: Flutter action
+#        uses: subosito/flutter-action@v1
+#        with:
+#          flutter-version: '3.3.x'
+#          channel: stable
+#
+#      - name: Install package dependencies
+#        run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
+#
+#      - name: Execute Build and Setup Commands
+#        run: |
+#          sudo mkdir -p /opt/android
+#          sudo chown $USER /opt/android
+#          cd /opt/android
+#          git clone https://github.com/cake-tech/cake_wallet.git --branch $GITHUB_HEAD_REF
+#          cd cake_wallet/scripts/android/
+#          ./install_ndk.sh
+#          source ./app_env.sh cakewallet
+#          ./app_config.sh
+#          ./build_all.sh
+#          ./copy_monero_deps.sh
+#
+#      - name: Install Flutter dependencies
+#        run: |
+#          cd /opt/android/cake_wallet
+#          flutter pub get
+#
+#      - 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 ${{ secrets.STORE_PASS }} -keypass ${{ secrets.KEY_PASS }}
+#
+#      - name: Generate key properties
+#        run: |
+#          cd /opt/android/cake_wallet
+#          flutter packages pub run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=${{ secrets.STORE_PASS }} keyPassword=${{ secrets.KEY_PASS }}
+#
+#      - name: Generate localization
+#        run: |
+#          cd /opt/android/cake_wallet
+#          flutter packages pub run tool/generate_localization.dart
+#
+#      - name: Build generated code
+#        run: |
+#          cd /opt/android/cake_wallet
+#          cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+#          cd cw_monero && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+#          cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+#          cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+#          flutter packages pub run build_runner build --delete-conflicting-outputs
+#
+#      - name: Add secrets
+#        run: |
+#          cd /opt/android/cake_wallet
+#          touch lib/.secrets.g.dart
+#          echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
+#          echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
+#          echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
+#          echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
+#          echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
+#          echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
+#          echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
+#          echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
+#          echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
+#          echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart
+#          echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart
+#          echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart
+#          echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart
+#          echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
+#          echo "const sideShiftApiKey = '${{ secrets.SIDE_SHIFT_API_KEY }}';" >> lib/.secrets.g.dart
+#          echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
+#          echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart
+#          echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart
+#          echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart
+#
+#      - name: Build
+#        run: |
+#          cd /opt/android/cake_wallet
+#          flutter build apk --release
 
 #      - name: Push to App Center
 #        run: |
@@ -108,9 +108,26 @@ jobs:
 #              --token ${{ secrets.APP_CENTER_TOKEN }} \
 #              --quiet
 
+#      - name: Send Test APK
+#        run: |
+#          cd /opt/android/cake_wallet
+#          var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/app-release.apk)
+#          curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}'
+
+
       - name: Send Test APK
         run: |
-          cd /opt/android/cake_wallet
-          var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/app-release.apk)
+          var=$(curl --upload-file pubspec_base.yaml https://transfer.sh/$GITHUB_HEAD_REF.apk)
           curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}'
 
+      - name: Rename apk
+      - run: |
+          mv pubspec_base.yaml $GITHUB_HEAD_REF.apk
+          ls
+
+      - name: Upload Artifact
+        uses: actions/upload-artifact@v3
+        with:
+          name: test-apks-artifacts
+          path: $GITHUB_HEAD_REF.apk
+

From b70838a308d7f3c9ef209ef7a1f3cc2245737297 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:16:04 +0200
Subject: [PATCH 30/61] Upload APK to github artifacts Rename apk

---
 .github/workflows/pr_test_build.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 398f1edd5..cdab77afb 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -121,7 +121,7 @@ jobs:
           curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}'
 
       - name: Rename apk
-      - run: |
+        run: |
           mv pubspec_base.yaml $GITHUB_HEAD_REF.apk
           ls
 

From b62e4cb0648a0014b5fbd339f52c06d03cae1ea8 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:19:43 +0200
Subject: [PATCH 31/61] fix artifact path

---
 .github/workflows/pr_test_build.yml | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index cdab77afb..e016cbf8f 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -111,15 +111,9 @@ jobs:
 #      - name: Send Test APK
 #        run: |
 #          cd /opt/android/cake_wallet
-#          var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/app-release.apk)
+#          var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/$GITHUB_HEAD_REF.apk)
 #          curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}'
 
-
-      - name: Send Test APK
-        run: |
-          var=$(curl --upload-file pubspec_base.yaml https://transfer.sh/$GITHUB_HEAD_REF.apk)
-          curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}'
-
       - name: Rename apk
         run: |
           mv pubspec_base.yaml $GITHUB_HEAD_REF.apk
@@ -129,5 +123,5 @@ jobs:
         uses: actions/upload-artifact@v3
         with:
           name: test-apks-artifacts
-          path: $GITHUB_HEAD_REF.apk
+          path: "\${{GITHUB_HEAD_REF}}.apk"
 

From fb2e7306ad5949497e286f829297796d3f7deb5c Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:23:58 +0200
Subject: [PATCH 32/61] fix artifact path

---
 .github/workflows/pr_test_build.yml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index e016cbf8f..d09b938b3 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -116,12 +116,13 @@ jobs:
 
       - name: Rename apk
         run: |
-          mv pubspec_base.yaml $GITHUB_HEAD_REF.apk
+          mkdir test-apk
+          mv pubspec_base.yaml test-apk/$GITHUB_HEAD_REF.apk
           ls
 
       - name: Upload Artifact
         uses: actions/upload-artifact@v3
         with:
           name: test-apks-artifacts
-          path: "\${{GITHUB_HEAD_REF}}.apk"
+          path: test-apk/*
 

From 28f1afd972b1dcab96a5ff76ffdbafe91f2ec17d Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:26:39 +0200
Subject: [PATCH 33/61] try different file

---
 .github/workflows/pr_test_build.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index d09b938b3..71c8a6d0e 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -117,7 +117,7 @@ jobs:
       - name: Rename apk
         run: |
           mkdir test-apk
-          mv pubspec_base.yaml test-apk/$GITHUB_HEAD_REF.apk
+          mv pubspec_base.yaml test-apk/second-test.apk
           ls
 
       - name: Upload Artifact

From 9b20af929204cb6cb0913ccfa101ef14c59cb4ca Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:33:09 +0200
Subject: [PATCH 34/61] try different file

---
 .github/workflows/pr_test_build.yml | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 71c8a6d0e..b2639e5e7 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -114,15 +114,22 @@ jobs:
 #          var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/$GITHUB_HEAD_REF.apk)
 #          curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}'
 
+#      - name: Rename apk
+#        run: |
+#          cd /opt/android/cake_wallet/build/app/outputs/apk/release
+#          mkdir test-apk
+#          mv app-release.apk test-apk/$GITHUB_HEAD_REF.apk
+
       - name: Rename apk
         run: |
           mkdir test-apk
-          mv pubspec_base.yaml test-apk/second-test.apk
+          mv pubspec_base.yaml test-apk/$GITHUB_HEAD_REF.apk
+          cd test-apk
           ls
 
       - name: Upload Artifact
         uses: actions/upload-artifact@v3
         with:
           name: test-apks-artifacts
-          path: test-apk/*
+          path: test-apk/"$GITHUB_HEAD_REF".apk
 

From 1198b164556380c8b63e1f011d2afc61ecbf877d Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:37:56 +0200
Subject: [PATCH 35/61] Try uploading single apk file

---
 .github/workflows/pr_test_build.yml | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index b2639e5e7..595ff3def 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -126,10 +126,22 @@ jobs:
           mv pubspec_base.yaml test-apk/$GITHUB_HEAD_REF.apk
           cd test-apk
           ls
+          apkPath=pwd/$GITHUB_HEAD_REF.apk
+          echo "===================="
+          echo apkPath
+          echo "===================="
 
       - name: Upload Artifact
+        continue-on-error: true
         uses: actions/upload-artifact@v3
         with:
           name: test-apks-artifacts
-          path: test-apk/"$GITHUB_HEAD_REF".apk
+          path: apkPath
+
+      - name: Upload Artifact
+        continue-on-error: true
+        uses: actions/upload-artifact@v3
+        with:
+          name: test-apks-artifacts
+          path: $apkPath
 

From 0c8636a77856f93b2c901abcce7367c6b452a691 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:46:03 +0200
Subject: [PATCH 36/61] Try uploading renamed apk file

---
 .github/workflows/pr_test_build.yml | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 595ff3def..01895c1fb 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -128,20 +128,30 @@ jobs:
           ls
           apkPath=pwd/$GITHUB_HEAD_REF.apk
           echo "===================="
-          echo apkPath
+          echo $apkPath
           echo "===================="
+          echo "artifactPath=test-apk/${{ GITHUB_HEAD_REF.apk }}" >> $GITHUB_ENV
+          echo ${{ env.artifactPath }}
 
       - name: Upload Artifact
         continue-on-error: true
         uses: actions/upload-artifact@v3
         with:
           name: test-apks-artifacts
-          path: apkPath
+          path: test-apk/${{ GITHUB_HEAD_REF }}.apk
 
       - name: Upload Artifact
         continue-on-error: true
         uses: actions/upload-artifact@v3
         with:
           name: test-apks-artifacts
-          path: $apkPath
+          path: ${{ apkPath }}
+
+      - name: Upload Artifact
+        continue-on-error: true
+        uses: actions/upload-artifact@v3
+        with:
+          name: test-apks-artifacts
+          path: ${{ env.artifactPath }}
+          retention-days: 30
 

From e78ef3c201a385b0fb40e478cf9444b74e93bfda Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:48:01 +0200
Subject: [PATCH 37/61] Try uploading renamed apk file

---
 .github/workflows/pr_test_build.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 01895c1fb..8a8760aad 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -126,7 +126,7 @@ jobs:
           mv pubspec_base.yaml test-apk/$GITHUB_HEAD_REF.apk
           cd test-apk
           ls
-          apkPath=pwd/$GITHUB_HEAD_REF.apk
+          apkPath=pwd/${{ GITHUB_HEAD_REF }}.apk
           echo "===================="
           echo $apkPath
           echo "===================="

From 12f4b9339c1659711137e9b2a4b59757a7b63f82 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:50:46 +0200
Subject: [PATCH 38/61] Try uploading renamed apk file

---
 .github/workflows/pr_test_build.yml | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 8a8760aad..818b0b8c9 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -126,12 +126,16 @@ jobs:
           mv pubspec_base.yaml test-apk/$GITHUB_HEAD_REF.apk
           cd test-apk
           ls
-          apkPath=pwd/${{ GITHUB_HEAD_REF }}.apk
+          apkPath=pwd/$GITHUB_HEAD_REF.apk
           echo "===================="
           echo $apkPath
           echo "===================="
-          echo "artifactPath=test-apk/${{ GITHUB_HEAD_REF.apk }}" >> $GITHUB_ENV
+          echo "artifactPath=test-apk/$GITHUB_HEAD_REF.apk" >> $GITHUB_ENV
+          echo "artifactPath2=test-apk/\$GITHUB_HEAD_REF.apk" >> $GITHUB_ENV
+          echo "artifactPath3=test-apk/\${{ GITHUB_HEAD_REF.apk }}" >> $GITHUB_ENV
           echo ${{ env.artifactPath }}
+          echo ${{ env.artifactPath2 }}
+          echo ${{ env.artifactPath3 }}
 
       - name: Upload Artifact
         continue-on-error: true
@@ -153,5 +157,21 @@ jobs:
         with:
           name: test-apks-artifacts
           path: ${{ env.artifactPath }}
-          retention-days: 30
+          retention-days: 1
+
+      - name: Upload Artifact
+        continue-on-error: true
+        uses: actions/upload-artifact@v3
+        with:
+          name: test-apks-artifacts
+          path: ${{ env.artifactPath2 }}
+          retention-days: 1
+
+      - name: Upload Artifact
+        continue-on-error: true
+        uses: actions/upload-artifact@v3
+        with:
+          name: test-apks-artifacts
+          path: ${{ env.artifactPath3 }}
+          retention-days: 1
 

From 71989cf6d79e977d772d55b8b5c232db824ef83b Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:52:04 +0200
Subject: [PATCH 39/61] Try uploading renamed apk file

---
 .github/workflows/pr_test_build.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 818b0b8c9..f1dae682b 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -142,7 +142,7 @@ jobs:
         uses: actions/upload-artifact@v3
         with:
           name: test-apks-artifacts
-          path: test-apk/${{ GITHUB_HEAD_REF }}.apk
+          path: test-apk/${{ $GITHUB_HEAD_REF }}.apk
 
       - name: Upload Artifact
         continue-on-error: true

From 8daf20753bd9ad9ff60bb70addb494188d29620c Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:52:33 +0200
Subject: [PATCH 40/61] Try uploading renamed apk file

---
 .github/workflows/pr_test_build.yml | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index f1dae682b..523f70725 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -137,13 +137,6 @@ jobs:
           echo ${{ env.artifactPath2 }}
           echo ${{ env.artifactPath3 }}
 
-      - name: Upload Artifact
-        continue-on-error: true
-        uses: actions/upload-artifact@v3
-        with:
-          name: test-apks-artifacts
-          path: test-apk/${{ $GITHUB_HEAD_REF }}.apk
-
       - name: Upload Artifact
         continue-on-error: true
         uses: actions/upload-artifact@v3

From 903cd7bf6f10c922765b42f29cd961500b6aef04 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:53:15 +0200
Subject: [PATCH 41/61] Try uploading renamed apk file

---
 .github/workflows/pr_test_build.yml | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 523f70725..d9509e813 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -137,13 +137,6 @@ jobs:
           echo ${{ env.artifactPath2 }}
           echo ${{ env.artifactPath3 }}
 
-      - name: Upload Artifact
-        continue-on-error: true
-        uses: actions/upload-artifact@v3
-        with:
-          name: test-apks-artifacts
-          path: ${{ apkPath }}
-
       - name: Upload Artifact
         continue-on-error: true
         uses: actions/upload-artifact@v3

From e516bd7a07e6b55ad389cede51dafcb0ce842912 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:55:29 +0200
Subject: [PATCH 42/61] Try uploading renamed apk file

---
 .github/workflows/pr_test_build.yml | 38 ++++++++++++++---------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index d9509e813..9e9393ed9 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -131,11 +131,11 @@ jobs:
           echo $apkPath
           echo "===================="
           echo "artifactPath=test-apk/$GITHUB_HEAD_REF.apk" >> $GITHUB_ENV
-          echo "artifactPath2=test-apk/\$GITHUB_HEAD_REF.apk" >> $GITHUB_ENV
-          echo "artifactPath3=test-apk/\${{ GITHUB_HEAD_REF.apk }}" >> $GITHUB_ENV
+#          echo "artifactPath2=test-apk/\$GITHUB_HEAD_REF.apk" >> $GITHUB_ENV
+#          echo "artifactPath3=test-apk/\${{ GITHUB_HEAD_REF.apk }}" >> $GITHUB_ENV
           echo ${{ env.artifactPath }}
-          echo ${{ env.artifactPath2 }}
-          echo ${{ env.artifactPath3 }}
+#          echo ${{ env.artifactPath2 }}
+#          echo ${{ env.artifactPath3 }}
 
       - name: Upload Artifact
         continue-on-error: true
@@ -145,19 +145,19 @@ jobs:
           path: ${{ env.artifactPath }}
           retention-days: 1
 
-      - name: Upload Artifact
-        continue-on-error: true
-        uses: actions/upload-artifact@v3
-        with:
-          name: test-apks-artifacts
-          path: ${{ env.artifactPath2 }}
-          retention-days: 1
-
-      - name: Upload Artifact
-        continue-on-error: true
-        uses: actions/upload-artifact@v3
-        with:
-          name: test-apks-artifacts
-          path: ${{ env.artifactPath3 }}
-          retention-days: 1
+#      - name: Upload Artifact
+#        continue-on-error: true
+#        uses: actions/upload-artifact@v3
+#        with:
+#          name: test-apks-artifacts
+#          path: ${{ env.artifactPath2 }}
+#          retention-days: 1
+#
+#      - name: Upload Artifact
+#        continue-on-error: true
+#        uses: actions/upload-artifact@v3
+#        with:
+#          name: test-apks-artifacts
+#          path: ${{ env.artifactPath3 }}
+#          retention-days: 1
 

From bd1a5cf3f7733a1cf426f40364346d213a2e3ef7 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 14:56:27 +0200
Subject: [PATCH 43/61] Try uploading renamed apk file

---
 .github/workflows/pr_test_build.yml | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 9e9393ed9..0304171b8 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -131,11 +131,7 @@ jobs:
           echo $apkPath
           echo "===================="
           echo "artifactPath=test-apk/$GITHUB_HEAD_REF.apk" >> $GITHUB_ENV
-#          echo "artifactPath2=test-apk/\$GITHUB_HEAD_REF.apk" >> $GITHUB_ENV
-#          echo "artifactPath3=test-apk/\${{ GITHUB_HEAD_REF.apk }}" >> $GITHUB_ENV
           echo ${{ env.artifactPath }}
-#          echo ${{ env.artifactPath2 }}
-#          echo ${{ env.artifactPath3 }}
 
       - name: Upload Artifact
         continue-on-error: true

From 5364dd87107c8699690a25bd394a171bedb550de Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 15:01:20 +0200
Subject: [PATCH 44/61] Try uploading renamed apk file

---
 .github/workflows/pr_test_build.yml | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 0304171b8..5121be130 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -135,11 +135,9 @@ jobs:
 
       - name: Upload Artifact
         continue-on-error: true
-        uses: actions/upload-artifact@v3
+        uses: kittaakos/upload-artifact-as-is@v0
         with:
-          name: test-apks-artifacts
-          path: ${{ env.artifactPath }}
-          retention-days: 1
+          path: test-apk/
 
 #      - name: Upload Artifact
 #        continue-on-error: true

From e264cb326db4f75dbd764d8fcd2c5978ca270592 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 15:15:56 +0200
Subject: [PATCH 45/61] Try uploading renamed apk file

---
 .github/workflows/pr_test_build.yml | 26 --------------------------
 1 file changed, 26 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 5121be130..8b038687b 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -124,34 +124,8 @@ jobs:
         run: |
           mkdir test-apk
           mv pubspec_base.yaml test-apk/$GITHUB_HEAD_REF.apk
-          cd test-apk
-          ls
-          apkPath=pwd/$GITHUB_HEAD_REF.apk
-          echo "===================="
-          echo $apkPath
-          echo "===================="
-          echo "artifactPath=test-apk/$GITHUB_HEAD_REF.apk" >> $GITHUB_ENV
-          echo ${{ env.artifactPath }}
 
       - name: Upload Artifact
-        continue-on-error: true
         uses: kittaakos/upload-artifact-as-is@v0
         with:
           path: test-apk/
-
-#      - name: Upload Artifact
-#        continue-on-error: true
-#        uses: actions/upload-artifact@v3
-#        with:
-#          name: test-apks-artifacts
-#          path: ${{ env.artifactPath2 }}
-#          retention-days: 1
-#
-#      - name: Upload Artifact
-#        continue-on-error: true
-#        uses: actions/upload-artifact@v3
-#        with:
-#          name: test-apks-artifacts
-#          path: ${{ env.artifactPath3 }}
-#          retention-days: 1
-

From d38b3b0e0675a8c3e1dadef067981298c111c283 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 15:19:51 +0200
Subject: [PATCH 46/61] Finalize upload to artifacts and renaming

---
 .github/workflows/pr_test_build.yml | 187 ++++++++++++++--------------
 1 file changed, 91 insertions(+), 96 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 8b038687b..5611fe578 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -11,89 +11,89 @@ jobs:
 
     steps:
       - uses: actions/checkout@v2
-#      - uses: actions/setup-java@v1
-#        with:
-#          java-version: '8.x'
-#
-#      - name: Flutter action
-#        uses: subosito/flutter-action@v1
-#        with:
-#          flutter-version: '3.3.x'
-#          channel: stable
-#
-#      - name: Install package dependencies
-#        run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
-#
-#      - name: Execute Build and Setup Commands
-#        run: |
-#          sudo mkdir -p /opt/android
-#          sudo chown $USER /opt/android
-#          cd /opt/android
-#          git clone https://github.com/cake-tech/cake_wallet.git --branch $GITHUB_HEAD_REF
-#          cd cake_wallet/scripts/android/
-#          ./install_ndk.sh
-#          source ./app_env.sh cakewallet
-#          ./app_config.sh
-#          ./build_all.sh
-#          ./copy_monero_deps.sh
-#
-#      - name: Install Flutter dependencies
-#        run: |
-#          cd /opt/android/cake_wallet
-#          flutter pub get
-#
-#      - 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 ${{ secrets.STORE_PASS }} -keypass ${{ secrets.KEY_PASS }}
-#
-#      - name: Generate key properties
-#        run: |
-#          cd /opt/android/cake_wallet
-#          flutter packages pub run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=${{ secrets.STORE_PASS }} keyPassword=${{ secrets.KEY_PASS }}
-#
-#      - name: Generate localization
-#        run: |
-#          cd /opt/android/cake_wallet
-#          flutter packages pub run tool/generate_localization.dart
-#
-#      - name: Build generated code
-#        run: |
-#          cd /opt/android/cake_wallet
-#          cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
-#          cd cw_monero && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
-#          cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
-#          cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
-#          flutter packages pub run build_runner build --delete-conflicting-outputs
-#
-#      - name: Add secrets
-#        run: |
-#          cd /opt/android/cake_wallet
-#          touch lib/.secrets.g.dart
-#          echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
-#          echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
-#          echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
-#          echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
-#          echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
-#          echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
-#          echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
-#          echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
-#          echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
-#          echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart
-#          echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart
-#          echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart
-#          echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart
-#          echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
-#          echo "const sideShiftApiKey = '${{ secrets.SIDE_SHIFT_API_KEY }}';" >> lib/.secrets.g.dart
-#          echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
-#          echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart
-#          echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart
-#          echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart
-#
-#      - name: Build
-#        run: |
-#          cd /opt/android/cake_wallet
-#          flutter build apk --release
+      - uses: actions/setup-java@v1
+        with:
+          java-version: '8.x'
+
+      - name: Flutter action
+        uses: subosito/flutter-action@v1
+        with:
+          flutter-version: '3.3.x'
+          channel: stable
+
+      - name: Install package dependencies
+        run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
+
+      - name: Execute Build and Setup Commands
+        run: |
+          sudo mkdir -p /opt/android
+          sudo chown $USER /opt/android
+          cd /opt/android
+          git clone https://github.com/cake-tech/cake_wallet.git --branch $GITHUB_HEAD_REF
+          cd cake_wallet/scripts/android/
+          ./install_ndk.sh
+          source ./app_env.sh cakewallet
+          ./app_config.sh
+          ./build_all.sh
+          ./copy_monero_deps.sh
+
+      - name: Install Flutter dependencies
+        run: |
+          cd /opt/android/cake_wallet
+          flutter pub get
+
+      - 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 ${{ secrets.STORE_PASS }} -keypass ${{ secrets.KEY_PASS }}
+
+      - name: Generate key properties
+        run: |
+          cd /opt/android/cake_wallet
+          flutter packages pub run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=${{ secrets.STORE_PASS }} keyPassword=${{ secrets.KEY_PASS }}
+
+      - name: Generate localization
+        run: |
+          cd /opt/android/cake_wallet
+          flutter packages pub run tool/generate_localization.dart
+
+      - name: Build generated code
+        run: |
+          cd /opt/android/cake_wallet
+          cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+          cd cw_monero && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+          cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+          cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+          flutter packages pub run build_runner build --delete-conflicting-outputs
+
+      - name: Add secrets
+        run: |
+          cd /opt/android/cake_wallet
+          touch lib/.secrets.g.dart
+          echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
+          echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
+          echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
+          echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
+          echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
+          echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
+          echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
+          echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
+          echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart
+          echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart
+          echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
+          echo "const sideShiftApiKey = '${{ secrets.SIDE_SHIFT_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart
+          echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart
+
+      - name: Build
+        run: |
+          cd /opt/android/cake_wallet
+          flutter build apk --release
 
 #      - name: Push to App Center
 #        run: |
@@ -108,24 +108,19 @@ jobs:
 #              --token ${{ secrets.APP_CENTER_TOKEN }} \
 #              --quiet
 
-#      - name: Send Test APK
-#        run: |
-#          cd /opt/android/cake_wallet
-#          var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/$GITHUB_HEAD_REF.apk)
-#          curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}'
-
-#      - name: Rename apk
-#        run: |
-#          cd /opt/android/cake_wallet/build/app/outputs/apk/release
-#          mkdir test-apk
-#          mv app-release.apk test-apk/$GITHUB_HEAD_REF.apk
+      - name: Send Test APK
+        run: |
+          cd /opt/android/cake_wallet
+          var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/$GITHUB_HEAD_REF.apk)
+          curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}'
 
       - name: Rename apk
         run: |
+          cd /opt/android/cake_wallet/build/app/outputs/apk/release
           mkdir test-apk
-          mv pubspec_base.yaml test-apk/$GITHUB_HEAD_REF.apk
+          mv app-release.apk test-apk/$GITHUB_HEAD_REF.apk
 
       - name: Upload Artifact
         uses: kittaakos/upload-artifact-as-is@v0
         with:
-          path: test-apk/
+          path: /opt/android/cake_wallet/build/app/outputs/apk/release/test-apk/

From 03a64b16859eb8951de25f66eed9b98787457c61 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 29 Nov 2022 15:49:24 +0200
Subject: [PATCH 47/61] Rename app and apk to ease testing process

---
 .github/workflows/pr_test_build.yml | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 5611fe578..190b891e1 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -90,6 +90,9 @@ jobs:
           echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart
           echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart
 
+      - name: Rename app
+        run: sed -i -e "s/\${APP_NAME}/$GITHUB_HEAD_REF/g" /opt/android/cake_wallet/android/app/src/main/AndroidManifest.xml
+
       - name: Build
         run: |
           cd /opt/android/cake_wallet
@@ -111,10 +114,10 @@ jobs:
       - name: Send Test APK
         run: |
           cd /opt/android/cake_wallet
-          var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/$GITHUB_HEAD_REF.apk)
+          var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/$GITHUB_HEAD_REF.apk -H "Max-Days: 10")
           curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}'
 
-      - name: Rename apk
+      - name: Rename apk file
         run: |
           cd /opt/android/cake_wallet/build/app/outputs/apk/release
           mkdir test-apk

From 6685fb580485eda3b7e1f77e24b43b3f79cdc28a Mon Sep 17 00:00:00 2001
From: Justin Ehrenhofer <justin.ehrenhofer@gmail.com>
Date: Tue, 29 Nov 2022 11:05:38 -0600
Subject: [PATCH 48/61] [CW-257] Change Bitcoin block explorer to mempool.space

---
 lib/view_model/transaction_details_view_model.dart | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart
index 8992071fd..f8729715b 100644
--- a/lib/view_model/transaction_details_view_model.dart
+++ b/lib/view_model/transaction_details_view_model.dart
@@ -184,7 +184,7 @@ abstract class TransactionDetailsViewModelBase with Store {
       case WalletType.monero:
         return 'https://monero.com/tx/${txId}';
       case WalletType.bitcoin:
-        return 'https://www.blockchain.com/btc/tx/${txId}';
+        return 'https://mempool.space/tx/${txId}';
       case WalletType.litecoin:
         return 'https://blockchair.com/litecoin/transaction/${txId}';
       case WalletType.haven:
@@ -199,7 +199,7 @@ abstract class TransactionDetailsViewModelBase with Store {
       case WalletType.monero:
         return S.current.view_transaction_on + 'Monero.com';
       case WalletType.bitcoin:
-        return S.current.view_transaction_on + 'Blockchain.com';
+        return S.current.view_transaction_on + 'mempool.space';
       case WalletType.litecoin:
         return S.current.view_transaction_on + 'Blockchair.com';
       case WalletType.haven:

From 59ee7aa975750ba17071916d4bd71c2a8cb19543 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Wed, 30 Nov 2022 01:37:56 +0200
Subject: [PATCH 49/61] Add onion node to already existing users

---
 lib/entities/default_settings_migration.dart | 22 ++++++++++++++------
 lib/main.dart                                |  2 +-
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart
index fb404cd88..27ada0b0c 100644
--- a/lib/entities/default_settings_migration.dart
+++ b/lib/entities/default_settings_migration.dart
@@ -135,19 +135,29 @@ Future defaultSettingsMigration(
           await changeDefaultHavenNode(nodes);
           break;
 
+        case 18:
+          await addOnionNode(nodes);
+          break;
+
         default:
           break;
       }
 
       await sharedPreferences.setInt(
-          'current_default_settings_migration_version', version);
+          PreferencesKey.currentDefaultSettingsMigrationVersion, version);
     } catch (e) {
       print('Migration error: ${e.toString()}');
     }
   });
 
   await sharedPreferences.setInt(
-      'current_default_settings_migration_version', version);
+      PreferencesKey.currentDefaultSettingsMigrationVersion, version);
+}
+
+Future<void> addOnionNode(Box<Node> nodes) async {
+  final onionNodeUri = "cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081";
+
+  await nodes.add(Node(uri: onionNodeUri, type: WalletType.monero));
 }
 
 Future<void> replaceNodesMigration({required Box<Node> nodes}) async {
@@ -178,7 +188,7 @@ Future<void> changeMoneroCurrentNodeToDefault(
   final node = getMoneroDefaultNode(nodes: nodes);
   final nodeId = node?.key as int ?? 0; // 0 - England
 
-  await sharedPreferences.setInt('current_node_id', nodeId);
+  await sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, nodeId);
 }
 
 Node? getBitcoinDefaultElectrumServer({required Box<Node> nodes}) {
@@ -225,7 +235,7 @@ Future<void> changeBitcoinCurrentElectrumServerToDefault(
   final server = getBitcoinDefaultElectrumServer(nodes: nodes);
   final serverId = server?.key as int ?? 0;
 
-  await sharedPreferences.setInt('current_node_id_btc', serverId);
+  await sharedPreferences.setInt(PreferencesKey.currentBitcoinElectrumSererIdKey, serverId);
 }
 
 Future<void> changeLitecoinCurrentElectrumServerToDefault(
@@ -234,7 +244,7 @@ Future<void> changeLitecoinCurrentElectrumServerToDefault(
   final server = getLitecoinDefaultElectrumServer(nodes: nodes);
   final serverId = server?.key as int ?? 0;
 
-  await sharedPreferences.setInt('current_node_id_ltc', serverId);
+  await sharedPreferences.setInt(PreferencesKey.currentLitecoinElectrumSererIdKey, serverId);
 }
 
 Future<void> changeHavenCurrentNodeToDefault(
@@ -254,7 +264,7 @@ Future<void> replaceDefaultNode(
     'eu-node.cakewallet.io:18081',
     'node.cakewallet.io:18081'
   ];
-  final currentNodeId = sharedPreferences.getInt('current_node_id');
+  final currentNodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey);
   final currentNode =
       nodes.values.firstWhereOrNull((Node node) => node.key == currentNodeId);
   final needToReplace =
diff --git a/lib/main.dart b/lib/main.dart
index 3cd5679b3..e1fade7b4 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -128,7 +128,7 @@ Future<void> main() async {
         exchangeTemplates: exchangeTemplates,
         transactionDescriptions: transactionDescriptions,
         secureStorage: secureStorage,
-        initialMigrationVersion: 17);
+        initialMigrationVersion: 18);
     runApp(App());
   } catch (e, stacktrace) {
     runApp(MaterialApp(

From 28abb4ded0589915444f2d7a46653ae70b455848 Mon Sep 17 00:00:00 2001
From: Godwin Asuquo <godilite@gmail.com>
Date: Wed, 30 Nov 2022 15:28:27 +0200
Subject: [PATCH 50/61] Add localization strings

---
 res/values/strings_de.arb | 3 +++
 res/values/strings_es.arb | 3 +++
 res/values/strings_fr.arb | 3 +++
 res/values/strings_hi.arb | 3 +++
 res/values/strings_hr.arb | 3 +++
 res/values/strings_it.arb | 3 +++
 res/values/strings_ja.arb | 3 +++
 res/values/strings_ko.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_uk.arb | 3 +++
 res/values/strings_zh.arb | 3 +++
 14 files changed, 42 insertions(+)

diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index e4854066b..ca09f67d5 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -652,6 +652,9 @@
   "use_suggested": "Vorgeschlagen verwenden",
   "do_not_share_warning_text" : "Teilen Sie diese nicht mit anderen, einschließlich des Supports.\n\nSie werden Ihr Geld stehlen!",
   "help": "hilfe",
+  "connection_sync": "Verbindung und Synchronisierung",
+  "security_and_backup": "Sicherheit und Datensicherung",
+  "create_backup": "Backup erstellen",
   "privacy_settings": "Datenschutzeinstellungen",
   "privacy": "Datenschutz",
   "display_settings": "Anzeigeeinstellungen",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 456f23dec..84b39e5b7 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -652,6 +652,9 @@
   "use_suggested": "Usar sugerido",
   "do_not_share_warning_text" : "No comparta estos con nadie más, incluido el soporte.\n\n¡Te robarán tu dinero!",
   "help": "ayuda",
+  "connection_sync": "Conexión y sincronización",
+  "security_and_backup": "Seguridad y respaldo",
+  "create_backup": "Crear copia de seguridad",
   "privacy_settings": "Configuración de privacidad",
   "privacy": "Privacidad",
   "display_settings": "Configuración de pantalla",
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index daae787b9..215b58245 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -650,6 +650,9 @@
   "use_suggested": "Utilisation suggérée",
   "do_not_share_warning_text" : "Ne les partagez avec personne d'autre, y compris avec l'assistance.\n\nIls vont voler votre argent!",
   "help": "aider",
+  "connection_sync": "Connexion et synchronisation",
+  "security_and_backup": "Sécurité et sauvegarde",
+  "create_backup": "Créer une sauvegarde",
   "privacy_settings": "Paramètres de confidentialité",
   "privacy": "Confidentialité",
   "display_settings": "Paramètres d'affichage",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index 532e8ede4..133432391 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -652,6 +652,9 @@
   "use_suggested": "सुझाए गए का प्रयोग करें",
   "do_not_share_warning_text" : "इन्हें समर्थन सहित किसी और के साथ साझा न करें।\n\nवे आपका पैसा चुरा लेंगे!",
   "help": "मदद करना",
+  "connection_sync": "कनेक्शन और सिंक",
+  "security_and_backup": "सुरक्षा और बैकअप",
+  "create_backup": "बैकअप बनाएँ",
   "privacy_settings": "गोपनीयता सेटिंग्स",
   "privacy": "गोपनीयता",
   "display_settings": "प्रदर्शन सेटिंग्स",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index e5c8598e1..1e8820130 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -652,6 +652,9 @@
   "use_suggested": "Koristite predloženo",
   "do_not_share_warning_text" : "Nemojte ih dijeliti ni s kim, uključujući podršku.\n\nUkrast će vam novac!",
   "help": "pomozite",
+  "connection_sync": "Povezivanje i sinkronizacija",
+  "security_and_backup": "Sigurnost i sigurnosna kopija",
+  "create_backup": "Stvori sigurnosnu kopiju",
   "privacy_settings": "Postavke privatnosti",
   "privacy": "Privatnost",
   "display_settings": "Postavke zaslona",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index 0a557ebb1..d16a6ce83 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -652,6 +652,9 @@
   "use_suggested": "Usa suggerito",
   "do_not_share_warning_text" : "Non condividerli con nessun altro, incluso il supporto.\n\nTi ruberanno i soldi!",
   "help": "aiuto",
+  "connection_sync": "Connessione e sincronizzazione",
+  "security_and_backup": "Sicurezza e backup",
+  "create_backup": "Crea backup",
   "privacy_settings": "Impostazioni privacy",
   "privacy": "Privacy",
   "display_settings": "Impostazioni di visualizzazione",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index 16d88db49..c6a3f486c 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -652,6 +652,9 @@
   "use_suggested": "推奨を使用",
   "do_not_share_warning_text" : "サポートを含め、これらを他の誰とも共有しないでください。\n\n彼らはあなたのお金を盗みます!",
   "help": "ヘルプ",
+  "connection_sync": "接続と同期",
+  "security_and_backup": "セキュリティとバックアップ",
+  "create_backup": "バックアップを作成",
   "privacy_settings": "プライバシー設定",
   "privacy": "プライバシー",
   "display_settings": "表示設定",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 99fe560ed..8aa917572 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -652,6 +652,9 @@
   "use_suggested": "추천 사용",
   "do_not_share_warning_text" : "지원을 포함하여 다른 사람과 이러한 정보를 공유하지 마십시오.\n\n그들은 당신의 돈을 훔칠 것입니다!",
   "help": "돕다",
+  "connection_sync": "연결 및 동기화",
+  "security_and_backup": "보안 및 백업",
+  "create_backup": "백업 생성",
   "privacy_settings": "개인정보 설정",
   "privacy": "프라이버시",
   "display_settings": "디스플레이 설정",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index cc4c6bbb1..61382db9e 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -652,6 +652,9 @@
   "use_suggested": "Gebruik aanbevolen",
   "do_not_share_warning_text" : "Deel deze met niemand anders, ook niet met support.\n\nZe zullen je geld stelen!",
   "help": "helpen",
+  "connection_sync": "Verbinding en synchronisatie",
+  "security_and_backup": "Beveiliging en back-up",
+  "create_backup": "Maak een back-up",
   "privacy_settings": "Privacy-instellingen",
   "privacy": "Privacy",
   "display_settings": "Weergave-instellingen",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 0d0159f7a..dbf43ccc0 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -652,6 +652,9 @@
   "use_suggested": "Użyj sugerowane",
   "do_not_share_warning_text" : "Nie udostępniaj ich nikomu innemu, w tym wsparcia.\n\nUkradną twoje pieniądze!",
   "help": "pomoc",
+  "connection_sync": "Połączenie i synchronizacja",
+  "security_and_backup": "Bezpieczeństwo i kopia zapasowa",
+  "create_backup": "Utwórz kopię zapasową",
   "privacy_settings": "Ustawienia prywatności",
   "privacy": "Prywatność",
   "display_settings": "Ustawienia wyświetlania",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 6d87183ee..f5ecbf64e 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -652,6 +652,9 @@
   "use_suggested": "Uso sugerido",
   "do_not_share_warning_text" : "Não os compartilhe com mais ninguém, incluindo suporte.\n\nEles vão roubar seu dinheiro!",
   "help": "ajuda",
+  "connection_sync": "Conexão e sincronização",
+  "security_and_backup": "Segurança e backup",
+  "create_backup": "Criar backup",
   "privacy_settings": "Configurações de privacidade",
   "privacy": "Privacidade",
   "display_settings": "Configurações de exibição",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index d2ec428c8..9be18510f 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -652,6 +652,9 @@
   "use_suggested": "Использовать предложенный",
   "do_not_share_warning_text" : "Не делитесь ими с кем-либо еще, в том числе со службой поддержки.\n\nОни украдут ваши деньги!",
   "help": "помощь",
+  "connection_sync": "Подключение и синхронизация",
+  "security_and_backup": "Безопасность и резервное копирование",
+  "create_backup": "Создать резервную копию",
   "privacy_settings": "Настройки конфиденциальности",
   "privacy": "Конфиденциальность",
   "display_settings": "Настройки отображения",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 42170382e..6012c8289 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -651,6 +651,9 @@
   "use_suggested": "Використати запропоноване",
   "do_not_share_warning_text" : "Не повідомляйте їх нікому, включно зі службою підтримки.\n\nВони вкрадуть ваші гроші!",
   "help": "допомога",
+  "connection_sync": "Підключення та синхронізація",
+  "security_and_backup": "Безпека та резервне копіювання",
+  "create_backup": "Створити резервну копію",
   "privacy_settings": "Налаштування конфіденційності",
   "privacy": "Конфіденційність",
   "display_settings": "Налаштування дисплея",
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index 8ffa37def..6d45f6d01 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -650,6 +650,9 @@
   "use_suggested": "使用建议",
   "do_not_share_warning_text" : "不要與其他任何人分享這些內容,包括支持。\n\n他們會偷你的錢!",
   "help": "帮助",
+  "connection_sync": "连接和同步",
+  "security_and_backup": "安全和备份",
+  "create_backup": "创建备份",
   "privacy_settings": "隐私设置",
   "privacy":"隐私",
   "display_settings": "显示设置",

From ffd0079e1d231180d52f52ec51dba975fcfbbdc3 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Thu, 1 Dec 2022 14:29:03 +0200
Subject: [PATCH 51/61] Check if user already has onion node before adding it

---
 lib/entities/default_settings_migration.dart | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart
index 27ada0b0c..9aff05500 100644
--- a/lib/entities/default_settings_migration.dart
+++ b/lib/entities/default_settings_migration.dart
@@ -157,7 +157,10 @@ Future defaultSettingsMigration(
 Future<void> addOnionNode(Box<Node> nodes) async {
   final onionNodeUri = "cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081";
 
-  await nodes.add(Node(uri: onionNodeUri, type: WalletType.monero));
+  // check if the user has this node before (added it manually)
+  if (nodes.values.firstWhereOrNull((element) => element.uriRaw == onionNodeUri) == null) {
+    await nodes.add(Node(uri: onionNodeUri, type: WalletType.monero));
+  }
 }
 
 Future<void> replaceNodesMigration({required Box<Node> nodes}) async {

From 47764835c36680125e409f54f97646ed83034736 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Thu, 1 Dec 2022 18:09:21 +0200
Subject: [PATCH 52/61] Fix nullability issue in create trade response

---
 lib/exchange/changenow/changenow_exchange_provider.dart | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/exchange/changenow/changenow_exchange_provider.dart b/lib/exchange/changenow/changenow_exchange_provider.dart
index 20f529733..9910c7b9a 100644
--- a/lib/exchange/changenow/changenow_exchange_provider.dart
+++ b/lib/exchange/changenow/changenow_exchange_provider.dart
@@ -114,7 +114,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
 
     final uri = Uri.https(apiAuthority, createTradePath);
     final response = await post(uri, headers: headers, body: json.encode(body));
-    
+
     if (response.statusCode == 400) {
       final responseJSON = json.decode(response.body) as Map<String, dynamic>;
       final error = responseJSON['error'] as String;
@@ -128,9 +128,9 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
 
     final responseJSON = json.decode(response.body) as Map<String, dynamic>;
     final id = responseJSON['id'] as String;
-    final inputAddress = responseJSON['payinAddress'] as String;
-    final refundAddress = responseJSON['refundAddress'] as String;
-    final extraId = responseJSON['payinExtraId'] as String;
+    final inputAddress = responseJSON['payinAddress'] as String?;
+    final refundAddress = responseJSON['refundAddress'] as String?;
+    final extraId = responseJSON['payinExtraId'] as String?;
 
     return Trade(
         id: id,

From cbe31aa5aa60c269139f1c3e44be126337a274b2 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Thu, 1 Dec 2022 18:21:19 +0200
Subject: [PATCH 53/61] Revert allowing nullable values for input and refund
 addresses

---
 lib/exchange/changenow/changenow_exchange_provider.dart | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/exchange/changenow/changenow_exchange_provider.dart b/lib/exchange/changenow/changenow_exchange_provider.dart
index 9910c7b9a..96b6142e6 100644
--- a/lib/exchange/changenow/changenow_exchange_provider.dart
+++ b/lib/exchange/changenow/changenow_exchange_provider.dart
@@ -128,8 +128,8 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
 
     final responseJSON = json.decode(response.body) as Map<String, dynamic>;
     final id = responseJSON['id'] as String;
-    final inputAddress = responseJSON['payinAddress'] as String?;
-    final refundAddress = responseJSON['refundAddress'] as String?;
+    final inputAddress = responseJSON['payinAddress'] as String;
+    final refundAddress = responseJSON['refundAddress'] as String;
     final extraId = responseJSON['payinExtraId'] as String?;
 
     return Trade(

From 8d9c0f2a4670be9f163f4e3d614f786e4bd0cd73 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Thu, 1 Dec 2022 20:47:13 +0200
Subject: [PATCH 54/61] Add bash script to run all generation commands in one
 time

---
 model_generator.sh | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 model_generator.sh

diff --git a/model_generator.sh b/model_generator.sh
new file mode 100644
index 000000000..f4ef8bdad
--- /dev/null
+++ b/model_generator.sh
@@ -0,0 +1,5 @@
+cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+cd cw_monero && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+flutter packages pub run build_runner build --delete-conflicting-outputs
\ No newline at end of file

From 03748d680ad7eedce158962581cfd17cd57bed8b Mon Sep 17 00:00:00 2001
From: Godwin Asuquo <godilite@gmail.com>
Date: Thu, 1 Dec 2022 21:21:51 +0200
Subject: [PATCH 55/61] [skip ci] format files

---
 lib/src/screens/settings/privacy_page.dart    | 36 +++++++++----------
 .../settings/display_settings_view_model.dart | 30 +++++++---------
 .../settings/other_settings_view_model.dart   | 36 ++++++++-----------
 .../settings/privacy_settings_view_model.dart | 16 ++++-----
 .../security_settings_view_model.dart         | 20 +++++------
 5 files changed, 58 insertions(+), 80 deletions(-)

diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart
index 47041b4fb..128d864f4 100644
--- a/lib/src/screens/settings/privacy_page.dart
+++ b/lib/src/screens/settings/privacy_page.dart
@@ -19,24 +19,24 @@ class PrivacyPage extends BasePage {
       padding: EdgeInsets.only(top: 10),
       child: Observer(builder: (_) {
         return Observer(builder: (_) {
-        return Column(
-          mainAxisSize: MainAxisSize.min, 
-          children: [
-             SettingsSwitcherCell(
-              title: S.current.disable_exchange,
-              value: _privacySettingsViewModel.disableExchange,
-              onValueChange: (BuildContext context, bool value) {
-                _privacySettingsViewModel.setEnableExchange(value);
-            }),
-            SettingsSwitcherCell(
-            title: S.current.settings_save_recipient_address,
-            value: _privacySettingsViewModel.shouldSaveRecipientAddress,
-            onValueChange: (BuildContext _, bool value) {
-              _privacySettingsViewModel.setShouldSaveRecipientAddress(value);
-            })         
-          ],
-        );
-      });
+          return Column(
+            mainAxisSize: MainAxisSize.min,
+            children: [
+              SettingsSwitcherCell(
+                  title: S.current.disable_exchange,
+                  value: _privacySettingsViewModel.disableExchange,
+                  onValueChange: (BuildContext context, bool value) {
+                    _privacySettingsViewModel.setEnableExchange(value);
+                  }),
+              SettingsSwitcherCell(
+                  title: S.current.settings_save_recipient_address,
+                  value: _privacySettingsViewModel.shouldSaveRecipientAddress,
+                  onValueChange: (BuildContext _, bool value) {
+                    _privacySettingsViewModel.setShouldSaveRecipientAddress(value);
+                  })
+            ],
+          );
+        });
       }),
     );
   }
diff --git a/lib/view_model/settings/display_settings_view_model.dart b/lib/view_model/settings/display_settings_view_model.dart
index 3537dfa6e..4e73b3399 100644
--- a/lib/view_model/settings/display_settings_view_model.dart
+++ b/lib/view_model/settings/display_settings_view_model.dart
@@ -8,10 +8,9 @@ part 'display_settings_view_model.g.dart';
 
 class DisplaySettingsViewModel = DisplaySettingsViewModelBase with _$DisplaySettingsViewModel;
 
-
 abstract class DisplaySettingsViewModelBase with Store {
   DisplaySettingsViewModelBase(
-      this._settingsStore,
+    this._settingsStore,
   );
 
   final SettingsStore _settingsStore;
@@ -22,10 +21,8 @@ abstract class DisplaySettingsViewModelBase with Store {
   @computed
   String get languageCode => _settingsStore.languageCode;
 
-
   @computed
-  BalanceDisplayMode get balanceDisplayMode =>
-      _settingsStore.balanceDisplayMode;
+  BalanceDisplayMode get balanceDisplayMode => _settingsStore.balanceDisplayMode;
 
   @computed
   bool get shouldDisplayBalance => balanceDisplayMode == BalanceDisplayMode.displayableBalance;
@@ -34,30 +31,27 @@ abstract class DisplaySettingsViewModelBase with Store {
   ThemeBase get theme => _settingsStore.currentTheme;
 
   @action
-  void setBalanceDisplayMode(BalanceDisplayMode value) =>
-      _settingsStore.balanceDisplayMode = value;
+  void setBalanceDisplayMode(BalanceDisplayMode value) => _settingsStore.balanceDisplayMode = value;
 
   @action
-  void setShouldDisplayBalance(bool value){
-  if (value) {
-    _settingsStore.balanceDisplayMode = BalanceDisplayMode.displayableBalance;
+  void setShouldDisplayBalance(bool value) {
+    if (value) {
+      _settingsStore.balanceDisplayMode = BalanceDisplayMode.displayableBalance;
     } else {
-    _settingsStore.balanceDisplayMode = BalanceDisplayMode.hiddenBalance;
+      _settingsStore.balanceDisplayMode = BalanceDisplayMode.hiddenBalance;
     }
   }
 
   @action
-  void onLanguageSelected (String code) {
+  void onLanguageSelected(String code) {
     _settingsStore.languageCode = code;
   }
 
   @action
-  void setTheme(ThemeBase newTheme){
-     _settingsStore.currentTheme = newTheme;
+  void setTheme(ThemeBase newTheme) {
+    _settingsStore.currentTheme = newTheme;
   }
 
   @action
-  void setFiatCurrency(FiatCurrency value) =>
-      _settingsStore.fiatCurrency = value;
-
-}
\ No newline at end of file
+  void setFiatCurrency(FiatCurrency value) => _settingsStore.fiatCurrency = value;
+}
diff --git a/lib/view_model/settings/other_settings_view_model.dart b/lib/view_model/settings/other_settings_view_model.dart
index b0ba4c9b5..b964adc6e 100644
--- a/lib/view_model/settings/other_settings_view_model.dart
+++ b/lib/view_model/settings/other_settings_view_model.dart
@@ -12,32 +12,26 @@ import 'package:package_info/package_info.dart';
 
 part 'other_settings_view_model.g.dart';
 
-class OtherSettingsViewModel = OtherSettingsViewModelBase
-    with _$OtherSettingsViewModel;
-
+class OtherSettingsViewModel = OtherSettingsViewModelBase with _$OtherSettingsViewModel;
 
 abstract class OtherSettingsViewModelBase with Store {
-  OtherSettingsViewModelBase(this._settingsStore,  WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
-              TransactionInfo>
-          wallet):
-  walletType = wallet.type,
-  _wallet = wallet,
-  currentVersion = ''{
-     PackageInfo.fromPlatform().then(
-        (PackageInfo packageInfo) => currentVersion = packageInfo.version);
+  OtherSettingsViewModelBase(
+      this._settingsStore, WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet)
+      : walletType = wallet.type,
+        _wallet = wallet,
+        currentVersion = '' {
+    PackageInfo.fromPlatform().then((PackageInfo packageInfo) => currentVersion = packageInfo.version);
 
     final priority = _settingsStore.priority[wallet.type];
     final priorities = priorityForWalletType(wallet.type);
 
     if (!priorities.contains(priority)) {
       _settingsStore.priority[wallet.type] = priorities.first;
+    }
   }
 
-   }
-
-     final WalletType walletType;
-  final  WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
-              TransactionInfo> _wallet;
+  final WalletType walletType;
+  final WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> _wallet;
 
   @observable
   String currentVersion;
@@ -55,11 +49,10 @@ abstract class OtherSettingsViewModelBase with Store {
     return priority;
   }
 
-   String getDisplayPriority(dynamic priority) {
+  String getDisplayPriority(dynamic priority) {
     final _priority = priority as TransactionPriority;
 
-    if (_wallet.type == WalletType.bitcoin
-        || _wallet.type == WalletType.litecoin) {
+    if (_wallet.type == WalletType.bitcoin || _wallet.type == WalletType.litecoin) {
       final rate = bitcoin!.getFeeRate(_wallet, _priority);
       return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate);
     }
@@ -67,6 +60,5 @@ abstract class OtherSettingsViewModelBase with Store {
     return priority.toString();
   }
 
-  void onDisplayPrioritySelected(TransactionPriority priority) =>
-    _settingsStore.priority[_wallet.type] = priority;
-}
\ No newline at end of file
+  void onDisplayPrioritySelected(TransactionPriority priority) => _settingsStore.priority[_wallet.type] = priority;
+}
diff --git a/lib/view_model/settings/privacy_settings_view_model.dart b/lib/view_model/settings/privacy_settings_view_model.dart
index 8433e673a..88311bf1f 100644
--- a/lib/view_model/settings/privacy_settings_view_model.dart
+++ b/lib/view_model/settings/privacy_settings_view_model.dart
@@ -3,8 +3,7 @@ import 'package:mobx/mobx.dart';
 
 part 'privacy_settings_view_model.g.dart';
 
-class PrivacySettingsViewModel = PrivacySettingsViewModelBase
-    with _$PrivacySettingsViewModel;
+class PrivacySettingsViewModel = PrivacySettingsViewModelBase with _$PrivacySettingsViewModel;
 
 abstract class PrivacySettingsViewModelBase with Store {
   PrivacySettingsViewModelBase(this._settingsStore);
@@ -15,14 +14,11 @@ abstract class PrivacySettingsViewModelBase with Store {
   bool get disableExchange => _settingsStore.disableExchange;
 
   @computed
-  bool get shouldSaveRecipientAddress =>
-      _settingsStore.shouldSaveRecipientAddress;
+  bool get shouldSaveRecipientAddress => _settingsStore.shouldSaveRecipientAddress;
 
   @action
-  void setShouldSaveRecipientAddress(bool value) =>
-      _settingsStore.shouldSaveRecipientAddress = value;
-  
+  void setShouldSaveRecipientAddress(bool value) => _settingsStore.shouldSaveRecipientAddress = value;
+
   @action
-  void setEnableExchange(bool value) =>
-      _settingsStore.disableExchange = value;
-}
\ No newline at end of file
+  void setEnableExchange(bool value) => _settingsStore.disableExchange = value;
+}
diff --git a/lib/view_model/settings/security_settings_view_model.dart b/lib/view_model/settings/security_settings_view_model.dart
index 9bf2fb6eb..4a88b633f 100644
--- a/lib/view_model/settings/security_settings_view_model.dart
+++ b/lib/view_model/settings/security_settings_view_model.dart
@@ -4,26 +4,22 @@ import 'package:mobx/mobx.dart';
 
 part 'security_settings_view_model.g.dart';
 
-class SecuritySettingsViewModel = SecuritySettingsViewModelBase
-    with _$SecuritySettingsViewModel;
+class SecuritySettingsViewModel = SecuritySettingsViewModelBase with _$SecuritySettingsViewModel;
 
 abstract class SecuritySettingsViewModelBase with Store {
-  SecuritySettingsViewModelBase(this._settingsStore): _biometricAuth = BiometricAuth();
+  SecuritySettingsViewModelBase(this._settingsStore) : _biometricAuth = BiometricAuth();
 
   final BiometricAuth _biometricAuth;
   final SettingsStore _settingsStore;
-  
+
   @computed
-  bool get allowBiometricalAuthentication =>
-      _settingsStore.allowBiometricalAuthentication;
+  bool get allowBiometricalAuthentication => _settingsStore.allowBiometricalAuthentication;
 
   @action
-  Future<bool> biometricAuthenticated()async{
-   return await _biometricAuth.canCheckBiometrics() && await _biometricAuth.isAuthenticated();
+  Future<bool> biometricAuthenticated() async {
+    return await _biometricAuth.canCheckBiometrics() && await _biometricAuth.isAuthenticated();
   }
 
   @action
-  void setAllowBiometricalAuthentication(bool value) =>
-      _settingsStore.allowBiometricalAuthentication = value;
-
-}
\ No newline at end of file
+  void setAllowBiometricalAuthentication(bool value) => _settingsStore.allowBiometricalAuthentication = value;
+}

From 914fffe51cdec4ba880032dd53cfe925328daefa Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Thu, 1 Dec 2022 21:33:17 +0200
Subject: [PATCH 56/61] Initialize wallet directly from constructor argument
 [skip ci]

---
 .../settings/other_settings_view_model.dart    | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lib/view_model/settings/other_settings_view_model.dart b/lib/view_model/settings/other_settings_view_model.dart
index b964adc6e..c57af50d9 100644
--- a/lib/view_model/settings/other_settings_view_model.dart
+++ b/lib/view_model/settings/other_settings_view_model.dart
@@ -15,18 +15,17 @@ part 'other_settings_view_model.g.dart';
 class OtherSettingsViewModel = OtherSettingsViewModelBase with _$OtherSettingsViewModel;
 
 abstract class OtherSettingsViewModelBase with Store {
-  OtherSettingsViewModelBase(
-      this._settingsStore, WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet)
-      : walletType = wallet.type,
-        _wallet = wallet,
+  OtherSettingsViewModelBase(this._settingsStore, this._wallet)
+      : walletType = _wallet.type,
         currentVersion = '' {
-    PackageInfo.fromPlatform().then((PackageInfo packageInfo) => currentVersion = packageInfo.version);
+    PackageInfo.fromPlatform()
+        .then((PackageInfo packageInfo) => currentVersion = packageInfo.version);
 
-    final priority = _settingsStore.priority[wallet.type];
-    final priorities = priorityForWalletType(wallet.type);
+    final priority = _settingsStore.priority[_wallet.type];
+    final priorities = priorityForWalletType(_wallet.type);
 
     if (!priorities.contains(priority)) {
-      _settingsStore.priority[wallet.type] = priorities.first;
+      _settingsStore.priority[_wallet.type] = priorities.first;
     }
   }
 
@@ -60,5 +59,6 @@ abstract class OtherSettingsViewModelBase with Store {
     return priority.toString();
   }
 
-  void onDisplayPrioritySelected(TransactionPriority priority) => _settingsStore.priority[_wallet.type] = priority;
+  void onDisplayPrioritySelected(TransactionPriority priority) =>
+      _settingsStore.priority[_wallet.type] = priority;
 }

From dd99508d3e3d894987dc2f5d1616f310c1586fb7 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Thu, 1 Dec 2022 22:11:51 +0200
Subject: [PATCH 57/61] Fix static amount value for determining best rate and
 replace it with the input the user types

---
 lib/view_model/exchange/exchange_view_model.dart | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart
index 725208324..ff3b66f73 100644
--- a/lib/view_model/exchange/exchange_view_model.dart
+++ b/lib/view_model/exchange/exchange_view_model.dart
@@ -296,12 +296,14 @@ abstract class ExchangeViewModelBase with Store {
   }
 
   Future<void> _calculateBestRate() async {
+    final amount = double.tryParse(depositAmount) ?? double.tryParse(receiveAmount) ?? 1;
+
     final result = await Future.wait<double>(
         _tradeAvailableProviders
             .map((element) => element.calculateAmount(
                 from: depositCurrency,
                 to: receiveCurrency,
-                amount: 1,
+                amount: amount,
                 isFixedRateMode: isFixedRateMode,
                 isReceiveAmount: false))
     );
@@ -311,7 +313,7 @@ abstract class ExchangeViewModelBase with Store {
     for (int i=0;i<result.length;i++) {
       if (result[i] != 0) {
         /// add this provider as its valid for this trade
-        _sortedAvailableProviders[result[i]] = _tradeAvailableProviders[i];
+        _sortedAvailableProviders[result[i] / amount] = _tradeAvailableProviders[i];
       }
     }
     if (_sortedAvailableProviders.isNotEmpty) {

From 091ac41ee276e8862a12af0b7362513270f88a84 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Thu, 1 Dec 2022 22:37:13 +0200
Subject: [PATCH 58/61] allow null minimum amount in limits

---
 lib/view_model/exchange/exchange_view_model.dart | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart
index ff3b66f73..fd66a4254 100644
--- a/lib/view_model/exchange/exchange_view_model.dart
+++ b/lib/view_model/exchange/exchange_view_model.dart
@@ -336,7 +336,7 @@ abstract class ExchangeViewModelBase with Store {
         ? depositCurrency
         : receiveCurrency;
 
-    double lowestMin = double.maxFinite;
+    double? lowestMin = double.maxFinite;
     double? highestMax = 0.0;
 
     for (var provider in selectedProviders) {
@@ -351,8 +351,8 @@ abstract class ExchangeViewModelBase with Store {
             to: to,
             isFixedRateMode: isFixedRateMode);
 
-        if (tempLimits.min != null && tempLimits.min! < lowestMin) {
-          lowestMin = tempLimits.min!;
+        if (lowestMin != null && (tempLimits.min ?? -1) < lowestMin) {
+          lowestMin = tempLimits.min;
         }
         if (highestMax != null && (tempLimits.max ?? double.maxFinite) > highestMax) {
           highestMax = tempLimits.max;
@@ -362,7 +362,7 @@ abstract class ExchangeViewModelBase with Store {
       }
     }
 
-    if (lowestMin < double.maxFinite) {
+    if (lowestMin != double.maxFinite) {
       limits = Limits(min: lowestMin, max: highestMax);
 
       limitsState = LimitsLoadedSuccessfully(limits: limits);

From 3bcd31ac44d95235bfb03a46497b71919c3ba28e Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Fri, 2 Dec 2022 20:38:16 +0200
Subject: [PATCH 59/61] calculate best rate based on min/max amount

---
 lib/view_model/exchange/exchange_view_model.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart
index fd66a4254..f9d832843 100644
--- a/lib/view_model/exchange/exchange_view_model.dart
+++ b/lib/view_model/exchange/exchange_view_model.dart
@@ -296,7 +296,7 @@ abstract class ExchangeViewModelBase with Store {
   }
 
   Future<void> _calculateBestRate() async {
-    final amount = double.tryParse(depositAmount) ?? double.tryParse(receiveAmount) ?? 1;
+    final amount = limits.min ?? limits.max ?? 1;
 
     final result = await Future.wait<double>(
         _tradeAvailableProviders

From 116e468581cf862584a640f41a07d77e0879f4f9 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Fri, 2 Dec 2022 23:20:06 +0200
Subject: [PATCH 60/61] calculate best rate based on deposit/receive amount

---
 lib/view_model/exchange/exchange_view_model.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart
index f9d832843..b03415f4a 100644
--- a/lib/view_model/exchange/exchange_view_model.dart
+++ b/lib/view_model/exchange/exchange_view_model.dart
@@ -296,7 +296,7 @@ abstract class ExchangeViewModelBase with Store {
   }
 
   Future<void> _calculateBestRate() async {
-    final amount = limits.min ?? limits.max ?? 1;
+    final amount = double.tryParse(isFixedRateMode ? receiveAmount : depositAmount) ?? 1;
 
     final result = await Future.wait<double>(
         _tradeAvailableProviders

From 98da1c221d2bd5f9162c950406e64b22366d10e6 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Sat, 3 Dec 2022 23:36:27 +0200
Subject: [PATCH 61/61] revert nullability change with navigation in
 authentication state change [skip_ci]

---
 lib/reactions/on_authentication_state_change.dart | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart
index 560326cb5..c91f5277e 100644
--- a/lib/reactions/on_authentication_state_change.dart
+++ b/lib/reactions/on_authentication_state_change.dart
@@ -23,12 +23,12 @@ void startAuthenticationStateChange(AuthenticationStore authenticationStore,
     }
 
     if (state == AuthenticationState.allowed) {
-      await navigatorKey.currentState?.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
+      await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
       return;
     }
 
     if (state == AuthenticationState.denied) {
-      await navigatorKey.currentState?.pushNamedAndRemoveUntil(Routes.welcome, (_) => false);
+      await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.welcome, (_) => false);
       return;
     }
   });