From d5fca1969e096ac7083bb4cbb780d0df81603ead Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Thu, 25 Jul 2024 02:59:45 +0200
Subject: [PATCH 01/81] add a script to download prebuilds of monero_c (#1554)

---
 pubspec_base.yaml                    |  1 +
 tool/download_moneroc_prebuilds.dart | 50 ++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)
 create mode 100644 tool/download_moneroc_prebuilds.dart

diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 458523fc2..2cfeae716 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -124,6 +124,7 @@ dev_dependencies:
     git:
       url: https://github.com/cake-tech/google-translator.git
       version: 1.0.0
+  archive: ^3.6.1
 
 dependency_overrides:
   bech32:
diff --git a/tool/download_moneroc_prebuilds.dart b/tool/download_moneroc_prebuilds.dart
new file mode 100644
index 000000000..58e8d4b03
--- /dev/null
+++ b/tool/download_moneroc_prebuilds.dart
@@ -0,0 +1,50 @@
+import 'package:dio/dio.dart';
+import 'package:archive/archive_io.dart';
+
+final _dio = Dio();
+
+final List<String> triplets = [
+  "x86_64-linux-gnu", // linux desktop - majority of users onlinux 
+  // "i686-linux-gnu", // not supported by cake
+  // "i686-meego-linux-gnu", // sailfishos (emulator)- not supported by cake
+  // "aarch64-linux-gnu", // not (yet) supported by cake - (mostly) mobile linux
+  // "aarch64-meego-linux-gnu", // sailfishos - not supported by cake
+  "x86_64-linux-android",
+  // "i686-linux-android", // not supported by monero_c - mostly old android emulators
+  "aarch64-linux-android",
+  "armv7a-linux-androideabi",
+  // "i686-w64-mingw32", // 32bit windows - not supported by monero_c
+  "x86_64-w64-mingw32",
+  // "x86_64-apple-darwin11", // Intel macbooks (contrib) - not used by cake 
+  // "aarch64-apple-darwin11", // apple silicon macbooks (contrib) - not used by cake
+  // "host-apple-darwin", // not available on CI (yet)
+  // "x86_64-host-apple-darwin", // not available on CI (yet)
+  "aarch64-host-apple-darwin", // apple silicon macbooks (local builds)
+  "host-apple-ios",
+];
+
+Future<void> main() async {
+  final resp = await _dio.get("https://api.github.com/repos/mrcyjanek/monero_c/releases");
+  final data = resp.data[0];
+  final tagName = data['tag_name'];
+  print("Downloading artifacts for: ${tagName}");
+  final assets = data['assets'] as List<dynamic>;
+  for (var i = 0; i < assets.length; i++) {
+    for (var triplet in triplets) {
+      final asset = assets[i];
+      final filename = asset["name"] as String;
+      if (!filename.contains(triplet)) continue;
+      final coin = filename.split("_")[0];
+      String localFilename = filename.replaceAll("${coin}_${triplet}_", "");
+      localFilename = "scripts/monero_c/release/${coin}/${triplet}_${localFilename}";
+      final url = asset["browser_download_url"] as String;
+      print("- downloading $localFilename");
+      await _dio.download(url, localFilename);
+      print("  extracting $localFilename");
+      final inputStream = InputFileStream(localFilename);
+      final archive = XZDecoder().decodeBuffer(inputStream);
+      final outputStream = OutputFileStream(localFilename.replaceAll(".xz", ""));
+      outputStream.writeBytes(archive);
+    }
+  }
+}
\ No newline at end of file

From eb8158e9963b6dc518fbb24ba5bd36251e5c47f7 Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Fri, 26 Jul 2024 17:36:18 +0200
Subject: [PATCH 02/81] fix invalid wallet pointer getting set even when we
 throw (#1556)

* fix invalid wallet pointer getting set even when we throw

* Hide "wallet seeds" field if there is no seeds (cases of restore from keys)

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
---
 cw_monero/lib/api/wallet_manager.dart      | 37 +++++++++++--------
 cw_wownero/lib/api/wallet_manager.dart     | 41 +++++++++++++---------
 lib/view_model/wallet_keys_view_model.dart | 12 +++----
 3 files changed, 53 insertions(+), 37 deletions(-)

diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart
index 02ce2b7d6..50ab41e04 100644
--- a/cw_monero/lib/api/wallet_manager.dart
+++ b/cw_monero/lib/api/wallet_manager.dart
@@ -32,13 +32,14 @@ void createWalletSync(
     required String language,
     int nettype = 0}) {
   txhistory = null;
-  wptr = monero.WalletManager_createWallet(wmPtr,
+  final newWptr = monero.WalletManager_createWallet(wmPtr,
       path: path, password: password, language: language, networkType: 0);
 
-  final status = monero.Wallet_status(wptr!);
+  final status = monero.Wallet_status(newWptr);
   if (status != 0) {
-    throw WalletCreationException(message: monero.Wallet_errorString(wptr!));
+    throw WalletCreationException(message: monero.Wallet_errorString(newWptr));
   }
+  wptr = newWptr;
   monero.Wallet_store(wptr!, path: path);
   openedWalletsByPath[path] = wptr!;
 
@@ -57,7 +58,7 @@ void restoreWalletFromSeedSync(
     int nettype = 0,
     int restoreHeight = 0}) {
   txhistory = null;
-  wptr = monero.WalletManager_recoveryWallet(
+  final newWptr = monero.WalletManager_recoveryWallet(
     wmPtr,
     path: path,
     password: password,
@@ -67,12 +68,13 @@ void restoreWalletFromSeedSync(
     networkType: 0,
   );
 
-  final status = monero.Wallet_status(wptr!);
+  final status = monero.Wallet_status(newWptr);
 
   if (status != 0) {
-    final error = monero.Wallet_errorString(wptr!);
+    final error = monero.Wallet_errorString(newWptr);
     throw WalletRestoreFromSeedException(message: error);
   }
+  wptr = newWptr;
 
   openedWalletsByPath[path] = wptr!;
 }
@@ -87,7 +89,7 @@ void restoreWalletFromKeysSync(
     int nettype = 0,
     int restoreHeight = 0}) {
   txhistory = null;
-  wptr = monero.WalletManager_createWalletFromKeys(
+  final newWptr = monero.WalletManager_createWalletFromKeys(
     wmPtr,
     path: path,
     password: password,
@@ -98,12 +100,14 @@ void restoreWalletFromKeysSync(
     nettype: 0,
   );
 
-  final status = monero.Wallet_status(wptr!);
+  final status = monero.Wallet_status(newWptr);
   if (status != 0) {
     throw WalletRestoreFromKeysException(
-        message: monero.Wallet_errorString(wptr!));
+        message: monero.Wallet_errorString(newWptr));
   }
 
+  wptr = newWptr;
+
   openedWalletsByPath[path] = wptr!;
 }
 
@@ -128,7 +132,7 @@ void restoreWalletFromSpendKeySync(
   // );
   
   txhistory = null;
-  wptr = monero.WalletManager_createDeterministicWalletFromSpendKey(
+  final newWptr = monero.WalletManager_createDeterministicWalletFromSpendKey(
     wmPtr,
     path: path,
     password: password,
@@ -138,14 +142,16 @@ void restoreWalletFromSpendKeySync(
     restoreHeight: restoreHeight,
   );
 
-  final status = monero.Wallet_status(wptr!);
+  final status = monero.Wallet_status(newWptr);
 
   if (status != 0) {
-    final err = monero.Wallet_errorString(wptr!);
+    final err = monero.Wallet_errorString(newWptr);
     print("err: $err");
     throw WalletRestoreFromKeysException(message: err);
   }
 
+  wptr = newWptr;
+
   monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
 
   storeSync();
@@ -203,15 +209,16 @@ void loadWallet(
       });
     }
     txhistory = null;
-    wptr = monero.WalletManager_openWallet(wmPtr,
+    final newWptr = monero.WalletManager_openWallet(wmPtr,
         path: path, password: password);
     _lastOpenedWallet = path;
-    final status = monero.Wallet_status(wptr!);
+    final status = monero.Wallet_status(newWptr);
     if (status != 0) {
-      final err = monero.Wallet_errorString(wptr!);
+      final err = monero.Wallet_errorString(newWptr);
       print(err);
       throw WalletOpeningException(message: err);
     }
+    wptr = newWptr;
     openedWalletsByPath[path] = wptr!;
   }
 }
diff --git a/cw_wownero/lib/api/wallet_manager.dart b/cw_wownero/lib/api/wallet_manager.dart
index 68d0796f9..afcc536e7 100644
--- a/cw_wownero/lib/api/wallet_manager.dart
+++ b/cw_wownero/lib/api/wallet_manager.dart
@@ -32,13 +32,14 @@ void createWalletSync(
     required String language,
     int nettype = 0}) {
   txhistory = null;
-  wptr = wownero.WalletManager_createWallet(wmPtr,
+  final newWptr = wownero.WalletManager_createWallet(wmPtr,
       path: path, password: password, language: language, networkType: 0);
 
-  final status = wownero.Wallet_status(wptr!);
+  final status = wownero.Wallet_status(newWptr);
   if (status != 0) {
-    throw WalletCreationException(message: wownero.Wallet_errorString(wptr!));
+    throw WalletCreationException(message: wownero.Wallet_errorString(newWptr));
   }
+  wptr = newWptr;
   wownero.Wallet_store(wptr!, path: path);
   openedWalletsByPath[path] = wptr!;
 
@@ -56,9 +57,10 @@ void restoreWalletFromSeedSync(
     required String seed,
     int nettype = 0,
     int restoreHeight = 0}) {
+  var newWptr;
   if (seed.split(" ").length == 14) {
     txhistory = null;
-    wptr = wownero.WOWNERO_deprecated_restore14WordSeed(
+    newWptr = wownero.WOWNERO_deprecated_restore14WordSeed(
       path: path,
       password: password,
       language: seed, // I KNOW - this is supposed to be called seed
@@ -70,7 +72,7 @@ void restoreWalletFromSeedSync(
     );
   } else {
     txhistory = null;
-    wptr = wownero.WalletManager_recoveryWallet(
+    newWptr = wownero.WalletManager_recoveryWallet(
       wmPtr,
       path: path,
       password: password,
@@ -81,13 +83,15 @@ void restoreWalletFromSeedSync(
     );
   }
 
-  final status = wownero.Wallet_status(wptr!);
+  final status = wownero.Wallet_status(newWptr);
 
   if (status != 0) {
-    final error = wownero.Wallet_errorString(wptr!);
+    final error = wownero.Wallet_errorString(newWptr);
     throw WalletRestoreFromSeedException(message: error);
   }
 
+  wptr = newWptr;
+
   openedWalletsByPath[path] = wptr!;
 }
 
@@ -101,7 +105,7 @@ void restoreWalletFromKeysSync(
     int nettype = 0,
     int restoreHeight = 0}) {
   txhistory = null;
-  wptr = wownero.WalletManager_createWalletFromKeys(
+  final newWptr = wownero.WalletManager_createWalletFromKeys(
     wmPtr,
     path: path,
     password: password,
@@ -112,12 +116,14 @@ void restoreWalletFromKeysSync(
     nettype: 0,
   );
 
-  final status = wownero.Wallet_status(wptr!);
+  final status = wownero.Wallet_status(newWptr);
   if (status != 0) {
     throw WalletRestoreFromKeysException(
-        message: wownero.Wallet_errorString(wptr!));
+        message: wownero.Wallet_errorString(newWptr));
   }
 
+  wptr = newWptr;
+
   openedWalletsByPath[path] = wptr!;
 }
 
@@ -142,7 +148,7 @@ void restoreWalletFromSpendKeySync(
   // );
 
   txhistory = null;
-  wptr = wownero.WalletManager_createDeterministicWalletFromSpendKey(
+  final newWptr = wownero.WalletManager_createDeterministicWalletFromSpendKey(
     wmPtr,
     path: path,
     password: password,
@@ -152,14 +158,16 @@ void restoreWalletFromSpendKeySync(
     restoreHeight: restoreHeight,
   );
 
-  final status = wownero.Wallet_status(wptr!);
+  final status = wownero.Wallet_status(newWptr);
 
   if (status != 0) {
-    final err = wownero.Wallet_errorString(wptr!);
+    final err = wownero.Wallet_errorString(newWptr);
     print("err: $err");
     throw WalletRestoreFromKeysException(message: err);
   }
 
+  wptr = newWptr;
+
   wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
 
   storeSync();
@@ -217,15 +225,16 @@ void loadWallet(
       });
     }
     txhistory = null;
-    wptr = wownero.WalletManager_openWallet(wmPtr,
+    final newWptr = wownero.WalletManager_openWallet(wmPtr,
         path: path, password: password);
     _lastOpenedWallet = path;
-    final status = wownero.Wallet_status(wptr!);
+    final status = wownero.Wallet_status(newWptr);
     if (status != 0) {
-      final err = wownero.Wallet_errorString(wptr!);
+      final err = wownero.Wallet_errorString(newWptr);
       print(err);
       throw WalletOpeningException(message: err);
     }
+    wptr = newWptr;
     openedWalletsByPath[path] = wptr!;
   }
 }
diff --git a/lib/view_model/wallet_keys_view_model.dart b/lib/view_model/wallet_keys_view_model.dart
index 511822601..1d5c27fed 100644
--- a/lib/view_model/wallet_keys_view_model.dart
+++ b/lib/view_model/wallet_keys_view_model.dart
@@ -83,8 +83,8 @@ abstract class WalletKeysViewModelBase with Store {
           StandartListItem(
               title: S.current.view_key_private,
               value: keys['privateViewKey']!),
-        StandartListItem(
-            title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
+        if (_appStore.wallet!.seed!.isNotEmpty)
+          StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
       ]);
 
       if (_appStore.wallet?.seed != null &&
@@ -123,8 +123,8 @@ abstract class WalletKeysViewModelBase with Store {
           StandartListItem(
               title: S.current.view_key_private,
               value: keys['privateViewKey']!),
-        StandartListItem(
-            title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
+        if (_appStore.wallet!.seed!.isNotEmpty)
+          StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
       ]);
     }
 
@@ -147,8 +147,8 @@ abstract class WalletKeysViewModelBase with Store {
           StandartListItem(
               title: S.current.view_key_private,
               value: keys['privateViewKey']!),
-        StandartListItem(
-            title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
+        if (_appStore.wallet!.seed!.isNotEmpty)
+          StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
       ]);
 
       if (_appStore.wallet?.seed != null &&

From 56ea67666dd928f78a125f00a5308bfba9a808dd Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Mon, 29 Jul 2024 13:09:53 -0700
Subject: [PATCH 03/81] connection reliability updates, update kotlin code to
 match swift code, minor electrum error handling

---
 cw_bitcoin/lib/electrum.dart                  | 19 ++--
 .../com/cakewallet/mweb/CwMwebPlugin.kt       |  6 ++
 cw_mweb/ios/Classes/CwMwebPlugin.swift        | 96 +++++++++----------
 cw_mweb/lib/cw_mweb.dart                      | 37 ++++++-
 cw_mweb/lib/cw_mweb_method_channel.dart       |  5 +
 cw_mweb/lib/cw_mweb_platform_interface.dart   |  4 +
 6 files changed, 107 insertions(+), 60 deletions(-)

diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart
index 983da52d2..b02e1d29a 100644
--- a/cw_bitcoin/lib/electrum.dart
+++ b/cw_bitcoin/lib/electrum.dart
@@ -356,14 +356,19 @@ class ElectrumClient {
   BehaviorSubject<Map<String, dynamic>>? tipListener;
   int? currentTip;
   Future<int?> getCurrentBlockChainTip() async {
-    final method = 'blockchain.headers.subscribe';
-    final cb = (result) => currentTip = result['height'] as int;
-    if (tipListener == null) {
-      tipListener = subscribe(id: method, method: method);
-      tipListener?.listen(cb);
-      callWithTimeout(method: method).then(cb);
+    try {
+      final method = 'blockchain.headers.subscribe';
+      final cb = (result) => currentTip = result['height'] as int;
+      if (tipListener == null) {
+        tipListener = subscribe(id: method, method: method);
+        tipListener?.listen(cb);
+        callWithTimeout(method: method).then(cb);
+      }
+      return currentTip;
+    } catch (_) {
+      // our websocket connection was likely terminated ungracefully :/
+      return null;
     }
-    return currentTip;
   }
 
   BehaviorSubject<Object>? chainTipSubscribe() {
diff --git a/cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt b/cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt
index fa4fc909f..2b366ad76 100644
--- a/cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt
+++ b/cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt
@@ -32,6 +32,11 @@ class CwMwebPlugin: FlutterPlugin, MethodCallHandler {
       server = server ?: Mwebd.newServer("", dataDir, "")
       port = port ?: server?.start(0)
       result.success(port)
+    } else if (call.method == "stop") {
+      server?.stop()
+      server = null
+      port = null
+      result.success(null)
     } else {
       result.notImplemented()
     }
@@ -41,5 +46,6 @@ class CwMwebPlugin: FlutterPlugin, MethodCallHandler {
     channel.setMethodCallHandler(null)
     server?.stop()
     server = null
+    port = null
   }
 }
diff --git a/cw_mweb/ios/Classes/CwMwebPlugin.swift b/cw_mweb/ios/Classes/CwMwebPlugin.swift
index 996d4184a..5c45a8434 100644
--- a/cw_mweb/ios/Classes/CwMwebPlugin.swift
+++ b/cw_mweb/ios/Classes/CwMwebPlugin.swift
@@ -11,6 +11,7 @@ public class CwMwebPlugin: NSObject, FlutterPlugin {
 
   private static var server: MwebdServer?
   private static var port: Int = 0
+  private static var dataDir: String?
     
   public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
       switch call.method {
@@ -18,54 +19,53 @@ public class CwMwebPlugin: NSObject, FlutterPlugin {
           result("iOS " + UIDevice.current.systemVersion)
       case "start":
           let args = call.arguments as? [String: String]
-        //   print("args: \(args)")
           let dataDir = args?["dataDir"]
-          var error: NSError?
-
-          if dataDir == "stop" && CwMwebPlugin.server != nil {
-              print("Stopping server")
-              CwMwebPlugin.server?.stop()
-              CwMwebPlugin.server = nil
-              result(0)
-              return
-          }
-          
-          if CwMwebPlugin.server == nil {
-              CwMwebPlugin.server = MwebdNewServer("", dataDir, "", &error)
-              
-              if let server = CwMwebPlugin.server {
-                  do {
-                      print("starting server \(CwMwebPlugin.port)")
-                      try server.start(0, ret0_: &CwMwebPlugin.port)
-                      result(CwMwebPlugin.port)
-                  } catch let startError as NSError {
-                      print("Server Start Error: \(startError.localizedDescription)")
-                      result(FlutterError(code: "Server Start Error", message: startError.localizedDescription, details: nil))
-                  }
-              } else if let error = error {
-                  print("Server Creation Error: \(error.localizedDescription)")
-                  result(FlutterError(code: "Server Creation Error", message: error.localizedDescription, details: nil))
-              } else {
-                  print("Unknown Error: Failed to create server")
-                  result(FlutterError(code: "Unknown Error", message: "Failed to create server", details: nil))
-              }
-          } else {
-            print("Server already running on port: \(CwMwebPlugin.port)")
-//              result(FlutterError(code: "Server Already Running", message: "The server is already running", details: nil))
-              result(CwMwebPlugin.port)
-          }
-      
-      
-      // result(0)
-    default:
-      result(FlutterMethodNotImplemented)
-    }
+          CwMwebPlugin.dataDir = dataDir
+          startServer(result: result)
+      case "stop":
+          stopServer()
+          result(nil)
+      default:
+          result(FlutterMethodNotImplemented)
+      }
   }
 
-    deinit {
-        print("Stopping and cleaning up server")
-        // Perform cleanup tasks
-        CwMwebPlugin.server?.stop()
-        CwMwebPlugin.server = nil
-    }
-}
+  private func startServer(result: @escaping FlutterResult) {
+      if CwMwebPlugin.server == nil {
+          var error: NSError?
+          CwMwebPlugin.server = MwebdNewServer("", CwMwebPlugin.dataDir, "", &error)
+          
+          if let server = CwMwebPlugin.server {
+              do {
+                  print("Starting server...")
+                  try server.start(0, ret0_: &CwMwebPlugin.port)
+                  print("Server started successfully on port: \(CwMwebPlugin.port)")
+                  result(CwMwebPlugin.port)
+              } catch let startError as NSError {
+                  print("Server Start Error: \(startError.localizedDescription)")
+                  result(FlutterError(code: "Server Start Error", message: startError.localizedDescription, details: nil))
+              }
+          } else if let error = error {
+              print("Server Creation Error: \(error.localizedDescription)")
+              result(FlutterError(code: "Server Creation Error", message: error.localizedDescription, details: nil))
+          } else {
+              print("Unknown Error: Failed to create server")
+              result(FlutterError(code: "Unknown Error", message: "Failed to create server", details: nil))
+          }
+      } else {
+          print("Server already running on port: \(CwMwebPlugin.port)")
+          result(CwMwebPlugin.port)
+      }
+  }
+
+  private func stopServer() {
+      print("Stopping server")
+      CwMwebPlugin.server?.stop()
+      CwMwebPlugin.server = nil
+      CwMwebPlugin.port = 0
+  }
+
+  deinit {
+      stopServer()
+  }
+}
\ No newline at end of file
diff --git a/cw_mweb/lib/cw_mweb.dart b/cw_mweb/lib/cw_mweb.dart
index 1db0c02f5..98afc73dd 100644
--- a/cw_mweb/lib/cw_mweb.dart
+++ b/cw_mweb/lib/cw_mweb.dart
@@ -6,22 +6,48 @@ import 'mwebd.pbgrpc.dart';
 class CwMweb {
   static RpcClient? _rpcClient;
   static ClientChannel? _clientChannel;
+  static int? _port;
 
-  static Future<RpcClient> stub() async {
+  static Future<void> _initializeClient() async {
     final appDir = await getApplicationSupportDirectory();
-    int port = await CwMwebPlatform.instance.start(appDir.path) ?? 0;
+    _port = await CwMwebPlatform.instance.start(appDir.path);
+    if (_port == null || _port == 0) {
+      throw Exception("Failed to start server");
+    }
+    print("Attempting to connect to server on port: $_port");
+
     _clientChannel = ClientChannel('127.0.0.1',
-        port: port,
+        port: _port!,
         options: const ChannelOptions(
           credentials: ChannelCredentials.insecure(),
           keepAlive: ClientKeepAliveOptions(permitWithoutCalls: true),
         ));
     _rpcClient = RpcClient(_clientChannel!);
-    return _rpcClient!;
+  }
+
+  static Future<RpcClient> stub({int maxRetries = 3}) async {
+    for (int i = 0; i < maxRetries; i++) {
+      try {
+        if (_rpcClient == null) {
+          await _initializeClient();
+        }
+        final status = await _rpcClient!
+            .status(StatusRequest(), options: CallOptions(timeout: const Duration(seconds: 3)));
+        if (status.blockTime == 0) {
+          throw Exception("blockTime shouldn't be 0! (this connection is likely broken)");
+        }
+        return _rpcClient!;
+      } catch (e) {
+        print("Attempt $i failed: $e");
+        await stop(); // call stop so we create a new instance before retrying
+        await Future.delayed(const Duration(seconds: 2)); // wait before retrying
+      }
+    }
+    throw Exception("Failed to connect after $maxRetries attempts");
   }
 
   static Future<void> stop() async {
-    await CwMwebPlatform.instance.start("stop");
+    await CwMwebPlatform.instance.stop();
     await cleanup();
   }
 
@@ -29,5 +55,6 @@ class CwMweb {
     await _clientChannel?.terminate();
     _rpcClient = null;
     _clientChannel = null;
+    _port = null;
   }
 }
diff --git a/cw_mweb/lib/cw_mweb_method_channel.dart b/cw_mweb/lib/cw_mweb_method_channel.dart
index cc880c6df..9451db310 100644
--- a/cw_mweb/lib/cw_mweb_method_channel.dart
+++ b/cw_mweb/lib/cw_mweb_method_channel.dart
@@ -14,4 +14,9 @@ class MethodChannelCwMweb extends CwMwebPlatform {
     final result = await methodChannel.invokeMethod<int>('start', {'dataDir': dataDir});
     return result;
   }
+
+  @override
+  Future<void> stop() async {
+    await methodChannel.invokeMethod<void>('stop');
+  }
 }
diff --git a/cw_mweb/lib/cw_mweb_platform_interface.dart b/cw_mweb/lib/cw_mweb_platform_interface.dart
index 974e07284..a5a46adbc 100644
--- a/cw_mweb/lib/cw_mweb_platform_interface.dart
+++ b/cw_mweb/lib/cw_mweb_platform_interface.dart
@@ -26,4 +26,8 @@ abstract class CwMwebPlatform extends PlatformInterface {
   Future<int?> start(String dataDir) {
     throw UnimplementedError('start() has not been implemented.');
   }
+
+  Future<void> stop() {
+    throw UnimplementedError('stop() has not been implemented.');
+  }
 }

From a2549b42b04fbce33b77dbf3fcdd4d6e711ac192 Mon Sep 17 00:00:00 2001
From: David Adegoke <64401859+Blazebrain@users.noreply.github.com>
Date: Wed, 31 Jul 2024 02:26:56 +0100
Subject: [PATCH 04/81] CW-680: Fix Wakelock Issue (#1557)

* chore: Bump up wakelock_plus dependency version

* Fix: try fixing ci failure by bumping jdk version
---
 .github/workflows/pr_test_build.yml | 2 +-
 pubspec_base.yaml                   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index f37919e9d..4c46137ac 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -41,7 +41,7 @@ jobs:
       - uses: actions/checkout@v2
       - uses: actions/setup-java@v1
         with:
-          java-version: "11.x"
+          java-version: "17.x"
       - name: Configure placeholder git details
         run: |
           git config --global user.email "CI@cakewallet.com"
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 2cfeae716..67a162674 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -66,7 +66,7 @@ dependencies:
       url: https://github.com/cake-tech/device_display_brightness.git
       ref: master
   workmanager: ^0.5.1
-  wakelock_plus: ^1.1.3
+  wakelock_plus: ^1.2.5
   flutter_mailer: ^2.0.2
   device_info_plus: ^9.1.0
   base32: 2.1.3

From 9da9bee384588675dda11cf28b58e74d0ac7a030 Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Tue, 6 Aug 2024 13:01:38 +0200
Subject: [PATCH 05/81] make the error more readable when node fails to respond
 (#1570)

---
 cw_monero/lib/api/transaction_history.dart | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart
index 5e33c6c56..c28f162be 100644
--- a/cw_monero/lib/api/transaction_history.dart
+++ b/cw_monero/lib/api/transaction_history.dart
@@ -110,7 +110,10 @@ Future<PendingTransactionDescription> createTransactionSync(
   })();
 
   if (error != null) {
-    final message = error;
+    String message = error;
+    if (message.contains("RPC error")) {
+      message = "Invalid node response, please try again or switch node\n\ntrace: $message";
+    }
     throw CreationTransactionException(message: message);
   }
 

From 5e944a8bf7069f0b083f177c44d1b4e5eb1f265e Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Tue, 6 Aug 2024 17:59:44 +0300
Subject: [PATCH 06/81] Try to show seeds if wallet files gets corrupted
 (#1567)

* add litecoin nodes
minor ui fix

* Try to open the wallet or fetch the seeds and show them to the user

* make sure the seeds are only displayed after authentication
---
 assets/litecoin_electrum_server_list.yml      | 17 ++++++-
 cw_core/lib/wallet_service.dart               | 19 +++++++
 cw_monero/lib/monero_wallet.dart              |  1 -
 cw_monero/lib/monero_wallet_service.dart      | 37 +++++++++++---
 lib/core/wallet_loading_service.dart          | 31 ++++++++++-
 lib/di.dart                                   | 14 +++++
 .../on_authentication_state_change.dart       | 14 +++++
 .../monero_account_edit_or_create_page.dart   |  4 +-
 lib/utils/exception_handler.dart              | 51 +++++++++++++++++++
 9 files changed, 175 insertions(+), 13 deletions(-)

diff --git a/assets/litecoin_electrum_server_list.yml b/assets/litecoin_electrum_server_list.yml
index 991762885..550b900e1 100644
--- a/assets/litecoin_electrum_server_list.yml
+++ b/assets/litecoin_electrum_server_list.yml
@@ -1,4 +1,19 @@
 -
   uri: ltc-electrum.cakewallet.com:50002
   useSSL: true
-  isDefault: true
\ No newline at end of file
+  isDefault: true
+-
+  uri: litecoin.stackwallet.com:20063
+  useSSL: true
+-
+  uri: electrum-ltc.bysh.me:50002
+  useSSL: true
+-
+  uri: lightweight.fiatfaucet.com:50002
+  useSSL: true
+-
+  uri: electrum.ltc.xurious.com:50002
+  useSSL: true
+-
+  uri: backup.electrum-ltc.org:443
+  useSSL: true
diff --git a/cw_core/lib/wallet_service.dart b/cw_core/lib/wallet_service.dart
index fcbd59ff3..d90ae30bc 100644
--- a/cw_core/lib/wallet_service.dart
+++ b/cw_core/lib/wallet_service.dart
@@ -1,6 +1,8 @@
+import 'dart:convert';
 import 'dart:io';
 
 import 'package:cw_core/pathForWallet.dart';
+import 'package:cw_core/utils/file.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -42,4 +44,21 @@ abstract class WalletService<N extends WalletCredentials, RFS extends WalletCred
       await File(walletDirPath).copy(backupWalletDirPath);
     }
   }
+
+  Future<String> getSeeds(String name, String password, WalletType type) async {
+    try {
+      final path = await pathForWallet(name: name, type: type);
+      final jsonSource = await read(path: path, password: password);
+      try {
+        final data = json.decode(jsonSource) as Map;
+        return data['mnemonic'] as String? ?? '';
+      } catch (_) {
+        // if not a valid json
+        return jsonSource.substring(0, 200);
+      }
+    } catch (_) {
+      // if the file couldn't be opened or read
+      return '';
+    }
+  }
 }
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index 4b596648e..b8e3c2765 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -19,7 +19,6 @@ import 'package:cw_core/transaction_priority.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
-import 'package:cw_monero/api/account_list.dart';
 import 'package:cw_monero/api/coins_info.dart';
 import 'package:cw_monero/api/monero_output.dart';
 import 'package:cw_monero/api/structs/pending_transaction.dart';
diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart
index ea2f3b766..3588ebb78 100644
--- a/cw_monero/lib/monero_wallet_service.dart
+++ b/cw_monero/lib/monero_wallet_service.dart
@@ -57,8 +57,11 @@ class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials {
   final String spendKey;
 }
 
-class MoneroWalletService extends WalletService<MoneroNewWalletCredentials,
-    MoneroRestoreWalletFromSeedCredentials, MoneroRestoreWalletFromKeysCredentials, MoneroNewWalletCredentials> {
+class MoneroWalletService extends WalletService<
+    MoneroNewWalletCredentials,
+    MoneroRestoreWalletFromSeedCredentials,
+    MoneroRestoreWalletFromKeysCredentials,
+    MoneroNewWalletCredentials> {
   MoneroWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
 
   final Box<WalletInfo> walletInfoSource;
@@ -183,11 +186,8 @@ class MoneroWalletService extends WalletService<MoneroNewWalletCredentials,
       final wmaddr = wmPtr.address;
       final waddr = openedWalletsByPath["$path/$wallet"]!.address;
       // await Isolate.run(() {
-        monero.WalletManager_closeWallet(
-            Pointer.fromAddress(wmaddr),
-            Pointer.fromAddress(waddr),
-            false
-        );
+      monero.WalletManager_closeWallet(
+          Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), false);
       // });
       openedWalletsByPath.remove("$path/$wallet");
       print("wallet closed");
@@ -248,7 +248,8 @@ class MoneroWalletService extends WalletService<MoneroNewWalletCredentials,
 
   @override
   Future<MoneroWallet> restoreFromHardwareWallet(MoneroNewWalletCredentials credentials) {
-    throw UnimplementedError("Restoring a Monero wallet from a hardware wallet is not yet supported!");
+    throw UnimplementedError(
+        "Restoring a Monero wallet from a hardware wallet is not yet supported!");
   }
 
   @override
@@ -350,4 +351,24 @@ class MoneroWalletService extends WalletService<MoneroNewWalletCredentials,
       print(e.toString());
     }
   }
+
+  @override
+  Future<String> getSeeds(String name, String password, WalletType type) async {
+    try {
+      final path = await pathForWallet(name: name, type: getType());
+
+      if (walletFilesExist(path)) {
+        await repairOldAndroidWallet(name);
+      }
+
+      await monero_wallet_manager.openWalletAsync({'path': path, 'password': password});
+      final walletInfo = walletInfoSource.values
+          .firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
+      final wallet = MoneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
+      return wallet.seed;
+    } catch (_) {
+      // if the file couldn't be opened or read
+      return '';
+    }
+  }
 }
diff --git a/lib/core/wallet_loading_service.dart b/lib/core/wallet_loading_service.dart
index 1f17a7a1c..ca29576e4 100644
--- a/lib/core/wallet_loading_service.dart
+++ b/lib/core/wallet_loading_service.dart
@@ -1,6 +1,9 @@
+import 'dart:async';
+
 import 'package:cake_wallet/core/generate_wallet_password.dart';
 import 'package:cake_wallet/core/key_service.dart';
 import 'package:cake_wallet/entities/preferences_key.dart';
+import 'package:cake_wallet/reactions/on_authentication_state_change.dart';
 import 'package:cake_wallet/utils/exception_handler.dart';
 import 'package:cw_core/cake_hive.dart';
 import 'package:cw_core/wallet_base.dart';
@@ -52,6 +55,12 @@ class WalletLoadingService {
     } catch (error, stack) {
       ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack));
 
+      // try fetching the seeds of the corrupted wallet to show it to the user
+      String corruptedWalletsSeeds = "Corrupted wallets seeds (if retrievable, empty otherwise):";
+      try {
+        corruptedWalletsSeeds += await _getCorruptedWalletSeeds(name, type);
+      } catch (_) {}
+
       // try opening another wallet that is not corrupted to give user access to the app
       final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
 
@@ -69,12 +78,23 @@ class WalletLoadingService {
           await sharedPreferences.setInt(
               PreferencesKey.currentWalletType, serializeToInt(wallet.type));
 
+          // if found a wallet that is not corrupted, then still display the seeds of the corrupted ones
+          authenticatedErrorStreamController.add(corruptedWalletsSeeds);
+
           return wallet;
-        } catch (_) {}
+        } catch (_) {
+          // save seeds and show corrupted wallets' seeds to the user
+          try {
+            final seeds = await _getCorruptedWalletSeeds(walletInfo.name, walletInfo.type);
+            if (!corruptedWalletsSeeds.contains(seeds)) {
+              corruptedWalletsSeeds += seeds;
+            }
+          } catch (_) {}
+        }
       }
 
       // if all user's wallets are corrupted throw exception
-      throw error;
+      throw error.toString() + "\n\n" + corruptedWalletsSeeds;
     }
   }
 
@@ -96,4 +116,11 @@ class WalletLoadingService {
     isPasswordUpdated = true;
     await sharedPreferences.setBool(key, isPasswordUpdated);
   }
+
+  Future<String> _getCorruptedWalletSeeds(String name, WalletType type) async {
+    final walletService = walletServiceFactory.call(type);
+    final password = await keyService.getWalletPassword(walletName: name);
+
+    return "\n\n$type ($name): ${await walletService.getSeeds(name, password, type)}";
+  }
 }
diff --git a/lib/di.dart b/lib/di.dart
index 1462370fc..a37574f21 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -1,3 +1,5 @@
+import 'dart:async' show Timer;
+
 import 'package:cake_wallet/.secrets.g.dart' as secrets;
 import 'package:cake_wallet/anonpay/anonpay_api.dart';
 import 'package:cake_wallet/anonpay/anonpay_info_base.dart';
@@ -487,6 +489,7 @@ Future<void> setup({
 
         if (loginError != null) {
           authPageState.changeProcessText('ERROR: ${loginError.toString()}');
+          loginError = null;
         }
 
         ReactionDisposer? _reaction;
@@ -498,6 +501,17 @@ Future<void> setup({
             linkViewModel.handleLink();
           }
         });
+
+        Timer.periodic(Duration(seconds: 1), (timer) {
+          if (timer.tick > 30) {
+            timer.cancel();
+          }
+
+          if (loginError != null) {
+            authPageState.changeProcessText('ERROR: ${loginError.toString()}');
+            timer.cancel();
+          }
+        });
       }
     });
   });
diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart
index 5f1214b76..e4fd9b32f 100644
--- a/lib/reactions/on_authentication_state_change.dart
+++ b/lib/reactions/on_authentication_state_change.dart
@@ -1,3 +1,5 @@
+import 'dart:async';
+
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/utils/exception_handler.dart';
 import 'package:flutter/widgets.dart';
@@ -8,9 +10,16 @@ import 'package:cake_wallet/store/authentication_store.dart';
 ReactionDisposer? _onAuthenticationStateChange;
 
 dynamic loginError;
+StreamController<dynamic> authenticatedErrorStreamController = StreamController<dynamic>();
 
 void startAuthenticationStateChange(
     AuthenticationStore authenticationStore, GlobalKey<NavigatorState> navigatorKey) {
+  authenticatedErrorStreamController.stream.listen((event) {
+    if (authenticationStore.state == AuthenticationState.allowed) {
+      ExceptionHandler.showError(event.toString(), delayInSeconds: 3);
+    }
+  });
+
   _onAuthenticationStateChange ??= autorun((_) async {
     final state = authenticationStore.state;
 
@@ -26,6 +35,11 @@ void startAuthenticationStateChange(
 
     if (state == AuthenticationState.allowed) {
       await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
+      if (!(await authenticatedErrorStreamController.stream.isEmpty)) {
+        ExceptionHandler.showError(
+            (await authenticatedErrorStreamController.stream.first).toString());
+        authenticatedErrorStreamController.stream.drain();
+      }
       return;
     }
   });
diff --git a/lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart b/lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart
index 779628be8..2c9918d74 100644
--- a/lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart
+++ b/lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart
@@ -51,7 +51,9 @@ class MoneroAccountEditOrCreatePage extends BasePage {
 
                           await moneroAccountCreationViewModel.save();
 
-                          Navigator.of(context).pop(_textController.text);
+                          if (context.mounted) {
+                            Navigator.of(context).pop(_textController.text);
+                          }
                         },
                         text: moneroAccountCreationViewModel.isEdit
                             ? S.of(context).rename
diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart
index b19b1bb7e..6045c0004 100644
--- a/lib/utils/exception_handler.dart
+++ b/lib/utils/exception_handler.dart
@@ -4,11 +4,13 @@ import 'package:cake_wallet/entities/preferences_key.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/main.dart';
 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
+import 'package:cake_wallet/utils/show_bar.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:cw_core/root_dir.dart';
 import 'package:device_info_plus/device_info_plus.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
 import 'package:flutter_mailer/flutter_mailer.dart';
 import 'package:cake_wallet/utils/package_info.dart';
 import 'package:shared_preferences/shared_preferences.dart';
@@ -254,4 +256,53 @@ class ExceptionHandler {
       'productName': data.productName,
     };
   }
+
+  static void showError(String error, {int? delayInSeconds}) async {
+    if (_hasError) {
+      return;
+    }
+    _hasError = true;
+
+    if (delayInSeconds != null) {
+      Future.delayed(Duration(seconds: delayInSeconds), () => _showCopyPopup(error));
+      return;
+    }
+
+    WidgetsBinding.instance.addPostFrameCallback(
+      (_) async => _showCopyPopup(error),
+    );
+  }
+
+  static Future<void> _showCopyPopup(String content) async {
+    if (navigatorKey.currentContext != null) {
+      final shouldCopy = await showPopUp<bool?>(
+        context: navigatorKey.currentContext!,
+        builder: (context) {
+          return AlertWithTwoActions(
+            isDividerExist: true,
+            alertTitle: S.of(context).error,
+            alertContent: content,
+            rightButtonText: S.of(context).copy,
+            leftButtonText: S.of(context).close,
+            actionRightButton: () {
+              Navigator.of(context).pop(true);
+            },
+            actionLeftButton: () {
+              Navigator.of(context).pop();
+            },
+          );
+        },
+      );
+
+      if (shouldCopy == true) {
+        await Clipboard.setData(ClipboardData(text: content));
+        await showBar<void>(
+          navigatorKey.currentContext!,
+          S.of(navigatorKey.currentContext!).copied_to_clipboard,
+        );
+      }
+    }
+
+    _hasError = false;
+  }
 }

From e58d87e94cc82e268fc5e5901e4bea47c7c4ce50 Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Wed, 7 Aug 2024 13:40:31 +0200
Subject: [PATCH 07/81] add card for when monero wallet is in broken state
 (#1578)

---
 .../screens/dashboard/pages/balance_page.dart   | 14 ++++++++++++++
 .../dashboard/dashboard_view_model.dart         | 17 +++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/lib/src/screens/dashboard/pages/balance_page.dart b/lib/src/screens/dashboard/pages/balance_page.dart
index d95c19dad..11abdeb58 100644
--- a/lib/src/screens/dashboard/pages/balance_page.dart
+++ b/lib/src/screens/dashboard/pages/balance_page.dart
@@ -250,6 +250,20 @@ class CryptoBalanceWidget extends StatelessWidget {
             Observer(builder: (context) {
               return Column(
                 children: [
+                  if (dashboardViewModel.isMoneroWalletBrokenReasons.isNotEmpty) ...[
+                    SizedBox(height: 10),
+                    Padding(
+                      padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
+                      child: DashBoardRoundedCardWidget(
+                        customBorder: 30,
+                        title: "Monero wallet is broken",
+                        subTitle: "Here are the things that are broken:\n - "
+                        +dashboardViewModel.isMoneroWalletBrokenReasons.join("\n - ")
+                        +"\n\nPlease restart your wallet and if it doesn't help contact our support.",
+                        onTap: () {},
+                      )
+                    )
+                  ],
                   if (dashboardViewModel.showSilentPaymentsCard) ...[
                     SizedBox(height: 10),
                     Padding(
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index 5b5353e06..06c565035 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -335,6 +335,23 @@ abstract class DashboardViewModelBase with Store {
       wallet.type == WalletType.wownero ||
       wallet.type == WalletType.haven;
 
+  @computed
+  List<String> get isMoneroWalletBrokenReasons {
+    if (wallet.type != WalletType.monero) return [];
+    final keys = monero!.getKeys(wallet);
+    List<String> errors = [
+      if (keys['privateSpendKey'] == List.generate(64, (index) => "0").join("")) "Private spend key is 0",
+      if (keys['privateViewKey'] == List.generate(64, (index) => "0").join("")) "private view key is 0",
+      if (keys['publicSpendKey'] == List.generate(64, (index) => "0").join("")) "public spend key is 0",
+      if (keys['publicViewKey'] == List.generate(64, (index) => "0").join("")) "private view key is 0",
+      if (wallet.seed == null) "wallet seed is null",
+      if (wallet.seed == "") "wallet seed is empty",
+      if (monero!.getSubaddressList(wallet).getAll(wallet)[0].address == "41d7FXjswpK1111111111111111111111111111111111111111111111111111111111111111111111111111112KhNi4") 
+        "primary address is invalid, you won't be able to receive / spend funds",
+    ];
+    return errors;
+  }
+
   @computed
   bool get hasSilentPayments => wallet.type == WalletType.bitcoin && !wallet.isHardwareWallet;
 

From 96e4a4eb6c41a0a3c541a617073096ef96c1492f Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Wed, 7 Aug 2024 18:12:49 +0200
Subject: [PATCH 08/81] monero fixes (#1581)

* correct comparision while syncing

* fix issue from report 25916.txt

* return proper address even if numSubaddresses returned 0
---
 cw_monero/lib/api/subaddress_list.dart       | 6 +++++-
 cw_monero/lib/api/wallet.dart                | 2 +-
 cw_monero/lib/monero_wallet_addresses.dart   | 2 +-
 cw_wownero/lib/api/subaddress_list.dart      | 6 +++++-
 cw_wownero/lib/wownero_wallet_addresses.dart | 2 +-
 5 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/cw_monero/lib/api/subaddress_list.dart b/cw_monero/lib/api/subaddress_list.dart
index 57edea76e..e5145692d 100644
--- a/cw_monero/lib/api/subaddress_list.dart
+++ b/cw_monero/lib/api/subaddress_list.dart
@@ -42,12 +42,16 @@ class Subaddress {
 
 List<Subaddress> getAllSubaddresses() {
   final size = monero.Wallet_numSubaddresses(wptr!, accountIndex: subaddress!.accountIndex);
-  return List.generate(size, (index) {
+  final list = List.generate(size, (index) {
     return Subaddress(
       accountIndex: subaddress!.accountIndex,
       addressIndex: index,
     );
   }).reversed.toList();
+  if (list.length == 0) {
+    list.add(Subaddress(addressIndex: subaddress!.accountIndex, accountIndex: 0));
+  }
+  return list;
 }
 
 void addSubaddressSync({required int accountIndex, required String label}) {
diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart
index 6ca9cd1bb..0f6e59c4e 100644
--- a/cw_monero/lib/api/wallet.dart
+++ b/cw_monero/lib/api/wallet.dart
@@ -131,7 +131,7 @@ void storeSync() async {
     return monero.Wallet_synchronized(Pointer.fromAddress(addr));
   });
   if (lastStorePointer == wptr!.address &&
-      lastStoreHeight + 5000 < monero.Wallet_blockChainHeight(wptr!) &&
+      lastStoreHeight + 5000 > monero.Wallet_blockChainHeight(wptr!) &&
       !synchronized) {
     return;
   }
diff --git a/cw_monero/lib/monero_wallet_addresses.dart b/cw_monero/lib/monero_wallet_addresses.dart
index f74e7dd5b..d4f22e46f 100644
--- a/cw_monero/lib/monero_wallet_addresses.dart
+++ b/cw_monero/lib/monero_wallet_addresses.dart
@@ -109,7 +109,7 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
         accountIndex: accountIndex,
         defaultLabel: defaultLabel,
         usedAddresses: usedAddresses.toList());
-    subaddress = subaddressList.subaddresses.last;
+    subaddress = (subaddressList.subaddresses.isEmpty) ? Subaddress(id: 0, address: address, label: defaultLabel) : subaddressList.subaddresses.last;
     address = subaddress!.address;
   }
 
diff --git a/cw_wownero/lib/api/subaddress_list.dart b/cw_wownero/lib/api/subaddress_list.dart
index cec7d94cb..d8c91a584 100644
--- a/cw_wownero/lib/api/subaddress_list.dart
+++ b/cw_wownero/lib/api/subaddress_list.dart
@@ -41,12 +41,16 @@ class Subaddress {
 
 List<Subaddress> getAllSubaddresses() {
   final size = wownero.Wallet_numSubaddresses(wptr!, accountIndex: subaddress!.accountIndex);
-  return List.generate(size, (index) {
+  final list = List.generate(size, (index) {
     return Subaddress(
       accountIndex: subaddress!.accountIndex,
       addressIndex: index,
     );
   }).reversed.toList();
+  if (list.isEmpty) {
+    list.add(Subaddress(addressIndex: 0, accountIndex: subaddress!.accountIndex));
+  }
+  return list;
 }
 
 void addSubaddressSync({required int accountIndex, required String label}) {
diff --git a/cw_wownero/lib/wownero_wallet_addresses.dart b/cw_wownero/lib/wownero_wallet_addresses.dart
index dc4b42840..9eeb182eb 100644
--- a/cw_wownero/lib/wownero_wallet_addresses.dart
+++ b/cw_wownero/lib/wownero_wallet_addresses.dart
@@ -109,7 +109,7 @@ abstract class WowneroWalletAddressesBase extends WalletAddresses with Store {
         accountIndex: accountIndex,
         defaultLabel: defaultLabel,
         usedAddresses: usedAddresses.toList());
-    subaddress = subaddressList.subaddresses.last;
+    subaddress = (subaddressList.subaddresses.isEmpty) ? Subaddress(id: 0, address: address, label: defaultLabel) : subaddressList.subaddresses.last;
     address = subaddress!.address;
   }
 

From 15d88e0f8dc8b9b3b055d913bb64e42ed5e322e0 Mon Sep 17 00:00:00 2001
From: Konstantin Ullrich <konstantinullrich12@gmail.com>
Date: Thu, 8 Aug 2024 12:17:17 +0200
Subject: [PATCH 09/81] Add Ledger Flex Support (#1576)

---
 cw_bitcoin/pubspec.yaml | 4 ++++
 cw_evm/pubspec.yaml     | 2 +-
 pubspec_base.yaml       | 2 +-
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml
index 66c5729e8..69ff3d29b 100644
--- a/cw_bitcoin/pubspec.yaml
+++ b/cw_bitcoin/pubspec.yaml
@@ -56,6 +56,10 @@ dev_dependencies:
   hive_generator: ^1.1.3
 
 dependency_overrides:
+  ledger_flutter:
+    git:
+      url: https://github.com/cake-tech/ledger-flutter.git
+      ref: cake-v3
   watcher: ^1.1.0
 
 # For information on the generic Dart part of this file, see the
diff --git a/cw_evm/pubspec.yaml b/cw_evm/pubspec.yaml
index e4b29b676..c3f4347c2 100644
--- a/cw_evm/pubspec.yaml
+++ b/cw_evm/pubspec.yaml
@@ -35,7 +35,7 @@ dependency_overrides:
   ledger_flutter:
     git:
       url: https://github.com/cake-tech/ledger-flutter.git
-      ref: cake
+      ref: cake-v3
   watcher: ^1.1.0
 
 dev_dependencies:
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 67a162674..84b4631fc 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -133,7 +133,7 @@ dependency_overrides:
   ledger_flutter:
     git:
       url: https://github.com/cake-tech/ledger-flutter.git
-      ref: cake-stax
+      ref: cake-v3
   web3dart:
     git:
       url: https://github.com/cake-tech/web3dart.git

From ba433ef6f30442e2ac69724fdcb4415699f3db8d Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Thu, 8 Aug 2024 03:27:04 -0700
Subject: [PATCH 10/81] Request timeout fix (#1584)

* always handle RequestFailedTimeoutException

* undo change that was for testing
---
 cw_bitcoin/lib/electrum.dart | 69 +++++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 25 deletions(-)

diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart
index b52015794..e3925ca74 100644
--- a/cw_bitcoin/lib/electrum.dart
+++ b/cw_bitcoin/lib/electrum.dart
@@ -236,25 +236,37 @@ class ElectrumClient {
         return [];
       });
 
-  Future<Map<String, dynamic>> getTransactionRaw({required String hash}) async =>
-      callWithTimeout(method: 'blockchain.transaction.get', params: [hash, true], timeout: 10000)
-          .then((dynamic result) {
-        if (result is Map<String, dynamic>) {
-          return result;
-        }
+  Future<Map<String, dynamic>> getTransactionRaw({required String hash}) async {
+    try {
+      final result = await callWithTimeout(
+          method: 'blockchain.transaction.get', params: [hash, true], timeout: 10000);
+      if (result is Map<String, dynamic>) {
+        return result;
+      }
+    } on RequestFailedTimeoutException catch (_) {
+      return <String, dynamic>{};
+    } catch (e) {
+      print("getTransactionRaw: ${e.toString()}");
+      return <String, dynamic>{};
+    }
+    return <String, dynamic>{};
+  }
 
-        return <String, dynamic>{};
-      });
-
-  Future<String> getTransactionHex({required String hash}) async =>
-      callWithTimeout(method: 'blockchain.transaction.get', params: [hash, false], timeout: 10000)
-          .then((dynamic result) {
-        if (result is String) {
-          return result;
-        }
-
-        return '';
-      });
+  Future<String> getTransactionHex({required String hash}) async {
+    try {
+      final result = await callWithTimeout(
+          method: 'blockchain.transaction.get', params: [hash, false], timeout: 10000);
+      if (result is String) {
+        return result;
+      }
+    } on RequestFailedTimeoutException catch (_) {
+      return '';
+    } catch (e) {
+      print("getTransactionHex: ${e.toString()}");
+      return '';
+    }
+    return '';
+  }
 
   Future<String> broadcastTransaction(
           {required String transactionRaw,
@@ -353,14 +365,21 @@ class ElectrumClient {
   //   "height": 520481,
   //   "hex": "00000020890208a0ae3a3892aa047c5468725846577cfcd9b512b50000000000000000005dc2b02f2d297a9064ee103036c14d678f9afc7e3d9409cf53fd58b82e938e8ecbeca05a2d2103188ce804c4"
   // }
-  Future<int?> getCurrentBlockChainTip() =>
-      callWithTimeout(method: 'blockchain.headers.subscribe').then((result) {
-        if (result is Map<String, dynamic>) {
-          return result["height"] as int;
-        }
 
-        return null;
-      });
+  Future<int?> getCurrentBlockChainTip() async {
+    try {
+      final result = await callWithTimeout(method: 'blockchain.headers.subscribe');
+      if (result is Map<String, dynamic>) {
+        return result["height"] as int;
+      }
+      return null;
+    } on RequestFailedTimeoutException catch (_) {
+      return null;
+    } catch (e) {
+      print("getCurrentBlockChainTip: ${e.toString()}");
+      return null;
+    }
+  }
 
   BehaviorSubject<Object>? chainTipSubscribe() {
     _id += 1;

From 8e7233b5c39faf19775989437649125b7563450d Mon Sep 17 00:00:00 2001
From: Konstantin Ullrich <konstantinullrich12@gmail.com>
Date: Fri, 9 Aug 2024 21:15:54 +0200
Subject: [PATCH 11/81] Monero stability and cleanup (#1572)

* migrate monero.dart from it's own repository to monero_c

* show errors when invalid monero_c library is being used

* Delete unused code

* Delete unused code

* Fix potential bug causing missing Polyseeds and tx-keys; Add Waring

* Remove unused wownero-code

* bump monero_c commit

---------

Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 cw_core/lib/monero_wallet_utils.dart          |    5 +-
 .../connection_to_node_exception.dart         |    5 -
 cw_monero/lib/api/structs/account_row.dart    |   12 -
 cw_monero/lib/api/structs/coins_info_row.dart |   73 -
 cw_monero/lib/api/structs/subaddress_row.dart |   15 -
 .../lib/api/structs/transaction_info_row.dart |   41 -
 cw_monero/lib/api/structs/ut8_box.dart        |    8 -
 cw_monero/lib/api/transaction_history.dart    |    5 +-
 cw_monero/lib/api/wallet_manager.dart         |   35 +
 cw_monero/lib/cw_monero.dart                  |    8 -
 cw_monero/lib/cw_monero_method_channel.dart   |   17 -
 .../lib/cw_monero_platform_interface.dart     |   29 -
 cw_monero/lib/monero_transaction_info.dart    |   23 -
 cw_monero/lib/monero_unspent.dart             |    9 -
 cw_monero/lib/monero_wallet.dart              |   24 +-
 cw_monero/lib/mymonero.dart                   | 1689 -----------------
 cw_monero/pubspec.lock                        |  200 +-
 cw_monero/pubspec.yaml                        |    5 +-
 .../connection_to_node_exception.dart         |    5 -
 cw_wownero/lib/api/structs/account_row.dart   |   12 -
 .../lib/api/structs/coins_info_row.dart       |   73 -
 .../lib/api/structs/subaddress_row.dart       |   15 -
 .../lib/api/structs/transaction_info_row.dart |   41 -
 cw_wownero/lib/api/structs/ut8_box.dart       |    8 -
 cw_wownero/lib/api/transaction_history.dart   |    4 +-
 cw_wownero/lib/api/wallet_manager.dart        |   35 +
 cw_wownero/lib/cw_wownero.dart                |    8 -
 cw_wownero/lib/cw_wownero_method_channel.dart |   17 -
 .../lib/cw_wownero_platform_interface.dart    |   29 -
 cw_wownero/lib/mywownero.dart                 | 1689 -----------------
 cw_wownero/lib/wownero_transaction_info.dart  |   21 -
 cw_wownero/lib/wownero_unspent.dart           |    9 -
 cw_wownero/lib/wownero_wallet.dart            |   22 +-
 cw_wownero/pubspec.lock                       |    8 +-
 cw_wownero/pubspec.yaml                       |    5 +-
 lib/monero/cw_monero.dart                     |    5 +
 .../screens/dashboard/pages/balance_page.dart |   30 +
 .../dashboard/dashboard_view_model.dart       |   22 +
 lib/wownero/cw_wownero.dart                   |    5 +
 scripts/prepare_moneroc.sh                    |    2 +-
 tool/configure.dart                           |    4 +
 41 files changed, 279 insertions(+), 3993 deletions(-)
 delete mode 100644 cw_monero/lib/api/exceptions/connection_to_node_exception.dart
 delete mode 100644 cw_monero/lib/api/structs/account_row.dart
 delete mode 100644 cw_monero/lib/api/structs/coins_info_row.dart
 delete mode 100644 cw_monero/lib/api/structs/subaddress_row.dart
 delete mode 100644 cw_monero/lib/api/structs/transaction_info_row.dart
 delete mode 100644 cw_monero/lib/api/structs/ut8_box.dart
 delete mode 100644 cw_monero/lib/cw_monero.dart
 delete mode 100644 cw_monero/lib/cw_monero_method_channel.dart
 delete mode 100644 cw_monero/lib/cw_monero_platform_interface.dart
 delete mode 100644 cw_monero/lib/mymonero.dart
 delete mode 100644 cw_wownero/lib/api/exceptions/connection_to_node_exception.dart
 delete mode 100644 cw_wownero/lib/api/structs/account_row.dart
 delete mode 100644 cw_wownero/lib/api/structs/coins_info_row.dart
 delete mode 100644 cw_wownero/lib/api/structs/subaddress_row.dart
 delete mode 100644 cw_wownero/lib/api/structs/transaction_info_row.dart
 delete mode 100644 cw_wownero/lib/api/structs/ut8_box.dart
 delete mode 100644 cw_wownero/lib/cw_wownero.dart
 delete mode 100644 cw_wownero/lib/cw_wownero_method_channel.dart
 delete mode 100644 cw_wownero/lib/cw_wownero_platform_interface.dart
 delete mode 100644 cw_wownero/lib/mywownero.dart

diff --git a/cw_core/lib/monero_wallet_utils.dart b/cw_core/lib/monero_wallet_utils.dart
index 1b1988eb6..8a4990f78 100644
--- a/cw_core/lib/monero_wallet_utils.dart
+++ b/cw_core/lib/monero_wallet_utils.dart
@@ -79,6 +79,7 @@ Future<bool> backupWalletFilesExists(String name) async {
       backupAddressListFile.existsSync();
 }
 
+// WARNING: Transaction keys and your Polyseed CANNOT be recovered if this file is deleted
 Future<void> removeCache(String name) async {
   final path = await pathForWallet(name: name, type: WalletType.monero);
   final cacheFile = File(path);
@@ -92,8 +93,8 @@ Future<void> restoreOrResetWalletFiles(String name) async {
   final backupsExists = await backupWalletFilesExists(name);
 
   if (backupsExists) {
+    await removeCache(name);
+
     await restoreWalletFiles(name);
   }
-
-  removeCache(name);
 }
diff --git a/cw_monero/lib/api/exceptions/connection_to_node_exception.dart b/cw_monero/lib/api/exceptions/connection_to_node_exception.dart
deleted file mode 100644
index 483b0a174..000000000
--- a/cw_monero/lib/api/exceptions/connection_to_node_exception.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-class ConnectionToNodeException implements Exception {
-  ConnectionToNodeException({required this.message});
-
-  final String message;
-}
\ No newline at end of file
diff --git a/cw_monero/lib/api/structs/account_row.dart b/cw_monero/lib/api/structs/account_row.dart
deleted file mode 100644
index aa492ee0f..000000000
--- a/cw_monero/lib/api/structs/account_row.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-import 'dart:ffi';
-import 'package:ffi/ffi.dart';
-
-class AccountRow extends Struct {
-  @Int64()
-  external int id;
-  
-  external Pointer<Utf8> label;
-
-  String getLabel() => label.toDartString();
-  int getId() => id;
-}
diff --git a/cw_monero/lib/api/structs/coins_info_row.dart b/cw_monero/lib/api/structs/coins_info_row.dart
deleted file mode 100644
index ff6f6ce73..000000000
--- a/cw_monero/lib/api/structs/coins_info_row.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-import 'dart:ffi';
-import 'package:ffi/ffi.dart';
-
-class CoinsInfoRow extends Struct {
-  @Int64()
-  external int blockHeight;
-
-  external Pointer<Utf8> hash;
-
-  @Uint64()
-  external int internalOutputIndex;
-
-  @Uint64()
-  external int globalOutputIndex;
-
-  @Int8()
-  external int spent;
-
-  @Int8()
-  external int frozen;
-
-  @Uint64()
-  external int spentHeight;
-
-  @Uint64()
-  external int amount;
-
-  @Int8()
-  external int rct;
-
-  @Int8()
-  external int keyImageKnown;
-
-  @Uint64()
-  external int pkIndex;
-
-  @Uint32()
-  external int subaddrIndex;
-
-  @Uint32()
-  external int subaddrAccount;
-
-  external Pointer<Utf8> address;
-
-  external Pointer<Utf8> addressLabel;
-
-  external Pointer<Utf8> keyImage;
-
-  @Uint64()
-  external int unlockTime;
-
-  @Int8()
-  external int unlocked;
-
-  external Pointer<Utf8> pubKey;
-
-  @Int8()
-  external int coinbase;
-
-  external Pointer<Utf8> description;
-
-  String getHash() => hash.toDartString();
-
-  String getAddress() => address.toDartString();
-
-  String getAddressLabel() => addressLabel.toDartString();
-
-  String getKeyImage() => keyImage.toDartString();
-
-  String getPubKey() => pubKey.toDartString();
-
-  String getDescription() => description.toDartString();
-}
diff --git a/cw_monero/lib/api/structs/subaddress_row.dart b/cw_monero/lib/api/structs/subaddress_row.dart
deleted file mode 100644
index d593a793d..000000000
--- a/cw_monero/lib/api/structs/subaddress_row.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-import 'dart:ffi';
-import 'package:ffi/ffi.dart';
-
-class SubaddressRow extends Struct {
-  @Int64()
-  external int id;
-  
-  external Pointer<Utf8> address;
-  
-  external Pointer<Utf8> label;
-
-  String getLabel() => label.toDartString();
-  String getAddress() => address.toDartString();
-  int getId() => id;
-}
\ No newline at end of file
diff --git a/cw_monero/lib/api/structs/transaction_info_row.dart b/cw_monero/lib/api/structs/transaction_info_row.dart
deleted file mode 100644
index bdcc64d3f..000000000
--- a/cw_monero/lib/api/structs/transaction_info_row.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-import 'dart:ffi';
-import 'package:ffi/ffi.dart';
-
-class TransactionInfoRow extends Struct {
-  @Uint64()
-  external int amount;
-
-  @Uint64()
-  external int fee;
-
-  @Uint64()
-  external int blockHeight;
-
-  @Uint64()
-  external int confirmations;
-
-  @Uint32()
-  external int subaddrAccount;
-
-  @Int8()
-  external int direction;
-
-  @Int8()
-  external int isPending;
-
-  @Uint32()
-  external int subaddrIndex;
-
-  external Pointer<Utf8> hash;
-
-  external Pointer<Utf8> paymentId;
-
-  @Int64()
-  external int datetime;
-
-  int getDatetime() => datetime;
-  int getAmount() => amount >= 0 ? amount : amount * -1;
-  bool getIsPending() => isPending != 0;
-  String getHash() => hash.toDartString();
-  String getPaymentId() => paymentId.toDartString();
-}
diff --git a/cw_monero/lib/api/structs/ut8_box.dart b/cw_monero/lib/api/structs/ut8_box.dart
deleted file mode 100644
index 53e678c88..000000000
--- a/cw_monero/lib/api/structs/ut8_box.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-import 'dart:ffi';
-import 'package:ffi/ffi.dart';
-
-class Utf8Box extends Struct {
-  external Pointer<Utf8> value;
-
-  String getValue() => value.toDartString();
-}
diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart
index c28f162be..b416e1b4e 100644
--- a/cw_monero/lib/api/transaction_history.dart
+++ b/cw_monero/lib/api/transaction_history.dart
@@ -1,4 +1,3 @@
-
 import 'dart:ffi';
 import 'dart:isolate';
 
@@ -288,7 +287,7 @@ class Transaction {
     };
   }
 
-  // S finalubAddress? subAddress;
+  // final SubAddress? subAddress;
   // List<Transfer> transfers = [];
   // final int txIndex;
   final monero.TransactionInfo txInfo;
@@ -324,4 +323,4 @@ class Transaction {
     required this.key,
     required this.txInfo
   });
-}
\ No newline at end of file
+}
diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart
index 50ab41e04..26c83b06e 100644
--- a/cw_monero/lib/api/wallet_manager.dart
+++ b/cw_monero/lib/api/wallet_manager.dart
@@ -1,4 +1,5 @@
 import 'dart:ffi';
+import 'dart:io';
 import 'dart:isolate';
 
 import 'package:cw_monero/api/account_list.dart';
@@ -8,8 +9,42 @@ import 'package:cw_monero/api/exceptions/wallet_restore_from_keys_exception.dart
 import 'package:cw_monero/api/exceptions/wallet_restore_from_seed_exception.dart';
 import 'package:cw_monero/api/transaction_history.dart';
 import 'package:cw_monero/api/wallet.dart';
+import 'package:flutter/foundation.dart';
 import 'package:monero/monero.dart' as monero;
 
+class MoneroCException implements Exception {
+  final String message;
+
+  MoneroCException(this.message);
+  
+  @override
+  String toString() {
+    return message;
+  }
+}
+
+void checkIfMoneroCIsFine() {
+  final cppCsCpp = monero.MONERO_checksum_wallet2_api_c_cpp();
+  final cppCsH = monero.MONERO_checksum_wallet2_api_c_h();
+  final cppCsExp = monero.MONERO_checksum_wallet2_api_c_exp();
+
+  final dartCsCpp = monero.wallet2_api_c_cpp_sha256;
+  final dartCsH = monero.wallet2_api_c_h_sha256;
+  final dartCsExp = monero.wallet2_api_c_exp_sha256;
+
+  if (cppCsCpp != dartCsCpp) {
+    throw MoneroCException("monero_c and monero.dart cpp wrapper code mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsCpp'\ndart: '$dartCsCpp'");
+  }
+
+  if (cppCsH != dartCsH) {
+    throw MoneroCException("monero_c and monero.dart cpp wrapper header mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsH'\ndart: '$dartCsH'");
+  }
+
+  if (cppCsExp != dartCsExp && (Platform.isIOS || Platform.isMacOS)) {
+    throw MoneroCException("monero_c and monero.dart wrapper export list mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsExp'\ndart: '$dartCsExp'");
+  }
+}
+
 monero.WalletManager? _wmPtr;
 final monero.WalletManager wmPtr = Pointer.fromAddress((() {
   try {
diff --git a/cw_monero/lib/cw_monero.dart b/cw_monero/lib/cw_monero.dart
deleted file mode 100644
index 7945a020e..000000000
--- a/cw_monero/lib/cw_monero.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-
-import 'cw_monero_platform_interface.dart';
-
-class CwMonero {
-  Future<String?> getPlatformVersion() {
-    return CwMoneroPlatform.instance.getPlatformVersion();
-  }
-}
diff --git a/cw_monero/lib/cw_monero_method_channel.dart b/cw_monero/lib/cw_monero_method_channel.dart
deleted file mode 100644
index 1cbca9f2c..000000000
--- a/cw_monero/lib/cw_monero_method_channel.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-import 'package:flutter/foundation.dart';
-import 'package:flutter/services.dart';
-
-import 'cw_monero_platform_interface.dart';
-
-/// An implementation of [CwMoneroPlatform] that uses method channels.
-class MethodChannelCwMonero extends CwMoneroPlatform {
-  /// The method channel used to interact with the native platform.
-  @visibleForTesting
-  final methodChannel = const MethodChannel('cw_monero');
-
-  @override
-  Future<String?> getPlatformVersion() async {
-    final version = await methodChannel.invokeMethod<String>('getPlatformVersion');
-    return version;
-  }
-}
diff --git a/cw_monero/lib/cw_monero_platform_interface.dart b/cw_monero/lib/cw_monero_platform_interface.dart
deleted file mode 100644
index 6c9b20a25..000000000
--- a/cw_monero/lib/cw_monero_platform_interface.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-import 'package:plugin_platform_interface/plugin_platform_interface.dart';
-
-import 'cw_monero_method_channel.dart';
-
-abstract class CwMoneroPlatform extends PlatformInterface {
-  /// Constructs a CwMoneroPlatform.
-  CwMoneroPlatform() : super(token: _token);
-
-  static final Object _token = Object();
-
-  static CwMoneroPlatform _instance = MethodChannelCwMonero();
-
-  /// The default instance of [CwMoneroPlatform] to use.
-  ///
-  /// Defaults to [MethodChannelCwMonero].
-  static CwMoneroPlatform get instance => _instance;
-
-  /// Platform-specific implementations should set this with their own
-  /// platform-specific class that extends [CwMoneroPlatform] when
-  /// they register themselves.
-  static set instance(CwMoneroPlatform instance) {
-    PlatformInterface.verifyToken(instance, _token);
-    _instance = instance;
-  }
-
-  Future<String?> getPlatformVersion() {
-    throw UnimplementedError('platformVersion() has not been implemented.');
-  }
-}
diff --git a/cw_monero/lib/monero_transaction_info.dart b/cw_monero/lib/monero_transaction_info.dart
index 596b26812..76064ad11 100644
--- a/cw_monero/lib/monero_transaction_info.dart
+++ b/cw_monero/lib/monero_transaction_info.dart
@@ -1,8 +1,5 @@
-import 'dart:math';
-
 import 'package:cw_core/transaction_info.dart';
 import 'package:cw_core/monero_amount_format.dart';
-import 'package:cw_monero/api/structs/transaction_info_row.dart';
 import 'package:cw_core/parseBoolFromString.dart';
 import 'package:cw_core/transaction_direction.dart';
 import 'package:cw_core/format_amount.dart';
@@ -37,26 +34,6 @@ class MoneroTransactionInfo extends TransactionInfo {
           };
         }
 
-  MoneroTransactionInfo.fromRow(TransactionInfoRow row)
-      : id = "${row.getHash()}_${row.getAmount()}_${row.subaddrAccount}_${row.subaddrIndex}",
-        txHash = row.getHash(),
-        height = row.blockHeight,
-        direction = parseTransactionDirectionFromInt(row.direction),
-        date = DateTime.fromMillisecondsSinceEpoch(row.getDatetime() * 1000),
-        isPending = row.isPending != 0,
-        amount = row.getAmount(),
-        accountIndex = row.subaddrAccount,
-        addressIndex = row.subaddrIndex,
-        confirmations = row.confirmations,
-        key = getTxKey(row.getHash()),
-        fee = row.fee {
-          additionalInfo = <String, dynamic>{
-            'key': key,
-            'accountIndex': accountIndex,
-            'addressIndex': addressIndex
-          };
-        }
-
   final String id;
   final String txHash;
   final int height;
diff --git a/cw_monero/lib/monero_unspent.dart b/cw_monero/lib/monero_unspent.dart
index 65b5c595d..87d8f0b39 100644
--- a/cw_monero/lib/monero_unspent.dart
+++ b/cw_monero/lib/monero_unspent.dart
@@ -1,5 +1,4 @@
 import 'package:cw_core/unspent_transaction_output.dart';
-import 'package:cw_monero/api/structs/coins_info_row.dart';
 
 class MoneroUnspent extends Unspent {
   MoneroUnspent(
@@ -8,13 +7,5 @@ class MoneroUnspent extends Unspent {
     this.isFrozen = isFrozen;
   }
 
-  factory MoneroUnspent.fromCoinsInfoRow(CoinsInfoRow coinsInfoRow) => MoneroUnspent(
-      coinsInfoRow.getAddress(),
-      coinsInfoRow.getHash(),
-      coinsInfoRow.getKeyImage(),
-      coinsInfoRow.amount,
-      coinsInfoRow.frozen == 1,
-      coinsInfoRow.unlocked == 1);
-
   final bool isUnlocked;
 }
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index b8e3c2765..9298f8a49 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -109,9 +109,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
 
   @override
   String get seed => monero_wallet.getSeed();
-  String  seedLegacy(String? language) {
-    return monero_wallet.getSeedLegacy(language);
-  }
+  String seedLegacy(String? language) => monero_wallet.getSeedLegacy(language);
 
   @override
   MoneroWalletKeys get keys => MoneroWalletKeys(
@@ -190,12 +188,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
   @override
   Future<void> startSync() async {
     try {
-      _setInitialHeight();
+      _assertInitialHeight();
     } catch (_) {
       // our restore height wasn't correct, so lets see if using the backup works:
       try {
-        await resetCache(name);
-        _setInitialHeight();
+        await resetCache(name); // Resetting the cache removes the TX Keys and Polyseed
+        _assertInitialHeight();
       } catch (e) {
         // we still couldn't get a valid height from the backup?!:
         // try to use the date instead:
@@ -635,18 +633,14 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
     _listener = monero_wallet.setListeners(_onNewBlock, _onNewTransaction);
   }
 
-  // check if the height is correct:
-  void _setInitialHeight() {
-    if (walletInfo.isRecovery) {
-      return;
-    }
+  /// Asserts the current height to be above [MIN_RESTORE_HEIGHT]
+  void _assertInitialHeight() {
+    if (walletInfo.isRecovery) return;
 
     final height = monero_wallet.getCurrentHeight();
 
-    if (height > MIN_RESTORE_HEIGHT) {
-      // the restore height is probably correct, so we do nothing:
-      return;
-    }
+    // the restore height is probably correct, so we do nothing:
+    if (height > MIN_RESTORE_HEIGHT) return;
 
     throw Exception("height isn't > $MIN_RESTORE_HEIGHT!");
   }
diff --git a/cw_monero/lib/mymonero.dart b/cw_monero/lib/mymonero.dart
deleted file mode 100644
index d50e48b64..000000000
--- a/cw_monero/lib/mymonero.dart
+++ /dev/null
@@ -1,1689 +0,0 @@
-const prefixLength = 3;
-
-String swapEndianBytes(String original) {
-  if (original.length != 8) {
-    return '';
-  }
-
-  return original[6] +
-      original[7] +
-      original[4] +
-      original[5] +
-      original[2] +
-      original[3] +
-      original[0] +
-      original[1];
-}
-
-List<String> tructWords(List<String> wordSet) {
-  final start = 0;
-  final end = prefixLength;
-
-  return wordSet.map((word) => word.substring(start, end)).toList();
-}
-
-String mnemonicDecode(String seed) {
-  final n = englistWordSet.length;
-  var out = '';
-  var wlist = seed.split(' ');
-  wlist.removeLast();
-
-  for (var i = 0; i < wlist.length; i += 3) {
-    final w1 =
-        tructWords(englistWordSet).indexOf(wlist[i].substring(0, prefixLength));
-    final w2 = tructWords(englistWordSet)
-        .indexOf(wlist[i + 1].substring(0, prefixLength));
-    final w3 = tructWords(englistWordSet)
-        .indexOf(wlist[i + 2].substring(0, prefixLength));
-
-    if (w1 == -1 || w2 == -1 || w3 == -1) {
-      print("invalid word in mnemonic");
-      return '';
-    }
-
-    final x = w1 + n * (((n - w1) + w2) % n) + n * n * (((n - w2) + w3) % n);
-
-    if (x % n != w1) {
-      print("Something went wrong when decoding your private key, please try again");
-      return '';
-    }
-
-    final _res = '0000000' + x.toRadixString(16);
-    final start = _res.length - 8;
-    final end = _res.length;
-    final res = _res.substring(start, end);
-
-    out += swapEndianBytes(res);
-  }
-
-  return out;
-}
-
-final englistWordSet = [
-  "abbey",
-  "abducts",
-  "ability",
-  "ablaze",
-  "abnormal",
-  "abort",
-  "abrasive",
-  "absorb",
-  "abyss",
-  "academy",
-  "aces",
-  "aching",
-  "acidic",
-  "acoustic",
-  "acquire",
-  "across",
-  "actress",
-  "acumen",
-  "adapt",
-  "addicted",
-  "adept",
-  "adhesive",
-  "adjust",
-  "adopt",
-  "adrenalin",
-  "adult",
-  "adventure",
-  "aerial",
-  "afar",
-  "affair",
-  "afield",
-  "afloat",
-  "afoot",
-  "afraid",
-  "after",
-  "against",
-  "agenda",
-  "aggravate",
-  "agile",
-  "aglow",
-  "agnostic",
-  "agony",
-  "agreed",
-  "ahead",
-  "aided",
-  "ailments",
-  "aimless",
-  "airport",
-  "aisle",
-  "ajar",
-  "akin",
-  "alarms",
-  "album",
-  "alchemy",
-  "alerts",
-  "algebra",
-  "alkaline",
-  "alley",
-  "almost",
-  "aloof",
-  "alpine",
-  "already",
-  "also",
-  "altitude",
-  "alumni",
-  "always",
-  "amaze",
-  "ambush",
-  "amended",
-  "amidst",
-  "ammo",
-  "amnesty",
-  "among",
-  "amply",
-  "amused",
-  "anchor",
-  "android",
-  "anecdote",
-  "angled",
-  "ankle",
-  "annoyed",
-  "answers",
-  "antics",
-  "anvil",
-  "anxiety",
-  "anybody",
-  "apart",
-  "apex",
-  "aphid",
-  "aplomb",
-  "apology",
-  "apply",
-  "apricot",
-  "aptitude",
-  "aquarium",
-  "arbitrary",
-  "archer",
-  "ardent",
-  "arena",
-  "argue",
-  "arises",
-  "army",
-  "around",
-  "arrow",
-  "arsenic",
-  "artistic",
-  "ascend",
-  "ashtray",
-  "aside",
-  "asked",
-  "asleep",
-  "aspire",
-  "assorted",
-  "asylum",
-  "athlete",
-  "atlas",
-  "atom",
-  "atrium",
-  "attire",
-  "auburn",
-  "auctions",
-  "audio",
-  "august",
-  "aunt",
-  "austere",
-  "autumn",
-  "avatar",
-  "avidly",
-  "avoid",
-  "awakened",
-  "awesome",
-  "awful",
-  "awkward",
-  "awning",
-  "awoken",
-  "axes",
-  "axis",
-  "axle",
-  "aztec",
-  "azure",
-  "baby",
-  "bacon",
-  "badge",
-  "baffles",
-  "bagpipe",
-  "bailed",
-  "bakery",
-  "balding",
-  "bamboo",
-  "banjo",
-  "baptism",
-  "basin",
-  "batch",
-  "bawled",
-  "bays",
-  "because",
-  "beer",
-  "befit",
-  "begun",
-  "behind",
-  "being",
-  "below",
-  "bemused",
-  "benches",
-  "berries",
-  "bested",
-  "betting",
-  "bevel",
-  "beware",
-  "beyond",
-  "bias",
-  "bicycle",
-  "bids",
-  "bifocals",
-  "biggest",
-  "bikini",
-  "bimonthly",
-  "binocular",
-  "biology",
-  "biplane",
-  "birth",
-  "biscuit",
-  "bite",
-  "biweekly",
-  "blender",
-  "blip",
-  "bluntly",
-  "boat",
-  "bobsled",
-  "bodies",
-  "bogeys",
-  "boil",
-  "boldly",
-  "bomb",
-  "border",
-  "boss",
-  "both",
-  "bounced",
-  "bovine",
-  "bowling",
-  "boxes",
-  "boyfriend",
-  "broken",
-  "brunt",
-  "bubble",
-  "buckets",
-  "budget",
-  "buffet",
-  "bugs",
-  "building",
-  "bulb",
-  "bumper",
-  "bunch",
-  "business",
-  "butter",
-  "buying",
-  "buzzer",
-  "bygones",
-  "byline",
-  "bypass",
-  "cabin",
-  "cactus",
-  "cadets",
-  "cafe",
-  "cage",
-  "cajun",
-  "cake",
-  "calamity",
-  "camp",
-  "candy",
-  "casket",
-  "catch",
-  "cause",
-  "cavernous",
-  "cease",
-  "cedar",
-  "ceiling",
-  "cell",
-  "cement",
-  "cent",
-  "certain",
-  "chlorine",
-  "chrome",
-  "cider",
-  "cigar",
-  "cinema",
-  "circle",
-  "cistern",
-  "citadel",
-  "civilian",
-  "claim",
-  "click",
-  "clue",
-  "coal",
-  "cobra",
-  "cocoa",
-  "code",
-  "coexist",
-  "coffee",
-  "cogs",
-  "cohesive",
-  "coils",
-  "colony",
-  "comb",
-  "cool",
-  "copy",
-  "corrode",
-  "costume",
-  "cottage",
-  "cousin",
-  "cowl",
-  "criminal",
-  "cube",
-  "cucumber",
-  "cuddled",
-  "cuffs",
-  "cuisine",
-  "cunning",
-  "cupcake",
-  "custom",
-  "cycling",
-  "cylinder",
-  "cynical",
-  "dabbing",
-  "dads",
-  "daft",
-  "dagger",
-  "daily",
-  "damp",
-  "dangerous",
-  "dapper",
-  "darted",
-  "dash",
-  "dating",
-  "dauntless",
-  "dawn",
-  "daytime",
-  "dazed",
-  "debut",
-  "decay",
-  "dedicated",
-  "deepest",
-  "deftly",
-  "degrees",
-  "dehydrate",
-  "deity",
-  "dejected",
-  "delayed",
-  "demonstrate",
-  "dented",
-  "deodorant",
-  "depth",
-  "desk",
-  "devoid",
-  "dewdrop",
-  "dexterity",
-  "dialect",
-  "dice",
-  "diet",
-  "different",
-  "digit",
-  "dilute",
-  "dime",
-  "dinner",
-  "diode",
-  "diplomat",
-  "directed",
-  "distance",
-  "ditch",
-  "divers",
-  "dizzy",
-  "doctor",
-  "dodge",
-  "does",
-  "dogs",
-  "doing",
-  "dolphin",
-  "domestic",
-  "donuts",
-  "doorway",
-  "dormant",
-  "dosage",
-  "dotted",
-  "double",
-  "dove",
-  "down",
-  "dozen",
-  "dreams",
-  "drinks",
-  "drowning",
-  "drunk",
-  "drying",
-  "dual",
-  "dubbed",
-  "duckling",
-  "dude",
-  "duets",
-  "duke",
-  "dullness",
-  "dummy",
-  "dunes",
-  "duplex",
-  "duration",
-  "dusted",
-  "duties",
-  "dwarf",
-  "dwelt",
-  "dwindling",
-  "dying",
-  "dynamite",
-  "dyslexic",
-  "each",
-  "eagle",
-  "earth",
-  "easy",
-  "eating",
-  "eavesdrop",
-  "eccentric",
-  "echo",
-  "eclipse",
-  "economics",
-  "ecstatic",
-  "eden",
-  "edgy",
-  "edited",
-  "educated",
-  "eels",
-  "efficient",
-  "eggs",
-  "egotistic",
-  "eight",
-  "either",
-  "eject",
-  "elapse",
-  "elbow",
-  "eldest",
-  "eleven",
-  "elite",
-  "elope",
-  "else",
-  "eluded",
-  "emails",
-  "ember",
-  "emerge",
-  "emit",
-  "emotion",
-  "empty",
-  "emulate",
-  "energy",
-  "enforce",
-  "enhanced",
-  "enigma",
-  "enjoy",
-  "enlist",
-  "enmity",
-  "enough",
-  "enraged",
-  "ensign",
-  "entrance",
-  "envy",
-  "epoxy",
-  "equip",
-  "erase",
-  "erected",
-  "erosion",
-  "error",
-  "eskimos",
-  "espionage",
-  "essential",
-  "estate",
-  "etched",
-  "eternal",
-  "ethics",
-  "etiquette",
-  "evaluate",
-  "evenings",
-  "evicted",
-  "evolved",
-  "examine",
-  "excess",
-  "exhale",
-  "exit",
-  "exotic",
-  "exquisite",
-  "extra",
-  "exult",
-  "fabrics",
-  "factual",
-  "fading",
-  "fainted",
-  "faked",
-  "fall",
-  "family",
-  "fancy",
-  "farming",
-  "fatal",
-  "faulty",
-  "fawns",
-  "faxed",
-  "fazed",
-  "feast",
-  "february",
-  "federal",
-  "feel",
-  "feline",
-  "females",
-  "fences",
-  "ferry",
-  "festival",
-  "fetches",
-  "fever",
-  "fewest",
-  "fiat",
-  "fibula",
-  "fictional",
-  "fidget",
-  "fierce",
-  "fifteen",
-  "fight",
-  "films",
-  "firm",
-  "fishing",
-  "fitting",
-  "five",
-  "fixate",
-  "fizzle",
-  "fleet",
-  "flippant",
-  "flying",
-  "foamy",
-  "focus",
-  "foes",
-  "foggy",
-  "foiled",
-  "folding",
-  "fonts",
-  "foolish",
-  "fossil",
-  "fountain",
-  "fowls",
-  "foxes",
-  "foyer",
-  "framed",
-  "friendly",
-  "frown",
-  "fruit",
-  "frying",
-  "fudge",
-  "fuel",
-  "fugitive",
-  "fully",
-  "fuming",
-  "fungal",
-  "furnished",
-  "fuselage",
-  "future",
-  "fuzzy",
-  "gables",
-  "gadget",
-  "gags",
-  "gained",
-  "galaxy",
-  "gambit",
-  "gang",
-  "gasp",
-  "gather",
-  "gauze",
-  "gave",
-  "gawk",
-  "gaze",
-  "gearbox",
-  "gecko",
-  "geek",
-  "gels",
-  "gemstone",
-  "general",
-  "geometry",
-  "germs",
-  "gesture",
-  "getting",
-  "geyser",
-  "ghetto",
-  "ghost",
-  "giant",
-  "giddy",
-  "gifts",
-  "gigantic",
-  "gills",
-  "gimmick",
-  "ginger",
-  "girth",
-  "giving",
-  "glass",
-  "gleeful",
-  "glide",
-  "gnaw",
-  "gnome",
-  "goat",
-  "goblet",
-  "godfather",
-  "goes",
-  "goggles",
-  "going",
-  "goldfish",
-  "gone",
-  "goodbye",
-  "gopher",
-  "gorilla",
-  "gossip",
-  "gotten",
-  "gourmet",
-  "governing",
-  "gown",
-  "greater",
-  "grunt",
-  "guarded",
-  "guest",
-  "guide",
-  "gulp",
-  "gumball",
-  "guru",
-  "gusts",
-  "gutter",
-  "guys",
-  "gymnast",
-  "gypsy",
-  "gyrate",
-  "habitat",
-  "hacksaw",
-  "haggled",
-  "hairy",
-  "hamburger",
-  "happens",
-  "hashing",
-  "hatchet",
-  "haunted",
-  "having",
-  "hawk",
-  "haystack",
-  "hazard",
-  "hectare",
-  "hedgehog",
-  "heels",
-  "hefty",
-  "height",
-  "hemlock",
-  "hence",
-  "heron",
-  "hesitate",
-  "hexagon",
-  "hickory",
-  "hiding",
-  "highway",
-  "hijack",
-  "hiker",
-  "hills",
-  "himself",
-  "hinder",
-  "hippo",
-  "hire",
-  "history",
-  "hitched",
-  "hive",
-  "hoax",
-  "hobby",
-  "hockey",
-  "hoisting",
-  "hold",
-  "honked",
-  "hookup",
-  "hope",
-  "hornet",
-  "hospital",
-  "hotel",
-  "hounded",
-  "hover",
-  "howls",
-  "hubcaps",
-  "huddle",
-  "huge",
-  "hull",
-  "humid",
-  "hunter",
-  "hurried",
-  "husband",
-  "huts",
-  "hybrid",
-  "hydrogen",
-  "hyper",
-  "iceberg",
-  "icing",
-  "icon",
-  "identity",
-  "idiom",
-  "idled",
-  "idols",
-  "igloo",
-  "ignore",
-  "iguana",
-  "illness",
-  "imagine",
-  "imbalance",
-  "imitate",
-  "impel",
-  "inactive",
-  "inbound",
-  "incur",
-  "industrial",
-  "inexact",
-  "inflamed",
-  "ingested",
-  "initiate",
-  "injury",
-  "inkling",
-  "inline",
-  "inmate",
-  "innocent",
-  "inorganic",
-  "input",
-  "inquest",
-  "inroads",
-  "insult",
-  "intended",
-  "inundate",
-  "invoke",
-  "inwardly",
-  "ionic",
-  "irate",
-  "iris",
-  "irony",
-  "irritate",
-  "island",
-  "isolated",
-  "issued",
-  "italics",
-  "itches",
-  "items",
-  "itinerary",
-  "itself",
-  "ivory",
-  "jabbed",
-  "jackets",
-  "jaded",
-  "jagged",
-  "jailed",
-  "jamming",
-  "january",
-  "jargon",
-  "jaunt",
-  "javelin",
-  "jaws",
-  "jazz",
-  "jeans",
-  "jeers",
-  "jellyfish",
-  "jeopardy",
-  "jerseys",
-  "jester",
-  "jetting",
-  "jewels",
-  "jigsaw",
-  "jingle",
-  "jittery",
-  "jive",
-  "jobs",
-  "jockey",
-  "jogger",
-  "joining",
-  "joking",
-  "jolted",
-  "jostle",
-  "journal",
-  "joyous",
-  "jubilee",
-  "judge",
-  "juggled",
-  "juicy",
-  "jukebox",
-  "july",
-  "jump",
-  "junk",
-  "jury",
-  "justice",
-  "juvenile",
-  "kangaroo",
-  "karate",
-  "keep",
-  "kennel",
-  "kept",
-  "kernels",
-  "kettle",
-  "keyboard",
-  "kickoff",
-  "kidneys",
-  "king",
-  "kiosk",
-  "kisses",
-  "kitchens",
-  "kiwi",
-  "knapsack",
-  "knee",
-  "knife",
-  "knowledge",
-  "knuckle",
-  "koala",
-  "laboratory",
-  "ladder",
-  "lagoon",
-  "lair",
-  "lakes",
-  "lamb",
-  "language",
-  "laptop",
-  "large",
-  "last",
-  "later",
-  "launching",
-  "lava",
-  "lawsuit",
-  "layout",
-  "lazy",
-  "lectures",
-  "ledge",
-  "leech",
-  "left",
-  "legion",
-  "leisure",
-  "lemon",
-  "lending",
-  "leopard",
-  "lesson",
-  "lettuce",
-  "lexicon",
-  "liar",
-  "library",
-  "licks",
-  "lids",
-  "lied",
-  "lifestyle",
-  "light",
-  "likewise",
-  "lilac",
-  "limits",
-  "linen",
-  "lion",
-  "lipstick",
-  "liquid",
-  "listen",
-  "lively",
-  "loaded",
-  "lobster",
-  "locker",
-  "lodge",
-  "lofty",
-  "logic",
-  "loincloth",
-  "long",
-  "looking",
-  "lopped",
-  "lordship",
-  "losing",
-  "lottery",
-  "loudly",
-  "love",
-  "lower",
-  "loyal",
-  "lucky",
-  "luggage",
-  "lukewarm",
-  "lullaby",
-  "lumber",
-  "lunar",
-  "lurk",
-  "lush",
-  "luxury",
-  "lymph",
-  "lynx",
-  "lyrics",
-  "macro",
-  "madness",
-  "magically",
-  "mailed",
-  "major",
-  "makeup",
-  "malady",
-  "mammal",
-  "maps",
-  "masterful",
-  "match",
-  "maul",
-  "maverick",
-  "maximum",
-  "mayor",
-  "maze",
-  "meant",
-  "mechanic",
-  "medicate",
-  "meeting",
-  "megabyte",
-  "melting",
-  "memoir",
-  "menu",
-  "merger",
-  "mesh",
-  "metro",
-  "mews",
-  "mice",
-  "midst",
-  "mighty",
-  "mime",
-  "mirror",
-  "misery",
-  "mittens",
-  "mixture",
-  "moat",
-  "mobile",
-  "mocked",
-  "mohawk",
-  "moisture",
-  "molten",
-  "moment",
-  "money",
-  "moon",
-  "mops",
-  "morsel",
-  "mostly",
-  "motherly",
-  "mouth",
-  "movement",
-  "mowing",
-  "much",
-  "muddy",
-  "muffin",
-  "mugged",
-  "mullet",
-  "mumble",
-  "mundane",
-  "muppet",
-  "mural",
-  "musical",
-  "muzzle",
-  "myriad",
-  "mystery",
-  "myth",
-  "nabbing",
-  "nagged",
-  "nail",
-  "names",
-  "nanny",
-  "napkin",
-  "narrate",
-  "nasty",
-  "natural",
-  "nautical",
-  "navy",
-  "nearby",
-  "necklace",
-  "needed",
-  "negative",
-  "neither",
-  "neon",
-  "nephew",
-  "nerves",
-  "nestle",
-  "network",
-  "neutral",
-  "never",
-  "newt",
-  "nexus",
-  "nibs",
-  "niche",
-  "niece",
-  "nifty",
-  "nightly",
-  "nimbly",
-  "nineteen",
-  "nirvana",
-  "nitrogen",
-  "nobody",
-  "nocturnal",
-  "nodes",
-  "noises",
-  "nomad",
-  "noodles",
-  "northern",
-  "nostril",
-  "noted",
-  "nouns",
-  "novelty",
-  "nowhere",
-  "nozzle",
-  "nuance",
-  "nucleus",
-  "nudged",
-  "nugget",
-  "nuisance",
-  "null",
-  "number",
-  "nuns",
-  "nurse",
-  "nutshell",
-  "nylon",
-  "oaks",
-  "oars",
-  "oasis",
-  "oatmeal",
-  "obedient",
-  "object",
-  "obliged",
-  "obnoxious",
-  "observant",
-  "obtains",
-  "obvious",
-  "occur",
-  "ocean",
-  "october",
-  "odds",
-  "odometer",
-  "offend",
-  "often",
-  "oilfield",
-  "ointment",
-  "okay",
-  "older",
-  "olive",
-  "olympics",
-  "omega",
-  "omission",
-  "omnibus",
-  "onboard",
-  "oncoming",
-  "oneself",
-  "ongoing",
-  "onion",
-  "online",
-  "onslaught",
-  "onto",
-  "onward",
-  "oozed",
-  "opacity",
-  "opened",
-  "opposite",
-  "optical",
-  "opus",
-  "orange",
-  "orbit",
-  "orchid",
-  "orders",
-  "organs",
-  "origin",
-  "ornament",
-  "orphans",
-  "oscar",
-  "ostrich",
-  "otherwise",
-  "otter",
-  "ouch",
-  "ought",
-  "ounce",
-  "ourselves",
-  "oust",
-  "outbreak",
-  "oval",
-  "oven",
-  "owed",
-  "owls",
-  "owner",
-  "oxidant",
-  "oxygen",
-  "oyster",
-  "ozone",
-  "pact",
-  "paddles",
-  "pager",
-  "pairing",
-  "palace",
-  "pamphlet",
-  "pancakes",
-  "paper",
-  "paradise",
-  "pastry",
-  "patio",
-  "pause",
-  "pavements",
-  "pawnshop",
-  "payment",
-  "peaches",
-  "pebbles",
-  "peculiar",
-  "pedantic",
-  "peeled",
-  "pegs",
-  "pelican",
-  "pencil",
-  "people",
-  "pepper",
-  "perfect",
-  "pests",
-  "petals",
-  "phase",
-  "pheasants",
-  "phone",
-  "phrases",
-  "physics",
-  "piano",
-  "picked",
-  "pierce",
-  "pigment",
-  "piloted",
-  "pimple",
-  "pinched",
-  "pioneer",
-  "pipeline",
-  "pirate",
-  "pistons",
-  "pitched",
-  "pivot",
-  "pixels",
-  "pizza",
-  "playful",
-  "pledge",
-  "pliers",
-  "plotting",
-  "plus",
-  "plywood",
-  "poaching",
-  "pockets",
-  "podcast",
-  "poetry",
-  "point",
-  "poker",
-  "polar",
-  "ponies",
-  "pool",
-  "popular",
-  "portents",
-  "possible",
-  "potato",
-  "pouch",
-  "poverty",
-  "powder",
-  "pram",
-  "present",
-  "pride",
-  "problems",
-  "pruned",
-  "prying",
-  "psychic",
-  "public",
-  "puck",
-  "puddle",
-  "puffin",
-  "pulp",
-  "pumpkins",
-  "punch",
-  "puppy",
-  "purged",
-  "push",
-  "putty",
-  "puzzled",
-  "pylons",
-  "pyramid",
-  "python",
-  "queen",
-  "quick",
-  "quote",
-  "rabbits",
-  "racetrack",
-  "radar",
-  "rafts",
-  "rage",
-  "railway",
-  "raking",
-  "rally",
-  "ramped",
-  "randomly",
-  "rapid",
-  "rarest",
-  "rash",
-  "rated",
-  "ravine",
-  "rays",
-  "razor",
-  "react",
-  "rebel",
-  "recipe",
-  "reduce",
-  "reef",
-  "refer",
-  "regular",
-  "reheat",
-  "reinvest",
-  "rejoices",
-  "rekindle",
-  "relic",
-  "remedy",
-  "renting",
-  "reorder",
-  "repent",
-  "request",
-  "reruns",
-  "rest",
-  "return",
-  "reunion",
-  "revamp",
-  "rewind",
-  "rhino",
-  "rhythm",
-  "ribbon",
-  "richly",
-  "ridges",
-  "rift",
-  "rigid",
-  "rims",
-  "ringing",
-  "riots",
-  "ripped",
-  "rising",
-  "ritual",
-  "river",
-  "roared",
-  "robot",
-  "rockets",
-  "rodent",
-  "rogue",
-  "roles",
-  "romance",
-  "roomy",
-  "roped",
-  "roster",
-  "rotate",
-  "rounded",
-  "rover",
-  "rowboat",
-  "royal",
-  "ruby",
-  "rudely",
-  "ruffled",
-  "rugged",
-  "ruined",
-  "ruling",
-  "rumble",
-  "runway",
-  "rural",
-  "rustled",
-  "ruthless",
-  "sabotage",
-  "sack",
-  "sadness",
-  "safety",
-  "saga",
-  "sailor",
-  "sake",
-  "salads",
-  "sample",
-  "sanity",
-  "sapling",
-  "sarcasm",
-  "sash",
-  "satin",
-  "saucepan",
-  "saved",
-  "sawmill",
-  "saxophone",
-  "sayings",
-  "scamper",
-  "scenic",
-  "school",
-  "science",
-  "scoop",
-  "scrub",
-  "scuba",
-  "seasons",
-  "second",
-  "sedan",
-  "seeded",
-  "segments",
-  "seismic",
-  "selfish",
-  "semifinal",
-  "sensible",
-  "september",
-  "sequence",
-  "serving",
-  "session",
-  "setup",
-  "seventh",
-  "sewage",
-  "shackles",
-  "shelter",
-  "shipped",
-  "shocking",
-  "shrugged",
-  "shuffled",
-  "shyness",
-  "siblings",
-  "sickness",
-  "sidekick",
-  "sieve",
-  "sifting",
-  "sighting",
-  "silk",
-  "simplest",
-  "sincerely",
-  "sipped",
-  "siren",
-  "situated",
-  "sixteen",
-  "sizes",
-  "skater",
-  "skew",
-  "skirting",
-  "skulls",
-  "skydive",
-  "slackens",
-  "sleepless",
-  "slid",
-  "slower",
-  "slug",
-  "smash",
-  "smelting",
-  "smidgen",
-  "smog",
-  "smuggled",
-  "snake",
-  "sneeze",
-  "sniff",
-  "snout",
-  "snug",
-  "soapy",
-  "sober",
-  "soccer",
-  "soda",
-  "software",
-  "soggy",
-  "soil",
-  "solved",
-  "somewhere",
-  "sonic",
-  "soothe",
-  "soprano",
-  "sorry",
-  "southern",
-  "sovereign",
-  "sowed",
-  "soya",
-  "space",
-  "speedy",
-  "sphere",
-  "spiders",
-  "splendid",
-  "spout",
-  "sprig",
-  "spud",
-  "spying",
-  "square",
-  "stacking",
-  "stellar",
-  "stick",
-  "stockpile",
-  "strained",
-  "stunning",
-  "stylishly",
-  "subtly",
-  "succeed",
-  "suddenly",
-  "suede",
-  "suffice",
-  "sugar",
-  "suitcase",
-  "sulking",
-  "summon",
-  "sunken",
-  "superior",
-  "surfer",
-  "sushi",
-  "suture",
-  "swagger",
-  "swept",
-  "swiftly",
-  "sword",
-  "swung",
-  "syllabus",
-  "symptoms",
-  "syndrome",
-  "syringe",
-  "system",
-  "taboo",
-  "tacit",
-  "tadpoles",
-  "tagged",
-  "tail",
-  "taken",
-  "talent",
-  "tamper",
-  "tanks",
-  "tapestry",
-  "tarnished",
-  "tasked",
-  "tattoo",
-  "taunts",
-  "tavern",
-  "tawny",
-  "taxi",
-  "teardrop",
-  "technical",
-  "tedious",
-  "teeming",
-  "tell",
-  "template",
-  "tender",
-  "tepid",
-  "tequila",
-  "terminal",
-  "testing",
-  "tether",
-  "textbook",
-  "thaw",
-  "theatrics",
-  "thirsty",
-  "thorn",
-  "threaten",
-  "thumbs",
-  "thwart",
-  "ticket",
-  "tidy",
-  "tiers",
-  "tiger",
-  "tilt",
-  "timber",
-  "tinted",
-  "tipsy",
-  "tirade",
-  "tissue",
-  "titans",
-  "toaster",
-  "tobacco",
-  "today",
-  "toenail",
-  "toffee",
-  "together",
-  "toilet",
-  "token",
-  "tolerant",
-  "tomorrow",
-  "tonic",
-  "toolbox",
-  "topic",
-  "torch",
-  "tossed",
-  "total",
-  "touchy",
-  "towel",
-  "toxic",
-  "toyed",
-  "trash",
-  "trendy",
-  "tribal",
-  "trolling",
-  "truth",
-  "trying",
-  "tsunami",
-  "tubes",
-  "tucks",
-  "tudor",
-  "tuesday",
-  "tufts",
-  "tugs",
-  "tuition",
-  "tulips",
-  "tumbling",
-  "tunnel",
-  "turnip",
-  "tusks",
-  "tutor",
-  "tuxedo",
-  "twang",
-  "tweezers",
-  "twice",
-  "twofold",
-  "tycoon",
-  "typist",
-  "tyrant",
-  "ugly",
-  "ulcers",
-  "ultimate",
-  "umbrella",
-  "umpire",
-  "unafraid",
-  "unbending",
-  "uncle",
-  "under",
-  "uneven",
-  "unfit",
-  "ungainly",
-  "unhappy",
-  "union",
-  "unjustly",
-  "unknown",
-  "unlikely",
-  "unmask",
-  "unnoticed",
-  "unopened",
-  "unplugs",
-  "unquoted",
-  "unrest",
-  "unsafe",
-  "until",
-  "unusual",
-  "unveil",
-  "unwind",
-  "unzip",
-  "upbeat",
-  "upcoming",
-  "update",
-  "upgrade",
-  "uphill",
-  "upkeep",
-  "upload",
-  "upon",
-  "upper",
-  "upright",
-  "upstairs",
-  "uptight",
-  "upwards",
-  "urban",
-  "urchins",
-  "urgent",
-  "usage",
-  "useful",
-  "usher",
-  "using",
-  "usual",
-  "utensils",
-  "utility",
-  "utmost",
-  "utopia",
-  "uttered",
-  "vacation",
-  "vague",
-  "vain",
-  "value",
-  "vampire",
-  "vane",
-  "vapidly",
-  "vary",
-  "vastness",
-  "vats",
-  "vaults",
-  "vector",
-  "veered",
-  "vegan",
-  "vehicle",
-  "vein",
-  "velvet",
-  "venomous",
-  "verification",
-  "vessel",
-  "veteran",
-  "vexed",
-  "vials",
-  "vibrate",
-  "victim",
-  "video",
-  "viewpoint",
-  "vigilant",
-  "viking",
-  "village",
-  "vinegar",
-  "violin",
-  "vipers",
-  "virtual",
-  "visited",
-  "vitals",
-  "vivid",
-  "vixen",
-  "vocal",
-  "vogue",
-  "voice",
-  "volcano",
-  "vortex",
-  "voted",
-  "voucher",
-  "vowels",
-  "voyage",
-  "vulture",
-  "wade",
-  "waffle",
-  "wagtail",
-  "waist",
-  "waking",
-  "wallets",
-  "wanted",
-  "warped",
-  "washing",
-  "water",
-  "waveform",
-  "waxing",
-  "wayside",
-  "weavers",
-  "website",
-  "wedge",
-  "weekday",
-  "weird",
-  "welders",
-  "went",
-  "wept",
-  "were",
-  "western",
-  "wetsuit",
-  "whale",
-  "when",
-  "whipped",
-  "whole",
-  "wickets",
-  "width",
-  "wield",
-  "wife",
-  "wiggle",
-  "wildly",
-  "winter",
-  "wipeout",
-  "wiring",
-  "wise",
-  "withdrawn",
-  "wives",
-  "wizard",
-  "wobbly",
-  "woes",
-  "woken",
-  "wolf",
-  "womanly",
-  "wonders",
-  "woozy",
-  "worry",
-  "wounded",
-  "woven",
-  "wrap",
-  "wrist",
-  "wrong",
-  "yacht",
-  "yahoo",
-  "yanks",
-  "yard",
-  "yawning",
-  "yearbook",
-  "yellow",
-  "yesterday",
-  "yeti",
-  "yields",
-  "yodel",
-  "yoga",
-  "younger",
-  "yoyo",
-  "zapped",
-  "zeal",
-  "zebra",
-  "zero",
-  "zesty",
-  "zigzags",
-  "zinger",
-  "zippers",
-  "zodiac",
-  "zombie",
-  "zones",
-  "zoom"
-];
diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock
index 011fed169..838f7224c 100644
--- a/cw_monero/pubspec.lock
+++ b/cw_monero/pubspec.lock
@@ -21,18 +21,18 @@ packages:
     dependency: transitive
     description:
       name: args
-      sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611"
+      sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.2"
+    version: "2.5.0"
   asn1lib:
     dependency: transitive
     description:
       name: asn1lib
-      sha256: ab96a1cb3beeccf8145c52e449233fe68364c9641623acd3adad66f8184f1039
+      sha256: "58082b3f0dca697204dbab0ef9ff208bfaea7767ea771076af9a343488428dda"
       url: "https://pub.dev"
     source: hosted
-    version: "1.4.0"
+    version: "1.5.3"
   async:
     dependency: transitive
     description:
@@ -53,10 +53,10 @@ packages:
     dependency: transitive
     description:
       name: build
-      sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777"
+      sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.1"
+    version: "2.4.1"
   build_config:
     dependency: transitive
     description:
@@ -69,10 +69,10 @@ packages:
     dependency: transitive
     description:
       name: build_daemon
-      sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65"
+      sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
       url: "https://pub.dev"
     source: hosted
-    version: "4.0.0"
+    version: "4.0.1"
   build_resolvers:
     dependency: "direct dev"
     description:
@@ -93,10 +93,10 @@ packages:
     dependency: transitive
     description:
       name: build_runner_core
-      sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292"
+      sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41"
       url: "https://pub.dev"
     source: hosted
-    version: "7.2.7"
+    version: "7.2.10"
   built_collection:
     dependency: transitive
     description:
@@ -109,10 +109,10 @@ packages:
     dependency: transitive
     description:
       name: built_value
-      sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725"
+      sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
       url: "https://pub.dev"
     source: hosted
-    version: "8.4.3"
+    version: "8.9.2"
   characters:
     dependency: transitive
     description:
@@ -125,10 +125,10 @@ packages:
     dependency: transitive
     description:
       name: checked_yaml
-      sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311"
+      sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.2"
+    version: "2.0.3"
   clock:
     dependency: transitive
     description:
@@ -141,10 +141,10 @@ packages:
     dependency: transitive
     description:
       name: code_builder
-      sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe"
+      sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
       url: "https://pub.dev"
     source: hosted
-    version: "4.4.0"
+    version: "4.10.0"
   collection:
     dependency: transitive
     description:
@@ -165,10 +165,10 @@ packages:
     dependency: transitive
     description:
       name: crypto
-      sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
+      sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.2"
+    version: "3.0.3"
   cw_core:
     dependency: "direct main"
     description:
@@ -188,10 +188,10 @@ packages:
     dependency: "direct main"
     description:
       name: encrypt
-      sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb"
+      sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2"
       url: "https://pub.dev"
     source: hosted
-    version: "5.0.1"
+    version: "5.0.3"
   fake_async:
     dependency: transitive
     description:
@@ -204,10 +204,10 @@ packages:
     dependency: "direct main"
     description:
       name: ffi
-      sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
+      sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.0"
+    version: "2.1.2"
   file:
     dependency: transitive
     description:
@@ -233,10 +233,10 @@ packages:
     dependency: "direct main"
     description:
       name: flutter_mobx
-      sha256: "0da4add0016387a7bf309a0d0c41d36c6b3ae25ed7a176409267f166509e723e"
+      sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e"
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.6+5"
+    version: "2.2.1+1"
   flutter_test:
     dependency: "direct dev"
     description: flutter
@@ -246,42 +246,42 @@ packages:
     dependency: transitive
     description:
       name: frontend_server_client
-      sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
+      sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
       url: "https://pub.dev"
     source: hosted
-    version: "3.2.0"
+    version: "4.0.0"
   glob:
     dependency: transitive
     description:
       name: glob
-      sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c"
+      sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.1"
+    version: "2.1.2"
   graphs:
     dependency: transitive
     description:
       name: graphs
-      sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2
+      sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.0"
+    version: "2.3.1"
   hashlib:
     dependency: transitive
     description:
       name: hashlib
-      sha256: "71bf102329ddb8e50c8a995ee4645ae7f1728bb65e575c17196b4d8262121a96"
+      sha256: "5037d3b8c36384c03a728543ae67d962a56970c5432a50862279fe68ee4c8411"
       url: "https://pub.dev"
     source: hosted
-    version: "1.12.0"
+    version: "1.19.1"
   hashlib_codecs:
     dependency: transitive
     description:
       name: hashlib_codecs
-      sha256: "49e2a471f74b15f1854263e58c2ac11f2b631b5b12c836f9708a35397d36d626"
+      sha256: "2b570061f5a4b378425be28a576c1e11783450355ad4345a19f606ff3d96db0f"
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.0"
+    version: "2.5.0"
   hive:
     dependency: transitive
     description:
@@ -302,10 +302,10 @@ packages:
     dependency: "direct main"
     description:
       name: http
-      sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
+      sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
       url: "https://pub.dev"
     source: hosted
-    version: "1.1.0"
+    version: "1.2.1"
   http_multi_server:
     dependency: transitive
     description:
@@ -342,18 +342,18 @@ packages:
     dependency: transitive
     description:
       name: js
-      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
+      sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
       url: "https://pub.dev"
     source: hosted
-    version: "0.6.7"
+    version: "0.7.1"
   json_annotation:
     dependency: transitive
     description:
       name: json_annotation
-      sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317
+      sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
       url: "https://pub.dev"
     source: hosted
-    version: "4.8.0"
+    version: "4.9.0"
   leak_tracker:
     dependency: transitive
     description:
@@ -382,10 +382,10 @@ packages:
     dependency: transitive
     description:
       name: logging
-      sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d"
+      sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
       url: "https://pub.dev"
     source: hosted
-    version: "1.1.1"
+    version: "1.2.0"
   matcher:
     dependency: transitive
     description:
@@ -414,33 +414,33 @@ packages:
     dependency: transitive
     description:
       name: mime
-      sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
+      sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2"
       url: "https://pub.dev"
     source: hosted
-    version: "1.0.4"
+    version: "1.0.5"
   mobx:
     dependency: "direct main"
     description:
       name: mobx
-      sha256: f1862bd92c6a903fab67338f27e2f731117c3cb9ea37cee1a487f9e4e0de314a
+      sha256: "63920b27b32ad1910adfe767ab1750e4c212e8923232a1f891597b362074ea5e"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.3+1"
+    version: "2.3.3+2"
   mobx_codegen:
     dependency: "direct dev"
     description:
       name: mobx_codegen
-      sha256: "86122e410d8ea24dda0c69adb5c2a6ccadd5ce02ad46e144764e0d0184a06181"
+      sha256: d4beb9cea4b7b014321235f8fdc7c2193ee0fe1d1198e9da7403f8bc85c4407c
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.1"
+    version: "2.3.0"
   monero:
     dependency: "direct main"
     description:
-      path: "."
-      ref: d46753eca865e9e56c2f0ef6fe485c42e11982c5
-      resolved-ref: d46753eca865e9e56c2f0ef6fe485c42e11982c5
-      url: "https://github.com/mrcyjanek/monero.dart"
+      path: "impls/monero.dart"
+      ref: "bcb328a4956105dc182afd0ce2e48fe263f5f20b"
+      resolved-ref: "bcb328a4956105dc182afd0ce2e48fe263f5f20b"
+      url: "https://github.com/mrcyjanek/monero_c"
     source: git
     version: "0.0.0"
   mutex:
@@ -451,6 +451,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.1.0"
+  nested:
+    dependency: transitive
+    description:
+      name: nested
+      sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.0"
   package_config:
     dependency: transitive
     description:
@@ -471,26 +479,26 @@ packages:
     dependency: "direct main"
     description:
       name: path_provider
-      sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
+      sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.1"
+    version: "2.1.3"
   path_provider_android:
     dependency: transitive
     description:
       name: path_provider_android
-      sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
+      sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.1"
+    version: "2.2.4"
   path_provider_foundation:
     dependency: transitive
     description:
       name: path_provider_foundation
-      sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
+      sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.1"
+    version: "2.4.0"
   path_provider_linux:
     dependency: transitive
     description:
@@ -503,10 +511,10 @@ packages:
     dependency: transitive
     description:
       name: path_provider_platform_interface
-      sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
+      sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.1"
+    version: "2.1.2"
   path_provider_windows:
     dependency: transitive
     description:
@@ -519,26 +527,26 @@ packages:
     dependency: transitive
     description:
       name: platform
-      sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
+      sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
       url: "https://pub.dev"
     source: hosted
-    version: "3.1.0"
+    version: "3.1.5"
   plugin_platform_interface:
     dependency: transitive
     description:
       name: plugin_platform_interface
-      sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
+      sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.3"
+    version: "2.1.8"
   pointycastle:
     dependency: transitive
     description:
       name: pointycastle
-      sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
+      sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
       url: "https://pub.dev"
     source: hosted
-    version: "3.7.3"
+    version: "3.9.1"
   polyseed:
     dependency: "direct main"
     description:
@@ -555,46 +563,46 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.5.1"
-  process:
+  provider:
     dependency: transitive
     description:
-      name: process
-      sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
+      name: provider
+      sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
       url: "https://pub.dev"
     source: hosted
-    version: "4.2.4"
+    version: "6.1.2"
   pub_semver:
     dependency: transitive
     description:
       name: pub_semver
-      sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17"
+      sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.3"
+    version: "2.1.4"
   pubspec_parse:
     dependency: transitive
     description:
       name: pubspec_parse
-      sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a"
+      sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.1"
+    version: "1.3.0"
   shelf:
     dependency: transitive
     description:
       name: shelf
-      sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c
+      sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
       url: "https://pub.dev"
     source: hosted
-    version: "1.4.0"
+    version: "1.4.1"
   shelf_web_socket:
     dependency: transitive
     description:
       name: shelf_web_socket
-      sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8
+      sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
       url: "https://pub.dev"
     source: hosted
-    version: "1.0.3"
+    version: "1.0.4"
   sky_engine:
     dependency: transitive
     description: flutter
@@ -604,10 +612,10 @@ packages:
     dependency: transitive
     description:
       name: socks5_proxy
-      sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a"
+      sha256: "616818a0ea1064a4823b53c9f7eaf8da64ed82dcd51ed71371c7e54751ed5053"
       url: "https://pub.dev"
     source: hosted
-    version: "1.0.4"
+    version: "1.0.6"
   source_gen:
     dependency: transitive
     description:
@@ -692,10 +700,10 @@ packages:
     dependency: transitive
     description:
       name: typed_data
-      sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
+      sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
       url: "https://pub.dev"
     source: hosted
-    version: "1.3.1"
+    version: "1.3.2"
   unorm_dart:
     dependency: transitive
     description:
@@ -728,38 +736,46 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.1.0"
+  web:
+    dependency: transitive
+    description:
+      name: web
+      sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.5.1"
   web_socket_channel:
     dependency: transitive
     description:
       name: web_socket_channel
-      sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b
+      sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42"
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.0"
+    version: "2.4.5"
   win32:
     dependency: transitive
     description:
       name: win32
-      sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46
+      sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
       url: "https://pub.dev"
     source: hosted
-    version: "3.1.3"
+    version: "5.5.0"
   xdg_directories:
     dependency: transitive
     description:
       name: xdg_directories
-      sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86
+      sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
       url: "https://pub.dev"
     source: hosted
-    version: "0.2.0+3"
+    version: "1.0.4"
   yaml:
     dependency: transitive
     description:
       name: yaml
-      sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370"
+      sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
       url: "https://pub.dev"
     source: hosted
-    version: "3.1.1"
+    version: "3.1.2"
 sdks:
-  dart: ">=3.2.0-0 <4.0.0"
-  flutter: ">=3.7.0"
+  dart: ">=3.3.0 <4.0.0"
+  flutter: ">=3.16.6"
diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml
index 53e50877f..b5a13a126 100644
--- a/cw_monero/pubspec.yaml
+++ b/cw_monero/pubspec.yaml
@@ -24,8 +24,9 @@ dependencies:
     path: ../cw_core
   monero:
     git:
-      url: https://github.com/mrcyjanek/monero.dart
-      ref: d46753eca865e9e56c2f0ef6fe485c42e11982c5
+      url: https://github.com/mrcyjanek/monero_c
+      ref: bcb328a4956105dc182afd0ce2e48fe263f5f20b # monero_c hash
+      path: impls/monero.dart
   mutex: ^3.1.0
 
 dev_dependencies:
diff --git a/cw_wownero/lib/api/exceptions/connection_to_node_exception.dart b/cw_wownero/lib/api/exceptions/connection_to_node_exception.dart
deleted file mode 100644
index 483b0a174..000000000
--- a/cw_wownero/lib/api/exceptions/connection_to_node_exception.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-class ConnectionToNodeException implements Exception {
-  ConnectionToNodeException({required this.message});
-
-  final String message;
-}
\ No newline at end of file
diff --git a/cw_wownero/lib/api/structs/account_row.dart b/cw_wownero/lib/api/structs/account_row.dart
deleted file mode 100644
index aa492ee0f..000000000
--- a/cw_wownero/lib/api/structs/account_row.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-import 'dart:ffi';
-import 'package:ffi/ffi.dart';
-
-class AccountRow extends Struct {
-  @Int64()
-  external int id;
-  
-  external Pointer<Utf8> label;
-
-  String getLabel() => label.toDartString();
-  int getId() => id;
-}
diff --git a/cw_wownero/lib/api/structs/coins_info_row.dart b/cw_wownero/lib/api/structs/coins_info_row.dart
deleted file mode 100644
index ff6f6ce73..000000000
--- a/cw_wownero/lib/api/structs/coins_info_row.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-import 'dart:ffi';
-import 'package:ffi/ffi.dart';
-
-class CoinsInfoRow extends Struct {
-  @Int64()
-  external int blockHeight;
-
-  external Pointer<Utf8> hash;
-
-  @Uint64()
-  external int internalOutputIndex;
-
-  @Uint64()
-  external int globalOutputIndex;
-
-  @Int8()
-  external int spent;
-
-  @Int8()
-  external int frozen;
-
-  @Uint64()
-  external int spentHeight;
-
-  @Uint64()
-  external int amount;
-
-  @Int8()
-  external int rct;
-
-  @Int8()
-  external int keyImageKnown;
-
-  @Uint64()
-  external int pkIndex;
-
-  @Uint32()
-  external int subaddrIndex;
-
-  @Uint32()
-  external int subaddrAccount;
-
-  external Pointer<Utf8> address;
-
-  external Pointer<Utf8> addressLabel;
-
-  external Pointer<Utf8> keyImage;
-
-  @Uint64()
-  external int unlockTime;
-
-  @Int8()
-  external int unlocked;
-
-  external Pointer<Utf8> pubKey;
-
-  @Int8()
-  external int coinbase;
-
-  external Pointer<Utf8> description;
-
-  String getHash() => hash.toDartString();
-
-  String getAddress() => address.toDartString();
-
-  String getAddressLabel() => addressLabel.toDartString();
-
-  String getKeyImage() => keyImage.toDartString();
-
-  String getPubKey() => pubKey.toDartString();
-
-  String getDescription() => description.toDartString();
-}
diff --git a/cw_wownero/lib/api/structs/subaddress_row.dart b/cw_wownero/lib/api/structs/subaddress_row.dart
deleted file mode 100644
index d593a793d..000000000
--- a/cw_wownero/lib/api/structs/subaddress_row.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-import 'dart:ffi';
-import 'package:ffi/ffi.dart';
-
-class SubaddressRow extends Struct {
-  @Int64()
-  external int id;
-  
-  external Pointer<Utf8> address;
-  
-  external Pointer<Utf8> label;
-
-  String getLabel() => label.toDartString();
-  String getAddress() => address.toDartString();
-  int getId() => id;
-}
\ No newline at end of file
diff --git a/cw_wownero/lib/api/structs/transaction_info_row.dart b/cw_wownero/lib/api/structs/transaction_info_row.dart
deleted file mode 100644
index bdcc64d3f..000000000
--- a/cw_wownero/lib/api/structs/transaction_info_row.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-import 'dart:ffi';
-import 'package:ffi/ffi.dart';
-
-class TransactionInfoRow extends Struct {
-  @Uint64()
-  external int amount;
-
-  @Uint64()
-  external int fee;
-
-  @Uint64()
-  external int blockHeight;
-
-  @Uint64()
-  external int confirmations;
-
-  @Uint32()
-  external int subaddrAccount;
-
-  @Int8()
-  external int direction;
-
-  @Int8()
-  external int isPending;
-
-  @Uint32()
-  external int subaddrIndex;
-
-  external Pointer<Utf8> hash;
-
-  external Pointer<Utf8> paymentId;
-
-  @Int64()
-  external int datetime;
-
-  int getDatetime() => datetime;
-  int getAmount() => amount >= 0 ? amount : amount * -1;
-  bool getIsPending() => isPending != 0;
-  String getHash() => hash.toDartString();
-  String getPaymentId() => paymentId.toDartString();
-}
diff --git a/cw_wownero/lib/api/structs/ut8_box.dart b/cw_wownero/lib/api/structs/ut8_box.dart
deleted file mode 100644
index 53e678c88..000000000
--- a/cw_wownero/lib/api/structs/ut8_box.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-import 'dart:ffi';
-import 'package:ffi/ffi.dart';
-
-class Utf8Box extends Struct {
-  external Pointer<Utf8> value;
-
-  String getValue() => value.toDartString();
-}
diff --git a/cw_wownero/lib/api/transaction_history.dart b/cw_wownero/lib/api/transaction_history.dart
index 3ccd0b3c6..a1e1e3c9b 100644
--- a/cw_wownero/lib/api/transaction_history.dart
+++ b/cw_wownero/lib/api/transaction_history.dart
@@ -285,7 +285,7 @@ class Transaction {
     };
   }
 
-  // S finalubAddress? subAddress;
+  // final SubAddress? subAddress;
   // List<Transfer> transfers = [];
   // final int txIndex;
   final wownero.TransactionInfo txInfo;
@@ -321,4 +321,4 @@ class Transaction {
     required this.key,
     required this.txInfo
   });
-}
\ No newline at end of file
+}
diff --git a/cw_wownero/lib/api/wallet_manager.dart b/cw_wownero/lib/api/wallet_manager.dart
index afcc536e7..7915373bb 100644
--- a/cw_wownero/lib/api/wallet_manager.dart
+++ b/cw_wownero/lib/api/wallet_manager.dart
@@ -1,4 +1,5 @@
 import 'dart:ffi';
+import 'dart:io';
 import 'dart:isolate';
 
 import 'package:cw_wownero/api/account_list.dart';
@@ -8,8 +9,42 @@ import 'package:cw_wownero/api/exceptions/wallet_restore_from_keys_exception.dar
 import 'package:cw_wownero/api/exceptions/wallet_restore_from_seed_exception.dart';
 import 'package:cw_wownero/api/transaction_history.dart';
 import 'package:cw_wownero/api/wallet.dart';
+import 'package:flutter/foundation.dart';
 import 'package:monero/wownero.dart' as wownero;
 
+class MoneroCException implements Exception {
+  final String message;
+
+  MoneroCException(this.message);
+
+  @override
+  String toString() {
+    return message;
+  }
+}
+
+void checkIfMoneroCIsFine() {
+  final cppCsCpp = wownero.WOWNERO_checksum_wallet2_api_c_cpp();
+  final cppCsH = wownero.WOWNERO_checksum_wallet2_api_c_h();
+  final cppCsExp = wownero.WOWNERO_checksum_wallet2_api_c_exp();
+
+  final dartCsCpp = wownero.wallet2_api_c_cpp_sha256;
+  final dartCsH = wownero.wallet2_api_c_h_sha256;
+  final dartCsExp = wownero.wallet2_api_c_exp_sha256;
+
+  if (cppCsCpp != dartCsCpp) {
+    throw MoneroCException("monero_c and monero.dart cpp wrapper code mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsCpp'\ndart: '$dartCsCpp'");
+  }
+
+  if (cppCsH != dartCsH) {
+    throw MoneroCException("monero_c and monero.dart cpp wrapper header mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsH'\ndart: '$dartCsH'");
+  }
+
+  if (cppCsExp != dartCsExp && (Platform.isIOS || Platform.isMacOS)) {
+    throw MoneroCException("monero_c and monero.dart wrapper export list mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsExp'\ndart: '$dartCsExp'");
+  }
+}
+
 wownero.WalletManager? _wmPtr;
 final wownero.WalletManager wmPtr = Pointer.fromAddress((() {
   try {
diff --git a/cw_wownero/lib/cw_wownero.dart b/cw_wownero/lib/cw_wownero.dart
deleted file mode 100644
index 33a55e305..000000000
--- a/cw_wownero/lib/cw_wownero.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-
-import 'cw_wownero_platform_interface.dart';
-
-class CwWownero {
-  Future<String?> getPlatformVersion() {
-    return CwWowneroPlatform.instance.getPlatformVersion();
-  }
-}
diff --git a/cw_wownero/lib/cw_wownero_method_channel.dart b/cw_wownero/lib/cw_wownero_method_channel.dart
deleted file mode 100644
index d797f5f81..000000000
--- a/cw_wownero/lib/cw_wownero_method_channel.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-import 'package:flutter/foundation.dart';
-import 'package:flutter/services.dart';
-
-import 'cw_wownero_platform_interface.dart';
-
-/// An implementation of [CwWowneroPlatform] that uses method channels.
-class MethodChannelCwWownero extends CwWowneroPlatform {
-  /// The method channel used to interact with the native platform.
-  @visibleForTesting
-  final methodChannel = const MethodChannel('cw_wownero');
-
-  @override
-  Future<String?> getPlatformVersion() async {
-    final version = await methodChannel.invokeMethod<String>('getPlatformVersion');
-    return version;
-  }
-}
diff --git a/cw_wownero/lib/cw_wownero_platform_interface.dart b/cw_wownero/lib/cw_wownero_platform_interface.dart
deleted file mode 100644
index 78b21592c..000000000
--- a/cw_wownero/lib/cw_wownero_platform_interface.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-import 'package:plugin_platform_interface/plugin_platform_interface.dart';
-
-import 'cw_wownero_method_channel.dart';
-
-abstract class CwWowneroPlatform extends PlatformInterface {
-  /// Constructs a CwWowneroPlatform.
-  CwWowneroPlatform() : super(token: _token);
-
-  static final Object _token = Object();
-
-  static CwWowneroPlatform _instance = MethodChannelCwWownero();
-
-  /// The default instance of [CwWowneroPlatform] to use.
-  ///
-  /// Defaults to [MethodChannelCwWownero].
-  static CwWowneroPlatform get instance => _instance;
-
-  /// Platform-specific implementations should set this with their own
-  /// platform-specific class that extends [CwWowneroPlatform] when
-  /// they register themselves.
-  static set instance(CwWowneroPlatform instance) {
-    PlatformInterface.verifyToken(instance, _token);
-    _instance = instance;
-  }
-
-  Future<String?> getPlatformVersion() {
-    throw UnimplementedError('platformVersion() has not been implemented.');
-  }
-}
diff --git a/cw_wownero/lib/mywownero.dart b/cw_wownero/lib/mywownero.dart
deleted file mode 100644
index d50e48b64..000000000
--- a/cw_wownero/lib/mywownero.dart
+++ /dev/null
@@ -1,1689 +0,0 @@
-const prefixLength = 3;
-
-String swapEndianBytes(String original) {
-  if (original.length != 8) {
-    return '';
-  }
-
-  return original[6] +
-      original[7] +
-      original[4] +
-      original[5] +
-      original[2] +
-      original[3] +
-      original[0] +
-      original[1];
-}
-
-List<String> tructWords(List<String> wordSet) {
-  final start = 0;
-  final end = prefixLength;
-
-  return wordSet.map((word) => word.substring(start, end)).toList();
-}
-
-String mnemonicDecode(String seed) {
-  final n = englistWordSet.length;
-  var out = '';
-  var wlist = seed.split(' ');
-  wlist.removeLast();
-
-  for (var i = 0; i < wlist.length; i += 3) {
-    final w1 =
-        tructWords(englistWordSet).indexOf(wlist[i].substring(0, prefixLength));
-    final w2 = tructWords(englistWordSet)
-        .indexOf(wlist[i + 1].substring(0, prefixLength));
-    final w3 = tructWords(englistWordSet)
-        .indexOf(wlist[i + 2].substring(0, prefixLength));
-
-    if (w1 == -1 || w2 == -1 || w3 == -1) {
-      print("invalid word in mnemonic");
-      return '';
-    }
-
-    final x = w1 + n * (((n - w1) + w2) % n) + n * n * (((n - w2) + w3) % n);
-
-    if (x % n != w1) {
-      print("Something went wrong when decoding your private key, please try again");
-      return '';
-    }
-
-    final _res = '0000000' + x.toRadixString(16);
-    final start = _res.length - 8;
-    final end = _res.length;
-    final res = _res.substring(start, end);
-
-    out += swapEndianBytes(res);
-  }
-
-  return out;
-}
-
-final englistWordSet = [
-  "abbey",
-  "abducts",
-  "ability",
-  "ablaze",
-  "abnormal",
-  "abort",
-  "abrasive",
-  "absorb",
-  "abyss",
-  "academy",
-  "aces",
-  "aching",
-  "acidic",
-  "acoustic",
-  "acquire",
-  "across",
-  "actress",
-  "acumen",
-  "adapt",
-  "addicted",
-  "adept",
-  "adhesive",
-  "adjust",
-  "adopt",
-  "adrenalin",
-  "adult",
-  "adventure",
-  "aerial",
-  "afar",
-  "affair",
-  "afield",
-  "afloat",
-  "afoot",
-  "afraid",
-  "after",
-  "against",
-  "agenda",
-  "aggravate",
-  "agile",
-  "aglow",
-  "agnostic",
-  "agony",
-  "agreed",
-  "ahead",
-  "aided",
-  "ailments",
-  "aimless",
-  "airport",
-  "aisle",
-  "ajar",
-  "akin",
-  "alarms",
-  "album",
-  "alchemy",
-  "alerts",
-  "algebra",
-  "alkaline",
-  "alley",
-  "almost",
-  "aloof",
-  "alpine",
-  "already",
-  "also",
-  "altitude",
-  "alumni",
-  "always",
-  "amaze",
-  "ambush",
-  "amended",
-  "amidst",
-  "ammo",
-  "amnesty",
-  "among",
-  "amply",
-  "amused",
-  "anchor",
-  "android",
-  "anecdote",
-  "angled",
-  "ankle",
-  "annoyed",
-  "answers",
-  "antics",
-  "anvil",
-  "anxiety",
-  "anybody",
-  "apart",
-  "apex",
-  "aphid",
-  "aplomb",
-  "apology",
-  "apply",
-  "apricot",
-  "aptitude",
-  "aquarium",
-  "arbitrary",
-  "archer",
-  "ardent",
-  "arena",
-  "argue",
-  "arises",
-  "army",
-  "around",
-  "arrow",
-  "arsenic",
-  "artistic",
-  "ascend",
-  "ashtray",
-  "aside",
-  "asked",
-  "asleep",
-  "aspire",
-  "assorted",
-  "asylum",
-  "athlete",
-  "atlas",
-  "atom",
-  "atrium",
-  "attire",
-  "auburn",
-  "auctions",
-  "audio",
-  "august",
-  "aunt",
-  "austere",
-  "autumn",
-  "avatar",
-  "avidly",
-  "avoid",
-  "awakened",
-  "awesome",
-  "awful",
-  "awkward",
-  "awning",
-  "awoken",
-  "axes",
-  "axis",
-  "axle",
-  "aztec",
-  "azure",
-  "baby",
-  "bacon",
-  "badge",
-  "baffles",
-  "bagpipe",
-  "bailed",
-  "bakery",
-  "balding",
-  "bamboo",
-  "banjo",
-  "baptism",
-  "basin",
-  "batch",
-  "bawled",
-  "bays",
-  "because",
-  "beer",
-  "befit",
-  "begun",
-  "behind",
-  "being",
-  "below",
-  "bemused",
-  "benches",
-  "berries",
-  "bested",
-  "betting",
-  "bevel",
-  "beware",
-  "beyond",
-  "bias",
-  "bicycle",
-  "bids",
-  "bifocals",
-  "biggest",
-  "bikini",
-  "bimonthly",
-  "binocular",
-  "biology",
-  "biplane",
-  "birth",
-  "biscuit",
-  "bite",
-  "biweekly",
-  "blender",
-  "blip",
-  "bluntly",
-  "boat",
-  "bobsled",
-  "bodies",
-  "bogeys",
-  "boil",
-  "boldly",
-  "bomb",
-  "border",
-  "boss",
-  "both",
-  "bounced",
-  "bovine",
-  "bowling",
-  "boxes",
-  "boyfriend",
-  "broken",
-  "brunt",
-  "bubble",
-  "buckets",
-  "budget",
-  "buffet",
-  "bugs",
-  "building",
-  "bulb",
-  "bumper",
-  "bunch",
-  "business",
-  "butter",
-  "buying",
-  "buzzer",
-  "bygones",
-  "byline",
-  "bypass",
-  "cabin",
-  "cactus",
-  "cadets",
-  "cafe",
-  "cage",
-  "cajun",
-  "cake",
-  "calamity",
-  "camp",
-  "candy",
-  "casket",
-  "catch",
-  "cause",
-  "cavernous",
-  "cease",
-  "cedar",
-  "ceiling",
-  "cell",
-  "cement",
-  "cent",
-  "certain",
-  "chlorine",
-  "chrome",
-  "cider",
-  "cigar",
-  "cinema",
-  "circle",
-  "cistern",
-  "citadel",
-  "civilian",
-  "claim",
-  "click",
-  "clue",
-  "coal",
-  "cobra",
-  "cocoa",
-  "code",
-  "coexist",
-  "coffee",
-  "cogs",
-  "cohesive",
-  "coils",
-  "colony",
-  "comb",
-  "cool",
-  "copy",
-  "corrode",
-  "costume",
-  "cottage",
-  "cousin",
-  "cowl",
-  "criminal",
-  "cube",
-  "cucumber",
-  "cuddled",
-  "cuffs",
-  "cuisine",
-  "cunning",
-  "cupcake",
-  "custom",
-  "cycling",
-  "cylinder",
-  "cynical",
-  "dabbing",
-  "dads",
-  "daft",
-  "dagger",
-  "daily",
-  "damp",
-  "dangerous",
-  "dapper",
-  "darted",
-  "dash",
-  "dating",
-  "dauntless",
-  "dawn",
-  "daytime",
-  "dazed",
-  "debut",
-  "decay",
-  "dedicated",
-  "deepest",
-  "deftly",
-  "degrees",
-  "dehydrate",
-  "deity",
-  "dejected",
-  "delayed",
-  "demonstrate",
-  "dented",
-  "deodorant",
-  "depth",
-  "desk",
-  "devoid",
-  "dewdrop",
-  "dexterity",
-  "dialect",
-  "dice",
-  "diet",
-  "different",
-  "digit",
-  "dilute",
-  "dime",
-  "dinner",
-  "diode",
-  "diplomat",
-  "directed",
-  "distance",
-  "ditch",
-  "divers",
-  "dizzy",
-  "doctor",
-  "dodge",
-  "does",
-  "dogs",
-  "doing",
-  "dolphin",
-  "domestic",
-  "donuts",
-  "doorway",
-  "dormant",
-  "dosage",
-  "dotted",
-  "double",
-  "dove",
-  "down",
-  "dozen",
-  "dreams",
-  "drinks",
-  "drowning",
-  "drunk",
-  "drying",
-  "dual",
-  "dubbed",
-  "duckling",
-  "dude",
-  "duets",
-  "duke",
-  "dullness",
-  "dummy",
-  "dunes",
-  "duplex",
-  "duration",
-  "dusted",
-  "duties",
-  "dwarf",
-  "dwelt",
-  "dwindling",
-  "dying",
-  "dynamite",
-  "dyslexic",
-  "each",
-  "eagle",
-  "earth",
-  "easy",
-  "eating",
-  "eavesdrop",
-  "eccentric",
-  "echo",
-  "eclipse",
-  "economics",
-  "ecstatic",
-  "eden",
-  "edgy",
-  "edited",
-  "educated",
-  "eels",
-  "efficient",
-  "eggs",
-  "egotistic",
-  "eight",
-  "either",
-  "eject",
-  "elapse",
-  "elbow",
-  "eldest",
-  "eleven",
-  "elite",
-  "elope",
-  "else",
-  "eluded",
-  "emails",
-  "ember",
-  "emerge",
-  "emit",
-  "emotion",
-  "empty",
-  "emulate",
-  "energy",
-  "enforce",
-  "enhanced",
-  "enigma",
-  "enjoy",
-  "enlist",
-  "enmity",
-  "enough",
-  "enraged",
-  "ensign",
-  "entrance",
-  "envy",
-  "epoxy",
-  "equip",
-  "erase",
-  "erected",
-  "erosion",
-  "error",
-  "eskimos",
-  "espionage",
-  "essential",
-  "estate",
-  "etched",
-  "eternal",
-  "ethics",
-  "etiquette",
-  "evaluate",
-  "evenings",
-  "evicted",
-  "evolved",
-  "examine",
-  "excess",
-  "exhale",
-  "exit",
-  "exotic",
-  "exquisite",
-  "extra",
-  "exult",
-  "fabrics",
-  "factual",
-  "fading",
-  "fainted",
-  "faked",
-  "fall",
-  "family",
-  "fancy",
-  "farming",
-  "fatal",
-  "faulty",
-  "fawns",
-  "faxed",
-  "fazed",
-  "feast",
-  "february",
-  "federal",
-  "feel",
-  "feline",
-  "females",
-  "fences",
-  "ferry",
-  "festival",
-  "fetches",
-  "fever",
-  "fewest",
-  "fiat",
-  "fibula",
-  "fictional",
-  "fidget",
-  "fierce",
-  "fifteen",
-  "fight",
-  "films",
-  "firm",
-  "fishing",
-  "fitting",
-  "five",
-  "fixate",
-  "fizzle",
-  "fleet",
-  "flippant",
-  "flying",
-  "foamy",
-  "focus",
-  "foes",
-  "foggy",
-  "foiled",
-  "folding",
-  "fonts",
-  "foolish",
-  "fossil",
-  "fountain",
-  "fowls",
-  "foxes",
-  "foyer",
-  "framed",
-  "friendly",
-  "frown",
-  "fruit",
-  "frying",
-  "fudge",
-  "fuel",
-  "fugitive",
-  "fully",
-  "fuming",
-  "fungal",
-  "furnished",
-  "fuselage",
-  "future",
-  "fuzzy",
-  "gables",
-  "gadget",
-  "gags",
-  "gained",
-  "galaxy",
-  "gambit",
-  "gang",
-  "gasp",
-  "gather",
-  "gauze",
-  "gave",
-  "gawk",
-  "gaze",
-  "gearbox",
-  "gecko",
-  "geek",
-  "gels",
-  "gemstone",
-  "general",
-  "geometry",
-  "germs",
-  "gesture",
-  "getting",
-  "geyser",
-  "ghetto",
-  "ghost",
-  "giant",
-  "giddy",
-  "gifts",
-  "gigantic",
-  "gills",
-  "gimmick",
-  "ginger",
-  "girth",
-  "giving",
-  "glass",
-  "gleeful",
-  "glide",
-  "gnaw",
-  "gnome",
-  "goat",
-  "goblet",
-  "godfather",
-  "goes",
-  "goggles",
-  "going",
-  "goldfish",
-  "gone",
-  "goodbye",
-  "gopher",
-  "gorilla",
-  "gossip",
-  "gotten",
-  "gourmet",
-  "governing",
-  "gown",
-  "greater",
-  "grunt",
-  "guarded",
-  "guest",
-  "guide",
-  "gulp",
-  "gumball",
-  "guru",
-  "gusts",
-  "gutter",
-  "guys",
-  "gymnast",
-  "gypsy",
-  "gyrate",
-  "habitat",
-  "hacksaw",
-  "haggled",
-  "hairy",
-  "hamburger",
-  "happens",
-  "hashing",
-  "hatchet",
-  "haunted",
-  "having",
-  "hawk",
-  "haystack",
-  "hazard",
-  "hectare",
-  "hedgehog",
-  "heels",
-  "hefty",
-  "height",
-  "hemlock",
-  "hence",
-  "heron",
-  "hesitate",
-  "hexagon",
-  "hickory",
-  "hiding",
-  "highway",
-  "hijack",
-  "hiker",
-  "hills",
-  "himself",
-  "hinder",
-  "hippo",
-  "hire",
-  "history",
-  "hitched",
-  "hive",
-  "hoax",
-  "hobby",
-  "hockey",
-  "hoisting",
-  "hold",
-  "honked",
-  "hookup",
-  "hope",
-  "hornet",
-  "hospital",
-  "hotel",
-  "hounded",
-  "hover",
-  "howls",
-  "hubcaps",
-  "huddle",
-  "huge",
-  "hull",
-  "humid",
-  "hunter",
-  "hurried",
-  "husband",
-  "huts",
-  "hybrid",
-  "hydrogen",
-  "hyper",
-  "iceberg",
-  "icing",
-  "icon",
-  "identity",
-  "idiom",
-  "idled",
-  "idols",
-  "igloo",
-  "ignore",
-  "iguana",
-  "illness",
-  "imagine",
-  "imbalance",
-  "imitate",
-  "impel",
-  "inactive",
-  "inbound",
-  "incur",
-  "industrial",
-  "inexact",
-  "inflamed",
-  "ingested",
-  "initiate",
-  "injury",
-  "inkling",
-  "inline",
-  "inmate",
-  "innocent",
-  "inorganic",
-  "input",
-  "inquest",
-  "inroads",
-  "insult",
-  "intended",
-  "inundate",
-  "invoke",
-  "inwardly",
-  "ionic",
-  "irate",
-  "iris",
-  "irony",
-  "irritate",
-  "island",
-  "isolated",
-  "issued",
-  "italics",
-  "itches",
-  "items",
-  "itinerary",
-  "itself",
-  "ivory",
-  "jabbed",
-  "jackets",
-  "jaded",
-  "jagged",
-  "jailed",
-  "jamming",
-  "january",
-  "jargon",
-  "jaunt",
-  "javelin",
-  "jaws",
-  "jazz",
-  "jeans",
-  "jeers",
-  "jellyfish",
-  "jeopardy",
-  "jerseys",
-  "jester",
-  "jetting",
-  "jewels",
-  "jigsaw",
-  "jingle",
-  "jittery",
-  "jive",
-  "jobs",
-  "jockey",
-  "jogger",
-  "joining",
-  "joking",
-  "jolted",
-  "jostle",
-  "journal",
-  "joyous",
-  "jubilee",
-  "judge",
-  "juggled",
-  "juicy",
-  "jukebox",
-  "july",
-  "jump",
-  "junk",
-  "jury",
-  "justice",
-  "juvenile",
-  "kangaroo",
-  "karate",
-  "keep",
-  "kennel",
-  "kept",
-  "kernels",
-  "kettle",
-  "keyboard",
-  "kickoff",
-  "kidneys",
-  "king",
-  "kiosk",
-  "kisses",
-  "kitchens",
-  "kiwi",
-  "knapsack",
-  "knee",
-  "knife",
-  "knowledge",
-  "knuckle",
-  "koala",
-  "laboratory",
-  "ladder",
-  "lagoon",
-  "lair",
-  "lakes",
-  "lamb",
-  "language",
-  "laptop",
-  "large",
-  "last",
-  "later",
-  "launching",
-  "lava",
-  "lawsuit",
-  "layout",
-  "lazy",
-  "lectures",
-  "ledge",
-  "leech",
-  "left",
-  "legion",
-  "leisure",
-  "lemon",
-  "lending",
-  "leopard",
-  "lesson",
-  "lettuce",
-  "lexicon",
-  "liar",
-  "library",
-  "licks",
-  "lids",
-  "lied",
-  "lifestyle",
-  "light",
-  "likewise",
-  "lilac",
-  "limits",
-  "linen",
-  "lion",
-  "lipstick",
-  "liquid",
-  "listen",
-  "lively",
-  "loaded",
-  "lobster",
-  "locker",
-  "lodge",
-  "lofty",
-  "logic",
-  "loincloth",
-  "long",
-  "looking",
-  "lopped",
-  "lordship",
-  "losing",
-  "lottery",
-  "loudly",
-  "love",
-  "lower",
-  "loyal",
-  "lucky",
-  "luggage",
-  "lukewarm",
-  "lullaby",
-  "lumber",
-  "lunar",
-  "lurk",
-  "lush",
-  "luxury",
-  "lymph",
-  "lynx",
-  "lyrics",
-  "macro",
-  "madness",
-  "magically",
-  "mailed",
-  "major",
-  "makeup",
-  "malady",
-  "mammal",
-  "maps",
-  "masterful",
-  "match",
-  "maul",
-  "maverick",
-  "maximum",
-  "mayor",
-  "maze",
-  "meant",
-  "mechanic",
-  "medicate",
-  "meeting",
-  "megabyte",
-  "melting",
-  "memoir",
-  "menu",
-  "merger",
-  "mesh",
-  "metro",
-  "mews",
-  "mice",
-  "midst",
-  "mighty",
-  "mime",
-  "mirror",
-  "misery",
-  "mittens",
-  "mixture",
-  "moat",
-  "mobile",
-  "mocked",
-  "mohawk",
-  "moisture",
-  "molten",
-  "moment",
-  "money",
-  "moon",
-  "mops",
-  "morsel",
-  "mostly",
-  "motherly",
-  "mouth",
-  "movement",
-  "mowing",
-  "much",
-  "muddy",
-  "muffin",
-  "mugged",
-  "mullet",
-  "mumble",
-  "mundane",
-  "muppet",
-  "mural",
-  "musical",
-  "muzzle",
-  "myriad",
-  "mystery",
-  "myth",
-  "nabbing",
-  "nagged",
-  "nail",
-  "names",
-  "nanny",
-  "napkin",
-  "narrate",
-  "nasty",
-  "natural",
-  "nautical",
-  "navy",
-  "nearby",
-  "necklace",
-  "needed",
-  "negative",
-  "neither",
-  "neon",
-  "nephew",
-  "nerves",
-  "nestle",
-  "network",
-  "neutral",
-  "never",
-  "newt",
-  "nexus",
-  "nibs",
-  "niche",
-  "niece",
-  "nifty",
-  "nightly",
-  "nimbly",
-  "nineteen",
-  "nirvana",
-  "nitrogen",
-  "nobody",
-  "nocturnal",
-  "nodes",
-  "noises",
-  "nomad",
-  "noodles",
-  "northern",
-  "nostril",
-  "noted",
-  "nouns",
-  "novelty",
-  "nowhere",
-  "nozzle",
-  "nuance",
-  "nucleus",
-  "nudged",
-  "nugget",
-  "nuisance",
-  "null",
-  "number",
-  "nuns",
-  "nurse",
-  "nutshell",
-  "nylon",
-  "oaks",
-  "oars",
-  "oasis",
-  "oatmeal",
-  "obedient",
-  "object",
-  "obliged",
-  "obnoxious",
-  "observant",
-  "obtains",
-  "obvious",
-  "occur",
-  "ocean",
-  "october",
-  "odds",
-  "odometer",
-  "offend",
-  "often",
-  "oilfield",
-  "ointment",
-  "okay",
-  "older",
-  "olive",
-  "olympics",
-  "omega",
-  "omission",
-  "omnibus",
-  "onboard",
-  "oncoming",
-  "oneself",
-  "ongoing",
-  "onion",
-  "online",
-  "onslaught",
-  "onto",
-  "onward",
-  "oozed",
-  "opacity",
-  "opened",
-  "opposite",
-  "optical",
-  "opus",
-  "orange",
-  "orbit",
-  "orchid",
-  "orders",
-  "organs",
-  "origin",
-  "ornament",
-  "orphans",
-  "oscar",
-  "ostrich",
-  "otherwise",
-  "otter",
-  "ouch",
-  "ought",
-  "ounce",
-  "ourselves",
-  "oust",
-  "outbreak",
-  "oval",
-  "oven",
-  "owed",
-  "owls",
-  "owner",
-  "oxidant",
-  "oxygen",
-  "oyster",
-  "ozone",
-  "pact",
-  "paddles",
-  "pager",
-  "pairing",
-  "palace",
-  "pamphlet",
-  "pancakes",
-  "paper",
-  "paradise",
-  "pastry",
-  "patio",
-  "pause",
-  "pavements",
-  "pawnshop",
-  "payment",
-  "peaches",
-  "pebbles",
-  "peculiar",
-  "pedantic",
-  "peeled",
-  "pegs",
-  "pelican",
-  "pencil",
-  "people",
-  "pepper",
-  "perfect",
-  "pests",
-  "petals",
-  "phase",
-  "pheasants",
-  "phone",
-  "phrases",
-  "physics",
-  "piano",
-  "picked",
-  "pierce",
-  "pigment",
-  "piloted",
-  "pimple",
-  "pinched",
-  "pioneer",
-  "pipeline",
-  "pirate",
-  "pistons",
-  "pitched",
-  "pivot",
-  "pixels",
-  "pizza",
-  "playful",
-  "pledge",
-  "pliers",
-  "plotting",
-  "plus",
-  "plywood",
-  "poaching",
-  "pockets",
-  "podcast",
-  "poetry",
-  "point",
-  "poker",
-  "polar",
-  "ponies",
-  "pool",
-  "popular",
-  "portents",
-  "possible",
-  "potato",
-  "pouch",
-  "poverty",
-  "powder",
-  "pram",
-  "present",
-  "pride",
-  "problems",
-  "pruned",
-  "prying",
-  "psychic",
-  "public",
-  "puck",
-  "puddle",
-  "puffin",
-  "pulp",
-  "pumpkins",
-  "punch",
-  "puppy",
-  "purged",
-  "push",
-  "putty",
-  "puzzled",
-  "pylons",
-  "pyramid",
-  "python",
-  "queen",
-  "quick",
-  "quote",
-  "rabbits",
-  "racetrack",
-  "radar",
-  "rafts",
-  "rage",
-  "railway",
-  "raking",
-  "rally",
-  "ramped",
-  "randomly",
-  "rapid",
-  "rarest",
-  "rash",
-  "rated",
-  "ravine",
-  "rays",
-  "razor",
-  "react",
-  "rebel",
-  "recipe",
-  "reduce",
-  "reef",
-  "refer",
-  "regular",
-  "reheat",
-  "reinvest",
-  "rejoices",
-  "rekindle",
-  "relic",
-  "remedy",
-  "renting",
-  "reorder",
-  "repent",
-  "request",
-  "reruns",
-  "rest",
-  "return",
-  "reunion",
-  "revamp",
-  "rewind",
-  "rhino",
-  "rhythm",
-  "ribbon",
-  "richly",
-  "ridges",
-  "rift",
-  "rigid",
-  "rims",
-  "ringing",
-  "riots",
-  "ripped",
-  "rising",
-  "ritual",
-  "river",
-  "roared",
-  "robot",
-  "rockets",
-  "rodent",
-  "rogue",
-  "roles",
-  "romance",
-  "roomy",
-  "roped",
-  "roster",
-  "rotate",
-  "rounded",
-  "rover",
-  "rowboat",
-  "royal",
-  "ruby",
-  "rudely",
-  "ruffled",
-  "rugged",
-  "ruined",
-  "ruling",
-  "rumble",
-  "runway",
-  "rural",
-  "rustled",
-  "ruthless",
-  "sabotage",
-  "sack",
-  "sadness",
-  "safety",
-  "saga",
-  "sailor",
-  "sake",
-  "salads",
-  "sample",
-  "sanity",
-  "sapling",
-  "sarcasm",
-  "sash",
-  "satin",
-  "saucepan",
-  "saved",
-  "sawmill",
-  "saxophone",
-  "sayings",
-  "scamper",
-  "scenic",
-  "school",
-  "science",
-  "scoop",
-  "scrub",
-  "scuba",
-  "seasons",
-  "second",
-  "sedan",
-  "seeded",
-  "segments",
-  "seismic",
-  "selfish",
-  "semifinal",
-  "sensible",
-  "september",
-  "sequence",
-  "serving",
-  "session",
-  "setup",
-  "seventh",
-  "sewage",
-  "shackles",
-  "shelter",
-  "shipped",
-  "shocking",
-  "shrugged",
-  "shuffled",
-  "shyness",
-  "siblings",
-  "sickness",
-  "sidekick",
-  "sieve",
-  "sifting",
-  "sighting",
-  "silk",
-  "simplest",
-  "sincerely",
-  "sipped",
-  "siren",
-  "situated",
-  "sixteen",
-  "sizes",
-  "skater",
-  "skew",
-  "skirting",
-  "skulls",
-  "skydive",
-  "slackens",
-  "sleepless",
-  "slid",
-  "slower",
-  "slug",
-  "smash",
-  "smelting",
-  "smidgen",
-  "smog",
-  "smuggled",
-  "snake",
-  "sneeze",
-  "sniff",
-  "snout",
-  "snug",
-  "soapy",
-  "sober",
-  "soccer",
-  "soda",
-  "software",
-  "soggy",
-  "soil",
-  "solved",
-  "somewhere",
-  "sonic",
-  "soothe",
-  "soprano",
-  "sorry",
-  "southern",
-  "sovereign",
-  "sowed",
-  "soya",
-  "space",
-  "speedy",
-  "sphere",
-  "spiders",
-  "splendid",
-  "spout",
-  "sprig",
-  "spud",
-  "spying",
-  "square",
-  "stacking",
-  "stellar",
-  "stick",
-  "stockpile",
-  "strained",
-  "stunning",
-  "stylishly",
-  "subtly",
-  "succeed",
-  "suddenly",
-  "suede",
-  "suffice",
-  "sugar",
-  "suitcase",
-  "sulking",
-  "summon",
-  "sunken",
-  "superior",
-  "surfer",
-  "sushi",
-  "suture",
-  "swagger",
-  "swept",
-  "swiftly",
-  "sword",
-  "swung",
-  "syllabus",
-  "symptoms",
-  "syndrome",
-  "syringe",
-  "system",
-  "taboo",
-  "tacit",
-  "tadpoles",
-  "tagged",
-  "tail",
-  "taken",
-  "talent",
-  "tamper",
-  "tanks",
-  "tapestry",
-  "tarnished",
-  "tasked",
-  "tattoo",
-  "taunts",
-  "tavern",
-  "tawny",
-  "taxi",
-  "teardrop",
-  "technical",
-  "tedious",
-  "teeming",
-  "tell",
-  "template",
-  "tender",
-  "tepid",
-  "tequila",
-  "terminal",
-  "testing",
-  "tether",
-  "textbook",
-  "thaw",
-  "theatrics",
-  "thirsty",
-  "thorn",
-  "threaten",
-  "thumbs",
-  "thwart",
-  "ticket",
-  "tidy",
-  "tiers",
-  "tiger",
-  "tilt",
-  "timber",
-  "tinted",
-  "tipsy",
-  "tirade",
-  "tissue",
-  "titans",
-  "toaster",
-  "tobacco",
-  "today",
-  "toenail",
-  "toffee",
-  "together",
-  "toilet",
-  "token",
-  "tolerant",
-  "tomorrow",
-  "tonic",
-  "toolbox",
-  "topic",
-  "torch",
-  "tossed",
-  "total",
-  "touchy",
-  "towel",
-  "toxic",
-  "toyed",
-  "trash",
-  "trendy",
-  "tribal",
-  "trolling",
-  "truth",
-  "trying",
-  "tsunami",
-  "tubes",
-  "tucks",
-  "tudor",
-  "tuesday",
-  "tufts",
-  "tugs",
-  "tuition",
-  "tulips",
-  "tumbling",
-  "tunnel",
-  "turnip",
-  "tusks",
-  "tutor",
-  "tuxedo",
-  "twang",
-  "tweezers",
-  "twice",
-  "twofold",
-  "tycoon",
-  "typist",
-  "tyrant",
-  "ugly",
-  "ulcers",
-  "ultimate",
-  "umbrella",
-  "umpire",
-  "unafraid",
-  "unbending",
-  "uncle",
-  "under",
-  "uneven",
-  "unfit",
-  "ungainly",
-  "unhappy",
-  "union",
-  "unjustly",
-  "unknown",
-  "unlikely",
-  "unmask",
-  "unnoticed",
-  "unopened",
-  "unplugs",
-  "unquoted",
-  "unrest",
-  "unsafe",
-  "until",
-  "unusual",
-  "unveil",
-  "unwind",
-  "unzip",
-  "upbeat",
-  "upcoming",
-  "update",
-  "upgrade",
-  "uphill",
-  "upkeep",
-  "upload",
-  "upon",
-  "upper",
-  "upright",
-  "upstairs",
-  "uptight",
-  "upwards",
-  "urban",
-  "urchins",
-  "urgent",
-  "usage",
-  "useful",
-  "usher",
-  "using",
-  "usual",
-  "utensils",
-  "utility",
-  "utmost",
-  "utopia",
-  "uttered",
-  "vacation",
-  "vague",
-  "vain",
-  "value",
-  "vampire",
-  "vane",
-  "vapidly",
-  "vary",
-  "vastness",
-  "vats",
-  "vaults",
-  "vector",
-  "veered",
-  "vegan",
-  "vehicle",
-  "vein",
-  "velvet",
-  "venomous",
-  "verification",
-  "vessel",
-  "veteran",
-  "vexed",
-  "vials",
-  "vibrate",
-  "victim",
-  "video",
-  "viewpoint",
-  "vigilant",
-  "viking",
-  "village",
-  "vinegar",
-  "violin",
-  "vipers",
-  "virtual",
-  "visited",
-  "vitals",
-  "vivid",
-  "vixen",
-  "vocal",
-  "vogue",
-  "voice",
-  "volcano",
-  "vortex",
-  "voted",
-  "voucher",
-  "vowels",
-  "voyage",
-  "vulture",
-  "wade",
-  "waffle",
-  "wagtail",
-  "waist",
-  "waking",
-  "wallets",
-  "wanted",
-  "warped",
-  "washing",
-  "water",
-  "waveform",
-  "waxing",
-  "wayside",
-  "weavers",
-  "website",
-  "wedge",
-  "weekday",
-  "weird",
-  "welders",
-  "went",
-  "wept",
-  "were",
-  "western",
-  "wetsuit",
-  "whale",
-  "when",
-  "whipped",
-  "whole",
-  "wickets",
-  "width",
-  "wield",
-  "wife",
-  "wiggle",
-  "wildly",
-  "winter",
-  "wipeout",
-  "wiring",
-  "wise",
-  "withdrawn",
-  "wives",
-  "wizard",
-  "wobbly",
-  "woes",
-  "woken",
-  "wolf",
-  "womanly",
-  "wonders",
-  "woozy",
-  "worry",
-  "wounded",
-  "woven",
-  "wrap",
-  "wrist",
-  "wrong",
-  "yacht",
-  "yahoo",
-  "yanks",
-  "yard",
-  "yawning",
-  "yearbook",
-  "yellow",
-  "yesterday",
-  "yeti",
-  "yields",
-  "yodel",
-  "yoga",
-  "younger",
-  "yoyo",
-  "zapped",
-  "zeal",
-  "zebra",
-  "zero",
-  "zesty",
-  "zigzags",
-  "zinger",
-  "zippers",
-  "zodiac",
-  "zombie",
-  "zones",
-  "zoom"
-];
diff --git a/cw_wownero/lib/wownero_transaction_info.dart b/cw_wownero/lib/wownero_transaction_info.dart
index 7b0073452..db5345e5d 100644
--- a/cw_wownero/lib/wownero_transaction_info.dart
+++ b/cw_wownero/lib/wownero_transaction_info.dart
@@ -1,6 +1,5 @@
 import 'package:cw_core/transaction_info.dart';
 import 'package:cw_core/wownero_amount_format.dart';
-import 'package:cw_wownero/api/structs/transaction_info_row.dart';
 import 'package:cw_core/parseBoolFromString.dart';
 import 'package:cw_core/transaction_direction.dart';
 import 'package:cw_core/format_amount.dart';
@@ -35,26 +34,6 @@ class WowneroTransactionInfo extends TransactionInfo {
           };
         }
 
-  WowneroTransactionInfo.fromRow(TransactionInfoRow row)
-      : id = "${row.getHash()}_${row.getAmount()}_${row.subaddrAccount}_${row.subaddrIndex}",
-        txHash = row.getHash(),
-        height = row.blockHeight,
-        direction = parseTransactionDirectionFromInt(row.direction),
-        date = DateTime.fromMillisecondsSinceEpoch(row.getDatetime() * 1000),
-        isPending = row.isPending != 0,
-        amount = row.getAmount(),
-        accountIndex = row.subaddrAccount,
-        addressIndex = row.subaddrIndex,
-        confirmations = row.confirmations,
-        key = getTxKey(row.getHash()),
-        fee = row.fee {
-          additionalInfo = <String, dynamic>{
-            'key': key,
-            'accountIndex': accountIndex,
-            'addressIndex': addressIndex
-          };
-        }
-
   final String id;
   final String txHash;
   final int height;
diff --git a/cw_wownero/lib/wownero_unspent.dart b/cw_wownero/lib/wownero_unspent.dart
index a79106886..fdfdfc7a4 100644
--- a/cw_wownero/lib/wownero_unspent.dart
+++ b/cw_wownero/lib/wownero_unspent.dart
@@ -1,5 +1,4 @@
 import 'package:cw_core/unspent_transaction_output.dart';
-import 'package:cw_wownero/api/structs/coins_info_row.dart';
 
 class WowneroUnspent extends Unspent {
   WowneroUnspent(
@@ -8,13 +7,5 @@ class WowneroUnspent extends Unspent {
     this.isFrozen = isFrozen;
   }
 
-  factory WowneroUnspent.fromCoinsInfoRow(CoinsInfoRow coinsInfoRow) => WowneroUnspent(
-      coinsInfoRow.getAddress(),
-      coinsInfoRow.getHash(),
-      coinsInfoRow.getKeyImage(),
-      coinsInfoRow.amount,
-      coinsInfoRow.frozen == 1,
-      coinsInfoRow.unlocked == 1);
-
   final bool isUnlocked;
 }
diff --git a/cw_wownero/lib/wownero_wallet.dart b/cw_wownero/lib/wownero_wallet.dart
index 52f84e26a..e02c0ec2e 100644
--- a/cw_wownero/lib/wownero_wallet.dart
+++ b/cw_wownero/lib/wownero_wallet.dart
@@ -107,9 +107,7 @@ abstract class WowneroWalletBase
   @override
   String get seed => wownero_wallet.getSeed();
 
-  String seedLegacy(String? language) {
-    return wownero_wallet.getSeedLegacy(language);
-  }
+  String seedLegacy(String? language) => wownero_wallet.getSeedLegacy(language);
 
   @override
   MoneroWalletKeys get keys => MoneroWalletKeys(
@@ -182,12 +180,12 @@ abstract class WowneroWalletBase
   @override
   Future<void> startSync() async {
     try {
-      _setInitialHeight();
+      _assertInitialHeight();
     } catch (_) {
       // our restore height wasn't correct, so lets see if using the backup works:
       try {
         await resetCache(name);
-        _setInitialHeight();
+        _assertInitialHeight();
       } catch (e) {
         // we still couldn't get a valid height from the backup?!:
         // try to use the date instead:
@@ -604,18 +602,14 @@ abstract class WowneroWalletBase
     _listener = wownero_wallet.setListeners(_onNewBlock, _onNewTransaction);
   }
 
-  // check if the height is correct:
-  void _setInitialHeight() {
-    if (walletInfo.isRecovery) {
-      return;
-    }
+  /// Asserts the current height to be above [MIN_RESTORE_HEIGHT]
+  void _assertInitialHeight() {
+    if (walletInfo.isRecovery) return;
 
     final height = wownero_wallet.getCurrentHeight();
 
-    if (height > MIN_RESTORE_HEIGHT) {
-      // the restore height is probably correct, so we do nothing:
-      return;
-    }
+    // the restore height is probably correct, so we do nothing:
+    if (height > MIN_RESTORE_HEIGHT) return;
 
     throw Exception("height isn't > $MIN_RESTORE_HEIGHT!");
   }
diff --git a/cw_wownero/pubspec.lock b/cw_wownero/pubspec.lock
index 011fed169..d91922ac9 100644
--- a/cw_wownero/pubspec.lock
+++ b/cw_wownero/pubspec.lock
@@ -437,10 +437,10 @@ packages:
   monero:
     dependency: "direct main"
     description:
-      path: "."
-      ref: d46753eca865e9e56c2f0ef6fe485c42e11982c5
-      resolved-ref: d46753eca865e9e56c2f0ef6fe485c42e11982c5
-      url: "https://github.com/mrcyjanek/monero.dart"
+      path: "impls/monero.dart"
+      ref: "bcb328a4956105dc182afd0ce2e48fe263f5f20b"
+      resolved-ref: "bcb328a4956105dc182afd0ce2e48fe263f5f20b"
+      url: "https://github.com/mrcyjanek/monero_c"
     source: git
     version: "0.0.0"
   mutex:
diff --git a/cw_wownero/pubspec.yaml b/cw_wownero/pubspec.yaml
index 4537955ab..7a45eb628 100644
--- a/cw_wownero/pubspec.yaml
+++ b/cw_wownero/pubspec.yaml
@@ -24,8 +24,9 @@ dependencies:
     path: ../cw_core
   monero:
     git:
-      url: https://github.com/mrcyjanek/monero.dart
-      ref: d46753eca865e9e56c2f0ef6fe485c42e11982c5
+      url: https://github.com/mrcyjanek/monero_c
+      ref: bcb328a4956105dc182afd0ce2e48fe263f5f20b # monero_c hash
+      path: impls/monero.dart
   mutex: ^3.1.0
 
 dev_dependencies:
diff --git a/lib/monero/cw_monero.dart b/lib/monero/cw_monero.dart
index c1384a3df..1f1888b44 100644
--- a/lib/monero/cw_monero.dart
+++ b/lib/monero/cw_monero.dart
@@ -346,4 +346,9 @@ class CWMonero extends Monero {
   Future<int> getCurrentHeight() async {
     return monero_wallet_api.getCurrentHeight();
   }
+
+  @override
+  void monerocCheck() {
+    checkIfMoneroCIsFine();
+  }
 }
diff --git a/lib/src/screens/dashboard/pages/balance_page.dart b/lib/src/screens/dashboard/pages/balance_page.dart
index 11abdeb58..1cf3e3e0c 100644
--- a/lib/src/screens/dashboard/pages/balance_page.dart
+++ b/lib/src/screens/dashboard/pages/balance_page.dart
@@ -124,6 +124,36 @@ class CryptoBalanceWidget extends StatelessWidget {
         child: Column(
           crossAxisAlignment: CrossAxisAlignment.center,
           children: [
+            Observer(
+              builder: (_) {
+                if (dashboardViewModel.getMoneroError != null) {
+                  return Padding(
+                    padding: const EdgeInsets.fromLTRB(16,0,16,16),
+                    child: DashBoardRoundedCardWidget(
+                      title: "Invalid monero bindings",
+                      subTitle: dashboardViewModel.getMoneroError.toString(),
+                      onTap: () {},
+                    ),
+                  );
+                }
+                return Container();
+              },
+            ),
+            Observer(
+              builder: (_) {
+                if (dashboardViewModel.getWowneroError != null) {
+                  return Padding(
+                    padding: const EdgeInsets.fromLTRB(16,0,16,16),
+                    child: DashBoardRoundedCardWidget(
+                      title: "Invalid wownero bindings",
+                      subTitle: dashboardViewModel.getWowneroError.toString(),
+                      onTap: () {},
+                    )
+                  );
+                }
+                return Container();
+              },
+            ),
             Observer(
                 builder: (_) => dashboardViewModel.balanceViewModel.hasAccounts
                     ? HomeScreenAccountWidget(
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index 06c565035..1baea76cd 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -11,6 +11,7 @@ import 'package:cake_wallet/entities/service_status.dart';
 import 'package:cake_wallet/exchange/exchange_provider_description.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/monero/monero.dart';
+import 'package:cake_wallet/wownero/wownero.dart' as wow;
 import 'package:cake_wallet/nano/nano.dart';
 import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
 import 'package:cake_wallet/store/app_store.dart';
@@ -336,6 +337,27 @@ abstract class DashboardViewModelBase with Store {
       wallet.type == WalletType.haven;
 
   @computed
+  String? get getMoneroError {
+    if (wallet.type != WalletType.monero) return null;
+    try {
+      monero!.monerocCheck();
+    } catch (e) {
+      return e.toString();
+    }
+    return null;
+  }
+
+  @computed
+  String? get getWowneroError {
+    if (wallet.type != WalletType.wownero) return null;
+    try {
+      wow.wownero!.wownerocCheck();
+    } catch (e) {
+      return e.toString();
+    }
+    return null;
+  }
+
   List<String> get isMoneroWalletBrokenReasons {
     if (wallet.type != WalletType.monero) return [];
     final keys = monero!.getKeys(wallet);
diff --git a/lib/wownero/cw_wownero.dart b/lib/wownero/cw_wownero.dart
index 03bebc463..0e0b00fd4 100644
--- a/lib/wownero/cw_wownero.dart
+++ b/lib/wownero/cw_wownero.dart
@@ -347,4 +347,9 @@ class CWWownero extends Wownero {
 
   String getLegacySeed(Object wallet, String langName) =>
       (wallet as WowneroWalletBase).seedLegacy(langName);
+
+  @override
+  void wownerocCheck() {
+    checkIfMoneroCIsFine();
+  }
 }
diff --git a/scripts/prepare_moneroc.sh b/scripts/prepare_moneroc.sh
index cac5d3ad2..2e53a54ea 100755
--- a/scripts/prepare_moneroc.sh
+++ b/scripts/prepare_moneroc.sh
@@ -8,7 +8,7 @@ if [[ ! -d "monero_c" ]];
 then
     git clone https://github.com/mrcyjanek/monero_c --branch rewrite-wip
     cd monero_c
-    git checkout c094ed5da69d2274747bf6edd7ca24124487bd34
+    git checkout bcb328a4956105dc182afd0ce2e48fe263f5f20b
     git reset --hard
     git submodule update --init --force --recursive
     ./apply_patches.sh monero
diff --git a/tool/configure.dart b/tool/configure.dart
index 853d06448..32b470979 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -262,6 +262,7 @@ import 'package:cw_core/monero_amount_format.dart';
 import 'package:cw_core/monero_transaction_priority.dart';
 import 'package:cw_monero/monero_unspent.dart';
 import 'package:cw_monero/monero_wallet_service.dart';
+import 'package:cw_monero/api/wallet_manager.dart';
 import 'package:cw_monero/monero_wallet.dart';
 import 'package:cw_monero/monero_transaction_info.dart';
 import 'package:cw_monero/monero_transaction_creation_credentials.dart';
@@ -377,6 +378,7 @@ abstract class Monero {
   double formatterMoneroAmountToDouble({required int amount});
   int formatterMoneroParseAmount({required String amount});
   Account getCurrentAccount(Object wallet);
+  void monerocCheck();
   void setCurrentAccount(Object wallet, int id, String label, String? balance);
   void onStartup();
   int getTransactionInfoAccountId(TransactionInfo tx);
@@ -449,6 +451,7 @@ import 'package:cw_wownero/wownero_transaction_info.dart';
 import 'package:cw_wownero/wownero_transaction_creation_credentials.dart';
 import 'package:cw_core/account.dart' as wownero_account;
 import 'package:cw_wownero/api/wallet.dart' as wownero_wallet_api;
+import 'package:cw_wownero/api/wallet_manager.dart';
 import 'package:cw_wownero/mnemonics/english.dart';
 import 'package:cw_wownero/mnemonics/chinese_simplified.dart';
 import 'package:cw_wownero/mnemonics/dutch.dart';
@@ -540,6 +543,7 @@ abstract class Wownero {
   Future<void> updateUnspents(Object wallet);
 
   Future<int> getCurrentHeight();
+  void wownerocCheck();
 
   WalletCredentials createWowneroRestoreWalletFromKeysCredentials({
     required String name,

From 8e4082d6806a89a256f827952036952a9ed21b47 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Fri, 9 Aug 2024 22:18:32 +0300
Subject: [PATCH 12/81] Generic fixes (#1583)

* add litecoin nodes
minor ui fix

* update build macos to build universal archs [skip ci]

* minor fix [skip ci]

* update share package

* change trocador onion url
---
 lib/anonpay/anonpay_api.dart                  |  2 +-
 .../screens/new_wallet/new_wallet_page.dart   | 30 ++++++++++---------
 .../address_edit_or_create_page.dart          |  6 ++--
 macos/Flutter/GeneratedPluginRegistrant.swift |  2 +-
 pubspec_base.yaml                             |  2 +-
 scripts/macos/build_all.sh                    |  2 +-
 .../flutter/generated_plugin_registrant.cc    |  3 ++
 windows/flutter/generated_plugins.cmake       |  1 +
 8 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/lib/anonpay/anonpay_api.dart b/lib/anonpay/anonpay_api.dart
index e46499407..acab662d1 100644
--- a/lib/anonpay/anonpay_api.dart
+++ b/lib/anonpay/anonpay_api.dart
@@ -20,7 +20,7 @@ class AnonPayApi {
   final WalletBase wallet;
 
   static const anonpayRef = secrets.anonPayReferralCode;
-  static const onionApiAuthority = 'trocadorfyhlu27aefre5u7zri66gudtzdyelymftvr4yjwcxhfaqsid.onion';
+  static const onionApiAuthority = 'tqzngtf2hybjbexznel6dhgsvbynjzezoybvtv6iofomx7gchqfssgqd.onion';
   static const clearNetAuthority = 'trocador.app';
   static const markup = secrets.trocadorExchangeMarkup;
   static const anonPayPath = '/anonpay';
diff --git a/lib/src/screens/new_wallet/new_wallet_page.dart b/lib/src/screens/new_wallet/new_wallet_page.dart
index 306c41479..d9427af0a 100644
--- a/lib/src/screens/new_wallet/new_wallet_page.dart
+++ b/lib/src/screens/new_wallet/new_wallet_page.dart
@@ -40,11 +40,11 @@ class NewWalletPage extends BasePage {
 
   @override
   Function(BuildContext)? get pushToNextWidget => (context) {
-    FocusScopeNode currentFocus = FocusScope.of(context);
-    if (!currentFocus.hasPrimaryFocus) {
-      currentFocus.focusedChild?.unfocus();
-    }
-  };
+        FocusScopeNode currentFocus = FocusScope.of(context);
+        if (!currentFocus.hasPrimaryFocus) {
+          currentFocus.focusedChild?.unfocus();
+        }
+      };
 
   @override
   Widget body(BuildContext context) => WalletNameForm(
@@ -88,15 +88,17 @@ class _WalletNameFormState extends State<WalletNameForm> {
 
       if (state is FailureState) {
         WidgetsBinding.instance.addPostFrameCallback((_) {
-          showPopUp<void>(
-              context: context,
-              builder: (_) {
-                return AlertWithOneAction(
-                    alertTitle: S.current.new_wallet,
-                    alertContent: state.error,
-                    buttonText: S.of(context).ok,
-                    buttonAction: () => Navigator.of(context).pop());
-              });
+          if (context.mounted) {
+            showPopUp<void>(
+                context: context,
+                builder: (_) {
+                  return AlertWithOneAction(
+                      alertTitle: S.current.new_wallet,
+                      alertContent: state.error,
+                      buttonText: S.of(context).ok,
+                      buttonAction: () => Navigator.of(context).pop());
+                });
+          }
         });
       }
     });
diff --git a/lib/src/screens/subaddress/address_edit_or_create_page.dart b/lib/src/screens/subaddress/address_edit_or_create_page.dart
index e067c78d0..b69a6d8df 100644
--- a/lib/src/screens/subaddress/address_edit_or_create_page.dart
+++ b/lib/src/screens/subaddress/address_edit_or_create_page.dart
@@ -58,7 +58,7 @@ class AddressEditOrCreatePage extends BasePage {
                   isLoading:
                       addressEditOrCreateViewModel.state is AddressIsSaving,
                   isDisabled:
-                      addressEditOrCreateViewModel.label?.isEmpty ?? true,
+                      addressEditOrCreateViewModel.label.isEmpty,
                 ),
               )
             ],
@@ -74,7 +74,9 @@ class AddressEditOrCreatePage extends BasePage {
             (AddressEditOrCreateState state) {
           if (state is AddressSavedSuccessfully) {
             WidgetsBinding.instance
-                .addPostFrameCallback((_) => Navigator.of(context).pop());
+                .addPostFrameCallback((_) {
+                  if (context.mounted) Navigator.of(context).pop();
+                });
           }
         });
 
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index 873d50649..338ece4ce 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -15,7 +15,7 @@ import in_app_review
 import package_info
 import package_info_plus
 import path_provider_foundation
-import share_plus_macos
+import share_plus
 import shared_preferences_foundation
 import url_launcher_macos
 import wakelock_plus
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 84b4631fc..463c04988 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -21,7 +21,7 @@ dependencies:
   mobx: ^2.1.4
   flutter_mobx: ^2.0.6+5
   flutter_slidable: ^3.0.1
-  share_plus: ^4.0.10
+  share_plus: ^10.0.0
   # date_range_picker: ^1.0.6
   #https://api.flutter.dev/flutter/material/showDateRangePicker.html
   dio: ^4.0.6
diff --git a/scripts/macos/build_all.sh b/scripts/macos/build_all.sh
index 4116704bf..030617f7d 100755
--- a/scripts/macos/build_all.sh
+++ b/scripts/macos/build_all.sh
@@ -1,3 +1,3 @@
 #!/bin/sh
 
-./build_monero_all.sh
\ No newline at end of file
+./build_monero_all.sh universal
\ No newline at end of file
diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc
index 323f53c9f..c6444e09c 100644
--- a/windows/flutter/generated_plugin_registrant.cc
+++ b/windows/flutter/generated_plugin_registrant.cc
@@ -10,6 +10,7 @@
 #include <flutter_local_authentication/flutter_local_authentication_plugin_c_api.h>
 #include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
 #include <permission_handler_windows/permission_handler_windows_plugin.h>
+#include <share_plus/share_plus_windows_plugin_c_api.h>
 #include <url_launcher_windows/url_launcher_windows.h>
 
 void RegisterPlugins(flutter::PluginRegistry* registry) {
@@ -21,6 +22,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
       registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
   PermissionHandlerWindowsPluginRegisterWithRegistrar(
       registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
+  SharePlusWindowsPluginCApiRegisterWithRegistrar(
+      registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
   UrlLauncherWindowsRegisterWithRegistrar(
       registry->GetRegistrarForPlugin("UrlLauncherWindows"));
 }
diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake
index d6d9b0a49..0a0b2f9eb 100644
--- a/windows/flutter/generated_plugins.cmake
+++ b/windows/flutter/generated_plugins.cmake
@@ -7,6 +7,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
   flutter_local_authentication
   flutter_secure_storage_windows
   permission_handler_windows
+  share_plus
   url_launcher_windows
 )
 

From fb33a6f23dce32172d9b80f343972dc4e07289c3 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Fri, 9 Aug 2024 23:15:30 +0300
Subject: [PATCH 13/81] Cw 688 avoid wallet file corruption (#1582)

* CW-688 Store Seed and keys in .keys file

* CW-688 Open wallet from keys in .keys file and migrate wallets using the old file

* CW-688 Open wallet from keys in .keys file and migrate wallets using the old file

* CW-688 Restore .keys file from .keys.backup

* CW-688 Restore .keys file from .keys.backup

* CW-688 Move saving .keys files into the save function instead of the service

* CW-688 Handle corrupt wallets

* CW-688 Handle corrupt wallets

* CW-688 Remove code duplication

* CW-688 Reduce cache dependency

* wrap any file reading/writing function with try/catch [skip ci]

---------

Co-authored-by: Konstantin Ullrich <konstantinullrich12@gmail.com>
---
 cw_bitcoin/lib/bitcoin_wallet.dart            |  66 +++++++----
 cw_bitcoin/lib/bitcoin_wallet_service.dart    |   2 +
 cw_bitcoin/lib/electrum_wallet.dart           |  14 ++-
 cw_bitcoin/lib/electrum_wallet_snapshot.dart  |   8 +-
 cw_bitcoin/lib/litecoin_wallet.dart           |  55 ++++++---
 cw_bitcoin/lib/litecoin_wallet_service.dart   |   1 +
 .../lib/src/bitcoin_cash_wallet.dart          |  35 ++++--
 .../lib/src/bitcoin_cash_wallet_service.dart  |   2 +
 cw_core/lib/wallet_keys_file.dart             | 110 ++++++++++++++++++
 cw_ethereum/lib/ethereum_wallet.dart          |  33 ++++--
 cw_evm/lib/evm_chain_wallet.dart              |  11 +-
 cw_nano/lib/nano_wallet.dart                  |  81 ++++++++-----
 cw_nano/lib/nano_wallet_service.dart          |   2 +-
 cw_polygon/lib/polygon_wallet.dart            |  37 ++++--
 cw_polygon/lib/polygon_wallet_service.dart    |   2 -
 cw_solana/lib/solana_wallet.dart              |  47 ++++++--
 cw_tron/lib/tron_wallet.dart                  |  66 +++++++----
 cw_tron/lib/tron_wallet_service.dart          |   5 +-
 18 files changed, 433 insertions(+), 144 deletions(-)
 create mode 100644 cw_core/lib/wallet_keys_file.dart

diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart
index d061480ed..ce3e2caa8 100644
--- a/cw_bitcoin/lib/bitcoin_wallet.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet.dart
@@ -6,15 +6,16 @@ import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
 import 'package:convert/convert.dart';
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
-import 'package:cw_bitcoin/electrum_derivations.dart';
 import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart';
 import 'package:cw_bitcoin/electrum_balance.dart';
+import 'package:cw_bitcoin/electrum_derivations.dart';
 import 'package:cw_bitcoin/electrum_wallet.dart';
 import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
 import 'package:cw_bitcoin/psbt_transaction_builder.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_keys_file.dart';
 import 'package:flutter/foundation.dart';
 import 'package:hive/hive.dart';
 import 'package:ledger_bitcoin/ledger_bitcoin.dart';
@@ -143,49 +144,66 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
     final network = walletInfo.network != null
         ? BasedUtxoNetwork.fromName(walletInfo.network!)
         : BitcoinNetwork.mainnet;
-    final snp = await ElectrumWalletSnapshot.load(name, walletInfo.type, password, network);
 
-    walletInfo.derivationInfo ??= DerivationInfo(
-      derivationType: snp.derivationType ?? DerivationType.electrum,
-      derivationPath: snp.derivationPath,
-    );
+    final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
+
+    ElectrumWalletSnapshot? snp = null;
+
+    try {
+      snp = await ElectrumWalletSnapshot.load(name, walletInfo.type, password, network);
+    } catch (e) {
+      if (!hasKeysFile) rethrow;
+    }
+
+    final WalletKeysData keysData;
+    // Migrate wallet from the old scheme to then new .keys file scheme
+    if (!hasKeysFile) {
+      keysData =
+          WalletKeysData(mnemonic: snp!.mnemonic, xPub: snp.xpub, passphrase: snp.passphrase);
+    } else {
+      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+    }
+
+    walletInfo.derivationInfo ??= DerivationInfo();
 
     // set the default if not present:
-    walletInfo.derivationInfo!.derivationPath = snp.derivationPath ?? electrum_path;
-    walletInfo.derivationInfo!.derivationType = snp.derivationType ?? DerivationType.electrum;
+    walletInfo.derivationInfo!.derivationPath ??= snp?.derivationPath ?? electrum_path;
+    walletInfo.derivationInfo!.derivationType ??= snp?.derivationType ?? DerivationType.electrum;
 
     Uint8List? seedBytes = null;
+    final mnemonic = keysData.mnemonic;
+    final passphrase = keysData.passphrase;
 
-    if (snp.mnemonic != null) {
+    if (mnemonic != null) {
       switch (walletInfo.derivationInfo!.derivationType) {
         case DerivationType.electrum:
-          seedBytes = await mnemonicToSeedBytes(snp.mnemonic!);
+          seedBytes = await mnemonicToSeedBytes(mnemonic);
           break;
         case DerivationType.bip39:
         default:
           seedBytes = await bip39.mnemonicToSeed(
-            snp.mnemonic!,
-            passphrase: snp.passphrase ?? '',
+            mnemonic,
+            passphrase: passphrase ?? '',
           );
           break;
       }
     }
 
     return BitcoinWallet(
-      mnemonic: snp.mnemonic,
-      xpub: snp.xpub,
+      mnemonic: mnemonic,
+      xpub: keysData.xPub,
       password: password,
-      passphrase: snp.passphrase,
+      passphrase: passphrase,
       walletInfo: walletInfo,
       unspentCoinsInfo: unspentCoinsInfo,
-      initialAddresses: snp.addresses,
-      initialSilentAddresses: snp.silentAddresses,
-      initialSilentAddressIndex: snp.silentAddressIndex,
-      initialBalance: snp.balance,
+      initialAddresses: snp?.addresses,
+      initialSilentAddresses: snp?.silentAddresses,
+      initialSilentAddressIndex: snp?.silentAddressIndex ?? 0,
+      initialBalance: snp?.balance,
       seedBytes: seedBytes,
-      initialRegularAddressIndex: snp.regularAddressIndex,
-      initialChangeAddressIndex: snp.changeAddressIndex,
-      addressPageType: snp.addressPageType,
+      initialRegularAddressIndex: snp?.regularAddressIndex,
+      initialChangeAddressIndex: snp?.changeAddressIndex,
+      addressPageType: snp?.addressPageType,
       networkParam: network,
       alwaysScan: alwaysScan,
     );
@@ -249,8 +267,8 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
       final accountPath = walletInfo.derivationInfo?.derivationPath;
       final derivationPath = accountPath != null ? "$accountPath/$isChange/$index" : null;
 
-      final signature = await _bitcoinLedgerApp!
-          .signMessage(_ledgerDevice!, message: ascii.encode(message), signDerivationPath: derivationPath);
+      final signature = await _bitcoinLedgerApp!.signMessage(_ledgerDevice!,
+          message: ascii.encode(message), signDerivationPath: derivationPath);
       return base64Encode(signature);
     }
 
diff --git a/cw_bitcoin/lib/bitcoin_wallet_service.dart b/cw_bitcoin/lib/bitcoin_wallet_service.dart
index a9a6d96db..cf93aa29d 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_service.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_service.dart
@@ -41,8 +41,10 @@ class BitcoinWalletService extends WalletService<
       unspentCoinsInfo: unspentCoinsInfoSource,
       network: network,
     );
+
     await wallet.save();
     await wallet.init();
+
     return wallet;
   }
 
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 39cf95009..e55e5ed0e 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -37,6 +37,7 @@ import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/utils/file.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_keys_file.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:cw_core/get_height_by_date.dart';
 import 'package:flutter/foundation.dart';
@@ -54,7 +55,7 @@ const int TWEAKS_COUNT = 25;
 
 abstract class ElectrumWalletBase
     extends WalletBase<ElectrumBalance, ElectrumTransactionHistory, ElectrumTransactionInfo>
-    with Store {
+    with Store, WalletKeysFile {
   ElectrumWalletBase({
     required String password,
     required WalletInfo walletInfo,
@@ -169,6 +170,10 @@ abstract class ElectrumWalletBase
   @override
   String? get seed => _mnemonic;
 
+  @override
+  WalletKeysData get walletKeysData =>
+      WalletKeysData(mnemonic: _mnemonic, xPub: xpub, passphrase: passphrase);
+
   bitcoin.NetworkType networkType;
   BasedUtxoNetwork network;
 
@@ -1076,6 +1081,11 @@ abstract class ElectrumWalletBase
 
   @override
   Future<void> save() async {
+    if (!(await WalletKeysFile.hasKeysFile(walletInfo.name, walletInfo.type))) {
+      await saveKeysFile(_password);
+      saveKeysFile(_password, true);
+    }
+
     final path = await makePath();
     await write(path: path, password: _password, data: toJSON());
     await transactionHistory.save();
@@ -1131,8 +1141,6 @@ abstract class ElectrumWalletBase
     _autoSaveTimer?.cancel();
   }
 
-  Future<String> makePath() async => pathForWallet(name: walletInfo.name, type: walletInfo.type);
-
   @action
   Future<void> updateAllUnspents() async {
     List<BitcoinUnspent> updatedUnspentCoins = [];
diff --git a/cw_bitcoin/lib/electrum_wallet_snapshot.dart b/cw_bitcoin/lib/electrum_wallet_snapshot.dart
index 15ad1cf63..082460f72 100644
--- a/cw_bitcoin/lib/electrum_wallet_snapshot.dart
+++ b/cw_bitcoin/lib/electrum_wallet_snapshot.dart
@@ -32,15 +32,21 @@ class ElectrumWalletSnapshot {
   final WalletType type;
   final String? addressPageType;
 
+  @deprecated
   String? mnemonic;
+
+  @deprecated
   String? xpub;
+
+  @deprecated
+  String? passphrase;
+
   List<BitcoinAddressRecord> addresses;
   List<BitcoinSilentPaymentAddressRecord> silentAddresses;
   ElectrumBalance balance;
   Map<String, int> regularAddressIndex;
   Map<String, int> changeAddressIndex;
   int silentAddressIndex;
-  String? passphrase;
   DerivationType? derivationType;
   String? derivationPath;
 
diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 209ddc774..bfb9a1b16 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -1,20 +1,21 @@
+import 'package:bip39/bip39.dart' as bip39;
 import 'package:bitcoin_base/bitcoin_base.dart';
+import 'package:cw_bitcoin/bitcoin_address_record.dart';
 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
 import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
-import 'package:cw_core/crypto_currency.dart';
-import 'package:cw_core/unspent_coins_info.dart';
+import 'package:cw_bitcoin/electrum_balance.dart';
+import 'package:cw_bitcoin/electrum_wallet.dart';
+import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
+import 'package:cw_bitcoin/litecoin_network.dart';
 import 'package:cw_bitcoin/litecoin_wallet_addresses.dart';
+import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/transaction_priority.dart';
+import 'package:cw_core/unspent_coins_info.dart';
+import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_keys_file.dart';
 import 'package:flutter/foundation.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
-import 'package:cw_core/wallet_info.dart';
-import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
-import 'package:cw_bitcoin/electrum_wallet.dart';
-import 'package:cw_bitcoin/bitcoin_address_record.dart';
-import 'package:cw_bitcoin/electrum_balance.dart';
-import 'package:cw_bitcoin/litecoin_network.dart';
-import 'package:bip39/bip39.dart' as bip39;
 
 part 'litecoin_wallet.g.dart';
 
@@ -101,19 +102,37 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     required Box<UnspentCoinsInfo> unspentCoinsInfo,
     required String password,
   }) async {
-    final snp =
-        await ElectrumWalletSnapshot.load(name, walletInfo.type, password, LitecoinNetwork.mainnet);
+    final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
+
+    ElectrumWalletSnapshot? snp = null;
+
+    try {
+      snp = await ElectrumWalletSnapshot.load(
+          name, walletInfo.type, password, LitecoinNetwork.mainnet);
+    } catch (e) {
+      if (!hasKeysFile) rethrow;
+    }
+
+    final WalletKeysData keysData;
+    // Migrate wallet from the old scheme to then new .keys file scheme
+    if (!hasKeysFile) {
+      keysData =
+          WalletKeysData(mnemonic: snp!.mnemonic, xPub: snp.xpub, passphrase: snp.passphrase);
+    } else {
+      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+    }
+
     return LitecoinWallet(
-      mnemonic: snp.mnemonic!,
+      mnemonic: keysData.mnemonic!,
       password: password,
       walletInfo: walletInfo,
       unspentCoinsInfo: unspentCoinsInfo,
-      initialAddresses: snp.addresses,
-      initialBalance: snp.balance,
-      seedBytes: await mnemonicToSeedBytes(snp.mnemonic!),
-      initialRegularAddressIndex: snp.regularAddressIndex,
-      initialChangeAddressIndex: snp.changeAddressIndex,
-      addressPageType: snp.addressPageType,
+      initialAddresses: snp?.addresses,
+      initialBalance: snp?.balance,
+      seedBytes: await mnemonicToSeedBytes(keysData.mnemonic!),
+      initialRegularAddressIndex: snp?.regularAddressIndex,
+      initialChangeAddressIndex: snp?.changeAddressIndex,
+      addressPageType: snp?.addressPageType,
     );
   }
 
diff --git a/cw_bitcoin/lib/litecoin_wallet_service.dart b/cw_bitcoin/lib/litecoin_wallet_service.dart
index bb51a4eaa..7025b72e5 100644
--- a/cw_bitcoin/lib/litecoin_wallet_service.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_service.dart
@@ -33,6 +33,7 @@ class LitecoinWalletService extends WalletService<
         passphrase: credentials.passphrase,
         walletInfo: credentials.walletInfo!,
         unspentCoinsInfo: unspentCoinsInfoSource);
+
     await wallet.save();
     await wallet.init();
 
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
index 51bd3612d..f15eed10d 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
@@ -12,6 +12,7 @@ import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/transaction_priority.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_keys_file.dart';
 import 'package:flutter/foundation.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
@@ -89,14 +90,32 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
     required Box<UnspentCoinsInfo> unspentCoinsInfo,
     required String password,
   }) async {
-    final snp = await ElectrumWalletSnapshot.load(
-        name, walletInfo.type, password, BitcoinCashNetwork.mainnet);
+    final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
+
+    ElectrumWalletSnapshot? snp = null;
+
+    try {
+      snp = await ElectrumWalletSnapshot.load(
+          name, walletInfo.type, password, BitcoinCashNetwork.mainnet);
+    } catch (e) {
+      if (!hasKeysFile) rethrow;
+    }
+
+    final WalletKeysData keysData;
+    // Migrate wallet from the old scheme to then new .keys file scheme
+    if (!hasKeysFile) {
+      keysData =
+          WalletKeysData(mnemonic: snp!.mnemonic, xPub: snp.xpub, passphrase: snp.passphrase);
+    } else {
+      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+    }
+
     return BitcoinCashWallet(
-      mnemonic: snp.mnemonic!,
+      mnemonic: keysData.mnemonic!,
       password: password,
       walletInfo: walletInfo,
       unspentCoinsInfo: unspentCoinsInfo,
-      initialAddresses: snp.addresses.map((addr) {
+      initialAddresses: snp?.addresses.map((addr) {
         try {
           BitcoinCashAddress(addr.address);
           return BitcoinAddressRecord(
@@ -116,10 +135,10 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
           );
         }
       }).toList(),
-      initialBalance: snp.balance,
-      seedBytes: await Mnemonic.toSeed(snp.mnemonic!),
-      initialRegularAddressIndex: snp.regularAddressIndex,
-      initialChangeAddressIndex: snp.changeAddressIndex,
+      initialBalance: snp?.balance,
+      seedBytes: await Mnemonic.toSeed(keysData.mnemonic!),
+      initialRegularAddressIndex: snp?.regularAddressIndex,
+      initialChangeAddressIndex: snp?.changeAddressIndex,
       addressPageType: P2pkhAddressType.p2pkh,
     );
   }
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
index e6c0cad07..01ae8ace3 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
@@ -34,8 +34,10 @@ class BitcoinCashWalletService extends WalletService<BitcoinCashNewWalletCredent
         password: credentials.password!,
         walletInfo: credentials.walletInfo!,
         unspentCoinsInfo: unspentCoinsInfoSource);
+
     await wallet.save();
     await wallet.init();
+
     return wallet;
   }
 
diff --git a/cw_core/lib/wallet_keys_file.dart b/cw_core/lib/wallet_keys_file.dart
new file mode 100644
index 000000000..45539e09d
--- /dev/null
+++ b/cw_core/lib/wallet_keys_file.dart
@@ -0,0 +1,110 @@
+import 'dart:convert';
+import 'dart:developer' as dev;
+import 'dart:io';
+
+import 'package:cw_core/balance.dart';
+import 'package:cw_core/pathForWallet.dart';
+import 'package:cw_core/transaction_history.dart';
+import 'package:cw_core/transaction_info.dart';
+import 'package:cw_core/utils/file.dart';
+import 'package:cw_core/wallet_base.dart';
+import 'package:cw_core/wallet_type.dart';
+
+mixin WalletKeysFile<BalanceType extends Balance, HistoryType extends TransactionHistoryBase,
+        TransactionType extends TransactionInfo>
+    on WalletBase<BalanceType, HistoryType, TransactionType> {
+  Future<String> makePath() => pathForWallet(name: walletInfo.name, type: walletInfo.type);
+
+  // this needs to be overridden
+  WalletKeysData get walletKeysData;
+
+  Future<String> makeKeysFilePath() async => "${await makePath()}.keys";
+
+  Future<void> saveKeysFile(String password, [bool isBackup = false]) async {
+    try {
+      final rootPath = await makeKeysFilePath();
+      final path = "$rootPath${isBackup ? ".backup" : ""}";
+      dev.log("Saving .keys file '$path'");
+      await write(path: path, password: password, data: walletKeysData.toJSON());
+    } catch (_) {}
+  }
+
+  static Future<void> createKeysFile(
+      String name, WalletType type, String password, WalletKeysData walletKeysData,
+      [bool withBackup = true]) async {
+    try {
+      final rootPath = await pathForWallet(name: name, type: type);
+      final path = "$rootPath.keys";
+
+      dev.log("Saving .keys file '$path'");
+      await write(path: path, password: password, data: walletKeysData.toJSON());
+
+      if (withBackup) {
+        dev.log("Saving .keys.backup file '$path.backup'");
+        await write(path: "$path.backup", password: password, data: walletKeysData.toJSON());
+      }
+    } catch (_) {}
+  }
+
+  static Future<bool> hasKeysFile(String name, WalletType type) async {
+    try {
+      final path = await pathForWallet(name: name, type: type);
+      return File("$path.keys").existsSync() || File("$path.keys.backup").existsSync();
+    } catch (_) {
+      return false;
+    }
+  }
+
+  static Future<WalletKeysData> readKeysFile(String name, WalletType type, String password) async {
+    final path = await pathForWallet(name: name, type: type);
+
+    var readPath = "$path.keys";
+    try {
+      if (!File(readPath).existsSync()) throw Exception("No .keys file found for $name $type");
+
+      final jsonSource = await read(path: readPath, password: password);
+      final data = json.decode(jsonSource) as Map<String, dynamic>;
+      return WalletKeysData.fromJSON(data);
+    } catch (e) {
+      dev.log("Failed to read .keys file. Trying .keys.backup file...");
+
+      readPath = "$readPath.backup";
+      if (!File(readPath).existsSync())
+        throw Exception("No .keys nor a .keys.backup file found for $name $type");
+
+      final jsonSource = await read(path: readPath, password: password);
+      final data = json.decode(jsonSource) as Map<String, dynamic>;
+      final keysData = WalletKeysData.fromJSON(data);
+
+      dev.log("Restoring .keys from .keys.backup");
+      createKeysFile(name, type, password, keysData, false);
+      return keysData;
+    }
+  }
+}
+
+class WalletKeysData {
+  final String? privateKey;
+  final String? mnemonic;
+  final String? altMnemonic;
+  final String? passphrase;
+  final String? xPub;
+
+  WalletKeysData({this.privateKey, this.mnemonic, this.altMnemonic, this.passphrase, this.xPub});
+
+  String toJSON() => jsonEncode({
+        "privateKey": privateKey,
+        "mnemonic": mnemonic,
+        if (altMnemonic != null) "altMnemonic": altMnemonic,
+        if (passphrase != null) "passphrase": passphrase,
+        if (xPub != null) "xPub": xPub
+      });
+
+  static WalletKeysData fromJSON(Map<String, dynamic> json) => WalletKeysData(
+        privateKey: json["privateKey"] as String?,
+        mnemonic: json["mnemonic"] as String?,
+        altMnemonic: json["altMnemonic"] as String?,
+        passphrase: json["passphrase"] as String?,
+        xPub: json["xPub"] as String?,
+      );
+}
diff --git a/cw_ethereum/lib/ethereum_wallet.dart b/cw_ethereum/lib/ethereum_wallet.dart
index 2c58cd31d..7bcd55cf4 100644
--- a/cw_ethereum/lib/ethereum_wallet.dart
+++ b/cw_ethereum/lib/ethereum_wallet.dart
@@ -6,6 +6,7 @@ import 'package:cw_core/erc20_token.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/transaction_direction.dart';
 import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_keys_file.dart';
 import 'package:cw_ethereum/default_ethereum_erc20_tokens.dart';
 import 'package:cw_ethereum/ethereum_client.dart';
 import 'package:cw_ethereum/ethereum_transaction_history.dart';
@@ -122,19 +123,37 @@ class EthereumWallet extends EVMChainWallet {
 
   static Future<EthereumWallet> open(
       {required String name, required String password, required WalletInfo walletInfo}) async {
+    final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
     final path = await pathForWallet(name: name, type: walletInfo.type);
-    final jsonSource = await read(path: path, password: password);
-    final data = json.decode(jsonSource) as Map;
-    final mnemonic = data['mnemonic'] as String?;
-    final privateKey = data['private_key'] as String?;
-    final balance = EVMChainERC20Balance.fromJSON(data['balance'] as String) ??
+
+    Map<String, dynamic>? data;
+    try {
+      final jsonSource = await read(path: path, password: password);
+
+      data = json.decode(jsonSource) as Map<String, dynamic>;
+    } catch (e) {
+      if (!hasKeysFile) rethrow;
+    }
+
+    final balance = EVMChainERC20Balance.fromJSON(data?['balance'] as String) ??
         EVMChainERC20Balance(BigInt.zero);
 
+    final WalletKeysData keysData;
+    // Migrate wallet from the old scheme to then new .keys file scheme
+    if (!hasKeysFile) {
+      final mnemonic = data!['mnemonic'] as String?;
+      final privateKey = data['private_key'] as String?;
+
+      keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
+    } else {
+      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+    }
+
     return EthereumWallet(
       walletInfo: walletInfo,
       password: password,
-      mnemonic: mnemonic,
-      privateKey: privateKey,
+      mnemonic: keysData.mnemonic,
+      privateKey: keysData.privateKey,
       initialBalance: balance,
       client: EthereumClient(),
     );
diff --git a/cw_evm/lib/evm_chain_wallet.dart b/cw_evm/lib/evm_chain_wallet.dart
index 760c50a04..55dcea959 100644
--- a/cw_evm/lib/evm_chain_wallet.dart
+++ b/cw_evm/lib/evm_chain_wallet.dart
@@ -16,6 +16,7 @@ import 'package:cw_core/transaction_priority.dart';
 import 'package:cw_core/wallet_addresses.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_keys_file.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:cw_evm/evm_chain_client.dart';
 import 'package:cw_evm/evm_chain_exceptions.dart';
@@ -58,7 +59,7 @@ abstract class EVMChainWallet = EVMChainWalletBase with _$EVMChainWallet;
 
 abstract class EVMChainWalletBase
     extends WalletBase<EVMChainERC20Balance, EVMChainTransactionHistory, EVMChainTransactionInfo>
-    with Store {
+    with Store, WalletKeysFile {
   EVMChainWalletBase({
     required WalletInfo walletInfo,
     required EVMChainClient client,
@@ -508,6 +509,11 @@ abstract class EVMChainWalletBase
 
   @override
   Future<void> save() async {
+    if (!(await WalletKeysFile.hasKeysFile(walletInfo.name, walletInfo.type))) {
+      await saveKeysFile(_password);
+      saveKeysFile(_password, true);
+    }
+
     await walletAddresses.updateAddressesInBox();
     final path = await makePath();
     await write(path: path, password: _password, data: toJSON());
@@ -522,7 +528,8 @@ abstract class EVMChainWalletBase
       ? HEX.encode((evmChainPrivateKey as EthPrivateKey).privateKey)
       : null;
 
-  Future<String> makePath() async => pathForWallet(name: walletInfo.name, type: walletInfo.type);
+  @override
+  WalletKeysData get walletKeysData => WalletKeysData(mnemonic: _mnemonic, privateKey: privateKey);
 
   String toJSON() => json.encode({
         'mnemonic': _mnemonic,
diff --git a/cw_nano/lib/nano_wallet.dart b/cw_nano/lib/nano_wallet.dart
index 5efe3006d..55e01d10b 100644
--- a/cw_nano/lib/nano_wallet.dart
+++ b/cw_nano/lib/nano_wallet.dart
@@ -1,8 +1,12 @@
+import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
 
+import 'package:bip39/bip39.dart' as bip39;
 import 'package:cw_core/cake_hive.dart';
 import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/n2_node.dart';
+import 'package:cw_core/nano_account.dart';
 import 'package:cw_core/nano_account_info_response.dart';
 import 'package:cw_core/node.dart';
 import 'package:cw_core/pathForWallet.dart';
@@ -10,23 +14,20 @@ import 'package:cw_core/pending_transaction.dart';
 import 'package:cw_core/sync_status.dart';
 import 'package:cw_core/transaction_direction.dart';
 import 'package:cw_core/transaction_priority.dart';
+import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_keys_file.dart';
 import 'package:cw_nano/file.dart';
-import 'package:cw_core/nano_account.dart';
-import 'package:cw_core/n2_node.dart';
 import 'package:cw_nano/nano_balance.dart';
 import 'package:cw_nano/nano_client.dart';
 import 'package:cw_nano/nano_transaction_credentials.dart';
 import 'package:cw_nano/nano_transaction_history.dart';
 import 'package:cw_nano/nano_transaction_info.dart';
+import 'package:cw_nano/nano_wallet_addresses.dart';
 import 'package:cw_nano/nano_wallet_keys.dart';
 import 'package:cw_nano/pending_nano_transaction.dart';
 import 'package:mobx/mobx.dart';
-import 'dart:async';
-import 'package:cw_nano/nano_wallet_addresses.dart';
-import 'package:cw_core/wallet_base.dart';
 import 'package:nanodart/nanodart.dart';
-import 'package:bip39/bip39.dart' as bip39;
 import 'package:nanoutil/nanoutil.dart';
 
 part 'nano_wallet.g.dart';
@@ -34,7 +35,8 @@ part 'nano_wallet.g.dart';
 class NanoWallet = NanoWalletBase with _$NanoWallet;
 
 abstract class NanoWalletBase
-    extends WalletBase<NanoBalance, NanoTransactionHistory, NanoTransactionInfo> with Store {
+    extends WalletBase<NanoBalance, NanoTransactionHistory, NanoTransactionInfo>
+    with Store, WalletKeysFile {
   NanoWalletBase({
     required WalletInfo walletInfo,
     required String mnemonic,
@@ -70,6 +72,7 @@ abstract class NanoWalletBase
 
   String? _representativeAddress;
   int repScore = 100;
+
   bool get isRepOk => repScore >= 90;
 
   late final NanoClient _client;
@@ -128,14 +131,10 @@ abstract class NanoWalletBase
   }
 
   @override
-  int calculateEstimatedFee(TransactionPriority priority, int? amount) {
-    return 0; // always 0 :)
-  }
+  int calculateEstimatedFee(TransactionPriority priority, int? amount) => 0; // always 0 :)
 
   @override
-  Future<void> changePassword(String password) {
-    throw UnimplementedError("changePassword");
-  }
+  Future<void> changePassword(String password) => throw UnimplementedError("changePassword");
 
   @override
   void close() {
@@ -170,9 +169,7 @@ abstract class NanoWalletBase
   }
 
   @override
-  Future<void> connectToPowNode({required Node node}) async {
-    _client.connectPow(node);
-  }
+  Future<void> connectToPowNode({required Node node}) async => _client.connectPow(node);
 
   @override
   Future<PendingTransaction> createTransaction(Object credentials) async {
@@ -296,9 +293,7 @@ abstract class NanoWalletBase
   }
 
   @override
-  NanoWalletKeys get keys {
-    return NanoWalletKeys(seedKey: _hexSeed!);
-  }
+  NanoWalletKeys get keys => NanoWalletKeys(seedKey: _hexSeed!);
 
   @override
   String? get privateKey => _privateKey!;
@@ -312,6 +307,11 @@ abstract class NanoWalletBase
 
   @override
   Future<void> save() async {
+    if (!(await WalletKeysFile.hasKeysFile(walletInfo.name, walletInfo.type))) {
+      await saveKeysFile(_password);
+      saveKeysFile(_password, true);
+    }
+
     await walletAddresses.updateAddressesInBox();
     final path = await makePath();
     await write(path: path, password: _password, data: toJSON());
@@ -323,6 +323,9 @@ abstract class NanoWalletBase
 
   String get hexSeed => _hexSeed!;
 
+  @override
+  WalletKeysData get walletKeysData => WalletKeysData(mnemonic: _mnemonic, altMnemonic: hexSeed);
+
   String get representative => _representativeAddress ?? "";
 
   @action
@@ -358,8 +361,6 @@ abstract class NanoWalletBase
     }
   }
 
-  Future<String> makePath() async => pathForWallet(name: walletInfo.name, type: walletInfo.type);
-
   String toJSON() => json.encode({
         'seedKey': _hexSeed,
         'mnemonic': _mnemonic,
@@ -373,31 +374,47 @@ abstract class NanoWalletBase
     required String password,
     required WalletInfo walletInfo,
   }) async {
+    final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
     final path = await pathForWallet(name: name, type: walletInfo.type);
-    final jsonSource = await read(path: path, password: password);
 
-    final data = json.decode(jsonSource) as Map;
-    final mnemonic = data['mnemonic'] as String;
+    Map<String, dynamic>? data = null;
+    try {
+      final jsonSource = await read(path: path, password: password);
+
+      data = json.decode(jsonSource) as Map<String, dynamic>;
+    } catch (e) {
+      if (!hasKeysFile) rethrow;
+    }
 
     final balance = NanoBalance.fromRawString(
-      currentBalance: data['currentBalance'] as String? ?? "0",
-      receivableBalance: data['receivableBalance'] as String? ?? "0",
+      currentBalance: data?['currentBalance'] as String? ?? "0",
+      receivableBalance: data?['receivableBalance'] as String? ?? "0",
     );
 
+    final WalletKeysData keysData;
+    // Migrate wallet from the old scheme to then new .keys file scheme
+    if (!hasKeysFile) {
+      final mnemonic = data!['mnemonic'] as String;
+      final isHexSeed = !mnemonic.contains(' ');
+
+      keysData = WalletKeysData(
+          mnemonic: isHexSeed ? null : mnemonic, altMnemonic: isHexSeed ? mnemonic : null);
+    } else {
+      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+    }
+
     DerivationType derivationType = DerivationType.nano;
-    if (data['derivationType'] == "DerivationType.bip39") {
+    if (data?['derivationType'] == "DerivationType.bip39") {
       derivationType = DerivationType.bip39;
     }
 
     walletInfo.derivationInfo ??= DerivationInfo(derivationType: derivationType);
-    if (walletInfo.derivationInfo!.derivationType == null) {
-      walletInfo.derivationInfo!.derivationType = derivationType;
-    }
+    walletInfo.derivationInfo!.derivationType ??= derivationType;
 
     return NanoWallet(
       walletInfo: walletInfo,
       password: password,
-      mnemonic: mnemonic,
+      mnemonic: keysData.mnemonic!,
       initialBalance: balance,
     );
     // init() should always be run after this!
@@ -435,7 +452,7 @@ abstract class NanoWalletBase
       _representativeAddress = await _client.getRepFromPrefs();
       throw Exception("Failed to get representative address $e");
     }
-    
+
     repScore = await _client.getRepScore(_representativeAddress!);
   }
 
diff --git a/cw_nano/lib/nano_wallet_service.dart b/cw_nano/lib/nano_wallet_service.dart
index a1af3c872..755598705 100644
--- a/cw_nano/lib/nano_wallet_service.dart
+++ b/cw_nano/lib/nano_wallet_service.dart
@@ -39,7 +39,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
       mnemonic: mnemonic,
       password: credentials.password!,
     );
-    wallet.init();
+    await wallet.init();
     return wallet;
   }
 
diff --git a/cw_polygon/lib/polygon_wallet.dart b/cw_polygon/lib/polygon_wallet.dart
index 60c7ad2ff..b0b0793b9 100644
--- a/cw_polygon/lib/polygon_wallet.dart
+++ b/cw_polygon/lib/polygon_wallet.dart
@@ -1,11 +1,12 @@
 import 'dart:convert';
 
-import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/cake_hive.dart';
+import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/erc20_token.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/transaction_direction.dart';
 import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_keys_file.dart';
 import 'package:cw_evm/evm_chain_transaction_history.dart';
 import 'package:cw_evm/evm_chain_transaction_info.dart';
 import 'package:cw_evm/evm_chain_transaction_model.dart';
@@ -13,9 +14,9 @@ import 'package:cw_evm/evm_chain_wallet.dart';
 import 'package:cw_evm/evm_erc20_balance.dart';
 import 'package:cw_evm/file.dart';
 import 'package:cw_polygon/default_polygon_erc20_tokens.dart';
-import 'package:cw_polygon/polygon_transaction_info.dart';
 import 'package:cw_polygon/polygon_client.dart';
 import 'package:cw_polygon/polygon_transaction_history.dart';
+import 'package:cw_polygon/polygon_transaction_info.dart';
 
 class PolygonWallet extends EVMChainWallet {
   PolygonWallet({
@@ -97,19 +98,37 @@ class PolygonWallet extends EVMChainWallet {
 
   static Future<PolygonWallet> open(
       {required String name, required String password, required WalletInfo walletInfo}) async {
+    final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
     final path = await pathForWallet(name: name, type: walletInfo.type);
-    final jsonSource = await read(path: path, password: password);
-    final data = json.decode(jsonSource) as Map;
-    final mnemonic = data['mnemonic'] as String?;
-    final privateKey = data['private_key'] as String?;
-    final balance = EVMChainERC20Balance.fromJSON(data['balance'] as String) ??
+
+    Map<String, dynamic>? data;
+    try {
+      final jsonSource = await read(path: path, password: password);
+
+      data = json.decode(jsonSource) as Map<String, dynamic>;
+    } catch (e) {
+      if (!hasKeysFile) rethrow;
+    }
+
+    final balance = EVMChainERC20Balance.fromJSON(data?['balance'] as String) ??
         EVMChainERC20Balance(BigInt.zero);
 
+    final WalletKeysData keysData;
+    // Migrate wallet from the old scheme to then new .keys file scheme
+    if (!hasKeysFile) {
+      final mnemonic = data!['mnemonic'] as String?;
+      final privateKey = data['private_key'] as String?;
+
+      keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
+    } else {
+      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+    }
+
     return PolygonWallet(
       walletInfo: walletInfo,
       password: password,
-      mnemonic: mnemonic,
-      privateKey: privateKey,
+      mnemonic: keysData.mnemonic,
+      privateKey: keysData.privateKey,
       initialBalance: balance,
       client: PolygonClient(),
     );
diff --git a/cw_polygon/lib/polygon_wallet_service.dart b/cw_polygon/lib/polygon_wallet_service.dart
index ee84a014e..14baffc44 100644
--- a/cw_polygon/lib/polygon_wallet_service.dart
+++ b/cw_polygon/lib/polygon_wallet_service.dart
@@ -35,7 +35,6 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
     await wallet.init();
     wallet.addInitialTokens();
     await wallet.save();
-
     return wallet;
   }
 
@@ -83,7 +82,6 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
     await wallet.init();
     wallet.addInitialTokens();
     await wallet.save();
-
     return wallet;
   }
 
diff --git a/cw_solana/lib/solana_wallet.dart b/cw_solana/lib/solana_wallet.dart
index 401968698..2b30a204c 100644
--- a/cw_solana/lib/solana_wallet.dart
+++ b/cw_solana/lib/solana_wallet.dart
@@ -1,6 +1,7 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
+
 import 'package:cw_core/cake_hive.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/node.dart';
@@ -12,6 +13,7 @@ import 'package:cw_core/transaction_priority.dart';
 import 'package:cw_core/wallet_addresses.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_keys_file.dart';
 import 'package:cw_solana/default_spl_tokens.dart';
 import 'package:cw_solana/file.dart';
 import 'package:cw_solana/solana_balance.dart';
@@ -36,7 +38,8 @@ part 'solana_wallet.g.dart';
 class SolanaWallet = SolanaWalletBase with _$SolanaWallet;
 
 abstract class SolanaWalletBase
-    extends WalletBase<SolanaBalance, SolanaTransactionHistory, SolanaTransactionInfo> with Store {
+    extends WalletBase<SolanaBalance, SolanaTransactionHistory, SolanaTransactionInfo>
+    with Store, WalletKeysFile {
   SolanaWalletBase({
     required WalletInfo walletInfo,
     String? mnemonic,
@@ -121,6 +124,9 @@ abstract class SolanaWalletBase
     return privateKey;
   }
 
+  @override
+  WalletKeysData get walletKeysData => WalletKeysData(mnemonic: _mnemonic, privateKey: privateKey);
+
   Future<void> init() async {
     final boxName = "${walletInfo.name.replaceAll(" ", "_")}_${SPLToken.boxName}";
 
@@ -336,6 +342,11 @@ abstract class SolanaWalletBase
 
   @override
   Future<void> save() async {
+    if (!(await WalletKeysFile.hasKeysFile(walletInfo.name, walletInfo.type))) {
+      await saveKeysFile(_password);
+      saveKeysFile(_password, true);
+    }
+
     await walletAddresses.updateAddressesInBox();
     final path = await makePath();
     await write(path: path, password: _password, data: toJSON());
@@ -361,8 +372,6 @@ abstract class SolanaWalletBase
     }
   }
 
-  Future<String> makePath() async => pathForWallet(name: walletInfo.name, type: walletInfo.type);
-
   String toJSON() => json.encode({
         'mnemonic': _mnemonic,
         'private_key': _hexPrivateKey,
@@ -374,18 +383,36 @@ abstract class SolanaWalletBase
     required String password,
     required WalletInfo walletInfo,
   }) async {
+    final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
     final path = await pathForWallet(name: name, type: walletInfo.type);
-    final jsonSource = await read(path: path, password: password);
-    final data = json.decode(jsonSource) as Map;
-    final mnemonic = data['mnemonic'] as String?;
-    final privateKey = data['private_key'] as String?;
-    final balance = SolanaBalance.fromJSON(data['balance'] as String) ?? SolanaBalance(0.0);
+
+    Map<String, dynamic>? data;
+    try {
+      final jsonSource = await read(path: path, password: password);
+
+      data = json.decode(jsonSource) as Map<String, dynamic>;
+    } catch (e) {
+      if (!hasKeysFile) rethrow;
+    }
+
+    final balance = SolanaBalance.fromJSON(data?['balance'] as String) ?? SolanaBalance(0.0);
+
+    final WalletKeysData keysData;
+    // Migrate wallet from the old scheme to then new .keys file scheme
+    if (!hasKeysFile) {
+      final mnemonic = data!['mnemonic'] as String?;
+      final privateKey = data['private_key'] as String?;
+
+      keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
+    } else {
+      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+    }
 
     return SolanaWallet(
       walletInfo: walletInfo,
       password: password,
-      mnemonic: mnemonic,
-      privateKey: privateKey,
+      mnemonic: keysData.mnemonic,
+      privateKey: keysData.privateKey,
       initialBalance: balance,
     );
   }
diff --git a/cw_tron/lib/tron_wallet.dart b/cw_tron/lib/tron_wallet.dart
index 96f92e450..cb4c9c024 100644
--- a/cw_tron/lib/tron_wallet.dart
+++ b/cw_tron/lib/tron_wallet.dart
@@ -16,6 +16,7 @@ import 'package:cw_core/transaction_priority.dart';
 import 'package:cw_core/wallet_addresses.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_keys_file.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:cw_tron/default_tron_tokens.dart';
 import 'package:cw_tron/file.dart';
@@ -37,7 +38,8 @@ part 'tron_wallet.g.dart';
 class TronWallet = TronWalletBase with _$TronWallet;
 
 abstract class TronWalletBase
-    extends WalletBase<TronBalance, TronTransactionHistory, TronTransactionInfo> with Store {
+    extends WalletBase<TronBalance, TronTransactionHistory, TronTransactionInfo>
+    with Store, WalletKeysFile {
   TronWalletBase({
     required WalletInfo walletInfo,
     String? mnemonic,
@@ -124,18 +126,36 @@ abstract class TronWalletBase
     required String password,
     required WalletInfo walletInfo,
   }) async {
+    final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
     final path = await pathForWallet(name: name, type: walletInfo.type);
-    final jsonSource = await read(path: path, password: password);
-    final data = json.decode(jsonSource) as Map;
-    final mnemonic = data['mnemonic'] as String?;
-    final privateKey = data['private_key'] as String?;
-    final balance = TronBalance.fromJSON(data['balance'] as String) ?? TronBalance(BigInt.zero);
+
+    Map<String, dynamic>? data;
+    try {
+      final jsonSource = await read(path: path, password: password);
+
+      data = json.decode(jsonSource) as Map<String, dynamic>;
+    } catch (e) {
+      if (!hasKeysFile) rethrow;
+    }
+
+    final balance = TronBalance.fromJSON(data?['balance'] as String) ?? TronBalance(BigInt.zero);
+
+    final WalletKeysData keysData;
+    // Migrate wallet from the old scheme to then new .keys file scheme
+    if (!hasKeysFile) {
+      final mnemonic = data!['mnemonic'] as String?;
+      final privateKey = data['private_key'] as String?;
+
+      keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
+    } else {
+      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+    }
 
     return TronWallet(
       walletInfo: walletInfo,
       password: password,
-      mnemonic: mnemonic,
-      privateKey: privateKey,
+      mnemonic: keysData.mnemonic,
+      privateKey: keysData.privateKey,
       initialBalance: balance,
     );
   }
@@ -163,9 +183,7 @@ abstract class TronWalletBase
   }) async {
     assert(mnemonic != null || privateKey != null);
 
-    if (privateKey != null) {
-      return TronPrivateKey(privateKey);
-    }
+    if (privateKey != null) return TronPrivateKey(privateKey);
 
     final seed = bip39.mnemonicToSeed(mnemonic!);
 
@@ -181,14 +199,10 @@ abstract class TronWalletBase
   int calculateEstimatedFee(TransactionPriority priority, int? amount) => 0;
 
   @override
-  Future<void> changePassword(String password) {
-    throw UnimplementedError("changePassword");
-  }
+  Future<void> changePassword(String password) => throw UnimplementedError("changePassword");
 
   @override
-  void close() {
-    _transactionsUpdateTimer?.cancel();
-  }
+  void close() => _transactionsUpdateTimer?.cancel();
 
   @action
   @override
@@ -406,12 +420,15 @@ abstract class TronWalletBase
   Object get keys => throw UnimplementedError("keys");
 
   @override
-  Future<void> rescan({required int height}) {
-    throw UnimplementedError("rescan");
-  }
+  Future<void> rescan({required int height}) => throw UnimplementedError("rescan");
 
   @override
   Future<void> save() async {
+    if (!(await WalletKeysFile.hasKeysFile(walletInfo.name, walletInfo.type))) {
+      await saveKeysFile(_password);
+      saveKeysFile(_password, true);
+    }
+
     await walletAddresses.updateAddressesInBox();
     final path = await makePath();
     await write(path: path, password: _password, data: toJSON());
@@ -424,7 +441,8 @@ abstract class TronWalletBase
   @override
   String get privateKey => _tronPrivateKey.toHex();
 
-  Future<String> makePath() async => pathForWallet(name: walletInfo.name, type: walletInfo.type);
+  @override
+  WalletKeysData get walletKeysData => WalletKeysData(mnemonic: _mnemonic, privateKey: privateKey);
 
   String toJSON() => json.encode({
         'mnemonic': _mnemonic,
@@ -512,7 +530,7 @@ abstract class TronWalletBase
 
   @override
   Future<void> renameWalletFiles(String newWalletName) async {
-    String transactionHistoryFileNameForWallet = 'tron_transactions.json';
+    const transactionHistoryFileNameForWallet = 'tron_transactions.json';
 
     final currentWalletPath = await pathForWallet(name: walletInfo.name, type: type);
     final currentWalletFile = File(currentWalletPath);
@@ -550,9 +568,7 @@ abstract class TronWalletBase
   Future<String> signMessage(String message, {String? address}) async =>
       _tronPrivateKey.signPersonalMessage(ascii.encode(message));
 
-  String getTronBase58AddressFromHex(String hexAddress) {
-    return TronAddress(hexAddress).toAddress();
-  }
+  String getTronBase58AddressFromHex(String hexAddress) => TronAddress(hexAddress).toAddress();
 
   void updateScanProviderUsageState(bool isEnabled) {
     if (isEnabled) {
diff --git a/cw_tron/lib/tron_wallet_service.dart b/cw_tron/lib/tron_wallet_service.dart
index c8344d5f4..ba217a265 100644
--- a/cw_tron/lib/tron_wallet_service.dart
+++ b/cw_tron/lib/tron_wallet_service.dart
@@ -1,6 +1,7 @@
 import 'dart:io';
 
 import 'package:bip39/bip39.dart' as bip39;
+import 'package:collection/collection.dart';
 import 'package:cw_core/balance.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/transaction_history.dart';
@@ -14,7 +15,6 @@ import 'package:cw_tron/tron_exception.dart';
 import 'package:cw_tron/tron_wallet.dart';
 import 'package:cw_tron/tron_wallet_creation_credentials.dart';
 import 'package:hive/hive.dart';
-import 'package:collection/collection.dart';
 
 class TronWalletService extends WalletService<
     TronNewWalletCredentials,
@@ -153,7 +153,8 @@ class TronWalletService extends WalletService<
   }
 
   @override
-  Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>> restoreFromHardwareWallet(TronNewWalletCredentials credentials) {
+  Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>>
+      restoreFromHardwareWallet(TronNewWalletCredentials credentials) {
     // TODO: implement restoreFromHardwareWallet
     throw UnimplementedError();
   }

From 14e99daa7398791cff5dbb9134e66f86f2142043 Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Sat, 10 Aug 2024 00:48:36 +0300
Subject: [PATCH 14/81] align the hint with the prefix in the text field
 (#1571)

* Update send_card.dart

* update currency amount text field widget

* Update qr_widget.dart
---
 lib/src/screens/exchange/exchange_page.dart   |  39 +--
 .../exchange/widgets/exchange_card.dart       | 131 +-------
 .../receive/widgets/currency_input_field.dart | 301 +++++++++++-------
 .../screens/receive/widgets/qr_widget.dart    |  44 ++-
 lib/src/screens/send/send_template_page.dart  |   2 +-
 .../widgets/prefix_currency_icon_widget.dart  |  65 ----
 lib/src/screens/send/widgets/send_card.dart   | 228 ++-----------
 .../send/widgets/send_template_card.dart      | 183 +++++------
 .../send/send_template_view_model.dart        |   5 +
 lib/view_model/send/template_view_model.dart  |  23 +-
 10 files changed, 371 insertions(+), 650 deletions(-)
 delete mode 100644 lib/src/screens/send/widgets/prefix_currency_icon_widget.dart

diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart
index 5c064df27..2c717a3c8 100644
--- a/lib/src/screens/exchange/exchange_page.dart
+++ b/lib/src/screens/exchange/exchange_page.dart
@@ -67,17 +67,6 @@ class ExchangePage extends BasePage {
   Debounce _depositAmountDebounce = Debounce(Duration(milliseconds: 500));
   var _isReactionsSet = false;
 
-  final arrowBottomPurple = Image.asset(
-    'assets/images/arrow_bottom_purple_icon.png',
-    color: Colors.white,
-    height: 8,
-  );
-  final arrowBottomCakeGreen = Image.asset(
-    'assets/images/arrow_bottom_cake_green.png',
-    color: Colors.white,
-    height: 8,
-  );
-
   late final String? depositWalletName;
   late final String? receiveWalletName;
 
@@ -101,11 +90,11 @@ class ExchangePage extends BasePage {
 
   @override
   Function(BuildContext)? get pushToNextWidget => (context) {
-    FocusScopeNode currentFocus = FocusScope.of(context);
-    if (!currentFocus.hasPrimaryFocus) {
-      currentFocus.focusedChild?.unfocus();
-    }
-  };
+        FocusScopeNode currentFocus = FocusScope.of(context);
+        if (!currentFocus.hasPrimaryFocus) {
+          currentFocus.focusedChild?.unfocus();
+        }
+      };
 
   @override
   Widget middle(BuildContext context) => Row(
@@ -340,7 +329,6 @@ class ExchangePage extends BasePage {
 
   void applyTemplate(
       BuildContext context, ExchangeViewModel exchangeViewModel, ExchangeTemplate template) async {
-
     final depositCryptoCurrency = CryptoCurrency.fromString(template.depositCurrency);
     final receiveCryptoCurrency = CryptoCurrency.fromString(template.receiveCurrency);
 
@@ -354,10 +342,12 @@ class ExchangePage extends BasePage {
     exchangeViewModel.isFixedRateMode = false;
 
     var domain = template.depositAddress;
-    exchangeViewModel.depositAddress = await fetchParsedAddress(context, domain, depositCryptoCurrency);
+    exchangeViewModel.depositAddress =
+        await fetchParsedAddress(context, domain, depositCryptoCurrency);
 
     domain = template.receiveAddress;
-    exchangeViewModel.receiveAddress = await fetchParsedAddress(context, domain, receiveCryptoCurrency);
+    exchangeViewModel.receiveAddress =
+        await fetchParsedAddress(context, domain, receiveCryptoCurrency);
   }
 
   void _setReactions(BuildContext context, ExchangeViewModel exchangeViewModel) {
@@ -529,14 +519,16 @@ class ExchangePage extends BasePage {
     _depositAddressFocus.addListener(() async {
       if (!_depositAddressFocus.hasFocus && depositAddressController.text.isNotEmpty) {
         final domain = depositAddressController.text;
-        exchangeViewModel.depositAddress = await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency);
+        exchangeViewModel.depositAddress =
+            await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency);
       }
     });
 
     _receiveAddressFocus.addListener(() async {
       if (!_receiveAddressFocus.hasFocus && receiveAddressController.text.isNotEmpty) {
         final domain = receiveAddressController.text;
-        exchangeViewModel.receiveAddress = await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency);
+        exchangeViewModel.receiveAddress =
+            await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency);
       }
     });
 
@@ -589,7 +581,8 @@ class ExchangePage extends BasePage {
     }
   }
 
-  Future<String> fetchParsedAddress(BuildContext context, String domain, CryptoCurrency currency) async {
+  Future<String> fetchParsedAddress(
+      BuildContext context, String domain, CryptoCurrency currency) async {
     final parsedAddress = await getIt.get<AddressResolver>().resolve(context, domain, currency);
     final address = await extractAddressFromParsed(context, parsedAddress);
     return address;
@@ -658,7 +651,6 @@ class ExchangePage extends BasePage {
 
                 exchangeViewModel.changeDepositCurrency(currency: currency);
               },
-              imageArrow: arrowBottomPurple,
               currencyButtonColor: Colors.transparent,
               addressButtonsColor:
                   Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
@@ -705,7 +697,6 @@ class ExchangePage extends BasePage {
               currencies: exchangeViewModel.receiveCurrencies,
               onCurrencySelected: (currency) =>
                   exchangeViewModel.changeReceiveCurrency(currency: currency),
-              imageArrow: arrowBottomCakeGreen,
               currencyButtonColor: Colors.transparent,
               addressButtonsColor:
                   Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
diff --git a/lib/src/screens/exchange/widgets/exchange_card.dart b/lib/src/screens/exchange/widgets/exchange_card.dart
index 760b0c137..02218f848 100644
--- a/lib/src/screens/exchange/widgets/exchange_card.dart
+++ b/lib/src/screens/exchange/widgets/exchange_card.dart
@@ -1,5 +1,6 @@
 import 'package:cake_wallet/core/amount_validator.dart';
 import 'package:cake_wallet/entities/contact_base.dart';
+import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart';
 import 'package:cake_wallet/themes/extensions/qr_code_theme.dart';
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
@@ -27,7 +28,7 @@ class ExchangeCard extends StatefulWidget {
       required this.isAmountEstimated,
       required this.currencies,
       required this.onCurrencySelected,
-      required this.imageArrow,
+      this.imageArrow,
       this.currencyValueValidator,
       this.addressTextFieldValidator,
       this.title = '',
@@ -58,7 +59,7 @@ class ExchangeCard extends StatefulWidget {
   final bool isAmountEstimated;
   final bool hasRefundAddress;
   final bool isMoneroWallet;
-  final Image imageArrow;
+  final Image? imageArrow;
   final Color currencyButtonColor;
   final Color? addressButtonsColor;
   final Color borderColor;
@@ -191,120 +192,18 @@ class ExchangeCardState extends State<ExchangeCard> {
             )
           ],
         ),
-        Padding(
-            padding: EdgeInsets.only(top: 20),
-            child: Row(
-              children: [
-                Container(
-                  padding: EdgeInsets.only(right: 8),
-                  height: 32,
-                  color: widget.currencyButtonColor,
-                  child: InkWell(
-                    onTap: () => _presentPicker(context),
-                    child: Row(
-                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                        mainAxisSize: MainAxisSize.min,
-                        children: <Widget>[
-                          Padding(
-                            padding: EdgeInsets.only(right: 5),
-                            child: widget.imageArrow,
-                          ),
-                          Text(_selectedCurrency.toString(),
-                              style: TextStyle(
-                                  fontWeight: FontWeight.w600, fontSize: 16, color: Colors.white))
-                        ]),
-                  ),
-                ),
-                if (_selectedCurrency.tag != null)
-                  Padding(
-                    padding: const EdgeInsets.only(right: 3.0),
-                    child: Container(
-                      height: 32,
-                      decoration: BoxDecoration(
-                          color: widget.addressButtonsColor ??
-                              Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
-                          borderRadius: BorderRadius.all(Radius.circular(6))),
-                      child: Center(
-                        child: Padding(
-                          padding: const EdgeInsets.all(6.0),
-                          child: Text(_selectedCurrency.tag!,
-                              style: TextStyle(
-                                  fontSize: 12,
-                                  fontWeight: FontWeight.bold,
-                                  color: Theme.of(context)
-                                      .extension<SendPageTheme>()!
-                                      .textFieldButtonIconColor)),
-                        ),
-                      ),
-                    ),
-                  ),
-                Padding(
-                  padding: const EdgeInsets.only(right: 4.0),
-                  child: Text(':',
-                      style: TextStyle(
-                          fontWeight: FontWeight.w600, fontSize: 16, color: Colors.white)),
-                ),
-                Expanded(
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Flexible(
-                        child: FocusTraversalOrder(
-                          order: NumericFocusOrder(1),
-                          child: BaseTextFormField(
-                              focusNode: widget.amountFocusNode,
-                              controller: amountController,
-                              enabled: _isAmountEditable,
-                              textAlign: TextAlign.left,
-                              keyboardType:
-                                  TextInputType.numberWithOptions(signed: false, decimal: true),
-                              inputFormatters: [
-                                FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]'))
-                              ],
-                              hintText: '0.0000',
-                              borderColor: Colors.transparent,
-                              //widget.borderColor,
-                              textStyle: TextStyle(
-                                  fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
-                              placeholderTextStyle: TextStyle(
-                                  fontSize: 16,
-                                  fontWeight: FontWeight.w600,
-                                  color: Theme.of(context)
-                                      .extension<ExchangePageTheme>()!
-                                      .hintTextColor),
-                              validator: _isAmountEditable
-                                      ? widget.currencyValueValidator
-                                      : null),
-                        ),
-                      ),
-                      if (widget.hasAllAmount)
-                        Container(
-                          height: 32,
-                          width: 32,
-                          decoration: BoxDecoration(
-                              color: Theme.of(context)
-                                  .extension<SendPageTheme>()!
-                                  .textFieldButtonColor,
-                              borderRadius: BorderRadius.all(Radius.circular(6))),
-                          child: InkWell(
-                            onTap: () => widget.allAmount?.call(),
-                            child: Center(
-                              child: Text(S.of(context).all,
-                                  textAlign: TextAlign.center,
-                                  style: TextStyle(
-                                      fontSize: 12,
-                                      fontWeight: FontWeight.bold,
-                                      color: Theme.of(context)
-                                          .extension<SendPageTheme>()!
-                                          .textFieldButtonIconColor)),
-                            ),
-                          ),
-                        )
-                    ],
-                  ),
-                ),
-              ],
-            )),
+        CurrencyAmountTextField(
+            imageArrow: widget.imageArrow,
+            selectedCurrency: _selectedCurrency.toString(),
+            amountFocusNode: widget.amountFocusNode,
+            amountController: amountController,
+            onTapPicker: () => _presentPicker(context),
+            isAmountEditable: _isAmountEditable,
+            isPickerEnable: true,
+            allAmountButton: widget.hasAllAmount,
+            currencyValueValidator: widget.currencyValueValidator,
+            tag: _selectedCurrency.tag,
+            allAmountCallback: widget.allAmount),
         Divider(height: 1, color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
         Padding(
           padding: EdgeInsets.only(top: 5),
diff --git a/lib/src/screens/receive/widgets/currency_input_field.dart b/lib/src/screens/receive/widgets/currency_input_field.dart
index 84b2a7bca..ce3de9a6c 100644
--- a/lib/src/screens/receive/widgets/currency_input_field.dart
+++ b/lib/src/screens/receive/widgets/currency_input_field.dart
@@ -1,135 +1,210 @@
+import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
-import 'package:cake_wallet/utils/responsive_layout_util.dart';
-import 'package:cw_core/crypto_currency.dart';
-import 'package:cw_core/currency.dart';
+import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
+import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
+import 'package:cake_wallet/themes/theme_base.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
-import 'package:cake_wallet/themes/extensions/picker_theme.dart';
-import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
 
-class CurrencyInputField extends StatelessWidget {
-  const CurrencyInputField({
-    super.key,
-    required this.onTapPicker,
+class CurrencyAmountTextField extends StatelessWidget {
+  const CurrencyAmountTextField({
     required this.selectedCurrency,
-    this.focusNode,
-    required this.controller,
-    required this.isLight,
+    required this.amountFocusNode,
+    required this.amountController,
+    required this.isAmountEditable,
+    this.allAmountButton = false,
+    this.isPickerEnable = false,
+    this.isSelected = false,
+    this.currentTheme = ThemeType.dark,
+    this.onTapPicker,
+    this.padding,
+    this.imageArrow,
+    this.hintText,
+    this.tag,
+    this.tagBackgroundColor,
+    this.currencyValueValidator,
+    this.allAmountCallback,
   });
 
-  final Function() onTapPicker;
-  final Currency selectedCurrency;
-  final FocusNode? focusNode;
-  final TextEditingController controller;
-  final bool isLight;
-
-  String get _currencyName {
-    if (selectedCurrency is CryptoCurrency) {
-      return (selectedCurrency as CryptoCurrency).title.toUpperCase();
-    }
-    return selectedCurrency.name.toUpperCase();
-  }
+  final Widget? imageArrow;
+  final String selectedCurrency;
+  final String? tag;
+  final String? hintText;
+  final Color? tagBackgroundColor;
+  final EdgeInsets? padding;
+  final FocusNode? amountFocusNode;
+  final TextEditingController amountController;
+  final bool isAmountEditable;
+  final FormFieldValidator<String>? currencyValueValidator;
+  final bool isPickerEnable;
+  final ThemeType currentTheme;
+  final bool isSelected;
+  final bool allAmountButton;
+  final VoidCallback? allAmountCallback;
+  final VoidCallback? onTapPicker;
 
   @override
   Widget build(BuildContext context) {
-    final arrowBottomPurple = Image.asset(
-      'assets/images/arrow_bottom_purple_icon.png',
-      color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
-      height: 8,
-    );
-    // This magic number for wider screen sets the text input focus at center of the inputfield
-    final _width =
-        responsiveLayoutUtil.shouldRenderMobileUI ? MediaQuery.of(context).size.width : 500;
-
-    return Column(
+    final textColor = currentTheme == ThemeType.light
+        ? Theme.of(context).appBarTheme.titleTextStyle!.color!
+        : Colors.white;
+    final _prefixContent = Row(
       children: [
-        Padding(
-          padding: EdgeInsets.only(top: 20),
-          child: SizedBox(
-            height: 40,
-            child: BaseTextFormField(
-              focusNode: focusNode,
-              controller: controller,
-              keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
-              inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d+(\.|\,)?\d{0,8}'))],
-              hintText: '0.000',
-              placeholderTextStyle: isLight
-                  ? null
-                  : TextStyle(
-                      color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
-                      fontWeight: FontWeight.w600,
-                    ),
-              borderColor: Theme.of(context).extension<PickerTheme>()!.dividerColor,
-              textColor: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
-              textStyle: TextStyle(
-                color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
-              ),
-              prefixIcon: Padding(
-                padding: EdgeInsets.only(
-                  left: _width / 4,
+        isPickerEnable
+            ? Container(
+                height: 32,
+                child: InkWell(
+                  onTap: onTapPicker,
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    mainAxisSize: MainAxisSize.min,
+                    children: <Widget>[
+                      Padding(
+                          padding: const EdgeInsets.only(right: 5),
+                          child: imageArrow ??
+                              Image.asset('assets/images/arrow_bottom_purple_icon.png',
+                                  color: textColor, height: 8)),
+                      Text(
+                        selectedCurrency,
+                        style: TextStyle(
+                          fontWeight: FontWeight.w600,
+                          fontSize: 16,
+                          color: textColor,
+                        ),
+                      ),
+                    ],
+                  ),
                 ),
-                child: Container(
-                  padding: EdgeInsets.only(right: 8),
-                  child: InkWell(
-                    onTap: onTapPicker,
-                    child: Row(
-                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                        mainAxisSize: MainAxisSize.min,
-                        children: <Widget>[
-                          Padding(
-                            padding: EdgeInsets.only(right: 5),
-                            child: arrowBottomPurple,
-                          ),
-                          Text(
-                            _currencyName,
-                            style: TextStyle(
-                              fontWeight: FontWeight.w600,
-                              fontSize: 16,
-                              color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
-                            ),
-                          ),
-                          if (selectedCurrency.tag != null)
-                            Padding(
-                              padding: const EdgeInsets.symmetric(horizontal: 3.0),
-                              child: Container(
-                                decoration: BoxDecoration(
-                                  color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
-                                  borderRadius: BorderRadius.all(
-                                    Radius.circular(6),
-                                  ),
-                                ),
-                                child: Center(
-                                  child: Text(
-                                    selectedCurrency.tag!,
-                                    style: TextStyle(
-                                      fontSize: 12,
-                                      fontWeight: FontWeight.bold,
-                                      color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor,
-                                    ),
-                                  ),
-                                ),
-                              ),
-                            ),
-                          Padding(
-                            padding: const EdgeInsets.only(bottom: 3.0),
-                            child: Text(
-                              ':',
-                              style: TextStyle(
-                                fontWeight: FontWeight.w600,
-                                fontSize: 20,
-                                color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
-                              ),
-                            ),
-                          ),
-                        ]),
+              )
+            : Text(
+                selectedCurrency,
+                style: TextStyle(
+                  fontWeight: FontWeight.w600,
+                  fontSize: 16,
+                  color: textColor,
+                ),
+              ),
+        if (tag != null)
+          Padding(
+            padding: const EdgeInsets.symmetric(horizontal: 3.0),
+            child: Container(
+              height: 32,
+              decoration: BoxDecoration(
+                color: tagBackgroundColor ??
+                    Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
+                borderRadius: const BorderRadius.all(Radius.circular(6)),
+              ),
+              child: Center(
+                child: Padding(
+                  padding: const EdgeInsets.all(6.0),
+                  child: Text(
+                    tag!,
+                    style: TextStyle(
+                      fontSize: 12,
+                      fontWeight: FontWeight.bold,
+                      color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor,
+                    ),
                   ),
                 ),
               ),
             ),
           ),
+        Padding(
+          padding: EdgeInsets.only(right: 4.0),
+          child: Text(
+            ':',
+            style: TextStyle(
+              fontWeight: FontWeight.w600,
+              fontSize: 16,
+              color: textColor,
+            ),
+          ),
         ),
       ],
     );
+    return Padding(
+      padding: padding ?? const EdgeInsets.only(top: 20),
+      child: Row(
+        children: [
+          isSelected
+              ? Container(
+                  child: _prefixContent,
+                  padding: EdgeInsets.symmetric(vertical: 4, horizontal: 8),
+                  margin: const EdgeInsets.only(right: 3),
+                  decoration: BoxDecoration(
+                    border: Border.all(
+                      color: textColor,
+                    ),
+                      borderRadius: BorderRadius.circular(26),
+                      color: Theme.of(context).primaryColor))
+              : _prefixContent,
+          Expanded(
+            child: Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Flexible(
+                  child: FocusTraversalOrder(
+                    order: NumericFocusOrder(1),
+                    child: BaseTextFormField(
+                      focusNode: amountFocusNode,
+                      controller: amountController,
+                      enabled: isAmountEditable,
+                      textAlign: TextAlign.left,
+                      keyboardType: const TextInputType.numberWithOptions(
+                        signed: false,
+                        decimal: true,
+                      ),
+                      inputFormatters: [
+                        FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]')),
+                      ],
+                      hintText: hintText ?? '0.0000',
+                      borderColor: Colors.transparent,
+                      textStyle: TextStyle(
+                        fontSize: 16,
+                        fontWeight: FontWeight.w600,
+                        color: textColor,
+                      ),
+                      placeholderTextStyle: TextStyle(
+                        fontSize: 16,
+                        fontWeight: FontWeight.w600,
+                        color: currentTheme == ThemeType.light
+                            ? Theme.of(context).appBarTheme.titleTextStyle!.color!
+                            : Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor,
+                      ),
+                      validator: isAmountEditable ? currencyValueValidator : null,
+                    ),
+                  ),
+                ),
+                if (allAmountButton)
+                  Container(
+                    height: 32,
+                    width: 32,
+                    decoration: BoxDecoration(
+                      color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
+                      borderRadius: const BorderRadius.all(Radius.circular(6)),
+                    ),
+                    child: InkWell(
+                      onTap: allAmountCallback,
+                      child: Center(
+                        child: Text(
+                          S.of(context).all,
+                          textAlign: TextAlign.center,
+                          style: TextStyle(
+                            fontSize: 12,
+                            fontWeight: FontWeight.bold,
+                            color: Theme.of(context)
+                                .extension<SendPageTheme>()!
+                                .textFieldButtonIconColor,
+                          ),
+                        ),
+                      ),
+                    ),
+                  ),
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
   }
 }
diff --git a/lib/src/screens/receive/widgets/qr_widget.dart b/lib/src/screens/receive/widgets/qr_widget.dart
index bbfd4d5c1..9f0db059a 100644
--- a/lib/src/screens/receive/widgets/qr_widget.dart
+++ b/lib/src/screens/receive/widgets/qr_widget.dart
@@ -1,11 +1,15 @@
 import 'package:cake_wallet/entities/qr_view_data.dart';
+import 'package:cake_wallet/themes/extensions/picker_theme.dart';
 import 'package:cake_wallet/themes/extensions/qr_code_theme.dart';
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
 import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart';
+import 'package:cake_wallet/themes/theme_base.dart';
 import 'package:cake_wallet/utils/brightness_util.dart';
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
 import 'package:cake_wallet/utils/show_bar.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cw_core/crypto_currency.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
@@ -38,6 +42,10 @@ class QRWidget extends StatelessWidget {
     final copyImage = Image.asset('assets/images/copy_address.png',
         color: Theme.of(context).extension<QRCodeTheme>()!.qrWidgetCopyButtonColor);
 
+    // This magic number for wider screen sets the text input focus at center of the inputfield
+    final _width =
+        responsiveLayoutUtil.shouldRenderMobileUI ? MediaQuery.of(context).size.width : 500;
+
     return Center(
       child: SingleChildScrollView(
         child: Column(
@@ -85,8 +93,9 @@ class QRWidget extends StatelessWidget {
                                   decoration: BoxDecoration(
                                     border: Border.all(
                                       width: 3,
-                                      color:
-                                          Theme.of(context).extension<DashboardPageTheme>()!.textColor,
+                                      color: Theme.of(context)
+                                          .extension<DashboardPageTheme>()!
+                                          .textColor,
                                     ),
                                   ),
                                   child: Container(
@@ -116,20 +125,23 @@ class QRWidget extends StatelessWidget {
                   children: <Widget>[
                     Expanded(
                       child: Form(
-                        key: formKey,
-                        child: CurrencyInputField(
-                          focusNode: amountTextFieldFocusNode,
-                          controller: amountController,
-                          onTapPicker: () => _presentPicker(context),
-                          selectedCurrency: addressListViewModel.selectedCurrency,
-                          isLight: isLight,
-                        ),
-                      ),
+                          key: formKey,
+                          child: CurrencyAmountTextField(
+                              selectedCurrency: _currencyName,
+                              amountFocusNode: amountTextFieldFocusNode,
+                              amountController: amountController,
+                              padding: EdgeInsets.only(top: 20, left: _width / 4),
+                              currentTheme: isLight ? ThemeType.light : ThemeType.dark,
+                              isAmountEditable: true,
+                              tag: addressListViewModel.selectedCurrency.tag,
+                              onTapPicker: () => _presentPicker(context),
+                              isPickerEnable: true)),
                     ),
                   ],
                 ),
               );
             }),
+            Divider(height: 1, color: Theme.of(context).extension<PickerTheme>()!.dividerColor),
             Padding(
               padding: EdgeInsets.only(top: 20, bottom: 8),
               child: Builder(
@@ -150,7 +162,8 @@ class QRWidget extends StatelessWidget {
                             style: TextStyle(
                                 fontSize: 15,
                                 fontWeight: FontWeight.w500,
-                                color: Theme.of(context).extension<DashboardPageTheme>()!.textColor),
+                                color:
+                                    Theme.of(context).extension<DashboardPageTheme>()!.textColor),
                           ),
                         ),
                         Padding(
@@ -169,6 +182,13 @@ class QRWidget extends StatelessWidget {
     );
   }
 
+  String get _currencyName {
+    if (addressListViewModel.selectedCurrency is CryptoCurrency) {
+      return (addressListViewModel.selectedCurrency as CryptoCurrency).title.toUpperCase();
+    }
+    return addressListViewModel.selectedCurrency.name.toUpperCase();
+  }
+
   void _presentPicker(BuildContext context) async {
     await showPopUp<void>(
       builder: (_) => CurrencyPicker(
diff --git a/lib/src/screens/send/send_template_page.dart b/lib/src/screens/send/send_template_page.dart
index 76414ecb2..f7c9da082 100644
--- a/lib/src/screens/send/send_template_page.dart
+++ b/lib/src/screens/send/send_template_page.dart
@@ -144,7 +144,7 @@ class SendTemplatePage extends BasePage {
                           .toList();
 
                       sendTemplateViewModel.addTemplate(
-                          isCurrencySelected: mainTemplate.isCurrencySelected,
+                          isCurrencySelected: mainTemplate.isCryptoSelected,
                           name: mainTemplate.name,
                           address: mainTemplate.address,
                           cryptoCurrency: mainTemplate.selectedCurrency.title,
diff --git a/lib/src/screens/send/widgets/prefix_currency_icon_widget.dart b/lib/src/screens/send/widgets/prefix_currency_icon_widget.dart
deleted file mode 100644
index d30349066..000000000
--- a/lib/src/screens/send/widgets/prefix_currency_icon_widget.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
-import 'package:flutter/material.dart';
-
-class PrefixCurrencyIcon extends StatelessWidget {
-  PrefixCurrencyIcon({
-    required this.isSelected,
-    required this.title,
-    this.onTap,
-  });
-
-  final bool isSelected;
-  final String title;
-  final Function()? onTap;
-
-  @override
-  Widget build(BuildContext context) {
-    return GestureDetector(
-      onTap: onTap,
-      child: Padding(
-        padding: EdgeInsets.fromLTRB(0, 6.0, 8.0, 0),
-        child: Column(
-          children: [
-            Container(
-              padding: EdgeInsets.symmetric(vertical: 4, horizontal: 8),
-              decoration: BoxDecoration(
-                borderRadius: BorderRadius.circular(26),
-                color: isSelected
-                    ? Theme.of(context)
-                        .extension<SendPageTheme>()!
-                        .templateSelectedCurrencyBackgroundColor
-                    : Colors.transparent,
-              ),
-              child: Row(
-                mainAxisSize: MainAxisSize.min,
-                children: <Widget>[
-                  if (onTap != null)
-                    Padding(
-                      padding: EdgeInsets.only(right: 5),
-                      child: Image.asset(
-                        'assets/images/arrow_bottom_purple_icon.png',
-                        color: Colors.white,
-                        height: 8,
-                      ),
-                    ),
-                  Text(
-                    title + ':',
-                    style: TextStyle(
-                      fontSize: 16,
-                      fontWeight: FontWeight.w600,
-                      color: isSelected
-                          ? Theme.of(context)
-                              .extension<SendPageTheme>()!
-                              .templateSelectedCurrencyTitleColor
-                          : Colors.white,
-                    ),
-                  ),
-                ],
-              ),
-            ),
-          ],
-        ),
-      ),
-    );
-  }
-}
diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart
index ec833159f..e2e7f25da 100644
--- a/lib/src/screens/send/widgets/send_card.dart
+++ b/lib/src/screens/send/widgets/send_card.dart
@@ -1,4 +1,5 @@
 import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
+import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart';
 import 'package:cake_wallet/src/widgets/picker.dart';
 import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
 import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
@@ -207,166 +208,19 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
                               textStyle: TextStyle(
                                   fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
                               validator: sendViewModel.addressValidator)),
-                    Observer(
-                      builder: (_) => Padding(
-                          padding: const EdgeInsets.only(top: 20),
-                          child: Row(
-                            children: [
-                              Padding(
-                                padding: const EdgeInsets.only(bottom: 8.0),
-                                child: Row(
-                                  children: [
-                                    sendViewModel.hasMultipleTokens
-                                        ? Container(
-                                            padding: EdgeInsets.only(right: 8),
-                                            height: 32,
-                                            child: InkWell(
-                                              onTap: () => _presentPicker(context),
-                                              child: Row(
-                                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                                                mainAxisSize: MainAxisSize.min,
-                                                children: <Widget>[
-                                                  Padding(
-                                                    padding: EdgeInsets.only(right: 5),
-                                                    child: Image.asset(
-                                                      'assets/images/arrow_bottom_purple_icon.png',
-                                                      color: Colors.white,
-                                                      height: 8,
-                                                    ),
-                                                  ),
-                                                  Text(
-                                                    sendViewModel.selectedCryptoCurrency.title,
-                                                    style: TextStyle(
-                                                        fontWeight: FontWeight.w600,
-                                                        fontSize: 16,
-                                                        color: Colors.white),
-                                                  ),
-                                                ],
-                                              ),
-                                            ),
-                                          )
-                                        : Text(
-                                            sendViewModel.selectedCryptoCurrency.title,
-                                            style: TextStyle(
-                                                fontWeight: FontWeight.w600,
-                                                fontSize: 16,
-                                                color: Colors.white),
-                                          ),
-                                    sendViewModel.selectedCryptoCurrency.tag != null
-                                        ? Padding(
-                                            padding: const EdgeInsets.fromLTRB(3.0, 0, 3.0, 0),
-                                            child: Container(
-                                              height: 32,
-                                              decoration: BoxDecoration(
-                                                  color: Theme.of(context)
-                                                      .extension<SendPageTheme>()!
-                                                      .textFieldButtonColor,
-                                                  borderRadius: BorderRadius.all(
-                                                    Radius.circular(6),
-                                                  )),
-                                              child: Center(
-                                                child: Padding(
-                                                  padding: const EdgeInsets.all(6.0),
-                                                  child: Text(
-                                                    sendViewModel.selectedCryptoCurrency.tag!,
-                                                    style: TextStyle(
-                                                        fontSize: 12,
-                                                        fontWeight: FontWeight.bold,
-                                                        color: Theme.of(context)
-                                                            .extension<SendPageTheme>()!
-                                                            .textFieldButtonIconColor),
-                                                  ),
-                                                ),
-                                              ),
-                                            ),
-                                          )
-                                        : Container(),
-                                    Padding(
-                                      padding: const EdgeInsets.only(right: 10.0),
-                                      child: Text(
-                                        ':',
-                                        style: TextStyle(
-                                            fontWeight: FontWeight.w600,
-                                            fontSize: 16,
-                                            color: Colors.white),
-                                      ),
-                                    ),
-                                  ],
-                                ),
-                              ),
-                              Expanded(
-                                child: Stack(
-                                  children: [
-                                    BaseTextFormField(
-                                      focusNode: cryptoAmountFocus,
-                                      controller: cryptoAmountController,
-                                      keyboardType: TextInputType.numberWithOptions(
-                                          signed: false, decimal: true),
-                                      inputFormatters: [
-                                        FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]'))
-                                      ],
-                                      suffixIcon: SizedBox(
-                                        width: prefixIconWidth,
-                                      ),
-                                      hintText: '0.0000',
-                                      borderColor: Colors.transparent,
-                                      textStyle: TextStyle(
-                                          fontSize: 14,
-                                          fontWeight: FontWeight.w500,
-                                          color: Colors.white),
-                                      placeholderTextStyle: TextStyle(
-                                          color: Theme.of(context)
-                                              .extension<SendPageTheme>()!
-                                              .textFieldHintColor,
-                                          fontWeight: FontWeight.w500,
-                                          fontSize: 14),
-                                      validator: output.sendAll
-                                          ? sendViewModel.allAmountValidator
-                                          : sendViewModel.amountValidator,
-                                    ),
-                                    if (!sendViewModel.isBatchSending)
-                                      Positioned(
-                                        top: 2,
-                                        right: 0,
-                                        child: Container(
-                                          width: prefixIconWidth,
-                                          height: prefixIconHeight,
-                                          child: InkWell(
-                                            onTap: () async {
-                                              output.setSendAll(sendViewModel.balance);
-                                            },
-                                            child: Container(
-                                              decoration: BoxDecoration(
-                                                color: Theme.of(context)
-                                                    .extension<SendPageTheme>()!
-                                                    .textFieldButtonColor,
-                                                borderRadius: BorderRadius.all(
-                                                  Radius.circular(6),
-                                                ),
-                                              ),
-                                              child: Center(
-                                                child: Text(
-                                                  S.of(context).all,
-                                                  textAlign: TextAlign.center,
-                                                  style: TextStyle(
-                                                    fontSize: 12,
-                                                    fontWeight: FontWeight.bold,
-                                                    color: Theme.of(context)
-                                                        .extension<SendPageTheme>()!
-                                                        .textFieldButtonIconColor,
-                                                  ),
-                                                ),
-                                              ),
-                                            ),
-                                          ),
-                                        ),
-                                      ),
-                                  ],
-                                ),
-                              ),
-                            ],
-                          )),
-                    ),
+                    CurrencyAmountTextField(
+                        selectedCurrency: sendViewModel.selectedCryptoCurrency.title,
+                        amountFocusNode: cryptoAmountFocus,
+                        amountController: cryptoAmountController,
+                        isAmountEditable: true,
+                        onTapPicker: () => _presentPicker(context),
+                        isPickerEnable: sendViewModel.hasMultipleTokens,
+                        tag: sendViewModel.selectedCryptoCurrency.tag,
+                        allAmountButton: !sendViewModel.isBatchSending,
+                        currencyValueValidator: output.sendAll
+                            ? sendViewModel.allAmountValidator
+                            : sendViewModel.amountValidator,
+                        allAmountCallback: () async => output.setSendAll(sendViewModel.balance)),
                     Divider(
                         height: 1,
                         color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
@@ -402,41 +256,16 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
                       ),
                     ),
                     if (!sendViewModel.isFiatDisabled)
-                      Padding(
-                        padding: const EdgeInsets.only(top: 20),
-                        child: BaseTextFormField(
-                          focusNode: fiatAmountFocus,
-                          controller: fiatAmountController,
-                          keyboardType:
-                              TextInputType.numberWithOptions(signed: false, decimal: true),
-                          inputFormatters: [
-                            FilteringTextInputFormatter.deny(
-                              RegExp('[\\-|\\ ]'),
-                            )
-                          ],
-                          prefixIcon: Padding(
-                            padding: EdgeInsets.only(top: 9),
-                            child: Text(
-                              sendViewModel.fiat.title + ':',
-                              style: TextStyle(
-                                fontSize: 16,
-                                fontWeight: FontWeight.w600,
-                                color: Colors.white,
-                              ),
-                            ),
-                          ),
+                      CurrencyAmountTextField(
+                          selectedCurrency: sendViewModel.fiat.title,
+                          amountFocusNode: fiatAmountFocus,
+                          amountController: fiatAmountController,
                           hintText: '0.00',
-                          borderColor:
-                              Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
-                          textStyle: TextStyle(
-                              fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
-                          placeholderTextStyle: TextStyle(
-                              color:
-                                  Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
-                              fontWeight: FontWeight.w500,
-                              fontSize: 14),
-                        ),
-                      ),
+                          isAmountEditable: true,
+                          allAmountButton: false),
+                    Divider(
+                        height: 1,
+                        color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
                     Padding(
                       padding: EdgeInsets.only(top: 20),
                       child: BaseTextFormField(
@@ -715,12 +544,11 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
     showPopUp<void>(
       context: context,
       builder: (_) => CurrencyPicker(
-        selectedAtIndex: sendViewModel.currencies.indexOf(sendViewModel.selectedCryptoCurrency),
-        items: sendViewModel.currencies,
-        hintText: S.of(context).search_currency,
-        onItemSelected: (Currency cur) =>
-            sendViewModel.selectedCryptoCurrency = (cur as CryptoCurrency),
-      ),
+          selectedAtIndex: sendViewModel.currencies.indexOf(sendViewModel.selectedCryptoCurrency),
+          items: sendViewModel.currencies,
+          hintText: S.of(context).search_currency,
+          onItemSelected: (Currency cur) =>
+              sendViewModel.selectedCryptoCurrency = (cur as CryptoCurrency)),
     );
   }
 
diff --git a/lib/src/screens/send/widgets/send_template_card.dart b/lib/src/screens/send/widgets/send_template_card.dart
index 4f62616e3..bf2a66b73 100644
--- a/lib/src/screens/send/widgets/send_template_card.dart
+++ b/lib/src/screens/send/widgets/send_template_card.dart
@@ -1,5 +1,5 @@
 import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
-import 'package:cake_wallet/src/screens/send/widgets/prefix_currency_icon_widget.dart';
+import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart';
 import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
 import 'package:cake_wallet/utils/payment_request.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
@@ -59,7 +59,8 @@ class SendTemplateCard extends StatelessWidget {
                       hintText: sendTemplateViewModel.recipients.length > 1
                           ? S.of(context).template_name
                           : S.of(context).send_name,
-                      borderColor: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
+                      borderColor:
+                          Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
                       textStyle:
                           TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
                       placeholderTextStyle: TextStyle(
@@ -69,107 +70,87 @@ class SendTemplateCard extends StatelessWidget {
                       validator: sendTemplateViewModel.templateValidator),
                 Padding(
                   padding: EdgeInsets.only(top: 20),
-                  child: Observer(
-                    builder: (context) {
-                      return AddressTextField(
-                        selectedCurrency: template.selectedCurrency,
-                        controller: _addressController,
-                        onURIScanned: (uri) {
-                          final paymentRequest = PaymentRequest.fromUri(uri);
-                          _addressController.text = paymentRequest.address;
-                          _cryptoAmountController.text = paymentRequest.amount;
-                        },
-                        options: [
-                          AddressTextFieldOption.paste,
-                          AddressTextFieldOption.qrCode,
-                          AddressTextFieldOption.addressBook
-                        ],
-                        onPushPasteButton: (context) async {
-                          template.output.resetParsedAddress();
-                          await template.output.fetchParsedAddress(context);
-                        },
-                        onPushAddressBookButton: (context) async {
-                          template.output.resetParsedAddress();
-                          await template.output.fetchParsedAddress(context);
-                        },
-                        buttonColor: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
-                        borderColor: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
-                        textStyle: TextStyle(
-                          fontSize: 14,
-                          fontWeight: FontWeight.w500,
-                          color: Colors.white,
-                        ),
-                        hintStyle: TextStyle(
-                          fontSize: 14,
-                          fontWeight: FontWeight.w500,
-                          color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
-                        ),
-                        validator: sendTemplateViewModel.addressValidator,
-                      );
-                    }
-                  ),
-                ),
-                Padding(
-                  padding: const EdgeInsets.only(top: 20),
-                  child: Focus(
-                    onFocusChange: (hasFocus) {
-                      if (hasFocus) {
-                        template.selectCurrency();
-                      }
-                    },
-                    child: BaseTextFormField(
-                      focusNode: _cryptoAmountFocus,
-                      controller: _cryptoAmountController,
-                      keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
-                      inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]'))],
-                      prefixIcon: Observer(
-                        builder: (_) => PrefixCurrencyIcon(
-                          title: template.selectedCurrency.title,
-                          isSelected: template.isCurrencySelected,
-                          onTap: sendTemplateViewModel.walletCurrencies.length > 1
-                              ? () => _presentPicker(context)
-                              : null,
-                        ),
-                      ),
-                      hintText: '0.0000',
-                      borderColor: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
-                      textStyle:
-                          TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
-                      placeholderTextStyle: TextStyle(
-                          color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
-                          fontWeight: FontWeight.w500,
-                          fontSize: 14),
-                      validator: sendTemplateViewModel.amountValidator,
-                    ),
-                  ),
-                ),
-                Padding(
-                  padding: const EdgeInsets.only(top: 20),
-                  child: Focus(
-                    onFocusChange: (hasFocus) {
-                      if (hasFocus) {
-                        template.selectFiat();
-                      }
-                    },
-                    child: BaseTextFormField(
-                      focusNode: _fiatAmountFocus,
-                      controller: _fiatAmountController,
-                      keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
-                      inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]'))],
-                      prefixIcon: Observer(
-                          builder: (_) => PrefixCurrencyIcon(
-                              title: sendTemplateViewModel.fiatCurrency,
-                              isSelected: template.isFiatSelected)),
-                      hintText: '0.00',
-                      borderColor: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
-                      textStyle:
-                          TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
-                      placeholderTextStyle: TextStyle(
-                        color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
-                        fontWeight: FontWeight.w500,
+                  child: Observer(builder: (context) {
+                    return AddressTextField(
+                      selectedCurrency: template.selectedCurrency,
+                      controller: _addressController,
+                      onURIScanned: (uri) {
+                        final paymentRequest = PaymentRequest.fromUri(uri);
+                        _addressController.text = paymentRequest.address;
+                        _cryptoAmountController.text = paymentRequest.amount;
+                      },
+                      options: [
+                        AddressTextFieldOption.paste,
+                        AddressTextFieldOption.qrCode,
+                        AddressTextFieldOption.addressBook
+                      ],
+                      onPushPasteButton: (context) async {
+                        template.output.resetParsedAddress();
+                        await template.output.fetchParsedAddress(context);
+                      },
+                      onPushAddressBookButton: (context) async {
+                        template.output.resetParsedAddress();
+                        await template.output.fetchParsedAddress(context);
+                      },
+                      buttonColor:
+                          Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
+                      borderColor:
+                          Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
+                      textStyle: TextStyle(
                         fontSize: 14,
+                        fontWeight: FontWeight.w500,
+                        color: Colors.white,
                       ),
-                    ),
+                      hintStyle: TextStyle(
+                        fontSize: 14,
+                        fontWeight: FontWeight.w500,
+                        color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
+                      ),
+                      validator: sendTemplateViewModel.addressValidator,
+                    );
+                  }),
+                ),
+                Focus(
+                  onFocusChange: (hasFocus) {
+                    if (hasFocus) template.setCryptoCurrency(true);
+                  },
+                  child: Column(
+                    children: [
+                      Observer(
+                          builder: (context) => CurrencyAmountTextField(
+                              selectedCurrency: template.selectedCurrency.title,
+                              amountFocusNode: _cryptoAmountFocus,
+                              amountController: _cryptoAmountController,
+                              isSelected: template.isCryptoSelected,
+                              tag: template.selectedCurrency.tag,
+                              isPickerEnable: sendTemplateViewModel.hasMultipleTokens,
+                              onTapPicker: () => _presentPicker(context),
+                              currencyValueValidator: sendTemplateViewModel.amountValidator,
+                              isAmountEditable: true)),
+                      Divider(
+                          height: 1,
+                          color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor)
+                    ],
+                  ),
+                ),
+                Focus(
+                  onFocusChange: (hasFocus) {
+                    if (hasFocus) template.setCryptoCurrency(false);
+                  },
+                  child: Column(
+                    children: [
+                      Observer(
+                          builder: (context) => CurrencyAmountTextField(
+                              selectedCurrency: sendTemplateViewModel.fiatCurrency,
+                              amountFocusNode: _fiatAmountFocus,
+                              amountController: _fiatAmountController,
+                              isSelected: !template.isCryptoSelected,
+                              hintText: '0.00',
+                              isAmountEditable: true)),
+                      Divider(
+                          height: 1,
+                          color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor)
+                    ],
                   ),
                 ),
               ],
diff --git a/lib/view_model/send/send_template_view_model.dart b/lib/view_model/send/send_template_view_model.dart
index 66a3c37c8..3c78f3000 100644
--- a/lib/view_model/send/send_template_view_model.dart
+++ b/lib/view_model/send/send_template_view_model.dart
@@ -1,3 +1,4 @@
+import 'package:cake_wallet/reactions/wallet_connect.dart';
 import 'package:cake_wallet/view_model/send/template_view_model.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -97,4 +98,8 @@ abstract class SendTemplateViewModelBase with Store {
 
   @computed
   List<CryptoCurrency> get walletCurrencies => _wallet.balance.keys.toList();
+
+  bool get hasMultipleTokens => isEVMCompatibleChain(_wallet.type) ||
+  _wallet.type == WalletType.solana ||
+  _wallet.type == WalletType.tron;
 }
diff --git a/lib/view_model/send/template_view_model.dart b/lib/view_model/send/template_view_model.dart
index 5b799c343..fcd40bd43 100644
--- a/lib/view_model/send/template_view_model.dart
+++ b/lib/view_model/send/template_view_model.dart
@@ -40,35 +40,22 @@ abstract class TemplateViewModelBase with Store {
   CryptoCurrency _currency;
 
   @observable
-  bool isCurrencySelected = true;
-
-  @observable
-  bool isFiatSelected = false;
+  bool isCryptoSelected = true;
 
   @action
-  void selectCurrency() {
-    isCurrencySelected = true;
-    isFiatSelected = false;
-  }
-
-  @action
-  void selectFiat() {
-    isFiatSelected = true;
-    isCurrencySelected = false;
-  }
+  void setCryptoCurrency(bool value) => isCryptoSelected = value;
 
   @action
   void reset() {
     name = '';
     address = '';
-    isCurrencySelected = true;
-    isFiatSelected = false;
+    isCryptoSelected = true;
     output.reset();
   }
 
   Template toTemplate({required String cryptoCurrency, required String fiatCurrency}) {
     return Template(
-        isCurrencySelectedRaw: isCurrencySelected,
+        isCurrencySelectedRaw: isCryptoSelected,
         nameRaw: name,
         addressRaw: address,
         cryptoCurrencyRaw: cryptoCurrency,
@@ -79,7 +66,7 @@ abstract class TemplateViewModelBase with Store {
 
   @action
   void changeSelectedCurrency(CryptoCurrency currency) {
-    isCurrencySelected = true;
+    isCryptoSelected = true;
     _currency = currency;
   }
 

From acadee6ed54f58c8001b136ff4cf439894a8aed5 Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Sat, 10 Aug 2024 00:49:27 +0300
Subject: [PATCH 15/81] fix custom rate issue (#1579)

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 lib/bitcoin/cw_bitcoin.dart                            |  7 +++++++
 .../rbf_details_list_fee_picker_item.dart              |  2 +-
 lib/src/widgets/standard_picker_list.dart              |  5 +++--
 lib/view_model/transaction_details_view_model.dart     | 10 +++++++---
 tool/configure.dart                                    |  1 +
 5 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart
index efb1211bc..a92aaad74 100644
--- a/lib/bitcoin/cw_bitcoin.dart
+++ b/lib/bitcoin/cw_bitcoin.dart
@@ -435,6 +435,13 @@ class CWBitcoin extends Bitcoin {
     );
   }
 
+  @override
+  int feeAmountWithFeeRate(Object wallet, int feeRate, int inputsCount, int outputsCount,
+      {int? size}) {
+    final bitcoinWallet = wallet as ElectrumWallet;
+    return bitcoinWallet.feeAmountWithFeeRate(feeRate, inputsCount, outputsCount, size: size);
+  }
+
   @override
   int getMaxCustomFeeRate(Object wallet) {
     final bitcoinWallet = wallet as ElectrumWallet;
diff --git a/lib/src/screens/transaction_details/rbf_details_list_fee_picker_item.dart b/lib/src/screens/transaction_details/rbf_details_list_fee_picker_item.dart
index 7615065d7..db3d94500 100644
--- a/lib/src/screens/transaction_details/rbf_details_list_fee_picker_item.dart
+++ b/lib/src/screens/transaction_details/rbf_details_list_fee_picker_item.dart
@@ -17,7 +17,7 @@ class StandardPickerListItem<T> extends TransactionDetailsListItem {
   final List<T> items;
   final String Function(T item, double sliderValue) displayItem;
   final Function(double) onSliderChanged;
-  final Function(T) onItemSelected;
+  final Function(T item, double sliderValue) onItemSelected;
   final int selectedIdx;
   final double? maxValue;
   final int customItemIndex;
diff --git a/lib/src/widgets/standard_picker_list.dart b/lib/src/widgets/standard_picker_list.dart
index ea8b07097..0e9831420 100644
--- a/lib/src/widgets/standard_picker_list.dart
+++ b/lib/src/widgets/standard_picker_list.dart
@@ -23,7 +23,7 @@ class StandardPickerList<T> extends StatefulWidget {
   final int customItemIndex;
   final String Function(T item, double sliderValue) displayItem;
   final Function(double) onSliderChanged;
-  final Function(T) onItemSelected;
+  final Function(T item, double sliderValue) onItemSelected;
   final String value;
   final int selectedIdx;
   final double customValue;
@@ -50,6 +50,7 @@ class _StandardPickerListState<T> extends State<StandardPickerList<T>> {
   @override
   Widget build(BuildContext context) {
     String adaptedDisplayItem(T item) => widget.displayItem(item, customValue);
+    String adaptedOnItemSelected(T item) => widget.onItemSelected(item, customValue).toString();
 
     return Column(
       children: [
@@ -74,7 +75,7 @@ class _StandardPickerListState<T> extends State<StandardPickerList<T>> {
             },
             onItemSelected: (T item) {
               setState(() => selectedIdx = widget.items.indexOf(item));
-              value = widget.onItemSelected(item).toString();
+              value = adaptedOnItemSelected(item);
             },
           ),
         ),
diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart
index 9e71837a7..ef6474974 100644
--- a/lib/view_model/transaction_details_view_model.dart
+++ b/lib/view_model/transaction_details_view_model.dart
@@ -378,9 +378,9 @@ abstract class TransactionDetailsViewModelBase with Store {
             sendViewModel.displayFeeRate(priority, sliderValue.round()),
         onSliderChanged: (double newValue) =>
             setNewFee(value: newValue, priority: transactionPriority!),
-        onItemSelected: (dynamic item) {
+        onItemSelected: (dynamic item, double sliderValue) {
           transactionPriority = item as TransactionPriority;
-          return setNewFee(priority: transactionPriority!);
+          return setNewFee(value: sliderValue, priority: transactionPriority!);
         }));
 
     if (transactionInfo.inputAddresses != null) {
@@ -427,7 +427,11 @@ abstract class TransactionDetailsViewModelBase with Store {
 
   String setNewFee({double? value, required TransactionPriority priority}) {
     newFee = priority == bitcoin!.getBitcoinTransactionPriorityCustom() && value != null
-        ? bitcoin!.getEstimatedFeeWithFeeRate(wallet, value.round(), transactionInfo.amount)
+        ? bitcoin!.feeAmountWithFeeRate(
+            wallet,
+            value.round(),
+            transactionInfo.inputAddresses?.length ?? 1,
+            transactionInfo.outputAddresses?.length ?? 1)
         : bitcoin!.getFeeAmountForPriority(
             wallet,
             priority,
diff --git a/tool/configure.dart b/tool/configure.dart
index 32b470979..8b5af92b2 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -210,6 +210,7 @@ abstract class Bitcoin {
   int getFeeAmountForPriority(Object wallet, TransactionPriority priority, int inputsCount, int outputsCount, {int? size});
   int getEstimatedFeeWithFeeRate(Object wallet, int feeRate, int? amount,
       {int? outputsCount, int? size});
+  int feeAmountWithFeeRate(Object wallet, int feeRate, int inputsCount, int outputsCount, {int? size});
   int getHeightByDate({required DateTime date});
   Future<void> rescan(Object wallet, {required int height, bool? doSingleScan});
   Future<bool> getNodeIsElectrsSPEnabled(Object wallet);

From 9c29dbd6fd7823e4deb5da871b752087ca8ef06f Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Sat, 10 Aug 2024 01:18:55 +0300
Subject: [PATCH 16/81] fix zero initial fee rates in RBF rate picker (#1585)

* fix zero initial fee rates in RBF rate picker

* fix for other settings page[skip ci]
---
 lib/di.dart                                                | 4 ++--
 lib/src/screens/settings/other_settings_page.dart          | 7 ++++++-
 .../transaction_details/transaction_details_page.dart      | 7 ++++++-
 lib/src/widgets/picker.dart                                | 4 ++--
 lib/view_model/settings/other_settings_view_model.dart     | 4 +++-
 5 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/lib/di.dart b/lib/di.dart
index a37574f21..a64270f6d 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -759,8 +759,8 @@ Future<void> setup({
   getIt.registerFactory(() => TrocadorProvidersViewModel(getIt.get<SettingsStore>()));
 
   getIt.registerFactory(() {
-    return OtherSettingsViewModel(getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!);
-  });
+    return OtherSettingsViewModel(getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!,
+        getIt.get<SendViewModel>());});
 
   getIt.registerFactory(() {
     return SecuritySettingsViewModel(getIt.get<SettingsStore>());
diff --git a/lib/src/screens/settings/other_settings_page.dart b/lib/src/screens/settings/other_settings_page.dart
index 9bba51944..137f699f5 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/bitcoin/bitcoin.dart';
 import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/routes.dart';
@@ -12,7 +13,11 @@ import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 
 class OtherSettingsPage extends BasePage {
-  OtherSettingsPage(this._otherSettingsViewModel);
+  OtherSettingsPage(this._otherSettingsViewModel) {
+    if (_otherSettingsViewModel.sendViewModel.isElectrumWallet) {
+      bitcoin!.updateFeeRates(_otherSettingsViewModel.sendViewModel.wallet);
+    }
+  }
 
   @override
   String get title => S.current.other_settings;
diff --git a/lib/src/screens/transaction_details/transaction_details_page.dart b/lib/src/screens/transaction_details/transaction_details_page.dart
index 7734f37ed..d06b935dd 100644
--- a/lib/src/screens/transaction_details/transaction_details_page.dart
+++ b/lib/src/screens/transaction_details/transaction_details_page.dart
@@ -1,3 +1,4 @@
+import 'package:cake_wallet/bitcoin/bitcoin.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/screens/base_page.dart';
@@ -15,7 +16,11 @@ import 'package:flutter/services.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 
 class TransactionDetailsPage extends BasePage {
-  TransactionDetailsPage({required this.transactionDetailsViewModel});
+  TransactionDetailsPage({required this.transactionDetailsViewModel}) {
+    if (transactionDetailsViewModel.sendViewModel.isElectrumWallet) {
+      bitcoin!.updateFeeRates(transactionDetailsViewModel.sendViewModel.wallet);
+    }
+  }
 
   @override
   String get title => S.current.transaction_details_title;
diff --git a/lib/src/widgets/picker.dart b/lib/src/widgets/picker.dart
index b744d1db0..a7cb03a4e 100644
--- a/lib/src/widgets/picker.dart
+++ b/lib/src/widgets/picker.dart
@@ -499,10 +499,10 @@ class _PickerState<Item> extends State<Picker<Item>> {
       children: <Widget>[
         Expanded(
           child: Slider(
-            value: widget.sliderValue ?? 1,
+            value: widget.sliderValue == null || widget.sliderValue! < 1 ? 1 : widget.sliderValue!,
             onChanged: isActivated ? widget.onSliderChanged : null,
             min: widget.minValue ?? 1,
-            max: widget.maxValue ?? 100,
+            max: (widget.maxValue == null || widget.maxValue! < 1) ? 100 : widget.maxValue!,
             divisions: 100,
           ),
         ),
diff --git a/lib/view_model/settings/other_settings_view_model.dart b/lib/view_model/settings/other_settings_view_model.dart
index bd04755fa..9af8c67cf 100644
--- a/lib/view_model/settings/other_settings_view_model.dart
+++ b/lib/view_model/settings/other_settings_view_model.dart
@@ -4,6 +4,7 @@ import 'package:cake_wallet/entities/provider_types.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/utils/package_info.dart';
+import 'package:cake_wallet/view_model/send/send_view_model.dart';
 // import 'package:package_info/package_info.dart';
 import 'package:collection/collection.dart';
 import 'package:cw_core/balance.dart';
@@ -20,7 +21,7 @@ class OtherSettingsViewModel = OtherSettingsViewModelBase
     with _$OtherSettingsViewModel;
 
 abstract class OtherSettingsViewModelBase with Store {
-  OtherSettingsViewModelBase(this._settingsStore, this._wallet)
+  OtherSettingsViewModelBase(this._settingsStore, this._wallet, this.sendViewModel)
       : walletType = _wallet.type,
         currentVersion = '' {
     PackageInfo.fromPlatform().then(
@@ -42,6 +43,7 @@ abstract class OtherSettingsViewModelBase with Store {
   String currentVersion;
 
   final SettingsStore _settingsStore;
+  final SendViewModel sendViewModel;
 
   @computed
   TransactionPriority get transactionPriority {

From b412d45f0e3a97758aa5b438c90979f2a39bb324 Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Sat, 10 Aug 2024 01:21:26 +0300
Subject: [PATCH 17/81] Cw 567 cant swipe through menus on desktop builds
 (#1563)

* MaterialApp scrollBehavior

* accessibility improvements
---
 lib/app_scroll_behavior.dart                  |  9 +++++
 lib/main.dart                                 |  3 ++
 lib/src/screens/dashboard/dashboard_page.dart |  6 +++-
 .../screens/dashboard/pages/balance_page.dart | 23 +++++++-----
 .../screens/restore/wallet_restore_page.dart  | 26 ++++++++------
 lib/src/screens/send/send_page.dart           |  9 +++--
 lib/src/screens/send/send_template_page.dart  | 36 +++++++++++--------
 7 files changed, 75 insertions(+), 37 deletions(-)
 create mode 100644 lib/app_scroll_behavior.dart

diff --git a/lib/app_scroll_behavior.dart b/lib/app_scroll_behavior.dart
new file mode 100644
index 000000000..d5abd5688
--- /dev/null
+++ b/lib/app_scroll_behavior.dart
@@ -0,0 +1,9 @@
+import 'dart:ui';
+
+import 'package:flutter/material.dart';
+
+class AppScrollBehavior extends MaterialScrollBehavior {
+  @override
+  Set<PointerDeviceKind> get dragDevices =>
+      {PointerDeviceKind.touch, PointerDeviceKind.mouse, PointerDeviceKind.trackpad};
+}
diff --git a/lib/main.dart b/lib/main.dart
index 014d5f011..1c0078e16 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,5 +1,6 @@
 import 'dart:async';
 import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
+import 'package:cake_wallet/app_scroll_behavior.dart';
 import 'package:cake_wallet/buy/order.dart';
 import 'package:cake_wallet/core/auth_service.dart';
 import 'package:cake_wallet/di.dart';
@@ -75,6 +76,7 @@ Future<void> main() async {
       runApp(
         MaterialApp(
           debugShowCheckedModeBanner: false,
+          scrollBehavior: AppScrollBehavior(),
           home: Scaffold(
             body: SingleChildScrollView(
               child: Container(
@@ -297,6 +299,7 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
             locale: Locale(settingsStore.languageCode),
             onGenerateRoute: (settings) => Router.createRoute(settings),
             initialRoute: initialRoute,
+            scrollBehavior: AppScrollBehavior(),
             home: _Home(),
           ));
     });
diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart
index 7a2055930..ad6e68cd8 100644
--- a/lib/src/screens/dashboard/dashboard_page.dart
+++ b/lib/src/screens/dashboard/dashboard_page.dart
@@ -237,7 +237,11 @@ class _DashboardPageView extends BasePage {
               padding: EdgeInsets.only(bottom: 24, top: 10),
               child: Observer(
                 builder: (context) {
-                  return ExcludeSemantics(
+                  return Semantics(
+                    button: false,
+                    label: 'Page Indicator',
+                    hint: 'Swipe to change page',
+                    excludeSemantics: true,
                     child: SmoothPageIndicator(
                       controller: controller,
                       count: pages.length,
diff --git a/lib/src/screens/dashboard/pages/balance_page.dart b/lib/src/screens/dashboard/pages/balance_page.dart
index 1cf3e3e0c..770cda6f9 100644
--- a/lib/src/screens/dashboard/pages/balance_page.dart
+++ b/lib/src/screens/dashboard/pages/balance_page.dart
@@ -23,6 +23,7 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
 import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
 import 'package:url_launcher/url_launcher.dart';
 
@@ -469,15 +470,19 @@ class BalanceRowWidget extends StatelessWidget {
                     children: [
                       Row(
                         children: [
-                          Text('${availableBalanceLabel}',
-                              style: TextStyle(
-                                  fontSize: 12,
-                                  fontFamily: 'Lato',
-                                  fontWeight: FontWeight.w400,
-                                  color: Theme.of(context)
-                                      .extension<BalancePageTheme>()!
-                                      .labelTextColor,
-                                  height: 1)),
+                          Semantics(
+                            hint: 'Double tap to see more information',
+                            container: true,
+                            child: Text('${availableBalanceLabel}',
+                                style: TextStyle(
+                                    fontSize: 12,
+                                    fontFamily: 'Lato',
+                                    fontWeight: FontWeight.w400,
+                                    color: Theme.of(context)
+                                        .extension<BalancePageTheme>()!
+                                        .labelTextColor,
+                                    height: 1)),
+                          ),
                           if (hasAdditionalBalance)
                             Padding(
                               padding: const EdgeInsets.symmetric(horizontal: 4),
diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart
index a9bd52b26..746b73dca 100644
--- a/lib/src/screens/restore/wallet_restore_page.dart
+++ b/lib/src/screens/restore/wallet_restore_page.dart
@@ -177,16 +177,22 @@ class WalletRestorePage extends BasePage {
                 if (_pages.length > 1)
                   Padding(
                     padding: EdgeInsets.only(top: 10),
-                    child: SmoothPageIndicator(
-                      controller: _controller,
-                      count: _pages.length,
-                      effect: ColorTransitionEffect(
-                        spacing: 6.0,
-                        radius: 6.0,
-                        dotWidth: 6.0,
-                        dotHeight: 6.0,
-                        dotColor: Theme.of(context).hintColor.withOpacity(0.5),
-                        activeDotColor: Theme.of(context).hintColor,
+                    child: Semantics(
+                      button: false,
+                      label: 'Page Indicator',
+                      hint: 'Swipe to change restore mode',
+                      excludeSemantics: true,
+                      child: SmoothPageIndicator(
+                        controller: _controller,
+                        count: _pages.length,
+                        effect: ColorTransitionEffect(
+                          spacing: 6.0,
+                          radius: 6.0,
+                          dotWidth: 6.0,
+                          dotHeight: 6.0,
+                          dotColor: Theme.of(context).hintColor.withOpacity(0.5),
+                          activeDotColor: Theme.of(context).hintColor,
+                        ),
                       ),
                     ),
                   ),
diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart
index b46a7f3db..97a7ad88d 100644
--- a/lib/src/screens/send/send_page.dart
+++ b/lib/src/screens/send/send_page.dart
@@ -212,7 +212,12 @@ class SendPage extends BasePage {
                           final count = sendViewModel.outputs.length;
 
                           return count > 1
-                              ? SmoothPageIndicator(
+                              ? Semantics (
+                          label: 'Page Indicator',
+                          hint: 'Swipe to change receiver',
+                              excludeSemantics: true,
+                                child:
+                          SmoothPageIndicator(
                                   controller: controller,
                                   count: count,
                                   effect: ScrollingDotsEffect(
@@ -226,7 +231,7 @@ class SendPage extends BasePage {
                                       activeDotColor: Theme.of(context)
                                           .extension<SendPageTheme>()!
                                           .templateBackgroundColor),
-                                )
+                                ))
                               : Offstage();
                         },
                       ),
diff --git a/lib/src/screens/send/send_template_page.dart b/lib/src/screens/send/send_template_page.dart
index f7c9da082..5db70c0eb 100644
--- a/lib/src/screens/send/send_template_page.dart
+++ b/lib/src/screens/send/send_template_page.dart
@@ -94,21 +94,27 @@ class SendTemplatePage extends BasePage {
                           final count = sendTemplateViewModel.recipients.length;
 
                           return count > 1
-                              ? SmoothPageIndicator(
-                                  controller: controller,
-                                  count: count,
-                                  effect: ScrollingDotsEffect(
-                                      spacing: 6.0,
-                                      radius: 6.0,
-                                      dotWidth: 6.0,
-                                      dotHeight: 6.0,
-                                      dotColor: Theme.of(context)
-                                          .extension<SendPageTheme>()!
-                                          .indicatorDotColor,
-                                      activeDotColor: Theme.of(context)
-                                          .extension<DashboardPageTheme>()!
-                                          .indicatorDotTheme
-                                          .activeIndicatorColor))
+                              ? Semantics(
+                            button: false,
+                            label: 'Page Indicator',
+                            hint: 'Swipe to change receiver',
+                            excludeSemantics: true,
+                                child: SmoothPageIndicator(
+                                    controller: controller,
+                                    count: count,
+                                    effect: ScrollingDotsEffect(
+                                        spacing: 6.0,
+                                        radius: 6.0,
+                                        dotWidth: 6.0,
+                                        dotHeight: 6.0,
+                                        dotColor: Theme.of(context)
+                                            .extension<SendPageTheme>()!
+                                            .indicatorDotColor,
+                                        activeDotColor: Theme.of(context)
+                                            .extension<DashboardPageTheme>()!
+                                            .indicatorDotTheme
+                                            .activeIndicatorColor)),
+                              )
                               : Offstage();
                         },
                       ),

From 96baf460f3492d1d5e4320b581bae79180b33790 Mon Sep 17 00:00:00 2001
From: David Adegoke <64401859+Blazebrain@users.noreply.github.com>
Date: Sat, 10 Aug 2024 00:02:47 +0100
Subject: [PATCH 18/81] Filters out TRC10 spam transactions and modifies Solana
 error messages (#1587)

* fix: Tron and solana fixes

* fix: Disable send all for solana wallets

* fix: Add localization and add tostring to get more info on error

* fix: Fix spelling for comment

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 cw_solana/lib/solana_client.dart            |  2 +-
 cw_solana/pubspec.yaml                      |  2 +-
 cw_tron/lib/tron_wallet.dart                |  5 +++++
 lib/src/screens/send/widgets/send_card.dart |  2 +-
 lib/view_model/send/send_view_model.dart    | 10 ++++++++--
 res/values/strings_ar.arb                   |  1 +
 res/values/strings_bg.arb                   |  1 +
 res/values/strings_cs.arb                   |  1 +
 res/values/strings_de.arb                   |  1 +
 res/values/strings_en.arb                   |  1 +
 res/values/strings_es.arb                   |  1 +
 res/values/strings_fr.arb                   |  1 +
 res/values/strings_ha.arb                   |  1 +
 res/values/strings_hi.arb                   |  1 +
 res/values/strings_hr.arb                   |  1 +
 res/values/strings_id.arb                   |  1 +
 res/values/strings_it.arb                   |  1 +
 res/values/strings_ja.arb                   |  1 +
 res/values/strings_ko.arb                   |  1 +
 res/values/strings_my.arb                   |  1 +
 res/values/strings_nl.arb                   |  1 +
 res/values/strings_pl.arb                   |  1 +
 res/values/strings_pt.arb                   |  1 +
 res/values/strings_ru.arb                   |  1 +
 res/values/strings_th.arb                   |  1 +
 res/values/strings_tl.arb                   |  1 +
 res/values/strings_tr.arb                   |  1 +
 res/values/strings_uk.arb                   |  1 +
 res/values/strings_ur.arb                   |  1 +
 res/values/strings_yo.arb                   |  1 +
 res/values/strings_zh.arb                   |  1 +
 31 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/cw_solana/lib/solana_client.dart b/cw_solana/lib/solana_client.dart
index 38f2864df..23e88fe5e 100644
--- a/cw_solana/lib/solana_client.dart
+++ b/cw_solana/lib/solana_client.dart
@@ -456,7 +456,7 @@ class SolanaWalletClient {
         funder: ownerKeypair,
       );
     } catch (e) {
-      throw Exception('Insufficient SOL balance to complete this transaction');
+      throw Exception('Insufficient SOL balance to complete this transaction: ${e.toString()}');
     }
 
     // Input by the user
diff --git a/cw_solana/pubspec.yaml b/cw_solana/pubspec.yaml
index 6b59282b4..6fd5cd97c 100644
--- a/cw_solana/pubspec.yaml
+++ b/cw_solana/pubspec.yaml
@@ -11,7 +11,7 @@ environment:
 dependencies:
   flutter:
     sdk: flutter
-  solana: ^0.30.1
+  solana: ^0.30.4
   cw_core:
     path: ../cw_core
   http: ^1.1.0
diff --git a/cw_tron/lib/tron_wallet.dart b/cw_tron/lib/tron_wallet.dart
index cb4c9c024..3566dcd94 100644
--- a/cw_tron/lib/tron_wallet.dart
+++ b/cw_tron/lib/tron_wallet.dart
@@ -349,6 +349,11 @@ abstract class TronWalletBase
         continue;
       }
 
+      // Filter out spam transaactions that involve receiving TRC10 assets transaction, we deal with TRX and TRC20 transactions
+      if (transactionModel.contracts?.first.type == "TransferAssetContract") {
+        continue;
+      }
+
       String? tokenSymbol;
       if (transactionModel.contractAddress != null) {
         final tokenAddress = TronAddress(transactionModel.contractAddress!);
diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart
index e2e7f25da..0a3de3e58 100644
--- a/lib/src/screens/send/widgets/send_card.dart
+++ b/lib/src/screens/send/widgets/send_card.dart
@@ -216,7 +216,7 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
                         onTapPicker: () => _presentPicker(context),
                         isPickerEnable: sendViewModel.hasMultipleTokens,
                         tag: sendViewModel.selectedCryptoCurrency.tag,
-                        allAmountButton: !sendViewModel.isBatchSending,
+                        allAmountButton: !sendViewModel.isBatchSending && sendViewModel.shouldDisplaySendALL,
                         currencyValueValidator: output.sendAll
                             ? sendViewModel.allAmountValidator
                             : sendViewModel.amountValidator,
diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart
index a1997e81d..d0514bb19 100644
--- a/lib/view_model/send/send_view_model.dart
+++ b/lib/view_model/send/send_view_model.dart
@@ -118,7 +118,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
   @computed
   bool get isBatchSending => outputs.length > 1;
 
-  bool get shouldDisplaySendALL => walletType != WalletType.solana || walletType != WalletType.tron;
+  bool get shouldDisplaySendALL => walletType != WalletType.solana;
 
   @computed
   String get pendingTransactionFiatAmount {
@@ -582,9 +582,15 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
   ) {
     String errorMessage = error.toString();
 
+    if (walletType == WalletType.solana) {
+      if (errorMessage.contains('insufficient funds for rent')) {
+        return S.current.insufficientFundsForRentError;
+      }
+
+      return errorMessage;
+    }
     if (walletType == WalletType.ethereum ||
         walletType == WalletType.polygon ||
-        walletType == WalletType.solana ||
         walletType == WalletType.haven) {
       if (errorMessage.contains('gas required exceeds allowance') ||
           errorMessage.contains('insufficient funds')) {
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index 435c7ccde..d543706fc 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -337,6 +337,7 @@
   "incoming": "الواردة",
   "incorrect_seed": "النص الذي تم إدخاله غير صالح.",
   "inputs": "المدخلات",
+  "insufficientFundsForRentError": "ليس لديك ما يكفي من SOL لتغطية رسوم المعاملة والإيجار للحساب. يرجى إضافة المزيد من sol إلى محفظتك أو تقليل مبلغ sol الذي ترسله",
   "introducing_cake_pay": "نقدم لكم Cake Pay!",
   "invalid_input": "مدخل غير صالح",
   "invoice_details": "تفاصيل الفاتورة",
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index 84bcabf9f..ede60567d 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -337,6 +337,7 @@
   "incoming": "Входящи",
   "incorrect_seed": "Въведеният текст е невалиден.",
   "inputs": "Входове",
+  "insufficientFundsForRentError": "Нямате достатъчно SOL, за да покриете таксата за транзакцията и наемането на сметката. Моля, добавете повече SOL към портфейла си или намалете сумата на SOL, която изпращате",
   "introducing_cake_pay": "Запознайте се с Cake Pay!",
   "invalid_input": "Невалиден вход",
   "invoice_details": "IДанни за фактура",
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index 731513bd7..8f2cda1e0 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -337,6 +337,7 @@
   "incoming": "Příchozí",
   "incorrect_seed": "Zadaný text není správný.",
   "inputs": "Vstupy",
+  "insufficientFundsForRentError": "Nemáte dostatek SOL na pokrytí transakčního poplatku a nájemného za účet. Laskavě přidejte do své peněženky více SOL nebo snižte množství Sol, kterou odesíláte",
   "introducing_cake_pay": "Představujeme Cake Pay!",
   "invalid_input": "Neplatný vstup",
   "invoice_details": "detaily faktury",
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 0f43e831d..59a23222c 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -337,6 +337,7 @@
   "incoming": "Eingehend",
   "incorrect_seed": "Der eingegebene Text ist ungültig.",
   "inputs": "Eingänge",
+  "insufficientFundsForRentError": "Sie haben nicht genug SOL, um die Transaktionsgebühr und die Miete für das Konto zu decken. Bitte fügen Sie mehr Sol zu Ihrer Brieftasche hinzu oder reduzieren Sie den von Ihnen gesendeten Sol -Betrag",
   "introducing_cake_pay": "Einführung von Cake Pay!",
   "invalid_input": "Ungültige Eingabe",
   "invoice_details": "Rechnungs-Details",
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index e4ef2119d..1bd3fc241 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -337,6 +337,7 @@
   "incoming": "Incoming",
   "incorrect_seed": "The text entered is not valid.",
   "inputs": "Inputs",
+  "insufficientFundsForRentError": "You do not have enough SOL to cover the transaction fee and rent for the account. Kindly add more SOL to your wallet or reduce the SOL amount you\\'re sending",
   "introducing_cake_pay": "Introducing Cake Pay!",
   "invalid_input": "Invalid input",
   "invoice_details": "Invoice details",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 0b7dc4a28..dc8aa3b95 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -337,6 +337,7 @@
   "incoming": "Entrante",
   "incorrect_seed": "El texto ingresado no es válido.",
   "inputs": "Entradas",
+  "insufficientFundsForRentError": "No tiene suficiente SOL para cubrir la tarifa de transacción y alquilar para la cuenta. Por favor, agregue más sol a su billetera o reduzca la cantidad de sol que está enviando",
   "introducing_cake_pay": "¡Presentamos Cake Pay!",
   "invalid_input": "Entrada inválida",
   "invoice_details": "Detalles de la factura",
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index fad9576e8..f7c45f7ef 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -337,6 +337,7 @@
   "incoming": "Entrantes",
   "incorrect_seed": "Le texte entré est invalide.",
   "inputs": "Contributions",
+  "insufficientFundsForRentError": "Vous n'avez pas assez de SOL pour couvrir les frais de transaction et le loyer pour le compte. Veuillez ajouter plus de Sol à votre portefeuille ou réduire la quantité de sol que vous envoyez",
   "introducing_cake_pay": "Présentation de Cake Pay !",
   "invalid_input": "Entrée invalide",
   "invoice_details": "Détails de la facture",
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index de963a52d..a5805bbb8 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -337,6 +337,7 @@
   "incoming": "Mai shigowa",
   "incorrect_seed": "rubutun da aka shigar ba shi da inganci.",
   "inputs": "Abubuwan da ke ciki",
+  "insufficientFundsForRentError": "Ba ku da isasshen Sol don rufe kuɗin ma'amala da haya don asusun. Da kyau ƙara ƙarin sool zuwa walat ɗinku ko rage adadin Sol ɗin da kuke aikawa",
   "introducing_cake_pay": "Gabatar da Cake Pay!",
   "invalid_input": "Shigar da ba daidai ba",
   "invoice_details": "Bayanin wadannan",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index edc301efe..4ab8e7534 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -337,6 +337,7 @@
   "incoming": "आने वाली",
   "incorrect_seed": "दर्ज किया गया पाठ मान्य नहीं है।",
   "inputs": "इनपुट",
+  "insufficientFundsForRentError": "आपके पास लेन -देन शुल्क और खाते के लिए किराए को कवर करने के लिए पर्याप्त सोल नहीं है। कृपया अपने बटुए में अधिक सोल जोड़ें या सोल राशि को कम करें जिसे आप भेज रहे हैं",
   "introducing_cake_pay": "परिचय Cake Pay!",
   "invalid_input": "अमान्य निवेश",
   "invoice_details": "चालान विवरण",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 03dfcd2a1..67095ba8f 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -337,6 +337,7 @@
   "incoming": "Dolazno",
   "incorrect_seed": "Uneseni tekst nije valjan.",
   "inputs": "Unosi",
+  "insufficientFundsForRentError": "Nemate dovoljno SOL -a za pokrivanje naknade za transakciju i najamninu za račun. Ljubazno dodajte više sol u svoj novčanik ili smanjite količinu SOL -a koju šaljete",
   "introducing_cake_pay": "Predstavljamo Cake Pay!",
   "invalid_input": "Pogrešan unos",
   "invoice_details": "Podaci o fakturi",
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index f3276ff6c..939b938fe 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -337,6 +337,7 @@
   "incoming": "Masuk",
   "incorrect_seed": "Teks yang dimasukkan tidak valid.",
   "inputs": "Input",
+  "insufficientFundsForRentError": "Anda tidak memiliki cukup SOL untuk menutupi biaya transaksi dan menyewa untuk akun tersebut. Mohon tambahkan lebih banyak sol ke dompet Anda atau kurangi jumlah sol yang Anda kirim",
   "introducing_cake_pay": "Perkenalkan Cake Pay!",
   "invalid_input": "Masukan tidak valid",
   "invoice_details": "Detail faktur",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index d021e37a3..29a142d1e 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -338,6 +338,7 @@
   "incoming": "In arrivo",
   "incorrect_seed": "Il testo inserito non è valido.",
   "inputs": "Input",
+  "insufficientFundsForRentError": "Non hai abbastanza SOL per coprire la tassa di transazione e l'affitto per il conto. Si prega di aggiungere più SOL al tuo portafoglio o ridurre l'importo SOL che stai inviando",
   "introducing_cake_pay": "Presentazione di Cake Pay!",
   "invalid_input": "Inserimento non valido",
   "invoice_details": "Dettagli della fattura",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index dd28f9688..3009aa115 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -338,6 +338,7 @@
   "incoming": "着信",
   "incorrect_seed": "入力されたテキストは無効です。",
   "inputs": "入力",
+  "insufficientFundsForRentError": "アカウントの取引料金とレンタルをカバーするのに十分なソルがありません。財布にソルを追加するか、送信するソル量を減らしてください",
   "introducing_cake_pay": "序章Cake Pay!",
   "invalid_input": "無効入力",
   "invoice_details": "請求の詳細",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 8b86c04c6..53b3cc875 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -337,6 +337,7 @@
   "incoming": "들어오는",
   "incorrect_seed": "입력하신 텍스트가 유효하지 않습니다.",
   "inputs": "입력",
+  "insufficientFundsForRentError": "거래 수수료와 계좌 임대료를 충당하기에 충분한 SOL이 없습니다. 지갑에 더 많은 솔을 추가하거나 보내는 솔을 줄이십시오.",
   "introducing_cake_pay": "소개 Cake Pay!",
   "invalid_input": "잘못된 입력",
   "invoice_details": "인보이스 세부정보",
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index 42eb54f21..64a7a1ad1 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -337,6 +337,7 @@
   "incoming": "ဝင်လာ",
   "incorrect_seed": "ထည့်သွင်းထားသော စာသားသည် မမှန်ကန်ပါ။",
   "inputs": "သွင်းငေှ",
+  "insufficientFundsForRentError": "သင်ငွေပေးချေမှုအခကြေးငွေကိုဖုံးအုပ်ရန်နှင့်အကောင့်ငှားရန်လုံလောက်သော sol ရှိသည်မဟုတ်ကြဘူး။ ကြင်နာစွာသင်၏ပိုက်ဆံအိတ်သို့ပိုမို sol ကိုပိုမိုထည့်ပါသို့မဟုတ်သင်ပို့ခြင်း sol ပမာဏကိုလျှော့ချပါ",
   "introducing_cake_pay": "Cake Pay ကို မိတ်ဆက်ခြင်း။",
   "invalid_input": "ထည့်သွင်းမှု မမှန်ကန်ပါ။",
   "invoice_details": "ပြေစာအသေးစိတ်",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index 53db56332..86f6b8c0b 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -337,6 +337,7 @@
   "incoming": "inkomend",
   "incorrect_seed": "De ingevoerde tekst is niet geldig.",
   "inputs": "Invoer",
+  "insufficientFundsForRentError": "U hebt niet genoeg SOL om de transactiekosten en huur voor de rekening te dekken. Voeg vriendelijk meer SOL toe aan uw portemonnee of verminder de SOL -hoeveelheid die u verzendt",
   "introducing_cake_pay": "Introductie van Cake Pay!",
   "invalid_input": "Ongeldige invoer",
   "invoice_details": "Factuurgegevens",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 898756982..34a8d57fe 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -337,6 +337,7 @@
   "incoming": "Przychodzące",
   "incorrect_seed": "Wprowadzony seed jest nieprawidłowy.",
   "inputs": "Wejścia",
+  "insufficientFundsForRentError": "Nie masz wystarczającej ilości SOL, aby pokryć opłatę za transakcję i czynsz za konto. Uprzejmie dodaj więcej sol do portfela lub zmniejsz solę, którą wysyłasz",
   "introducing_cake_pay": "Przedstawiamy Cake Pay!",
   "invalid_input": "Nieprawidłowe dane wejściowe",
   "invoice_details": "Dane do faktury",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 9e99866cb..67d68988f 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -337,6 +337,7 @@
   "incoming": "Recebidas",
   "incorrect_seed": "O texto digitado não é válido.",
   "inputs": "Entradas",
+  "insufficientFundsForRentError": "Você não tem Sol suficiente para cobrir a taxa de transação e o aluguel da conta. Por favor, adicione mais sol à sua carteira ou reduza a quantidade de sol que você envia",
   "introducing_cake_pay": "Apresentando o Cake Pay!",
   "invalid_input": "Entrada inválida",
   "invoice_details": "Detalhes da fatura",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index 8d3892ace..521cda83d 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -337,6 +337,7 @@
   "incoming": "Входящие",
   "incorrect_seed": "Введённый текст некорректный.",
   "inputs": "Входы",
+  "insufficientFundsForRentError": "У вас недостаточно Sol, чтобы покрыть плату за транзакцию и аренду для счета. Пожалуйста, добавьте больше Sol в свой кошелек или уменьшите сумму Sol, которую вы отправляете",
   "introducing_cake_pay": "Представляем Cake Pay!",
   "invalid_input": "Неверный Ввод",
   "invoice_details": "Детали счета",
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index 9db9caa68..996472f47 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -337,6 +337,7 @@
   "incoming": "ขาเข้า",
   "incorrect_seed": "ข้อความที่ป้อนไม่ถูกต้อง",
   "inputs": "อินพุต",
+  "insufficientFundsForRentError": "คุณไม่มีโซลเพียงพอที่จะครอบคลุมค่าธรรมเนียมการทำธุรกรรมและค่าเช่าสำหรับบัญชี กรุณาเพิ่มโซลให้มากขึ้นลงในกระเป๋าเงินของคุณหรือลดจำนวนโซลที่คุณส่งมา",
   "introducing_cake_pay": "ยินดีต้อนรับสู่ Cake Pay!",
   "invalid_input": "อินพุตไม่ถูกต้อง",
   "invoice_details": "รายละเอียดใบแจ้งหนี้",
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index 0f77f4813..27e4974bb 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -337,6 +337,7 @@
   "incoming": "Papasok",
   "incorrect_seed": "Ang teksto na ipinasok ay hindi wasto.",
   "inputs": "Mga input",
+  "insufficientFundsForRentError": "Wala kang sapat na sol upang masakop ang bayad sa transaksyon at upa para sa account. Mabait na magdagdag ng higit pa sa iyong pitaka o bawasan ang halaga ng sol na iyong ipinapadala",
   "introducing_cake_pay": "Ipinakikilala ang cake pay!",
   "invalid_input": "Di -wastong input",
   "invoice_details": "Mga detalye ng invoice",
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index 961f0cf77..74b72581e 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -337,6 +337,7 @@
   "incoming": "Gelen",
   "incorrect_seed": "Girilen metin geçerli değil.",
   "inputs": "Girişler",
+  "insufficientFundsForRentError": "İşlem ücretini karşılamak ve hesap için kiralamak için yeterli SOL'nuz yok. Lütfen cüzdanınıza daha fazla sol ekleyin veya gönderdiğiniz sol miktarını azaltın",
   "introducing_cake_pay": "Cake Pay ile tanışın!",
   "invalid_input": "Geçersiz Giriş",
   "invoice_details": "fatura detayları",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index c9cda0854..74b2e4703 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -337,6 +337,7 @@
   "incoming": "Вхідні",
   "incorrect_seed": "Введений текст невірний.",
   "inputs": "Вхoди",
+  "insufficientFundsForRentError": "У вас недостатньо SOL, щоб покрити плату за транзакцію та оренду на рахунок. Будь ласка, додайте до свого гаманця більше SOL або зменшіть суму, яку ви надсилаєте",
   "introducing_cake_pay": "Представляємо Cake Pay!",
   "invalid_input": "Неправильні дані",
   "invoice_details": "Реквізити рахунку-фактури",
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index 43cab6370..35d024188 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -337,6 +337,7 @@
   "incoming": "آنے والا",
   "incorrect_seed": "درج کردہ متن درست نہیں ہے۔",
   "inputs": "آدانوں",
+  "insufficientFundsForRentError": "آپ کے پاس ٹرانزیکشن فیس اور اکاؤنٹ کے لئے کرایہ لینے کے ل enough اتنا SOL نہیں ہے۔ برائے مہربانی اپنے بٹوے میں مزید سول شامل کریں یا آپ کو بھیجنے والی سول رقم کو کم کریں",
   "introducing_cake_pay": "Cake پے کا تعارف!",
   "invalid_input": "غلط ان پٹ",
   "invoice_details": "رسید کی تفصیلات",
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index b7d8ad828..29b8d9b71 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -338,6 +338,7 @@
   "incoming": "Wọ́n tó ń bọ̀",
   "incorrect_seed": "Ọ̀rọ̀ tí a tẹ̀ kì í ṣe èyí.",
   "inputs": "Igbewọle",
+  "insufficientFundsForRentError": "O ko ni Sol kan lati bo owo isanwo naa ki o yalo fun iroyin naa. Fi agbara kun Sol diẹ sii si apamọwọ rẹ tabi dinku soso naa ti o \\ 'tun n firanṣẹ",
   "introducing_cake_pay": "Ẹ bá Cake Pay!",
   "invalid_input": "Iṣawọle ti ko tọ",
   "invoice_details": "Iru awọn ẹya ọrọ",
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index 389cf6c24..a30acad70 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -337,6 +337,7 @@
   "incoming": "收到",
   "incorrect_seed": "输入的文字无效。",
   "inputs": "输入",
+  "insufficientFundsForRentError": "您没有足够的溶胶来支付该帐户的交易费和租金。请在钱包中添加更多溶胶或减少您发送的溶胶量",
   "introducing_cake_pay": "介绍 Cake Pay!",
   "invalid_input": "输入无效",
   "invoice_details": "发票明细",

From bbba41396d32b0fde52b6d676ee310c9fa26f639 Mon Sep 17 00:00:00 2001
From: Rafael <github@rafael.saes.dev>
Date: Sun, 11 Aug 2024 20:49:45 -0300
Subject: [PATCH 19/81] Fixes node connection, and sp, and electrum (#1577)

* refactor: remove bitcoin_flutter, update deps, electrs node improvements

* feat: connecting/disconnecting improvements, fix rescan by date, scanning message

* chore: print

* Update pubspec.yaml

* Update pubspec.yaml

* handle null sockets, retry connection on connect failure

* fix imports

* fix transaction history

* fix RBF

* minor fixes/readability enhancements [skip ci]

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
Co-authored-by: Matthew Fosse <matt@fosse.co>
---
 .../lib/bitcoin_hardware_wallet_service.dart  |   5 +-
 cw_bitcoin/lib/bitcoin_wallet.dart            |  18 +-
 cw_bitcoin/lib/bitcoin_wallet_addresses.dart  |   5 +-
 cw_bitcoin/lib/electrum.dart                  | 111 ++++---
 cw_bitcoin/lib/electrum_transaction_info.dart |   4 +-
 cw_bitcoin/lib/electrum_wallet.dart           | 295 +++++++++++-------
 cw_bitcoin/lib/electrum_wallet_addresses.dart |  30 +-
 cw_bitcoin/lib/litecoin_network.dart          |   9 -
 cw_bitcoin/lib/litecoin_wallet.dart           |   6 +-
 cw_bitcoin/lib/litecoin_wallet_addresses.dart |   6 +-
 cw_bitcoin/lib/utils.dart                     |  72 ++---
 cw_bitcoin/pubspec.lock                       |  79 ++---
 cw_bitcoin/pubspec.yaml                       |  12 +-
 .../lib/src/bitcoin_cash_wallet.dart          |  26 +-
 .../src/bitcoin_cash_wallet_addresses.dart    |   6 +-
 .../lib/src/bitcoin_cash_wallet_service.dart  |  12 +-
 cw_bitcoin_cash/lib/src/mnemonic.dart         |   2 +-
 cw_bitcoin_cash/pubspec.yaml                  |   8 +-
 cw_core/lib/get_height_by_date.dart           |   7 +-
 cw_core/lib/node.dart                         |   9 +-
 cw_core/lib/sync_status.dart                  |   5 +
 cw_core/lib/transaction_info.dart             |   5 +-
 cw_haven/pubspec.lock                         |  16 +-
 cw_monero/pubspec.lock                        |   4 +-
 cw_nano/pubspec.lock                          |  54 ++--
 cw_nano/pubspec.yaml                          |   1 +
 cw_tron/pubspec.yaml                          |   4 +-
 cw_wownero/pubspec.lock                       |  20 +-
 ios/Podfile.lock                              |  12 +-
 lib/bitcoin/cw_bitcoin.dart                   |  50 +--
 lib/core/sync_status_title.dart               |   4 +
 .../cake_pay_confirm_purchase_card_page.dart  |  48 +--
 pubspec_base.yaml                             |   6 +-
 res/values/strings_ar.arb                     |   1 +
 res/values/strings_bg.arb                     |   1 +
 res/values/strings_cs.arb                     |   1 +
 res/values/strings_de.arb                     |   1 +
 res/values/strings_en.arb                     |   1 +
 res/values/strings_es.arb                     |   1 +
 res/values/strings_fr.arb                     |   1 +
 res/values/strings_ha.arb                     |   1 +
 res/values/strings_hi.arb                     |   1 +
 res/values/strings_hr.arb                     |   1 +
 res/values/strings_id.arb                     |   1 +
 res/values/strings_it.arb                     |   1 +
 res/values/strings_ja.arb                     |   1 +
 res/values/strings_ko.arb                     |   1 +
 res/values/strings_my.arb                     |   1 +
 res/values/strings_nl.arb                     |   1 +
 res/values/strings_pl.arb                     |   1 +
 res/values/strings_pt.arb                     |   1 +
 res/values/strings_ru.arb                     |   1 +
 res/values/strings_th.arb                     |   1 +
 res/values/strings_tl.arb                     |   1 +
 res/values/strings_tr.arb                     |   1 +
 res/values/strings_uk.arb                     |   1 +
 res/values/strings_ur.arb                     |   1 +
 res/values/strings_yo.arb                     |   1 +
 res/values/strings_zh.arb                     |   1 +
 tool/configure.dart                           |   3 +-
 60 files changed, 525 insertions(+), 455 deletions(-)
 delete mode 100644 cw_bitcoin/lib/litecoin_network.dart

diff --git a/cw_bitcoin/lib/bitcoin_hardware_wallet_service.dart b/cw_bitcoin/lib/bitcoin_hardware_wallet_service.dart
index 345d645d1..de339175d 100644
--- a/cw_bitcoin/lib/bitcoin_hardware_wallet_service.dart
+++ b/cw_bitcoin/lib/bitcoin_hardware_wallet_service.dart
@@ -1,7 +1,7 @@
 import 'dart:async';
 
 import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart';
+import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:cw_bitcoin/utils.dart';
 import 'package:cw_core/hardware/hardware_account_data.dart';
 import 'package:ledger_bitcoin/ledger_bitcoin.dart';
@@ -25,7 +25,8 @@ class BitcoinHardwareWalletService {
     for (final i in indexRange) {
       final derivationPath = "m/84'/0'/$i'";
       final xpub = await bitcoinLedgerApp.getXPubKey(device, derivationPath: derivationPath);
-      HDWallet hd = HDWallet.fromBase58(xpub).derive(0);
+      Bip32Slip10Secp256k1 hd =
+          Bip32Slip10Secp256k1.fromExtendedKey(xpub).childKey(Bip32KeyIndex(0));
 
       final address = generateP2WPKHAddress(hd: hd, index: 0, network: BitcoinNetwork.mainnet);
 
diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart
index ce3e2caa8..7b8250541 100644
--- a/cw_bitcoin/lib/bitcoin_wallet.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet.dart
@@ -2,8 +2,7 @@ import 'dart:convert';
 
 import 'package:bip39/bip39.dart' as bip39;
 import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
-import 'package:convert/convert.dart';
+import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
 import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart';
@@ -51,11 +50,11 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
           password: password,
           walletInfo: walletInfo,
           unspentCoinsInfo: unspentCoinsInfo,
-          networkType: networkParam == null
-              ? bitcoin.bitcoin
+          network: networkParam == null
+              ? BitcoinNetwork.mainnet
               : networkParam == BitcoinNetwork.mainnet
-                  ? bitcoin.bitcoin
-                  : bitcoin.testnet,
+                  ? BitcoinNetwork.mainnet
+                  : BitcoinNetwork.testnet,
           initialAddresses: initialAddresses,
           initialBalance: initialBalance,
           seedBytes: seedBytes,
@@ -76,10 +75,9 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
       initialSilentAddresses: initialSilentAddresses,
       initialSilentAddressIndex: initialSilentAddressIndex,
       mainHd: hd,
-      sideHd: accountHD.derive(1),
+      sideHd: accountHD.childKey(Bip32KeyIndex(1)),
       network: networkParam ?? network,
-      masterHd:
-          seedBytes != null ? bitcoin.HDWallet.fromSeed(seedBytes, network: networkType) : null,
+      masterHd: seedBytes != null ? Bip32Slip10Secp256k1.fromSeed(seedBytes) : null,
     );
 
     autorun((_) {
@@ -253,7 +251,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
         PSBTTransactionBuild(inputs: psbtReadyInputs, outputs: outputs, enableRBF: enableRBF);
 
     final rawHex = await _bitcoinLedgerApp!.signPsbt(_ledgerDevice!, psbt: psbt.psbt);
-    return BtcTransaction.fromRaw(hex.encode(rawHex));
+    return BtcTransaction.fromRaw(BytesUtils.toHexString(rawHex));
   }
 
   @override
diff --git a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart
index 486e69b11..697719894 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart
@@ -1,5 +1,5 @@
 import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart';
+import 'package:blockchain_utils/bip/bip/bip32/bip32.dart';
 import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
 import 'package:cw_bitcoin/utils.dart';
 import 'package:cw_core/wallet_info.dart';
@@ -24,7 +24,8 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
   }) : super(walletInfo);
 
   @override
-  String getAddress({required int index, required HDWallet hd, BitcoinAddressType? addressType}) {
+  String getAddress(
+      {required int index, required Bip32Slip10Secp256k1 hd, BitcoinAddressType? addressType}) {
     if (addressType == P2pkhAddressType.p2pkh)
       return generateP2PKHAddress(hd: hd, index: index, network: network);
 
diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart
index e3925ca74..69b07d7c1 100644
--- a/cw_bitcoin/lib/electrum.dart
+++ b/cw_bitcoin/lib/electrum.dart
@@ -8,6 +8,8 @@ import 'package:cw_bitcoin/script_hash.dart';
 import 'package:flutter/foundation.dart';
 import 'package:rxdart/rxdart.dart';
 
+enum ConnectionStatus { connected, disconnected, connecting, failed }
+
 String jsonrpcparams(List<Object> params) {
   final _params = params.map((val) => '"${val.toString()}"').join(',');
   return '[$_params]';
@@ -41,7 +43,7 @@ class ElectrumClient {
 
   bool get isConnected => _isConnected;
   Socket? socket;
-  void Function(bool?)? onConnectionStatusChange;
+  void Function(ConnectionStatus)? onConnectionStatusChange;
   int _id;
   final Map<String, SocketTask> _tasks;
   Map<String, SocketTask> get tasks => _tasks;
@@ -60,17 +62,33 @@ class ElectrumClient {
   }
 
   Future<void> connect({required String host, required int port, bool? useSSL}) async {
+    _setConnectionStatus(ConnectionStatus.connecting);
+
     try {
       await socket?.close();
     } catch (_) {}
 
-    if (useSSL == false || (useSSL == null && uri.toString().contains("btc-electrum"))) {
-      socket = await Socket.connect(host, port, timeout: connectionTimeout);
-    } else {
-      socket = await SecureSocket.connect(host, port,
-          timeout: connectionTimeout, onBadCertificate: (_) => true);
+    try {
+      if (useSSL == false || (useSSL == null && uri.toString().contains("btc-electrum"))) {
+        socket = await Socket.connect(host, port, timeout: connectionTimeout);
+      } else {
+        socket = await SecureSocket.connect(
+          host,
+          port,
+          timeout: connectionTimeout,
+          onBadCertificate: (_) => true,
+        );
+      }
+    } catch (_) {
+      _setConnectionStatus(ConnectionStatus.failed);
+      return;
     }
-    _setIsConnected(true);
+
+    if (socket == null) {
+      _setConnectionStatus(ConnectionStatus.failed);
+      return;
+    }
+    _setConnectionStatus(ConnectionStatus.connected);
 
     socket!.listen((Uint8List event) {
       try {
@@ -86,13 +104,20 @@ class ElectrumClient {
         print(e.toString());
       }
     }, onError: (Object error) {
-      print(error.toString());
+      final errorMsg = error.toString();
+      print(errorMsg);
       unterminatedString = '';
-      _setIsConnected(false);
+
+      final currentHost = socket?.address.host;
+      final isErrorForCurrentHost = errorMsg.contains(" ${currentHost} ");
+
+      if (currentHost != null && isErrorForCurrentHost)
+        _setConnectionStatus(ConnectionStatus.failed);
     }, onDone: () {
       unterminatedString = '';
-      _setIsConnected(null);
+      if (host == socket?.address.host) _setConnectionStatus(ConnectionStatus.disconnected);
     });
+
     keepAlive();
   }
 
@@ -144,9 +169,9 @@ class ElectrumClient {
   Future<void> ping() async {
     try {
       await callWithTimeout(method: 'server.ping');
-      _setIsConnected(true);
+      _setConnectionStatus(ConnectionStatus.connected);
     } on RequestFailedTimeoutException catch (_) {
-      _setIsConnected(null);
+      _setConnectionStatus(ConnectionStatus.disconnected);
     }
   }
 
@@ -236,37 +261,39 @@ class ElectrumClient {
         return [];
       });
 
-  Future<Map<String, dynamic>> getTransactionRaw({required String hash}) async {
+  Future<dynamic> getTransaction({required String hash, required bool verbose}) async {
     try {
       final result = await callWithTimeout(
-          method: 'blockchain.transaction.get', params: [hash, true], timeout: 10000);
+          method: 'blockchain.transaction.get', params: [hash, verbose], timeout: 10000);
       if (result is Map<String, dynamic>) {
         return result;
       }
     } on RequestFailedTimeoutException catch (_) {
       return <String, dynamic>{};
     } catch (e) {
-      print("getTransactionRaw: ${e.toString()}");
+      print("getTransaction: ${e.toString()}");
       return <String, dynamic>{};
     }
     return <String, dynamic>{};
   }
 
-  Future<String> getTransactionHex({required String hash}) async {
-    try {
-      final result = await callWithTimeout(
-          method: 'blockchain.transaction.get', params: [hash, false], timeout: 10000);
-      if (result is String) {
-        return result;
-      }
-    } on RequestFailedTimeoutException catch (_) {
-      return '';
-    } catch (e) {
-      print("getTransactionHex: ${e.toString()}");
-      return '';
-    }
-    return '';
-  }
+  Future<Map<String, dynamic>> getTransactionVerbose({required String hash}) =>
+      getTransaction(hash: hash, verbose: true).then((dynamic result) {
+        if (result is Map<String, dynamic>) {
+          return result;
+        }
+
+        return <String, dynamic>{};
+      });
+
+  Future<String> getTransactionHex({required String hash}) =>
+      getTransaction(hash: hash, verbose: false).then((dynamic result) {
+        if (result is String) {
+          return result;
+        }
+
+        return '';
+      });
 
   Future<String> broadcastTransaction(
           {required String transactionRaw,
@@ -348,7 +375,7 @@ class ElectrumClient {
     try {
       final topDoubleString = await estimatefee(p: 1);
       final middleDoubleString = await estimatefee(p: 5);
-      final bottomDoubleString = await estimatefee(p: 100);
+      final bottomDoubleString = await estimatefee(p: 10);
       final top = (stringDoubleToBitcoinAmount(topDoubleString.toString()) / 1000).round();
       final middle = (stringDoubleToBitcoinAmount(middleDoubleString.toString()) / 1000).round();
       final bottom = (stringDoubleToBitcoinAmount(bottomDoubleString.toString()) / 1000).round();
@@ -398,6 +425,10 @@ class ElectrumClient {
   BehaviorSubject<T>? subscribe<T>(
       {required String id, required String method, List<Object> params = const []}) {
     try {
+      if (socket == null) {
+        _setConnectionStatus(ConnectionStatus.failed);
+        return null;
+      }
       final subscription = BehaviorSubject<T>();
       _regisrySubscription(id, subscription);
       socket!.write(jsonrpc(method: method, id: _id, params: params));
@@ -411,6 +442,10 @@ class ElectrumClient {
 
   Future<dynamic> call(
       {required String method, List<Object> params = const [], Function(int)? idCallback}) async {
+    if (socket == null) {
+      _setConnectionStatus(ConnectionStatus.failed);
+      return null;
+    }
     final completer = Completer<dynamic>();
     _id += 1;
     final id = _id;
@@ -424,6 +459,10 @@ class ElectrumClient {
   Future<dynamic> callWithTimeout(
       {required String method, List<Object> params = const [], int timeout = 4000}) async {
     try {
+      if (socket == null) {
+        _setConnectionStatus(ConnectionStatus.failed);
+        return null;
+      }
       final completer = Completer<dynamic>();
       _id += 1;
       final id = _id;
@@ -445,6 +484,7 @@ class ElectrumClient {
     _aliveTimer?.cancel();
     try {
       await socket?.close();
+      socket = null;
     } catch (_) {}
     onConnectionStatusChange = null;
   }
@@ -493,12 +533,9 @@ class ElectrumClient {
     }
   }
 
-  void _setIsConnected(bool? isConnected) {
-    if (_isConnected != isConnected) {
-      onConnectionStatusChange?.call(isConnected);
-    }
-
-    _isConnected = isConnected ?? false;
+  void _setConnectionStatus(ConnectionStatus status) {
+    onConnectionStatusChange?.call(status);
+    _isConnected = status == ConnectionStatus.connected;
   }
 
   void _handleResponse(Map<String, dynamic> response) {
diff --git a/cw_bitcoin/lib/electrum_transaction_info.dart b/cw_bitcoin/lib/electrum_transaction_info.dart
index d06cfe9de..ea4a3de33 100644
--- a/cw_bitcoin/lib/electrum_transaction_info.dart
+++ b/cw_bitcoin/lib/electrum_transaction_info.dart
@@ -22,7 +22,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
 
   ElectrumTransactionInfo(this.type,
       {required String id,
-      required int height,
+      int? height,
       required int amount,
       int? fee,
       List<String>? inputAddresses,
@@ -99,7 +99,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
 
   factory ElectrumTransactionInfo.fromElectrumBundle(
       ElectrumTransactionBundle bundle, WalletType type, BasedUtxoNetwork network,
-      {required Set<String> addresses, required int height}) {
+      {required Set<String> addresses, int? height}) {
     final date = bundle.time != null
         ? DateTime.fromMillisecondsSinceEpoch(bundle.time! * 1000)
         : DateTime.now();
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index e55e5ed0e..e1b038beb 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -5,7 +5,6 @@ import 'dart:isolate';
 import 'dart:math';
 
 import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
 import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:collection/collection.dart';
 import 'package:cw_bitcoin/address_from_output.dart';
@@ -22,7 +21,6 @@ import 'package:cw_bitcoin/electrum_transaction_history.dart';
 import 'package:cw_bitcoin/electrum_transaction_info.dart';
 import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
 import 'package:cw_bitcoin/exceptions.dart';
-import 'package:cw_bitcoin/litecoin_network.dart';
 import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
 import 'package:cw_bitcoin/script_hash.dart';
 import 'package:cw_bitcoin/utils.dart';
@@ -42,7 +40,6 @@ import 'package:cw_core/wallet_type.dart';
 import 'package:cw_core/get_height_by_date.dart';
 import 'package:flutter/foundation.dart';
 import 'package:hive/hive.dart';
-import 'package:http/http.dart' as http;
 import 'package:mobx/mobx.dart';
 import 'package:rxdart/subjects.dart';
 import 'package:sp_scanner/sp_scanner.dart';
@@ -60,7 +57,7 @@ abstract class ElectrumWalletBase
     required String password,
     required WalletInfo walletInfo,
     required Box<UnspentCoinsInfo> unspentCoinsInfo,
-    required this.networkType,
+    required this.network,
     String? xpub,
     String? mnemonic,
     Uint8List? seedBytes,
@@ -71,7 +68,7 @@ abstract class ElectrumWalletBase
     CryptoCurrency? currency,
     this.alwaysScan,
   })  : accountHD =
-            getAccountHDWallet(currency, networkType, seedBytes, xpub, walletInfo.derivationInfo),
+            getAccountHDWallet(currency, network, seedBytes, xpub, walletInfo.derivationInfo),
         syncStatus = NotConnectedSyncStatus(),
         _password = password,
         _feeRates = <int>[],
@@ -90,8 +87,7 @@ abstract class ElectrumWalletBase
               }
             : {}),
         this.unspentCoinsInfo = unspentCoinsInfo,
-        this.network = _getNetwork(networkType, currency),
-        this.isTestnet = networkType == bitcoin.testnet,
+        this.isTestnet = network == BitcoinNetwork.testnet,
         this._mnemonic = mnemonic,
         super(walletInfo) {
     this.electrumClient = electrumClient ?? ElectrumClient();
@@ -101,12 +97,8 @@ abstract class ElectrumWalletBase
     reaction((_) => syncStatus, _syncStatusReaction);
   }
 
-  static bitcoin.HDWallet getAccountHDWallet(
-      CryptoCurrency? currency,
-      bitcoin.NetworkType networkType,
-      Uint8List? seedBytes,
-      String? xpub,
-      DerivationInfo? derivationInfo) {
+  static Bip32Slip10Secp256k1 getAccountHDWallet(CryptoCurrency? currency, BasedUtxoNetwork network,
+      Uint8List? seedBytes, String? xpub, DerivationInfo? derivationInfo) {
     if (seedBytes == null && xpub == null) {
       throw Exception(
           "To create a Wallet you need either a seed or an xpub. This should not happen");
@@ -115,25 +107,26 @@ abstract class ElectrumWalletBase
     if (seedBytes != null) {
       return currency == CryptoCurrency.bch
           ? bitcoinCashHDWallet(seedBytes)
-          : bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
-              .derivePath(_hardenedDerivationPath(derivationInfo?.derivationPath ?? electrum_path));
+          : Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath(
+                  _hardenedDerivationPath(derivationInfo?.derivationPath ?? electrum_path))
+              as Bip32Slip10Secp256k1;
     }
 
-    return bitcoin.HDWallet.fromBase58(xpub!);
+    return Bip32Slip10Secp256k1.fromExtendedKey(xpub!);
   }
 
-  static bitcoin.HDWallet bitcoinCashHDWallet(Uint8List seedBytes) =>
-      bitcoin.HDWallet.fromSeed(seedBytes).derivePath("m/44'/145'/0'");
+  static Bip32Slip10Secp256k1 bitcoinCashHDWallet(Uint8List seedBytes) =>
+      Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath("m/44'/145'/0'") as Bip32Slip10Secp256k1;
 
   static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
       inputsCount * 68 + outputsCounts * 34 + 10;
 
   bool? alwaysScan;
 
-  final bitcoin.HDWallet accountHD;
+  final Bip32Slip10Secp256k1 accountHD;
   final String? _mnemonic;
 
-  bitcoin.HDWallet get hd => accountHD.derive(0);
+  Bip32Slip10Secp256k1 get hd => accountHD.childKey(Bip32KeyIndex(0));
   final String? passphrase;
 
   @override
@@ -165,7 +158,7 @@ abstract class ElectrumWalletBase
       .map((addr) => scriptHash(addr.address, network: network))
       .toList();
 
-  String get xpub => accountHD.base58!;
+  String get xpub => accountHD.publicKey.toExtended;
 
   @override
   String? get seed => _mnemonic;
@@ -174,7 +167,6 @@ abstract class ElectrumWalletBase
   WalletKeysData get walletKeysData =>
       WalletKeysData(mnemonic: _mnemonic, xPub: xpub, passphrase: passphrase);
 
-  bitcoin.NetworkType networkType;
   BasedUtxoNetwork network;
 
   @override
@@ -190,24 +182,21 @@ abstract class ElectrumWalletBase
   bool _isTryingToConnect = false;
 
   @action
-  Future<void> setSilentPaymentsScanning(bool active, bool usingElectrs) async {
+  Future<void> setSilentPaymentsScanning(bool active) async {
     silentPaymentsScanningActive = active;
 
     if (active) {
-      syncStatus = AttemptingSyncStatus();
+      syncStatus = StartingScanSyncStatus();
 
       final tip = await getUpdatedChainTip();
 
       if (tip == walletInfo.restoreHeight) {
         syncStatus = SyncedTipSyncStatus(tip);
+        return;
       }
 
       if (tip > walletInfo.restoreHeight) {
-        _setListeners(
-          walletInfo.restoreHeight,
-          chainTipParam: _currentChainTip,
-          usingElectrs: usingElectrs,
-        );
+        _setListeners(walletInfo.restoreHeight, chainTipParam: _currentChainTip);
       }
     } else {
       alwaysScan = false;
@@ -245,8 +234,11 @@ abstract class ElectrumWalletBase
   }
 
   @override
-  BitcoinWalletKeys get keys =>
-      BitcoinWalletKeys(wif: hd.wif!, privateKey: hd.privKey!, publicKey: hd.pubKey!);
+  BitcoinWalletKeys get keys => BitcoinWalletKeys(
+        wif: WifEncoder.encode(hd.privateKey.raw, netVer: network.wifNetVer),
+        privateKey: hd.privateKey.toHex(),
+        publicKey: hd.publicKey.toHex(),
+      );
 
   String _password;
   List<BitcoinUnspent> unspentCoins;
@@ -278,7 +270,7 @@ abstract class ElectrumWalletBase
     int height, {
     int? chainTipParam,
     bool? doSingleScan,
-    bool? usingElectrs,
+    bool? usingSupportedNode,
   }) async {
     final chainTip = chainTipParam ?? await getUpdatedChainTip();
 
@@ -287,7 +279,7 @@ abstract class ElectrumWalletBase
       return;
     }
 
-    syncStatus = AttemptingSyncStatus();
+    syncStatus = StartingScanSyncStatus();
 
     if (_isolate != null) {
       final runningIsolate = await _isolate!;
@@ -305,7 +297,9 @@ abstract class ElectrumWalletBase
           chainTip: chainTip,
           electrumClient: ElectrumClient(),
           transactionHistoryIds: transactionHistory.transactions.keys.toList(),
-          node: usingElectrs == true ? ScanNode(node!.uri, node!.useSSL) : null,
+          node: (await getNodeSupportsSilentPayments()) == true
+              ? ScanNode(node!.uri, node!.useSSL)
+              : null,
           labels: walletAddresses.labels,
           labelIndexes: walletAddresses.silentAddresses
               .where((addr) => addr.type == SilentPaymentsAddresType.p2sp && addr.index >= 1)
@@ -393,7 +387,7 @@ abstract class ElectrumWalletBase
               BigintUtils.fromBytes(BytesUtils.fromHexString(unspent.silentPaymentLabel!)),
             )
           : silentAddress.B_spend,
-      hrp: silentAddress.hrp,
+      network: network,
     );
 
     final addressRecord = walletAddresses.silentAddresses
@@ -422,8 +416,6 @@ abstract class ElectrumWalletBase
       await updateAllUnspents();
       await updateBalance();
 
-      Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
-
       if (alwaysScan == true) {
         _setListeners(walletInfo.restoreHeight);
       } else {
@@ -446,6 +438,58 @@ abstract class ElectrumWalletBase
 
   Node? node;
 
+  Future<bool> getNodeIsElectrs() async {
+    if (node == null) {
+      return false;
+    }
+
+    final version = await electrumClient.version();
+
+    if (version.isNotEmpty) {
+      final server = version[0];
+
+      if (server.toLowerCase().contains('electrs')) {
+        node!.isElectrs = true;
+        node!.save();
+        return node!.isElectrs!;
+      }
+    }
+
+
+    node!.isElectrs = false;
+    node!.save();
+    return node!.isElectrs!;
+  }
+
+  Future<bool> getNodeSupportsSilentPayments() async {
+    // As of today (august 2024), only ElectrumRS supports silent payments
+    if (!(await getNodeIsElectrs())) {
+      return false;
+    }
+
+    if (node == null) {
+      return false;
+    }
+
+    try {
+      final tweaksResponse = await electrumClient.getTweaks(height: 0);
+
+      if (tweaksResponse != null) {
+        node!.supportsSilentPayments = true;
+        node!.save();
+        return node!.supportsSilentPayments!;
+      }
+    } on RequestFailedTimeoutException catch (_) {
+      node!.supportsSilentPayments = false;
+      node!.save();
+      return node!.supportsSilentPayments!;
+    } catch (_) {}
+
+    node!.supportsSilentPayments = false;
+    node!.save();
+    return node!.supportsSilentPayments!;
+  }
+
   @action
   @override
   Future<void> connectToNode({required Node node}) async {
@@ -507,13 +551,6 @@ abstract class ElectrumWalletBase
 
       final hd =
           utx.bitcoinAddressRecord.isHidden ? walletAddresses.sideHd : walletAddresses.mainHd;
-      final derivationPath =
-          "${_hardenedDerivationPath(walletInfo.derivationInfo?.derivationPath ?? "m/0'")}"
-          "/${utx.bitcoinAddressRecord.isHidden ? "1" : "0"}"
-          "/${utx.bitcoinAddressRecord.index}";
-      final pubKeyHex = hd.derive(utx.bitcoinAddressRecord.index).pubKey!;
-
-      publicKeys[address.pubKeyHash()] = PublicKeyWithDerivationPath(pubKeyHex, derivationPath);
 
       if (utx.bitcoinAddressRecord is BitcoinSilentPaymentAddressRecord) {
         final unspentAddress = utx.bitcoinAddressRecord as BitcoinSilentPaymentAddressRecord;
@@ -530,6 +567,7 @@ abstract class ElectrumWalletBase
       }
 
       vinOutpoints.add(Outpoint(txid: utx.hash, index: utx.vout));
+      String pubKeyHex;
 
       if (privkey != null) {
         inputPrivKeyInfos.add(ECPrivateInfo(
@@ -537,8 +575,18 @@ abstract class ElectrumWalletBase
           address.type == SegwitAddresType.p2tr,
           tweak: !isSilentPayment,
         ));
+
+        pubKeyHex = privkey.getPublic().toHex();
+      } else {
+        pubKeyHex = hd.childKey(Bip32KeyIndex(utx.bitcoinAddressRecord.index)).publicKey.toHex();
       }
 
+      final derivationPath =
+          "${_hardenedDerivationPath(walletInfo.derivationInfo?.derivationPath ?? "m/0'")}"
+          "/${utx.bitcoinAddressRecord.isHidden ? "1" : "0"}"
+          "/${utx.bitcoinAddressRecord.index}";
+      publicKeys[address.pubKeyHash()] = PublicKeyWithDerivationPath(pubKeyHex, derivationPath);
+
       utxos.add(
         UtxoWithAddress(
           utxo: BitcoinUtxo(
@@ -1127,10 +1175,9 @@ abstract class ElectrumWalletBase
     int? chainTip,
     ScanData? scanData,
     bool? doSingleScan,
-    bool? usingElectrs,
   }) async {
     silentPaymentsScanningActive = true;
-    _setListeners(height, doSingleScan: doSingleScan, usingElectrs: usingElectrs);
+    _setListeners(height, doSingleScan: doSingleScan);
   }
 
   @override
@@ -1228,7 +1275,7 @@ abstract class ElectrumWalletBase
     await Future.wait(unspents.map((unspent) async {
       try {
         final coin = BitcoinUnspent.fromJSON(address, unspent);
-        final tx = await fetchTransactionInfo(hash: coin.hash, height: 0);
+        final tx = await fetchTransactionInfo(hash: coin.hash);
         coin.isChange = address.isHidden;
         coin.confirmations = tx?.confirmations;
 
@@ -1283,9 +1330,17 @@ abstract class ElectrumWalletBase
   }
 
   Future<bool> canReplaceByFee(String hash) async {
-    final verboseTransaction = await electrumClient.getTransactionRaw(hash: hash);
-    final confirmations = verboseTransaction['confirmations'] as int? ?? 0;
-    final transactionHex = verboseTransaction['hex'] as String?;
+    final verboseTransaction = await electrumClient.getTransactionVerbose(hash: hash);
+
+    final String? transactionHex;
+    int confirmations = 0;
+
+    if (verboseTransaction.isEmpty) {
+      transactionHex = await electrumClient.getTransactionHex(hash: hash);
+    } else {
+      confirmations = verboseTransaction['confirmations'] as int? ?? 0;
+      transactionHex = verboseTransaction['hex'] as String?;
+    }
 
     if (confirmations > 0) return false;
 
@@ -1293,10 +1348,7 @@ abstract class ElectrumWalletBase
       return false;
     }
 
-    final original = bitcoin.Transaction.fromHex(transactionHex);
-
-    return original.ins
-        .any((element) => element.sequence != null && element.sequence! < 4294967293);
+    return BtcTransaction.fromRaw(transactionHex).canReplaceByFee;
   }
 
   Future<bool> isChangeSufficientForFee(String txId, int newFee) async {
@@ -1455,50 +1507,73 @@ abstract class ElectrumWalletBase
     }
   }
 
-  Future<ElectrumTransactionBundle> getTransactionExpanded({required String hash}) async {
+  Future<ElectrumTransactionBundle> getTransactionExpanded(
+      {required String hash, int? height}) async {
     String transactionHex;
+    // TODO: time is not always available, and calculating it from height is not always accurate.
+    // Add settings to choose API provider and use and http server instead of electrum for this.
     int? time;
-    int confirmations = 0;
-    if (network == BitcoinNetwork.testnet) {
-      // Testnet public electrum server does not support verbose transaction fetching
+    int? confirmations;
+
+    final verboseTransaction = await electrumClient.getTransactionVerbose(hash: hash);
+
+    if (verboseTransaction.isEmpty) {
       transactionHex = await electrumClient.getTransactionHex(hash: hash);
-
-      final status = json.decode(
-          (await http.get(Uri.parse("https://blockstream.info/testnet/api/tx/$hash/status"))).body);
-
-      time = status["block_time"] as int?;
-      final height = status["block_height"] as int? ?? 0;
-      final tip = await getUpdatedChainTip();
-      if (tip > 0) confirmations = height > 0 ? tip - height + 1 : 0;
     } else {
-      final verboseTransaction = await electrumClient.getTransactionRaw(hash: hash);
-
       transactionHex = verboseTransaction['hex'] as String;
       time = verboseTransaction['time'] as int?;
-      confirmations = verboseTransaction['confirmations'] as int? ?? 0;
+      confirmations = verboseTransaction['confirmations'] as int?;
+    }
+
+    if (height != null) {
+      if (time == null) {
+        time = (getDateByBitcoinHeight(height).millisecondsSinceEpoch / 1000).round();
+      }
+
+      if (confirmations == null) {
+        final tip = await getUpdatedChainTip();
+        if (tip > 0 && height > 0) {
+          // Add one because the block itself is the first confirmation
+          confirmations = tip - height + 1;
+        }
+      }
     }
 
     final original = BtcTransaction.fromRaw(transactionHex);
     final ins = <BtcTransaction>[];
 
     for (final vin in original.inputs) {
-      ins.add(BtcTransaction.fromRaw(await electrumClient.getTransactionHex(hash: vin.txId)));
+      final verboseTransaction = await electrumClient.getTransactionVerbose(hash: vin.txId);
+
+      final String inputTransactionHex;
+
+      if (verboseTransaction.isEmpty) {
+        inputTransactionHex = await electrumClient.getTransactionHex(hash: hash);
+      } else {
+        inputTransactionHex = verboseTransaction['hex'] as String;
+      }
+
+      ins.add(BtcTransaction.fromRaw(inputTransactionHex));
     }
 
     return ElectrumTransactionBundle(
       original,
       ins: ins,
       time: time,
-      confirmations: confirmations,
+      confirmations: confirmations ?? 0,
     );
   }
 
   Future<ElectrumTransactionInfo?> fetchTransactionInfo(
-      {required String hash, required int height, bool? retryOnFailure}) async {
+      {required String hash, int? height, bool? retryOnFailure}) async {
     try {
       return ElectrumTransactionInfo.fromElectrumBundle(
-          await getTransactionExpanded(hash: hash), walletInfo.type, network,
-          addresses: addressesSet, height: height);
+        await getTransactionExpanded(hash: hash, height: height),
+        walletInfo.type,
+        network,
+        addresses: addressesSet,
+        height: height,
+      );
     } catch (e) {
       if (e is FormatException && retryOnFailure == true) {
         await Future.delayed(const Duration(seconds: 2));
@@ -1649,8 +1724,8 @@ abstract class ElectrumWalletBase
       await getCurrentChainTip();
 
       transactionHistory.transactions.values.forEach((tx) async {
-        if (tx.unspents != null && tx.unspents!.isNotEmpty && tx.height > 0) {
-          tx.confirmations = await getCurrentChainTip() - tx.height + 1;
+        if (tx.unspents != null && tx.unspents!.isNotEmpty && tx.height != null && tx.height! > 0) {
+          tx.confirmations = await getCurrentChainTip() - tx.height! + 1;
         }
       });
 
@@ -1766,8 +1841,12 @@ abstract class ElectrumWalletBase
     final index = address != null
         ? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
         : null;
-    final HD = index == null ? hd : hd.derive(index);
-    return base64Encode(HD.signMessage(message));
+    final HD = index == null ? hd : hd.childKey(Bip32KeyIndex(index));
+    final priv = ECPrivate.fromWif(
+      WifEncoder.encode(HD.privateKey.raw, netVer: network.wifNetVer),
+      netVersion: network.wifNetVer,
+    );
+    return priv.signMessage(StringUtils.encode(message));
   }
 
   Future<void> _setInitialHeight() async {
@@ -1793,43 +1872,42 @@ abstract class ElectrumWalletBase
     });
   }
 
-  static BasedUtxoNetwork _getNetwork(bitcoin.NetworkType networkType, CryptoCurrency? currency) {
-    if (networkType == bitcoin.bitcoin && currency == CryptoCurrency.bch) {
-      return BitcoinCashNetwork.mainnet;
-    }
-
-    if (networkType == litecoinNetwork) {
-      return LitecoinNetwork.mainnet;
-    }
-
-    if (networkType == bitcoin.testnet) {
-      return BitcoinNetwork.testnet;
-    }
-
-    return BitcoinNetwork.mainnet;
-  }
-
   static String _hardenedDerivationPath(String derivationPath) =>
       derivationPath.substring(0, derivationPath.lastIndexOf("'") + 1);
 
   @action
-  void _onConnectionStatusChange(bool? isConnected) {
-    if (syncStatus is SyncingSyncStatus) return;
+  void _onConnectionStatusChange(ConnectionStatus status) {
+    switch (status) {
+      case ConnectionStatus.connected:
+        if (syncStatus is NotConnectedSyncStatus ||
+            syncStatus is LostConnectionSyncStatus ||
+            syncStatus is ConnectingSyncStatus) {
+          syncStatus = AttemptingSyncStatus();
+          startSync();
+        }
 
-    if (isConnected == true && syncStatus is! SyncedSyncStatus) {
-      syncStatus = ConnectedSyncStatus();
-    } else if (isConnected == false) {
-      syncStatus = LostConnectionSyncStatus();
-    } else if (isConnected != true && syncStatus is! ConnectingSyncStatus) {
-      syncStatus = NotConnectedSyncStatus();
+        break;
+      case ConnectionStatus.disconnected:
+        syncStatus = NotConnectedSyncStatus();
+        break;
+      case ConnectionStatus.failed:
+        syncStatus = LostConnectionSyncStatus();
+        // wait for 5 seconds and then try to reconnect:
+        Future.delayed(Duration(seconds: 5), () {
+          electrumClient.connectToUri(
+            node!.uri,
+            useSSL: node!.useSSL ?? false,
+          );
+        });
+        break;
+      case ConnectionStatus.connecting:
+        syncStatus = ConnectingSyncStatus();
+        break;
+      default:
     }
   }
 
   void _syncStatusReaction(SyncStatus syncStatus) async {
-    if (syncStatus is! AttemptingSyncStatus && syncStatus is! SyncedTipSyncStatus) {
-      silentPaymentsScanningActive = syncStatus is SyncingSyncStatus;
-    }
-
     if (syncStatus is NotConnectedSyncStatus) {
       // Needs to re-subscribe to all scripthashes when reconnected
       _scripthashesUpdateSubject = {};
@@ -1950,8 +2028,8 @@ Future<void> startRefresh(ScanData scanData) async {
       final tweaks = t as Map<String, dynamic>;
 
       if (tweaks["message"] != null) {
-        // re-subscribe to continue receiving messages
-        electrumClient.tweaksSubscribe(height: syncHeight, count: count);
+        // re-subscribe to continue receiving messages, starting from the next unscanned height
+        electrumClient.tweaksSubscribe(height: syncHeight + 1, count: count);
         return;
       }
 
@@ -2180,3 +2258,4 @@ class UtxoDetails {
     required this.spendsUnconfirmedTX,
   });
 }
+
diff --git a/cw_bitcoin/lib/electrum_wallet_addresses.dart b/cw_bitcoin/lib/electrum_wallet_addresses.dart
index b39821dbb..a0424c934 100644
--- a/cw_bitcoin/lib/electrum_wallet_addresses.dart
+++ b/cw_bitcoin/lib/electrum_wallet_addresses.dart
@@ -1,5 +1,4 @@
 import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
 import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
 import 'package:cw_core/wallet_addresses.dart';
@@ -30,7 +29,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
     Map<String, int>? initialChangeAddressIndex,
     List<BitcoinSilentPaymentAddressRecord>? initialSilentAddresses,
     int initialSilentAddressIndex = 0,
-    bitcoin.HDWallet? masterHd,
+    Bip32Slip10Secp256k1? masterHd,
     BitcoinAddressType? initialAddressPageType,
   })  : _addresses = ObservableList<BitcoinAddressRecord>.of((initialAddresses ?? []).toSet()),
         addressesByReceiveType =
@@ -53,9 +52,10 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
         super(walletInfo) {
     if (masterHd != null) {
       silentAddress = SilentPaymentOwner.fromPrivateKeys(
-          b_scan: ECPrivate.fromHex(masterHd.derivePath(SCAN_PATH).privKey!),
-          b_spend: ECPrivate.fromHex(masterHd.derivePath(SPEND_PATH).privKey!),
-          hrp: network == BitcoinNetwork.testnet ? 'tsp' : 'sp');
+        b_scan: ECPrivate.fromHex(masterHd.derivePath(SCAN_PATH).privateKey.toHex()),
+        b_spend: ECPrivate.fromHex(masterHd.derivePath(SPEND_PATH).privateKey.toHex()),
+        network: network,
+      );
 
       if (silentAddresses.length == 0) {
         silentAddresses.add(BitcoinSilentPaymentAddressRecord(
@@ -92,8 +92,8 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
   final ObservableList<BitcoinAddressRecord> changeAddresses;
   final ObservableList<BitcoinSilentPaymentAddressRecord> silentAddresses;
   final BasedUtxoNetwork network;
-  final bitcoin.HDWallet mainHd;
-  final bitcoin.HDWallet sideHd;
+  final Bip32Slip10Secp256k1 mainHd;
+  final Bip32Slip10Secp256k1 sideHd;
 
   @observable
   SilentPaymentOwner? silentAddress;
@@ -318,7 +318,9 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
   }
 
   String getAddress(
-          {required int index, required bitcoin.HDWallet hd, BitcoinAddressType? addressType}) =>
+          {required int index,
+          required Bip32Slip10Secp256k1 hd,
+          BitcoinAddressType? addressType}) =>
       '';
 
   @override
@@ -540,11 +542,13 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
 
   void _validateAddresses() {
     _addresses.forEach((element) {
-      if (!element.isHidden && element.address !=
-          getAddress(index: element.index, hd: mainHd, addressType: element.type)) {
+      if (!element.isHidden &&
+          element.address !=
+              getAddress(index: element.index, hd: mainHd, addressType: element.type)) {
         element.isHidden = true;
-      } else if (element.isHidden && element.address !=
-          getAddress(index: element.index, hd: sideHd, addressType: element.type)) {
+      } else if (element.isHidden &&
+          element.address !=
+              getAddress(index: element.index, hd: sideHd, addressType: element.type)) {
         element.isHidden = false;
       }
     });
@@ -562,7 +566,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
     return _isAddressByType(addressRecord, addressPageType);
   }
 
-  bitcoin.HDWallet _getHd(bool isHidden) => isHidden ? sideHd : mainHd;
+  Bip32Slip10Secp256k1 _getHd(bool isHidden) => isHidden ? sideHd : mainHd;
   bool _isAddressByType(BitcoinAddressRecord addr, BitcoinAddressType type) => addr.type == type;
   bool _isUnusedReceiveAddressByType(BitcoinAddressRecord addr, BitcoinAddressType type) =>
       !addr.isHidden && !addr.isUsed && addr.type == type;
diff --git a/cw_bitcoin/lib/litecoin_network.dart b/cw_bitcoin/lib/litecoin_network.dart
deleted file mode 100644
index d7ad2f837..000000000
--- a/cw_bitcoin/lib/litecoin_network.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-import 'package:bitcoin_flutter/bitcoin_flutter.dart';
-
-final litecoinNetwork = NetworkType(
-    messagePrefix: '\x19Litecoin Signed Message:\n',
-    bech32: 'ltc',
-    bip32: Bip32Type(public: 0x0488b21e, private: 0x0488ade4),
-    pubKeyHash: 0x30,
-    scriptHash: 0x32,
-    wif: 0xb0);
diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index bfb9a1b16..64e53ca5d 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -1,12 +1,12 @@
 import 'package:bip39/bip39.dart' as bip39;
 import 'package:bitcoin_base/bitcoin_base.dart';
+import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
 import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
 import 'package:cw_bitcoin/electrum_balance.dart';
 import 'package:cw_bitcoin/electrum_wallet.dart';
 import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
-import 'package:cw_bitcoin/litecoin_network.dart';
 import 'package:cw_bitcoin/litecoin_wallet_addresses.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/transaction_priority.dart';
@@ -38,7 +38,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
             password: password,
             walletInfo: walletInfo,
             unspentCoinsInfo: unspentCoinsInfo,
-            networkType: litecoinNetwork,
+            network: LitecoinNetwork.mainnet,
             initialAddresses: initialAddresses,
             initialBalance: initialBalance,
             seedBytes: seedBytes,
@@ -49,7 +49,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       initialRegularAddressIndex: initialRegularAddressIndex,
       initialChangeAddressIndex: initialChangeAddressIndex,
       mainHd: hd,
-      sideHd: accountHD.derive(1),
+      sideHd: accountHD.childKey(Bip32KeyIndex(1)),
       network: network,
     );
     autorun((_) {
diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
index 99b7445fc..6945db445 100644
--- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
@@ -1,5 +1,5 @@
 import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
+import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:cw_bitcoin/utils.dart';
 import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
 import 'package:cw_core/wallet_info.dart';
@@ -22,6 +22,8 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
 
   @override
   String getAddress(
-          {required int index, required bitcoin.HDWallet hd, BitcoinAddressType? addressType}) =>
+          {required int index,
+          required Bip32Slip10Secp256k1 hd,
+          BitcoinAddressType? addressType}) =>
       generateP2WPKHAddress(hd: hd, index: index, network: network);
 }
diff --git a/cw_bitcoin/lib/utils.dart b/cw_bitcoin/lib/utils.dart
index e3ebc00db..29d7a9bf3 100644
--- a/cw_bitcoin/lib/utils.dart
+++ b/cw_bitcoin/lib/utils.dart
@@ -1,68 +1,54 @@
-import 'dart:typed_data';
 import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:flutter/foundation.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
-import 'package:bitcoin_flutter/src/payments/index.dart' show PaymentData;
-import 'package:hex/hex.dart';
-
-bitcoin.PaymentData generatePaymentData({
-  required bitcoin.HDWallet hd,
-  required int index,
-}) {
-  final pubKey = hd.derive(index).pubKey!;
-  return PaymentData(pubkey: Uint8List.fromList(HEX.decode(pubKey)));
-}
+import 'package:blockchain_utils/blockchain_utils.dart';
 
 ECPrivate generateECPrivate({
-  required bitcoin.HDWallet hd,
+  required Bip32Slip10Secp256k1 hd,
   required BasedUtxoNetwork network,
   required int index,
-}) {
-  final wif = hd.derive(index).wif!;
-  return ECPrivate.fromWif(wif, netVersion: network.wifNetVer);
-}
+}) =>
+    ECPrivate(hd.childKey(Bip32KeyIndex(index)).privateKey);
 
 String generateP2WPKHAddress({
-  required bitcoin.HDWallet hd,
+  required Bip32Slip10Secp256k1 hd,
   required BasedUtxoNetwork network,
   required int index,
-}) {
-  final pubKey = hd.derive(index).pubKey!;
-  return ECPublic.fromHex(pubKey).toP2wpkhAddress().toAddress(network);
-}
+}) =>
+    ECPublic.fromBip32(hd.childKey(Bip32KeyIndex(index)).publicKey)
+        .toP2wpkhAddress()
+        .toAddress(network);
 
 String generateP2SHAddress({
-  required bitcoin.HDWallet hd,
+  required Bip32Slip10Secp256k1 hd,
   required BasedUtxoNetwork network,
   required int index,
-}) {
-  final pubKey = hd.derive(index).pubKey!;
-  return ECPublic.fromHex(pubKey).toP2wpkhInP2sh().toAddress(network);
-}
+}) =>
+    ECPublic.fromBip32(hd.childKey(Bip32KeyIndex(index)).publicKey)
+        .toP2wshInP2sh()
+        .toAddress(network);
 
 String generateP2WSHAddress({
-  required bitcoin.HDWallet hd,
+  required Bip32Slip10Secp256k1 hd,
   required BasedUtxoNetwork network,
   required int index,
-}) {
-  final pubKey = hd.derive(index).pubKey!;
-  return ECPublic.fromHex(pubKey).toP2wshAddress().toAddress(network);
-}
+}) =>
+    ECPublic.fromBip32(hd.childKey(Bip32KeyIndex(index)).publicKey)
+        .toP2wshAddress()
+        .toAddress(network);
 
 String generateP2PKHAddress({
-  required bitcoin.HDWallet hd,
+  required Bip32Slip10Secp256k1 hd,
   required BasedUtxoNetwork network,
   required int index,
-}) {
-  final pubKey = hd.derive(index).pubKey!;
-  return ECPublic.fromHex(pubKey).toP2pkhAddress().toAddress(network);
-}
+}) =>
+    ECPublic.fromBip32(hd.childKey(Bip32KeyIndex(index)).publicKey)
+        .toP2pkhAddress()
+        .toAddress(network);
 
 String generateP2TRAddress({
-  required bitcoin.HDWallet hd,
+  required Bip32Slip10Secp256k1 hd,
   required BasedUtxoNetwork network,
   required int index,
-}) {
-  final pubKey = hd.derive(index).pubKey!;
-  return ECPublic.fromHex(pubKey).toTaprootAddress().toAddress(network);
-}
+}) =>
+    ECPublic.fromBip32(hd.childKey(Bip32KeyIndex(index)).publicKey)
+        .toTaprootAddress()
+        .toAddress(network);
diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock
index 15f7cdb43..be7862e26 100644
--- a/cw_bitcoin/pubspec.lock
+++ b/cw_bitcoin/pubspec.lock
@@ -41,15 +41,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.11.0"
-  bech32:
-    dependency: transitive
-    description:
-      path: "."
-      ref: "cake-0.2.2"
-      resolved-ref: "05755063b593aa6cca0a4820a318e0ce17de6192"
-      url: "https://github.com/cake-tech/bech32.git"
-    source: git
-    version: "0.2.2"
   bip32:
     dependency: transitive
     description:
@@ -79,29 +70,20 @@ packages:
     dependency: "direct main"
     description:
       path: "."
-      ref: cake-update-v3
-      resolved-ref: cc99eedb1d28ee9376dda0465ef72aa627ac6149
+      ref: cake-update-v4
+      resolved-ref: "574486bfcdbbaf978dcd006b46fc8716f880da29"
       url: "https://github.com/cake-tech/bitcoin_base"
     source: git
-    version: "4.2.1"
-  bitcoin_flutter:
-    dependency: "direct main"
-    description:
-      path: "."
-      ref: cake-update-v4
-      resolved-ref: e19ffb7e7977278a75b27e0479b3c6f4034223b3
-      url: "https://github.com/cake-tech/bitcoin_flutter.git"
-    source: git
-    version: "2.1.0"
+    version: "4.7.0"
   blockchain_utils:
     dependency: "direct main"
     description:
       path: "."
-      ref: cake-update-v1
-      resolved-ref: cabd7e0e16c4da9920338c76eff3aeb8af0211f3
+      ref: cake-update-v2
+      resolved-ref: "59fdf29d72068e0522a96a8953ed7272833a9f57"
       url: "https://github.com/cake-tech/blockchain_utils"
     source: git
-    version: "2.1.2"
+    version: "3.3.0"
   boolean_selector:
     dependency: transitive
     description:
@@ -411,10 +393,10 @@ packages:
     dependency: "direct main"
     description:
       name: http
-      sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
+      sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.1"
+    version: "1.2.2"
   http_multi_server:
     dependency: transitive
     description:
@@ -499,11 +481,12 @@ packages:
   ledger_flutter:
     dependency: "direct main"
     description:
-      name: ledger_flutter
-      sha256: f1680060ed6ff78f275837e0024ccaf667715a59ba7aa29fa7354bc7752e71c8
-      url: "https://pub.dev"
-    source: hosted
-    version: "1.0.1"
+      path: "."
+      ref: cake-v3
+      resolved-ref: "66469ff9dffe2417c70ae7287c9d76d2fe7157a4"
+      url: "https://github.com/cake-tech/ledger-flutter.git"
+    source: git
+    version: "1.0.2"
   ledger_usb:
     dependency: transitive
     description:
@@ -596,10 +579,10 @@ packages:
     dependency: "direct main"
     description:
       name: path_provider
-      sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161
+      sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.3"
+    version: "2.1.4"
   path_provider_android:
     dependency: transitive
     description:
@@ -636,18 +619,18 @@ packages:
     dependency: transitive
     description:
       name: path_provider_windows
-      sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
+      sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.1"
+    version: "2.3.0"
   platform:
     dependency: transitive
     description:
       name: platform
-      sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
+      sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
       url: "https://pub.dev"
     source: hosted
-    version: "3.1.4"
+    version: "3.1.5"
   plugin_platform_interface:
     dependency: transitive
     description:
@@ -700,10 +683,10 @@ packages:
     dependency: transitive
     description:
       name: pubspec_parse
-      sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
+      sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.3"
+    version: "1.3.0"
   quiver:
     dependency: transitive
     description:
@@ -761,10 +744,10 @@ packages:
     dependency: transitive
     description:
       name: socks5_proxy
-      sha256: "045cbba84f6e2b01c1c77634a63e926352bf110ef5f07fc462c6d43bbd4b6a83"
+      sha256: "616818a0ea1064a4823b53c9f7eaf8da64ed82dcd51ed71371c7e54751ed5053"
       url: "https://pub.dev"
     source: hosted
-    version: "1.0.5+dev.2"
+    version: "1.0.6"
   source_gen:
     dependency: transitive
     description:
@@ -793,9 +776,9 @@ packages:
     dependency: "direct main"
     description:
       path: "."
-      ref: "sp_v2.0.0"
-      resolved-ref: "62c152b9086cd968019128845371072f7e1168de"
-      url: "https://github.com/cake-tech/sp_scanner"
+      ref: "sp_v4.0.0"
+      resolved-ref: "3b8ae38592c0584f53560071dc18bc570758fe13"
+      url: "https://github.com/rafael-xmr/sp_scanner"
     source: git
     version: "0.0.1"
   stack_trace:
@@ -910,14 +893,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.4.5"
-  win32:
-    dependency: transitive
-    description:
-      name: win32
-      sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
-      url: "https://pub.dev"
-    source: hosted
-    version: "5.5.0"
   xdg_directories:
     dependency: transitive
     description:
diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml
index 69ff3d29b..449833220 100644
--- a/cw_bitcoin/pubspec.yaml
+++ b/cw_bitcoin/pubspec.yaml
@@ -19,10 +19,6 @@ dependencies:
   intl: ^0.18.0
   cw_core:
     path: ../cw_core
-  bitcoin_flutter:
-    git:
-      url: https://github.com/cake-tech/bitcoin_flutter.git
-      ref: cake-update-v4
   bitbox:
     git:
       url: https://github.com/cake-tech/bitbox-flutter.git
@@ -32,19 +28,19 @@ dependencies:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v3
+      ref: cake-update-v4
   blockchain_utils:
     git:
       url: https://github.com/cake-tech/blockchain_utils
-      ref: cake-update-v1
+      ref: cake-update-v2
   ledger_flutter: ^1.0.1
   ledger_bitcoin:
     git:
       url: https://github.com/cake-tech/ledger-bitcoin
   sp_scanner:
     git:
-      url: https://github.com/cake-tech/sp_scanner
-      ref: sp_v2.0.0
+      url: https://github.com/rafael-xmr/sp_scanner
+      ref: sp_v4.0.0
 
 
 dev_dependencies:
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
index f15eed10d..8323c01a8 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
@@ -1,8 +1,6 @@
-import 'dart:convert';
-
 import 'package:bitbox/bitbox.dart' as bitbox;
 import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
+import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
 import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
 import 'package:cw_bitcoin/electrum_balance.dart';
@@ -40,7 +38,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
             password: password,
             walletInfo: walletInfo,
             unspentCoinsInfo: unspentCoinsInfo,
-            networkType: bitcoin.bitcoin,
+            network: BitcoinCashNetwork.mainnet,
             initialAddresses: initialAddresses,
             initialBalance: initialBalance,
             seedBytes: seedBytes,
@@ -51,7 +49,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
       initialRegularAddressIndex: initialRegularAddressIndex,
       initialChangeAddressIndex: initialChangeAddressIndex,
       mainHd: hd,
-      sideHd: accountHD.derive(1),
+      sideHd: accountHD.childKey(Bip32KeyIndex(1)),
       network: network,
       initialAddressPageType: addressPageType,
     );
@@ -77,7 +75,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
       unspentCoinsInfo: unspentCoinsInfo,
       initialAddresses: initialAddresses,
       initialBalance: initialBalance,
-      seedBytes: await Mnemonic.toSeed(mnemonic),
+      seedBytes: await MnemonicBip39.toSeed(mnemonic),
       initialRegularAddressIndex: initialRegularAddressIndex,
       initialChangeAddressIndex: initialChangeAddressIndex,
       addressPageType: P2pkhAddressType.p2pkh,
@@ -136,15 +134,17 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
         }
       }).toList(),
       initialBalance: snp?.balance,
-      seedBytes: await Mnemonic.toSeed(keysData.mnemonic!),
+      seedBytes: await MnemonicBip39.toSeed(keysData.mnemonic!),
       initialRegularAddressIndex: snp?.regularAddressIndex,
       initialChangeAddressIndex: snp?.changeAddressIndex,
       addressPageType: P2pkhAddressType.p2pkh,
     );
   }
 
-  bitbox.ECPair generateKeyPair({required bitcoin.HDWallet hd, required int index}) =>
-      bitbox.ECPair.fromWIF(hd.derive(index).wif!);
+  bitbox.ECPair generateKeyPair({required Bip32Slip10Secp256k1 hd, required int index}) =>
+      bitbox.ECPair.fromPrivateKey(
+        Uint8List.fromList(hd.childKey(Bip32KeyIndex(index)).privateKey.raw),
+      );
 
   int calculateEstimatedFeeWithFeeRate(int feeRate, int? amount, {int? outputsCount, int? size}) {
     int inputsCount = 0;
@@ -190,7 +190,11 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
             .firstWhere((element) => element.address == AddressUtils.toLegacyAddress(address))
             .index
         : null;
-    final HD = index == null ? hd : hd.derive(index);
-    return base64Encode(HD.signMessage(message));
+    final HD = index == null ? hd : hd.childKey(Bip32KeyIndex(index));
+    final priv = ECPrivate.fromWif(
+      WifEncoder.encode(HD.privateKey.raw, netVer: network.wifNetVer),
+      netVersion: network.wifNetVer,
+    );
+    return priv.signMessage(StringUtils.encode(message));
   }
 }
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_addresses.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_addresses.dart
index d543e944c..7342dc7f5 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_addresses.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_addresses.dart
@@ -1,5 +1,5 @@
 import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
+import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
 import 'package:cw_bitcoin/utils.dart';
 import 'package:cw_core/wallet_info.dart';
@@ -23,6 +23,8 @@ abstract class BitcoinCashWalletAddressesBase extends ElectrumWalletAddresses wi
 
   @override
   String getAddress(
-          {required int index, required bitcoin.HDWallet hd, BitcoinAddressType? addressType}) =>
+          {required int index,
+          required Bip32Slip10Secp256k1 hd,
+          BitcoinAddressType? addressType}) =>
       generateP2PKHAddress(hd: hd, index: index, network: network);
 }
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
index 01ae8ace3..002e52c4f 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
@@ -11,8 +11,11 @@ import 'package:cw_core/wallet_type.dart';
 import 'package:collection/collection.dart';
 import 'package:hive/hive.dart';
 
-class BitcoinCashWalletService extends WalletService<BitcoinCashNewWalletCredentials,
-    BitcoinCashRestoreWalletFromSeedCredentials, BitcoinCashRestoreWalletFromWIFCredentials, BitcoinCashNewWalletCredentials> {
+class BitcoinCashWalletService extends WalletService<
+    BitcoinCashNewWalletCredentials,
+    BitcoinCashRestoreWalletFromSeedCredentials,
+    BitcoinCashRestoreWalletFromWIFCredentials,
+    BitcoinCashNewWalletCredentials> {
   BitcoinCashWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
 
   final Box<WalletInfo> walletInfoSource;
@@ -30,7 +33,7 @@ class BitcoinCashWalletService extends WalletService<BitcoinCashNewWalletCredent
     final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
 
     final wallet = await BitcoinCashWalletBase.create(
-        mnemonic: await Mnemonic.generate(strength: strength),
+        mnemonic: await MnemonicBip39.generate(strength: strength),
         password: credentials.password!,
         walletInfo: credentials.walletInfo!,
         unspentCoinsInfo: unspentCoinsInfoSource);
@@ -97,7 +100,8 @@ class BitcoinCashWalletService extends WalletService<BitcoinCashNewWalletCredent
 
   @override
   Future<BitcoinCashWallet> restoreFromHardwareWallet(BitcoinCashNewWalletCredentials credentials) {
-    throw UnimplementedError("Restoring a Bitcoin Cash wallet from a hardware wallet is not yet supported!");
+    throw UnimplementedError(
+        "Restoring a Bitcoin Cash wallet from a hardware wallet is not yet supported!");
   }
 
   @override
diff --git a/cw_bitcoin_cash/lib/src/mnemonic.dart b/cw_bitcoin_cash/lib/src/mnemonic.dart
index b1f1ee984..7aac1d5c4 100644
--- a/cw_bitcoin_cash/lib/src/mnemonic.dart
+++ b/cw_bitcoin_cash/lib/src/mnemonic.dart
@@ -2,7 +2,7 @@ import 'dart:typed_data';
 
 import 'package:bip39/bip39.dart' as bip39;
 
-class Mnemonic {
+class MnemonicBip39 {
   /// Generate bip39 mnemonic
   static String generate({int strength = 128}) => bip39.generateMnemonic(strength: strength);
 
diff --git a/cw_bitcoin_cash/pubspec.yaml b/cw_bitcoin_cash/pubspec.yaml
index a0ce889c1..3728bafc5 100644
--- a/cw_bitcoin_cash/pubspec.yaml
+++ b/cw_bitcoin_cash/pubspec.yaml
@@ -21,10 +21,6 @@ dependencies:
     path: ../cw_core
   cw_bitcoin:
     path: ../cw_bitcoin
-  bitcoin_flutter:
-    git:
-      url: https://github.com/cake-tech/bitcoin_flutter.git
-      ref: cake-update-v4
   bitbox:
     git:
       url: https://github.com/cake-tech/bitbox-flutter.git
@@ -32,11 +28,11 @@ dependencies:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v3
+      ref: cake-update-v4
   blockchain_utils:
     git:
       url: https://github.com/cake-tech/blockchain_utils
-      ref: cake-update-v1
+      ref: cake-update-v2
 
 dev_dependencies:
   flutter_test:
diff --git a/cw_core/lib/get_height_by_date.dart b/cw_core/lib/get_height_by_date.dart
index 6f1b4078b..204f03d62 100644
--- a/cw_core/lib/get_height_by_date.dart
+++ b/cw_core/lib/get_height_by_date.dart
@@ -245,6 +245,8 @@ Future<int> getHavenCurrentHeight() async {
 
 // Data taken from https://timechaincalendar.com/
 const bitcoinDates = {
+  "2024-08": 854889,
+  "2024-07": 850182,
   "2024-06": 846005,
   "2024-05": 841590,
   "2024-04": 837182,
@@ -371,7 +373,8 @@ const wowDates = {
 
 int getWowneroHeightByDate({required DateTime date}) {
   String closestKey =
-  wowDates.keys.firstWhere((key) => formatMapKey(key).isBefore(date), orElse: () => '');
+      wowDates.keys.firstWhere((key) => formatMapKey(key).isBefore(date), orElse: () => '');
 
   return wowDates[closestKey] ?? 0;
-}
\ No newline at end of file
+}
+
diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart
index f35ea589f..85c61de15 100644
--- a/cw_core/lib/node.dart
+++ b/cw_core/lib/node.dart
@@ -11,7 +11,8 @@ import 'package:http/io_client.dart' as ioc;
 
 part 'node.g.dart';
 
-Uri createUriFromElectrumAddress(String address, String path) => Uri.tryParse('tcp://$address$path')!;
+Uri createUriFromElectrumAddress(String address, String path) =>
+    Uri.tryParse('tcp://$address$path')!;
 
 @HiveType(typeId: Node.typeId)
 class Node extends HiveObject with Keyable {
@@ -72,6 +73,12 @@ class Node extends HiveObject with Keyable {
   @HiveField(7, defaultValue: '')
   String? path;
 
+  @HiveField(8)
+  bool? isElectrs;
+
+  @HiveField(9)
+  bool? supportsSilentPayments;
+
   bool get isSSL => useSSL ?? false;
 
   bool get useSocksProxy => socksProxyAddress == null ? false : socksProxyAddress!.isNotEmpty;
diff --git a/cw_core/lib/sync_status.dart b/cw_core/lib/sync_status.dart
index 55c31877f..ea015340c 100644
--- a/cw_core/lib/sync_status.dart
+++ b/cw_core/lib/sync_status.dart
@@ -3,6 +3,11 @@ abstract class SyncStatus {
   double progress();
 }
 
+class StartingScanSyncStatus extends SyncStatus {
+  @override
+  double progress() => 0.0;
+}
+
 class SyncingSyncStatus extends SyncStatus {
   SyncingSyncStatus(this.blocksLeft, this.ptc);
 
diff --git a/cw_core/lib/transaction_info.dart b/cw_core/lib/transaction_info.dart
index e363d88db..971e4ecdb 100644
--- a/cw_core/lib/transaction_info.dart
+++ b/cw_core/lib/transaction_info.dart
@@ -9,7 +9,7 @@ abstract class TransactionInfo extends Object with Keyable {
   late TransactionDirection direction;
   late bool isPending;
   late DateTime date;
-  late int height;
+  int? height;
   late int confirmations;
   String amountFormatted();
   String fiatAmount();
@@ -25,4 +25,5 @@ abstract class TransactionInfo extends Object with Keyable {
   dynamic get keyIndex => id;
 
   late Map<String, dynamic> additionalInfo;
-}
\ No newline at end of file
+}
+
diff --git a/cw_haven/pubspec.lock b/cw_haven/pubspec.lock
index b8583d219..c34e164f4 100644
--- a/cw_haven/pubspec.lock
+++ b/cw_haven/pubspec.lock
@@ -254,10 +254,10 @@ packages:
     dependency: transitive
     description:
       name: glob
-      sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c"
+      sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.1"
+    version: "2.1.2"
   graphs:
     dependency: transitive
     description:
@@ -514,14 +514,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.5.1"
-  process:
-    dependency: transitive
-    description:
-      name: process
-      sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
-      url: "https://pub.dev"
-    source: hosted
-    version: "4.2.4"
   pub_semver:
     dependency: transitive
     description:
@@ -707,10 +699,10 @@ packages:
     dependency: transitive
     description:
       name: xdg_directories
-      sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86
+      sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
       url: "https://pub.dev"
     source: hosted
-    version: "0.2.0+3"
+    version: "1.0.4"
   yaml:
     dependency: transitive
     description:
diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock
index 838f7224c..38299b2dc 100644
--- a/cw_monero/pubspec.lock
+++ b/cw_monero/pubspec.lock
@@ -438,8 +438,8 @@ packages:
     dependency: "direct main"
     description:
       path: "impls/monero.dart"
-      ref: "bcb328a4956105dc182afd0ce2e48fe263f5f20b"
-      resolved-ref: "bcb328a4956105dc182afd0ce2e48fe263f5f20b"
+      ref: bcb328a4956105dc182afd0ce2e48fe263f5f20b
+      resolved-ref: bcb328a4956105dc182afd0ce2e48fe263f5f20b
       url: "https://github.com/mrcyjanek/monero_c"
     source: git
     version: "0.0.0"
diff --git a/cw_nano/pubspec.lock b/cw_nano/pubspec.lock
index 70f2f6f0b..c3d4b26b6 100644
--- a/cw_nano/pubspec.lock
+++ b/cw_nano/pubspec.lock
@@ -29,10 +29,10 @@ packages:
     dependency: transitive
     description:
       name: asn1lib
-      sha256: b74e3842a52c61f8819a1ec8444b4de5419b41a7465e69d4aa681445377398b0
+      sha256: "58082b3f0dca697204dbab0ef9ff208bfaea7767ea771076af9a343488428dda"
       url: "https://pub.dev"
     source: hosted
-    version: "1.4.1"
+    version: "1.5.3"
   async:
     dependency: transitive
     description:
@@ -114,7 +114,7 @@ packages:
     source: hosted
     version: "2.4.9"
   build_runner_core:
-    dependency: transitive
+    dependency: "direct overridden"
     description:
       name: build_runner_core
       sha256: "0671ad4162ed510b70d0eb4ad6354c249f8429cab4ae7a4cec86bbc2886eb76e"
@@ -133,10 +133,10 @@ packages:
     dependency: transitive
     description:
       name: built_value
-      sha256: "598a2a682e2a7a90f08ba39c0aaa9374c5112340f0a2e275f61b59389543d166"
+      sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
       url: "https://pub.dev"
     source: hosted
-    version: "8.6.1"
+    version: "8.9.2"
   characters:
     dependency: transitive
     description:
@@ -165,10 +165,10 @@ packages:
     dependency: transitive
     description:
       name: code_builder
-      sha256: "4ad01d6e56db961d29661561effde45e519939fdaeb46c351275b182eac70189"
+      sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
       url: "https://pub.dev"
     source: hosted
-    version: "4.5.0"
+    version: "4.10.0"
   collection:
     dependency: transitive
     description:
@@ -220,10 +220,10 @@ packages:
     dependency: "direct main"
     description:
       name: ed25519_hd_key
-      sha256: "326608234e986ea826a5db4cf4cd6826058d860875a3fff7926c0725fe1a604d"
+      sha256: c5c9f11a03f5789bf9dcd9ae88d641571c802640851f1cacdb13123f171b3a26
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.0"
+    version: "2.2.1"
   encrypt:
     dependency: transitive
     description:
@@ -244,10 +244,10 @@ packages:
     dependency: transitive
     description:
       name: ffi
-      sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99
+      sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.2"
+    version: "2.1.2"
   file:
     dependency: transitive
     description:
@@ -475,10 +475,10 @@ packages:
     dependency: "direct main"
     description:
       name: mobx
-      sha256: "0afcf88b3ee9d6819890bf16c11a727fc8c62cf736fda8e5d3b9b4eace4e62ea"
+      sha256: "63920b27b32ad1910adfe767ab1750e4c212e8923232a1f891597b362074ea5e"
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.0"
+    version: "2.3.3+2"
   mobx_codegen:
     dependency: "direct dev"
     description:
@@ -572,10 +572,10 @@ packages:
     dependency: transitive
     description:
       name: pinenacl
-      sha256: e5fb0bce1717b7f136f35ee98b5c02b3e6383211f8a77ca882fa7812232a07b9
+      sha256: "3a5503637587d635647c93ea9a8fecf48a420cc7deebe6f1fc85c2a5637ab327"
       url: "https://pub.dev"
     source: hosted
-    version: "0.3.4"
+    version: "0.5.1"
   platform:
     dependency: transitive
     description:
@@ -588,10 +588,10 @@ packages:
     dependency: transitive
     description:
       name: plugin_platform_interface
-      sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd"
+      sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.5"
+    version: "2.1.8"
   pointycastle:
     dependency: transitive
     description:
@@ -652,10 +652,10 @@ packages:
     dependency: transitive
     description:
       name: shared_preferences_foundation
-      sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7"
+      sha256: "671e7a931f55a08aa45be2a13fe7247f2a41237897df434b30d2012388191833"
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.4"
+    version: "2.5.0"
   shared_preferences_linux:
     dependency: transitive
     description:
@@ -668,10 +668,10 @@ packages:
     dependency: transitive
     description:
       name: shared_preferences_platform_interface
-      sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a
+      sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.1"
+    version: "2.4.1"
   shared_preferences_web:
     dependency: transitive
     description:
@@ -849,18 +849,18 @@ packages:
     dependency: transitive
     description:
       name: win32
-      sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c"
+      sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
       url: "https://pub.dev"
     source: hosted
-    version: "4.1.4"
+    version: "5.5.0"
   xdg_directories:
     dependency: transitive
     description:
       name: xdg_directories
-      sha256: e0b1147eec179d3911f1f19b59206448f78195ca1d20514134e10641b7d7fbff
+      sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
       url: "https://pub.dev"
     source: hosted
-    version: "1.0.1"
+    version: "1.0.4"
   yaml:
     dependency: transitive
     description:
@@ -870,5 +870,5 @@ packages:
     source: hosted
     version: "3.1.2"
 sdks:
-  dart: ">=3.2.0-0 <4.0.0"
-  flutter: ">=3.7.0"
+  dart: ">=3.3.0 <4.0.0"
+  flutter: ">=3.16.6"
diff --git a/cw_nano/pubspec.yaml b/cw_nano/pubspec.yaml
index 768c1bb4e..6fae6a895 100644
--- a/cw_nano/pubspec.yaml
+++ b/cw_nano/pubspec.yaml
@@ -38,6 +38,7 @@ dev_dependencies:
 
 dependency_overrides:
   watcher: ^1.1.0
+  build_runner_core: 7.2.7+1
 
 # For information on the generic Dart part of this file, see the
 # following page: https://dart.dev/tools/pub/pubspec
diff --git a/cw_tron/pubspec.yaml b/cw_tron/pubspec.yaml
index f27e1b460..e69fd7ca0 100644
--- a/cw_tron/pubspec.yaml
+++ b/cw_tron/pubspec.yaml
@@ -18,11 +18,11 @@ dependencies:
   on_chain:
     git:
       url: https://github.com/cake-tech/On_chain
-      ref: cake-update-v1
+      ref: cake-update-v2
   blockchain_utils:
     git:
       url: https://github.com/cake-tech/blockchain_utils
-      ref: cake-update-v1
+      ref: cake-update-v2
   mobx: ^2.3.0+1
   bip39: ^1.0.6
   hive: ^2.2.3
diff --git a/cw_wownero/pubspec.lock b/cw_wownero/pubspec.lock
index d91922ac9..737743925 100644
--- a/cw_wownero/pubspec.lock
+++ b/cw_wownero/pubspec.lock
@@ -254,10 +254,10 @@ packages:
     dependency: transitive
     description:
       name: glob
-      sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c"
+      sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.1"
+    version: "2.1.2"
   graphs:
     dependency: transitive
     description:
@@ -438,8 +438,8 @@ packages:
     dependency: "direct main"
     description:
       path: "impls/monero.dart"
-      ref: "bcb328a4956105dc182afd0ce2e48fe263f5f20b"
-      resolved-ref: "bcb328a4956105dc182afd0ce2e48fe263f5f20b"
+      ref: bcb328a4956105dc182afd0ce2e48fe263f5f20b
+      resolved-ref: bcb328a4956105dc182afd0ce2e48fe263f5f20b
       url: "https://github.com/mrcyjanek/monero_c"
     source: git
     version: "0.0.0"
@@ -555,14 +555,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.5.1"
-  process:
-    dependency: transitive
-    description:
-      name: process
-      sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
-      url: "https://pub.dev"
-    source: hosted
-    version: "4.2.4"
   pub_semver:
     dependency: transitive
     description:
@@ -748,10 +740,10 @@ packages:
     dependency: transitive
     description:
       name: xdg_directories
-      sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86
+      sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
       url: "https://pub.dev"
     source: hosted
-    version: "0.2.0+3"
+    version: "1.0.4"
   yaml:
     dependency: transitive
     description:
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index fddf6e24f..fb6dc4ecf 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -94,6 +94,8 @@ PODS:
   - shared_preferences_foundation (0.0.1):
     - Flutter
     - FlutterMacOS
+  - sp_scanner (0.0.1):
+    - Flutter
   - SwiftProtobuf (1.26.0)
   - SwiftyGif (5.4.5)
   - Toast (4.1.1)
@@ -132,6 +134,7 @@ DEPENDENCIES:
   - sensitive_clipboard (from `.symlinks/plugins/sensitive_clipboard/ios`)
   - share_plus (from `.symlinks/plugins/share_plus/ios`)
   - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
+  - sp_scanner (from `.symlinks/plugins/sp_scanner/ios`)
   - uni_links (from `.symlinks/plugins/uni_links/ios`)
   - UnstoppableDomainsResolution (~> 4.0.0)
   - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
@@ -197,6 +200,8 @@ EXTERNAL SOURCES:
     :path: ".symlinks/plugins/share_plus/ios"
   shared_preferences_foundation:
     :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
+  sp_scanner:
+    :path: ".symlinks/plugins/sp_scanner/ios"
   uni_links:
     :path: ".symlinks/plugins/uni_links/ios"
   url_launcher_ios:
@@ -227,7 +232,7 @@ SPEC CHECKSUMS:
   MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
   OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
   package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
-  package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85
+  package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
   path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
   permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
   Protobuf: fb2c13674723f76ff6eede14f78847a776455fa2
@@ -235,15 +240,16 @@ SPEC CHECKSUMS:
   reactive_ble_mobile: 9ce6723d37ccf701dbffd202d487f23f5de03b4c
   SDWebImage: 066c47b573f408f18caa467d71deace7c0f8280d
   sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986
-  share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
+  share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
   shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
+  sp_scanner: eaa617fa827396b967116b7f1f43549ca62e9a12
   SwiftProtobuf: 5e8349171e7c2f88f5b9e683cb3cb79d1dc780b3
   SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
   Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
   uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
   UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841
   url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
-  wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47
+  wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1
   workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
 
 PODFILE CHECKSUM: a2fe518be61cdbdc5b0e2da085ab543d556af2d3
diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart
index a92aaad74..edfc77acb 100644
--- a/lib/bitcoin/cw_bitcoin.dart
+++ b/lib/bitcoin/cw_bitcoin.dart
@@ -302,16 +302,13 @@ class CWBitcoin extends Bitcoin {
     await electrumClient.connectToUri(node.uri, useSSL: node.useSSL);
 
     late BasedUtxoNetwork network;
-    btc.NetworkType networkType;
     switch (node.type) {
       case WalletType.litecoin:
         network = LitecoinNetwork.mainnet;
-        networkType = litecoinNetwork;
         break;
       case WalletType.bitcoin:
       default:
         network = BitcoinNetwork.mainnet;
-        networkType = btc.bitcoin;
         break;
     }
 
@@ -341,10 +338,8 @@ class CWBitcoin extends Bitcoin {
             balancePath += "/0";
           }
 
-          final hd = btc.HDWallet.fromSeed(
-            seedBytes,
-            network: networkType,
-          ).derivePath(balancePath);
+          final hd = Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath(balancePath)
+              as Bip32Slip10Secp256k1;
 
           // derive address at index 0:
           String? address;
@@ -515,10 +510,7 @@ class CWBitcoin extends Bitcoin {
   @override
   Future<void> setScanningActive(Object wallet, bool active) async {
     final bitcoinWallet = wallet as ElectrumWallet;
-    bitcoinWallet.setSilentPaymentsScanning(
-      active,
-      active && (await getNodeIsElectrsSPEnabled(wallet)),
-    );
+    bitcoinWallet.setSilentPaymentsScanning(active);
   }
 
   @override
@@ -536,44 +528,10 @@ class CWBitcoin extends Bitcoin {
     bitcoinWallet.rescan(height: height, doSingleScan: doSingleScan);
   }
 
-  Future<bool> getNodeIsElectrs(Object wallet) async {
-    final bitcoinWallet = wallet as ElectrumWallet;
-
-    final version = await bitcoinWallet.electrumClient.version();
-
-    if (version.isEmpty) {
-      return false;
-    }
-
-    final server = version[0];
-
-    if (server.toLowerCase().contains('electrs')) {
-      return true;
-    }
-
-    return false;
-  }
-
   @override
   Future<bool> getNodeIsElectrsSPEnabled(Object wallet) async {
-    if (!(await getNodeIsElectrs(wallet))) {
-      return false;
-    }
-
     final bitcoinWallet = wallet as ElectrumWallet;
-    try {
-      final tweaksResponse = await bitcoinWallet.electrumClient.getTweaks(height: 0);
-
-      if (tweaksResponse != null) {
-        return true;
-      }
-    } on RequestFailedTimeoutException catch (_) {
-      return false;
-    } catch (_) {
-      rethrow;
-    }
-
-    return false;
+    return bitcoinWallet.getNodeSupportsSilentPayments();
   }
 
   @override
diff --git a/lib/core/sync_status_title.dart b/lib/core/sync_status_title.dart
index c4cc3929f..465211f23 100644
--- a/lib/core/sync_status_title.dart
+++ b/lib/core/sync_status_title.dart
@@ -52,5 +52,9 @@ String syncStatusTitle(SyncStatus syncStatus) {
     return S.current.sync_status_syncronizing;
   }
 
+  if (syncStatus is StartingScanSyncStatus) {
+    return S.current.sync_status_starting_scan;
+  }
+
   return '';
 }
diff --git a/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart b/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart
index fd8dce103..02ddf037d 100644
--- a/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart
+++ b/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart
@@ -34,7 +34,7 @@ class CakePayBuyCardDetailPage extends BasePage {
 
   @override
   Widget? middle(BuildContext context) {
-    return  Text(
+    return Text(
       title,
       textAlign: TextAlign.center,
       maxLines: 2,
@@ -359,7 +359,7 @@ class CakePayBuyCardDetailPage extends BasePage {
     reaction((_) => cakePayPurchaseViewModel.sendViewModel.state, (ExecutionState state) {
       if (state is FailureState) {
         WidgetsBinding.instance.addPostFrameCallback((_) {
-          showStateAlert(context, S.of(context).error, state.error);
+          if (context.mounted) showStateAlert(context, S.of(context).error, state.error);
         });
       }
 
@@ -381,31 +381,35 @@ class CakePayBuyCardDetailPage extends BasePage {
   }
 
   void showStateAlert(BuildContext context, String title, String content) {
-    showPopUp<void>(
-        context: context,
-        builder: (BuildContext context) {
-          return AlertWithOneAction(
-              alertTitle: title,
-              alertContent: content,
-              buttonText: S.of(context).ok,
-              buttonAction: () => Navigator.of(context).pop());
-        });
+    if (context.mounted) {
+      showPopUp<void>(
+          context: context,
+          builder: (BuildContext context) {
+            return AlertWithOneAction(
+                alertTitle: title,
+                alertContent: content,
+                buttonText: S.of(context).ok,
+                buttonAction: () => Navigator.of(context).pop());
+          });
+    }
   }
 
   Future<void> showSentAlert(BuildContext context) async {
+    if (!context.mounted) {
+      return;
+    }
     final order = cakePayPurchaseViewModel.order!.orderId;
     final isCopy = await showPopUp<bool>(
-        context: context,
-        builder: (BuildContext context) {
-          return AlertWithTwoActions(
-              alertTitle: S.of(context).transaction_sent,
-              alertContent:
-              S.of(context).cake_pay_save_order + '\n${order}',
-              leftButtonText: S.of(context).ignor,
-              rightButtonText: S.of(context).copy,
-              actionLeftButton: () => Navigator.of(context).pop(false),
-              actionRightButton: () => Navigator.of(context).pop(true));
-        }) ??
+            context: context,
+            builder: (BuildContext context) {
+              return AlertWithTwoActions(
+                  alertTitle: S.of(context).transaction_sent,
+                  alertContent: S.of(context).cake_pay_save_order + '\n${order}',
+                  leftButtonText: S.of(context).ignor,
+                  rightButtonText: S.of(context).copy,
+                  actionLeftButton: () => Navigator.of(context).pop(false),
+                  actionRightButton: () => Navigator.of(context).pop(true));
+            }) ??
         false;
 
     if (isCopy) {
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 463c04988..90072a7c1 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -87,10 +87,6 @@ dependencies:
     git:
       url: https://github.com/cake-tech/ens_dart.git
       ref: main
-  bitcoin_flutter:
-    git:
-      url: https://github.com/cake-tech/bitcoin_flutter.git
-      ref: cake-update-v4
   fluttertoast: 8.1.4
 #  tor:
 #    git:
@@ -104,7 +100,7 @@ dependencies:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v3
+      ref: cake-update-v4
   ledger_flutter: ^1.0.1
   hashlib: 1.12.0
 
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index d543706fc..4cf9509f8 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -695,6 +695,7 @@
   "sync_status_connecting": "يتم التوصيل",
   "sync_status_failed_connect": "انقطع الاتصال",
   "sync_status_not_connected": "غير متصل",
+  "sync_status_starting_scan": "بدء المسح",
   "sync_status_starting_sync": "بدء المزامنة",
   "sync_status_syncronized": "متزامن",
   "sync_status_syncronizing": "يتم المزامنة",
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index ede60567d..b76401cf4 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -695,6 +695,7 @@
   "sync_status_connecting": "СВЪРЗВАНЕ",
   "sync_status_failed_connect": "НЕУСПЕШНО СВЪРЗВАНЕ",
   "sync_status_not_connected": "НЯМА ВРЪЗКА",
+  "sync_status_starting_scan": "Стартово сканиране",
   "sync_status_starting_sync": "ЗАПОЧВАНЕ НА СИНХРОНИЗАЦИЯ",
   "sync_status_syncronized": "СИНХРОНИЗИРАНО",
   "sync_status_syncronizing": "СИНХРОНИЗИРАНЕ",
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index 8f2cda1e0..c5d374dd0 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -695,6 +695,7 @@
   "sync_status_connecting": "PŘIPOJOVÁNÍ",
   "sync_status_failed_connect": "ODPOJENO",
   "sync_status_not_connected": "NEPŘIPOJENO",
+  "sync_status_starting_scan": "Počáteční skenování",
   "sync_status_starting_sync": "SPOUŠTĚNÍ SYNCHRONIZACE",
   "sync_status_syncronized": "SYNCHRONIZOVÁNO",
   "sync_status_syncronizing": "SYNCHRONIZUJI",
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 59a23222c..7b6613dd6 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -696,6 +696,7 @@
   "sync_status_connecting": "VERBINDEN",
   "sync_status_failed_connect": "GETRENNT",
   "sync_status_not_connected": "NICHT VERBUNDEN",
+  "sync_status_starting_scan": "Scan beginnen",
   "sync_status_starting_sync": "STARTE SYNCHRONISIERUNG",
   "sync_status_syncronized": "SYNCHRONISIERT",
   "sync_status_syncronizing": "SYNCHRONISIERE",
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 1bd3fc241..35712a780 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -696,6 +696,7 @@
   "sync_status_connecting": "CONNECTING",
   "sync_status_failed_connect": "DISCONNECTED",
   "sync_status_not_connected": "NOT CONNECTED",
+  "sync_status_starting_scan": "STARTING SCAN",
   "sync_status_starting_sync": "STARTING SYNC",
   "sync_status_syncronized": "SYNCHRONIZED",
   "sync_status_syncronizing": "SYNCHRONIZING",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index dc8aa3b95..31a6e6865 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -696,6 +696,7 @@
   "sync_status_connecting": "CONECTANDO",
   "sync_status_failed_connect": "DESCONECTADO",
   "sync_status_not_connected": "NO CONECTADO",
+  "sync_status_starting_scan": "Escaneo inicial",
   "sync_status_starting_sync": "EMPEZANDO A SINCRONIZAR",
   "sync_status_syncronized": "SINCRONIZADO",
   "sync_status_syncronizing": "SINCRONIZANDO",
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index f7c45f7ef..03d4a73dd 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -695,6 +695,7 @@
   "sync_status_connecting": "CONNEXION EN COURS",
   "sync_status_failed_connect": "DÉCONNECTÉ",
   "sync_status_not_connected": "NON CONNECTÉ",
+  "sync_status_starting_scan": "Démarrage",
   "sync_status_starting_sync": "DÉBUT DE SYNCHRO",
   "sync_status_syncronized": "SYNCHRONISÉ",
   "sync_status_syncronizing": "SYNCHRONISATION EN COURS",
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index a5805bbb8..922f9a51b 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -697,6 +697,7 @@
   "sync_status_connecting": "HADA",
   "sync_status_failed_connect": "BABU INTERNET",
   "sync_status_not_connected": "BABU INTERNET",
+  "sync_status_starting_scan": "Fara scan",
   "sync_status_starting_sync": "KWAFI",
   "sync_status_syncronized": "KYAU",
   "sync_status_syncronizing": "KWAFI",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index 4ab8e7534..db6940e8b 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -697,6 +697,7 @@
   "sync_status_connecting": "कनेक्ट",
   "sync_status_failed_connect": "डिस्कनेक्ट किया गया",
   "sync_status_not_connected": "जुड़े नहीं हैं",
+  "sync_status_starting_scan": "स्कैन शुरू करना",
   "sync_status_starting_sync": "सिताज़ा करना",
   "sync_status_syncronized": "सिंक्रनाइज़",
   "sync_status_syncronizing": "सिंक्रनाइज़ करने",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 67095ba8f..57cf1361e 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -695,6 +695,7 @@
   "sync_status_connecting": "SPAJANJE",
   "sync_status_failed_connect": "ISKLJUČENO",
   "sync_status_not_connected": "NIJE POVEZANO",
+  "sync_status_starting_scan": "Početno skeniranje",
   "sync_status_starting_sync": "ZAPOČINJEMO SINKRONIZIRANJE",
   "sync_status_syncronized": "SINKRONIZIRANO",
   "sync_status_syncronizing": "SINKRONIZIRANJE",
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index 939b938fe..97a4afd3f 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -698,6 +698,7 @@
   "sync_status_connecting": "MENGHUBUNGKAN",
   "sync_status_failed_connect": "GAGAL TERHUBUNG",
   "sync_status_not_connected": "TIDAK TERHUBUNG",
+  "sync_status_starting_scan": "Mulai pindai",
   "sync_status_starting_sync": "MULAI SINKRONISASI",
   "sync_status_syncronized": "SUDAH TERSINKRONISASI",
   "sync_status_syncronizing": "SEDANG SINKRONISASI",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index 29a142d1e..42c2e628d 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -697,6 +697,7 @@
   "sync_status_connecting": "CONNESSIONE",
   "sync_status_failed_connect": "DISCONNESSO",
   "sync_status_not_connected": "NON CONNESSO",
+  "sync_status_starting_scan": "Scansione di partenza",
   "sync_status_starting_sync": "INIZIO SINC",
   "sync_status_syncronized": "SINCRONIZZATO",
   "sync_status_syncronizing": "SINCRONIZZAZIONE",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index 3009aa115..72b1f7d09 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -696,6 +696,7 @@
   "sync_status_connecting": "接続中",
   "sync_status_failed_connect": "切断されました",
   "sync_status_not_connected": "接続されていません",
+  "sync_status_starting_scan": "スキャンを開始します",
   "sync_status_starting_sync": "同期の開始",
   "sync_status_syncronized": "同期された",
   "sync_status_syncronizing": "同期",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 53b3cc875..b8cfee1b5 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -696,6 +696,7 @@
   "sync_status_connecting": "연결 중",
   "sync_status_failed_connect": "연결 해제",
   "sync_status_not_connected": "연결되지 않은",
+  "sync_status_starting_scan": "스캔 시작",
   "sync_status_starting_sync": "동기화 시작",
   "sync_status_syncronized": "동기화",
   "sync_status_syncronizing": "동기화",
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index 64a7a1ad1..52fe72ea6 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -695,6 +695,7 @@
   "sync_status_connecting": "ချိတ်ဆက်ခြင်း။",
   "sync_status_failed_connect": "အဆက်အသွယ်ဖြတ်ထားသည်။",
   "sync_status_not_connected": "မချိတ်ဆက်ပါ။",
+  "sync_status_starting_scan": "စကင်ဖတ်စစ်ဆေးမှု",
   "sync_status_starting_sync": "စင့်ခ်လုပ်ခြင်း။",
   "sync_status_syncronized": "ထပ်တူပြုထားသည်။",
   "sync_status_syncronizing": "ထပ်တူပြုခြင်း။",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index 86f6b8c0b..cde10506f 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -695,6 +695,7 @@
   "sync_status_connecting": "AANSLUITING",
   "sync_status_failed_connect": "LOSGEKOPPELD",
   "sync_status_not_connected": "NIET VERBONDEN",
+  "sync_status_starting_scan": "Startscan",
   "sync_status_starting_sync": "BEGINNEN MET SYNCHRONISEREN",
   "sync_status_syncronized": "SYNCHRONIZED",
   "sync_status_syncronizing": "SYNCHRONISEREN",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 34a8d57fe..a22034c96 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -695,6 +695,7 @@
   "sync_status_connecting": "ŁĄCZENIE",
   "sync_status_failed_connect": "POŁĄCZENIE NIEUDANE",
   "sync_status_not_connected": "NIE POŁĄCZONY",
+  "sync_status_starting_scan": "Rozpoczęcie skanowania",
   "sync_status_starting_sync": "ROZPOCZĘCIE SYNCHRONIZACJI",
   "sync_status_syncronized": "ZSYNCHRONIZOWANO",
   "sync_status_syncronizing": "SYNCHRONIZACJA",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 67d68988f..8f87ca59f 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -697,6 +697,7 @@
   "sync_status_connecting": "CONECTANDO",
   "sync_status_failed_connect": "DESCONECTADO",
   "sync_status_not_connected": "DESCONECTADO",
+  "sync_status_starting_scan": "Diretor inicial",
   "sync_status_starting_sync": "INICIANDO SINCRONIZAÇÃO",
   "sync_status_syncronized": "SINCRONIZADO",
   "sync_status_syncronizing": "SINCRONIZANDO",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index 521cda83d..9f360137f 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -696,6 +696,7 @@
   "sync_status_connecting": "ПОДКЛЮЧЕНИЕ",
   "sync_status_failed_connect": "ОТКЛЮЧЕНО",
   "sync_status_not_connected": "НЕ ПОДКЛЮЧЁН",
+  "sync_status_starting_scan": "Начальное сканирование",
   "sync_status_starting_sync": "НАЧАЛО СИНХРОНИЗАЦИИ",
   "sync_status_syncronized": "СИНХРОНИЗИРОВАН",
   "sync_status_syncronizing": "СИНХРОНИЗАЦИЯ",
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index 996472f47..a178d2452 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -695,6 +695,7 @@
   "sync_status_connecting": "กำลังเชื่อมต่อ",
   "sync_status_failed_connect": "การเชื่อมต่อล้มเหลว",
   "sync_status_not_connected": "ไม่ได้เชื่อมต่อ",
+  "sync_status_starting_scan": "เริ่มการสแกน",
   "sync_status_starting_sync": "กำลังเริ่มซิงโครไนซ์",
   "sync_status_syncronized": "ซิงโครไนซ์แล้ว",
   "sync_status_syncronizing": "กำลังซิงโครไนซ์",
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index 27e4974bb..f49d3ddee 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -695,6 +695,7 @@
   "sync_status_connecting": "Pagkonekta",
   "sync_status_failed_connect": "Naka -disconnect",
   "sync_status_not_connected": "HINDI KONEKTADO",
+  "sync_status_starting_scan": "Simula sa pag -scan",
   "sync_status_starting_sync": "Simula sa pag -sync",
   "sync_status_syncronized": "Naka -synchronize",
   "sync_status_syncronizing": "Pag -synchronize",
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index 74b72581e..c73765f64 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -695,6 +695,7 @@
   "sync_status_connecting": "BAĞLANILIYOR",
   "sync_status_failed_connect": "BAĞLANTI KESİLDİ",
   "sync_status_not_connected": "BAĞLI DEĞİL",
+  "sync_status_starting_scan": "Başlangıç ​​taraması",
   "sync_status_starting_sync": "SENKRONİZE BAŞLATILIYOR",
   "sync_status_syncronized": "SENKRONİZE EDİLDİ",
   "sync_status_syncronizing": "SENKRONİZE EDİLİYOR",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 74b2e4703..d088dd1b2 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -696,6 +696,7 @@
   "sync_status_connecting": "ПІДКЛЮЧЕННЯ",
   "sync_status_failed_connect": "ВІДКЛЮЧЕНО",
   "sync_status_not_connected": "НЕ ПІДКЛЮЧЕННИЙ",
+  "sync_status_starting_scan": "Початок сканування",
   "sync_status_starting_sync": "ПОЧАТОК СИНХРОНІЗАЦІЇ",
   "sync_status_syncronized": "СИНХРОНІЗОВАНИЙ",
   "sync_status_syncronizing": "СИНХРОНІЗАЦІЯ",
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index 35d024188..0694463de 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -697,6 +697,7 @@
   "sync_status_connecting": "جڑ رہا ہے۔",
   "sync_status_failed_connect": "منقطع",
   "sync_status_not_connected": "منسلک نہیں",
+  "sync_status_starting_scan": "اسکین شروع کرنا",
   "sync_status_starting_sync": "مطابقت پذیری شروع کر رہا ہے۔",
   "sync_status_syncronized": "مطابقت پذیر",
   "sync_status_syncronizing": "مطابقت پذیری",
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index 29b8d9b71..87df87aca 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -696,6 +696,7 @@
   "sync_status_connecting": "Ń DÁRAPỌ̀ MỌ́",
   "sync_status_failed_connect": "ÌKÀNPỌ̀ TI KÚ",
   "sync_status_not_connected": "KÒ TI DÁRAPỌ̀ MỌ́ Ọ",
+  "sync_status_starting_scan": "Bibẹrẹ ọlọjẹ",
   "sync_status_starting_sync": "Ń BẸ̀RẸ̀ RẸ́",
   "sync_status_syncronized": "TI MÚDỌ́GBA",
   "sync_status_syncronizing": "Ń MÚDỌ́GBA",
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index a30acad70..89eca2073 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -695,6 +695,7 @@
   "sync_status_connecting": "连接中",
   "sync_status_failed_connect": "断线",
   "sync_status_not_connected": "未连接",
+  "sync_status_starting_scan": "开始扫描",
   "sync_status_starting_sync": "开始同步",
   "sync_status_syncronized": "已同步",
   "sync_status_syncronizing": "正在同步",
diff --git a/tool/configure.dart b/tool/configure.dart
index 8b5af92b2..c37946476 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -94,12 +94,11 @@ import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:hive/hive.dart';
 import 'package:ledger_flutter/ledger_flutter.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart' as btc;
+import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:bip39/bip39.dart' as bip39;
 """;
   const bitcoinCWHeaders = """
 import 'package:cw_bitcoin/utils.dart';
-import 'package:cw_bitcoin/litecoin_network.dart';
 import 'package:cw_bitcoin/electrum_derivations.dart';
 import 'package:cw_bitcoin/electrum.dart';
 import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';

From 88a57c1541e06264a3f690c4d83bb8918e29621d Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Mon, 12 Aug 2024 02:53:13 +0300
Subject: [PATCH 20/81] V4.19.2 v1.16.2 (#1591)

* refactor: remove bitcoin_flutter, update deps, electrs node improvements

* feat: connecting/disconnecting improvements, fix rescan by date, scanning message

* chore: print

* Update pubspec.yaml

* Update pubspec.yaml

* handle null sockets, retry connection on connect failure

* fix imports

* update app versions

* fix transaction history

* fix RBF

* update android build number [skip ci]

---------

Co-authored-by: Rafael Saes <git@rafael.saes.dev>
Co-authored-by: Matthew Fosse <matt@fosse.co>
---
 assets/text/Monerocom_Release_Notes.txt | 5 +++--
 assets/text/Release_Notes.txt           | 9 +++++----
 scripts/android/app_env.sh              | 8 ++++----
 scripts/ios/app_env.sh                  | 8 ++++----
 scripts/macos/app_env.sh                | 8 ++++----
 5 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt
index 2a6c07abe..c90d54524 100644
--- a/assets/text/Monerocom_Release_Notes.txt
+++ b/assets/text/Monerocom_Release_Notes.txt
@@ -1,3 +1,4 @@
-Monero enhancements
-Synchronization improvements
+Monero synchronization improvements
+Enhance error handling
+UI enhancements
 Bug fixes
\ No newline at end of file
diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt
index d17a22c84..34bca2e5e 100644
--- a/assets/text/Release_Notes.txt
+++ b/assets/text/Release_Notes.txt
@@ -1,5 +1,6 @@
-Monero and Ethereum enhancements
-Synchronization improvements
-Exchange flow enhancements
-Ledger improvements
+Wallets enhancements
+Monero synchronization improvements
+Improve wallet backups
+Enhance error handling
+UI enhancements
 Bug fixes
\ No newline at end of file
diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index a270afab0..35444dcd5 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
 APP_ANDROID_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.16.1"
-MONERO_COM_BUILD_NUMBER=95
+MONERO_COM_VERSION="1.16.2"
+MONERO_COM_BUILD_NUMBER=96
 MONERO_COM_BUNDLE_ID="com.monero.app"
 MONERO_COM_PACKAGE="com.monero.app"
 MONERO_COM_SCHEME="monero.com"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.19.1"
-CAKEWALLET_BUILD_NUMBER=221
+CAKEWALLET_VERSION="4.19.2"
+CAKEWALLET_BUILD_NUMBER=223
 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
 CAKEWALLET_SCHEME="cakewallet"
diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh
index 22daba5de..30573035a 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.16.1"
-MONERO_COM_BUILD_NUMBER=93
+MONERO_COM_VERSION="1.16.2"
+MONERO_COM_BUILD_NUMBER=94
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.19.1"
-CAKEWALLET_BUILD_NUMBER=256
+CAKEWALLET_VERSION="4.19.2"
+CAKEWALLET_BUILD_NUMBER=261
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 HAVEN_NAME="Haven"
diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh
index d46900405..2f6d51a93 100755
--- a/scripts/macos/app_env.sh
+++ b/scripts/macos/app_env.sh
@@ -16,13 +16,13 @@ if [ -n "$1" ]; then
 fi
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.6.1"
-MONERO_COM_BUILD_NUMBER=26
+MONERO_COM_VERSION="1.6.2"
+MONERO_COM_BUILD_NUMBER=27
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="1.12.1"
-CAKEWALLET_BUILD_NUMBER=82
+CAKEWALLET_VERSION="1.12.2"
+CAKEWALLET_BUILD_NUMBER=83
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then

From c1215f403284d0df224d7e2e7d98f70ebf834075 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Mon, 12 Aug 2024 10:54:43 -0700
Subject: [PATCH 21/81] dep fixes

---
 cw_bitcoin_cash/pubspec.yaml | 4 ++--
 pubspec_base.yaml            | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/cw_bitcoin_cash/pubspec.yaml b/cw_bitcoin_cash/pubspec.yaml
index 9c2561def..149777b27 100644
--- a/cw_bitcoin_cash/pubspec.yaml
+++ b/cw_bitcoin_cash/pubspec.yaml
@@ -28,7 +28,7 @@ dependencies:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-mweb
+      ref: cake-update-v5
   blockchain_utils:
     git:
       url: https://github.com/cake-tech/blockchain_utils
@@ -46,7 +46,7 @@ dependency_overrides:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-mweb
+      ref: cake-update-v5
 
 # For information on the generic Dart part of this file, see the
 # following page: https://dart.dev/tools/pub/pubspec
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 4c4df60fc..a2e804350 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -100,7 +100,7 @@ dependencies:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-mweb
+      ref: cake-update-v5
   ledger_flutter: ^1.0.1
   hashlib: 1.12.0
 
@@ -139,7 +139,7 @@ dependency_overrides:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-mweb
+      ref: cake-update-v5
 
 flutter_icons:
   image_path: "assets/images/app_logo.png"

From b686c82a44dfd5032e1de5f3b7220ac2eb7cdde2 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Mon, 12 Aug 2024 12:15:32 -0700
Subject: [PATCH 22/81] minor fix

---
 cw_bitcoin/lib/litecoin_wallet.dart | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 49401f6fd..dea91b345 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -35,7 +35,6 @@ import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:cw_mweb/cw_mweb.dart';
-import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
 
 part 'litecoin_wallet.g.dart';
 
@@ -87,7 +86,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   }
 
   late final Bip32Slip10Secp256k1 mwebHd;
-  late final bitcoin.HDWallet oldMwebHd;
   late final Box<MwebUtxo> mwebUtxosBox;
   Timer? _syncTimer;
   StreamSubscription<Utxo>? _utxoStream;
@@ -371,7 +369,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   }
 
   Future<void> processMwebUtxos() async {
-    // final scanSecret = oldMwebHd.derive(0x80000000).privKey!;
     int restoreHeight = walletInfo.restoreHeight;
     print("SCANNING FROM HEIGHT: $restoreHeight");
     final req = UtxosRequest(scanSecret: scanSecret, fromHeight: restoreHeight);

From 1809f91f0122fd4e3726da2edf2aecb2d6d7244c Mon Sep 17 00:00:00 2001
From: tuxsudo <tuxsudo@tux.pizza>
Date: Mon, 12 Aug 2024 15:17:01 -0400
Subject: [PATCH 23/81] Fix logo sizing (#1592)

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 7823734fb..6e507bfcd 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 <div align="center">
 
-<img height="100" src=".github/assets/Logo_CakeWallet.png">
+![logo](.github/assets/Logo_CakeWallet.png)
 
 </div>
 

From 3408de80d6cbc57306786dea8eec7cbd6d4687d9 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Mon, 12 Aug 2024 12:46:36 -0700
Subject: [PATCH 24/81] more merge fixes

---
 cw_bitcoin/lib/electrum_wallet.dart           |  2 +-
 cw_bitcoin/lib/electrum_wallet_addresses.dart | 20 ++++++++++---------
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 45e7b24ab..9b2b6fd7a 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -2,7 +2,6 @@ import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
 import 'dart:isolate';
-import 'dart:math';
 
 import 'package:bitcoin_base/bitcoin_base.dart';
 import 'package:blockchain_utils/blockchain_utils.dart';
@@ -21,6 +20,7 @@ import 'package:cw_bitcoin/electrum_transaction_history.dart';
 import 'package:cw_bitcoin/electrum_transaction_info.dart';
 import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
 import 'package:cw_bitcoin/exceptions.dart';
+import 'package:cw_bitcoin/litecoin_wallet.dart';
 import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
 import 'package:cw_bitcoin/script_hash.dart';
 import 'package:cw_bitcoin/utils.dart';
diff --git a/cw_bitcoin/lib/electrum_wallet_addresses.dart b/cw_bitcoin/lib/electrum_wallet_addresses.dart
index 166ec9bb3..388b3d468 100644
--- a/cw_bitcoin/lib/electrum_wallet_addresses.dart
+++ b/cw_bitcoin/lib/electrum_wallet_addresses.dart
@@ -319,16 +319,18 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
     return address;
   }
 
-  String getAddress(
-          {required int index,
-          required Bip32Slip10Secp256k1 hd,
-          BitcoinAddressType? addressType}) =>
+  String getAddress({
+    required int index,
+    required Bip32Slip10Secp256k1 hd,
+    BitcoinAddressType? addressType,
+  }) =>
       '';
 
-  Future<String> getAddressAsync(
-          {required int index,
-          required bitcoin.HDWallet hd,
-          BitcoinAddressType? addressType}) async =>
+  Future<String> getAddressAsync({
+    required int index,
+    required Bip32Slip10Secp256k1 hd,
+    BitcoinAddressType? addressType,
+  }) async =>
       getAddress(index: index, hd: hd, addressType: addressType);
 
   void addBitcoinAddressTypes() {
@@ -416,7 +418,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
         } else {
           addressesMap[address] = 'Active - P2WPKH';
         }
-        
+
         final lastMweb = _addresses.firstWhere(
             (addressRecord) => _isUnusedReceiveAddressByType(addressRecord, SegwitAddresType.mweb));
         if (lastMweb.address != address) {

From 8949db3b93c9c0b4a0c68d39b155064b24af1f05 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Mon, 12 Aug 2024 14:55:55 -0700
Subject: [PATCH 25/81] bitcoin_flutter removal fixes

---
 cw_bitcoin/lib/electrum_wallet.dart           | 14 +++++++++-----
 cw_bitcoin/lib/litecoin_wallet.dart           |  4 +---
 cw_bitcoin/lib/litecoin_wallet_addresses.dart |  5 +++--
 cw_bitcoin/pubspec.yaml                       |  5 ++++-
 4 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 9b2b6fd7a..c06435d8e 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -105,11 +105,17 @@ abstract class ElectrumWalletBase
     }
 
     if (seedBytes != null) {
-      return currency == CryptoCurrency.bch
-          ? bitcoinCashHDWallet(seedBytes)
-          : Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath(
+      switch (currency) {
+        case CryptoCurrency.btc:
+        case CryptoCurrency.ltc:
+          return Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath(
                   _hardenedDerivationPath(derivationInfo?.derivationPath ?? electrum_path))
               as Bip32Slip10Secp256k1;
+        case CryptoCurrency.bch:
+          return bitcoinCashHDWallet(seedBytes);
+        default:
+          throw Exception("Unsupported currency");
+      }
     }
 
     return Bip32Slip10Secp256k1.fromExtendedKey(xpub!);
@@ -461,7 +467,6 @@ abstract class ElectrumWalletBase
       }
     }
 
-
     node!.isElectrs = false;
     node!.save();
     return node!.isElectrs!;
@@ -2281,4 +2286,3 @@ class UtxoDetails {
     required this.spendsUnconfirmedTX,
   });
 }
-
diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index dea91b345..6d7554bab 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -1,6 +1,5 @@
 import 'dart:async';
 import 'dart:math';
-import 'package:blockchain_utils/bip/bip/bip32/base/bip32_base.dart';
 import 'package:collection/collection.dart';
 import 'package:convert/convert.dart' as convert;
 import 'package:crypto/crypto.dart';
@@ -65,7 +64,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
           seedBytes: seedBytes,
           currency: CryptoCurrency.ltc,
         ) {
-    mwebHd = Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath("m/1000") as Bip32Slip10Secp256k1;
+    mwebHd = Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath("m/1000'") as Bip32Slip10Secp256k1;
     mwebEnabled = alwaysScan ?? false;
     walletAddresses = LitecoinWalletAddresses(
       walletInfo,
@@ -84,7 +83,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       _stub = value;
     });
   }
-
   late final Bip32Slip10Secp256k1 mwebHd;
   late final Box<MwebUtxo> mwebUtxosBox;
   Timer? _syncTimer;
diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
index 7fc013211..46ab1d12a 100644
--- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
@@ -27,9 +27,10 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
   }
 
   final Bip32Slip10Secp256k1 mwebHd;
+
   List<int> get scanSecret => mwebHd.childKey(Bip32KeyIndex(0x80000000)).privateKey.privKey.raw;
-  // TODO: I'm not 100% sure if it's supposed to be the compressed or uncompressed public key!
-  List<int> get spendPubkey => mwebHd.childKey(Bip32KeyIndex(0x80000001)).publicKey.pubKey.compressed;
+  List<int> get spendPubkey =>
+      mwebHd.childKey(Bip32KeyIndex(0x80000001)).publicKey.pubKey.compressed;
 
   List<String> mwebAddrs = [];
 
diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml
index fc20cf2f9..23ce23e18 100644
--- a/cw_bitcoin/pubspec.yaml
+++ b/cw_bitcoin/pubspec.yaml
@@ -45,7 +45,6 @@ dependencies:
       url: https://github.com/rafael-xmr/sp_scanner
       ref: sp_v4.0.0
 
-
 dev_dependencies:
   flutter_test:
     sdk: flutter
@@ -66,6 +65,10 @@ dependency_overrides:
       url: https://github.com/cake-tech/bitcoin_base
       ref: cake-update-v5
 
+
+
+  pointycastle: 3.7.4
+
 # For information on the generic Dart part of this file, see the
 # following page: https://dart.dev/tools/pub/pubspec
 

From 3b635218a5bee77e9f267b1504e78cd8d786b311 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Tue, 13 Aug 2024 01:04:05 +0300
Subject: [PATCH 26/81] minor fix (#1597)

---
 ios/Podfile.lock                        | 38 +++++++++++++++++++++++++
 ios/Runner.xcodeproj/project.pbxproj    |  6 ++--
 lib/utils/exception_handler.dart        |  1 +
 scripts/android/app_env.sh              |  8 +++---
 scripts/ios/app_env.sh                  |  8 +++---
 scripts/windows/build_exe_installer.iss |  2 +-
 6 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index fb6dc4ecf..212d1ec1c 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -8,6 +8,36 @@ PODS:
     - Flutter
     - ReachabilitySwift
   - CryptoSwift (1.8.2)
+  - cw_haven (0.0.1):
+    - cw_haven/Boost (= 0.0.1)
+    - cw_haven/Haven (= 0.0.1)
+    - cw_haven/OpenSSL (= 0.0.1)
+    - cw_haven/Sodium (= 0.0.1)
+    - cw_shared_external
+    - Flutter
+  - cw_haven/Boost (0.0.1):
+    - cw_shared_external
+    - Flutter
+  - cw_haven/Haven (0.0.1):
+    - cw_shared_external
+    - Flutter
+  - cw_haven/OpenSSL (0.0.1):
+    - cw_shared_external
+    - Flutter
+  - cw_haven/Sodium (0.0.1):
+    - cw_shared_external
+    - Flutter
+  - cw_shared_external (0.0.1):
+    - cw_shared_external/Boost (= 0.0.1)
+    - cw_shared_external/OpenSSL (= 0.0.1)
+    - cw_shared_external/Sodium (= 0.0.1)
+    - Flutter
+  - cw_shared_external/Boost (0.0.1):
+    - Flutter
+  - cw_shared_external/OpenSSL (0.0.1):
+    - Flutter
+  - cw_shared_external/Sodium (0.0.1):
+    - Flutter
   - device_display_brightness (0.0.1):
     - Flutter
   - device_info_plus (0.0.1):
@@ -115,6 +145,8 @@ DEPENDENCIES:
   - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
   - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
   - CryptoSwift
+  - cw_haven (from `.symlinks/plugins/cw_haven/ios`)
+  - cw_shared_external (from `.symlinks/plugins/cw_shared_external/ios`)
   - device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`)
   - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
   - devicelocale (from `.symlinks/plugins/devicelocale/ios`)
@@ -162,6 +194,10 @@ EXTERNAL SOURCES:
     :path: ".symlinks/plugins/barcode_scan2/ios"
   connectivity_plus:
     :path: ".symlinks/plugins/connectivity_plus/ios"
+  cw_haven:
+    :path: ".symlinks/plugins/cw_haven/ios"
+  cw_shared_external:
+    :path: ".symlinks/plugins/cw_shared_external/ios"
   device_display_brightness:
     :path: ".symlinks/plugins/device_display_brightness/ios"
   device_info_plus:
@@ -216,6 +252,8 @@ SPEC CHECKSUMS:
   BigInt: f668a80089607f521586bbe29513d708491ef2f7
   connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d
   CryptoSwift: c63a805d8bb5e5538e88af4e44bb537776af11ea
+  cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a
+  cw_shared_external: 2972d872b8917603478117c9957dfca611845a92
   device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7
   device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
   devicelocale: b22617f40038496deffba44747101255cee005b0
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index 417c522a6..688fa2c39 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -483,7 +483,7 @@
 					"$(PROJECT_DIR)/Flutter",
 				);
 				MARKETING_VERSION = 1.0.1;
-				PRODUCT_BUNDLE_IDENTIFIER = "com.fotolockr.cakewallet";
+				PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
 				SWIFT_VERSION = 5.0;
@@ -629,7 +629,7 @@
 					"$(PROJECT_DIR)/Flutter",
 				);
 				MARKETING_VERSION = 1.0.1;
-				PRODUCT_BUNDLE_IDENTIFIER = "com.fotolockr.cakewallet";
+				PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
 				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -667,7 +667,7 @@
 					"$(PROJECT_DIR)/Flutter",
 				);
 				MARKETING_VERSION = 1.0.1;
-				PRODUCT_BUNDLE_IDENTIFIER = "com.fotolockr.cakewallet";
+				PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
 				SWIFT_VERSION = 5.0;
diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart
index 6045c0004..5e0c83f88 100644
--- a/lib/utils/exception_handler.dart
+++ b/lib/utils/exception_handler.dart
@@ -173,6 +173,7 @@ class ExceptionHandler {
     "OS Error: Network is unreachable",
     "ClientException: Write failed, uri=http",
     "Connection terminated during handshake",
+    "Corrupted wallets seeds",
   ];
 
   static Future<void> _addDeviceInfo(File file) async {
diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index 35444dcd5..c91f24622 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
 APP_ANDROID_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.16.2"
-MONERO_COM_BUILD_NUMBER=96
+MONERO_COM_VERSION="1.16.3"
+MONERO_COM_BUILD_NUMBER=97
 MONERO_COM_BUNDLE_ID="com.monero.app"
 MONERO_COM_PACKAGE="com.monero.app"
 MONERO_COM_SCHEME="monero.com"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.19.2"
-CAKEWALLET_BUILD_NUMBER=223
+CAKEWALLET_VERSION="4.19.3"
+CAKEWALLET_BUILD_NUMBER=224
 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
 CAKEWALLET_SCHEME="cakewallet"
diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh
index 30573035a..e32b3e9f3 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.16.2"
-MONERO_COM_BUILD_NUMBER=94
+MONERO_COM_VERSION="1.16.3"
+MONERO_COM_BUILD_NUMBER=95
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.19.2"
-CAKEWALLET_BUILD_NUMBER=261
+CAKEWALLET_VERSION="4.19.3"
+CAKEWALLET_BUILD_NUMBER=262
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 HAVEN_NAME="Haven"
diff --git a/scripts/windows/build_exe_installer.iss b/scripts/windows/build_exe_installer.iss
index ef26941d7..216f367ca 100644
--- a/scripts/windows/build_exe_installer.iss
+++ b/scripts/windows/build_exe_installer.iss
@@ -1,5 +1,5 @@
 #define MyAppName "Cake Wallet"
-#define MyAppVersion "0.0.3"
+#define MyAppVersion "0.0.4"
 #define MyAppPublisher "Cake Labs LLC"
 #define MyAppURL "https://cakewallet.com/"
 #define MyAppExeName "CakeWallet.exe"

From 1ce60d62b3121cfbd6b882c041283556c2c7bca7 Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Tue, 13 Aug 2024 00:18:14 +0200
Subject: [PATCH 27/81] CW-676 Add Linux scripts to build monero_c for linux
 platform (#1527)

* Revert "Revert btc address types"

This reverts commit a49e57e3

* Re-add Bitcoin Address types
Fix conflicts with main

* fix: label issues, clear spent utxo

* chore: deps

* fix: build

* fix: missing types

* feat: new electrs API & changes, fixes for last block scanning

* Update Monero

* not sure why it's failing

* Enable Exolix
Improve service updates indicator
New versions

* Add exolix Api token to limits api

* Ignore reporting network issues

* Change default bitcoin node

* Merge main and update linux version

* Update app version [skip ci]

* New versions

* Fix conflicts and update linux version

* minor fix

* feat: Scan Silent Payments homepage toggle

* chore: build configure

* feat: generic fixes, testnet UI improvements, useSSL on bitcoin nodes

* fix: invalid Object in sendData

* feat: improve addresses page & address book displays

* feat: silent payments labeled addresses disclaimer

* fix: missing i18n

* chore: print

* feat: single block scan, rescan by date working for btc mainnet

* feat: new cake features page replace market page, move sp scan toggle, auto switch node pop up alert

* feat: delete silent addresses

* fix: red dot in non ssl nodes

* fix: inconsistent connection states, fix tx history

* fix: tx & balance displays, cpfp sending

* feat: new rust lib

* chore: node path

* fix: check node based on network

* fix: missing txcount from addresses

* style: padding in feature page cards

* fix: restore not getting all wallet addresses by type

* fix: auto switch node broken

* fix: silent payment txs not being restored

* update linux version

* feat: change scanning to subscription model, sync improvements

* fix: scan re-subscription

* fix: default nodes

* fix: improve scanning by date, fix single block scan

* refactor: common function for input tx selection

* various fixes for build issues

* initial monero.dart implementation

* ...

* multiple wallets
new lib
minor fixes

* other fixes from monero.dart and monero_c

* fix: nodes & build

* update build scripts
fix polyseed

* remove unnecessary code

* Add windows app, build scripts and build guide for it.

* Minor fix in generated monero configs

* Merge and fix main

* fix: send all with multiple outs

* add missing monero_c command

* add android build script

* update version

* Merge and fix main

* undo android ndk removal

* Fix modified exception_handler.dart

* Temporarily remove haven

* fix build issues

* fix pr script

* Fixes for build monero.dart (monero_c) for windows.

* monero build script

* wip: ios build script

* refactor: unchanged file

* Added build guides for iOS and macOS. Replaced nproc call on macOS. Added macOS configuration for configure_cake_wallet.sh script.

* Update monero.dart and monero_c versions.

* Add missed windows build scripts

* Update the application configuration for windows build script.

* Update cw_monero pubspec lock file for monero.dart

* Update pr_test_build.yml

* chore: upgrade

* chore: merge changes

* refactor: unchanged files [skip ci]

* Fix conflicts with main

* fix for multiple wallets

* update app version [skip ci]

* Add tron to windows application configuration.

* Add macOS option for description message in configure_cake_wallet.sh

* fix missing encryption utils in hardware wallet functions [skip ci]

* fix conflicts

* Include missed monero dll for windows.

* reformatting [skip ci]

* fix conflicts with main

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

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

* add missing nano secrets file [skip ci]

* ios library

* don't pull prebuilds android

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

* remove tron

* feat: sync fixes, sp settings

* feat: fix resyncing

* store crash fix

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

* fix monero_c build issues

* libstdc++

* merge main and update version

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

* update pubspec.lock

* fix build script

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

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

* fix: params

* feat: electrum migration if using cake electrum

* fix nodes
update versions

* re-enable tron

* update sp_scanner to work on iOS [skip ci]

* bump monero_c hash

* bump monero_c commit

* bump moneroc version

* bump monero_c commit

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

* fix: wrong socket for old electrum nodes

* update version

* Fix unchecked wallet type call

* get App Dir correctly in default_settings_migration.dart

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

* backup fix

* fix NTFS issues

* Add Tron
Update Linux version

* Close the wallet when the wallet gets changed

* fix: double balance

* feat: node domain

* fix: menu name

* bump monero_c commit

* fix: update tip on set scanning

* fix: connection switching back and forth

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

* chore: fix build

* minor enhancements

* fixes and enhancements

* solve conflicts with main

* Only stop wallet on rename and delete

* fix: status toggle

* minor enhancement

* Monero.com fixes

* bump monero_c commit

* update sp_scanner to include windows and linux

* merge main

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

* fix: Tron file write, build scripts

* - merge linux with Monero Dart
- Temporarily disable Monero

* fix other issues with linux

* linux ci
fix build script

* Update pr_test_build_linux.yml

install required packages

* add linux desktop dependencies

* don't use apk in linux build releases

* don't copy the file to test-apk

* fix linux runtime issues

* remove libc++_shared.so

* fix issues with linux

* prepare both android and linux (because otherwise it will fail)

* ci script updates

* run apt update

* bump image to ubuntu 22.04
note: remember to put it down later

* bump python version

* remove some dependencies

* remove unused import

* add missing dependencies

* fix dependencies

* some fixes

* remove print [skip ci]

* Add back RunnerBase.entitlements
minor fixes [skip ci]

* fix memory leak / infinite recurrsion when opening xmr wallet

* url_launcher_linux: 3.1.1 # https://github.com/flutter/flutter/issues/153083

* fix conflicts with main

* handle walletKeysFile with encryptionUtils

* update app version [skip ci]

* add wownero [skip ci]

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
Co-authored-by: Rafael Saes <git@rafael.saes.dev>
Co-authored-by: M <m@cakewallet.com>
Co-authored-by: Konstantin Ullrich <konstantinullrich12@gmail.com>
---
 .github/workflows/cache_dependencies.yml      |   2 +-
 ...st_build.yml => pr_test_build_android.yml} |   4 +-
 .github/workflows/pr_test_build_linux.yml     | 186 ++++++++++++
 .gitignore                                    |   2 +
 .metadata                                     |   6 +
 build-guide-linux.md                          | 176 ++++++++++++
 com.cakewallet.CakeWallet.yml                 |  35 +++
 configure_cake_wallet.sh                      |  14 +-
 cw_bitcoin/lib/bitcoin_wallet.dart            |  31 +-
 .../bitcoin_wallet_creation_credentials.dart  |   2 +
 cw_bitcoin/lib/bitcoin_wallet_service.dart    |  10 +-
 .../lib/electrum_transaction_history.dart     |  11 +-
 cw_bitcoin/lib/electrum_wallet.dart           |  22 +-
 cw_bitcoin/lib/electrum_wallet_snapshot.dart  |   5 +-
 cw_bitcoin/lib/litecoin_wallet.dart           |  36 ++-
 cw_bitcoin/lib/litecoin_wallet_service.dart   |  84 +++---
 cw_bitcoin/pubspec.lock                       |  25 ++
 .../lib/src/bitcoin_cash_wallet.dart          |  23 +-
 ...coin_cash_wallet_creation_credentials.dart |   4 +-
 .../lib/src/bitcoin_cash_wallet_service.dart  |  27 +-
 cw_core/lib/encryption_file_utils.dart        |  42 +++
 cw_core/lib/wallet_base.dart                  |   2 +
 cw_core/lib/wallet_keys_file.dart             |  31 +-
 cw_core/pubspec.lock                          |  33 +++
 cw_core/pubspec.yaml                          |   5 +
 .../lib/ethereum_transaction_history.dart     |   1 +
 cw_ethereum/lib/ethereum_wallet.dart          |  27 +-
 cw_ethereum/lib/ethereum_wallet_service.dart  |  15 +-
 cw_evm/lib/evm_chain_transaction_history.dart |  10 +-
 cw_evm/lib/evm_chain_wallet.dart              |  21 +-
 ...evm_chain_wallet_creation_credentials.dart |   4 +-
 cw_evm/lib/evm_chain_wallet_service.dart      |   3 +-
 cw_evm/lib/file.dart                          |  39 ---
 cw_evm/pubspec.yaml                           |   1 +
 cw_haven/lib/haven_wallet.dart                |   9 +-
 cw_haven/pubspec.lock                         |  33 +++
 cw_monero/.metadata                           |   3 +
 cw_monero/example/linux/.gitignore            |   1 +
 cw_monero/example/linux/CMakeLists.txt        | 138 +++++++++
 .../example/linux/flutter/CMakeLists.txt      |  88 ++++++
 .../flutter/generated_plugin_registrant.cc    |  15 +
 .../flutter/generated_plugin_registrant.h     |  15 +
 .../linux/flutter/generated_plugins.cmake     |  24 ++
 cw_monero/example/linux/main.cc               |   6 +
 cw_monero/example/linux/my_application.cc     | 104 +++++++
 cw_monero/example/linux/my_application.h      |  18 ++
 cw_monero/lib/api/account_list.dart           |   1 -
 cw_monero/lib/api/wallet_manager.dart         |   2 +
 cw_monero/lib/monero_wallet.dart              |  10 +-
 cw_monero/lib/monero_wallet_service.dart      |  57 +++-
 cw_monero/linux/CMakeLists.txt                | 270 ++++++++++++++++++
 cw_monero/linux/cw_monero_plugin.cc           |  70 +++++
 .../flutter/generated_plugin_registrant.cc    |  11 +
 .../flutter/generated_plugin_registrant.h     |  15 +
 .../linux/flutter/generated_plugins.cmake     |  23 ++
 .../include/cw_monero/cw_monero_plugin.h      |  26 ++
 cw_monero/pubspec.lock                        |  37 ++-
 cw_nano/lib/file.dart                         |  39 ---
 cw_nano/lib/nano_transaction_history.dart     |  22 +-
 cw_nano/lib/nano_wallet.dart                  |  32 ++-
 cw_nano/lib/nano_wallet_service.dart          |  17 +-
 cw_nano/pubspec.lock                          |  33 +++
 .../lib/polygon_transaction_history.dart      |   1 +
 cw_polygon/lib/polygon_wallet.dart            |  30 +-
 cw_polygon/lib/polygon_wallet_service.dart    |  15 +-
 cw_solana/lib/file.dart                       |  39 ---
 cw_solana/lib/solana_transaction_history.dart |  10 +-
 cw_solana/lib/solana_wallet.dart              |  34 ++-
 .../solana_wallet_creation_credentials.dart   |   4 +-
 cw_solana/lib/solana_wallet_service.dart      |  15 +-
 cw_tron/lib/file.dart                         |  39 ---
 cw_tron/lib/tron_transaction_history.dart     |  10 +-
 cw_tron/lib/tron_wallet.dart                  |  27 +-
 .../lib/tron_wallet_creation_credentials.dart |   4 +-
 cw_tron/lib/tron_wallet_service.dart          |  15 +-
 cw_wownero/lib/wownero_wallet.dart            |   7 +-
 cw_wownero/lib/wownero_wallet_service.dart    |  12 +-
 cw_wownero/pubspec.lock                       |  33 +++
 lib/bitcoin/cw_bitcoin.dart                   |  12 +-
 lib/bitcoin_cash/cw_bitcoin_cash.dart         |   7 +-
 lib/core/backup_service.dart                  |   2 +-
 lib/core/wallet_creation_service.dart         |  32 ++-
 lib/core/wallet_loading_service.dart          |  19 +-
 lib/di.dart                                   |  86 +++++-
 lib/entities/load_current_wallet.dart         |   7 +-
 lib/ethereum/cw_ethereum.dart                 |   7 +-
 lib/main.dart                                 |   4 +-
 lib/nano/cw_nano.dart                         |   4 +-
 lib/polygon/cw_polygon.dart                   |   7 +-
 .../on_authentication_state_change.dart       |   3 +-
 lib/router.dart                               |  79 +++--
 lib/routes.dart                               |   2 +
 lib/solana/cw_solana.dart                     |   7 +-
 lib/src/screens/auth/auth_page.dart           |  15 +-
 .../desktop_action_button.dart                |  78 ++---
 .../desktop_wallet_selection_dropdown.dart    |  28 +-
 .../screens/new_wallet/new_wallet_page.dart   |  94 +++++-
 .../wallet_restore_from_keys_form.dart        |  49 +++-
 .../wallet_restore_from_seed_form.dart        |  49 +++-
 .../screens/restore/wallet_restore_page.dart  |  10 +-
 lib/src/screens/root/root.dart                |   1 +
 .../settings/security_backup_page.dart        |  19 +-
 lib/src/screens/wallet/wallet_edit_page.dart  |  49 +++-
 .../screens/wallet_list/wallet_list_page.dart |  17 ++
 .../wallet_unlock_arguments.dart              |  17 ++
 .../wallet_unlock/wallet_unlock_page.dart     | 238 +++++++++++++++
 lib/src/widgets/address_text_field.dart       |   7 +-
 lib/store/settings_store.dart                 |   1 +
 lib/tron/cw_tron.dart                         |   8 +-
 lib/utils/package_info.dart                   |   2 +-
 lib/view_model/wallet_creation_vm.dart        |  18 ++
 .../wallet_list/wallet_edit_view_model.dart   |   5 +-
 lib/view_model/wallet_new_vm.dart             |  18 +-
 lib/view_model/wallet_restore_view_model.dart |   2 +-
 .../wallet_unlock_loadable_view_model.dart    |  63 ++++
 .../wallet_unlock_verifiable_view_model.dart  |  60 ++++
 lib/view_model/wallet_unlock_view_model.dart  |  11 +
 linux/.gitignore                              |   1 +
 linux/CMakeLists.txt                          | 144 ++++++++++
 linux/com.cakewallet.CakeWallet.desktop       |   9 +
 linux/flutter/CMakeLists.txt                  |  88 ++++++
 linux/flutter/generated_plugin_registrant.cc  |  27 ++
 linux/flutter/generated_plugin_registrant.h   |  15 +
 linux/flutter/generated_plugins.cmake         |  28 ++
 linux/main.cc                                 |   6 +
 linux/my_application.cc                       | 104 +++++++
 linux/my_application.h                        |  18 ++
 macos/CakeWallet/decrypt.swift                |  16 ++
 macos/Flutter/GeneratedPluginRegistrant.swift |   2 -
 macos/Runner/RunnerBase.entitlements          |   2 +-
 model_generator.sh                            |   1 +
 pubspec_base.yaml                             |   4 +-
 res/values/strings_ar.arb                     |   6 +
 res/values/strings_bg.arb                     |   6 +
 res/values/strings_cs.arb                     |   6 +
 res/values/strings_de.arb                     |   6 +
 res/values/strings_en.arb                     |   6 +
 res/values/strings_es.arb                     |   6 +
 res/values/strings_fr.arb                     |   6 +
 res/values/strings_ha.arb                     |   6 +
 res/values/strings_hi.arb                     |   6 +
 res/values/strings_hr.arb                     |   6 +
 res/values/strings_id.arb                     |   6 +
 res/values/strings_it.arb                     |   6 +
 res/values/strings_ja.arb                     |   6 +
 res/values/strings_ko.arb                     |   6 +
 res/values/strings_my.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_th.arb                     |   6 +
 res/values/strings_tl.arb                     |   6 +
 res/values/strings_tr.arb                     |   6 +
 res/values/strings_uk.arb                     |   6 +
 res/values/strings_ur.arb                     |   6 +
 res/values/strings_yo.arb                     |   6 +
 res/values/strings_zh.arb                     |   6 +
 scripts/android/shell.nix                     |  16 --
 scripts/ios/gen_framework.sh                  |   2 +-
 scripts/linux/app_config.sh                   |  25 ++
 scripts/linux/app_env.fish                    |  35 +++
 scripts/linux/app_env.sh                      |  35 +++
 scripts/linux/build_all.sh                    |   3 +
 scripts/linux/build_boost.sh                  |  36 +++
 scripts/linux/build_expat.sh                  |  20 ++
 scripts/linux/build_iconv.sh                  |  22 ++
 scripts/linux/build_monero.sh                 |  40 +++
 scripts/linux/build_monero_all.sh             |  21 ++
 scripts/linux/build_openssl.sh                |  19 ++
 scripts/linux/build_sodium.sh                 |  19 ++
 scripts/linux/build_unbound.sh                |  25 ++
 scripts/linux/build_zmq.sh                    |  17 ++
 scripts/linux/cakewallet.sh                   |   4 +
 scripts/linux/config.sh                       |  13 +
 scripts/linux/gcc10.nix                       |  12 +
 scripts/linux/setup.sh                        |   9 +
 tool/configure.dart                           |  34 +--
 178 files changed, 3955 insertions(+), 563 deletions(-)
 rename .github/workflows/{pr_test_build.yml => pr_test_build_android.yml} (98%)
 create mode 100644 .github/workflows/pr_test_build_linux.yml
 create mode 100644 build-guide-linux.md
 create mode 100644 com.cakewallet.CakeWallet.yml
 create mode 100644 cw_core/lib/encryption_file_utils.dart
 delete mode 100644 cw_evm/lib/file.dart
 create mode 100644 cw_monero/example/linux/.gitignore
 create mode 100644 cw_monero/example/linux/CMakeLists.txt
 create mode 100644 cw_monero/example/linux/flutter/CMakeLists.txt
 create mode 100644 cw_monero/example/linux/flutter/generated_plugin_registrant.cc
 create mode 100644 cw_monero/example/linux/flutter/generated_plugin_registrant.h
 create mode 100644 cw_monero/example/linux/flutter/generated_plugins.cmake
 create mode 100644 cw_monero/example/linux/main.cc
 create mode 100644 cw_monero/example/linux/my_application.cc
 create mode 100644 cw_monero/example/linux/my_application.h
 create mode 100644 cw_monero/linux/CMakeLists.txt
 create mode 100644 cw_monero/linux/cw_monero_plugin.cc
 create mode 100644 cw_monero/linux/flutter/generated_plugin_registrant.cc
 create mode 100644 cw_monero/linux/flutter/generated_plugin_registrant.h
 create mode 100644 cw_monero/linux/flutter/generated_plugins.cmake
 create mode 100644 cw_monero/linux/include/cw_monero/cw_monero_plugin.h
 delete mode 100644 cw_nano/lib/file.dart
 delete mode 100644 cw_solana/lib/file.dart
 delete mode 100644 cw_tron/lib/file.dart
 create mode 100644 lib/src/screens/wallet_unlock/wallet_unlock_arguments.dart
 create mode 100644 lib/src/screens/wallet_unlock/wallet_unlock_page.dart
 create mode 100644 lib/view_model/wallet_unlock_loadable_view_model.dart
 create mode 100644 lib/view_model/wallet_unlock_verifiable_view_model.dart
 create mode 100644 lib/view_model/wallet_unlock_view_model.dart
 create mode 100644 linux/.gitignore
 create mode 100644 linux/CMakeLists.txt
 create mode 100644 linux/com.cakewallet.CakeWallet.desktop
 create mode 100644 linux/flutter/CMakeLists.txt
 create mode 100644 linux/flutter/generated_plugin_registrant.cc
 create mode 100644 linux/flutter/generated_plugin_registrant.h
 create mode 100644 linux/flutter/generated_plugins.cmake
 create mode 100644 linux/main.cc
 create mode 100644 linux/my_application.cc
 create mode 100644 linux/my_application.h
 create mode 100644 macos/CakeWallet/decrypt.swift
 delete mode 100644 scripts/android/shell.nix
 create mode 100755 scripts/linux/app_config.sh
 create mode 100644 scripts/linux/app_env.fish
 create mode 100755 scripts/linux/app_env.sh
 create mode 100755 scripts/linux/build_all.sh
 create mode 100755 scripts/linux/build_boost.sh
 create mode 100755 scripts/linux/build_expat.sh
 create mode 100755 scripts/linux/build_iconv.sh
 create mode 100755 scripts/linux/build_monero.sh
 create mode 100755 scripts/linux/build_monero_all.sh
 create mode 100755 scripts/linux/build_openssl.sh
 create mode 100755 scripts/linux/build_sodium.sh
 create mode 100755 scripts/linux/build_unbound.sh
 create mode 100755 scripts/linux/build_zmq.sh
 create mode 100755 scripts/linux/cakewallet.sh
 create mode 100755 scripts/linux/config.sh
 create mode 100644 scripts/linux/gcc10.nix
 create mode 100755 scripts/linux/setup.sh

diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml
index e9c53c00f..cca5bb4bf 100644
--- a/.github/workflows/cache_dependencies.yml
+++ b/.github/workflows/cache_dependencies.yml
@@ -25,7 +25,7 @@ jobs:
       - uses: actions/checkout@v2
       - uses: actions/setup-java@v1
         with:
-          java-version: "11.x"
+          java-version: "17.x"
       - name: Configure placeholder git details
         run: |
           git config --global user.email "CI@cakewallet.com"
diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build_android.yml
similarity index 98%
rename from .github/workflows/pr_test_build.yml
rename to .github/workflows/pr_test_build_android.yml
index 4c46137ac..ea8770860 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build_android.yml
@@ -53,7 +53,9 @@ jobs:
           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
+        run: |
+          sudo apt update
+          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: |
diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml
new file mode 100644
index 000000000..12c930120
--- /dev/null
+++ b/.github/workflows/pr_test_build_linux.yml
@@ -0,0 +1,186 @@
+name: PR Test Build linux
+
+on:
+  pull_request:
+    branches: [main]
+  workflow_dispatch:
+    inputs:
+      branch:
+        description: "Branch name to build"
+        required: true
+        default: "main"
+
+jobs:
+  PR_test_build:
+    runs-on: ubuntu-20.04
+    env:
+      STORE_PASS: test@cake_wallet
+      KEY_PASS: test@cake_wallet
+      PR_NUMBER: ${{ github.event.number }}
+
+    steps:
+      - name: is pr
+        if: github.event_name == 'pull_request'
+        run: echo "BRANCH_NAME=${GITHUB_HEAD_REF}" >> $GITHUB_ENV
+
+      - name: is not pr
+        if: github.event_name != 'pull_request'
+        run: echo "BRANCH_NAME=${{ github.event.inputs.branch }}" >> $GITHUB_ENVg
+
+      - uses: actions/checkout@v2
+      - uses: actions/setup-java@v1
+        with:
+          java-version: "17.x"
+      - name: Configure placeholder git details
+        run: |
+          git config --global user.email "CI@cakewallet.com"
+          git config --global user.name "Cake Github Actions"
+      - name: Flutter action
+        uses: subosito/flutter-action@v1
+        with:
+          flutter-version: "3.19.6"
+          channel: stable
+
+      - name: Install package dependencies
+        run: |
+          sudo apt update
+          sudo apt-get install -y curl unzip automake build-essential file pkg-config git python-is-python3 libtool libtinfo5 cmake clang
+
+      - name: Install desktop dependencies
+        run: |
+          sudo apt update
+          sudo apt install -y ninja-build libgtk-3-dev gperf
+      - name: Execute Build and Setup Commands
+        run: |
+          sudo mkdir -p /opt/android
+          sudo chown $USER /opt/android
+          cd /opt/android
+          -y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+          cargo install cargo-ndk
+          git clone https://github.com/cake-tech/cake_wallet.git --branch ${{ env.BRANCH_NAME }}
+          cd scripts && ./gen_android_manifest.sh && cd ..
+          cd cake_wallet/scripts/android/
+          source ./app_env.sh cakewallet
+          ./app_config.sh
+          cd ../../..
+          cd cake_wallet/scripts/linux/
+          source ./app_env.sh cakewallet
+          ./app_config.sh
+          cd ../../..
+
+      - name: Cache Externals
+        id: cache-externals
+        uses: actions/cache@v3
+        with:
+          path: |
+            /opt/android/cake_wallet/cw_haven/android/.cxx
+            /opt/android/cake_wallet/scripts/monero_c/release
+          key: linux-${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh') }}
+
+      - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
+        name: Generate Externals
+        run: |
+          cd /opt/android/cake_wallet/scripts/linux/
+          source ./app_env.sh cakewallet
+          ./build_monero_all.sh
+
+      - name: Install Flutter dependencies
+        run: |
+          cd /opt/android/cake_wallet
+          flutter pub get
+
+      - 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
+          ./model_generator.sh
+
+      - name: Add secrets
+        run: |
+          cd /opt/android/cake_wallet
+          touch lib/.secrets.g.dart
+          touch cw_evm/lib/.secrets.g.dart
+          touch cw_solana/lib/.secrets.g.dart
+          touch cw_core/lib/.secrets.g.dart
+          touch cw_nano/lib/.secrets.g.dart
+          touch cw_tron/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 changeNowApiKeyDesktop = '${{ secrets.CHANGE_NOW_API_KEY_DESKTOP }}';" >> 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 simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const simpleSwapApiKeyDesktop = '${{ secrets.SIMPLE_SWAP_API_KEY_DESKTOP }}';" >> 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
+          echo "const twitterBearerToken = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
+          echo "const trocadorApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const trocadorExchangeMarkup = '${{ secrets.TROCADOR_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
+          echo "const anonPayReferralCode = '${{ secrets.ANON_PAY_REFERRAL_CODE }}';" >> lib/.secrets.g.dart
+          echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
+          echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
+          echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
+          echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
+          echo "const exchangeHelperApiKey = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart
+          echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
+          echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
+          echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
+          echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
+          echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
+          echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
+          echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
+          echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
+          echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
+          echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
+          echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
+
+      - name: Rename app
+        run: |
+          echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
+
+      - name: Build
+        run: |
+          cd /opt/android/cake_wallet
+          flutter build linux --release
+
+      - name: Prepare release zip file
+        run: |
+          cd /opt/android/cake_wallet/build/linux/x64/release
+          zip -r ${{env.BRANCH_NAME}}.zip bundle
+
+      - name: Upload Artifact
+        uses: kittaakos/upload-artifact-as-is@v0
+        with:
+          path: /opt/android/cake_wallet/build/linux/x64/release/${{env.BRANCH_NAME}}.zip
+
+      - name: Send Test APK
+        continue-on-error: true
+        uses: adrey/slack-file-upload-action@1.0.5
+        with:
+          token: ${{ secrets.SLACK_APP_TOKEN }}
+          path: /opt/android/cake_wallet/build/linux/x64/release/${{env.BRANCH_NAME}}.zip
+          channel: ${{ secrets.SLACK_APK_CHANNEL }}
+          title: "${{ env.BRANCH_NAME }}_linux.zip"
+          filename: ${{ env.BRANCH_NAME }}_linux.zip
+          initial_comment: ${{ github.event.head_commit.message }}
diff --git a/.gitignore b/.gitignore
index 77441e66f..8336ca512 100644
--- a/.gitignore
+++ b/.gitignore
@@ -160,6 +160,8 @@ macos/Runner/Release.entitlements
 macos/Runner/Runner.entitlements
 lib/core/secure_storage.dart
 
+lib/core/secure_storage.dart
+
 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
diff --git a/.metadata b/.metadata
index 7d00ca21a..c7b8dc9f8 100644
--- a/.metadata
+++ b/.metadata
@@ -18,6 +18,12 @@ migration:
     - platform: windows
       create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
       base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
+    - platform: macos
+      create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
+      base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
+    - platform: linux
+      create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
+      base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
 
   # User provided section
 
diff --git a/build-guide-linux.md b/build-guide-linux.md
new file mode 100644
index 000000000..e0158945b
--- /dev/null
+++ b/build-guide-linux.md
@@ -0,0 +1,176 @@
+# Building CakeWallet for Linux
+
+## Requirements and Setup
+
+The following are the system requirements to build CakeWallet for your Linux device.
+
+```
+Ubuntu >= 16.04
+Flutter 3.10.x
+```
+
+## Building CakeWallet on Linux
+
+These steps will help you configure and execute a build of CakeWallet from its source code.
+
+### 1. Installing Package Dependencies
+
+CakeWallet requires some packages to be install on your build system. You may easily install them on your build system with the following command:
+
+`$ sudo apt install build-essential cmake pkg-config git curl autoconf libtool`
+
+> [!WARNING]
+>
+> ### Check gcc version
+>
+> It is needed to use gcc 10 or 9 to successfully link dependencies with flutter.\
+> To check what gcc version you are using:
+>
+> ```bash
+> $ gcc --version
+> $ g++ --version
+> ```
+>
+> If you are using gcc version newer than 10, then you need to downgrade to version 10.4.0:
+>
+> ```bash
+> $ sudo apt install gcc-10 g++-10
+> $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10
+> $ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10
+> ```
+
+> [!NOTE]
+>
+> Alternatively, you can use the [nix-shell](https://nixos.org/) with the `gcc10.nix` file\
+> present on `scripts/linux` like so:
+> ```bash
+> $ nix-shell gcc10.nix
+> ```
+> This will get you in a nix environment with all the required dependencies that you can use to build the software from,\
+> and it works in any linux distro.
+
+### 2. Installing Flutter
+
+Need to install flutter. For this please check section [How to install flutter on Linux](https://docs.flutter.dev/get-started/install/linux).
+
+### 3. Verify Installations
+
+Verify that the Flutter have been correctly installed on your system with the following command:
+
+`$ flutter doctor`
+
+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, 3.10.x, on Linux, locale en_US.UTF-8)
+```
+
+### 4. Acquiring the CakeWallet Source Code
+
+Download CakeWallet source code
+
+`$ git clone https://github.com/cake-tech/cake_wallet.git --branch linux/password-direct-input`
+
+Proceed into the source code before proceeding with the next steps:
+
+`$ cd cake_wallet/scripts/linux/`
+
+To configure some project properties run:
+
+`$ ./cakewallet.sh`
+
+Build the Monero libraries and their dependencies:
+
+`$ ./build_all.sh`
+
+Now the dependencies need to be copied into the CakeWallet project with this command:
+
+`$ ./setup.sh`
+
+It is now time to change back to the base directory of the CakeWallet source code:
+
+`$ cd ../../`
+
+Install Flutter package dependencies with this command:
+
+`$ flutter pub get`
+
+> #### If you will get an error like:
+>
+> ```
+> The plugin `cw_shared_external` requires your app to be migrated to the Android embedding v2. Follow the steps on the migration doc above and re-run
+> this command.
+> ```
+>
+> Then need to config Android project settings. For this open `scripts/android` (`$ cd scripts/android`) directory and run followed commands:
+>
+> ```
+> $ source ./app_env.sh cakewallet
+> $ ./app_config.sh
+> $ cd ../..
+> ```
+>
+> Then re-configure Linux project again. For this open `scripts/linux` (`$cd scripts/linux`) directory and run:
+> `$ ./cakewallet.sh`
+> and back to project root directory:
+> `$ cd ../..`
+> and fetch dependecies again
+> `$ flutter pub get`
+
+Your CakeWallet binary will be built with some specific keys for iterate with 3rd party services. You may generate these secret keys placeholders with the following command:
+
+`$ flutter packages pub run tool/generate_new_secrets.dart`
+
+We will generate mobx models for the project.
+
+`$ ./model_generator.sh`
+
+Then we need to generate localization files.
+
+`$ flutter packages pub run tool/generate_localization.dart`
+
+### 5. Build!
+
+`$ flutter build linux --release`
+
+Path to executable file will be:
+
+`build/linux/x64/release/bundle/cake_wallet`
+
+> ### Troubleshooting
+>
+> If you got an error while building the application with `$ flutter build linux --release` command, add `-v` argument to the command (`$ flutter build linux -v --release`) to get details.\
+> If you got in flutter build logs: undefined reference to `hid_free_enumeration`, or another error with undefined reference to `hid_*`, then rebuild monero lib without hidapi lib. Check does exists `libhidapi-dev` in your scope and remove it from your scope for build without it.
+
+# Flatpak
+
+For package the built application into flatpak you need fistly to install `flatpak` and `flatpak-builder`:
+
+`$ sudo apt install flatpak flatpak-builder`
+
+Then need to [add flathub](https://flatpak.org/setup/Ubuntu) (or just `$ flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo`). Then need to install freedesktop runtime and sdk:
+
+`$ flatpak install flathub org.freedesktop.Platform//22.08 org.freedesktop.Sdk//22.08`
+
+To build with using of `flatpak-build` directory run next:
+
+`$ flatpak-builder --force-clean flatpak-build com.cakewallet.CakeWallet.yml`
+
+And then export bundle:
+
+`$ flatpak build-export export flatpak-build`
+
+`$ flatpak build-bundle export cake_wallet.flatpak com.cakewallet.CakeWallet`
+
+Result file: `cake_wallet.flatpak` should be generated in current directory.
+
+For install generated flatpak file use:
+
+`$ flatpak --user install cake_wallet.flatpak`
+
+For run the installed application run:
+
+`$ flatpak run com.cakewallet.CakeWallet`
+
+Copyright (c) 2023 Cake Technologies LLC.
diff --git a/com.cakewallet.CakeWallet.yml b/com.cakewallet.CakeWallet.yml
new file mode 100644
index 000000000..83efa1388
--- /dev/null
+++ b/com.cakewallet.CakeWallet.yml
@@ -0,0 +1,35 @@
+app-id: com.cakewallet.CakeWallet
+runtime: org.freedesktop.Platform
+runtime-version: '22.08'
+sdk: org.freedesktop.Sdk
+command: cake_wallet
+separate-locales: false
+finish-args:
+  - --share=ipc
+  - --socket=fallback-x11
+  - --socket=wayland
+  - --device=dri
+  - --socket=pulseaudio
+  - --share=network
+  - --filesystem=home
+modules:
+  - name: cake_wallet
+    buildsystem: simple
+    only-arches:
+      - x86_64
+    build-commands:
+      - "cp -R bundle /app/cake_wallet"
+      - "chmod +x /app/cake_wallet/cake_wallet"
+      - "mkdir -p /app/bin"
+      - "ln -s /app/cake_wallet/cake_wallet /app/bin/cake_wallet"
+      - "mkdir -p /app/share/icons/hicolor/scalable/apps"
+      - "cp cakewallet_icon_180.png /app/share/icons/hicolor/scalable/apps/com.cakewallet.CakeWallet.png"
+      - "mkdir -p /app/share/applications"
+      - "cp com.cakewallet.CakeWallet.desktop /app/share/applications"
+    sources:
+      - type: dir
+        path: build/linux/x64/release
+      - type: file
+        path: assets/images/cakewallet_icon_180.png
+      - type: file
+        path: linux/com.cakewallet.CakeWallet.desktop
diff --git a/configure_cake_wallet.sh b/configure_cake_wallet.sh
index 0539221a3..90ce1c446 100755
--- a/configure_cake_wallet.sh
+++ b/configure_cake_wallet.sh
@@ -3,12 +3,13 @@
 IOS="ios"
 ANDROID="android"
 MACOS="macos"
+LINUX="linux"
 
-PLATFORMS=($IOS $ANDROID $MACOS)
+PLATFORMS=($IOS $ANDROID $MACOS $LINUX)
 PLATFORM=$1
 
 if ! [[ " ${PLATFORMS[*]} " =~ " ${PLATFORM} " ]]; then
-    echo "specify platform: ./configure_cake_wallet.sh ios|android|macos"
+    echo "specify platform: ./configure_cake_wallet.sh ios|android|macos|linux"
     exit 1
 fi
 
@@ -27,9 +28,14 @@ if [ "$PLATFORM" == "$ANDROID" ]; then
     cd scripts/android
 fi
 
+if [ "$PLATFORM" == "$LINUX" ]; then
+    echo "Configuring for linux"
+    cd scripts/linux
+fi
+
 source ./app_env.sh cakewallet
 ./app_config.sh
 cd ../.. && flutter pub get
-#flutter packages pub run tool/generate_localization.dart
+flutter packages pub run tool/generate_localization.dart
 ./model_generator.sh
-#cd macos && pod install
\ No newline at end of file
+#cd macos && pod install
diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart
index 7b8250541..e2e537ee8 100644
--- a/cw_bitcoin/lib/bitcoin_wallet.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet.dart
@@ -5,9 +5,10 @@ import 'package:bitcoin_base/bitcoin_base.dart';
 import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
+import 'package:cw_core/encryption_file_utils.dart';
+import 'package:cw_bitcoin/electrum_derivations.dart';
 import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart';
 import 'package:cw_bitcoin/electrum_balance.dart';
-import 'package:cw_bitcoin/electrum_derivations.dart';
 import 'package:cw_bitcoin/electrum_wallet.dart';
 import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
 import 'package:cw_bitcoin/psbt_transaction_builder.dart';
@@ -30,6 +31,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
     required String password,
     required WalletInfo walletInfo,
     required Box<UnspentCoinsInfo> unspentCoinsInfo,
+    required EncryptionFileUtils encryptionFileUtils,
     Uint8List? seedBytes,
     String? mnemonic,
     String? xpub,
@@ -58,6 +60,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
           initialAddresses: initialAddresses,
           initialBalance: initialBalance,
           seedBytes: seedBytes,
+          encryptionFileUtils: encryptionFileUtils,
           currency:
               networkParam == BitcoinNetwork.testnet ? CryptoCurrency.tbtc : CryptoCurrency.btc,
           alwaysScan: alwaysScan,
@@ -90,6 +93,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
     required String password,
     required WalletInfo walletInfo,
     required Box<UnspentCoinsInfo> unspentCoinsInfo,
+    required EncryptionFileUtils encryptionFileUtils,
     String? passphrase,
     String? addressPageType,
     BasedUtxoNetwork? network,
@@ -124,6 +128,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
       initialSilentAddresses: initialSilentAddresses,
       initialSilentAddressIndex: initialSilentAddressIndex,
       initialBalance: initialBalance,
+      encryptionFileUtils: encryptionFileUtils,
       seedBytes: seedBytes,
       initialRegularAddressIndex: initialRegularAddressIndex,
       initialChangeAddressIndex: initialChangeAddressIndex,
@@ -137,6 +142,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
     required WalletInfo walletInfo,
     required Box<UnspentCoinsInfo> unspentCoinsInfo,
     required String password,
+    required EncryptionFileUtils encryptionFileUtils,
     required bool alwaysScan,
   }) async {
     final network = walletInfo.network != null
@@ -148,7 +154,13 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
     ElectrumWalletSnapshot? snp = null;
 
     try {
-      snp = await ElectrumWalletSnapshot.load(name, walletInfo.type, password, network);
+      snp = await ElectrumWalletSnapshot.load(
+        encryptionFileUtils,
+        name,
+        walletInfo.type,
+        password,
+        network,
+      );
     } catch (e) {
       if (!hasKeysFile) rethrow;
     }
@@ -156,10 +168,18 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
     final WalletKeysData keysData;
     // Migrate wallet from the old scheme to then new .keys file scheme
     if (!hasKeysFile) {
-      keysData =
-          WalletKeysData(mnemonic: snp!.mnemonic, xPub: snp.xpub, passphrase: snp.passphrase);
+      keysData = WalletKeysData(
+        mnemonic: snp!.mnemonic,
+        xPub: snp.xpub,
+        passphrase: snp.passphrase,
+      );
     } else {
-      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+      keysData = await WalletKeysFile.readKeysFile(
+        name,
+        walletInfo.type,
+        password,
+        encryptionFileUtils,
+      );
     }
 
     walletInfo.derivationInfo ??= DerivationInfo();
@@ -198,6 +218,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
       initialSilentAddresses: snp?.silentAddresses,
       initialSilentAddressIndex: snp?.silentAddressIndex ?? 0,
       initialBalance: snp?.balance,
+      encryptionFileUtils: encryptionFileUtils,
       seedBytes: seedBytes,
       initialRegularAddressIndex: snp?.regularAddressIndex,
       initialChangeAddressIndex: snp?.changeAddressIndex,
diff --git a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
index 915d7cc10..91b8e4ae2 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
@@ -6,11 +6,13 @@ class BitcoinNewWalletCredentials extends WalletCredentials {
   BitcoinNewWalletCredentials(
       {required String name,
       WalletInfo? walletInfo,
+      String? password,
       DerivationType? derivationType,
       String? derivationPath})
       : super(
           name: name,
           walletInfo: walletInfo,
+          password: password,
         );
 }
 
diff --git a/cw_bitcoin/lib/bitcoin_wallet_service.dart b/cw_bitcoin/lib/bitcoin_wallet_service.dart
index cf93aa29d..d6d97f3de 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_service.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_service.dart
@@ -3,6 +3,7 @@ import 'package:bitcoin_base/bitcoin_base.dart';
 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
 import 'package:cw_bitcoin/mnemonic_is_incorrect_exception.dart';
 import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_service.dart';
@@ -19,11 +20,12 @@ class BitcoinWalletService extends WalletService<
     BitcoinRestoreWalletFromSeedCredentials,
     BitcoinRestoreWalletFromWIFCredentials,
     BitcoinRestoreWalletFromHardware> {
-  BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.alwaysScan);
+  BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.alwaysScan, this.isDirect);
 
   final Box<WalletInfo> walletInfoSource;
   final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
   final bool alwaysScan;
+  final bool isDirect;
 
   @override
   WalletType getType() => WalletType.bitcoin;
@@ -40,6 +42,7 @@ class BitcoinWalletService extends WalletService<
       walletInfo: credentials.walletInfo!,
       unspentCoinsInfo: unspentCoinsInfoSource,
       network: network,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.save();
@@ -63,6 +66,7 @@ class BitcoinWalletService extends WalletService<
         walletInfo: walletInfo,
         unspentCoinsInfo: unspentCoinsInfoSource,
         alwaysScan: alwaysScan,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
       await wallet.init();
       saveBackup(name);
@@ -75,6 +79,7 @@ class BitcoinWalletService extends WalletService<
         walletInfo: walletInfo,
         unspentCoinsInfo: unspentCoinsInfoSource,
         alwaysScan: alwaysScan,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
       await wallet.init();
       return wallet;
@@ -99,6 +104,7 @@ class BitcoinWalletService extends WalletService<
       walletInfo: currentWalletInfo,
       unspentCoinsInfo: unspentCoinsInfoSource,
       alwaysScan: alwaysScan,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await currentWallet.renameWalletFiles(newName);
@@ -125,6 +131,7 @@ class BitcoinWalletService extends WalletService<
       walletInfo: credentials.walletInfo!,
       unspentCoinsInfo: unspentCoinsInfoSource,
       networkParam: network,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
     await wallet.save();
     await wallet.init();
@@ -153,6 +160,7 @@ class BitcoinWalletService extends WalletService<
       walletInfo: credentials.walletInfo!,
       unspentCoinsInfo: unspentCoinsInfoSource,
       network: network,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
     await wallet.save();
     await wallet.init();
diff --git a/cw_bitcoin/lib/electrum_transaction_history.dart b/cw_bitcoin/lib/electrum_transaction_history.dart
index a7de414e4..806f813dd 100644
--- a/cw_bitcoin/lib/electrum_transaction_history.dart
+++ b/cw_bitcoin/lib/electrum_transaction_history.dart
@@ -1,4 +1,5 @@
 import 'dart:convert';
+import 'package:cw_core/encryption_file_utils.dart';
 
 import 'package:cw_bitcoin/electrum_transaction_info.dart';
 import 'package:cw_core/pathForWallet.dart';
@@ -6,6 +7,8 @@ import 'package:cw_core/transaction_history.dart';
 import 'package:cw_core/utils/file.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:mobx/mobx.dart';
+import 'package:cw_core/transaction_history.dart';
+import 'package:cw_bitcoin/electrum_transaction_info.dart';
 
 part 'electrum_transaction_history.g.dart';
 
@@ -15,13 +18,15 @@ class ElectrumTransactionHistory = ElectrumTransactionHistoryBase with _$Electru
 
 abstract class ElectrumTransactionHistoryBase
     extends TransactionHistoryBase<ElectrumTransactionInfo> with Store {
-  ElectrumTransactionHistoryBase({required this.walletInfo, required String password})
+  ElectrumTransactionHistoryBase(
+      {required this.walletInfo, required String password, required this.encryptionFileUtils})
       : _password = password,
         _height = 0 {
     transactions = ObservableMap<String, ElectrumTransactionInfo>();
   }
 
   final WalletInfo walletInfo;
+  final EncryptionFileUtils encryptionFileUtils;
   String _password;
   int _height;
 
@@ -44,7 +49,7 @@ abstract class ElectrumTransactionHistoryBase
         txjson[tx.key] = tx.value.toJson();
       }
       final data = json.encode({'height': _height, 'transactions': txjson});
-      await writeData(path: path, password: _password, data: data);
+      await encryptionFileUtils.write(path: path, password: _password, data: data);
     } catch (e) {
       print('Error while save bitcoin transaction history: ${e.toString()}');
     }
@@ -58,7 +63,7 @@ abstract class ElectrumTransactionHistoryBase
   Future<Map<String, dynamic>> _read() async {
     final dirPath = await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
     final path = '$dirPath/$transactionsHistoryFileName';
-    final content = await read(path: path, password: _password);
+    final content = await encryptionFileUtils.read(path: path, password: _password);
     return json.decode(content) as Map<String, dynamic>;
   }
 
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index e1b038beb..501d94e54 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -5,6 +5,7 @@ import 'dart:isolate';
 import 'dart:math';
 
 import 'package:bitcoin_base/bitcoin_base.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:collection/collection.dart';
 import 'package:cw_bitcoin/address_from_output.dart';
@@ -32,7 +33,6 @@ import 'package:cw_core/sync_status.dart';
 import 'package:cw_core/transaction_direction.dart';
 import 'package:cw_core/transaction_priority.dart';
 import 'package:cw_core/unspent_coins_info.dart';
-import 'package:cw_core/utils/file.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_keys_file.dart';
@@ -58,6 +58,7 @@ abstract class ElectrumWalletBase
     required WalletInfo walletInfo,
     required Box<UnspentCoinsInfo> unspentCoinsInfo,
     required this.network,
+    required this.encryptionFileUtils,
     String? xpub,
     String? mnemonic,
     Uint8List? seedBytes,
@@ -92,7 +93,11 @@ abstract class ElectrumWalletBase
         super(walletInfo) {
     this.electrumClient = electrumClient ?? ElectrumClient();
     this.walletInfo = walletInfo;
-    transactionHistory = ElectrumTransactionHistory(walletInfo: walletInfo, password: password);
+    transactionHistory = ElectrumTransactionHistory(
+      walletInfo: walletInfo,
+      password: password,
+      encryptionFileUtils: encryptionFileUtils,
+    );
 
     reaction((_) => syncStatus, _syncStatusReaction);
   }
@@ -127,6 +132,8 @@ abstract class ElectrumWalletBase
   final String? _mnemonic;
 
   Bip32Slip10Secp256k1 get hd => accountHD.childKey(Bip32KeyIndex(0));
+
+  final EncryptionFileUtils encryptionFileUtils;
   final String? passphrase;
 
   @override
@@ -167,6 +174,9 @@ abstract class ElectrumWalletBase
   WalletKeysData get walletKeysData =>
       WalletKeysData(mnemonic: _mnemonic, xPub: xpub, passphrase: passphrase);
 
+  @override
+  String get password => _password;
+
   BasedUtxoNetwork network;
 
   @override
@@ -455,7 +465,6 @@ abstract class ElectrumWalletBase
       }
     }
 
-
     node!.isElectrs = false;
     node!.save();
     return node!.isElectrs!;
@@ -1130,12 +1139,12 @@ abstract class ElectrumWalletBase
   @override
   Future<void> save() async {
     if (!(await WalletKeysFile.hasKeysFile(walletInfo.name, walletInfo.type))) {
-      await saveKeysFile(_password);
-      saveKeysFile(_password, true);
+      await saveKeysFile(_password, encryptionFileUtils);
+      saveKeysFile(_password, encryptionFileUtils, true);
     }
 
     final path = await makePath();
-    await write(path: path, password: _password, data: toJSON());
+    await encryptionFileUtils.write(path: path, password: _password, data: toJSON());
     await transactionHistory.save();
   }
 
@@ -2258,4 +2267,3 @@ class UtxoDetails {
     required this.spendsUnconfirmedTX,
   });
 }
-
diff --git a/cw_bitcoin/lib/electrum_wallet_snapshot.dart b/cw_bitcoin/lib/electrum_wallet_snapshot.dart
index 082460f72..fa58be238 100644
--- a/cw_bitcoin/lib/electrum_wallet_snapshot.dart
+++ b/cw_bitcoin/lib/electrum_wallet_snapshot.dart
@@ -2,6 +2,7 @@ import 'dart:convert';
 import 'package:bitcoin_base/bitcoin_base.dart';
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
 import 'package:cw_bitcoin/electrum_balance.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_bitcoin/electrum_derivations.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/wallet_info.dart';
@@ -51,9 +52,9 @@ class ElectrumWalletSnapshot {
   String? derivationPath;
 
   static Future<ElectrumWalletSnapshot> load(
-      String name, WalletType type, String password, BasedUtxoNetwork network) async {
+      EncryptionFileUtils encryptionFileUtils, String name, WalletType type, String password, BasedUtxoNetwork network) async {
     final path = await pathForWallet(name: name, type: type);
-    final jsonSource = await read(path: path, password: password);
+    final jsonSource = await encryptionFileUtils.read(path: path, password: password);
     final data = json.decode(jsonSource) as Map;
     final addressesTmp = data['addresses'] as List? ?? <Object>[];
     final mnemonic = data['mnemonic'] as String?;
diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 64e53ca5d..d8c04dba6 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -4,13 +4,14 @@ import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
 import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
+import 'package:cw_core/encryption_file_utils.dart';
+import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_bitcoin/electrum_balance.dart';
 import 'package:cw_bitcoin/electrum_wallet.dart';
 import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
 import 'package:cw_bitcoin/litecoin_wallet_addresses.dart';
-import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/transaction_priority.dart';
-import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_keys_file.dart';
 import 'package:flutter/foundation.dart';
@@ -28,6 +29,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     required WalletInfo walletInfo,
     required Box<UnspentCoinsInfo> unspentCoinsInfo,
     required Uint8List seedBytes,
+    required EncryptionFileUtils encryptionFileUtils,
     String? addressPageType,
     List<BitcoinAddressRecord>? initialAddresses,
     ElectrumBalance? initialBalance,
@@ -42,6 +44,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
             initialAddresses: initialAddresses,
             initialBalance: initialBalance,
             seedBytes: seedBytes,
+            encryptionFileUtils: encryptionFileUtils,
             currency: CryptoCurrency.ltc) {
     walletAddresses = LitecoinWalletAddresses(
       walletInfo,
@@ -62,6 +65,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       required String password,
       required WalletInfo walletInfo,
       required Box<UnspentCoinsInfo> unspentCoinsInfo,
+      required EncryptionFileUtils encryptionFileUtils,
       String? passphrase,
       String? addressPageType,
       List<BitcoinAddressRecord>? initialAddresses,
@@ -89,6 +93,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       unspentCoinsInfo: unspentCoinsInfo,
       initialAddresses: initialAddresses,
       initialBalance: initialBalance,
+      encryptionFileUtils: encryptionFileUtils,
       seedBytes: seedBytes,
       initialRegularAddressIndex: initialRegularAddressIndex,
       initialChangeAddressIndex: initialChangeAddressIndex,
@@ -96,19 +101,24 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     );
   }
 
-  static Future<LitecoinWallet> open({
-    required String name,
-    required WalletInfo walletInfo,
-    required Box<UnspentCoinsInfo> unspentCoinsInfo,
-    required String password,
-  }) async {
+  static Future<LitecoinWallet> open(
+      {required String name,
+      required WalletInfo walletInfo,
+      required Box<UnspentCoinsInfo> unspentCoinsInfo,
+      required String password,
+      required EncryptionFileUtils encryptionFileUtils}) async {
     final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
 
     ElectrumWalletSnapshot? snp = null;
 
     try {
       snp = await ElectrumWalletSnapshot.load(
-          name, walletInfo.type, password, LitecoinNetwork.mainnet);
+        encryptionFileUtils,
+        name,
+        walletInfo.type,
+        password,
+        LitecoinNetwork.mainnet,
+      );
     } catch (e) {
       if (!hasKeysFile) rethrow;
     }
@@ -119,7 +129,12 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       keysData =
           WalletKeysData(mnemonic: snp!.mnemonic, xPub: snp.xpub, passphrase: snp.passphrase);
     } else {
-      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+      keysData = await WalletKeysFile.readKeysFile(
+        name,
+        walletInfo.type,
+        password,
+        encryptionFileUtils,
+      );
     }
 
     return LitecoinWallet(
@@ -130,6 +145,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       initialAddresses: snp?.addresses,
       initialBalance: snp?.balance,
       seedBytes: await mnemonicToSeedBytes(keysData.mnemonic!),
+      encryptionFileUtils: encryptionFileUtils,
       initialRegularAddressIndex: snp?.regularAddressIndex,
       initialChangeAddressIndex: snp?.changeAddressIndex,
       addressPageType: snp?.addressPageType,
diff --git a/cw_bitcoin/lib/litecoin_wallet_service.dart b/cw_bitcoin/lib/litecoin_wallet_service.dart
index 7025b72e5..a46b12a2e 100644
--- a/cw_bitcoin/lib/litecoin_wallet_service.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_service.dart
@@ -1,4 +1,5 @@
 import 'dart:io';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:hive/hive.dart';
 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
@@ -16,11 +17,13 @@ import 'package:bip39/bip39.dart' as bip39;
 class LitecoinWalletService extends WalletService<
     BitcoinNewWalletCredentials,
     BitcoinRestoreWalletFromSeedCredentials,
-    BitcoinRestoreWalletFromWIFCredentials,BitcoinNewWalletCredentials> {
-  LitecoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
+    BitcoinRestoreWalletFromWIFCredentials,
+    BitcoinNewWalletCredentials> {
+  LitecoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.isDirect);
 
   final Box<WalletInfo> walletInfoSource;
   final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
+  final bool isDirect;
 
   @override
   WalletType getType() => WalletType.litecoin;
@@ -28,12 +31,13 @@ class LitecoinWalletService extends WalletService<
   @override
   Future<LitecoinWallet> create(BitcoinNewWalletCredentials credentials, {bool? isTestnet}) async {
     final wallet = await LitecoinWalletBase.create(
-        mnemonic: await generateElectrumMnemonic(),
-        password: credentials.password!,
-        passphrase: credentials.passphrase,
-        walletInfo: credentials.walletInfo!,
-        unspentCoinsInfo: unspentCoinsInfoSource);
-
+      mnemonic: await generateElectrumMnemonic(),
+      password: credentials.password!,
+      passphrase: credentials.passphrase,
+      walletInfo: credentials.walletInfo!,
+      unspentCoinsInfo: unspentCoinsInfoSource,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+    );
     await wallet.save();
     await wallet.init();
 
@@ -46,21 +50,29 @@ class LitecoinWalletService extends WalletService<
 
   @override
   Future<LitecoinWallet> openWallet(String name, String password) async {
-    final walletInfo = walletInfoSource.values.firstWhereOrNull(
-        (info) => info.id == WalletBase.idFor(name, getType()))!;
+    final walletInfo = walletInfoSource.values
+        .firstWhereOrNull((info) => info.id == WalletBase.idFor(name, getType()))!;
 
     try {
       final wallet = await LitecoinWalletBase.open(
-          password: password, name: name, walletInfo: walletInfo,
-          unspentCoinsInfo: unspentCoinsInfoSource);
+        password: password,
+        name: name,
+        walletInfo: walletInfo,
+        unspentCoinsInfo: unspentCoinsInfoSource,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+      );
       await wallet.init();
       saveBackup(name);
       return wallet;
     } catch (_) {
       await restoreWalletFilesFromBackup(name);
       final wallet = await LitecoinWalletBase.open(
-          password: password, name: name, walletInfo: walletInfo,
-          unspentCoinsInfo: unspentCoinsInfoSource);
+        password: password,
+        name: name,
+        walletInfo: walletInfo,
+        unspentCoinsInfo: unspentCoinsInfoSource,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+      );
       await wallet.init();
       return wallet;
     }
@@ -68,22 +80,23 @@ class LitecoinWalletService extends WalletService<
 
   @override
   Future<void> remove(String wallet) async {
-    File(await pathForWalletDir(name: wallet, type: getType()))
-        .delete(recursive: true);
-    final walletInfo = walletInfoSource.values.firstWhereOrNull(
-        (info) => info.id == WalletBase.idFor(wallet, getType()))!;
+    File(await pathForWalletDir(name: wallet, type: getType())).delete(recursive: true);
+    final walletInfo = walletInfoSource.values
+        .firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!;
     await walletInfoSource.delete(walletInfo.key);
   }
 
   @override
   Future<void> rename(String currentName, String password, String newName) async {
-    final currentWalletInfo = walletInfoSource.values.firstWhereOrNull(
-        (info) => info.id == WalletBase.idFor(currentName, getType()))!;
+    final currentWalletInfo = walletInfoSource.values
+        .firstWhereOrNull((info) => info.id == WalletBase.idFor(currentName, getType()))!;
     final currentWallet = await LitecoinWalletBase.open(
-        password: password,
-        name: currentName,
-        walletInfo: currentWalletInfo,
-        unspentCoinsInfo: unspentCoinsInfoSource);
+      password: password,
+      name: currentName,
+      walletInfo: currentWalletInfo,
+      unspentCoinsInfo: unspentCoinsInfoSource,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+    );
 
     await currentWallet.renameWalletFiles(newName);
     await saveBackup(newName);
@@ -97,27 +110,30 @@ class LitecoinWalletService extends WalletService<
 
   @override
   Future<LitecoinWallet> restoreFromHardwareWallet(BitcoinNewWalletCredentials credentials) {
-    throw UnimplementedError("Restoring a Litecoin wallet from a hardware wallet is not yet supported!");
+    throw UnimplementedError(
+        "Restoring a Litecoin wallet from a hardware wallet is not yet supported!");
   }
 
   @override
-  Future<LitecoinWallet> restoreFromKeys(
-          BitcoinRestoreWalletFromWIFCredentials credentials, {bool? isTestnet}) async =>
+  Future<LitecoinWallet> restoreFromKeys(BitcoinRestoreWalletFromWIFCredentials credentials,
+          {bool? isTestnet}) async =>
       throw UnimplementedError();
 
   @override
-  Future<LitecoinWallet> restoreFromSeed(
-      BitcoinRestoreWalletFromSeedCredentials credentials, {bool? isTestnet}) async {
+  Future<LitecoinWallet> restoreFromSeed(BitcoinRestoreWalletFromSeedCredentials credentials,
+      {bool? isTestnet}) async {
     if (!validateMnemonic(credentials.mnemonic) && !bip39.validateMnemonic(credentials.mnemonic)) {
       throw LitecoinMnemonicIsIncorrectException();
     }
 
     final wallet = await LitecoinWalletBase.create(
-        password: credentials.password!,
-        passphrase: credentials.passphrase,
-        mnemonic: credentials.mnemonic,
-        walletInfo: credentials.walletInfo!,
-        unspentCoinsInfo: unspentCoinsInfoSource);
+      password: credentials.password!,
+      passphrase: credentials.passphrase,
+      mnemonic: credentials.mnemonic,
+      walletInfo: credentials.walletInfo!,
+      unspentCoinsInfo: unspentCoinsInfoSource,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+    );
     await wallet.save();
     await wallet.init();
     return wallet;
diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock
index be7862e26..12274c1e6 100644
--- a/cw_bitcoin/pubspec.lock
+++ b/cw_bitcoin/pubspec.lock
@@ -164,6 +164,15 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "8.9.2"
+  cake_backup:
+    dependency: transitive
+    description:
+      path: "."
+      ref: main
+      resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38"
+      url: "https://github.com/cake-tech/cake_backup.git"
+    source: git
+    version: "1.0.0+1"
   characters:
     dependency: transitive
     description:
@@ -236,6 +245,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.7.0"
+  cupertino_icons:
+    dependency: transitive
+    description:
+      name: cupertino_icons
+      sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.8"
   cw_core:
     dependency: "direct main"
     description:
@@ -837,6 +854,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.1"
+  tuple:
+    dependency: transitive
+    description:
+      name: tuple
+      sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.2"
   typed_data:
     dependency: transitive
     description:
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
index 8323c01a8..a59569ae6 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
@@ -1,6 +1,7 @@
 import 'package:bitbox/bitbox.dart' as bitbox;
 import 'package:bitcoin_base/bitcoin_base.dart';
 import 'package:blockchain_utils/blockchain_utils.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
 import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
 import 'package:cw_bitcoin/electrum_balance.dart';
@@ -28,6 +29,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
     required WalletInfo walletInfo,
     required Box<UnspentCoinsInfo> unspentCoinsInfo,
     required Uint8List seedBytes,
+    required EncryptionFileUtils encryptionFileUtils,
     BitcoinAddressType? addressPageType,
     List<BitcoinAddressRecord>? initialAddresses,
     ElectrumBalance? initialBalance,
@@ -42,7 +44,8 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
             initialAddresses: initialAddresses,
             initialBalance: initialBalance,
             seedBytes: seedBytes,
-            currency: CryptoCurrency.bch) {
+            currency: CryptoCurrency.bch,
+            encryptionFileUtils: encryptionFileUtils) {
     walletAddresses = BitcoinCashWalletAddresses(
       walletInfo,
       initialAddresses: initialAddresses,
@@ -63,6 +66,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
       required String password,
       required WalletInfo walletInfo,
       required Box<UnspentCoinsInfo> unspentCoinsInfo,
+      required EncryptionFileUtils encryptionFileUtils,
       String? addressPageType,
       List<BitcoinAddressRecord>? initialAddresses,
       ElectrumBalance? initialBalance,
@@ -76,6 +80,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
       initialAddresses: initialAddresses,
       initialBalance: initialBalance,
       seedBytes: await MnemonicBip39.toSeed(mnemonic),
+      encryptionFileUtils: encryptionFileUtils,
       initialRegularAddressIndex: initialRegularAddressIndex,
       initialChangeAddressIndex: initialChangeAddressIndex,
       addressPageType: P2pkhAddressType.p2pkh,
@@ -87,6 +92,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
     required WalletInfo walletInfo,
     required Box<UnspentCoinsInfo> unspentCoinsInfo,
     required String password,
+    required EncryptionFileUtils encryptionFileUtils,
   }) async {
     final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
 
@@ -94,7 +100,12 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
 
     try {
       snp = await ElectrumWalletSnapshot.load(
-          name, walletInfo.type, password, BitcoinCashNetwork.mainnet);
+        encryptionFileUtils,
+        name,
+        walletInfo.type,
+        password,
+        BitcoinCashNetwork.mainnet,
+      );
     } catch (e) {
       if (!hasKeysFile) rethrow;
     }
@@ -105,7 +116,12 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
       keysData =
           WalletKeysData(mnemonic: snp!.mnemonic, xPub: snp.xpub, passphrase: snp.passphrase);
     } else {
-      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+      keysData = await WalletKeysFile.readKeysFile(
+        name,
+        walletInfo.type,
+        password,
+        encryptionFileUtils,
+      );
     }
 
     return BitcoinCashWallet(
@@ -135,6 +151,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
       }).toList(),
       initialBalance: snp?.balance,
       seedBytes: await MnemonicBip39.toSeed(keysData.mnemonic!),
+      encryptionFileUtils: encryptionFileUtils,
       initialRegularAddressIndex: snp?.regularAddressIndex,
       initialChangeAddressIndex: snp?.changeAddressIndex,
       addressPageType: P2pkhAddressType.p2pkh,
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_creation_credentials.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_creation_credentials.dart
index 72caa6c58..017040c5d 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_creation_credentials.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_creation_credentials.dart
@@ -2,8 +2,8 @@ import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 
 class BitcoinCashNewWalletCredentials extends WalletCredentials {
-  BitcoinCashNewWalletCredentials({required String name, WalletInfo? walletInfo})
-      : super(name: name, walletInfo: walletInfo);
+  BitcoinCashNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password})
+      : super(name: name, walletInfo: walletInfo, password: password);
 }
 
 class BitcoinCashRestoreWalletFromSeedCredentials extends WalletCredentials {
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
index 002e52c4f..a970be261 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
@@ -2,6 +2,7 @@ import 'dart:io';
 
 import 'package:bip39/bip39.dart';
 import 'package:cw_bitcoin_cash/cw_bitcoin_cash.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_base.dart';
@@ -16,10 +17,11 @@ class BitcoinCashWalletService extends WalletService<
     BitcoinCashRestoreWalletFromSeedCredentials,
     BitcoinCashRestoreWalletFromWIFCredentials,
     BitcoinCashNewWalletCredentials> {
-  BitcoinCashWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
+  BitcoinCashWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.isDirect);
 
   final Box<WalletInfo> walletInfoSource;
   final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
+  final bool isDirect;
 
   @override
   WalletType getType() => WalletType.bitcoinCash;
@@ -34,10 +36,11 @@ class BitcoinCashWalletService extends WalletService<
 
     final wallet = await BitcoinCashWalletBase.create(
         mnemonic: await MnemonicBip39.generate(strength: strength),
-        password: credentials.password!,
-        walletInfo: credentials.walletInfo!,
-        unspentCoinsInfo: unspentCoinsInfoSource);
-
+      password: credentials.password!,
+      walletInfo: credentials.walletInfo!,
+      unspentCoinsInfo: unspentCoinsInfoSource,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+    );
     await wallet.save();
     await wallet.init();
 
@@ -54,7 +57,9 @@ class BitcoinCashWalletService extends WalletService<
           password: password,
           name: name,
           walletInfo: walletInfo,
-          unspentCoinsInfo: unspentCoinsInfoSource);
+          unspentCoinsInfo: unspentCoinsInfoSource,
+          encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+      );
       await wallet.init();
       saveBackup(name);
       return wallet;
@@ -64,7 +69,9 @@ class BitcoinCashWalletService extends WalletService<
           password: password,
           name: name,
           walletInfo: walletInfo,
-          unspentCoinsInfo: unspentCoinsInfoSource);
+          unspentCoinsInfo: unspentCoinsInfoSource,
+          encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+      );
       await wallet.init();
       return wallet;
     }
@@ -86,7 +93,8 @@ class BitcoinCashWalletService extends WalletService<
         password: password,
         name: currentName,
         walletInfo: currentWalletInfo,
-        unspentCoinsInfo: unspentCoinsInfoSource);
+        unspentCoinsInfo: unspentCoinsInfoSource,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect));
 
     await currentWallet.renameWalletFiles(newName);
     await saveBackup(newName);
@@ -121,7 +129,8 @@ class BitcoinCashWalletService extends WalletService<
         password: credentials.password!,
         mnemonic: credentials.mnemonic,
         walletInfo: credentials.walletInfo!,
-        unspentCoinsInfo: unspentCoinsInfoSource);
+        unspentCoinsInfo: unspentCoinsInfoSource,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect));
     await wallet.save();
     await wallet.init();
     return wallet;
diff --git a/cw_core/lib/encryption_file_utils.dart b/cw_core/lib/encryption_file_utils.dart
new file mode 100644
index 000000000..1889c4389
--- /dev/null
+++ b/cw_core/lib/encryption_file_utils.dart
@@ -0,0 +1,42 @@
+import 'dart:io';
+import 'dart:typed_data';
+import 'package:cw_core/utils/file.dart' as file;
+import 'package:cake_backup/backup.dart' as cwb;
+
+EncryptionFileUtils encryptionFileUtilsFor(bool direct)
+ => direct
+ 	? XChaCha20EncryptionFileUtils()
+ 	: Salsa20EncryhptionFileUtils();
+
+abstract class EncryptionFileUtils {
+	Future<void> write({required String path, required String password, required String data});
+	Future<String> read({required String path, required String password});
+}
+
+class Salsa20EncryhptionFileUtils extends EncryptionFileUtils {
+	// Requires legacy complex key + iv as password 
+	@override
+	Future<void> write({required String path, required String password, required String data}) async
+		=> await file.write(path: path, password: password, data: data);
+
+	// Requires legacy complex key + iv as password 
+	@override
+	Future<String> read({required String path, required String password}) async
+		=> await file.read(path: path, password: password);
+}
+
+class XChaCha20EncryptionFileUtils extends EncryptionFileUtils {
+	@override
+	Future<void> write({required String path, required String password, required String data}) async {
+		final encrypted = await cwb.encrypt(password, Uint8List.fromList(data.codeUnits));
+		await File(path).writeAsBytes(encrypted);
+	}
+	
+	@override
+	Future<String> read({required String path, required String password}) async {
+		final file = File(path);
+		final encrypted = await file.readAsBytes();
+		final bytes = await cwb.decrypt(password, encrypted);
+		return String.fromCharCodes(bytes);
+	}
+}
\ No newline at end of file
diff --git a/cw_core/lib/wallet_base.dart b/cw_core/lib/wallet_base.dart
index a616b0bfd..f7af15224 100644
--- a/cw_core/lib/wallet_base.dart
+++ b/cw_core/lib/wallet_base.dart
@@ -84,6 +84,8 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
 
   Future<void> changePassword(String password);
 
+  String get password;
+
   Future<void>? updateBalance();
 
   void setExceptionHandler(void Function(FlutterErrorDetails) onError) => null;
diff --git a/cw_core/lib/wallet_keys_file.dart b/cw_core/lib/wallet_keys_file.dart
index 45539e09d..638cdc39d 100644
--- a/cw_core/lib/wallet_keys_file.dart
+++ b/cw_core/lib/wallet_keys_file.dart
@@ -3,10 +3,10 @@ import 'dart:developer' as dev;
 import 'dart:io';
 
 import 'package:cw_core/balance.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/transaction_history.dart';
 import 'package:cw_core/transaction_info.dart';
-import 'package:cw_core/utils/file.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_type.dart';
 
@@ -20,28 +20,32 @@ mixin WalletKeysFile<BalanceType extends Balance, HistoryType extends Transactio
 
   Future<String> makeKeysFilePath() async => "${await makePath()}.keys";
 
-  Future<void> saveKeysFile(String password, [bool isBackup = false]) async {
+  Future<void> saveKeysFile(String password, EncryptionFileUtils encryptionFileUtils,
+      [bool isBackup = false]) async {
     try {
       final rootPath = await makeKeysFilePath();
       final path = "$rootPath${isBackup ? ".backup" : ""}";
       dev.log("Saving .keys file '$path'");
-      await write(path: path, password: password, data: walletKeysData.toJSON());
+      await encryptionFileUtils.write(
+          path: path, password: password, data: walletKeysData.toJSON());
     } catch (_) {}
   }
 
-  static Future<void> createKeysFile(
-      String name, WalletType type, String password, WalletKeysData walletKeysData,
+  static Future<void> createKeysFile(String name, WalletType type, String password,
+      WalletKeysData walletKeysData, EncryptionFileUtils encryptionFileUtils,
       [bool withBackup = true]) async {
     try {
       final rootPath = await pathForWallet(name: name, type: type);
       final path = "$rootPath.keys";
 
       dev.log("Saving .keys file '$path'");
-      await write(path: path, password: password, data: walletKeysData.toJSON());
+      await encryptionFileUtils.write(
+          path: path, password: password, data: walletKeysData.toJSON());
 
       if (withBackup) {
         dev.log("Saving .keys.backup file '$path.backup'");
-        await write(path: "$path.backup", password: password, data: walletKeysData.toJSON());
+        await encryptionFileUtils.write(
+            path: "$path.backup", password: password, data: walletKeysData.toJSON());
       }
     } catch (_) {}
   }
@@ -55,14 +59,19 @@ mixin WalletKeysFile<BalanceType extends Balance, HistoryType extends Transactio
     }
   }
 
-  static Future<WalletKeysData> readKeysFile(String name, WalletType type, String password) async {
+  static Future<WalletKeysData> readKeysFile(
+    String name,
+    WalletType type,
+    String password,
+    EncryptionFileUtils encryptionFileUtils,
+  ) async {
     final path = await pathForWallet(name: name, type: type);
 
     var readPath = "$path.keys";
     try {
       if (!File(readPath).existsSync()) throw Exception("No .keys file found for $name $type");
 
-      final jsonSource = await read(path: readPath, password: password);
+      final jsonSource = await encryptionFileUtils.read(path: readPath, password: password);
       final data = json.decode(jsonSource) as Map<String, dynamic>;
       return WalletKeysData.fromJSON(data);
     } catch (e) {
@@ -72,12 +81,12 @@ mixin WalletKeysFile<BalanceType extends Balance, HistoryType extends Transactio
       if (!File(readPath).existsSync())
         throw Exception("No .keys nor a .keys.backup file found for $name $type");
 
-      final jsonSource = await read(path: readPath, password: password);
+      final jsonSource = await encryptionFileUtils.read(path: readPath, password: password);
       final data = json.decode(jsonSource) as Map<String, dynamic>;
       final keysData = WalletKeysData.fromJSON(data);
 
       dev.log("Restoring .keys from .keys.backup");
-      createKeysFile(name, type, password, keysData, false);
+      createKeysFile(name, type, password, keysData, encryptionFileUtils, false);
       return keysData;
     }
   }
diff --git a/cw_core/pubspec.lock b/cw_core/pubspec.lock
index 518c71b94..e905af2d9 100644
--- a/cw_core/pubspec.lock
+++ b/cw_core/pubspec.lock
@@ -113,6 +113,15 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "8.8.1"
+  cake_backup:
+    dependency: "direct main"
+    description:
+      path: "."
+      ref: main
+      resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38"
+      url: "https://github.com/cake-tech/cake_backup.git"
+    source: git
+    version: "1.0.0+1"
   characters:
     dependency: transitive
     description:
@@ -169,6 +178,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.0.3"
+  cryptography:
+    dependency: transitive
+    description:
+      name: cryptography
+      sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.5.0"
+  cupertino_icons:
+    dependency: transitive
+    description:
+      name: cupertino_icons
+      sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.6"
   dart_style:
     dependency: transitive
     description:
@@ -648,6 +673,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.1"
+  tuple:
+    dependency: transitive
+    description:
+      name: tuple
+      sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.2"
   typed_data:
     dependency: transitive
     description:
diff --git a/cw_core/pubspec.yaml b/cw_core/pubspec.yaml
index 0513b122c..4497a709d 100644
--- a/cw_core/pubspec.yaml
+++ b/cw_core/pubspec.yaml
@@ -19,6 +19,11 @@ dependencies:
   flutter_mobx: ^2.0.6+1
   intl: ^0.18.0
   encrypt: ^5.0.1
+  cake_backup:
+    git:
+      url: https://github.com/cake-tech/cake_backup.git
+      ref: main
+      version: 1.0.0
   socks5_proxy: ^1.0.4
   unorm_dart: ^0.3.0
 #  tor:
diff --git a/cw_ethereum/lib/ethereum_transaction_history.dart b/cw_ethereum/lib/ethereum_transaction_history.dart
index f774ae905..fbb8ab79d 100644
--- a/cw_ethereum/lib/ethereum_transaction_history.dart
+++ b/cw_ethereum/lib/ethereum_transaction_history.dart
@@ -7,6 +7,7 @@ class EthereumTransactionHistory extends EVMChainTransactionHistory {
   EthereumTransactionHistory({
     required super.walletInfo,
     required super.password,
+    required super.encryptionFileUtils,
   });
 
   @override
diff --git a/cw_ethereum/lib/ethereum_wallet.dart b/cw_ethereum/lib/ethereum_wallet.dart
index 7bcd55cf4..51aeab5e1 100644
--- a/cw_ethereum/lib/ethereum_wallet.dart
+++ b/cw_ethereum/lib/ethereum_wallet.dart
@@ -2,6 +2,7 @@ import 'dart:convert';
 
 import 'package:cw_core/cake_hive.dart';
 import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/erc20_token.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/transaction_direction.dart';
@@ -16,7 +17,6 @@ import 'package:cw_evm/evm_chain_transaction_info.dart';
 import 'package:cw_evm/evm_chain_transaction_model.dart';
 import 'package:cw_evm/evm_chain_wallet.dart';
 import 'package:cw_evm/evm_erc20_balance.dart';
-import 'package:cw_evm/file.dart';
 
 class EthereumWallet extends EVMChainWallet {
   EthereumWallet({
@@ -26,6 +26,7 @@ class EthereumWallet extends EVMChainWallet {
     super.mnemonic,
     super.initialBalance,
     super.privateKey,
+    required super.encryptionFileUtils,
   }) : super(nativeCurrency: CryptoCurrency.eth);
 
   @override
@@ -117,18 +118,24 @@ class EthereumWallet extends EVMChainWallet {
   }
 
   @override
-  EVMChainTransactionHistory setUpTransactionHistory(WalletInfo walletInfo, String password) {
-    return EthereumTransactionHistory(walletInfo: walletInfo, password: password);
+  EVMChainTransactionHistory setUpTransactionHistory(
+      WalletInfo walletInfo, String password, EncryptionFileUtils encryptionFileUtils) {
+    return EthereumTransactionHistory(
+        walletInfo: walletInfo, password: password, encryptionFileUtils: encryptionFileUtils);
   }
 
-  static Future<EthereumWallet> open(
-      {required String name, required String password, required WalletInfo walletInfo}) async {
+  static Future<EthereumWallet> open({
+    required String name,
+    required String password,
+    required WalletInfo walletInfo,
+    required EncryptionFileUtils encryptionFileUtils,
+  }) async {
     final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
     final path = await pathForWallet(name: name, type: walletInfo.type);
 
     Map<String, dynamic>? data;
     try {
-      final jsonSource = await read(path: path, password: password);
+      final jsonSource = await encryptionFileUtils.read(path: path, password: password);
 
       data = json.decode(jsonSource) as Map<String, dynamic>;
     } catch (e) {
@@ -146,7 +153,12 @@ class EthereumWallet extends EVMChainWallet {
 
       keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
     } else {
-      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+      keysData = await WalletKeysFile.readKeysFile(
+        name,
+        walletInfo.type,
+        password,
+        encryptionFileUtils,
+      );
     }
 
     return EthereumWallet(
@@ -156,6 +168,7 @@ class EthereumWallet extends EVMChainWallet {
       privateKey: keysData.privateKey,
       initialBalance: balance,
       client: EthereumClient(),
+      encryptionFileUtils: encryptionFileUtils,
     );
   }
 }
diff --git a/cw_ethereum/lib/ethereum_wallet_service.dart b/cw_ethereum/lib/ethereum_wallet_service.dart
index c0d3df2d6..84fc0a277 100644
--- a/cw_ethereum/lib/ethereum_wallet_service.dart
+++ b/cw_ethereum/lib/ethereum_wallet_service.dart
@@ -1,4 +1,5 @@
 import 'package:bip39/bip39.dart' as bip39;
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -9,7 +10,7 @@ import 'package:cw_evm/evm_chain_wallet_creation_credentials.dart';
 import 'package:cw_evm/evm_chain_wallet_service.dart';
 
 class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
-  EthereumWalletService(super.walletInfoSource, {required this.client});
+  EthereumWalletService(super.walletInfoSource, super.isDirect, {required this.client});
 
   late EthereumClient client;
 
@@ -27,6 +28,7 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
       mnemonic: mnemonic,
       password: credentials.password!,
       client: client,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -46,6 +48,7 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
         name: name,
         password: password,
         walletInfo: walletInfo,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
 
       await wallet.init();
@@ -59,6 +62,7 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
         name: name,
         password: password,
         walletInfo: walletInfo,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
       await wallet.init();
       await wallet.save();
@@ -71,7 +75,11 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
     final currentWalletInfo = walletInfoSource.values
         .firstWhere((info) => info.id == WalletBase.idFor(currentName, getType()));
     final currentWallet = await EthereumWallet.open(
-        password: password, name: currentName, walletInfo: currentWalletInfo);
+      password: password,
+      name: currentName,
+      walletInfo: currentWalletInfo,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+    );
 
     await currentWallet.renameWalletFiles(newName);
     await saveBackup(newName);
@@ -97,6 +105,7 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
       walletInfo: credentials.walletInfo!,
       password: credentials.password!,
       client: client,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -114,6 +123,7 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
       privateKey: credentials.privateKey,
       walletInfo: credentials.walletInfo!,
       client: client,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -135,6 +145,7 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
       mnemonic: credentials.mnemonic,
       walletInfo: credentials.walletInfo!,
       client: client,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
diff --git a/cw_evm/lib/evm_chain_transaction_history.dart b/cw_evm/lib/evm_chain_transaction_history.dart
index 2f5c31e82..c4d91783f 100644
--- a/cw_evm/lib/evm_chain_transaction_history.dart
+++ b/cw_evm/lib/evm_chain_transaction_history.dart
@@ -1,10 +1,10 @@
 import 'dart:convert';
 import 'dart:core';
 import 'dart:developer';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_evm/evm_chain_transaction_info.dart';
-import 'package:cw_evm/file.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cw_core/transaction_history.dart';
 
@@ -15,7 +15,8 @@ abstract class EVMChainTransactionHistory = EVMChainTransactionHistoryBase
 
 abstract class EVMChainTransactionHistoryBase
     extends TransactionHistoryBase<EVMChainTransactionInfo> with Store {
-  EVMChainTransactionHistoryBase({required this.walletInfo, required String password})
+  EVMChainTransactionHistoryBase(
+      {required this.walletInfo, required String password, required this.encryptionFileUtils})
       : _password = password {
     transactions = ObservableMap<String, EVMChainTransactionInfo>();
   }
@@ -23,6 +24,7 @@ abstract class EVMChainTransactionHistoryBase
   String _password;
 
   final WalletInfo walletInfo;
+  final EncryptionFileUtils encryptionFileUtils;
 
   //! Method to be overridden by all child classes
 
@@ -41,7 +43,7 @@ abstract class EVMChainTransactionHistoryBase
       final dirPath = await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
       String path = '$dirPath/$transactionsHistoryFileNameForWallet';
       final data = json.encode({'transactions': transactions});
-      await writeData(path: path, password: _password, data: data);
+      await encryptionFileUtils.write(path: path, password: _password, data: data);
     } catch (e, s) {
       log('Error while saving ${walletInfo.type.name} transaction history: ${e.toString()}');
       log(s.toString());
@@ -59,7 +61,7 @@ abstract class EVMChainTransactionHistoryBase
     final transactionsHistoryFileNameForWallet = getTransactionHistoryFileName();
     final dirPath = await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
     String path = '$dirPath/$transactionsHistoryFileNameForWallet';
-    final content = await read(path: path, password: _password);
+    final content = await encryptionFileUtils.read(path: path, password: _password);
     if (content.isEmpty) {
       return {};
     }
diff --git a/cw_evm/lib/evm_chain_wallet.dart b/cw_evm/lib/evm_chain_wallet.dart
index 55dcea959..80a366e6f 100644
--- a/cw_evm/lib/evm_chain_wallet.dart
+++ b/cw_evm/lib/evm_chain_wallet.dart
@@ -7,6 +7,7 @@ import 'package:bip32/bip32.dart' as bip32;
 import 'package:bip39/bip39.dart' as bip39;
 import 'package:cw_core/cake_hive.dart';
 import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/erc20_token.dart';
 import 'package:cw_core/node.dart';
 import 'package:cw_core/pathForWallet.dart';
@@ -27,7 +28,6 @@ import 'package:cw_evm/evm_chain_transaction_model.dart';
 import 'package:cw_evm/evm_chain_transaction_priority.dart';
 import 'package:cw_evm/evm_chain_wallet_addresses.dart';
 import 'package:cw_evm/evm_ledger_credentials.dart';
-import 'package:cw_evm/file.dart';
 import 'package:flutter/foundation.dart';
 import 'package:hex/hex.dart';
 import 'package:hive/hive.dart';
@@ -68,6 +68,7 @@ abstract class EVMChainWalletBase
     String? privateKey,
     required String password,
     EVMChainERC20Balance? initialBalance,
+    required this.encryptionFileUtils,
   })  : syncStatus = const NotConnectedSyncStatus(),
         _password = password,
         _mnemonic = mnemonic,
@@ -83,7 +84,7 @@ abstract class EVMChainWalletBase
         ),
         super(walletInfo) {
     this.walletInfo = walletInfo;
-    transactionHistory = setUpTransactionHistory(walletInfo, password);
+    transactionHistory = setUpTransactionHistory(walletInfo, password, encryptionFileUtils);
 
     if (!CakeHive.isAdapterRegistered(Erc20Token.typeId)) {
       CakeHive.registerAdapter(Erc20TokenAdapter());
@@ -95,6 +96,7 @@ abstract class EVMChainWalletBase
   final String? _mnemonic;
   final String? _hexPrivateKey;
   final String _password;
+  final EncryptionFileUtils encryptionFileUtils;
 
   late final Box<Erc20Token> erc20TokensBox;
 
@@ -149,7 +151,11 @@ abstract class EVMChainWalletBase
 
   Erc20Token createNewErc20TokenObject(Erc20Token token, String? iconPath);
 
-  EVMChainTransactionHistory setUpTransactionHistory(WalletInfo walletInfo, String password);
+  EVMChainTransactionHistory setUpTransactionHistory(
+    WalletInfo walletInfo,
+    String password,
+    EncryptionFileUtils encryptionFileUtils,
+  );
 
   //! Common Methods across child classes
 
@@ -510,13 +516,13 @@ abstract class EVMChainWalletBase
   @override
   Future<void> save() async {
     if (!(await WalletKeysFile.hasKeysFile(walletInfo.name, walletInfo.type))) {
-      await saveKeysFile(_password);
-      saveKeysFile(_password, true);
+      await saveKeysFile(_password, encryptionFileUtils);
+      saveKeysFile(_password, encryptionFileUtils, true);
     }
 
     await walletAddresses.updateAddressesInBox();
     final path = await makePath();
-    await write(path: path, password: _password, data: toJSON());
+    await encryptionFileUtils.write(path: path, password: _password, data: toJSON());
     await transactionHistory.save();
   }
 
@@ -690,4 +696,7 @@ abstract class EVMChainWalletBase
       bytesToHex(await _evmChainPrivateKey.signPersonalMessage(ascii.encode(message)));
 
   Web3Client? getWeb3Client() => _client.getWeb3Client();
+
+  @override
+  String get password => _password;
 }
diff --git a/cw_evm/lib/evm_chain_wallet_creation_credentials.dart b/cw_evm/lib/evm_chain_wallet_creation_credentials.dart
index be763bac7..e8a13cbb9 100644
--- a/cw_evm/lib/evm_chain_wallet_creation_credentials.dart
+++ b/cw_evm/lib/evm_chain_wallet_creation_credentials.dart
@@ -3,8 +3,8 @@ import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 
 class EVMChainNewWalletCredentials extends WalletCredentials {
-  EVMChainNewWalletCredentials({required String name, WalletInfo? walletInfo})
-      : super(name: name, walletInfo: walletInfo);
+  EVMChainNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password})
+      : super(name: name, walletInfo: walletInfo, password: password);
 }
 
 class EVMChainRestoreWalletFromSeedCredentials extends WalletCredentials {
diff --git a/cw_evm/lib/evm_chain_wallet_service.dart b/cw_evm/lib/evm_chain_wallet_service.dart
index 2bbe6bd47..e6bb41b86 100644
--- a/cw_evm/lib/evm_chain_wallet_service.dart
+++ b/cw_evm/lib/evm_chain_wallet_service.dart
@@ -15,9 +15,10 @@ abstract class EVMChainWalletService<T extends EVMChainWallet> extends WalletSer
     EVMChainRestoreWalletFromSeedCredentials,
     EVMChainRestoreWalletFromPrivateKey,
     EVMChainRestoreWalletFromHardware> {
-  EVMChainWalletService(this.walletInfoSource);
+  EVMChainWalletService(this.walletInfoSource, this.isDirect);
 
   final Box<WalletInfo> walletInfoSource;
+  final bool isDirect;
 
   @override
   WalletType getType();
diff --git a/cw_evm/lib/file.dart b/cw_evm/lib/file.dart
deleted file mode 100644
index 8fd236ec3..000000000
--- a/cw_evm/lib/file.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-import 'dart:io';
-import 'package:cw_core/key.dart';
-import 'package:encrypt/encrypt.dart' as encrypt;
-
-Future<void> write(
-    {required String path,
-    required String password,
-    required String data}) async {
-  final keys = extractKeys(password);
-  final key = encrypt.Key.fromBase64(keys.first);
-  final iv = encrypt.IV.fromBase64(keys.last);
-  final encrypted = await encode(key: key, iv: iv, data: data);
-  final f = File(path);
-  f.writeAsStringSync(encrypted);
-}
-
-Future<void> writeData(
-    {required String path,
-    required String password,
-    required String data}) async {
-  final keys = extractKeys(password);
-  final key = encrypt.Key.fromBase64(keys.first);
-  final iv = encrypt.IV.fromBase64(keys.last);
-  final encrypted = await encode(key: key, iv: iv, data: data);
-  final f = File(path);
-  f.writeAsStringSync(encrypted);
-}
-
-Future<String> read({required String path, required String password}) async {
-  final file = File(path);
-
-  if (!file.existsSync()) {
-    file.createSync();
-  }
-
-  final encrypted = file.readAsStringSync();
-
-  return decode(password: password, data: encrypted);
-}
diff --git a/cw_evm/pubspec.yaml b/cw_evm/pubspec.yaml
index c3f4347c2..b24e375a7 100644
--- a/cw_evm/pubspec.yaml
+++ b/cw_evm/pubspec.yaml
@@ -20,6 +20,7 @@ dependencies:
   hive: ^2.2.3
   collection: ^1.17.1
   shared_preferences: ^2.0.15
+  mobx: ^2.0.7+4
   cw_core:
     path: ../cw_core
   ledger_flutter: ^1.0.1
diff --git a/cw_haven/lib/haven_wallet.dart b/cw_haven/lib/haven_wallet.dart
index e639be4b9..c0ecbca68 100644
--- a/cw_haven/lib/haven_wallet.dart
+++ b/cw_haven/lib/haven_wallet.dart
@@ -38,9 +38,10 @@ class HavenWallet = HavenWalletBase with _$HavenWallet;
 
 abstract class HavenWalletBase
     extends WalletBase<MoneroBalance, HavenTransactionHistory, HavenTransactionInfo> with Store {
-  HavenWalletBase({required WalletInfo walletInfo})
+  HavenWalletBase({required WalletInfo walletInfo, String? password})
       : balance = ObservableMap.of(getHavenBalance(accountIndex: 0)),
         _isTransactionUpdating = false,
+        _password = password ?? '',
         _hasSyncAfterStartup = false,
         walletAddresses = HavenWalletAddresses(walletInfo),
         syncStatus = NotConnectedSyncStatus(),
@@ -56,6 +57,7 @@ abstract class HavenWalletBase
   }
 
   static const int _autoSaveInterval = 30;
+  final String _password;
 
   @override
   HavenWalletAddresses walletAddresses;
@@ -111,7 +113,7 @@ abstract class HavenWalletBase
     _onAccountChangeReaction?.reaction.dispose();
     _autoSaveTimer?.cancel();
   }
-  
+
   @override
   Future<void> connectToNode({required Node node}) async {
     try {
@@ -414,4 +416,7 @@ abstract class HavenWalletBase
       print(e.toString());
     }
   }
+
+  @override
+  String get password => _password;
 }
diff --git a/cw_haven/pubspec.lock b/cw_haven/pubspec.lock
index c34e164f4..6e840224c 100644
--- a/cw_haven/pubspec.lock
+++ b/cw_haven/pubspec.lock
@@ -113,6 +113,15 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "8.4.3"
+  cake_backup:
+    dependency: transitive
+    description:
+      path: "."
+      ref: main
+      resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38"
+      url: "https://github.com/cake-tech/cake_backup.git"
+    source: git
+    version: "1.0.0+1"
   characters:
     dependency: transitive
     description:
@@ -169,6 +178,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.0.2"
+  cryptography:
+    dependency: transitive
+    description:
+      name: cryptography
+      sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.5.0"
+  cupertino_icons:
+    dependency: transitive
+    description:
+      name: cupertino_icons
+      sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.6"
   cw_core:
     dependency: "direct main"
     description:
@@ -639,6 +664,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.1"
+  tuple:
+    dependency: transitive
+    description:
+      name: tuple
+      sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.2"
   typed_data:
     dependency: transitive
     description:
diff --git a/cw_monero/.metadata b/cw_monero/.metadata
index 46a2f7f6f..679a0404c 100644
--- a/cw_monero/.metadata
+++ b/cw_monero/.metadata
@@ -18,6 +18,9 @@ migration:
     - platform: macos
       create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
       base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
+    - platform: linux
+      create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
+      base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
 
   # User provided section
 
diff --git a/cw_monero/example/linux/.gitignore b/cw_monero/example/linux/.gitignore
new file mode 100644
index 000000000..d3896c984
--- /dev/null
+++ b/cw_monero/example/linux/.gitignore
@@ -0,0 +1 @@
+flutter/ephemeral
diff --git a/cw_monero/example/linux/CMakeLists.txt b/cw_monero/example/linux/CMakeLists.txt
new file mode 100644
index 000000000..8b2f28252
--- /dev/null
+++ b/cw_monero/example/linux/CMakeLists.txt
@@ -0,0 +1,138 @@
+# Project-level configuration.
+cmake_minimum_required(VERSION 3.10)
+project(runner LANGUAGES CXX)
+
+# The name of the executable created for the application. Change this to change
+# the on-disk name of your application.
+set(BINARY_NAME "cw_monero_example")
+# The unique GTK application identifier for this application. See:
+# https://wiki.gnome.org/HowDoI/ChooseApplicationID
+set(APPLICATION_ID "com.cakewallet.cw_monero")
+
+# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
+# versions of CMake.
+cmake_policy(SET CMP0063 NEW)
+
+# Load bundled libraries from the lib/ directory relative to the binary.
+set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
+
+# Root filesystem for cross-building.
+if(FLUTTER_TARGET_PLATFORM_SYSROOT)
+  set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
+  set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
+  set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+  set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+  set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+  set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+endif()
+
+# Define build configuration options.
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+  set(CMAKE_BUILD_TYPE "Debug" CACHE
+    STRING "Flutter build mode" FORCE)
+  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
+    "Debug" "Profile" "Release")
+endif()
+
+# Compilation settings that should be applied to most targets.
+#
+# Be cautious about adding new options here, as plugins use this function by
+# default. In most cases, you should add new options to specific targets instead
+# of modifying this function.
+function(APPLY_STANDARD_SETTINGS TARGET)
+  target_compile_features(${TARGET} PUBLIC cxx_std_14)
+  target_compile_options(${TARGET} PRIVATE -Wall -Werror)
+  target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
+  target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
+endfunction()
+
+# Flutter library and tool build rules.
+set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
+add_subdirectory(${FLUTTER_MANAGED_DIR})
+
+# System-level dependencies.
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
+
+add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
+
+# Define the application target. To change its name, change BINARY_NAME above,
+# not the value here, or `flutter run` will no longer work.
+#
+# Any new source files that you add to the application should be added here.
+add_executable(${BINARY_NAME}
+  "main.cc"
+  "my_application.cc"
+  "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
+)
+
+# Apply the standard set of build settings. This can be removed for applications
+# that need different build settings.
+apply_standard_settings(${BINARY_NAME})
+
+# Add dependency libraries. Add any application-specific dependencies here.
+target_link_libraries(${BINARY_NAME} PRIVATE flutter)
+target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
+
+# Run the Flutter tool portions of the build. This must not be removed.
+add_dependencies(${BINARY_NAME} flutter_assemble)
+
+# Only the install-generated bundle's copy of the executable will launch
+# correctly, since the resources must in the right relative locations. To avoid
+# people trying to run the unbundled copy, put it in a subdirectory instead of
+# the default top-level location.
+set_target_properties(${BINARY_NAME}
+  PROPERTIES
+  RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
+)
+
+# Generated plugin build rules, which manage building the plugins and adding
+# them to the application.
+include(flutter/generated_plugins.cmake)
+
+
+# === Installation ===
+# By default, "installing" just makes a relocatable bundle in the build
+# directory.
+set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+  set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
+endif()
+
+# Start with a clean build bundle directory every time.
+install(CODE "
+  file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
+  " COMPONENT Runtime)
+
+set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
+set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
+
+install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
+  COMPONENT Runtime)
+
+install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
+  COMPONENT Runtime)
+
+install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+  COMPONENT Runtime)
+
+foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
+  install(FILES "${bundled_library}"
+    DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+    COMPONENT Runtime)
+endforeach(bundled_library)
+
+# Fully re-copy the assets directory on each build to avoid having stale files
+# from a previous install.
+set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
+install(CODE "
+  file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
+  " COMPONENT Runtime)
+install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
+  DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
+
+# Install the AOT library on non-Debug builds only.
+if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
+  install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+    COMPONENT Runtime)
+endif()
diff --git a/cw_monero/example/linux/flutter/CMakeLists.txt b/cw_monero/example/linux/flutter/CMakeLists.txt
new file mode 100644
index 000000000..d5bd01648
--- /dev/null
+++ b/cw_monero/example/linux/flutter/CMakeLists.txt
@@ -0,0 +1,88 @@
+# This file controls Flutter-level build steps. It should not be edited.
+cmake_minimum_required(VERSION 3.10)
+
+set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
+
+# Configuration provided via flutter tool.
+include(${EPHEMERAL_DIR}/generated_config.cmake)
+
+# TODO: Move the rest of this into files in ephemeral. See
+# https://github.com/flutter/flutter/issues/57146.
+
+# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
+# which isn't available in 3.10.
+function(list_prepend LIST_NAME PREFIX)
+    set(NEW_LIST "")
+    foreach(element ${${LIST_NAME}})
+        list(APPEND NEW_LIST "${PREFIX}${element}")
+    endforeach(element)
+    set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
+endfunction()
+
+# === Flutter Library ===
+# System-level dependencies.
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
+pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
+pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
+
+set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
+
+# Published to parent scope for install step.
+set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
+set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
+set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
+set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
+
+list(APPEND FLUTTER_LIBRARY_HEADERS
+  "fl_basic_message_channel.h"
+  "fl_binary_codec.h"
+  "fl_binary_messenger.h"
+  "fl_dart_project.h"
+  "fl_engine.h"
+  "fl_json_message_codec.h"
+  "fl_json_method_codec.h"
+  "fl_message_codec.h"
+  "fl_method_call.h"
+  "fl_method_channel.h"
+  "fl_method_codec.h"
+  "fl_method_response.h"
+  "fl_plugin_registrar.h"
+  "fl_plugin_registry.h"
+  "fl_standard_message_codec.h"
+  "fl_standard_method_codec.h"
+  "fl_string_codec.h"
+  "fl_value.h"
+  "fl_view.h"
+  "flutter_linux.h"
+)
+list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
+add_library(flutter INTERFACE)
+target_include_directories(flutter INTERFACE
+  "${EPHEMERAL_DIR}"
+)
+target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
+target_link_libraries(flutter INTERFACE
+  PkgConfig::GTK
+  PkgConfig::GLIB
+  PkgConfig::GIO
+)
+add_dependencies(flutter flutter_assemble)
+
+# === Flutter tool backend ===
+# _phony_ is a non-existent file to force this command to run every time,
+# since currently there's no way to get a full input/output list from the
+# flutter tool.
+add_custom_command(
+  OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
+    ${CMAKE_CURRENT_BINARY_DIR}/_phony_
+  COMMAND ${CMAKE_COMMAND} -E env
+    ${FLUTTER_TOOL_ENVIRONMENT}
+    "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
+      ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
+  VERBATIM
+)
+add_custom_target(flutter_assemble DEPENDS
+  "${FLUTTER_LIBRARY}"
+  ${FLUTTER_LIBRARY_HEADERS}
+)
diff --git a/cw_monero/example/linux/flutter/generated_plugin_registrant.cc b/cw_monero/example/linux/flutter/generated_plugin_registrant.cc
new file mode 100644
index 000000000..1936c88a6
--- /dev/null
+++ b/cw_monero/example/linux/flutter/generated_plugin_registrant.cc
@@ -0,0 +1,15 @@
+//
+//  Generated file. Do not edit.
+//
+
+// clang-format off
+
+#include "generated_plugin_registrant.h"
+
+#include <cw_monero/cw_monero_plugin.h>
+
+void fl_register_plugins(FlPluginRegistry* registry) {
+  g_autoptr(FlPluginRegistrar) cw_monero_registrar =
+      fl_plugin_registry_get_registrar_for_plugin(registry, "CwMoneroPlugin");
+  cw_monero_plugin_register_with_registrar(cw_monero_registrar);
+}
diff --git a/cw_monero/example/linux/flutter/generated_plugin_registrant.h b/cw_monero/example/linux/flutter/generated_plugin_registrant.h
new file mode 100644
index 000000000..e0f0a47bc
--- /dev/null
+++ b/cw_monero/example/linux/flutter/generated_plugin_registrant.h
@@ -0,0 +1,15 @@
+//
+//  Generated file. Do not edit.
+//
+
+// clang-format off
+
+#ifndef GENERATED_PLUGIN_REGISTRANT_
+#define GENERATED_PLUGIN_REGISTRANT_
+
+#include <flutter_linux/flutter_linux.h>
+
+// Registers Flutter plugins.
+void fl_register_plugins(FlPluginRegistry* registry);
+
+#endif  // GENERATED_PLUGIN_REGISTRANT_
diff --git a/cw_monero/example/linux/flutter/generated_plugins.cmake b/cw_monero/example/linux/flutter/generated_plugins.cmake
new file mode 100644
index 000000000..efcc9a8f9
--- /dev/null
+++ b/cw_monero/example/linux/flutter/generated_plugins.cmake
@@ -0,0 +1,24 @@
+#
+# Generated file, do not edit.
+#
+
+list(APPEND FLUTTER_PLUGIN_LIST
+  cw_monero
+)
+
+list(APPEND FLUTTER_FFI_PLUGIN_LIST
+)
+
+set(PLUGIN_BUNDLED_LIBRARIES)
+
+foreach(plugin ${FLUTTER_PLUGIN_LIST})
+  add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
+  target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
+  list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
+  list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
+endforeach(plugin)
+
+foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
+  add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
+  list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
+endforeach(ffi_plugin)
diff --git a/cw_monero/example/linux/main.cc b/cw_monero/example/linux/main.cc
new file mode 100644
index 000000000..e7c5c5437
--- /dev/null
+++ b/cw_monero/example/linux/main.cc
@@ -0,0 +1,6 @@
+#include "my_application.h"
+
+int main(int argc, char** argv) {
+  g_autoptr(MyApplication) app = my_application_new();
+  return g_application_run(G_APPLICATION(app), argc, argv);
+}
diff --git a/cw_monero/example/linux/my_application.cc b/cw_monero/example/linux/my_application.cc
new file mode 100644
index 000000000..875fc557a
--- /dev/null
+++ b/cw_monero/example/linux/my_application.cc
@@ -0,0 +1,104 @@
+#include "my_application.h"
+
+#include <flutter_linux/flutter_linux.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+
+#include "flutter/generated_plugin_registrant.h"
+
+struct _MyApplication {
+  GtkApplication parent_instance;
+  char** dart_entrypoint_arguments;
+};
+
+G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
+
+// Implements GApplication::activate.
+static void my_application_activate(GApplication* application) {
+  MyApplication* self = MY_APPLICATION(application);
+  GtkWindow* window =
+      GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
+
+  // Use a header bar when running in GNOME as this is the common style used
+  // by applications and is the setup most users will be using (e.g. Ubuntu
+  // desktop).
+  // If running on X and not using GNOME then just use a traditional title bar
+  // in case the window manager does more exotic layout, e.g. tiling.
+  // If running on Wayland assume the header bar will work (may need changing
+  // if future cases occur).
+  gboolean use_header_bar = TRUE;
+#ifdef GDK_WINDOWING_X11
+  GdkScreen* screen = gtk_window_get_screen(window);
+  if (GDK_IS_X11_SCREEN(screen)) {
+    const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
+    if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
+      use_header_bar = FALSE;
+    }
+  }
+#endif
+  if (use_header_bar) {
+    GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
+    gtk_widget_show(GTK_WIDGET(header_bar));
+    gtk_header_bar_set_title(header_bar, "cw_monero_example");
+    gtk_header_bar_set_show_close_button(header_bar, TRUE);
+    gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
+  } else {
+    gtk_window_set_title(window, "cw_monero_example");
+  }
+
+  gtk_window_set_default_size(window, 1280, 720);
+  gtk_widget_show(GTK_WIDGET(window));
+
+  g_autoptr(FlDartProject) project = fl_dart_project_new();
+  fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
+
+  FlView* view = fl_view_new(project);
+  gtk_widget_show(GTK_WIDGET(view));
+  gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
+
+  fl_register_plugins(FL_PLUGIN_REGISTRY(view));
+
+  gtk_widget_grab_focus(GTK_WIDGET(view));
+}
+
+// Implements GApplication::local_command_line.
+static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
+  MyApplication* self = MY_APPLICATION(application);
+  // Strip out the first argument as it is the binary name.
+  self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
+
+  g_autoptr(GError) error = nullptr;
+  if (!g_application_register(application, nullptr, &error)) {
+     g_warning("Failed to register: %s", error->message);
+     *exit_status = 1;
+     return TRUE;
+  }
+
+  g_application_activate(application);
+  *exit_status = 0;
+
+  return TRUE;
+}
+
+// Implements GObject::dispose.
+static void my_application_dispose(GObject* object) {
+  MyApplication* self = MY_APPLICATION(object);
+  g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
+  G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
+}
+
+static void my_application_class_init(MyApplicationClass* klass) {
+  G_APPLICATION_CLASS(klass)->activate = my_application_activate;
+  G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
+  G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
+}
+
+static void my_application_init(MyApplication* self) {}
+
+MyApplication* my_application_new() {
+  return MY_APPLICATION(g_object_new(my_application_get_type(),
+                                     "application-id", APPLICATION_ID,
+                                     "flags", G_APPLICATION_NON_UNIQUE,
+                                     nullptr));
+}
diff --git a/cw_monero/example/linux/my_application.h b/cw_monero/example/linux/my_application.h
new file mode 100644
index 000000000..72271d5e4
--- /dev/null
+++ b/cw_monero/example/linux/my_application.h
@@ -0,0 +1,18 @@
+#ifndef FLUTTER_MY_APPLICATION_H_
+#define FLUTTER_MY_APPLICATION_H_
+
+#include <gtk/gtk.h>
+
+G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
+                     GtkApplication)
+
+/**
+ * my_application_new:
+ *
+ * Creates a new Flutter-based application.
+ *
+ * Returns: a new #MyApplication.
+ */
+MyApplication* my_application_new();
+
+#endif  // FLUTTER_MY_APPLICATION_H_
diff --git a/cw_monero/lib/api/account_list.dart b/cw_monero/lib/api/account_list.dart
index 199896631..7cb95a507 100644
--- a/cw_monero/lib/api/account_list.dart
+++ b/cw_monero/lib/api/account_list.dart
@@ -34,7 +34,6 @@ List<monero.SubaddressAccountRow> getAllAccount() {
   // final size = monero.Wallet_numSubaddressAccounts(wptr!);
   refreshAccounts();
   int size = monero.SubaddressAccount_getAll_size(subaddressAccount!);
-  print("size: $size");
   if (size == 0) {
     monero.Wallet_addSubaddressAccount(wptr!);
     return getAllAccount();
diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart
index 26c83b06e..14bf92d16 100644
--- a/cw_monero/lib/api/wallet_manager.dart
+++ b/cw_monero/lib/api/wallet_manager.dart
@@ -7,6 +7,8 @@ import 'package:cw_monero/api/exceptions/wallet_creation_exception.dart';
 import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
 import 'package:cw_monero/api/exceptions/wallet_restore_from_keys_exception.dart';
 import 'package:cw_monero/api/exceptions/wallet_restore_from_seed_exception.dart';
+import 'package:cw_monero/api/wallet.dart';
+import 'package:flutter/foundation.dart';
 import 'package:cw_monero/api/transaction_history.dart';
 import 'package:cw_monero/api/wallet.dart';
 import 'package:flutter/foundation.dart';
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index 9298f8a49..31e09ca2d 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -3,6 +3,8 @@ import 'dart:ffi';
 import 'dart:io';
 import 'dart:isolate';
 
+import 'package:cw_core/pathForWallet.dart';
+import 'package:cw_core/transaction_priority.dart';
 import 'package:cw_core/account.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/monero_amount_format.dart';
@@ -50,7 +52,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
     MoneroTransactionHistory, MoneroTransactionInfo> with Store {
   MoneroWalletBase(
       {required WalletInfo walletInfo,
-      required Box<UnspentCoinsInfo> unspentCoinsInfo})
+      required Box<UnspentCoinsInfo> unspentCoinsInfo,
+      required String password})
       : balance = ObservableMap<CryptoCurrency, MoneroBalance>.of({
           CryptoCurrency.xmr: MoneroBalance(
               fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
@@ -59,6 +62,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
         _isTransactionUpdating = false,
         _hasSyncAfterStartup = false,
         isEnabledAutoGenerateSubaddress = false,
+        _password = password,
         syncStatus = NotConnectedSyncStatus(),
         unspentCoins = [],
         this.unspentCoinsInfo = unspentCoinsInfo,
@@ -111,6 +115,9 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
   String get seed => monero_wallet.getSeed();
   String seedLegacy(String? language) => monero_wallet.getSeedLegacy(language);
 
+  @override
+  String get password => _password;
+
   @override
   MoneroWalletKeys get keys => MoneroWalletKeys(
       privateSpendKey: monero_wallet.getSecretSpendKey(),
@@ -127,6 +134,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
   bool _hasSyncAfterStartup;
   Timer? _autoSaveTimer;
   List<MoneroUnspent> unspentCoins;
+  String _password;
 
   Future<void> init() async {
     await walletAddresses.init();
diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart
index 3588ebb78..d771d1815 100644
--- a/cw_monero/lib/monero_wallet_service.dart
+++ b/cw_monero/lib/monero_wallet_service.dart
@@ -93,7 +93,9 @@ class MoneroWalletService extends WalletService<
       await monero_wallet_manager.createWallet(
           path: path, password: credentials.password!, language: credentials.language);
       final wallet = MoneroWallet(
-          walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
+        walletInfo: credentials.walletInfo!,
+        unspentCoinsInfo: unspentCoinsInfoSource,
+        password: credentials.password!);
       await wallet.init();
 
       return wallet;
@@ -126,10 +128,14 @@ class MoneroWalletService extends WalletService<
         await repairOldAndroidWallet(name);
       }
 
-      await monero_wallet_manager.openWalletAsync({'path': path, 'password': password});
-      final walletInfo = walletInfoSource.values
-          .firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
-      wallet = MoneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
+      await monero_wallet_manager
+          .openWalletAsync({'path': path, 'password': password});
+      final walletInfo = walletInfoSource.values.firstWhere(
+          (info) => info.id == WalletBase.idFor(name, getType()));
+      final wallet = MoneroWallet(
+        walletInfo: walletInfo,
+        unspentCoinsInfo: unspentCoinsInfoSource,
+        password: password);
       final isValid = wallet.walletAddresses.validate();
 
       if (!isValid) {
@@ -162,15 +168,22 @@ class MoneroWalletService extends WalletService<
       final bool invalidSignature = e.toString().contains('invalid signature') ||
           (e is WalletOpeningException && e.message.contains('invalid signature'));
 
+      final bool invalidPassword = e.toString().contains('invalid password') ||
+          (e is WalletOpeningException && e.message.contains('invalid password'));
+
       if (!isBadAlloc &&
           !doesNotCorrespond &&
           !isMissingCacheFilesIOS &&
           !isMissingCacheFilesAndroid &&
           !invalidSignature &&
+          !invalidPassword &&
           wallet != null &&
           wallet.onError != null) {
         wallet.onError!(FlutterErrorDetails(exception: e, stack: s));
       }
+      if (invalidPassword) {
+        rethrow;
+      }
 
       await restoreOrResetWalletFiles(name);
       return openWallet(name, password);
@@ -206,11 +219,15 @@ class MoneroWalletService extends WalletService<
   }
 
   @override
-  Future<void> rename(String currentName, String password, String newName) async {
-    final currentWalletInfo = walletInfoSource.values
-        .firstWhere((info) => info.id == WalletBase.idFor(currentName, getType()));
-    final currentWallet =
-        MoneroWallet(walletInfo: currentWalletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
+  Future<void> rename(
+      String currentName, String password, String newName) async {
+    final currentWalletInfo = walletInfoSource.values.firstWhere(
+        (info) => info.id == WalletBase.idFor(currentName, getType()));
+    final currentWallet = MoneroWallet(
+      walletInfo: currentWalletInfo,
+      unspentCoinsInfo: unspentCoinsInfoSource,
+      password: password,
+    );
 
     await currentWallet.renameWalletFiles(newName);
 
@@ -235,7 +252,9 @@ class MoneroWalletService extends WalletService<
           viewKey: credentials.viewKey,
           spendKey: credentials.spendKey);
       final wallet = MoneroWallet(
-          walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
+        walletInfo: credentials.walletInfo!,
+        unspentCoinsInfo: unspentCoinsInfoSource,
+        password: credentials.password!);
       await wallet.init();
 
       return wallet;
@@ -268,7 +287,9 @@ class MoneroWalletService extends WalletService<
           seed: credentials.mnemonic,
           restoreHeight: credentials.height!);
       final wallet = MoneroWallet(
-          walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
+        walletInfo: credentials.walletInfo!,
+        unspentCoinsInfo: unspentCoinsInfoSource,
+        password: credentials.password!);
       await wallet.init();
 
       return wallet;
@@ -315,7 +336,11 @@ class MoneroWalletService extends WalletService<
         restoreHeight: height,
         spendKey: spendKey);
 
-    final wallet = MoneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
+    final wallet = MoneroWallet(
+      walletInfo: walletInfo,
+      unspentCoinsInfo: unspentCoinsInfoSource,
+      password: password,
+    );
     await wallet.init();
 
     return wallet;
@@ -364,7 +389,11 @@ class MoneroWalletService extends WalletService<
       await monero_wallet_manager.openWalletAsync({'path': path, 'password': password});
       final walletInfo = walletInfoSource.values
           .firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
-      final wallet = MoneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
+      final wallet = MoneroWallet(
+        walletInfo: walletInfo,
+        unspentCoinsInfo: unspentCoinsInfoSource,
+        password: password,
+      );
       return wallet.seed;
     } catch (_) {
       // if the file couldn't be opened or read
diff --git a/cw_monero/linux/CMakeLists.txt b/cw_monero/linux/CMakeLists.txt
new file mode 100644
index 000000000..ba685269d
--- /dev/null
+++ b/cw_monero/linux/CMakeLists.txt
@@ -0,0 +1,270 @@
+# The Flutter tooling requires that developers have CMake 3.10 or later
+# installed. You should not increase this version, as doing so will cause
+# the plugin to fail to compile for some customers of the plugin.
+cmake_minimum_required(VERSION 3.10)
+
+# Project-level configuration.
+set(PROJECT_NAME "cw_monero")
+project(${PROJECT_NAME} LANGUAGES CXX)
+
+# This value is used when generating builds using this plugin, so it must
+# not be changed.
+set(PLUGIN_NAME "cw_monero_plugin")
+
+# Define the plugin library target. Its name must not be changed (see comment
+# on PLUGIN_NAME above).
+#
+# Any new source files that you add to the plugin should be added here.
+add_library(${PLUGIN_NAME} SHARED
+  "cw_monero_plugin.cc"
+  "../ios/Classes/monero_api.cpp"
+)
+
+# Apply a standard set of build settings that are configured in the
+# application-level CMakeLists.txt. This can be removed for plugins that want
+# full control over build settings.
+apply_standard_settings(${PLUGIN_NAME})
+
+# Symbols are hidden by default to reduce the chance of accidental conflicts
+# between plugins. This should not be removed; any symbols that should be
+# exported should be explicitly exported with the FLUTTER_PLUGIN_EXPORT macro.
+set_target_properties(${PLUGIN_NAME} PROPERTIES
+  CXX_VISIBILITY_PRESET hidden)
+target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
+
+# Source include directories and library dependencies. Add any plugin-specific
+# dependencies here.
+target_include_directories(${PLUGIN_NAME} INTERFACE
+  "${CMAKE_CURRENT_SOURCE_DIR}/include")
+target_link_libraries(${PLUGIN_NAME} PRIVATE flutter)
+target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK)
+target_link_libraries(${PLUGIN_NAME} PUBLIC cw_monero)
+# List of absolute paths to libraries that should be bundled with the plugin.
+# This list could contain prebuilt libraries, or libraries created by an
+# external build triggered from this build file.
+set(cw_monero_bundled_libraries
+  ""
+  PARENT_SCOPE
+)
+
+add_library( cw_monero
+             STATIC
+             ../ios/Classes/monero_api.cpp)
+
+set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../cw_shared_external/ios/External/linux)
+
+############
+# libsodium
+############
+
+add_library(sodium STATIC IMPORTED)
+set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libsodium.a)
+
+############
+# OpenSSL
+############
+
+add_library(crypto STATIC IMPORTED)
+set_target_properties(crypto PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libcrypto.a)
+
+add_library(ssl STATIC IMPORTED)
+set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libssl.a)
+
+############
+# Boost
+############
+
+add_library(boost_chrono STATIC IMPORTED)
+set_target_properties(boost_chrono PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libboost_chrono.a)
+
+add_library(boost_date_time STATIC IMPORTED)
+set_target_properties(boost_date_time PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libboost_date_time.a)
+
+add_library(boost_filesystem STATIC IMPORTED)
+set_target_properties(boost_filesystem PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libboost_filesystem.a)
+
+add_library(boost_program_options STATIC IMPORTED)
+set_target_properties(boost_program_options PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libboost_program_options.a)
+
+add_library(boost_regex STATIC IMPORTED)
+set_target_properties(boost_regex PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libboost_regex.a)
+
+add_library(boost_serialization STATIC IMPORTED)
+set_target_properties(boost_serialization PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libboost_serialization.a)
+
+add_library(boost_system STATIC IMPORTED)
+set_target_properties(boost_system PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libboost_system.a)
+
+add_library(boost_thread STATIC IMPORTED)
+set_target_properties(boost_thread PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libboost_thread.a)
+
+add_library(boost_wserialization STATIC IMPORTED)
+set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libboost_wserialization.a)
+
+#############
+# Monero
+#############
+
+
+add_library(wallet STATIC IMPORTED)
+set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libwallet.a)
+        
+add_library(wallet_api STATIC IMPORTED)
+set_target_properties(wallet_api PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libwallet_api.a)
+
+add_library(cryptonote_core STATIC IMPORTED)
+set_target_properties(cryptonote_core PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libcryptonote_core.a)
+
+add_library(cryptonote_basic STATIC IMPORTED)
+set_target_properties(cryptonote_basic PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libcryptonote_basic.a)
+
+add_library(cryptonote_format_utils_basic STATIC IMPORTED)
+set_target_properties(cryptonote_format_utils_basic PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libcryptonote_format_utils_basic.a)        
+
+add_library(mnemonics STATIC IMPORTED)
+set_target_properties(mnemonics PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libmnemonics.a)
+
+add_library(common STATIC IMPORTED)
+set_target_properties(common PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libcommon.a)
+
+add_library(cncrypto STATIC IMPORTED)
+set_target_properties(cncrypto PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libcncrypto.a)
+
+add_library(ringct STATIC IMPORTED)
+set_target_properties(ringct PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libringct.a)
+
+add_library(ringct_basic STATIC IMPORTED)
+set_target_properties(ringct_basic PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libringct_basic.a)
+
+add_library(blockchain_db STATIC IMPORTED)
+set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libblockchain_db.a)
+
+add_library(lmdb STATIC IMPORTED)
+set_target_properties(lmdb PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/liblmdb.a)
+
+add_library(easylogging STATIC IMPORTED)
+set_target_properties(easylogging PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libeasylogging.a)
+
+add_library(epee STATIC IMPORTED)
+set_target_properties(epee PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libepee.a)
+
+add_library(blocks STATIC IMPORTED)
+set_target_properties(blocks PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libblocks.a)
+
+add_library(checkpoints STATIC IMPORTED)
+set_target_properties(checkpoints PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libcheckpoints.a)
+
+add_library(device STATIC IMPORTED)
+set_target_properties(device PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libdevice.a)
+
+add_library(device_trezor STATIC IMPORTED)
+set_target_properties(device_trezor PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libdevice_trezor.a)
+
+add_library(multisig STATIC IMPORTED)
+set_target_properties(multisig PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libmultisig.a)
+
+add_library(version STATIC IMPORTED)
+set_target_properties(version PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libversion.a)
+
+add_library(net STATIC IMPORTED)
+set_target_properties(net PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libnet.a)
+        
+add_library(hardforks STATIC IMPORTED)
+set_target_properties(hardforks PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libhardforks.a)
+
+add_library(randomx STATIC IMPORTED)
+set_target_properties(randomx PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/librandomx.a)
+
+add_library(rpc_base STATIC IMPORTED)
+set_target_properties(rpc_base PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/librpc_base.a)
+
+add_library(wallet-crypto STATIC IMPORTED)
+set_target_properties(wallet-crypto PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/monero/libwallet-crypto.a)
+
+add_library(unbound STATIC IMPORTED)
+set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
+        ${EXTERNAL_LIBS_DIR}/lib/libunbound.a)
+
+include_directories( ${EXTERNAL_LIBS_DIR}/include )
+
+target_link_libraries(  cw_monero
+                       
+                        wallet_api
+                        wallet
+                        cryptonote_core
+                        cryptonote_basic
+                        cryptonote_format_utils_basic
+                        mnemonics
+                        ringct
+                        ringct_basic
+                        net
+                        common
+                        cncrypto
+                        blockchain_db
+                        lmdb
+                        easylogging
+                        unbound
+                        epee
+                        blocks
+                        checkpoints
+                        device
+                        device_trezor
+                        multisig
+                        version
+                        randomx
+                        hardforks
+                        rpc_base
+                        wallet-crypto
+
+                        boost_chrono
+                        boost_date_time
+                        boost_filesystem
+                        boost_program_options
+                        boost_regex
+                        boost_serialization
+                        boost_system
+                        boost_thread
+                        boost_wserialization
+
+                        ssl
+                        crypto
+                        
+                        sodium
+                        )
diff --git a/cw_monero/linux/cw_monero_plugin.cc b/cw_monero/linux/cw_monero_plugin.cc
new file mode 100644
index 000000000..ca8524c9e
--- /dev/null
+++ b/cw_monero/linux/cw_monero_plugin.cc
@@ -0,0 +1,70 @@
+#include "include/cw_monero/cw_monero_plugin.h"
+
+#include <flutter_linux/flutter_linux.h>
+#include <gtk/gtk.h>
+#include <sys/utsname.h>
+
+#include <cstring>
+
+#define CW_MONERO_PLUGIN(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj), cw_monero_plugin_get_type(), \
+                              CwMoneroPlugin))
+
+struct _CwMoneroPlugin {
+  GObject parent_instance;
+};
+
+G_DEFINE_TYPE(CwMoneroPlugin, cw_monero_plugin, g_object_get_type())
+
+// Called when a method call is received from Flutter.
+static void cw_monero_plugin_handle_method_call(
+    CwMoneroPlugin* self,
+    FlMethodCall* method_call) {
+  g_autoptr(FlMethodResponse) response = nullptr;
+
+  const gchar* method = fl_method_call_get_name(method_call);
+
+  if (strcmp(method, "getPlatformVersion") == 0) {
+    struct utsname uname_data = {};
+    uname(&uname_data);
+    g_autofree gchar *version = g_strdup_printf("Linux %s", uname_data.version);
+    g_autoptr(FlValue) result = fl_value_new_string(version);
+    response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
+  } else {
+    response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
+  }
+
+  fl_method_call_respond(method_call, response, nullptr);
+}
+
+static void cw_monero_plugin_dispose(GObject* object) {
+  G_OBJECT_CLASS(cw_monero_plugin_parent_class)->dispose(object);
+}
+
+static void cw_monero_plugin_class_init(CwMoneroPluginClass* klass) {
+  G_OBJECT_CLASS(klass)->dispose = cw_monero_plugin_dispose;
+}
+
+static void cw_monero_plugin_init(CwMoneroPlugin* self) {}
+
+static void method_call_cb(FlMethodChannel* channel, FlMethodCall* method_call,
+                           gpointer user_data) {
+  CwMoneroPlugin* plugin = CW_MONERO_PLUGIN(user_data);
+  cw_monero_plugin_handle_method_call(plugin, method_call);
+}
+
+void cw_monero_plugin_register_with_registrar(FlPluginRegistrar* registrar) {
+  CwMoneroPlugin* plugin = CW_MONERO_PLUGIN(
+      g_object_new(cw_monero_plugin_get_type(), nullptr));
+
+  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
+  g_autoptr(FlMethodChannel) channel =
+      fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar),
+                            "cw_monero",
+                            FL_METHOD_CODEC(codec));
+  fl_method_channel_set_method_call_handler(channel, method_call_cb,
+                                            g_object_ref(plugin),
+                                            g_object_unref);
+
+  g_object_unref(plugin);
+}
diff --git a/cw_monero/linux/flutter/generated_plugin_registrant.cc b/cw_monero/linux/flutter/generated_plugin_registrant.cc
new file mode 100644
index 000000000..e71a16d23
--- /dev/null
+++ b/cw_monero/linux/flutter/generated_plugin_registrant.cc
@@ -0,0 +1,11 @@
+//
+//  Generated file. Do not edit.
+//
+
+// clang-format off
+
+#include "generated_plugin_registrant.h"
+
+
+void fl_register_plugins(FlPluginRegistry* registry) {
+}
diff --git a/cw_monero/linux/flutter/generated_plugin_registrant.h b/cw_monero/linux/flutter/generated_plugin_registrant.h
new file mode 100644
index 000000000..e0f0a47bc
--- /dev/null
+++ b/cw_monero/linux/flutter/generated_plugin_registrant.h
@@ -0,0 +1,15 @@
+//
+//  Generated file. Do not edit.
+//
+
+// clang-format off
+
+#ifndef GENERATED_PLUGIN_REGISTRANT_
+#define GENERATED_PLUGIN_REGISTRANT_
+
+#include <flutter_linux/flutter_linux.h>
+
+// Registers Flutter plugins.
+void fl_register_plugins(FlPluginRegistry* registry);
+
+#endif  // GENERATED_PLUGIN_REGISTRANT_
diff --git a/cw_monero/linux/flutter/generated_plugins.cmake b/cw_monero/linux/flutter/generated_plugins.cmake
new file mode 100644
index 000000000..2e1de87a7
--- /dev/null
+++ b/cw_monero/linux/flutter/generated_plugins.cmake
@@ -0,0 +1,23 @@
+#
+# Generated file, do not edit.
+#
+
+list(APPEND FLUTTER_PLUGIN_LIST
+)
+
+list(APPEND FLUTTER_FFI_PLUGIN_LIST
+)
+
+set(PLUGIN_BUNDLED_LIBRARIES)
+
+foreach(plugin ${FLUTTER_PLUGIN_LIST})
+  add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
+  target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
+  list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
+  list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
+endforeach(plugin)
+
+foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
+  add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
+  list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
+endforeach(ffi_plugin)
diff --git a/cw_monero/linux/include/cw_monero/cw_monero_plugin.h b/cw_monero/linux/include/cw_monero/cw_monero_plugin.h
new file mode 100644
index 000000000..387903ff6
--- /dev/null
+++ b/cw_monero/linux/include/cw_monero/cw_monero_plugin.h
@@ -0,0 +1,26 @@
+#ifndef FLUTTER_PLUGIN_CW_MONERO_PLUGIN_H_
+#define FLUTTER_PLUGIN_CW_MONERO_PLUGIN_H_
+
+#include <flutter_linux/flutter_linux.h>
+
+G_BEGIN_DECLS
+
+#ifdef FLUTTER_PLUGIN_IMPL
+#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default")))
+#else
+#define FLUTTER_PLUGIN_EXPORT
+#endif
+
+typedef struct _CwMoneroPlugin CwMoneroPlugin;
+typedef struct {
+  GObjectClass parent_class;
+} CwMoneroPluginClass;
+
+FLUTTER_PLUGIN_EXPORT GType cw_monero_plugin_get_type();
+
+FLUTTER_PLUGIN_EXPORT void cw_monero_plugin_register_with_registrar(
+    FlPluginRegistrar* registrar);
+
+G_END_DECLS
+
+#endif  // FLUTTER_PLUGIN_CW_MONERO_PLUGIN_H_
diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock
index 38299b2dc..07c3b8876 100644
--- a/cw_monero/pubspec.lock
+++ b/cw_monero/pubspec.lock
@@ -113,6 +113,15 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "8.9.2"
+  cake_backup:
+    dependency: transitive
+    description:
+      path: "."
+      ref: main
+      resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38"
+      url: "https://github.com/cake-tech/cake_backup.git"
+    source: git
+    version: "1.0.0+1"
   characters:
     dependency: transitive
     description:
@@ -169,6 +178,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.0.3"
+  cryptography:
+    dependency: transitive
+    description:
+      name: cryptography
+      sha256: d146b76d33d94548cf035233fbc2f4338c1242fa119013bead807d033fc4ae05
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.7.0"
+  cupertino_icons:
+    dependency: transitive
+    description:
+      name: cupertino_icons
+      sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.8"
   cw_core:
     dependency: "direct main"
     description:
@@ -342,10 +367,10 @@ packages:
     dependency: transitive
     description:
       name: js
-      sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
+      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
       url: "https://pub.dev"
     source: hosted
-    version: "0.7.1"
+    version: "0.6.7"
   json_annotation:
     dependency: transitive
     description:
@@ -696,6 +721,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.1"
+  tuple:
+    dependency: transitive
+    description:
+      name: tuple
+      sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.2"
   typed_data:
     dependency: transitive
     description:
diff --git a/cw_nano/lib/file.dart b/cw_nano/lib/file.dart
deleted file mode 100644
index 8fd236ec3..000000000
--- a/cw_nano/lib/file.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-import 'dart:io';
-import 'package:cw_core/key.dart';
-import 'package:encrypt/encrypt.dart' as encrypt;
-
-Future<void> write(
-    {required String path,
-    required String password,
-    required String data}) async {
-  final keys = extractKeys(password);
-  final key = encrypt.Key.fromBase64(keys.first);
-  final iv = encrypt.IV.fromBase64(keys.last);
-  final encrypted = await encode(key: key, iv: iv, data: data);
-  final f = File(path);
-  f.writeAsStringSync(encrypted);
-}
-
-Future<void> writeData(
-    {required String path,
-    required String password,
-    required String data}) async {
-  final keys = extractKeys(password);
-  final key = encrypt.Key.fromBase64(keys.first);
-  final iv = encrypt.IV.fromBase64(keys.last);
-  final encrypted = await encode(key: key, iv: iv, data: data);
-  final f = File(path);
-  f.writeAsStringSync(encrypted);
-}
-
-Future<String> read({required String path, required String password}) async {
-  final file = File(path);
-
-  if (!file.existsSync()) {
-    file.createSync();
-  }
-
-  final encrypted = file.readAsStringSync();
-
-  return decode(password: password, data: encrypted);
-}
diff --git a/cw_nano/lib/nano_transaction_history.dart b/cw_nano/lib/nano_transaction_history.dart
index dadd353c4..44d64f7d4 100644
--- a/cw_nano/lib/nano_transaction_history.dart
+++ b/cw_nano/lib/nano_transaction_history.dart
@@ -2,24 +2,29 @@ import 'dart:convert';
 import 'dart:core';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/wallet_info.dart';
-import 'package:cw_nano/file.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cw_core/transaction_history.dart';
 import 'package:cw_nano/nano_transaction_info.dart';
 
 part 'nano_transaction_history.g.dart';
+
 const transactionsHistoryFileName = 'transactions.json';
 
 class NanoTransactionHistory = NanoTransactionHistoryBase with _$NanoTransactionHistory;
 
-abstract class NanoTransactionHistoryBase
-    extends TransactionHistoryBase<NanoTransactionInfo> with Store {
-  NanoTransactionHistoryBase({required this.walletInfo, required String password})
-      : _password = password {
+abstract class NanoTransactionHistoryBase extends TransactionHistoryBase<NanoTransactionInfo>
+    with Store {
+  NanoTransactionHistoryBase({
+    required this.walletInfo,
+    required String password,
+    required this.encryptionFileUtils,
+  }) : _password = password {
     transactions = ObservableMap<String, NanoTransactionInfo>();
   }
 
   final WalletInfo walletInfo;
+  final EncryptionFileUtils encryptionFileUtils;
   String _password;
 
   Future<void> init() async => await _load();
@@ -30,7 +35,7 @@ abstract class NanoTransactionHistoryBase
       final dirPath = await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
       final path = '$dirPath/$transactionsHistoryFileName';
       final data = json.encode({'transactions': transactions});
-      await writeData(path: path, password: _password, data: data);
+      await encryptionFileUtils.write(path: path, password: _password, data: data);
     } catch (e) {
       print('Error while save nano transaction history: ${e.toString()}');
     }
@@ -46,7 +51,10 @@ abstract class NanoTransactionHistoryBase
   Future<Map<String, dynamic>> _read() async {
     final dirPath = await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
     final path = '$dirPath/$transactionsHistoryFileName';
-    final content = await read(path: path, password: _password);
+    final content = await encryptionFileUtils.read(path: path, password: _password);
+    if (content.isEmpty) {
+      return {};
+    }
     return json.decode(content) as Map<String, dynamic>;
   }
 
diff --git a/cw_nano/lib/nano_wallet.dart b/cw_nano/lib/nano_wallet.dart
index 55e01d10b..cba8d09a0 100644
--- a/cw_nano/lib/nano_wallet.dart
+++ b/cw_nano/lib/nano_wallet.dart
@@ -5,6 +5,7 @@ import 'dart:io';
 import 'package:bip39/bip39.dart' as bip39;
 import 'package:cw_core/cake_hive.dart';
 import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/n2_node.dart';
 import 'package:cw_core/nano_account.dart';
 import 'package:cw_core/nano_account_info_response.dart';
@@ -17,7 +18,6 @@ import 'package:cw_core/transaction_priority.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_keys_file.dart';
-import 'package:cw_nano/file.dart';
 import 'package:cw_nano/nano_balance.dart';
 import 'package:cw_nano/nano_client.dart';
 import 'package:cw_nano/nano_transaction_credentials.dart';
@@ -42,11 +42,13 @@ abstract class NanoWalletBase
     required String mnemonic,
     required String password,
     NanoBalance? initialBalance,
+    required EncryptionFileUtils encryptionFileUtils,
   })  : syncStatus = NotConnectedSyncStatus(),
         _password = password,
         _mnemonic = mnemonic,
         _derivationType = walletInfo.derivationInfo!.derivationType!,
         _isTransactionUpdating = false,
+        _encryptionFileUtils = encryptionFileUtils,
         _client = NanoClient(),
         walletAddresses = NanoWalletAddresses(walletInfo),
         balance = ObservableMap<CryptoCurrency, NanoBalance>.of({
@@ -55,7 +57,11 @@ abstract class NanoWalletBase
         }),
         super(walletInfo) {
     this.walletInfo = walletInfo;
-    transactionHistory = NanoTransactionHistory(walletInfo: walletInfo, password: password);
+    transactionHistory = NanoTransactionHistory(
+      walletInfo: walletInfo,
+      password: password,
+      encryptionFileUtils: encryptionFileUtils,
+    );
     if (!CakeHive.isAdapterRegistered(NanoAccount.typeId)) {
       CakeHive.registerAdapter(NanoAccountAdapter());
     }
@@ -65,6 +71,8 @@ abstract class NanoWalletBase
   final String _password;
   DerivationType _derivationType;
 
+  final EncryptionFileUtils _encryptionFileUtils;
+
   String? _privateKey;
   String? _publicAddress;
   String? _hexSeed;
@@ -89,6 +97,9 @@ abstract class NanoWalletBase
   @observable
   late ObservableMap<CryptoCurrency, NanoBalance> balance;
 
+  @override
+  String get password => _password;
+
   static const int POLL_INTERVAL_SECONDS = 10;
 
   // initialize the different forms of private / public key we'll need:
@@ -308,13 +319,13 @@ abstract class NanoWalletBase
   @override
   Future<void> save() async {
     if (!(await WalletKeysFile.hasKeysFile(walletInfo.name, walletInfo.type))) {
-      await saveKeysFile(_password);
-      saveKeysFile(_password, true);
+      await saveKeysFile(_password, _encryptionFileUtils);
+      saveKeysFile(_password, _encryptionFileUtils, true);
     }
 
     await walletAddresses.updateAddressesInBox();
     final path = await makePath();
-    await write(path: path, password: _password, data: toJSON());
+    await _encryptionFileUtils.write(path: path, password: _password, data: toJSON());
     await transactionHistory.save();
   }
 
@@ -373,13 +384,14 @@ abstract class NanoWalletBase
     required String name,
     required String password,
     required WalletInfo walletInfo,
+    required EncryptionFileUtils encryptionFileUtils,
   }) async {
     final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
     final path = await pathForWallet(name: name, type: walletInfo.type);
 
     Map<String, dynamic>? data = null;
     try {
-      final jsonSource = await read(path: path, password: password);
+      final jsonSource = await encryptionFileUtils.read(path: path, password: password);
 
       data = json.decode(jsonSource) as Map<String, dynamic>;
     } catch (e) {
@@ -400,7 +412,12 @@ abstract class NanoWalletBase
       keysData = WalletKeysData(
           mnemonic: isHexSeed ? null : mnemonic, altMnemonic: isHexSeed ? mnemonic : null);
     } else {
-      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+      keysData = await WalletKeysFile.readKeysFile(
+        name,
+        walletInfo.type,
+        password,
+        encryptionFileUtils,
+      );
     }
 
     DerivationType derivationType = DerivationType.nano;
@@ -416,6 +433,7 @@ abstract class NanoWalletBase
       password: password,
       mnemonic: keysData.mnemonic!,
       initialBalance: balance,
+      encryptionFileUtils: encryptionFileUtils,
     );
     // init() should always be run after this!
   }
diff --git a/cw_nano/lib/nano_wallet_service.dart b/cw_nano/lib/nano_wallet_service.dart
index 755598705..ac3d6581a 100644
--- a/cw_nano/lib/nano_wallet_service.dart
+++ b/cw_nano/lib/nano_wallet_service.dart
@@ -1,6 +1,7 @@
 import 'dart:io';
 
 import 'package:cw_core/pathForWallet.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_service.dart';
@@ -15,9 +16,10 @@ import 'package:nanoutil/nanoutil.dart';
 
 class NanoWalletService extends WalletService<NanoNewWalletCredentials,
     NanoRestoreWalletFromSeedCredentials, NanoRestoreWalletFromKeysCredentials, NanoNewWalletCredentials> {
-  NanoWalletService(this.walletInfoSource);
+  NanoWalletService(this.walletInfoSource, this.isDirect);
 
   final Box<WalletInfo> walletInfoSource;
+  final bool isDirect;
 
   static bool walletFilesExist(String path) =>
       !File(path).existsSync() && !File('$path.keys').existsSync();
@@ -38,6 +40,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
       walletInfo: credentials.walletInfo!,
       mnemonic: mnemonic,
       password: credentials.password!,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
     await wallet.init();
     return wallet;
@@ -65,8 +68,12 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
 
     String randomWords =
         (List<String>.from(nm.NanoMnemomics.WORDLIST)..shuffle()).take(24).join(' ');
-    final currentWallet =
-        NanoWallet(walletInfo: currentWalletInfo, password: password, mnemonic: randomWords);
+    final currentWallet = NanoWallet(
+      walletInfo: currentWalletInfo,
+      password: password,
+      mnemonic: randomWords,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+    );
 
     await currentWallet.renameWalletFiles(newName);
     await saveBackup(newName);
@@ -103,6 +110,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
       password: credentials.password!,
       mnemonic: mnemonic ?? credentials.seedKey,
       walletInfo: credentials.walletInfo!,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
     await wallet.init();
     await wallet.save();
@@ -139,6 +147,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
       password: credentials.password!,
       mnemonic: credentials.mnemonic,
       walletInfo: credentials.walletInfo!,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -160,6 +169,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
         name: name,
         password: password,
         walletInfo: walletInfo,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
 
       await wallet.init();
@@ -172,6 +182,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
         name: name,
         password: password,
         walletInfo: walletInfo,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
 
       await wallet.init();
diff --git a/cw_nano/pubspec.lock b/cw_nano/pubspec.lock
index c3d4b26b6..bbe909199 100644
--- a/cw_nano/pubspec.lock
+++ b/cw_nano/pubspec.lock
@@ -137,6 +137,15 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "8.9.2"
+  cake_backup:
+    dependency: transitive
+    description:
+      path: "."
+      ref: main
+      resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38"
+      url: "https://github.com/cake-tech/cake_backup.git"
+    source: git
+    version: "1.0.0+1"
   characters:
     dependency: transitive
     description:
@@ -193,6 +202,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.0.3"
+  cryptography:
+    dependency: transitive
+    description:
+      name: cryptography
+      sha256: d146b76d33d94548cf035233fbc2f4338c1242fa119013bead807d033fc4ae05
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.7.0"
+  cupertino_icons:
+    dependency: transitive
+    description:
+      name: cupertino_icons
+      sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.8"
   cw_core:
     dependency: "direct main"
     description:
@@ -797,6 +822,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.1"
+  tuple:
+    dependency: transitive
+    description:
+      name: tuple
+      sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.2"
   typed_data:
     dependency: transitive
     description:
diff --git a/cw_polygon/lib/polygon_transaction_history.dart b/cw_polygon/lib/polygon_transaction_history.dart
index 8674882cd..27547b7ee 100644
--- a/cw_polygon/lib/polygon_transaction_history.dart
+++ b/cw_polygon/lib/polygon_transaction_history.dart
@@ -8,6 +8,7 @@ class PolygonTransactionHistory extends EVMChainTransactionHistory {
   PolygonTransactionHistory({
     required super.walletInfo,
     required super.password,
+    required super.encryptionFileUtils,
   });
 
   @override
diff --git a/cw_polygon/lib/polygon_wallet.dart b/cw_polygon/lib/polygon_wallet.dart
index b0b0793b9..eb59a746e 100644
--- a/cw_polygon/lib/polygon_wallet.dart
+++ b/cw_polygon/lib/polygon_wallet.dart
@@ -2,6 +2,7 @@ import 'dart:convert';
 
 import 'package:cw_core/cake_hive.dart';
 import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/erc20_token.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/transaction_direction.dart';
@@ -12,7 +13,6 @@ import 'package:cw_evm/evm_chain_transaction_info.dart';
 import 'package:cw_evm/evm_chain_transaction_model.dart';
 import 'package:cw_evm/evm_chain_wallet.dart';
 import 'package:cw_evm/evm_erc20_balance.dart';
-import 'package:cw_evm/file.dart';
 import 'package:cw_polygon/default_polygon_erc20_tokens.dart';
 import 'package:cw_polygon/polygon_client.dart';
 import 'package:cw_polygon/polygon_transaction_history.dart';
@@ -26,6 +26,7 @@ class PolygonWallet extends EVMChainWallet {
     super.initialBalance,
     super.privateKey,
     required super.client,
+    required super.encryptionFileUtils,
   }) : super(nativeCurrency: CryptoCurrency.maticpoly);
 
   @override
@@ -92,18 +93,27 @@ class PolygonWallet extends EVMChainWallet {
   }
 
   @override
-  EVMChainTransactionHistory setUpTransactionHistory(WalletInfo walletInfo, String password) {
-    return PolygonTransactionHistory(walletInfo: walletInfo, password: password);
+  EVMChainTransactionHistory setUpTransactionHistory(
+      WalletInfo walletInfo, String password, EncryptionFileUtils encryptionFileUtils) {
+    return PolygonTransactionHistory(
+      walletInfo: walletInfo,
+      password: password,
+      encryptionFileUtils: encryptionFileUtils,
+    );
   }
 
-  static Future<PolygonWallet> open(
-      {required String name, required String password, required WalletInfo walletInfo}) async {
+  static Future<PolygonWallet> open({
+    required String name,
+    required String password,
+    required WalletInfo walletInfo,
+    required EncryptionFileUtils encryptionFileUtils,
+  }) async {
     final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
     final path = await pathForWallet(name: name, type: walletInfo.type);
 
     Map<String, dynamic>? data;
     try {
-      final jsonSource = await read(path: path, password: password);
+      final jsonSource = await encryptionFileUtils.read(path: path, password: password);
 
       data = json.decode(jsonSource) as Map<String, dynamic>;
     } catch (e) {
@@ -121,7 +131,12 @@ class PolygonWallet extends EVMChainWallet {
 
       keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
     } else {
-      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+      keysData = await WalletKeysFile.readKeysFile(
+        name,
+        walletInfo.type,
+        password,
+        encryptionFileUtils,
+      );
     }
 
     return PolygonWallet(
@@ -131,6 +146,7 @@ class PolygonWallet extends EVMChainWallet {
       privateKey: keysData.privateKey,
       initialBalance: balance,
       client: PolygonClient(),
+      encryptionFileUtils: encryptionFileUtils,
     );
   }
 }
diff --git a/cw_polygon/lib/polygon_wallet_service.dart b/cw_polygon/lib/polygon_wallet_service.dart
index 14baffc44..4efc312f7 100644
--- a/cw_polygon/lib/polygon_wallet_service.dart
+++ b/cw_polygon/lib/polygon_wallet_service.dart
@@ -1,4 +1,5 @@
 import 'package:bip39/bip39.dart' as bip39;
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -10,7 +11,7 @@ import 'package:cw_polygon/polygon_wallet.dart';
 
 class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
   PolygonWalletService(
-    super.walletInfoSource, {
+    super.walletInfoSource, super.isDirect, {
     required this.client,
   });
 
@@ -30,6 +31,7 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
       mnemonic: mnemonic,
       password: credentials.password!,
       client: client,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -48,6 +50,7 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
         name: name,
         password: password,
         walletInfo: walletInfo,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
 
       await wallet.init();
@@ -61,6 +64,7 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
         name: name,
         password: password,
         walletInfo: walletInfo,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
 
       await wallet.init();
@@ -77,6 +81,7 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
       privateKey: credentials.privateKey,
       walletInfo: credentials.walletInfo!,
       client: client,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -99,6 +104,7 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
       walletInfo: credentials.walletInfo!,
       password: credentials.password!,
       client: client,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -120,6 +126,7 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
       mnemonic: credentials.mnemonic,
       walletInfo: credentials.walletInfo!,
       client: client,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -134,7 +141,11 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
     final currentWalletInfo = walletInfoSource.values
         .firstWhere((info) => info.id == WalletBase.idFor(currentName, getType()));
     final currentWallet = await PolygonWallet.open(
-        password: password, name: currentName, walletInfo: currentWalletInfo);
+      password: password,
+      name: currentName,
+      walletInfo: currentWalletInfo,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+    );
 
     await currentWallet.renameWalletFiles(newName);
     await saveBackup(newName);
diff --git a/cw_solana/lib/file.dart b/cw_solana/lib/file.dart
deleted file mode 100644
index 8fd236ec3..000000000
--- a/cw_solana/lib/file.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-import 'dart:io';
-import 'package:cw_core/key.dart';
-import 'package:encrypt/encrypt.dart' as encrypt;
-
-Future<void> write(
-    {required String path,
-    required String password,
-    required String data}) async {
-  final keys = extractKeys(password);
-  final key = encrypt.Key.fromBase64(keys.first);
-  final iv = encrypt.IV.fromBase64(keys.last);
-  final encrypted = await encode(key: key, iv: iv, data: data);
-  final f = File(path);
-  f.writeAsStringSync(encrypted);
-}
-
-Future<void> writeData(
-    {required String path,
-    required String password,
-    required String data}) async {
-  final keys = extractKeys(password);
-  final key = encrypt.Key.fromBase64(keys.first);
-  final iv = encrypt.IV.fromBase64(keys.last);
-  final encrypted = await encode(key: key, iv: iv, data: data);
-  final f = File(path);
-  f.writeAsStringSync(encrypted);
-}
-
-Future<String> read({required String path, required String password}) async {
-  final file = File(path);
-
-  if (!file.existsSync()) {
-    file.createSync();
-  }
-
-  final encrypted = file.readAsStringSync();
-
-  return decode(password: password, data: encrypted);
-}
diff --git a/cw_solana/lib/solana_transaction_history.dart b/cw_solana/lib/solana_transaction_history.dart
index c03de19ad..77f93b9ee 100644
--- a/cw_solana/lib/solana_transaction_history.dart
+++ b/cw_solana/lib/solana_transaction_history.dart
@@ -1,8 +1,8 @@
 import 'dart:convert';
 import 'dart:core';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/wallet_info.dart';
-import 'package:cw_solana/file.dart';
 import 'package:cw_solana/solana_transaction_info.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cw_core/transaction_history.dart';
@@ -15,12 +15,14 @@ class SolanaTransactionHistory = SolanaTransactionHistoryBase with _$SolanaTrans
 
 abstract class SolanaTransactionHistoryBase extends TransactionHistoryBase<SolanaTransactionInfo>
     with Store {
-  SolanaTransactionHistoryBase({required this.walletInfo, required String password})
+  SolanaTransactionHistoryBase(
+      {required this.walletInfo, required String password, required this.encryptionFileUtils})
       : _password = password {
     transactions = ObservableMap<String, SolanaTransactionInfo>();
   }
 
   final WalletInfo walletInfo;
+  final EncryptionFileUtils encryptionFileUtils;
   String _password;
 
   Future<void> init() async => await _load();
@@ -32,7 +34,7 @@ abstract class SolanaTransactionHistoryBase extends TransactionHistoryBase<Solan
       final path = '$dirPath/$transactionsHistoryFileName';
       final transactionMaps = transactions.map((key, value) => MapEntry(key, value.toJson()));
       final data = json.encode({'transactions': transactionMaps});
-      await writeData(path: path, password: _password, data: data);
+      await encryptionFileUtils.write(path: path, password: _password, data: data);
     } catch (e, s) {
       print('Error while saving solana transaction history: ${e.toString()}');
       print(s);
@@ -49,7 +51,7 @@ abstract class SolanaTransactionHistoryBase extends TransactionHistoryBase<Solan
   Future<Map<String, dynamic>> _read() async {
     final dirPath = await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
     final path = '$dirPath/$transactionsHistoryFileName';
-    final content = await read(path: path, password: _password);
+    final content = await encryptionFileUtils.read(path: path, password: _password);
     if (content.isEmpty) {
       return {};
     }
diff --git a/cw_solana/lib/solana_wallet.dart b/cw_solana/lib/solana_wallet.dart
index 2b30a204c..66b8bca42 100644
--- a/cw_solana/lib/solana_wallet.dart
+++ b/cw_solana/lib/solana_wallet.dart
@@ -4,6 +4,7 @@ import 'dart:io';
 
 import 'package:cw_core/cake_hive.dart';
 import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/node.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/pending_transaction.dart';
@@ -15,7 +16,6 @@ import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_keys_file.dart';
 import 'package:cw_solana/default_spl_tokens.dart';
-import 'package:cw_solana/file.dart';
 import 'package:cw_solana/solana_balance.dart';
 import 'package:cw_solana/solana_client.dart';
 import 'package:cw_solana/solana_exceptions.dart';
@@ -46,6 +46,7 @@ abstract class SolanaWalletBase
     String? privateKey,
     required String password,
     SolanaBalance? initialBalance,
+    required this.encryptionFileUtils,
   })  : syncStatus = const NotConnectedSyncStatus(),
         _password = password,
         _mnemonic = mnemonic,
@@ -56,7 +57,11 @@ abstract class SolanaWalletBase
             {CryptoCurrency.sol: initialBalance ?? SolanaBalance(BigInt.zero.toDouble())}),
         super(walletInfo) {
     this.walletInfo = walletInfo;
-    transactionHistory = SolanaTransactionHistory(walletInfo: walletInfo, password: password);
+    transactionHistory = SolanaTransactionHistory(
+      walletInfo: walletInfo,
+      password: password,
+      encryptionFileUtils: encryptionFileUtils,
+    );
 
     if (!CakeHive.isAdapterRegistered(SPLToken.typeId)) {
       CakeHive.registerAdapter(SPLTokenAdapter());
@@ -68,6 +73,7 @@ abstract class SolanaWalletBase
   final String _password;
   final String? _mnemonic;
   final String? _hexPrivateKey;
+  final EncryptionFileUtils encryptionFileUtils;
 
   // The Solana WalletPair
   Ed25519HDKeyPair? _walletKeyPair;
@@ -77,7 +83,7 @@ abstract class SolanaWalletBase
   // To access the privateKey bytes.
   Ed25519HDKeyPairData? _keyPairData;
 
-  late SolanaWalletClient _client;
+  late final SolanaWalletClient _client;
 
   @observable
   double? estimatedFee;
@@ -97,7 +103,7 @@ abstract class SolanaWalletBase
   @observable
   late ObservableMap<CryptoCurrency, SolanaBalance> balance;
 
-  Completer<SharedPreferences> _sharedPrefs = Completer();
+  final Completer<SharedPreferences> _sharedPrefs = Completer();
 
   @override
   Ed25519HDKeyPairData get keys {
@@ -343,13 +349,13 @@ abstract class SolanaWalletBase
   @override
   Future<void> save() async {
     if (!(await WalletKeysFile.hasKeysFile(walletInfo.name, walletInfo.type))) {
-      await saveKeysFile(_password);
-      saveKeysFile(_password, true);
+      await saveKeysFile(_password, encryptionFileUtils);
+      saveKeysFile(_password, encryptionFileUtils, true);
     }
 
     await walletAddresses.updateAddressesInBox();
     final path = await makePath();
-    await write(path: path, password: _password, data: toJSON());
+    await encryptionFileUtils.write(path: path, password: _password, data: toJSON());
     await transactionHistory.save();
   }
 
@@ -382,13 +388,14 @@ abstract class SolanaWalletBase
     required String name,
     required String password,
     required WalletInfo walletInfo,
+    required EncryptionFileUtils encryptionFileUtils,
   }) async {
     final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
     final path = await pathForWallet(name: name, type: walletInfo.type);
 
     Map<String, dynamic>? data;
     try {
-      final jsonSource = await read(path: path, password: password);
+      final jsonSource = await encryptionFileUtils.read(path: path, password: password);
 
       data = json.decode(jsonSource) as Map<String, dynamic>;
     } catch (e) {
@@ -405,7 +412,12 @@ abstract class SolanaWalletBase
 
       keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
     } else {
-      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+      keysData = await WalletKeysFile.readKeysFile(
+        name,
+        walletInfo.type,
+        password,
+        encryptionFileUtils,
+      );
     }
 
     return SolanaWallet(
@@ -414,6 +426,7 @@ abstract class SolanaWalletBase
       mnemonic: keysData.mnemonic,
       privateKey: keysData.privateKey,
       initialBalance: balance,
+      encryptionFileUtils: encryptionFileUtils,
     );
   }
 
@@ -572,4 +585,7 @@ abstract class SolanaWalletBase
   }
 
   SolanaClient? get solanaClient => _client.getSolanaClient;
+
+  @override
+  String get password => _password;
 }
diff --git a/cw_solana/lib/solana_wallet_creation_credentials.dart b/cw_solana/lib/solana_wallet_creation_credentials.dart
index 881c30abd..5b4fa1774 100644
--- a/cw_solana/lib/solana_wallet_creation_credentials.dart
+++ b/cw_solana/lib/solana_wallet_creation_credentials.dart
@@ -2,8 +2,8 @@ import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 
 class SolanaNewWalletCredentials extends WalletCredentials {
-  SolanaNewWalletCredentials({required String name, WalletInfo? walletInfo})
-      : super(name: name, walletInfo: walletInfo);
+  SolanaNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password})
+      : super(name: name, walletInfo: walletInfo, password: password);
 }
 
 class SolanaRestoreWalletFromSeedCredentials extends WalletCredentials {
diff --git a/cw_solana/lib/solana_wallet_service.dart b/cw_solana/lib/solana_wallet_service.dart
index 4afb2f7f4..7461be33b 100644
--- a/cw_solana/lib/solana_wallet_service.dart
+++ b/cw_solana/lib/solana_wallet_service.dart
@@ -2,6 +2,7 @@ import 'dart:io';
 
 import 'package:bip39/bip39.dart' as bip39;
 import 'package:collection/collection.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/balance.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/transaction_history.dart';
@@ -17,9 +18,10 @@ import 'package:hive/hive.dart';
 
 class SolanaWalletService extends WalletService<SolanaNewWalletCredentials,
     SolanaRestoreWalletFromSeedCredentials, SolanaRestoreWalletFromPrivateKey, SolanaNewWalletCredentials> {
-  SolanaWalletService(this.walletInfoSource);
+  SolanaWalletService(this.walletInfoSource, this.isDirect);
 
   final Box<WalletInfo> walletInfoSource;
+  final bool isDirect;
 
   @override
   Future<SolanaWallet> create(SolanaNewWalletCredentials credentials, {bool? isTestnet}) async {
@@ -31,6 +33,7 @@ class SolanaWalletService extends WalletService<SolanaNewWalletCredentials,
       walletInfo: credentials.walletInfo!,
       mnemonic: mnemonic,
       password: credentials.password!,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -56,6 +59,7 @@ class SolanaWalletService extends WalletService<SolanaNewWalletCredentials,
         name: name,
         password: password,
         walletInfo: walletInfo,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
 
       await wallet.init();
@@ -69,6 +73,7 @@ class SolanaWalletService extends WalletService<SolanaNewWalletCredentials,
         name: name,
         password: password,
         walletInfo: walletInfo,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
 
       await wallet.init();
@@ -92,6 +97,7 @@ class SolanaWalletService extends WalletService<SolanaNewWalletCredentials,
       password: credentials.password!,
       privateKey: credentials.privateKey,
       walletInfo: credentials.walletInfo!,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -112,6 +118,7 @@ class SolanaWalletService extends WalletService<SolanaNewWalletCredentials,
       password: credentials.password!,
       mnemonic: credentials.mnemonic,
       walletInfo: credentials.walletInfo!,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -126,7 +133,11 @@ class SolanaWalletService extends WalletService<SolanaNewWalletCredentials,
     final currentWalletInfo = walletInfoSource.values
         .firstWhere((info) => info.id == WalletBase.idFor(currentName, getType()));
     final currentWallet = await SolanaWalletBase.open(
-        password: password, name: currentName, walletInfo: currentWalletInfo);
+      password: password,
+      name: currentName,
+      walletInfo: currentWalletInfo,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+    );
 
     await currentWallet.renameWalletFiles(newName);
     await saveBackup(newName);
diff --git a/cw_tron/lib/file.dart b/cw_tron/lib/file.dart
deleted file mode 100644
index 8fd236ec3..000000000
--- a/cw_tron/lib/file.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-import 'dart:io';
-import 'package:cw_core/key.dart';
-import 'package:encrypt/encrypt.dart' as encrypt;
-
-Future<void> write(
-    {required String path,
-    required String password,
-    required String data}) async {
-  final keys = extractKeys(password);
-  final key = encrypt.Key.fromBase64(keys.first);
-  final iv = encrypt.IV.fromBase64(keys.last);
-  final encrypted = await encode(key: key, iv: iv, data: data);
-  final f = File(path);
-  f.writeAsStringSync(encrypted);
-}
-
-Future<void> writeData(
-    {required String path,
-    required String password,
-    required String data}) async {
-  final keys = extractKeys(password);
-  final key = encrypt.Key.fromBase64(keys.first);
-  final iv = encrypt.IV.fromBase64(keys.last);
-  final encrypted = await encode(key: key, iv: iv, data: data);
-  final f = File(path);
-  f.writeAsStringSync(encrypted);
-}
-
-Future<String> read({required String path, required String password}) async {
-  final file = File(path);
-
-  if (!file.existsSync()) {
-    file.createSync();
-  }
-
-  final encrypted = file.readAsStringSync();
-
-  return decode(password: password, data: encrypted);
-}
diff --git a/cw_tron/lib/tron_transaction_history.dart b/cw_tron/lib/tron_transaction_history.dart
index 7d7274226..9d226c09c 100644
--- a/cw_tron/lib/tron_transaction_history.dart
+++ b/cw_tron/lib/tron_transaction_history.dart
@@ -3,7 +3,7 @@ import 'dart:core';
 import 'dart:developer';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/wallet_info.dart';
-import 'package:cw_evm/file.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_tron/tron_transaction_info.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cw_core/transaction_history.dart';
@@ -14,7 +14,8 @@ class TronTransactionHistory = TronTransactionHistoryBase with _$TronTransaction
 
 abstract class TronTransactionHistoryBase extends TransactionHistoryBase<TronTransactionInfo>
     with Store {
-  TronTransactionHistoryBase({required this.walletInfo, required String password})
+  TronTransactionHistoryBase(
+      {required this.walletInfo, required String password, required this.encryptionFileUtils})
       : _password = password {
     transactions = ObservableMap<String, TronTransactionInfo>();
   }
@@ -22,6 +23,7 @@ abstract class TronTransactionHistoryBase extends TransactionHistoryBase<TronTra
   String _password;
 
   final WalletInfo walletInfo;
+  final EncryptionFileUtils encryptionFileUtils;
 
   Future<void> init() async => await _load();
 
@@ -33,7 +35,7 @@ abstract class TronTransactionHistoryBase extends TransactionHistoryBase<TronTra
       String path = '$dirPath/$transactionsHistoryFileNameForWallet';
       final transactionMaps = transactions.map((key, value) => MapEntry(key, value.toJson()));
       final data = json.encode({'transactions': transactionMaps});
-      await writeData(path: path, password: _password, data: data);
+      await encryptionFileUtils.write(path: path, password: _password, data: data);
     } catch (e, s) {
       log('Error while saving ${walletInfo.type.name} transaction history: ${e.toString()}');
       log(s.toString());
@@ -51,7 +53,7 @@ abstract class TronTransactionHistoryBase extends TransactionHistoryBase<TronTra
     String transactionsHistoryFileNameForWallet = 'tron_transactions.json';
     final dirPath = await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
     String path = '$dirPath/$transactionsHistoryFileNameForWallet';
-    final content = await read(path: path, password: _password);
+    final content = await encryptionFileUtils.read(path: path, password: _password);
     if (content.isEmpty) {
       return {};
     }
diff --git a/cw_tron/lib/tron_wallet.dart b/cw_tron/lib/tron_wallet.dart
index 3566dcd94..7dc43b4bb 100644
--- a/cw_tron/lib/tron_wallet.dart
+++ b/cw_tron/lib/tron_wallet.dart
@@ -7,6 +7,7 @@ import 'package:bip39/bip39.dart' as bip39;
 import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:cw_core/cake_hive.dart';
 import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/node.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/pending_transaction.dart';
@@ -19,7 +20,6 @@ import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_keys_file.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:cw_tron/default_tron_tokens.dart';
-import 'package:cw_tron/file.dart';
 import 'package:cw_tron/tron_abi.dart';
 import 'package:cw_tron/tron_balance.dart';
 import 'package:cw_tron/tron_client.dart';
@@ -46,6 +46,7 @@ abstract class TronWalletBase
     String? privateKey,
     required String password,
     TronBalance? initialBalance,
+    required this.encryptionFileUtils,
   })  : syncStatus = const NotConnectedSyncStatus(),
         _password = password,
         _mnemonic = mnemonic,
@@ -57,7 +58,8 @@ abstract class TronWalletBase
         ),
         super(walletInfo) {
     this.walletInfo = walletInfo;
-    transactionHistory = TronTransactionHistory(walletInfo: walletInfo, password: password);
+    transactionHistory = TronTransactionHistory(
+        walletInfo: walletInfo, password: password, encryptionFileUtils: encryptionFileUtils);
 
     if (!CakeHive.isAdapterRegistered(TronToken.typeId)) {
       CakeHive.registerAdapter(TronTokenAdapter());
@@ -67,6 +69,7 @@ abstract class TronWalletBase
   final String? _mnemonic;
   final String? _hexPrivateKey;
   final String _password;
+  final EncryptionFileUtils encryptionFileUtils;
 
   late final Box<TronToken> tronTokensBox;
 
@@ -125,13 +128,14 @@ abstract class TronWalletBase
     required String name,
     required String password,
     required WalletInfo walletInfo,
+    required EncryptionFileUtils encryptionFileUtils,
   }) async {
     final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
     final path = await pathForWallet(name: name, type: walletInfo.type);
 
     Map<String, dynamic>? data;
     try {
-      final jsonSource = await read(path: path, password: password);
+      final jsonSource = await encryptionFileUtils.read(path: path, password: password);
 
       data = json.decode(jsonSource) as Map<String, dynamic>;
     } catch (e) {
@@ -148,7 +152,12 @@ abstract class TronWalletBase
 
       keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
     } else {
-      keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
+      keysData = await WalletKeysFile.readKeysFile(
+        name,
+        walletInfo.type,
+        password,
+        encryptionFileUtils,
+      );
     }
 
     return TronWallet(
@@ -157,6 +166,7 @@ abstract class TronWalletBase
       mnemonic: keysData.mnemonic,
       privateKey: keysData.privateKey,
       initialBalance: balance,
+      encryptionFileUtils: encryptionFileUtils,
     );
   }
 
@@ -430,13 +440,13 @@ abstract class TronWalletBase
   @override
   Future<void> save() async {
     if (!(await WalletKeysFile.hasKeysFile(walletInfo.name, walletInfo.type))) {
-      await saveKeysFile(_password);
-      saveKeysFile(_password, true);
+      await saveKeysFile(_password, encryptionFileUtils);
+      saveKeysFile(_password, encryptionFileUtils, true);
     }
 
     await walletAddresses.updateAddressesInBox();
     final path = await makePath();
-    await write(path: path, password: _password, data: toJSON());
+    await encryptionFileUtils.write(path: path, password: _password, data: toJSON());
     await transactionHistory.save();
   }
 
@@ -584,4 +594,7 @@ abstract class TronWalletBase
       _transactionsUpdateTimer?.cancel();
     }
   }
+
+  @override
+  String get password => _password;
 }
diff --git a/cw_tron/lib/tron_wallet_creation_credentials.dart b/cw_tron/lib/tron_wallet_creation_credentials.dart
index dc4f389aa..ed5e1c164 100644
--- a/cw_tron/lib/tron_wallet_creation_credentials.dart
+++ b/cw_tron/lib/tron_wallet_creation_credentials.dart
@@ -2,8 +2,8 @@ import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 
 class TronNewWalletCredentials extends WalletCredentials {
-  TronNewWalletCredentials({required String name, WalletInfo? walletInfo})
-      : super(name: name, walletInfo: walletInfo);
+  TronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password})
+      : super(name: name, walletInfo: walletInfo, password: password);
 }
 
 class TronRestoreWalletFromSeedCredentials extends WalletCredentials {
diff --git a/cw_tron/lib/tron_wallet_service.dart b/cw_tron/lib/tron_wallet_service.dart
index ba217a265..dacef439a 100644
--- a/cw_tron/lib/tron_wallet_service.dart
+++ b/cw_tron/lib/tron_wallet_service.dart
@@ -3,6 +3,7 @@ import 'dart:io';
 import 'package:bip39/bip39.dart' as bip39;
 import 'package:collection/collection.dart';
 import 'package:cw_core/balance.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/transaction_history.dart';
 import 'package:cw_core/transaction_info.dart';
@@ -21,11 +22,12 @@ class TronWalletService extends WalletService<
     TronRestoreWalletFromSeedCredentials,
     TronRestoreWalletFromPrivateKey,
     TronNewWalletCredentials> {
-  TronWalletService(this.walletInfoSource, {required this.client});
+  TronWalletService(this.walletInfoSource, {required this.client, required this.isDirect});
 
   late TronClient client;
 
   final Box<WalletInfo> walletInfoSource;
+  final bool isDirect;
 
   @override
   WalletType getType() => WalletType.tron;
@@ -43,6 +45,7 @@ class TronWalletService extends WalletService<
       walletInfo: credentials.walletInfo!,
       mnemonic: mnemonic,
       password: credentials.password!,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -62,6 +65,7 @@ class TronWalletService extends WalletService<
         name: name,
         password: password,
         walletInfo: walletInfo,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
 
       await wallet.init();
@@ -75,6 +79,7 @@ class TronWalletService extends WalletService<
         name: name,
         password: password,
         walletInfo: walletInfo,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
 
       await wallet.init();
@@ -92,6 +97,7 @@ class TronWalletService extends WalletService<
       password: credentials.password!,
       privateKey: credentials.privateKey,
       walletInfo: credentials.walletInfo!,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -114,6 +120,7 @@ class TronWalletService extends WalletService<
       password: credentials.password!,
       mnemonic: credentials.mnemonic,
       walletInfo: credentials.walletInfo!,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
     );
 
     await wallet.init();
@@ -128,7 +135,11 @@ class TronWalletService extends WalletService<
     final currentWalletInfo = walletInfoSource.values
         .firstWhere((info) => info.id == WalletBase.idFor(currentName, getType()));
     final currentWallet = await TronWalletBase.open(
-        password: password, name: currentName, walletInfo: currentWalletInfo);
+      password: password,
+      name: currentName,
+      walletInfo: currentWalletInfo,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+    );
 
     await currentWallet.renameWalletFiles(newName);
     await saveBackup(newName);
diff --git a/cw_wownero/lib/wownero_wallet.dart b/cw_wownero/lib/wownero_wallet.dart
index e02c0ec2e..85f5e4b2f 100644
--- a/cw_wownero/lib/wownero_wallet.dart
+++ b/cw_wownero/lib/wownero_wallet.dart
@@ -50,7 +50,7 @@ abstract class WowneroWalletBase
     extends WalletBase<WowneroBalance, WowneroTransactionHistory, WowneroTransactionInfo>
     with Store {
   WowneroWalletBase(
-      {required WalletInfo walletInfo, required Box<UnspentCoinsInfo> unspentCoinsInfo})
+      {required WalletInfo walletInfo, required Box<UnspentCoinsInfo> unspentCoinsInfo, required String password})
       : balance = ObservableMap<CryptoCurrency, WowneroBalance>.of({
           CryptoCurrency.wow: WowneroBalance(
               fullBalance: wownero_wallet.getFullBalance(accountIndex: 0),
@@ -58,6 +58,7 @@ abstract class WowneroWalletBase
         }),
         _isTransactionUpdating = false,
         _hasSyncAfterStartup = false,
+        _password = password,
         isEnabledAutoGenerateSubaddress = false,
         syncStatus = NotConnectedSyncStatus(),
         unspentCoins = [],
@@ -109,6 +110,10 @@ abstract class WowneroWalletBase
 
   String seedLegacy(String? language) => wownero_wallet.getSeedLegacy(language);
 
+  String get password => _password;
+
+  String _password;
+
   @override
   MoneroWalletKeys get keys => MoneroWalletKeys(
       privateSpendKey: wownero_wallet.getSecretSpendKey(),
diff --git a/cw_wownero/lib/wownero_wallet_service.dart b/cw_wownero/lib/wownero_wallet_service.dart
index 13cab8f61..286bfccd0 100644
--- a/cw_wownero/lib/wownero_wallet_service.dart
+++ b/cw_wownero/lib/wownero_wallet_service.dart
@@ -93,7 +93,7 @@ class WowneroWalletService extends WalletService<
       await wownero_wallet_manager.createWallet(
           path: path, password: credentials.password!, language: credentials.language);
       final wallet = WowneroWallet(
-          walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
+          walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource, password: credentials.password!);
       await wallet.init();
 
       return wallet;
@@ -129,7 +129,7 @@ class WowneroWalletService extends WalletService<
       await wownero_wallet_manager.openWalletAsync({'path': path, 'password': password});
       final walletInfo = walletInfoSource.values
           .firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
-      wallet = WowneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
+      wallet = WowneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource, password: password);
       final isValid = wallet.walletAddresses.validate();
 
       if (!isValid) {
@@ -210,7 +210,7 @@ class WowneroWalletService extends WalletService<
     final currentWalletInfo = walletInfoSource.values
         .firstWhere((info) => info.id == WalletBase.idFor(currentName, getType()));
     final currentWallet =
-        WowneroWallet(walletInfo: currentWalletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
+        WowneroWallet(walletInfo: currentWalletInfo, unspentCoinsInfo: unspentCoinsInfoSource, password: password);
 
     await currentWallet.renameWalletFiles(newName);
 
@@ -235,7 +235,7 @@ class WowneroWalletService extends WalletService<
           viewKey: credentials.viewKey,
           spendKey: credentials.spendKey);
       final wallet = WowneroWallet(
-          walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
+          walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource, password: credentials.password!);
       await wallet.init();
 
       return wallet;
@@ -268,7 +268,7 @@ class WowneroWalletService extends WalletService<
           seed: credentials.mnemonic,
           restoreHeight: credentials.height!);
       final wallet = WowneroWallet(
-          walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
+          walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource, password: credentials.password!);
       await wallet.init();
 
       return wallet;
@@ -315,7 +315,7 @@ class WowneroWalletService extends WalletService<
         restoreHeight: height,
         spendKey: spendKey);
 
-    final wallet = WowneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
+    final wallet = WowneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource, password: password);
     await wallet.init();
 
     return wallet;
diff --git a/cw_wownero/pubspec.lock b/cw_wownero/pubspec.lock
index 737743925..85d856b35 100644
--- a/cw_wownero/pubspec.lock
+++ b/cw_wownero/pubspec.lock
@@ -113,6 +113,15 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "8.4.3"
+  cake_backup:
+    dependency: transitive
+    description:
+      path: "."
+      ref: main
+      resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38"
+      url: "https://github.com/cake-tech/cake_backup.git"
+    source: git
+    version: "1.0.0+1"
   characters:
     dependency: transitive
     description:
@@ -169,6 +178,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.0.2"
+  cryptography:
+    dependency: transitive
+    description:
+      name: cryptography
+      sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.5.0"
+  cupertino_icons:
+    dependency: transitive
+    description:
+      name: cupertino_icons
+      sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.8"
   cw_core:
     dependency: "direct main"
     description:
@@ -680,6 +705,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.1"
+  tuple:
+    dependency: transitive
+    description:
+      name: tuple
+      sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.2"
   typed_data:
     dependency: transitive
     description:
diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart
index edfc77acb..989cd2b35 100644
--- a/lib/bitcoin/cw_bitcoin.dart
+++ b/lib/bitcoin/cw_bitcoin.dart
@@ -29,8 +29,8 @@ class CWBitcoin extends Bitcoin {
 
   @override
   WalletCredentials createBitcoinNewWalletCredentials(
-          {required String name, WalletInfo? walletInfo}) =>
-      BitcoinNewWalletCredentials(name: name, walletInfo: walletInfo);
+          {required String name, WalletInfo? walletInfo, String? password}) =>
+      BitcoinNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
 
   @override
   WalletCredentials createBitcoinHardwareWalletCredentials(
@@ -203,13 +203,13 @@ class CWBitcoin extends Bitcoin {
   }
 
   WalletService createBitcoinWalletService(
-      Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan) {
-    return BitcoinWalletService(walletInfoSource, unspentCoinSource, alwaysScan);
+      Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan, bool isDirect) {
+    return BitcoinWalletService(walletInfoSource, unspentCoinSource, alwaysScan, isDirect);
   }
 
   WalletService createLitecoinWalletService(
-      Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource) {
-    return LitecoinWalletService(walletInfoSource, unspentCoinSource);
+      Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
+    return LitecoinWalletService(walletInfoSource, unspentCoinSource, isDirect);
   }
 
   @override
diff --git a/lib/bitcoin_cash/cw_bitcoin_cash.dart b/lib/bitcoin_cash/cw_bitcoin_cash.dart
index 6e169209f..fcb34a286 100644
--- a/lib/bitcoin_cash/cw_bitcoin_cash.dart
+++ b/lib/bitcoin_cash/cw_bitcoin_cash.dart
@@ -6,16 +6,17 @@ class CWBitcoinCash extends BitcoinCash {
 
   @override
   WalletService createBitcoinCashWalletService(
-      Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource) {
-    return BitcoinCashWalletService(walletInfoSource, unspentCoinSource);
+      Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
+    return BitcoinCashWalletService(walletInfoSource, unspentCoinSource, isDirect);
   }
 
   @override
   WalletCredentials createBitcoinCashNewWalletCredentials({
     required String name,
     WalletInfo? walletInfo,
+    String? password,
   }) =>
-      BitcoinCashNewWalletCredentials(name: name, walletInfo: walletInfo);
+      BitcoinCashNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
 
   @override
   WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials(
diff --git a/lib/core/backup_service.dart b/lib/core/backup_service.dart
index 577238baf..42e24d3c7 100644
--- a/lib/core/backup_service.dart
+++ b/lib/core/backup_service.dart
@@ -3,6 +3,7 @@ import 'dart:io';
 import 'dart:typed_data';
 import 'package:cake_wallet/core/secure_storage.dart';
 import 'package:cake_wallet/themes/theme_list.dart';
+import 'package:cw_core/root_dir.dart';
 import 'package:cake_wallet/utils/device_info.dart';
 import 'package:cw_core/root_dir.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -20,7 +21,6 @@ import 'package:cake_wallet/entities/secret_store_key.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cake_wallet/.secrets.g.dart' as secrets;
 import 'package:cake_wallet/wallet_types.g.dart';
-
 import 'package:cake_backup/backup.dart' as cake_backup;
 
 class BackupService {
diff --git a/lib/core/wallet_creation_service.dart b/lib/core/wallet_creation_service.dart
index 2f3acb6c9..823aa7e84 100644
--- a/lib/core/wallet_creation_service.dart
+++ b/lib/core/wallet_creation_service.dart
@@ -15,7 +15,6 @@ import 'package:cw_core/wallet_type.dart';
 class WalletCreationService {
   WalletCreationService(
       {required WalletType initialType,
-      required this.secureStorage,
       required this.keyService,
       required this.sharedPreferences,
       required this.settingsStore,
@@ -25,7 +24,6 @@ class WalletCreationService {
   }
 
   WalletType type;
-  final SecureStorage secureStorage;
   final SharedPreferences sharedPreferences;
   final SettingsStore settingsStore;
   final KeyService keyService;
@@ -56,12 +54,16 @@ class WalletCreationService {
 
   Future<WalletBase> create(WalletCredentials credentials, {bool? isTestnet}) async {
     checkIfExists(credentials.name);
-    final password = generateWalletPassword();
-    credentials.password = password;
+
+    if (credentials.password == null) {
+      credentials.password = generateWalletPassword();
+      await keyService.saveWalletPassword(
+        password: credentials.password!, walletName: credentials.name);
+    }
+
     if (_hasSeedPhraseLengthOption) {
       credentials.seedPhraseLength = settingsStore.seedPhraseLength.value;
     }
-    await keyService.saveWalletPassword(password: password, walletName: credentials.name);
     final wallet = await _service!.create(credentials, isTestnet: isTestnet);
 
     if (wallet.type == WalletType.monero) {
@@ -94,9 +96,13 @@ class WalletCreationService {
 
   Future<WalletBase> restoreFromKeys(WalletCredentials credentials, {bool? isTestnet}) async {
     checkIfExists(credentials.name);
-    final password = generateWalletPassword();
-    credentials.password = password;
-    await keyService.saveWalletPassword(password: password, walletName: credentials.name);
+
+    if (credentials.password == null) {
+      credentials.password = generateWalletPassword();
+      await keyService.saveWalletPassword(
+        password: credentials.password!, walletName: credentials.name);
+    }
+
     final wallet = await _service!.restoreFromKeys(credentials, isTestnet: isTestnet);
 
     if (wallet.type == WalletType.monero) {
@@ -109,9 +115,13 @@ class WalletCreationService {
 
   Future<WalletBase> restoreFromSeed(WalletCredentials credentials, {bool? isTestnet}) async {
     checkIfExists(credentials.name);
-    final password = generateWalletPassword();
-    credentials.password = password;
-    await keyService.saveWalletPassword(password: password, walletName: credentials.name);
+
+    if (credentials.password == null) {
+      credentials.password = generateWalletPassword();
+      await keyService.saveWalletPassword(
+        password: credentials.password!, walletName: credentials.name);
+    }
+
     final wallet = await _service!.restoreFromSeed(credentials, isTestnet: isTestnet);
 
     if (wallet.type == WalletType.monero) {
diff --git a/lib/core/wallet_loading_service.dart b/lib/core/wallet_loading_service.dart
index ca29576e4..2b570f14c 100644
--- a/lib/core/wallet_loading_service.dart
+++ b/lib/core/wallet_loading_service.dart
@@ -20,17 +20,18 @@ class WalletLoadingService {
   final KeyService keyService;
   final WalletService Function(WalletType type) walletServiceFactory;
 
-  Future<void> renameWallet(WalletType type, String name, String newName) async {
+  Future<void> renameWallet(WalletType type, String name, String newName,
+      {String? password}) async {
     final walletService = walletServiceFactory.call(type);
-    final password = await keyService.getWalletPassword(walletName: name);
+    final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
 
     // Save the current wallet's password to the new wallet name's key
-    await keyService.saveWalletPassword(walletName: newName, password: password);
+    await keyService.saveWalletPassword(walletName: newName, password: walletPassword);
     // Delete previous wallet name from keyService to keep only new wallet's name
     // otherwise keeps duplicate (old and new names)
     await keyService.deleteWalletPassword(walletName: name);
 
-    await walletService.rename(name, password, newName);
+    await walletService.rename(name, walletPassword, newName);
 
     // set shared preferences flag based on previous wallet name
     if (type == WalletType.monero) {
@@ -41,11 +42,11 @@ class WalletLoadingService {
     }
   }
 
-  Future<WalletBase> load(WalletType type, String name) async {
+  Future<WalletBase> load(WalletType type, String name, {String? password}) async {
     try {
       final walletService = walletServiceFactory.call(type);
-      final password = await keyService.getWalletPassword(walletName: name);
-      final wallet = await walletService.openWallet(name, password);
+      final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
+      final wallet = await walletService.openWallet(name, walletPassword);
 
       if (type == WalletType.monero) {
         await updateMoneroWalletPassword(wallet);
@@ -67,8 +68,8 @@ class WalletLoadingService {
       for (var walletInfo in walletInfoSource.values) {
         try {
           final walletService = walletServiceFactory.call(walletInfo.type);
-          final password = await keyService.getWalletPassword(walletName: walletInfo.name);
-          final wallet = await walletService.openWallet(walletInfo.name, password);
+          final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
+          final wallet = await walletService.openWallet(walletInfo.name, walletPassword);
 
           if (walletInfo.type == WalletType.monero) {
             await updateMoneroWalletPassword(wallet);
diff --git a/lib/di.dart b/lib/di.dart
index a64270f6d..7c22e809c 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -30,6 +30,7 @@ import 'package:cake_wallet/entities/contact.dart';
 import 'package:cake_wallet/entities/contact_record.dart';
 import 'package:cake_wallet/entities/exchange_api_mode.dart';
 import 'package:cake_wallet/entities/parse_address_from_domain.dart';
+import 'package:cake_wallet/entities/preferences_key.dart';
 import 'package:cake_wallet/entities/qr_view_data.dart';
 import 'package:cake_wallet/entities/template.dart';
 import 'package:cake_wallet/entities/transaction_description.dart';
@@ -113,6 +114,8 @@ import 'package:cake_wallet/src/screens/support_chat/support_chat_page.dart';
 import 'package:cake_wallet/src/screens/support_other_links/support_other_links_page.dart';
 import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart';
 import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart';
+import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
+import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_page.dart';
 import 'package:cake_wallet/themes/theme_list.dart';
 import 'package:cake_wallet/utils/device_info.dart';
 import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
@@ -217,6 +220,8 @@ import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
 import 'package:cake_wallet/view_model/wallet_new_vm.dart';
 import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
 import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
+import 'package:cake_wallet/view_model/wallet_unlock_loadable_view_model.dart';
+import 'package:cake_wallet/view_model/wallet_unlock_verifiable_view_model.dart';
 import 'package:cake_wallet/wownero/wownero.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/receive_page_option.dart';
@@ -337,7 +342,6 @@ Future<void> setup({
       WalletCreationService(
           initialType: type,
           keyService: getIt.get<KeyService>(),
-          secureStorage: getIt.get<SecureStorage>(),
           sharedPreferences: getIt.get<SharedPreferences>(),
           settingsStore: getIt.get<SettingsStore>(),
           walletInfoSource: _walletInfoSource));
@@ -357,6 +361,65 @@ Future<void> setup({
       getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
       type: type));
 
+  getIt.registerFactoryParam<WalletUnlockPage, WalletUnlockArguments, bool>((args, closable) {
+    return WalletUnlockPage(
+      getIt.get<WalletUnlockLoadableViewModel>(param1: args),
+      args.callback,
+      args.authPasswordHandler,
+      closable: closable);
+  }, instanceName: 'wallet_unlock_loadable');
+
+  getIt.registerFactory<WalletUnlockPage>(
+    () => getIt.get<WalletUnlockPage>(
+      param1: WalletUnlockArguments(
+        callback: (bool successful, _) {
+          if (successful) {
+            final authStore = getIt.get<AuthenticationStore>();
+            authStore.allowed();
+          }}),
+      param2: false,
+      instanceName: 'wallet_unlock_loadable'),
+    instanceName: 'wallet_password_login');
+
+  getIt.registerFactoryParam<WalletUnlockPage, WalletUnlockArguments, bool>((args, closable) {
+    return WalletUnlockPage(
+      getIt.get<WalletUnlockVerifiableViewModel>(param1: args),
+      args.callback,
+      args.authPasswordHandler,
+      closable: closable);
+  }, instanceName: 'wallet_unlock_verifiable');
+
+  getIt.registerFactoryParam<WalletUnlockLoadableViewModel, WalletUnlockArguments, void>((args, _) {
+    final currentWalletName = getIt
+      .get<SharedPreferences>()
+      .getString(PreferencesKey.currentWalletName) ?? '';
+    final currentWalletTypeRaw =
+      getIt.get<SharedPreferences>()
+        .getInt(PreferencesKey.currentWalletType) ?? 0;
+    final currentWalletType = deserializeFromInt(currentWalletTypeRaw);
+
+    return WalletUnlockLoadableViewModel(
+      getIt.get<AppStore>(),
+      getIt.get<WalletLoadingService>(),
+      walletName: args.walletName ?? currentWalletName,
+      walletType: args.walletType ?? currentWalletType);
+  });
+
+  getIt.registerFactoryParam<WalletUnlockVerifiableViewModel, WalletUnlockArguments, void>((args, _) {
+    final currentWalletName = getIt
+      .get<SharedPreferences>()
+      .getString(PreferencesKey.currentWalletName) ?? '';
+    final currentWalletTypeRaw =
+      getIt.get<SharedPreferences>()
+        .getInt(PreferencesKey.currentWalletType) ?? 0;
+    final currentWalletType = deserializeFromInt(currentWalletTypeRaw);
+
+    return WalletUnlockVerifiableViewModel(
+      getIt.get<AppStore>(),
+      walletName: args.walletName ?? currentWalletName,
+      walletType: args.walletType ?? currentWalletType);
+  });
+
   getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) {
     return WalletRestorationFromQRVM(getIt.get<AppStore>(),
         getIt.get<WalletCreationService>(param1: type), _walletInfoSource, type);
@@ -907,23 +970,28 @@ Future<void> setup({
           _walletInfoSource,
           _unspentCoinsInfoSource,
           getIt.get<SettingsStore>().silentPaymentsAlwaysScan,
+          SettingsStoreBase.walletPasswordDirectInput,
         );
       case WalletType.litecoin:
-        return bitcoin!.createLitecoinWalletService(_walletInfoSource, _unspentCoinsInfoSource);
+        return bitcoin!.createLitecoinWalletService(_walletInfoSource, _unspentCoinsInfoSource,
+            SettingsStoreBase.walletPasswordDirectInput);
       case WalletType.ethereum:
-        return ethereum!.createEthereumWalletService(_walletInfoSource);
+        return ethereum!.createEthereumWalletService(
+            _walletInfoSource, SettingsStoreBase.walletPasswordDirectInput);
       case WalletType.bitcoinCash:
-        return bitcoinCash!
-            .createBitcoinCashWalletService(_walletInfoSource, _unspentCoinsInfoSource);
+        return bitcoinCash!.createBitcoinCashWalletService(_walletInfoSource,
+            _unspentCoinsInfoSource, SettingsStoreBase.walletPasswordDirectInput);
       case WalletType.nano:
       case WalletType.banano:
-        return nano!.createNanoWalletService(_walletInfoSource);
+        return nano!.createNanoWalletService(_walletInfoSource, SettingsStoreBase.walletPasswordDirectInput);
       case WalletType.polygon:
-        return polygon!.createPolygonWalletService(_walletInfoSource);
+        return polygon!.createPolygonWalletService(
+            _walletInfoSource, SettingsStoreBase.walletPasswordDirectInput);
       case WalletType.solana:
-        return solana!.createSolanaWalletService(_walletInfoSource);
+        return solana!.createSolanaWalletService(
+            _walletInfoSource, SettingsStoreBase.walletPasswordDirectInput);
       case WalletType.tron:
-        return tron!.createTronWalletService(_walletInfoSource);
+        return tron!.createTronWalletService(_walletInfoSource, SettingsStoreBase.walletPasswordDirectInput);
       case WalletType.wownero:
         return wownero!.createWowneroWalletService(_walletInfoSource, _unspentCoinsInfoSource);
       case WalletType.none:
diff --git a/lib/entities/load_current_wallet.dart b/lib/entities/load_current_wallet.dart
index 595bc2233..e67b59997 100644
--- a/lib/entities/load_current_wallet.dart
+++ b/lib/entities/load_current_wallet.dart
@@ -6,7 +6,7 @@ import 'package:cake_wallet/entities/preferences_key.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:cake_wallet/core/wallet_loading_service.dart';
 
-Future<void> loadCurrentWallet() async {
+Future<void> loadCurrentWallet({String? password}) async {
   final appStore = getIt.get<AppStore>();
   final name = getIt
       .get<SharedPreferences>()
@@ -21,7 +21,10 @@ Future<void> loadCurrentWallet() async {
 
   final type = deserializeFromInt(typeRaw);
   final walletLoadingService = getIt.get<WalletLoadingService>();
-  final wallet = await walletLoadingService.load(type, name);
+  final wallet = await walletLoadingService.load(
+    type,
+    name,
+    password: password);
   await appStore.changeCurrentWallet(wallet);
 
   getIt.get<BackgroundTasks>().registerSyncTask();
diff --git a/lib/ethereum/cw_ethereum.dart b/lib/ethereum/cw_ethereum.dart
index 7b593d58d..4e210b227 100644
--- a/lib/ethereum/cw_ethereum.dart
+++ b/lib/ethereum/cw_ethereum.dart
@@ -4,15 +4,16 @@ class CWEthereum extends Ethereum {
   @override
   List<String> getEthereumWordList(String language) => EVMChainMnemonics.englishWordlist;
 
-  WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource) =>
-      EthereumWalletService(walletInfoSource, client: EthereumClient());
+  WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource, bool isDirect) =>
+      EthereumWalletService(walletInfoSource, isDirect, client: EthereumClient());
 
   @override
   WalletCredentials createEthereumNewWalletCredentials({
     required String name,
     WalletInfo? walletInfo,
+    String? password,
   }) =>
-      EVMChainNewWalletCredentials(name: name, walletInfo: walletInfo);
+      EVMChainNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
 
   @override
   WalletCredentials createEthereumRestoreWalletFromSeedCredentials({
diff --git a/lib/main.dart b/lib/main.dart
index 1c0078e16..aeb76b3a8 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -48,6 +48,7 @@ final rootKey = GlobalKey<RootState>();
 final RouteObserver<PageRoute<dynamic>> routeObserver = RouteObserver<PageRoute<dynamic>>();
 
 Future<void> main() async {
+
   bool isAppRunning = false;
   await runZonedGuarded(() async {
     WidgetsFlutterBinding.ensureInitialized();
@@ -170,7 +171,6 @@ Future<void> initializeAppConfigs() async {
   }
 
   final secureStorage = secureStorageShared;
-
   final transactionDescriptionsBoxKey =
       await getEncryptionKey(secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
   final tradesBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Trade.boxKey);
@@ -247,8 +247,8 @@ Future<void> initialSetup(
     ordersSource: ordersSource,
     anonpayInvoiceInfoSource: anonpayInvoiceInfo,
     unspentCoinsInfoSource: unspentCoinsInfoSource,
-    secureStorage: secureStorage,
     navigatorKey: navigatorKey,
+    secureStorage: secureStorage,
   );
   await bootstrap(navigatorKey);
   monero?.onStartup();
diff --git a/lib/nano/cw_nano.dart b/lib/nano/cw_nano.dart
index ad02d2ccb..8cf640d8b 100644
--- a/lib/nano/cw_nano.dart
+++ b/lib/nano/cw_nano.dart
@@ -75,8 +75,8 @@ class CWNano extends Nano {
   }
 
   @override
-  WalletService createNanoWalletService(Box<WalletInfo> walletInfoSource) {
-    return NanoWalletService(walletInfoSource);
+  WalletService createNanoWalletService(Box<WalletInfo> walletInfoSource, bool isDirect) {
+    return NanoWalletService(walletInfoSource, isDirect);
   }
 
   @override
diff --git a/lib/polygon/cw_polygon.dart b/lib/polygon/cw_polygon.dart
index 2dcb1b4a6..5bb87ff5b 100644
--- a/lib/polygon/cw_polygon.dart
+++ b/lib/polygon/cw_polygon.dart
@@ -4,15 +4,16 @@ class CWPolygon extends Polygon {
   @override
   List<String> getPolygonWordList(String language) => EVMChainMnemonics.englishWordlist;
 
-  WalletService createPolygonWalletService(Box<WalletInfo> walletInfoSource) =>
-      PolygonWalletService(walletInfoSource, client: PolygonClient());
+  WalletService createPolygonWalletService(Box<WalletInfo> walletInfoSource, bool isDirect) =>
+      PolygonWalletService(walletInfoSource, isDirect, client: PolygonClient());
 
   @override
   WalletCredentials createPolygonNewWalletCredentials({
     required String name,
     WalletInfo? walletInfo,
+    String? password
   }) =>
-      EVMChainNewWalletCredentials(name: name, walletInfo: walletInfo);
+      EVMChainNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
 
   @override
   WalletCredentials createPolygonRestoreWalletFromSeedCredentials({
diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart
index e4fd9b32f..95cbd51df 100644
--- a/lib/reactions/on_authentication_state_change.dart
+++ b/lib/reactions/on_authentication_state_change.dart
@@ -2,6 +2,7 @@ import 'dart:async';
 
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/utils/exception_handler.dart';
+import 'package:cake_wallet/store/settings_store.dart';
 import 'package:flutter/widgets.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cake_wallet/entities/load_current_wallet.dart';
@@ -23,7 +24,7 @@ void startAuthenticationStateChange(
   _onAuthenticationStateChange ??= autorun((_) async {
     final state = authenticationStore.state;
 
-    if (state == AuthenticationState.installed) {
+    if (state == AuthenticationState.installed && !SettingsStoreBase.walletPasswordDirectInput) {
       try {
         await loadCurrentWallet();
       } catch (error, stack) {
diff --git a/lib/router.dart b/lib/router.dart
index c09664cef..498077511 100644
--- a/lib/router.dart
+++ b/lib/router.dart
@@ -90,7 +90,11 @@ import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart';
 import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart';
 import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
 import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
+import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_page.dart';
 import 'package:cake_wallet/src/screens/welcome/create_welcome_page.dart';
+import 'package:cake_wallet/store/settings_store.dart';
+import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
+import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/utils/payment_request.dart';
 import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
 import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
@@ -125,6 +129,14 @@ Route<dynamic> createRoute(RouteSettings settings) {
       return MaterialPageRoute<void>(builder: (_) => createWelcomePage());
 
     case Routes.newWalletFromWelcome:
+      if (SettingsStoreBase.walletPasswordDirectInput) {
+        if (availableWalletTypes.length == 1) {
+          return createRoute(RouteSettings(name: Routes.newWallet, arguments: availableWalletTypes.first));
+        } else {
+          return createRoute(RouteSettings(name: Routes.newWalletType));
+        }
+      }
+
       return CupertinoPageRoute<void>(
           builder: (_) =>
               getIt.get<SetupPinCodePage>(param1: (PinCodeState<PinCodeWidget> context, dynamic _) {
@@ -176,6 +188,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
               param2: [false, false]));
 
     case Routes.restoreOptions:
+      if (SettingsStoreBase.walletPasswordDirectInput) {
+        return createRoute(RouteSettings(name: Routes.restoreWalletType));
+      }
+
       final isNewInstall = settings.arguments as bool;
       return CupertinoPageRoute<void>(
           fullscreenDialog: true,
@@ -328,8 +344,16 @@ Route<dynamic> createRoute(RouteSettings settings) {
     case Routes.auth:
       return MaterialPageRoute<void>(
           fullscreenDialog: true,
-          builder: (_) => getIt.get<AuthPage>(
-              param1: settings.arguments as OnAuthenticationFinished, param2: true));
+          builder: (_)
+            => SettingsStoreBase.walletPasswordDirectInput
+                ? getIt.get<WalletUnlockPage>(
+                    param1: WalletUnlockArguments(
+                      callback: settings.arguments as OnAuthenticationFinished),
+                      instanceName: 'wallet_unlock_verifiable',
+                    param2: true)
+                : getIt.get<AuthPage>(
+                    param1: settings.arguments as OnAuthenticationFinished,
+                    param2: true));
 
     case Routes.totpAuthCodePage:
       final args = settings.arguments as TotpAuthArgumentsModel;
@@ -340,24 +364,32 @@ Route<dynamic> createRoute(RouteSettings settings) {
         ),
       );
 
-    case Routes.login:
-      return CupertinoPageRoute<void>(
-          builder: (context) => WillPopScope(
-                child: getIt.get<AuthPage>(instanceName: 'login'),
-                onWillPop: () async =>
-                    // FIX-ME: Additional check does it works correctly
-                    (await SystemChannels.platform.invokeMethod<bool>('SystemNavigator.pop') ??
-                        false),
-              ),
-          fullscreenDialog: true);
+    case Routes.walletUnlockLoadable:
+      return MaterialPageRoute<void>(
+          fullscreenDialog: true,
+          builder: (_)
+            => getIt.get<WalletUnlockPage>(
+              param1: settings.arguments as WalletUnlockArguments,
+                instanceName: 'wallet_unlock_loadable',
+              param2: true));
 
     case Routes.unlock:
       return MaterialPageRoute<void>(
           fullscreenDialog: true,
-          builder: (_) => WillPopScope(
-              child: getIt.get<AuthPage>(
-                  param1: settings.arguments as OnAuthenticationFinished, param2: false),
-              onWillPop: () async => false));
+          builder: (_)
+            => SettingsStoreBase.walletPasswordDirectInput
+                ? WillPopScope(
+                    child: getIt.get<WalletUnlockPage>(
+                      param1: WalletUnlockArguments(
+                        callback: settings.arguments as OnAuthenticationFinished),
+                      param2: false,
+                      instanceName: 'wallet_unlock_verifiable'),
+                    onWillPop: () async => false)
+                : WillPopScope(
+                    child: getIt.get<AuthPage>(
+                      param1: settings.arguments as OnAuthenticationFinished,
+                      param2: false),
+                  onWillPop: () async => false));
 
     case Routes.silentPaymentsSettings:
       return CupertinoPageRoute<void>(
@@ -397,6 +429,17 @@ Route<dynamic> createRoute(RouteSettings settings) {
           builder: (_) => getIt.get<NodeCreateOrEditPage>(
               param1: args?['editingNode'] as Node?, param2: args?['isSelected'] as bool?));
 
+    case Routes.login:
+      return CupertinoPageRoute<void>(
+          builder: (context) => WillPopScope(
+              child: SettingsStoreBase.walletPasswordDirectInput
+                ? getIt.get<WalletUnlockPage>(instanceName: 'wallet_password_login')
+                : getIt.get<AuthPage>(instanceName: 'login'),
+              onWillPop: () async =>
+              // FIX-ME: Additional check does it works correctly
+                  (await SystemChannels.platform.invokeMethod<bool>('SystemNavigator.pop') ?? false)),
+          fullscreenDialog: true);
+
     case Routes.newPowNode:
       final args = settings.arguments as Map<String, dynamic>?;
       return CupertinoPageRoute<void>(
@@ -486,7 +529,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
           fullscreenDialog: true, builder: (_) => getIt.get<RestoreFromBackupPage>());
 
     case Routes.support:
-      return CupertinoPageRoute<void>(builder: (_) => getIt.get<SupportPage>());
+      return CupertinoPageRoute<void>(
+          fullscreenDialog: true,
+          builder: (_) => getIt.get<SupportPage>());
 
     case Routes.supportLiveChat:
       return CupertinoPageRoute<void>(builder: (_) => getIt.get<SupportChatPage>());
diff --git a/lib/routes.dart b/lib/routes.dart
index 78a93bee7..caa7eb39e 100644
--- a/lib/routes.dart
+++ b/lib/routes.dart
@@ -82,6 +82,8 @@ class Routes {
   static const otherSettingsPage = '/other_settings_page';
   static const advancedPrivacySettings = '/advanced_privacy_settings';
   static const sweepingWalletPage = '/sweeping_wallet_page';
+  static const walletPasswordUnlock = '/wallet_password_unlock';
+  static const walletUnlockLoadable = '/wallet_unlock_loadable';
   static const anonPayInvoicePage = '/anon_pay_invoice_page';
   static const anonPayReceivePage = '/anon_pay_receive_page';
   static const anonPayDetailsPage = '/anon_pay_details_page';
diff --git a/lib/solana/cw_solana.dart b/lib/solana/cw_solana.dart
index af66cf3e5..e70739db9 100644
--- a/lib/solana/cw_solana.dart
+++ b/lib/solana/cw_solana.dart
@@ -4,15 +4,16 @@ class CWSolana extends Solana {
   @override
   List<String> getSolanaWordList(String language) => SolanaMnemonics.englishWordlist;
 
-  WalletService createSolanaWalletService(Box<WalletInfo> walletInfoSource) =>
-      SolanaWalletService(walletInfoSource);
+  WalletService createSolanaWalletService(Box<WalletInfo> walletInfoSource, bool isDirect) =>
+      SolanaWalletService(walletInfoSource, isDirect);
 
   @override
   WalletCredentials createSolanaNewWalletCredentials({
     required String name,
     WalletInfo? walletInfo,
+    String? password,
   }) =>
-      SolanaNewWalletCredentials(name: name, walletInfo: walletInfo);
+      SolanaNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
 
   @override
   WalletCredentials createSolanaRestoreWalletFromSeedCredentials({
diff --git a/lib/src/screens/auth/auth_page.dart b/lib/src/screens/auth/auth_page.dart
index dcd1c8016..d14a12527 100644
--- a/lib/src/screens/auth/auth_page.dart
+++ b/lib/src/screens/auth/auth_page.dart
@@ -12,6 +12,12 @@ import 'package:cake_wallet/core/execution_state.dart';
 
 typedef OnAuthenticationFinished = void Function(bool, AuthPageState);
 
+abstract class AuthPageState<T extends StatefulWidget> extends State<T> {
+  void changeProcessText(String text);
+  void hideProgressText();
+  Future<void> close({String? route, dynamic arguments});
+}
+
 class AuthPage extends StatefulWidget {
   AuthPage(this.authViewModel,
       {required this.onAuthenticationFinished,
@@ -22,10 +28,10 @@ class AuthPage extends StatefulWidget {
   final bool closable;
 
   @override
-  AuthPageState createState() => AuthPageState();
+  AuthPageState createState() => AuthPagePinCodeStateImpl();
 }
 
-class AuthPageState extends State<AuthPage> {
+class AuthPagePinCodeStateImpl extends AuthPageState<AuthPage> {
   final _key = GlobalKey<ScaffoldState>();
   final _pinCodeKey = GlobalKey<PinCodeState>();
   final _backArrowImageDarkTheme =
@@ -55,8 +61,6 @@ class AuthPageState extends State<AuthPage> {
       }
 
       if (state is FailureState) {
-        print('X');
-        print(state.error);
         WidgetsBinding.instance.addPostFrameCallback((_) async {
           _pinCodeKey.currentState?.clear();
           dismissFlushBar(_authBar);
@@ -95,17 +99,20 @@ class AuthPageState extends State<AuthPage> {
     super.dispose();
   }
 
+  @override
   void changeProcessText(String text) {
     dismissFlushBar(_authBar);
     _progressBar = createBar<void>(text, duration: null)
       ..show(_key.currentContext!);
   }
 
+  @override
   void hideProgressText() {
     dismissFlushBar(_progressBar);
     _progressBar = null;
   }
 
+  @override
   Future<void> close({String? route, dynamic arguments}) async {
     if (_key.currentContext == null) {
       throw Exception('Key context is null. Should be not happened');
diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart
index 7e9b2b23d..f49047e0b 100644
--- a/lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart
+++ b/lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart
@@ -2,6 +2,9 @@ import 'package:auto_size_text/auto_size_text.dart';
 import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
 import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
 import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
+import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
+import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
+import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
 import 'package:flutter/material.dart';
 
 class DesktopActionButton extends StatelessWidget {
@@ -24,45 +27,48 @@ class DesktopActionButton extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return Padding(
-      padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
-      child: GestureDetector(
-        onTap: onTap,
-        child: Container(
-          padding: EdgeInsets.symmetric(vertical: 25),
-          width: double.infinity,
-          decoration: BoxDecoration(
-            borderRadius: BorderRadius.circular(15.0),
-            color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
-          ),
-          child: Center(
-            child: Row(
-              mainAxisSize: MainAxisSize.min,
-              children: [
-                Image.asset(
-                  image,
-                  height: 30,
-                  width: 30,
-                  color: isEnabled
-                      ? Theme.of(context).extension<DashboardPageTheme>()!.textColor
-                      : Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
-                ),
-                const SizedBox(width: 10),
-                AutoSizeText(
-                  title,
-                  style: TextStyle(
-                    fontSize: 24,
-                    fontFamily: 'Lato',
-                    fontWeight: FontWeight.bold,
+    return MouseRegion(
+      cursor: SystemMouseCursors.click,
+      child: Padding(
+        padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
+        child: GestureDetector(
+          onTap: onTap,
+          child: Container(
+            padding: EdgeInsets.symmetric(vertical: 25),
+            width: double.infinity,
+            decoration: BoxDecoration(
+              borderRadius: BorderRadius.circular(15.0),
+              color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
+            ),
+            child: Center(
+              child: Row(
+                mainAxisSize: MainAxisSize.min,
+                children: [
+                  Image.asset(
+                    image,
+                    height: 30,
+                    width: 30,
                     color: isEnabled
                         ? Theme.of(context).extension<DashboardPageTheme>()!.textColor
-                        : null,
-                    height: 1,
+                        : Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
                   ),
-                  maxLines: 1,
-                  textAlign: TextAlign.center,
-                )
-              ],
+                  const SizedBox(width: 10),
+                  AutoSizeText(
+                    title,
+                    style: TextStyle(
+                      fontSize: 24,
+                      fontFamily: 'Lato',
+                      fontWeight: FontWeight.bold,
+                      color: isEnabled
+                          ? Theme.of(context).extension<DashboardPageTheme>()!.textColor
+                          : null,
+                      height: 1,
+                    ),
+                    maxLines: 1,
+                    textAlign: TextAlign.center,
+                  )
+                ],
+              ),
             ),
           ),
         ),
diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
index 46e63af01..94489a945 100644
--- a/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
+++ b/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
@@ -4,9 +4,12 @@ import 'package:cake_wallet/core/auth_service.dart';
 import 'package:cake_wallet/entities/desktop_dropdown_item.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/routes.dart';
+import 'package:cake_wallet/src/screens/auth/auth_page.dart';
 import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart';
+import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
 import 'package:cake_wallet/themes/extensions/menu_theme.dart';
+import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/utils/show_bar.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
@@ -176,12 +179,25 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
   }
 
   Future<void> _loadWallet(WalletListItem wallet) async {
-    widget._authService.authenticateAction(
-      context,
-      onAuthSuccess: (isAuthenticatedSuccessfully) async {
-        if (!isAuthenticatedSuccessfully) {
-          return;
-        }
+    if (SettingsStoreBase.walletPasswordDirectInput) {
+      Navigator.of(context).pushNamed(
+          Routes.walletUnlockLoadable,
+          arguments: WalletUnlockArguments(
+              callback: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
+                if (isAuthenticatedSuccessfully) {
+                  auth.close();
+                  setState(() {});
+                }
+              }, walletName: wallet.name,
+              walletType: wallet.type));
+      return;
+    }
+
+    widget._authService.authenticateAction(context,
+        onAuthSuccess: (isAuthenticatedSuccessfully) async {
+      if (!isAuthenticatedSuccessfully) {
+        return;
+      }
 
         try {
           if (context.mounted) {
diff --git a/lib/src/screens/new_wallet/new_wallet_page.dart b/lib/src/screens/new_wallet/new_wallet_page.dart
index d9427af0a..b66aab4cf 100644
--- a/lib/src/screens/new_wallet/new_wallet_page.dart
+++ b/lib/src/screens/new_wallet/new_wallet_page.dart
@@ -68,14 +68,19 @@ class _WalletNameFormState extends State<WalletNameForm> {
   _WalletNameFormState(this._walletNewVM)
       : _formKey = GlobalKey<FormState>(),
         _languageSelectorKey = GlobalKey<SeedLanguageSelectorState>(),
-        _controller = TextEditingController();
+        _nameController = TextEditingController(),
+        _passwordController = _walletNewVM.hasWalletPassword ? TextEditingController() : null,
+        _repeatedPasswordController =
+            _walletNewVM.hasWalletPassword ? TextEditingController() : null;
 
   static const aspectRatioImage = 1.22;
 
   final GlobalKey<FormState> _formKey;
   final GlobalKey<SeedLanguageSelectorState> _languageSelectorKey;
   final WalletNewVM _walletNewVM;
-  final TextEditingController _controller;
+  final TextEditingController _nameController;
+  final TextEditingController? _passwordController;
+  final TextEditingController? _repeatedPasswordController;
   ReactionDisposer? _stateReaction;
 
   @override
@@ -130,12 +135,11 @@ class _WalletNameFormState extends State<WalletNameForm> {
                     padding: EdgeInsets.only(top: 24),
                     child: Form(
                       key: _formKey,
-                      child: Stack(
-                        alignment: Alignment.centerRight,
+                      child: Column(
                         children: [
                           TextFormField(
                             onChanged: (value) => _walletNewVM.name = value,
-                            controller: _controller,
+                            controller: _nameController,
                             textAlign: TextAlign.center,
                             style: TextStyle(
                                 fontSize: 20.0,
@@ -169,10 +173,10 @@ class _WalletNameFormState extends State<WalletNameForm> {
                                     FocusManager.instance.primaryFocus?.unfocus();
 
                                     setState(() {
-                                      _controller.text = rName;
+                                      _nameController.text = rName;
                                       _walletNewVM.name = rName;
-                                      _controller.selection = TextSelection.fromPosition(
-                                          TextPosition(offset: _controller.text.length));
+                                      _nameController.selection = TextSelection.fromPosition(
+                                          TextPosition(offset: _nameController.text.length));
                                     });
                                   },
                                   icon: Container(
@@ -195,6 +199,80 @@ class _WalletNameFormState extends State<WalletNameForm> {
                             ),
                             validator: WalletNameValidator(),
                           ),
+                          if (_walletNewVM.hasWalletPassword) ...[
+                            TextFormField(
+                              onChanged: (value) => _walletNewVM.walletPassword = value,
+                              controller: _passwordController,
+                              textAlign: TextAlign.center,
+                              obscureText: true,
+                              style: TextStyle(
+                                fontSize: 20.0,
+                                fontWeight: FontWeight.w600,
+                                color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
+                              ),
+                              decoration: InputDecoration(
+                                hintStyle: TextStyle(
+                                  fontSize: 18.0,
+                                  fontWeight: FontWeight.w500,
+                                  color:
+                                      Theme.of(context).extension<NewWalletTheme>()!.hintTextColor,
+                                ),
+                                hintText: S.of(context).password,
+                                focusedBorder: UnderlineInputBorder(
+                                  borderSide: BorderSide(
+                                    color: Theme.of(context)
+                                        .extension<NewWalletTheme>()!
+                                        .underlineColor,
+                                    width: 1.0,
+                                  ),
+                                ),
+                                enabledBorder: UnderlineInputBorder(
+                                  borderSide: BorderSide(
+                                    color: Theme.of(context)
+                                        .extension<NewWalletTheme>()!
+                                        .underlineColor,
+                                    width: 1.0,
+                                  ),
+                                ),
+                              ),
+                            ),
+                            TextFormField(
+                              onChanged: (value) => _walletNewVM.repeatedWalletPassword = value,
+                              controller: _repeatedPasswordController,
+                              textAlign: TextAlign.center,
+                              obscureText: true,
+                              style: TextStyle(
+                                fontSize: 20.0,
+                                fontWeight: FontWeight.w600,
+                                color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
+                              ),
+                              decoration: InputDecoration(
+                                hintStyle: TextStyle(
+                                  fontSize: 18.0,
+                                  fontWeight: FontWeight.w500,
+                                  color:
+                                      Theme.of(context).extension<NewWalletTheme>()!.hintTextColor,
+                                ),
+                                hintText: S.of(context).repeat_wallet_password,
+                                focusedBorder: UnderlineInputBorder(
+                                  borderSide: BorderSide(
+                                    color: Theme.of(context)
+                                        .extension<NewWalletTheme>()!
+                                        .underlineColor,
+                                    width: 1.0,
+                                  ),
+                                ),
+                                enabledBorder: UnderlineInputBorder(
+                                  borderSide: BorderSide(
+                                    color: Theme.of(context)
+                                        .extension<NewWalletTheme>()!
+                                        .underlineColor,
+                                    width: 1.0,
+                                  ),
+                                ),
+                              ),
+                            ),
+                          ],
                         ],
                       ),
                     ),
diff --git a/lib/src/screens/restore/wallet_restore_from_keys_form.dart b/lib/src/screens/restore/wallet_restore_from_keys_form.dart
index f8336a2e8..56e49b087 100644
--- a/lib/src/screens/restore/wallet_restore_from_keys_form.dart
+++ b/lib/src/screens/restore/wallet_restore_from_keys_form.dart
@@ -16,6 +16,9 @@ class WalletRestoreFromKeysFrom extends StatefulWidget {
     required this.onPrivateKeyChange,
     required this.displayPrivateKeyField,
     required this.onHeightOrDateEntered,
+    required this.displayWalletPassword,
+    required this.onRepeatedPasswordChange,
+    this.onPasswordChange,
     Key? key,
   }) : super(key: key);
 
@@ -23,13 +26,17 @@ class WalletRestoreFromKeysFrom extends StatefulWidget {
   final WalletRestoreViewModel walletRestoreViewModel;
   final void Function(String)? onPrivateKeyChange;
   final bool displayPrivateKeyField;
+  final bool displayWalletPassword;
+  final void Function(String)? onPasswordChange;
+  final void Function(String)? onRepeatedPasswordChange;
 
   @override
-  WalletRestoreFromKeysFromState createState() => WalletRestoreFromKeysFromState();
+  WalletRestoreFromKeysFromState createState() =>
+      WalletRestoreFromKeysFromState(displayWalletPassword: displayWalletPassword);
 }
 
 class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
-  WalletRestoreFromKeysFromState()
+  WalletRestoreFromKeysFromState({required bool displayWalletPassword})
       : formKey = GlobalKey<FormState>(),
         blockchainHeightKey = GlobalKey<BlockchainHeightState>(),
         nameController = TextEditingController(),
@@ -37,7 +44,9 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
         viewKeyController = TextEditingController(),
         spendKeyController = TextEditingController(),
         privateKeyController = TextEditingController(),
-        nameTextEditingController = TextEditingController();
+        nameTextEditingController = TextEditingController(),
+        passwordTextEditingController = displayWalletPassword ? TextEditingController() : null,
+        repeatedPasswordTextEditingController = displayWalletPassword ? TextEditingController() : null;
 
   final GlobalKey<FormState> formKey;
   final GlobalKey<BlockchainHeightState> blockchainHeightKey;
@@ -47,9 +56,22 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
   final TextEditingController spendKeyController;
   final TextEditingController nameTextEditingController;
   final TextEditingController privateKeyController;
+  final TextEditingController? passwordTextEditingController;
+  final TextEditingController? repeatedPasswordTextEditingController;
+  void Function()? passwordListener;
+  void Function()? repeatedPasswordListener;
 
   @override
   void initState() {
+    if (passwordTextEditingController != null) {
+      passwordListener = () => widget.onPasswordChange?.call(passwordTextEditingController!.text);
+      passwordTextEditingController?.addListener(passwordListener!);
+    }
+
+    if (repeatedPasswordTextEditingController != null) {
+      repeatedPasswordListener = () => widget.onRepeatedPasswordChange?.call(repeatedPasswordTextEditingController!.text);
+      repeatedPasswordTextEditingController?.addListener(repeatedPasswordListener!);
+    }
     super.initState();
 
     privateKeyController.addListener(() {
@@ -67,6 +89,14 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
     viewKeyController.dispose();
     privateKeyController.dispose();
     spendKeyController.dispose();
+    passwordTextEditingController?.dispose();
+    if (passwordListener != null) {
+      passwordTextEditingController?.removeListener(passwordListener!);
+    }
+
+    if (repeatedPasswordListener != null) {
+      repeatedPasswordTextEditingController?.removeListener(repeatedPasswordListener!);
+    }
     super.dispose();
   }
 
@@ -114,6 +144,19 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
                 ),
               ],
             ),
+            if (widget.displayWalletPassword)
+              ...[Container(
+                  padding: EdgeInsets.only(top: 20.0),
+                  child: BaseTextFormField(
+                    controller: passwordTextEditingController,
+                    hintText: S.of(context).password,
+                    obscureText: true)),
+                Container(
+                  padding: EdgeInsets.only(top: 20.0),
+                  child: BaseTextFormField(
+                    controller: repeatedPasswordTextEditingController,
+                    hintText: S.of(context).repeat_wallet_password,
+                    obscureText: true))],
             Container(height: 20),
             _restoreFromKeysFormFields(),
           ],
diff --git a/lib/src/screens/restore/wallet_restore_from_seed_form.dart b/lib/src/screens/restore/wallet_restore_from_seed_form.dart
index 1f22af0cb..ec40eb1c1 100644
--- a/lib/src/screens/restore/wallet_restore_from_seed_form.dart
+++ b/lib/src/screens/restore/wallet_restore_from_seed_form.dart
@@ -22,34 +22,43 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
       required this.displayBlockHeightSelector,
       required this.displayPassphrase,
       required this.type,
+      required this.displayWalletPassword,
       required this.seedTypeViewModel,
       this.blockHeightFocusNode,
       this.onHeightOrDateEntered,
       this.onSeedChange,
-      this.onLanguageChange})
+      this.onLanguageChange,
+      this.onPasswordChange,
+      this.onRepeatedPasswordChange})
       : super(key: key);
 
   final WalletType type;
   final bool displayLanguageSelector;
   final bool displayBlockHeightSelector;
+  final bool displayWalletPassword;
   final bool displayPassphrase;
   final SeedTypeViewModel seedTypeViewModel;
   final FocusNode? blockHeightFocusNode;
   final Function(bool)? onHeightOrDateEntered;
   final void Function(String)? onSeedChange;
   final void Function(String)? onLanguageChange;
+  final void Function(String)? onPasswordChange;
+  final void Function(String)? onRepeatedPasswordChange;
 
   @override
-  WalletRestoreFromSeedFormState createState() => WalletRestoreFromSeedFormState('English');
+  WalletRestoreFromSeedFormState createState() =>
+      WalletRestoreFromSeedFormState('English', displayWalletPassword: displayWalletPassword);
 }
 
 class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
-  WalletRestoreFromSeedFormState(this.language)
+  WalletRestoreFromSeedFormState(this.language, {required bool displayWalletPassword})
       : seedWidgetStateKey = GlobalKey<SeedWidgetState>(),
         blockchainHeightKey = GlobalKey<BlockchainHeightState>(),
         formKey = GlobalKey<FormState>(),
         languageController = TextEditingController(),
         nameTextEditingController = TextEditingController(),
+        passwordTextEditingController = displayWalletPassword ? TextEditingController() : null,
+        repeatedPasswordTextEditingController = displayWalletPassword ? TextEditingController() : null,
         passphraseController = TextEditingController(),
         seedTypeController = TextEditingController();
 
@@ -57,16 +66,30 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
   final GlobalKey<BlockchainHeightState> blockchainHeightKey;
   final TextEditingController languageController;
   final TextEditingController nameTextEditingController;
+  final TextEditingController? passwordTextEditingController;
+  final TextEditingController? repeatedPasswordTextEditingController;
   final TextEditingController seedTypeController;
   final TextEditingController passphraseController;
   final GlobalKey<FormState> formKey;
   late ReactionDisposer moneroSeedTypeReaction;
   String language;
+  void Function()? passwordListener;
+  void Function()? repeatedPasswordListener;
 
   @override
   void initState() {
     _setSeedType(widget.seedTypeViewModel.moneroSeedType);
     _setLanguageLabel(language);
+
+    if (passwordTextEditingController != null) {
+      passwordListener = () => widget.onPasswordChange?.call(passwordTextEditingController!.text);
+      passwordTextEditingController?.addListener(passwordListener!);
+    }
+
+    if (repeatedPasswordTextEditingController != null) {
+      repeatedPasswordListener = () => widget.onRepeatedPasswordChange?.call(repeatedPasswordTextEditingController!.text);
+      repeatedPasswordTextEditingController?.addListener(repeatedPasswordListener!);
+    }
     moneroSeedTypeReaction =
         reaction((_) => widget.seedTypeViewModel.moneroSeedType, (SeedType item) {
       _setSeedType(item);
@@ -78,8 +101,16 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
 
   @override
   void dispose() {
-    super.dispose();
     moneroSeedTypeReaction();
+
+    if (passwordListener != null) {
+      passwordTextEditingController?.removeListener(passwordListener!);
+    }
+
+    if (repeatedPasswordListener != null) {
+      repeatedPasswordTextEditingController?.removeListener(repeatedPasswordListener!);
+    }
+    super.dispose();
   }
 
   void onSeedChange(String seed) {
@@ -177,6 +208,16 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
                 ),
               ),
             ),
+          if (widget.displayWalletPassword)
+            ...[BaseTextFormField(
+                controller: passwordTextEditingController,
+                hintText: S.of(context).password,
+                obscureText: true),
+              BaseTextFormField(
+                  controller: repeatedPasswordTextEditingController,
+                  hintText: S.of(context).repeat_wallet_password,
+                  obscureText: true)],
+          if (widget.displayLanguageSelector)
           if (!seedTypeController.value.text.contains("14") && widget.displayLanguageSelector)
             GestureDetector(
               onTap: () async {
diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart
index 746b73dca..cd6383c0d 100644
--- a/lib/src/screens/restore/wallet_restore_page.dart
+++ b/lib/src/screens/restore/wallet_restore_page.dart
@@ -53,7 +53,10 @@ class WalletRestorePage extends BasePage {
               onLanguageChange: (String language) {
                 final isPolyseed = language.startsWith("POLYSEED_");
                 _validateOnChange(isPolyseed: isPolyseed);
-              }));
+              },
+              displayWalletPassword: walletRestoreViewModel.hasWalletPassword,
+              onPasswordChange: (String password) => walletRestoreViewModel.walletPassword = password,
+              onRepeatedPasswordChange: (String repeatedPassword) => walletRestoreViewModel.repeatedWalletPassword = repeatedPassword));
           break;
         case WalletRestoreMode.keys:
           _pages.add(WalletRestoreFromKeysFrom(
@@ -66,6 +69,9 @@ class WalletRestorePage extends BasePage {
                 }
               },
               displayPrivateKeyField: walletRestoreViewModel.hasRestoreFromPrivateKey,
+              displayWalletPassword: walletRestoreViewModel.hasWalletPassword,
+              onPasswordChange: (String password) => walletRestoreViewModel.walletPassword = password,
+              onRepeatedPasswordChange: (String repeatedPassword) => walletRestoreViewModel.repeatedWalletPassword = repeatedPassword,
               onHeightOrDateEntered: (value) => walletRestoreViewModel.isButtonEnabled = value));
           break;
         default:
@@ -127,6 +133,8 @@ class WalletRestorePage extends BasePage {
 
     reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) {
       walletRestoreViewModel.isButtonEnabled = false;
+      walletRestoreViewModel.walletPassword = null;
+      walletRestoreViewModel.repeatedWalletPassword = null;
 
       walletRestoreFromSeedFormKey
           .currentState!.blockchainHeightKey.currentState!.restoreHeightController.text = '';
diff --git a/lib/src/screens/root/root.dart b/lib/src/screens/root/root.dart
index 7ad8af4c5..8ce0ddde9 100644
--- a/lib/src/screens/root/root.dart
+++ b/lib/src/screens/root/root.dart
@@ -1,4 +1,5 @@
 import 'dart:async';
+import 'dart:io';
 import 'package:cake_wallet/core/auth_service.dart';
 import 'package:cake_wallet/core/totp_request_details.dart';
 import 'package:cake_wallet/utils/device_info.dart';
diff --git a/lib/src/screens/settings/security_backup_page.dart b/lib/src/screens/settings/security_backup_page.dart
index 470f49190..04ae53d77 100644
--- a/lib/src/screens/settings/security_backup_page.dart
+++ b/lib/src/screens/settings/security_backup_page.dart
@@ -10,6 +10,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_switcher_cell.dart';
 import 'package:cake_wallet/utils/device_info.dart';
+import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
@@ -41,15 +42,16 @@ class SecurityBackupPage extends BasePage {
                     _securitySettingsViewModel.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
               ),
             ),
-          SettingsCellWithArrow(
-            title: S.current.create_backup,
-            handler: (_) => _authService.authenticateAction(
-              context,
-              route: Routes.backup,
-              conditionToDetermineIfToUse2FA: _securitySettingsViewModel
-                  .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
+          if (!SettingsStoreBase.walletPasswordDirectInput)
+            SettingsCellWithArrow(
+              title: S.current.create_backup,
+              handler: (_) => _authService.authenticateAction(
+                context,
+                route: Routes.backup,
+                conditionToDetermineIfToUse2FA: _securitySettingsViewModel
+                    .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
+              ),
             ),
-          ),
           SettingsCellWithArrow(
             title: S.current.settings_change_pin,
             handler: (_) => _authService.authenticateAction(
@@ -119,6 +121,5 @@ class SecurityBackupPage extends BasePage {
         ],
       ),
     );
-    
   }
 }
diff --git a/lib/src/screens/wallet/wallet_edit_page.dart b/lib/src/screens/wallet/wallet_edit_page.dart
index 7c90ba2c5..2d1bb9e47 100644
--- a/lib/src/screens/wallet/wallet_edit_page.dart
+++ b/lib/src/screens/wallet/wallet_edit_page.dart
@@ -4,6 +4,12 @@ import 'package:cake_wallet/core/wallet_name_validator.dart';
 import 'package:cake_wallet/palette.dart';
 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
+import 'package:cake_wallet/routes.dart';
+import 'package:cake_wallet/src/screens/auth/auth_page.dart';
+import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
+import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
+import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/utils/show_bar.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:cake_wallet/view_model/wallet_list/wallet_edit_view_model.dart';
@@ -94,9 +100,38 @@ class WalletEditPage extends BasePage {
                                 );
                               } else {
                                 try {
-                                  await walletEditViewModel.changeName(editingWallet);
-                                  Navigator.of(context).pop();
-                                  walletEditViewModel.resetState();
+                                  bool confirmed = false;
+
+                                  if (SettingsStoreBase
+                                      .walletPasswordDirectInput) {
+                                    await Navigator.of(context).pushNamed(
+                                        Routes.walletUnlockLoadable,
+                                        arguments: WalletUnlockArguments(
+                                            authPasswordHandler:
+                                                (String password) async {
+                                              await walletEditViewModel
+                                                  .changeName(editingWallet,
+                                                  password: password);
+                                            },
+                                            callback: (bool
+                                            isAuthenticatedSuccessfully,
+                                                AuthPageState auth) async {
+                                              if (isAuthenticatedSuccessfully) {
+                                                auth.close();
+                                                confirmed = true;
+                                              }
+                                            },
+                                            walletName: editingWallet.name,
+                                            walletType: editingWallet.type));
+                                  } else {
+                                    await walletEditViewModel.changeName(editingWallet);
+                                    confirmed = true;
+                                  }
+
+                                  if (confirmed) {
+                                    Navigator.of(context).pop();
+                                    walletEditViewModel.resetState();
+                                  }
                                 } catch (e) {}
                               }
                             }
@@ -120,11 +155,11 @@ class WalletEditPage extends BasePage {
 
   Future<void> _removeWallet(BuildContext context) async {
     authService.authenticateAction(context, onAuthSuccess: (isAuthenticatedSuccessfully) async {
-      if (!isAuthenticatedSuccessfully) {
-        return;
-      }
+        if (!isAuthenticatedSuccessfully) {
+          return;
+        }
 
-      _onSuccessfulAuth(context);
+        _onSuccessfulAuth(context);
       },
       conditionToDetermineIfToUse2FA: false,
     );
diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart
index 2a4841608..0d6d9e912 100644
--- a/lib/src/screens/wallet_list/wallet_list_page.dart
+++ b/lib/src/screens/wallet_list/wallet_list_page.dart
@@ -1,7 +1,10 @@
 import 'package:cake_wallet/entities/wallet_list_order_types.dart';
 import 'package:cake_wallet/src/screens/dashboard/widgets/filter_list_widget.dart';
 import 'package:cake_wallet/src/screens/wallet_list/filtered_list.dart';
+import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
+import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
+import 'package:cake_wallet/src/screens/auth/auth_page.dart';
 import 'package:cake_wallet/core/auth_service.dart';
 import 'package:cake_wallet/themes/extensions/filter_theme.dart';
 import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
@@ -336,6 +339,20 @@ class WalletListBodyState extends State<WalletListBody> {
   }
 
   Future<void> _loadWallet(WalletListItem wallet) async {
+    if (SettingsStoreBase.walletPasswordDirectInput) {
+      Navigator.of(context).pushNamed(
+          Routes.walletUnlockLoadable,
+          arguments: WalletUnlockArguments(
+              callback: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
+                if (isAuthenticatedSuccessfully) {
+                  auth.close();
+                  setState(() {});
+                }
+              }, walletName: wallet.name,
+              walletType: wallet.type));
+      return;
+    }
+
     await widget.authService.authenticateAction(
       context,
       onAuthSuccess: (isAuthenticatedSuccessfully) async {
diff --git a/lib/src/screens/wallet_unlock/wallet_unlock_arguments.dart b/lib/src/screens/wallet_unlock/wallet_unlock_arguments.dart
new file mode 100644
index 000000000..5b6d4dd16
--- /dev/null
+++ b/lib/src/screens/wallet_unlock/wallet_unlock_arguments.dart
@@ -0,0 +1,17 @@
+import 'package:cake_wallet/src/screens/auth/auth_page.dart';
+import 'package:cw_core/wallet_type.dart';
+
+typedef AuthPasswordHandler = Future<void> Function(String);
+
+class WalletUnlockArguments {
+  WalletUnlockArguments(
+      {required this.callback,
+      this.walletName,
+      this.walletType,
+      this.authPasswordHandler});
+
+  final OnAuthenticationFinished callback;
+  final AuthPasswordHandler? authPasswordHandler;
+  final String? walletName;
+  final WalletType? walletType;
+}
diff --git a/lib/src/screens/wallet_unlock/wallet_unlock_page.dart b/lib/src/screens/wallet_unlock/wallet_unlock_page.dart
new file mode 100644
index 000000000..3e6966f9d
--- /dev/null
+++ b/lib/src/screens/wallet_unlock/wallet_unlock_page.dart
@@ -0,0 +1,238 @@
+import 'package:another_flushbar/flushbar.dart';
+import 'package:cake_wallet/core/execution_state.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/auth/auth_page.dart';
+import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
+import 'package:cake_wallet/src/widgets/primary_button.dart';
+import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
+import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
+import 'package:cake_wallet/utils/show_bar.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:cake_wallet/view_model/wallet_unlock_view_model.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+import 'package:mobx/mobx.dart';
+
+class WalletUnlockPage extends StatefulWidget {
+  WalletUnlockPage(
+      this.walletUnlockViewModel, this.onAuthenticationFinished, this.authPasswordHandler,
+      {required this.closable});
+
+  final WalletUnlockViewModel walletUnlockViewModel;
+  final OnAuthenticationFinished onAuthenticationFinished;
+  final AuthPasswordHandler? authPasswordHandler;
+  final bool closable;
+
+  @override
+  State<StatefulWidget> createState() => WalletUnlockPageState();
+}
+
+class WalletUnlockPageState extends AuthPageState<WalletUnlockPage> {
+  WalletUnlockPageState() : _passwordController = TextEditingController();
+
+  final TextEditingController _passwordController;
+  final _key = GlobalKey<ScaffoldState>();
+  final _backArrowImageDarkTheme = Image.asset('assets/images/close_button.png');
+  ReactionDisposer? _reaction;
+  Flushbar<void>? _authBar;
+  Flushbar<void>? _progressBar;
+  void Function()? _passwordControllerListener;
+
+  @override
+  void initState() {
+    _reaction ??= reaction((_) => widget.walletUnlockViewModel.state, (ExecutionState state) {
+      if (state is ExecutedSuccessfullyState) {
+        WidgetsBinding.instance.addPostFrameCallback((_) {
+          widget.onAuthenticationFinished(true, this);
+        });
+        setState(() {});
+      }
+
+      if (state is IsExecutingState) {
+        WidgetsBinding.instance.addPostFrameCallback((_) {
+          // null duration to make it indefinite until its disposed
+          _authBar = createBar<void>(S.of(context).authentication, duration: null)..show(context);
+        });
+      }
+
+      if (state is FailureState) {
+        WidgetsBinding.instance.addPostFrameCallback((_) async {
+          dismissFlushBar(_authBar);
+          showBar<void>(context, S.of(context).failed_authentication(state.error));
+
+          widget.onAuthenticationFinished(false, this);
+        });
+      }
+    });
+
+    _passwordControllerListener =
+        () => widget.walletUnlockViewModel.setPassword(_passwordController.text);
+
+    if (_passwordControllerListener != null) {
+      _passwordController.addListener(_passwordControllerListener!);
+    }
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    _reaction?.reaction.dispose();
+
+    if (_passwordControllerListener != null) {
+      _passwordController.removeListener(_passwordControllerListener!);
+    }
+
+    super.dispose();
+  }
+
+  @override
+  void changeProcessText(String text) {
+    dismissFlushBar(_authBar);
+    _progressBar = createBar<void>(text, duration: null)..show(_key.currentContext!);
+  }
+
+  @override
+  void hideProgressText() {
+    dismissFlushBar(_progressBar);
+    _progressBar = null;
+  }
+
+  void dismissFlushBar(Flushbar<dynamic>? bar) {
+    WidgetsBinding.instance.addPostFrameCallback((_) async {
+      await bar?.dismiss();
+    });
+  }
+
+  @override
+  Future<void> close({String? route, arguments}) async {
+    if (_key.currentContext == null) {
+      throw Exception('Key context is null. Should be not happened');
+    }
+
+    /// not the best scenario, but WidgetsBinding is not behaving correctly on Android
+    await Future<void>.delayed(Duration(milliseconds: 50));
+    await _authBar?.dismiss();
+    await Future<void>.delayed(Duration(milliseconds: 50));
+    await _progressBar?.dismiss();
+    await Future<void>.delayed(Duration(milliseconds: 50));
+    if (route != null) {
+      Navigator.of(_key.currentContext!).pushReplacementNamed(route, arguments: arguments);
+    } else {
+      Navigator.of(_key.currentContext!).pop();
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      key: _key,
+      appBar: CupertinoNavigationBar(
+          leading: widget.closable
+              ? Container(
+                  padding: EdgeInsets.only(top: 10),
+                  child: SizedBox(
+                    height: 37,
+                    width: 37,
+                    child: InkWell(
+                      onTap: () => Navigator.of(context).pop(),
+                      child: _backArrowImageDarkTheme,
+                    ),
+                  ))
+              : Container(),
+          backgroundColor: Theme.of(context).colorScheme.background,
+          border: null),
+      resizeToAvoidBottomInset: false,
+      body: Center(
+        child: ConstrainedBox(
+          constraints: BoxConstraints(
+            maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint,
+          ),
+          child: Column(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              Expanded(
+                child: Column(
+                  mainAxisAlignment: MainAxisAlignment.center,
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  children: [
+                    Text(
+                      widget.walletUnlockViewModel.walletName,
+                      textAlign: TextAlign.center,
+                      style: TextStyle(
+                        fontSize: 24,
+                        fontWeight: FontWeight.w500,
+                        color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
+                      ),
+                    ),
+                    SizedBox(height: 24),
+                    Form(
+                      child: TextFormField(
+                        onChanged: (value) => null,
+                        controller: _passwordController,
+                        textAlign: TextAlign.center,
+                        obscureText: true,
+                        style: TextStyle(
+                          fontSize: 20.0,
+                          fontWeight: FontWeight.w600,
+                          color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
+                        ),
+                        decoration: InputDecoration(
+                          hintStyle: TextStyle(
+                            fontSize: 18.0,
+                            fontWeight: FontWeight.w500,
+                            color: Theme.of(context).extension<NewWalletTheme>()!.hintTextColor,
+                          ),
+                          hintText: S.of(context).enter_wallet_password,
+                          focusedBorder: UnderlineInputBorder(
+                            borderSide: BorderSide(
+                              color: Theme.of(context).extension<NewWalletTheme>()!.underlineColor,
+                              width: 1.0,
+                            ),
+                          ),
+                          enabledBorder: UnderlineInputBorder(
+                            borderSide: BorderSide(
+                              color: Theme.of(context).extension<NewWalletTheme>()!.underlineColor,
+                              width: 1.0,
+                            ),
+                          ),
+                        ),
+                      ),
+                    ),
+                  ],
+                ),
+              ),
+              Padding(
+                padding: EdgeInsets.only(bottom: 24),
+                child: Observer(
+                  builder: (_) => LoadingPrimaryButton(
+                      onPressed: () async {
+                        if (widget.authPasswordHandler != null) {
+                          try {
+                            await widget
+                                .authPasswordHandler!(widget.walletUnlockViewModel.password);
+                            widget.walletUnlockViewModel.success();
+                          } catch (e) {
+                            widget.walletUnlockViewModel.failure(e);
+                          }
+                          return;
+                        }
+
+                        widget.walletUnlockViewModel.unlock();
+                      },
+                      text: S.of(context).unlock,
+                      color: Colors.green,
+                      textColor: Colors.white,
+                      isLoading: widget.walletUnlockViewModel.state is IsExecutingState,
+                      isDisabled: widget.walletUnlockViewModel.state is IsExecutingState),
+                ),
+              ),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/src/widgets/address_text_field.dart b/lib/src/widgets/address_text_field.dart
index 0467b18a2..f79da8069 100644
--- a/lib/src/widgets/address_text_field.dart
+++ b/lib/src/widgets/address_text_field.dart
@@ -1,5 +1,5 @@
-import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cake_wallet/utils/device_info.dart';
+import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter/material.dart';
@@ -19,7 +19,10 @@ class AddressTextField extends StatelessWidget {
       {required this.controller,
       this.isActive = true,
       this.placeholder,
-      this.options = const [AddressTextFieldOption.qrCode, AddressTextFieldOption.addressBook],
+      this.options = const [
+        AddressTextFieldOption.qrCode,
+        AddressTextFieldOption.addressBook
+      ],
       this.onURIScanned,
       this.focusNode,
       this.isBorderExist = true,
diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart
index 8fb26df53..df2c7767f 100644
--- a/lib/store/settings_store.dart
+++ b/lib/store/settings_store.dart
@@ -553,6 +553,7 @@ abstract class SettingsStoreBase with Store {
   static const defaultActionsMode = 11;
   static const defaultPinCodeTimeOutDuration = PinCodeRequiredDuration.tenminutes;
   static const defaultAutoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.initialized;
+  static final walletPasswordDirectInput = Platform.isLinux;
   static const defaultSeedPhraseLength = SeedPhraseLength.twelveWords;
   static const defaultMoneroSeedType = SeedType.defaultSeedType;
 
diff --git a/lib/tron/cw_tron.dart b/lib/tron/cw_tron.dart
index 52b4f59f7..c6ac89342 100644
--- a/lib/tron/cw_tron.dart
+++ b/lib/tron/cw_tron.dart
@@ -4,15 +4,17 @@ class CWTron extends Tron {
   @override
   List<String> getTronWordList(String language) => EVMChainMnemonics.englishWordlist;
 
-  WalletService createTronWalletService(Box<WalletInfo> walletInfoSource) =>
-      TronWalletService(walletInfoSource, client: TronClient());
+  @override
+  WalletService createTronWalletService(Box<WalletInfo> walletInfoSource, bool isDirect) =>
+      TronWalletService(walletInfoSource, client: TronClient(), isDirect: isDirect);
 
   @override
   WalletCredentials createTronNewWalletCredentials({
     required String name,
     WalletInfo? walletInfo,
+    String? password,
   }) =>
-      TronNewWalletCredentials(name: name, walletInfo: walletInfo);
+      TronNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
 
   @override
   WalletCredentials createTronRestoreWalletFromSeedCredentials({
diff --git a/lib/utils/package_info.dart b/lib/utils/package_info.dart
index 8b911f887..5f3f0e743 100644
--- a/lib/utils/package_info.dart
+++ b/lib/utils/package_info.dart
@@ -1,5 +1,5 @@
 import 'dart:io';
-import 'package:package_info/package_info.dart' as __package_info__;
+import 'package:package_info_plus/package_info_plus.dart' as __package_info__;
 
 abstract class _EnvKeys {
     static const kWinAppName = 'CW_WIN_APP_NAME';
diff --git a/lib/view_model/wallet_creation_vm.dart b/lib/view_model/wallet_creation_vm.dart
index 36661ac7e..43386494e 100644
--- a/lib/view_model/wallet_creation_vm.dart
+++ b/lib/view_model/wallet_creation_vm.dart
@@ -1,5 +1,7 @@
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
 import 'package:cake_wallet/core/wallet_creation_service.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/di.dart';
 import 'package:cake_wallet/entities/background_tasks.dart';
 import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
@@ -37,6 +39,14 @@ abstract class WalletCreationVMBase with Store {
   @observable
   ExecutionState state;
 
+  @observable
+  String? walletPassword;
+
+  @observable
+  String? repeatedWalletPassword;
+
+  bool get hasWalletPassword => SettingsStoreBase.walletPasswordDirectInput;
+
   WalletType type;
   final bool isRecovery;
   final WalletCreationService walletCreationService;
@@ -59,6 +69,14 @@ abstract class WalletCreationVMBase with Store {
         name = await generateName();
       }
 
+      if (hasWalletPassword && (walletPassword?.isEmpty ?? true)) {
+        throw Exception(S.current.wallet_password_is_empty);
+      }
+
+      if (hasWalletPassword && walletPassword != repeatedWalletPassword) {
+        throw Exception(S.current.repeated_password_is_incorrect);
+      }
+
       walletCreationService.checkIfExists(name);
       final dirPath = await pathForWalletDir(name: name, type: type);
       final path = await pathForWallet(name: name, type: type);
diff --git a/lib/view_model/wallet_list/wallet_edit_view_model.dart b/lib/view_model/wallet_list/wallet_edit_view_model.dart
index 0582c3f87..e5bfcd4e3 100644
--- a/lib/view_model/wallet_list/wallet_edit_view_model.dart
+++ b/lib/view_model/wallet_list/wallet_edit_view_model.dart
@@ -32,10 +32,11 @@ abstract class WalletEditViewModelBase with Store {
   final WalletLoadingService _walletLoadingService;
 
   @action
-  Future<void> changeName(WalletListItem walletItem) async {
+  Future<void> changeName(WalletListItem walletItem, {String? password}) async {
     state = WalletEditRenamePending();
     await _walletLoadingService.renameWallet(
-        walletItem.type, walletItem.name, newName);
+        walletItem.type, walletItem.name, newName,
+        password: password);
     _walletListViewModel.updateList();
   }
 
diff --git a/lib/view_model/wallet_new_vm.dart b/lib/view_model/wallet_new_vm.dart
index 4729a38b2..a618695b1 100644
--- a/lib/view_model/wallet_new_vm.dart
+++ b/lib/view_model/wallet_new_vm.dart
@@ -66,25 +66,25 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
     switch (type) {
       case WalletType.monero:
         return monero!.createMoneroNewWalletCredentials(
-            name: name, language: options!.first as String, isPolyseed: options.last as bool);
+            name: name, language: options!.first as String, password: walletPassword, isPolyseed: options.last as bool);
       case WalletType.bitcoin:
-        return bitcoin!.createBitcoinNewWalletCredentials(name: name);
+        return bitcoin!.createBitcoinNewWalletCredentials(name: name, password: walletPassword);
       case WalletType.litecoin:
-        return bitcoin!.createBitcoinNewWalletCredentials(name: name);
+        return bitcoin!.createBitcoinNewWalletCredentials(name: name, password: walletPassword);
       case WalletType.haven:
-        return haven!
-            .createHavenNewWalletCredentials(name: name, language: options!.first as String);
+        return haven!.createHavenNewWalletCredentials(
+            name: name, language: options!.first as String, password: walletPassword);
       case WalletType.ethereum:
-        return ethereum!.createEthereumNewWalletCredentials(name: name);
+        return ethereum!.createEthereumNewWalletCredentials(name: name, password: walletPassword);
       case WalletType.bitcoinCash:
-        return bitcoinCash!.createBitcoinCashNewWalletCredentials(name: name);
+        return bitcoinCash!.createBitcoinCashNewWalletCredentials(name: name, password: walletPassword);
       case WalletType.nano:
       case WalletType.banano:
         return nano!.createNanoNewWalletCredentials(name: name);
       case WalletType.polygon:
-        return polygon!.createPolygonNewWalletCredentials(name: name);
+        return polygon!.createPolygonNewWalletCredentials(name: name, password: walletPassword);
       case WalletType.solana:
-        return solana!.createSolanaNewWalletCredentials(name: name);
+        return solana!.createSolanaNewWalletCredentials(name: name, password: walletPassword);
       case WalletType.tron:
         return tron!.createTronNewWalletCredentials(name: name);
       case WalletType.wownero:
diff --git a/lib/view_model/wallet_restore_view_model.dart b/lib/view_model/wallet_restore_view_model.dart
index 25a555b44..a38baabd8 100644
--- a/lib/view_model/wallet_restore_view_model.dart
+++ b/lib/view_model/wallet_restore_view_model.dart
@@ -86,7 +86,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
 
   @override
   WalletCredentials getCredentials(dynamic options) {
-    final password = generateWalletPassword();
+    final password = walletPassword ?? generateWalletPassword();
     String? passphrase = options['passphrase'] as String?;
     final height = options['height'] as int? ?? 0;
     name = options['name'] as String;
diff --git a/lib/view_model/wallet_unlock_loadable_view_model.dart b/lib/view_model/wallet_unlock_loadable_view_model.dart
new file mode 100644
index 000000000..f5e7bb917
--- /dev/null
+++ b/lib/view_model/wallet_unlock_loadable_view_model.dart
@@ -0,0 +1,63 @@
+import 'package:mobx/mobx.dart';
+import 'package:cake_wallet/core/execution_state.dart';
+import 'package:cake_wallet/core/wallet_loading_service.dart';
+import 'package:cake_wallet/store/app_store.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:cake_wallet/view_model/wallet_unlock_view_model.dart';
+
+part 'wallet_unlock_loadable_view_model.g.dart';
+
+class WalletUnlockLoadableViewModel = WalletUnlockLoadableViewModelBase
+    with _$WalletUnlockLoadableViewModel;
+
+abstract class WalletUnlockLoadableViewModelBase extends WalletUnlockViewModel with Store {
+  WalletUnlockLoadableViewModelBase(this._appStore, this._walletLoadingService,
+      {required this.walletName, required this.walletType})
+      : password = '',
+        state = InitialExecutionState();
+
+  final String walletName;
+
+  final WalletType walletType;
+
+  @override
+  @observable
+  String password;
+
+  @override
+  @observable
+  ExecutionState state;
+
+  final WalletLoadingService _walletLoadingService;
+
+  final AppStore _appStore;
+
+  @override
+  @action
+  void setPassword(String password) => this.password = password;
+
+  @override
+  @action
+  Future<void> unlock() async {
+    try {
+      state = InitialExecutionState();
+      final wallet = await _walletLoadingService.load(walletType, walletName, password: password);
+      _appStore.changeCurrentWallet(wallet);
+      success();
+    } catch (e) {
+      failure(e.toString());
+    }
+  }
+
+  @override
+  @action
+  void success() {
+    state = ExecutedSuccessfullyState();
+  }
+
+  @override
+  @action
+  void failure(e) {
+    state = FailureState(e.toString());
+  }
+}
diff --git a/lib/view_model/wallet_unlock_verifiable_view_model.dart b/lib/view_model/wallet_unlock_verifiable_view_model.dart
new file mode 100644
index 000000000..d6f5f0e7d
--- /dev/null
+++ b/lib/view_model/wallet_unlock_verifiable_view_model.dart
@@ -0,0 +1,60 @@
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/store/app_store.dart';
+import 'package:mobx/mobx.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:cake_wallet/core/execution_state.dart';
+import 'package:cake_wallet/view_model/wallet_unlock_view_model.dart';
+
+part 'wallet_unlock_verifiable_view_model.g.dart';
+
+class WalletUnlockVerifiableViewModel = WalletUnlockVerifiableViewModelBase
+    with _$WalletUnlockVerifiableViewModel;
+
+abstract class WalletUnlockVerifiableViewModelBase extends WalletUnlockViewModel with Store {
+  WalletUnlockVerifiableViewModelBase(this.appStore,
+      {required this.walletName, required this.walletType})
+      : password = '',
+        state = InitialExecutionState();
+
+  final String walletName;
+
+  final WalletType walletType;
+
+  final AppStore appStore;
+
+  @override
+  @observable
+  String password;
+
+  @override
+  @observable
+  ExecutionState state;
+
+  @override
+  @action
+  void setPassword(String password) => this.password = password;
+
+  @override
+  @action
+  Future<void> unlock() async {
+    try {
+      state = appStore.wallet!.password == password
+          ? ExecutedSuccessfullyState()
+          : FailureState(S.current.invalid_password);
+    } catch (e) {
+      failure('${S.current.invalid_password}\n${e.toString()}');
+    }
+  }
+
+  @override
+  @action
+  void success() {
+    state = ExecutedSuccessfullyState();
+  }
+
+  @override
+  @action
+  void failure(e) {
+    state = FailureState(e.toString());
+  }
+}
diff --git a/lib/view_model/wallet_unlock_view_model.dart b/lib/view_model/wallet_unlock_view_model.dart
new file mode 100644
index 000000000..f0131c61f
--- /dev/null
+++ b/lib/view_model/wallet_unlock_view_model.dart
@@ -0,0 +1,11 @@
+import 'package:cake_wallet/core/execution_state.dart';
+
+abstract class WalletUnlockViewModel {
+  String get walletName;
+  String get password;
+  void setPassword(String password);
+  ExecutionState get state;
+  Future<void> unlock();
+  void success();
+  void failure(dynamic e);
+}
diff --git a/linux/.gitignore b/linux/.gitignore
new file mode 100644
index 000000000..d3896c984
--- /dev/null
+++ b/linux/.gitignore
@@ -0,0 +1 @@
+flutter/ephemeral
diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt
new file mode 100644
index 000000000..bfce34c34
--- /dev/null
+++ b/linux/CMakeLists.txt
@@ -0,0 +1,144 @@
+# Project-level configuration.
+cmake_minimum_required(VERSION 3.10)
+project(runner LANGUAGES CXX)
+
+# The name of the executable created for the application. Change this to change
+# the on-disk name of your application.
+set(BINARY_NAME "cake_wallet")
+# The unique GTK application identifier for this application. See:
+# https://wiki.gnome.org/HowDoI/ChooseApplicationID
+set(APPLICATION_ID "com.example.cake_wallet")
+
+# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
+# versions of CMake.
+cmake_policy(SET CMP0063 NEW)
+
+# Load bundled libraries from the lib/ directory relative to the binary.
+set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
+
+# Root filesystem for cross-building.
+if(FLUTTER_TARGET_PLATFORM_SYSROOT)
+  set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
+  set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
+  set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+  set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+  set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+  set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+endif()
+
+# Define build configuration options.
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+  set(CMAKE_BUILD_TYPE "Debug" CACHE
+    STRING "Flutter build mode" FORCE)
+  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
+    "Debug" "Profile" "Release")
+endif()
+
+# Compilation settings that should be applied to most targets.
+#
+# Be cautious about adding new options here, as plugins use this function by
+# default. In most cases, you should add new options to specific targets instead
+# of modifying this function.
+function(APPLY_STANDARD_SETTINGS TARGET)
+  target_compile_features(${TARGET} PUBLIC cxx_std_14)
+  target_compile_options(${TARGET} PRIVATE -Wall -Werror)
+  target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
+  target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
+endfunction()
+
+# Flutter library and tool build rules.
+set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
+add_subdirectory(${FLUTTER_MANAGED_DIR})
+
+# System-level dependencies.
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
+
+add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
+
+# Define the application target. To change its name, change BINARY_NAME above,
+# not the value here, or `flutter run` will no longer work.
+#
+# Any new source files that you add to the application should be added here.
+add_executable(${BINARY_NAME}
+  "main.cc"
+  "my_application.cc"
+  "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
+)
+
+# Apply the standard set of build settings. This can be removed for applications
+# that need different build settings.
+apply_standard_settings(${BINARY_NAME})
+
+# Add dependency libraries. Add any application-specific dependencies here.
+target_link_libraries(${BINARY_NAME} PRIVATE flutter)
+target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
+
+# Run the Flutter tool portions of the build. This must not be removed.
+add_dependencies(${BINARY_NAME} flutter_assemble)
+
+# Only the install-generated bundle's copy of the executable will launch
+# correctly, since the resources must in the right relative locations. To avoid
+# people trying to run the unbundled copy, put it in a subdirectory instead of
+# the default top-level location.
+set_target_properties(${BINARY_NAME}
+  PROPERTIES
+  RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
+)
+
+# Generated plugin build rules, which manage building the plugins and adding
+# them to the application.
+include(flutter/generated_plugins.cmake)
+
+
+# === Installation ===
+# By default, "installing" just makes a relocatable bundle in the build
+# directory.
+set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+  set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
+endif()
+
+# Start with a clean build bundle directory every time.
+install(CODE "
+  file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
+  " COMPONENT Runtime)
+
+set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
+set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
+
+install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/monero_c/release/monero/x86_64-linux-gnu_libwallet2_api_c.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "monero_libwallet2_api_c.so"
+  COMPONENT Runtime)
+
+install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/monero_c/release/wownero/x86_64-linux-gnu_libwallet2_api_c.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "wownero_libwallet2_api_c.so"
+  COMPONENT Runtime)
+
+install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
+  COMPONENT Runtime)
+
+install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
+  COMPONENT Runtime)
+
+install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+  COMPONENT Runtime)
+
+foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
+  install(FILES "${bundled_library}"
+    DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+    COMPONENT Runtime)
+endforeach(bundled_library)
+
+# Fully re-copy the assets directory on each build to avoid having stale files
+# from a previous install.
+set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
+install(CODE "
+  file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
+  " COMPONENT Runtime)
+install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
+  DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
+
+# Install the AOT library on non-Debug builds only.
+if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
+  install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+    COMPONENT Runtime)
+endif()
diff --git a/linux/com.cakewallet.CakeWallet.desktop b/linux/com.cakewallet.CakeWallet.desktop
new file mode 100644
index 000000000..eb76a2fb5
--- /dev/null
+++ b/linux/com.cakewallet.CakeWallet.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Version=1.0
+Type=Application
+Name=Cake Wallet
+Comment=A noncustodial multi-currency wallet
+Categories=Office;Finance;
+Terminal=false
+Icon=com.cakewallet.CakeWallet
+Exec=cake_wallet
diff --git a/linux/flutter/CMakeLists.txt b/linux/flutter/CMakeLists.txt
new file mode 100644
index 000000000..d5bd01648
--- /dev/null
+++ b/linux/flutter/CMakeLists.txt
@@ -0,0 +1,88 @@
+# This file controls Flutter-level build steps. It should not be edited.
+cmake_minimum_required(VERSION 3.10)
+
+set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
+
+# Configuration provided via flutter tool.
+include(${EPHEMERAL_DIR}/generated_config.cmake)
+
+# TODO: Move the rest of this into files in ephemeral. See
+# https://github.com/flutter/flutter/issues/57146.
+
+# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
+# which isn't available in 3.10.
+function(list_prepend LIST_NAME PREFIX)
+    set(NEW_LIST "")
+    foreach(element ${${LIST_NAME}})
+        list(APPEND NEW_LIST "${PREFIX}${element}")
+    endforeach(element)
+    set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
+endfunction()
+
+# === Flutter Library ===
+# System-level dependencies.
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
+pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
+pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
+
+set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
+
+# Published to parent scope for install step.
+set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
+set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
+set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
+set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
+
+list(APPEND FLUTTER_LIBRARY_HEADERS
+  "fl_basic_message_channel.h"
+  "fl_binary_codec.h"
+  "fl_binary_messenger.h"
+  "fl_dart_project.h"
+  "fl_engine.h"
+  "fl_json_message_codec.h"
+  "fl_json_method_codec.h"
+  "fl_message_codec.h"
+  "fl_method_call.h"
+  "fl_method_channel.h"
+  "fl_method_codec.h"
+  "fl_method_response.h"
+  "fl_plugin_registrar.h"
+  "fl_plugin_registry.h"
+  "fl_standard_message_codec.h"
+  "fl_standard_method_codec.h"
+  "fl_string_codec.h"
+  "fl_value.h"
+  "fl_view.h"
+  "flutter_linux.h"
+)
+list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
+add_library(flutter INTERFACE)
+target_include_directories(flutter INTERFACE
+  "${EPHEMERAL_DIR}"
+)
+target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
+target_link_libraries(flutter INTERFACE
+  PkgConfig::GTK
+  PkgConfig::GLIB
+  PkgConfig::GIO
+)
+add_dependencies(flutter flutter_assemble)
+
+# === Flutter tool backend ===
+# _phony_ is a non-existent file to force this command to run every time,
+# since currently there's no way to get a full input/output list from the
+# flutter tool.
+add_custom_command(
+  OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
+    ${CMAKE_CURRENT_BINARY_DIR}/_phony_
+  COMMAND ${CMAKE_COMMAND} -E env
+    ${FLUTTER_TOOL_ENVIRONMENT}
+    "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
+      ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
+  VERBATIM
+)
+add_custom_target(flutter_assemble DEPENDS
+  "${FLUTTER_LIBRARY}"
+  ${FLUTTER_LIBRARY_HEADERS}
+)
diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc
new file mode 100644
index 000000000..01b922894
--- /dev/null
+++ b/linux/flutter/generated_plugin_registrant.cc
@@ -0,0 +1,27 @@
+//
+//  Generated file. Do not edit.
+//
+
+// clang-format off
+
+#include "generated_plugin_registrant.h"
+
+#include <devicelocale/devicelocale_plugin.h>
+#include <flutter_local_authentication/flutter_local_authentication_plugin.h>
+#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
+#include <url_launcher_linux/url_launcher_plugin.h>
+
+void fl_register_plugins(FlPluginRegistry* registry) {
+  g_autoptr(FlPluginRegistrar) devicelocale_registrar =
+      fl_plugin_registry_get_registrar_for_plugin(registry, "DevicelocalePlugin");
+  devicelocale_plugin_register_with_registrar(devicelocale_registrar);
+  g_autoptr(FlPluginRegistrar) flutter_local_authentication_registrar =
+      fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterLocalAuthenticationPlugin");
+  flutter_local_authentication_plugin_register_with_registrar(flutter_local_authentication_registrar);
+  g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
+      fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
+  flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
+  g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
+      fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
+  url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
+}
diff --git a/linux/flutter/generated_plugin_registrant.h b/linux/flutter/generated_plugin_registrant.h
new file mode 100644
index 000000000..e0f0a47bc
--- /dev/null
+++ b/linux/flutter/generated_plugin_registrant.h
@@ -0,0 +1,15 @@
+//
+//  Generated file. Do not edit.
+//
+
+// clang-format off
+
+#ifndef GENERATED_PLUGIN_REGISTRANT_
+#define GENERATED_PLUGIN_REGISTRANT_
+
+#include <flutter_linux/flutter_linux.h>
+
+// Registers Flutter plugins.
+void fl_register_plugins(FlPluginRegistry* registry);
+
+#endif  // GENERATED_PLUGIN_REGISTRANT_
diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake
new file mode 100644
index 000000000..f52be7481
--- /dev/null
+++ b/linux/flutter/generated_plugins.cmake
@@ -0,0 +1,28 @@
+#
+# Generated file, do not edit.
+#
+
+list(APPEND FLUTTER_PLUGIN_LIST
+  devicelocale
+  flutter_local_authentication
+  flutter_secure_storage_linux
+  url_launcher_linux
+)
+
+list(APPEND FLUTTER_FFI_PLUGIN_LIST
+  sp_scanner
+)
+
+set(PLUGIN_BUNDLED_LIBRARIES)
+
+foreach(plugin ${FLUTTER_PLUGIN_LIST})
+  add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
+  target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
+  list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
+  list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
+endforeach(plugin)
+
+foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
+  add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
+  list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
+endforeach(ffi_plugin)
diff --git a/linux/main.cc b/linux/main.cc
new file mode 100644
index 000000000..e7c5c5437
--- /dev/null
+++ b/linux/main.cc
@@ -0,0 +1,6 @@
+#include "my_application.h"
+
+int main(int argc, char** argv) {
+  g_autoptr(MyApplication) app = my_application_new();
+  return g_application_run(G_APPLICATION(app), argc, argv);
+}
diff --git a/linux/my_application.cc b/linux/my_application.cc
new file mode 100644
index 000000000..7375d05ca
--- /dev/null
+++ b/linux/my_application.cc
@@ -0,0 +1,104 @@
+#include "my_application.h"
+
+#include <flutter_linux/flutter_linux.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+
+#include "flutter/generated_plugin_registrant.h"
+
+struct _MyApplication {
+  GtkApplication parent_instance;
+  char** dart_entrypoint_arguments;
+};
+
+G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
+
+// Implements GApplication::activate.
+static void my_application_activate(GApplication* application) {
+  MyApplication* self = MY_APPLICATION(application);
+  GtkWindow* window =
+      GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
+
+  // Use a header bar when running in GNOME as this is the common style used
+  // by applications and is the setup most users will be using (e.g. Ubuntu
+  // desktop).
+  // If running on X and not using GNOME then just use a traditional title bar
+  // in case the window manager does more exotic layout, e.g. tiling.
+  // If running on Wayland assume the header bar will work (may need changing
+  // if future cases occur).
+  gboolean use_header_bar = TRUE;
+#ifdef GDK_WINDOWING_X11
+  GdkScreen* screen = gtk_window_get_screen(window);
+  if (GDK_IS_X11_SCREEN(screen)) {
+    const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
+    if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
+      use_header_bar = FALSE;
+    }
+  }
+#endif
+  if (use_header_bar) {
+    GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
+    gtk_widget_show(GTK_WIDGET(header_bar));
+    gtk_header_bar_set_title(header_bar, "cake_wallet");
+    gtk_header_bar_set_show_close_button(header_bar, TRUE);
+    gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
+  } else {
+    gtk_window_set_title(window, "cake_wallet");
+  }
+
+  gtk_window_set_default_size(window, 1280, 720);
+  gtk_widget_show(GTK_WIDGET(window));
+
+  g_autoptr(FlDartProject) project = fl_dart_project_new();
+  fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
+
+  FlView* view = fl_view_new(project);
+  gtk_widget_show(GTK_WIDGET(view));
+  gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
+
+  fl_register_plugins(FL_PLUGIN_REGISTRY(view));
+
+  gtk_widget_grab_focus(GTK_WIDGET(view));
+}
+
+// Implements GApplication::local_command_line.
+static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
+  MyApplication* self = MY_APPLICATION(application);
+  // Strip out the first argument as it is the binary name.
+  self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
+
+  g_autoptr(GError) error = nullptr;
+  if (!g_application_register(application, nullptr, &error)) {
+     g_warning("Failed to register: %s", error->message);
+     *exit_status = 1;
+     return TRUE;
+  }
+
+  g_application_activate(application);
+  *exit_status = 0;
+
+  return TRUE;
+}
+
+// Implements GObject::dispose.
+static void my_application_dispose(GObject* object) {
+  MyApplication* self = MY_APPLICATION(object);
+  g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
+  G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
+}
+
+static void my_application_class_init(MyApplicationClass* klass) {
+  G_APPLICATION_CLASS(klass)->activate = my_application_activate;
+  G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
+  G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
+}
+
+static void my_application_init(MyApplication* self) {}
+
+MyApplication* my_application_new() {
+  return MY_APPLICATION(g_object_new(my_application_get_type(),
+                                     "application-id", APPLICATION_ID,
+                                     "flags", G_APPLICATION_NON_UNIQUE,
+                                     nullptr));
+}
diff --git a/linux/my_application.h b/linux/my_application.h
new file mode 100644
index 000000000..72271d5e4
--- /dev/null
+++ b/linux/my_application.h
@@ -0,0 +1,18 @@
+#ifndef FLUTTER_MY_APPLICATION_H_
+#define FLUTTER_MY_APPLICATION_H_
+
+#include <gtk/gtk.h>
+
+G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
+                     GtkApplication)
+
+/**
+ * my_application_new:
+ *
+ * Creates a new Flutter-based application.
+ *
+ * Returns: a new #MyApplication.
+ */
+MyApplication* my_application_new();
+
+#endif  // FLUTTER_MY_APPLICATION_H_
diff --git a/macos/CakeWallet/decrypt.swift b/macos/CakeWallet/decrypt.swift
new file mode 100644
index 000000000..5f24ad3fb
--- /dev/null
+++ b/macos/CakeWallet/decrypt.swift
@@ -0,0 +1,16 @@
+import Foundation
+import CryptoSwift
+
+func decrypt(data: Data, key: String, salt: String) -> String? {
+    let keyBytes = key.data(using: .utf8)?.bytes ?? []
+    let saltBytes = salt.data(using: .utf8)?.bytes ?? []
+    
+    guard let PBKDF2key = try? PKCS5.PBKDF2(password: keyBytes, salt:  saltBytes, iterations: 4096, variant: .sha256).calculate(),
+          let cipher = try? Blowfish(key: PBKDF2key, padding: .pkcs7),
+          let decryptedBytes = try? cipher.decrypt(data.bytes) else {
+        return nil
+    }
+    
+    let decryptedData = Data(decryptedBytes)
+    return String(data: decryptedData, encoding: .utf8)
+}
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index 338ece4ce..0b4ee9415 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -12,7 +12,6 @@ import flutter_inappwebview_macos
 import flutter_local_authentication
 import flutter_secure_storage_macos
 import in_app_review
-import package_info
 import package_info_plus
 import path_provider_foundation
 import share_plus
@@ -28,7 +27,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
   FlutterLocalAuthenticationPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalAuthenticationPlugin"))
   FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
   InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
-  FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin"))
   FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
   PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
   SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
diff --git a/macos/Runner/RunnerBase.entitlements b/macos/Runner/RunnerBase.entitlements
index 186b61b17..22be818c6 100644
--- a/macos/Runner/RunnerBase.entitlements
+++ b/macos/Runner/RunnerBase.entitlements
@@ -11,4 +11,4 @@
 		<string>$(AppIdentifierPrefix)${BUNDLE_ID}</string>
 	</array>
 </dict>
-</plist>
+</plist>
\ No newline at end of file
diff --git a/model_generator.sh b/model_generator.sh
index 58ce9b5d0..8a1173f7d 100755
--- a/model_generator.sh
+++ b/model_generator.sh
@@ -1,3 +1,4 @@
+#!/bin/bash
 cd cw_core; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd ..
 cd cw_evm; 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 ..
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 90072a7c1..567d1b210 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -31,8 +31,7 @@ dependencies:
   flutter_local_authentication:
     git:
       url: https://github.com/cake-tech/flutter_local_authentication
-  package_info: ^2.0.0
-  #package_info_plus: ^1.4.2
+  package_info_plus: ^8.0.1
   devicelocale:
     git:
       url: https://github.com/cake-tech/flutter-devicelocale
@@ -80,6 +79,7 @@ dependencies:
   path_provider_android: ^2.2.1
   shared_preferences_android: 2.0.17
   url_launcher_android: 6.0.24
+  url_launcher_linux: 3.1.1 # https://github.com/flutter/flutter/issues/153083
   sensitive_clipboard: ^1.0.0
   walletconnect_flutter_v2: ^2.1.4
   eth_sig_util: ^0.0.9
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index 4cf9509f8..98cafdebc 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -236,6 +236,7 @@
   "enter_code": "ادخل الرمز",
   "enter_seed_phrase": "أدخل عبارة البذور الخاصة بك",
   "enter_totp_code": "الرجاء إدخال رمز TOTP.",
+  "enter_wallet_password": "أدخل كلمة مرور المحفظة",
   "enter_your_note": "أدخل ملاحظتك ...",
   "enter_your_pin": "أدخل كود الرقم السري",
   "enter_your_pin_again": "أدخل PIN الخاص بك مرة أخرى",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "ليس لديك ما يكفي من SOL لتغطية رسوم المعاملة والإيجار للحساب. يرجى إضافة المزيد من sol إلى محفظتك أو تقليل مبلغ sol الذي ترسله",
   "introducing_cake_pay": "نقدم لكم Cake Pay!",
   "invalid_input": "مدخل غير صالح",
+  "invalid_password": "رمز مرور خاطئ",
   "invoice_details": "تفاصيل الفاتورة",
   "is_percentage": "يكون",
   "last_30_days": "آخر 30 يومًا",
@@ -499,6 +501,8 @@
   "rename": "إعادة تسمية",
   "rep_warning": "تحذير تمثيلي",
   "rep_warning_sub": "لا يبدو أن ممثلك في وضع جيد. اضغط هنا لاختيار واحدة جديدة",
+  "repeat_wallet_password": "كرر كلمة مرور المحفظة",
+  "repeated_password_is_incorrect": "كلمة المرور المتكررة غير صحيحة. يرجى تكرار كلمة مرور المحفظة مرة أخرى.",
   "require_for_adding_contacts": "تتطلب إضافة جهات اتصال",
   "require_for_all_security_and_backup_settings": "مطلوب لجميع إعدادات الأمان والنسخ الاحتياطي",
   "require_for_assessing_wallet": "تتطلب الوصول إلى المحفظة",
@@ -797,6 +801,7 @@
   "unavailable_balance_description": ".ﺎﻫﺪﻴﻤﺠﺗ ءﺎﻐﻟﺇ ﺭﺮﻘﺗ ﻰﺘﺣ ﺕﻼﻣﺎﻌﻤﻠﻟ ﻝﻮﺻﻮﻠﻟ ﺔﻠﺑﺎﻗ ﺮﻴﻏ ﺓﺪﻤﺠﻤﻟﺍ ﺓﺪﺻﺭﻷﺍ ﻞﻈﺗ ﺎﻤﻨﻴﺑ ،ﺎﻬﺑ ﺔﺻﺎﺨﻟﺍ ﺕﻼﻣﺎﻌﻤﻟﺍ ﻝﺎﻤﺘﻛﺍ ﺩﺮﺠﻤﺑ ﺔﺣﺎﺘﻣ ﺔﻠﻔﻘﻤﻟﺍ ﺓﺪﺻﺭﻷﺍ ﺢﺒﺼﺘﺳ .ﻚﺑ ﺔﺻﺎﺨﻟﺍ ﺕﻼﻤﻌﻟﺍ ﻲﻓ ﻢﻜﺤﺘﻟﺍ ﺕﺍﺩﺍﺪﻋﺇ ﻲﻓ ﻂﺸﻧ ﻞﻜﺸﺑ ﺎﻫﺪﻴﻤﺠﺘﺑ ﺖﻤﻗ",
   "unconfirmed": "رصيد غير مؤكد",
   "understand": "لقد فهمت",
+  "unlock": "الغاء القفل",
   "unmatched_currencies": "عملة محفظتك الحالية لا تتطابق مع عملة QR الممسوحة ضوئيًا",
   "unspent_change": "يتغير",
   "unspent_coins_details_title": "تفاصيل العملات الغير المنفقة",
@@ -838,6 +843,7 @@
   "wallet_menu": "قائمة",
   "wallet_name": "اسم المحفظة",
   "wallet_name_exists": "توجد بالفعل محفظة بهذا الاسم. الرجاء اختيار اسم مختلف أو إعادة تسمية المحفظة الأخرى أولاً.",
+  "wallet_password_is_empty": "كلمة مرور المحفظة فارغة. يجب ألا تكون كلمة مرور المحفظة فارغة",
   "wallet_recovery_height": "ارتفاع الاسترداد",
   "wallet_restoration_store_incorrect_seed_length": "طول السييد غير صحيح",
   "wallet_seed": "سييد المحفظة",
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index b76401cf4..b51167dab 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -236,6 +236,7 @@
   "enter_code": "Въведете код",
   "enter_seed_phrase": "Въведете вашата фраза за семена",
   "enter_totp_code": "Моля, въведете TOTP кода.",
+  "enter_wallet_password": "Въведете паролата за портфейла",
   "enter_your_note": "Въвеждане на бележка…",
   "enter_your_pin": "Въведете PIN",
   "enter_your_pin_again": "Въведете своя PIN отново",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "Нямате достатъчно SOL, за да покриете таксата за транзакцията и наемането на сметката. Моля, добавете повече SOL към портфейла си или намалете сумата на SOL, която изпращате",
   "introducing_cake_pay": "Запознайте се с Cake Pay!",
   "invalid_input": "Невалиден вход",
+  "invalid_password": "Невалидна парола",
   "invoice_details": "IДанни за фактура",
   "is_percentage": "е",
   "last_30_days": "Последните 30 дни",
@@ -499,6 +501,8 @@
   "rename": "Промяна на името",
   "rep_warning": "Представително предупреждение",
   "rep_warning_sub": "Вашият представител изглежда не е в добро състояние. Докоснете тук, за да изберете нов",
+  "repeat_wallet_password": "Повторете паролата на портфейла",
+  "repeated_password_is_incorrect": "Многократната парола е неправилна. Моля, повторете отново паролата за портфейла.",
   "require_for_adding_contacts": "Изисква се за добавяне на контакти",
   "require_for_all_security_and_backup_settings": "Изисква се за всички настройки за сигурност и архивиране",
   "require_for_assessing_wallet": "Изискване за достъп до портфейла",
@@ -797,6 +801,7 @@
   "unavailable_balance_description": "Неналично салдо: Тази обща сума включва средства, които са заключени в чакащи транзакции и тези, които сте замразили активно в настройките за контрол на монетите. Заключените баланси ще станат достъпни, след като съответните им транзакции бъдат завършени, докато замразените баланси остават недостъпни за транзакции, докато не решите да ги размразите.",
   "unconfirmed": "Непотвърден баланс",
   "understand": "Разбирам",
+  "unlock": "Отключване",
   "unmatched_currencies": "Валутата на този портфейл не съвпада с тази от сканирания QR код",
   "unspent_change": "Промяна",
   "unspent_coins_details_title": "Подробности за неизползваните монети",
@@ -838,6 +843,7 @@
   "wallet_menu": "Меню",
   "wallet_name": "Име на портфейл",
   "wallet_name_exists": "Вече има портфейл с това име. Моля, изберете друго име или преименувайте другия портфейл.",
+  "wallet_password_is_empty": "Паролата за портфейл е празна. Паролата за портфейл не трябва да е празна",
   "wallet_recovery_height": "Височина на възстановяване",
   "wallet_restoration_store_incorrect_seed_length": "Грешна дължина на seed-а",
   "wallet_seed": "Seed на портфейла",
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index c5d374dd0..d47ca932c 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -236,6 +236,7 @@
   "enter_code": "Zadejte kód",
   "enter_seed_phrase": "Zadejte svou frázi semen",
   "enter_totp_code": "Zadejte kód TOTP.",
+  "enter_wallet_password": "Zadejte heslo peněženky",
   "enter_your_note": "Zadejte poznámku…",
   "enter_your_pin": "Zadejte svůj PIN",
   "enter_your_pin_again": "Zadejte znovu svůj PIN",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "Nemáte dostatek SOL na pokrytí transakčního poplatku a nájemného za účet. Laskavě přidejte do své peněženky více SOL nebo snižte množství Sol, kterou odesíláte",
   "introducing_cake_pay": "Představujeme Cake Pay!",
   "invalid_input": "Neplatný vstup",
+  "invalid_password": "Neplatné heslo",
   "invoice_details": "detaily faktury",
   "is_percentage": "je",
   "last_30_days": "Posledních 30 dnů",
@@ -499,6 +501,8 @@
   "rename": "Přejmenovat",
   "rep_warning": "Reprezentativní varování",
   "rep_warning_sub": "Zdá se, že váš zástupce není v dobrém stavu. Klepnutím zde vyberte nový",
+  "repeat_wallet_password": "Opakujte heslo peněženky",
+  "repeated_password_is_incorrect": "Opakované heslo je nesprávné. Znovu opakujte heslo peněženky.",
   "require_for_adding_contacts": "Vyžadovat pro přidání kontaktů",
   "require_for_all_security_and_backup_settings": "Vyžadovat všechna nastavení zabezpečení a zálohování",
   "require_for_assessing_wallet": "Vyžadovat pro přístup k peněžence",
@@ -797,6 +801,7 @@
   "unavailable_balance_description": "Nedostupný zůstatek: Tento součet zahrnuje prostředky, které jsou uzamčeny v nevyřízených transakcích a ty, které jste aktivně zmrazili v nastavení kontroly mincí. Uzamčené zůstatky budou k dispozici po dokončení příslušných transakcí, zatímco zmrazené zůstatky zůstanou pro transakce nepřístupné, dokud se nerozhodnete je uvolnit.",
   "unconfirmed": "Nepotvrzený zůstatek",
   "understand": "Rozumím",
+  "unlock": "Odemknout",
   "unmatched_currencies": "Měna vaší současné peněženky neodpovídá té v naskenovaném QR kódu",
   "unspent_change": "Změna",
   "unspent_coins_details_title": "Podrobnosti o neutracených mincích",
@@ -838,6 +843,7 @@
   "wallet_menu": "Menu",
   "wallet_name": "Název peněženky",
   "wallet_name_exists": "Peněženka s tímto názvem už existuje. Prosím zvolte si jiný název, nebo nejprve přejmenujte nejprve druhou peněženku.",
+  "wallet_password_is_empty": "Heslo peněženky je prázdné. Heslo peněženky by nemělo být prázdné",
   "wallet_recovery_height": "Výška zotavení",
   "wallet_restoration_store_incorrect_seed_length": "Nesprávná délka seedu",
   "wallet_seed": "Seed peněženky",
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 7b6613dd6..e64c3bc27 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -236,6 +236,7 @@
   "enter_code": "Code eingeben",
   "enter_seed_phrase": "Geben Sie Ihre Seed-Phrase ein",
   "enter_totp_code": "Bitte geben Sie den TOTP-Code ein.",
+  "enter_wallet_password": "Geben Sie das Brieftaschenkennwort ein",
   "enter_your_note": "Geben Sie Ihre Bemerkung ein…",
   "enter_your_pin": "PIN eingeben",
   "enter_your_pin_again": "Geben Sie Ihre PIN erneut ein",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "Sie haben nicht genug SOL, um die Transaktionsgebühr und die Miete für das Konto zu decken. Bitte fügen Sie mehr Sol zu Ihrer Brieftasche hinzu oder reduzieren Sie den von Ihnen gesendeten Sol -Betrag",
   "introducing_cake_pay": "Einführung von Cake Pay!",
   "invalid_input": "Ungültige Eingabe",
+  "invalid_password": "Ungültiges Passwort",
   "invoice_details": "Rechnungs-Details",
   "is_percentage": "ist",
   "last_30_days": "Letzte 30 Tage",
@@ -500,6 +502,8 @@
   "rename": "Umbenennen",
   "rep_warning": "Repräsentative Warnung",
   "rep_warning_sub": "Ihr Vertreter scheint nicht gut zu sein. Tippen Sie hier, um eine neue auszuwählen",
+  "repeat_wallet_password": "Wiederholen Sie das Brieftaschenkennwort",
+  "repeated_password_is_incorrect": "Wiederholtes Passwort ist falsch. Bitte wiederholen Sie das Brieftaschenkennwort erneut.",
   "require_for_adding_contacts": "Erforderlich zum Hinzufügen von Kontakten",
   "require_for_all_security_and_backup_settings": "Für alle Sicherheits- und Sicherungseinstellungen erforderlich",
   "require_for_assessing_wallet": "Für den Zugriff auf die Wallet erforderlich",
@@ -799,6 +803,7 @@
   "unconfirmed": "Unbestätigter Saldo",
   "und": "und",
   "understand": "Ich verstehe",
+  "unlock": "Freischalten",
   "unmatched_currencies": "Die Währung Ihres aktuellen Wallets stimmt nicht mit der des gescannten QR überein",
   "unspent_change": "Wechselgeld",
   "unspent_coins_details_title": "Details zu nicht ausgegebenen Coins",
@@ -841,6 +846,7 @@
   "wallet_menu": "Wallet-Menü",
   "wallet_name": "Walletname",
   "wallet_name_exists": "Wallet mit diesem Namen existiert bereits",
+  "wallet_password_is_empty": "Brieftaschenkennwort ist leer. Brieftaschenkennwort sollte nicht leer sein",
   "wallet_recovery_height": "Erstellungshöhe",
   "wallet_restoration_store_incorrect_seed_length": "Falsche Seed-Länge",
   "wallet_seed": "Wallet-Seed",
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 35712a780..9d7d9ad49 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -236,6 +236,7 @@
   "enter_code": "Enter code",
   "enter_seed_phrase": "Enter your seed phrase",
   "enter_totp_code": "Please enter the TOTP Code.",
+  "enter_wallet_password": "Enter the wallet password",
   "enter_your_note": "Enter your note…",
   "enter_your_pin": "Enter your PIN",
   "enter_your_pin_again": "Enter your pin again",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "You do not have enough SOL to cover the transaction fee and rent for the account. Kindly add more SOL to your wallet or reduce the SOL amount you\\'re sending",
   "introducing_cake_pay": "Introducing Cake Pay!",
   "invalid_input": "Invalid input",
+  "invalid_password": "Invalid password",
   "invoice_details": "Invoice details",
   "is_percentage": "is",
   "last_30_days": "Last 30 days",
@@ -499,6 +501,8 @@
   "rename": "Rename",
   "rep_warning": "Representative Warning",
   "rep_warning_sub": "Your representative does not appear to be in good standing. Tap here to select a new one",
+  "repeat_wallet_password": "Repeat the wallet password",
+  "repeated_password_is_incorrect": "Repeated password is incorrect. Please repeat the wallet password again.",
   "require_for_adding_contacts": "Require for adding contacts",
   "require_for_all_security_and_backup_settings": "Require for all security and backup settings",
   "require_for_assessing_wallet": "Require for accessing wallet",
@@ -798,6 +802,7 @@
   "unavailable_balance_description": "Unavailable Balance: This total includes funds that are locked in pending transactions and those you have actively frozen in your coin control settings. Locked balances will become available once their respective transactions are completed, while frozen balances remain inaccessible for transactions until you decide to unfreeze them.",
   "unconfirmed": "Unconfirmed Balance",
   "understand": "I understand",
+  "unlock": "Unlock",
   "unmatched_currencies": "Your current wallet's currency does not match that of the scanned QR",
   "unspent_change": "Change",
   "unspent_coins_details_title": "Unspent coins details",
@@ -839,6 +844,7 @@
   "wallet_menu": "Menu",
   "wallet_name": "Wallet name",
   "wallet_name_exists": "A wallet with that name already exists. Please choose a different name or rename the other wallet first.",
+  "wallet_password_is_empty": "Wallet password is empty. Wallet password should not be empty",
   "wallet_recovery_height": "Recovery Height",
   "wallet_restoration_store_incorrect_seed_length": "Incorrect seed length",
   "wallet_seed": "Wallet seed",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 31a6e6865..e7f1366a5 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -236,6 +236,7 @@
   "enter_code": "Ingresar código",
   "enter_seed_phrase": "Ingrese su frase de semillas",
   "enter_totp_code": "Ingrese el código TOTP.",
+  "enter_wallet_password": "Ingrese la contraseña de la billetera",
   "enter_your_note": "Ingresa tu nota…",
   "enter_your_pin": "Introduce tu PIN",
   "enter_your_pin_again": "Ingrese su PIN nuevamente",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "No tiene suficiente SOL para cubrir la tarifa de transacción y alquilar para la cuenta. Por favor, agregue más sol a su billetera o reduzca la cantidad de sol que está enviando",
   "introducing_cake_pay": "¡Presentamos Cake Pay!",
   "invalid_input": "Entrada inválida",
+  "invalid_password": "Contraseña invalida",
   "invoice_details": "Detalles de la factura",
   "is_percentage": "es",
   "last_30_days": "Últimos 30 días",
@@ -500,6 +502,8 @@
   "rename": "Rebautizar",
   "rep_warning": "Advertencia representativa",
   "rep_warning_sub": "Su representante no parece estar en buena posición. Toque aquí para seleccionar uno nuevo",
+  "repeat_wallet_password": "Repita la contraseña de billetera",
+  "repeated_password_is_incorrect": "La contraseña repetida es incorrecta. Repita la contraseña de la billetera nuevamente.",
   "require_for_adding_contacts": "Requerido para agregar contactos",
   "require_for_all_security_and_backup_settings": "Requerido para todas las configuraciones de seguridad y copia de seguridad",
   "require_for_assessing_wallet": "Requerido para acceder a la billetera",
@@ -798,6 +802,7 @@
   "unavailable_balance_description": "Saldo no disponible: este total incluye fondos que están bloqueados en transacciones pendientes y aquellos que usted ha congelado activamente en su configuración de control de monedas. Los saldos bloqueados estarán disponibles una vez que se completen sus respectivas transacciones, mientras que los saldos congelados permanecerán inaccesibles para las transacciones hasta que usted decida descongelarlos.",
   "unconfirmed": "Saldo no confirmado",
   "understand": "Entiendo",
+  "unlock": "desbloquear",
   "unmatched_currencies": "La moneda de su billetera actual no coincide con la del QR escaneado",
   "unspent_change": "Cambiar",
   "unspent_coins_details_title": "Detalles de monedas no gastadas",
@@ -839,6 +844,7 @@
   "wallet_menu": "Menú de billetera",
   "wallet_name": "Nombre de la billetera",
   "wallet_name_exists": "Wallet con ese nombre ya ha existido",
+  "wallet_password_is_empty": "La contraseña de billetera está vacía. La contraseña de la billetera no debe estar vacía",
   "wallet_recovery_height": "Altura de recuperación",
   "wallet_restoration_store_incorrect_seed_length": "Longitud de semilla incorrecta",
   "wallet_seed": "Semilla de billetera",
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index 03d4a73dd..7965eca12 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -236,6 +236,7 @@
   "enter_code": "Entrez le code",
   "enter_seed_phrase": "Entrez votre phrase secrète (seed)",
   "enter_totp_code": "Veuillez entrer le code TOTP.",
+  "enter_wallet_password": "Entrez le mot de passe du portefeuille",
   "enter_your_note": "Entrez votre note…",
   "enter_your_pin": "Entrez votre code PIN",
   "enter_your_pin_again": "Entrez à nouveau votre code PIN",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "Vous n'avez pas assez de SOL pour couvrir les frais de transaction et le loyer pour le compte. Veuillez ajouter plus de Sol à votre portefeuille ou réduire la quantité de sol que vous envoyez",
   "introducing_cake_pay": "Présentation de Cake Pay !",
   "invalid_input": "Entrée invalide",
+  "invalid_password": "Mot de passe incorrect",
   "invoice_details": "Détails de la facture",
   "is_percentage": "est",
   "last_30_days": "30 derniers jours",
@@ -499,6 +501,8 @@
   "rename": "Renommer",
   "rep_warning": "Avertissement représentatif",
   "rep_warning_sub": "Votre représentant ne semble pas être en règle. Appuyez ici pour en sélectionner un nouveau",
+  "repeat_wallet_password": "Répétez le mot de passe du portefeuille",
+  "repeated_password_is_incorrect": "Le mot de passe répété est incorrect. Veuillez répéter le mot de passe du portefeuille.",
   "require_for_adding_contacts": "Requis pour ajouter des contacts",
   "require_for_all_security_and_backup_settings": "Exiger pour tous les paramètres de sécurité et de sauvegarde",
   "require_for_assessing_wallet": "Nécessaire pour accéder au portefeuille",
@@ -797,6 +801,7 @@
   "unavailable_balance_description": "Solde indisponible : ce total comprend les fonds bloqués dans les transactions en attente et ceux que vous avez activement gelés dans vos paramètres de contrôle des pièces. Les soldes bloqués deviendront disponibles une fois leurs transactions respectives terminées, tandis que les soldes gelés resteront inaccessibles aux transactions jusqu'à ce que vous décidiez de les débloquer.",
   "unconfirmed": "Solde non confirmé",
   "understand": "J'ai compris",
+  "unlock": "Ouvrir",
   "unmatched_currencies": "La devise de votre portefeuille (wallet) actuel ne correspond pas à celle du QR code scanné",
   "unspent_change": "Monnaie",
   "unspent_coins_details_title": "Détails des pièces (coins) non dépensées",
@@ -838,6 +843,7 @@
   "wallet_menu": "Menu",
   "wallet_name": "Nom du Portefeuille (Wallet)",
   "wallet_name_exists": "Un portefeuille (wallet) portant ce nom existe déjà",
+  "wallet_password_is_empty": "Le mot de passe du portefeuille est vide. Le mot de passe du portefeuille ne doit pas être vide",
   "wallet_recovery_height": "Hauteur de récupération",
   "wallet_restoration_store_incorrect_seed_length": "Longueur de phrase secrète (seed) incorrecte",
   "wallet_seed": "Phrase secrète (seed) du portefeuille (wallet)",
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index 922f9a51b..d2c58971f 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -236,6 +236,7 @@
   "enter_code": "Shigar da lamba",
   "enter_seed_phrase": "Shigar da Sert Sentarku",
   "enter_totp_code": "Da fatan za a shigar da lambar tnp.",
+  "enter_wallet_password": "Shigar da kalmar sirri ta walat",
   "enter_your_note": "Shigar da bayanin kula…",
   "enter_your_pin": "Shigar da PIN",
   "enter_your_pin_again": "Shigar da PIN ɗinku na sake",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "Ba ku da isasshen Sol don rufe kuɗin ma'amala da haya don asusun. Da kyau ƙara ƙarin sool zuwa walat ɗinku ko rage adadin Sol ɗin da kuke aikawa",
   "introducing_cake_pay": "Gabatar da Cake Pay!",
   "invalid_input": "Shigar da ba daidai ba",
+  "invalid_password": "Kalmar sirri mara inganci",
   "invoice_details": "Bayanin wadannan",
   "is_percentage": "shine",
   "last_30_days": "Kwanaki 30 na ƙarshe",
@@ -501,6 +503,8 @@
   "rename": "Sake suna",
   "rep_warning": "Gargadi Wakilin",
   "rep_warning_sub": "Wakilinku bai bayyana ya kasance cikin kyakkyawan yanayi ba. Matsa nan don zaɓar sabon",
+  "repeat_wallet_password": "Maimaita kalmar sirri",
+  "repeated_password_is_incorrect": "Maimaita kalmar sirri ba daidai ba ce. Da fatan za a sake maimaita kalmar sirri.",
   "require_for_adding_contacts": "Bukatar ƙara lambobin sadarwa",
   "require_for_all_security_and_backup_settings": "Bukatar duk tsaro da saitunan wariyar ajiya",
   "require_for_assessing_wallet": "Bukatar samun damar walat",
@@ -799,6 +803,7 @@
   "unavailable_balance_description": "Ma'auni Babu: Wannan jimlar ya haɗa da kuɗi waɗanda ke kulle a cikin ma'amaloli da ke jiran aiki da waɗanda kuka daskare sosai a cikin saitunan sarrafa kuɗin ku. Ma'auni da aka kulle za su kasance da zarar an kammala ma'amalolinsu, yayin da daskararrun ma'auni ba za su iya samun damar yin ciniki ba har sai kun yanke shawarar cire su.",
   "unconfirmed": "Ba a tabbatar ba",
   "understand": "na gane",
+  "unlock": "Buɗe",
   "unmatched_currencies": "Nau'in walat ɗin ku na yanzu bai dace da na lambar QR da aka bincika ba",
   "unspent_change": "Canza",
   "unspent_coins_details_title": "Bayanan tsabar kudi da ba a kashe ba",
@@ -840,6 +845,7 @@
   "wallet_menu": "Menu",
   "wallet_name": "Sunan walat",
   "wallet_name_exists": "Wallet mai wannan sunan ya riga ya wanzu. Da fatan za a zaɓi wani suna daban ko sake suna ɗayan walat tukuna.",
+  "wallet_password_is_empty": "Alamar Wallet babu komai. Al'adun Wallet bai zama komai ba",
   "wallet_recovery_height": "Mai Tsaro",
   "wallet_restoration_store_incorrect_seed_length": "kalmar sirrin iri ba daidai ba",
   "wallet_seed": "kalmar sirri na walat",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index db6940e8b..baa3925c0 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -236,6 +236,7 @@
   "enter_code": "कोड दर्ज करें",
   "enter_seed_phrase": "अपना बीज वाक्यांश दर्ज करें",
   "enter_totp_code": "कृपया TOTP कोड दर्ज करें।",
+  "enter_wallet_password": "वॉलेट पासवर्ड दर्ज करें",
   "enter_your_note": "अपना नोट दर्ज करें ...",
   "enter_your_pin": "अपना पिन दर्ज करो",
   "enter_your_pin_again": "फिर से अपना पिन डालें",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "आपके पास लेन -देन शुल्क और खाते के लिए किराए को कवर करने के लिए पर्याप्त सोल नहीं है। कृपया अपने बटुए में अधिक सोल जोड़ें या सोल राशि को कम करें जिसे आप भेज रहे हैं",
   "introducing_cake_pay": "परिचय Cake Pay!",
   "invalid_input": "अमान्य निवेश",
+  "invalid_password": "अवैध पासवर्ड",
   "invoice_details": "चालान विवरण",
   "is_percentage": "है",
   "last_30_days": "पिछले 30 दिन",
@@ -501,6 +503,8 @@
   "rename": "नाम बदलें",
   "rep_warning": "प्रतिनिधि चेतावनी",
   "rep_warning_sub": "आपका प्रतिनिधि अच्छी स्थिति में नहीं दिखाई देता है। एक नया चयन करने के लिए यहां टैप करें",
+  "repeat_wallet_password": "वॉलेट पासवर्ड दोहराएं",
+  "repeated_password_is_incorrect": "बार -बार पासवर्ड गलत है। कृपया फिर से वॉलेट पासवर्ड दोहराएं।",
   "require_for_adding_contacts": "संपर्क जोड़ने के लिए आवश्यकता है",
   "require_for_all_security_and_backup_settings": "सभी सुरक्षा और बैकअप सेटिंग्स की आवश्यकता है",
   "require_for_assessing_wallet": "वॉलेट तक पहुँचने के लिए आवश्यकता है",
@@ -799,6 +803,7 @@
   "unavailable_balance_description": "अनुपलब्ध शेष राशि: इस कुल में वे धनराशि शामिल हैं जो लंबित लेनदेन में बंद हैं और जिन्हें आपने अपनी सिक्का नियंत्रण सेटिंग्स में सक्रिय रूप से जमा कर रखा है। लॉक किए गए शेष उनके संबंधित लेन-देन पूरे होने के बाद उपलब्ध हो जाएंगे, जबकि जमे हुए शेष लेन-देन के लिए अप्राप्य रहेंगे जब तक कि आप उन्हें अनफ्रीज करने का निर्णय नहीं लेते।",
   "unconfirmed": "अपुष्ट शेष राशि",
   "understand": "मुझे समझ",
+  "unlock": "अनलॉक",
   "unmatched_currencies": "आपके वर्तमान वॉलेट की मुद्रा स्कैन किए गए क्यूआर से मेल नहीं खाती",
   "unspent_change": "परिवर्तन",
   "unspent_coins_details_title": "अव्ययित सिक्कों का विवरण",
@@ -840,6 +845,7 @@
   "wallet_menu": "बटुआ मेनू",
   "wallet_name": "बटुए का नाम",
   "wallet_name_exists": "उस नाम वाला वॉलेट पहले से मौजूद है",
+  "wallet_password_is_empty": "वॉलेट पासवर्ड खाली है। वॉलेट पासवर्ड खाली नहीं होना चाहिए",
   "wallet_recovery_height": "वसूली ऊंचाई",
   "wallet_restoration_store_incorrect_seed_length": "गलत बीज की लंबाई",
   "wallet_seed": "बटुआ का बीज",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 57cf1361e..e6b820300 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -236,6 +236,7 @@
   "enter_code": "Unesite kod",
   "enter_seed_phrase": "Unesite svoju sjemensku frazu",
   "enter_totp_code": "Unesite TOTP kod.",
+  "enter_wallet_password": "Unesite lozinku za novčanik",
   "enter_your_note": "Unesite svoju poruku…",
   "enter_your_pin": "Upišite PIN",
   "enter_your_pin_again": "Ponovno upišite pin",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "Nemate dovoljno SOL -a za pokrivanje naknade za transakciju i najamninu za račun. Ljubazno dodajte više sol u svoj novčanik ili smanjite količinu SOL -a koju šaljete",
   "introducing_cake_pay": "Predstavljamo Cake Pay!",
   "invalid_input": "Pogrešan unos",
+  "invalid_password": "Netočna zaporka",
   "invoice_details": "Podaci o fakturi",
   "is_percentage": "je",
   "last_30_days": "Zadnjih 30 dana",
@@ -499,6 +501,8 @@
   "rename": "Preimenuj",
   "rep_warning": "Reprezentativno upozorenje",
   "rep_warning_sub": "Čini se da vaš predstavnik nije u dobrom stanju. Dodirnite ovdje za odabir novog",
+  "repeat_wallet_password": "Ponovite lozinku za novčanik",
+  "repeated_password_is_incorrect": "Ponovljena lozinka je netočna. Molimo ponovite lozinku za novčanik.",
   "require_for_adding_contacts": "Zahtijeva za dodavanje kontakata",
   "require_for_all_security_and_backup_settings": "Zahtijeva za sve postavke sigurnosti i sigurnosne kopije",
   "require_for_assessing_wallet": "Potreban za pristup novčaniku",
@@ -797,6 +801,7 @@
   "unavailable_balance_description": "Nedostupno stanje: Ovaj ukupni iznos uključuje sredstva koja su zaključana u transakcijama na čekanju i ona koja ste aktivno zamrznuli u postavkama kontrole novčića. Zaključani saldi postat će dostupni kada se dovrše njihove transakcije, dok zamrznuti saldi ostaju nedostupni za transakcije sve dok ih ne odlučite odmrznuti.",
   "unconfirmed": "Nepotvrđeno stanje",
   "understand": "Razumijem",
+  "unlock": "Otključati",
   "unmatched_currencies": "Valuta vašeg trenutnog novčanika ne odgovara onoj na skeniranom QR-u",
   "unspent_change": "Promijeniti",
   "unspent_coins_details_title": "Nepotrošeni detalji o novčićima",
@@ -838,6 +843,7 @@
   "wallet_menu": "Izbornik",
   "wallet_name": "Ime novčanika",
   "wallet_name_exists": "Novčanik s tim nazivom već postoji",
+  "wallet_password_is_empty": "Lozinka za novčanik je prazna. Lozinka za novčanik ne bi trebala biti prazna",
   "wallet_recovery_height": "Visina oporavka",
   "wallet_restoration_store_incorrect_seed_length": "Netočna dužina pristupnog izraza",
   "wallet_seed": "Pristupni izraz novčanika",
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index 97a4afd3f..0b8077807 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -236,6 +236,7 @@
   "enter_code": "Masukkan kode",
   "enter_seed_phrase": "Masukkan frasa benih Anda",
   "enter_totp_code": "Masukkan Kode TOTP.",
+  "enter_wallet_password": "Masukkan Kata Sandi Dompet",
   "enter_your_note": "Masukkan catatan Anda...",
   "enter_your_pin": "Masukkan PIN Anda",
   "enter_your_pin_again": "Masukkan PIN Anda lagi",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "Anda tidak memiliki cukup SOL untuk menutupi biaya transaksi dan menyewa untuk akun tersebut. Mohon tambahkan lebih banyak sol ke dompet Anda atau kurangi jumlah sol yang Anda kirim",
   "introducing_cake_pay": "Perkenalkan Cake Pay!",
   "invalid_input": "Masukan tidak valid",
+  "invalid_password": "Kata sandi salah",
   "invoice_details": "Detail faktur",
   "is_percentage": "adalah",
   "last_30_days": "30 hari terakhir",
@@ -501,6 +503,8 @@
   "rename": "Ganti nama",
   "rep_warning": "Peringatan Perwakilan",
   "rep_warning_sub": "Perwakilan Anda tampaknya tidak bereputasi baik. Ketuk di sini untuk memilih yang baru",
+  "repeat_wallet_password": "Ulangi Kata Sandi Dompet",
+  "repeated_password_is_incorrect": "Kata sandi yang diulang tidak benar. Harap ulangi kata sandi dompet lagi.",
   "require_for_adding_contacts": "Membutuhkan untuk menambahkan kontak",
   "require_for_all_security_and_backup_settings": "Memerlukan untuk semua pengaturan keamanan dan pencadangan",
   "require_for_assessing_wallet": "Diperlukan untuk mengakses dompet",
@@ -800,6 +804,7 @@
   "unavailable_balance_description": "Saldo Tidak Tersedia: Total ini termasuk dana yang terkunci dalam transaksi yang tertunda dan dana yang telah Anda bekukan secara aktif di pengaturan kontrol koin Anda. Saldo yang terkunci akan tersedia setelah transaksi masing-masing selesai, sedangkan saldo yang dibekukan tetap tidak dapat diakses untuk transaksi sampai Anda memutuskan untuk mencairkannya.",
   "unconfirmed": "Saldo Belum Dikonfirmasi",
   "understand": "Saya mengerti",
+  "unlock": "Membuka kunci",
   "unmatched_currencies": "Mata uang dompet Anda saat ini tidak cocok dengan yang ditandai QR",
   "unspent_change": "Mengubah",
   "unspent_coins_details_title": "Rincian koin yang tidak terpakai",
@@ -841,6 +846,7 @@
   "wallet_menu": "Menu",
   "wallet_name": "Nama Dompet",
   "wallet_name_exists": "Nama dompet sudah ada. Silakan pilih nama yang berbeda atau ganti nama dompet yang lain terlebih dahulu.",
+  "wallet_password_is_empty": "Kata sandi dompet kosong. Kata sandi dompet tidak boleh kosong",
   "wallet_recovery_height": "Tinggi pemulihan",
   "wallet_restoration_store_incorrect_seed_length": "Panjang seed yang salah",
   "wallet_seed": "Seed dompet",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index 42c2e628d..b7a81ef9a 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -237,6 +237,7 @@
   "enter_code": "Inserisci codice",
   "enter_seed_phrase": "Inserisci la tua frase di semi",
   "enter_totp_code": "Inserisci il codice TOTP.",
+  "enter_wallet_password": "Immettere la password del portafoglio",
   "enter_your_note": "Inserisci la tua nota…",
   "enter_your_pin": "Inserisci il tuo PIN",
   "enter_your_pin_again": "Inserisci il tuo pin di nuovo",
@@ -341,6 +342,7 @@
   "insufficientFundsForRentError": "Non hai abbastanza SOL per coprire la tassa di transazione e l'affitto per il conto. Si prega di aggiungere più SOL al tuo portafoglio o ridurre l'importo SOL che stai inviando",
   "introducing_cake_pay": "Presentazione di Cake Pay!",
   "invalid_input": "Inserimento non valido",
+  "invalid_password": "Password non valida",
   "invoice_details": "Dettagli della fattura",
   "is_percentage": "è",
   "last_30_days": "Ultimi 30 giorni",
@@ -501,6 +503,8 @@
   "rename": "Rinomina",
   "rep_warning": "Avvertenza rappresentativa",
   "rep_warning_sub": "Il tuo rappresentante non sembra essere in regola. Tocca qui per selezionarne uno nuovo",
+  "repeat_wallet_password": "Ripeti la password del portafoglio",
+  "repeated_password_is_incorrect": "La password ripetuta non è corretta. Si prega di ripetere di nuovo la password del portafoglio.",
   "require_for_adding_contacts": "Richiesto per l'aggiunta di contatti",
   "require_for_all_security_and_backup_settings": "Richiedi per tutte le impostazioni di sicurezza e backup",
   "require_for_assessing_wallet": "Richiesto per l'accesso al portafoglio",
@@ -799,6 +803,7 @@
   "unavailable_balance_description": "Saldo non disponibile: questo totale include i fondi bloccati nelle transazioni in sospeso e quelli che hai congelato attivamente nelle impostazioni di controllo delle monete. I saldi bloccati diventeranno disponibili una volta completate le rispettive transazioni, mentre i saldi congelati rimarranno inaccessibili per le transazioni finché non deciderai di sbloccarli.",
   "unconfirmed": "Saldo non confermato",
   "understand": "Capisco",
+  "unlock": "Sbloccare",
   "unmatched_currencies": "La valuta del tuo portafoglio attuale non corrisponde a quella del QR scansionato",
   "unspent_change": "Modifica",
   "unspent_coins_details_title": "Dettagli sulle monete non spese",
@@ -841,6 +846,7 @@
   "wallet_menu": "Menù",
   "wallet_name": "Nome del Portafoglio",
   "wallet_name_exists": "Il portafoglio con quel nome è già esistito",
+  "wallet_password_is_empty": "La password del portafoglio è vuota. La password del portafoglio non dovrebbe essere vuota",
   "wallet_recovery_height": "Altezza di recupero",
   "wallet_restoration_store_incorrect_seed_length": "Lunghezza seme non corretta",
   "wallet_seed": "Seme Portafoglio",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index 72b1f7d09..a13a4e6f0 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -236,6 +236,7 @@
   "enter_code": "コードを入力",
   "enter_seed_phrase": "シードフレーズを入力してください",
   "enter_totp_code": "TOTPコードを入力してください。",
+  "enter_wallet_password": "ウォレットパスワードを入力します",
   "enter_your_note": "メモを入力してください…",
   "enter_your_pin": "PINを入力してください",
   "enter_your_pin_again": "ピンをもう一度入力してください",
@@ -341,6 +342,7 @@
   "insufficientFundsForRentError": "アカウントの取引料金とレンタルをカバーするのに十分なソルがありません。財布にソルを追加するか、送信するソル量を減らしてください",
   "introducing_cake_pay": "序章Cake Pay!",
   "invalid_input": "無効入力",
+  "invalid_password": "無効なパスワード",
   "invoice_details": "請求の詳細",
   "is_percentage": "is",
   "last_30_days": "過去30日",
@@ -500,6 +502,8 @@
   "rename": "リネーム",
   "rep_warning": "代表的な警告",
   "rep_warning_sub": "あなたの代表者は良好な状態ではないようです。ここをタップして、新しいものを選択します",
+  "repeat_wallet_password": "ウォレットパスワードを繰り返します",
+  "repeated_password_is_incorrect": "繰り返しパスワードが正しくありません。ウォレットのパスワードをもう一度繰り返してください。",
   "require_for_adding_contacts": "連絡先の追加に必要",
   "require_for_all_security_and_backup_settings": "すべてのセキュリティおよびバックアップ設定に必須",
   "require_for_assessing_wallet": "ウォレットにアクセスするために必要です",
@@ -798,6 +802,7 @@
   "unavailable_balance_description": "利用不可能な残高: この合計には、保留中のトランザクションにロックされている資金と、コイン管理設定でアクティブに凍結した資金が含まれます。ロックされた残高は、それぞれの取引が完了すると利用可能になりますが、凍結された残高は、凍結を解除するまで取引にアクセスできません。",
   "unconfirmed": "残高未確認",
   "understand": "わかります",
+  "unlock": "ロックを解除します",
   "unmatched_currencies": "現在のウォレットの通貨がスキャンされたQRの通貨と一致しません",
   "unspent_change": "変化",
   "unspent_coins_details_title": "未使用のコインの詳細",
@@ -839,6 +844,7 @@
   "wallet_menu": "ウォレットメニュー",
   "wallet_name": "ウォレット名",
   "wallet_name_exists": "その名前のウォレットはすでに存在しています",
+  "wallet_password_is_empty": "ウォレットパスワードは空です。ウォレットのパスワードは空にしてはいけません",
   "wallet_recovery_height": "回復の高さ",
   "wallet_restoration_store_incorrect_seed_length": "誤ったシード長s",
   "wallet_seed": "ウォレットシード",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index b8cfee1b5..d20546f41 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -236,6 +236,7 @@
   "enter_code": "코드 입력",
   "enter_seed_phrase": "시드 문구를 입력하십시오",
   "enter_totp_code": "TOTP 코드를 입력하세요.",
+  "enter_wallet_password": "지갑 암호를 입력하십시오",
   "enter_your_note": "메모를 입력하세요…",
   "enter_your_pin": "PIN을 입력하십시오",
   "enter_your_pin_again": "다시 핀을 입력",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "거래 수수료와 계좌 임대료를 충당하기에 충분한 SOL이 없습니다. 지갑에 더 많은 솔을 추가하거나 보내는 솔을 줄이십시오.",
   "introducing_cake_pay": "소개 Cake Pay!",
   "invalid_input": "잘못된 입력",
+  "invalid_password": "유효하지 않은 비밀번호",
   "invoice_details": "인보이스 세부정보",
   "is_percentage": "이다",
   "last_30_days": "지난 30일",
@@ -500,6 +502,8 @@
   "rename": "이름 바꾸기",
   "rep_warning": "대표 경고",
   "rep_warning_sub": "귀하의 대표는 양호한 상태가 아닌 것 같습니다. 새 것을 선택하려면 여기를 탭하십시오",
+  "repeat_wallet_password": "지갑 암호를 반복하십시오",
+  "repeated_password_is_incorrect": "반복 된 비밀번호가 올바르지 않습니다. 지갑 암호를 다시 반복하십시오.",
   "require_for_adding_contacts": "연락처 추가에 필요",
   "require_for_all_security_and_backup_settings": "모든 보안 및 백업 설정에 필요",
   "require_for_assessing_wallet": "지갑 접근을 위해 필요",
@@ -798,6 +802,7 @@
   "unavailable_balance_description": "사용할 수 없는 잔액: 이 총계에는 보류 중인 거래에 잠겨 있는 자금과 코인 관리 설정에서 적극적으로 동결된 자금이 포함됩니다. 잠긴 잔액은 해당 거래가 완료되면 사용할 수 있게 되며, 동결된 잔액은 동결을 해제하기 전까지 거래에 액세스할 수 없습니다.",
   "unconfirmed": "확인되지 않은 잔액",
   "understand": "이해 했어요",
+  "unlock": "터놓다",
   "unmatched_currencies": "현재 지갑의 통화가 스캔한 QR의 통화와 일치하지 않습니다.",
   "unspent_change": "변화",
   "unspent_coins_details_title": "사용하지 않은 동전 세부 정보",
@@ -839,6 +844,7 @@
   "wallet_menu": "월렛 메뉴",
   "wallet_name": "지갑 이름",
   "wallet_name_exists": "해당 이름의 지갑이 이미 존재합니다.",
+  "wallet_password_is_empty": "지갑 암호는 비어 있습니다. 지갑 암호는 비어 있지 않아야합니다",
   "wallet_recovery_height": "복구 높이",
   "wallet_restoration_store_incorrect_seed_length": "시드 길이가 잘못되었습니다",
   "wallet_seed": "지갑 시드",
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index 52fe72ea6..06d7cf627 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -236,6 +236,7 @@
   "enter_code": "ကုဒ်ထည့်ပါ။",
   "enter_seed_phrase": "သင့်ရဲ့မျိုးစေ့စကားစုကိုရိုက်ထည့်ပါ",
   "enter_totp_code": "ကျေးဇူးပြု၍ TOTP ကုဒ်ကို ထည့်ပါ။",
+  "enter_wallet_password": "ပိုက်ဆံအိတ်စကားဝှက်ကိုရိုက်ထည့်ပါ",
   "enter_your_note": "သင့်မှတ်စုကို ထည့်ပါ...",
   "enter_your_pin": "သင်၏ PIN ကိုထည့်ပါ။",
   "enter_your_pin_again": "သင့်ပင်နံပါတ်ကို ထပ်မံထည့်သွင်းပါ။",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "သင်ငွေပေးချေမှုအခကြေးငွေကိုဖုံးအုပ်ရန်နှင့်အကောင့်ငှားရန်လုံလောက်သော sol ရှိသည်မဟုတ်ကြဘူး။ ကြင်နာစွာသင်၏ပိုက်ဆံအိတ်သို့ပိုမို sol ကိုပိုမိုထည့်ပါသို့မဟုတ်သင်ပို့ခြင်း sol ပမာဏကိုလျှော့ချပါ",
   "introducing_cake_pay": "Cake Pay ကို မိတ်ဆက်ခြင်း။",
   "invalid_input": "ထည့်သွင်းမှု မမှန်ကန်ပါ။",
+  "invalid_password": "မမှန်ကန်သောစကားဝှက်",
   "invoice_details": "ပြေစာအသေးစိတ်",
   "is_percentage": "သည်",
   "last_30_days": "လွန်ခဲ့သော ရက် 30",
@@ -499,6 +501,8 @@
   "rename": "အမည်ပြောင်းပါ။",
   "rep_warning": "ကိုယ်စားလှယ်သတိပေးချက်",
   "rep_warning_sub": "သင်၏ကိုယ်စားလှယ်သည်ကောင်းမွန်သောရပ်တည်မှုတွင်မဖြစ်သင့်ပါ။ အသစ်တစ်ခုကိုရွေးချယ်ရန်ဤနေရာတွင်အသာပုတ်ပါ",
+  "repeat_wallet_password": "ပိုက်ဆံအိတ်စကားဝှက်ကိုပြန်လုပ်ပါ",
+  "repeated_password_is_incorrect": "ထပ်ခါတလဲလဲစကားဝှက်မမှန်ကန်ပါ ကျေးဇူးပြုပြီးပိုက်ဆံအိတ်စကားဝှက်ကိုပြန်လုပ်ပါ။",
   "require_for_adding_contacts": "အဆက်အသွယ်များထည့်ရန် လိုအပ်သည်။",
   "require_for_all_security_and_backup_settings": "လုံခြုံရေးနှင့် အရန်ဆက်တင်များအားလုံးအတွက် လိုအပ်ပါသည်။",
   "require_for_assessing_wallet": "ပိုက်ဆံအိတ်ကို ဝင်သုံးရန် လိုအပ်သည်။",
@@ -797,6 +801,7 @@
   "unavailable_balance_description": "မရရှိနိုင်သော လက်ကျန်ငွေ- ဤစုစုပေါင်းတွင် ဆိုင်းငံ့ထားသော ငွေပေးငွေယူများတွင် သော့ခတ်ထားသော ငွေကြေးများနှင့် သင်၏ coin ထိန်းချုပ်မှုဆက်တင်များတွင် သင် တက်ကြွစွာ အေးခဲထားသော ငွေများ ပါဝင်သည်။ သော့ခတ်ထားသော လက်ကျန်ငွေများကို ၎င်းတို့၏ သက်ဆိုင်ရာ ငွေပေးငွေယူများ ပြီးမြောက်သည်နှင့် တပြိုင်နက် ရရှိနိုင်မည်ဖြစ်ပြီး၊ အေးခဲထားသော လက်ကျန်များကို ၎င်းတို့အား ပြန်ဖြုတ်ရန် သင်ဆုံးဖြတ်သည်အထိ ငွေပေးငွေယူများအတွက် ဆက်လက်၍မရနိုင်ပါ။",
   "unconfirmed": "အတည်မပြုနိုင်သော လက်ကျန်ငွေ",
   "understand": "ကျွန်တော်နားလည်ပါတယ်",
+  "unlock": "သော့ဖွင့်",
   "unmatched_currencies": "သင့်လက်ရှိပိုက်ဆံအိတ်၏ငွေကြေးသည် စကင်ဖတ်ထားသော QR နှင့် မကိုက်ညီပါ။",
   "unspent_change": "ပေြာင်းလဲခြင်း",
   "unspent_coins_details_title": "အသုံးမဝင်သော အကြွေစေ့အသေးစိတ်များ",
@@ -838,6 +843,7 @@
   "wallet_menu": "မီနူး",
   "wallet_name": "ပိုက်ဆံအိတ်နာမည",
   "wallet_name_exists": "ထိုအမည်ဖြင့် ပိုက်ဆံအိတ်တစ်ခု ရှိနှင့်ပြီးဖြစ်သည်။ အခြားအမည်တစ်ခုကို ရွေးပါ သို့မဟုတ် အခြားပိုက်ဆံအိတ်ကို ဦးစွာ အမည်ပြောင်းပါ။",
+  "wallet_password_is_empty": "ပိုက်ဆံအိတ်စကားဝှက်သည်ဗလာဖြစ်သည်။ ပိုက်ဆံအိတ်စကားဝှက်သည်အချည်းနှီးဖြစ်သင့်သည်",
   "wallet_recovery_height": "ပြန်လည်ထူထောင်ရေးအမြင့်",
   "wallet_restoration_store_incorrect_seed_length": "မျိုးစေ့အရှည် မမှန်ပါ။",
   "wallet_seed": "ပိုက်ဆံအိတ်စေ့",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index cde10506f..78caef912 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -236,6 +236,7 @@
   "enter_code": "Voer code in",
   "enter_seed_phrase": "Voer uw zaadzin in",
   "enter_totp_code": "Voer de TOTP-code in.",
+  "enter_wallet_password": "Voer het Wallet -wachtwoord in",
   "enter_your_note": "Voer uw notitie in ...",
   "enter_your_pin": "Voer uw pincode in",
   "enter_your_pin_again": "Voer uw PIN opnieuw in",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "U hebt niet genoeg SOL om de transactiekosten en huur voor de rekening te dekken. Voeg vriendelijk meer SOL toe aan uw portemonnee of verminder de SOL -hoeveelheid die u verzendt",
   "introducing_cake_pay": "Introductie van Cake Pay!",
   "invalid_input": "Ongeldige invoer",
+  "invalid_password": "Ongeldig wachtwoord",
   "invoice_details": "Factuurgegevens",
   "is_percentage": "is",
   "last_30_days": "Laatste 30 dagen",
@@ -499,6 +501,8 @@
   "rename": "Hernoemen",
   "rep_warning": "Representatieve waarschuwing",
   "rep_warning_sub": "Uw vertegenwoordiger lijkt niet goed te staan. Tik hier om een ​​nieuwe te selecteren",
+  "repeat_wallet_password": "Herhaal het Wallet -wachtwoord",
+  "repeated_password_is_incorrect": "Herhaald wachtwoord is onjuist. Herhaal het Wallet -wachtwoord opnieuw.",
   "require_for_adding_contacts": "Vereist voor het toevoegen van contacten",
   "require_for_all_security_and_backup_settings": "Vereist voor alle beveiligings- en back-upinstellingen",
   "require_for_assessing_wallet": "Vereist voor toegang tot portemonnee",
@@ -797,6 +801,7 @@
   "unavailable_balance_description": "Niet-beschikbaar saldo: Dit totaal omvat het geld dat is vergrendeld in lopende transacties en het geld dat u actief hebt bevroren in uw muntcontrole-instellingen. Vergrendelde saldi komen beschikbaar zodra de betreffende transacties zijn voltooid, terwijl bevroren saldi ontoegankelijk blijven voor transacties totdat u besluit ze weer vrij te geven.",
   "unconfirmed": "Onbevestigd saldo",
   "understand": "Ik begrijp het",
+  "unlock": "Ontgrendelen",
   "unmatched_currencies": "De valuta van uw huidige portemonnee komt niet overeen met die van de gescande QR",
   "unspent_change": "Wijziging",
   "unspent_coins_details_title": "Details van niet-uitgegeven munten",
@@ -839,6 +844,7 @@
   "wallet_menu": "Portemonnee-menu",
   "wallet_name": "Portemonnee naam",
   "wallet_name_exists": "Portemonnee met die naam bestaat al",
+  "wallet_password_is_empty": "Wallet -wachtwoord is leeg. Wallet -wachtwoord mag niet leeg zijn",
   "wallet_recovery_height": "Herstelhoogte",
   "wallet_restoration_store_incorrect_seed_length": "Onjuiste zaadlengte",
   "wallet_seed": "Portemonnee zaad",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index a22034c96..7de435319 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -236,6 +236,7 @@
   "enter_code": "Wprowadź kod",
   "enter_seed_phrase": "Wprowadź swoją frazę nasienną",
   "enter_totp_code": "Wprowadź kod TOTP.",
+  "enter_wallet_password": "Wprowadź hasło portfela",
   "enter_your_note": "Wpisz notatkę…",
   "enter_your_pin": "Wpisz kod PIN",
   "enter_your_pin_again": "Wprowadź ponownie swój kod PIN",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "Nie masz wystarczającej ilości SOL, aby pokryć opłatę za transakcję i czynsz za konto. Uprzejmie dodaj więcej sol do portfela lub zmniejsz solę, którą wysyłasz",
   "introducing_cake_pay": "Przedstawiamy Cake Pay!",
   "invalid_input": "Nieprawidłowe dane wejściowe",
+  "invalid_password": "Nieprawidłowe hasło",
   "invoice_details": "Dane do faktury",
   "is_percentage": "jest",
   "last_30_days": "Ostatnie 30 dni",
@@ -499,6 +501,8 @@
   "rename": "Zmień nazwę",
   "rep_warning": "Przedstawicielskie ostrzeżenie",
   "rep_warning_sub": "Twój przedstawiciel nie wydaje się mieć dobrej opinii. Stuknij tutaj, aby wybrać nowy",
+  "repeat_wallet_password": "Powtórz hasło portfela",
+  "repeated_password_is_incorrect": "Powtarzane hasło jest nieprawidłowe. Powtórz ponownie hasło portfela.",
   "require_for_adding_contacts": "Wymagane do dodania kontaktów",
   "require_for_all_security_and_backup_settings": "Wymagaj dla wszystkich ustawień zabezpieczeń i kopii zapasowych",
   "require_for_assessing_wallet": "Wymagaj dostępu do portfela",
@@ -797,6 +801,7 @@
   "unavailable_balance_description": "Niedostępne saldo: Suma ta obejmuje środki zablokowane w transakcjach oczekujących oraz te, które aktywnie zamroziłeś w ustawieniach kontroli monet. Zablokowane salda staną się dostępne po zakończeniu odpowiednich transakcji, natomiast zamrożone salda pozostaną niedostępne dla transakcji, dopóki nie zdecydujesz się ich odblokować.",
   "unconfirmed": "Niepotwierdzone saldo",
   "understand": "Rozumiem",
+  "unlock": "Odblokować",
   "unmatched_currencies": "Waluta Twojego obecnego portfela nie zgadza się z waluctą zeskanowanego kodu QR",
   "unspent_change": "Zmiana",
   "unspent_coins_details_title": "Szczegóły niewydanych monet",
@@ -838,6 +843,7 @@
   "wallet_menu": "Menu portfela",
   "wallet_name": "Nazwa portfela",
   "wallet_name_exists": "Portfel o tej nazwie już istnieje",
+  "wallet_password_is_empty": "Hasło portfela jest puste. Hasło portfela nie powinno być puste",
   "wallet_recovery_height": "Wysokość odzysku",
   "wallet_restoration_store_incorrect_seed_length": "Nieprawidłowa długość frazy seed",
   "wallet_seed": "Seed portfela",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 8f87ca59f..a3d789cab 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -236,6 +236,7 @@
   "enter_code": "Digite o código",
   "enter_seed_phrase": "Digite sua frase de semente",
   "enter_totp_code": "Digite o código TOTP.",
+  "enter_wallet_password": "Digite a senha da carteira",
   "enter_your_note": "Insira sua nota ...",
   "enter_your_pin": "Insira seu PIN",
   "enter_your_pin_again": "Insira seu PIN novamente",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "Você não tem Sol suficiente para cobrir a taxa de transação e o aluguel da conta. Por favor, adicione mais sol à sua carteira ou reduza a quantidade de sol que você envia",
   "introducing_cake_pay": "Apresentando o Cake Pay!",
   "invalid_input": "Entrada inválida",
+  "invalid_password": "Senha inválida",
   "invoice_details": "Detalhes da fatura",
   "is_percentage": "é",
   "last_30_days": "Últimos 30 dias",
@@ -501,6 +503,8 @@
   "rename": "Renomear",
   "rep_warning": "Aviso representativo",
   "rep_warning_sub": "Seu representante não parece estar em boa posição. Toque aqui para selecionar um novo",
+  "repeat_wallet_password": "Repita a senha da carteira",
+  "repeated_password_is_incorrect": "A senha repetida está incorreta. Repita a senha da carteira novamente.",
   "require_for_adding_contacts": "Requer para adicionar contatos",
   "require_for_all_security_and_backup_settings": "Exigir todas as configurações de segurança e backup",
   "require_for_assessing_wallet": "Requer para acessar a carteira",
@@ -799,6 +803,7 @@
   "unavailable_balance_description": "Saldo Indisponível: Este total inclui fundos bloqueados em transações pendentes e aqueles que você congelou ativamente nas configurações de controle de moedas. Os saldos bloqueados ficarão disponíveis assim que suas respectivas transações forem concluídas, enquanto os saldos congelados permanecerão inacessíveis para transações até que você decida descongelá-los.",
   "unconfirmed": "Saldo não confirmado",
   "understand": "Entendo",
+  "unlock": "Desbloquear",
   "unmatched_currencies": "A moeda da sua carteira atual não corresponde à do QR digitalizado",
   "unspent_change": "Troco",
   "unspent_coins_details_title": "Detalhes de moedas não gastas",
@@ -841,6 +846,7 @@
   "wallet_menu": "Menu",
   "wallet_name": "Nome da carteira",
   "wallet_name_exists": "A carteira com esse nome já existe",
+  "wallet_password_is_empty": "A senha da carteira está vazia. A senha da carteira não deve estar vazia",
   "wallet_recovery_height": "Altura de recuperação",
   "wallet_restoration_store_incorrect_seed_length": "Comprimento de semente incorreto",
   "wallet_seed": "Semente de carteira",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index 9f360137f..d84aa146f 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -236,6 +236,7 @@
   "enter_code": "Введите код",
   "enter_seed_phrase": "Введите свою семенную фразу",
   "enter_totp_code": "Пожалуйста, введите TOTP-код.",
+  "enter_wallet_password": "Введите пароль кошелька",
   "enter_your_note": "Введите примечание…",
   "enter_your_pin": "Введите ваш PIN",
   "enter_your_pin_again": "Введите PIN еще раз",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "У вас недостаточно Sol, чтобы покрыть плату за транзакцию и аренду для счета. Пожалуйста, добавьте больше Sol в свой кошелек или уменьшите сумму Sol, которую вы отправляете",
   "introducing_cake_pay": "Представляем Cake Pay!",
   "invalid_input": "Неверный Ввод",
+  "invalid_password": "Неверный пароль",
   "invoice_details": "Детали счета",
   "is_percentage": "есть",
   "last_30_days": "Последние 30 дней",
@@ -500,6 +502,8 @@
   "rename": "Переименовать",
   "rep_warning": "Представительное предупреждение",
   "rep_warning_sub": "Ваш представитель, похоже, не в хорошей репутации. Нажмите здесь, чтобы выбрать новый",
+  "repeat_wallet_password": "Повторите пароль кошелька",
+  "repeated_password_is_incorrect": "Повторный пароль неверен. Пожалуйста, повторите пароль кошелька снова.",
   "require_for_adding_contacts": "Требовать добавления контактов",
   "require_for_all_security_and_backup_settings": "Требовать все настройки безопасности и резервного копирования",
   "require_for_assessing_wallet": "Требовать для доступа к кошельку",
@@ -798,6 +802,7 @@
   "unavailable_balance_description": "Недоступный баланс: в эту сумму входят средства, заблокированные в ожидающих транзакциях, и средства, которые вы активно заморозили в настройках управления монетами. Заблокированные балансы станут доступны после завершения соответствующих транзакций, а замороженные балансы останутся недоступными для транзакций, пока вы не решите их разморозить.",
   "unconfirmed": "Неподтвержденный баланс",
   "understand": "Понятно",
+  "unlock": "Разблокировать",
   "unmatched_currencies": "Валюта вашего текущего кошелька не соответствует валюте отсканированного QR-кода.",
   "unspent_change": "Изменять",
   "unspent_coins_details_title": "Сведения о неизрасходованных монетах",
@@ -839,6 +844,7 @@
   "wallet_menu": "Меню кошелька",
   "wallet_name": "Имя кошелька",
   "wallet_name_exists": "Кошелек с таким именем уже существует",
+  "wallet_password_is_empty": "Пароль кошелька пуст. Пароль кошелька не должен быть пустым",
   "wallet_recovery_height": "Высота восстановления",
   "wallet_restoration_store_incorrect_seed_length": "Неверная длина мнемонической фразы",
   "wallet_seed": "Мнемоническая фраза кошелька",
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index a178d2452..2adccb2cf 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -236,6 +236,7 @@
   "enter_code": "กรอกรหัส",
   "enter_seed_phrase": "ป้อนวลีเมล็ดพันธุ์ของคุณ",
   "enter_totp_code": "กรุณาใส่รหัสทีโอที",
+  "enter_wallet_password": "ป้อนรหัสผ่านกระเป๋าเงิน",
   "enter_your_note": "ใส่บันทึกของคุณ...",
   "enter_your_pin": "ใส่ PIN ของคุณ",
   "enter_your_pin_again": "ใส่ PIN ของคุณอีกครั้ง",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "คุณไม่มีโซลเพียงพอที่จะครอบคลุมค่าธรรมเนียมการทำธุรกรรมและค่าเช่าสำหรับบัญชี กรุณาเพิ่มโซลให้มากขึ้นลงในกระเป๋าเงินของคุณหรือลดจำนวนโซลที่คุณส่งมา",
   "introducing_cake_pay": "ยินดีต้อนรับสู่ Cake Pay!",
   "invalid_input": "อินพุตไม่ถูกต้อง",
+  "invalid_password": "รหัสผ่านไม่ถูกต้อง",
   "invoice_details": "รายละเอียดใบแจ้งหนี้",
   "is_percentage": "เป็น",
   "last_30_days": "30 วันล่าสุด",
@@ -499,6 +501,8 @@
   "rename": "เปลี่ยนชื่อ",
   "rep_warning": "คำเตือนตัวแทน",
   "rep_warning_sub": "ตัวแทนของคุณดูเหมือนจะไม่อยู่ในสถานะที่ดี แตะที่นี่เพื่อเลือกอันใหม่",
+  "repeat_wallet_password": "ทำซ้ำรหัสผ่านกระเป๋าเงิน",
+  "repeated_password_is_incorrect": "รหัสผ่านซ้ำไม่ถูกต้อง โปรดทำซ้ำรหัสผ่านกระเป๋าเงินอีกครั้ง",
   "require_for_adding_contacts": "ต้องการสำหรับการเพิ่มผู้ติดต่อ",
   "require_for_all_security_and_backup_settings": "จำเป็นสำหรับการตั้งค่าความปลอดภัยและการสำรองข้อมูลทั้งหมด",
   "require_for_assessing_wallet": "จำเป็นสำหรับการเข้าถึงกระเป๋าเงิน",
@@ -797,6 +801,7 @@
   "unavailable_balance_description": "ยอดคงเหลือที่ไม่พร้อมใช้งาน: ยอดรวมนี้รวมถึงเงินทุนที่ถูกล็อคในการทำธุรกรรมที่รอดำเนินการและที่คุณได้แช่แข็งไว้ในการตั้งค่าการควบคุมเหรียญของคุณ ยอดคงเหลือที่ถูกล็อคจะพร้อมใช้งานเมื่อธุรกรรมที่เกี่ยวข้องเสร็จสมบูรณ์ ในขณะที่ยอดคงเหลือที่แช่แข็งจะไม่สามารถเข้าถึงได้สำหรับธุรกรรมจนกว่าคุณจะตัดสินใจยกเลิกการแช่แข็ง",
   "unconfirmed": "ยอดคงเหลือที่ไม่ได้รับการยืนยัน",
   "understand": "ฉันเข้าใจ",
+  "unlock": "ปลดล็อค",
   "unmatched_currencies": "สกุลเงินของกระเป๋าปัจจุบันของคุณไม่ตรงกับของ QR ที่สแกน",
   "unspent_change": "เปลี่ยน",
   "unspent_coins_details_title": "รายละเอียดเหรียญที่ไม่ได้ใช้",
@@ -838,6 +843,7 @@
   "wallet_menu": "เมนู",
   "wallet_name": "ชื่อกระเป๋า",
   "wallet_name_exists": "กระเป๋าที่มีชื่อนี้มีอยู่แล้ว โปรดเลือกชื่ออื่นหรือเปลี่ยนชื่อกระเป๋าอื่นก่อน",
+  "wallet_password_is_empty": "รหัสผ่านกระเป๋าเงินว่างเปล่า รหัสผ่านกระเป๋าเงินไม่ควรว่างเปล่า",
   "wallet_recovery_height": "ความสูงของการกู้คืน",
   "wallet_restoration_store_incorrect_seed_length": "ความยาวของซีดไม่ถูกต้อง",
   "wallet_seed": "ซีดของกระเป๋า",
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index f49d3ddee..3bbae2e50 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -236,6 +236,7 @@
   "enter_code": "Ipasok ang code",
   "enter_seed_phrase": "Ipasok ang iyong pariralang binhi",
   "enter_totp_code": "Mangyaring ipasok ang TOTP code.",
+  "enter_wallet_password": "Ipasok ang password ng pitaka",
   "enter_your_note": "Ipasok ang iyong tala ...",
   "enter_your_pin": "Ipasok ang iyong pin",
   "enter_your_pin_again": "Ipasok muli ang iyong pin",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "Wala kang sapat na sol upang masakop ang bayad sa transaksyon at upa para sa account. Mabait na magdagdag ng higit pa sa iyong pitaka o bawasan ang halaga ng sol na iyong ipinapadala",
   "introducing_cake_pay": "Ipinakikilala ang cake pay!",
   "invalid_input": "Di -wastong input",
+  "invalid_password": "Di wastong password",
   "invoice_details": "Mga detalye ng invoice",
   "is_percentage": "ay",
   "last_30_days": "Huling 30 araw",
@@ -499,6 +501,8 @@
   "rename": "Palitan ang pangalan",
   "rep_warning": "Babala ng kinatawan",
   "rep_warning_sub": "Ang iyong kinatawan ay hindi lilitaw na nasa mabuting kalagayan. Tapikin dito upang pumili ng bago",
+  "repeat_wallet_password": "Ulitin ang password ng pitaka",
+  "repeated_password_is_incorrect": "Ang paulit -ulit na password ay hindi tama. Mangyaring ulitin muli ang password ng pitaka.",
   "require_for_adding_contacts": "Nangangailangan para sa pagdaragdag ng mga contact",
   "require_for_all_security_and_backup_settings": "Nangangailangan para sa lahat ng mga setting ng seguridad at backup",
   "require_for_assessing_wallet": "Nangangailangan para sa pag -access ng pitaka",
@@ -797,6 +801,7 @@
   "unavailable_balance_description": "Hindi Available na Balanse: Kasama sa kabuuang ito ang mga pondong naka-lock sa mga nakabinbing transaksyon at ang mga aktibong na-freeze mo sa iyong mga setting ng kontrol ng coin. Magiging available ang mga naka-lock na balanse kapag nakumpleto na ang kani-kanilang mga transaksyon, habang ang mga nakapirming balanse ay nananatiling hindi naa-access para sa mga transaksyon hanggang sa magpasya kang i-unfreeze ang mga ito.",
   "unconfirmed": "Hindi nakumpirma na balanse",
   "understand": "naiintindihan ko",
+  "unlock": "I -unlock",
   "unmatched_currencies": "Ang pera ng iyong kasalukuyang pitaka ay hindi tumutugma sa na -scan na QR",
   "unspent_change": "Baguhin",
   "unspent_coins_details_title": "Mga Detalye ng Unspent Coins",
@@ -838,6 +843,7 @@
   "wallet_menu": "Menu",
   "wallet_name": "Pangalan ng Wallet",
   "wallet_name_exists": "Ang isang pitaka na may pangalang iyon ay mayroon na. Mangyaring pumili ng ibang pangalan o palitan muna ang iba pang pitaka.",
+  "wallet_password_is_empty": "Walang laman ang password ng wallet. Ang password ng wallet ay hindi dapat walang laman",
   "wallet_recovery_height": "Taas ng pagbawi",
   "wallet_restoration_store_incorrect_seed_length": "Maling haba ng binhi",
   "wallet_seed": "SEED ng Wallet",
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index c73765f64..b47787bbd 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -236,6 +236,7 @@
   "enter_code": "Kodu girin",
   "enter_seed_phrase": "Tohum ifadenizi girin",
   "enter_totp_code": "Lütfen TOTP Kodunu giriniz.",
+  "enter_wallet_password": "Cüzdan şifresini girin",
   "enter_your_note": "Notunu gir…",
   "enter_your_pin": "PIN'ini gir",
   "enter_your_pin_again": "PIN kodunu tekrar girin",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "İşlem ücretini karşılamak ve hesap için kiralamak için yeterli SOL'nuz yok. Lütfen cüzdanınıza daha fazla sol ekleyin veya gönderdiğiniz sol miktarını azaltın",
   "introducing_cake_pay": "Cake Pay ile tanışın!",
   "invalid_input": "Geçersiz Giriş",
+  "invalid_password": "Geçersiz şifre",
   "invoice_details": "fatura detayları",
   "is_percentage": "is",
   "last_30_days": "Son 30 gün",
@@ -499,6 +501,8 @@
   "rename": "Yeniden adlandır",
   "rep_warning": "Temsilci uyarı",
   "rep_warning_sub": "Temsilciniz iyi durumda görünmüyor. Yeni bir tane seçmek için buraya dokunun",
+  "repeat_wallet_password": "Cüzdan şifresini tekrarlayın",
+  "repeated_password_is_incorrect": "Tekrarlanan şifre yanlış. Lütfen cüzdan şifresini tekrarlayın.",
   "require_for_adding_contacts": "Kişi eklemek için gerekli",
   "require_for_all_security_and_backup_settings": "Tüm güvenlik ve yedekleme ayarları için iste",
   "require_for_assessing_wallet": "Cüzdana erişmek için gerekli",
@@ -797,6 +801,7 @@
   "unavailable_balance_description": "Kullanılamayan Bakiye: Bu toplam, bekleyen işlemlerde kilitlenen fonları ve jeton kontrol ayarlarınızda aktif olarak dondurduğunuz fonları içerir. Kilitli bakiyeler, ilgili işlemleri tamamlandıktan sonra kullanılabilir hale gelir; dondurulmuş bakiyeler ise siz onları dondurmaya karar verene kadar işlemler için erişilemez durumda kalır.",
   "unconfirmed": "Onaylanmamış Bakiye",
   "understand": "Anladım",
+  "unlock": "Kilidini aç",
   "unmatched_currencies": "Mevcut cüzdanınızın para birimi taranan QR ile eşleşmiyor",
   "unspent_change": "Değiştirmek",
   "unspent_coins_details_title": "Harcanmamış koin detayları",
@@ -838,6 +843,7 @@
   "wallet_menu": "Menü",
   "wallet_name": "Cüzdan ismi",
   "wallet_name_exists": "Bu isimde bir cüzdan zaten mevcut. Lütfen farklı bir isim seç veya önce diğer cüzdanı yeniden adlandır.",
+  "wallet_password_is_empty": "Cüzdan şifresi boş. Cüzdan şifresi boş olmamalı",
   "wallet_recovery_height": "Kurtarma Yüksekliği",
   "wallet_restoration_store_incorrect_seed_length": "Yanlış tohum uzunluğu",
   "wallet_seed": "Cüzdan tohumu",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index d088dd1b2..328548087 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -236,6 +236,7 @@
   "enter_code": "Введіть код",
   "enter_seed_phrase": "Введіть свою насіннєву фразу",
   "enter_totp_code": "Будь ласка, введіть код TOTP.",
+  "enter_wallet_password": "Введіть пароль гаманця",
   "enter_your_note": "Введіть примітку…",
   "enter_your_pin": "Введіть ваш PIN",
   "enter_your_pin_again": "Введіть PIN ще раз",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "У вас недостатньо SOL, щоб покрити плату за транзакцію та оренду на рахунок. Будь ласка, додайте до свого гаманця більше SOL або зменшіть суму, яку ви надсилаєте",
   "introducing_cake_pay": "Представляємо Cake Pay!",
   "invalid_input": "Неправильні дані",
+  "invalid_password": "Недійсний пароль",
   "invoice_details": "Реквізити рахунку-фактури",
   "is_percentage": "є",
   "last_30_days": "Останні 30 днів",
@@ -500,6 +502,8 @@
   "rename": "Перейменувати",
   "rep_warning": "Представницьке попередження",
   "rep_warning_sub": "Ваш представник, схоже, не має доброго становища. Торкніться тут, щоб вибрати новий",
+  "repeat_wallet_password": "Повторіть пароль гаманця",
+  "repeated_password_is_incorrect": "Повторний пароль невірний. Будь ласка, повторіть пароль гаманця ще раз.",
   "require_for_adding_contacts": "Потрібен для додавання контактів",
   "require_for_all_security_and_backup_settings": "Вимагати всіх налаштувань безпеки та резервного копіювання",
   "require_for_assessing_wallet": "Потрібен доступ до гаманця",
@@ -798,6 +802,7 @@
   "unavailable_balance_description": "Недоступний баланс: ця сума включає кошти, заблоковані в незавершених транзакціях, і ті, які ви активно заморозили в налаштуваннях контролю монет. Заблоковані баланси стануть доступними після завершення відповідних транзакцій, тоді як заморожені баланси залишаються недоступними для транзакцій, доки ви не вирішите їх розморозити.",
   "unconfirmed": "Непідтверджений баланс",
   "understand": "Зрозуміло",
+  "unlock": "Розблокувати",
   "unmatched_currencies": "Валюта вашого гаманця не збігається з валютою сканованого QR-коду",
   "unspent_change": "Зміна",
   "unspent_coins_details_title": "Відомості про невитрачені монети",
@@ -839,6 +844,7 @@
   "wallet_menu": "Меню гаманця",
   "wallet_name": "Ім'я гаманця",
   "wallet_name_exists": "Гаманець з такою назвою вже існує",
+  "wallet_password_is_empty": "Пароль гаманця порожній. Пароль гаманця не повинен бути порожнім",
   "wallet_recovery_height": "Висота відновлення",
   "wallet_restoration_store_incorrect_seed_length": "Невірна довжина мнемонічної фрази",
   "wallet_seed": "Мнемонічна фраза гаманця",
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index 0694463de..7d794f9bb 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -236,6 +236,7 @@
   "enter_code": "کوڈ درج کریں",
   "enter_seed_phrase": "اپنے بیج کا جملہ درج کریں",
   "enter_totp_code": "براہ کرم TOTP کوڈ درج کریں۔",
+  "enter_wallet_password": "پرس کا پاس ورڈ درج کریں",
   "enter_your_note": "اپنا نوٹ درج کریں…",
   "enter_your_pin": "اپنا PIN درج کریں۔",
   "enter_your_pin_again": "اپنا پن دوبارہ درج کریں۔",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "آپ کے پاس ٹرانزیکشن فیس اور اکاؤنٹ کے لئے کرایہ لینے کے ل enough اتنا SOL نہیں ہے۔ برائے مہربانی اپنے بٹوے میں مزید سول شامل کریں یا آپ کو بھیجنے والی سول رقم کو کم کریں",
   "introducing_cake_pay": "Cake پے کا تعارف!",
   "invalid_input": "غلط ان پٹ",
+  "invalid_password": "غلط پاسورڈ",
   "invoice_details": "رسید کی تفصیلات",
   "is_percentage": "ہے",
   "last_30_days": "آخری 30 دن",
@@ -501,6 +503,8 @@
   "rename": "نام تبدیل کریں۔",
   "rep_warning": "نمائندہ انتباہ",
   "rep_warning_sub": "آپ کا نمائندہ اچھ standing ے مقام پر نہیں دکھائی دیتا ہے۔ نیا منتخب کرنے کے لئے یہاں ٹیپ کریں",
+  "repeat_wallet_password": "بٹوے کا پاس ورڈ دہرائیں",
+  "repeated_password_is_incorrect": "بار بار پاس ورڈ غلط ہے۔ براہ کرم دوبارہ پرس کا پاس ورڈ دہرائیں۔",
   "require_for_adding_contacts": "رابطوں کو شامل کرنے کی ضرورت ہے۔",
   "require_for_all_security_and_backup_settings": "تمام سیکورٹی اور بیک اپ کی ترتیبات کے لیے درکار ہے۔",
   "require_for_assessing_wallet": "بٹوے تک رسائی کے لیے درکار ہے۔",
@@ -799,6 +803,7 @@
   "unavailable_balance_description": "۔ﮯﺗﺮﮐ ﮟﯿﮩﻧ ﮧﻠﺼﯿﻓ ﺎﮐ ﮯﻧﺮﮐ ﺪﻤﺠﻨﻣ ﻥﺍ ﮟﯿﮩﻧﺍ ﭖﺁ ﮧﮐ ﮏﺗ ﺐﺟ ﮟﯿﮨ ﮯﺘﮨﺭ ﯽﺋﺎﺳﺭ ﻞﺑﺎﻗﺎﻧ ﮏﺗ ﺖﻗﻭ ﺱﺍ ﮯﯿﻟ ﮯﮐ ﻦﯾﺩ ﻦﯿﻟ ﺲﻨﻠﯿﺑ ﺪﻤﺠﻨﻣ ﮧﮐ ﺐﺟ ،ﮯﮔ ﮟﯿﺋﺎﺟ ﻮﮨ ﺏﺎﯿﺘﺳﺩ ﺲﻨﻠﯿﺑ ﻞﻔﻘﻣ ﺪﻌﺑ ﮯﮐ ﮯﻧﻮﮨ ﻞﻤﮑﻣ ﻦﯾﺩ ﻦﯿﻟ ﮧﻘﻠﻌﺘﻣ ﮯﮐ ﻥﺍ ۔ﮯﮨ ﺎﮭﮐﺭ ﺮ",
   "unconfirmed": "غیر تصدیق شدہ بیلنس",
   "understand": "میں سمجھتا ہوں۔",
+  "unlock": "غیر مقفل",
   "unmatched_currencies": "آپ کے پرس کی موجودہ کرنسی اسکین شدہ QR سے مماثل نہیں ہے۔",
   "unspent_change": "تبدیل کریں",
   "unspent_coins_details_title": "غیر خرچ شدہ سککوں کی تفصیلات",
@@ -840,6 +845,7 @@
   "wallet_menu": "مینو",
   "wallet_name": "بٹوے کا نام",
   "wallet_name_exists": "اس نام کا پرس پہلے سے موجود ہے۔ براہ کرم ایک مختلف نام منتخب کریں یا پہلے دوسرے بٹوے کا نام تبدیل کریں۔",
+  "wallet_password_is_empty": "پرس کا پاس ورڈ خالی ہے۔ پرس کا پاس ورڈ خالی نہیں ہونا چاہئے",
   "wallet_recovery_height": "بحالی کی اونچائی",
   "wallet_restoration_store_incorrect_seed_length": "غلط بیج کی لمبائی",
   "wallet_seed": "بٹوے کا بیج",
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index 87df87aca..2150a503f 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -237,6 +237,7 @@
   "enter_code": "Tẹ̀ ọ̀rọ̀",
   "enter_seed_phrase": "Tẹ ọrọ-iru irugbin rẹ",
   "enter_totp_code": "Jọwọ pọ koodu TOTP.",
+  "enter_wallet_password": "Tẹ ọrọ igbaniwọle apamọwọ",
   "enter_your_note": "Tẹ̀ àkọsílẹ̀ yín",
   "enter_your_pin": "Tẹ̀ òǹkà ìdánimọ̀ àdáni yín",
   "enter_your_pin_again": "Tún òǹkà ìdánimọ̀ àdáni yín tẹ̀",
@@ -341,6 +342,7 @@
   "insufficientFundsForRentError": "O ko ni Sol kan lati bo owo isanwo naa ki o yalo fun iroyin naa. Fi agbara kun Sol diẹ sii si apamọwọ rẹ tabi dinku soso naa ti o \\ 'tun n firanṣẹ",
   "introducing_cake_pay": "Ẹ bá Cake Pay!",
   "invalid_input": "Iṣawọle ti ko tọ",
+  "invalid_password": "Ọrọ igbaniwọle ti ko wulo",
   "invoice_details": "Iru awọn ẹya ọrọ",
   "is_percentage": "jẹ́",
   "last_30_days": "Ọ̀jọ̀ mọ́gbọ̀n tó kọjà",
@@ -500,6 +502,8 @@
   "rename": "Pààrọ̀ orúkọ",
   "rep_warning": "Ikilọ aṣoju",
   "rep_warning_sub": "Aṣoju rẹ ko han lati wa ni iduro to dara. Fọwọ ba ibi lati yan ọkan titun kan",
+  "repeat_wallet_password": "Tun ọrọ igbaniwọle apamọwọ naa",
+  "repeated_password_is_incorrect": "Ọrọ igbaniwọle tun jẹ aṣiṣe. Jọwọ tun ọrọigbaniwọle apamọwọ lẹẹkansi.",
   "require_for_adding_contacts": "Beere fun fifi awọn olubasọrọ kun",
   "require_for_all_security_and_backup_settings": "Beere fun gbogbo aabo ati awọn eto afẹyinti",
   "require_for_assessing_wallet": "Beere fun wiwọle si apamọwọ",
@@ -798,6 +802,7 @@
   "unavailable_balance_description": "Iwontunws.funfun ti ko si: Lapapọ yii pẹlu awọn owo ti o wa ni titiipa ni awọn iṣowo isunmọ ati awọn ti o ti didi ni itara ninu awọn eto iṣakoso owo rẹ. Awọn iwọntunwọnsi titiipa yoo wa ni kete ti awọn iṣowo oniwun wọn ba ti pari, lakoko ti awọn iwọntunwọnsi tio tutunini ko ni iraye si fun awọn iṣowo titi iwọ o fi pinnu lati mu wọn kuro.",
   "unconfirmed": "A kò tí ì jẹ́rìí ẹ̀",
   "understand": "Ó ye mi",
+  "unlock": "Sisalẹ",
   "unmatched_currencies": "Irú owó ti àpamọ́wọ́ yín kì í ṣe irú ti yíya àmì ìlujá",
   "unspent_change": "Yipada",
   "unspent_coins_details_title": "Àwọn owó ẹyọ t'á kò tí ì san",
@@ -839,6 +844,7 @@
   "wallet_menu": "Mẹ́nù",
   "wallet_name": "Orúkọ àpamọ́wọ́",
   "wallet_name_exists": "Ẹ ti ní àpamọ́wọ́ pẹ̀lú orúkọ̀ yẹn. Ẹ jọ̀wọ́ yàn orúkọ̀ tó yàtọ̀ tàbí pààrọ̀ orúkọ ti àpamọ́wọ́ tẹ́lẹ̀.",
+  "wallet_password_is_empty": "Ọrọ igbaniwọle apamọwọ ti ṣofo. Ọrọ igbaniwọle apamọwọ ko yẹ ki o ṣofo",
   "wallet_recovery_height": "Iga Imularada",
   "wallet_restoration_store_incorrect_seed_length": "Gígùn hóró tí a máa ń lò kọ́ ni èyí",
   "wallet_seed": "Hóró àpamọ́wọ́",
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index 89eca2073..5db53a423 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -236,6 +236,7 @@
   "enter_code": "输入代码",
   "enter_seed_phrase": "输入您的种子短语",
   "enter_totp_code": "请输入 TOTP 代码。",
+  "enter_wallet_password": "输入钱包密码",
   "enter_your_note": "输入您的笔记...",
   "enter_your_pin": "输入密码",
   "enter_your_pin_again": "再次输入您的PIN码",
@@ -340,6 +341,7 @@
   "insufficientFundsForRentError": "您没有足够的溶胶来支付该帐户的交易费和租金。请在钱包中添加更多溶胶或减少您发送的溶胶量",
   "introducing_cake_pay": "介绍 Cake Pay!",
   "invalid_input": "输入无效",
+  "invalid_password": "无效的密码",
   "invoice_details": "发票明细",
   "is_percentage": "是",
   "last_30_days": "过去 30 天",
@@ -499,6 +501,8 @@
   "rename": "重命名",
   "rep_warning": "代表性警告",
   "rep_warning_sub": "您的代表似乎并不信誉良好。点击这里选择一个新的",
+  "repeat_wallet_password": "重复钱包密码",
+  "repeated_password_is_incorrect": "重复密码不正确。请再次重复钱包密码。",
   "require_for_adding_contacts": "需要添加联系人",
   "require_for_all_security_and_backup_settings": "需要所有安全和备份设置",
   "require_for_assessing_wallet": "需要访问钱包",
@@ -797,6 +801,7 @@
   "unavailable_balance_description": "不可用余额:此总额包括锁定在待处理交易中的资金以及您在硬币控制设置中主动冻结的资金。一旦各自的交易完成,锁定的余额将变得可用,而冻结的余额在您决定解冻之前仍然无法进行交易。",
   "unconfirmed": "未确认余额",
   "understand": "我已知晓",
+  "unlock": "开锁",
   "unmatched_currencies": "您当前钱包的货币与扫描的 QR 的货币不匹配",
   "unspent_change": "改变",
   "unspent_coins_details_title": "未使用代幣詳情",
@@ -838,6 +843,7 @@
   "wallet_menu": "钱包菜单",
   "wallet_name": "钱包名称",
   "wallet_name_exists": "同名的钱包已经存在",
+  "wallet_password_is_empty": "钱包密码为空。钱包密码不应为空",
   "wallet_recovery_height": "恢复高度",
   "wallet_restoration_store_incorrect_seed_length": "种子长度错误",
   "wallet_seed": "钱包种子",
diff --git a/scripts/android/shell.nix b/scripts/android/shell.nix
deleted file mode 100644
index b89da09c0..000000000
--- a/scripts/android/shell.nix
+++ /dev/null
@@ -1,16 +0,0 @@
-{ pkgs ? import <nixpkgs> {} }:
-
-pkgs.mkShell {
-  buildInputs = [
-    pkgs.curl
-    pkgs.unzip
-    pkgs.automake
-    pkgs.file
-    pkgs.pkg-config
-    pkgs.git
-    pkgs.libtool
-    pkgs.ncurses5
-    pkgs.openjdk8
-    pkgs.clang
-  ];
-}
diff --git a/scripts/ios/gen_framework.sh b/scripts/ios/gen_framework.sh
index 950a7afe5..5c9bcd228 100755
--- a/scripts/ios/gen_framework.sh
+++ b/scripts/ios/gen_framework.sh
@@ -28,4 +28,4 @@ fi
 cd $FRWK_DIR # go to iOS framework dir
 lipo -create $DYLIB_LINK_PATH -output WowneroWallet
 
-echo "Generated ${FRWK_DIR}"
\ No newline at end of file
+echo "Generated ${FRWK_DIR}"
diff --git a/scripts/linux/app_config.sh b/scripts/linux/app_config.sh
new file mode 100755
index 000000000..b4ca1423c
--- /dev/null
+++ b/scripts/linux/app_config.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+CAKEWALLET="cakewallet"
+DIR=`pwd`
+
+if [ -z "$APP_LINUX_TYPE" ]; then
+        echo "Please set APP_LINUX_TYPE"
+        exit 1
+fi
+
+cd ../.. # go to root
+CONFIG_ARGS=""
+
+case $APP_LINUX_TYPE in
+        $CAKEWALLET)
+		CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --excludeFlutterSecureStorage";;
+esac
+
+cp -rf pubspec_description.yaml pubspec.yaml
+flutter pub get
+flutter pub run tool/generate_pubspec.dart
+flutter pub get
+flutter packages pub run tool/configure.dart $CONFIG_ARGS
+sed -i '0,/version: 0.0.0/s//version: '"${APP_LINUX_VERSION}"'+'"${APP_LINUX_BUILD_NUMBER}"'/' pubspec.yaml
+cd $DIR
diff --git a/scripts/linux/app_env.fish b/scripts/linux/app_env.fish
new file mode 100644
index 000000000..8dec90ce3
--- /dev/null
+++ b/scripts/linux/app_env.fish
@@ -0,0 +1,35 @@
+#!/usr/bin/env fish
+
+set -g APP_LINUX_NAME ""
+set -g APP_LINUX_VERSION ""
+set -g APP_LINUX_BUILD_NUMBER ""
+
+set -g CAKEWALLET "cakewallet"
+
+set -g TYPES $CAKEWALLET
+set -g APP_LINUX_TYPE $CAKEWALLET
+
+if test -n "$argv[1]"
+    set -g APP_LINUX_TYPE $argv[1]
+end
+
+set -g CAKEWALLET_NAME "Cake Wallet"
+set -g CAKEWALLET_VERSION "1.9.0"
+set -g CAKEWALLET_BUILD_NUMBER 29
+
+if not contains -- $APP_LINUX_TYPE $TYPES
+    echo "Wrong app type."
+    exit 1
+end
+
+switch $APP_LINUX_TYPE
+    case $CAKEWALLET
+        set -g APP_LINUX_NAME $CAKEWALLET_NAME
+        set -g APP_LINUX_VERSION $CAKEWALLET_VERSION
+        set -g APP_LINUX_BUILD_NUMBER $CAKEWALLET_BUILD_NUMBER
+end
+
+export APP_LINUX_TYPE
+export APP_LINUX_NAME
+export APP_LINUX_VERSION
+export APP_LINUX_BUILD_NUMBER
diff --git a/scripts/linux/app_env.sh b/scripts/linux/app_env.sh
new file mode 100755
index 000000000..729cf376b
--- /dev/null
+++ b/scripts/linux/app_env.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+APP_LINUX_NAME=""
+APP_LINUX_VERSION=""
+APP_LINUX_BUILD_VERSION=""
+
+CAKEWALLET="cakewallet"
+
+TYPES=($CAKEWALLET)
+APP_LINUX_TYPE=$CAKEWALLET
+
+if [ -n "$1" ]; then
+	APP_LINUX_TYPE=$1
+fi
+
+CAKEWALLET_NAME="Cake Wallet"
+CAKEWALLET_VERSION="1.9.2"
+CAKEWALLET_BUILD_NUMBER=30
+
+if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
+    echo "Wrong app type."
+    exit 1
+fi
+
+case $APP_LINUX_TYPE in
+	$CAKEWALLET)
+		APP_LINUX_NAME=$CAKEWALLET_NAME
+		APP_LINUX_VERSION=$CAKEWALLET_VERSION
+		APP_LINUX_BUILD_NUMBER=$CAKEWALLET_BUILD_NUMBER;;
+esac
+
+export APP_LINUX_TYPE
+export APP_LINUX_NAME
+export APP_LINUX_VERSION
+export APP_LINUX_BUILD_NUMBER
diff --git a/scripts/linux/build_all.sh b/scripts/linux/build_all.sh
new file mode 100755
index 000000000..e2bdb081c
--- /dev/null
+++ b/scripts/linux/build_all.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+./build_monero_all.sh
diff --git a/scripts/linux/build_boost.sh b/scripts/linux/build_boost.sh
new file mode 100755
index 000000000..3ac613e7c
--- /dev/null
+++ b/scripts/linux/build_boost.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+set -e
+
+. ./config.sh
+
+BOOST_SRC_DIR=${EXTERNAL_LINUX_SOURCE_DIR}/boost_1_82_0
+BOOST_FILENAME=boost_1_82_0.tar.bz2
+BOOST_VERSION=1.82.0
+BOOST_FILE_PATH=${EXTERNAL_LINUX_SOURCE_DIR}/$BOOST_FILENAME
+BOOST_SHA256="a6e1ab9b0860e6a2881dd7b21fe9f737a095e5f33a3a874afc6a345228597ee6"
+
+if [ ! -e "$BOOST_FILE_PATH" ]; then
+	curl -L http://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION}/${BOOST_FILENAME} > $BOOST_FILE_PATH
+fi
+
+echo $BOOST_SHA256 $BOOST_FILE_PATH | sha256sum -c - || exit 1
+
+cd $EXTERNAL_LINUX_SOURCE_DIR
+rm -rf $BOOST_SRC_DIR
+tar -xvf $BOOST_FILE_PATH -C $EXTERNAL_LINUX_SOURCE_DIR
+cd $BOOST_SRC_DIR
+./bootstrap.sh --prefix=${EXTERNAL_LINUX_DIR} 
+./b2 cxxflags=-fPIC cflags=-fPIC \
+     --with-chrono \
+     --with-date_time \
+     --with-filesystem \
+     --with-program_options \
+     --with-regex \
+     --with-serialization \
+     --with-system \
+     --with-thread \
+     --with-locale \
+    link=static \
+    install
+ 
diff --git a/scripts/linux/build_expat.sh b/scripts/linux/build_expat.sh
new file mode 100755
index 000000000..a45852d1d
--- /dev/null
+++ b/scripts/linux/build_expat.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+set -e
+
+. ./config.sh
+
+
+EXPAT_VERSION=R_2_4_8
+EXPAT_HASH="3bab6c09bbe8bf42d84b81563ddbcf4cca4be838"
+EXPAT_SRC_DIR=${EXTERNAL_LINUX_SOURCE_DIR}/libexpat
+
+git clone https://github.com/libexpat/libexpat.git -b ${EXPAT_VERSION} ${EXPAT_SRC_DIR}
+cd $EXPAT_SRC_DIR
+test `git rev-parse HEAD` = ${EXPAT_HASH} || exit 1
+cd $EXPAT_SRC_DIR/expat
+
+./buildconf.sh
+./configure --enable-static --disable-shared --prefix=${EXTERNAL_LINUX_DIR}
+make
+make install
diff --git a/scripts/linux/build_iconv.sh b/scripts/linux/build_iconv.sh
new file mode 100755
index 000000000..29812cdb3
--- /dev/null
+++ b/scripts/linux/build_iconv.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+set -e
+
+. ./config.sh
+
+export ICONV_FILENAME=libiconv-1.16.tar.gz
+export ICONV_FILE_PATH=${EXTERNAL_LINUX_SOURCE_DIR}/${ICONV_FILENAME}
+export ICONV_SRC_DIR=${EXTERNAL_LINUX_SOURCE_DIR}/libiconv-1.16
+ICONV_SHA256="e6a1b1b589654277ee790cce3734f07876ac4ccfaecbee8afa0b649cf529cc04"
+
+curl http://ftp.gnu.org/pub/gnu/libiconv/${ICONV_FILENAME} -o $ICONV_FILE_PATH
+echo $ICONV_SHA256 $ICONV_FILE_PATH | sha256sum -c - || exit 1
+
+cd $EXTERNAL_LINUX_SOURCE_DIR
+rm -rf $ICONV_SRC_DIR
+tar -xzf $ICONV_FILE_PATH -C $EXTERNAL_LINUX_SOURCE_DIR
+cd $ICONV_SRC_DIR
+
+./configure --prefix=${EXTERNAL_LINUX_DIR}
+make
+make install
diff --git a/scripts/linux/build_monero.sh b/scripts/linux/build_monero.sh
new file mode 100755
index 000000000..cbefec08e
--- /dev/null
+++ b/scripts/linux/build_monero.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+. ./config.sh
+
+MONERO_URL="https://github.com/cake-tech/monero.git"
+MONERO_DIR_PATH="${EXTERNAL_LINUX_SOURCE_DIR}/monero"
+MONERO_VERSION=release-v0.18.3.2
+PREFIX=${EXTERNAL_LINUX_DIR}
+DEST_LIB_DIR=${EXTERNAL_LINUX_LIB_DIR}/monero
+DEST_INCLUDE_DIR=${EXTERNAL_LINUX_INCLUDE_DIR}/monero
+
+echo "Cloning monero from - $MONERO_URL to - $MONERO_DIR_PATH"
+git clone $MONERO_URL $MONERO_DIR_PATH
+cd $MONERO_DIR_PATH
+git checkout $MONERO_VERSION
+git submodule update --init --force
+rm -rf ./build/release
+mkdir -p ./build/release
+cd ./build/release
+
+mkdir -p $DEST_LIB_DIR
+mkdir -p $DEST_INCLUDE_DIR
+
+echo "Building LINUX"
+export CMAKE_INCLUDE_PATH="${PREFIX}/include"
+export CMAKE_LIBRARY_PATH="${PREFIX}/lib"
+
+cmake -DSTATIC=ON \
+	-DBUILD_GUI_DEPS=ON \
+	-DUNBOUND_INCLUDE_DIR=${EXTERNAL_LINUX_INCLUDE_DIR} \
+	-DCMAKE_INSTALL_PREFIX=${PREFIX} \
+	  -DUSE_DEVICE_TREZOR=OFF \
+    -DMANUAL_SUBMODULES=1 \
+	../..
+
+make wallet_api -j$(($(nproc) / 2))
+
+find . -path ./lib -prune -o -name '*.a' -exec cp '{}' lib \;
+cp -r ./lib/* $DEST_LIB_DIR
+cp ../../src/wallet/api/wallet2_api.h $DEST_INCLUDE_DIR
diff --git a/scripts/linux/build_monero_all.sh b/scripts/linux/build_monero_all.sh
new file mode 100755
index 000000000..5dc512527
--- /dev/null
+++ b/scripts/linux/build_monero_all.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+
+. ./config.sh
+
+
+set -x -e
+
+cd "$(dirname "$0")"
+
+NPROC="-j$(nproc)"
+
+../prepare_moneroc.sh
+
+for COIN in monero wownero;
+do
+    pushd ../monero_c
+        ./build_single.sh ${COIN} $(gcc -dumpmachine) $NPROC
+    popd
+    unxz -f ../monero_c/release/${COIN}/$(gcc -dumpmachine)_libwallet2_api_c.so.xz
+done
diff --git a/scripts/linux/build_openssl.sh b/scripts/linux/build_openssl.sh
new file mode 100755
index 000000000..205cf7abf
--- /dev/null
+++ b/scripts/linux/build_openssl.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+set -e
+
+. ./config.sh
+
+OPENSSL_FILENAME=openssl-1.1.1q.tar.gz
+OPENSSL_FILE_PATH=${EXTERNAL_LINUX_SOURCE_DIR}/${OPENSSL_FILENAME}
+OPENSSL_SRC_DIR=${EXTERNAL_LINUX_SOURCE_DIR}/openssl-1.1.1q
+OPENSSL_SHA256="d7939ce614029cdff0b6c20f0e2e5703158a489a72b2507b8bd51bf8c8fd10ca"
+
+curl https://www.openssl.org/source/${OPENSSL_FILENAME} -o ${OPENSSL_FILE_PATH}
+
+rm -rf $OPENSSL_SRC_DIR
+tar -xzf $OPENSSL_FILE_PATH -C $EXTERNAL_LINUX_SOURCE_DIR
+cd $OPENSSL_SRC_DIR
+export CFLAGS=-fPIC
+./config -fPIC shared --prefix=${EXTERNAL_LINUX_DIR}
+make install
diff --git a/scripts/linux/build_sodium.sh b/scripts/linux/build_sodium.sh
new file mode 100755
index 000000000..3a6f6adf9
--- /dev/null
+++ b/scripts/linux/build_sodium.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+set -e
+
+. ./config.sh
+
+SODIUM_PATH="${EXTERNAL_LINUX_SOURCE_DIR}/libsodium"
+SODIUM_URL="https://github.com/jedisct1/libsodium.git"
+
+echo "============================ SODIUM ============================"
+
+echo "Cloning SODIUM from - $SODIUM_URL"
+git clone $SODIUM_URL $SODIUM_PATH --branch stable
+cd $SODIUM_PATH
+
+
+./configure --prefix=${EXTERNAL_LINUX_DIR}
+make
+make install
diff --git a/scripts/linux/build_unbound.sh b/scripts/linux/build_unbound.sh
new file mode 100755
index 000000000..1ae917da9
--- /dev/null
+++ b/scripts/linux/build_unbound.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+set -e
+
+. ./config.sh
+
+UNBOUND_VERSION=release-1.16.2
+UNBOUND_HASH="cbed768b8ff9bfcf11089a5f1699b7e5707f1ea5"
+UNBOUND_DIR_PATH="${EXTERNAL_LINUX_SOURCE_DIR}/unbound-1.16.2"
+
+echo "============================ Unbound ============================"
+rm -rf ${UNBOUND_DIR_PATH}
+git clone https://github.com/NLnetLabs/unbound.git -b ${UNBOUND_VERSION} ${UNBOUND_DIR_PATH}
+cd $UNBOUND_DIR_PATH
+test `git rev-parse HEAD` = ${UNBOUND_HASH} || exit 1
+
+export CFLAGS=-fPIC
+./configure cxxflags=-fPIC cflags=-fPIC \
+	--prefix="${EXTERNAL_LINUX_DIR}" \
+	--with-ssl="${EXTERNAL_LINUX_DIR}" \
+	--with-libexpat="${EXTERNAL_LINUX_DIR}" \
+	--enable-static \
+	--disable-flto
+make
+make install
diff --git a/scripts/linux/build_zmq.sh b/scripts/linux/build_zmq.sh
new file mode 100755
index 000000000..f6980e40d
--- /dev/null
+++ b/scripts/linux/build_zmq.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+. ./config.sh
+
+ZMQ_PATH="${EXTERNAL_LINUX_SOURCE_DIR}/libzmq"
+ZMQ_URL="https://github.com/zeromq/libzmq.git"
+
+echo "============================ ZMQ ============================"
+
+echo "Cloning ZMQ from - $ZMQ_URL"
+git clone $ZMQ_URL $ZMQ_PATH
+cd $ZMQ_PATH
+mkdir cmake-build
+cd cmake-build
+cmake .. -DCMAKE_INSTALL_PREFIX="${EXTERNAL_LINUX_DIR}"
+make
+make install
diff --git a/scripts/linux/cakewallet.sh b/scripts/linux/cakewallet.sh
new file mode 100755
index 000000000..89c7a7ef0
--- /dev/null
+++ b/scripts/linux/cakewallet.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+. ./app_env.sh "cakewallet"
+. ./app_config.sh
diff --git a/scripts/linux/config.sh b/scripts/linux/config.sh
new file mode 100755
index 000000000..3fbdf349e
--- /dev/null
+++ b/scripts/linux/config.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+export LINUX_SCRIPTS_DIR=`pwd`
+export CW_ROOT=${LINUX_SCRIPTS_DIR}/../..
+export EXTERNAL_DIR=${CW_ROOT}/cw_shared_external/ios/External
+export EXTERNAL_LINUX_DIR=${EXTERNAL_DIR}/linux
+export EXTERNAL_LINUX_SOURCE_DIR=${EXTERNAL_LINUX_DIR}/sources
+export EXTERNAL_LINUX_LIB_DIR=${EXTERNAL_LINUX_DIR}/lib
+export EXTERNAL_LINUX_INCLUDE_DIR=${EXTERNAL_LINUX_DIR}/include
+
+mkdir -p $EXTERNAL_LINUX_LIB_DIR
+mkdir -p $EXTERNAL_LINUX_INCLUDE_DIR
+mkdir -p $EXTERNAL_LINUX_SOURCE_DIR
diff --git a/scripts/linux/gcc10.nix b/scripts/linux/gcc10.nix
new file mode 100644
index 000000000..dfc01986a
--- /dev/null
+++ b/scripts/linux/gcc10.nix
@@ -0,0 +1,12 @@
+with import <nixpkgs> {};
+gcc10Stdenv.mkDerivation {
+  name="gcc10-stdenv";
+  buildInputs = [
+    pkgs.cmake
+    pkgs.pkg-config
+    pkgs.autoconf
+    pkgs.libtool
+    pkgs.expat
+  ];
+}
+
diff --git a/scripts/linux/setup.sh b/scripts/linux/setup.sh
new file mode 100755
index 000000000..a323cf027
--- /dev/null
+++ b/scripts/linux/setup.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+. ./config.sh
+
+CW_EXTERNAL_DIR=${CW_ROOT}/cw_monero/ios/External/linux
+CW_EXTERNAL_DIR_INCLUDE=${CW_EXTERNAL_DIR}/include
+
+mkdir -p $CW_EXTERNAL_DIR_INCLUDE
+cp $EXTERNAL_LINUX_INCLUDE_DIR/monero/wallet2_api.h $CW_EXTERNAL_DIR_INCLUDE
diff --git a/tool/configure.dart b/tool/configure.dart
index c37946476..a0104c34e 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -150,7 +150,7 @@ abstract class Bitcoin {
     String? passphrase,
   });
   WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo});
-  WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo});
+  WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password});
   WalletCredentials createBitcoinHardwareWalletCredentials({required String name, required HardwareAccountData accountData, WalletInfo? walletInfo});
   List<String> getWordList();
   Map<String, String> getWalletKeys(Object wallet);
@@ -179,8 +179,8 @@ abstract class Bitcoin {
   List<Unspent> getUnspents(Object wallet);
   Future<void> updateUnspents(Object wallet);
   WalletService createBitcoinWalletService(
-      Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan);
-  WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource);
+      Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan, bool isDirect);
+  WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
   TransactionPriority getBitcoinTransactionPriorityMedium();
   TransactionPriority getBitcoinTransactionPriorityCustom();
   TransactionPriority getLitecoinTransactionPriorityMedium();
@@ -369,7 +369,7 @@ abstract class Monero {
     required String language,
     required int height});
   WalletCredentials createMoneroRestoreWalletFromSeedCredentials({required String name, required String password, required int height, required String mnemonic});
-  WalletCredentials createMoneroNewWalletCredentials({required String name, required String language, required bool isPolyseed, String password});
+  WalletCredentials createMoneroNewWalletCredentials({required String name, required String language, required bool isPolyseed, String? password});
   Map<String, String> getKeys(Object wallet);
   int? getRestoreHeight(Object wallet);
   Object createMoneroTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority});
@@ -734,7 +734,7 @@ abstract class Haven {
       required String language,
       required int height});
   WalletCredentials createHavenRestoreWalletFromSeedCredentials({required String name, required String password, required int height, required String mnemonic});
-  WalletCredentials createHavenNewWalletCredentials({required String name, required String language, String password});
+  WalletCredentials createHavenNewWalletCredentials({required String name, required String language, String? password});
   Map<String, String> getKeys(Object wallet);
   Object createHavenTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority, required String assetType});
   String formatterMoneroAmountToString({required int amount});
@@ -828,8 +828,8 @@ import 'package:eth_sig_util/util/utils.dart';
   const ethereumContent = """
 abstract class Ethereum {
   List<String> getEthereumWordList(String language);
-  WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource);
-  WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo});
+  WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
+  WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password});
   WalletCredentials createEthereumRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
   WalletCredentials createEthereumRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
   WalletCredentials createEthereumHardwareWalletCredentials({required String name, required HardwareAccountData hwAccountData, WalletInfo? walletInfo});
@@ -932,8 +932,8 @@ import 'package:eth_sig_util/util/utils.dart';
   const polygonContent = """
 abstract class Polygon {
   List<String> getPolygonWordList(String language);
-  WalletService createPolygonWalletService(Box<WalletInfo> walletInfoSource);
-  WalletCredentials createPolygonNewWalletCredentials({required String name, WalletInfo? walletInfo});
+  WalletService createPolygonWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
+  WalletCredentials createPolygonNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password});
   WalletCredentials createPolygonRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
   WalletCredentials createPolygonRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
   WalletCredentials createPolygonHardwareWalletCredentials({required String name, required HardwareAccountData hwAccountData, WalletInfo? walletInfo});
@@ -1017,10 +1017,10 @@ abstract class BitcoinCash {
   String getCashAddrFormat(String address);
 
   WalletService createBitcoinCashWalletService(
-      Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource);
+      Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
 
   WalletCredentials createBitcoinCashNewWalletCredentials(
-      {required String name, WalletInfo? walletInfo});
+      {required String name, WalletInfo? walletInfo, String? password});
 
   WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials(
       {required String name, required String mnemonic, required String password});
@@ -1097,11 +1097,11 @@ abstract class Nano {
 
   void setCurrentAccount(Object wallet, int id, String label, String? balance);
 
-  WalletService createNanoWalletService(Box<WalletInfo> walletInfoSource);
+  WalletService createNanoWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
 
   WalletCredentials createNanoNewWalletCredentials({
     required String name,
-    String password,
+    String? password,
   });
   
   WalletCredentials createNanoRestoreWalletFromSeedCredentials({
@@ -1215,9 +1215,9 @@ import 'package:cw_solana/solana_wallet_creation_credentials.dart';
   const solanaContent = """
 abstract class Solana {
   List<String> getSolanaWordList(String language);
-  WalletService createSolanaWalletService(Box<WalletInfo> walletInfoSource);
+  WalletService createSolanaWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
   WalletCredentials createSolanaNewWalletCredentials(
-      {required String name, WalletInfo? walletInfo});
+      {required String name, WalletInfo? walletInfo, String? password});
   WalletCredentials createSolanaRestoreWalletFromSeedCredentials(
       {required String name, required String mnemonic, required String password});
   WalletCredentials createSolanaRestoreWalletFromPrivateKey(
@@ -1302,8 +1302,8 @@ import 'package:cw_tron/tron_wallet_service.dart';
   const tronContent = """
 abstract class Tron {
   List<String> getTronWordList(String language);
-  WalletService createTronWalletService(Box<WalletInfo> walletInfoSource);
-  WalletCredentials createTronNewWalletCredentials({required String name, WalletInfo? walletInfo});
+  WalletService createTronWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
+  WalletCredentials createTronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password});
   WalletCredentials createTronRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
   WalletCredentials createTronRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
   String getAddress(WalletBase wallet);

From 0491ad9ee24175240556ad4bb63634b52d78f0b2 Mon Sep 17 00:00:00 2001
From: tuxsudo <tuxsudo@tux.pizza>
Date: Tue, 13 Aug 2024 07:15:47 -0400
Subject: [PATCH 28/81] Update support links (#1595)

* Update support links list, add proper support for light/dark icons, update provider icons

* Update trocador icon

* Update variable

* trial fix for android build

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
---
 android/build.gradle                          |   4 +-
 assets/images/dfx_dark.png                    | Bin 3515 -> 10166 bytes
 assets/images/dfx_light.png                   | Bin 3502 -> 12024 bytes
 assets/images/moonpay.png                     | Bin 1392 -> 16575 bytes
 assets/images/moonpay_dark.png                | Bin 23214 -> 14212 bytes
 assets/images/moonpay_light.png               | Bin 20800 -> 13866 bytes
 assets/images/trocador.png                    | Bin 10417 -> 28127 bytes
 cw_haven/android/build.gradle                 |   4 +-
 cw_shared_external/android/build.gradle       |   4 +-
 .../support_other_links_page.dart             |  10 ++--
 lib/view_model/settings/link_list_item.dart   |   2 +
 lib/view_model/support_view_model.dart        |  47 ++++++++++++------
 12 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/android/build.gradle b/android/build.gradle
index aa9f5005d..7ddb75179 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -2,7 +2,7 @@ buildscript {
     ext.kotlin_version = '1.8.21'
     repositories {
         google()
-        jcenter()
+        mavenCentral()
     }
 
     dependencies {
@@ -15,7 +15,7 @@ buildscript {
 allprojects {
     repositories {
         google()
-        jcenter()
+        mavenCentral()
     }
 }
 
diff --git a/assets/images/dfx_dark.png b/assets/images/dfx_dark.png
index cbba87372adad4c0c3f5d14dec996aacea01ee88..6ac112eae3be1f20e7195d60fd0bb8ef357e2d70 100644
GIT binary patch
literal 10166
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
MrlCfYn#1e=1A%Q7*8l(j

literal 3515
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

diff --git a/assets/images/dfx_light.png b/assets/images/dfx_light.png
index e4836be3ebecc08d3d0dee8fe3af672c511c7c2f..a045d3e681c7f9648178a5a887652ba7de507105 100644
GIT binary patch
literal 12024
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
Y>6`U?A5T+(s&(MuJ#ExSHS6&I13;;u^Z)<=

literal 3502
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

diff --git a/assets/images/moonpay.png b/assets/images/moonpay.png
index b02af6c00d107b4f68d30a5d5d6b7ee86c81f509..088c93d592cdcd5dbf0f55c05205d410903f7329 100644
GIT binary patch
literal 16575
zcmbVzc_5V0_xBx>F=d^yOx93I!pKfSwn|YdTUmz664`e#Wh%RrE$ft|EFnwDHbyAx
zL?UG=ds(t)fA6F3_kDlwKkpy!A8DTZ+<Wf1=bn4cx#xVIuyY1_th;!30RUJ}ozyl0
z08K>xVKK1fCQGq8{BNi0Niz=snD-$6P#`%K4;xV)MtUc}t2X`#_^`uH^Q<NSMKR3l
zL`DEKE}qiXyy%OX>a*~+=z2W9VJCG8L-cTzwaNPRDvn#*0riwoMv__rWOWHa9wC8`
z+*|gFK4(-wnz9%}x#QduX|HOJ*Oo<QRgG384jUf%w%T)JYH@ZgDwb$_=x{b0_v(yY
zo85Cbb^myWy`7hX12L{++Of?q&fWa%%fIa*>M176!6##azi(xk-kKU9)Grm+C^)Nc
zmbwkk2`OjKF7Py-e>U~{NW<7te}6CDq()ch8Kk!4962}M|Ff=C<lqhQv!agbujkCq
zWZqcKpFcF}a$|MCme+QKUAfVFFY{%F`~Ynzh!9W0*W^4N+>N!O_~yj~@|T@wvag?a
znrbvVol>7^^SjsAPu2ba4g;wB)+g56RyWDHhx%u{T?M-2T8xSwH_y#<y`S9bx9Ddv
z*Ce9=T|XoLn7RJSC;!v+LfLzsmTu~Gr|_R?c9*JYooE?N^l5Wq^bn>2Fn(8TxtzOW
zn6|*KzT3j3L~Wz}y20$!qELH38?PwRA@6YIv~*w1Iqlh4hi>sK&x%xok8RWGRnDLE
zsu0f8=A3@U*Kk<M`|)43>R0xWNK%GuYKUEokmr|oGWUu((w9E`^G1Z)bv=YJ^RCao
zYaidw(3X;Z<`{o$zQjVe`dwi~p~J?;L?{6O^TyA)i#Owo7UEeW#1IDTqeA}XO#6>4
zQqUdO_l|T=M+?MY(ZKrEQVhRTe@&9n>ebczxtcsvLYFvg^^g%s5n{_#M(J1FhYJ<o
z_uvq!ya%c=nvqra;6RE@M!~Va`=5U2unG}wU_*rPqOX<~HFy2(y!=I*No5fhK<e%B
z{t(e|z4xpT`$n1!BKDR`%hlcq-Z_8YasGLI+2PGwmCyJ+P{&*10<8EyS;rg-htpjD
z*<^1gFFleHE$DvcTj$FjCavUfE))RSo-1!ut%kGaY8dfih2|T@7dB)$(Zt=5aM-Of
zcNgc?mz(($Z{lm%m8vw))SrP&DaAUvpVwZsB*|!nB!xeQvU5E$9rWozzrnxPuN~)!
zmdSzARC^71uC>kL_yC?vJ7l1*=uD7|)kMSGw6uw0!%S2r6S7SOUasqf>o-?ByGSb&
zt+U#VI27>BYL-wH65v<ov~IC*i55eaz~;5`X1V6%`Tp>enIvyKSL{viTLDjpLIJ3>
z-rDT`8IsaD!zsO^<kIOki9#E5Zagz#VQ^Tw`&LBs#ITwSLbqr6Yg3gxO1E(`*#6ut
zUk(8gM99;@7D++2hp6LEH|`2_sn>nNK}lN=<}f8)h;}(LNU76>jfq<unqvJ$h-A^m
z&Ki*)6dC;Y#jm(n^rYI$FafH@Q~{;E2uGJy=HlxPzEaIAc>vPJoFsknab`m{ia=n9
zd}4ni6f#9Z;jCHC@@bucvST3w+ZVmuHprA<2VSfDIR`R_nizFZ<MIil$Aal1N3joe
z@bQ&rh6P*gsva9^h;H~hs-P+eX{1|wsLbx+>;+rCOWrMEP>;r+NMxpURm!adtxokH
zB3bcCYi|xp`?NXN^K+trMgjj0)0H$3V#0e?<kp1^%P?iaPB<tw>b&685w#=(s*OBJ
z@vCM3t%dthvjIc)4^H8MM$F`q<8SveutYn0jkR1>%p^i~DPlR77Gi&%0D6h@cbjYa
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
Q3^X{UW1#)&g!P^O1qB%bP5=M^

literal 1392
zcmeAS@N?(olHy`uVBq!ia0vp^;y^6H!3HD+Ytl-A6id3JuOkD)#(wTUiL5}rLb6AY
zF9SoB8UsT^3j@P1pisjL28L1t28LG&3=CE?fMyiT*%fF5l&DCJ@J#ddWzYh$IT%<O
zg&3HDEJh$?V3cA2nFeGrcri-D*+GmNP&G^p4DFc=EKoI3KpF%*fEc6)LNhI3f~yc;
zzzk<gfRxT~U3?NqaTa()7Bet#3xhBt!>l<#Nv5>Skcg59UmvUF{9L`nl>DSry^7od
zkS+$B3M(KpH?<^Dp&~aYuh^=>Rtc=a3djZt>nkaMm6T-LDn<APC^+XAr7D=|8R!`(
z*>Nc-DA*LGq*(>IxIwi8dA3R!B_#z``ugSN<$C4Ddih1^`i7R4mih)p`bI{&Koz>h
zm3bwJ6}oxF$`C_f=D4I5Cl_TFlw{`TDS*sPOv*1Uu~kw6Sp)|Vca~(PA#BPkhI$L=
zL4A;nzM-ChJ~nNs6`44+fn*@s!2W_*X9F_K%D*Tx73g4)v+N9Qz!sp0A)E(MACy|0
zpHm7_9-5a~VrK-^f+mcl3uL!dKxRd1PNYj_ZfagJ$R=Ym8-1)2ST#l<X*5CBh$Mlo
z(K$aSzbLpMF*z0FEwEikLQvH<`k<IViWx|>gGGVyZpUS#4^KmOT)on|-+^iNgQtsQ
zhzIZ0se8Sg9R*t7n_lc_T`-M}MS9~UCy_O}wG11#Y~Q$L(<javM%Ar1ezBA_b@g_*
z<pg!sYbY9Cf3LGStvG)j=aN$g3e(ch&71r8q-j^%)kluf{*zKzc-LR<dTb#Xa`~+J
zL%y{J&%@s+d@-KD5xea}@rUgP)K^TXR&IZt%r3;p+WaWO(zHRpIs3ueDGO4z{yC;7
z>hdb>%CV`(^O<k5|0oNbv?gk8z?qqAbpJcZE#1c^*0>|I!11l9{%%(Ngec}WY&JVI
zx}u)l=5yTt)c2A1YqgS4w%rFz+wL=1^>IZ^61tbUCA3-PsI9=PGQ}56d*=$Il=<mZ
zUsJg&`S@z*_BMW|^{%hX?rrz;?kRnFv#<9-SW7{k@NUj%&CI9|J@dEzluWGOx69$<
zbH#NXJx}+Etv3Cbx`8KU=3|fbW}KOa0;~UjObV{NvgL>Pkt#V$_5brG_s_9#UlhK;
z@7=+v6F0x#vUbs|zO`&N_MZ=OS(o4EI^piH>}bil%*h3ZCmlEW=90{6Izz3jM{(!T
z59|kK$N6&1w^x4gSN5Z}!?)>6;&1ZpV9s1U(Sjv;Ry%+B`=xXK3xAG0acZM?Ilu9d
z*9nXsZv<c54mxW6aNcpnq+1ax-{%HvM+v{olzr^;JW-S}*Yb(Rwf&p^>+6e1p86qv
YGw80q^r|1g;*f#C)78&qol`;+0McLD?*IS*

diff --git a/assets/images/moonpay_dark.png b/assets/images/moonpay_dark.png
index 872e322e2a5f8ab6a639f5949dff97ffcd325e00..21de98eb4389c69e334e252a65652e2c79c06255 100644
GIT binary patch
literal 14212
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
NZZq3mcTA|K{ukylw<`bu

literal 23214
zcmZ^~1zeQf*DgFWjyi+E0D?*mUDDl1hjdGKcT0|-gi_KWASK<MBZ44}(k%i8DM;71
z@&CT(J>U7x_xO8$j&tw5@4eUB>sr@}iBMIRy@NxH1A##9$jeEoLm<$#tN#%<z&8c)
zEW;28{I0E}q^iB7tfaGpvzvyCskx=BrIV$bt+~3a1O&n#6{TfpL#lO8G`*>YnPw<t
ztf1h{-3y+CS_k#f(3zhXmNkxZkK!F_AIE;)n15?a$MyXz&z4d2-ec5<!ln47OZ^Y@
zly)VXuUK+wRde7W3`Zj;vhTj!N3J(<)wIMn+PC%39j|3<2mV-a-&(j8+xSR7X@M5@
zh`5|(_3Ls?&stZPpvQ-Rkvjn+EX>h~Oo?<*lJA`zGn?D!PYaU=4TqQ3>*cDl(D3;e
zQ>FZURLho-3&QSd!(jO1(_ZAH*%7i!$RPv0jQ_C?qVpgVcc*$dHI6gfSo#q|@#~AO
z+3=e`s1KgPZ@TZyMho*4mN8QGOMm7qNmHi&+7@yeR4+Ym-!&Ve5>vw-aBuNi<3Tc$
zThg~MRF>AtoJV*Ct8Gm;>e8~w7Ws!7V%XC9!VTw-XqUN`Un}WPkD_9}Q7rTOu~ci+
zVu+9D2jRX?TT*9r9L5<qo`LEax7TpVAxq0lES1j=smUvqY?;FQqjYR|dv?Q*8rO)d
zU;$e!*0zF^BLewWk&hp3z52e3r~O{EOQ$F^S>oK7rQzNuT9KDV8Mi%p**(wpPrP*A
zrXrT#2;9F#{F;_cyY7!fZ;(zMeIClV-Xkbxd9GJ!Hogy<)saQKsv1ubziA-aMVJ!x
zS^Pt&?*<{e34v5B8rRle-z4`v4)IT$cR%xO-W`oEZ7g;&9$!EjH0>^W*ME+(OB7sE
z?~D|8Zrf;4x84r)wJGr&L0Y*`k8#Me$-fCXBBhF7VSh-Oi+)4@S;OMB#i*ddU7nsK
zDtC*$rqMB9D7AVP->cSFKfND+y0ErLS*jiGR><N*O$|>C+xI0-IvEKDIO)7<k<rd-
znQ;H*L1Rs9$KugDGxpYP__EXZ$7H4P55A|jFKz~23tFGmZs1wx9?-@KXm-}`lHC(g
zwh+x{(Q+`Y$<5K@(LRAu^g{xgd|D9JH}ua|4nK>%vHyJdhJr5W`@)Low;}f|w=CDi
z;9kQeRySieV^<3IELpoT-)(ODt%}?#oHg5IwYe;br&BD#3>Gg$IzM(=D60G<d>M)~
zWqanuS3(eV->~IIPo=X(NkD1v{UY}br_!2<Z(^D<NjK>I3%+l2T~l`Y9!f1Q_K@m@
zW6QJ9&HVzeKt++63d|?>KMumz&HRo1xkc}Zb-IK+Tzu88w()1o?N@dG-R0M|Z)@w)
zen)=%yz<=)r-GA-==Lf$n_<2AXA9|Q!QHxKn^j1qA18mOv;4*R{aN39OZTiB{Act+
zhfnJTaF<H2jhx!_^9EagZ`+2HiWc}BsQb`&nJvQj$3s4T&`}{CE}>Z8*Y|OvU4Tsa
zw;5fYo<9rNyEe86Y0SR7c1i1VtJ{2{9{_}urLMe{k`jaod`3WEP<+TW@Cge3K*DSx
z@PD5n5IXQT1Om&3{r5M}wd`yE^ZDwbg+`JW7y`G|)b-F+dLn4<?8s_r;cRBf>f`8g
zH2@;)BM3e^T6&nGeH<N}+y#9^sQ!%*1fQ?IW}`y?8{%OvLZz#uik5VCvqbZ<va_;N
ziQ=HqXkj-CD?xQBng5y&{v|?X<Kf{V$j0XF?ak`V#p>*4&Bh@hAi&1X$;Qda0!Fa7
z`#O1;`mi{;Q~zg?|6WJR(%sz6*2Tlt*$I8MuBn-`r-uj?)zyps*MI-nr-!Z8|Gde`
z{lAU{4#;-(gpGrho$dcN&C<vA|7Y6OlmATncdq}uPWWmuK@~S!OR(XqZHaOS|9ipz
z>%0Hip77Nwf~vMYmJYg7wvLug?pJfT`FVxe{;yB|uQT=je`o%0PyTDBFx!=!{x`Y(
zM=Afl1zHis5oY^e8WzR*&3%mr0uhJEOFh=~fo{G<rf7~gl_w88xSoiX%yu>5C6*G8
zrDP%&`KcB%D)k-Gq?Yl<hi5HiC4>KM{K{yGO?l)qGwe47{6zC7o!#tmsB7U|cqq+0
zH8|l-)rTZohsj!bzsifti$%uB7xslqO6<0I&MsRf7K|%IO6$U?#UU_4f~h9=9}9hR
zxkjb7J8iE5`81xWPf=PgXqRdkBu4FbRLq#ii16A8L1C!EU@SS|3gs=hx~w>?H7i3j
z&*;qTz^`ZQ1H<4q@5Bwu?jQ@X&C`DTjl+HUU<f=CC7$vMYpQdCkPDveUq694EGmTx
zy^oPWlUHaIy&~k2czc>)5_C__@g5H50ls*O`IJq{1}-$h<yN9c;qu6{s^oTe1B67l
z>HFW$v|QVlpF0>ls#+-Dh9mN#A@tc}JigD!l2Ehf3nx^<avg_H*y7~;+T|x$)CZ9J
zFl62QB%L_=4;;1D#pn8rECF?xc-X@nt;+ql{$>s05A9CDlgpN6;qHg{zb*fGUhk(=
zO@VY8q}=f{lM$D2z%?U#Z)4_Al}<(31b2Xo7`nb(euAtMaghlY-$0@Vs+>Fj3Zf~U
zsJCUA)<TaIPn5Hit&=NH#|~7dzem!IsVEfkt;a(!Q+P`>L@jiR4Il8oXHvPOEh8hn
zB4)Z$A()r&dYcf#-Fm$JT>M`;By>xB@Eiq*X|!Fx$s{Wb-`vmbS?Thx$b+{Kj2rTi
z*2_g^<wUvJ-ZTiN7s!fwmirg)6Ek65xSQD=^E~&?f;Eg;%SbtI^RqJyP9+T%(sa+8
ze1NP{(iboomFYItT0z=9M#Gg&qU?O+{@``L=T58tC4)p2GC@O|ijRs6o;%<=L}>^s
zR>f06VdGSlMudwM{Cco+v%1&WMhNu4U(5(n?zK?imm0zzW^(dos3rnafSe*-^kx=i
zh~xbLq|FUOxZ4zdHH_<Oe1XU)<X8S<OsLO@k4AaIW-XVp2)ETTSmWv!;RrZ5>D_y5
zFBD@>Up<d{J*>8I8xPTy5*(F5ua_Xs7Ewi!LhcF{>mp%@UXy>lId9ft?O&B6VyF}>
z{sqyB4ht;fm!=w&qLa6uXF3gG*J*;j(QJb^y*g`>a($ko6eADDA*b9DFJ=GSMRLD#
zplPd<+{HD$i}ZL?5{I5GJaX&ix~ES!t>Yge4uyHnT!b&P(Tuc`7((#V6{&;SlRrgh
z-a*K{-ZW+P`*GwK`H^^IjUN8x$&!FTQ0_7{zAZVCqPt4rh<9j{gp2JU-Q#+lx2&4A
ziWBo+`k)<@sxYYj=5L)yZ^dli)nd2_&GBnU=Mxo%h+z2fErlcJ$VF`jeRVqg#}Jr|
zNy)PFy&xt`U_UPktqR5&yuN#y0dHzyHz+&mxThZi2ey|IY&daIwj898t)pXr^N>IV
zVyf&<ptF_@Zwhm}P<3skipOZaj59#>%3|RsM%^SdBPF}ECi>0buKsemlvz-W#U1-Z
z!I)XmOE3|IsDi@U@ha(?C{$aOVUEm3c<5NlVD_(goN$`no9q2Cgu`03^yNrYusA>b
zN%ngNBW6q>O9oRBZ6B~Fh6ZIsz2!FLVs>$RQ8+pbo56%u4Gv}zI2P(Ip&gkEVTCZ>
zNyl5`u5}})pzZauubG#;Sd8R-K?hJI{07F6^E;7r%gr_pVmedl6tEz>t!y?c(#<{9
z6|?Lac`A#gc>?fbmtZP;@IWTC?WSXL3z8A+?|t68L8XXY`IAQZs;qN5fL~SUN(F5r
zCf5taN2T3z!*G<<Fe29&2wAau*Q$GTw1MarB?JS5ui2k=<Nv&WYs1=I0>P~qPSF?_
z77TAH$tk0-cR!@+^L<c-gmF-rxPK9=Fn<<FHp@{>qR~%-4R3m4;wo1jGC>DF#^i|1
z)mf7|e3C(kXFr1R4*nRv=a{B)sw{_sh6+56vMrZOkp1;tS$d0_1O<b?QNkLP2+A%C
z^G!Py^b4_C(&x3&_MS2>P<yX2Q1u~gb>@P_3E<84m!xE;UcP=EbYH54=->}Hdh*^y
zrWRe>HP~zjYY`+;>=8wXqetPQN!|y44+0_%IIj;;4sbYGAl=wf#nj?%wwTRDr`&~R
zA%)9!H+BzjvikEIV-YTlLNp_R+SHGo@{cH(_GqQ0rd1jfu49e}9#Gv+`bp{<@|Jmd
zTlqxTq>HqMcM`*^PPdrf8?cg6N46%BjRW8KR_Sc__soLucR?QxlHIHvWiU0pA!aO{
zUS}Uol|$-vO_c(^ERQ9>dzwB(<~=1qlgXMlY$r3oVdGAw8rJtjzhS@fLCUKLaEG{&
zt&}y&qd$FJxd%TMlR{+%1n}|B63~1at?C6V>QV{RQ!*)V%mX}r@%otoQ!#Z5RibY%
zb6u%s_yt|;EN0pwWo5^t2A)IU%Zf|Bsex%S!*zc=DVvhG%%V+Z6%vNy^bWfANAb9E
z<IxasLVg3*N0Uu!XGbk>gmE8m$QCMj#!d~0@V;Gph{t(L1B|gC@G;nWTQ<6P`q_(1
zbb)dJ&z3o2_YbFKHC4$csXQh2YcNKtoj89H$z@?`X;Ik;EmljNCR>``gW$<JPV;7}
z9D~(^>}QC)1aZIP^Tr|Rj!JiRg@;m~9AyTy9B{}WWSVVlH$2S<2ea)E;GXUyrxG&F
zxt|#s2T?D61o#rx^Q<9_rZ1%Sn`t+B%jVKeIM~&1f+KM{f9d73C;LkBS=SA!3nkJO
z6X*+Pd?Ul%2#+*q;ph<>OhBR;W=Lz%o|6{oPmc|s_Rf28OOxKYr0rmA-}i+^)lC=>
zc^=|SZ6YIobgw{8FVVytwH8aPlQXBGC6d#7+lZ3mJuyNY%Ll7tvaRhp)>>4^%YF`T
zOfW=61qspgy)Wi&(FtKV4NH6jHnoG8dJ=j$(zNk+r}&Ap62d*$u|l~uZ23;{a?rim
zo4SP3k`NdQktS}hwG%sJ+c4F{^0V)YfvC$hy8usv^{#lr4m?%Dd$*v#YM#QaikIU(
zZT%GMZp*o~A>1Kl%xV{{kpY^nK9Ft=nkykNpnRldUdQrx+`n%A#^PG%hP%B&f?r9m
zZRE{U1MY5sn5b}KXnN=hL&V;0;X@*8zs8;o^L6=zj?(2dW~x3>w|oX*Fx7B}gU)1+
zEg{}&qE932q0{eWG<t+}q|dcRwZo}^N>FmQpnjQFFNZJ$UzS})0;vW>QQBdx%H4DC
zr~1N{8DLjpoI|7}%@w(SD|6)%jy!OSnU*XmB$x?`JY)#`D#>B-0s=?J(!lD~7i@*A
z41MFN1_-O;8D{-H2dR_lnc`W5Ts_x>DXyf5+_PF2Cg`I9o&`DZMloU2v#^Ko<_z%F
zXb2R+O;!0+|HiJM7B#DqlXyzHRIMK@!tK6eRr31jc6*pH3cw+HBp54nA|k$g<`uGe
z_DBL^$_jh`jWwd0<tx8p+~hmr&To8I@;ifzj;wv89V*$~wz8Lm2`A3S%3&7qEz|i|
z<fWyWAk@59`s$U$PIwt*h=i?84;H)x82nOd_e?uXP&54plh<%fy3)T_s%BspX3n1v
z<r_0)zHXC&m^$T96jI;Oej^b1HchV2>FR2u7@lO8d5M&{{~qa-pE3taQJssE*(7+)
zidb6hF?B{5UM;0SV-n9UQslnwN?V{}$r;)tUQ_ZtqtNgmr`7N|<<&C5!D8^Ig(<%T
zdoq8kxPE4S@xFSm)>b>=ve58JRcaV+`jw!L#7)Bb_%&4Q#g--YBA8&NP9qukmM#8{
z)Rrw25?4}!V3rUm{4sI-v!P0%j{vnX(url54KeakN$sE9Z`>igQfn~0zGNepc1Y#A
zu54+fOiIllt(vH&@ehXGY@H+|#npx-s4BJgZzuALQK$#RmESPc-jhr4TmQJAv6fgU
z=dJS^s22Z;NsWKa!_Fkysh&3mif!zQ365z>>7%bcODg>4qycb+Mm@l&Xzo(t|IosW
zqe7l*ungc^>c>8}<uxBs<G=%V@D5a;sXD7mpzfA&-hqe}(B`~Ni4@17r(Lu+DY#x{
z;@NEu{)~Rn(U_)-^b`eC?GXKsv)_*&&HoI_%8|NKfDv*E`>T7SX~tf!sy|E6R9mt^
zn^~lQpWUnM#fPh-e38s9F$kdZ8&Zy$+~xM{e3Z4VRx2;HVe4>;{wH|=(0>#3xN>Zt
zx@hMsq|kOvB3Jp``S)EOZ!u^6y9g*H7`5ltg%Y>Ytxv^c4DrMV29&LA4_+tW0J8=$
zF+rn5NRjb%16i6#l@~w`9gk*$v@Fyj<vfI5Uui{^7us@oRDu7aBjGKV)kAzXAcypE
z`*tb~$4{m1W~^6wy8*BNbqI;rdvjx!V4rKW^O0J;?ACpT-Ey~_W|kpwtT9Z#-odq^
z?I5kBtjv>y&&h)#=<H9q4bNuXq*2TAg5UP0ot@p>hno}|PaEo!g%Om1K%Cr70!ZT4
z_D(BV*EES?7SEhn`VMXs9U;JxIQmMj&8K|cTLyg23&IT^ztkJdx^Wtw?b|h&hn0!z
zKC_u9O<iATYgr#JNnW3<$Rgn|3nk&POIV+4a{u)rwptxll28@X<*S%~T}r^1>V;m8
zL!e0E(VdWrMddp-##i*I4>4uqGgE7uYV*9+|9Dp%`FCqxh<e2Q(`#3vhgvsZo^CVw
zh7N5;_-*sV+0jzA8{Ijez<A!oc?p42DP@<J4-ICD%qpdFb}PLV91r*#r_@0jXtUVf
zMk3@@Dzsi&Ggs9^zMjVCOx}+7x!m<l=&`=MJBKTfov2pSU$MxDJr>)yxIyS8J}ALb
z1Oa`s@#V?n)@H-vL5q*ds^_mS-2sO!i=Ow5{j0b>&>cx&W%}>SWjHPuc7;ksBuh<O
zMfl3Z8D*ugMpC0}(y(bf_H!%^bIV)J>#Pl?AtEIA=10m6h4@T6;oirq$t~rEjuZ0F
zWnr_4m+TRH>M^TQbbe-`dO362nw!Xtk5rQPC4r*Fktqmc?|ILy`dKG;{RXEywX7Yt
zoX3k3TQ;iu=XfR!zCS5NW+F;;wzlwpC}k={$gR;J_u9;!8A&yo-2g^~hMrSzZMAHR
zdhd_x2>JC14t>a6zBnEZ+8Pqt7A9BUpNQR~8K7<>#EY7XKv|LH5rpmy*`T{|fM1Y<
zy}HjfWPp<?78Dpe9%^(@Y5I{fc^Oya@5soyvg(UT#f*xG7O|@PRuQ{so=#zDKj%~c
zJTxg-GVi%><*mC44ZeG8QqQIflt{e4NAWdp`~MJ%_{#==zhU{;oOUSa*1K|Sad;gt
z0-^AMnn)2CwG^;I@o}X8&WD>@vx^sAYvb>WNeG@p4<g5%1NTT8w%bo%s_HKnA8C@0
z%Vlh~yFZe2xVlS<+R7Tjlu0Wb!~kR?usPDN<|f+@>IOVgX)WdCa>zxVHHJ|HPTe84
zxPKjKiSHx*>r^qLKYgfdK;gN9(=yTI4#C4rJj)0Vg8(dm>TCq&*Vp$g=FtLlo;eP3
z+GS5yqeV|_tZySM34Z31Rs}Q&By~Qb6g3+09^A;kjO=sb;RLolO6PKUe%PX+EYKaW
z`<Z@}ms@;&z}wv95tznr{PfR$wYxN0awAkP+wu6*=g6uW5!hxF5*2<OV|=!Jf9q^-
z*n75qnknel-A`EE2Luv&aEC50XKk*&KHbeO*L!?^ERnz5is#)6DPT}Mc4+hO;u6kR
z!*EUMjmX4Cixl*bCEwe&GOm^l1Fa!ci9Pmr#*gs(lODx$wuR)d$9R>B^}K@IlvLbw
zCJmcgZHGqQTTMTB7d|JM!2=n*#MqM13a4h&1A?md@GV;DwGYwixSd3ZBPlGoTlHy?
zK|AZ+TFd^VEnr6O^qD?pe?m9PRI-)D9M0D!e>=baeW;75k(%D9?Z=aqC8Y5JsF6re
zsgtwuYn@x{r`FxJ;eai7r=bjiRt2rQ+&}CR&ma-*D{MVotK@rxuxGV((B#I~FevOZ
zrAd6)lwV)C+b>7E($}d~)Co_p<;@G)Zoir6UbnI<hC41#UG{NQ`#pk#ODX_&kg1q?
zN-}`zqcqtTAQ1vmV@)c!&B828h%fsz<$7geig31#$^;%Tr%=4gri%B<Z`0T-I^BDw
z9!g4lhC5gsCYRPHWH4@o#*qi&EJVTFw5C)GaRE`w3@*dxvFMHMVwJ-a{xED;`GPGo
z@Wi&KSkn^kGPk@vQ(HS4MIfu4Lfc2(Z5nNsC%aEsPpI`6%>noDZ~68ytR;_SUbpN<
zH7#}4v)_yp?yPOl4QOQ*{tsEjVSJ-Lxk#e}&X0zjDEZS)dvd$y;+)8-)4uTPAV>R0
zsr5CFGI<%=*h+XTEpJo1(#Q@x-`{q-c*zb?1q>L)in&9=+b9}v(pYCd`BLAt(;h%=
zjo)gbjzNppCjM4Y#n!oTRGQ;*vD}N^C^_1`HmRRIaXFzJfIT?F%UiYtrKb7PE+6$?
zjB?b6RwFW429MSC1SI50oA7GTg9(edk~?pifXrf%rFu1=$b6PCPU{n8l#?0Jzn|9G
zt!kGW{A%{H6u@vkZPm_QBe%@M6}HWj0nVx=FBZ=-0C&!p3AnRPT9<y726P{ksv*ed
zHOIS0FrF{za)$X)1L1lm4gx)vk!1Z63T8l&L~zlQpVT@U8s9g_xhVNzUNO^j4z`P#
zme>2T9oAoYjrRHmJoJSr66fR9wAH+3xH&O)?>6Q)ehR-Uh_NIHro==)rKu8Ok`&J0
zSG&Pe`0=T&qLMb>u68iWbY?<)HMrsG@>g!cb9-UF?fhW2=&zW=`xcL1%i0x2n^%6p
zYuvSbcq=PVDR-?{MOtSc4_xPh`C9KJyj6a0TZb@lJXnqOuuQ_Moj-ob=hyyr5vUv)
zI(+Hpx|5bLo>zSG)YCNSP)v10M+-;uE)*ngO!^WSF-a=lqL9KzOCeEw)%lFD1N<Wq
zC0d+kL0Ym!C&OKtzl`5CT8~7livrJ2_Rnp<74&pF*tt(B3_IAFZ1!9?Sf40`YSQhK
zDJ*Iv*Xkst4mYfflXJ|vMTb{A56VAAg_C1!zZOvTY1t5+%JxnX^wF6#AE{0^`46b_
zm`>RE2A}Z{%NjG_fM@^>?Rxht3U(Sfjhi4tX6Wh^^RR?&p!)QF<ap^KwO}>iyZNXT
zA#W$f&vFD1=#<Xwai_fn<A39*UZ1F}&`b~BHYO*D*+7L0Leo2Zk9Swq__(SL9{Lg8
zDr)p?kuRas%$Sw@H1a|(dghfU->SpJor5_YQIJ{)#WU&BKEIKFN4V~TlHTC1rd(61
z<bA7$J{YPB*~D4(yfE?G$bob|wwK!U{T4G=4Zp3jIj>osF;p@8x)`qeZnLUL9wz{2
zJ9rYS;nTY2q9ZO?E#^n2OHnQJm~^=$q1CtJcgq)<9BNl|@)nF)dy4yds2zUx9pSGH
zzO|BX%V=v!T2EqfTQX|ii_iFcl7a$nvx1!JqVn5ndOutBam^mB`AWRTYH;p-R$!kL
z^#U<=ZFDQwI!EGIg=+wBZ{O{<+QEcC?;Xq($_H>M)GDGj>D=7H@$rrn_C{65p{B&c
zR7pH=?{Jfpek7RQmj~xgA*kfRAV<;S`bS^xUdyxO<<MTDyl0wpUrgNruaQp^xJ;>+
z*iTU;)aHsaciyr1|AO+`-L=HL!oJYEG$ln_r#$<b9Qc?L6^@IE5xd|Q{X{pXKGWH7
zL)0M6tI#>0kb%L)RJ-kU(k-kt7yQi=2uHZ``WK@1x))JtLF@Xq*Ku$(Q}(l@qkfa=
zWIJ7jG)TJO2U71{ZEqRRE+cI9v*RtUGYv?XZnMk^nE*_^iZI0S5mSY}>ao#qx`C6J
zob=n5+OeNBc!69EVSbx+Iv!Dqsg|`bw(p2a5l_w@s@Gh<K{vp3Y1gg&_@QzWm|u%T
z-x#%}nCU#MM|g~ph65Ewly~kpE~=@b!73!M@W&o$k@bi?mY4GD4$*fPCDEOam@k#8
z>b57;|1-jG+tGdkl_MSuMiIhDcurXdPH=NVP*Y!`uaLhRZfCcVe_P@nVuT1&*BQP+
zXlBg3W0+$3Ho{HcxGawyjPZis6+JSszQuqlR>aO=XP%=FP!gWS-`=0w$$3tOKNQTj
zjyY2^0<aIKz)Y0sw`|QjstHK&AazM}^-(Zt7X|H8{}QZ@X_D4^<{5kSf6^(}sW4J4
z<b=+kcWzWR#9VwFetJf<wtZ|%Y6+a)AG(nW<7@(&ZW3j=iLW=_1-B0jKlLZDy0dz-
zztYqyqy5yD`f3~pExTD)c*@gE(i+<k)fqRjUkgQn;}(470Z7i@P{O}T#yGhsa0EQ~
zM7iO5v&XMD2;=47U9-*|n}Xh3q&j=wEe^kk98BeQP~14>Gy{Y^&bxr(h8kdfv7|6M
zM4R7DUUySB@#`xQRk8`!p3gQ;wSSQ?CJ#E4PO)61jeMj%+W2k?h8ZJxz+<QR`=RD7
z$c7}Xvre}2Uarh=XXzzsL*NV<_(1X@(B>}U^+T?LIF06&NgEQ9Gy2$=w#zzIGZ9#i
zB~R5t!EVPhQ9+9?A1#uj&e7EtnY&=$IPiLh>19FB-zxyua~V?NiAiP}oVS6HdxQqQ
zH5^s^jrl=nRJ<>2roDRKmm|0pyrvpCwL)ax6RlJqkN0;dg{w+Vi}=%xlFaAy0LP{?
z#YxPFezwp{_TC08Ga0LA{Wj6y2i5O~10@ser*gP42kI^F6{m~OWV8Yk?_cW$c@&x~
zaYI8xt7po7o?$3qsGqds{_pW}z)C;p$lN(b42-XCu>F`->#L8H1)j_PkGo<~C^y(h
zGcrZoAJBbAI3^5BO!>z$q)H|s;IW=9rK}}Sb<P=KOp4Yo`QksrgyRZy;IN(`3CO0e
zYWn?CRMDQuld#!3`yY1p_HRYbqzjoa+v^m=>C9Ex%Xl?Rd;TFU_#vOKK@nZ?!N_ju
z`#gc#32HSRn*ty*keW8mOH9)KqwtC_Duw6i7FuzVVWyb)->sv?)2*?J657FDn+Gyf
zR8Yy;Mbz4j_mvqmeev9!scU_mclUX)2;RKmrBAz-)3^FSH`;FwmJ$ifl(Ly4h^cF`
z+Z~q|<&A;o&knzZQ8W*x^I3;}=%Tzo$RJcS9^*Ju>w3CT6SF?@E(F}Mb1&(wd98&|
zx(CUIUa6<6Y(aXylq-+quv1ih*Z+jJeZ0{wrX}1l7s*V<A@)A<E?WcV7fGxNOvr1)
zrK01aS-;vs-YUW5a2#;w#E66QdGE#ja~{!_jhQNQ*()di?C;OGh=X|<%=zh|_f0a7
zSo?{AeljXCq;yRwU^W(O!}Xupe%~}NDRJHB`_pzC#!G*|T+zCGMGiROyv4@J^JvRk
zHFq;UuI#>At0$B4V#h<HxS>L+V&{LqZcSTfd9rn!xzVv2Hjja`G5##>XX<dAtsk1`
z5Lt<p<opv(9ql6d^7c22>EPwI!-aJKz>_A-Vr{4tVc%+@%d_g6)<(rN&bDyn1Z7d9
zr(cHE6U&P6zZ)~IudZrJJVhiZnoL()IxV#NI(>M4J=KQFfqI4i2Fc@eU0gCjZUV=E
zx%Pn5Posp34)sC5!*D6K)`qjT^;2zGZKf(sw~F3pnq}V`RNnDM?(MieVOC7>WS`~{
z^!r(&A&?kL1XIHE`SI3!4p6T-V0oN>2Kg2pm=sG7z1JrO$v`Zh%Kz-IO~d8IY0pfS
z!fWGJAJ;Xz=kt3N6dM$&jTZ#ki!qh$vo$C$o?j!9xOYkvelx~ky=a|TTv>fB)XLdo
zG_Sk&*F=n=dR4Hj@?yKa)LWyn6rOCYI}&!=Y%`nL&}%muzbXq2z70J2m8!UO96{^6
zeihZRw$=X8r~T9=Gag!ioC`eN+<K$vuxcm~iu6|uc&1)-kjOk>@QF3?(XU<nO200;
zPejRV#+iIdGki142XrGuo8+EfLXHJIe~;z0JPZ%2SA9XI7}`sq%V0|Wv^a4UXOD@{
zK*R1^UPv%rrMJ#D2wbgk-%n}ehJHc*{q>c8FLuoL$J^woNfXhdrEA_t-@>dj3)tS?
zX51_b{*e{5u-UTRjtv*ZIO4CpG3H>^OYzjRt@IBPJh?D8y@!}O{oobx>`R_}s^6yr
zWsY}lu!F7I`FL`%K>xKj4Q<YE^D1pdsk{d`dKy(kk7?wcuCMj~5Iq#&vmPSlvl+?8
z{?0a8L}pOB1~w+B_v5W)6=6#h856jF(VA=*C};4G&V$XRO3!>%q~aeI^8B5UI<vd{
zip}dlgwgcm@2{-{4Q1EadPl`bMa<D?wWZ?WlzB`Ofr>Ck>@FiWJ1i)kox)Jz*D9iB
z9<`yR@GeiD0@~v3zh2hRym)zW_@v>1`rd5e@w)M4bIaLo|2!6RO|qD0%5DqT^*~Fb
z@KIt`jq=9O0#xkKfasuKh2e`nU&;B*iPgKiZ`hdd(Ieql@Ukk6Wc21AJu||GS3Zu0
za?azc()H6f$`02L^WWhTlSq^z{kv66+vz44*cZHET-HN#0&Xk4nprft4DboM30_xR
zI`J1$y4wQp%NHNsk`mZz6Ewf{5PNalErtGo9ENivdxvtP1(`hQKQTnQaHN+;Sq*1y
zHno-L1!t}-7M&IqZQFzR7KQ(K>AQMp(`UZ{iBXN~WtE+O-!d*Lyi3D!^U|*22JT!t
z{2_KJfLWlO%#T+Qou2pk9+k@Y`1{X%5!69lML^lo*BN4Yx@T1QekUgY(AFMT@Ov$E
z@>1jn>U*%xs3(08V9{wOgNJ(HRT8E-Xutb-SLn7{wCUGbG4%<riI)>euD1?Ws<z%*
zYwz`0x7;CmL%bnk=|>y+zJg$~bJ4jkS3PvPBYj*+@8d-;s`4<}ad0kE#LvnoXr_I>
zz>l^oF1YS(Tc?$yts`-Rci&B1@{H8#{SxDIJGC=;V*aVuM!dd=ZN~eKyNz3<qY2-n
z!>}jLwNW@n;-jLVL}wB&V&L=bMQXgMf`M{kIxpKHfXK}!JIh24PMZMezVH|v<+M|{
zwzoRoQlInR8ypBQ?06i1IM2GbQ5N{rh4*cN%s|0LxZAFvj8Tlk;P<QKN@_mRQ4J}<
ziPW8)!B3c&m{@bg@seNAR<E|ad+SA`(E@MQ03T5v!&r61w9~a^=lgpFjHaUPx>g6Y
zVc1&RuLhSF=ktyY^Pk@MeYTx=o;g(=d9}#Ifh$gZ>$@@$2LeZrt+^(euetuIv;OSH
z1N2EwkBS81V}HJmd^-}9In0cY|3uuKV7v8a&MWmxg~+>aG`T88O#&#LzU9V<&iHl{
z>THZXvZ=BctC@D-qd*i<S5~F4-*4@C^n@(Y_3bkG$&kHzH^V27EJI$Q9~tg*k%XxY
z-^_krw>p*12DEDnbCdiEwf~g#j`UR#4mdTf5_wM=dP`sI`h&1{E)+??sZr#$Im5#(
zqj?WRTQL?YhM#@g9+l91vd-TMN=e`^eedRN1SqVKeyt5&i`q*;4&Ix+*ptxxJL}Z0
zw<!XTz71uaZ&(X~$Pm9N(2O_L(TW-hqjGVlRAc2eyC~y~VoQkI{6n(?vZzfpLxTOb
zGoO3}gU8>Y__rFr&m}Nw%z=A*tonPe1>cW$U?C_FB(vtniZtG`-aj>zmS3%NUR;<i
zQL)Yn@UqfV)Nco^505bU#2kmivbibj71}SIjybDXGT}t520w@Rzu#_nR>#8vg>@r6
zK;Q~;Z<1TR)G?1T*_Ztq9H!s+Vh73H(uKUs_1ou&`fjm;r0HxFF;8FALoPZ3kTE1P
zuuLGehRxCpl<f+{>ZI^=ZIyH>?pd1X3;)A!W!$t%8gt?F3OnuDFK>7mKj$YKJ>?-e
zEB67M;vpuJ&pETE$ZGT9tyAmqOiea=8;(2Hm#tH6$ARZ3O?cEY7VxGq`tJUsSG5te
z>`#}4Ti$uU2t5{3I9h)haZDx#tN+<5V#8_sCGY5AOm`e5d*Ip8K#0~;RZ33YW83hk
zVq?Ee9vyxCbzY~rpQ0B>-wj89Puo|td36JyEW{=K^D0OE;LhnZPSGR#$k5}BmznqR
z*A|(-rQRXf6EcGTjg?=!NSe2&7RNF}%Z@Xej9Z39PkmS-&rrcwYxqJeJH-@AhSJn1
zKa}TchA7-9=-ku$i#&Z3$Ypi+*gT37#sEicwKYlZW0LDGzv9><j*yBKUpO6zvby+k
zzRJo;t`==_E6MK5+3_Bi1}jxxK0dW!5xi7o`lHE24+7*<tYIwqO;MQxPBa6>R)s%`
z89<2Ya6U7dE8F81(NX+3cexrdwHr6lQ(6JCP|#sG@w~ZAiU?PfGW4K*4N!sKypA*X
z$Z{)b;^3t*dd4-PvLJOLjK^PK>J-{U8JBWVUvzI+c<+f(SfuS~_vl8MeuLFX#=ZzB
ziK%j60`ItQ(G4_D%u66|@I2|-wjpTT8xp$mML!(ssbTO=8k2yblg$0cSHtlz0o5}t
z%zI9qrDevNbMBKy?NXV+Z&7URM`rI|MzxkbNO=OAI4s4b8v5*D+=`PC+(zc9aQ>7S
zhYL4w{5`>+Z7*b;^f>i`93$uO2~~2P#@JHhZ+gtv-}hg#Prk>?-98u@Y;^tpfU&1=
z@QqV(R7RP~uDI?Oed0?Px^g!3FK_4qp@#{}*BH?j-W}RE@C_b9KdK4xc1m$HkXqno
z54qpKTbE9x8rK~^G)fDm&wWidJ;Sx-DmQLKBBna`@nTOa$ADOrS_(_&Rp~9~OUon?
z^_(#ZQR_H6F_^~F59nj*s3<RpW1|pLk`nWIE%pv7=Ze$3r*bk;c$Sg`ZIy1T3JV(1
zMl~jC<glj0jIv>Tkm;gBrW|CZC~6s}Y(_XpNFk@5->Yvg8Elpc7AHmM8rO;12P9ur
zAmvRgSfv9@MQIx1hHdaF^GSN5$@-t)8?_@UWyAyzmN^DYp0I=d4F-j!kvXGK0a>cf
ztolq&MLwBE40{;^biHLF?5g0Q1`~1f!&@Vb2oGEUOv(um6TG^+HE300==#Tr<f|c%
zVW(>c7UTzCG^S2%Kc39Vh~_>v`PTWuX{=DKm54BE4T}>4Bv=eO)2x!B{_5VFrUXUQ
zn?Jv;Yc=6<9VSyx3~aX@W(s|O&4pSGue-ITsf=A{X%KY`NCzibq1|DtCo~=EFK8z5
z-kAC}B)I+v)O3FTCYIPl?W6|p+pf<}^jz(O8urogR_9!};y&M;%f~xTYXhm{eDGUn
z6a@M|LsBP`+z(T%?GHJk-c(Y0z*NM}Ye_`?8)w@C{C;|BP{KQ@MslQY9gb<JG*L>v
z4Ar9D7f0WPFHDN8-4!r3qJMQ56EZGe|L3cUnCG<{w_TXEOXaH5k8WUYV~pCKHQhJz
z`LNkU&ph~r79C5gN^j~k`b5Q|;p+`40oeI+A9Dq0ju^R{g1QSmy*YLw3=}XWo!!LU
zRKuccI$3*vduAZH7?r~7m?rcqFTPlvFHs^p4Sunk++k6$Ra$Uo><$Kj$3ISfF~c(}
z7kXPUk&%Sg!R5Yz%j07IPkM+I#Fe`qiiQFsilt=7hBn=JFiyMko#Jw;OfOz<v!wZ@
zst~+be5tHq!OiP73f!mLn07D5(;p`%&XA(J80l9;P46Vbc8#n(cQov!5ZoZ(VbQI`
z-XRy}ry?@F0WX#@5lyZx`Lxi~+$?CF{3pfXU1XH_cpTcKCz$M(*Ao;v)(vKeT4Op0
z)^~2>*=v>~R01s%QZIws1TA~uP#7b9WtL%Ipa!Zv)(!Qp#rak5;l^})n2`j%$_q8R
ztLoF??~;n<Xfh$0=_d{$;<51h+3==U<7mv?YN|db@uf8T^2Z4z?BD3&8^0Wcco8T$
z4$K;_nM|DI7F02r)iaFD>%mv2mjiEqFF(c>tQ)lYRISf8I1AtYq<}bjf|VHvjYXa<
z-4qi~khD_v{6lH7*JbQEuJwoGfg<G+7wBaXz2;cl2x<qNWPTe}O0?!;aCH@vgN^B}
z6mwmD`h7CW7ZA{XK@!jvj+d(CDN&yE8;ufz)%VS``tF%o^WBgHAkPXony$=+UX2xH
zpXCmfZ8LJJI@W6dNQW2pIz`gqk6Nxw6MdFHXBTl14#>u^yRFE9!sVQg5N0365D%eV
z<HTsC`GZ14xLf{CZ}L+>5=zO0K&NB`q?1(L-Z<!dpK@G^2PH=YjecuUN58<W6s$O{
z#I>8T-1H;UU6#}}^oJV*1ZGRSvr#kLjJbBRU_9VV`5`zTCHE1i`Qb~jXhJb7_$GHZ
zSL#_ZdFViI6bFHEL#ckl(D>L`BS7zyr>rj?qm|%SnRJjRFa$M;FDtz51qon#!6bpp
zT@m4K*w>7r$M6jbeW4_viEChaXnpnDCl0j^xmMs3E=2`LB{_~c<XVFUswcsC?!jfJ
zKXYTK`k=e{KLO_ra@kCw5=Z|6T?P<+pWT(u&?MzilpF;#y6A76FR{p)x|euayVYRY
zfaOMWb91m=wk{$sMtpB=kSn<caH%xWAAk6HK$F$Yu`$3+vm`+dNwKPk)}&|b{BSYr
z>7}bM*}tbl^}VNnu;Q!!x_1ln7yswi_c5UQtoIDM<hu;Iq3&i!I3`g^2|z0EA)$Dc
z=KaweV8d5UjoFqIzAJGMg?u@XL6HqMe<b^Sm<E4I-3wA?mpqfiW=t;r8O%XEz$~=+
zxobt1$LazN2RO|n8wWmAJ4j{hew<ASJ?)u{<^e0pK}-*tw3@osxKtyr8Wl<HuVX6(
z4nUt<R(fn|g#Qf%R}_PIuz4Be0dG$x<S-?`q0@W8x5sm9ZhCXB>1&TVBgl~V%9_N8
z9Jts|mV2IVcLcT113Pg5r#Ptk1w{3N;j}kC2Xr0=pI>w6A%()^L4VTeR1TNbz)lr+
zBxqwuqr!4b-lII|iGw6p2RPJi&9}7hE&6}$!M|FaK_(keGAEFO>V8v+3#+0AJxTBB
zY8YX7mRTn1x35}1dPu*zCm~*0RDmYG(=kn;j=dt9NDKttM~SV{xy$n969&?`p}~9w
z9q->T+yIM)L3)e?YUN07!VonoWwkEfB(fB89)LtSDU8%_b%e^16tT0Dj9XS~`tin9
z1+|$>$m>XzSQ<FURn%4C{&Xn>_o`~t_gUsCLMjPDZAFo0HJT$GUX4r22!kb}Duco|
zAJB-S8G$q@p6;evXa0G2FA{JRCR!|qE~CJ%bR5`}WJzUT6fO$PAV;{|eike{(TgXZ
z5@3U`j3WxVtPnnEEXPkMxgND_a9D>hZ^ZoK3}AY51xo3{Nm5>5zv?iMpz#E)3RN{X
zKOj)yLeOVbJw*QJ`;&N<F}FY8g;oG_Fc%_1qU2!E&}nmKR=w&jbEHKW1b&9bR{gvw
z-536!2c;k>_TLY7K9M*dsok~|&;AXzAETrS*k%>{s?-sP(yg;gr07-!;HwO-&lEi4
zwlIuF2<}e>RwIy$EE2qW4S@^i4kC5~wG#o+sqlx%b7;{Av->%~ly8tj-;lvX@s_eI
zvc%P&j3al*Yr^OXOG?~X^y@u@ytn?U;^<LApkjy(P&9P{q5oCtG4P)3LsTI#uxIj-
z*+|~->YKq9FM@#^*R3^w1Hm*Bh^L6uE}iVJi>%Nw13Tw~M$30Zs2lNs#$xh95bK|k
zyTyavoSk$?Pu`*wV+Aod7Vek;(kEC}8vzGboD))b@8Q+fueohm`~H8w-37Tnzg{J6
z(Aee-BaIIv$Zxenv70WK67G4p9v?M0%|8vKa|71{gSV7&`!>t<Fj<rL$h}$ZthQ@%
z3^5RT%&t!yG3+q`c$&t(8YZ4S6xzfa8i}uWogO2_%dFg;0_m}MO@jN?9WKgaY9*gU
z8qFytfJ{KXUO^$Qo?(L-MQ_8lsRv9=3P7^>U&X-|z5p=EHhZ_gZoF7)VbdWL0xy;f
zHm??(D;n2<IRhia#>WTW^s#s$4uSL2T?<x-GbPY{$?hjUB#*r&TrGiyfYU(5^Ls0i
zt=N1A+}{6FCcK#U>A%ib?-cLPSK2E}1OOyfeok@(!E~W)z7{B%`G1Jh#4n7etEj`P
zd66u3y5uYXKLByL+nabIP!Im^o!h`D^sWn-UdWEr(N>+^B@?6>W$}LwaAKojF|ewR
z>?0)_RwqMAKkzz*`6odJoGDm_2mzM^iV<(TM|J}<fPQFt5S;dZo(12hkEy@Z;9X+=
z#>wyryS<8pp{J*3IfzqA2NFX+b%jk4RKD=3cbr|js#f|LyP)gfcU8rV5+8D`_n&rF
z^42jhdCVz8fO(g)^G$<DLku}p70z%fpHMA9XQE<ZJyG6k*jInz3n_iBU0769gubr_
zMs*-v9-Sy9>`Kt>n3lJnbPilI5n!_PKlnMC`+AH9bXGkF=J4R2Uf-PvY<VI%o>fej
zz(XInoEPW~2sR(3kG-eC0%Kccl1Xu=VLDsc)qAnjdjmAtqJh89Z>&TP^lPQ)r0gen
zIf-Q{q4+@tJ6-Mr=(0fHhTSA}5q~fa3fj-nCOM~<Zr8W*twiovX<%3y$WAh6hph?V
zCx_dMQaE0~Tuo6+y0=3(J>gO&B_7^N<r{{b8S|CshLGVe2vU!c$K?P$@@eS^L3s%Q
z6}qvh3lOUSZnr)g1p*Vb4~GE2n?Tg66&wEu1Z~FfjR&>naiBhjudBPb^-?4i&pkkp
zHc$*?hZUa4gF+)30V550teQW7LJB|aD1X`6sw*T`mKD6MM6i@M!cDDy)gl8%e97Mk
zMoxto$Bb8)^O;Tz{@9#3esT`?cTU6N$&!wGP^p6p4ovC6l_}j+S(3Efu0I*ypc|Mb
zGZ-pYDGc4d%0pjhBQxY+7&Kz4%~I$F=n7%P<lotpNg=^6TJi?q>;ox<Iay$WDc~C)
z*#2t(J@HHwJ0Feuw{5^IwNv69z`5=N&^P)S#|MKKaM!+zV_$!IIIEyJ%TC$xiePC)
zH3Qd=5_Jz6-Im>}?u3BX%e#}XpvUD>YF=&}C~F};b+<=?sJ?6ACMk$|kS-hDRpXTc
zic4kwG&sn;_+$K<GWM%@x!GyHnNS%^4j{xE<~1-~B^xaM1UWEl?M-Q#8OO#k8%e+q
zqWM?!CTsx0n4!@E#;)qRNASS-ioVv)Qu~Gegrh<Khf~@q5c-HthpB7e;4TB#A1883
zQkfhkTmL9wu3)z&;Itc(E$yubk#r5G4xZ@7^WZGFhq}Ah0Lb-gz$%EUNlaO#3Z8EQ
zU)@2%ZX$kN;4=&gQuEko9-%ehK^QTH>uh|r9VzU?nr7)Azi!T@9^0fOFZv=fyk=~D
z>#LFf!O=8;qij+zy5ffW#TD7?>zt!4eSdQ-YZYZezaTO|4m_Wh2HdNq2uM#Fy}v~{
zD@G;1q~bp3yKHuAE|;t(R1<90F)<zRl>1ZtRzN7YFt68DISCXrjJXPM&X5HOPwIge
zy*^VzLA&HjafC2h)Y1cHD878olcjfNpLl2oct?BJ%&u2faA2y;dw3UmiNGR!z@a-c
zFf#bVyn>E9UTNuTrg+|&lkzpHf=x}PV6z{G7-WeC5O15@0$WQBCettN*my{NT{8yT
z@?}CLQp;E~rRE_8n>OThm*4@Plfea<1F&Xcyrrq#(3pX7`jHirhR;1^`^B0n$5oyF
zRg(oi5-qjbhM>+=QdHy$z$f1l4UP>usn-V6TV`gSPJ(6=y032_Fg#k91P|_Q(rE#|
zbW)BINcvlgDogPM_o=jtT7sKjuk#K@+yl%cm`o$wO`uDTgaekvP1|SX9N(GY`8zHg
z{N~jCQw#;gEg=qkm@6fggD^R%a|i}cYklo_oYtD)7~z3DRSjshSVZO%Of`Gjuelw7
zRtSY*DFtAcY#8OYf|ji24R+&9+kw0i=o@h5k?`XRrD?q{;d<An^EU<p)(UVeE&=`_
zS8`slp8UAc4oa?s1eNAUweklP4@*=`+!=Emtdh9R>O+ZnE}u~7%z8`wf&+4mi<$m;
z)yAeNgN09%pH!=HK|!r{hYz_onm=XqC0sy%WK120W^fC>A+@_-5fpG3bq0uEAC*ZD
zD#w6`6JIt4>zJRWxf?!>Ggj!EC~Bv`lHrks=L4FpQc##72ox8d8E~M-=dvV@OB+iF
z)1s|Z%3Xa!5zS!T<zRHKqGkBXcGXKlU@gVm%ud8gGP@bRG4(j1WcJ3`Rw{OHH9@tU
zeQ!onz+*lC{Ig1+`u2Te&}E<wY&Ah4(gTmq#af^~(T{O9)IW+!#Uw#eAl(aO3${Mf
zI~s!DTA)>NFmcqf%^+it^d^BD70!g&<SeaYwcKVH$5zV>Oh130@Ra|T7ro0M&*Vls
z1~gQIL<K3A^q)#DayU^Ub>Eu09<^0}_DyViUd;XK#nghY;t6;!L4oVy;;<t*E+h{n
zM~?vofIgA^F^yjy<Q4H!OU5(<U;AAP9Zc&xX@`b?ecy3oqS~~EUlj&qV#x0R3XqM2
zd6n*rSP;Zck$J*MX!|z%c&bYkr}uHPG`EF}`_V3dLp6g!K+|hdnit|Hh$)We4DT!E
z34XdtJ9BCYnr)$j4^X<Fw=HQ=KHaP=pzKHHHD&5_>g7il4AePBf0cV^@cCml+2Fi*
zl74&_(}*|47-G+D7Fc8Ok(rpIBxk?)r^>3f%*im~@A~Ahq05KsOMv6<qAJa=sSRCw
zspLw%BSV|xpsWpU&Fki2he>lh>kzfaJ|H|Y9L^M(e|d+5saJ^zK@%^2m5eT_X#Xwf
zwUP4V<{u^{c=;Rl%N+bL@FHvG>h}W^+UktH25Vg(OVEGehz(_IG*Zgfo9--<7TTf$
z+GLY-gw5)4c<kEcDHbbgcWZx?09qMx<Bl6!Ypn0-qfP!Du~qnu+Ygp9eb*jNg7`Qg
z9(xW)`KafvswJL$v+Q#4+<GRcPi0tir)bccJ{uIqW_j$_>K>}ULiG?xV56ZzM5xtJ
zZU!fxw2<j|s-I%dX_q^CXT%q6BXJP7$%Us3-9FP2uF%|qzmfbm8U&#b3~qjyd+X6R
zJtZD>a<*%M>)qkCKk9B`fs@`|c(z_vn~S}?hkw+0zkMm`k=`=!R4_Qc_>vC(8Z($>
z+m%r^wKfzu`3lc=*q)xI<u&jc#7Nym*@UlCyAgkZxt+x63=7|?x!{_5M7_0ZCpWVf
z^N{P4p~tASZBOteBehAu!igvphNNWYDv8LP`{U0zYd5*N!Fr;bKlLS$fQfqN*ZV9%
zKTgl?NWw%yaaKfExOjz88>chP1_<6cs);oyRbzuip!15IXHP%equts8Vt!`PJA2|&
z*d-{h9US~No7`s!YOR5fkB+r~P4tviQ1{6@t&Sbn58$ft+O;Fxi7v~Ni+nwcckc>V
z^r8;8FE6$e?~5xVx`KoEUDwy)2%2y#?)h$avf{LWIZbc<$WG;)vnVrlrFqX??@lCr
zV=9-mwl<^*jWUJxka=hLo&D+Y4HD~g47If+@G;J{)SvsDy!0b{`gZg9{StMfaHV>7
z%f5S)ZGMMWO3uTpyvpCnd%l^dE;{_dD~3E0F{@9{WhQJnwzYWL|FqHN-Bs)LEP&0Y
zcuU^T|FsDWz7?7z1K~Du7e@!Zv;jXCh)UViVl;kULA_RL>V0JP@P&o4NyphL8zmGY
zg{o|S%|M^S=xXK-3)<C4D6=t^9nj9+;+pk57>{(^<oh6maSmA52RTc_uW$U=V!;m=
zIWd2}_p~ftBq3pvpOig6facG<X8DxKBfZ4!PKQtO89`+++efxGY5g<xj{0k+l^_vB
zHTYmhqyQcbz;5895sN<O;NvIhsG3^@DfDXOdOqHke$VmO*m_C*J~w+>TE&%6VsORI
zMnHmh07O`&-&g}B!LL_N4mQ`Xit7iU=-)dNZi*_51*s7~#T4T*_Mi_A?F;5Z<5ZH4
zJTLv+I*$J;W0f5M*Eh%W-DY5<q=5mpJn&afN`PiblYkd<{c(7;0A4t|^{+F7EMeu0
z7vFk%K+Wmr#Ziw~bG>6z!1hg*K16izzS?@pgf$36(NGeW7~H-JY^dI){M0p*_~)F$
zWver*8$}xL1^xCz!LM}iE8A@Y#!i^PwWY0;BR*76ZNKgoBVb)h4qJb>T~BpQC154{
z=&vn(JJ+!A*YWZ3V@;}Vajeikrz>{$4cBR7s%qg@E*v2h4-VGBU}}V);ERb$88ms=
zu0U~k!_q&kzm8yW<#T+LYZ}LrUns~{*NR3k$QG)x(;{HQ*BSe)T(UbeXm>RNPI##m
z>Ys>8EoHb5xq8oi@MraSX#>=4698gQI6>v;Zo~5fHW$;0AR^|~uJgx2Zzgsf-yMU7
zcuqHE`<vmxi@fUfqBa45IENDWJU&0q&kne~Dp<J1L-9y<L&kS6n@qv}xW0Z9)BqZP
zWK7&urR~_vtTt@7$}`Bnkv+qXoU-xF4n2O6&3wnd%i(S>Ub@2yCi|_t`>~f<ZJ3kK
zQ=!2&w83Iog&s&beOy&`)S@=YUByaIx84GvMrb=WXGqacI6LJm!45A_$;$LSvI6S-
zpebI2LP7mhrWbDW|LG$52E}lrDo5QYkTq?V_k0jws!{K|@slI1CGz}Mn2_2~8qceT
zo$3p?&pj5c{#J{=WVk7xT1_ou@>Cc6G$D-FtiF%iZb6@dx8mo;K{|>QlgO;o%whhC
zy}`>RTtlyVFu+mcBYE#@qaugP1i?0?z#yZ}R?0`0k|Z4Il5P&UqUFf`ChkdddS!iK
zto8xr6(yWVE>)rI3mnON{Q$2~<cS(D>$~WbGKr|P&CeU%k>?wHl)A8bixp7B)EySk
z9f)9?pU`MuFK;1L<fCgZa&_^B@utk_bdvtQ_X<oLTr3UIS@lm={qg_QaOLq(Z|}dE
zCT4WA%%CjUccrN88f0wKSVLu3NDVHorN%OfFEg%PmWUD+Dv~9QWh$~p5@yCOOZMGl
z|DEZ+et#S1bIx;~=bX>yc`x;=0*4@4$qeX5^-z$IIi8)WHiKcL_V)$9;u3E&@%7$q
zzcgB0hN0u(VU0Nf4)?XKM~tS!*95d9qmLf{aIRDR^J^#Xt}z}liyU3%;?U3~E}e-4
z?bViX1pR2_O=O65KHe7<Eut@~+`qPL8a86Nq~?5B#zmGkol5|U#z8+wzrl*1tV>wq
zHb=fNGre)213@bs3{dQt)3EOal|ibNn_F6&ha5@6jIQM!)UuAeA)rN>yIyh2($)zn
zn@8Lr-RV_(m3Y+|06~Q?(EHZtU9G#FQU2A{v2(GQi{MHy-@(B%s6G5gkGLK>gj!;G
z0hps7XH|MNku8R^xcW72D`v9}`yAYYCSYxsucd&BlW?)~Czxj1*|xtZ1{LF~QEw=U
zE=gbWD(yF;0=^40j;o+fvL(Wv_-PxOf7z2r%(lW=s_xsIRL+J7Ua0;a^A+7TXU$e%
z`cWqS{pkIpgO4t3HXy}M!|Io#&%6iMs@6FH-1X2e=5Stdmr^78O$qzB0z{~tjZw#x
zBR}!=@n(W`q+0M82R^;55S#I#U5V0h;g0Qwk0s4w6UayyG{(Kw6zSOVGY0Zf5ZL7h
zU+nDD;&1dCb<}+M(Xu5Hc3``xme(u!hng}LecVII+qR42HYb@%gdA3RHu3QRJG;%1
zNqw;d7{75^4Cdpq+_8B4_vGMbhol!&X^0)rt@8sd$akQp>B#Vt`Vw&md&l~Yy@7`E
zSF+?jciC3iL2q7uZ3a>R6urVy`$<Bz2I~C%&alaM95B#nSbXz-oZ}C25O=0N)2^iW
z8(X-ISE=qbq3ib7v#$@ZptB*k!<l3Ee5+5}?DAxRYmW_i(*xH2G4|VZxqJJdjh*A<
z{_Zr|s72wj7n#~Bn>X+CVMfNYM4v^<uZ7)~Zqr#^Ec*VX<=@P?t%$evzHgY>04jBn
z-9+!rnEL>Pz~}e!7*81-Mdm3}Ew3t9y_6Q0?B?7CvW#w>|3%Cn@D&~KRdIQS$9OkG
z4XNq-*#NlC)(Chmq~R}hRl<<UXk>h0#7d(j`_wa080cna`B!~`BJLV2-7qFNTe8=P
zEC{GB!oi@~NC6j9{w>WQHZ0ZPw=8;#qy-3!4_?Q97YD@3<Pc8{(N1HIcLEB2Rbw>a
zrk40wchpk|#D00S&)zq%VP|M*u<x}^m|8=md+VMTRwewW(8%8-JHyODK-fv0lgrhk
zMnHoQgja^`iQCQ<Or)e@$JC?7Et#;;5lVI%H-BW{Twe`Kfuyxm+d~h&e*gn4%Cs!~
zp4^Hm;OL<H1P_f!lgqOWdXuDL;FxJo`Yh4(S$|yb!bP4k%Qe8Wn3XZlo!{T?ZvcIL
z%{)^xPvuQ=k6ryLpPJ90dN9N5g@({+6o@<-PAjQ#l<G*Xt2plEsyZQfLA00)HQfi!
zJ2X`FU^9$4l)*D&=X6&(obyWeI1n4$Z2Voj)*0YPVYuPJOsIz;l&G*YgS(M2D$p*$
zyRNEGq$efEJEL-e^0n048KEro2O}{OxhsVNL@<#{T=&&#f|rID*L%#n8YL6dC4O@h
zL7+3@f5)u<{Qi<6bTm5kME2u%e2EE~7W0aasqJSPa(Hf0CcLqn478)yUz>@~zdCzo
zyu>AOX-p)YccXg3VYnx@e8NwDo?exG1SBYx>1K=z+aV@z>-J=%;;0~oKSASX(xW3Y
zndDo)<xwt-AH{(d=io}SXddaAQDP9Q(f@#V7qlBgrChjb)|2HLrfy_K^6?3=)-xTj
z?ib;5UQS&FhUc)zmbwAhem($#&6-32%#=r9r%kyr{p$QkLxUEe(G7ijdTA(@M=~?M
zM3`6*O$>&j)8q~Y3Cd$>+={NMQpjoaub=<^y=;NK0>{(JKGOZus#H=Oq1CtMjC=u2
zQ9;II{?<U%YoMWXp7O77Oc6PM%fdri)^>(`<(%u~5Aa$!OA&6_jGuBHJBVdBjEH5t
zwfRx1t&m>B{`Oo}_qvd8?bsjAWo2b$R#)&ySU+>8Pm}5hFlxs{5gi8{4mZ_PFZwqX
zl4ZG~$9{4GAH{MIkkE69d-bdMXP;9t85jHbtkAXiM~VH-|6n?aY*9%W#5%1#z{GgJ
zG1pIFjzpkQ3rx@vIQK4<PU)+;b%aLwxN##})qAjhXK`*5&_^%NgE&m7waZL3eKmv|
z#1nNU0@Dq)n3m^W$rIe<JEqbax2}gdr0#VpUSYcrKF>ghOaq!K-S#s8J-#mB=~~sj
z>db5YFY0er#{#4(6+ydfxF_B5Hq`BW)hGPdV#@&bFzpiB=Wvk7;NQhIU>Er!1xc&h
z?^9wobQq_8mm=ziMrFac-~$$5gz&qUb1?KrXZk+jIbT9@yPKKwET<N*bSvB_x)2c&
zrxkhCx$O;?b4I1?9CK@<dgbJQf4($oLRx((6_PFG>Qln@mhaM42^EA6N|g27G&Aa=
zY;eX|qdQ-oeqR_l?LL3TeY&<)wPj{|&(cTeKSgL#2y|d_tfe5fywcV!ik@Tnxwe>#
zl2h07|8wt#%{xRSckW?RC*1R+=z@mF){Vk;?NS60&i^g$Oe7(&vq5$#_k{1|4xOoO
z?<edZJ4)I48e9i924DmA;0R{LKmfL{q-OYQF!#M;0m(*@<ag%+<5bgF>#qkPkUt^5
z1}$0lnp2eZ=ZtIQcy}SUacgb6OtzAX<uk&HRIE<qvDHx*(kkICvw(P*L}_*y>B4`G
z@2<Lf8ff3y>p>S5@M@Hx1MA*bQ!sRGT*cY!2e+w{+b2ri_x}HK(qZ#Xt9F5A&PeQB
z`&rGEPxw<mk|KJVtJ_EQt^Rusf23ldQZ?TZl&F<>M<4n2x19~YuyK1{c7T?^r4p$+
znlT3ocYP+Aa@|}JlL6PbqI8}tj8ufx8a_<q9$>B3fUN5_MOAuuTQHjL^z6}7_3|sm
z1uPNyp~zzHGP-cX%Wi)O=QsrepyI`gowxESO{9|#FR1;u=MqLP@uz0bSegxOvljuq
zc{n{d=fLBbZv!AZfHAlQpqmN)Xp+C%h>en=X5}Zmg;b~G`bvQWD(M8PiNZ1<DB~$7
ztq%066>9PqOcl+ChP*q5zP@8SJ<z54XOZxSRN3MMtQWugv&XkxRS(S`Dp~i-8Q0vw
zu^z#iChgUAcK5DU8)Y$thtHidUyJ|X!3UN7<jeZdLj(i@2s{c)_3+R(ogQ}|vlaTv
z;GV)$US2xY*N@^;GkjN61`tJ}t^@*~Vb?q>yc;S}S3;GKsu4LK_%CMrZu$80d)Zt6
ziH<*V)1JDS_th|qT*!%@Meu+JLDuY9CAd@fx`{{8te6A%-eBwU;{Z`+%^>Y~%-Lx#
z{lK&tMrg5w<g|7u4F=MODjBIciFTZ37-^@cw#*lWC)O14_YyjvrA>8_32G11_x{Ar
z0tunK*gb=s%#toNbCrmyAsJ?<bJ-$=^p^S!tXO?~Flj&N=K4m4blXv~ESBjMRTH(D
zp)Oi{vuYXh0-2HuTwFki1W{%74?at^olzZbO5X-B_V#&lXofno&xf-9z0O#Lr7#3T
z-GFWi7UM+R0t~qyi4o7LL0<0rkOH{&atm7q85<v$Syim-3KhN8KZcyNiB2thaS=$}
zFUBM5u{qvjM};)rDcB%t0iXykctq7&4JR4^g}K$0@7uLXHZqlX_MP%_9Xk)(6xPIz
zQ4o9KU)%;YyD~<Z?VcV1cLoHXHY;4brWaJssvl#`NNNA&Z}T-OGxghxqMsbZtpe5U
z&;8)9|J}gHulFY}Or%^&GdMePB~yPnk6sk-5aBNQ>20ZPgmGAUdZJvPH3~<h^IXoY
z)EK-8`BLxlgP4ZU{5LV5I&CZ)Eb)`p$-F>3pev>X!w=74rCNfUnnvXYNC1Y`M0yhB
z@Wm4EqPAKd=7S6~2A^{)CrGRF#`Xe|KLHRfgdNADk}q3NIC|#Mt%O0MYe47RyDgFK
zGMp=Ky?{G}<Yh&L0lk=6#ksicj`VTXAUq+MzI9C6o-Znj9`U@UzsRuU*T@kIZ47I!
zFI6GgH)pU&cS2wqpm;>lJ)hK!|8QNXZ>N*h<Q6-;r%|l<|BIm2%-c4V-t6*I4wC-x
zJRngcs;WC|+S=x89eLr>%LJe_1d2I5Dx1(qniv{sFqXDu4u!9wufeu)<Ac_GS7R=o
z`bL%$27?g~V7F~1Zjn|?_K)L8#}I$ZQ^b>r;htI*I=n&7x;7T4Sk)y4Ts@*0mz-k#
zx&K*9Bb}X&ME;NooX3%;OLpUU7s|O=2Z8Pt#E;gp_P|cfubqyT7gR_=e)1I4*TvX@
z2Uj*elXZ%3LVH=Olry0ASyZvt=E|oL7d`?Vo3QXezO<*-E|2L=RQ;bD$RL{9qf&4@
z-=S_wH?yR9csRJ~T7a2Vty%ZfBWYG{yyS-v_+~wtT<HPUmGj17bq;L_#>c-EdfV&!
zm%H`HW=64uHuvB(l`2o;B+r88$zS){Vl^bZQ+32RA8K%68l^fwReaYQ^{ctdoiF_O
zi(%%o9{wP&ov@~J?kT6my$(M9xd&hv>hNCzF9JGAL5qlDWZUUHKt*Wx<TvGXWW2G&
zFcm~jnnqt?<vWSG=HKV^pct3h<G1pVC&0j7fj|{jT&pi_(dy#ymhHH&+X1IhTG6)J
zP|F0Lc4fB&pMm-E%g;P1%w3{H&)voRPshRg=w+y{+@3sgqRD+q@@@+tg~a?-n=)I@
z{@rD=&Lp|NSRv9_1YQ7MBG>|B+(ZpDL>>dWiZ;V5<DsBV;*UfM@6H0F1q^fux`lYv
z=V8w?+qz4k3t|A<;~7l>gKraYIh;0u=2bgx(xwDbzYbQ_9%z5GUN&F2!HgQK5$;{p
z?iQa*m}xd>>ZYi!9sxC^1<AJRF>HOs#@CYze)9a7r^g)C{%J@~J%iA-#83r?c+z#?
z_qew9kC{5sG9g%0H}mIExWHT>Hv=^g2K=`w*mVH8leHttXw2J~&Lhkh%?lIv+6w2R
zDo=C8NWaqaV+X9<SA9Mriwd1`K?DKi<~OZmp;rf)c~{7TpI!6#&A&Q<={|>5wJpx^
z-hHq5{MgkFykSSvug1_k!>%f;-UtQYGKF?k_BHQ_A;M|yb0hNM&IeJYk;W<jK5fPK
z57nmVMwkfUAKT;(56Az77UNcguDLHXAt#RCaKG>+9S6Kkgsz32Gk#*8vY|>ik(%0A
zE$~)53})LpiIr}NFv**nS<h_GmcPxMkMv&iaenpNjO@^C18+>GvI&Hd#y`gT3ul-5
zXA3CXbt?5~T(~!E&$(-{5}{Z{syugsEAl1}O(xjKvR3bYt@5=uV>mzonX;0TR*#2$
zpbS!+R)m}Q5kY+YEZ?#~m1QQ`4x6-aK~CQkOkdvn_y2sbPq_N3fSJ~dSY0((qc0o=
zOt-f5n&zZhN{`qblWvX%q^pc{j#e|oI;6M_b}z>bivfGX{TBo^vBQT;8i7COFpZZ4
zwowVM`R{*4{t~pg!F<wCNK=SXD1t)0#DQi9XInvNsr2#_L}LLnBcoH{p}h3Bp^4wU
zEbp+#rf~IRkO+9D*vPZrdB_R1J^2(X7F)>7t%Pkf6~^%3*->jc$~(YjaRj3;Rs=Td
z?SbuX5iE=TA%)R)aXb3#4*c9PjL8$N7IV}zmd_jT!C01CWrbHGihhqECpNZH%lM%2
zV8!uSWrZ*(@)p5==bxq}c}_*~qb6cN&C}J|EyO1Z%+x0DKmk$&<`^B<xCJ*ZV825_
ztY?w6TOV^F2U5(axn<#3S3F27`2|{W5g&nh-Gj;O;_uSm94E?f;_7;DZxrV=(<_j_
zjS~(;o3x}_d|&WE!*{TNyOJSW2prQGxx*LjS0tLm$)F1z56Zg*1RJrMUZ4?!?v*B<
zwabVYzms9i%t-yo+hsHV%9yC@fS?_AXt2pSrR;>XlP%L?-L$`|EhSE+>8fQ&$|@w-
z?b=~vPV>O@fl~IfeS}p7Gw}u3WG58}G!o44a1(ZnwG^#e6vtWB<cr$Qf>nA?+F<)n
zx0h@yu)VdjS0=w0+i$=F7}vGk_Du`8QcYyOdCCWoGw)`mDnVtas=*slq!sLp|4H9x
z2EdKa>P`WTAMww*8nlBSUX|f61WfR7RFCoP2jf?oUP!fQ-G7s`D*lZZT;uZk^Q9aR
zL}i_jw?x<nx6<MhdW9y^WmXCF56#xnjkN(eKWr1;I>Q706*_bJIkuod&KdUv_j2Jo
zcn_RJmc4lCeG~uAkG^*U7y*JPCg6Kqu3m&9XL1?gkH+nIjTEXZrE~$wj8OgCq^X%t
z^x=sH##vxm2YAWwfGhTFlt)rx$*PtjPeVdgIlsw<UFWts5!B{MaA}VU`QNxUX~iQ9
zbjG!yIgM`pH%~ak5~CQ;Av$KtvOk763f&13a2juB4<9bp(=^umf-Dr~2F&Ub!cgP7
z;!xylJ;PJN``PSMvi8hrxH6}2+h&7er*)3FxD)>k=d&lFM?l6M=`NG>f=T^woJd9d
zqr~~0sgpY8slQ8?LeG<Cj?~DBdnCt3omcYV1%+{Z`tvXhm1I$!MA&Q$Hha17u3Dlw
zS}f|s{QfdW(-v7nd_N{Cgb=H0!3UGLL_}HKd<4CeudC}e<P=2vBqT$N`4OkekO`43
zv&GQnOwV{e3v-s>shUKAmu4a$C;f96o~EmNzb-GO_xS7}a}V2+`$cN0ZDt#q!{dfn
z-tmfx>|(LiJ~;pyoBk6B1hF~H_#r8@FjoG*5$^);o_HB~TE)YlhTw;8-kSl{OUTi9
hh8d_e1+nD=$V|w|6dO9B6L`NKGQpS`ywP{L|9?N3T;%`&

diff --git a/assets/images/moonpay_light.png b/assets/images/moonpay_light.png
index c76ae6e74ec7e578874528b4c670ca4829be5647..3d3de2e4f17670fec4f60e869ad7b8151e37e202 100644
GIT binary patch
literal 13866
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

literal 20800
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

diff --git a/assets/images/trocador.png b/assets/images/trocador.png
index 67c9f221c8586f309e22acf4853735ffdd4c3e15..37e643de48f76cb0938d9cdab0f81daf84997176 100644
GIT binary patch
literal 28127
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

literal 10417
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
BizEO5

diff --git a/cw_haven/android/build.gradle b/cw_haven/android/build.gradle
index fb941f657..87e8df641 100644
--- a/cw_haven/android/build.gradle
+++ b/cw_haven/android/build.gradle
@@ -5,7 +5,7 @@ buildscript {
     ext.kotlin_version = '1.7.10'
     repositories {
         google()
-        jcenter()
+        mavenCentral()
     }
 
     dependencies {
@@ -17,7 +17,7 @@ buildscript {
 rootProject.allprojects {
     repositories {
         google()
-        jcenter()
+        mavenCentral()
     }
 }
 
diff --git a/cw_shared_external/android/build.gradle b/cw_shared_external/android/build.gradle
index 8db51f0e6..64b550364 100644
--- a/cw_shared_external/android/build.gradle
+++ b/cw_shared_external/android/build.gradle
@@ -5,7 +5,7 @@ buildscript {
     ext.kotlin_version = '1.7.10'
     repositories {
         google()
-        jcenter()
+        mavenCentral()
     }
 
     dependencies {
@@ -17,7 +17,7 @@ buildscript {
 rootProject.allprojects {
     repositories {
         google()
-        jcenter()
+        mavenCentral()
     }
 }
 
diff --git a/lib/src/screens/support_other_links/support_other_links_page.dart b/lib/src/screens/support_other_links/support_other_links_page.dart
index 681a44f8f..7a1a945ca 100644
--- a/lib/src/screens/support_other_links/support_other_links_page.dart
+++ b/lib/src/screens/support_other_links/support_other_links_page.dart
@@ -7,6 +7,7 @@ import 'package:cake_wallet/view_model/settings/regular_list_item.dart';
 import 'package:cake_wallet/view_model/support_view_model.dart';
 import 'package:flutter/material.dart';
 import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 
 class SupportOtherLinksPage extends BasePage {
@@ -22,8 +23,11 @@ class SupportOtherLinksPage extends BasePage {
 
   @override
   Widget body(BuildContext context) {
+
     final iconColor = Theme.of(context).extension<SupportPageTheme>()!.iconColor;
 
+    final isLightMode = Theme.of(context).extension<OptionTileTheme>()?.useDarkImage ?? false;
+
     return Container(
       child: Center(
         child: ConstrainedBox(
@@ -37,16 +41,16 @@ class SupportOtherLinksPage extends BasePage {
                 if (item is RegularListItem) {
                   return SettingsCellWithArrow(title: item.title, handler: item.handler);
                 }
-
                 if (item is LinkListItem) {
+                  bool hasLightIcon = false;
+                  if (item.lightIcon != null) hasLightIcon = true;
                   return SettingsLinkProviderCell(
                       title: item.title,
-                      icon: item.icon,
+                      icon: isLightMode && hasLightIcon ? item.lightIcon : item.icon,
                       iconColor: item.hasIconColor ? iconColor : null,
                       link: item.link,
                       linkTitle: item.linkTitle);
                 }
-
                 return Container();
               }),
         ),
diff --git a/lib/view_model/settings/link_list_item.dart b/lib/view_model/settings/link_list_item.dart
index 4ee4162a9..8d7607eb5 100644
--- a/lib/view_model/settings/link_list_item.dart
+++ b/lib/view_model/settings/link_list_item.dart
@@ -8,10 +8,12 @@ class LinkListItem extends SettingsListItem {
         required this.link,
         required this.linkTitle,
         this.icon,
+        this.lightIcon,
         this.hasIconColor = false})
       : super(title);
 
   final String? icon;
+  final String? lightIcon;
   final String link;
   final String linkTitle;
   final bool hasIconColor;
diff --git a/lib/view_model/support_view_model.dart b/lib/view_model/support_view_model.dart
index ccef76154..2bb749b42 100644
--- a/lib/view_model/support_view_model.dart
+++ b/lib/view_model/support_view_model.dart
@@ -33,11 +33,6 @@ abstract class SupportViewModelBase with Store {
           icon: 'assets/images/Telegram.png',
           linkTitle: '@cakewallet_bot',
           link: 'https://t.me/cakewallet_bot'),
-      LinkListItem(
-          title: 'Twitter',
-          icon: 'assets/images/Twitter.png',
-          linkTitle: '@cakewallet',
-          link: 'https://twitter.com/cakewallet'),
       LinkListItem(
           title: 'ChangeNow',
           icon: 'assets/images/change_now.png',
@@ -46,7 +41,7 @@ abstract class SupportViewModelBase with Store {
     LinkListItem(
         title: 'SideShift',
         icon: 'assets/images/sideshift.png',
-        linkTitle: S.current.help,
+        linkTitle: 'help.sideshift.ai',
         link: 'https://help.sideshift.ai/en/'),
     LinkListItem(
         title: 'SimpleSwap',
@@ -58,19 +53,41 @@ abstract class SupportViewModelBase with Store {
         icon: 'assets/images/exolix.png',
         linkTitle: 'support@exolix.com',
         link: 'mailto:support@exolix.com'),
-      if (!isMoneroOnly) ... [    
-         LinkListItem(
-     title: 'Wyre',
-             icon: 'assets/images/wyre.png',
-             linkTitle: S.current.submit_request,
-             link: 'https://wyre-support.zendesk.com/hc/en-us/requests/new'),
+    LinkListItem(
+        title: 'Quantex',
+        icon: 'assets/images/quantex.png',
+        linkTitle: 'help.myquantex.com',
+        link: 'mailto:support@exolix.com'),
+    LinkListItem(
+        title: 'Trocador',
+        icon: 'assets/images/trocador.png',
+        linkTitle: 'mail@trocador.app',
+        link: 'mailto:mail@trocador.app'),
+    LinkListItem(
+        title: 'Onramper',
+        icon: 'assets/images/onramper_dark.png',
+        lightIcon: 'assets/images/onramper_light.png',
+        linkTitle: 'View exchanges',
+        link: 'https://guides.cakewallet.com/docs/service-support/buy/#onramper'),
+    LinkListItem(
+        title: 'DFX',
+        icon: 'assets/images/dfx_dark.png',
+        lightIcon: 'assets/images/dfx_light.png',
+        linkTitle: 'support@dfx.swiss',
+        link: 'mailto:support@dfx.swiss'),
+      if (!isMoneroOnly) ... [
    LinkListItem(
      title: 'MoonPay',
              icon: 'assets/images/moonpay.png',
-             hasIconColor: true,
              linkTitle: S.current.submit_request,
-             link: 'https://support.moonpay.com/hc/en-gb/requests/new')
-    ]
+             link: 'https://support.moonpay.com/hc/en-gb/requests/new'),
+    LinkListItem(
+        title: 'Robinhood Connect',
+        icon: 'assets/images/robinhood_dark.png',
+        lightIcon: 'assets/images/robinhood_light.png',
+        linkTitle: S.current.submit_request,
+        link: 'https://robinhood.com/contact')
+  ]
       //LinkListItem(
       //    title: 'Yat',
       //    icon: 'assets/images/yat_mini_logo.png',

From 29492998216ec65a5b986a8ca168c97a2b68f727 Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Tue, 13 Aug 2024 14:15:31 +0200
Subject: [PATCH 29/81] unstoppable domains fix (#1600)

---
 android/app/build.gradle                      |  1 -
 .../cakewallet/cake_wallet/MainActivity.java  | 29 -------------------
 .../com/cakewallet/haven/MainActivity.java    | 29 -------------------
 .../java/com/monero/app/MainActivity.java     | 29 -------------------
 ios/Podfile                                   |  1 -
 ios/Runner/AppDelegate.swift                  | 23 +--------------
 lib/entities/unstoppable_domain_address.dart  | 27 +++++++++--------
 7 files changed, 16 insertions(+), 123 deletions(-)

diff --git a/android/app/build.gradle b/android/app/build.gradle
index 60defb1fd..2f5427531 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -91,5 +91,4 @@ dependencies {
     testImplementation 'junit:junit:4.12'
     androidTestImplementation 'androidx.test:runner:1.3.0'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
-    implementation 'com.unstoppabledomains:resolution:5.0.0'
 }
diff --git a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java
index 29b37c46c..df3f6be01 100644
--- a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java
+++ b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java
@@ -20,14 +20,10 @@ import android.net.Uri;
 import android.os.PowerManager;
 import android.provider.Settings;
 
-import com.unstoppabledomains.resolution.DomainResolution;
-import com.unstoppabledomains.resolution.Resolution;
-
 import java.security.SecureRandom;
 
 public class MainActivity extends FlutterFragmentActivity {
     final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
-    final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
     boolean isAppSecure = false;
 
     @Override
@@ -53,14 +49,6 @@ public class MainActivity extends FlutterFragmentActivity {
                     random.nextBytes(bytes);
                     handler.post(() -> result.success(bytes));
                     break;
-                case "getUnstoppableDomainAddress":
-                    int version = Build.VERSION.SDK_INT;
-                    if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
-                        getUnstoppableDomainAddress(call, result);
-                    } else {
-                        handler.post(() -> result.success(""));
-                    }
-                    break;
                 case "setIsAppSecure":
                     isAppSecure = call.argument("isAppSecure");
                     if (isAppSecure) {
@@ -85,23 +73,6 @@ public class MainActivity extends FlutterFragmentActivity {
         }
     }
 
-    private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
-        DomainResolution resolution = new Resolution();
-        Handler handler = new Handler(Looper.getMainLooper());
-        String domain = call.argument("domain");
-        String ticker = call.argument("ticker");
-
-        AsyncTask.execute(() -> {
-            try {
-                String address = resolution.getAddress(domain, ticker);
-                handler.post(() -> result.success(address));
-            } catch (Exception e) {
-                System.out.println("Expected Address, but got " + e.getMessage());
-                handler.post(() -> result.success(""));
-            }
-        });
-    }
-
     private void disableBatteryOptimization() {
         String packageName = getPackageName();
         PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
diff --git a/android/app/src/main/java/com/cakewallet/haven/MainActivity.java b/android/app/src/main/java/com/cakewallet/haven/MainActivity.java
index d0a465d22..83a790683 100644
--- a/android/app/src/main/java/com/cakewallet/haven/MainActivity.java
+++ b/android/app/src/main/java/com/cakewallet/haven/MainActivity.java
@@ -19,14 +19,10 @@ import android.net.Uri;
 import android.os.PowerManager;
 import android.provider.Settings;
 
-import com.unstoppabledomains.resolution.DomainResolution;
-import com.unstoppabledomains.resolution.Resolution;
-
 import java.security.SecureRandom;
 
 public class MainActivity extends FlutterFragmentActivity {
     final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
-    final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
 
     @Override
     public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
@@ -51,14 +47,6 @@ public class MainActivity extends FlutterFragmentActivity {
                     random.nextBytes(bytes);
                     handler.post(() -> result.success(bytes));
                     break;
-                case "getUnstoppableDomainAddress":
-                    int  version = Build.VERSION.SDK_INT;
-                    if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
-                        getUnstoppableDomainAddress(call, result);
-                    } else {
-                        handler.post(() -> result.success(""));
-                    }
-                    break;
                 case "disableBatteryOptimization":
                     disableBatteryOptimization();
                     handler.post(() -> result.success(null));
@@ -75,23 +63,6 @@ public class MainActivity extends FlutterFragmentActivity {
         }
     }
 
-    private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
-        DomainResolution resolution = new Resolution();
-        Handler handler = new Handler(Looper.getMainLooper());
-        String domain = call.argument("domain");
-        String ticker = call.argument("ticker");
-
-        AsyncTask.execute(() -> {
-            try {
-                String address = resolution.getAddress(domain, ticker);
-                handler.post(() -> result.success(address));
-            } catch (Exception e) {
-                System.out.println("Expected Address, but got " + e.getMessage());
-                handler.post(() -> result.success(""));
-            }
-        });
-    }
-
     private void disableBatteryOptimization() {
         String packageName = getPackageName();
         PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
diff --git a/android/app/src/main/java/com/monero/app/MainActivity.java b/android/app/src/main/java/com/monero/app/MainActivity.java
index 49c368ec7..e6306d27b 100644
--- a/android/app/src/main/java/com/monero/app/MainActivity.java
+++ b/android/app/src/main/java/com/monero/app/MainActivity.java
@@ -19,14 +19,10 @@ import android.net.Uri;
 import android.os.PowerManager;
 import android.provider.Settings;
 
-import com.unstoppabledomains.resolution.DomainResolution;
-import com.unstoppabledomains.resolution.Resolution;
-
 import java.security.SecureRandom;
 
 public class MainActivity extends FlutterFragmentActivity {
     final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
-    final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
     boolean isAppSecure = false;
 
     @Override
@@ -52,14 +48,6 @@ public class MainActivity extends FlutterFragmentActivity {
                     random.nextBytes(bytes);
                     handler.post(() -> result.success(bytes));
                     break;
-                case "getUnstoppableDomainAddress":
-                    int version = Build.VERSION.SDK_INT;
-                    if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
-                        getUnstoppableDomainAddress(call, result);
-                    } else {
-                        handler.post(() -> result.success(""));
-                    }
-                    break;
                 case "setIsAppSecure":
                     isAppSecure = call.argument("isAppSecure");
                     if (isAppSecure) {
@@ -84,23 +72,6 @@ public class MainActivity extends FlutterFragmentActivity {
         }
     }
 
-    private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
-        DomainResolution resolution = new Resolution();
-        Handler handler = new Handler(Looper.getMainLooper());
-        String domain = call.argument("domain");
-        String ticker = call.argument("ticker");
-
-        AsyncTask.execute(() -> {
-            try {
-                String address = resolution.getAddress(domain, ticker);
-                handler.post(() -> result.success(address));
-            } catch (Exception e) {
-                System.out.println("Expected Address, but got " + e.getMessage());
-                handler.post(() -> result.success(""));
-            }
-        });
-    }
-
     private void disableBatteryOptimization() {
         String packageName = getPackageName();
         PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
diff --git a/ios/Podfile b/ios/Podfile
index 51622ff10..f0a0721a6 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -36,7 +36,6 @@ target 'Runner' do
 
   # Cake Wallet (Legacy)
   pod 'CryptoSwift'
-  pod 'UnstoppableDomainsResolution', '~> 4.0.0'
 end
 
 post_install do |installer|
diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift
index acdfa4346..0cc4eebe8 100644
--- a/ios/Runner/AppDelegate.swift
+++ b/ios/Runner/AppDelegate.swift
@@ -1,6 +1,5 @@
 import UIKit
 import Flutter
-import UnstoppableDomainsResolution
 import workmanager
 
 @UIApplicationMain
@@ -87,27 +86,7 @@ import workmanager
                 }
 
                 result(secRandom(count: count))
-            case "getUnstoppableDomainAddress":
-                guard let args = call.arguments as? Dictionary<String, String>,
-                      let domain = args["domain"],
-                      let ticker = args["ticker"],
-                      let resolution = self?.resolution else {
-                    result(nil)
-                    return
-                }
-                        
-                resolution.addr(domain: domain, ticker: ticker) { addrResult in
-                  var address : String = ""
-                    
-                  switch addrResult {
-                      case .success(let returnValue):
-                        address = returnValue
-                      case .failure(let error):
-                        print("Expected Address, but got \(error)")
-                    }
-                    
-                    result(address)
-                }
+
             case "setIsAppSecure":
                 guard let args = call.arguments as? Dictionary<String, Bool>,
                     let isAppSecure = args["isAppSecure"] else {
diff --git a/lib/entities/unstoppable_domain_address.dart b/lib/entities/unstoppable_domain_address.dart
index c5ec71ab5..0f56517b8 100644
--- a/lib/entities/unstoppable_domain_address.dart
+++ b/lib/entities/unstoppable_domain_address.dart
@@ -1,5 +1,7 @@
-import 'package:cake_wallet/utils/device_info.dart';
+import 'dart:convert';
+
 import 'package:flutter/services.dart';
+import 'package:http/http.dart' as http;
 
 const channel = MethodChannel('com.cake_wallet/native_utils');
 
@@ -7,18 +9,19 @@ Future<String> fetchUnstoppableDomainAddress(String domain, String ticker) async
   var address = '';
 
   try {
-    if (DeviceInfo.instance.isMobile) {
-      address = await channel.invokeMethod<String>(
-          'getUnstoppableDomainAddress',
-          <String, String> {
-            'domain' : domain,
-            'ticker' : ticker
-          }
-      ) ?? '';
-    } else {
-      // TODO: Integrate with Unstoppable domains resolution API
-      return address;
+    final uri = Uri.parse("https://api.unstoppabledomains.com/profile/public/${Uri.encodeQueryComponent(domain)}?fields=records");
+    final jsonString = await http.read(uri);
+    final jsonParsed = json.decode(jsonString) as Map<String, dynamic>;
+    if (jsonParsed["records"] == null) {
+      throw Exception(".records response from $uri is empty");
+    };
+    final records = jsonParsed["records"] as Map<String, dynamic>;
+    final key = "crypto.${ticker.toUpperCase()}.address";
+    if (records[key] == null) {
+      throw Exception(".records.${key} response from $uri is empty");
     }
+
+    return records[key] as String? ?? '';
   } catch (e) {
     print('Unstoppable domain error: ${e.toString()}');
     address = '';

From 4b69277858a75ea3beafb268eb9f4c60cef9f070 Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Tue, 13 Aug 2024 15:47:37 +0200
Subject: [PATCH 30/81] add mutex around _confirmForm to prevent the wallets
 from breaking (#1602)

* add mutex around _confirmForm to prevent the wallets from breaking

* add async

* drop mutex for a boolean

* don't make the variable global
---
 .../screens/new_wallet/new_wallet_page.dart   |  49 +++---
 .../screens/restore/wallet_restore_page.dart  | 139 ++++++++++--------
 2 files changed, 106 insertions(+), 82 deletions(-)

diff --git a/lib/src/screens/new_wallet/new_wallet_page.dart b/lib/src/screens/new_wallet/new_wallet_page.dart
index b66aab4cf..cd5a7ce8d 100644
--- a/lib/src/screens/new_wallet/new_wallet_page.dart
+++ b/lib/src/screens/new_wallet/new_wallet_page.dart
@@ -25,6 +25,7 @@ import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
 import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
 import 'package:cake_wallet/entities/seed_type.dart';
 
+
 class NewWalletPage extends BasePage {
   NewWalletPage(this._walletNewVM, this._seedTypeViewModel);
 
@@ -74,6 +75,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
             _walletNewVM.hasWalletPassword ? TextEditingController() : null;
 
   static const aspectRatioImage = 1.22;
+  static bool formProcessing = false;
 
   final GlobalKey<FormState> _formKey;
   final GlobalKey<SeedLanguageSelectorState> _languageSelectorKey;
@@ -347,26 +349,35 @@ class _WalletNameFormState extends State<WalletNameForm> {
     );
   }
 
-  void _confirmForm() {
-    if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
-      return;
-    }
-    if (_walletNewVM.nameExists(_walletNewVM.name)) {
-      showPopUp<void>(
-          context: context,
-          builder: (_) {
-            return AlertWithOneAction(
-                alertTitle: '',
-                alertContent: S.of(context).wallet_name_exists,
-                buttonText: S.of(context).ok,
-                buttonAction: () => Navigator.of(context).pop());
-          });
-    } else {
-      _walletNewVM.create(
-          options: _walletNewVM.hasLanguageSelector
-              ? [_languageSelectorKey.currentState!.selected, isPolyseed]
-              : null);
+  void _confirmForm() async {
+    if (formProcessing) return;
+    formProcessing = true;
+    try {
+      if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
+        formProcessing = false;
+        return;
+      }
+      if (_walletNewVM.nameExists(_walletNewVM.name)) {
+        await showPopUp<void>(
+            context: context,
+            builder: (_) {
+              return AlertWithOneAction(
+                  alertTitle: '',
+                  alertContent: S.of(context).wallet_name_exists,
+                  buttonText: S.of(context).ok,
+                  buttonAction: () => Navigator.of(context).pop());
+            });
+      } else {
+        await _walletNewVM.create(
+            options: _walletNewVM.hasLanguageSelector
+                ? [_languageSelectorKey.currentState!.selected, isPolyseed]
+                : null);
+      }
+    } catch (e) {
+      formProcessing = false;
+      rethrow;
     }
+    formProcessing = false;
   }
 
   bool get isPolyseed => widget._seedTypeViewModel.moneroSeedType == SeedType.polyseed;
diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart
index cd6383c0d..29bc29986 100644
--- a/lib/src/screens/restore/wallet_restore_page.dart
+++ b/lib/src/screens/restore/wallet_restore_page.dart
@@ -2,6 +2,7 @@ import 'package:cake_wallet/core/execution_state.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart';
 import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.dart';
 import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
@@ -80,6 +81,8 @@ class WalletRestorePage extends BasePage {
     });
   }
 
+  static bool formProcessing = false;
+
   @override
   Widget middle(BuildContext context) => Observer(
       builder: (_) => Text(
@@ -350,75 +353,85 @@ class WalletRestorePage extends BasePage {
   }
 
   Future<void> _confirmForm(BuildContext context) async {
-    // Dismissing all visible keyboard to provide context for navigation
-    FocusManager.instance.primaryFocus?.unfocus();
+    if (formProcessing) return;
+    formProcessing = true;
+    try {
+      // Dismissing all visible keyboard to provide context for navigation
+      FocusManager.instance.primaryFocus?.unfocus();
 
-    late BuildContext? formContext;
-    late GlobalKey<FormState>? formKey;
-    late String name;
-    if (walletRestoreViewModel.mode == WalletRestoreMode.seed) {
-      formContext = walletRestoreFromSeedFormKey.currentContext;
-      formKey = walletRestoreFromSeedFormKey.currentState!.formKey;
-      name = walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.value.text;
-    } else if (walletRestoreViewModel.mode == WalletRestoreMode.keys) {
-      formContext = walletRestoreFromKeysFormKey.currentContext;
-      formKey = walletRestoreFromKeysFormKey.currentState!.formKey;
-      name = walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.value.text;
-    }
-
-    if (!formKey!.currentState!.validate()) {
-      return;
-    }
-
-    if (walletRestoreViewModel.nameExists(name)) {
-      showNameExistsAlert(formContext!);
-      return;
-    }
-
-    walletRestoreViewModel.state = IsExecutingState();
-
-    DerivationInfo? dInfo;
-
-    // get info about the different derivations:
-    List<DerivationInfo> derivations =
-        await walletRestoreViewModel.getDerivationInfo(_credentials());
-
-    int derivationsWithHistory = 0;
-    int derivationWithHistoryIndex = 0;
-    for (int i = 0; i < derivations.length; i++) {
-      if (derivations[i].transactionsCount > 0) {
-        derivationsWithHistory++;
-        derivationWithHistoryIndex = i;
+      late BuildContext? formContext;
+      late GlobalKey<FormState>? formKey;
+      late String name;
+      if (walletRestoreViewModel.mode == WalletRestoreMode.seed) {
+        formContext = walletRestoreFromSeedFormKey.currentContext;
+        formKey = walletRestoreFromSeedFormKey.currentState!.formKey;
+        name = walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.value.text;
+      } else if (walletRestoreViewModel.mode == WalletRestoreMode.keys) {
+        formContext = walletRestoreFromKeysFormKey.currentContext;
+        formKey = walletRestoreFromKeysFormKey.currentState!.formKey;
+        name = walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.value.text;
       }
-    }
 
-    if (derivationsWithHistory > 1) {
-      dInfo = await Navigator.of(context).pushNamed(
-        Routes.restoreWalletChooseDerivation,
-        arguments: derivations,
-      ) as DerivationInfo?;
-    } else if (derivationsWithHistory == 1) {
-      dInfo = derivations[derivationWithHistoryIndex];
-    }
-
-    // get the default derivation for this wallet type:
-    if (dInfo == null) {
-      // we only return 1 derivation if we're pretty sure we know which one to use:
-      if (derivations.length == 1) {
-        dInfo = derivations.first;
-      } else {
-        // if we have multiple possible derivations, and none have histories
-        // we just default to the most common one:
-        dInfo = walletRestoreViewModel.getCommonRestoreDerivation();
+      if (!formKey!.currentState!.validate()) {
+        formProcessing = false;
+        return;
       }
-    }
 
-    this.derivationInfo = dInfo;
-    if (this.derivationInfo == null) {
-      this.derivationInfo = walletRestoreViewModel.getDefaultDerivation();
-    }
+      if (walletRestoreViewModel.nameExists(name)) {
+        showNameExistsAlert(formContext!);
+        formProcessing = false;
+        return;
+      }
 
-    walletRestoreViewModel.create(options: _credentials());
+      walletRestoreViewModel.state = IsExecutingState();
+
+      DerivationInfo? dInfo;
+
+      // get info about the different derivations:
+      List<DerivationInfo> derivations =
+          await walletRestoreViewModel.getDerivationInfo(_credentials());
+
+      int derivationsWithHistory = 0;
+      int derivationWithHistoryIndex = 0;
+      for (int i = 0; i < derivations.length; i++) {
+        if (derivations[i].transactionsCount > 0) {
+          derivationsWithHistory++;
+          derivationWithHistoryIndex = i;
+        }
+      }
+
+      if (derivationsWithHistory > 1) {
+        dInfo = await Navigator.of(context).pushNamed(
+          Routes.restoreWalletChooseDerivation,
+          arguments: derivations,
+        ) as DerivationInfo?;
+      } else if (derivationsWithHistory == 1) {
+        dInfo = derivations[derivationWithHistoryIndex];
+      }
+
+      // get the default derivation for this wallet type:
+      if (dInfo == null) {
+        // we only return 1 derivation if we're pretty sure we know which one to use:
+        if (derivations.length == 1) {
+          dInfo = derivations.first;
+        } else {
+          // if we have multiple possible derivations, and none have histories
+          // we just default to the most common one:
+          dInfo = walletRestoreViewModel.getCommonRestoreDerivation();
+        }
+      }
+
+      this.derivationInfo = dInfo;
+      if (this.derivationInfo == null) {
+        this.derivationInfo = walletRestoreViewModel.getDefaultDerivation();
+      }
+
+      await walletRestoreViewModel.create(options: _credentials());
+    } catch (e) {
+      formProcessing = false;
+      rethrow;
+    }
+    formProcessing = false;
   }
 
   Future<void> showNameExistsAlert(BuildContext context) {

From 4e7e00b975816cffec2d23866c3b5d59fb8445b9 Mon Sep 17 00:00:00 2001
From: David Adegoke <64401859+Blazebrain@users.noreply.github.com>
Date: Tue, 13 Aug 2024 19:25:18 +0100
Subject: [PATCH 31/81] Fix: Remove resolution scope from unstoppable domains
 plugin (#1604)

---
 ios/Runner/AppDelegate.swift | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift
index 0cc4eebe8..402f6556b 100644
--- a/ios/Runner/AppDelegate.swift
+++ b/ios/Runner/AppDelegate.swift
@@ -3,11 +3,7 @@ import Flutter
 import workmanager
 
 @UIApplicationMain
-@objc class AppDelegate: FlutterAppDelegate {
-    lazy var resolution : Resolution? =  {
-               return try? Resolution()
-            }()
-    
+@objc class AppDelegate: FlutterAppDelegate {    
     override func application(
         _ application: UIApplication,
         didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?

From 525df820c3f6bccf7d2f1b419ae261d015bee37f Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Tue, 13 Aug 2024 22:51:25 +0300
Subject: [PATCH 32/81] Generic fixes (#1605)

* minor fixes

* fix not saving wallet password to secure storage

* cache linux deps as well
---
 .github/workflows/cache_dependencies.yml         |  5 ++++-
 cw_monero/lib/api/wallet_manager.dart            |  3 ---
 lib/core/wallet_creation_service.dart            | 13 ++++++-------
 lib/src/screens/new_wallet/new_wallet_page.dart  | 12 ++++++------
 lib/src/screens/restore/wallet_restore_page.dart | 15 +++++++--------
 lib/view_model/wallet_creation_vm.dart           |  2 --
 6 files changed, 23 insertions(+), 27 deletions(-)

diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml
index cca5bb4bf..72a74a8b2 100644
--- a/.github/workflows/cache_dependencies.yml
+++ b/.github/workflows/cache_dependencies.yml
@@ -60,7 +60,7 @@ jobs:
           path: |
             /opt/android/cake_wallet/cw_haven/android/.cxx
             /opt/android/cake_wallet/scripts/monero_c/release
-          key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh') }}
+          key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
 
       - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
         name: Generate Externals
@@ -68,3 +68,6 @@ jobs:
           cd /opt/android/cake_wallet/scripts/android/
           source ./app_env.sh cakewallet
           ./build_monero_all.sh
+          cd ../linux/
+          source ./app_env.sh cakewallet
+          ./build_monero_all.sh
diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart
index 14bf92d16..ce4d41010 100644
--- a/cw_monero/lib/api/wallet_manager.dart
+++ b/cw_monero/lib/api/wallet_manager.dart
@@ -8,10 +8,7 @@ import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
 import 'package:cw_monero/api/exceptions/wallet_restore_from_keys_exception.dart';
 import 'package:cw_monero/api/exceptions/wallet_restore_from_seed_exception.dart';
 import 'package:cw_monero/api/wallet.dart';
-import 'package:flutter/foundation.dart';
 import 'package:cw_monero/api/transaction_history.dart';
-import 'package:cw_monero/api/wallet.dart';
-import 'package:flutter/foundation.dart';
 import 'package:monero/monero.dart' as monero;
 
 class MoneroCException implements Exception {
diff --git a/lib/core/wallet_creation_service.dart b/lib/core/wallet_creation_service.dart
index 823aa7e84..1e9299282 100644
--- a/lib/core/wallet_creation_service.dart
+++ b/lib/core/wallet_creation_service.dart
@@ -1,4 +1,3 @@
-import 'package:cake_wallet/core/secure_storage.dart';
 import 'package:cake_wallet/di.dart';
 import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cw_core/wallet_info.dart';
@@ -57,9 +56,9 @@ class WalletCreationService {
 
     if (credentials.password == null) {
       credentials.password = generateWalletPassword();
-      await keyService.saveWalletPassword(
-        password: credentials.password!, walletName: credentials.name);
     }
+    await keyService.saveWalletPassword(
+        password: credentials.password!, walletName: credentials.name);
 
     if (_hasSeedPhraseLengthOption) {
       credentials.seedPhraseLength = settingsStore.seedPhraseLength.value;
@@ -99,9 +98,9 @@ class WalletCreationService {
 
     if (credentials.password == null) {
       credentials.password = generateWalletPassword();
-      await keyService.saveWalletPassword(
-        password: credentials.password!, walletName: credentials.name);
     }
+    await keyService.saveWalletPassword(
+        password: credentials.password!, walletName: credentials.name);
 
     final wallet = await _service!.restoreFromKeys(credentials, isTestnet: isTestnet);
 
@@ -118,9 +117,9 @@ class WalletCreationService {
 
     if (credentials.password == null) {
       credentials.password = generateWalletPassword();
-      await keyService.saveWalletPassword(
-        password: credentials.password!, walletName: credentials.name);
     }
+    await keyService.saveWalletPassword(
+        password: credentials.password!, walletName: credentials.name);
 
     final wallet = await _service!.restoreFromSeed(credentials, isTestnet: isTestnet);
 
diff --git a/lib/src/screens/new_wallet/new_wallet_page.dart b/lib/src/screens/new_wallet/new_wallet_page.dart
index cd5a7ce8d..cb451c056 100644
--- a/lib/src/screens/new_wallet/new_wallet_page.dart
+++ b/lib/src/screens/new_wallet/new_wallet_page.dart
@@ -75,7 +75,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
             _walletNewVM.hasWalletPassword ? TextEditingController() : null;
 
   static const aspectRatioImage = 1.22;
-  static bool formProcessing = false;
+  bool _formProcessing = false;
 
   final GlobalKey<FormState> _formKey;
   final GlobalKey<SeedLanguageSelectorState> _languageSelectorKey;
@@ -350,11 +350,11 @@ class _WalletNameFormState extends State<WalletNameForm> {
   }
 
   void _confirmForm() async {
-    if (formProcessing) return;
-    formProcessing = true;
+    if (_formProcessing) return;
+    _formProcessing = true;
     try {
       if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
-        formProcessing = false;
+        _formProcessing = false;
         return;
       }
       if (_walletNewVM.nameExists(_walletNewVM.name)) {
@@ -374,10 +374,10 @@ class _WalletNameFormState extends State<WalletNameForm> {
                 : null);
       }
     } catch (e) {
-      formProcessing = false;
+      _formProcessing = false;
       rethrow;
     }
-    formProcessing = false;
+    _formProcessing = false;
   }
 
   bool get isPolyseed => widget._seedTypeViewModel.moneroSeedType == SeedType.polyseed;
diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart
index 29bc29986..c8fa3665e 100644
--- a/lib/src/screens/restore/wallet_restore_page.dart
+++ b/lib/src/screens/restore/wallet_restore_page.dart
@@ -2,7 +2,6 @@ import 'package:cake_wallet/core/execution_state.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/screens/base_page.dart';
-import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart';
 import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.dart';
 import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
@@ -81,7 +80,7 @@ class WalletRestorePage extends BasePage {
     });
   }
 
-  static bool formProcessing = false;
+  bool _formProcessing = false;
 
   @override
   Widget middle(BuildContext context) => Observer(
@@ -353,8 +352,8 @@ class WalletRestorePage extends BasePage {
   }
 
   Future<void> _confirmForm(BuildContext context) async {
-    if (formProcessing) return;
-    formProcessing = true;
+    if (_formProcessing) return;
+    _formProcessing = true;
     try {
       // Dismissing all visible keyboard to provide context for navigation
       FocusManager.instance.primaryFocus?.unfocus();
@@ -373,13 +372,13 @@ class WalletRestorePage extends BasePage {
       }
 
       if (!formKey!.currentState!.validate()) {
-        formProcessing = false;
+        _formProcessing = false;
         return;
       }
 
       if (walletRestoreViewModel.nameExists(name)) {
         showNameExistsAlert(formContext!);
-        formProcessing = false;
+        _formProcessing = false;
         return;
       }
 
@@ -428,10 +427,10 @@ class WalletRestorePage extends BasePage {
 
       await walletRestoreViewModel.create(options: _credentials());
     } catch (e) {
-      formProcessing = false;
+      _formProcessing = false;
       rethrow;
     }
-    formProcessing = false;
+    _formProcessing = false;
   }
 
   Future<void> showNameExistsAlert(BuildContext context) {
diff --git a/lib/view_model/wallet_creation_vm.dart b/lib/view_model/wallet_creation_vm.dart
index 43386494e..5a9a1d093 100644
--- a/lib/view_model/wallet_creation_vm.dart
+++ b/lib/view_model/wallet_creation_vm.dart
@@ -110,8 +110,6 @@ abstract class WalletCreationVMBase with Store {
       _appStore.authenticationStore.allowed();
       state = ExecutedSuccessfullyState();
     } catch (e, s) {
-      print("@@@@@@@@");
-      print(s);
       state = FailureState(e.toString());
     }
   }

From b0ece46f29b3829482f42349c8688d74caa43b7d Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Tue, 13 Aug 2024 23:15:32 +0300
Subject: [PATCH 33/81] use the cached deps for both jobs [skip ci]

---
 .github/workflows/pr_test_build_android.yml | 2 +-
 .github/workflows/pr_test_build_linux.yml   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml
index ea8770860..5dbf1610f 100644
--- a/.github/workflows/pr_test_build_android.yml
+++ b/.github/workflows/pr_test_build_android.yml
@@ -78,7 +78,7 @@ jobs:
           path: |
             /opt/android/cake_wallet/cw_haven/android/.cxx
             /opt/android/cake_wallet/scripts/monero_c/release
-          key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh') }}
+          key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
 
       - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
         name: Generate Externals
diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml
index 12c930120..37253e96f 100644
--- a/.github/workflows/pr_test_build_linux.yml
+++ b/.github/workflows/pr_test_build_linux.yml
@@ -75,7 +75,7 @@ jobs:
           path: |
             /opt/android/cake_wallet/cw_haven/android/.cxx
             /opt/android/cake_wallet/scripts/monero_c/release
-          key: linux-${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh') }}
+          key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
 
       - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
         name: Generate Externals

From 390fdda0231d45d6aff44b5d837e19afc04d3068 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Wed, 14 Aug 2024 00:58:13 +0300
Subject: [PATCH 34/81] fix caching linux deps

---
 .github/workflows/cache_dependencies.yml | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml
index 72a74a8b2..f5fbf4826 100644
--- a/.github/workflows/cache_dependencies.yml
+++ b/.github/workflows/cache_dependencies.yml
@@ -37,7 +37,12 @@ jobs:
           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
+        run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python-is-python3 libtool libtinfo5 cmake clang
+
+      - name: Install desktop dependencies
+        run: |
+          sudo apt update
+          sudo apt install -y ninja-build libgtk-3-dev gperf
 
       - name: Execute Build and Setup Commands
         run: |
@@ -70,4 +75,5 @@ jobs:
           ./build_monero_all.sh
           cd ../linux/
           source ./app_env.sh cakewallet
+          ./app_config.sh
           ./build_monero_all.sh

From 20252cdea8b4c822ef643dd2e3cc2315b977aed1 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Wed, 14 Aug 2024 01:37:04 +0300
Subject: [PATCH 35/81] cache only android deps only have linux build as an
 artifact

---
 .github/workflows/cache_dependencies.yml  | 11 +----------
 .github/workflows/pr_test_build_linux.yml | 21 +++++++++++----------
 2 files changed, 12 insertions(+), 20 deletions(-)

diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml
index f5fbf4826..902a44a42 100644
--- a/.github/workflows/cache_dependencies.yml
+++ b/.github/workflows/cache_dependencies.yml
@@ -37,12 +37,7 @@ jobs:
           channel: stable
 
       - name: Install package dependencies
-        run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python-is-python3 libtool libtinfo5 cmake clang
-
-      - name: Install desktop dependencies
-        run: |
-          sudo apt update
-          sudo apt install -y ninja-build libgtk-3-dev gperf
+        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: |
@@ -73,7 +68,3 @@ jobs:
           cd /opt/android/cake_wallet/scripts/android/
           source ./app_env.sh cakewallet
           ./build_monero_all.sh
-          cd ../linux/
-          source ./app_env.sh cakewallet
-          ./app_config.sh
-          ./build_monero_all.sh
diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml
index 37253e96f..c1a3a3be4 100644
--- a/.github/workflows/pr_test_build_linux.yml
+++ b/.github/workflows/pr_test_build_linux.yml
@@ -174,13 +174,14 @@ jobs:
         with:
           path: /opt/android/cake_wallet/build/linux/x64/release/${{env.BRANCH_NAME}}.zip
 
-      - name: Send Test APK
-        continue-on-error: true
-        uses: adrey/slack-file-upload-action@1.0.5
-        with:
-          token: ${{ secrets.SLACK_APP_TOKEN }}
-          path: /opt/android/cake_wallet/build/linux/x64/release/${{env.BRANCH_NAME}}.zip
-          channel: ${{ secrets.SLACK_APK_CHANNEL }}
-          title: "${{ env.BRANCH_NAME }}_linux.zip"
-          filename: ${{ env.BRANCH_NAME }}_linux.zip
-          initial_comment: ${{ github.event.head_commit.message }}
+#        Just as an artifact would be enough
+#      - name: Send Test APK
+#        continue-on-error: true
+#        uses: adrey/slack-file-upload-action@1.0.5
+#        with:
+#          token: ${{ secrets.SLACK_APP_TOKEN }}
+#          path: /opt/android/cake_wallet/build/linux/x64/release/${{env.BRANCH_NAME}}.zip
+#          channel: ${{ secrets.SLACK_APK_CHANNEL }}
+#          title: "${{ env.BRANCH_NAME }}_linux.zip"
+#          filename: ${{ env.BRANCH_NAME }}_linux.zip
+#          initial_comment: ${{ github.event.head_commit.message }}

From 183f9c191d292ed9fb5d6b1d1bcf6982e1424445 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Wed, 14 Aug 2024 17:49:56 +0300
Subject: [PATCH 36/81] Update pr_test_build_linux.yml

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

diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml
index c1a3a3be4..7935dd177 100644
--- a/.github/workflows/pr_test_build_linux.yml
+++ b/.github/workflows/pr_test_build_linux.yml
@@ -75,7 +75,7 @@ jobs:
           path: |
             /opt/android/cake_wallet/cw_haven/android/.cxx
             /opt/android/cake_wallet/scripts/monero_c/release
-          key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
+          key: linux_${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
 
       - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
         name: Generate Externals

From d8accfb38b00b4fcd63a37a615c787557b656084 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Wed, 14 Aug 2024 11:31:28 -0700
Subject: [PATCH 37/81] [skip ci] fix always scan setting, swift updates

---
 cw_bitcoin/lib/litecoin_wallet.dart    | 12 ++++++++++++
 cw_mweb/ios/Classes/CwMwebPlugin.swift | 24 ++++++++++++------------
 2 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 0b4ec5459..a5702547f 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -189,6 +189,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       initialRegularAddressIndex: snp?.regularAddressIndex,
       initialChangeAddressIndex: snp?.changeAddressIndex,
       addressPageType: snp?.addressPageType,
+      alwaysScan: alwaysScan,
     );
   }
 
@@ -818,4 +819,15 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     stopSync();
     startSync();
   }
+
+  Future<RpcClient> getStub() async {
+    _stub = await CwMweb.stub();
+    return _stub;
+  }
+
+  Future<StatusResponse> getStatusRequest() async {
+    await getStub();
+    final resp = await _stub.status(StatusRequest());
+    return resp;
+  }
 }
diff --git a/cw_mweb/ios/Classes/CwMwebPlugin.swift b/cw_mweb/ios/Classes/CwMwebPlugin.swift
index 5c45a8434..fff1283d8 100644
--- a/cw_mweb/ios/Classes/CwMwebPlugin.swift
+++ b/cw_mweb/ios/Classes/CwMwebPlugin.swift
@@ -15,18 +15,18 @@ public class CwMwebPlugin: NSObject, FlutterPlugin {
     
   public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
       switch call.method {
-      case "getPlatformVersion":
-          result("iOS " + UIDevice.current.systemVersion)
-      case "start":
-          let args = call.arguments as? [String: String]
-          let dataDir = args?["dataDir"]
-          CwMwebPlugin.dataDir = dataDir
-          startServer(result: result)
-      case "stop":
-          stopServer()
-          result(nil)
-      default:
-          result(FlutterMethodNotImplemented)
+        case "getPlatformVersion":
+            result("iOS " + UIDevice.current.systemVersion)
+        case "start":
+            let args = call.arguments as? [String: String]
+            let dataDir = args?["dataDir"]
+            CwMwebPlugin.dataDir = dataDir
+            startServer(result: result)
+        case "stop":
+            stopServer()
+            result(nil)
+        default:
+            result(FlutterMethodNotImplemented)
       }
   }
 

From c4499869e591a9bc4d4541b7a763d8a7b7b09a97 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Wed, 14 Aug 2024 12:31:27 -0700
Subject: [PATCH 38/81] updates

---
 cw_bitcoin/lib/litecoin_wallet.dart | 66 +++++++++++++++--------------
 1 file changed, 34 insertions(+), 32 deletions(-)

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index a5702547f..e48db6475 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -90,8 +90,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   late final Bip32Slip10Secp256k1 mwebHd;
   late final Box<MwebUtxo> mwebUtxosBox;
   Timer? _syncTimer;
+  Timer? _feeRatesTimer;
   StreamSubscription<Utxo>? _utxoStream;
-  int mwebUtxosHeight = 0;
   late RpcClient _stub;
   late bool mwebEnabled;
 
@@ -196,6 +196,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   @action
   @override
   Future<void> startSync() async {
+    print("STARTING SYNC");
     if (!mwebEnabled) {
       syncStatus = SyncronizingSyncStatus();
       await subscribeForUpdates();
@@ -208,21 +209,24 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     await updateTransactions();
     await updateFeeRates();
 
-    Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
+    _feeRatesTimer?.cancel();
+    _feeRatesTimer =
+        Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
 
     _stub = await CwMweb.stub();
     _syncTimer?.cancel();
     _syncTimer = Timer.periodic(const Duration(milliseconds: 1500), (timer) async {
       if (syncStatus is FailedSyncStatus) return;
-      final height = await electrumClient.getCurrentBlockChainTip() ?? 0;
+      final nodeHeight = await electrumClient.getCurrentBlockChainTip() ?? 0;
       final resp = await _stub.status(StatusRequest());
-      if (resp.blockHeaderHeight < height) {
+
+      if (resp.blockHeaderHeight < nodeHeight) {
         int h = resp.blockHeaderHeight;
         syncStatus = SyncingSyncStatus(height - h, h / height);
-      } else if (resp.mwebHeaderHeight < height) {
+      } else if (resp.mwebHeaderHeight < nodeHeight) {
         int h = resp.mwebHeaderHeight;
         syncStatus = SyncingSyncStatus(height - h, h / height);
-      } else if (resp.mwebUtxosHeight < height) {
+      } else if (resp.mwebUtxosHeight < nodeHeight) {
         syncStatus = SyncingSyncStatus(1, 0.999);
       } else {
         // prevent unnecessary reaction triggers:
@@ -230,14 +234,14 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
           syncStatus = SyncedSyncStatus();
         }
 
-        if (resp.mwebUtxosHeight > mwebUtxosHeight) {
-          mwebUtxosHeight = resp.mwebUtxosHeight;
+        if (resp.mwebUtxosHeight > walletInfo.restoreHeight) {
+          await walletInfo.updateRestoreHeight(resp.mwebUtxosHeight);
           await checkMwebUtxosSpent();
           // update the confirmations for each transaction:
           for (final transaction in transactionHistory.transactions.values) {
             if (transaction.isPending) continue;
-            int txHeight = transaction.height ?? mwebUtxosHeight;
-            final confirmations = (mwebUtxosHeight - txHeight) + 1;
+            int txHeight = transaction.height ?? resp.mwebUtxosHeight;
+            final confirmations = (resp.mwebUtxosHeight - txHeight) + 1;
             if (transaction.confirmations == confirmations) continue;
             transaction.confirmations = confirmations;
             transactionHistory.addOne(transaction);
@@ -292,7 +296,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   }) async {
     await mwebUtxosBox.clear();
     transactionHistory.clear();
-    mwebUtxosHeight = height;
     await walletInfo.updateRestoreHeight(height);
 
     // reset coin balances and txCount to 0:
@@ -307,7 +310,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       addressRecord.txCount = 0;
     }
 
-    print("STARTING SYNC");
     await startSync();
   }
 
@@ -362,6 +364,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       final addressRecord = walletAddresses.allAddresses
           .firstWhereOrNull((addressRecord) => addressRecord.address == utxo.address);
       if (addressRecord == null) {
+        print("we don't have this address in the wallet! ${utxo.address}");
         return;
       }
 
@@ -391,21 +394,20 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     final req = UtxosRequest(scanSecret: scanSecret, fromHeight: restoreHeight);
 
     // process old utxos:
-    for (final utxo in mwebUtxosBox.values) {
-      if (utxo.address.isEmpty) {
-        continue;
-      }
+    // for (final utxo in mwebUtxosBox.values) {
+    //   if (utxo.address.isEmpty) {
+    //     continue;
+    //   }
 
-      // if (walletInfo.restoreHeight > utxo.height) {
-      //   continue;
-      // }
+    //   // if (walletInfo.restoreHeight > utxo.height) {
+    //   //   continue;
+    //   // }
+    //   // await handleIncoming(utxo, _stub);
 
-      await handleIncoming(utxo, _stub);
-
-      if (utxo.height > walletInfo.restoreHeight) {
-        await walletInfo.updateRestoreHeight(utxo.height);
-      }
-    }
+    //   if (utxo.height > walletInfo.restoreHeight) {
+    //     await walletInfo.updateRestoreHeight(utxo.height);
+    //   }
+    // }
 
     // process new utxos as they come in:
     _utxoStream?.cancel();
@@ -418,10 +420,10 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
         value: sUtxo.value.toInt(),
       );
 
-      if (mwebUtxosBox.containsKey(utxo.outputId)) {
-        // we've already stored this utxo, skip it:
-        return;
-      }
+      // if (mwebUtxosBox.containsKey(utxo.outputId)) {
+      //   // we've already stored this utxo, skip it:
+      //   return;
+      // }
 
       // if (utxo.address.isEmpty) {
       //   await updateUnspent();
@@ -631,10 +633,10 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
 
     // update the txCount for each address using the tx history, since we can't rely on mwebd
     // to have an accurate count, we should just keep it in sync with what we know from the tx history:
-    for (var tx in transactionHistory.transactions.values) {
-      if (tx.isPending) continue;
+    for (final tx in transactionHistory.transactions.values) {
+      // if (tx.isPending) continue;
       final txAddresses = tx.inputAddresses! + tx.outputAddresses!;
-      for (var address in txAddresses) {
+      for (final address in txAddresses) {
         final addressRecord = walletAddresses.allAddresses
             .firstWhereOrNull((addressRecord) => addressRecord.address == address);
         if (addressRecord == null) {

From 192045310cd0c252e03f61344e05253200e91c20 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Wed, 14 Aug 2024 13:16:52 -0700
Subject: [PATCH 39/81] fixes

---
 cw_bitcoin/lib/electrum.dart        | 5 ++++-
 cw_bitcoin/lib/litecoin_wallet.dart | 4 ++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart
index d58e31e45..879f4a5f9 100644
--- a/cw_bitcoin/lib/electrum.dart
+++ b/cw_bitcoin/lib/electrum.dart
@@ -115,7 +115,10 @@ class ElectrumClient {
         _setConnectionStatus(ConnectionStatus.failed);
     }, onDone: () {
       unterminatedString = '';
-      if (host == socket?.address.host) _setConnectionStatus(ConnectionStatus.disconnected);
+      if (host == socket?.address.host) {
+        _setConnectionStatus(ConnectionStatus.disconnected);
+      }
+      socket = null;
     });
 
     keepAlive();
diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index e48db6475..9cec5a2c2 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -222,10 +222,10 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
 
       if (resp.blockHeaderHeight < nodeHeight) {
         int h = resp.blockHeaderHeight;
-        syncStatus = SyncingSyncStatus(height - h, h / height);
+        syncStatus = SyncingSyncStatus(nodeHeight - h, h / nodeHeight);
       } else if (resp.mwebHeaderHeight < nodeHeight) {
         int h = resp.mwebHeaderHeight;
-        syncStatus = SyncingSyncStatus(height - h, h / height);
+        syncStatus = SyncingSyncStatus(nodeHeight - h, h / nodeHeight);
       } else if (resp.mwebUtxosHeight < nodeHeight) {
         syncStatus = SyncingSyncStatus(1, 0.999);
       } else {

From d96bab43c9fee91b464166f7747be3b864b7f5ff Mon Sep 17 00:00:00 2001
From: Rafael <github@rafael.saes.dev>
Date: Wed, 14 Aug 2024 20:40:40 -0300
Subject: [PATCH 40/81] fix: p2sh addr (#1607)

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

diff --git a/cw_bitcoin/lib/utils.dart b/cw_bitcoin/lib/utils.dart
index 29d7a9bf3..a7435bed1 100644
--- a/cw_bitcoin/lib/utils.dart
+++ b/cw_bitcoin/lib/utils.dart
@@ -23,7 +23,7 @@ String generateP2SHAddress({
   required int index,
 }) =>
     ECPublic.fromBip32(hd.childKey(Bip32KeyIndex(index)).publicKey)
-        .toP2wshInP2sh()
+        .toP2wpkhInP2sh()
         .toAddress(network);
 
 String generateP2WSHAddress({

From 4fa487fa275b9d1fc1343c7852d763b899dcb74b Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Thu, 15 Aug 2024 01:41:22 +0200
Subject: [PATCH 41/81] seed fixes (#1594)

* seed fixes + jCenter removal

* set seed language to English if none
show error when requesting seed

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 cw_monero/lib/api/wallet.dart                      |  5 ++++-
 cw_monero/lib/api/wallet_manager.dart              | 11 ++++++++++-
 cw_wownero/lib/api/wallet.dart                     |  5 ++++-
 cw_wownero/lib/api/wallet_manager.dart             | 11 ++++++++++-
 lib/view_model/dashboard/dashboard_view_model.dart | 13 ++++++++-----
 5 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart
index 0f6e59c4e..973a38535 100644
--- a/cw_monero/lib/api/wallet.dart
+++ b/cw_monero/lib/api/wallet.dart
@@ -39,7 +39,7 @@ String getSeed() {
   if (polyseed != "") {
     return polyseed;
   }
-  final legacy = monero.Wallet_seed(wptr!, seedOffset: '');
+  final legacy = getSeedLegacy("English");
   return legacy;
 }
 
@@ -49,6 +49,9 @@ String getSeedLegacy(String? language) {
     monero.Wallet_setSeedLanguage(wptr!, language: language ?? "English");
     legacy = monero.Wallet_seed(wptr!, seedOffset: '');
   }
+  if (monero.Wallet_status(wptr!) != 0) {
+    return monero.Wallet_errorString(wptr!);
+  }
   return legacy;
 }
 
diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart
index ce4d41010..f06fe3e66 100644
--- a/cw_monero/lib/api/wallet_manager.dart
+++ b/cw_monero/lib/api/wallet_manager.dart
@@ -123,7 +123,16 @@ void restoreWalletFromKeysSync(
     int nettype = 0,
     int restoreHeight = 0}) {
   txhistory = null;
-  final newWptr = monero.WalletManager_createWalletFromKeys(
+  final newWptr = spendKey != ""
+   ? monero.WalletManager_createDeterministicWalletFromSpendKey(
+    wmPtr,
+    path: path,
+    password: password,
+    language: language,
+    spendKeyString: spendKey, 
+    newWallet: true, // TODO(mrcyjanek): safe to remove
+    restoreHeight: restoreHeight)
+   : monero.WalletManager_createWalletFromKeys(
     wmPtr,
     path: path,
     password: password,
diff --git a/cw_wownero/lib/api/wallet.dart b/cw_wownero/lib/api/wallet.dart
index 96822dfe4..2ccd560ed 100644
--- a/cw_wownero/lib/api/wallet.dart
+++ b/cw_wownero/lib/api/wallet.dart
@@ -41,7 +41,7 @@ String getSeed() {
   if (polyseed != "") {
     return polyseed;
   }
-  final legacy = wownero.Wallet_seed(wptr!, seedOffset: '');
+  final legacy = getSeedLegacy(null);
   return legacy;
 }
 
@@ -51,6 +51,9 @@ String getSeedLegacy(String? language) {
     wownero.Wallet_setSeedLanguage(wptr!, language: language ?? "English");
     legacy = wownero.Wallet_seed(wptr!, seedOffset: '');
   }
+  if (wownero.Wallet_status(wptr!) != 0) {
+    return wownero.Wallet_errorString(wptr!);
+  }
   return legacy;
 }
 
diff --git a/cw_wownero/lib/api/wallet_manager.dart b/cw_wownero/lib/api/wallet_manager.dart
index 7915373bb..660433ba6 100644
--- a/cw_wownero/lib/api/wallet_manager.dart
+++ b/cw_wownero/lib/api/wallet_manager.dart
@@ -140,7 +140,16 @@ void restoreWalletFromKeysSync(
     int nettype = 0,
     int restoreHeight = 0}) {
   txhistory = null;
-  final newWptr = wownero.WalletManager_createWalletFromKeys(
+  final newWptr =  spendKey != ""
+   ? wownero.WalletManager_createDeterministicWalletFromSpendKey(
+    wmPtr,
+    path: path,
+    password: password,
+    language: language,
+    spendKeyString: spendKey, 
+    newWallet: true, // TODO(mrcyjanek): safe to remove
+    restoreHeight: restoreHeight)
+   : wownero.WalletManager_createWalletFromKeys(
     wmPtr,
     path: path,
     password: password,
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index 1baea76cd..e98412dce 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -362,12 +362,15 @@ abstract class DashboardViewModelBase with Store {
     if (wallet.type != WalletType.monero) return [];
     final keys = monero!.getKeys(wallet);
     List<String> errors = [
-      if (keys['privateSpendKey'] == List.generate(64, (index) => "0").join("")) "Private spend key is 0",
+      // leaving these commented out for now, I'll be able to fix that properly in the airgap update
+      // to not cause work duplication, this will do the job as well, it will be slightly less precise
+      // about what happened - but still enough.
+      // if (keys['privateSpendKey'] == List.generate(64, (index) => "0").join("")) "Private spend key is 0",
       if (keys['privateViewKey'] == List.generate(64, (index) => "0").join("")) "private view key is 0",
-      if (keys['publicSpendKey'] == List.generate(64, (index) => "0").join("")) "public spend key is 0",
-      if (keys['publicViewKey'] == List.generate(64, (index) => "0").join("")) "private view key is 0",
-      if (wallet.seed == null) "wallet seed is null",
-      if (wallet.seed == "") "wallet seed is empty",
+      // if (keys['publicSpendKey'] == List.generate(64, (index) => "0").join("")) "public spend key is 0",
+      if (keys['publicViewKey'] == List.generate(64, (index) => "0").join("")) "public view key is 0",
+      // if (wallet.seed == null) "wallet seed is null",
+      // if (wallet.seed == "") "wallet seed is empty",
       if (monero!.getSubaddressList(wallet).getAll(wallet)[0].address == "41d7FXjswpK1111111111111111111111111111111111111111111111111111111111111111111111111111112KhNi4") 
         "primary address is invalid, you won't be able to receive / spend funds",
     ];

From 40496fbfe73d56903213c40482a6ab6ee03a5022 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ren=C3=A9=20Brunner?= <rbrunner@dreamshare.ch>
Date: Thu, 15 Aug 2024 19:04:11 +0200
Subject: [PATCH 42/81] Major overhaul of the Tagalog localization (#1611)

---
 res/values/strings_tl.arb | 1058 ++++++++++++++++++-------------------
 1 file changed, 529 insertions(+), 529 deletions(-)

diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index 3bbae2e50..22093f772 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -1,735 +1,735 @@
 {
-  "about_cake_pay": "Pinapayagan ka ng cake Pay na madaling bumili ng mga kard ng regalo na may mga virtual na pag -aari, gastusin agad sa higit sa 150,000 mga mangangalakal sa Estados Unidos.",
+  "about_cake_pay": "Binibigyan-daan ka ng Cake Pay na madaling makabili ng mga gift card na may mga virtual na asset na magagastos kaagad sa mahigit na 150,000 merchant sa United States.",
   "account": "Account",
   "accounts": "Mga Account",
-  "accounts_subaddresses": "Mga Account at Subaddresses",
-  "activate": "Buhayin",
+  "accounts_subaddresses": "Mga account at mga subaddress",
+  "activate": "Aktibahin",
   "active": "Aktibo",
-  "active_cards": "Mga aktibong kard",
+  "active_cards": "Mga aktibong card",
   "activeConnectionsPrompt": "Lalabas dito ang mga aktibong koneksyon",
-  "add": "Idagdag",
+  "add": "Magdagdag",
   "add_contact": "Magdagdag ng contact",
-  "add_contact_to_address_book": "Nais mo bang idagdag ang contact na ito sa iyong address book?",
-  "add_custom_node": "Magdagdag ng bagong pasadyang node",
-  "add_custom_redemption": "Magdagdag ng pasadyang pagtubos",
-  "add_fund_to_card": "Magdagdag ng prepaid na pondo sa mga kard (hanggang sa ${value})",
+  "add_contact_to_address_book": "Gusto mo bang idagdag ang contact na ito sa iyong address book?",
+  "add_custom_node": "Magdagdag ng Bagong Custom Node",
+  "add_custom_redemption": "Magdagdag ng Custom Redemption",
+  "add_fund_to_card": "Magdagdag ng mga prepaid na pondo sa card (hanggang sa ${value})",
   "add_new_node": "Magdagdag ng bagong node",
   "add_new_word": "Magdagdag ng bagong salita",
   "add_receiver": "Magdagdag ng isa pang tatanggap (opsyonal)",
   "add_secret_code": "O, idagdag ang sikretong code na ito sa isang authenticator app",
-  "add_tip": "Magdagdag ng tip",
-  "add_token_disclaimer_check": "Kinumpirma ko ang address ng kontrata ng token at impormasyon gamit ang isang kagalang -galang na mapagkukunan. Ang pagdaragdag ng nakakahamak o hindi tamang impormasyon ay maaaring magresulta sa pagkawala ng mga pondo.",
-  "add_token_warning": "Huwag i -edit o magdagdag ng mga token tulad ng itinuro ng mga scammers.\nLaging kumpirmahin ang mga token address na may mga kagalang -galang na mapagkukunan!",
+  "add_tip": "Magdagdag ng Tip",
+  "add_token_disclaimer_check": "Kinumpirma ko ang address ng kontrata ng token at impormasyon gamit ang isang kagalang-galang na mapagkukunan. Ang pagdaragdag ng nakakahamak o hindi tamang impormasyon ay maaaring magresulta sa pagkawala ng mga pondo.",
+  "add_token_warning": "Huwag i-edit o magdagdag ng mga token tulad ng itinuro ng mga scammers.\nLaging kumpirmahin ang mga token address na may mga kagalang-galang na mapagkukunan!",
   "add_value": "Magdagdag ng halaga",
   "address": "Address",
   "address_book": "Address Book",
-  "address_book_menu": "Address Book",
+  "address_book_menu": "Address book",
   "address_detected": "Nakita ang address",
-  "address_from_domain": "Ang address na ito ay mula sa ${domain} sa mga hindi mapigilan na mga domain",
-  "address_from_yat": "Ang address na ito ay mula sa ${emoji} sa yat",
-  "address_label": "Address Label",
+  "address_from_domain": "Ang address na ito ay mula sa ${domain} mga Unstoppable Domains",
+  "address_from_yat": "Ang address na ito ay mula sa ${emoji} sa Yat",
+  "address_label": "Label ng address",
   "address_remove_contact": "Alisin ang contact",
   "address_remove_content": "Sigurado ka bang nais mong alisin ang napiling contact?",
-  "addresses": "Mga address",
+  "addresses": "Mga Address",
   "advanced_settings": "Mga Advanced na Setting",
   "aggressive": "Agresibo",
-  "agree": "Sumang -ayon",
-  "agree_and_continue": "Sumang -ayon at magpatuloy",
-  "agree_to": "Sa pamamagitan ng paglikha ng account sumasang -ayon ka sa",
-  "all": "Lahat",
-  "all_trades": "Lahat ng mga kalakal",
+  "agree": "Sumang-ayon",
+  "agree_and_continue": "Sumang-ayon & Magpatuloy",
+  "agree_to": "Sa pamamagitan ng paggawa ng account sumasang-ayon ka sa ",
+  "all": "LAHAT",
+  "all_trades": "Lahat ng mga trade",
   "all_transactions": "Lahat ng mga transaksyon",
   "alphabetical": "Alpabeto",
   "already_have_account": "Mayroon nang account?",
   "always": "Palagi",
-  "amount": "Halaga:",
+  "amount": "Halaga: ",
   "amount_is_below_minimum_limit": "Ang iyong balanse pagkatapos ng mga bayarin ay mas mababa kaysa sa minimum na halaga na kinakailangan para sa palitan (${min})",
   "amount_is_estimate": "Ang natanggap na halaga ay isang pagtatantya",
   "amount_is_guaranteed": "Ang natanggap na halaga ay garantisado",
   "and": "at",
-  "anonpay_description": "Bumuo ng ${type}. Ang tatanggap ay maaaring ${method} na may anumang suportadong cryptocurrency, at makakatanggap ka ng mga pondo sa pitaka na ito.",
-  "apk_update": "APK Update",
+  "anonpay_description": "Bumuo ng ${type}. Ang tatanggap ay maaaring ${method} na may anumang suportadong cryptocurrency, at makakatanggap ka ng mga pondo sa wallet na ito.",
+  "apk_update": "APK update",
   "approve": "Aprubahan",
   "arrive_in_this_address": "Ang ${currency} ${tag} ay darating sa address na ito",
   "ascending": "Umakyat",
-  "ask_each_time": "Magtanong sa bawat oras",
-  "auth_store_ban_timeout": "ban_timeout",
-  "auth_store_banned_for": "Pinagbawalan para sa",
-  "auth_store_banned_minutes": "minuto",
-  "auth_store_incorrect_password": "Maling pin",
+  "ask_each_time": "Magtanong sa tuwing",
+  "auth_store_ban_timeout": "ban timeout",
+  "auth_store_banned_for": "Pinagbawalan para sa ",
+  "auth_store_banned_minutes": " minuto",
+  "auth_store_incorrect_password": "Maling PIN",
   "authenticated": "Napatunayan",
   "authentication": "Pagpapatunay",
   "auto_generate_addresses": "Auto bumuo ng mga address",
-  "auto_generate_subaddresses": "Ang Auto ay bumubuo ng mga subaddresses",
+  "auto_generate_subaddresses": "Auto bumuo ng mga subaddress",
   "automatic": "Awtomatiko",
-  "available_balance": "Magagamit na balanse",
+  "available_balance": "Magagamit na Balanse",
   "available_balance_description": "Ang \"magagamit na balanse\" o \"nakumpirma na balanse\" ay mga pondo na maaaring gastusin kaagad. Kung lumilitaw ang mga pondo sa mas mababang balanse ngunit hindi ang nangungunang balanse, dapat kang maghintay ng ilang minuto para sa mga papasok na pondo upang makakuha ng mas maraming mga kumpirmasyon sa network. Matapos silang makakuha ng higit pang mga kumpirmasyon, gugugol sila.",
   "avg_savings": "Avg. Matitipid",
   "awaitDAppProcessing": "Pakihintay na matapos ang pagproseso ng dApp.",
-  "awaiting_payment_confirmation": "Naghihintay ng kumpirmasyon sa pagbabayad",
-  "background_sync_mode": "Mode ng pag -sync ng background",
+  "awaiting_payment_confirmation": "Nanghihintay ng Kumpirmasyon sa Pagbabayad",
+  "background_sync_mode": "Background sync mode",
   "backup": "Backup",
-  "backup_file": "Backup file",
-  "backup_password": "Backup password",
-  "balance": "Balansehin",
+  "backup_file": "Backup na file",
+  "backup_password": "Backup na password",
+  "balance": "Balanse",
   "balance_page": "Pahina ng Balanse",
   "bill_amount": "Halaga ng Bill",
-  "billing_address_info": "Kung tatanungin ang isang address ng pagsingil, ibigay ang iyong address sa pagpapadala",
-  "biometric_auth_reason": "I -scan ang iyong fingerprint upang mapatunayan",
-  "bitcoin_dark_theme": "Bitcoin Madilim na Tema",
-  "bitcoin_light_theme": "Tema ng ilaw ng bitcoin",
-  "bitcoin_payments_require_1_confirmation": "Ang mga pagbabayad sa Bitcoin ay nangangailangan ng 1 kumpirmasyon, na maaaring tumagal ng 20 minuto o mas mahaba. Salamat sa iyong pasensya! Mag -email ka kapag nakumpirma ang pagbabayad.",
-  "block_remaining": "1 bloke ang natitira",
+  "billing_address_info": "Kung humihingi ng billing address, ibigay ang iyong shipping address",
+  "biometric_auth_reason": "I-scan ang iyong fingerprint para ma-authenticate",
+  "bitcoin_dark_theme": "Bitcoin Dark Theme",
+  "bitcoin_light_theme": "Bitcoin Light Theme",
+  "bitcoin_payments_require_1_confirmation": "Ang mga pagbabayad sa Bitcoin ay nangangailangan ng 1 kumpirmasyon, na maaaring tumagal ng 20 minuto o mas mahaba. Salamat sa iyong pasensya! Mag-email ka kapag nakumpirma ang pagbabayad.",
+  "block_remaining": "1 Bloke ang Natitira",
   "Blocks_remaining": "Ang natitirang ${status} ay natitira",
   "bluetooth": "Bluetooth",
-  "bright_theme": "Maliwanag",
-  "bump_fee": "Bayad sa paga",
-  "buy": "Bilhin",
+  "bright_theme": "Bright",
+  "bump_fee": "Dagdagan ang fee",
+  "buy": "Bumili",
   "buy_alert_content": "Sa kasalukuyan ay sinusuportahan lamang namin ang pagbili ng Bitcoin, Ethereum, Litecoin, at Monero. Mangyaring lumikha o lumipat sa iyong Bitcoin, Ethereum, Litecoin, o Monero Wallet.",
-  "buy_bitcoin": "Bumili ng bitcoin",
-  "buy_now": "Bumili ka na ngayon",
+  "buy_bitcoin": "Bumili ng Bitcoin",
+  "buy_now": "Bumili Ngayon",
   "buy_provider_unavailable": "Kasalukuyang hindi available ang provider.",
-  "buy_with": "Bumili ka",
-  "by_cake_pay": "sa pamamagitan ng cake pay",
-  "cake_2fa_preset": "Cake 2fa preset",
-  "cake_dark_theme": "Cake madilim na tema",
-  "cake_pay_account_note": "Mag -sign up na may isang email address lamang upang makita at bumili ng mga kard. Ang ilan ay magagamit kahit sa isang diskwento!",
-  "cake_pay_learn_more": "Agad na bumili at tubusin ang mga kard ng regalo sa app!\nMag -swipe pakaliwa sa kanan upang matuto nang higit pa.",
-  "cake_pay_save_order": "Ang card ay dapat ipadala sa iyong e-mail sa loob ng 1 araw ng negosyo \n i-save ang iyong order ID:",
+  "buy_with": "Bumili ng",
+  "by_cake_pay": "by Cake Pay",
+  "cake_2fa_preset": "Cake 2FA Preset",
+  "cake_dark_theme": "Cake Dark Theme",
+  "cake_pay_account_note": "Mag-sign up na may isang email address lamang upang makita at bumili ng mga kard. Ang ilan ay magagamit kahit sa isang diskwento!",
+  "cake_pay_learn_more": "Agad na bumili at tubusin ang mga kard ng regalo sa app!\nMag-swipe pakaliwa sa kanan upang matuto nang higit pa.",
+  "cake_pay_save_order": "Ang card ay dapat ipadala sa iyong email sa loob ng 1 araw ng negosyo \n I-save ang iyong order ID:",
   "cake_pay_subtitle": "Bumili ng mga pandaigdigang prepaid card at gift card",
   "cake_pay_web_cards_subtitle": "Bumili ng mga pandaigdigang prepaid card at gift card",
-  "cake_pay_web_cards_title": "Cake pay web card",
-  "cake_wallet": "Cake wallet",
-  "cakepay_prepaid_card": "Cakepay prepaid debit card",
+  "cake_pay_web_cards_title": "Cake Pay Web Cards",
+  "cake_wallet": "Cake Wallet",
+  "cakepay_prepaid_card": "CakePay Prepaid Debit Card",
   "camera_consent": "Gagamitin ang iyong camera upang kumuha ng larawan para sa mga layunin ng pagkakakilanlan sa pamamagitan ng ${provider}. Pakisuri ang kanilang Patakaran sa Privacy para sa mga detalye.",
   "camera_permission_is_required": "Kinakailangan ang pahintulot sa camera.\nMangyaring paganahin ito mula sa mga setting ng app.",
   "cancel": "Kanselahin",
   "card_address": "Address:",
   "cardholder_agreement": "Kasunduan sa Cardholder",
   "cards": "Mga Card",
-  "chains": "Mga tanikala",
-  "change": "Palitan",
-  "change_backup_password_alert": "Ang iyong mga nakaraang backup file ay hindi magagamit upang mai -import gamit ang bagong backup password. Ang bagong backup na password ay gagamitin lamang para sa mga bagong backup file. Sigurado ka bang nais mong baguhin ang backup password?",
+  "chains": "Mga Chain",
+  "change": "Sukli",
+  "change_backup_password_alert": "Ang iyong mga nakaraang backup na file ay hindi magagamit upang i-import gamit ang bagong backup na password. Ang bagong backup na password ay gagamitin lamang para sa mga bagong backup na file. Sigurado ka bang gusto mong baguhin ang backup na password?",
   "change_currency": "Baguhin ang pera",
   "change_current_node": "Sigurado ka bang baguhin ang kasalukuyang node sa ${node}?",
   "change_current_node_title": "Baguhin ang kasalukuyang node",
-  "change_exchange_provider": "Baguhin ang tagapagbigay ng palitan",
+  "change_exchange_provider": "Baguhin ang exchange provider",
   "change_language": "Baguhin ang wika",
   "change_language_to": "Baguhin ang wika sa ${language}?",
-  "change_password": "Palitan ANG password",
-  "change_rep": "Baguhin ang kinatawan",
-  "change_rep_message": "Sigurado ka bang nais mong baguhin ang mga kinatawan?",
-  "change_rep_successful": "Matagumpay na nagbago ng kinatawan",
-  "change_wallet_alert_content": "Nais mo bang baguhin ang kasalukuyang pitaka sa ${wallet_name}?",
-  "change_wallet_alert_title": "Baguhin ang kasalukuyang pitaka",
+  "change_password": "Baguhin ang password",
+  "change_rep": "Baguhin ang Representative",
+  "change_rep_message": "Sigurado ka bang nais mong baguhin ang mga representative?",
+  "change_rep_successful": "Matagumpay na nagbago ng representative",
+  "change_wallet_alert_content": "Gusto mo bang palitan ang kasalukuyang wallet sa ${wallet_name}?",
+  "change_wallet_alert_title": "Baguhin ang kasalukuyang wallet",
   "choose_account": "Pumili ng account",
   "choose_address": "Mangyaring piliin ang address:",
   "choose_card_value": "Pumili ng isang halaga ng card",
-  "choose_derivation": "Piliin ang derivation ng Wallet",
+  "choose_derivation": "Piliin ang Derivation ng Wallet",
   "choose_from_available_options": "Pumili mula sa magagamit na mga pagpipilian:",
   "choose_one": "Pumili ng isa",
   "choose_relay": "Mangyaring pumili ng relay na gagamitin",
-  "choose_wallet_currency": "Mangyaring piliin ang Pera ng Wallet:",
-  "clear": "Malinaw",
+  "choose_wallet_currency": "Mangyaring piliin ang pera ng wallet:",
+  "clear": "Burahin",
   "clearnet_link": "Link ng Clearnet",
-  "close": "Malapit",
-  "coin_control": "Control ng barya (opsyonal)",
-  "cold_or_recover_wallet": "Magdagdag ng isang malamig na pitaka o mabawi ang isang wallet ng papel",
-  "color_theme": "Tema ng kulay",
-  "commit_transaction_amount_fee": "Gumawa ng transaksyon\nHalaga: ${amount}\nBayad: ${fee}",
+  "close": "Isara",
+  "coin_control": "Coin control (opsyonal)",
+  "cold_or_recover_wallet": "Magdagdag ng isang cold wallet o mabawi ang isang paper wallet",
+  "color_theme": "Color theme",
+  "commit_transaction_amount_fee": "Gumawa ng transaksyon\nHalaga: ${amount}\nFee: ${fee}",
   "confirm": "Kumpirmahin",
-  "confirm_delete_template": "Ang pagkilos na ito ay tatanggalin ang template na ito. Nais mo bang magpatuloy?",
-  "confirm_delete_wallet": "Ang pagkilos na ito ay tatanggalin ang pitaka na ito. Nais mo bang magpatuloy?",
-  "confirm_fee_deduction": "Kumpirmahin ang pagbabawas ng bayad",
-  "confirm_fee_deduction_content": "Sumasang -ayon ka bang bawasan ang bayad mula sa output?",
+  "confirm_delete_template": "Tatanggalin ng pagkilos na ito ang template na ito. Gusto mo bang magpatuloy?",
+  "confirm_delete_wallet": "Tatanggalin ng pagkilos na ito ang wallet na ito. Gusto mo bang magpatuloy?",
+  "confirm_fee_deduction": "Kumpirmahin ang pagbabawas ng fee",
+  "confirm_fee_deduction_content": "Sumasang-ayon ka bang bawasan ang fee mula sa output?",
   "confirm_sending": "Kumpirmahin ang pagpapadala",
-  "confirm_silent_payments_switch_node": "Ang iyong kasalukuyang node ay hindi sumusuporta sa tahimik na pagbabayad \\ ncake wallet ay lilipat sa isang katugmang node, para lamang sa pag -scan",
+  "confirm_silent_payments_switch_node": "Ang iyong kasalukuyang node ay hindi sumusuporta sa tahimik na pagbabayad \\ nCake Wallet ay lilipat sa isang katugmang node, para lamang sa pag-scan",
   "confirmations": "Mga kumpirmasyon",
-  "confirmed": "Nakumpirma na balanse",
+  "confirmed": "Nakumpirma na Balanse",
   "confirmed_tx": "Nakumpirma",
-  "congratulations": "Binabati kita!",
-  "connect_an_existing_yat": "Ikonekta ang isang umiiral na yat",
-  "connect_yats": "Ikonekta ang mga yats",
-  "connect_your_hardware_wallet": "Ikonekta ang iyong wallet ng hardware gamit ang Bluetooth o USB",
-  "connect_your_hardware_wallet_ios": "Ikonekta ang iyong wallet ng hardware gamit ang Bluetooth",
-  "connection_sync": "Koneksyon at pag -sync",
+  "congratulations": "Congratulations!",
+  "connect_an_existing_yat": "Ikonekta ang isang umiiral na Yat",
+  "connect_yats": "Ikonekta sa Yats",
+  "connect_your_hardware_wallet": "Ikonekta ang iyong hardware wallet gamit ang Bluetooth o USB",
+  "connect_your_hardware_wallet_ios": "Ikonekta ang iyong wallet gamit ang Bluetooth",
+  "connection_sync": "Koneksyon at pag-sync",
   "connectWalletPrompt": "Ikonekta ang iyong wallet sa WalletConnect upang gumawa ng mga transaksyon",
-  "contact": "Makipag -ugnay",
-  "contact_list_contacts": "Mga contact",
-  "contact_list_wallets": "Ang mga wallets ko",
-  "contact_name": "pangalan ng contact",
-  "contact_support": "Makipag -ugnay sa suporta",
+  "contact": "Contact",
+  "contact_list_contacts": "Mga Contact",
+  "contact_list_wallets": "Mga Wallet Ko",
+  "contact_name": "Pangalan ng Contact",
+  "contact_support": "Makipag-ugnay sa Suporta",
   "continue_text": "Magpatuloy",
   "contractName": "Pangalan ng Kontrata",
   "contractSymbol": "Simbolo ng Kontrata",
-  "copied_key_to_clipboard": "Kinopya ang ${key} sa clipboard",
-  "copied_to_clipboard": "Kinopya sa clipboard",
-  "copy": "Kopya",
-  "copy_address": "Kopyahin ang address",
-  "copy_id": "Kopyahin ang id",
+  "copied_key_to_clipboard": "Kinopya ang ${key} sa Clipboard",
+  "copied_to_clipboard": "Kinopya sa Clipboard",
+  "copy": "Kopyahin",
+  "copy_address": "Kopyahin ang Address",
+  "copy_id": "Kopyahin ang ID",
   "copyWalletConnectLink": "Kopyahin ang link ng WalletConnect mula sa dApp at i-paste dito",
   "countries": "Mga bansa",
-  "create_account": "Lumikha ng account",
-  "create_backup": "Gumawa ng backup",
+  "create_account": "Lumikha ng Account",
+  "create_backup": "Lumikha ng backup",
   "create_donation_link": "Lumikha ng link ng donasyon",
   "create_invoice": "Lumikha ng invoice",
-  "create_new": "Lumikha ng bagong pitaka",
-  "create_new_account": "Lumikha ng Bagong Account",
-  "creating_new_wallet": "Lumilikha ng bagong pitaka",
+  "create_new": "Lumikha ng Bagong Wallet",
+  "create_new_account": "Lumikha ng bagong account",
+  "creating_new_wallet": "Lumikha ng bagong wallet",
   "creating_new_wallet_error": "Error: ${description}",
   "creation_date": "Petsa ng paglikha",
-  "custom": "pasadya",
-  "custom_drag": "Pasadyang (hawakan at i -drag)",
-  "custom_redeem_amount": "Pasadyang tinubos ang halaga",
-  "custom_value": "Pasadyang halaga",
-  "dark_theme": "Madilim",
-  "debit_card": "Debit card",
-  "debit_card_terms": "Ang pag -iimbak at paggamit ng numero ng iyong card ng pagbabayad (at mga kredensyal na naaayon sa iyong numero ng card ng pagbabayad) sa digital na pitaka na ito ay napapailalim sa mga termino at kundisyon ng naaangkop na kasunduan sa cardholder kasama ang nagbigay ng card ng pagbabayad, tulad ng sa oras -oras.",
+  "custom": "Pasadya",
+  "custom_drag": "Pasadya (Hawakan at I-drag)",
+  "custom_redeem_amount": "Pasadyang Tinubos ang Halaga",
+  "custom_value": "Pasadyang Halaga",
+  "dark_theme": "Dark",
+  "debit_card": "Debit Card",
+  "debit_card_terms": "Ang pag-iimbak at paggamit ng iyong numero sa card (at mga kredensyal na nauugnay sa numero ng iyong card sa pagbabayad) sa pagbabayad sa digital wallet na ito ay napapailalim sa mga tuntunin at kundisyon ng naaangkop na kasunduan sa may-ari ng card kasama ang nagbigay ng card ng pagbabayad, na may bisa sa pana-panahon.",
   "decimal_places_error": "Masyadong maraming mga lugar na desimal",
-  "decimals_cannot_be_zero": "Ang Token Decimal ay hindi maaaring maging zero.",
-  "default_buy_provider": "Default na Provider ng Pagbili",
+  "decimals_cannot_be_zero": "Ang token decimal ay hindi maaaring maging zero.",
+  "default_buy_provider": "Default na Buy Provider",
   "default_sell_provider": "Default na Sell Provider",
   "delete": "Tanggalin",
-  "delete_account": "Tanggalin ang account",
-  "delete_wallet": "Tanggalin ang pitaka",
-  "delete_wallet_confirm_message": "Sigurado ka bang nais mong tanggalin ang ${wallet_name} wallet?",
+  "delete_account": "Tanggalin ang Account",
+  "delete_wallet": "Tanggalin ang wallet",
+  "delete_wallet_confirm_message": "Sigurado ka ba na gusto mong tanggalin ang iyong ${wallet_name} wallet?",
   "deleteConnectionConfirmationPrompt": "Sigurado ka bang gusto mong tanggalin ang koneksyon sa",
-  "denominations": "Denominasyon",
+  "denominations": "Mga Denominasyon",
   "descending": "Pababang",
   "description": "Paglalarawan",
   "destination_tag": "Tag ng patutunguhan:",
-  "dfx_option_description": "Bumili ng crypto kasama ang EUR & CHF. Para sa mga customer at corporate customer sa Europa",
+  "dfx_option_description": "Bumili ng crypto kasama ang EUR & CHF. Para sa mga retail customer at corporate customer sa Europe",
   "didnt_get_code": "Hindi nakuha ang code?",
-  "digit_pin": "-digit pin",
-  "digital_and_physical_card": "Digital at Physical Prepaid Debit Card",
+  "digit_pin": "-digit PIN",
+  "digital_and_physical_card": " digital at pisikal na prepaid debit card",
   "disable": "Huwag paganahin",
-  "disable_bulletin": "Huwag paganahin ang Bulletin ng Katayuan ng Serbisyo",
+  "disable_bulletin": "Huwag paganahin ang bulletin ng katayuan ng serbisyo",
   "disable_buy": "Huwag paganahin ang pagkilos ng pagbili",
-  "disable_cake_2fa": "Huwag paganahin ang cake 2FA",
+  "disable_cake_2fa": "Huwag paganahin ang Cake 2FA",
   "disable_exchange": "Huwag paganahin ang palitan",
-  "disable_fiat": "Huwag paganahin ang Fiat",
+  "disable_fiat": "Huwag paganahin ang fiat",
   "disable_sell": "Huwag paganahin ang pagkilos ng pagbebenta",
-  "disableBatteryOptimization": "Huwag paganahin ang pag -optimize ng baterya",
-  "disableBatteryOptimizationDescription": "Nais mo bang huwag paganahin ang pag -optimize ng baterya upang gawing mas malaya at maayos ang pag -sync ng background?",
+  "disableBatteryOptimization": "Huwag Paganahin ang Pag-optimize ng Baterya",
+  "disableBatteryOptimizationDescription": "Nais mo bang huwag paganahin ang pag-optimize ng baterya upang gawing mas malaya at maayos ang background sync?",
   "disabled": "Hindi pinagana",
   "discount": "Makatipid ng ${value}%",
   "display_settings": "Mga setting ng pagpapakita",
   "displayable": "Maipapakita",
-  "do_not_have_enough_gas_asset": "Wala kang sapat na ${currency} para gumawa ng transaksyon sa kasalukuyang kundisyon ng network ng blockchain. Kailangan mo ng higit pang ${currency} upang magbayad ng mga bayarin sa network ng blockchain, kahit na nagpapadala ka ng ibang asset.",
-  "do_not_send": "Huwag magpadala",
-  "do_not_share_warning_text": "Huwag ibahagi ang mga ito sa sinumang iba pa, kabilang ang suporta.\n\nAng iyong mga pondo ay maaari at ninakaw!",
+  "do_not_have_enough_gas_asset": "Wala kang sapat na ${currency} para gumawa ng transaksyon sa kasalukuyang kundisyon ng network ng blockchain. Kailangan mo ng higit pang ${currency} upang magbayad ng mga fee sa network ng blockchain, kahit na nagpapadala ka ng ibang asset.",
+  "do_not_send": "Huwag ipadala",
+  "do_not_share_warning_text": "Huwag ibahagi ang mga ito sa sinuman kasama ang tagatustos.\n\nMaaaring manakaw ang iyong mga pondo!",
   "do_not_show_me": "Huwag mo itong ipakita muli",
   "domain_looks_up": "Mga paghahanap ng domain",
-  "donation_link_details": "Mga Detalye ng Link ng Donasyon",
-  "e_sign_consent": "E-sign na pahintulot",
-  "edit": "I -edit",
-  "edit_backup_password": "I -edit ang backup password",
-  "edit_node": "I -edit ang node",
-  "edit_token": "I -edit ang token",
-  "electrum_address_disclaimer": "Bumubuo kami ng mga bagong address sa tuwing gumagamit ka ng isa, ngunit ang mga nakaraang address ay patuloy na gumagana",
-  "email_address": "Email address",
-  "enable_replace_by_fee": "Paganahin ang palitan-by-fee",
-  "enable_silent_payments_scanning": "Paganahin ang pag -scan ng tahimik na pagbabayad",
+  "donation_link_details": "Mga detalye ng link ng donasyon",
+  "e_sign_consent": "E-Sign Consent",
+  "edit": "I-edit",
+  "edit_backup_password": "I-edit ang backup na password",
+  "edit_node": "I-edit ang Node",
+  "edit_token": "I-edit ang token",
+  "electrum_address_disclaimer": "Bumubuo kami ng mga bagong address sa tuwing gagamit ka ng isa, ngunit ang mga nakaraang address ay patuloy na gumagana",
+  "email_address": "Email Address",
+  "enable_replace_by_fee": "Paganahin ang  Replace-By-Fee",
+  "enable_silent_payments_scanning": "Paganahin ang pag-scan ng mga tahimik na pagbabayad",
   "enabled": "Pinagana",
   "enter_amount": "Ipasok ang halaga",
-  "enter_backup_password": "Ipasok ang backup password dito",
+  "enter_backup_password": "Ipasok ang backup na password dito",
   "enter_code": "Ipasok ang code",
-  "enter_seed_phrase": "Ipasok ang iyong pariralang binhi",
-  "enter_totp_code": "Mangyaring ipasok ang TOTP code.",
-  "enter_wallet_password": "Ipasok ang password ng pitaka",
+  "enter_seed_phrase": "Ipasok ang iyong seed phrase",
+  "enter_totp_code": "Ipasok ang TOTP code",
+  "enter_wallet_password": "Ipasok ang password ng wallet",
   "enter_your_note": "Ipasok ang iyong tala ...",
-  "enter_your_pin": "Ipasok ang iyong pin",
-  "enter_your_pin_again": "Ipasok muli ang iyong pin",
-  "enterTokenID": "Ilagay ang token ID",
-  "enterWalletConnectURI": "Ilagay ang WalletConnect URI",
+  "enter_your_pin": "Ipasok ang iyong PIN",
+  "enter_your_pin_again": "Ipasok muli ang iyong PIN",
+  "enterTokenID": "Ipasok ang token ID",
+  "enterWalletConnectURI": "Ipasok ang WalletConnect URI",
   "error": "Error",
-  "error_dialog_content": "Oops, nakakuha kami ng ilang error.\n\nMangyaring ipadala ang ulat ng pag -crash sa aming koponan ng suporta upang maging mas mahusay ang application.",
+  "error_dialog_content": "Oops, nakakuha kami ng ilang error.\n\nMangyaring ipadala ang crash report sa aming koponan ng suporta upang maging mas mahusay ang application.",
   "error_text_account_name": "Ang pangalan ng account ay maaari lamang maglaman ng mga titik, numero\nat dapat sa pagitan ng 1 at 15 character ang haba",
   "error_text_address": "Ang wallet address ay dapat na tumutugma sa uri\nng cryptocurrency",
   "error_text_amount": "Ang halaga ay maaari lamang maglaman ng mga numero",
-  "error_text_contact_name": "Ang pangalan ng contact ay hindi maaaring maglaman ng mga simbolo ng ',' \"\nat dapat sa pagitan ng 1 at 32 character ang haba",
-  "error_text_crypto_currency": "Ang bilang ng mga numero ng fraction\ndapat mas mababa o katumbas ng 12",
-  "error_text_fiat": "Ang halaga ng halaga ay hindi maaaring lumampas sa magagamit na balanse.\nAng bilang ng mga numero ng fraction ay dapat na mas mababa o katumbas ng 2",
+  "error_text_contact_name": "Ang pangalan ng contact ay hindi maaaring maglaman ng ` , ' \" mga symbolo\nat dapat nasa pagitan ng 1 at 32 character ang haba",
+  "error_text_crypto_currency": "Ang bilang ng mga fraction digit\nay dapat mas mababa o katumbas ng 12",
+  "error_text_fiat": "Ang halaga ay hindi maaaring lumampas sa magagamit na balanse.\nang bilang ng mga fraction digit ay dapat na mas kaunti o katumbas ng 2",
   "error_text_input_above_maximum_limit": "Ang halaga ay higit pa sa maximum",
   "error_text_input_below_minimum_limit": "Ang halaga ay mas mababa sa minimum",
-  "error_text_keys": "Ang mga susi ng wallet ay maaari lamang maglaman ng 64 chars sa hex",
-  "error_text_limits_loading_failed": "Ang kalakalan para sa ${provider} ay hindi nilikha. Nabigo ang mga limitasyon sa paglo -load",
-  "error_text_maximum_limit": "Ang kalakalan para sa ${provider} ay hindi nilikha. Ang halaga ay higit na maximum: ${max} ${currency}",
-  "error_text_minimal_limit": "Ang kalakalan para sa ${provider} ay hindi nilikha. Ang halaga ay mas mababa pagkatapos ng minimal: ${min} ${currency}",
-  "error_text_node_address": "Mangyaring magpasok ng isang address ng IPv4",
-  "error_text_node_port": "Ang Node Port ay maaari lamang maglaman ng mga numero sa pagitan ng 0 at 65535",
-  "error_text_node_proxy_address": "Mangyaring ipasok ang <ipv4 address>: <dort>, halimbawa 127.0.0.1:9050",
-  "error_text_payment_id": "Ang Payment ID ay maaari lamang maglaman mula 16 hanggang 64 chars sa hex",
+  "error_text_keys": "Ang mga wallet key ay maaari lamang maglaman ng 64 chars sa hex",
+  "error_text_limits_loading_failed": "Ang kalakalan para sa ${provider} hindi nilikha . Nabigo ang pag-load ng mga limitasyon",
+  "error_text_maximum_limit": "Ang kalakalan para sa ${provider} ay hindi nilikha. Ang halaga ay higit sa maximum: ${max} ${currency}",
+  "error_text_minimal_limit": "Ang kalakalan para sa ${provider} ay hindi nilikha. Ang halaga ay mas mababa sa minimum: ${min} ${currency}",
+  "error_text_node_address": "Pakipasok isan iPv4 address",
+  "error_text_node_port": "Ang node port ay maaari lamang maglaman ng numero sa pagitan ng 0 at 65535",
+  "error_text_node_proxy_address": "Pakipasok <IPv4 address>: <port>, halimbawa 127.0.0.1:9050",
+  "error_text_payment_id": "Ang Payment ID ay dapat maglaman ng 16 na char sa hex",
   "error_text_subaddress_name": "Ang pangalan ng subaddress ay hindi maaaring maglaman ng mga simbolo na `, '\"\nat dapat sa pagitan ng 1 at 20 character ang haba",
   "error_text_template": "Ang pangalan ng template at address ay hindi maaaring maglaman ng mga simbolo ng ',' \"\nat dapat sa pagitan ng 1 at 106 na character ang haba",
-  "error_text_wallet_name": "Ang pangalan ng pitaka ay maaari lamang maglaman ng mga titik, numero, _ - mga simbolo\nat dapat sa pagitan ng 1 at 33 character ang haba",
+  "error_text_wallet_name": "Ang pangalan ng wallet ay maaari lamang maglaman ng mga titik, numero, _ - mga simbolo\nat dapat sa pagitan ng 1 at 33 character ang haba",
   "error_text_xmr": "Ang halaga ng XMR ay hindi maaaring lumampas sa magagamit na balanse.\nAng bilang ng mga numero ng fraction ay dapat na mas mababa o katumbas ng 12",
   "errorGettingCredentials": "Nabigo: Error habang kumukuha ng mga kredensyal",
-  "errorSigningTransaction": "May naganap na error habang pinipirmahan ang transaksyon",
+  "errorSigningTransaction": "Error habang pinipirmahan ang transaksyon",
   "estimated": "Tinatayang",
-  "estimated_new_fee": "Tinatayang bagong bayad",
+  "estimated_new_fee": "Tinatayang bagong fee",
   "estimated_receive_amount": "Tinatayang natanggap na halaga",
   "etherscan_history": "Kasaysayan ng Etherscan",
   "event": "Kaganapan",
   "events": "Mga kaganapan",
   "exchange": "Palitan",
-  "exchange_incorrect_current_wallet_for_xmr": "Kung nais mong makipagpalitan ng XMR mula sa iyong balanse ng cake wallet Monero, mangyaring lumipat sa iyong Monero Wallet muna.",
+  "exchange_incorrect_current_wallet_for_xmr": "Kung gusto mong palitan ang XMR mula sa iyong balanse ng Monero ng Cake Wallet, mangyaring lumipat muna sa iyong Monero wallet.",
   "exchange_new_template": "Bagong template",
   "exchange_provider_unsupported": "Ang ${providerName} ay hindi na suportado!",
-  "exchange_result_confirm": "Sa pamamagitan ng pagpindot ng kumpirmahin, magpapadala ka ng ${fetchingLabel} ${from} mula sa iyong pitaka na tinatawag na ${walletName} sa address na ipinakita sa ibaba. O maaari kang magpadala mula sa iyong panlabas na pitaka sa ibaba address/qr code.\n\nMangyaring pindutin ang kumpirmahin na magpatuloy o bumalik upang baguhin ang mga halaga.",
-  "exchange_result_description": "Dapat kang magpadala ng isang minimum na ${fetchingLabel} ${from} hanggang sa address na ipinakita sa susunod na pahina. Kung nagpapadala ka ng isang halaga na mas mababa kaysa sa ${fetchingLabel} ${from} maaaring hindi ito ma -convert at maaaring hindi ito ibabalik.",
-  "exchange_result_write_down_ID": "*Mangyaring kopyahin o isulat ang iyong ID na ipinakita sa itaas.",
+  "exchange_result_confirm": "Sa pamamagitan ng pagpindot sa kumpirmahin, ikaw ay magpapadala ${fetchingLabel} ${from} mula sa inyong wallet na tinatawag ${walletName} sa wallet na ipinapakita sa ibaba. O pwede kang magpadala sa inyong external wallet sa ibabang address/QR code.\n\nPara magpatuloy, mangyaring pindutin upang kumpirmahin o bumalik para baguhin ang halaga.",
+  "exchange_result_description": "Kailangan mong magpadala ng minimum ${fetchingLabel} ${from} sa address na ipinakita sa susunod na pahina. Kung magpapadala ka ng halagang mas masmababa sa ${fetchingLabel} ${from} maaring hindi ito ma-convert at maaaring hindi ito ma-refund.",
+  "exchange_result_write_down_ID": "*Mangyaring kopyahin o isulat ang inyong ID na ipinapakita sa itaas.",
   "exchange_result_write_down_trade_id": "Mangyaring kopyahin o isulat ang trade ID upang magpatuloy.",
-  "exchange_sync_alert_content": "Mangyaring maghintay hanggang ang iyong pitaka ay naka -synchronize",
-  "expired": "Nag -expire",
-  "expires": "Mag -expire",
+  "exchange_sync_alert_content": "Mangyaring maghintay hanggang ang iyong wallet ay naka-synchronize",
+  "expired": "Nag-expire na",
+  "expires": "Mag-e-expire",
   "expiresOn": "Mag-e-expire sa",
-  "expiry_and_validity": "Pag -expire at bisa",
-  "export_backup": "I -export ang backup",
+  "expiry_and_validity": "Pag-expire at Bisa",
+  "export_backup": "I-export ang backup",
   "extra_id": "Dagdag na ID:",
   "extracted_address_content": "Magpapadala ka ng pondo sa\n${recipient_name}",
-  "failed_authentication": "Nabigong pagpapatunay. ${state_error}",
+  "failed_authentication": "Nabigo ang pagpapatunay. ${state_error}",
   "faq": "FAQ",
   "features": "Mga tampok",
   "fetching": "Pagkuha",
   "fiat_api": "Fiat API",
   "fiat_balance": "Balanse ng fiat",
   "field_required": "Kinakailangan ang patlang na ito",
-  "fill_code": "Mangyaring punan ang verification code na ibinigay sa iyong email",
+  "fill_code": "Mangyaring ilagay ang verfification code na ibinigay sa iyong email",
   "filter_by": "Filter ni",
-  "first_wallet_text": "Kahanga -hangang pitaka para sa Monero, Bitcoin, Ethereum, Litecoin, at Haven",
+  "first_wallet_text": "Kahanga-hangang wallet para sa Monero, Bitcoin, Litecoin, Ethereum, at Haven",
   "fixed_pair_not_supported": "Ang nakapirming pares na ito ay hindi suportado sa mga napiling palitan",
-  "fixed_rate": "Naayos na rate",
-  "fixed_rate_alert": "Magagawa mong ipasok ang makatanggap na halaga kapag naka -check ang naayos na mode ng rate. Nais mo bang lumipat sa nakapirming mode ng rate?",
-  "forgot_password": "Nakalimutan ang password",
-  "freeze": "I -freeze",
-  "frequently_asked_questions": "Madalas na nagtanong",
+  "fixed_rate": "Fixed rate",
+  "fixed_rate_alert": "Makakapagpasok ka ng halaga ng pagtanggap kapag nasuri ang fixed rate mode. Gusto mo bang lumipat sa fixed rate mode?",
+  "forgot_password": "Nakalimutan ang Password",
+  "freeze": "I-freeze",
+  "frequently_asked_questions": "Mga madalas itanong",
   "frozen": "Frozen",
-  "full_balance": "Buong balanse",
+  "full_balance": "Buong Balanse",
   "generate_name": "Bumuo ng pangalan",
   "generating_gift_card": "Bumubuo ng Gift Card",
-  "get_a": "Kumuha ng",
-  "get_card_note": "na maaari mong i -reload sa mga digital na pera. Walang karagdagang impormasyon na kailangan!",
-  "get_your_yat": "Kunin ang iyong yat",
+  "get_a": "Kumuha ng ",
+  "get_card_note": " na maaari mong i-load gamit ang mga digital na pera. Walang karagdagang impormasyon na kailangan!",
+  "get_your_yat": "Kunin ang iyong Yat",
   "gift_card_amount": "Halaga ng Gift Card",
-  "gift_card_balance_note": "Ang mga kard ng regalo na may natitirang balanse ay lilitaw dito",
-  "gift_card_is_generated": "Ang card ng regalo ay nabuo",
-  "gift_card_number": "Numero ng regalo card",
-  "gift_card_redeemed_note": "Ang mga kard ng regalo na iyong tinubos ay lilitaw dito",
-  "gift_cards": "Mga kard ng regalo",
-  "gift_cards_unavailable": "Magagamit ang mga gift card para sa pagbili lamang kasama ang Monero, Bitcoin, at Litecoin sa oras na ito",
+  "gift_card_balance_note": "Lalabas dito ang mga gift card na may natitirang balanse",
+  "gift_card_is_generated": "Nabuo ang gift card",
+  "gift_card_number": "Numero ng gift card",
+  "gift_card_redeemed_note": "Lalabas dito ang mga gift card na na-redeem mo",
+  "gift_cards": "Mga Gift Card",
+  "gift_cards_unavailable": "Ang mga gift card ay magagamit lamang para bilhin gamit ng Monero, Bitcoin, at Litecoin sa ngayon",
   "got_it": "Nakuha ko",
-  "gross_balance": "Balanse ng gross",
+  "gross_balance": "Kabuuang balanse",
   "group_by_type": "Pangkat ayon sa uri",
-  "haven_app": "Haven sa pamamagitan ng cake wallet",
-  "haven_app_wallet_text": "Galing ng pitaka para sa Haven",
+  "haven_app": "Haven by Cake Wallet",
+  "haven_app_wallet_text": "Kahanga-hangang wallet para sa Haven",
   "help": "Tulong",
-  "hidden_balance": "Nakatagong balanse",
+  "hidden_balance": "Nakatagong Balanse",
   "hide_details": "Itago ang mga detalye",
-  "high_contrast_theme": "Mataas na tema ng kaibahan",
+  "high_contrast_theme": "High Contrast Theme",
   "home_screen_settings": "Mga setting ng home screen",
   "how_to_use": "Paano gamitin",
-  "how_to_use_card": "Paano gamitin ang kard na ito",
-  "id": "ID:",
+  "how_to_use_card": "Paano gamitin ang card na ito",
+  "id": "ID: ",
   "ignor": "Huwag pansinin",
-  "import": "Angkat",
+  "import": "Mag-import",
   "importNFTs": "Mag-import ng mga NFT",
-  "in_store": "Nakatago",
+  "in_store": "Nasa Stock",
   "incoming": "Papasok",
-  "incorrect_seed": "Ang teksto na ipinasok ay hindi wasto.",
+  "incorrect_seed": "Ang text na ipinasok ay hindi wasto.",
   "inputs": "Mga input",
-  "insufficientFundsForRentError": "Wala kang sapat na sol upang masakop ang bayad sa transaksyon at upa para sa account. Mabait na magdagdag ng higit pa sa iyong pitaka o bawasan ang halaga ng sol na iyong ipinapadala",
-  "introducing_cake_pay": "Ipinakikilala ang cake pay!",
-  "invalid_input": "Di -wastong input",
-  "invalid_password": "Di wastong password",
+  "insufficientFundsForRentError": "Wala kang sapat na SOL upang masakop ang fee sa transaksyon at upa para sa account. Mabait na magdagdag ng higit pa sa iyong wallet o bawasan ang halaga ng SOL na iyong ipinapadala",
+  "introducing_cake_pay": "Pagpapakilala ng Cake Pay!",
+  "invalid_input": "Di-wastong input",
+  "invalid_password": "Di-wastong password",
   "invoice_details": "Mga detalye ng invoice",
   "is_percentage": "ay",
-  "last_30_days": "Huling 30 araw",
+  "last_30_days": "Huling 30 na araw",
   "learn_more": "Matuto nang higit pa",
-  "ledger_connection_error": "Nabigong kumonekta sa iyo ledger. Pakisubukang muli.",
-  "ledger_error_device_locked": "Naka -lock ang ledger",
-  "ledger_error_tx_rejected_by_user": "Ang transaksyon ay tinanggihan sa aparato",
-  "ledger_error_wrong_app": "Mangyaring tiyaking pinipili mo ang tamang app sa iyong ledger",
-  "ledger_please_enable_bluetooth": "Mangyaring paganahin ang Bluetooth upang makita ang iyong ledger",
-  "light_theme": "Ilaw",
-  "load_more": "Mag -load pa",
-  "loading_your_wallet": "Naglo -load ng iyong pitaka",
-  "login": "Mag log in",
-  "logout": "Mag -logout",
-  "low_fee": "Mababang bayad",
-  "low_fee_alert": "Kasalukuyan kang gumagamit ng isang mababang priyoridad sa bayad sa network. Maaari itong maging sanhi ng mahabang paghihintay, iba't ibang mga rate, o kanselahin ang mga trading. Inirerekumenda namin ang pagtatakda ng isang mas mataas na bayad para sa isang mas mahusay na karanasan.",
+  "ledger_connection_error": "Nabigong kumonekta sa iyong Ledger. Pakisubukang muli.",
+  "ledger_error_device_locked": "Naka-lock ang Ledger",
+  "ledger_error_tx_rejected_by_user": "Ang transaksyon ay tinanggihan sa hardware wallet",
+  "ledger_error_wrong_app": "Mangyaring tiyaking pinipili mo ang tamang app sa iyong Ledger",
+  "ledger_please_enable_bluetooth": "Mangyaring paganahin ang Bluetooth upang makita ang iyong Ledger",
+  "light_theme": "Light",
+  "load_more": "Mag-load pa",
+  "loading_your_wallet": "Naglo-load ng iyong wallet",
+  "login": "Mag-login",
+  "logout": "Mag-logout",
+  "low_fee": "Mababang fee",
+  "low_fee_alert": "Kasalukuyan kang gumagamit ng isang mababang priyoridad sa network fee. Maaari itong maging sanhi ng mahabang paghihintay, iba't ibang mga rate, o kanselahin ang mga trading. Inirerekumenda namin ang pagtatakda ng isang mas mataas na fee para sa isang mas mahusay na karanasan.",
   "manage_nodes": "Pamahalaan ang mga node",
-  "manage_pow_nodes": "Pamahalaan ang mga POW node",
-  "manage_yats": "Pamahalaan ang mga yats",
+  "manage_pow_nodes": "Pamahalaan ang mga PoW node",
+  "manage_yats": "Pamahalaan ang mga Yat",
   "mark_as_redeemed": "Markahan bilang tinubos",
   "market_place": "Marketplace",
-  "matrix_green_dark_theme": "Matrix Green Madilim na Tema",
+  "matrix_green_dark_theme": "Matrix Green Dark Theme",
   "max_amount": "Max: ${value}",
   "max_value": "Max: ${value} ${currency}",
   "memo": "Memo:",
   "message": "Mensahe",
-  "methods": "Paraan",
+  "methods": "Mga Paraan",
   "min_amount": "Min: ${value}",
   "min_value": "Min: ${value} ${currency}",
   "minutes_to_pin_code": "${minute} minuto",
-  "mm": "Mm",
-  "modify_2fa": "Baguhin ang cake 2FA",
-  "monero_com": "Monero.com sa pamamagitan ng cake wallet",
-  "monero_com_wallet_text": "Galing ng pitaka para sa Monero",
-  "monero_dark_theme": "Monero Madilim na Tema",
-  "monero_light_theme": "Tema ng Monero Light",
-  "moonpay_alert_text": "Ang halaga ng halaga ay dapat na higit pa o katumbas ng ${minAmount} ${fiatCurrency}",
-  "more_options": "Higit pang mga pagpipilian",
+  "mm": "MM",
+  "modify_2fa": "Baguhin ang Cake 2FA",
+  "monero_com": "Monero.com by Cake Wallet",
+  "monero_com_wallet_text": "Kahanga-hangang wallet para sa Monero",
+  "monero_dark_theme": "Monero Dark Theme",
+  "monero_light_theme": "Monero Light Theme",
+  "moonpay_alert_text": "Ang halaga ay dapat na higit pa o katumbas ng ${minAmount} ${fiatCurrency}",
+  "more_options": "Higit pang mga Pagpipilian",
   "name": "Pangalan",
-  "nano_current_rep": "Kasalukuyang kinatawan",
-  "nano_gpt_thanks_message": "Salamat sa paggamit ng nanogpt! Tandaan na bumalik sa browser matapos makumpleto ang iyong transaksyon!",
-  "nano_pick_new_rep": "Pumili ng isang bagong kinatawan",
-  "nanogpt_subtitle": "Ang lahat ng mga pinakabagong modelo (GPT-4, Claude). \\ Nno subscription, magbayad gamit ang crypto.",
+  "nano_current_rep": "Kasalukuyang Representative",
+  "nano_gpt_thanks_message": "Salamat sa paggamit ng NanoGPT! Tandaan na bumalik sa browser matapos makumpleto ang iyong transaksyon!",
+  "nano_pick_new_rep": "Pumili ng isang bagong representative",
+  "nanogpt_subtitle": "Ang lahat ng mga pinakabagong modelo (GPT-4, Claude). \nNo subscription, magbayad gamit ang crypto.",
   "narrow": "Makitid",
   "new_first_wallet_text": "Panatilihing ligtas ang iyong crypto, piraso ng cake",
-  "new_node_testing": "Bagong pagsubok sa node",
+  "new_node_testing": "Bagong node testing",
   "new_subaddress_create": "Lumikha",
   "new_subaddress_label_name": "Pangalan ng label",
-  "new_subaddress_title": "Bagong tirahan",
-  "new_template": "Bagong template",
-  "new_wallet": "Bagong pitaka",
+  "new_subaddress_title": "Bagong address",
+  "new_template": "Bagong Template",
+  "new_wallet": "Bagong Wallet",
   "newConnection": "Bagong Koneksyon",
-  "no_cards_found": "Walang nahanap na mga kard",
+  "no_cards_found": "Walang nahanap na mga card",
   "no_id_needed": "Hindi kailangan ng ID!",
-  "no_id_required": "Walang kinakailangang ID. I -top up at gumastos kahit saan",
+  "no_id_required": "Hindi kailangan ng ID. I-top up at gumastos kahit saan",
   "no_relay_on_domain": "Walang relay para sa domain ng user o hindi available ang relay. Mangyaring pumili ng relay na gagamitin.",
   "no_relays": "Walang mga relay",
   "no_relays_message": "Nakakita kami ng Nostr NIP-05 record para sa user na ito, ngunit hindi ito naglalaman ng anumang mga relay. Mangyaring atasan ang tatanggap na magdagdag ng mga relay sa kanilang Nostr record.",
   "node_address": "Node address",
   "node_connection_failed": "Nabigo ang koneksyon",
-  "node_connection_successful": "Ang koneksyon ay matagumpay",
-  "node_new": "Bagong node",
+  "node_connection_successful": "Naging tagumpay ang konekyson",
+  "node_new": "Bagong Node",
   "node_port": "Node port",
-  "node_reset_settings_title": "I -reset ang Mga Setting",
-  "node_test": "Pagsusulit",
-  "nodes": "Node",
-  "nodes_list_reset_to_default_message": "Sigurado ka bang nais mong i -reset ang mga setting upang default?",
-  "none_of_selected_providers_can_exchange": "Wala sa mga napiling tagapagkaloob na maaaring gumawa ng palitan na ito",
+  "node_reset_settings_title": "I-reset ang mga settings",
+  "node_test": "Test",
+  "nodes": "Mga node",
+  "nodes_list_reset_to_default_message": "Sigurado ka bang gusto mo bang i-reset ang mga settings sa default?",
+  "none_of_selected_providers_can_exchange": "Wala sa mga napiling provider ang makakagawa ng palitan na ito",
   "noNFTYet": "Wala pang NFT",
   "normal": "Normal",
-  "note_optional": "Tandaan (Opsyonal)",
-  "note_tap_to_change": "Tandaan (Tapikin upang baguhin)",
+  "note_optional": "Tala (opsyonal)",
+  "note_tap_to_change": "Tala (i-tap para baguhin)",
   "nullURIError": "Ang URI ay null",
-  "offer_expires_in": "Mag -expire ang alok sa:",
+  "offer_expires_in": "Mag-expire ang alok sa: ",
   "offline": "Offline",
-  "ok": "Ok",
-  "old_fee": "Matandang bayad",
-  "onion_link": "Link ng Onion",
+  "ok": "OK",
+  "old_fee": "Dating fee",
+  "onion_link": "Onion link",
   "online": "Online",
-  "onramper_option_description": "Mabilis na bumili ng crypto na may maraming paraan ng pagbabayad. Available sa karamihan ng mga bansa. Iba-iba ang mga spread at bayarin.",
+  "onramper_option_description": "Mabilis na bumili ng crypto na may maraming paraan ng pagbabayad. Available sa karamihan ng mga bansa. Iba-iba ang mga spread at fee.",
   "open_gift_card": "Buksan ang Gift Card",
   "optional_description": "Opsyonal na paglalarawan",
-  "optional_email_hint": "Opsyonal na Payee Notification Email",
+  "optional_email_hint": "Opsyonal na payee notification email",
   "optional_name": "Opsyonal na pangalan ng tatanggap",
-  "optionally_order_card": "Opsyonal na mag -order ng isang pisikal na kard.",
-  "orbot_running_alert": "Mangyaring tiyakin na ang Orbot ay tumatakbo bago kumonekta sa node na ito.",
+  "optionally_order_card": "Opsyonal na mag-order ng pisikal na card.",
+  "orbot_running_alert": "Pakitiyak na tumatakbo ang Orbot bago kumonekta sa node na ito.",
   "order_by": "Iniutos ni",
-  "order_id": "Order id",
-  "order_physical_card": "Mag -order ng pisikal na kard",
+  "order_id": "Order ID",
+  "order_physical_card": "Mag-order ng Pisical na Card",
   "other_settings": "Iba pang mga setting",
-  "outdated_electrum_wallet_description": "Ang mga bagong wallets ng Bitcoin na nilikha sa cake ay mayroon na ngayong 24-salitang binhi. Ipinag-uutos na lumikha ka ng isang bagong pitaka ng Bitcoin at ilipat ang lahat ng iyong mga pondo sa bagong 24-salitang pitaka, at itigil ang paggamit ng mga pitaka na may 12-salitang binhi. Mangyaring gawin ito kaagad upang ma -secure ang iyong mga pondo.",
-  "outdated_electrum_wallet_receive_warning": "Kung ang pitaka na ito ay may 12-salitang binhi at nilikha sa cake, huwag magdeposito sa Bitcoin sa pitaka na ito. Ang anumang BTC na inilipat sa pitaka na ito ay maaaring mawala. Lumikha ng isang bagong 24-word wallet (tapikin ang menu sa kanang tuktok, piliin ang mga pitaka, piliin ang Lumikha ng Bagong Wallet, pagkatapos ay piliin ang Bitcoin) at agad na ilipat ang iyong BTC doon. Ang mga bagong (24-salita) BTC Wallets mula sa cake ay ligtas",
+  "outdated_electrum_wallet_description": "Ang mga bagong Bitcoin wallet na ginagawa sa Cake ay mayroon na ngayong 24 na salita na seed. Ipinag-uutos na lumikha ka ng bagong bitcoin wallet at ilipat ang lahat ng iyong pondo sa bagong 24-salitang wallet, at ihinto ang paggamit ng mga wallet na may 12-salitang seed. Mangyaring gawin ito kaagad upang ma-secure ang iyong mga pondo.",
+  "outdated_electrum_wallet_receive_warning": "Kung ang wallet na ito ay may 12-word seed na ginawa sa Cake, huwag magdeposito ng Bitcoin sa wallet na ito. Anumang BTC na inilipat sa wallet na ito ay maaaring mawala. Lumikha ng bagong 24 na salita na wallet (i-tap ang menu sa kanang taas, piliin ang Mga Wallets, piliin ang Lumikha ng Bagong Wallet, pagkatapos ay piliin ang Bitcoin) at agad na ilipat ang iyong BTC doon. Bagong (24 na salita) BTC wallet mula sa Cake ay ligtas",
   "outgoing": "Palabas",
   "outputs": "Mga output",
-  "overwrite_amount": "Overwrite na halaga",
-  "pairingInvalidEvent": "Pagpares ng Di-wastong Kaganapan",
+  "overwrite_amount": "I-overwrite ang halaga",
+  "pairingInvalidEvent": "Pairing Invalid Event",
   "passphrase": "Passphrase (opsyonal)",
   "password": "Password",
-  "paste": "I -paste",
+  "paste": "I-paste",
   "pause_wallet_creation": "Kasalukuyang naka-pause ang kakayahang gumawa ng Haven Wallet.",
-  "payment_id": "Payment ID:",
-  "payment_was_received": "Natanggap ang iyong pagbabayad.",
-  "pending": "(Pending)",
+  "payment_id": "Payment ID: ",
+  "payment_was_received": "Natanggap ang iyong bayad.",
+  "pending": "(hindi pa tapos)",
   "percentageOf": "ng ${amount}",
-  "pin_at_top": "Pin ${token} sa tuktok",
-  "pin_is_incorrect": "Mali ang pin",
-  "pin_number": "Numero ng pin",
+  "pin_at_top": "I-pin ${token} sa tuktok",
+  "pin_is_incorrect": "Mali ang PIN",
+  "pin_number": "Numero ng PIN",
   "placeholder_contacts": "Ang iyong mga contact ay ipapakita dito",
   "placeholder_transactions": "Ang iyong mga transaksyon ay ipapakita dito",
-  "please_fill_totp": "Mangyaring punan ang 8-digit na code na naroroon sa iyong iba pang aparato",
-  "please_make_selection": "Mangyaring gumawa ng isang pagpipilian sa ibaba upang lumikha o mabawi ang iyong pitaka.",
-  "please_reference_document": "Mangyaring sanggunian ang mga dokumento sa ibaba para sa karagdagang impormasyon.",
+  "please_fill_totp": "Mangyaring punan ang 8-digit na code na naroroon sa iyong iba pang device",
+  "please_make_selection": "Mangyaring gumawa ng isang pagpipilian sa ibaba upang lumikha o mabawi ang iyong wallet.",
+  "please_reference_document": "Mangyaring sumangguni sa mga dokumento sa ibaba para sa karagdagang impormasyon.",
   "please_select": "Pakipili:",
-  "please_select_backup_file": "Mangyaring piliin ang backup file at ipasok ang backup password.",
-  "please_try_to_connect_to_another_node": "Mangyaring subukang kumonekta sa isa pang node",
+  "please_select_backup_file": "Mangyaring piliin ang backup na file at ipasok ang backup na password.",
+  "please_try_to_connect_to_another_node": "Pakisubukang kumonekta sa iba pang node",
   "please_wait": "Mangyaring maghintay",
   "polygonscan_history": "Kasaysayan ng PolygonScan",
-  "powered_by": "Pinapagana ng ${title}",
-  "pre_seed_button_text": "Naiintindihan ko. Ipakita sa akin ang aking binhi",
-  "pre_seed_description": "Sa susunod na pahina makikita mo ang isang serye ng mga ${words} na mga salita. Ito ang iyong natatangi at pribadong binhi at ito ang tanging paraan upang mabawi ang iyong pitaka kung sakaling mawala o madepektong paggawa. Responsibilidad mong isulat ito at itago ito sa isang ligtas na lugar sa labas ng cake wallet app.",
-  "pre_seed_title": "Mahalaga",
-  "prepaid_cards": "Prepaid card",
-  "prevent_screenshots": "Maiwasan ang mga screenshot at pag -record ng screen",
-  "privacy": "Privacy",
+  "powered_by": "Pinapatakbo ng${title}",
+  "pre_seed_button_text": "Naiitindihan ko. Ipakita ang aking seed",
+  "pre_seed_description": "Sa susunod na pahina ay makikita mo ang isang serye ng ${words} na salita. Ito ang iyong natatangi at pribadong seed at ito ang tanging paraan upang mabawi ang iyong wallet kung sakaling mawala o hindi gumana. Responsibilidad mong isulat ito sa isang ligtas na lugar sa labas ng Cake Wallet app.",
+  "pre_seed_title": "MAHALAGA",
+  "prepaid_cards": "Mga Prepaid Card",
+  "prevent_screenshots": "Maiwasan ang mga screenshot at pag-record ng screen",
+  "privacy": "Pagkapribado",
   "privacy_policy": "Patakaran sa Pagkapribado",
   "privacy_settings": "Settings para sa pagsasa-pribado",
-  "private_key": "Pribadong susi",
-  "proceed_after_one_minute": "Kung ang screen ay hindi magpatuloy pagkatapos ng 1 minuto, suriin ang iyong email.",
-  "proceed_on_device": "Magpatuloy sa iyong aparato",
-  "proceed_on_device_description": "Mangyaring sundin ang mga tagubilin na sinenyasan sa iyong wallet ng hardware",
+  "private_key": "Private key",
+  "proceed_after_one_minute": "Kung ang screen ay hindi magpapatuloy pagkatapos ng 1 minuto, suriin ang iyong email.",
+  "proceed_on_device": "Magpatuloy sa iyong hardware wallet",
+  "proceed_on_device_description": "Mangyaring sundin ang mga tagubilin na sinenyasan sa iyong hardware wallet",
   "profile": "Profile",
   "provider_error": "${provider} error",
-  "public_key": "Pampublikong susi",
+  "public_key": "Public key",
   "purchase_gift_card": "Bumili ng Gift Card",
-  "purple_dark_theme": "Purple Madilim na Tema",
-  "qr_fullscreen": "Tapikin upang buksan ang buong screen QR code",
-  "qr_payment_amount": "Ang QR code na ito ay naglalaman ng isang halaga ng pagbabayad. Nais mo bang i -overwrite ang kasalukuyang halaga?",
+  "purple_dark_theme": "Purple Dark Theme",
+  "qr_fullscreen": "I-tap para makuha ang buong screen na QR code",
+  "qr_payment_amount": "Ang QR code na ito ay naglalaman ng halaga ng pagbabayad. Gusto mo bang i-overwrite ang kasalukuyang halaga?",
   "quantity": "Dami",
-  "question_to_disable_2fa": "Sigurado ka bang nais mong huwag paganahin ang cake 2fa? Ang isang 2FA code ay hindi na kinakailangan upang ma -access ang pitaka at ilang mga pag -andar.",
+  "question_to_disable_2fa": "Sigurado ka bang nais mong huwag paganahin ang Cake 2FA? Ang isang 2FA code ay hindi na kinakailangan upang ma-access ang wallet at ilang mga pag-andar.",
   "receivable_balance": "Natatanggap na balanse",
   "receive": "Tumanggap",
   "receive_amount": "Halaga",
   "received": "Natanggap",
   "recipient_address": "Address ng tatanggap",
   "reconnect": "Kumonekta muli",
-  "reconnect_alert_text": "Sigurado ka bang nais mong muling kumonekta?",
-  "reconnection": "Pag -ugnay muli",
-  "red_dark_theme": "Red Madilim na Tema",
-  "red_light_theme": "Red light tema",
+  "reconnect_alert_text": "Sigurado ka bang gusto mong kumonekta uli?",
+  "reconnection": "Muling pagkakakonekta",
+  "red_dark_theme": "Red Dark Theme",
+  "red_light_theme": "Red Light Theme",
   "redeemed": "Tinubos",
-  "refund_address": "Refund address",
+  "refund_address": "Address ng refund",
   "reject": "Tanggihan",
   "remaining": "natitira",
   "remove": "Alisin",
   "remove_node": "Alisin ang node",
-  "remove_node_message": "Sigurado ka bang nais mong alisin ang napiling node?",
+  "remove_node_message": "Sigurado ka bang gusto mong alisin ang napiling node?",
   "rename": "Palitan ang pangalan",
-  "rep_warning": "Babala ng kinatawan",
-  "rep_warning_sub": "Ang iyong kinatawan ay hindi lilitaw na nasa mabuting kalagayan. Tapikin dito upang pumili ng bago",
-  "repeat_wallet_password": "Ulitin ang password ng pitaka",
-  "repeated_password_is_incorrect": "Ang paulit -ulit na password ay hindi tama. Mangyaring ulitin muli ang password ng pitaka.",
+  "rep_warning": "Babala ng Representative",
+  "rep_warning_sub": "Ang iyong representative ay hindi lilitaw na nasa mabuting kalagayan. Tapikin dito upang pumili ng bago",
+  "repeat_wallet_password": "Ulitin ang password ng wallet",
+  "repeated_password_is_incorrect": "Ang paulit-ulit na password ay hindi tama. Mangyaring ulitin muli ang password ng wallet.",
   "require_for_adding_contacts": "Nangangailangan para sa pagdaragdag ng mga contact",
   "require_for_all_security_and_backup_settings": "Nangangailangan para sa lahat ng mga setting ng seguridad at backup",
-  "require_for_assessing_wallet": "Nangangailangan para sa pag -access ng pitaka",
-  "require_for_creating_new_wallets": "Nangangailangan para sa paglikha ng mga bagong pitaka",
-  "require_for_exchanges_to_external_wallets": "Kinakailangan para sa mga palitan sa mga panlabas na wallet",
-  "require_for_exchanges_to_internal_wallets": "Nangangailangan para sa mga palitan sa mga panloob na mga pitaka",
+  "require_for_assessing_wallet": "Nangangailangan para sa pag-access ng wallet",
+  "require_for_creating_new_wallets": "Nangangailangan para sa paglikha ng mga bagong wallet",
+  "require_for_exchanges_to_external_wallets": "Nangangailangan para sa mga palitan sa mga panlabas na wallet",
+  "require_for_exchanges_to_internal_wallets": "Nangangailangan para sa mga palitan sa mga panloob na wallet",
   "require_for_sends_to_contacts": "Nangangailangan para sa pagpapadala sa mga contact",
-  "require_for_sends_to_internal_wallets": "Nangangailangan para sa pagpapadala sa mga panloob na mga pitaka",
+  "require_for_sends_to_internal_wallets": "Nangangailangan para sa pagpapadala sa mga panloob na wallet",
   "require_for_sends_to_non_contacts": "Nangangailangan para sa pagpapadala sa mga hindi contact",
-  "require_pin_after": "Nangangailangan ng pin pagkatapos",
-  "rescan": "Rescan",
-  "resend_code": "Mangyaring ipagpatuloy ito",
-  "reset": "I -reset",
-  "reset_password": "I -reset ang password",
-  "restore_active_seed": "Aktibong binhi",
+  "require_pin_after": "Nangangailangan ng PIN pagkatapos",
+  "rescan": "Muling i-scan",
+  "resend_code": "Mangyaring ipadala ito muli",
+  "reset": "I-reset",
+  "reset_password": "I-reset ang password",
+  "restore_active_seed": "Aktibong seed",
   "restore_address": "Address",
-  "restore_bitcoin_description_from_keys": "Ibalik ang iyong pitaka mula sa nabuong wif string mula sa iyong mga pribadong susi",
-  "restore_bitcoin_description_from_seed": "Ibalik ang iyong pitaka mula sa 24 na code ng kombinasyon ng salita",
+  "restore_bitcoin_description_from_keys": "Ibalik ang iyong wallet mula sa nabuong WIF string mula sa iyong mga private key",
+  "restore_bitcoin_description_from_seed": "Ibalik ang iyong wallet mula sa 24 na salita na seed",
   "restore_bitcoin_title_from_keys": "Ibalik mula sa WIF",
-  "restore_description_from_backup": "Maaari mong ibalik ang buong cake wallet app mula sa iyong back-up file",
-  "restore_description_from_hardware_wallet": "Ibalik mula sa isang ledger hardware wallet",
-  "restore_description_from_keys": "Ibalik ang iyong pitaka mula sa nabuong mga keystroke na na -save mula sa iyong mga pribadong susi",
-  "restore_description_from_seed": "Ibalik ang iyong pitaka mula sa alinman sa 25 salita o 13 na code ng kombinasyon ng salita",
-  "restore_description_from_seed_keys": "Ibalik ang iyong pitaka mula sa mga binhi/susi na na -save mo upang ma -secure ang lugar",
-  "restore_from_date_or_blockheight": "Mangyaring magpasok ng isang petsa ng ilang araw bago mo nilikha ang pitaka na ito. O kung alam mo ang blockheight, mangyaring ipasok ito sa halip",
-  "restore_from_seed_placeholder": "Mangyaring ipasok o i -paste ang iyong binhi dito",
-  "restore_new_seed": "Bagong binhi",
+  "restore_description_from_backup": "Maari mong ibalik ang buong Cake Wallet app sa iyong backup file",
+  "restore_description_from_hardware_wallet": "Ibalik mula sa isang Ledger hardware wallet",
+  "restore_description_from_keys": "Ibalik ang iyong wallet mula sa nabuong mga keystrokes na na-save mula sa iyong mga private key",
+  "restore_description_from_seed": "Ibalik ang iyong wallet mula sa alinman sa 25 na salita o 13 na salita na seed",
+  "restore_description_from_seed_keys": "Ibalik ang inyong wallet mula sa inyong seed/keys na iyong na-save sa ligtas na lugar",
+  "restore_from_date_or_blockheight": "Mangyaring maglagay ng petsa ilang araw bago mo ginawa ang wallet na ito. O kung alam mo ang block height pwede ilagay ito sa halip",
+  "restore_from_seed_placeholder": "Mangyaring ipasok o idikit ang iyong seed dito",
+  "restore_new_seed": "Bagong seed",
   "restore_next": "Susunod",
   "restore_recover": "Ibalik",
-  "restore_restore_wallet": "Ibalik ang pitaka",
-  "restore_seed_keys_restore": "Ibinalik ang mga binhi/susi",
-  "restore_spend_key_private": "Gumastos ng susi (pribado)",
+  "restore_restore_wallet": "Ibalik ang wallet",
+  "restore_seed_keys_restore": "Ibalik mula sa Seed/Keys",
+  "restore_spend_key_private": "Spend key (private)",
   "restore_title_from_backup": "Ibalik mula sa backup",
-  "restore_title_from_hardware_wallet": "Ibalik mula sa pitaka ng hardware",
-  "restore_title_from_keys": "Ibalik mula sa mga susi",
-  "restore_title_from_seed": "Ibalik mula sa binhi",
-  "restore_title_from_seed_keys": "Ibalik mula sa mga binhi/susi",
-  "restore_view_key_private": "Tingnan ang Key (Pribado)",
-  "restore_wallet": "Ibalik ang pitaka",
-  "restore_wallet_name": "Pangalan ng Wallet",
-  "restore_wallet_restore_description": "Paglalarawan ng Wallet",
+  "restore_title_from_hardware_wallet": "Ibalik mula sa hardware wallet",
+  "restore_title_from_keys": "Ibalik mula sa keys",
+  "restore_title_from_seed": "Ibalik mula sa seed",
+  "restore_title_from_seed_keys": "Ibalik mula sa seed/keys",
+  "restore_view_key_private": "View key (private)",
+  "restore_wallet": "Ibalik ang wallet",
+  "restore_wallet_name": "Pangalan ng wallet",
+  "restore_wallet_restore_description": "Paglalarawan ng pagpapanumbalik ng wallet",
   "robinhood_option_description": "Bumili at ilipat kaagad gamit ang iyong debit card, bank account, o balanse ng Robinhood. USA lang.",
-  "router_no_route": "Walang ruta na tinukoy para sa ${name}",
-  "save": "I -save",
-  "save_backup_password": "Mangyaring tiyaking nai -save mo ang iyong backup password. Hindi mo mai -import ang iyong mga backup na file nang wala ito.",
-  "save_backup_password_alert": "I -save ang backup password",
-  "save_to_downloads": "I -save sa mga pag -download",
-  "saved_the_trade_id": "Nai -save ko ang trade ID",
-  "scan_one_block": "I -scan ang isang bloke",
-  "scan_qr_code": "I -scan ang QR Code",
-  "scan_qr_code_to_get_address": "I -scan ang QR code upang makuha ang address",
+  "router_no_route": "Walang tinukoy na ruta para sa ${name}",
+  "save": "I-save",
+  "save_backup_password": "Pakitiyak na nai-save mo ang iyong backup na password. Hindi mo mai-import ang iyong mga backup na file kun wala ito.",
+  "save_backup_password_alert": "I-save ang backup na password",
+  "save_to_downloads": "I-save sa mga Pag-download",
+  "saved_the_trade_id": "Nai-save ko na ang trade ID",
+  "scan_one_block": "I-scan ang isang bloke",
+  "scan_qr_code": "I-scan ang QR code",
+  "scan_qr_code_to_get_address": "I-scan ang QR code upang makuha ang address",
   "scan_qr_on_device": "I-scan ang QR code na ito sa ibang device",
   "search": "Maghanap",
   "search_add_token": "Maghanap / Magdagdag ng Token",
   "search_category": "Kategorya ng paghahanap",
   "search_currency": "Maghanap ng pera",
   "search_language": "Maghanap ng wika",
-  "second_intro_content": "Ang iyong yat ay isang solong natatanging address ng emoji na pumapalit sa lahat ng iyong mahabang hexadecimal address para sa lahat ng iyong mga pera.",
-  "second_intro_title": "Isang address ng emoji upang mamuno sa kanilang lahat",
+  "second_intro_content": "Ang iyong Yat ay isang natatanging emoji address na pumapalit sa lahat ng iyong mahabang hexadecimal address para sa lahat ng iyong pera.",
+  "second_intro_title": "Isang emoji address para pamunuan silang lahat",
   "security_and_backup": "Seguridad at backup",
-  "seed_alert_back": "Bumalik ka",
-  "seed_alert_content": "Ang binhi ay ang tanging paraan upang mabawi ang iyong pitaka. Nasulat mo na ba ito?",
-  "seed_alert_title": "Pansin",
+  "seed_alert_back": "Bumalik",
+  "seed_alert_content": "Ang seed ay ang tanging paraan upang mabawi ang iyong wallet. Naisulat mo na ba?",
+  "seed_alert_title": "Attention",
   "seed_alert_yes": "Oo meron ako",
-  "seed_choose": "Pumili ng wika ng binhi",
+  "seed_choose": "Pumili ng seed language",
   "seed_hex_form": "Wallet seed (hex form)",
-  "seed_key": "Seed Key",
-  "seed_language": "Wika ng binhi",
-  "seed_language_chinese": "Tsino",
-  "seed_language_chinese_traditional": "Intsik (tradisyonal)",
+  "seed_key": "Seed key",
+  "seed_language": "Wika ng seed",
+  "seed_language_chinese": "Chinese",
+  "seed_language_chinese_traditional": "Chinese (Traditional)",
   "seed_language_czech": "Czech",
   "seed_language_dutch": "Dutch",
-  "seed_language_english": "Ingles",
-  "seed_language_french": "Pranses",
-  "seed_language_german": "Aleman",
-  "seed_language_italian": "Italyano",
-  "seed_language_japanese": "Hapon",
+  "seed_language_english": "English",
+  "seed_language_french": "French",
+  "seed_language_german": "German",
+  "seed_language_italian": "Italian",
+  "seed_language_japanese": "Japanese",
   "seed_language_korean": "Korean",
   "seed_language_next": "Susunod",
-  "seed_language_portuguese": "Portuges",
+  "seed_language_portuguese": "Portuguese",
   "seed_language_russian": "Russian",
-  "seed_language_spanish": "Espanyol",
-  "seed_phrase_length": "Haba ng parirala ng binhi",
-  "seed_reminder": "Mangyaring isulat ang mga ito kung sakaling mawala ka o punasan ang iyong telepono",
-  "seed_share": "Magbahagi ng binhi",
-  "seed_title": "Binhi",
-  "seedtype": "Seedtype",
-  "seedtype_legacy": "Pamana (25 salita)",
+  "seed_language_spanish": "Spanish",
+  "seed_phrase_length": "Haba ng parirala ng seed",
+  "seed_reminder": "Mangyaring isulat ang mga ito kung sakaling mawala o mabura sa inyong telepono",
+  "seed_share": "Ibahagi ang seed",
+  "seed_title": "Seed",
+  "seedtype": "Seed type",
+  "seedtype_legacy": "Legacy (25 na salita)",
   "seedtype_polyseed": "Polyseed (16 na salita)",
-  "select_backup_file": "Piliin ang backup file",
+  "select_backup_file": "Piliin ang backup na file",
   "select_buy_provider_notice": "Pumili ng provider ng pagbili sa itaas. Maaari mong laktawan ang screen na ito sa pamamagitan ng pagtatakda ng iyong default na provider ng pagbili sa mga setting ng app.",
-  "select_destination": "Mangyaring piliin ang patutunguhan para sa backup file.",
+  "select_destination": "Mangyaring piliin ang patutunguhan para sa backup na file.",
   "select_sell_provider_notice": "Pumili ng provider ng nagbebenta sa itaas. Maaari mong laktawan ang screen na ito sa pamamagitan ng pagtatakda ng iyong default na sell provider sa mga setting ng app.",
   "sell": "Ibenta",
-  "sell_alert_content": "Kasalukuyan lamang naming sinusuportahan ang pagbebenta ng Bitcoin, Ethereum at Litecoin. Mangyaring lumikha o lumipat sa iyong Bitcoin, Ethereum o Litecoin Wallet.",
+  "sell_alert_content": "Kasalukuyan lamang naming sinusuportahan ang pagbebenta ng Bitcoin, Ethereum at Litecoin. Mangyaring lumikha o lumipat sa iyong Bitcoin, Ethereum o Litecoin wallet.",
   "sell_monero_com_alert_content": "Ang pagbebenta ng Monero ay hindi pa suportado",
   "send": "Ipadala",
   "send_address": "${cryptoCurrency} address",
   "send_amount": "Halaga:",
   "send_creating_transaction": "Paglikha ng transaksyon",
-  "send_error_currency": "Ang pera ay maaari lamang maglaman ng mga numero",
-  "send_error_minimum_value": "Ang pinakamababang halaga ng halaga ay 0.01",
-  "send_estimated_fee": "Tinatayang bayad:",
-  "send_fee": "Bayad:",
+  "send_error_currency": "Ang halaga ay maaari lamang maglaman ng mga numero",
+  "send_error_minimum_value": "Ang minimum na halaga ay 0.01",
+  "send_estimated_fee": "Tinatayang fee:",
+  "send_fee": "Fee:",
   "send_name": "Pangalan",
   "send_new": "Bago",
-  "send_payment_id": "Payment ID (Opsyonal)",
-  "send_priority": "Sa kasalukuyan ang bayad ay nakatakda sa ${transactionPriority} priority.\nAng priority ng transaksyon ay maaaring maiakma sa mga setting",
-  "send_sending": "Pagpapadala ...",
-  "send_success": "Ang iyong ${crypto} ay matagumpay na naipadala",
-  "send_templates": "Mga template",
+  "send_payment_id": "Payment ID (opsyonal)",
+  "send_priority": "Kasalukuyang nakatakda ang fee sa ${transactionPriority} priyoridad.\n Ang priyoridad ng transaksyon ay maaaring isaayos sa mga setting",
+  "send_sending": "Nagpapadala...",
+  "send_success": "Matagumpay na naipadala ang iyong ${crypto}",
+  "send_templates": "Mga Template",
   "send_title": "Ipadala",
-  "send_to_this_address": "Magpadala ng ${currency} ${tag} sa address na ito",
-  "send_xmr": "Magpadala ng XMR",
-  "send_your_wallet": "Iyong pitaka",
-  "sending": "Pagpapadala",
+  "send_to_this_address": "Ipadala ang ${currency} ${tag} sa address na ito",
+  "send_xmr": "Ipadala ang XMR",
+  "send_your_wallet": "Iyong wallet",
+  "sending": "Nagpapadala",
   "sent": "Ipinadala",
-  "service_health_disabled": "Hindi pinagana ang Bulletin ng Serbisyo sa Kalusugan",
-  "service_health_disabled_message": "Ito ang pahina ng Bulletin ng Serbisyo ng Bulletin, maaari mong paganahin ang pahinang ito sa ilalim ng Mga Setting -> Pagkapribado",
-  "settings": "Mga setting",
-  "settings_all": "Lahat",
-  "settings_allow_biometrical_authentication": "Payagan ang pagpapatunay ng biometrical",
+  "service_health_disabled": "Hindi pinagana ang Service Health Bulletin",
+  "service_health_disabled_message": "Ito ang pahina ng Service Health Bulletin, maaari mong paganahin ang pahinang ito sa ilalim ng Mga Setting -> Pagkapribado",
+  "settings": "Mga Setting",
+  "settings_all": "LAHAT",
+  "settings_allow_biometrical_authentication": "Payagan ang biometrical authentication",
   "settings_can_be_changed_later": "Ang mga setting na ito ay maaaring mabago mamaya sa mga setting ng app",
   "settings_change_language": "Baguhin ang wika",
-  "settings_change_pin": "Baguhin ang pin",
+  "settings_change_pin": "Baguhin ang PIN",
   "settings_currency": "Pera",
   "settings_current_node": "Kasalukuyang node",
-  "settings_dark_mode": "Madilim na mode",
+  "settings_dark_mode": "Dark mode",
   "settings_display_balance": "Ipakita ang balanse",
   "settings_display_on_dashboard_list": "Ipakita sa listahan ng dashboard",
-  "settings_fee_priority": "Priority priority",
-  "settings_nodes": "Node",
+  "settings_fee_priority": "Priyoridad sa fee",
+  "settings_nodes": "Mga node",
   "settings_none": "Wala",
-  "settings_only_trades": "TRADES LAMANG",
+  "settings_only_trades": "Mga nangangalakal lamang",
   "settings_only_transactions": "Mga transaksyon lamang",
   "settings_personal": "Personal",
-  "settings_save_recipient_address": "I -save ang address ng tatanggap",
+  "settings_save_recipient_address": "I-save ang address ng tatanggap",
   "settings_support": "Suporta",
   "settings_terms_and_conditions": "Mga Tuntunin at Kundisyon",
-  "settings_title": "Mga setting",
-  "settings_trades": "Trading",
-  "settings_transactions": "Mga Transaksyon",
-  "settings_wallets": "Wallets",
-  "setup_2fa": "Setup cake 2fa",
-  "setup_2fa_text": "Gumagana ang Cake 2FA gamit ang TOTP bilang pangalawang kadahilanan sa pagpapatunay.\n\nAng TOTP ng Cake 2FA ay nangangailangan ng SHA-512 at 8 digit na suporta; nagbibigay ito ng mas mataas na seguridad. Higit pang impormasyon at suportadong app ang makikita sa gabay.",
-  "setup_pin": "Setup pin",
-  "setup_successful": "Matagumpay na na -set up ang iyong pin!",
+  "settings_title": "Mga Setting",
+  "settings_trades": "Mga kalakalan",
+  "settings_transactions": "Mga transaksyon",
+  "settings_wallets": "Mga wallet",
+  "setup_2fa": "Setup Cake 2FA",
+  "setup_2fa_text": "Gumagana ang Cake 2FA gamit ang TOTP bilang pangalawang kadahilanan sa pagpapatunay.\n\nAng TOTP ng Cake 2FA ay nangangailangan ng SHA-512 at 8 digit na suporta; nagbibigay ito ng mas mataas na seguridad. Higit pang impormasyon at suportadong app ang makikita sa guide.",
+  "setup_pin": "I-Setup ang PIN",
+  "setup_successful": "Matagumpay na na-set up ang iyong PIN!",
   "setup_totp_recommended": "I-setup ang TOTP",
-  "setup_warning_2fa_text": "Kakailanganin mong ibalik ang iyong wallet mula sa mnemonic seed.\n\nHindi ka matutulungan ng suporta sa cake kung mawawalan ka ng access sa iyong 2FA o mnemonic seeds.\nAng Cake 2FA ay pangalawang pagpapatotoo para sa ilang partikular na pagkilos sa wallet. Bago gamitin ang Cake 2FA, inirerekomenda naming basahin ang gabay.HINDI ito kasing-secure ng malamig na imbakan.\n\nKung nawalan ka ng access sa iyong 2FA app o TOTP keys, MAWAWALA ka ng access sa wallet na ito. ",
-  "setup_your_debit_card": "I -set up ang iyong debit card",
+  "setup_warning_2fa_text": "Ang Cake 2FA ay pangalawang pagpapatotoo para sa ilang partikular na pagkilos sa wallet. HINDI ito kasing-secure ng cold wallet.\n\nKung mawalan ka ng access sa iyong 2FA app o TOTP keys, MAWAWALA ka ng access sa wallet na ito. Kakailanganin mong i-restore ang iyong wallet mula sa mnemonic seed.\n\nHindi ka matutulungan ng Cake support kung mawawalan ka ng access sa iyong 2FA o mnemonic seeds.\nBago gamitin ang Cake 2FA, inirerekomenda naming basahin ang guide.",
+  "setup_your_debit_card": "I-set up ang iyong debit card",
   "share": "Ibahagi",
   "share_address": "Ibahagi ang address",
   "show_details": "Ipakita ang mga detalye",
-  "show_keys": "Ipakita ang mga binhi/susi",
+  "show_keys": "Ipakita ang mga seed/key",
   "show_market_place": "Ipakita ang Marketplace",
-  "show_seed": "Magpakita ng binhi",
-  "sign_up": "Mag -sign up",
-  "signTransaction": "Mag-sign Transaksyon",
-  "signup_for_card_accept_terms": "Mag -sign up para sa card at tanggapin ang mga termino.",
+  "show_seed": "Ipakita ang seed",
+  "sign_up": "Mag-sign Up",
+  "signTransaction": "Mag-sign ang Transaksyon",
+  "signup_for_card_accept_terms": "Mag-sign up para sa card at tanggapin ang mga tuntunin.",
   "silent_payments": "Tahimik na pagbabayad",
-  "silent_payments_always_scan": "Itakda ang mga tahimik na pagbabayad na laging nag -scan",
+  "silent_payments_always_scan": "Itakda ang mga tahimik na pagbabayad na laging nag-scan",
   "silent_payments_disclaimer": "Ang mga bagong address ay hindi mga bagong pagkakakilanlan. Ito ay isang muling paggamit ng isang umiiral na pagkakakilanlan na may ibang label.",
   "silent_payments_display_card": "Ipakita ang Silent Payment Card",
-  "silent_payments_scan_from_date": "I -scan mula sa petsa",
-  "silent_payments_scan_from_date_or_blockheight": "Mangyaring ipasok ang taas ng block na nais mong simulan ang pag -scan para sa papasok na tahimik na pagbabayad, o, gamitin ang petsa sa halip. Maaari kang pumili kung ang pitaka ay patuloy na pag -scan sa bawat bloke, o suriin lamang ang tinukoy na taas.",
-  "silent_payments_scan_from_height": "I -scan mula sa taas ng block",
-  "silent_payments_scanned_tip": "Na -scan sa tip! (${tip})",
-  "silent_payments_scanning": "Tahimik na pag -scan ng mga pagbabayad",
+  "silent_payments_scan_from_date": "I-scan mula sa petsa",
+  "silent_payments_scan_from_date_or_blockheight": "Mangyaring ipasok ang block height na gusto mong simulan ang pag-scan para sa papasok na tahimik na pagbabayad, o, gamitin ang petsa sa halip. Maaari kang pumili kung ang wallet ay patuloy na pag-scan sa bawat bloke, o suriin lamang ang tinukoy na taas.",
+  "silent_payments_scan_from_height": "I-scan mula sa block height",
+  "silent_payments_scanned_tip": "Na-scan sa tip! (${tip})",
+  "silent_payments_scanning": "Pag-scan ng tahimik na pagbabayad",
   "silent_payments_settings": "Mga setting ng tahimik na pagbabayad",
   "slidable": "Slidable",
-  "sort_by": "Pag -uri -uriin sa pamamagitan ng",
-  "spend_key_private": "Gumastos ng susi (pribado)",
-  "spend_key_public": "Gumastos ng susi (publiko)",
-  "status": "Katayuan:",
+  "sort_by": "Pag-uri-uriin sa pamamagitan ng",
+  "spend_key_private": "Spend key (private)",
+  "spend_key_public": "Spend key (public)",
+  "status": "Katayuan: ",
   "string_default": "Default",
   "subaddress_title": "Listahan ng Subaddress",
-  "subaddresses": "Mga Subaddresses",
+  "subaddresses": "Mga Subaddress",
   "submit_request": "magsumite ng isang kahilingan",
   "successful": "Matagumpay",
   "support_description_guides": "Dokumentasyon at suporta para sa mga karaniwang isyu",
   "support_description_live_chat": "Libre at mabilis! Ang mga bihasang kinatawan ng suporta ay magagamit upang tulungan",
   "support_description_other_links": "Sumali sa aming mga komunidad o maabot sa amin ang aming mga kasosyo sa pamamagitan ng iba pang mga pamamaraan",
-  "support_title_guides": "Mga Gabay sa Wallet ng cake",
+  "support_title_guides": "Mga guide sa Cake Wallet",
   "support_title_live_chat": "Live na suporta",
   "support_title_other_links": "Iba pang mga link sa suporta",
-  "sweeping_wallet": "Pagwawalis ng pitaka",
-  "sweeping_wallet_alert": "Hindi ito dapat magtagal. Huwag iwanan ang screen na ito o maaaring mawala ang mga pondo ng swept.",
+  "sweeping_wallet": "Sweeping wallet",
+  "sweeping_wallet_alert": "Hindi ito dapat magtagal. HUWAG iwanan ang screen na ito o maaaring mawala ang mga pondo.",
   "switchToETHWallet": "Mangyaring lumipat sa isang Ethereum wallet at subukang muli",
   "switchToEVMCompatibleWallet": "Mangyaring lumipat sa isang EVM compatible na wallet at subukang muli (Ethereum, Polygon)",
   "symbol": "Simbolo",
-  "sync_all_wallets": "I -sync ang lahat ng mga pitaka",
-  "sync_status_attempting_sync": "Pagtatangka ng pag -sync",
-  "sync_status_connected": "Konektado",
-  "sync_status_connecting": "Pagkonekta",
-  "sync_status_failed_connect": "Naka -disconnect",
+  "sync_all_wallets": "I-sync ang lahat ng mga wallet",
+  "sync_status_attempting_sync": "SINUSUBUKANG I-SYNC",
+  "sync_status_connected": "KONEKTADO",
+  "sync_status_connecting": "KUMOKENEKTA",
+  "sync_status_failed_connect": "NADISKONEKTA",
   "sync_status_not_connected": "HINDI KONEKTADO",
-  "sync_status_starting_scan": "Simula sa pag -scan",
-  "sync_status_starting_sync": "Simula sa pag -sync",
-  "sync_status_syncronized": "Naka -synchronize",
-  "sync_status_syncronizing": "Pag -synchronize",
-  "sync_status_timed_out": "Nag -time out",
-  "sync_status_unsupported": "Hindi suportadong node",
-  "syncing_wallet_alert_content": "Ang iyong balanse at listahan ng transaksyon ay maaaring hindi kumpleto hanggang sa sabihin nito na \"naka -synchronize\" sa tuktok. Mag -click/tap upang malaman ang higit pa.",
-  "syncing_wallet_alert_title": "Ang iyong pitaka ay nag -sync",
+  "sync_status_starting_scan": "SIMULA SA PAG-SCAN",
+  "sync_status_starting_sync": "SIMULA SA PAG-SYNC",
+  "sync_status_syncronized": "NAKA-SYNCHRONIZE",
+  "sync_status_syncronizing": "PAG-SYNCHRONIZE",
+  "sync_status_timed_out": "NAG-TIME OUT",
+  "sync_status_unsupported": "HINDI SUPORTADONG NODE",
+  "syncing_wallet_alert_content": "Ang iyong balanse at listahan ng transaksyon ay maaaring hindi kumpleto hanggang sa sabihin nito na \"NAKA-SYNCHRONIZE\" sa tuktok. Mag-click/tap upang malaman ang higit pa.",
+  "syncing_wallet_alert_title": "Ang iyong wallet ay nag-sync",
   "template": "Template",
   "template_name": "Pangalan ng Template",
   "testnet_coins_no_value": "Ang mga barya ng testnet ay walang halaga",
-  "third_intro_content": "Ang mga yats ay nakatira sa labas ng cake wallet, din. Ang anumang address ng pitaka sa mundo ay maaaring mapalitan ng isang yat!",
-  "third_intro_title": "Si Yat ay mahusay na gumaganap sa iba",
-  "thorchain_contract_address_not_supported": "Hindi sinusuportahan ng Thorchain ang pagpapadala sa isang address ng kontrata",
-  "thorchain_taproot_address_not_supported": "Ang Tagabigay ng Thorchain ay hindi sumusuporta sa mga address ng taproot. Mangyaring baguhin ang address o pumili ng ibang provider.",
+  "third_intro_content": "Nabubuhay rin ang Yats sa labas ng Cake Wallet. Anumang wallet address sa mundo ay maaaring palitan ng Yat!",
+  "third_intro_title": "Magaling makipaglaro ang Yat sa iba",
+  "thorchain_contract_address_not_supported": "Hindi sinusuportahan ng THORChain ang pagpapadala sa isang address ng kontrata",
+  "thorchain_taproot_address_not_supported": "Ang provider ng THORChain ay hindi sumusuporta sa mga address ng Taproot. Mangyaring baguhin ang address o pumili ng ibang provider.",
   "time": "${minutes} m ${seconds} s",
   "tip": "Tip:",
   "today": "Ngayon",
-  "token_contract_address": "Token Address ng Kontrata",
-  "token_decimal": "Token Decimal",
-  "token_name": "Pangalan ng Token hal: Tether",
-  "token_symbol": "Simbolo ng token hal: USDT",
+  "token_contract_address": "Address ng token contract",
+  "token_decimal": "Token decimal",
+  "token_name": "Pangalan ng token, halimbawa: Tether",
+  "token_symbol": "Simbolo ng token, halimbawa: USDT",
   "tokenID": "ID",
   "tor_connection": "Koneksyon ng Tor",
-  "tor_only": "Tor lang",
+  "tor_only": "Tor lamang",
   "total": "Kabuuan",
-  "total_saving": "Kabuuang pagtitipid",
-  "totp_2fa_failure": "Maling code. Mangyaring subukan ang ibang code o makabuo ng isang bagong lihim na susi. Gumamit ng isang katugmang 2FA app na sumusuporta sa 8-digit na mga code at SHA512.",
-  "totp_2fa_success": "Tagumpay! Pinagana ang cake 2FA para sa pitaka na ito. Tandaan na i -save ang iyong mnemonic seed kung sakaling mawalan ka ng pag -access sa pitaka.",
+  "total_saving": "Kabuuang ipon",
+  "totp_2fa_failure": "Maling code. Mangyaring subukan ang ibang code o makabuo ng isang bagong secret key. Gumamit ng isang katugmang 2FA app na sumusuporta sa 8-digit na mga code at SHA512.",
+  "totp_2fa_success": "Tagumpay! Pinagana ang Cake 2FA para sa wallet na ito. Tandaan na i-save ang iyong mnemonic seed kung sakaling mawalan ka ng pag-access sa wallet.",
   "totp_auth_url": "TOTP AUTH URL",
-  "totp_code": "TOTP code",
+  "totp_code": "TOTP Code",
   "totp_secret_code": "TOTP Secret Code",
   "totp_verification_success": "Matagumpay ang pagpapatunay!",
   "track": "Subaybayan",
@@ -738,14 +738,14 @@
   "trade_details_fetching": "Pagkuha",
   "trade_details_id": "ID",
   "trade_details_pair": "Pares",
-  "trade_details_provider": "Tagabigay",
+  "trade_details_provider": "Provider",
   "trade_details_state": "Katayuan",
-  "trade_details_title": "Mga detalye sa kalakalan",
+  "trade_details_title": "Mga detalye ng kalakalan",
   "trade_for_not_created": "Ang kalakalan para sa ${title} ay hindi nilikha.",
-  "trade_history_title": "Kasaysayan ng Kalakal",
+  "trade_history_title": "Kasaysayan ng kalakalan",
   "trade_id": "Trade ID:",
-  "trade_id_not_found": "Trade ${tradeId} ng ${title} Hindi natagpuan.",
-  "trade_is_powered_by": "Ang kalakalan na ito ay pinalakas ng ${provider}",
+  "trade_id_not_found": "Kalakala na ${tradeId} ng ${title} ay hindi natagpuan.",
+  "trade_is_powered_by": "Ang kalakal na ito ay pinatakbo ng ${provider}",
   "trade_not_created": "Hindi nilikha ang kalakalan",
   "trade_not_found": "Hindi natagpuan ang kalakalan.",
   "trade_state_btc_sent": "Ipinadala ang BTC",
@@ -753,134 +753,134 @@
   "trade_state_confirming": "Pagkumpirma",
   "trade_state_created": "Nilikha",
   "trade_state_finished": "Tapos na",
-  "trade_state_paid": "Bayad",
+  "trade_state_paid": "Binayaran",
   "trade_state_paid_unconfirmed": "Bayad na hindi nakumpirma",
-  "trade_state_pending": "Nakabinbin",
-  "trade_state_timeout": "Oras ng oras",
-  "trade_state_to_be_created": "Upang malikha",
+  "trade_state_pending": "Hindi pa tapos",
+  "trade_state_timeout": "Timeout",
+  "trade_state_to_be_created": "lilikhain",
   "trade_state_traded": "Ipinagpalit",
   "trade_state_trading": "Pangangalakal",
-  "trade_state_underpaid": "Underpaid",
-  "trade_state_unpaid": "Walang bayad",
-  "trades": "Trading",
+  "trade_state_underpaid": "Kulang sa bayad",
+  "trade_state_unpaid": "Hindi nabayaran",
+  "trades": "Pangangalakal",
   "transaction_details_amount": "Halaga",
   "transaction_details_copied": "${title} kinopya sa clipboard",
   "transaction_details_date": "Petsa",
-  "transaction_details_fee": "Bayad",
-  "transaction_details_height": "Taas",
+  "transaction_details_fee": "Fee",
+  "transaction_details_height": "Height",
   "transaction_details_recipient_address": "Mga address ng tatanggap",
-  "transaction_details_source_address": "SOURCE ADDRESS",
+  "transaction_details_source_address": "Address ng pinagmulan",
   "transaction_details_title": "Mga detalye ng transaksyon",
   "transaction_details_transaction_id": "Transaction ID",
-  "transaction_key": "Susi ng transaksyon",
+  "transaction_key": "Transaction Key",
   "transaction_priority_fast": "Mabilis",
   "transaction_priority_fastest": "Pinakamabilis",
-  "transaction_priority_medium": "Katamtaman",
+  "transaction_priority_medium": "Medium",
   "transaction_priority_regular": "Regular",
   "transaction_priority_slow": "Mabagal",
   "transaction_sent": "Ipinadala ang transaksyon!",
-  "transaction_sent_notice": "Kung ang screen ay hindi magpatuloy pagkatapos ng 1 minuto, suriin ang isang block explorer at ang iyong email.",
+  "transaction_sent_notice": "Kung hindi magpapatuloy ang screen pagkatapos ng 1 minuto, tingnan ang block explorer at ang iyong email.",
   "transactions": "Mga Transaksyon",
-  "transactions_by_date": "Mga Transaksyon ayon sa Petsa",
-  "trongrid_history": "Kasaysayan ng Trongrid",
+  "transactions_by_date": "Mga transaksyon ayon sa petsa",
+  "trongrid_history": "Kasaysayan ng TronGrid",
   "trusted": "Pinagkakatiwalaan",
-  "tx_commit_exception_no_dust_on_change": "Ang transaksyon ay tinanggihan sa halagang ito. Sa mga barya na ito maaari kang magpadala ng ${min} nang walang pagbabago o ${max} na nagbabalik ng pagbabago.",
-  "tx_commit_failed": "Nabigo ang transaksyon sa transaksyon. Mangyaring makipag -ugnay sa suporta.",
-  "tx_invalid_input": "Gumagamit ka ng maling uri ng pag -input para sa ganitong uri ng pagbabayad",
-  "tx_no_dust_exception": "Ang transaksyon ay tinanggihan sa pamamagitan ng pagpapadala ng isang maliit na maliit. Mangyaring subukang dagdagan ang halaga.",
-  "tx_not_enough_inputs_exception": "Hindi sapat na magagamit ang mga input. Mangyaring pumili ng higit pa sa ilalim ng control ng barya",
-  "tx_rejected_bip68_final": "Ang transaksyon ay hindi nakumpirma na mga input at nabigo na palitan ng bayad.",
-  "tx_rejected_dust_change": "Ang transaksyon na tinanggihan ng mga patakaran sa network, mababang halaga ng pagbabago (alikabok). Subukang ipadala ang lahat o bawasan ang halaga.",
-  "tx_rejected_dust_output": "Ang transaksyon na tinanggihan ng mga patakaran sa network, mababang halaga ng output (alikabok). Mangyaring dagdagan ang halaga.",
-  "tx_rejected_dust_output_send_all": "Ang transaksyon na tinanggihan ng mga patakaran sa network, mababang halaga ng output (alikabok). Mangyaring suriin ang balanse ng mga barya na napili sa ilalim ng kontrol ng barya.",
-  "tx_rejected_vout_negative": "Hindi sapat na balanse upang magbayad para sa mga bayarin ng transaksyon na ito. Mangyaring suriin ang balanse ng mga barya sa ilalim ng kontrol ng barya.",
+  "tx_commit_exception_no_dust_on_change": "Ang transaksyon ay tinanggihan sa halagang ito. Sa mga barya na ito maaari kang magpadala ng ${min} nang walang sukli o ${max} na nagbabalik ng sukli.",
+  "tx_commit_failed": "Nabigo ang transaksyon. Mangyaring makipag-ugnay sa suporta.",
+  "tx_invalid_input": "Gumagamit ka ng maling uri ng pag-input para sa ganitong uri ng pagbabayad",
+  "tx_no_dust_exception": "Ang transaksyon ay tinanggihan sa pamamagitan ng pagpapadala ng isang maliit na halaga. Mangyaring subukang dagdagan ang halaga.",
+  "tx_not_enough_inputs_exception": "Hindi sapat na magagamit ang mga input. Mangyaring pumili ng higit pa sa ilalim ng Coin Control",
+  "tx_rejected_bip68_final": "Ang transaksyon ay hindi nakumpirma na mga input at nabigo na palitan ng fee.",
+  "tx_rejected_dust_change": "Ang transaksyon na tinanggihan ng mga patakaran sa network, mababang halaga ng fee (dust). Subukang ipadala ang lahat o bawasan ang halaga.",
+  "tx_rejected_dust_output": "Ang transaksyon na tinanggihan ng mga patakaran sa network, mababang halaga ng output (dust). Mangyaring dagdagan ang halaga.",
+  "tx_rejected_dust_output_send_all": "Ang transaksyon na tinanggihan ng mga patakaran sa network, mababang halaga ng output (dust). Mangyaring suriin ang balanse ng mga barya na napili sa ilalim ng Coin Control.",
+  "tx_rejected_vout_negative": "Hindi sapat na balanse upang magbayad para sa mga fee ng transaksyon na ito. Mangyaring suriin ang balanse ng mga barya sa ilalim ng Coin Control.",
   "tx_wrong_balance_exception": "Wala kang sapat na ${currency} upang maipadala ang halagang ito.",
-  "tx_wrong_balance_with_amount_exception": "Wala kang sapat ${currency} Upang ipadala ang kabuuang halaga ng ${amount}",
-  "tx_zero_fee_exception": "Hindi maaaring magpadala ng transaksyon na may 0 bayad. Subukan ang pagtaas ng rate o pagsuri sa iyong koneksyon para sa pinakabagong mga pagtatantya.",
+  "tx_wrong_balance_with_amount_exception": "Wala kang sapat ${currency} upang ipadala ang kabuuang halaga ng ${amount}",
+  "tx_zero_fee_exception": "Hindi maaaring magpadala ng transaksyon na may 0 fee. Subukan ang pagtaas ng rate o pagsuri sa iyong koneksyon para sa pinakabagong mga pagtatantya.",
   "unavailable_balance": "Hindi available na balanse",
-  "unavailable_balance_description": "Hindi Available na Balanse: Kasama sa kabuuang ito ang mga pondong naka-lock sa mga nakabinbing transaksyon at ang mga aktibong na-freeze mo sa iyong mga setting ng kontrol ng coin. Magiging available ang mga naka-lock na balanse kapag nakumpleto na ang kani-kanilang mga transaksyon, habang ang mga nakapirming balanse ay nananatiling hindi naa-access para sa mga transaksyon hanggang sa magpasya kang i-unfreeze ang mga ito.",
+  "unavailable_balance_description": "Hindi available na balanse: Kasama sa kabuuang ito ang mga pondong naka-lock sa mga nakabinbing transaksyon at ang mga aktibong na-freeze mo sa iyong mga setting ng Coin Control. Magiging available ang mga naka-lock na balanse kapag nakumpleto na ang kani-kanilang mga transaksyon, habang ang mga nakapirming balanse ay nananatiling hindi naa-access para sa mga transaksyon hanggang sa magpasya kang i-unfreeze ang mga ito.",
   "unconfirmed": "Hindi nakumpirma na balanse",
-  "understand": "naiintindihan ko",
-  "unlock": "I -unlock",
-  "unmatched_currencies": "Ang pera ng iyong kasalukuyang pitaka ay hindi tumutugma sa na -scan na QR",
-  "unspent_change": "Baguhin",
-  "unspent_coins_details_title": "Mga Detalye ng Unspent Coins",
-  "unspent_coins_title": "Unspent barya",
-  "unsupported_asset": "Hindi namin sinusuportahan ang pagkilos na ito para sa asset na ito. Mangyaring lumikha o lumipat sa isang pitaka ng isang suportadong uri ng pag -aari.",
+  "understand": "Naiitindihan ko",
+  "unlock": "I-unlock",
+  "unmatched_currencies": "Hindi tumutugma ang pera ng iyong kasalukuyang wallet sa na-scan na QR",
+  "unspent_change": "Sukli",
+  "unspent_coins_details_title": "Mga detalye ng mga hindi nagastos na barya",
+  "unspent_coins_title": "Mga hindi nagamit na barya",
+  "unsupported_asset": "Hindi namin sinusuportahan ang pagkilos na ito para sa asset na ito. Mangyaring lumikha o lumipat sa isang wallet ng isang suportadong uri ng asset.",
   "uptime": "Uptime",
-  "upto": "Hanggang sa ${value}",
+  "upto": "hanggang sa ${value}",
   "usb": "USB",
-  "use": "Lumipat sa",
-  "use_card_info_three": "Gamitin ang digital card online o sa mga pamamaraan ng pagbabayad na walang contact.",
-  "use_card_info_two": "Ang mga pondo ay na -convert sa USD kapag gaganapin sila sa prepaid account, hindi sa mga digital na pera.",
+  "use": "Lumipat sa ",
+  "use_card_info_three": "Gamitin ang digital card online o sa mga paraan ng pagbabayad na walang contact.",
+  "use_card_info_two": "Ang mga pondo ay na-convert sa USD kapag hawak sa prepaid account, hindi sa mga digital na pera.",
   "use_ssl": "Gumamit ng SSL",
   "use_suggested": "Gumamit ng iminungkahing",
   "use_testnet": "Gumamit ng testnet",
   "value": "Halaga",
   "value_type": "Uri ng halaga",
-  "variable_pair_not_supported": "Ang variable na pares na ito ay hindi suportado sa mga napiling palitan",
-  "verification": "Pag -verify",
-  "verify_with_2fa": "Mag -verify sa cake 2FA",
+  "variable_pair_not_supported": "Ang variable na pares na ito ay hindi suportado sa mga napiling exchange",
+  "verification": "Pag-verify",
+  "verify_with_2fa": "Mag-verify sa Cake 2FA",
   "version": "Bersyon ${currentVersion}",
   "view_all": "Tingnan lahat",
   "view_in_block_explorer": "Tingnan sa Block Explorer",
-  "view_key_private": "Tingnan ang Key (Pribado)",
-  "view_key_public": "Tingnan ang Key (Publiko)",
-  "view_transaction_on": "Tingnan ang transaksyon sa",
+  "view_key_private": "Tingnan ang view key (private)",
+  "view_key_public": "Tingnan ang view key (public)",
+  "view_transaction_on": "Tingnan ang transaksyon sa ",
   "voting_weight": "Bigat ng pagboto",
   "waitFewSecondForTxUpdate": "Mangyaring maghintay ng ilang segundo para makita ang transaksyon sa history ng mga transaksyon",
-  "wallet_keys": "Mga buto/susi ng pitaka",
-  "wallet_list_create_new_wallet": "Lumikha ng bagong pitaka",
-  "wallet_list_edit_wallet": "I -edit ang Wallet",
-  "wallet_list_failed_to_load": "Nabigong mag -load ng ${wallet_name} pitaka. ${error}",
+  "wallet_keys": "Wallet seed/keys",
+  "wallet_list_create_new_wallet": "Lumikha ng bagong wallet",
+  "wallet_list_edit_wallet": "I-edit ang wallet",
+  "wallet_list_failed_to_load": "Nabigong na-load ang ${wallet_name} na wallet. ${error}",
   "wallet_list_failed_to_remove": "Nabigong alisin ang ${wallet_name} wallet. ${error}",
-  "wallet_list_load_wallet": "Mag -load ng pitaka",
-  "wallet_list_loading_wallet": "Naglo -load ng ${wallet_name} Wallet",
-  "wallet_list_removing_wallet": "Pag -alis ng ${wallet_name} Wallet",
-  "wallet_list_restore_wallet": "Ibalik ang pitaka",
+  "wallet_list_load_wallet": "I-load ang wallet",
+  "wallet_list_loading_wallet": "Naglo-load ng ${wallet_name} wallet",
+  "wallet_list_removing_wallet": "Nag-aalis ang ${wallet_name} na wallet",
+  "wallet_list_restore_wallet": "Ibalik ang Wallet",
   "wallet_list_title": "Monero Wallet",
-  "wallet_list_wallet_name": "Pangalan ng Wallet",
+  "wallet_list_wallet_name": "Pangalan ng wallet",
   "wallet_menu": "Menu",
-  "wallet_name": "Pangalan ng Wallet",
-  "wallet_name_exists": "Ang isang pitaka na may pangalang iyon ay mayroon na. Mangyaring pumili ng ibang pangalan o palitan muna ang iba pang pitaka.",
+  "wallet_name": "Pangalan ng wallet",
+  "wallet_name_exists": "Ang isang wallet na may pangalang iyon ay mayroon na. Mangyaring pumili ng ibang pangalan o palitan muna ang iba pang wallet.",
   "wallet_password_is_empty": "Walang laman ang password ng wallet. Ang password ng wallet ay hindi dapat walang laman",
-  "wallet_recovery_height": "Taas ng pagbawi",
-  "wallet_restoration_store_incorrect_seed_length": "Maling haba ng binhi",
-  "wallet_seed": "SEED ng Wallet",
+  "wallet_recovery_height": "Recovery Height",
+  "wallet_restoration_store_incorrect_seed_length": "Maling haba ng seed",
+  "wallet_seed": "Wallet seed",
   "wallet_seed_legacy": "Legacy wallet seed",
   "wallet_store_monero_wallet": "Monero Wallet",
   "walletConnect": "WalletConnect",
-  "wallets": "Wallets",
+  "wallets": "Mga Wallet",
   "warning": "Babala",
   "welcome": "Maligayang pagdating sa",
-  "welcome_to_cakepay": "Maligayang pagdating sa cake pay!",
+  "welcome_to_cakepay": "Maligayang pagdating sa Cake Pay!",
   "what_is_silent_payments": "Ano ang tahimik na pagbabayad?",
   "widgets_address": "Address",
   "widgets_or": "o",
-  "widgets_restore_from_blockheight": "Ibalik mula sa blockheight",
+  "widgets_restore_from_blockheight": "Ibalik mula sa block height",
   "widgets_restore_from_date": "Ibalik mula sa petsa",
-  "widgets_seed": "Binhi",
+  "widgets_seed": "Seed",
   "wouoldLikeToConnect": "gustong kumonekta",
-  "write_down_backup_password": "Mangyaring isulat ang iyong backup password, na ginagamit para sa pag -import ng iyong mga backup file.",
-  "xlm_extra_info": "Mangyaring huwag kalimutan na tukuyin ang memo ID habang ipinapadala ang transaksyon ng XLM para sa palitan",
-  "xmr_available_balance": "Magagamit na balanse",
-  "xmr_full_balance": "Buong balanse",
+  "write_down_backup_password": "Mangyaring isulat ang iyong backup na password na ginagamit para sa pag-import ng iyong mga backup na file.",
+  "xlm_extra_info": "Mangyaring huwag kalimutang tukuyin ang Memo ID habang ipinapadala ang transaksyon sa XLM para sa palitan",
+  "xmr_available_balance": "Magagamit na Balanse",
+  "xmr_full_balance": "Buong Balanse",
   "xmr_hidden": "Nakatago",
-  "xmr_to_error": "Xmr.to error",
-  "xmr_to_error_description": "Di -wastong halaga. Pinakamataas na limitasyon ng 8 numero pagkatapos ng punto ng desimal",
-  "xrp_extra_info": "Mangyaring huwag kalimutan na tukuyin ang patutunguhan na tag habang ipinapadala ang transaksyon ng XRP para sa palitan",
+  "xmr_to_error": "XMR.TO error",
+  "xmr_to_error_description": "Hindi wastong halaga. Maximum�na limitasyon 8 digit pagkatapos ng decimal point",
+  "xrp_extra_info": "Mangyaring huwag kalimutan na tukuyin ang Destination Tag habang ipinapadala ang transaksyon ng XRP para sa palitan",
   "yat": "Yat",
-  "yat_address": "Yat address",
-  "yat_alert_content": "Ang mga gumagamit ng cake wallet ay maaari na ngayong magpadala at makatanggap ng lahat ng kanilang mga paboritong pera na may isang one-of-a-kind emoji-based username.",
-  "yat_alert_title": "Magpadala at tumanggap ng crypto nang mas madali sa yat",
-  "yat_error": "Error sa yat",
-  "yat_error_content": "Walang mga address na naka -link sa yat na ito. Subukan ang isa pang yat",
-  "yat_popup_content": "Maaari ka na ngayong magpadala at makatanggap ng crypto sa cake wallet kasama ang iyong yat - isang maikli, emoji na batay sa username. Pamahalaan ang mga yats anumang oras sa screen ng Mga Setting",
-  "yat_popup_title": "Ang iyong wallet address ay maaaring ma -emojified.",
+  "yat_address": "Yat Address",
+  "yat_alert_content": "Ang mga gumagamit ng Cake Wallet ay maaari na ngayong magpadala at tumanggap ng lahat ng kanilang mga paboritong pera gamit ang isa sa isang uri ng emoji-based na username.",
+  "yat_alert_title": "Magpadala at tumanggap ng crypto nang mas madali gamit ang Yat",
+  "yat_error": "Error sa Yat",
+  "yat_error_content": "Walang mga address na naka-link sa Yat na ito. Subukan ang isa pang Yat",
+  "yat_popup_content": "Maaari ka na ngayong magpadala at tumanggap ng crypto sa Cake Wallet gamit ang iyong Yat - isang maikling emoji-based na username. Pamahalaan ang Yats anumang oras sa screen ng mga setting",
+  "yat_popup_title": "Ang iyong wallet address ay maaring ma-emojified.",
   "yesterday": "Kahapon",
   "you_now_have_debit_card": "Mayroon ka na ngayong debit card",
-  "you_pay": "Magbabayad ka",
-  "you_will_get": "Mag -convert sa",
-  "you_will_send": "I -convert mula sa",
+  "you_pay": "Magbayad ka",
+  "you_will_get": "I-convert sa",
+  "you_will_send": "I-convert mula sa",
   "yy": "YY"
-}
\ No newline at end of file
+}

From 102139b0611dc3dceffedea26085eaef89ac31f4 Mon Sep 17 00:00:00 2001
From: Rafael <github@rafael.saes.dev>
Date: Thu, 15 Aug 2024 22:34:41 -0300
Subject: [PATCH 43/81] feat: more info on privkey error (#1612)

---
 cw_bitcoin/lib/electrum_wallet.dart | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 501d94e54..9dc8de083 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -993,11 +993,29 @@ abstract class ElectrumWalletBase
       bool hasTaprootInputs = false;
 
       final transaction = txb.buildTransaction((txDigest, utxo, publicKey, sighash) {
-        final key = estimatedTx.inputPrivKeyInfos
-            .firstWhereOrNull((element) => element.privkey.getPublic().toHex() == publicKey);
+        String error = "Cannot find private key.";
+
+        ECPrivateInfo? key;
+
+        if (estimatedTx.inputPrivKeyInfos.isEmpty) {
+          error += "\nNo private keys generated.";
+        } else {
+          error += "\nAddress: ${utxo.ownerDetails.address.toAddress()}";
+
+          key = estimatedTx.inputPrivKeyInfos.firstWhereOrNull((element) {
+            final elemPubkey = element.privkey.getPublic().toHex();
+            if (elemPubkey == publicKey) {
+              return true;
+            } else {
+              error += "\nExpected: $publicKey";
+              error += "\nPubkey: $elemPubkey";
+              return false;
+            }
+          });
+        }
 
         if (key == null) {
-          throw Exception("Cannot find private key");
+          throw Exception(error);
         }
 
         if (utxo.utxo.isP2tr()) {

From fb3f64facfb2dd5b6eb1b236a8c1fc074384f3ab Mon Sep 17 00:00:00 2001
From: David Adegoke <64401859+Blazebrain@users.noreply.github.com>
Date: Fri, 16 Aug 2024 23:21:03 +0100
Subject: [PATCH 44/81] fix: Restore backup bug fix and clean up sol error
 message (#1614)

* fix: Restore backup bug fix and clean up sol error message

* fix: Add async await to reinitialize
---
 lib/reactions/bootstrap.dart                  | 10 ++++----
 .../on_authentication_state_change.dart       | 16 +++++++++++--
 lib/view_model/send/send_view_model.dart      | 24 +++++++++++++++++++
 res/values/strings_ar.arb                     |  2 ++
 res/values/strings_bg.arb                     |  2 ++
 res/values/strings_cs.arb                     |  2 ++
 res/values/strings_de.arb                     |  2 ++
 res/values/strings_en.arb                     |  2 ++
 res/values/strings_es.arb                     |  2 ++
 res/values/strings_fr.arb                     |  2 ++
 res/values/strings_ha.arb                     |  2 ++
 res/values/strings_hi.arb                     |  2 ++
 res/values/strings_hr.arb                     |  2 ++
 res/values/strings_id.arb                     |  2 ++
 res/values/strings_it.arb                     |  2 ++
 res/values/strings_ja.arb                     |  2 ++
 res/values/strings_ko.arb                     |  2 ++
 res/values/strings_my.arb                     |  2 ++
 res/values/strings_nl.arb                     |  2 ++
 res/values/strings_pl.arb                     |  2 ++
 res/values/strings_pt.arb                     |  2 ++
 res/values/strings_ru.arb                     |  2 ++
 res/values/strings_th.arb                     |  2 ++
 res/values/strings_tl.arb                     |  4 +++-
 res/values/strings_tr.arb                     |  2 ++
 res/values/strings_uk.arb                     |  2 ++
 res/values/strings_ur.arb                     |  2 ++
 res/values/strings_yo.arb                     |  2 ++
 res/values/strings_zh.arb                     |  2 ++
 29 files changed, 95 insertions(+), 9 deletions(-)

diff --git a/lib/reactions/bootstrap.dart b/lib/reactions/bootstrap.dart
index e78d8a01d..5b1a0ace7 100644
--- a/lib/reactions/bootstrap.dart
+++ b/lib/reactions/bootstrap.dart
@@ -21,16 +21,14 @@ Future<void> bootstrap(GlobalKey<NavigatorState> navigatorKey) async {
   final settingsStore = getIt.get<SettingsStore>();
   final fiatConversionStore = getIt.get<FiatConversionStore>();
 
-  final currentWalletName = getIt
-      .get<SharedPreferences>()
-      .getString(PreferencesKey.currentWalletName);
+  final currentWalletName =
+      getIt.get<SharedPreferences>().getString(PreferencesKey.currentWalletName);
   if (currentWalletName != null) {
     authenticationStore.installed();
   }
 
-  startAuthenticationStateChange(authenticationStore, navigatorKey);
-  startCurrentWalletChangeReaction(
-      appStore, settingsStore, fiatConversionStore);
+  await startAuthenticationStateChange(authenticationStore, navigatorKey);
+  startCurrentWalletChangeReaction(appStore, settingsStore, fiatConversionStore);
   startCurrentFiatChangeReaction(appStore, settingsStore, fiatConversionStore);
   startCurrentFiatApiModeChangeReaction(appStore, settingsStore, fiatConversionStore);
   startOnCurrentNodeChangeReaction(appStore);
diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart
index 95cbd51df..014306b98 100644
--- a/lib/reactions/on_authentication_state_change.dart
+++ b/lib/reactions/on_authentication_state_change.dart
@@ -13,8 +13,20 @@ ReactionDisposer? _onAuthenticationStateChange;
 dynamic loginError;
 StreamController<dynamic> authenticatedErrorStreamController = StreamController<dynamic>();
 
-void startAuthenticationStateChange(
-    AuthenticationStore authenticationStore, GlobalKey<NavigatorState> navigatorKey) {
+Future<void> reInitializeStreamController() async {
+  if (!authenticatedErrorStreamController.isClosed) {
+    await authenticatedErrorStreamController.close();
+  }
+
+  authenticatedErrorStreamController = StreamController<dynamic>();
+}
+
+Future<void> startAuthenticationStateChange(
+  AuthenticationStore authenticationStore,
+  GlobalKey<NavigatorState> navigatorKey,
+) async {
+  await reInitializeStreamController();
+
   authenticatedErrorStreamController.stream.listen((event) {
     if (authenticationStore.state == AuthenticationState.allowed) {
       ExceptionHandler.showError(event.toString(), delayInSeconds: 3);
diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart
index d0514bb19..863c83957 100644
--- a/lib/view_model/send/send_view_model.dart
+++ b/lib/view_model/send/send_view_model.dart
@@ -583,6 +583,30 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
     String errorMessage = error.toString();
 
     if (walletType == WalletType.solana) {
+      if (errorMessage.contains('insufficient lamports')) {
+        double solValueNeeded = 0.0;
+
+        // Regular expression to match the number after "need". This shows the exact lamports the user needs to perform the transaction.
+        RegExp regExp = RegExp(r'need (\d+)');
+
+        // Find the match
+        Match? match = regExp.firstMatch(errorMessage);
+
+        if (match != null) {
+          String neededAmount = match.group(1)!;
+          final lamportsNeeded = int.tryParse(neededAmount);
+
+          // 5000 lamport used here is the constant for sending a transaction on solana
+          int lamportsPerSol = 1000000000;
+
+          solValueNeeded =
+              lamportsNeeded != null ? ((lamportsNeeded + 5000) / lamportsPerSol) : 0.0;
+          return S.current.insufficient_lamports(solValueNeeded.toString());
+        } else {
+          print("No match found.");
+          return S.current.insufficient_lamport_for_tx;
+        }
+      }
       if (errorMessage.contains('insufficient funds for rent')) {
         return S.current.insufficientFundsForRentError;
       }
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index 98cafdebc..a73067383 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -338,6 +338,8 @@
   "incoming": "الواردة",
   "incorrect_seed": "النص الذي تم إدخاله غير صالح.",
   "inputs": "المدخلات",
+  "insufficient_lamport_for_tx": "ليس لديك ما يكفي من SOL لتغطية المعاملة ورسوم المعاملات الخاصة بها. يرجى إضافة المزيد من SOL إلى محفظتك أو تقليل كمية SOL التي ترسلها.",
+  "insufficient_lamports": "ليس لديك ما يكفي من SOL لتغطية المعاملة ورسوم المعاملات الخاصة بها. تحتاج على الأقل ${solValueNeeded} sol. يرجى إضافة المزيد من sol إلى محفظتك أو تقليل مبلغ sol الذي ترسله",
   "insufficientFundsForRentError": "ليس لديك ما يكفي من SOL لتغطية رسوم المعاملة والإيجار للحساب. يرجى إضافة المزيد من sol إلى محفظتك أو تقليل مبلغ sol الذي ترسله",
   "introducing_cake_pay": "نقدم لكم Cake Pay!",
   "invalid_input": "مدخل غير صالح",
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index b51167dab..b60cbc55c 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -338,6 +338,8 @@
   "incoming": "Входящи",
   "incorrect_seed": "Въведеният текст е невалиден.",
   "inputs": "Входове",
+  "insufficient_lamport_for_tx": "Нямате достатъчно SOL, за да покриете транзакцията и таксата му за транзакция. Моля, добавете повече SOL към портфейла си или намалете сумата на SOL, която изпращате.",
+  "insufficient_lamports": "Нямате достатъчно SOL, за да покриете транзакцията и таксата му за транзакция. Имате нужда от поне ${solValueNeeded} sol. Моля, добавете повече SOL към портфейла си или намалете сумата на SOL, която изпращате",
   "insufficientFundsForRentError": "Нямате достатъчно SOL, за да покриете таксата за транзакцията и наемането на сметката. Моля, добавете повече SOL към портфейла си или намалете сумата на SOL, която изпращате",
   "introducing_cake_pay": "Запознайте се с Cake Pay!",
   "invalid_input": "Невалиден вход",
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index d47ca932c..537695dd9 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -338,6 +338,8 @@
   "incoming": "Příchozí",
   "incorrect_seed": "Zadaný text není správný.",
   "inputs": "Vstupy",
+  "insufficient_lamport_for_tx": "Nemáte dostatek SOL na pokrytí transakce a jejího transakčního poplatku. Laskavě přidejte do své peněženky více solu nebo snižte množství Sol, kterou odesíláte.",
+  "insufficient_lamports": "Nemáte dostatek SOL na pokrytí transakce a jejího transakčního poplatku. Potřebujete alespoň ${solValueNeeded} sol. Laskavě přidejte do své peněženky více SOL nebo snižte množství Sol, kterou odesíláte",
   "insufficientFundsForRentError": "Nemáte dostatek SOL na pokrytí transakčního poplatku a nájemného za účet. Laskavě přidejte do své peněženky více SOL nebo snižte množství Sol, kterou odesíláte",
   "introducing_cake_pay": "Představujeme Cake Pay!",
   "invalid_input": "Neplatný vstup",
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index e64c3bc27..052015367 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -338,6 +338,8 @@
   "incoming": "Eingehend",
   "incorrect_seed": "Der eingegebene Text ist ungültig.",
   "inputs": "Eingänge",
+  "insufficient_lamport_for_tx": "Sie haben nicht genug SOL, um die Transaktion und ihre Transaktionsgebühr abzudecken. Bitte fügen Sie Ihrer Brieftasche mehr Sol hinzu oder reduzieren Sie die SO -Menge, die Sie senden.",
+  "insufficient_lamports": "Sie haben nicht genug SOL, um die Transaktion und ihre Transaktionsgebühr abzudecken. Sie brauchen mindestens ${solValueNeeded} Sol. Bitte fügen Sie mehr Sol zu Ihrer Wallet hinzu oder reduzieren Sie den von Ihnen gesendeten Sol -Betrag",
   "insufficientFundsForRentError": "Sie haben nicht genug SOL, um die Transaktionsgebühr und die Miete für das Konto zu decken. Bitte fügen Sie mehr Sol zu Ihrer Brieftasche hinzu oder reduzieren Sie den von Ihnen gesendeten Sol -Betrag",
   "introducing_cake_pay": "Einführung von Cake Pay!",
   "invalid_input": "Ungültige Eingabe",
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 9d7d9ad49..0f0ebd470 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -338,6 +338,8 @@
   "incoming": "Incoming",
   "incorrect_seed": "The text entered is not valid.",
   "inputs": "Inputs",
+  "insufficient_lamport_for_tx": "You do not have enough SOL to cover the transaction and its transaction fee. Kindly add more SOL to your wallet or reduce the SOL amount you\\'re sending.",
+  "insufficient_lamports": "You do not have enough SOL to cover the transaction and its transaction fee. You need at least ${solValueNeeded} SOL. Kindly add more SOL to your wallet or reduce the SOL amount you\\'re sending",
   "insufficientFundsForRentError": "You do not have enough SOL to cover the transaction fee and rent for the account. Kindly add more SOL to your wallet or reduce the SOL amount you\\'re sending",
   "introducing_cake_pay": "Introducing Cake Pay!",
   "invalid_input": "Invalid input",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index e7f1366a5..1e6eeae59 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -338,6 +338,8 @@
   "incoming": "Entrante",
   "incorrect_seed": "El texto ingresado no es válido.",
   "inputs": "Entradas",
+  "insufficient_lamport_for_tx": "No tiene suficiente SOL para cubrir la transacción y su tarifa de transacción. Por favor, agregue más SOL a su billetera o reduzca la cantidad de sol que está enviando.",
+  "insufficient_lamports": "No tiene suficiente SOL para cubrir la transacción y su tarifa de transacción. Necesita al menos ${solValueNeeded} sol. Por favor, agregue más sol a su billetera o reduzca la cantidad de sol que está enviando",
   "insufficientFundsForRentError": "No tiene suficiente SOL para cubrir la tarifa de transacción y alquilar para la cuenta. Por favor, agregue más sol a su billetera o reduzca la cantidad de sol que está enviando",
   "introducing_cake_pay": "¡Presentamos Cake Pay!",
   "invalid_input": "Entrada inválida",
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index 7965eca12..a64a69514 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -338,6 +338,8 @@
   "incoming": "Entrantes",
   "incorrect_seed": "Le texte entré est invalide.",
   "inputs": "Contributions",
+  "insufficient_lamport_for_tx": "Vous n'avez pas assez de sol pour couvrir la transaction et ses frais de transaction. Veuillez ajouter plus de Sol à votre portefeuille ou réduire la quantité de Sol que vous envoyez.",
+  "insufficient_lamports": "Vous n'avez pas assez de sol pour couvrir la transaction et ses frais de transaction. Vous avez besoin d'au moins ${solValueNeeded} sol. Veuillez ajouter plus de Sol à votre portefeuille ou réduire la quantité de sol que vous envoyez",
   "insufficientFundsForRentError": "Vous n'avez pas assez de SOL pour couvrir les frais de transaction et le loyer pour le compte. Veuillez ajouter plus de Sol à votre portefeuille ou réduire la quantité de sol que vous envoyez",
   "introducing_cake_pay": "Présentation de Cake Pay !",
   "invalid_input": "Entrée invalide",
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index d2c58971f..219b3c939 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -338,6 +338,8 @@
   "incoming": "Mai shigowa",
   "incorrect_seed": "rubutun da aka shigar ba shi da inganci.",
   "inputs": "Abubuwan da ke ciki",
+  "insufficient_lamport_for_tx": "Ba ku da isasshen sool don rufe ma'amala da kuɗin ma'amala. Da unara ƙara ƙarin sool a cikin walat ɗinku ko rage adadin Sol ɗin da kuke aikawa.",
+  "insufficient_lamports": "Ba ku da isasshen sool don rufe ma'amala da kuɗin ma'amala. Kuna buƙatar aƙalla ${solValueNeeded} Sol. Da kyau ƙara ƙarin sool zuwa walat ɗinku ko rage adadin Sol ɗin da kuke aikawa",
   "insufficientFundsForRentError": "Ba ku da isasshen Sol don rufe kuɗin ma'amala da haya don asusun. Da kyau ƙara ƙarin sool zuwa walat ɗinku ko rage adadin Sol ɗin da kuke aikawa",
   "introducing_cake_pay": "Gabatar da Cake Pay!",
   "invalid_input": "Shigar da ba daidai ba",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index baa3925c0..b711939a4 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -338,6 +338,8 @@
   "incoming": "आने वाली",
   "incorrect_seed": "दर्ज किया गया पाठ मान्य नहीं है।",
   "inputs": "इनपुट",
+  "insufficient_lamport_for_tx": "आपके पास लेनदेन और इसके लेनदेन शुल्क को कवर करने के लिए पर्याप्त सोल नहीं है। कृपया अपने बटुए में अधिक सोल जोड़ें या आपके द्वारा भेजे जा रहे सोल राशि को कम करें।",
+  "insufficient_lamports": "आपके पास लेनदेन और इसके लेनदेन शुल्क को कवर करने के लिए पर्याप्त सोल नहीं है। आपको कम से कम ${solValueNeeded} सोल की आवश्यकता है। कृपया अपने बटुए में अधिक सोल जोड़ें या सोल राशि को कम करें जिसे आप भेज रहे हैं",
   "insufficientFundsForRentError": "आपके पास लेन -देन शुल्क और खाते के लिए किराए को कवर करने के लिए पर्याप्त सोल नहीं है। कृपया अपने बटुए में अधिक सोल जोड़ें या सोल राशि को कम करें जिसे आप भेज रहे हैं",
   "introducing_cake_pay": "परिचय Cake Pay!",
   "invalid_input": "अमान्य निवेश",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index e6b820300..401514735 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -338,6 +338,8 @@
   "incoming": "Dolazno",
   "incorrect_seed": "Uneseni tekst nije valjan.",
   "inputs": "Unosi",
+  "insufficient_lamport_for_tx": "Nemate dovoljno SOL -a da pokriva transakciju i njegovu transakcijsku naknadu. Ljubazno dodajte više sol u svoj novčanik ili smanjite količinu SOL -a koju šaljete.",
+  "insufficient_lamports": "Nemate dovoljno SOL -a da pokriva transakciju i njegovu transakcijsku naknadu. Trebate najmanje ${solValueNeeded} sol. Ljubazno dodajte više sol u svoj novčanik ili smanjite količinu SOL -a koju šaljete",
   "insufficientFundsForRentError": "Nemate dovoljno SOL -a za pokrivanje naknade za transakciju i najamninu za račun. Ljubazno dodajte više sol u svoj novčanik ili smanjite količinu SOL -a koju šaljete",
   "introducing_cake_pay": "Predstavljamo Cake Pay!",
   "invalid_input": "Pogrešan unos",
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index 0b8077807..b6210b5dd 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -338,6 +338,8 @@
   "incoming": "Masuk",
   "incorrect_seed": "Teks yang dimasukkan tidak valid.",
   "inputs": "Input",
+  "insufficient_lamport_for_tx": "Anda tidak memiliki cukup SOL untuk menutupi transaksi dan biaya transaksinya. Mohon tambahkan lebih banyak sol ke dompet Anda atau kurangi jumlah sol yang Anda kirim.",
+  "insufficient_lamports": "Anda tidak memiliki cukup SOL untuk menutupi transaksi dan biaya transaksinya. Anda membutuhkan setidaknya ${solValueNeeded} sol. Mohon tambahkan lebih banyak sol ke dompet Anda atau kurangi jumlah sol yang Anda kirim",
   "insufficientFundsForRentError": "Anda tidak memiliki cukup SOL untuk menutupi biaya transaksi dan menyewa untuk akun tersebut. Mohon tambahkan lebih banyak sol ke dompet Anda atau kurangi jumlah sol yang Anda kirim",
   "introducing_cake_pay": "Perkenalkan Cake Pay!",
   "invalid_input": "Masukan tidak valid",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index b7a81ef9a..fc4abf7c4 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -339,6 +339,8 @@
   "incoming": "In arrivo",
   "incorrect_seed": "Il testo inserito non è valido.",
   "inputs": "Input",
+  "insufficient_lamport_for_tx": "Non hai abbastanza SOL per coprire la transazione e la sua quota di transazione. Si prega di aggiungere più SOL al tuo portafoglio o ridurre l'importo SOL che stai inviando.",
+  "insufficient_lamports": "Non hai abbastanza SOL per coprire la transazione e la sua quota di transazione. Hai bisogno di almeno ${solValueNeeded} sol. Si prega di aggiungere più SOL al tuo portafoglio o ridurre l'importo SOL che stai inviando",
   "insufficientFundsForRentError": "Non hai abbastanza SOL per coprire la tassa di transazione e l'affitto per il conto. Si prega di aggiungere più SOL al tuo portafoglio o ridurre l'importo SOL che stai inviando",
   "introducing_cake_pay": "Presentazione di Cake Pay!",
   "invalid_input": "Inserimento non valido",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index a13a4e6f0..98495fc8b 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -339,6 +339,8 @@
   "incoming": "着信",
   "incorrect_seed": "入力されたテキストは無効です。",
   "inputs": "入力",
+  "insufficient_lamport_for_tx": "トランザクションとその取引手数料をカバーするのに十分なSOLがありません。財布にソルを追加するか、送信するソル量を減らしてください。",
+  "insufficient_lamports": "トランザクションとその取引手数料をカバーするのに十分なSOLがありません。少なくとも${solValueNeeded} solが必要です。財布にソルを追加するか、送信するソル量を減らしてください",
   "insufficientFundsForRentError": "アカウントの取引料金とレンタルをカバーするのに十分なソルがありません。財布にソルを追加するか、送信するソル量を減らしてください",
   "introducing_cake_pay": "序章Cake Pay!",
   "invalid_input": "無効入力",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index d20546f41..60c52b21f 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -338,6 +338,8 @@
   "incoming": "들어오는",
   "incorrect_seed": "입력하신 텍스트가 유효하지 않습니다.",
   "inputs": "입력",
+  "insufficient_lamport_for_tx": "거래 및 거래 수수료를 충당하기에 충분한 SOL이 없습니다. 지갑에 더 많은 솔을 추가하거나 보내는 솔을 줄입니다.",
+  "insufficient_lamports": "거래 및 거래 수수료를 충당하기에 충분한 SOL이 없습니다. 최소 ${solValueNeeded} sol이 필요합니다. 지갑에 더 많은 솔을 추가하거나 보내는 솔을 줄이십시오.",
   "insufficientFundsForRentError": "거래 수수료와 계좌 임대료를 충당하기에 충분한 SOL이 없습니다. 지갑에 더 많은 솔을 추가하거나 보내는 솔을 줄이십시오.",
   "introducing_cake_pay": "소개 Cake Pay!",
   "invalid_input": "잘못된 입력",
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index 06d7cf627..42643be48 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -338,6 +338,8 @@
   "incoming": "ဝင်လာ",
   "incorrect_seed": "ထည့်သွင်းထားသော စာသားသည် မမှန်ကန်ပါ။",
   "inputs": "သွင်းငေှ",
+  "insufficient_lamport_for_tx": "သငျသညျငွေပေးငွေယူနှင့်၎င်း၏ငွေပေးငွေယူကြေးကိုဖုံးလွှမ်းရန် sol ရှိသည်မဟုတ်ကြဘူး။ ကြင်နာစွာသင်၏ပိုက်ဆံအိတ်သို့ပိုမို sol ကိုထပ်ထည့်ပါသို့မဟုတ်သင်ပို့လွှတ်ခြင်း sol ပမာဏကိုလျှော့ချပါ။",
+  "insufficient_lamports": "သငျသညျငွေပေးငွေယူနှင့်၎င်း၏ငွေပေးငွေယူကြေးကိုဖုံးလွှမ်းရန် sol ရှိသည်မဟုတ်ကြဘူး။ သင်အနည်းဆုံး ${solValueNeeded} s ကိုလိုအပ်ပါတယ်။ ကြင်နာစွာသင်၏ပိုက်ဆံအိတ်သို့ပိုမို sol ကိုထပ်ထည့်ပါသို့မဟုတ်သင်ပို့နေသော sol ပမာဏကိုလျှော့ချပါ",
   "insufficientFundsForRentError": "သင်ငွေပေးချေမှုအခကြေးငွေကိုဖုံးအုပ်ရန်နှင့်အကောင့်ငှားရန်လုံလောက်သော sol ရှိသည်မဟုတ်ကြဘူး။ ကြင်နာစွာသင်၏ပိုက်ဆံအိတ်သို့ပိုမို sol ကိုပိုမိုထည့်ပါသို့မဟုတ်သင်ပို့ခြင်း sol ပမာဏကိုလျှော့ချပါ",
   "introducing_cake_pay": "Cake Pay ကို မိတ်ဆက်ခြင်း။",
   "invalid_input": "ထည့်သွင်းမှု မမှန်ကန်ပါ။",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index 78caef912..0f6149182 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -338,6 +338,8 @@
   "incoming": "inkomend",
   "incorrect_seed": "De ingevoerde tekst is niet geldig.",
   "inputs": "Invoer",
+  "insufficient_lamport_for_tx": "U hebt niet genoeg SOL om de transactie en de transactiekosten te dekken. Voeg vriendelijk meer SOL toe aan uw portemonnee of verminder de SOL -hoeveelheid die u verzendt.",
+  "insufficient_lamports": "U hebt niet genoeg SOL om de transactie en de transactiekosten te dekken. Je hebt minstens ${solValueNeeded} sol nodig. Voeg vriendelijk meer Sol toe aan uw portemonnee of verminder de SOL -hoeveelheid die u verzendt",
   "insufficientFundsForRentError": "U hebt niet genoeg SOL om de transactiekosten en huur voor de rekening te dekken. Voeg vriendelijk meer SOL toe aan uw portemonnee of verminder de SOL -hoeveelheid die u verzendt",
   "introducing_cake_pay": "Introductie van Cake Pay!",
   "invalid_input": "Ongeldige invoer",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 7de435319..48d6e38f6 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -338,6 +338,8 @@
   "incoming": "Przychodzące",
   "incorrect_seed": "Wprowadzony seed jest nieprawidłowy.",
   "inputs": "Wejścia",
+  "insufficient_lamport_for_tx": "Nie masz wystarczającej ilości SOL, aby pokryć transakcję i opłatę za transakcję. Uprzejmie dodaj więcej sol do portfela lub zmniejsz wysyłaną kwotę SOL.",
+  "insufficient_lamports": "Nie masz wystarczającej ilości SOL, aby pokryć transakcję i opłatę za transakcję. Potrzebujesz przynajmniej ${solValueNeeded} sol. Uprzejmie dodaj więcej sol do portfela lub zmniejsz wysyłaną kwotę SOL, którą wysyłasz",
   "insufficientFundsForRentError": "Nie masz wystarczającej ilości SOL, aby pokryć opłatę za transakcję i czynsz za konto. Uprzejmie dodaj więcej sol do portfela lub zmniejsz solę, którą wysyłasz",
   "introducing_cake_pay": "Przedstawiamy Cake Pay!",
   "invalid_input": "Nieprawidłowe dane wejściowe",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index a3d789cab..070f3f776 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -338,6 +338,8 @@
   "incoming": "Recebidas",
   "incorrect_seed": "O texto digitado não é válido.",
   "inputs": "Entradas",
+  "insufficient_lamport_for_tx": "Você não tem Sol suficiente para cobrir a transação e sua taxa de transação. Por favor, adicione mais sol à sua carteira ou reduza a quantidade de sol que você envia.",
+  "insufficient_lamports": "Você não tem Sol suficiente para cobrir a transação e sua taxa de transação. Você precisa de pelo menos ${solValueNeeded} sol. Por favor, adicione mais sol à sua carteira ou reduza a quantidade de sol que você está enviando",
   "insufficientFundsForRentError": "Você não tem Sol suficiente para cobrir a taxa de transação e o aluguel da conta. Por favor, adicione mais sol à sua carteira ou reduza a quantidade de sol que você envia",
   "introducing_cake_pay": "Apresentando o Cake Pay!",
   "invalid_input": "Entrada inválida",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index d84aa146f..695877c77 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -338,6 +338,8 @@
   "incoming": "Входящие",
   "incorrect_seed": "Введённый текст некорректный.",
   "inputs": "Входы",
+  "insufficient_lamport_for_tx": "У вас недостаточно Sol, чтобы покрыть транзакцию и плату за транзакцию. Пожалуйста, добавьте больше Sol в свой кошелек или уменьшите сумму Sol, которую вы отправляете.",
+  "insufficient_lamports": "У вас недостаточно Sol, чтобы покрыть транзакцию и плату за транзакцию. Вам нужен как минимум ${solValueNeeded} sol. Пожалуйста, добавьте больше Sol в свой кошелек или уменьшите сумму Sol, которую вы отправляете",
   "insufficientFundsForRentError": "У вас недостаточно Sol, чтобы покрыть плату за транзакцию и аренду для счета. Пожалуйста, добавьте больше Sol в свой кошелек или уменьшите сумму Sol, которую вы отправляете",
   "introducing_cake_pay": "Представляем Cake Pay!",
   "invalid_input": "Неверный Ввод",
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index 2adccb2cf..5757eed0b 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -338,6 +338,8 @@
   "incoming": "ขาเข้า",
   "incorrect_seed": "ข้อความที่ป้อนไม่ถูกต้อง",
   "inputs": "อินพุต",
+  "insufficient_lamport_for_tx": "คุณไม่มีโซลเพียงพอที่จะครอบคลุมการทำธุรกรรมและค่าธรรมเนียมการทำธุรกรรม กรุณาเพิ่มโซลให้มากขึ้นลงในกระเป๋าเงินของคุณหรือลดจำนวนโซลที่คุณส่งมา",
+  "insufficient_lamports": "คุณไม่มีโซลเพียงพอที่จะครอบคลุมการทำธุรกรรมและค่าธรรมเนียมการทำธุรกรรม คุณต้องการอย่างน้อย ${solValueNeeded} SOL กรุณาเพิ่มโซลให้มากขึ้นลงในกระเป๋าเงินของคุณหรือลดจำนวนโซลที่คุณกำลังส่ง",
   "insufficientFundsForRentError": "คุณไม่มีโซลเพียงพอที่จะครอบคลุมค่าธรรมเนียมการทำธุรกรรมและค่าเช่าสำหรับบัญชี กรุณาเพิ่มโซลให้มากขึ้นลงในกระเป๋าเงินของคุณหรือลดจำนวนโซลที่คุณส่งมา",
   "introducing_cake_pay": "ยินดีต้อนรับสู่ Cake Pay!",
   "invalid_input": "อินพุตไม่ถูกต้อง",
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index 22093f772..7fc83afd8 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -338,6 +338,8 @@
   "incoming": "Papasok",
   "incorrect_seed": "Ang text na ipinasok ay hindi wasto.",
   "inputs": "Mga input",
+  "insufficient_lamport_for_tx": "Wala kang sapat na SOL upang masakop ang transaksyon at ang bayad sa transaksyon nito. Mabuting magdagdag ng higit pa sa iyong pitaka o bawasan ang sol na halaga na iyong ipinapadala.",
+  "insufficient_lamports": "Wala kang sapat na SOL upang masakop ang transaksyon at ang bayad sa transaksyon nito. Kailangan mo ng hindi bababa sa ${solValueNeeded} sol. Mabait na magdagdag ng higit pang sol sa iyong pitaka o bawasan ang dami ng iyong ipinapadala",
   "insufficientFundsForRentError": "Wala kang sapat na SOL upang masakop ang fee sa transaksyon at upa para sa account. Mabait na magdagdag ng higit pa sa iyong wallet o bawasan ang halaga ng SOL na iyong ipinapadala",
   "introducing_cake_pay": "Pagpapakilala ng Cake Pay!",
   "invalid_input": "Di-wastong input",
@@ -883,4 +885,4 @@
   "you_will_get": "I-convert sa",
   "you_will_send": "I-convert mula sa",
   "yy": "YY"
-}
+}
\ No newline at end of file
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index b47787bbd..4d1aa43e4 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -338,6 +338,8 @@
   "incoming": "Gelen",
   "incorrect_seed": "Girilen metin geçerli değil.",
   "inputs": "Girişler",
+  "insufficient_lamport_for_tx": "İşlemi ve işlem ücretini karşılamak için yeterli SOL'unuz yok. Lütfen cüzdanınıza daha fazla SOL ekleyin veya gönderdiğiniz sol miktarını azaltın.",
+  "insufficient_lamports": "İşlemi ve işlem ücretini karşılamak için yeterli SOL'unuz yok. En az ${solValueNeeded} Sol'a ihtiyacınız var. Lütfen cüzdanınıza daha fazla sol ekleyin veya gönderdiğiniz sol miktarını azaltın",
   "insufficientFundsForRentError": "İşlem ücretini karşılamak ve hesap için kiralamak için yeterli SOL'nuz yok. Lütfen cüzdanınıza daha fazla sol ekleyin veya gönderdiğiniz sol miktarını azaltın",
   "introducing_cake_pay": "Cake Pay ile tanışın!",
   "invalid_input": "Geçersiz Giriş",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 328548087..22edec0d5 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -338,6 +338,8 @@
   "incoming": "Вхідні",
   "incorrect_seed": "Введений текст невірний.",
   "inputs": "Вхoди",
+  "insufficient_lamport_for_tx": "У вас недостатньо SOL, щоб покрити транзакцію та її плату за трансакцію. Будь ласка, додайте до свого гаманця більше SOL або зменшіть суму, яку ви надсилаєте.",
+  "insufficient_lamports": "У вас недостатньо SOL, щоб покрити транзакцію та її плату за трансакцію. Вам потрібно щонайменше ${solValueNeeded} sol. Будь ласка, додайте до свого гаманця більше SOL або зменшіть суму Sol, яку ви надсилаєте",
   "insufficientFundsForRentError": "У вас недостатньо SOL, щоб покрити плату за транзакцію та оренду на рахунок. Будь ласка, додайте до свого гаманця більше SOL або зменшіть суму, яку ви надсилаєте",
   "introducing_cake_pay": "Представляємо Cake Pay!",
   "invalid_input": "Неправильні дані",
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index 7d794f9bb..590f344d8 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -338,6 +338,8 @@
   "incoming": "آنے والا",
   "incorrect_seed": "درج کردہ متن درست نہیں ہے۔",
   "inputs": "آدانوں",
+  "insufficient_lamport_for_tx": "آپ کے پاس ٹرانزیکشن اور اس کے لین دین کی فیس کا احاطہ کرنے کے لئے کافی SOL نہیں ہے۔ برائے مہربانی اپنے بٹوے میں مزید سول شامل کریں یا آپ کو بھیجنے والی سول رقم کو کم کریں۔",
+  "insufficient_lamports": "آپ کے پاس ٹرانزیکشن اور اس کے لین دین کی فیس کا احاطہ کرنے کے لئے کافی SOL نہیں ہے۔ آپ کو کم از کم ${solValueNeeded} sol کی ضرورت ہے۔ برائے مہربانی اپنے بٹوے میں مزید SOL شامل کریں یا آپ جس SOL رقم کو بھیج رہے ہو اسے کم کریں",
   "insufficientFundsForRentError": "آپ کے پاس ٹرانزیکشن فیس اور اکاؤنٹ کے لئے کرایہ لینے کے ل enough اتنا SOL نہیں ہے۔ برائے مہربانی اپنے بٹوے میں مزید سول شامل کریں یا آپ کو بھیجنے والی سول رقم کو کم کریں",
   "introducing_cake_pay": "Cake پے کا تعارف!",
   "invalid_input": "غلط ان پٹ",
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index 2150a503f..e5cf3d3f9 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -339,6 +339,8 @@
   "incoming": "Wọ́n tó ń bọ̀",
   "incorrect_seed": "Ọ̀rọ̀ tí a tẹ̀ kì í ṣe èyí.",
   "inputs": "Igbewọle",
+  "insufficient_lamport_for_tx": "O ko ni sosi to lati bo idunadura ati idiyele iṣowo rẹ. Fi agbara kun Sol diẹ sii si apamọwọ rẹ tabi dinku sodo naa ti o \\ 'tun n firanṣẹ.",
+  "insufficient_lamports": "O ko ni sosi to lati bo idunadura ati idiyele iṣowo rẹ. O nilo o kere ju ${solValueNeeded}. Fi agbara kun Sol diẹ sii si apamọwọ rẹ tabi dinku soso ti o n firanṣẹ",
   "insufficientFundsForRentError": "O ko ni Sol kan lati bo owo isanwo naa ki o yalo fun iroyin naa. Fi agbara kun Sol diẹ sii si apamọwọ rẹ tabi dinku soso naa ti o \\ 'tun n firanṣẹ",
   "introducing_cake_pay": "Ẹ bá Cake Pay!",
   "invalid_input": "Iṣawọle ti ko tọ",
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index 5db53a423..25024d0ed 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -338,6 +338,8 @@
   "incoming": "收到",
   "incorrect_seed": "输入的文字无效。",
   "inputs": "输入",
+  "insufficient_lamport_for_tx": "您没有足够的溶胶来支付交易及其交易费用。请在您的钱包中添加更多溶胶或减少您发送的溶胶量。",
+  "insufficient_lamports": "您没有足够的溶胶来支付交易及其交易费用。您至少需要${solValueNeeded} sol。请在您的钱包中添加更多溶胶或减少您发送的溶胶量",
   "insufficientFundsForRentError": "您没有足够的溶胶来支付该帐户的交易费和租金。请在钱包中添加更多溶胶或减少您发送的溶胶量",
   "introducing_cake_pay": "介绍 Cake Pay!",
   "invalid_input": "输入无效",

From ab1f267c78abdb8d4e0f03d80b51ccc6b0485a02 Mon Sep 17 00:00:00 2001
From: tuxpizza <tuxsudo@tux.pizza>
Date: Fri, 16 Aug 2024 18:45:06 -0400
Subject: [PATCH 45/81] Update flags

---
 assets/images/flags/are.png | Bin 287 -> 190 bytes
 assets/images/flags/arg.png | Bin 340 -> 440 bytes
 assets/images/flags/aus.png | Bin 1390 -> 873 bytes
 assets/images/flags/bgd.png | Bin 446 -> 447 bytes
 assets/images/flags/bgr.png | Bin 735 -> 193 bytes
 assets/images/flags/bra.png | Bin 1269 -> 692 bytes
 assets/images/flags/cad.png | Bin 1005 -> 417 bytes
 7 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/assets/images/flags/are.png b/assets/images/flags/are.png
index ae68c4ff2a1768cadb388223715b2f0dc75642df..8eb1e2bd3815aa15b34deb6a323f0b55a87df21f 100644
GIT binary patch
literal 190
zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC&H|6fVg?3oVGw3ym^DWNC|Ka>
z;uumf=k3*vyhjW;SOb=I1;reF``lAGa^juhwWp_idurRsDDa_^p`qSjpS$hK&9&23
zTyQXM+~j2JerHKQ=f#h0?qy%AJGppEgf+BHijTx{O_h+%uSl7>)1{T|63Z#BvoeKV
k3xyUZKX+$i*tk%>YwzQm5~UY2fp#-^y85}Sb4q9e08`9Dc>n+a

literal 287
zcmeAS@N?(olHy`uVBq!ia0vp^T0ktt!3HD`?mYJmNHG=%xjQkeJ16rJ$YDu$^mSxl
z*x1kgCy^D%=PdAuEM{QfI}E~%$MaXD00p;rx;TbJxF<`nDvKI8Wg7h8ciV9=TThJb
zZAGbpulR*(!FP6Q8n!PEu5ez-+qT^KKlA2W_v`B=C0?{nWboYiPgq{uxv*O4uzH-{
z3Xa@^t9In=`0Y`o(Y!)~`S8})JUmK=0vK;GxhXUlo%C4z|G%T;7uLl)=iN$>u%0qg
z^3(!-g|!t)>FFBZJ}_MV!mv7Qt<w66D%K;j9RBc~S<J1lzJlqc)Qk@KvtO^UFXoeF
gUEHA6(8$Oz?{C=rybaBwK=(6vy85}Sb4q9e0F&ZqJOBUy

diff --git a/assets/images/flags/arg.png b/assets/images/flags/arg.png
index c5bd233d2fdf7ab8618ee9f75f1bf913e581acf7..b941801284174a855e748daface2029e463d16e8 100644
GIT binary patch
literal 440
zcmV;p0Z0CcP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00009a7bBm000XU
z000XU0RWnu7ytkPYDq*vRCt{2mcdE_Q51$}r_azLoQLQEiXNokiWx1URhwR*T@hG;
zQjr@C$%ad25Ckm*gCbH1YSA<^j^j+4ccxkhe*`U}bvAS3d~o*n`|r8u9z`Jtf*^?h
z0OPNasT306bOWFk`cBv_!RQh5@Ka?pM!CcvSr7z}sgzL)_~Hek-GFmZM89<mVKyOp
zt{eiQ{|x(V2YPk}Px&<5lSQ-(DfAi@_+lV|fZ2dkO5<*20{ZG0?94dy%p{Cm24UVt
zU%;*9VHIZKY$fn^6vulx4s$I5>u?#}nihQl@4AY1X$jVbis5Mt!)grOtO~c1gm<|g
zeS!Xc4aQy)#^w|{+bYa;6;^f{PI&>sZbe_f7XpKabJ)ccI@&xQb92yh4BnN7z!%XM
z2)-uKXWDN40NuKVfpPPz6DSz9z+aT|ldx9<M#~%zKUGHSG?#dtW)V0PBLN<MvW!}Y
iOZtcjf*=S&k&q8nk^OL+MjQqJ0000<MNUMnLSTXtZm`w>

literal 340
zcmeAS@N?(olHy`uVBq!ia0vp^T0ktt!3-q7rQ00=QjEnx?oJHr&dIz4a#+$GeH|GX
zHuiJ>Nn{1`Jpz0}Tuav6FIs(X@rhT9Prm*S0{_0hef<9JiH}dN-P_%Jael<b`Qi8W
z^!@qu^Vyj-=cc>gpT+y^?3zb&dGGD+yErfW;=G8(Ctd>$TX{@F2}ntl1o;Jn&A}uX
z&I;?j0;=IG@Q5sCVBk9p!i>lBSEK+13q4&NLoEESUOdUwpdiwkxLHO@X4Ap%^_La;
z8WW4mb^jC;Ka77d)pgVVAh!z%w*(cQ>i?}R@@Stk!OOEzQFD3KoM*1d9$hOpo~ush
zb<<eBn!9ltU)AmY-jc>wn>X~kpFh7oHSu()$H($e-eoTJOAO;ayjFXwZ&ErLXgPzY
LtDnm{r-UW|t%;#5

diff --git a/assets/images/flags/aus.png b/assets/images/flags/aus.png
index c8837731c58a5746ff36872629dfabac35b11026..79a9744255c5642e75c8c4961602459a8c617513 100644
GIT binary patch
delta 865
zcmV-n1D^cu3h4$RiBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hmj!{e*+sy
zL_t(|ob8wUOOsI?#`ou}3-v>-vISYtinN-yG($@Z3bWFb0u5$Kplzu%CrqZI+nDCC
zBxEX5s3obT)ekD!buruKHZSwG?cJU@FHOR|&V}!mgZF`lb2vNa<@?z=-*e&dIC0{{
zi4!MITR=;O4iF8Gm=Kqu0bd{we=w0LMnId0sn3oB3Op?DfvutvmgEG+K5Uq`R<@hD
zuwBoA$7qDhML}LWh+V>(e*#F$ZpEbD082_D<{nqUx3m;Ffb867Fh1>sIq3}M6mt07
zE`0s&K<3r94FLp4YoTxKhrL7s>%|PX$HzcXUNmS&BL~12$gx{k17-C~f7qo`SW=U*
zGBijBYUr87L6M3PASeGheyMdZi{r7-q655Mj7?aPa-k(`!SmMx@H_6T79ZOCV9m;e
z<DLZG83$%&mjeLa==(5zIScl}d{AaHoC_|LN_(+=e|1=c=Q9ByMEwmAiXsMJ`V$!2
z4kZ{-LK6z_cF|>20?6dAf9csGWmGO9p-6>#%?Mp?I*G|nRHGV#+fBjq(+Jy*Yp~zS
zgF)LL08mieg=yO&yiO-(D`c>wCSk0_0CBo5@=44W$dPfS4PU-F;PZIkR5!w$cp65H
z9^{N5zpn)#ZGt08G&R46*Xx6OVw~Q&>_vCb+|Z9bhn0~7Xz!Sye}h_iI}A%&3LNES
zP%3)q8SxKd0`U9XB|ScUwgD6cr=|&J@hO-zt(yu`6ePI=0O-B`z692cbd2g>;3UI+
zC>Q|o&KLzARS#f!*#l~73ig7$fIi0))wnI`4r#}c1xfAz0CJLARrM$?>BhEw%pcqc
z!0%(?M)VE*VC+Nge^^8hWPKX~1WWF9lQ`Utjc<Ue=^ggQZZ1D~{|jIv=NEO-j#_|H
zX)o=l1>lE!36a+t(+;)e0S=w0Ls?}%>eM5&%d1||ZBYZj7s#P~@^ST!L+VjA0|muh
zn4e!+1t4|O#zrtAHm=j53?c`V&Av#R)Y<wsWo%rhLm5QgH@V{TI@)Z$d4+6Vr=!I@
r4nV-o09ai@oH%jf#EBCpUgY%~h2)=G+55lw00000NkvXXu0mjfA-jy#

delta 1386
zcmV-w1(o{g2JQ+WiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000F8Nkl<Zcmd5=T}&KR6h1TiL$|W9KqM$X
zOEFliq%=SZHrUc&V^d9<5;xJN{yo{KNvWoZFAb3JV8mE?slmh$lg8RmYfWr4S`my*
zidks4@)HyZAT?$i*ny?HtUJ5oe>s=E)0ydP*>-v0OYWRAch0@@&6#uVAAlZ$S!ru)
z6G<wHA|$ghDWcYXjkcmjiUwPi7z2^PA~ZHO3c+AdsHv%ep`ju6jPyVtAWTh7DTWV&
zva&MPM@~+T!tKN1u;6ew6#ksrQC&krgF^jKJ=JOZ<@)I8D2$Db#XTO6f709AOMS$(
zM2Vm!5{cL{GBPaDXjG78S#Ua?M4G*jbeqklEG#U*y<lv^^;GSwR;z+~JU2HthBD^$
zdSyWnn2Q0~Tju8G>=$mi#zB_d!~6HahmsZg2me$%ZawxK96i+q)S|oP7_@g?QlIVK
zS^)1t0BWyZW%th(R>Me0e}ObHv&TJNfl}`8?~hqgA=iuOMe(ItkNbp6hU)Jx!xx}{
z8DTB%5d01VR~C2^_9GMj!aBf>f6sz{F-A95UW+kh89+h<sPC!Y4@ScN!aTKy?T==|
zH(N7Qg2OL1L#Jeefx$mgVsPr@3m`3pb$`VS#0f(XbVLc#tCgC&e++=v4l=EQE~CS6
zdojrFo5pSc)R(W8#Pfy%yi}~VcYQvR^yRKB2O~)`6;KkAWJ3UEoOKi8+!bjF)&a#^
zcEft$G0TtHh%k;Ovg%RF^2LthI>VBO><~|QQOtHiu>CaCovm-`>Su5Nr+>p|LvTMR
zEy@E*y_varT|JUie}_-qudhtJfG0@~X0dHY1$gW0AhK&a)FUa%`mc)1A@tKlI5ct%
ztrdtp^E8XmGefhcL|o3zAO%B^3?H5Jpp65X-{{uaEiW&}Gcz-pE@~UR-1H>)njV3(
zm?TfFNbvi6Z-b|x3J#pR0oTXoRJ&>X^0!8pU{~=@_`0$he;&U4D}3PXV{MPrl;}t_
z)|Erw*%sKbttctc_O5T?ct`JDALDYl^d6;v#X%R|KYxaK@WPS9@X1sVeBD>nM$%FU
z{<dvWb(Jvk??l2UvZHW_2&0F8ac+az<<)SwK7JEsZq7ph6UYcx)@Ih1PveASP?HJa
zs4aYc@zSlxe_gSXDk#?K!xDTsA4|!eCXtIj_`o-APIPDfa5m<SKA8xoul)n*fIK{X
zANE~6eV|!xn1T;aD$)7*dwbE1-r7=_%d*plzmxy|bRe08gAsgjqY}-_%Y(oC$s4r1
zz84Pet6~FnSI^ID&MNBxa-Q98XC4((X+W`8^+XYqf0O`joKDHZ>41i;wLs3}9wnk{
zE^{dMnvZ_UBn?yVbew<Sgd_BHz5=Z+2U4=-Yh1Q^N~r~Y&)&lyuNtShf};;kHOBb@
zo|ClI)zvwE^H(pz2Eya^zO0Ffi4|037Nf+PR@Sh=Kr<6@Bk)ZX&^7}$7%-9ITxTA|
z4Oo0~e{vG16J-`Q43t^i!^JQ@iL9dA+@ZAk{eCOX`yzz`E&X^i(vyXUc5^04lEN1g
z#y*U;T5wxxZ?RaEP$(pqmX^|fiHOG4aTJNhu`-J8j?nyyTUREjV8;~DA(B+I^$FV$
z*Kt|K<lx|7cm=_2c_CYpB_$=SFOqc6ZINUoKtDf!WqNu#N}M3ET{eSyU|>8n;P;6G
s3DNk>?2y55cp*ZP0|~M-J9yyuAKVAP`)@@c&Hw-a07*qoM6N<$f`p)$rvLx|

diff --git a/assets/images/flags/bgd.png b/assets/images/flags/bgd.png
index 0f8c5cfe543515fb1c5b2e9520656dbc2783beb3..505636a801fe7459a7f7fd7000f6d74d014e7cde 100644
GIT binary patch
literal 447
zcmV;w0YLtVP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00009a7bBm000XU
z000XU0RWnu7ytkPaY;l$RCt{2m`zT@Fc5_;5WND6vP!rCW!LPe(nXV0)W8DoiEmP%
zw*bMB_$_xpupjiIdPAf(#8#ZpdD4@j$cg52?D12CV6j*%7VBR~E9#U>@?DT-0OfyH
zH7_Cc=b7l`iY^jK4}%FkhhzHgj|$@&_s&yUjA`W;n5B}IK}@uNvexgxm`+pK9)R6k
z(PEfxEc~}`ql|X)762@26mNVTP5lDQQdzrr<7p=S0Q7QItY=$*k07?+*d<kX2;IiE
zc;hqMO<hujhaQg-X8`wuq<MhXaC6J7YMc|IX@IZ($Qc0MCAtjodEf!y<<PzZ89#+_
z^8m;;t^n?iC(Q#On7IOwKHBKs)g`?-=tN6j2bs{SNR_q#nXf1zRz|9<Tl_rA?2Ffy
z0Eoml!>m>kZAF|GD<f4_*%KJ!WZ7uP0A^z&m?7Jsx8tybagBTEHW=fyc+LNXl=~Ug
p`~{T%S=C#;2Usi?i^US%(+?UD(B+QH!(IRY002ovPDHLkV1nh5$NT^Q

literal 446
zcmeAS@N?(olHy`uVBq!ia0vp^T0ktt!3-q7rQ00=QjEnx?oJHr&dIz4a#+$GeH|GX
zHuiJ>Nn{1`D*}8%Tp6<b7_$ACviyu<y^DQ3W;(gecW`TSclQhP;!pEcN$^===lV{^
z@u#Na4^78!T8<Ztox_4XZx}j#(Q^E%<@j04vC_*!IMw&Gsq;5Y$4^?0L7`qnJ{~8`
zoVn6{Su*_&Sh#%Db~KOn7EJZMW8f4W<axow8EE;dPuG-zltxLAU+{n80K>jjdJ;fA
zoCO|{#S9F5he4R}c>anMpx|sz7sn6_|E-r^@--O<xCLtIX<S;hpy~I$@Ab|Ze|fCD
z=3FeOn|P8}(}(%=wKyq*KeM&i&u`_=RDbjBS96BP<Lx26j|vx+CaDGc$YrcLG}CWy
z&b|XY8N1GOS4T#!jX&oQwDq91?B=_PZzh)18@!nFm@~P5$#ZTk|M>a-AF8!18XjzB
xvG?B8RJCz?e)rl9>$?x{Yw>-e87#eWtE#f1n{<nXf+*0L44$rjF6*2Ung9>TytM!T

diff --git a/assets/images/flags/bgr.png b/assets/images/flags/bgr.png
index a89509f1fe0a556e5c983509983685d07615e426..d89a0ae89bff348beeb221066ea35302e9dca0e6 100644
GIT binary patch
delta 179
zcmcc5dXQ1EGr-TCmrII^fq{Y7)59eQNE?7K2OE$KXZqPbQBk74*we)^q+-t7t2=oQ
zIB>XJ%<Rcv-tL*%EiJjcq+!Fq$r=sOObieB^Y-2oQEFVooYu1I<-{F2g=fRR7P)1A
zRJQ(E5!}HtiEoDBt7YzwHXN~xzj|2m?9u)+iuqg<9WF2$JKg=_F+;WQ=c-x8Qr+^B
e3=B~(n0qIk7CCg#%^K(oP6kg`KbLh*2~7awy+hsr

delta 725
zcmV;`0xJE%0pA57iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hNe*tq+
zM?wIu&K&6g000DMK}|sb0I`n?{9y$E00MMLL_t(|0nJ!Ft{O2Aws)652_&GPNWnuK
zAPp4~1uX~Q63HdVc{o5)QU(R2C=wJD2)z;{KtckR{h7??w_cgez9gkT$!})u@w|^&
z&v<Pio+0zvWHNCeiAcU@lhYj2fBqkH9YZ=9+mx6B$Z(Ux;ZR;K7uoCe#B#Y*W6)2h
zliY5%l=)$z+wCeJjYfmC{q1&>l}d&5IOd^mFc=X0pdWpvU#+iJE3sa$<MDV*)9DmG
zVv{Hcy1wrhN~Mw;1c400P}XWSkXHW?dZAFD<MAl|hU^@z|F50rdBl3$e{41*meFFd
z2&I&7KA64R@AoSl@*P=%IF5It(WnG&2&9KUhr>ZW9uGwKMOXrk;>&)&cX`P~{76{5
zDy-#l*%g+7mxQBrM_3LdHe^Z^i6Sfmzj{O!yktrgnJz2?mpsjhJagd7kFUZea9yQV
ztEKcOqLalpVH1W4NkF}Nf4yLBhT3DXU~Nn$GjGy5YGX1XcxHK03Kp)g5J`Db$)psc
z6j%e)QT_^3ywqN=2R?uQC2Yb^4xY}PG@^iQL_dA_NVC~Y=~nOcNO1m6R=OgpS=$CA
z_)|o|+QvGH?bD2?N~U75XdO|Lla6S-*=(X%idSI?ViK=>>WKK&fB$*7W9f12^6+Ji
zLlzErdLnf6<vBGEXXo>o>h=0t?aTPc+M3X|nD4qSU9Z=$)9Hi>(KyX|M3p-OF0ejN
zxbZ?(5{(_-+2jg|X7(qxSFKm8RVC;1`R&fowz|O<vfXYgUyyj#woKCJwRzv|b^$nv
z<hY!N^umBLmj?PdE4h$xvSXBU$&k6caKt+o60oD3iwBM01g|~t1h6P`00000NkvXX
Hu0mjfjJ;7d

diff --git a/assets/images/flags/bra.png b/assets/images/flags/bra.png
index ecac6f5a3e8a3c3a191f64fa2fe3a1e1814ff0cc..ee0b0e8c6ff274d6dc5486cae634698ae73df233 100644
GIT binary patch
delta 683
zcmV;c0#yC=3A6<viBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hmj!{e*$Jn
zL_t(|ob8tHOH)x8$It&&lKG=lE^0$!B?S2ce5G&1*j@xmSug5M1O;t_1YhdJ-vjXn
zn@B2(ELhQKC0T~GU09Jx@s;P&t<-z(Id}JLI5}T<U~tFX`Fy|6d7d$*q@<*zq;wXf
zMVnDh#S}pFj3>}K*@$?m3ahU#f8xeeV|fAGkJm&0SOM&vGb;b-JRYyqoqmAUKdzex
zKVCA^V6p*@yKYyq(qOUxc&-;K4JHG?%JuBqO9(v+qP;tU%l<K=I=aIMg@VR2S!pmY
z0Cuh~%(kQcS`-(qOj#B^Ta0x`NrM#%VAtz(_)6cT?cvR$?^r?PU8dn0f555NbMJfz
z-c8`voizjp*U{OVfUj*1l|E~ThU=rqWokX$4OalX3A4E|4=WuU{Km^ySqzV+(bczn
z1SlK|c$!o~0HPCS`9&HV$uCH(?qYpw52-ggvbp^eK-(X_;o*}cYOl^17aJZX6&FBs
zu2a?dtuJo#%{c@H*DxM?e~+yG^DoHG?sxP*SP^=+T^d|~fu#m~-4O$DnmlGzw@l;S
zqb+2%^9IC^{a-@wCKJibf?CKw(S(^~HTOqo=JNo|s%n|W)1eg7na|w!Qu|UHd%ncH
zG-yeQ0+==Q{I+Y?J&jSPG-$($w9&sYIs!dY<Jxs8i_9(!T27*ie{3n%R*>tO3;?Gz
z2!fWBlk--Gj|;jk4ZtZ4+OV{wI(s6<c%`Dxk#OKd+vqM`mk!`&Qps>#D+U1XZg}l=
ztyBOaX?S&AD>i^#8nRs1N(J!$A3>R}Yo!Dzb}<DIJ!J_fDJdx_DX}utA(Xc0>7V5Q
R1ONa407*qoM6N<$0fOwqHw*v(

delta 1264
zcmV<M1P}YP1@#FbiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000DvNkl<Zcmd5=Ur1Y582|3gwK1DEiPDsI
zQ)9;du$EPfY=s8Q274I;h2h&kH~KEV4^-Hm?cN90u{{aHKJ2L*reK+2rgWomxY{&Y
znXAPlHECj+KeylS=n2=GKgQ^Te?Ry*=brnWbAR_c-}%mW4$(m<m1JUKLPe?Tx>8N2
zf~ZFQL;9+QQZ?z8hzWoUi{khDm1Huhc)eZ<g+k&T>hXA7i9{m0>Bq?9@rW^;PNy#Q
zGntHHv)Od{9{tef^Z9g)gLbqT$CdSPI84jS%f+FgA$@js7Go5RL_yG!f6Zo_tX8Wf
zm&+;nd|qj7Z3SuZLDZX?n)FyKMzvt>BkT3*X_}^Uz1Y^)R^YO*w6v606h)Yrn7w6V
zW8=&pUn~FcV;7wctoeUF^B$M^Kp;@ixB}CwY(@5umeWEK=;GP4@GKVapvqSEDGQwd
z`kl{(oCJ)VR5~Fzv^-6{fAg5;y<s8K??0rj<}4i-ScE7`MB&8LAVxbjDdM|Fqn(?j
zw&9D<Xuj_O4PV%zMzOuUO)`3DvJtDC=xDR=W{XW<ddO3~Lo>H8(@mDY9-XJe3oG@1
zuudbNKA>rq0auL1R=R0z*LtM!?RI-9d}`Dn#ywAj1u^B5KV1`If5e@?JB37_+G+gD
zyEJ$%Mw5{aA@w4aN)=mLT15TGK8l5M@9KR)6eMp2`)FqVb8^4oBu8s=nLd61)|NjP
z@rCO4U5CSQ(4ufy4!X5FF)3+9BNEo@<o`mY#LE=*yZgx5YNL2^m)4fkbmPYbp#zr~
zW)}e9E{~b)_v;tvf5!U7y4^t#l@41C1LwAB>fNaLh#6zwZBinc5%oFxe~%1Xx2MNN
zBj3D9(M6pCzm<=PABOKvKI)*EO&1-8x~ATt6{@}iN%NE^b}}^g>k8fcc0-V!n*6M4
z|L7qWEelTw1=WB*{$%O0m@YF0uRSBA3=W?1N|^g)l`VR!f2<v2^)6naJ8?VJf}HIV
z(f0QCnjP@xWB+!OXTf{G3IkXFEKNNi3B$_L(t{t~F1^2>dW}8~T@qs@^0k8wj8|sS
zdI6FkE5i&H3Br#gi!#BB39z5F(dfYMLI<SKr+2aEP%BEnc*cO=(2j(U&iv;R+a`#*
z&p#Kd8?n>ze|na#bngXxkPO7n(pTZPj~ws;nd6Eqnv+)EK{Z?Ox}~9P0^8*HTTjZO
z0<1W;;;w5|SHed>6zsfXW|(XqQ(wx=8--kKu&@Lci)W#?VUj>1k<g76#ZjZFnQ?bS
z-=Skdrg-)GVJ#RfDiUWj;+R47l8%d$ASl5LsmR9>e^D2!o)2Kf)z#GkFROJrEnqHu
zhAXf&ak$eD9PYT(wzjr3-uG4Hr+ca29#F5Avl<U)@GF^2n8z^d8X<Mj-(s=o>2x~p
zcDr$20?}eAjxy0AH|E&fS@;DXT}27ufe{$fC?Ur7eciOIb6O_KU@(~3Wk_8q&_&tV
z*(t_CMu}&s%OtZdmuoi~jpo3K_K(YzP`WTMUmD2g{R;`z{I1d^gX!`@r79N^(5rOu
aAn^)nJ*dJK1w8iv0000<MNUMnLSTYd&vD=Y

diff --git a/assets/images/flags/cad.png b/assets/images/flags/cad.png
index 106cea5b9cc398a4b2287a4f5397c90f144dda31..862b6f4ef901a6b6e379dc139a06caedabb88a2b 100644
GIT binary patch
delta 405
zcmV;G0c!s32cZKYiBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hmj!{e*sfT
zL_t(|ob8oAO9L?&#t(`*iy-Las`LYh<v1-4(jwNusnF3nD1y55(};_>st9#*5I==d
zagWuzE$Q7o5{rKZgEd7jC(i>fgd{J?FYljt9z{_UMg0fC_b`Zwr|?$|1KxuGf)NOr
zLM&qOO&vt-V?<|%`RqcE4;>_{f0Ib76X<qs^8=uEml0lHK(=b{K6<R@^qTVk$=a0B
zH>pj#4-nU9jlOYx&V2yYTrm2ot&+O{YCAx5c>=j#G5X4bDxPoJkb5ic0U#*!_biPV
zebe$-e;gFt0Fa+LjjhSndUgPBz25fnss1DG@3KuH{oC3CMCV7@rjRa3Yqhgz4ba=1
zM|gEgfT2>zCK6x0yvVwZ{^W2cKQf^YFOMRvj3eHdL9bE#c=1N@bxyD8J<b9M!)0uI
zKmdRE2-p~0iU0w8M!;hViN7jhilQir@^YvbKOf+jg$@7R00000NkvXXu0mjf7Y?%E

delta 998
zcmV<C0~!3G1MLSPiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000AmNkl<ZcmcJT%TE(g6vofYv=kzx&;~R`
zfph~wcO=FI3;qe>MiZku-Dq6s!YCL_G|{+orEXZ_!mSGvmY}ec8WTc_DJV594aGie
zXU6m0^p3-{&`xLkB{%mmXKufqe|zS>h>oH(OLKE`Dss~_mE&xhB-L);;$792s}5UB
zm;hopDKj%ON}*6trlzK7eSKX#LwSFHU)kE)G97=65{ZQ9V_;ywl=h`kN$Kh7G39f-
zhqmeIX%qdR9c}i0WqD&`gObUlF*`eJE-fvg55q1L0<}t|5)6exTD4kLe`>Xw5)OwU
zTKpi&!C=tL<#Kcq&Ua+FUAsUaU~<`rMx#3C`r6uBO;Hr#Vq*1LI-Tx%eX#SDtD`3g
znf$U%evrH{+R9}6)?i|S^V;(AvL4_9T(7bh)m9?gMK2tX7VaaDjPmGdJc>Fhs%+($
z(#Qw$@8413;|KBsyC#)<f5Kodf?uy*Qf~1r`2{{g<N?`$ASMs|cs5VfoitT<IdOgW
z!ClcFUwA>ClFeo*5{U?1mPhfGlLxxuXQ}vk#i}C&g52f>7HMhnJoLhYoPzOl4bQsA
z&x>bzJuKXEcz9^Ya)3G{yZA<k0L4!$6o1k<#9Ch;rLJA3Qx`9hf6B7}W`e<+cc@+Z
z`};AU{}YOU<w=*^poJr}xA@qq?{SPe`T2BS{27D+h%Y>+P7y;dmpeDWOLl(S;!{%o
zmON7L8g2}acIh}qGdvBsrP-fpg`A!&p_mHXFwE0V^y>At?PFJNaD3h-x5&}9gvMeq
za?6=}kJ|b;U~~HZe?xK$oY&ydPJx$B@+_Wp;z<DKNsr>I_p~Ab%#)bh<urul6m5Ta
zrBXchF88=%_e35Uwk?xboiJa9CML-b<OUu?Z|%(eqSKYgNj{&qw22snYOkA;{{dDe
zXan+4ML1@V52(Css@^xv0{)P!wO)9X4`9aT=B93v`JFt{e?2})-9E%8wD1{D=b?vK
z^T^?j^FSt(3GlkFA{6XfKa`IP5BuQ^afKm6+1ZEF){eBr`<kYi#bU8GHa3Ry5`-Go
zJjy~1ZmhDqEBr!<kFFv|;*QH~QbdkqZ?D@HWx2PvSLCa!tEDm{ZDoQj@{y4d(HC;m
zr7erB3=IvHJX5Ju6`H7iTyBPSVc@(pkoEe7gz9|O?2^H8d7;uV7ZR{*cJUzj3;fU)
UCY?K~#sB~S07*qoM6N<$f&x|Go&W#<


From 989f7fe1977918efa3375efb36290ec8aae53f69 Mon Sep 17 00:00:00 2001
From: tuxpizza <tuxsudo@tux.pizza>
Date: Fri, 16 Aug 2024 21:09:23 -0400
Subject: [PATCH 46/81] Update more flags

---
 assets/images/flags/arg.png | Bin 440 -> 1183 bytes
 assets/images/flags/aus.png | Bin 873 -> 1834 bytes
 assets/images/flags/bgd.png | Bin 447 -> 913 bytes
 assets/images/flags/bgr.png | Bin 193 -> 372 bytes
 assets/images/flags/cad.png | Bin 417 -> 788 bytes
 assets/images/flags/che.png | Bin 855 -> 371 bytes
 assets/images/flags/chl.png | Bin 351 -> 753 bytes
 assets/images/flags/chn.png | Bin 860 -> 840 bytes
 assets/images/flags/col.png | Bin 217 -> 381 bytes
 assets/images/flags/czk.png | Bin 915 -> 830 bytes
 assets/images/flags/deu.png | Bin 703 -> 370 bytes
 assets/images/flags/dnk.png | Bin 801 -> 387 bytes
 assets/images/flags/egy.png | Bin 431 -> 553 bytes
 assets/images/flags/esp.png | Bin 1090 -> 1874 bytes
 assets/images/flags/fra.png | Bin 700 -> 351 bytes
 assets/images/flags/gbr.png | Bin 1341 -> 1944 bytes
 assets/images/flags/gha.png | Bin 432 -> 762 bytes
 assets/images/flags/gtm.png | Bin 477 -> 1691 bytes
 assets/images/flags/hkg.png | Bin 1023 -> 2007 bytes
 assets/images/flags/hrv.png | Bin 1088 -> 1421 bytes
 assets/images/flags/hun.png | Bin 728 -> 373 bytes
 assets/images/flags/idn.png | Bin 684 -> 360 bytes
 assets/images/flags/irn.png | Bin 615 -> 1150 bytes
 assets/images/flags/isl.png | Bin 867 -> 424 bytes
 assets/images/flags/isr.png | Bin 937 -> 994 bytes
 assets/images/flags/ita.png | Bin 705 -> 351 bytes
 assets/images/flags/jpn.png | Bin 896 -> 851 bytes
 assets/images/flags/kor.png | Bin 1119 -> 2594 bytes
 assets/images/flags/mar.png | Bin 429 -> 849 bytes
 assets/images/flags/mex.png | Bin 1013 -> 1620 bytes
 assets/images/flags/mmr.png | Bin 902 -> 1041 bytes
 assets/images/flags/mys.png | Bin 1082 -> 1436 bytes
 assets/images/flags/nga.png | Bin 193 -> 351 bytes
 assets/images/flags/nld.png | Bin 762 -> 372 bytes
 assets/images/flags/nor.png | Bin 898 -> 424 bytes
 assets/images/flags/nzl.png | Bin 1373 -> 2096 bytes
 assets/images/flags/pak.png | Bin 899 -> 1157 bytes
 assets/images/flags/phl.png | Bin 1179 -> 1565 bytes
 assets/images/flags/pol.png | Bin 707 -> 366 bytes
 assets/images/flags/prt.png | Bin 1169 -> 2611 bytes
 assets/images/flags/rou.png | Bin 705 -> 351 bytes
 assets/images/flags/rus.png | Bin 702 -> 371 bytes
 assets/images/flags/saf.png | Bin 1319 -> 750 bytes
 assets/images/flags/sau.png | Bin 476 -> 2201 bytes
 assets/images/flags/sgp.png | Bin 902 -> 1123 bytes
 assets/images/flags/usa.png | Bin 1220 -> 597 bytes
 46 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/assets/images/flags/arg.png b/assets/images/flags/arg.png
index b941801284174a855e748daface2029e463d16e8..d8745845501576ded2c11ef07a2ecc62b9258469 100644
GIT binary patch
literal 1183
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|QH-
zr;B4q#hkY@qcdbmMUH*mHhbH$pbx$xs{(vmyZpI=9BVad12bEKvNB(LC?zFzO<!kv
zknQp$wY^K$&PoXO_K42bQ=NFSSD@%(#^sPpA*#D)-+kxv&CJ@`diTtk60Z)cN8Yc|
z|DW>h_rb<mo0|KU&u7on)lzB^aN<xz5K9(Jc#^tdn*1y_69+Nt1QUm4jI6bfx@It*
zHgWhO;&q4Nqmze?<D;VqY$sa7c@k%`am;t>lvar2=v4REBXNdd=Z7vuoy!algEb17
zk8mq~Wa$)dmQ)arGi-Tkn%D5yBEgd1ms#pThpfSLiG+h*zZRbLIj~Xp#wm+8F=E?N
z*EZgZ$!SPcNtBfOvXN~?xLw1gpS(Rg4PP+3Pms%RnA@o+yi0wLf4J0yng4lj9u;s}
ze&1!yV_TKq`x>gYiruu<z2Kge(DQ4;jyi_40<N$_`g`KTB`1Xbx$vIvaopF_9QEP7
z55m_w?%pWA@N%_)^?uo1F|9}Xe=m%&>N(@W`{m}!KifLq-4<oLF^$!Fw#%l^0!q5<
zf)@LPFQ@t^tb3Gs=C{|z2h}XEX1?`^sg&Kh@w;H&T9+Sh<WiCaBW7;-@bCJ5#+^Es
z7ON-r{7B%Ln*8yRA4`AU(Z9FOZrI(GST3eqxQxZ?vGI<*<=TgQcTafro8wqYvfUcj
z@B9Dp1{@R2weOhnN3-Xl*OC3Tavzro{V{%V^pwAxjl_osjc*!*zH40R)^~b+ul-7Z
ztjSKcoxk^UzpuY5o#58w;djqv&vG`#`@ugp*9gy<Ej?l18`p2M#D9H{oAEZz!dBX#
zzJy(Ax_!&7t2|q`%icP(<io$%#0EQS)~&Bq7KLjITKr?0Gq3l+4EFl(l^ZTSKl#6G
zm$_2eDv7Amj}6rO6h9wd@!{UxM27;YTL-2`?7GeM^iZD8mA4I5N!$kS4tlK@zsBqT
zul!LA=c2Q>C%jtgkoBN=Meh3qO%tU(|4Z{5QeOq=g(}qTmC1S?JwvZrs5{+z;oSRk
z?5)ebtF8DNEwDF$>+LPQi0!K;#__(HKfC4oJ1*uqp~6O0|5$Y{g>e@DF!*xrZosU0
zhYxK${$PDAXMJe?;WZ&$cPcEeY%3Rhe}mt8w!ppZ)jS5145l(n%e(%ZHLh01v~AS_
zGn?)g{B}BXDnw6R&sVrn!LT#_b;7Uullgrw_QfVQZ2o1js{Qk!W4FF5Uj1(v^mo3a
zyd~@3a|(aH<~zUt&+@Q1m80Awxl&VaPyBVs2W#pk1&Al4CVBXqDc!2$_;p4>$N6~7
zRc(WOQ|0L~EmI?B&sT^^Z1}ui+{9SuME$A_TOQQUUvakQ!#=KK4C!;lcnhxWU|jTn
z%e0s{P^LPxJm3*qhq%)tP9c3ZV+XxGNgTi&_Jh0}mh79xfRu;9x!E=EQGDW;kF`(R
S^~``J4uhwwpUXO@geCyffEt(p

delta 429
zcmV;e0aE^-3Ah6xiBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hmj!{e*tPq
zL_t(|ob8suN&-<7hG(bG&?20N=mClzq~MAfEuvMMUZ7nOSb<WJ8x6^ZOJ)!REd+xi
zQVD9&G&7FlOqzG5S_ppxEuwWcbK`t)_V@emx#u25AqavXi2nfNuaKz}65w<LpceX0
z*e${65%cg<Wi&>)#2;A@1dyqee^Cnf;sv7JfOAnqzjX{@HX(Yh90H>M4Et;cdUgg+
z`83><MYIbk^cofTVjzKl*??0@<8EaF`sx_$%sBMSB#d1KVctexz^&zB6=vaVCGd6>
z$9p*rb1ebua2eg27JUKlx{7vb3D$;+;b{!RY7E`13b&Gkcex*Zf&P6Bf5u)C#^w|{
z+bYa;6;^f{PI&>sZbe_f7XpKabJ)ccI@&xQb92yh4BnN7z!%XM2)-uKXWDN40NuKV
zfpPPz6DSz9z+aT|ldx9<M#~%zKUGHSG?#dtW)V0PBLN<MvW!}YOZtcjf*=S&k&q8n
Xk^OL+MjQqJ0000<MNUMn143Yei6XI!

diff --git a/assets/images/flags/aus.png b/assets/images/flags/aus.png
index 79a9744255c5642e75c8c4961602459a8c617513..2364fa9ef3d39340243f402f78bc102b43e89624 100644
GIT binary patch
delta 1833
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
XT~~JTs3Lbs00000NkvXXu0mjfv`}?{

delta 865
zcmV-n1D^b<4(SFViBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hmj!{e*+sy
zL_t(|ob8wUOOsI?#`ou}3-v>-vISYtinN-yG($@Z3bWFb0u5$Kplzu%CrqZI+nDCC
zBxEX5s3obT)ekD!buruKHZSwG?cJU@FHOR|&V}!mgZF`lb2vNa<@?z=-*e&dIC0{{
zi4!MITR=;O4iF8Gm=Kqu0bd{we=w0LMnId0sn3oB3Op?DfvutvmgEG+K5Uq`R<@hD
zuwBoA$7qDhML}LWh+V>(e*#F$ZpEbD082_D<{nqUx3m;Ffb867Fh1>sIq3}M6mt07
zE`0s&K<3r94FLp4YoTxKhrL7s>%|PX$HzcXUNmS&BL~12$gx{k17-C~f7qo`SW=U*
zGBijBYUr87L6M3PASeGheyMdZi{r7-q655Mj7?aPa-k(`!SmMx@H_6T79ZOCV9m;e
z<DLZG83$%&mjeLa==(5zIScl}d{AaHoC_|LN_(+=e|1=c=Q9ByMEwmAiXsMJ`V$!2
z4kZ{-LK6z_cF|>20?6dAf9csGWmGO9p-6>#%?Mp?I*G|nRHGV#+fBjq(+Jy*Yp~zS
zgF)LL08mieg=yO&yiO-(D`c>wCSk0_0CBo5@=44W$dPfS4PU-F;PZIkR5!w$cp65H
z9^{N5zpn)#ZGt08G&R46*Xx6OVw~Q&>_vCb+|Z9bhn0~7Xz!Sye}h_iI}A%&3LNES
zP%3)q8SxKd0`U9XB|ScUwgD6cr=|&J@hO-zt(yu`6ePI=0O-B`z692cbd2g>;3UI+
zC>Q|o&KLzARS#f!*#l~73ig7$fIi0))wnI`4r#}c1xfAz0CJLARrM$?>BhEw%pcqc
z!0%(?M)VE*VC+Nge^^8hWPKX~1WWF9lQ`Utjc<Ue=^ggQZZ1D~{|jIv=NEO-j#_|H
zX)o=l1>lE!36a+t(+;)e0S=w0Ls?}%>eM5&%d1||ZBYZj7s#P~@^ST!L+VjA0|muh
zn4e!+1t4|O#zrtAHm=j53?c`V&Av#R)Y<wsWo%rhLm5QgH@V{TI@)Z$d4+6Vr=!I@
r4nV-o09ai@oH%jf#EBCpUgY%~h2)=G+55lw00000NkvXXu0mjfNob6f

diff --git a/assets/images/flags/bgd.png b/assets/images/flags/bgd.png
index 505636a801fe7459a7f7fd7000f6d74d014e7cde..802233d1c0aa5415b9355fe228414612898cfbf7 100644
GIT binary patch
delta 905
zcmV;419tqs1Ca+IiBL{Q4GJ0x0000DNk~Le0001B0001B2nGNE0OFW;IFTV2e*;5F
zL_t(|ob8)SPZLoXh9}+@F1<t>ThfKH69S3aE^wi?g>*VdK#T2J5HZ610*yaF-3w9U
zPcZ7j%f?@!(I4PtCEyy}eCDk~VkS%!Y3DmL=Y5hlX;Prg`<^+M?|gV3A%qY@2qA<J
zLI@#*5JCtcZV?)x%-}p=07iF!e=z{V0GyuU{)+Y&40A39U>Jb<C=B@o=o=Ao3KDfQ
zxCR*aWb-1tciBj_eO2yUn2~4WzI;46Dc_4V`C0fay#8=%s`nm#rqXW9o@EP6&3XW(
zg^t{xn3k{QhRCr?JJOeOL+(vXOL5_vzPVWo;OO;^Jgx-t<M_@@-%j`&e-EpH99it>
zo1BFJI{ut&6l=RSKCbmrUFKV}`bOIt!2YGKJUQ3uyYUj!qe{^GEOo<e3gF<)uDls(
z4%~c+^m?S(`%HDyZ3qCPF-`L&(%aKbIbhRHNh^RfrX5KT7H6je==!s2=1Zh@YtGF8
z4lj0OtyEVJV53;GV~d)0e*oC$Ynv~TR&AJy(hLBn(|#PXq))<k8PYy6rx^gs3)-ej
zOekA85dey0sMBa0E-|6rgrZ;W13*<%+iXeD+4*+<13<Z0+h|G9?Ta({58(M&`lnv`
zM?D?)^B({%PPC1d1ic@g%zprbC^bu;go9!31F&iTFEMQvY7Bq@e<Z;vNOCa+aS=AU
z0dN~?bOW&YAa=`zgBY5ow2hVoopGTQfnwa}vi?Pk#Pq4$(Cwy6D*y<kUv0xBrn~1a
z>zVKRh0JE5CMR6Fkb%&Vpl!TFdf?iXBy{LT*NRK|^-|r<OL+*rn%V(e2^?)p*%Ep+
zwaj0!Vd~Ki0Qayjf5!aO&3`r8lzmGU7_S`wghp93%%)}j%TYGxZrh}r#?EM^8rU`R
zZFmCy6nZt+2CzH&HdMD~!L>Pnt-jIKYS23%?bdkw4eax=?Nv89D*<?sa5_cV;(uyK
z_#KoN)K9os4#10qA{m;d(6@uu5p*x$av$Xk2(RA_PxanIUr8BNP5zsz_J|5ICYzrC
z&jm36!vNGrVaO*y--wV?kf@u%HNdzhF2aTZsE@*sPk_D=p{-L8A%qY@2qA<JLI@#*
f5JCtcUXJ($LK;Uj7##-`00000NkvXXu0mjf&?}!+

delta 436
zcmV;l0Zaao2fqU$iBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hmj!{e*tkx
zL_t(|ob8xRPQx$|g)I=h0*kUrxB+F??5NU3lT_5e0`G}$QlPg0!IAhacR;Wo^rCu0
zq&CD>oX~mFlcLCp=5y@vQ-ol#SS%LnUq~zJluPnmkY)hoe^xawA@%2(=;ewo5=jq(
z2|b5n`tFYk;~MwQQ(25@<rkQxf0C9#OtgQp*6+cXPE*+)fZbftVwi3${I_qTjCS%C
z04!=0Z+sn1{Q}HVS-W`SX(s&u^m0|KXIp@eAhzGwB~^F`-Nv?f<1^b$T~dXI9*+`d
z0QZBWd4Sh&bIYu1oD-sHfUo|@835iTx(x7n-~r&}(7pp1KZSAg0LV73e*o@|C(Q#O
zn7IOwKHBKs)g`?-=tN6j2bs{SNR_q#nXf1zRz|9<Tl_rA?2Ffy0Eoml!>m>kZAF|G
zD<f4_*%KJ!WZ7uP0A^z&m?7Jsx8tybagBTEHW=fyc+LNXl=~Ug`~{T%S=C#;2Usi?
ei^US%(+?UD(B+QH!(IRY3IG5}MNUMnLSTY=RLHLY

diff --git a/assets/images/flags/bgr.png b/assets/images/flags/bgr.png
index d89a0ae89bff348beeb221066ea35302e9dca0e6..fc53406b4090230652c132e2f3b7cede6928c901 100644
GIT binary patch
literal 372
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TR)
zr;B4q#hkZS5B450;BgK#e>Ryv^YYT0nJ&?;2M)ffZQz|S#R6mq1YGDUzQ5?ZF+WSe
zW>(<?q7JXc&2tWDH<WPqbDxkd+_PYhq}hXSlLhxNb!`8zqhXKWaqd&I6PfeuB_C=x
zRG=%empgFF|KjJF>`XUqHgP6!FZkLmZT3LWVOQ&E)+fCYaRK*uq&NIN$&t@^Bzi}T
z!@Z8DtWVEwVB9^w=YyET9yCSo<@pyp(~z29sn9S}cLu{UhN%5J5}Df=F6rusPcUBu
zc3J|^Y4d<i+W<1`Q`4uk8x1%8-72^g?j0&(tW-V)c5E8Zu|FR(!hFoY@Ywz%d*(fz
Ts+E=DTS20pu6{1-oD!M<LCuhv

delta 180
zcmeyubdXW8Gr-TCmrII^fq{Y7)59eQNE?7K2OE$KXZqPbQBk~}q1e;KF{EP7+p9Zy
z4>)kRT+HmrVBYST*)1)(yrf~nzsVX6(M${v`1AJO6H#hh#GKZ$>*d59I)!J$zZSV=
ze^j>qSrOd9GKp`7;Hzcsk2V~!jK6wV^6b(6Gm80K6CExv8av(n;xR+D@8_yn#!}t#
fk_-${FPM8LofbKC(9N2G0q8hSS3j3^P6<r__$5Q|

diff --git a/assets/images/flags/cad.png b/assets/images/flags/cad.png
index 862b6f4ef901a6b6e379dc139a06caedabb88a2b..a96ea16f6bff593736079166deb76abf71ab87d7 100644
GIT binary patch
delta 779
zcmV+m1N8i%1C$0KiBL{Q4GJ0x0000DNk~Le0001B0001B2nGNE0OFW;IFTV2e*(ry
zL_t(|ob8&;YZE~jhl7F$dhr86@ZeR^yI*TdQPEVf3Z4S?W|dk5<0a_9gU5PTM8tz1
zN2>_!$%FV;C>8J1ZjxH!W|O?~E*OX*Ni&=7rkUq~Ic&STlg`um&CJ_oG5`Po00000
z00000002%QUPcDlj9=Q)O$Iz3e+cjqkos@6VFsi>u!aaqe{fj?{NZmb!af4nhI(v6
zg$UvxCLF|k7GX*e9;FERHxtTB?__P^CEL(6ig7EymZg5>fHbmuWp(*G=YXUI1chtO
zK7xD}0Z9rdFTQQ-r~L61C*jQyP@Nl>(wBv{==r~&#^k=1C@OwilpueJe^NwT0rjf~
zqXDkoIU}X7pCu?vb)0SbJ-tWo)oXp0T2M>@wcHWw15hn@6ald#Xy%l)fa>kj2#CGg
z$!Dzv1P>+=5LdvT$2n^O`YdZeOaYboS!)56r*{z$SHSwSht>ktpFcuC-<f~^qLi23
zi&-s3*T3J)TMN)<Th0ZAf2qDdk8R&u_Wyz!=XXWVh118S{OPr<eRyHrw-)Mj;H$G|
zqwB_n-3aI@U}9&>Al5JMw-!*peyHVI-^~o@HRZ>)4Sd=++t_vlG_$@-NkI~BT3K~&
z4d_%<lZ0DT#QXWfJprA{%93!?h2H61P>^C2b&DQn1gxYKMZKcOe;ENLr6}qZJ<bRy
z>OpC4JaGZxtrIPOX>(3MS_3bAia>ye03yg6!3at#lEMvU|HwyB(jvk>2i{o$W|MyK
zVfh>g@Daca=*G}Y{fQmY$nKHajl&Y&JSO4HNvYmD7uAj`Po~@Y(XZ+E^d7xepV4Ra
z9r`XJ$WnyaU^Wl>Vg1gp0R{o-Mvy@O0*uSsP%|VA0X_nl0Ui+~L=bC$un7As!t8=P
zwxPl{lyiV^5c4^RaT4|@MaamNA^-pY0000000000001(h#9z(Ff=*C}P$>Wa002ov
JPDHLkV1fn|T~Gi3

delta 405
zcmV;G0c!q~2B8BXiBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hmj!{e*sfT
zL_t(|ob8oAO9L?&#t(`*iy-Las`LYh<v1-4(jwNusnF3nD1y55(};_>st9#*5I==d
zagWuzE$Q7o5{rKZgEd7jC(i>fgd{J?FYljt9z{_UMg0fC_b`Zwr|?$|1KxuGf)NOr
zLM&qOO&vt-V?<|%`RqcE4;>_{f0Ib76X<qs^8=uEml0lHK(=b{K6<R@^qTVk$=a0B
zH>pj#4-nU9jlOYx&V2yYTrm2ot&+O{YCAx5c>=j#G5X4bDxPoJkb5ic0U#*!_biPV
zebe$-e;gFt0Fa+LjjhSndUgPBz25fnss1DG@3KuH{oC3CMCV7@rjRa3Yqhgz4ba=1
zM|gEgfT2>zCK6x0yvVwZ{^W2cKQf^YFOMRvj3eHdL9bE#c=1N@bxyD8J<b9M!)0uI
zKmdRE2-p~0iU0w8M!;hViN7jhilQir@^YvbKOf+jg$@7R00000NkvXXu0mjfh@P^B

diff --git a/assets/images/flags/che.png b/assets/images/flags/che.png
index 427db0fbcedfb9f5799a40fd9c7ca644c5b698f1..eab82b7080c999e2b8cf662f719a21c828ca7041 100644
GIT binary patch
literal 371
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TR~
zr;B4q#hkY{4)QW9@~}9VKl^vONQ*<T|MH|{w@>z;n5w-*fqH=;CUw`bE6LUZ4(a?e
z7@`=$?F*MOdojEWw#aj+6MW2hO5d6NOYP#8Xoin4p<6MB)-g}}yN>V1)PH-KR{Yp>
zx4|yo#!;6+cEcn)#m~7@HZZuc=Xl6VsK$Iu{mu32b6Vs9uN`_^4@_!r^IG_FD|j;`
zGI0ny%wRagBB0h_z}Uj6;KPu3o%O?)c=6f;`C<-7#ow`giG0kN#rUFO>KD$L`HNdv
z4XhHJe;v?x*rk6vJYc^0X{NA4stq4Sr|e($`O(k&>MQOWGG#Cx@qf63@uzE#y2gGU
r*$dx$h4Rpa&Yl+ng&hM!L)B#d`8PhzpXs{vCy4Lq>gTe~DWM4f0E3BP

delta 847
zcmV-V1F-z_0@ns1iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0008)Nkl<Zcmd5=&1(}u6n{IrNhmh`ga}n?
zEglLUdniH=MG*gj{te!}=_yC=UOjm4Ur@x-n^fClB7qR2rXrDiki=|4c6WTgA+zkR
ziRP=YKN#NInKzSP-n{vELllNFf2w4&Spg}fG{)JCC?aV8pS~g>Ma0%8rT{WrjH9C?
zqup*B`}_NJb#<lMpf?%~qf{!%$RDHK-CZ@t`ue)m_O@*sOG`^qx1%5G4i66{#z8&m
zg5zpEm&;K;pZAWBkLAh93C8e(L_yH(_xp)dDrF7^1H*9~Bb`ozwE98le~Cmw*6Vfp
z7ovT%KB=8$S(0^cV`IZ*>0Vx5I)-5=7ZbBLE0s#}ZS(tQuDC}r0JHx3?Dm5_R-N<n
zbJt=8t{3b@5f_pGxbW<mJc};Ag>K-OGAU*Va<XWFNbNl&v9jWS+aEvByuc!a^ob&f
zX-;gtenZxsyGkEiSE&5te-X`tTCGN_tE-BaKlNDU6f-bMpOc^%qtoelT8}l+wY4?h
zqbf!bu)OKgG`RKnDP>+{Lv=bnfduRK--Q>`uUA>>yg#K`por?@ZW@@px`V_<4jyS2
z=@pt4v7UP1uk8t20VO8xPj0J4&W}o{&e{rlFxu|5TQn{7Z2Lqve>XRYTGtZ~@cZnP
zzMO^Q4KcaseKeU&hCLcbz<IpC`y2k;C(=zq-*NTLI<~-t8o<=6oB6@P0nLk_FQ5DR
zEDI-!X0s^^g@V#mjDqzdE+zJ-`EN@>;AGM%kw5iFGbm=@ttouga{}fSi$&KX`Hf-%
zaN!)zWp9G43?+9gf30e@YVo-*5DLMoAM|nI5lqeySNbv$9V2QRgtkS0(==tb+jVw!
zc91WDsOKM{Ow{Ab0lT};9c)frl|<ozdu-B$L<!apZM#}uUS3x6;^M;YF|@5Nu!Y>-
z-d1Bl;#=D?$$lo2>6Odn0XWexT^<Gh!65o*pudL?5+d3*CF+qO@^~R=%!35%Mm;=e
Z`~hi4)I5wXPz?Y8002ovPDHLkV1in2kIw)A

diff --git a/assets/images/flags/chl.png b/assets/images/flags/chl.png
index 73a38f406dcf90e3faebc0be75ad62082c76c2a5..4328f0d081e2e142649ba1dc3254e3176a98dd93 100644
GIT binary patch
literal 753
zcmV<N0uKF&P)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h00009a7bBm000XU
z000XU0RWnu7ytkQqe(<TRCt{2n#*ewQ544KAG>s+sNf4x>jP^SqM&G(y3v(&(~a4<
zutfwZ;=-lY*b=o=v5LV~ixcbO!qi87prX-2lgyDj&>D@C2PQd9=J$gGA-T!o`|dg4
z+)F$U000000000000000AW`(}xG9?D+n}op11tv60o7mx1)V#B4xX5lzT=Z*fK@VJ
zWHcwkqd5$)N(T6^zRHXFFBo7I4A^-nBVi~}?LM60G1Ru%fYivGtdJU>!vNc61G2N9
zRt<PE`w;_d8x7ceU|b5taMb|!dTZY}Ct=$}15TcOEElij{#j$01^FBIUfg>3TU<rN
z5GTyKU1M_j+PsuXzju10l)_N1->|a2_Z9}kQES{BJ@r5q-sT$?|K0naGI07KmvObI
zXXbC%la6+>d*rN#+xK3}rhV!9&JtGt#<F9sBHS!rS}Mj0?>?(G?|U%d{|wmHKOx1k
zr=N<MUkYV={{#lu7InbTg=aO#k6S|r1g$Y(I{V=dv4c1HsLF9`Fd%5Y0q*d%Tqsop
z?MgtGAIi2ga47TFKu~r>2%k&ML;~l36lC!H(~8f}3}xlp_vL8KU}^>fY?BSR|7bC~
ze%^oVZtR-gBX{Jv|5>J{7csy#(SVJ6({kzR%jk4mYpq-3*1GR7f&%^(;de_0w5t3y
z5R@2T^@XAXtiD)`AlrRK23QOrgsUOO6Uu9u235t!0I%hn4+D&Dhhu=jfJA4EM+SHp
zpuG!)4$v1u7(x1CkO3xnMF<-VP~U|@2j~kSj39k6$N-bPB7_YFsP96d1N4OuMv%T3
zWPnLt5yA!o)OVrK0s2A+BS>EiGQcFS2w{T(>bp?r0DU2Z5u`5$8DNrEHA5Hx00000
j000000002M>n45yf861J?TPT900000NkvXXu0mjf=Z;M@

literal 351
zcmeAS@N?(olHy`uVBq!ia0vp^T0ktt!3-q7rQ00=QjEnx?oJHr&dIz4a#+$GeH|GX
zHuiJ>Nn{1`!vlOmTp28viF&Pl_3p?2|Nr@1R<qbFXE0xy(RGT!Vwri$&Xs!}zI^wc
z!E9+z<>B9d{>3#N_bol>TXK-udbyCrY*qI~FYZ14^Y+bA9j)Vf+BdBYZ`m4M*OmvG
zou@x_6OfWE3GxdDnv4@LM7BN80xIMz@Q5sCVBk9p!i>lBSEK+1Gdx`!LoEE?p5M-O
zz<|f~qDb_+!m6+T>(h-S_DFo<s5l+FMW!W$bw|+_udBYZ-z%r`ESb}y&=;_Bi(!;!
z%IebC=Q<?}KkGiU>@^kYJ@1h5rq^#}W#nhqT}!_`J|q5;^~>c&B5PQ9AF@r54V9B-
S6Hx=&$>8bg=d#Wzp$Pz4<(P2*

diff --git a/assets/images/flags/chn.png b/assets/images/flags/chn.png
index 7a03dd26ea68bb9b9121578c4ed78fff0879012e..d326f7afa3ec0efc90e70d8bd2bd9a143d529503 100644
GIT binary patch
literal 840
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|V19
zPZ!6KiaBp*?9LVm6ghT$#tOms6%z8@Tun(eETTRhI~)VKn_K&jEfLumv1Up}dH~B>
zvuxF-wR3xWJ33kwqB>ibYAAIW)*n%CKRJoFa>m^=Rq5~k{(W%Z>ARbW&wjtVQ~XYa
z6KFXcIE0)~Rhl#{vw`v4d#1w-?Tmr>g`RoY2d-|tv^4Y{YuELL<-3=*-`>kDGM_Oy
zdI`VnrGC4Y(d)nb+fY)xxP0Lw!vm_9{;s|B#6imZkf{BBHk+HOw)eI7zM3YN^I0#b
zkXIsduA4FI4b@8tcP%bttYz%?3flVQucGK$M)~SXO|zQWLrd7^#4G-l^mu&e)SLXe
z9l^Wqyo^2YM=Igy=4&UnESeDJeW~K(_U+dsKYV+zh0*NXt7Y!yp80$p@%_salV_i9
zobl5zVMXk(yY{&ay}5d)58rxnWozynX2t*e8Mm7+|NATEW77RC4qG?u{Q2o^RPUXN
z)b=mCta+u~GY_0hz4Umlad_3@#Q$5fZ)}y?`SH`QFFghprhS(hqGBSIYwd3B_z~ad
zdHq_YxI?S?fkz?HyQcc+I8|hO&wo4doX+=uAGnSIRo++l`(}20&F`~CMIRn;U20g^
z*P4CEWq--K!@r%iBbeWn{;lTTb$jaBv;4(E^K`qmwth{jx0>Ykch1w4!~+)U4`(*b
z$(>$zHP=2Y!+-nI#K*VxJdMcPe5k)jXkPRT>)_>=-|xM&*3ypm#+<)tmeY1mxoUsR
zvtpZu{&(;9e4gUsKR#vdkL-J@ceH^EWY!I{<al*|okuR&meaETXI^VCQh%7krMWQY
zc7W4E2?H6o`SCH#s}jHbJZhX^vc_(I1>24dzy2gi1#m7uufL4(X#t4y;1MTJfy9Ga
z(Ju1?`vsD?Kk2iX9yls4lGx68FMMGI^B-=-Z3_RB0+?fJ90kirS9t2R7z;cJ0vQup
Zj>J!$H*^2%Wk+g2;-0R4F6*2UngF69goFS9

delta 852
zcmV-a1FQVV2HXZAiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0008<Nkl<Zcmd5<Jx?1!5S_g{V@zU<F)~Vp
z<SIoXMWRVTL6Ov{sM4j$-=IvFK0Osp(x;$7NdZ*^h{ghmCJDxlKk(PxZRRbR%iduF
zE^OVC&O0|dJNxeKhj)qMP@|shf9-7trPf-Fiy84acKkhU9jkN_u@Nx?kl{ydZf>ep
ztEJZ0*Xi)^(A2@M*XycUt?I;wQKeEbIf})imiTVBt8%%VmU^^<Z)0OaBM<!W*?Gl2
zIy$1`<Ku8^YfJC$?jlEM69qxH-|uI#*{nMp4wdiwDxc4TwCNCbCX>-ue^*y@7m{tn
zerTNMd7ABTd3ibDGB`Lm@Rd?VVq*60#l^+kPUGZ+U)LxdIDfbL;whK@-rind<_1ge
zbUGc__mZ5e1XO(6qZwe0N6*DH#ET<do>Oiz(pwE_{<$CXIgd0Ae>yY^*qrX{5hNF0
z4r9LF50Bbk=ZvzCUkzy5f50L{>4^iASZt6hz3-A&HVcmOuLo4$nWyHLY%GcYYr4wT
zYBeep3O9=^>XcWx*w^1P6m}Fn`Or4+zdtU}^|wqc$)M`ew811JPGcp({QUDdOSMlq
znt$fss>ie_yy??4(QdcHh|jnnnTr4xP!do)=qQ>dmX?;VpWkr6e~(O98@{!&LyM4X
zPZ)ankXgX6k-xi#VpiLe4R6ADqvR|Wl0Zf~k_KBr8X=<{5iONUlr})TTN{2F0r7a%
zM~Y6gkY)`z<I2f8wZMTIFp3K6w4u>xXj@Uk+CG$|1^8#O6*WVT<3FVgHYcMfU%<j<
zvl+0Y=adqF3!k0>e;#^})v?Rn+1Z)5xVY%@Wy|3kp_vLn5U7=vl~@wg@vYOey}Z06
zyI$I%UTndrT*;g$d6N%$4-J_QP9y<{%7(9*C@Kbg`|I;<v&+H#a=F|)Jw5IA81VJ}
z0e*Q${r>*Gu~G6>*VNm#Jcva*i5I|!Sm~FA8ZZ}JEsUB*D#;Nar~a!y@z$ls<kKVa
ej`AhzBm4zv>%4mj(7M6^0000<MNUMnLSTZZ^PRZ>

diff --git a/assets/images/flags/col.png b/assets/images/flags/col.png
index 9a0fc6ac169953ac83b00dbcdef14529a6242e0f..798cd637404bfaeafc120824f91bf4a9c2531ed4 100644
GIT binary patch
literal 381
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TSJ
zr;B4q#hkZy4t5@K5OBV@&vMl<!;%er3zSxKCMF)tXseRfV)WFN<%#148UX<kuGg==
ztMX-L3o%RJ(O~OYw<DEVk8MftjW~z6jxfhc!yJdR*2*zF9m_ZDZP+8Qw&_#SjfPp}
zZaX9d{1dAgD;1+ypB~-7X!^dVz))e{p>Ir|oVIYC>P}?Nx+nQC$-$=eE$frk4ACj#
zhuN;|F+Oy(p@Qo+_X+Nc_oE!YSKhK+pLw8RGOq+PAG2HdolT7V%$GFxfb7{0Hsc&n
zM?2$3k$WJ=M1w6#zxVgAW7_(%*QUG@8#Xg0A4og!qAS`g!BAl?lI7ok8fODFZWEs%
sz9=*xjz@aK^SkwR>bx*-Gpw2al)184!*<&}c|DMzr>mdKI;Vst0Jg%72><{9

literal 217
zcmeAS@N?(olHy`uVBq!ia0vp^T0ktt!3-q7rQ00=QjEnx?oJHr&dIz4a#+$GeH|GX
zHuiJ>Nn{1`B?5dxT>qbCcy)kV)V7Afpj}Y6VY{&D2?0HzWXq&w4}cU$NswRge+Xc>
z*St3pD8^af5n0T@z;_sg8IR|$NC66(dAc};Sops^wUd{@fQQ-e`PF~YyDu_a=kO4`
zrjxic>cIMoRt(oUcjzfZnLnsvxX!&NXraqgsb|pwjmIy3SPC?O!PC{xWt~$(69A0L
BN8tbf

diff --git a/assets/images/flags/czk.png b/assets/images/flags/czk.png
index a6c13a7738cb9601c3f9279ec6e887dd752ac6cf..e4578e86c30c4fea54b712a01db32c9a760e2574 100644
GIT binary patch
delta 822
zcmV-61Ihf82fhX&iBL{Q4GJ0x0000DNk~Le0001B0001B2nGNE0OFW;IFTV2e**AH
zL_t(|ob8xRNK|1IhHpU-ErN(zwF_!l%UaBQGY*s1_%r@cSWsqdD%(hl><5dWMMVTg
zP~fU2qD5w<sZo|1_9q&eqnUo`Du|#(5Crwcb-duNO>pl0&ilaG-|sy4Y#z@egb+dq
zA%qY@2qA<JLI@#56%8l*FgP-ef4rUJ*#EzSe+n>_9Vpq|g&Vg=Fg`;Gc?ki*9B%5v
z%i&MF1S=%KpY*QBxY9a=4>PkAVFd&PQ{UK&-q%x<V1)$CU&GFYYnbLW<Rt_Iv!~%1
zy89=24OU2iKSk9YIN$OHqf@+wyo7*YY7ad{=ZgtmgB23sPqL~Lr!EZQfBnQ~im(C#
zf~h(91Z_QeO0Yr#{7F=G%wNOsgrx{8ARw5Ex*ptlI7SIpNI)=+X9n<gY=$DNkN|&5
z_jcpf{ZUG=LIQ$e>YkGo;E(py?MVyJp1QrT2+*3ky)X$di&FP<C8;}<0*s>69a;fq
zQR?m)_$a<8wE~ResXGz^e~iPaJ5mCSpSr6%arW{nXHs|M1Q^FscVq<^M^bmB1sDfX
zw-W-)qSXB^VyW9H0cIg}=h~xl4bBP3R^-r?P6075662JB<{eG=9$zWGRCNNXDsG}b
zwN-qX>I5VzAK}vWqxcbDA-+g;0&2@!F;ui!e1Yl&B(sIT{%35tfB5p$3D{S54dcm;
z;!9H}AeC*$_2T{b6<a30Fm(dz%dTQFxn6ux>I9^-ZO9eZ;CF1P_>$BKI8u5Mvx#-$
z%TXtwID4<~*T<KLFGih!W0`aKl2|Lg5Oo4F*}Hg<F2SFep1(dc0*+^z@innpd<oDd
zAZp1NE(wTYGKLERfBa-TklG^tU}zKILNZ2F1r(C;Ch<o?n*i66F`^`(uG~+?8^j+5
zZ30|Q#t6HB17$5vCu4+Fz&0hx7-1BkDH$V70yHLLghfCh8LtulXlN6lJsCq%!0F5h
zd^4-WKNMO85JCtcgb+dqA%qY@2qA<J;<?0MTMLdo_s2?+3;+NC07*qoM6N<$g1v%c
AxBvhE

delta 907
zcmV;619bep29pONiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0009hNkl<Zcmc&&J!n%=6h800B&CqpKPWD?
zr7n(Qhc1Q2;^g2~oVqxv9b5!K9J-2vW8Fj?Iuxv%pi2Zn3$2RU+F}W5sagX`Q<5f4
zlf3KsE<KNzM;g;KKObDqdH0=rfBW^j=iQupiOOMAYBMu4CahA*I4-6_Gu`q38Ed+%
z>4|lSX@CqjBODGJ>2%r{85yDF<z@X2{_gIs5sgNb=O3ft;bA>TPfw4M_*^b$bar+s
zd5>}E8yg!_m<RpnbI&XO%E}6@uCCgXlap$Gejan!ZlWM)<@0%eM@NTMe<&1;VzFq1
zLLrdWe-OUk?^nrWlB&TwM*Ldid_JFI-|p@0EwL>vEiDxd!_X2Fv$wXlw*zazD?ga?
zAo}i2g}Gg(c7d0Fb7ErR0=vaXBvR73!P1-i`}?Ml1RlPK(8Z}I^ewtW?EtGd$g5`|
z4e@Ns3(hIa8@%;5MdLSTf9d}0Yud{kP^;nQWY#j^>B2`Ezcowmzs9K5z()w{5JeJK
z8vu2$-F?<lbrXpM$?oA0#aCX-U{QDO&1Y&hy1Kd?PBksP7f^Tl@hh5sw4nWFA(P42
z;@3q~F!%P0PKRcx+uhw=uBaqzJ!qA>ny4h~Y0zwSebhiCf5$0(e|wtN_BN>@IDgJr
zZHFkf0y;x=<7(n3-TC!_LZw4$BxJQ6qJ4dRl%SL2>|ur;Y`&vQnLpHMK)gU8P_Ae_
zxE}vbH+DWXTtxxI<Ne)H^u!-hGgb6LYFw$TYX($&zV@;uBmorEfL0W&M@L7i4rrx{
zf>bJ{*4NjyulG@~f38-Pv|2?0ewo~g>ZQjq!yDKR72V*i$>zdY`&v;xfY}=x8zs(y
zEeUFuiUM2F7N6ltoR%m|RN3K<tuG#r`}nYBA{E@FAN=Fe!+khIUP&?Gox>aJhQwmL
zWmzhl%@&7-hHzd2QQN7Wn5fO21(rL{19E(H)fSB>Mx~sEVMTNIAH`<H4+ewUE-o(S
z4j2+E4Y9BT0|R<4SUgKClg#(`_aDS!u>v^J(Q&yFoC^c*rGY#jT}YVTca<&~JeL<H
h9djXpxJnlff`1s`Cmiv7H!}bL002ovPDHLkV1f$wrN#gN

diff --git a/assets/images/flags/deu.png b/assets/images/flags/deu.png
index 95b88a0ea0984caf47534eaf9f175e4cf91e71e2..9bebd76f30c61842f4ad37a208786446701249b3 100644
GIT binary patch
literal 370
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TRq
zr;B4q#hkZSH}<j^@;C>k2Tyf2Usxesnz~DiO=iwL_8SbIo!N{)?GUio;%oM=z0VpM
zw4x0dr!ctf-;v5($K<j7!;XeMg2%Z}%}!*_n%7gnsc`SmW2R4TGWr_%ZM-WgjSi_c
zRB-ompO7xxvtW;;*@9;$Ij$dPezAAfwQM<#gmiAT2Hl2>`gu1SR2xdTZ?it>%>e7X
z@j0bsJHsR09PtU}i}r$aCY+xvc#o-L`-WJDdmZ1JKBe7gu=RJVsJCtSZDPB=QlVkC
z?hJ-?5QoVzE{VROr;zVb?O17?b6~Ezat*6Me&TMRQ{S>aJ-dOid|uB7QHMRPZ-GwT
qB0k0ZFxwrVQ@=k(_?O|e{YUnuyXJ*KVZWF`LE!1?=d#Wzp$P#09f)B7

delta 694
zcmV;n0!jVy0>1?ziBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP00071Nkl<ZcmdT|%c>$V5Uq5#ID+B}TzbV{
za3#3#C;WzCHZ#BA|M&&7b1Nv!Mpq(omx2%Q(rwd^Or2<&*wfC;GWS4P)k!5DE9qDj
zqGyOAnNFt;w3Jf3@+lC<^#8|Lf5*^H&Nm~b05U9MJRXbd^(qE~0j*Xm)d%~0K8xLM
zCv!iH`u)C|quFdq?H>ezs8lLa_hTH|Mx&9$JZMLoIj^?Y>osjQn{+an$k}X$IZ~4-
z2)bbymdfR_8%2?b<5<*cHIP<c2)k4&$<ygXe?xwZw*S}9^E}CR+G@2Df7Z!zxr~Jn
z_c@roI~)!xZ0=d4C9>z>ePQtsNcF*?cQ}gJA8%w2-gxy~Ud03tj&9{W<&tGEIXPrG
z@Df62M6rp<G8~Ub(x*p86mL0MhI+l8aq`TL?_?K#ete|WYE{`!M1PQ7STq_q&y}r~
zUT;{Np@`}YYcoFI@r0wme@6UqJhj_xvJD8Hj_A`{-~38eq5Z3k^ZlMx(LGa9u#G5v
zqbw)ZnYFb*LJfdumYLgz%jF`?h$_}LCM6C2XEGzImL6pWSq46uQf;e<asifZx7$QY
zdM8Veru5D=T*6Bavhu08W9=Od2ak&_2V22R{b0Y^9%gZdeT5~1f1RHr?`uN)V!Z3R
z()azi*Xzae`5Z*k?7(NDDK|zO?vMurT)HX^;fZhT;zL8s_J^;pZBEOSUMv>DjiG(D
zz!$pP?W(z;@vMEBWZ3C+Zu|W{0w;Qu%SFg84Dy!-`uTAo;pF>@E*Wx{7Y@C+kbqy&
c#e>FgB@n_Wbe`jN3;+NC07*qoM6N<$f{4mSssI20

diff --git a/assets/images/flags/dnk.png b/assets/images/flags/dnk.png
index 69dd1b2b8d6117df195668916b901d61126123d6..e02d42bfefa7c501c7e03b7dd44f4828a1f129b4 100644
GIT binary patch
delta 375
zcmZ3;*37Kf8Q|y6%O%Cdz`(%k>ERLtq!U1xgAGVNno({sQBk~}(bUt$F{EP7+gskN
zm;*Un1J$4XQCE(UX<R?oZ^45=wUt{B)_JYppR5Gb0|5>0hLXk0ufFsy`~LoSzHoyG
zgX9N3RgEbNE-{-tyx4MEB!!1JIpZd?PExX9_G|-9B@aPYZlz<qhI-dTeX}y&Sx=Ig
z`}<r8|B3gTw+GdmSX!|xn4|LE_hgZ9Sd$xn#{aGhEsu?tEm&<j^Q)>n$AO!*CQJn^
z4=$!^e`yeFcpDyJlyF~gDa%`HXMT(G#=bu|4*b&Ak=*dU<JT3TlJA}C^y&_r?=EB#
zU<xpD;FMBb@s+{X!sMY5tEBUBiCf<ox+5ZvoKo}Yk_d8H^V)KY?}9t!Du#OB=X&y<
zeQ#V;!gb(uw+6c;`^><mTb`FZjZ7XEO(~xupPXU;TZ11K0t`p=KeF3#{F172xsnYM
N^mO%eS?83{1OP>Fjtu|+

delta 792
zcmV+z1LypM1EB^XiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0008ENkl<ZcmdT|KdTx+5TCs}l?RIdh$Jag
zBt?o;v9+)dqzFig_Yv|D(wHV`(gt2WKq~9>wt}Vz(KI5y7fC?yPf$D$?`|`*xW{^E
zas(6h{a~5d-P!Ty?B47jfJ3ljf2G-M8YDUA?3B%sVyO0i7;7lf2-yb21c(e4R<GCD
zYPDk3Y886Dp6DZeu~@LtXv9N*3@Vk1@R7}CxwN-!n_XO7aM@4esI6A3aq>g$)Ta8C
zdcWU?!C>Gw8V%lRwaACB5+#DB<2bQIB4O@!JLbABOQljoTKpjCu~>}Hf9G@f9l~Rz
z9@WmWERMRL%jG<jUbowI8Dk>Efb7l5WD<Y-+5XBHlpq4`Tt0;dSFeKlx7SxNdGj95
z1!Q*pvYL5_s@rb2Jqr~Iy@63Q7&9V~{2yQ(N;rEa&Z0+kLw4YrGC?z_oD9$$^bwK_
zh|(ek%`ltIKxU7CD1GIie;Ly0bihgLsb8<xzSOlQn#p8>h*EkI3l@_uJpS@AvJ*3t
zI;h`!aR~*?t!KsaXMrk+$_1M!-G{%0l}?HBuW)P9lO-D{6*$-5BRim}S0m{DT!FV-
z!MP!4J0P0R=i$?%Cy^b5_xd02KAd&0C(Q1yAs&w(MpQ>o@G!pze+gf^9Z7{e<I0n@
zwx9zwK}1xt)(y+$lB*FFtaUt;(9WbrR7^cxGe9$7YC7EO@dD-#heOZja08kE8Q$O>
z&cmrEvi#t3htir(rxxz}1}z2k=tugg<)L2AXkE#}MA%2zR)w^s@uq3=&1U14%VoMR
z5m7(bLXoJCjXMmtZi54Cyt)cW1s!kEWJ8jQ+P=5lNIjWM3fbv&>@7mt%0jjzi^Zbw
zMUv{$7D+mVLSZ`|k9Wig_SfZO2p$Z=j|Q^7e~>W3ea9XdLXQ^)oOqBRyJHUz62AZ~
W*t!&Ijc_3V0000<MNUMnLSTYXd~uin

diff --git a/assets/images/flags/egy.png b/assets/images/flags/egy.png
index 062ee21cffb817a2175fc63e6feeffc3a923ecf2..692e7de78e0cd84191acd3bb5d53bb717fb0182b 100644
GIT binary patch
literal 553
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|Vo2
zPZ!6KiaBp*Z1g%DAky~Uxn#mGt$R;x8v7q)@A#p&E=XN4%3YjYy-;NJIw@XFkw6aj
zybKu^k*<&a#rygBT5j_^{D0oE{*nOD0tDD}D7iqZWEmryOKx+b!;ywH;V}x#Ol&K5
zUzo|TSKu7irEW*IBY(OC`Xm(IJEb#yak9|%&}Wkr_^j<@k<_q<doJe%?uTm>_DZBU
zoLSHD@J2Cn*QTOXuY8z!G`8}ZNid6jR$ia}c-g9-F8^$9N(P)i_D+4_%3nFrAl?J*
zkGF&D`Prsa6|!40c3)lh|JKL-q4Ap&AM>oZF0lXn%?*WYKW07pZYpiC;0S}-1NAGi
zK^vOBED}#~s6WN|uudw#-+kYnTi>64ZM=S2_g>S#%MIJRW9uvTeEt4;?y`CF<^Fsv
z>c4*B-2al<eKm!}H|B(YUq1i&ORKp{?_aX5>G->l@oLSb85hcGtLItm7qyDr{`}><
zlKfv>>)!P(ef@d&tsU1dBqg*mrk>|DFkZgKnAhOI7Tz|-Hpa;HI~>>~Kw&fk7)Hmy
tVH8p4$|22mf(W7L^Sp@Q2eLSvA2IJ(b8=DX<9DSX2~Sr)mvv4FO#mrU=(hj>

literal 431
zcmeAS@N?(olHy`uVBq!ia0vp^T0ktt!3-q7rQ00=QjEnx?oJHr&dIz4a#+$GeH|GX
zHuiJ>Nn{1`>jHd2T+a!ro#j<N%cp!VG5>yI{>_N!JF%(%LEzul57)ncdHCY`!gmjM
zzJId+{gVTCkCtBA<ay^v@twnkw-4rA-yQej#^M(@7XAD8_ujFJmp7L^IMw*-){1+_
zDt~;u_2Kc(H+NUPy}$0m;~hUg-3bc|3k?kp3UCkfbqw-%1KJM+SxK|D0x7MMAirR+
zrNj^nMk_wV0CjN|ctjR6Fz_7)VaDV6D^h@hEuJopAr}63&+HUxG7xD^yrQA-TkTXI
z)1>e9jvD7udy2bFM1F~So;zc2xMbVkAm_vU%i8nZ@5oP>7veNWpXohsP;lzZZ>6>&
zHLrHedv7Jt;@@o0b(o>~L*}Hk?Is5ma%SC^cMS})RQs_1n(yte{ya@zmP#GVtm2no
jdAa7{{$StgB|&<=8CeUry$hKKbPt24tDnm{r-UW|um;*(

diff --git a/assets/images/flags/esp.png b/assets/images/flags/esp.png
index 0193a6a44bf2ffce70281ce6137a2301239dcb15..6b12aff49d000a6dfdc2dec326ef044842ad74aa 100644
GIT binary patch
literal 1874
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

delta 1084
zcmV-C1jGB%4#Ef_iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000BmNkl<Zcmd5=&2Cdi6#nM^IZkZs*pW*J
z4Xy<#QY#e2qEV$RQdNjeTXhq4*;egabdyy#t<)E2)dvV&R7eOGh=AAxB@zM>NH8G;
z2MY(^II-iO_})9rxn!&x%lQF0f71P=(K$17X8ifgnYnWY*bCOKOioTJBsu47Kbtm1
z@!B6UR`E!s#kNVz1(6YjjgODBQmMq!=``l%=G;EgH#Rod^71lo`C~|>QtlkRy}ex8
zSF2SP3<kOEr*YIaHa5m-9%`pH@4Ql<pP$FV!h$m~F~O&%rf3ewOOyzzfAxA@4+H{g
zqtRfNWwCHLOr+f(Bwg2aZki?zLhBf*AJtCNG%j=}7K_<J+OxB>7GunHF$8-xo6Q=3
zK3ID!8qUB65UgMPb}@BcsMhrKw5<t+T(1Z(Dt;kJATDC{RI!RS)fL$xVoHV2;N_&i
z=b%kUQj-l7#9!W6g`ZIPf5|{35^*<K)1$P@@g6ADLO5;+l1)w;-V>IQMBXf7Eq4Z4
zwu&0#NS_lEIYo3D<#O2xg+d=j^vd6_U_Ldl%`+H^$MJHlh^_BSxHN{2BN~m;dG6}&
z(#wE72<0t?KmJki_2mZi<PMa$jyL@ZhJOuXWH^NXuNXK^xE__Cf4hUAheH^>JcKv5
z7LlFjh?xwhzxf^Z>n!lu9SmHe|9Tb2g(DwN&+i#{_FoTPJk;?xat`^xN%ZyfARHaS
ztC=pW&c?9*sPkTxtKB48C=?DH@KGv=E_MQ`uWCqdufsfh3fFJ_i_O*B;>37@okA2n
z2^*b;T<zv&ii?c_e`NL@u>HIS=VAm}myN*LbqrTc821fqjoiV|KpDBuf56T*LpM4H
za-Lxrdp&v>VqfT}I`_~OdKb<gpGtsN6$DKSo10-&a1(aiLMK7a^Lq5qjYME94Ayr6
z-ThDT<990V<^s4davq;3Pf+U9G0^BnvC)q>a_A)F9oM}*e;s8&kT2nvPnX_RLN>lV
zxzy~Vph@Byjsx-nFG=d7qocvU9_2RSBm8_icw%vJu_jc@jZtDvmlF64^kpJ$1esKU
z(hT?vVk0?HcReZ+Fej7A*bcaF?s>#T<Z!l#Pa@0rBzHn;`Fvgz$(BN);Jx~hzF&BF
zle1#6$Z5$)e{Y?m)z%AXOXF2l<&{dsN+y$(FA-6vd5#LAj%aKMch|*$sz_a3NkvRd
z0bL<U#oNAXTamiBmbr3fW~N#bkhZdrEy=;bL3b{aRF}4bWId5c)K*qj8pH{^>2f<X
z9}HR_4P<@yK|*QmYxl^|@_3<Op9cxDYxnRV@fP`~5*}x81fP@u0000<MNUMnLSTYR
C$@2mL

diff --git a/assets/images/flags/fra.png b/assets/images/flags/fra.png
index 91dce8ff249363df0de2e3ca30d522f1fd706630..2f432f4af94391a874411510c5b75e3b085b0bdb 100644
GIT binary patch
literal 351
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TR=
zr;B4q#hkadZ}T1s;Bh&a%M-|a^wQL&Cq#8*55x<kxOuU5*sQA+0_q2X9aDZkzG=MP
z^4se0e9Nz&m}Tl1{x_80X?i4PGLKR2&{u)De8)KF$EGDU>^}rn^KbmB`bI;kPw80X
zgu^?mdZL#v>|6ZUqUsDYPfC`;X0;@@NrsbTj1!%IN}XE2mLpqp<20jhO*&~;ldj$B
z**r^Pb!W2qm7+Y|=j+~PyneZHp4~5oMmJWe)e|Oa)GA!)a7bp6V(R5G30t5@8RuI$
fGcUw{C+sU3-<p5-*#7acA4tU0)z4*}Q$iB}<m`R*

delta 691
zcmV;k0!;ni0=xwwiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0006}Nkl<ZcmdT|%c>ed5UuVRBZA@!%p%|w
zS0P(>!G-@2+$I0w|M(MT6$D*sHe$@hmEZ#u$6+3ws>T}H$(VRIm%ay@s_v<7kJUXr
zRRwShk<|u+fh4Jv68CH}nl$bIe=}DaQl@MZVj4sSo9Oj=;&?oYPNxIY=~O=>eZSv}
z<#MS~e+=5~wqB!Jttz(nJWmt~1;x*49*uRoT}A8AIE|U>vOb&5U_PJ6{eE8!heKK;
zHi;5J$M^kQKA(4jAP`{~ic+aWr1cMyp3CLbZnuMfAw7rnN9|nKRj9|ce_Aa<8BHdW
zPza%249MPDuh;K>Y`*@)?h`zK)`t@O`u+`Gg59UjFERi9<$eAm%5XFqMJ_7jdWl|?
zkCJ>PJmKy+xQh{WB#+{ma=<c}oFrHddI?D;MClNNW!P@Fz_&+2l-_c%4CQh;;bisJ
zpH8Qkb*qV1DwSK0@`1G(f0`&CSex<ot|z(*Y{XyJQ@vgX+d$4^kGfzn$a#3bCmyx>
zMdBEjBWr6x0X0E;lv&$`!{MMzk80L71|{@mGCiudp3)4k40tu&e(Ny-ix-OpM$+mT
zECDin#vCrfttYbTCb>iDZZ;bilPyU{!3_OKzjr*$<c!W02NUTvf6}%l*p}uyj-$@!
zbJ%LNC|@F?adP1!(HI8<bhnQaJWO4+q=pM$(Bw>#nmK;8J+odc7PTCY$KD0Ow%o{;
zWV6}SYmuZr+agK7(P&&&t5rap;F>OHAt@N7iw4}k79?c)SyquDRlJaJryxOgS%nA2
ZAB{+&z3z1gMF0Q*2>?k&PDHLkV1m3;H;@1T

diff --git a/assets/images/flags/gbr.png b/assets/images/flags/gbr.png
index 151f06db5d24edc7968bac82d4d4745723bc5ea4..8b53f88518fa62d52323e49d268d3beb3aa10e53 100644
GIT binary patch
literal 1944
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

delta 1337
zcmV-91;+ZA54{Q@iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000EiNkl<Zcmd6rUrbw77{I@K+fu8Pmf|}9
z1uBN<o<?L^5^91=co~KTl_j!ellU@O=AMkx$bgV6Qxg@9VQ&P3TO!f9P3D7>@h~II
zqVfQQKx(%z$%>^NO<QXJT)*#(e{;R}_O^6xUG^m>=iGa~^WES5&N<)t1E3Z`FZJ~F
zh?Gl`B;?Z3NupAJleVHF7d5&v7!!iQBs4ZQ3Xw=esH>}ksi`SeN99l`B=~$jN%Lb+
zU0uy=l$V!FTt6O<3l@t-;`P*y-g!J8iR{pOdZ)C@%QG`GFgrV&X=`hfe?~?|$VNs9
zN`Qt$B4IL{&4y$$DWp;<!D_V<H2WZxO(v7Hy1EMaMB9d!3)M3kjS`kK4u>O+dD`ps
zrUXG?E(WAGEG;dSd^{JObGElsCHL-u6K8&hp>HOj5IOKlJq&)dA12GUtKPdq)6ntu
zmj&6empuqaI$ng18Y@Hxe}>@ZW$)E@YaP#ERcd^EJk7=ix?YS%qaspQt(-as;pTnN
z6<dJ0;WrsXF@*rTk2J#{$6H{}#cyGG?_pTG?4_=*!rn8`FeE*ZH^4DvFjqb%8z?q#
zE<i5CLQMQwR5qSI)(zEP^g%I!3jrhsVj-bPNV$<K&>*Jq<a(k4f4Wg=S0Vt{KNx_-
zwZCLwz|_^=0!I<}<WKYP-H+37btzadpmGc@_jpzH)`lIhrF}PCFgu~Of0WsM$`Ayb
z&30>&aYdTtl>1Sk5a7cI+|lWQGdEHoNt=5xA7E+c0ko5bPfw1iejFiHag<^vI@D;{
z_Cn`P?S}}MJdynVe<F6#uUQ~vo?D(E(VO-B=k(fAyH(ed&_6f^;k9^H{V(T_mz9>5
zu48;osX!+tCbB?pM{<GwU#YLJw_#7m36ym`4Ok4iSs%Jnxnp}zTjU~}^?bRzpGAcG
zTzGhrL4(1<!pyxE-rI6`s;H;{_d;Q7doH=#lPOqJ10^LTf9ilwLh(~8_A(2Gr=8&N
z{|SGeKATl<ZFmmDObg_bl~ZRS^0QZ`?G7-#)P&*b5{utjA?M+&XC7s=7@kZNo~{I*
zmBSN@pRezP)<+C1P%D=?{t*h)g9{NB13&3{RoA1vxXO^UZZ*OK=YN3Eg-a?OS~4Gh
z=OB!hY=z#>e@0aS|9R(cw#ms!3a~6Z3Cf0SMS80lcKve$Jva=@c>w$0!+pS7EbsbH
zo}z8u5Zc|{)Bpz$y#c1-uVLl%IaW_Ap6}2xs72r_I>3AbPoQjP?smIj@WcHK@Oob_
z_%@cze1Nwj1Wa8_iGJ+p=<ue%C*B{E=I7^Gy^&MXf2L%65digsc^K1Xz;?S`J`(Xm
z70@vwp@1a7N5A?UMw(uRS_GuAb~hlkz}xl>K;J_(U`OCBul+YEi3LMbhCj17iU+XF
z;^JaD1JbpJQMuTFg#Z%^p5fByO@ftFhda!Tfk42B>%K@sfp7gts7&wlKBPRHg~MTq
zx{S(Ne;Zm|rEpzpZ!j37SS*%uxm<K!BG8PyG9hRNUnbGr3EHvX(Us+t(C|8{#3-kv
ze7~U^<7L{GQBGlH9fj-iM7oq$R#q}wl+!cUMaYEH>0I~w{YheijpMSO$QK6MO9TGA
vaUmgU>+~)eG?y15<hYO^J-v$uF8=~^Ju`Rv4^Dqm00000NkvXXu0mjfn+|lA

diff --git a/assets/images/flags/gha.png b/assets/images/flags/gha.png
index 8d6801e816e465426525c8b78e3ca509e0b7cb19..6e38331bb418390460876eb1e53239ce1b51b499 100644
GIT binary patch
literal 762
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|V0<
zPZ!6KiaBp*SZ9j_iZr~Bzj^&la$0~(YL~7Hw_#J*zHWt%*03f)!RDl;XBz@HaJmE}
zPj6rm?JYcb>X;kb)~ikdBGQHyM<-ezwCPB^t2AeC@qT_jozr)pp85IC_W3(0W}wY*
z@IZ8?q0<cC)r?F%@7SCh92>6do-<(PVcJrjc#QLczKa|8C4DyI13$!h5}O&m#?B~Y
z`ocZ&V$+xIgFFWRSe<VuIMj-#&0+ZKl(I$PZ;}CXPyImwGiN=8_eURj?U~Q_^zh*T
z+kVGIAxwF5^H06qIIT+V9+$<2-D>RLuU!57A?U#Jn*pn?dI`#>D}AlmBWz%LZ<5#2
zpd)t+%Wnl_vdBoU)aSOad*mmr)!MMWc;c08@1xrj<LhS@FXpvWeDHg+$FlWXpZvR8
zfBb3i!J?1<+iLR{fBm-mO?j66bYrGZaXRbYm83ks_G*_CztrtVtIqguxjO&2C1a)j
zwDbK+mK*DrUgwu;|8}kW_M~sc7TQ2JZ`vW?S+!1cYpCu1_#3NVPQBdtr)uH+{hygW
zF-Bk7uyxKQjuX`z_f!jf6HU0D@jNn$(fIo9TGli7B<|gPzo)^tUAmTaj_sv@^P8tI
z)tx&owDr2!?-%>31XthRoc$*1ZH>43gPUj1&5GamEiEPAV}JZHqso<<j>)cvK6mz2
z?OQ5rV7BW@-7f2_PgO;K7t|Vyo?5pgY|TyssTI$owHUj(C+6G_(oH+C{kZi1r5_$=
z>WKTZ9Syxw=Vtx>5=TX~zD}OQ|K0c2ZJl2j<S?nM^+jG3ufT*?c?K*?I6mw;Dw*aW
z&UkCL!9$i8;z|oyUy3(NPWUCx^H7BG6_J7^Cs^Uh2E>?Q^pV{-vtHogW#d>7-_zC4
JWt~$(6980(P;&qP

literal 432
zcmeAS@N?(olHy`uVBq!ia0vp^T0ktt!3-q7rQ00=QjEnx?oJHr&dIz4a#+$GeH|GX
zHuiJ>Nn{1`O9OmDT+a!ro#j)z8>DzINb$Ol!r#kc|F4Oy=;ix!QSA2xvF~Taew`O{
zw`TisPHaXUubnZgsSYbU8{?0&Vq2#P$Vq~%`gK9<^C?jcMP?y>rvH~j|6dW?JyRgs
zi~aT%q0nB#us%bF8vUSdLxxNThAan$Y<r*<hrNLlfRuVkkYDhBq5wm4*z}t~Et~}&
zk;M!Qe1}1p@p%4<6rkWlPZ!4!3;(O9PK!Akh_oi^stT5BcI|52R{7uEWJ7A_)Ppl6
zey~N}O#j=bWUXJyp*Q0m$Ao+QG3SdvUY%ga_ebFaklth~$0g|M)FRV9Rk!w-=d9FB
zq5TCBH-nCSUZm6gr<e2El+e=4S45Aoy*z%Q?61L>*ltb__vSfin$JCxm@ch<xqQCt
ilKLj@WiIJUymVJQPL<qs^>PN#aSWcWelF{r5}E+EySQ}#

diff --git a/assets/images/flags/gtm.png b/assets/images/flags/gtm.png
index 2083ad806201dab8c664d23f312a03005a84ae58..8841a352a0b0659868ef8e059b3c4a016305d8fb 100644
GIT binary patch
literal 1691
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

literal 477
zcmV<30V4j1P)<h;3K|Lk000e1NJLTq001fg000^Y1^@s6!MV=%00001b5ch_0Itp)
z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0dh%1K~z{r?UqkV
z0znvuf4gd{tC>O&YKJHyAp%LSdG`zS8R`?+7w8gQ>e3;^z)R3SBPk`+wlFO=(sFIv
z7PoC3f=&rDfzUjcci8zcJp0Zt3^@N4fmDY~wrG*zuT1#d*jQa~>M(TPOss8HoH{If
z>xpkak<^igi?W7`vWA(cWeqM2!+b~I>N{hWFcH01737X~U>F+e^<!-3v(OD4hZlJ?
z)jN`+gNbP6<{TcE1j}e3BA1bjx=~h&5bf1ZE(;_@2es(emRB2Bn46BnB}MHoA|}0t
zJ)t7t4?*ob41$y}>1a?6<MFwLw%UZIhtSm{sNL4k?mj`5{Pxe#pIK^AK@gB$&fs8o
z6W7%eJfSo`f+@VHuQ)60Bej^eGxYsn($T4K42k3lPOCYzwI-BS30hCV{LB(&V{wwA
zgXyEBr)%&^KA5KITvGwxIGGu-M~Uq9L$tSf%ro{wk_Ajf{}L|B8ZOG=Fah`kF#3bQ
T;$;@`00000NkvXXu0mjf<a*9Q

diff --git a/assets/images/flags/hkg.png b/assets/images/flags/hkg.png
index 85925604ee0b25a7debd69a34f0e8dcc38ea6fad..8c4cd78ae538aedc49a5d0dcd3d9fdd3f67583b1 100644
GIT binary patch
literal 2007
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

delta 1016
zcmV<U0|)%q5B~=tiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000A&Nkl<Zcmd5=y-!n76hH6vRX)<vmPQ;*
z3Sp7KL=zGg8$)88ScnM&3=VDvcfpAX^bbItNtA&>7MR2^;DEwp08I!%EDo4{mwwpS
z_dLIA@AL5}YWq6$m)xB5?mO@Hf7f%)J@<p?ER<SpW@bi(G)+^v$fib9?e_opR<%jh
zVQUc+02yw|@bIvb&1RLs!9m*I-WKnmCzDC#;NZY?{4wh9?-yf)LLpPy7YYTXqoc!=
z@9`b_qS2^{anO%G`?yly+1a7p-CbjBY|LC*TEZBHohS%;N~Mywt*y;de=e65UDp-A
z-w)E_2cdhtUNezM(BI(vM(Y1-r)iqWy3yU;U13?-+S<|;MG-D0X77o`VwYZ}_V)O(
zms$f~A6&UPz*1jdU$1Da!1XG75&6+7B!OOzo`<7Y!GkJ$Ij20-Vz6^ksl|aw2x$>T
z5>pf48y%<1v-70-1LPL*e|Vf^^{|LymXk|_CLc4&=hS&;gp6#O+#(PNSe#si-sv^p
z=mh1KUyFY2YJ}V(m&+Ma*T@Af4O}O+D<HgA{P13o>+Bk#;>Qj0a|(bs-sRU;C^`R(
z>P0XZL_PmQ6bZ{km+A$GA=LW!Bhq6>f>8PRh$`HIkEY1Tq)CT9e>o-oP<-wQH3|`W
znXvUDzqTqo29oVVQ99-4-0~uonfQ<CNnwNj^ukLzeY;9-;3`K!5`^H{pPxTbczRa!
z8JUdGkpjo}Zd2mvw9p%YEKgRBq7;yq>PG(EifAZHAPk9cgD`RwsgP<QKPAqUr*Jq-
zjiP<%7JG1xC(r~1f9^kI!o7ktau$7!0?s>E@EZk6k*`YTci7XES$H8N>M15#qk!}5
z9(A=MVKyVw@E#@;auS5U-MzsjYlE_H7Re3d9#`z5dDF@(sMfKV`Qm;#u>s-7pJ){0
zUDpC!M+;0=7ao<Yn+-Q4fmAAGaT7U;V?eVuCCvm@CU67ff1!$S%%BznPb6!t7arvU
zn6baVU*TSNv1%f~h0kym4n4@4XAXBPwUd(*jn{n@sbJswLBA+H?1wYt6+#BxIfm2L
z4rz<;Jsyvl&*$~NzCN6nK-946C=)ffv&`-;VW#oXRY)`*xX31XNHlwY)iy76pU)@c
z=H_Oh$dI<OPQey35{ZbhAn`11nPjP_r>A&$cvuD}svehX!MZSTUK+^f>V<^rd{^s|
m!Et$^(ghb1u&Z_PAn^+>4^HWvuBV#-0000<MNUMnLSTaSnB-#s

diff --git a/assets/images/flags/hrv.png b/assets/images/flags/hrv.png
index 9c87c5d0ed8fc429c3918b628d71cf64f49a63fa..43c936b1e35192a76c8946d10727ef6214503818 100644
GIT binary patch
delta 1417
zcmV;41$O$t2#pINiBL{Q4GJ0x0000DNk~Le0001B0001B2nGNE0OFW;IFTV2e+55D
zL_t(|ob8zXQxtU^$N2~L=lZc`>R%wrNvzwuJva@}4uS#&548?O67c~dd;mm}%7Mf@
z$-{&c@DWiPAHavQNo&Bten1^3AsnZ;i*Dx*e0Vpz<mtBIQQ>@fc)w;oGjQL}?(Dwb
z`}usnyHQbu5JCtcgb+dqA%qY@e+VIjOe+GGXfUFmng%q$BK85J0TvoCty^3aXFxO!
z5d9PeSOMaN2(Sf-7lSjvGW}vo4dLDdyB?yiW6B%QV^y$hPBktlDdFF)zMY1JM{Z(4
zTQ52@GQz)qqa^FO*Q^uMm<eyd)wEQ6yV#9EIY$4#Uyemuf)}w#M`1}ke~j|k8*qHd
zDkPuwA>mw55AE;PoI<Rb^O2sXMOs3=eyny5zx5R~tlNrHOABbglf)mCW02d_rHh(*
z^cFnjJFzQ14=r&^&}mD6Uw&E7Ys{|*i~lh4tJ}lkKa3pbcC2W;jHC`#&vBmd>t?V5
zMlqndaI;C+%l3J=BhS>^e~&kAIVv3MvFXD-ro5FECrk#+FFk9@+qnG%4H(UU>?1c!
zf~|6UF)OJxEUJ=p5XFUiO?fNU9Wfc;-ha)MH@71|14c7oXSv5DSl-8{Q6Ha+i;5Gy
z@@snDxs)tZUhe9HCIfC)RpPg%eK_9L2lwUBNToDfq5-2Ba4RtmfAiW04Z=E4`Ef^n
z6+c<yanQa9HI6md;;J$k@NVvYgZOh@UqfA(I&yCLB?Ol*!j0AwxH5kM4S3QJ++1_m
zB(6Kz6Bbr$N6WHy>%)5a-cCJoTDq~+wcF6DvMVp3w0j6=J8xppQwuf4f!?CE+yzD2
zfm}&{#~}XVLp`W-e{DdUJxi~G0eSRYjJBrb98)q;R^E(x9e<4U{qsRoc873rV<in3
z%NB6`j+3a~(txh?^#3i`vG<GMZt2GSwm#wFkLg8BRaJ<LK&JEQ36SX&dT&}xcmvdo
zxhCQ6UA%zDx!>Jo&iV0@A?Mx?-<xvO^duTU10ui*P}zb4e{4YlXF#SC!IISoRh5Nf
zc<-0E+j<}z!_AF`bv<X_-*TGv7}m9Ostexa42WoeD;4*z_ZS9haBZHUDuTJ$hIKtB
z|2<<)L5^{7U+>Y+ExN@{{2Ab)0W?5m1%NF`*bq*}P)!wv8@;2)SM^U`|A!pyoZ7iX
zx7dk412Xs~e@p{ZRsi@dNK^}2_|{W<6Aol?21GO<P_PuCO(n(wT33sq9o3JbuGTbk
zO*vm|H>`)si=h@Q;}DKm0iRUppB~108>;P!)UBIoKtuyNP9vDNWZVtVj#1CI(}0Ku
z_<T?kEqHLdf7}ds(BB6&QHJXG(SWfG;((_{p9AA%e?X}81E_V|go{6>7coikLUcT9
z^Wc{_8KL3={ZsPY!!5Yme)3VY9Ws56);~i(p3{0@WUVM4eGVDVC?4VWrNyK$KvKMr
zZRPOA%|yT&gL~io$8D$_1D`z>uiG{Wzn@8GfTVcgQVQX7%))R><G(gQJH{6ui!7y3
z_<c-Te*+}Ni+Ecp`W-R`w{F3M-~AB{&~gSpt<;aP+scGr|D-oSQoMLxsl^UQHhy(j
zFi=v2;f7r%1BU877$_;!b3S)0!gETk@avv321tL!i^?|S*jD1q8>#qtwjF-k4EU`x
z&>L^X**Ph2TMO`l@|p1KoU#T;Qy^%7LIZ?9UxgAYK)etVTab7$I0KaF7aYP04G{hm
zN~{3!LP%^u;>F+$P^MpS2rD!|_){pc0>ld;P1F`d2qA<JLI@#*5JCtcgb+eV)Kub6
X%=p|TH2(CN00000NkvXXu0mjfe-xFV

delta 1082
zcmV-A1jYM}3&02=iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000BkNkl<Zcmd5=O=uHA6#jNM{fV|_+e$&i
zW?Pkd5D|*lN`;6&7x542$wS+_5Co5cRZkxEDk>E((vuzp5j29R)fN;@p;+qLB5LV>
zZPJir*Y`G^b+e>uCn@xUmw7w;e|GZidv9jv4Ui9|ko5HQsNCANt*m5IKvb{&Kb}=R
zt?ILNi8)|0BuXR_Q5F^!l$Mqj3=R%D_gJ5qnNdbZM{VDWp{c3K8Kb7A#uoO;WKszR
zgSNQO&v9RSd%Ml!a6k8X#}#@!9>>tokk!%AVfXd*@fenuC==9DsZ?1-e?^6sPN$Vj
zCZkkWS2Jnn4_PlOE3>Dkr|~!VpAq{1+64jun{=zTwl+&`c3@y2qbN#l3}UafwY9Me
zOcHxN2)WTD=T(vf*pbc;xn3nNa(;xdPC%g!Q}i^7VwSH}af5P7Ln)x^C>6Y%0w@w@
z?N+?seE_L<;|Mj><JGx+e?VgxW0&ICJ^2YoPKIE_UPAvq1{v@q%p=N43<=zbbmQ64
zJ!nh5MaA$>d<|A&&isaB$K$y1CW8B|VRSbiL$s$0tHspR6hfhp!^;gl&vHoM)W@fo
z->@H(yP6T&R0%D)6Wg;}F#Pc#+P5s?!iN{=d~ydeAd)Vp{LpuGe_^$VkX(Lz6Q}1t
zL*FqE+>Y|1>g1}K+z9jVdFa+6(A<R8;@9ifR#jD10it*BLIz!pjeubQ&z}Q_4&^#Y
zH%K>bUC;GPKyPj3_52S}PFPxWAq^3UD_6+Hk$gQ|nibC>Dn578=<KBFZ|1xyyeD))
zyhs$iJUKXX2H3k7fB5nR=<d#?fzW$<rBjL_mM3@C^HLxU;WhRull1FFKt$X1XkA?$
zq!Ep-9Qq>2vh&Kz%kvlf-2Xj;47OEgadC4z7h(=IlVkniLqx3;WHAaEu=8lvyB>8X
z(t`)Xkj1Cq4_te67Tbs%Vlj+gy@}{O1+RwW$K>}Fdt7H1e@&ZK`ho_6rr9}%BEjBe
zj4u?w$1#lF5P397WHUUO+?{zTzywP{k}*3w>vD5uJ(mHpo07GJuIo-o#1KUlxXi#h
z11(LK&>fFb0cMSij8Jk}a+}6Afi*@oT$V!5WbM4-j@rP)#6*C;`zoh`ck9RcO6lP(
z&N#0)WUTwgfAHISA#C}1P1Ec|B9So+BNL0on5gA`nTV)GooRA+if0;?u1?EB122(D
zf?F1E|FUgD=(H_!+W!9j<Pt&H3SnDr8yXs%vAE@HVM`=a_4V~jrfH^`6PC;6LU0cZ
z{D%hOdig*?_1`OW$lyD?P_e>+1ltulco6svjE`(#5SuPyEdT%j07*qoM6N<$f_QWN
A{r~^~

diff --git a/assets/images/flags/hun.png b/assets/images/flags/hun.png
index 9722561a8b65934e625e2106dafa76132c2f4a36..397910aa3824250defc881a91dca9bf3418de7be 100644
GIT binary patch
literal 373
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TSF
zr;B4q#hkZSFLtsT@;G0dVru_VJ$C6qhZ$UZLV2pzoM$yvIC%}I5(*r&v-%c&oXO5K
z<7N|Q0@s4C-O^?W913?26){#SpW;3>JCQlfUh<)4Lk0I~)+fCh`WpFdyfgl$v@B<M
zq^l!7!F<u41$!jT6246qoM$h0U}yft-$28501bNpG3<e;!>-ojK&=*W0rz;M3x1#E
zh-W+!T@mAOuj4W6)3X~Gx6kkSAnLFOP0@XM{)D&7U;I47%=jkfAj<~U3%`!?N`C-3
z?J3hIHyyA;ZU7y!9q5o4J%#)upPD|U-DtS$?^eOBa1Tw<_kMPmj~N(x{vVMq)xCC-
SdCev>kf^7tpUXO@geCxO<&RPT

delta 719
zcmV;=0x<pc0@wv1iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0007QNkl<ZcmdT|JC7PM5FUFM5E6)&M9Cql
z^t2R|Dbw&vQl+Cwl`6_FNRtMoNSWd!S|TVR4MOBZg~THw;vtrG=Ckn1td`_T-zQl!
zYma^3jUUVm(Je$$>vp>mQYj_wf7v87Y1{v2uC%0#*+#@PK!%%Wx7%X3+lgkgNu$w7
zk3rvTHexoLsn|b8jYdPSQ7V;`u|FIRBAd-BGmd%aYqeSm>!2Tf_PRzNkH<8bOu|m5
zqk6p_)(CB)An2V=r&K1B@y_S72!cT5^Ldcge-L^ql~U{Vn*N3O9HT$if6n)P#d=sS
zmoF?Y!{IOxLTDEgv-cK@Mf%h4^iM(Rft-N)^|tE0VkPMJ`xl=TxL&dsrJ$4}Bmwcj
zyXWyPUhpMNH=ikw9D~hClH<T7gp7#d5R+qAtyW}SkBBI4IXQ+xp%8KM?Sb-}*W?oZ
zeEl5eayhNv5Usy|M=qiGfA|gWxz_d8n*-}IG*NS4UB=6Mp70d72(#PKWvWyv<Qm|-
zbULj)dUNYPeECQ&0nX!FA9*yoNZ)@vl4~$Au8FLj1p;aSM5D;uHEg$AWqVY!b}=X^
z7K_66sNQ;{8RQuFX$p<5J<17KIGs*8l2%XT3Y2={9PYwf53=eef4O7nFPBT7lP!s(
zV26It?;Q_2Im5ZamO+oN5x2ErY%$;SJhk8NgL=J=d<jIu=$DC!hTM5(cb|B|fm2s4
z(Rkq_o9rRc?Eb6m-sl{bX*n1S4o8NuH4V0qwOUQD1&MEC%Op?LYV|mu&(GjQ*K|1v
zQNbWyG%(-Sf`p8ZB_$OZV#NzdcM1})ODa4V`~~2TsE>#Fbf5qL002ovPDHLkV1lns
BP4@r*

diff --git a/assets/images/flags/idn.png b/assets/images/flags/idn.png
index 52c9659213385314b3c321c31eaace4332e5df9e..d1f01d8b52358d1da592bfcd2abb229923edde2b 100644
GIT binary patch
literal 360
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TR!
zr;B4q#hkZS8#`G7IGhjOpYhjR`9#=*(2XgU&mE;a7FF^CwL*Z!(QDCF@t++Srs~dM
z@M2gVe`hnJKf_D0b=)VUH^v3r<B<;dp3>sY@R2Gaua7go_^DI7?^z>*TC@RU4};(S
z9qG(=Odi`e#5&yT_}26(?MA~+b!8i-4(f>5%fUR#!0_RpaD9V;Vsm1fl|M+-)78&q
Iol`;+0F<nUs{jB1

delta 674
zcmV;T0$u&+0;~lgiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0006(Nkl<Zcmd5=&8q4!5Kh{vS5W)|mmcvI
zTnR3G3E#)}@g>{}y4013oTcCoD6OSGx%1^ZB`x)yv&;u`CQT<fpEJ`W6Cv`DWwKZ-
z9B8GK{A5!ij%okHSjW&#!8RkNe*rQiayFaE$KxT#<FVLoxB4C0x7$q~k4IJbVPZ5I
z={Y)`j$->D2xPrpSNtC1&^Mh<73M)d`pkK`z1!`?e!oxW^SN3smzX0piGrXThGC^v
ztGQ7W$vBQ>v)Ke`{SVQuR4VFvy^8;#IELH5wevhrQ9JE+y9w!Jv)RN_f69Mz5PNqr
znZN}n5@mys8&BlCKO`O;ssE7c9r7ab<4afq3iTI7&!s3Pcy{;&<&-NdgUQJemIEIl
zbVd|OEG)z2auK|GWJK|m3(L@IwK7gthyM9|rrfrgXuI9cdz2H_W@w_Eur?zfdMoxM
zLqy5)gr&enaI`({==FNSe>T8*)oN9H)Dsp1&ZG4`Tkx&^kob(tCu?hg12v#M%B*d}
z{eD-bM>T634<*={Opof&qs$PNftIHHUQY#BdN>>ss{X!(B}misn`*d(LJzVkSKN{I
z&gZj7#g>CqFpqv{e@YLtI743XVWK!k(bfdpV!Z3R%J=<vI2^{Sc-0C-(`;uVqA7Jo
z<nE9L1XQ|e4WWr&Wa2|Z%>K8n&+SH|q4j#b4qgPdWq~d9U@*{gLF1WiiDcOC_g|;e
zDFP?)E|<%YT^JNE4fy$eA>kC?m0dCvE-xJM;X(p-Wfu>OziJI8Xh{@s+W-In07*qo
IM6N<$f|&p~Z~y=R

diff --git a/assets/images/flags/irn.png b/assets/images/flags/irn.png
index 151a039194fca308ba1f7ec415d6cadeb04737ae..ec59e48c35666557441d538bdc037275e2338606 100644
GIT binary patch
literal 1150
zcmV-^1cCdBP)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h00009a7bBm000XU
z000XU0RWnu7ytkSFiAu~RCt{2nA>j?R}jYi9|00^xJ$@y-~@vZs0B4|K->4;=u2Bv
z?v=_dp#s`UtqLt@+dj2V6|{kd04jJLUx*z$cI>?+n@E12YG&mn<)L|sW{>@S(kQd%
z?1}cw@0^))oJv6u1VIo4K@bE%5ClOG1VIo4LC`=cYvl-*TelbhfTg>@0Kfu(flhHL
z)PNiSXs^O7c7T2$vPePt!9WeL2G3B0EdWqog<0$X{Xk@qg7kxd8ek2cp$J<5puP&T
z*a7;1$RY*l2P2U+AP83owz6(90Dw?;f%OG|_T<CJcf80}w<X++2H<yG`CGqwjVi}a
zQ0dSiDjhydm1D=Lac%rR?<CcX1mHY=Le-B>l55Y9zZg=mv`p>$52$|WvKaf^#(n%w
z_2kFoOg~ls?!Exfxb-#JTek`X=Y>t}2Y*U?=kLdq->^Zf^Jq%i7=)WIP-kjd#>{{7
zt@`&H4PgGe?<K&EiR<LM9#!6XH}2z{-vbcm|D|QBoOoO60;eSIoB!dq`aFyT;8teI
z9v-HdJ$uOa0&0v;Q2p|i{|6AR(A<}osDAw`8N*}kEnCQ&t*Xz*H~@2J&q;9WSFXx4
z2UBwW8UWgV+^3nnd&Os9+&_2zg8F=n15i3}K!WGYl%%k-?==_J1mHEA(&iS5@wno_
zgX;4!4uCy8OoiRM#c$rTB#?pYuL;0+JZWoMzsPf8*Dfi@+Ve3EKw;-j*#+!#5q=#2
zpNisB(A4xR03A0f+~X7STpZmOgG_=M1E4rEDz+Mc^Uw2F0AAQJ0Oxr=ZtpyK7N4A=
z|1%;GwC7_SfZ8XY$_XY|45|6k-6*IxZpQuY%h?zJ`@MEP0dZUF?mfAf+37UZK0Bp8
zAL9UYCLhJ=g^#59jT@<y+b?H*?&pHs1K_pV(YU2$S?&C;TYf1QwAB~2B$zP(f^daq
z-+P~GXU>XWerqf$u6KTvXWw6p0kF?)&D(e6xjZ%|&$Z7_Q}u%n)#qU>0I$`i@*8iG
zztExfUz4)3`BdW+%hGRe-YmvGA6L0>=QnMVQxT8hvGMLmh#3VSU<lP3E&TSo_<W(_
z70#*1n`=;E`*teq*g;;cPQ`t>=;C(q3wf8v@L28dHy%K++Lo3jt;pqSWRwcqwu!ON
zZMD;9;u?`uGaEn{8UM=3r<-04u!qu#{N=N+0Qinat)G9D<7xTGQAt1fp&>Ee1>DAc
z{0_gX{k?q$An1Wu49S~siO=@~HukxVe*xA0zP<+#7;XR%CLBOFlO|Yt-C_U$8Qld2
z02u%n=oFVi4M+ok_A2aR2j~Z)ixi|E4Ag+k;2DZ=1_0DoVHZ0<KM-A{ApKyV24n`$
zP=qr8puP&b*a7;1=pqH_2P2U+0D>S0f*=TjAP9mW2!bF8f*=TjQvIZV0ogs8bdqQ9
Qr~m)}07*qoM6N<$f(zFmVE_OC

literal 615
zcmV-t0+{`YP)<h;3K|Lk000e1NJLTq001fg000^Y1^@s6!MV=%00001b5ch_0Itp)
z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0sKisK~z{r?NmW)
z6G0UIW@dMjHkT+xu=G$BBGf}~y$Sva^{juO*Zzebd-3YUi+Jr15WMx4TS+lq#2^F-
zfh8MfcE<OfNlYX`lHEeU{owJwH@t7=8+PBI!v6|2$%033pM?qC3VeR`apq4?^46m=
zS~eDph7jO`--=)_^H><BrypL1{l-1yK8FiA5*>piaNZ%-5p^ixMrmjYOI#_1NEzwp
z&AE>cn(1lHg*Ekb=J&LZPcPoj{4E%L(|#8o-+3sUH{lH#yqP2OnsQ8sXD)-$28oH0
z+L0KF=zx(U9@V7ZI{R-u@su_5dXtFm%kV2+KY6~~DBY;=^W?wvB<ubAl8b;YSiaG`
z-$!<Jg^;FFt40I$lM|S|J*hXrywTF8KE1qz?RI&03Ff?37D_X!c6Z^2L-^4Mfr2@&
zm4(tiy&nwlv(v%g;zH`?=_!&{3%c2qdK28rKRU&@-IiQCK9*brD~<j*KM%>#5rT6F
z<1sW1M6gyu@9fAr@*IfhP2@XGgKO{UO|vpY+{3@XN_`yv?*B_a>mzQjuW|S6Y`M|y
z!9j=*4~26xi<L3-Cu@W(gR0d4s(G?iz5a(!*QtjORoq`hPvLq!Jh-`8ZnQ)GCUhmZ
zVL`Me*3q}-TGyWXA|@G|>Pvf`ZX1=+3KdEL@C&cMcXNVJ|C9g#002ovPDHLkV1m^=
BADsXI

diff --git a/assets/images/flags/isl.png b/assets/images/flags/isl.png
index ed545e9056f6309113a5556ce16425a617dc4251..d24f29abbac82b2957a536cf05d85123c26cf4c2 100644
GIT binary patch
delta 412
zcmaFNwt`u)Gr-TCmrII^fq{Y7)59eQNGE_W2OE%lG^5;NqM~>`W0a?hV@SoEx3?Vg
zS`2tv6XSWF@>u5NwYFF^YL|vzF_PMP=t9l@C$ikf_{#p=a{+3Fg5Zn4PG~3H{iZ+B
zd(N?sKUd%Tyxy5{7t;@>a~GQ0#HOS*DBj_DSioJxE4yxCCjW*G)9#2HEuMnSA{#F?
zbrkkWY!7xmd9l7(=5F4Cx1X7-YMmsF_S&tK+4ygcg=w;ckuzgaS@6Ff&g;8sKF16C
z^RnI$IUrupCbs4JwgusPBaW;uTEO7_Rxzl-m2p{Kaw1y`Q^@>7Us$iGD{WoyE9FiR
zTf~vFsDQfSqE)6cNq55L+hn~kYZNP)YFJpavBq#u-}!K9ZJm=v|NLbQ;|~NhTxmMf
zu#B};@r{@X&%+Ylt?VY(FKp<z+0yQsqw0F0NlG(G{aBzgyWzUK4mX#yef!liX>oOJ
z&`-v{mIo)i<oZx4RB_0@;3{VzEOZzc6x1FtH+^gLUCx}^1rqgi^>bP0l+XkK*HNh5

delta 859
zcmV-h1El<@1LFoEiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0008`Nkl<ZcmdT|PiqrF6o0e3NeLvRO<|#z
zHnbPdErLR6^8v(@)q^)Z_2|)y<lwPVZys{hg9bl<o?=f15^sqhA;cOe1oB6c=8xIz
z_}-8iCQD)$jk5k=cyDIjy!`TJe|Fx?0L+5TE9rFFAjvsri)`i;L$|+Ttf5K6W2=Y>
z5E(2il}fR0x6AhS_MliSiayfY?KZ1ctK9R)V0(L8_*h$8<I;XG7_dkr!eu{=qqhD1
zeNKL;o!WH2QZJQCP%f9<qoX69&1T7ms}m)H=4dnut*oq=<MEg|j>BTHe;AP#KS+8g
z6ymK`3w{Of7^(ZUvn-3F?j{n63Cc;KP;eMyBE*2~&3e5a&Tl;UjGVXN3QXQUgw|;W
z+RrnhZl64X=3xqUj$gwP@%5nf@)}Afm&;8oR4DWYM$zy?@*iRgXV1i0oKVG(t+=L4
z2pDuu1_T`R5t39yX%R!ff6#0;LGB)kD1GG+FvR0=#VOEJ-|O{UsatwS^~GKIT_o-3
zAB~@fd$%*Rp9@_Or3H(dE+o!A_;S$2@}vAk)dwFxiPVvRzXy>|F@52;WJO+GxZfc_
zxW8e<F`@%Z&CY+bJ*hQHTY>%T)VG7ncV}?<J}30pom&vOxeH6jf5}s|Jt?B=>+8@w
zIP^6>X~$sv?LrZa+}IUlYmF`}6V1nuARG?QMwGB~{Kl69I+S=(YxI1N_lxToJY1t{
z!w+0W(jm{d@?;%Y(1DsDA}U!24V_Mh>k$>KgLo)eU0r2*M8(w8H3I?$+?rIb7ZJq^
zm|Lk-@FeY?LtwzqfAJ1C!Ko**eCBe8(rPps7Uq3}mV$otBYn~G&@X4Su4u|g_xkYK
z>X5cH-ZV|#@AsW#GD-I(BI>FXibP#(9Amgglwa}cDkK$jJVcW|Nh*5#)V446Xf!Hh
zKA#^95z<x`vL(5>xhZ^+q`I_4k|W!;hqYR5Oq^hPU7iQ^F<{_*G?4Y_gM{JjoA=1z
ldAu-S!Gi?Z&3kx|_z6dD+ZQImsn-Ai002ovPDHLkV1j32mh}Jt

diff --git a/assets/images/flags/isr.png b/assets/images/flags/isr.png
index 9f815dcbd42f579ef1f007da9f92055d77a05e86..f28dff1ad7067a4e7a44626caa9d7b8ed858b615 100644
GIT binary patch
delta 987
zcmV<110?*Z2jT}IiBL{Q4GJ0x0000DNk~Le0001B0001B2nGNE0OFW;IFTV2e*=_B
zL_t(|ob8%jPZL2DhWpQ|kqh<0So{j22}Gla-jG1NQ?Qp>K~0Pw5V_IBn$!#IhqO?k
zAVjJN+KL5YixgTq>C#^?W~Ovos8}$iXS(}7$w{`;-Oc2@bI#d0yA}%o0000000000
z00000089tdavYXBFdskwjdp=Se*g^vm^#H-Py=!hfO-`&l_S7vb90#cz<dA!Y_tmu
z0@xscsZ*Q<HNXu4s8^vC5kT(<D^d`>GnA|W)EgCMaDxCE1gP3-3WO5UsGVxc2uQO{
ze(}Z!-rOGKDYi*IAJYl&;&oInY=h1y`Fu<zz;c4|<IV4N0gj#b@uftDe|%o15y0O2
zSvtPs_LMYnEXJtkWeNdi=GOS(Mh|Z|<K^?w6p#E&^CM@ya%}obl6-!K79f+&@wS^2
za>e&PpVP<1u^7A38ItEv&(p91xIBx}(I;B`d}S@GkN;lJa$9Ra{^#;8k<YU(1?app
zU9)yTmwg%n>=YmpOUt}|f6&es_2Sz?3IhBs3Lf_7b9rmW7~jZlmWgwy(aopAtGhby
z(`-^N(4|fmb>VX7xV-nHfqA5$-5i)qYy9-3d@g@86f35uo_u=hafB;6uiFup=Zch8
z7;_HA<d~=vt0@fv{Ik${m$nt!(aD7TeYDBP7vq&TTg&l`+?a`LfBd1iEYK%g{POo(
zAANyVwg|J5baAySBpr75@hrb^Jt&U{UPbnN4{@%zMqDfIA&$j8Rd_^IUI13uY@PDx
zh4Wn72v2S7J$0;SG~U!cs$Z|tCao?6U?uGaVZ-C`eP2H^kxyN+P0?4mc0d5Fx&jQ3
z{VEEeP@kwSB4B2#f8T=?MBMLjJozeLy6m?I_rJ^+Vezu2P=r<K6Dc17t{wfJ;N(ix
z9z#{=6V=Z~>|Ly^Pb4;3mG04fFI?8|5t}+}#P%S-gBr9VM7skKK-i3H*dY#5khZ<w
zQwuBY6F~s&|NBIRan<@gbz6j41rxda+SViL{b$8o?sz(<e^kH6umZ4>K2hPN{PzXC
zl&`r6_P%iOvy@vOmFxEyIszCz%u>S!ou!{9{ve-^sUm>k<6Jc?fX~zEMPPMihDkxp
zr~=fg9bi_oKma!cpk9SmL;$@btVluh&Oi;Yna@y!Z4iKb6<Sq}0P2kjGq^zj4FZs_
zLWT&ScLYNUF`{<{YJg@wt5}2q0000000000000000AMj1e*n;~d*#Hd#k~Lk002ov
JPDHLkV1kXq#=!sp

delta 929
zcmV;S177^%2dM`kiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0009%Nkl<Zcmd5=&1(}u6o0e3X&X#5Nuhp0
z5{r6nZJ`88i6=o1icl<Gtl-H@^)Ij<z1h15J!%g2qTns<rB+%!C3rEeg`x!V0SWma
zn;qYqWR}gEsO;vjKbX9?Z{JLQfBWXmC%_=su(G+isgUHHvr#@niemTwM_t7x6^E}y
zOn}H>Vd-?5)oL}iu&@A!hlk=F>6J=_6$%CJ_%N8AofU0FqfsvXo6RN*27_F_r+Q>t
zUS8(Z4%x|OZ&&KMTn_U2yt%r%$}^b^wPD(c5<#`yZU-hOC)G};!wkb<f8lVLNQ*xt
zJrD@+a=8qDgR_p*|JP5`G>*C%i^aMqy9Wmc24k$(2C`REsZ<a{u5+KjG)*0YH-$x`
zK#Cs>y@F9x^q<WH_y-B>Jr#SgOAnf~Vos?SZtsGhu!Nj21%<AF&q0Hbq(zjH7<`6O
zsRVNNu)3Z`IsbSK#(`?he}G6>1Fu+IJY`LvWAFN>FTTOn8y&`hdcAH+-TP-FaJCS#
zS~np3r8m#sT&Y1Mq+toTj&39pVRA5u7ARqH(gnBJ-YLSX_s4?h`t@_dcJ<*Wn7e!u
z?&0(Ljq~6Yf~ZVbw|KOcfE|ov;%pF}Jh&)qBD$Z;V<AZxTaN0#e_FuUpe>2Sy+Te;
zR`SqP;1)069gBPv@<gx6?cE~gW&pNc|A37<?iaj2rl;xYX>f~ME2klSB__K2@$;|3
z_V(GlAnyefyorg4!H9YRjcPfv)ALcF-Q?UQ_k&Y{f`_Btis)EZq>Z(t=SbQi_qbyB
zB#kWf0sMp|=xy4Ge=Lo9YiI5^RI62so0y)6wI4Snv@#Jlg4OkO%=n&J0YBmX-Jprb
z5uuB$#{-zTx3||#oS8bp^GO_h06dBu;Tf)rT~8YmK5)20sTGSw4cC2zQh~O9vLflD
z(!+i@qr9RnBi-4C)7K8^OZ8P%<&8$eNG6j;Hk&1)rnQ73cTp3K9b5_8SfPnWS0Slj
z!!2}akfdU__k9~u4~0TP?(gq6TL|eZ3;B|a$K#?clJqQnkz{*jW~Qa<dWSec|F}F1
z)`bCgTpGyd{)L3%e8-1eGB_?T6c}+KL4JJ5#e>9e<NtU|;8a1+00000NkvXXu0mjf
DBbd4W

diff --git a/assets/images/flags/ita.png b/assets/images/flags/ita.png
index 768f5a181113a79c959a77069defaffb9ad059f5..8af7190b89419b859f9fa1d5e998a1ae87eba906 100644
GIT binary patch
literal 351
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TR=
zr;B4q#hkadZ}T1s;Bh&q+b#cVp|;c(k)2ITnSXFMo$*-7F!A_Se<q*-KrsDN#l5O$
zrpN2PzOr2&SJ!Zu|AG96zUY8EO~;H6IPZ`<^jh~scE+BzzV{6BNnaJW?Q4;BJra1t
zg1bl}yuI+X$(6zq8TbCmhDIOWlxr?$JdE5XC9CCV#5@1oDw?RPdM)T!+=QcRqRvFk
zE({Y+HZ6S97Ikjz(>q&bb8T&}U3QmOxUj+@S=2~qDL;#pU`CIF^Mb&}V_YT_a{lEl
eV1)SZr@H=}hVw5Jj(j%<33$5txvX<aXaWEu6M&Qe

delta 696
zcmV;p0!RJd0>K3#iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP00073Nkl<ZcmdT|JI)$05FUG%AS4hkg_0jp
zrASAUf`Us><PfQH0q(;I($Pgopj40sA@Yj~iH8K*Wwj4y#$r}xvm~U5<b0Afv-a40
zjAy-`0l0_AYopOfl2l5GM>aW4f137xm@5q_Gqx!)4I+b03<d*nKA%Oe*Ms?duE$6}
z9*<(ZUaQO>gKoF0*QnR)itT;h7o}23@i@(+zJ9;2XdUXOK672x7mEcfm&;^09IEkn
zOlu@2Q6lIBK~N|bi%uAZB8nnWsZ@xx{z1|Ug@QU94)8l<=dk{)o$I;^fAyr%Xv8Sv
z*=!aGA+(DD**n|q_RZIi<?qP(1)hZZ^acI~-`;<C+7?;=`24o?4%KKfnZzzC<a&u-
z#Q3N@P4Zs@J@|sV=in~J^elM*W6A-`U~-aRIp`%MnG&TS2FtMD?}1N`lqkLBU>T~_
zYRbv#t-o9@3F}r9t<`Gxe;(z4wHcZy2dvHb|Bfd*3T(tL$5XS}1lvH)V~@IEG01s%
zzNa3w`bFY9F5j%J1zo5K+M~?cHk?i;WqMSzw((LzUnbL|dh0380Ly?!)BU#|6R>2p
zTE(E$D_DXA)GOw2F>XDPRd>l9N_V&0xtMH83I+4(NBX1iFq1Qie=ELBWY@^rnqXU+
z?>LU~JTK~WI+QOF(Ih?ak!XUQA-X%j2|lK-T2jM>uV~_tq-OTtY(3V?<+7I3>D0d>
z*p?gFl5DrzdM%Rl%(h4}Xti3`&1Mr4C%C1{c}NQe*`fhI-wF~kJC;{u$P_OmJSa$z
eU0&gV@e^hAq{-9k4u5L^0000<MNUMnLSTa2yhGdo

diff --git a/assets/images/flags/jpn.png b/assets/images/flags/jpn.png
index a13ef4178331b7b40ae696ed4cc5a2669d055b3a..b5c6fb4c407735bb094aa75c02cd8bbfb2418b04 100644
GIT binary patch
delta 843
zcmV-R1GM~r2h#>2iBL{Q4GJ0x0000DNk~Le0001B0001B2nGNE0OFW;IFTV2e**<c
zL_t(|ob8&+Zqq;%hV4b$buVvFg?7`c(hJW)TUHPS9*2V1(j<jF4WZ&WfKucncIqss
zbE{7>$`cG4D`~5U0%>C(C-Z;OzlpP%|DQR>o*Bac0000000000000000000$D@b%D
z)D6u81R!`P7y=LoK<g4`pa*mje*pI^B&+~_BM2pk-wgBsp`Xx%1p;87g@hHrZv>$P
z4QE2@>v#F<)uD8s>`8ldRhDLFWpQdMP-$*1_)R^#JbW!%-_F>Lo`@dc`)%nRWu&vU
zEiJ<sN|o&$>1DE#sKY*vu?(Pgl9%Ph#i5NKR5_85wS0knJYy4pUvJ9lf3xQgHhxgm
zR7z5#i2(j){*`kf?X|U$o8OnSu_676ixqH}`Q=0+H1ltlB+d|GS%Um}Gt`;?r<FjB
z76PDN0AbYpfA)lQ8Uc`c+sPLqH@~mi#}mCvkngug@~U}X*@;Jye<#E$0Po!qoB7wP
zAa|^908Vm?J%Gy2uATv?f4v=x+5AAJDO+df`URji)+}!Gd%Aq{R=)t$&ZQLt^OfBF
z1N{Q9S60}K@5^3a*DnCIhi}Eee5K;Tf_?!Mr>EJCzt+qQ0<aJON)YK(g3yGS1912D
z`D=eq?!i<2dVspUV8y_EZ9l}+)e*}y<FOU-<EMTBC^`4IZZc|Be|8^7Hs06;;AOJx
z0eHtB^bLTh6UjmRU9y*!^*)dx(UtX2pV<PapMHsStg#G$)S-MT6}kD<7cV0pXKVwY
zMl-l75|#N*GKp&`gCY18H<Es!4&tvasw}fVzAHf7gy3v$hC1_cHSs^nQ8k?or{*)=
zh8vp|K(|ycoCf9Mf59bZX_@71XY2zYCF)2on+vXv47F`xn!y*YmwPX%E%?VVwgHG6
zsjDMu(@Y(ptBbtqNK>7vDV65ugL7T=O#LUyy&Y`=pa~HI5D0*M77|tfzY&BI#BT<A
zfY489!U6%X&qBfq;5UL$g80oq4-onZO<2S{0000000000ApigX00000004|h;y2?i
Vae>hv`WOHJ002ovPDHLkV1m8<c8UN1

delta 888
zcmV-;1Bd+627m`4iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0009ONkl<ZcmdT|O=}ZD7=CAWLmNnJ+Crf{
zq-ie^Pt}5@(nGy@^ORe`>dlk>0Wsh&@Z`-8@Rp0cdD31y1RC_xfKXznP$AGZkdP0u
z+3|hG&azq4G`m4qADF)H&O9@HfAY@v5Dh{MOZj}>fR$2;%Q!=l;pJaZ*YH@w$907%
zKny3by}d0OjfPlXU#C*3q{`r*pP!3Lr6PSlj8<1yRU5Ojvr_Zh?Y4-=<5HKS9`d%f
zwj|m?KJvWnYX9)?kjmw<lgs5~p-?~@j#nrIn%!<UHZ?V6_If>G+qOt1f0Gcc{vrHW
zEGEy+&S(_;b+kV&&$2AZzB4yB*Js;5I5@C{5P#ZW_2%a0W}HJ_l@WpCI8_ebG$#vz
zRDU@121gO&W0@iXj^Z-+p2@w~$G4#icubiTF?cl@6meh@!df~5gP20Xt~coC%lB0K
z@QIq=zN@^%T9(pJcWCj!e|-vz)6-L$nVC_#+=yb9QwVgbCse$dqe}jjD-wWT-hD=2
zR_-ZI7_dlJ(?nel0j0Z-Mhej!L_H{)&8DOMiG-fK+Z!ud;9zJ3MJkmVjHn*4LGkPD
z-q_re0Ni0vLiKhR1n9~jV-MUg-LLWAEKjabECoSerIIwgyfijHf1X)Vb%H|owkvdg
zex8D2@!|MuWSI37!TT$sVUT{Zqat+`z**c4E)>D@Ml|$}gs!~x`SnP#C<A9YGyX8~
zLZ5N<$vQM3;LeYabmPqnO0HdZ^Wm>Ne@wT(7D9^zaG>@gwz08sO-2maY!<UG#z`1j
z^(2Rqe+BGJI-+jZf8&}#5d%-8!M&a@V9wFeQJ<rIOc4QJMUMFn*XPLuv2x&Y$JVOV
zY8GF%3=9SD(GUJ*!^3+ytJmvNA13^5__<zaF6x`6DO;_UoylbE{r!Cib=-B7g*u$s
z<8XJmLYuFy$|7;Y9j3Hkk-YgA+?MteiG;GnVzJ#}Xs%A+PQs?sY1I}izBQLcb{7^F
zI@M~m2TgQwT^<Ja!9e;R4fOZLgM{HPlS3XEe2*6fUGg9So*eS<pz#}Y&H<Ellww5y
O0000<MNUMnLSTa2C8*;7

diff --git a/assets/images/flags/kor.png b/assets/images/flags/kor.png
index 36e867ea8c5a382c4140e5404889b7457dd6a729..ccc181522a3c114c5de614e17e345e02797758e4 100644
GIT binary patch
literal 2594
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
Eg7u{9_y7O^

delta 1113
zcmV-f1g86<6yFFTiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000B@Nkl<Zcmd5<&ubGw6n>jcTSK}v;Grso
zL@1PkHiaD8Tic62Kx{>N6Pw~m5Zcl|z@ELdCx3yqMO3gJdKC|*D4r}<yi^M|Dj4;W
zU|NgCWSsB0vrac#cQ<<QgJI^qe|<Ca_Pv>JW(@L%p|yoAi(T|yviqCTdClP--)+Z;
zc*tgdf4_;^ZbwmPGMNUYvy0NBj_BX@HpW7+bx~DposuJ%$DTK8_l<b{6+7A9-rlge
zxoNhvw3xb4B9U<HN~MzLAM3WtMsIuBczribQxuEEYN1g0A;pSaemk5>f2H<RtJS>t
zPXJ$J;F|2{I^i|9wzf>eFp?Ai`Fx)0g^XYzJNSa^4i68rjP*crZIBFgB**|WGc)XH
zcXu~svsns*#l=O+<#HsmN8{t;zV=vx3kwUp?ASSU4gxqhH#f&oK_56B6r-b~+y{Lz
zMo`EN2S*Kd6cG(N8KStff3(E1+zd4~+aC*5DVJ;X>2#WZbY*3QrlzK7XlRJSAR5#V
zgJUv85zb;#J@tjFH|fir1;@$8g9m8esS|YI!g-eUR8LGyP+wmkkL9-nmY0{o3IdMu
z8qg`o3vdc4L-dhCJ$-BEFH-sWiyiieY~k81Dm{Keo%es)B8me8e*-i!GQx7uOagF}
zdCZR=u>lZO<sf9>&9&RK;c`;P*6THnHX@5YV`F1nhfKYpq8RPy=!mVZu70JEcyuyL
z`#!AI=*vbU*Ou5O(`u&l(}xrmy}iAAW3kvbnZXJ+lR<SN|9OKR6s;Ql_2vxq@6U3X
zOdO@s#x^g7u+X#2f4d$O;I~G1!@c+s$~7f-IC;a$IC3tQqPy|KR4;7m<jur8OQv3g
z9VFG-EYoVyWaJoG)$gn;N1AHvULDFX3;YcNokluvy68kdcDj>mIOydhaOP;I)5d13
zhwvR9^-Dd78cqW9^YgrGnF-Ez)8e!D^zv=dvtM6VD@~s3f8n+|+0ak%uwswhU|AMt
z8W9!XGe3I5T2T{$Vsx@!xpImwolR4+HSXvV@dnoAE+5}91_&M}Tgao7eKT;Wm21@U
zyL!pfM9j|43Q5>vaBxsePfyp_6gR$$^-tv*z3L}}BG%W}x$TFZo}L!6uX*}r^8GDD
z04c}K2`R&Je{draZ{*^Jy51#|NggA}Maa&wb9)NB+u<Bij>`y^OPEc8l%o&&sxkb4
z+kTC%tE($60zy6&M7==TgQBgiEoQ&j97Le3R4VVpe**YoKSh{A6(ylIWon~%lE}3D
zkzaRvwABMei~4x7U6p5iMY0SYct5=QspqO^aX)$8FEagl20OKCyX`f-KA(H;zq*IG
fVfe`ZVob(QBp$46n)2^-00000NkvXXu0mjfRsR@`

diff --git a/assets/images/flags/mar.png b/assets/images/flags/mar.png
index 65b31c8922927a7de8b332a4ddf9af8c22f061e8..dda3a0131f837726ae2e041ef3c8e185a4f00af3 100644
GIT binary patch
literal 849
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|PU&
zr;B4q#hkY@&U%L=iX1y%v*PTHp2d%AUYyxmzCmiU(di>SN~=%GczZ2Bb8LMSOW^5_
zjwUl!R^2ETN2l&6x9%o0$Jr}<l|1C%-!Fc&?^aGvlgGI`zwPWT6wbxYshszH&hx#_
zEI`YVK|`R1lH0|$Oa^9;Zw&_-ni$>ITR5=^@Jz64<q}rVZ#l#@Nt{{I;hCt@jD&_C
znjte7DiuY-ChU<o!C<sr;1CP*5&wmUSWa*++|cyor~})C%2ok2357Z?QMCvEyFS<|
z=&#wR{UX`q%=yoOAMJWfAH@03(U;8;e}6cF+3j?sUfhPC*#-*tx(nHA`dV(x(l5wc
zctGD;`O#mA^aF?A%`i(izUAn2ewCxY4bL?Mt8a?YOaFN*VYb=B+3b1F^Nb#_3)&Yi
z`m;hJI-Gx3a?W|{7|UtTw4FWow&lI^{PXSR@o2NpUMuX34h6Gml%LP%`uOs(r0$3P
zR~%H&uMhTpbpP;XwiR1Fcib0FuRixs`SIL8cJ~gXdr9ieeY3*$ahk(@%kKRqY?a>%
zyt?Z@23YI2H$VDYeUD*l*!oMpck0c~N2lkMJ(JnDd-Kw7H@jn8y7$%IdX{wcnR@Km
zM}L2vV{kp<-RmePe==+1>cg6GSsbrE?A^FM^nZSV(sB8u#E*8h*$qmMKD%GOW1U)f
zz2`9V<Vrco*B7n_mfwHB`pMT*lipq2&Zg7ee8=?lhqre*_g%gn#2sD!UOy`E@Aug$
ze_PhQ=c$OwxTe(KyKddWlR<6k-}x8SEnIM)^N#0^d-t{OEzjp&!MFZi!5!&~YxlXl
zU7qoMc}Hw;m@fO0-(Qw8YA<BSUwzBQWa8uPxxMu@=@r*^{rg;{;V-=*!}WjF_Wxhc
zJ$Tk!vVWiPgJ6{{isuh8OcG}kc1WADJbc0@M^HL>v^*e@=}BuqgyW|q1?CfboH&Ge
o1nh}VG^?I-BBw(TyW!6f|Fgvlk5Bxm?FQm|y85}Sb4q9e0L8(3kN^Mx

literal 429
zcmeAS@N?(olHy`uVBq!ia0vp^T0ktt!3-q7rQ00=QjEnx?oJHr&dIz4a#+$GeH|GX
zHuiJ>Nn{1`a{_!qTo0=29#+?#X{>idO*hQL;E=lRQ8nESI(kVi21^X|;$00goD7QX
z^}W3f{k;tLYv@ie(+~7CXtL4|@-$edt9MvUcekc)vWtOrfMK?yL7S!i7HwV2K*PzV
zdQ(jGavcqJXzA|M(%q+_3$*a`(uX!cN~I*oFZe%Uz!0Is%L`P`S>O>_%)r2R7=#&*
z=dVZs3eNI$aSXBWzkB{PU$cUML!gM`(d|u-ZlC)9KUvyJ(bwAd#*U2lY%}HvC>-1U
zTI1sj{tSUO#+=xAjb0_LXmKaW=Qe(merz<5xM`>9?K(|7HS)<!k9ggp>`?Pu_0;QT
zrL4-*PMxpVb(hLju{NhmsFuvxGVj>-{)HuRM|O3kwkfv+ZhhMxw7vFo#evLTtG5SR
jgZ9WTnHTHWyOa5&v_*(i>NO6aD;Ydp{an^LB{Ts53(lu;

diff --git a/assets/images/flags/mex.png b/assets/images/flags/mex.png
index 9531a3ea2d50531dc9fb94d7bfd80ac3b540c52d..f81102912d513273712d7307e6955a42e6bffa94 100644
GIT binary patch
delta 1618
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
Q0000007*qoM6N<$f*L*CWdHyG

delta 1006
zcmV<K0}=ex4D|;giBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000AuNkl<Zcmd5=%WqOo6#ni5kl&9-TNEEr
zBrJRzHB}o8iH(cKg;5vQbm78<8`t^=bYbGg#D$3~UAQqOUHKp2N*mk6MoSkGgo+wz
zfwnYI1nzjwwL`9yYP}`qe#zvVf0;Qme4KgQa|ZYoN~bb9I;yf1LMZFmbSSFT{tshS
zi&WceTf|H-87j));Gj}2mzDnheoRhIntiO7N+l(oPK&lbhFC0S&e7Z3E2Mq3T2;JW
zuaNybj@#n#xZruXo!hMQN_~2I8p&kR7#<!LV`F1HhhZhk1hrbN=JI$ve_Fj>R~n6m
z;`jTRwE2UqyId|&EEe%Qw2zVcM(uQ67o;0~eSJ-m&54PLhN38@i$UzQTrTH+bu2JL
z)xFpNqM_~hc=sv(2GhsS<NNIA4cQXw?CoQ_4v^YNBoa-X6n4EzUZnjI*bvEo0rKEp
zT0M<cvB`B+cF>;E;4oM@f2nXd_z<#e5#>z`hoMj?K;9lLqI}BXFa(3a7AGBDM5UZZ
z;`w8IO-`aGdKedP-ht=;0PJFUdD-y!e5T$tqDxEPkbU_OrSyBuOif`n@do8jDcrdK
z40h4e)5G_<shdkLH|%DxIQI_Q4qisHT%f=2#{O6c^Vzq^eMq7ke=t2NH>@2LOJCqx
zsY6@xAU~gg5)4Dp3K+U|&m>u^Rj{~}M=%h^X0Yk&Nz-&JE~fE3U4-F^;pBx81P`6S
zizg4TbI)$LeL6)MRoKOv>xr)dJMeDtBQux6Q2Z<&m4kRXFOc0DhW|1V4n&aoIs<>u
z{s(W(^%M$)U<Youe;20*t|RyU1+E_1hbxUKobLn9ojQ(%<~y7?It065=dJPRX24`G
zoEw3E?lra?xP%>%0sL3WB7SxRKA$}YFxYw0qkNdU^F`8qICJ{iPyOfsx&;~I%E;QW
z;DDOJL|c)$)3C6xAgmrWSvxT(;V+Zbqvq0cngNG_4w4~tf77FsfElS&stF-x;Sd-Q
zvy{U%Y3Z4)_$9d`sps=~osun;w}LhFV|~5tVNK3>U-6Q$-abdWtrgOi$7`A<DwRqj
z8jW(k#6*qOJxW9kYOIsHYc!xrsjDfu(8Md?D2^l-Yx}BgMd}omnR0x5yt+b=wz9A-
z%Sa?*&c%}JMADW>*23ZNN+y%3GbgO3%bn1AFlc`?koDCE3AMei(<4LM<AsWK9wgYV
c)5C+r57|r$8Z>J34gdfE07*qoM6N<$f-Z*O_5c6?

diff --git a/assets/images/flags/mmr.png b/assets/images/flags/mmr.png
index 7fc6e1661e30095a674fc29adc152e21974b3022..c2f9fec10f6886b8d184cb7431a32d7ce5d7188c 100644
GIT binary patch
literal 1041
zcmV+s1n&EZP)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h00009a7bBm000XU
z000XU0RWnu7ytkR!%0LzRCt{2ncGW~aTv$FGx~#SNlGyjD~gDY(nV0giY!Gk3d^jE
z4s^Kb03~c4=|CoF8lmELQ&Bb}=wN29O*)xbzS}!}w|&DclUQ@r=AQTP{lEiWxb1nq
zpWopf%gZB#5JCtcgb+dqA%qY@2qDB$z?~0P{<LL40dCm^MgeXLu=Ej^$2%aO0;E?V
zxC7*a0FNN~Fn9;JtyjE+-4u|$73G<kC>^Y9Ywm#VVxZeD--l%d1Wo~glk$C7Q@{)$
z><7XFiND4Bv6=vH5q{w<l<&uK0{kZ?1^AE4_hUH$YTu*)wcjwukU0c&*^ornZ27({
zBfxhkS%B}Ld|#Fk5PX>|Ak<?H0S>1PdanJAWk^Nctupcc(v{%_G<naZ6wvhKtayK>
z7Z4cgO(`HS^jf?>Qw!L8b0yMI+ptQ!Ptyu$>^hxRz^%up#rrg^0N>z?v;z7+KNs&)
zw*p+AI)t?l^vYOd6xSb~z-H$ha|#%*eGO~i|I!1!@qYL%4m7Sa_YRn-@(V@iczz8r
z#GnTr^tNEz#d*^{w{8SX)S32bDB)qT;6tM$sPC-F*}S?F;BeZo>-tjkeDLNx{Ju}m
zP;+B>PG{An0Eg3t&8~v@<rj%+(;j>@7DcnS9$Q=mIiFLv0vtc<aPtOy{vMdN@Q0KS
zINIV6n@{%w98Mc5FBjuc-@UAd@AY+}>Pm^|Y=#iv$ntlFiD!H1c?>7O;k4n%olO}F
z7=I7xISebn<*Cb9fYVbaK8IliJbmZMSU|VWEk1`K1#G`GKYo5^iWV6|#U;D=Jcbic
z-?<0bBG=z`GZLWKXF(68x!bcQK<jK1pJ$?sAz)D<poab`*zrn>8j8QC_*_O25U$-h
zb)exeMo%4^{QpDy(h5^+tHtLsi~z0uZpt8|Z{Hxaac$CTLhDx{+WRW?ZfR>3pUW5m
zO6MY`jQlyodo55F6;1itv4*QaEcthaSTG1>;amzxCqUg@nH=8mSEw~re;uB>vmCK6
zgUQFx?g|P>d;GLE{T5op`xwF1i~l*e;EGa29^L<a2esa&fGLA3nG;{_iR2>~JAV$!
z0^9$GRy;d?Swl<w&Jg=H9RCd70jZ9T>aB^OKE8*#eN)zg3T;`B=zu?Q4DHxT0V$84
zrUq!94g{CkvmR1#$^7_}kaqhf1x$4TD<=31V?T!4&0Q2=rvUL)sBj0!2chr?k`IG-
zfZck<OV~~U;;T^M4v-H*(d!XJ2qA<JLI@#*5JCtcgb+eVo|*UoOHsb0O8{+K00000
LNkvXXu0mjfX2sp$

literal 902
zcmV;119|+3P)<h;3K|Lk000e1NJLTq001fg000^Y1^@s6!MV=%0009`Nkl<ZScUDE
zUuauZ9LGQB+<VicO_sD}=^BgHt(&o_e^znga0m_rA3FCk%C<6aAn1e%K8(G}d{Xd1
z#3I&*4xhxKb?U>OEPLqO5J6qpmWOs7&Dvy;(WFV*`{($Ot;@~U{9B*{_l3i~zr*j(
z_xHW`oO>=j#{U$e)Nn2_4@7{>#?V<q07%G}dE)Mb{s4#4>qf%GK{hqD0PH(MRPn77
z<%&KWY`_x%1eo(pm7#g51W*9cbsW)i3JOij43sG<9!6gUv;ZB$(9(-&JzA8ZNm96|
zU0kkh4XH9)AjlS$2!#e2^!5U9+4Cleg>wY`n@~!X`PYhjn~#g=fz&|7Fo8fyNix64
zav=pmE0$F@WZ~1jA24{w_n-EUI5>5#sIqJ+wx?{oEgfv}b)%F*-PdwCrXEbRLo+Le
ztvahnCHds}<LnOaCcYFWV=kc-C=|oJ``3Kmj=avdd&kLHIdrMx(^}aP+|G1*n$fGH
zWUVYd%~!GBT*<wQs9vQ*DKzqSo<CC;*w^zGyPh6i*Vm_cIofx`HJ8XG7>|!purjnt
z4_Z}4OKR8b31~tiXat#Dn56&5ehy6@Vm3QlHEywx<k-|PcAV*BVr~Mz?nke4<+_ME
zqVlkXVik+7wr*k_&+%*GH)1~zFcu$Mx4@a}Kk)2NQBKdCrZ4miJ^m*#v9X1!TCWtY
zwr+OT`Y3Dw0$ZZY-}r-T>8tB{UcWs<+DH?5>J^fvxfWY5Ttq(`HR=ks^Eph>&(N3e
zugzJ1PooMe7`t`?@NWNmgunU)>*fMRsJ*WIBkK`8d{(PHix7}rgoE!ucq;(8ugA%p
z_!yPT6F7B}wv!(cFanJ52Aur@+QXonhKRb}gk<#9C2Bl5sZ|q|&C>b%1afmH>7fx;
zE}Td2*@iH5%$YczffosVKZXnixwU5qOcT*sc}prmCVXXT(_N$S51ehG$D-uF`Hp1o
zOPGKCixJz22>8M4#fZItH9JQt_8QBdk7C54U|9{9Ygkc)0LQ^uNFqW(gue~!vV|fg
ztgPUqZXv^)!Q%m^=11>RwDDtzQXmAfyQ^rIlY}BE!$3y5@7WEaoM?ukqL0F_$VPK`
cj7J0i0iaD6g5?oxDgXcg07*qoM6N<$g0{o7^8f$<

diff --git a/assets/images/flags/mys.png b/assets/images/flags/mys.png
index 022476291461fe068760cc472e5ea14c49b156cc..d151a3e4f14a96253cbbbcdea1417280c203c656 100644
GIT binary patch
literal 1436
zcmb_cdpHvc9GzCeCi2d1t*@C~k6I{hr0ZE`ERp9Wl=owKZi`mC<S`T#t#HjN%40XQ
z#wA8b4@UE7Y>3)$X{Z%u>+)}Z-{1G0-}%mW&L8KmLw3QOQB=@Y0001rC<i;&Ee_a*
zob1-0xsU&Ci{xV*yyF1?km@#M0ENX`0KhH`%Fg;cp?K*5(aAkg>*e2t^o@!TWOG-2
zep`OS+{HtydtkvNU#oyjQhDmfnl||x3f6agCxPjlWSS-!{>PgO%r0XwtSRtx^*FcD
z!=tu|=TqOvsJ86D2|u^U6EOUik}r}d7A}{dH1S=WeBqjs2576xPsa`bEh1oPK@Dr}
zOaKUMCF_(n34f8UQt5YN83H|+!Lt_o%+A##Z02S)1w*eqY1NlfLGvx6UNvu!RhheZ
zn!_ZvI76Z@rGUN6JBpHO7r#n|3^GqO{yOtzj8<WrJBhK4Haa$!^H5+>{y1Eso%Iao
zs|*YpQ@W-u;E_gR6B9NDM-+yxCkc&{>H<%2UO*6%$@35Lp7fz!m01Kb6J|U^D1)q7
zihehgv;Xu8!`z)rfw&><@W03JGw^p`xN^(qJ*xH)0|sofH*n%Qb{wEC?Uf?KWfKcR
zBUHjUDMz%Eb@IFTBC<eQZxD|6s}TrxZ*=MPj??CO>215aeJ187V4ivysa160LVMts
zq*EJp1xflQ-Jt{JW6*Znt5|#xd(9<pwbe{?e}aT4x}!D&<+M78UKyhCnZ5nhRBCc9
zdp?)^;3@V>K^WIR#}6H;5;6Cdj1DW+?KcUg=YJgH=iKBUCq>fn^Xp5g-fpH7kINaa
zF;mZp@Duw_*hF2MGRqJQQlSIN@TFQaY4~S*)QAm1$|>1Ui>H+G71y)aELfGs3eRXR
zM_m}$;7yn^x_5IeZc%&XO0$WpNUUg<-Z(wEBN}Pw3YQB-Us$xv$AzlG)3``oT`aS`
zOWgb6rET{yHBIj6$Js@CL=-I8F#0G}hI;F*yWHKDs0@8z^Pi?PgVM8mc47=Rf>t=4
zfQ4F&X2|^k5;WJ3rkr~A;ppmJstXz^LY7S-LYxiEDb@HA`Kqi%S5|YxYn88WVn6l#
z+fk>M<$3;HXGWADgxT%X;6L6RceiFLuvz!*Y#HOIw?0}q)CnDa;IFIevi<P6;XdC5
zZn6DsYd^lpG>_<!rZu53R%1+pAk18_m9d@CUCP)eZ1TX(LWrpu7CX)DV+C&>FP7nM
zwxz{RdC_}gLMsVMxrHa=O6tG03V|mZYls~mz<oJkE^-Nc2`67=v<|gtDbkyX>!BF7
zN3{rnQ9D6DL`Cu49qKy6c}<3Ae8<;TtN3^=nml#s2(uMJpSj#fA&XLz5BIm~V0$Bl
zH7Z2@a2UyJZN<6h2Q~RdaMLf}jN>6p?`g}HW%6@IvsHmiJBYqgcCdjk%kmxNR^dE@
zvf52X4zUtsV;29h@Vve2s_RIxlQ8ocZm<@ZZOLlO!cnwK*3Uq}6_1MOJTq`4;3eBa
zRZVx<v?(5aFXDFGr3H2IHR&brWi*eq!gzWPGi>TCyVX%FOHtIAoXAua3)mYU6`WHz
zJH$OynCj)okxio8K4yb?yGNb8G%-+HvGln!>S@K3Oj8|7w%>Jk4A~12c396;>u8Id
z;j-IzxWWhG7^uxExeSrw=*D<7{^@-H3Agu-4Q?oFP{Z9Vd+B6GS<!Njaw9Zz572i5
zlnajW(}6n(jhu}M+gmXxQFH7ANYe5)={x6nl|iYy!7-fx-r2Go@SwjO#~+<H>FoIb
hN0onCuq~N=ZVgg%aeCk#a0a;TqU<qtG@F2w{{S%Ywd()?

delta 1076
zcmV-41k3xJ3%Up)iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000BeNkl<Zcmd5=&1(}u6o31Xgg|1`Mk<z4
zV-LoIf|^6D6kIQQ5|vW$<6;kb6}5jryeqw`m*T}s5evO}>E24A!GgA85A6m@#X{PY
zgrsSb9p9UFw!53H79F8K7~Y%Ne>bzgee-7a%>a0z1eIJar;=ohDF@jE6xD72hrX&y
zsy<tX7zdHTq8Nsul*?r$lgU6npXbj=-`w0(mY0{A@57+Kzn_oM+1bg2eXUkgqR}W5
z&#51^4Gs=68i(4c%{{Kr7Zw&^adFWe9v)^B6B9Is?IubDwR*iCibNt>f1}Y*n$4yX
zkH?8Le<A6iP>5}8Y{2i}?<4fX+UdH^P`A6fx>_h(b8~Y|MNznm0oiM-tE=Iene*SU
zdJ6s#bMO`<pfG9}XHhmy(`@Oekn2_SBE^S?q>)*JTZRQ&<p`MhlURBV^@h~=I7q;$
zjj=HeXR$>UU9@6MX+lrLf9vq^<tHwmzPjQNOr0!)^&`$@sS<_~en1dnh5<4Vef?U)
z5CjiVH^!dLa55Jk3^`<oG~vm;FR)dKfVCFG66eJI_<H&@NI^Es7p8|O1u;n?`0(Zu
zjN}ZD$4I|z6!^0XXNoYtl!O;=Gl8BxGd&G5P<-?VIyyQyFI6<se=6rhd&;~{MBJbc
zxO!=glN5D|-~S0D>1>~EQ(r2FcZu{=JY*B`9Vp;5({s`Z^WT$@i0!m_bm`hPkbz1%
zZO3A<V50L&$9eqSGFD*H+}{K!7K!+znc|x-)j9D>xa|e!R#rd;5_j(^p2b7~i<_=v
zaA))eOuv}|>v5jPe<6W9NvofGkuNNzEj$D&rU|maiHhHy01>!&e+b5&&%o#RAK=|o
z8r!-!Q63rrE8PuiWCWxDSG|X5;LDKAozd&?H^?vsQgHcl`}R~U79j^F$bdAD!v1VK
zM3c!R3^jj(49JSnqOL<Y9QJyYAZxYCLK3GQSH0s=C!l2Qe}6I|a$J#FA6ZaB?M5h@
z%^qV%4C!>5_Q4PqMHj3oDUp`-NJ8So3Fk<}6K86qV}`6eQWm0?W#e(gsVj68>Fw=}
z+O}O_M+B`_t1vJy5Ji4Gq4yl_Q0nXJ>pK4TRSE@>`VmMMIjbM;!&#|RVu?gzcklC!
z;kR`|*iwH@f74jCT5YCMDLOCFDb#lIQ6y?(V*~#Lb?i{XqbrwGaNun;sgk7PZr`)5
z3LVojE@x+FYugB6D+<|??Ca~}W09n~utk#f?(Xhw%d#583HFZ5L2xb%nD5d+)b}nV
uRR1#;aLM4iyinnQ3kkAg0T&MfzW_q{PP*S@o+AJN3IG5}MNUMnLSTXza`YJh

diff --git a/assets/images/flags/nga.png b/assets/images/flags/nga.png
index ebfd82449d575856a0f2622a4cb1dacd2a8c8107..26efc073e8c39b2247fd0571e654bcec0bbd0ef1 100644
GIT binary patch
literal 351
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TR=
zr;B4q#hkad5Aq%g;Bh%PWo!G|iC(&{>l8{DwkssKEn*OHoRq)+F;G7cH0+<`zTVot
z_?^3bd40V2gA&F+OmQE@L+TwL%RNw&F@N|~<cZ-HIp^cm4dNRs1f%m0^(np5NSecH
z+0%V^N2$~+i(P$-kJ}t@P-8R7R!UQeR6c1aY&NBT;h$Sw8>R(iYbNWTND9+QTYJ`G
zb?4Su7G=)5&yN+oyVbXCUfk=Ki}?jITo!EPlI*-B&D6_f;<iBXLWe^#s}zNt{pJ^-
d-g`XVhLLCPq0@&pHXj2CdAj<!taD0e0su4pe9`~_

literal 193
zcmeAS@N?(olHy`uVBq!ia0vp^T0ktt!3-q7rQ00=QjEnx?oJHr&dIz4a#+$GeH|GX
zHuiJ>Nn{1``2&1HTp8K}MJFb_`ugGj|NlU-HHv!^fD~&<kY6xR<UhmjZG6E%0nP%C
z$YKTtzQZ8Qcszea3Q$nX)5S5w!aq4dQR;%9CNq<Pk>O!RVdW437PqN=TC$;DyMmM$
eb*F6Fz`$_p497z6<qAeXT@0SCelF{r5}E*pR5w2W

diff --git a/assets/images/flags/nld.png b/assets/images/flags/nld.png
index 62dbc205834a2822186eb8423d4af92be5f4e6a2..2209374269e59a1b8d38c3e944d6521fba407b1b 100644
GIT binary patch
literal 372
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TR)
zr;B4q#hkZS8#`GHd7Lkrhy^)!&0WWosP!S#FvD^`f0o0fwT3|55YP~IMaK29F+YpJ
zW>(<?A`Y*`&2tV2IP7YD%Jj)?iue@s!)#~jj1C1ed=#6;eL^}gF5n)Iw88I_9R7?)
zq9gPa@?9z&D~)pwyir%Sskdn;zQ5=@(69oKVWJSjv>Qse`+-^u_bk{WY4+gTWWjw*
z9os+bXxJloocq-5MCLqu$%onv73hlW<qq8Pzxa73JJXGuO`Hkb3%+(sn>`Q&I_)&;
zlimohLpA^%k`Hvqju?k~9Zy-Gp54H>dw$OcF^4^9ir&lf!+gxZAo0J`zE*-kVq(xC
PageB|tDnm{r-UW|Hs^*>

delta 753
zcmV<N0uKH30{R6ZiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0007yNkl<Zcmd5=yRI5B5Vdy~E+~)y1tlT$
zNkfr_f;1_TnjgqFq)fqw+&|z8(osYrNKmAJf&w9hG$8S~NIZAfnKQu~v)Y@ai;rY^
zY>&-hc4qt#;ubQgwA*b5wNgqxf2NaA98>=<a~-30V!9DA2FOs6&1O^Xb~{<G*Trx+
z<T1$W^;%A+Qx*GTqE@T%8pUE!Y5l|DAhX%5(&LzizDA>=unzjsXRfQ|(P$*b<8jz(
zwN$6m!5X1S6a?MV>6E&=yK^s>i}Zb8=JR=w<{yNdN~P3lwGw|qe2$j?e^t-(JVkO?
zDwP7NgTY|nODWmJg4nzB`8@sc`|7I{@|Cav#QNL)%NMV6xtvdy4L$0U%jHs@&u8#{
z`r8@)FQgRD7K?>TE)!5w!Fk!_nM}qNmVsQt(Xt~f2Lc;)L==G{ECYRdSQWfvL==%O
zECZ!H%}IIYz}qjMh4k!je^urC;?w(gs$4E}`-bR~YDL%tO%mWwuN~HA@E!|?wK15?
zxQX(pjll%tndylIIuKZAQQ(@MIG9*4Qh_x<9;H(l^Wwc;56pgS==5U8X5|MV8&Ahh
zWKrPFhkIMjB#h@ovfJ&lZ1rA`0H<>@%S=?WwhajI8;gRqjd>J1f0JoZcFS}+Z5>gQ
zleTC$nM?v={2=VX1Km0T`t-?{yX|)C;$)3W7A|;t7G(4#t!Q4(Hk*wq6bip`Uu=!I
zt_iJ+`L64#{eJIPt5yF>G>oDiR_*nAXG*Xqns6XT<{E_-K9b5FHHz7P)!l2EE@NEx
z`~Aa_pmlYDF6v69N5X5NMqBF=$rJhJaW<P>z)4)M%SnhH4C0Rlx_y0+aN=W0j|{QL
j3r9TiAOXFkhX;+H^-j9<KlMsU00000NkvXXu0mjfd^TnH

diff --git a/assets/images/flags/nor.png b/assets/images/flags/nor.png
index bd226c0a6a50b3bd61123d838f48336157bcd3d9..dfb43c5d54b66e95602afaf09732b277f352a03d 100644
GIT binary patch
delta 412
zcmZo-U%{-{8Q|y6%O%Cdz`(%k>ERLtq!U1xgAGVNno({sQBk~}G0M}$F{EP7+gpx#
zEe1TTiSat0BrS6CT3aj}wMxUU7)fnCbfISd6It$Kd}V*`xd637L9k&|k9N}CZ~7Cx
z?Ry`84&VDczMaX0^#kjig{-Y&Q_>m~ZFnBO6MG^hwQgZ1|Ar3U?uhN2la-o8HePD#
zC~TJ49_)PbV!dOZocV=sKN;8BE##RQHb0~<qS|lHEJL1|0S$BRPO<-YVYSlzKjBA$
zof*v_M!(&v`yy0d>~FYbK*Q2+0-6UFF$8blXu!OSDP;bkFRWM8m9{SUm2#(uE#gR7
zR6t#E(JE7!q&s2rZL(gNHHwu?H7u;zSYx=S?|itlw$90-Z~n4|@eUdeS&nH3E;Q{@
zd?O~(R<Nt>7IRy6#`cbzEr*r1O;XBmY!=xl{CLGe#~x|(0JD_~fv$b>0_fU0hiX5A
slvzwQ^H}D6;EySF5`l#d149Sr4~DvAOW#**OR7Mkp00i_>zopr0RAPTS^xk5

delta 890
zcmV-=1BLvk1A+%3iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0009QNkl<ZcmdT|&1(}u6o0e3NsXi=O|XXw
zH5977*I*Al<Zlpr*5aw&yeNo51i^nmk6OQOJ*Z%>wkNf;#a{XarBux+kPl4FhuPin
zy&*H*Ecw_bLAF1bytgy&z5Mpgf9!k#G=sG&>2z8n$vJ23Y+4k}Y2U?Hb4bl)tB45@
z87wT7O0iO@#HOdGVRLg+w2@vY6xiY6A$PqPOiWCO7$YMiT-sME6&4DGxNIjss+*mi
z<rIhNsm>W!>f77fu(Pvc&&|#8rKKf`VLOQuLA_S11%`%(^m@I{Ow(k;f5XE>TKpmD
zfk1%g^Lgk5w~y4l+8KtyQMY5Un1#~X*w`=`V<N?X?Db406I}lNXO{uL)QO0ZOhS0^
z1w4NC3DVD(MO`X+8CKrhh4RBk@b|+<7z8-5AJ;F$rcgCkS63|q6-vE^S=73b{GT8$
z*n2wmqD9Y|Y``(4gU{gPf24uWK_4MWMU)0H_zbyR4&>~ih|*UMK0_oDQJf5CgOR-2
z)mfjq(zZ<-8}k&yD~`W@vBTl8(3^;c7hgg@ICp0Oe-~g-h|bK=d@giBlm;wLx-kFX
zwdWvPyO|Sx@7Jk(dx0P-2kfi&-=G&1OO>8|JK<X7L_agrlNzHme-+%iG2=PF)?P*w
zLgHc^m(fWWG<H|MtKL>b<MB8wKE3HV2(9&s=-BCey<&3m2?T?|=8O`K=Wlm)rs*kk
z|6a?s+S_+f|GWZ&0woW>dX-VNBAM&!&=0Kr{k~%~A$(r#iRI4Px1bF*frzS|x!+JM
z7P&K{g0&wvCDCY<e>pQMx}J_1;4|RVWJ_IS6c1qb!NGxL1OEv=0dc`IoP}LaWO>u!
z4yBRJW({2TH5v-etsm*_hKKWTM&pXQjC6Mlx2+S>mi%>H=jC$QOe7L?ULvBlT0)Vi
zjg@swcMTmXcytw#3I?vCNtq-SXMMxAEOp$L3AwhmR;ePSP^~OvOLBaCT*M+t&(ao2
z)<#E1t4Bvib>ak#<8mvg3j_D1fqZUUNNDc1R+kK}%L@(KTu6{ztBVJTf8aCZ8PR=&
Qy8r+H07*qoM6N<$f-xhZO8@`>

diff --git a/assets/images/flags/nzl.png b/assets/images/flags/nzl.png
index 11c6ade9cd644d01e7dbaf97538302ba811d55cc..306fdc77864f157879ae836d48175cc4b9377a95 100644
GIT binary patch
literal 2096
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
a3I78RbNZD0LbmDv0000<MNUMnLSTZmK*D|i

delta 1369
zcmV-f1*ZD25ZwwPiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000E?Nkl<Zcmd5=ZAe>J7=CVY{pw5;m4&Vq
z&8!<1i#o(wR;#w?nAm+#<`{JB#~5p=KQ<`J`fIj-1|5TSurfz!X%UpV{U~dZt?j1W
z2WHb+yG3yg)=IjKtZHIhVw#V;fA>9jZ<BbVqmHx>9Nzbw^PY2``=0lF0`ZXaQb$LJ
zfu*7-QZgHzWQet2rL7@G8WL<ZVggKtl2l(`FZp~vsj{*X!^6X(j`g{@IcaioQc3tR
z6crVTK5}w$6xBWu2uN93S&CZE?YOL_rbgj@xSY#k`&D&^!-27}v1m(6e~Z%F+sl1K
zV~H|BV=x#@%gD$uhC(4J91cq+lZi=-53-(?mZr?k&SE7bwo&!}YA4IGLV7eeH#b5u
zGBh+4mLy5I7{uP_a=Fq^1arp`juie=TZ2#CM)dqL9oPBk58puf(IW^>{{c_uaWuVm
zF0Q_Q`_nl1co@a~SA<P>e^nzsar*IqxLsE`UP3b5-`^jRNnzI;$cu(!B`+4XS|fPu
z>JMnAiq>X*!il&~@M}RZx~CE68}{Ptl?ki?g*19b8pQ}_WVMuH%E*LzNPn%W4l3b8
zULW2nFT=^qf@MAJ*zyDpq|c$`r!Pc4x^ufA_!$xO%#W<f#Fn22e~&i+k5Aw0%!xu!
z=wfD3AX8|_SqIua_Qo2%+*k(XdpjcDd6Bm?@5XPnuL`eKjP}9*>qK1L1^Xm@G@!LV
za{MB0yJnJ-+)qF0lVqIuTc#gdPIjC1nwjEsktSD2BbrJ0$l;sE|A>RxTQQPmPFnwY
z-3GXP_i*%@{si4@f4pQS1ZXu0YeUbo94SWo$jW{pk{TyDwqpEbXPn{AEgN9IJ}Pvh
zc|CHPcj0<@lQ#4$?@iwk^^vkt^iAB2Yac!JEp_TbG9(W7)=g%(=0jS{E-WlWv$M08
z6MeJotdOralwyB|2cAQH@K8Q;-(K`&Y(!=H4cL}!`v-p)f2#pcI=SndAYD+q1DA`R
zK{u7_#pa%EPvXMQx1a}(*<%&i)b1`0Pp%U`VX;^wbutN}ylc>+s}aons#{bpzR-lu
zpaoss4$3)ky3`ie`I#>VafW1F^>b*gkBIg2rK>-pfeBaLCu~`tg|^+rXmF0e*jS14
zmqwQnog%x#e`H5{9Fbf;3WBJ*-M#Zo0>O(+@D5hPfc+*0bO^hvpT{Zi5C<^65QWED
zf`P%CN&6WcOCBb1%hM~Hc6o2)<)iDe18YHD^;6iF>BIZqP2o>NCLR>A%aazPGcz-2
zck?pp#af|y7;7M@LLF^`T9B8Qher+UJf1(S%Xoyrf6k*>uX$9#Ljo^J7Sp;FZPYWa
zda_PA@=fV@H*gCdY?e@%pFHgNK+O;yRavJJyvJ{Rwt{v%Q__Qr$K%nsi5O+pe6mK0
z@%F%9E7tSQq+W@{!I=yBnt>EU?`RhbTAHG?jtX5YPjmr`I-O2BNh>QK<x>h}n(lBB
z@+M#If0Ve(9ZA{kcFVNy8#okVkAAEt3y;{#8OIe58S9CCB-+M8wdM9kqfznu{b8HU
z#`h&A8r2qjA{wQ_5V<=@4FYs^6_OKgV`SoI$tkvc$=0vxbSx9nZnp;(397A{*p_8M
zL4oLtCFfOJA{n$=t&3ArQz7PrrR%aDv<HL4FGmA4zw{tsNUYO)WJq|tFd)f;1l#F7
bJgE2=4E*4{CRBGF00000NkvXXu0mjfip-4#

diff --git a/assets/images/flags/pak.png b/assets/images/flags/pak.png
index 1462650e4748c4867a35f9e20d3d418b88836b49..b8c966ea17e1194cef8a1ec1d57eae66d29b5642 100644
GIT binary patch
literal 1157
zcmV;01bX|4P)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h00009a7bBm000XU
z000XU0RWnu7ytkSH%UZ6RCt{2nu|}3VI0T%KOS^AF1Zdfj5W=~mKjF5%@dVNC6{v7
z##};VDfir&%SIckw20&qN-8#mm@uX@=`Z-%?^Va4SEqX4<8jXO{cPW@b>5!SzTfBh
z{odz&-k=}=0000000000000000002A;={*JWVbe-*-An>An70kAk|I;1RxQB)}<&2
zJ-~qgRL??z6`<Y-ffA(N4D<l0pU{LQ0#H5+1y+E1BLqs2dNa@iq&+4CFLYAa`f%mu
zYT1ON(&kadl`Q4PY8QYrHiV89oT94NFQ|81f91w%6~N%c;dHO&5xJV0DRSprOJgm`
zUWNcfC(W;@tv1XrEHAcfUc;9!G<HoGR)FYW*=e2mtU0@-W#f39(&{pD#Po6hE<81Y
zmK|D!5+wdGi)((X`E?ET)IGYFWs@4eeK*ECUU-J~<z`b&eJy=%bW!-G2rqvdtXB_+
zOq=62pT%KV8L!6zCr#Zt(;a}PHk{t<vy$YO0R%5}Qst}XznK(&V0jnD>1_mgH2);M
zYIxVic-FPD0_qms69EVh;}&NnwlQk_hDlwT^;5P?r>tv-jS^-S!1c01TS{9%t$^EA
z_u3dWFn*}z5;SdFq-hD-h!W&*8#Ov5)O4nDIk96#{?>%AW>Izh%b!g+)mszRWCf(;
ztTzpSXRsZHeErr$r8R%thHi?W#DgmlfRGM4SA5AdfI$h?N>Hn?5tHp3^x(x4(*U~C
zgw2FU5wd-Q-h6y-8o<)*B%hQBU(4@$z~@GnX#hDlPAfN4>j3H+>WvMWIx~ayE<vuQ
zW}2HGt$apn+k{<B%~VuzTe+bDAHca=7ylXnYxXYdkE9WR{JROs$JVtQ0PkG;EW(kb
z&sM;w<WSS+HJ&<OeA%Z@Ftsj0LOQ7US!ufguy$P9quktp4IplRg4Y08+b^d3WF_#J
z<JL~lH-H`sobH2oZ{nuichLab%;&K(a<grF_~(}a2<f1iX|p>NKx<>R<G`Nx8PDI=
z(e&+6wgu|90SG>n&;NBO-w_p6+##6}+o>HhUps$q4Bf0OF~&HQmt&jxejh-u*bw6t
zlFo#{;@$MAqVtq=IGHA<PNpG=BaD*5X7kVd{GUJLYdp`2?>xItJ!ASI0O1kBpoC!^
z?gv&>URPz?nM1&=0O1kB-Rg%vGoNQZe}~=X2TTB>r5qi}J7K%|T=VTNI{_JhXwi%v
zvy5_K)%eFRD{Z~o(Ix=VvQLQ1j5qFFygjz?6kl8Pw1i?am-zHupnwlRcxcqBv9#jo
zYC3!Cg7G3R-vRNV4(s)Y_r@C#{25;}a^;wR_J3&;fcVda03-rXJ_`j_fO;bYN|1Up
z&;z7?LKBt<K=~{bSOMyd5GX<F%|H*3`Uy=~{^tPz0000000000000000000G6iEC4
X+7VL!f6D=y00000NkvXXu0mjfi}w|1

literal 899
zcmV-}1AP36P)<h;3K|Lk000e1NJLTq001fg000^Y1^@s6!MV=%0009@Nkl<ZScUDE
zO>9(E6vuz(z1Nv>rqj-JDoE1`2~BDE)F_ddG!RMLG>~XO0T*ms=t>D8x-oG_K;y>(
zjWH%o{i-ISU|a|)E_7vLL<xb#B-)OhT3QC$m+5@HdtA&gof%u0$g3>ue|OKl@7!O`
zx%b@jU|IiDN$o&YOMngNLW^g!F5ORTWhOm}w0A5um#61a&JBapu)wZac&BC84y=aB
z1tWQfRL9Z?di$~+^m+y|Q;6M|uzxTAKt;e3^wRIFySI<Md!NQqMN7r`d1KJo8B`5w
zJkaJ7=o6@*D0+E}-TMyk)5woxGSif<PC_NBY7D_pi0)NAkQ^s04o)b9HVNwwsBJ+q
z#m-&3IrYki9DVl~XNNzAj!r}>_cEWOR4Q@e#n<`z<o6709iaHvc+*?>0;*T9(B9w6
zH*cMySjcmH_)S<HMJmD4QW4a!XZs*Kwru0k2e-3r{R2?Qf$^H!!=KYWon_zt#{l^C
z@&&y79JII3pF!Kf4g?wbe26tGdx%C_`S#}@2>0}ob+0!Rq9p=VHQ>N~eVYIX1%uU#
zb3-D6F$P-OI5F}z`H2Y%T0~ZLBY_a8S<HP^x1V|i1T3rUYD3>fHur9V)D$@Nagaa|
zH$O+QGl6vVRKCA8q%WXiSx|)Ek{7GC*Is&~%#a!dyC$#3KrjR?E#*>`b;~xn^+V{-
zt&a!!?7P#rSr>qvTOQ_vq0<lupy&TUrzX(+99k@(b1phM27jjM@83)$5}mKLOARWW
z_mKYO0ta7ywrYE7$1X<CBsqBac@k^agXh7_H4uw|!99FAe1?II58+OZHx<#w?#VRT
zYPD$hBvO89lH&|Md4MmDzmFsJF_@moV2t7JSOS1oKYfQIN1uaG7zwv7^h&9oOI4lt
zlX_Lec96AQeD%pk#2;D13-2A{eDWf>LJojLTby__#?aZ5tbY7{jvRUhqA?`W*3?t#
zPeiNU1S|`kz5<h3SP>!I)lJ)75!`$ZH$4XFS?CBMD_4Ngn?cq^)W7zo>>4}|iFH6c
zffjOPCsJg+5?FRQ&Ff<2lIAs6mKFo`uVGe2T7u9L{D-|s)v+{!dfen!<Uf>DSeCV{
ZzX9uZNFJe!mcal3002ovPDHLkV1n|ltBn8v

diff --git a/assets/images/flags/phl.png b/assets/images/flags/phl.png
index b453f3933bef2d4dff687e33c06ef62e44e38e70..3c2ce7bf3940d32ad9f44dc13432b7cf8a8d1ef8 100644
GIT binary patch
delta 1562
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
M07*qoM6N<$f)kd|hX4Qo

delta 1173
zcmV;G1Zw-844VldiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000CqNkl<Zcmc&&UuauZ82_DnlXNjnleSn?
zY#R#}VH1ZHg;}xeMK=Gimx3>ofkO~vf-nSetSBf$pEd>OgKhU{WskZC(LPv9rA0y0
z7KUBhMLVkfpC-+cdyn6Dl5@DZf2PeIn)C-J-?`_0=j4~~{LaaD4p0tJsSFGZSZt+~
zVmF@(#q#=B>1%nc<?}Vf6qpPZ(bv}}wzjrJPfrh~rl!<8uCJ}FiMhEs>HA^m>grNs
zG&eU(?VrtNMK~Om`aSpKw%*=e$>VT4w|U3a^<*-M>FH^=zrSCOjEwLYf3BA(6SQ-=
zT(F^`!OrLNqEIM^Xf(>C)faL-7!1nQ)m7{Te;-}HSHD0YAgS)Qw6r*6oyp0`f)GN5
z7{uOArBb1xuW!tJJUG)i^zA$j9&(}Y(ACGNQWzZ_b(A(J^w#$Fw$=S`Q|DLbBe?a=
zb2!=^$H78$((KtRLw>S!e=}*y#@*YHx8FwMfkyl~`~n8we;SDgBRD81P9<1nZ$j;`
zx~>CulX^V!;v=|q{Uuy{{V?LuAPxe&2-zB<EMir$WB+p=ID14z_{_-!>WP(=73kf=
z5am_AYY%5rNnr58Gb+OM(r+vlGn_2!K~8CQ=MT84bEY}b=G0BUf9Z7EMKz-G&L?m;
zzk}Mrg6&1p|6YY8%kb*AR)pj6czHy%V7(CczX9QFz?nNm1iyqc`xJS{A;O2t{8+y~
zUVgIX`VH`h7OVzGj;CI3+$c&ww`YC^ND7D?gNU6dHd2J!@1DcpyO(j1NS{9cJ^q|s
z!oDC-vFbsjmk2B>e-esV3F5wE)FTQJdA7`5G@VdeTf?<0_<ZadoQ+NF2j1*%HnVMr
z@>XEJn5UQaQpp-+65C@y)5+qyLywz%R)Gj+W}m>qTgU0Q{e}I8o^3<4wY9a(L8ixw
zBm*%>+FPxMK7dRAS_mI8nN0Tg8KmC(2<fq3Pz!MILZMK3e?<KdEw2^{XOqPUGTFqC
zYI8QWuypAP{`q1UwFC!`_IDFextBA`K!iUu&qad!r^9N{Ij+vEt0Mi=1d>OO<Ibhe
z>PC{m2{nU>n#`QR3&^`Au?}y(d>S`jd95akWiPC+uS;)46>F80@W0RB7g&T!hrCc`
zpFdTz#ZnFYf6t^N${JNu&&Ldv<~{lYmOdS>s}6SqZA~sE&d@~p0OpR5k2~qf-xe3n
zzSB|fDXs(;a*@t(4oy8LCbH~sM>ep$yd0pzmc>%=rhZ&EIjaxe!x`&JClmfL{Jvgj
zU+!<)w#;NQg+wC3=OrfUn(T>)y40AbaObE)mX5B<YjUB1cgQ8fmW#K&<eSm;#>Pfv
zCnhGcI|S{k3;VL|=;%;mvE^s&OC)n`ZEZXA^YeM;gwk=j63m5x|I$D|mo6kM|GP?;
n48F??3%guMuwSK%2aW##N(*w>#@c-p00000NkvXXu0mjfjH^P1

diff --git a/assets/images/flags/pol.png b/assets/images/flags/pol.png
index 30d5a937142eed15a38ddce4a631634da569e945..1188eccd10748b7b8b9228c1868f93b71d716eff 100644
GIT binary patch
literal 366
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TRi
zr;B4q#hkZS4|cLR@;G1YS|wcYZ>EHg^WF5t5+-Zzv#Tncyk-g14FLzVs_yacjsNVx
zFj;p7gB!!@_&XaJ*E3ww%@LnqzG&})J(6Y#-%fJ$Gd!Y-$oYQug4aJUd^Y803AowB
zxqxNEucNZkA2<~59(v96$t^}-BfpJzMXk{x)rJc0_1q_<3&BoU0Cd81pcD4!DdZpd
z+Vm;yM#C+2<rt=p?H_hE>=C@qeQI_hbJqNx0#1c{Xa;?K%n0)<1H*IskL){+OMTqi
Rw3GuR>gnp|vd$@?2>>=*i|zmb

delta 698
zcmV;r0!97q0>cF%iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP00075Nkl<Zcmd5=%c>$V5Ka2w0~AykmtJu_
zJ6D1OZv6oN$N%vs+zPtXg)ky_si1;j+xDZTPHv~k?ddynmpKrtI$bG`l~lz<h|iE^
zZ9bnnkVGWEvMFhfY5$+Gjv<|be{D`o0c5zz$z&q$_q!YphhnqYsCUq>*Q-1n4pjJI
zVlWseAMJLVw0#f+vR<!~evfhJ8;{2XKj=rF=~wI9?N;n|yL2|2(PFWHkJKazf^Haw
zezjV4qbQPb9Lr|23DW8dq5Hm1m&--`3&k;7|E`_qdBl3!>2wm7$$Gtxf2EWkKA62b
z8jb24@*`P-G)<4w>9h)N2&9LP^Z6`auNR{GCM*F*@$Gavxx8c&ek3ej71mm<<_gQe
zOTy8*BP<6J8!{(~L=l#OryfxSFPRfXrVGo!B~NoAtEZmpYCg+W6YX}pxvq%n1#2_Z
z9*YHQV=|d}gMv@G^Y@Qmf5ImCKYcRGlTyruYZJ2aB=VifC<WF4byP=G?e)S^Ab2`=
z@`&09kX$a8O1HX>BEk88veFe%&Du5~!9PV5tZl5L*qO|Ts${BED%KG-Iq8U|`~5yi
ziQa`JNJ+f&sUzX3|NC&q(&O6Y;h!}QSvcV7fzZ)c=F~i#-EKE(f3;d4wXfi#Xlp{-
zV!Z3R^mshte!m}QMAJO$5moMt_?R2=fPfdWl4$Js$tDj-G_yameQ3SWXehZ_t%4^*
z+v)~e$X>6fd_m$_+cL?J*XHwhJVxLovg2|Y@(TkhTpH-->_WmRzN3;$hQj5ABfhwh
gfE|@wJZSs@bICd!5IYUJga7~l07*qoM6N<$g0#0tp8x;=

diff --git a/assets/images/flags/prt.png b/assets/images/flags/prt.png
index ff5a25fa9ddfb8672af0b9d1e1b0b4f2d32cd314..26867667933a2001c192be5f23275e4ac50e1320 100644
GIT binary patch
literal 2611
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
VTnVtGk<tJF002ovPDHLkV1g^j>H+`&

delta 1163
zcmV;61a$ke6p;xbiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000CgNkl<Zcmd5=&u<$=6#jO-apWq&n^?*L
zp>!HbTO_I&e8?qL7P$7{9&!K)HE`jCaF3jt|A6opkOP84RLMOdZmxt>S&D^wNTQ&S
zuB(VcM3N0Lc8q^4-&<!a*K+C_f4fyaY4qOCycvIf^XAPD;CUF`%JTBEDbn|S<2;)#
z#ca3l(bsH~W`}KySO6izVmOXtoSd8(i9`aqTrOx6{pje(*xlXrJN_7EW@dshCMG6)
zZC@^zjYuTo>vriUb@TJ{zKkRFQrAAN);Bgbu(`R}SX^B6*Vfi#j7B?Ae<2vER4OB*
zqobi}wQAIAHDi2yTu28$DEi3Ah<|u^h!>%=kJew-&ay0@dSh~OvQAlFUtg~oh7q_J
zWFOkw+Y3Lw`FM+;m(eFyGr-;7F;tLs;UmYnLA932Wa<_balJ_|n*WF7s{%cEnX?z-
zEY{`Q)D4WO5H1+nIhnZNe~?8e($W<Y#OMQR6j)jSZ2o6A0^~mhj`P3*3tS8Z2L}g;
zMx)I|rYmKYzw7|Xw*coRkotiiVG`yNv`NrVK-vM~)Kwk>gCtv=`kwmKE#T{03ehz1
z+XI%L81<^z_LRk*bx>HL634(O7K;t7Tm5uYF{YvSnz~Z}yrm>me>{#9N!daypN7qP
zmww1Ek!uPA!M1J5=Ybx0R0nJ?IM+zPI~yd!;v|7DzQLUzKLGCE57<fwC=#??3^myW
z9@X1jFUSIVm==Qc=C>^W{0-#(MAA`6X9}<r6}St{_Bf?0qzf1d`ioKi9rY#&{_DZ{
z4!GjAs&QPb1m1KWf6^vOlG5g3VCdOy5tUTX3vLm}u-yAaNZ6RYbcp!17@lnZg}b*I
z7r8BXo(r1<y+;^In$oi!9Hn@2VH&j}+1c#zi#pktfbVb9d$M0VP*_N~P)|~D-+q@Q
ze`XR*lRx8B@{>!?eu#na&ef~Ya5#L*(^R#usrO2Z(Lb2qe<-7$d7NsSi8BrL)tA&s
z?pSfk^YkkJ)IAK0SS;4^s1WUIM_T2P^AV#Ylk@Pt<>AUF9#)cy(@l1(E|TPq&zl>-
zFrd%4!RZNoV&&InPECEx58uPnEe{!HDkZUbXDGS81$}_mBuD1v=6c5Hd3Y7)QNfMt
z*WcLQ-ae&Te+yz%SoeD<c^#0QNw^90r3!M*zy$*rQfsddJjx4LV`pbaPSVeCK|qGj
zc!#SqK839R+~tna+TY)|c-b-~6xxq|qMsKY?Uysp^L&{y(L2ZJv~7pBmHwen$S;*j
zHKml?mxO4el}Aam!OAM#U15hZudacV!ht2AOCqJTVb`D8mb5-LHWtWiHd{U=w5={;
zD{^{zIv7i&d}~{htV~T!ow}}D6;3$2E_Xxg!JzZeK!2Y-NSK{%-5wb_9xqIs^B^I1
d-5wq^{sS-xIiH(xHM;-+002ovPDHLkV1mJOD~tdD

diff --git a/assets/images/flags/rou.png b/assets/images/flags/rou.png
index 49b36b438d254a3a8a5c957df494a81db4b1f9cc..db1e24ca2487e378d7f49adc54242b67f60a0ae4 100644
GIT binary patch
delta 339
zcmX@edY?(LGr-TCmrII^fq{Y7)59eQNGE_W2OE%lG^5;NqM~>`qoAjYV@SoEx3^FG
zItL249PDe>o!vKyVekBkSv+s%3I?d|<<QxGey$}aP!kaR(UzYdU;TWmd;OPPPu5PC
zfAEm~1AoOaU5z})&paOl?D!v6aetDMTEFnK>;vaFH62%{Z&=)6(KTbULVMwJgLQt+
zvhK$Vzno#_Njc}ROf9M2ZIa=nIWspb{3ChldRWWWDG}Z?_bPNprW>v{d%Q;NSk|LA
zZBgfJPw(6+n`>)(?ecPdfs8p0i@78_FL5*Va+s)H0P~r68{Jr>gfloy{1yZ@wmB#>
z^>Ui9NU2{~;o!VLu<;m+6jQHoM#uui3mp#0K*h&6O|*bIT^48>0#!d|k@~y05fmyw
b@I?P7Tjj;L7R!FuA`sux)z4*}Q$iB}R>guj

delta 696
zcmV;p0!RJd0>K3#iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP00073Nkl<ZcmdT|yRI5B5VgHa5E6)&M3I7v
zsM4jNrJ%_t@Fn>H{vv;nhM%B|kf4bKX%He;R7gA&5D&4eGsj|9X0zmSi!1pa$(mVv
zYz||ucV>jRg-mLlPDep%t>rzNe}txN`xoXaORAV{M9ctWsL58VCAZtHY&05TI2@WW
z=<D@bPN!2H`(vVBubVZB#iC~W!{Hz^nT+Of%tK$Z+0<AE{phpTWqmXniSc+Gw%cvp
z?RK$7XcGlN?{qq)(&@B!KA&X}1TvS)fwcKS=&4jnuU0GZKg8#-{-~YrfBTyBuv98t
zNL~hmK_I0xE*8Yzo6qMTe*F3Ji#R`t2N8V#CSHS|t-`~$#QOKw&mTYGXL`Nf#U}->
zSL8+Y8j^1f^57Hgo=3ZQ!L#B4I#Zr-3^pev90y)P$cQKov2YB_<x=qN5fQ~(E*wKX
zpN}{>z4g1@E@a(lqJ=`?f7YXXU|ohG$_LhEyua%SSAmQ8=Xxra%fdCldF)YNI1D(C
z?)S)}PQOST<8ox}ED%rw#-q&IHEcE;ZF|(Pb}=Zym&x|1*?OcI!ZFa*bo;HR1T36P
zCWxe;g(C=sex@AmLR$~A`X;#}=`R)wpOP(wqhN=A(C-}&J2}I-f8t;wzDC^E2HRr3
z=XrX+-v_l?4fzs?hS7yjL__L4le<qe;XtXYk!ZB=kxcfGXm<bAcF%e?n>DiE?;nl?
zw&ey}$ZEA})`G+{+Y-rBrBXT0X0tOmiEFx?gs5N;FB<UkwIHG5V@XAZSn)!MI|T{Y
eB^4eRe*vC?qrVT;4t0+J0000<MNUMnLSTY8?L>V5

diff --git a/assets/images/flags/rus.png b/assets/images/flags/rus.png
index 2633dcbd057fd6d6a0839c5213d01d3c3f52384c..460c7b8138c69e826822f7a70548d73cefc95560 100644
GIT binary patch
literal 371
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TR~
zr;B4q#hkZS8GBg_d7Li_t?pWw(C%;TQl#M)7kh8I&w;W>hCs~_&=5A~x7gnKl?n~B
zb!RZFV~E<nBau0daY=MVjKjT-$E;7!ZeZL#zvqLf!=BdTtWSC^;sWmRNEiG*$q~<Z
z1YObJj||u9y5^m?5jb#8%!eVGVQu`K4UGK^mvm$F6!MRJYWkFRqv5W<TLrhmy+co#
zKDp`WYvi}_-uRo+vYp`(x}yIT45scEf1F`vJd<;f#ens~ucN%u1}qcu5_dN25qt`E
z+Ge2BM1W2M88$_Hiuqx-Gj&FXf*C%FP2)Zx9SC-;0noAM<@sSgW?+!`-)TQh?3q+0
R*YRH<QBPMtmvv4FO#m4rk0k&A

delta 693
zcmV;m0!sb!0=@+yiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP00070Nkl<ZcmdT|O|IH75FRH%6bZzigwzcW
zvFQO=QL*3>T%f1ulG}8_CD<at5>^PIE|K_Ac_Ktf?9S(hBfm7XUHW~JnTb6%ALEIc
zG0}U7qBfmQJxHaLcxF@3Jlp;se{(%cdO6#Sm<Gsj6XWq%T(4I#7z}8&TIn(9=kr<Y
zb~}~(Vbt&U^%~7)QyKd(3`M0<QDz+T&^H>56xKmM`s{U$zFx0sv)RbWWTIxX8P<?C
zQ4sW_C@Pi9Wj~H%ktB(z)oLKEzYuz<R8ptYiT;NC9HalQT@VC{b=hjQe^Qp|a=A=|
z5N~TRdw)0_R@mix<p`vddv@L@ZUG#rKiKsidlB*RLXLpF_`<vA^Dd@%_RIjsluwSq
z=H!v%z)J|35k(M_V>lj<WKNHaDBf~%4E1_F;}qBf;_DA`3141cWwlz>y3;Y*Xf!g9
zYN94!U4|xV0@h`GyyFQ+e}Rkm<9KSf+vFPHJmb-T90r`n=lfe$#Vvc0*1x`!OZZm(
zoaMwOvvw9pr~weoGIQ5(xm=X(QO(-Lqy+y=wnz2Wqs$=3z(<oby7nj+U~;?Nri#>0
zas=SQHC)PD53=fAamO+^91Z~&TOLBePW_-i3lF<ELtL3;BELr7f7XVv#eCoQ)$Mjm
zdc9sUpU**5W(PhKmE0M#yCa?ua_Ooi8ZUfjlN%(O-T$z?8J*KIEf<SLcxM<}(_jnP
z?RNEAka#w>Ofu?pI`{p4AA=J;%H<+t7X~VKX<(io7ZP56Och)*<Ss8fdU7EFJ5_M;
bVDK9hM=C)$++G?03jhEBNkvXXu0mjf{F6Fg

diff --git a/assets/images/flags/saf.png b/assets/images/flags/saf.png
index 3b9cbded835862dc7257ce7bfb0d046fbe6ea1d3..9accc6b5f9ad41cde32436944177d41b8048d80a 100644
GIT binary patch
delta 741
zcmV<B0vi3N3ho6ViBL{Q4GJ0x0000DNk~Le0001B0001B2nGNE0OFW;IFTV2e*&OM
zL_t(|ob8;!Y7<cuK(liz_zxPvruyJPCPI-)s2go5VlDU!F1oZZLPdiJMf7b%#HAaP
zMZwaI6sk}Jmx7c^s3?kbVO@<$D_$9Kqs_w5nRnkL=fM4eIlMFPPH0Od0000000000
z00000fT5xi8~LA^Z^n{z6Zw~)f1Qr(+-}IH$THFXXONkIbSCdj%jTDN(u-teSw4@C
zAtB09KsxqDBu`(rdP>-Pza`sOW|0u(D1ao{Fa(e!t1o~gS$zQ{$sSC=)rS+A2uNq@
z{zYkTx49)neF%`3hvnJIbY>E`CE5N?fUF&obUv=v<;<;WW+GVJY<~jMf7yL?T;?8~
z%S-}`o9$1)?;%OzRlsIz<Zl6g=EM4gpCl!T?A%-!UI8PfDv#r{JtdGNo4<ggrYh;o
zT^^TY^~in^BuTsoNT*(_$wqUu=V|bEOX_yz+ug<C6p#){vbq9Dk_|%uNwWF^NRrhT
z5K@wgNM-^;NzzaYNasW#e~a7D3Lr^=2=JYxN<k-A0lt$|Dd6NTz;}`=1siVyNRrVP
zK$48U0Fq?F5O8T`ig!Y+AmEreEqCJc+=^m_6L7Ltmp4trUJxrJh~yZZTM)@HdV2uL
zF?x%bujJT*|2~kp0H4X3<a4xMa_0F#hU5g1piq*tw7emw#vVx7f4V}=fdqt*oKE+L
zG!|c|KS=KaLb&C$x4z1S*(d4`(W?NG<MafO9H(~zNRHD<5Xo`6?|`?hQPn?DN|If<
zw(wm2WvM2BTaF7y0E?B=6X0vH`rg@->y1_QG=!5N7AsK|;On1t6!lw9Id1_Z#}!+^
zpnuCLhb&+aKOdKiJ0gHvj?)o9a-7}?AURGiK_tiJ^9}$200000000000000e4HCZq
XI;qe3)RpYl00000NkvXXu0mjf6!=J6

delta 1314
zcmV+-1>O4Y1*ZxjiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000EMNkl<ZcmchbUrbw79LK-6y`@yjC{+HM
zunt2qNt{_Q0~0hQnGen^VGsDA)3q<Y4ty~#CX_eFG6O!jJqVhZ%<wY*zZh5l5JCb$
zqhL@11*!!SXc@J%>!0iIci_}Ze|HO;w0@JD^Xt98d;00`oZqkK9ALi`qs!;>nYh(7
zP08nDaGCV}hrDajwWb{3ESM0((51NDZe@FWTWM`=#njZ4c*b@(999+<7POonhNh+_
z(MM%vr6&D%c6Jn-&8Erc{2t%y=;+Y6AHL7`^!-YEW@ZMnv$L7*?rv>#e{_`l$ml^C
z(40slELN-4oJ=N_R4S#EmzOiN_(HZV7K^sIxru|6`;N39)K67ajqFTSRaKhW^yK7Z
zN>LOMVi3JK7z~z-KkN97(2vW`T$Q!(w4O!Z*;kNS{R`2rKF8MZ4g4P>>LssQagxlG
z-|tVG$>3o!$K!Ezt@+r1f8IF~{~P{=U-047H*i+hqy5E~U_W;rndml>^S`5*q6j)Z
zh{WEZk<Elcp^QmBU|3IG*zl!5cnzM>cX8sX7a#vQi$|~Y<FU~%Q1-%k6jRJ3ZIk}N
z@Do8SJ~IcmBZ|X-e~fKpfvu;XMzO?6xDS*kvG+P9%2o__PA>{*e^==}<OA-!`6j#s
z9ki;bd+#QkSA0<G>rqH;Y-~VQ4>3m@8X6eb^5yq|w}x&<v9y+g=czP&C&O^rlK44V
zib%?QUq?TM7BDn+8%qR!=DBldeC>4so1CAcc^t)2^{Lr*m6{~aQBhQ>hEYIO+r-4g
zmfq3x{3GbQcnq#ue-$IEmFQorK_Fg|x8vOkagnM;4WeIvhWPXpj-rl_J~?K$+v8N9
zQwM^wT(xEbE)&2EIkM^?;M%;M%aV4vqYIAGG8{$i?d=tm^*dS6mX;O^72Q%JP(84Z
zU@s9g19Nma%EeThe=`dzl1Wb3gA`ax!*e~16PH5x?uT%;e?sIdX@!;v|3SxT&hAPx
zOtL~smM8g*q7)n?N11}YS1ZudWhXcjdjF`yV9<$TOOAFH)ai6$etsTCfR`_nqvwJh
zpqkmgSS<kaMUoSU6RD>F$<*B3jFOU){SiG3aA@V>0Q;|vA+UTGM-c~)k|`U}`x0rl
zepZM~9|=+Ye+)c${T#XVEBXfra%BrgRommpu8A2myLfh=vWj}itv_4_?{qEvk^IBw
zZaPJPFN@YcwgT_9ThuP2kdg~{5m7eU+S+hupjrTSJ|tl08-)jCMIsSxZf;K4s-)&c
zN#}Iafq?w4Gu+)P0C{LTyNUxS<#0F@eMH63^ESgDf3X?AK*_<Yd`^_e-2{5y{uYBb
zCQ)orY0A)cMA#ytv;oVEkB_Hu=E-HkZqx(HOvXJ`Wb)wqlLEHr(zIpT!=)*jyt&i%
zZSEL+eSKY}|9ulr1>WGv_t@rpMt$lxXFRWX$k@*9BiC0i>C5k%&1NkYi=|vH7w?xC
z^xv%rc!6f<W|G34;DrEfT}8_mbsQ&`7`J@s@9+7>q|M7RZfSwDL;J9-ue{io+s4L5
z(HFP;S^5%WqNb)M9tZ@I%!Iw|vXQa}2Dyg@^7Gz-gemu#(IG?5;e`o#4kXym=-@%>
YA4O!x;nxv(wg3PC07*qoM6N<$f-ZoGN&o-=

diff --git a/assets/images/flags/sau.png b/assets/images/flags/sau.png
index 97951983a0a89eab9edc06ebfd093923f0f0baf2..255dabeddbe0895439e11dc9ba0daae4bcf517c5 100644
GIT binary patch
literal 2201
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
PzXkwlW^Gz)ax?xve&0M}

literal 476
zcmV<20VDp2P)<h;3K|Lk000e1NJLTq001fg000^Y1^@s6!MV=%0004_Nkl<ZScUDC
zPbj2e7{GsqETa)EQKQ5jgu|9XEe8iVh}@8i%a*2$@~^DOZp*A)lp0E#l7r%4w-jY%
zV{61GWtfAKT?b1JON~BeK5Jg5nVKlRW)QyL<$a&t=jr+Ny!F1I@k|Nvi)ypQ19@D}
zz^czr_mCcH&_sjH(-sw0>DtwcK0E?P>o~=kdA_r#@JNJJ;@jIVSMu*nR9Bbl7f00R
z`$?ZFE^5X<v9P`7%aN5cWaW&sgk<KnR_;es2!XIlSbmHE&{b+8#GC^_<M)0(mzlBs
zwj=lb0$}gsGyv(H<zytLP&8;(-80lL$}zsbO;MOGl#ZFNxXu;a7Yg>j+sJMg0<bj<
zlb8CM;><TBwU>|>{SsqLJO|EyEblt#o*ShitB}q8otqm;`yaep)e{}6Y~iGL5n+{B
z`m@2IWtJn^iM!v1M|c1*G!^h}Y7hX^L^pl&V@$69WVosg_kRV$izu~iwVx^IXrjR;
zERf>W=22e7CEb`8t2c0bdP1z;;Csf@5|C(iPjw*Ws(3V4uZaemM<c57Y`FxSzKWjr
Smh*%F0000<MNUMnLSTY|dF5mP

diff --git a/assets/images/flags/sgp.png b/assets/images/flags/sgp.png
index 5782ea1448b20532100edbaeb2afcab47b8cee9c..a677561d43422e8442382a789a685f79ab0c74c6 100644
GIT binary patch
delta 1117
zcmV-j1fu(f2jd7KiBL{Q4GJ0x0000DNk~Le0001B0001B2nGNE0OFW;IFTV2e*_gt
zL_t(|ob8%hXcSi%$2YVgRjT#1D!%l|*Y>g9)Lo-dp?E2+6d&rPMX`h`L5X+=B~)5b
zS_5gcU<0PLMZDBv1kv77s>B;!&}h7%i4U`TcJ`9ZuI~QJoHemCW8+F9-|o!+2Ok+S
zXNH;o|D5lebIt|=gb+dqA%qY@e+VIj5JCtcg!l>s17HMRm<BW;DBHnkK#&IbI>iNE
zSPckOBD1m<$+jI(Xa7R9y9<U9LG;#jBo6IC_VXIx-Iv4#faeUTu0a3BkD#tzfT7I6
zh+eyd^tNTl%^5HL((tMQ`Pwmvx3}4ZHzHB=eZ30#@GJj&UA8VHE(FTme}Mdq*PzaK
z*u;<Y+%Ke>r(IKBf&9#I$h|)a>f%58IA1$fT#)iKV9LudPaSske5(cwb)A)}BE3C@
z6m{b&vdi8U7o;o=NH>0J7hjo3eY>Hk2Z*=-fXLn3=xb^a7o#i<$WMP2kvrY?g4^At
z|L<&@oBg`|+He)pTNmp3e_;K^GunGGhHXIqx(|!${Z@@g{Iu)29xncCtGGZVZ$SKL
ztIL3gi{E_GCRB-3^E$*%pF-q8FU%7MkX`=HkoQb)`55N!NA<nT-;SVv(*kj!O4a~%
zsnbz>l`hJ*cA-kdI{(n;(_btt>cJ8RTXg%x{%^!ZDro}-zGD8HfB&6r@-?FoKe88@
zHFJ<^USFI62bz(opM}KFP2wVzwgEl&?FQVs;WogUgjH7*j;D@#_JdVd3{Kp1`^VRM
zF-9N-ow28&XiTRZ=@)}v42b{oy}Jl6d27gPa`Pq*>pVOZ!#1FQ?Fa79(3Xuun|Az1
zccFe9kLJID<laVce__hT0Bgb(y?xVF2dsrTXIpD&!aR9Ue<{T}+L7M6=*fM;RY<jL
zhPv=KBKPj<8S<kAlf?xpc>}CSH-6$C1-myrwQXwmW_{jTHFcR8u0r(sWqm%g`aN-R
z%4;#s>e-I@K&F1Ct8KD%n_hmlzVn@5H@UeJkZjwDOv7ySe|=RaE>8Ivp!WjCLY;Fg
zNB8z1vtqivUAU@nZ0&|Q>Og+roa5NbF=7T3Oc;asv3>3hnWl!~zW;;%ixD+oa7%Li
ze5fnu?S;AP3esPGrqhh{OT*I!3`D3B*%i}}+_xRE&Oh~L{NSei;qUZ0ZpsJvyC8UW
z1Ta7Yf~DUPe>ehyC2oLohRZNVR0A5IWIGiNP&B~TX)VASVA25TUTAOx$O~aG1<8xS
z8le0aEW(Ngi1$K+BS2mVgDFT}4AubUzhDtoG(fx;8XN)gLKsXz@?x+CDE|eEu%ZFt
zz0lwYkQc&W3X&ItH9+|<ScDY~5buQsM}WK#22+r{GZ?G^%74KktV-MfLI@#*5JCtc
jgb+dqA%qY@0$$=@XRi&wqs5nf00000NkvXXu0mjfp7R;L

delta 894
zcmV-^1A+YG2!;nCiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0009UNkl<Zcmd5=O=uHA6n?Y2Ng7N@n?j`u
zZ7CM(xtAV_6p!9iswYLzTM;~}rye}?D&kS_-h&>*n@~Im)mBf9f}zw>5d!(qr1^2P
zJHBtstdljVy)^6x!+SIPX7c5mf48$UL(~n?tE{Z7Sg=w`(J!V)vCR1Y^tB9Yg<=C@
z3LwKpEG{mJYPBln=H_T?YfC+YUoMx$&d!bu{V|%Jo>pUwjEqPf-)J;MGMSY6Ir^b(
zVPQdH9JHg&99R3>+uM}O<@}|kCAqe?hB17TC<xlERx6fBBy87pMZ4V=f9Z4@q}30?
zkHuoLR4UP72=~$cQR5uPk?i}~Y}RAzZEkM1g%C<&V)pj_{(k&rg+6h0lA?jHS578o
z*|yi$*FA?FNN=%<oF6B;NLr`HY3Rl^;=f40UcVvl^A{Q*CVBR3o<&b_(XE_Qwi#v5
z&QRw0GexrT<SF^zzSGe4f2(ArQ#2@;oUDF9>Bp<AU|x{~Ia#fd`~D;OYzIjeFCm#k
zk;K}!&(4r_dR$GnU{cBZcNIB3^~vR110h>17D=xj0a3i=+LyIj5DX;`9y}!ZcO|2P
z)kjL%<3=Wv34XNa)FU5J;up^U31W2<mo6$_smb+0pjNB-bQn>fe|qO0+2_tEV)AE|
z+;<;Td+Wt3t{=ae!0_;Jx1u^>O&}kCT)wH)OD^9I$U$kW1cL_F(I8>N04d~W6yTVZ
zZ0;>Z3iI>-E>Bnrq6j_Pfuf_MqZBnjym&mW6m=-VfOx#V2MfNW2t)62_0Br7z=j%7
zifYzTL#0xYrlN|qf4M1%3h-qz6;)G@V+KVGyfk%x>-hlY=ks}wPk(z95%|8p$7eW?
zrygWw*Wr$>Qz#T1K5SV?1#{~Mzh8Qohco1r-b{qY2*;YxvFLBxwyf9d?Ww6LoR>h<
z557!H)aOQ*<!*6@1|MCOMd5*)98!lxG21(_b?v88DP=b{R5lt-hK|(*v9J>p6KX72
z)O9SAY>kbLHFtM+U2vk#ak&?Q3xn{bfv$HhB&_hWUY87^%L|M8Tu30U*TsXzZ^Tmp
U`=k5dkN^Mx07*qoM6N<$f~h5^zW@LL

diff --git a/assets/images/flags/usa.png b/assets/images/flags/usa.png
index a8c44ce75b7960e2d1cd9cd820ebba0ad23c2334..30fc880b74cb7775b913419e21d038dd5c9ec206 100644
GIT binary patch
literal 597
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|OJg
zr;B4q#hkY@HhM8T3bZ};Ub;6)+uKokV~9)020=%`8ix4?qBe4wEfWybF%cB;77TRR
zC@98vGR!IFW`iQ9RPMQ%cWUH$wwK>-`G5cBOwXlEK%0<&T8Cj@s_<6}F2R^m6=r4`
zwh4^(2Sr1!mb1QnbC1t<qw72Ue3QqQst)Jz&WN||?rh!qIp0;IYJcTdDe39!zwyk7
zwCVNNUwb33zJ$f={FizA{vZGM@1S!|>-Qh7QOoo9vi<mztMd4~<c6)avelmN_cDp>
zw707j$$$6hT^vw;8PAMa)-Q!KioPxJZ&>u5zkmMj>P*`T)~WXzLKwbheV1K$$#^fn
z*a@ZY*<X+E*i?D3bBkGe!?zDyM~*by31G{Z&EC{%>G0V`Ku2Ohr5s0?k;7{nfi)5f
zN`Y*i3s(Fr+H4uT>lZ9d;XA>5hVj;~|7U{OGT!_*=4Q)y2P1(>-u^e%&RucspZ(^f
zhHo4|!x_}|H6$NAaec~Fq`HdnQtmAM$^?f##z)I9OlJJ#RIyH>(r^Xi&b>dja(Hjg
zT==Ask&pR^f1(2OlU9xx$4^NC%yafWSl<y-DXsOFx%MP8a}ke#ed|1)3F3!}Sx<H^
p+{EUAOPfSg3nNnefS6jT4~1O={%z<exHtpE_jL7hS?83{1OPxx>2Ux6

delta 1215
zcmV;w1VH=M1jGp;iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000D8Nkl<Zcmd5=O=x3P6h7}Ksi7%JQ|NRU
zOiRf)BUorDOoF6NL6B*8ikXGD8W7w#3&D+UD!6eoV8zWWx)Ov5h$u|m*|EXW($K=t
z4q-y5Lu+fGX*FqHLw=s;JLwHCe<7nT9z#C3ocqo__vX9b{mH$Ts2y6jw6L(C!`im3
zJujw9(w*`DQCD|Zy(6|oOaL;RwAtBNtynB-)6>(GPN$^|`ID0qEtkvL9UY_b@o{Nm
zaB$F8@s?$2KA+E4<){Z=JRY~v4*c*r+g16UogLcU-EAZi2|JlgqK$@=e<%nVl}g3a
z*VkuMt5vO5t7!uR10XFwh`h(+u?vL){Tn*#sQmwpGfmUxd?OSJ)!EiJH#cjVrisMF
z?2Y~XeQz*0`-JSqXt8K<WuG*N{MD;h=;_k~x_mh#zQe;p%ZE6>-$zqVHt01gPcGv3
zdtv`|wzZX&mAc6pNUyVsf4ZTcjZRHPgg}3Plc>%81QC$5ZKZ~fB24t?s32uXBX8ZL
zS4M;6B1Q{K-xxfKb$po0%X7+r&1Mg1=8XwTtv(jAAPC>&WQ11P2cR>nzdja%AP<Ev
zCEliM^HFjWzVDU{o`Tdy6c`x^$&i8sEC@i|+qZAhg9nd<V5wvYfARVG8??N<A)SGL
z_ltYf_oYQ{1B<YYC?+w6^6bo_NaTu;fm(BOH-uz@$tKyNGx7L@_-1A%XlpAgO27Z=
zH423caudftd`p2qpt;DD6RX_AU$>Z8(m?{M&CNG`P#KF0K9p~7XQeI_eVOY`xjgiN
zUw&$BpJrzv2th@te}qK?63Y)aT0RW@ojbQ^Y3XP2fh;-{PN!TS`ckRX@caGUi9#tT
zrdB`5sbPnr7<wVe>McK97ax*&ct*a^Ai0TPC9kzDCQMk~bj1N;ckjMKi;LgOiU(nt
z3cM3wkzpQ7XP6``zR{s~KmCAScX{Y37HehY|CIl}crBSee~%gc3-b{}4T4zpAmUUM
zbJXdB!syWTKXWu`x;ykA=e7f^sKtNHwYH%Lxg#bA3xEI;<|TZxv5z$USyoZS0ik{m
zQRM|}Pshi{wD|Q$)KlQ0SBIMx(V?Ls`t7|Bsh0rpyk2j+qJVYq2lWyl9?#L1qOD`t
zn~#2^UczTQfAs2%E2k$_u=UC3)N4=&cu^FYXf#TNjWqQVPESwmOeQ0FQIlDFUSgzD
zslTa*5R1jy_E8~=Yewd)`_xO|t*OD+5y{J{=L=Y4ZEdZdS-k&DBP~ol0GsS*l}p|_
ztBK2<-FCTSYv%KLlmGX1oKJD|Qx%biuUn(e%NgcXe=rzq?tL9?bjCWNVo~2P47*$|
z*T%-ia9;w^hOPpcXoH<qmb-#^!B<zYNZjx_hm>KFoc@d0vdZ(ZOzislx^>P_u__@J
zHXII1Td??6u}rcuJUo29x3^aXC%U*UcSGyJp!3l{eP29C=$&QV9vM0wFLZj&g9PHb
dJv=D<6$8r>xt=s2$20%{002ovPDHLkV1nqqMVtTt


From ec8c404086f0c87e000afb881e9c4ba600e5602b Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Sat, 17 Aug 2024 04:25:10 +0200
Subject: [PATCH 47/81] fix rosseta builds (#1593)

---
 scripts/macos/build_monero_all.sh | 11 +++++------
 scripts/prepare_moneroc.sh        |  2 +-
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/scripts/macos/build_monero_all.sh b/scripts/macos/build_monero_all.sh
index 9f6130066..c934b4667 100755
--- a/scripts/macos/build_monero_all.sh
+++ b/scripts/macos/build_monero_all.sh
@@ -43,15 +43,14 @@ else
 	    WOWNERO_LIBS=" -arch ${ARCH} ${WOWNEROC_RELEASE_DIR}/${HOST}_libwallet2_api_c.dylib"
 
 	    if [[ ! $(uname -m) == $ARCH ]]; then
-		PRC="arch -${ARCH}"
+			PRC="arch -${ARCH}"
 	    fi
 
-            pushd ../monero_c
+		pushd ../monero_c
             $PRC ./build_single.sh ${COIN} ${HOST} $NPROC
-	    unxz -f ./release/${COIN}/${HOST}_libwallet2_api_c.dylib.xz
-
-            popd
-	 done
+	    	unxz -f ./release/${COIN}/${HOST}_libwallet2_api_c.dylib.xz
+		popd
+	done
     done
 fi
 
diff --git a/scripts/prepare_moneroc.sh b/scripts/prepare_moneroc.sh
index 2e53a54ea..94754c935 100755
--- a/scripts/prepare_moneroc.sh
+++ b/scripts/prepare_moneroc.sh
@@ -8,7 +8,7 @@ if [[ ! -d "monero_c" ]];
 then
     git clone https://github.com/mrcyjanek/monero_c --branch rewrite-wip
     cd monero_c
-    git checkout bcb328a4956105dc182afd0ce2e48fe263f5f20b
+    git checkout 5de323b1ba7387cf73973042f06383d4dbe619f5
     git reset --hard
     git submodule update --init --force --recursive
     ./apply_patches.sh monero

From eef319658a1934c15768b335c7164b491de403f0 Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Sat, 17 Aug 2024 04:30:48 +0200
Subject: [PATCH 48/81] Fix legacy seeds not being displayed when polyseed is
 not supported (#1608)

* Fix legacy seeds not being displayed when polyseed is not supported

* fallback to english on Japanese, it errors with empty errorString - probably some kind of normalization issue
---
 cw_monero/lib/api/wallet.dart             | 13 ++++++++++++-
 cw_monero/pubspec.lock                    |  9 +++++----
 cw_monero/pubspec.yaml                    |  5 ++++-
 cw_wownero/lib/api/wallet.dart            | 13 ++++++++++++-
 cw_wownero/pubspec.lock                   |  9 +++++----
 cw_wownero/pubspec.yaml                   |  5 ++++-
 lib/src/widgets/seed_language_picker.dart |  2 +-
 pubspec_base.yaml                         |  5 ++++-
 8 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart
index 973a38535..1a6e5315d 100644
--- a/cw_monero/lib/api/wallet.dart
+++ b/cw_monero/lib/api/wallet.dart
@@ -45,12 +45,23 @@ String getSeed() {
 
 String getSeedLegacy(String? language) {
   var legacy = monero.Wallet_seed(wptr!, seedOffset: '');
+  switch (language) {
+    case "Chinese (Traditional)": language = "Chinese (simplified)"; break;
+    case "Chinese (Simplified)": language = "Chinese (simplified)"; break;
+    case "Korean": language = "English"; break;
+    case "Czech": language = "English"; break;
+    case "Japanese": language = "English"; break;
+  }
   if (monero.Wallet_status(wptr!) != 0) {
     monero.Wallet_setSeedLanguage(wptr!, language: language ?? "English");
     legacy = monero.Wallet_seed(wptr!, seedOffset: '');
   }
   if (monero.Wallet_status(wptr!) != 0) {
-    return monero.Wallet_errorString(wptr!);
+    final err = monero.Wallet_errorString(wptr!);
+    if (legacy.isNotEmpty) {
+      return "$err\n\n$legacy";
+    }
+    return err;
   }
   return legacy;
 }
diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock
index 07c3b8876..51efd4076 100644
--- a/cw_monero/pubspec.lock
+++ b/cw_monero/pubspec.lock
@@ -575,10 +575,11 @@ packages:
   polyseed:
     dependency: "direct main"
     description:
-      name: polyseed
-      sha256: edf28042e7b0b28f97a0469aa98e6e4015937cef6b9340cd6ad2822139c95217
-      url: "https://pub.dev"
-    source: hosted
+      path: "."
+      ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
+      resolved-ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
+      url: "https://github.com/mrcyjanek/polyseed_dart"
+    source: git
     version: "0.0.5"
   pool:
     dependency: transitive
diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml
index b5a13a126..7f5da2621 100644
--- a/cw_monero/pubspec.yaml
+++ b/cw_monero/pubspec.yaml
@@ -19,7 +19,10 @@ dependencies:
   flutter_mobx: ^2.0.6+1
   intl: ^0.18.0
   encrypt: ^5.0.1
-  polyseed: ^0.0.5
+  polyseed:
+    git:
+      url: https://github.com/mrcyjanek/polyseed_dart
+      ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
   cw_core:
     path: ../cw_core
   monero:
diff --git a/cw_wownero/lib/api/wallet.dart b/cw_wownero/lib/api/wallet.dart
index 2ccd560ed..0a06a9950 100644
--- a/cw_wownero/lib/api/wallet.dart
+++ b/cw_wownero/lib/api/wallet.dart
@@ -47,12 +47,23 @@ String getSeed() {
 
 String getSeedLegacy(String? language) {
   var legacy = wownero.Wallet_seed(wptr!, seedOffset: '');
+  switch (language) {
+    case "Chinese (Traditional)": language = "Chinese (simplified)"; break;
+    case "Chinese (Simplified)": language = "Chinese (simplified)"; break;
+    case "Korean": language = "English"; break;
+    case "Czech": language = "English"; break;
+    case "Japanese": language = "English"; break;
+  }
   if (wownero.Wallet_status(wptr!) != 0) {
     wownero.Wallet_setSeedLanguage(wptr!, language: language ?? "English");
     legacy = wownero.Wallet_seed(wptr!, seedOffset: '');
   }
   if (wownero.Wallet_status(wptr!) != 0) {
-    return wownero.Wallet_errorString(wptr!);
+    final err = wownero.Wallet_errorString(wptr!);
+    if (legacy.isNotEmpty) {
+      return "$err\n\n$legacy";
+    }
+    return err;
   }
   return legacy;
 }
diff --git a/cw_wownero/pubspec.lock b/cw_wownero/pubspec.lock
index 85d856b35..f164b3086 100644
--- a/cw_wownero/pubspec.lock
+++ b/cw_wownero/pubspec.lock
@@ -567,10 +567,11 @@ packages:
   polyseed:
     dependency: "direct main"
     description:
-      name: polyseed
-      sha256: edf28042e7b0b28f97a0469aa98e6e4015937cef6b9340cd6ad2822139c95217
-      url: "https://pub.dev"
-    source: hosted
+      path: "."
+      ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
+      resolved-ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
+      url: "https://github.com/mrcyjanek/polyseed_dart"
+    source: git
     version: "0.0.5"
   pool:
     dependency: transitive
diff --git a/cw_wownero/pubspec.yaml b/cw_wownero/pubspec.yaml
index 7a45eb628..eb14286a9 100644
--- a/cw_wownero/pubspec.yaml
+++ b/cw_wownero/pubspec.yaml
@@ -19,7 +19,10 @@ dependencies:
   flutter_mobx: ^2.0.6+1
   intl: ^0.18.0
   encrypt: ^5.0.1
-  polyseed: ^0.0.5
+  polyseed:
+    git:
+      url: https://github.com/mrcyjanek/polyseed_dart
+      ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
   cw_core:
     path: ../cw_core
   monero:
diff --git a/lib/src/widgets/seed_language_picker.dart b/lib/src/widgets/seed_language_picker.dart
index 3bb0376b1..5cb8f2fd3 100644
--- a/lib/src/widgets/seed_language_picker.dart
+++ b/lib/src/widgets/seed_language_picker.dart
@@ -17,7 +17,7 @@ class SeedLanguagePickerOption {
 final List<SeedLanguagePickerOption> seedLanguages = [
   SeedLanguagePickerOption('English', S.current.seed_language_english,
       Image.asset('assets/images/flags/usa.png'), [SeedType.legacy, SeedType.polyseed]),
-  SeedLanguagePickerOption('Chinese (simplified)', S.current.seed_language_chinese,
+  SeedLanguagePickerOption('Chinese (Simplified)', S.current.seed_language_chinese,
       Image.asset('assets/images/flags/chn.png'), [SeedType.legacy, SeedType.polyseed]),
   SeedLanguagePickerOption('Chinese (Traditional)', S.current.seed_language_chinese_traditional,
       Image.asset('assets/images/flags/chn.png'), [SeedType.polyseed]),
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 567d1b210..a2f346bae 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -94,7 +94,10 @@ dependencies:
 #      ref: main
   socks5_proxy: ^1.0.4
   flutter_svg: ^2.0.9
-  polyseed: ^0.0.5
+  polyseed:
+    git:
+      url: https://github.com/mrcyjanek/polyseed_dart
+      ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
   nostr_tools: ^1.0.9
   solana: ^0.30.1
   bitcoin_base:

From e8a03fc00e22a6428996a5f4bf5ba1f127340bf1 Mon Sep 17 00:00:00 2001
From: tuxpizza <tuxsudo@tux.pizza>
Date: Sat, 17 Aug 2024 12:40:52 -0400
Subject: [PATCH 49/81] Update even more flags

---
 assets/images/flags/are.png | Bin 190 -> 376 bytes
 assets/images/flags/eur.png | Bin 1005 -> 1476 bytes
 assets/images/flags/swe.png | Bin 752 -> 390 bytes
 assets/images/flags/tha.png | Bin 774 -> 384 bytes
 assets/images/flags/tur.png | Bin 1037 -> 1088 bytes
 assets/images/flags/twn.png | Bin 373 -> 1005 bytes
 assets/images/flags/ven.png | Bin 1009 -> 887 bytes
 assets/images/flags/vnm.png | Bin 448 -> 882 bytes
 8 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/assets/images/flags/are.png b/assets/images/flags/are.png
index 8eb1e2bd3815aa15b34deb6a323f0b55a87df21f..2df30486a8deca355ea0d7b2cacfe03f727fad2e 100644
GIT binary patch
literal 376
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TR$
zr;B4q#hkZS4`#YL@;F~ysdeVj`Z@n%ULN?M_&epN6o<x<=S@-*QnGb{CO|-fNc?>H
z`}<ek)qi!InXzP>08<8IPo3v!wmmEp@*b8kRw{23pJINP?Td}%LotUvt+!d9^xlXI
zxW^-X;d4q$G{Z-+Jn;$UN!5;(#yJk>CkwtyWSsMR+3yO4hS|C;4C@%&_Ag0gzQ^RT
z{lkuiJ%Y!%Pt8tbeg`y5yP<-+pZkP#;hqJ1B+VY2n=H7GsRLb+wNAsTMO8Ke4yoLV
z4MGQAOy82@z^QQeP!Z5sr@%&K&Fd-PRJcb_<nKqAhZz_ezRv%_s8-nDC!4N!6eR5F
L>gTe~DWM4f#2b#!

delta 177
zcmeytw2x7-Gr-TCmrII^fq{Y7)59eQNE?7K2OE$KXZqPbQBk~}p}^C{F{EP7+p8OS
zj~H;U1}y6eiaGlBxu<gE#5=`nPfz*w)V7mR;6o=vL%qR1ciWYlYp1Qa;9%Ui$;sIL
z&XR!6iyzzE%f423a`Bc3YiOGkABp9fDj}O+kur0qODo$YmQ!43WeU9(3N224?#{-r
caiM(I-p4m3N-t&t9l_wq?&{~V&MBb@0Am+IiU0rr

diff --git a/assets/images/flags/eur.png b/assets/images/flags/eur.png
index 1312b02007b5f5523281584836f39d9a3e8e592c..2500968a920165a9ec656e8c7cc6f94e50c710b2 100644
GIT binary patch
delta 1473
zcmV;y1wQ)i2gC~@iBL{Q4GJ0x0000DNk~Le0001B0001B2nGNE0OFW;IFTV2e+70)
zL_t(|ob6kUQxs(w=l{xDP_%)tTt062I&M%2Bu1+t5jgOKs4-*ikPibA910~06u1ks
zA<P^_LdQx$Y6@*2m1g>!si{ey=J(bfd!I0Hd+)LP{AQlH-Mzi%`R((2zwh0oBnE@Q
zU@#aA27|$1Fc=I5gTY`h7z_r(e^O9XAF=ri%K;0Z$}M0lfXV_`x`|8TKETHU$S#En
z*MQh0VSm*L+JEqb^rTw03A%o%fMzZgNatZG0Sfo^(fb20(zT0rq930ShGSf_@9UG!
z&lCb2X*w41yOc~XjSW}$ldl=B;k)(tWC7HbBsg9;MgKf_GHPi~&h*maf9;+A<l`9E
zBHa&P@Cn~6K!k+WxIEO^<)pdKb3{^Sr*p)4waXK>7W}!COiQyF!f+g}^y9bi0blS5
z-#ACCXo6X?3932broZn$70|5U{LtZ+kb8F(4U)U1k+x-z3d1q31>c9?hVzM7+ysRY
z!E?MJAX&}sS2vs}_|W@Ae+=#eA|$K5qh2KGr|))%&(=2AhLZ&!dY_2F0z^nwM@K!?
zHn>Im>}+sTTl?V+CksBD|NDe*#IU>o#TC6&UfCrz5qbj`aI#D%JTYEEQ<Fu~6R#O2
zauXkxm|K9{lGF57r<1&A%jwa>EuuX>KUyY+g_zyOJL!mt*x&#zf8Yde;0Ug!6Cfqa
zOBcpULuRm3lSQ;WXC&?dq~?s$<&TR)_)MPPBZju76F?K;-dE51A9nfcG?9pSCtoiD
zIB0yp4IE9~2mG>-O26IRMn5lXr@!tihClFX1p*wv1)RXm=$KLk$S545{=Q1_nU;5!
zdV3C0_U<#%1VC(Xe*hOfH`5Bh=3@aA$pwLHfNEg@cG^FXUIG=#9Hj|>vGx2+mgw+g
zCs~PLPv@Q!9E}_rOA!DMq^(Mx>aCJ8@lsYXZ~`}N71k&b;x52I|I74f`M;$H%^ojr
zA>X-jY5z*;4IIGbaS%sv2KP-bz}D<BvG}Hcxam*rw8NG-f3*Nyz)8>XlkvTR`=%EF
zR@c}Z^MAUO7+df^XW(o^94P|yoUEqX*KE{u^eA2btbm5!J0LybN{|f=9uVBX5nM4t
zHjMzm%ezJ{_bLg_QHlU;zQhwC+AcOF&K6HD2_ZmLT}#4j6;!Zo@wH=gu<p2Z1o-l5
zE-ifVTtd_Wf6N2Ey{U?h*VF<Ol)g(>CLHwrt(85UOS2htb<#n*<Fq3|Z-|N5;GppV
zH*f@3(+L1;_B4jfIC~8m?ybc-JL^Jb=&fxV-;0#60>Hkxk?DWnALi1fC0{de(D;Cx
z(eb1TAa*q`CezI;c{F{|F1CWmT$n>_Z~zx@0ym@ke<i5`q~{L>j5c1XZl_(2&|S?&
zEYgMZiP+$vor4=VnpS|d+Q?8v%tbK5rzr)fs&5hPab<05%zVD$Y!yB+|B(HB2`j+c
z-8FRMaz6cjZ>vZa_UYiftGjmHKJi=lfG_xjZ=53*3lNkn+uqZ(H1|xvu<*g1bjmB~
zUw5)>e|ydZjPr%h`83LV-neo8rmX>r>Z8Wj-v~&StLe?C_ZODEBP`lI@S*pK7&4zR
zp#|tUSxtW|rqBg%sTdM=cSUb1#z)G8MY{(+;0r$C8!=db2+68;dHgTiVTc&+1--1|
z0kM#W88lu!h2a?2@Lllz@SzQL;XB-0ms|tXf3+teJ%5;PP1!=WmEW1kHhf>F>6;*B
zjfTBN59e35mE$;(_Zyi`07doDuXj_$JHId-%jRP#0aV8zeKb}o{<nqU7}sR;vWx)A
zCN>s8WdWp@LWOI9{6r|+1j$bZ_W`Q)Y}HPf!C){L3<iV2U@#aA27|$1Fc=I5gTY8L
b7Zd&kch!_kX|6Rd00000NkvXXu0mjfDhR%N

delta 998
zcmV<C0~!3p3+)FXiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000AmNkl<Zcmd5=Pft@p5TEz@D%L<+TEmGy
z4F}@QCOsGpheoa#^-zyWyy*qL0sRPgBJm)2GO-6^@JiB)k|vOp1DFs(3iL#5DMI?k
zzV<o4wfpjT7VW-5!Y|p(yxrODe{^PNc6N!*L+jL1sgw?CS(bK@OoygB<^MBRcTn9W
zYbz!IWw>dHL_#|~J=NmzIBjffh%xZT$H&^<-k#<9V>CWKF4h<v9JHi-wOZ8zfq*5)
zF%Nx{lam(KK|lJO>q>rWYm2tGw_C|%(n_b(Sfk}s6bkz4^}4^Wug}+Le>61HG_`?&
z0Vpkg5WL^-w@RfF{R{3nlJ8c|Fbs?NRyZ7PGHtG}ubY~t2@?}*?<*7vH`ad5eCN+G
zx*ph141Bo5)XZcuO@kSjUS})n<i9pb0%PnwAA7Nh4_)^1p7PNpAQ~xB=vIX;15TZE
z>Jd<C=D{~xxw)xTN=>iWe`8N#xt<h95P}-A1DlvkQbxIQiyq(Iq}<^M<(QxQ_{<)Q
z4HsyZ70>KUkQWq-MG6LkBFIFp;?%%;8iB0&@`SDkuqytP3gYxO#H7M$&-CnixO8b|
zxoi1_WSSBaJEVfMv$K}u4e|)MI{)K#*YXRiQ<N`-Nd=)$2>D#_e?n1gSWdbsYf!!z
zQIgLUhN%|_*URIsTfl|$k5-hT8M2t8>V64Ndlc3@;lNM{4#@8FRw-8lq=LWF6H);M
zyPFI}vFB8=ymp^dA-!!|G!jwUb3kn5@JeJQU_5D2&*>?}`)z*uOV{%Ad|KhuQUQ!7
zEeh8w1(HO!u9u1af9c|D@&Z}o%F0?9<#sTk2>JAC@tkXAHoy_O^y0mc@d^~wQc=4y
z_W}gg8@8^@0C4Z@!#^%Ygn!<QDd${?a=C2lrnR;9-(-BPJ^x8PLX>%dYR?HCxM#cz
z^2t=iSuYA_bmE#pHR>5&t=9=0NG-mO2wp@zU%*<sySrRTe_IE1ZD1Yn9j?jNL}6l`
zyWBA~j*gBDKKFIhr?}wBY2Zc8+5yhX8TJ*53GnVU+_FwcS<LtOd{(7WF{9Ba?n_X#
zW#>^=w8fnbHg_HSg0HTEqVdAm6ctc3XMbC^BKiLQenGR@Y_-Oava&%IbaZr7tObg1
zDa%UMhlYk~Jo$XS0iCFQUG4<?!NC1!AivuW61sb=(<6iH@j|By9wZ>w>ES`*H)E$K
Ur5XeJk^lez07*qoM6N<$f)!2PPyhe`

diff --git a/assets/images/flags/swe.png b/assets/images/flags/swe.png
index ef73086f6d3a0054edddd56f218f9f49a9908350..e5ee36d2feb051709c7cb0fcc6d9f303cbceba5e 100644
GIT binary patch
delta 378
zcmeys+QzKd8Q|y6%O%Cdz`(%k>ERLtq!U1xgAGVNno({sQBk~}(ZbWkF{EP7+gqo3
z4?A$U2EJd>=(c=+W@Fn4tJxmYl!T8z_j;2oQP(fS4%7t!A2f<W<1_a@o)Y`__r6@F
z4J;09HBOvbsw=)S_*$4gG+>o<J}q(U8$)+Q)R9AKK3y6?E|;4+3O##P7rIWC+VxD<
zvoG%Rxf1?}@0;uUgG?-Uu`HOYvflS(nQ&NB5I@KNt_v-%&6h3MY&!F(raZ@id9@}?
z8(1G)OnrTU*@<CUeB$YbO7|^7ChvJ{6YS5MJk(`)ynaLKfj!E<!o4qCRo`Xzld)d^
z7^efL!)XRpjj0PRFq=HQ)N)%Sg~vBJ;|8-%QmSC~Yy(XtPeIdl0naZqUE8DFS(trq
z=9LSj_R8-1j1|>_ZxtRZO!f+}@U-%rrgo?AQ{Sgdp5Ao%r;M;5Xm~uof>Eif(~fN&
QPaH_l)78&qol`;+0E=^y%m4rY

delta 743
zcmV<D0vP><1MmeQiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0007oNkl<ZcmdT|%c>ed5UuVR6+!U@!rgd9
zvPhP}MF<Fy?D7FFvduo9kRaT@$Ra=B2V@y{LC~e%jfe?CK=1*I<1mj-RbvnBFeZ{0
zeGfEM(^Fj@t9z=u8sHo(sdc+ue@;>e!7kY(G_KqKVl3ArkJ(1VB!~<))^4}iZntC2
zW)nuEk$gw`X0u_l*-XU#7&ICU>7!IC31#m%4$Ee<LcOPP)YodY1o@$U>eKxyeLNn+
zWHJdmosQ`BdgLS2i4sA}b=_1Zld(L{W4`aRd_GU4<qwjcN~Oely@sD5e?CU(*V@^(
zEl>~3<#K>B7!HR%V@!q^kiE57EYe?|zP(4zw{QhMzq*4LH<ReO|NRNP{PZ6F9>mx7
z<ilfB{C>Y5*r-tGIYyCROY;AK-Qw(7IEw*2an+4$$^yfnbK+n)=p!T<5v4^8hGDf@
zfyy2cQTockFcb=fh?CJ%f4|@FL!}!{v{)=g5vBAb7c3@S2;aPh-$nc8{*T5d;rZxU
zq|1n^1#2=MUV5TbU?S9P+p42dsQ~|YceR6mzt;miTD^mGI?c|Ang|LW=JzP!8~q`v
zGp;&W8w)y66J$gcYtyjZZiOCE$=bw23GGaJMCH^|nE{3YQ`7lge~$%NIGs)d5aBm4
z1;_<!xB#b~$cnS#4yC<ZE^XZRIV}bK=tugc<)Ig6w64@)BJLw@t3%n+c+0ZH;c)Ql
z^*Yr{L^O<cCL|hSr-$Koae#xRtCZBx@exf9B&q5BC)<P4bGe+9gTcT#B9yIaWJ|JE
zt4UuZ=~>w#Nw-?9Js#)txksGfR4ykWx-f`e8mQ;fg#?ekOS)u;U0!gwa3Mi<Nf!?a
ZKLCn&vE83H)an2L002ovPDHLkV1kx=S84zN

diff --git a/assets/images/flags/tha.png b/assets/images/flags/tha.png
index 1bdb04d00001d7a8b71af56f2f69b2c86d70fcea..a99cd4d483a8e78c03cef007fae5e34812cece20 100644
GIT binary patch
literal 384
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|TRx
zr;B4q#hkad4{{zc5OBV@@^JX~nR<6y4=!oS5p_&_UK_wX$;PTBgb`=}1gwn+<-eLO
z$FX1&tFQy-g0G$0(g92!+Y2fgE0w1SPcc8t7Gf{?@K*)H?>qc=*H<buOxB&j(8mxp
zf5#@q?F^T6@5DLW>v+rZ^y~)4<@0+!{H$O|j^mF7DVzyZxD29jI#8huNZ~`U!p%U1
zA`W|64|AW8Hk`9ykEB_`x5<L@m^!u>Q~<4Q16zBh&gjtR$Bawtqu$$32io`u-6}z#
z3AceJY@7=;Vg8+lFa2j;pI2=V0t%l734;w@@arVUbfDfCknK-_w*Pnn3PULP>i>s9
W$i3~n=<1qzAR$jzKbLh*2~7aNMV3DR

delta 765
zcmV<Z0s{Sj1BM16iBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP0007;Nkl<Zcmd5=JC9O96h8OCt|Sm%37ssV
z(OL=`3ar=4gg;@lw%J5BvD#t_weu&CSh=;dBv67OAq16*ghzz%2>0Icd?Rynx!zUF
z`I5;wcjnCOx97|Z=M2#)jHuRVe>6-;A%t<CO++(;_Wzh`2BaCX^@&M<3^$`zs~M}+
z$|#r1)a`cV81%(rVT?v25&FldR4U0eGMS7}_S@~&h{xkXjbk4As@1B%I_O7Va9ySM
zdOhm*`(C|X7tLl9Yj{DTAZYFP``G#Uxpg=k499VdWHJfT@()6f#bRPUf1lIe5T2v-
z|FyGiTd?kBvsss=+v#*1!!V?aiP>9|$>i+ic=we*FGvr3`}ipJn5ENdwOpGOxZY$h
z^8T=NAqiY?^em2|iw{%v@}9CtGXy!=!GR|?SELm_+{l9o)hCKg{P6iD>4e$!Yf7b3
z@{swV$0;Yxz$AT6C!xRlfBc1X!g{^-5{ZP=Pl&#~eos0folfIEm%0qS+ORr95>-EU
zI>RK*p`z^*oy}&XBUH3~qPbj-bOW6C$Au4Ey?I4C;r6zH`~7!T#mzrRm(QM(P5@Dr
z<EqSBTOgqZq({NJQmN37Pj{pfmdm9W3<gq{-elIX2aFe^%}>$@fA0!sDc+-7cBJEn
z9%Tk;2ELj+rOWGy3ovgu9J<{5oiqWsa1H0OH$hgM6n8A`>2zvyv1KAZ4W@q3(HFI7
zusFlMLNWn8yhhkI2xW`;mSu^}X5$o#Mbt|m>iHKw6ZN?B!0z5-UvTLvB^ochW0MUe
zTCo3UyHPr)Wm2}=Q|;}Jp=?!yEo7lkkZVEWTiG(neLkPxjmP5yIMK0Oj)MPS5PmdJ
v-^T|DGdvdc$PjwGFzKEL3D`wFJShAEs8qVcYmOlW00000NkvXXu0mjfi^^_d

diff --git a/assets/images/flags/tur.png b/assets/images/flags/tur.png
index 166c6313a131fbe928dda9d4811f343a79cf7a6d..e86b5a85e937ba903a7f14a47b000ec6f851ed47 100644
GIT binary patch
literal 1088
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|WCX
zPZ!6KiaBp*Wp?-_iX2~GtKOx?B_G(u?^Psux`#7)O=O$PH&gH40G?A)Z4+Z7?KpZ5
zo(THpRQA(gn}=~^+sut;Dvn3|v%32w>yGsmo5y?J@BJS?m;Z9^yzlq^|F?NwIj?wq
zs-P2xVv7KR5YkA9PKcPgjFERksc;Y54HJb6s^=a_C0t~9tHYAsuumX?^OAUTc7yDm
z2TD1Y8NQ+k{`lWruwCoG6}<!VR1aL$dEjdH;h*jYMfnr8On3G($=qaF(#IkswTk<R
zJo7IThHYoq<7|)H2Szc~=rEjn!+vZ_u(;MP-U&J9>O=S4xbDZ4t<IQyo4M2X@PFxW
zaf$nk9vMsY!oEme*xfhz;8V`}0@(}eJ9i0un9De6W6=4%6S5CSt>k8im%6aptl;~i
z?LQ)SH_kJ?DlfOsRH1nF_8-T$t+qF*$vyCgCI9357>24V0reR_t~K0v<!~;!{G)w6
z)1;&`b5(O{KPsJXNIiM)rarrVu=zZzQ*&nSGkWkZwfy5#2hsTZcY2qfWm`A@(@`IT
z^aBsX4)n{vW1Dj?{oAq2X_k*qo!s?i>$}j!ub$+bYk0bN@9Fc86w~r+9{Z%<S-<qa
zlyiMAF7IY)zud4VCgEiVgOq}Llzv^l?u-sz<3q{&t2v+S=lfrqw0zeJE4G+Z1>*a^
zbnlFkjh3Au&40({^}py#k-e+M1DNyX7mK^@nlHNZ<h!efo<9BV^Z)P*p@bUuQpc}6
zJBshc&X|5)t8B8Tq2Jl*&Ue1&-(zd(YItJCX!gKs*=~b)r)ORPNx=zUSrmS^{m!@D
z`TWa5rpyBidGFoK+;w+PSy9ECMf?scEdG?cRXOlRSf0DxFy&tx?~Ers+RynUqc_z#
zF1q|eyMkFqM#6!)ZR<C)17EHcoOMZ$nOT~;-g9<!(sH1;Ce~iQ%W!k=mo=%^8q)a}
zt-BY#k8!_Ov-Hc)XUrbEZ4VXK|HLyv=ltnHa|b)?m$z@+X*_ccEEZvOr&{bpSm-Y^
z!4D5UtYs8BUS2VKLwV~j=fmIGPGq~UpZ;l6sm+Ei<Advbm{r(JnC0$%o5wl5e^#{c
zn-{&Oj2)b|bv~_~p_+ec+tMFN)}0+D4o<%uUN2{Ct-R-UV(XgNbD7uP-aWYB*&maQ
zhuls~KevgYUh7D_rf%V_8$12ye&^Yobk*3jD&67cgrdzE8$N%$b~xJ4_^tTDq~*1>
z4-Ga{@)>Mdy3668@d4c@IRY0-4|H)bGs%eYZpdgT6KgVdi09bA^0ND&=>fjD0>N#W
q4OQ3$l_sS#pkzB>2Anqk2j|0D8OG|#dsBf$0)wZkpUXO@geCxvt^Aw-

literal 1037
zcmV+o1oHcdP)<h;3K|Lk000e1NJLTq001fg000^Y1^@s6!MV=%0004mX+uL$Nkc;*
zaB^>EX>4Tx04R}tkv&MmP!xqvQ>8^J4rUM$%ut;yh>AFB6^c+H)C#RSn7s54nlvOS
zE{=k0!NH%!s)LKOt`4q(Aov5~>f)s6A|>9}6k5c1;qgAsyXWxUeSlCeGu`eQ2Xw=+
zQi-^f$*xMFR|F7&h%kl~W}9=eoP=+E-BUN!U5sb>_x)MDTFz!bKq8)HrsWWC5KnJ9
zCg*)(krfq<_?&pmq6-o~a$WWKjdP*N0?!n!bZVYhB$f&ttadOfS~~F*aa7X{$`>*o
zYn-<@>*XqI-IKpCk~3D8xlU^c2`pj>G9;*|qJ%OW#Ar82v5}(lxQ~CZ>6gi+lB)zp
zjs;YpLuvZK|KRs*?fm3~mlTNu-7l{DF#?2kfkw@BzmHwFaRLONfh(i!uhfB=Ptt2`
zEqVm>Z37qAZB5++E_Z-|CsVPMrWB+l<nzG$8GTb0=)VPe*1Wm3&T;wxq-j>k8{ps&
z7%foty3f1AopbxQr!~JHC5&>2@ijKN00006VoOIv0RI600RN!9r;`8x010qNS#tmY
z4c7nw4c7reD4Tcy00JFJL_t(o!|j&MYZFlv#eb8T)Mh#v6G2lKf)zhvY|($BLPa48
z*{k5kqMKr&ML|U<T4>3_h*hN0jSEFvu~0Em7ybbSMKnfqp@>l-am-hnnT(5pNknL3
zOsX}xtM}kO-r;c0y$4#=q$QMJ-pfAoUjnx&o3QaYRtux62B=iaBeBy*$B84j`g)PJ
zZ3RG&zacjlB{MOJk@)=gH7bXKcq3y7iUNS~;UoFzJcU=UajaEw2K;32-Y0kOL0vWa
zTa3z~AnR^k1wjDQL>n37dpLrbU;L@h>EDjCXBUO%FIJvWabqXGg{L^&ZU9ol=SW|^
zwv4DG&~=10ZJ4?NhOsiPS56+aK`t#kBOSTE`~zLLKJa=`hX=~25gKcz_P$>GoVhUt
zX7wXi9U7qcO`~mhH~B~NWbe#0Zahg{o9%PqWvsHMI%Hf2_v0BK0a3&=dI3REY6AIx
z4t)LXyOOJS?x@&rX0qg_XGxtp1BO9r=qzSBjT{O#R-^g3D9-MHWvpX|$xPj<TBq7*
zxMaQ>%~Um`>4`~-nr1P&rw66~cm)b94vNVn+NE$A)n;RX8lMs*`v;*|1i*9gJnHE|
z1Xuenz0QE&mWR2xRMQOo;}z;UbO7&_aU7~zTA`1hpvU3}s@qzjx2MU?%+_^<)|5xZ
z4ePB?vTrZamM#!Q^jMtS!>A>ZFJJ4PM_a+UX@hgCnznubZgRnjEZ(vm00000NkvXX
Hu0mjfBSqfA

diff --git a/assets/images/flags/twn.png b/assets/images/flags/twn.png
index 4af8ba78d6a7e891800d67ee6be6c1eee9cd4883..34a2b37db2d786516482fa989fed3631412b64a8 100644
GIT binary patch
literal 1005
zcmV<J0}}j+P)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h00009a7bBm000XU
z000XU0RWnu7ytkRpGibPRCt{2np;a$Q546|_lUHY>_R<Q7L;wvheSz*o{~a+tWV$<
zh@R@Dyo?%-n&M>;gf0pe^B_b%XelaMO$0r4p}dkF5tjV-aE@opF=sroN6-HU3&uVB
z9ESDZ>vGo7vIrrB5JCtcgb+dqA%qY@2niIqN1n(*GEvrnG76w503%>0OsAAwrXc^F
zRC=jh8wIfTzXn`6+4#@e{hFw@-R#X}1nkWry{!{cc=l<++R%&7GW7gY!rIl-P14!?
zfdcp)0ij1D@^Si?E5iAswKDhnugw2h(VwwaaH>hBCw@r7!*>+GZvm>yBLW-|?v(V1
z!|jqD*ZH8TEJ6YN79cOXP8JtdwS#9Se@a`!m@7bA{g_?@*pruCM*;RCK>mqF>Fb!3
z*7{MoSJ5vQkJan-=-?Nz?RDvD8JEh^h+IA%(uU97;c@+4bTAfAQCYP*G9Ev8E6*C=
z>wBj18zksY!q?6;%j{JAR4*;s+OY%uvvTWtSJG=Lin{fl=wM7=18@)Ai(OC}X~&z_
zak?Gn7hed=n^!SeUb3|zGHw=hxFXp0y6gO{of9J<4H2fszw5N)IDdX_MYggqzpB5(
zo}TbT+9#hW$m0aGm&oHNxRp10^%_ooGVol0Jym59eGRU4T2u<KODABofTvqH6Ft5|
zeojb#kCc;)<wZMQ#B)NMYfH9_41d$b7=kbY{v$xqxfZFpJ0LInW>OXah1VHHIAH(q
z>#thWROUt!^e!k_3PQn6hBKC^VhZv{0B<LRJ|BOh+d;wI3ZkVrFR=(0rr7~80z88?
zZySmh)9HjzBari9IQfqAv1e^9-iCT-M-;%P2Qf#4?Tim%JCKU=QACk)FxA8m4r7IQ
z{*UR?jTD1CkHQSY9<1Rz?<k_WJfiP`d!_o0z;sc~h$5U&kh5yt+>gj;4{Z+P!gZr=
zs^TzipU2V86E4TmmYEka&Uk?@WUS15C5g7RldmNG7l1G2Ewe><JLA8lSY`#-Pm>I2
zEi<YOr2rNMkPJBKi~w~&Q;_K&D2LoAfT94#PoXdZ%sWDug3LREH9!T=ScDY?Fn$V!
z5n$dC!W3lQ8LR;+c*Y{ED1h-(D2xE}ju56G^Uh!mP{A`6VMPIqpF&{-n0JIQ1(|mS
zYk&%#u?Q;)VEhycBfz{Pgel0pGgt#u@Qg)RQ2^toP%=3J2qA<JLI@#*5JCtcgb+dq
bu?`a(Yyx9wZqx`900000NkvXXu0mjf_8GtV

literal 373
zcmeAS@N?(olHy`uVBq!ia0vp^T0ktt!3-q7rQ00=QjEnx?oJHr&dIz4a#+$GeH|GX
zHuiJ>Nn{1`V*`9bTp1XqiZXP*WZ?P7z`)KvgNbRHgv5Mi=4m1#b1N&4$H(tsV3=ZU
zy{@$M*!1aFu3ULrQgYPVdMyXX3_H8^4GpKheEIeN|Nqj`qaq9)q6{6H47INrxL+}F
z|6yPR+A#Ii<8mM+UlQaO3{-{(Fr1Yv696jZEbxddW?<ku48n}Z^H-z*1<O2L978Pp
z-(IlfYfunz4Ga)q7hyj#^RNEp4tv8O4%U);uO`l6a=5j-LgeN{m95o*PMdp#jAf@h
zb&V9WEWX@zy;s2ZcBtPi{-ThqDbDhf7X4-t-e0yMy|PZM?U|&0+8XHw^#z@G>liAS
lxR#%<lbTv3)|^$#^g`eC&F;EK_kb>7@O1TaS?83{1OP(Cm7xFt

diff --git a/assets/images/flags/ven.png b/assets/images/flags/ven.png
index fcc25ef2b301e4a653f2d467d7803d3e5b5e55cd..c189b05452fa2be94ea5dc3c09672d34b7e9bc25 100644
GIT binary patch
delta 879
zcmey!{+&&+Gr-TCmrII^fq{Y7)59eQNGE_W2OE%lG^5;NqM~>`v!<tuV@SoEw=+(A
zhX#rq`+h%B-+Qx(W_5$b$pu9LP75a5o(Obpej(4X?)<J<sVOQfsX}5;c5JvLw8)cx
z_FQ4dAPWs0r>d2b_w?;P-g{%HxochV`+s#C9_;vTnZ0)NzP;af$vtloaN<xzB0g}n
z@EJ|tCgsskf1#|=vmt<~qV|a8R|a*)HQ|a|nBQ<S$~t~K8o<x-*Vy!70Mm^1P8sYs
z#F?y`-gGaN6Zn;$b!Z`rL44~4z76^;B`i0^ooyAqoWIg?xPyDbWbtO5Y1^by_AqpF
zz51W2r#0;((~;Z1HWpOg&40}O>GcJP{kikvuW<!zvFn?4E3bY}%~v_*@ADQvz2cD7
zcU|VO%=?FXul-Eh!l0U(dn4ka;pSD|r*Eep;|h~^FMchnBE(tq?~`cdQQwunE6*C9
z`zUwsbfKNM{1?~x*WOPxWYUSd*l<1H?!m_k9IL*UEj`w4zU9Hc=EN(e-xq#M@Xwk9
zw!pLRbL6iD`oFf+t?#K9SWplvbG@qFz;^D8jepteL}t04zBBdz>cYHt9}lNbu6r?g
z-`e~7pO~IJIl5uX3c>Joc23#9V`Z$0WOugq*1v5&{{d!}2iFAa=sUTg;v1HINy*xi
z^?m98qMQrtwW|Nqc#h4IzMajOm9@KY^?yk>cl#vQlbu_RC-WSuPx3kTEw16uqqLrV
ze_1{~dC74~``psC8eh&zv=~a>u4d$ue|vP}uh|ubfAa2i9gOHXdE*}U1mox_bARil
zr>;5ijiJs@<95lhH3FW=eD%M!O#I69Vg8cK>Fj4&Gu}(Me4VFP&l0g|6XRW5enUgU
z){`gmcU%<z^W}5#z8*u#*_H<N;?IuU*%ZfcYg4GNgtYYWA3sE{N!2Y*%z1VoX2#{3
zBRwq)v$xMbe(jWB&dN7O`eMb;vLt}zCYv+;$nj%3vPjqAflP{CuIU7ZbHJnoOhS9?
z9?hw0n9Oi(wE-xBxGYdUu}|U^<2n0a;WD8EHKJ^{7{9f0K$6V?*Pp<|<OfV)ha9XA
z>=S70Q}~^<g5Bc3kM9lF7zX4t3rfN<W*=pv!jpcM9;vPa<{<`8S3j3^P6<r_Dc_x>

delta 1002
zcmV<G0~P%D2Jr_WiBL{Q4GJ0x0000DNk~Le0000g0000Q2nGNE0KvJ=_K_hMe*gh<
zQb$4nuFf3k00004XF*Lt006O%3;baP000AqNkl<Zcmd5=O-vI(6n^_tYm?S4tq_d-
zR4xJ<gpi;I4#k9v2SpPOo{VQN9`xReHxm;sUcD0&y%1waEEf!>B$7x`(=<g(R8rcN
zHZ8T?9p4+6&2}wF>7o6S$$LBVe|Gxqn>Vj-2A~#Fy%vc?WRi?A=`fo*O}5+r=Uv$*
zWrwXrjDyHvlfvP!l+Wj-@$qq3U0vm4q~~%uDVa<%$A`hdzyP14qoacf`%<YSc|0B_
z#_2uko1C0vG!OMtpM74TudlB|JRUb^XJ^^`{5;KJ+KCcDrCct%+-|p0f2mZYYPBl)
zd_E%0e~@&S%f+(UEF1;rJ3>FMovNw~bu$nM7$}WcELN2yiK#S*?B#Si?OL9Dzk$^I
z^*n&4X#j=}tpc*%y#6RWI5jmzA7Btsa=naRl!@flt_r`B!w}E(z}V#vaH%^3tpF}{
zKdzpFt7y=(ECw*96q3)De*+Nul7a3|Yw$AW2EC#}s~|WLWanVNT7akd+weH^0HU!V
ztfdraC1?|pw1`p=le`x2!`jyb_$tdV)G2{>+6Aq`&dv^q>|w1d?Q)VX?+>^;(g|gE
z0xq7?;7V@+S_Qw~Z>7(g0DQ4D!le;VKrfC$LMuRG=`6Ggg+jsfe|o)KuOWK>`7LM$
zqeI<1uju(b(9WEOj~hRs8C(s%rF_nHPLu)`lP;VT_wJ0r=2njD`tCl-(cyCtI<N7*
zSBsyaS#Y8vU{8YZL<n9lZdjfaAa4qy<mpseuNiL?GBkluj|MZ-gWQYtNTjy*$<0g;
z!AbE?dZJX&2xxi3e-jtr;gdH<+R;Zu=H79#!o!U~thPlo7z{$A(05D6x6L2lR)Cx*
zJj!c6EU_@(tDYO*1HYk-u+W?J<E}4Z`B<gRWNoCIf4)IGVFA2WO)M(wwgnZ`1R`ox
z=IsVu*O}d;oV6%Q+6h>^OLmX$7bAGgfHniBCR6C#qj&%_e-nv>VKQi&-9%jQ3}@id
z6IoVsxI?LKZ*Qykzb{iLh|-Th`eET=Kb%oq(UOtwoWp5rhp?sh6-8miVzC+ug{skL
zl!%&E!bhSec2>~cWy)Q6bmfv7PE7xgMUvF){Rg&1p<`Lb<;u!RX%8W6MI&31eSLj=
zE|T;tY>{NSK&z{3FO^DFh!Y$fm+Qg0FmPTPi06X~3E4ST?~=iBc_G6g7ZPMw@8Ut=
YFC`2cH_eDwQ~&?~07*qoM6N<$f*IY<ga7~l

diff --git a/assets/images/flags/vnm.png b/assets/images/flags/vnm.png
index 3cbbf878f49fb4e71c9cb2a85ce3896d9fd2c55e..d313c99126bf81d51941f83d23c27d2b30aed718 100644
GIT binary patch
literal 882
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wk0|T>)
zr;B4q#hkaZtn-B(MOy#%A6x%5IoxTHV*`tagR`R}BP&azz#j%F4TerNUR{oiAeRdl
z8d+Q?Ff82YDdYTzz0$(XkW;Db$#K`+7jHE@?yxW{PkUZ-Y2}*O*!#xC>(Z|;6aZR{
z0^Af^6+C*@up2mh&@+%wNNBhyD1L}Xz@VX8)awnyKQ|8-fqG*D=9bDs0%8UYwP=D|
zR|Nh&X|XN5p16kbsdS-MeE((;^YvuUsM$UnuO}{Hycsg%7B^q1Sk9?sKVKW3Yq)e(
zBJk?RkX=H_>yKM7UsIbD%e>ED<>qU{Qw?iWSHy1H&9-H~)fC?k*He2Kk9zO@@iBDI
z3U?mXLk+hs$Nl-S%J!mi+ZJ;LVeu=oULWmWA9iq|Pt0HEncvt%^jv<=dcV5B?o?d-
z1Kx<*EAsaH!sOL%yuJ*y^QpwvXTOzGuVjhmPCG7fN>ZV9!JUN$e`}`x%RhU+V)C*(
z7dgrr{+w;`2?=;Q&ox9c@pHJ$uWt$ud5c^wG~6|)*Yi3%^Kbu>w0mJm9@>(QpY(m@
zIWGVDd}W{M|Kr^vzVacD)mMqJd4wlAcAM+I(&5`LZFRa&Jlkl|f$ta3F>G9Ve)-}n
zKQ{bk+&gpQ%hQtoPF%dlpviJ}u58T@DV6V1?{+aKJCxqJwUzN|p(%fAl+=cwg&iD|
zGQaI&PIUMelJY`vj{V8v8(dQuwZF3;_cu<jmin@@TDSb~E$Ist>F<BszGrQ0bNe4-
z?Bl&vhD)Y0Za)6|@$$`E&gTD?J;$^8_!WzW%uI);>#lBJba$q~g$=@jtM>mbP6&Uu
zLex1*GGP8I+rAaHeii>&e@z$v_Kw;7|E^zCq70YxGVVMa{qeG%Rmi?=zs27j-5Bxx
zYU;ZVE0E0T?Yg%r=H3hboOb6skACo$67RYH`?HcA3U%CO-njSv@x8-)#lM5RE*Wr;
zfsy$}_`)N65As`FSU#FF8#~NU=Sd_&(D|e!N=gNC95g)sFzsFCKh^oXvnxo_)78&q
Iol`;+0Ci@BApigX

literal 448
zcmeAS@N?(olHy`uVBq!ia0vp^T0ktt!3-q7rQ00=QjEnx?oJHr&dIz4a#+$GeH|GX
zHuiJ>Nn{1`a{_!qTyLq$-cpu*7$|;IN%q4Ep1bDKzh5xl)|R=gC38z%_C=-8|NjiP
zRAe6oiGSI{`SUjGj~lE%uCxAm$8^t1>it5Ve?J%>g^K@rz;eex`qzDyXE`Dtmhybr
z&-wiv`{PKlTWYe;ONDOh$UH9*0$RxZx8ov^QYi`Y3;s_SFhuC^@&eU!7I;J!GcfQS
z24TkI`72U@f@?ip978Pp&rZC_*KEMUVi?Z!tgS$P>CgZ5I$Ok=)I9bm82a~_MrF!6
z$33&Vy5m4_sDbZ-!pAOKb8asJQl&B17Zy5)N<O~xS+KUh_*llyMJpU7j(W~gOv@B<
zPjq<AYAX84>4A9Qlizu(vRDGbR!2_VaN1^NsQKz!SH7r}th&1Bg;nF*k8!uI)JZTN
zTR8v4U+3jk>nm3>fBsz&m8<pj-|wiktDbAVa(x%D^bbSK2aBZNxwnmh4rlOm^>bP0
Hl+XkKu%*pp


From 83ef61e92877dfaa7b506df2982d983162c8f0cc Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Sat, 17 Aug 2024 19:10:27 -0400
Subject: [PATCH 50/81] Cw 565 sign messages (#1378)

* version bump to 3.13.9, auth working on mac

* bump flutter version in workflow file

* workflow fix

* test fix

* downgrade flutter version

* test fix

* test fix

* update gradle version

* start working on ui for message signing

* updates

* sign working for a few wallet types

* updates & verification for electrum currencies

* nano support

* sign/verify working on eth, bitcoin broken

* update translations

* Implement Verify Message for Monero

* save [skip ci]

* pub key extraction working

* fixes for electrum signing

* verify working for solana!

* electrum still not working :( [skip ci]

* electrum messages working!

* fixes for updated dart version, localization file updates

* remove accidental inclusion

* missed some unimplemented throws

* Update res/values/strings_de.arb

Co-authored-by: Konstantin Ullrich <konstantinullrich12@gmail.com>

* Apply suggestions from code review

Co-authored-by: Konstantin Ullrich <konstantinullrich12@gmail.com>

* review suggestions and updates [skip ci]

* [skip ci] add polygon

* [skip ci] merge mac-auth/update version

* fix litecoin

* bio auth mac fix

* remove comment and change duration from 2 to 0

* cherry pick previous changes

* litecoin fixes, sign form fixes, use new walletAddressPicker

* support accounts

* verify messages working for monero

* working sign and verify messages for nano

* electrum signing working [skip ci]

* additional nano fixes

* update translations

* attempt to decode signatures with base64

* workaround for secure storage bug on mac

* bump version to 3.19.5 (because breez will need this version anyways)

* some code cleanup

* some changess didn't get saved

* just documenting the issue [skip ci]

* undo accidental removal + minor code cleanup

* merge conflicts

* merge fixes [skip ci]

* add tron support

* [wip] fixing

* remove duplicate references to electrum path for maintainability

* fixes

* minor fix

* fixes

* undo debug comment

* update migration for all electrum based wallets

* hotfixes

* copy over the rest of the fixes

* minor code cleanup [skip ci]

* updates

* electrum signing workinggit statusgit statusgit statusgit status!

* copy same fixes for litecoin

* litecoin fixes

* add v to litecoin signatures

* fix dependencies

* fix bitcoin_base version

* merge fix

* dep override

* fix conflicts with main

* trial fix for android build

* fixes

* fix

* dep fix, should build

* fix signing for bitcoin cash

* [skip ci] minor code cleanup

* [skip ci] minor code cleanup 2

* forgot wonero, various other fixes

* more fixes

* fix solana (untested)

---------

Co-authored-by: Konstantin Ullrich <konstantinullrich12@gmail.com>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 cw_bitcoin/lib/electrum_wallet.dart           |  73 ++++++-
 cw_bitcoin/lib/litecoin_wallet.dart           | 131 +++++++++++-
 cw_bitcoin/pubspec.yaml                       |   8 +-
 .../lib/src/bitcoin_cash_wallet.dart          |  11 +-
 cw_bitcoin_cash/pubspec.yaml                  |   8 +-
 cw_core/lib/wallet_base.dart                  |   5 +-
 cw_evm/lib/evm_chain_wallet.dart              |  20 +-
 cw_evm/pubspec.yaml                           |   2 +
 cw_monero/lib/api/wallet.dart                 |   4 +
 cw_monero/lib/monero_wallet.dart              |   8 +
 cw_nano/lib/nano_block_info_response.dart     |  37 ++++
 cw_nano/lib/nano_client.dart                  |  87 ++++++--
 cw_nano/lib/nano_wallet.dart                  |  25 ++-
 cw_nano/pubspec.lock                          |   8 +-
 cw_nano/pubspec.yaml                          |   3 +-
 cw_solana/lib/solana_wallet.dart              |  54 ++++-
 cw_tron/lib/tron_wallet.dart                  |  14 +-
 cw_wownero/lib/api/wallet.dart                |   4 +
 cw_wownero/lib/wownero_wallet.dart            |   7 +
 lib/bitcoin/cw_bitcoin.dart                   |   4 +-
 lib/buy/dfx/dfx_buy_provider.dart             |   4 +-
 lib/buy/robinhood/robinhood_buy_provider.dart |   6 +-
 lib/di.dart                                   |  16 +-
 lib/router.dart                               |  14 ++
 lib/routes.dart                               |   2 +
 .../cake_pay_confirm_purchase_card_page.dart  |  18 +-
 .../dashboard/pages/cake_features_page.dart   |  14 ++
 lib/src/screens/dashboard/sign_page.dart      | 202 ++++++++++++++++++
 .../screens/dashboard/widgets/sign_form.dart  |  98 +++++++++
 .../dashboard/widgets/verify_form.dart        |  92 ++++++++
 .../screens/receive/address_list_page.dart    |  31 +++
 lib/src/screens/receive/receive_page.dart     | 104 +--------
 .../screens/receive/widgets/address_list.dart | 120 +++++++++++
 lib/src/widgets/address_text_field.dart       | 194 ++++++++++-------
 .../dashboard/dashboard_view_model.dart       |  36 +++-
 lib/view_model/dashboard/sign_view_model.dart |  55 +++++
 .../wallet_address_list_view_model.dart       |   9 +
 lib/view_model/wallet_creation_vm.dart        |   8 +-
 pubspec_base.yaml                             |   6 +-
 res/values/strings_ar.arb                     |   8 +
 res/values/strings_bg.arb                     |   8 +
 res/values/strings_cs.arb                     |   8 +
 res/values/strings_de.arb                     |   8 +
 res/values/strings_en.arb                     |   8 +
 res/values/strings_es.arb                     |   8 +
 res/values/strings_fr.arb                     |   8 +
 res/values/strings_ha.arb                     |   8 +
 res/values/strings_hi.arb                     |   8 +
 res/values/strings_hr.arb                     |   8 +
 res/values/strings_id.arb                     |   8 +
 res/values/strings_it.arb                     |   8 +
 res/values/strings_ja.arb                     |   8 +
 res/values/strings_ko.arb                     |   8 +
 res/values/strings_my.arb                     |   8 +
 res/values/strings_nl.arb                     |   8 +
 res/values/strings_pl.arb                     |   8 +
 res/values/strings_pt.arb                     |   8 +
 res/values/strings_ru.arb                     |   8 +
 res/values/strings_th.arb                     |   8 +
 res/values/strings_tl.arb                     |   8 +
 res/values/strings_tr.arb                     |   8 +
 res/values/strings_uk.arb                     |   8 +
 res/values/strings_ur.arb                     |   8 +
 res/values/strings_yo.arb                     |   8 +
 res/values/strings_zh.arb                     |   8 +
 65 files changed, 1479 insertions(+), 271 deletions(-)
 create mode 100644 cw_nano/lib/nano_block_info_response.dart
 create mode 100644 lib/src/screens/dashboard/sign_page.dart
 create mode 100644 lib/src/screens/dashboard/widgets/sign_form.dart
 create mode 100644 lib/src/screens/dashboard/widgets/verify_form.dart
 create mode 100644 lib/src/screens/receive/address_list_page.dart
 create mode 100644 lib/src/screens/receive/widgets/address_list.dart
 create mode 100644 lib/view_model/dashboard/sign_view_model.dart

diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 9dc8de083..8f2360f26 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -42,6 +42,7 @@ import 'package:flutter/foundation.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:rxdart/subjects.dart';
+import 'package:http/http.dart' as http;
 import 'package:sp_scanner/sp_scanner.dart';
 
 part 'electrum_wallet.g.dart';
@@ -132,6 +133,7 @@ abstract class ElectrumWalletBase
   final String? _mnemonic;
 
   Bip32Slip10Secp256k1 get hd => accountHD.childKey(Bip32KeyIndex(0));
+  Bip32Slip10Secp256k1 get sideHd => accountHD.childKey(Bip32KeyIndex(1));
 
   final EncryptionFileUtils encryptionFileUtils;
   final String? passphrase;
@@ -591,7 +593,7 @@ abstract class ElectrumWalletBase
       }
 
       final derivationPath =
-          "${_hardenedDerivationPath(walletInfo.derivationInfo?.derivationPath ?? "m/0'")}"
+          "${_hardenedDerivationPath(walletInfo.derivationInfo?.derivationPath ?? electrum_path)}"
           "/${utx.bitcoinAddressRecord.isHidden ? "1" : "0"}"
           "/${utx.bitcoinAddressRecord.index}";
       publicKeys[address.pubKeyHash()] = PublicKeyWithDerivationPath(pubKeyHex, derivationPath);
@@ -1869,11 +1871,70 @@ abstract class ElectrumWalletBase
         ? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
         : null;
     final HD = index == null ? hd : hd.childKey(Bip32KeyIndex(index));
-    final priv = ECPrivate.fromWif(
-      WifEncoder.encode(HD.privateKey.raw, netVer: network.wifNetVer),
-      netVersion: network.wifNetVer,
-    );
-    return priv.signMessage(StringUtils.encode(message));
+    final priv = ECPrivate.fromHex(HD.privateKey.privKey.toHex());
+
+    String messagePrefix = '\x18Bitcoin Signed Message:\n';
+    final hexEncoded = priv.signMessage(utf8.encode(message), messagePrefix: messagePrefix);
+    final decodedSig = hex.decode(hexEncoded);
+    return base64Encode(decodedSig);
+  }
+
+  @override
+  Future<bool> verifyMessage(String message, String signature, {String? address = null}) async {
+    if (address == null) {
+      return false;
+    }
+
+    List<int> sigDecodedBytes = [];
+
+    if (signature.endsWith('=')) {
+      sigDecodedBytes = base64.decode(signature);
+    } else {
+      sigDecodedBytes = hex.decode(signature);
+    }
+
+    if (sigDecodedBytes.length != 64 && sigDecodedBytes.length != 65) {
+      throw ArgumentException(
+          "signature must be 64 bytes without recover-id or 65 bytes with recover-id");
+    }
+
+    String messagePrefix = '\x18Bitcoin Signed Message:\n';
+    final messageHash = QuickCrypto.sha256Hash(
+        BitcoinSignerUtils.magicMessage(utf8.encode(message), messagePrefix));
+
+    List<int> correctSignature =
+        sigDecodedBytes.length == 65 ? sigDecodedBytes.sublist(1) : List.from(sigDecodedBytes);
+    List<int> rBytes = correctSignature.sublist(0, 32);
+    List<int> sBytes = correctSignature.sublist(32);
+    final sig = ECDSASignature(BigintUtils.fromBytes(rBytes), BigintUtils.fromBytes(sBytes));
+
+    List<int> possibleRecoverIds = [0, 1];
+
+    final baseAddress = addressTypeFromStr(address, network);
+
+    for (int recoveryId in possibleRecoverIds) {
+      final pubKey = sig.recoverPublicKey(messageHash, Curves.generatorSecp256k1, recoveryId);
+
+      final recoveredPub = ECPublic.fromBytes(pubKey!.toBytes());
+
+      String? recoveredAddress;
+
+      if (baseAddress is P2pkAddress) {
+        recoveredAddress = recoveredPub.toP2pkAddress().toAddress(network);
+      } else if (baseAddress is P2pkhAddress) {
+        recoveredAddress = recoveredPub.toP2pkhAddress().toAddress(network);
+      } else if (baseAddress is P2wshAddress) {
+        recoveredAddress = recoveredPub.toP2wshAddress().toAddress(network);
+      } else if (baseAddress is P2wpkhAddress) {
+        recoveredAddress = recoveredPub.toP2wpkhAddress().toAddress(network);
+      }
+
+      if (recoveredAddress == address) {
+        return true;
+      }
+    }
+
+    return false;
   }
 
   Future<void> _setInitialHeight() async {
diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index d8c04dba6..890d98342 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -1,6 +1,9 @@
-import 'package:bip39/bip39.dart' as bip39;
+import 'dart:convert';
+
 import 'package:bitcoin_base/bitcoin_base.dart';
 import 'package:blockchain_utils/blockchain_utils.dart';
+import 'package:blockchain_utils/signer/ecdsa_signing_key.dart';
+import 'package:bip39/bip39.dart' as bip39;
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
 import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
@@ -17,6 +20,9 @@ import 'package:cw_core/wallet_keys_file.dart';
 import 'package:flutter/foundation.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
+import 'package:bitcoin_base/src/crypto/keypair/sign_utils.dart';
+import 'package:pointycastle/ecc/api.dart';
+import 'package:pointycastle/ecc/curves/secp256k1.dart';
 
 part 'litecoin_wallet.g.dart';
 
@@ -167,4 +173,127 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
 
     return 0;
   }
+
+  @override
+  Future<String> signMessage(String message, {String? address = null}) async {
+    final index = address != null
+        ? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
+        : null;
+    final HD = index == null ? hd : hd.childKey(Bip32KeyIndex(index));
+    final priv = ECPrivate.fromHex(HD.privateKey.privKey.toHex());
+
+    final privateKey = ECDSAPrivateKey.fromBytes(
+      priv.toBytes(),
+      Curves.generatorSecp256k1,
+    );
+
+    final signature =
+        signLitecoinMessage(utf8.encode(message), privateKey: privateKey, bipPrive: priv.prive);
+
+    return base64Encode(signature);
+  }
+
+  List<int> _magicPrefix(List<int> message, List<int> messagePrefix) {
+    final encodeLength = IntUtils.encodeVarint(message.length);
+
+    return [...messagePrefix, ...encodeLength, ...message];
+  }
+
+  List<int> signLitecoinMessage(List<int> message,
+      {required ECDSAPrivateKey privateKey, required Bip32PrivateKey bipPrive}) {
+    String messagePrefix = '\x19Litecoin Signed Message:\n';
+    final messageHash = QuickCrypto.sha256Hash(magicMessage(message, messagePrefix));
+    final signingKey = EcdsaSigningKey(privateKey);
+    ECDSASignature ecdsaSign =
+        signingKey.signDigestDeterminstic(digest: messageHash, hashFunc: () => SHA256());
+    final n = Curves.generatorSecp256k1.order! >> 1;
+    BigInt newS;
+    if (ecdsaSign.s.compareTo(n) > 0) {
+      newS = Curves.generatorSecp256k1.order! - ecdsaSign.s;
+    } else {
+      newS = ecdsaSign.s;
+    }
+    final rawSig = ECDSASignature(ecdsaSign.r, newS);
+    final rawSigBytes = rawSig.toBytes(BitcoinSignerUtils.baselen);
+
+    final pub = bipPrive.publicKey;
+    final ECDomainParameters curve = ECCurve_secp256k1();
+    final point = curve.curve.decodePoint(pub.point.toBytes());
+
+    final rawSigEc = ECSignature(rawSig.r, rawSig.s);
+
+    final recId = SignUtils.findRecoveryId(
+      SignUtils.getHexString(messageHash, offset: 0, length: messageHash.length),
+      rawSigEc,
+      Uint8List.fromList(pub.uncompressed),
+    );
+
+    final v = recId + 27 + (point!.isCompressed ? 4 : 0);
+
+    final combined = Uint8List.fromList([v, ...rawSigBytes]);
+
+    return combined;
+  }
+
+  List<int> magicMessage(List<int> message, String messagePrefix) {
+    final prefixBytes = StringUtils.encode(messagePrefix);
+    final magic = _magicPrefix(message, prefixBytes);
+    return QuickCrypto.sha256Hash(magic);
+  }
+
+  @override
+  Future<bool> verifyMessage(String message, String signature, {String? address = null}) async {
+    if (address == null) {
+      return false;
+    }
+
+    List<int> sigDecodedBytes = [];
+
+    if (signature.endsWith('=')) {
+      sigDecodedBytes = base64.decode(signature);
+    } else {
+      sigDecodedBytes = hex.decode(signature);
+    }
+
+    if (sigDecodedBytes.length != 64 && sigDecodedBytes.length != 65) {
+      throw ArgumentException(
+          "litecoin signature must be 64 bytes without recover-id or 65 bytes with recover-id");
+    }
+
+    String messagePrefix = '\x19Litecoin Signed Message:\n';
+    final messageHash = QuickCrypto.sha256Hash(magicMessage(utf8.encode(message), messagePrefix));
+
+    List<int> correctSignature =
+        sigDecodedBytes.length == 65 ? sigDecodedBytes.sublist(1) : List.from(sigDecodedBytes);
+    List<int> rBytes = correctSignature.sublist(0, 32);
+    List<int> sBytes = correctSignature.sublist(32);
+    final sig = ECDSASignature(BigintUtils.fromBytes(rBytes), BigintUtils.fromBytes(sBytes));
+
+    List<int> possibleRecoverIds = [0, 1];
+
+    final baseAddress = addressTypeFromStr(address, network);
+
+    for (int recoveryId in possibleRecoverIds) {
+      final pubKey = sig.recoverPublicKey(messageHash, Curves.generatorSecp256k1, recoveryId);
+      final recoveredPub = ECPublic.fromBytes(pubKey!.toBytes());
+
+      String? recoveredAddress;
+
+      if (baseAddress is P2pkAddress) {
+        recoveredAddress = recoveredPub.toP2pkAddress().toAddress(network);
+      } else if (baseAddress is P2pkhAddress) {
+        recoveredAddress = recoveredPub.toP2pkhAddress().toAddress(network);
+      } else if (baseAddress is P2wshAddress) {
+        recoveredAddress = recoveredPub.toP2wshAddress().toAddress(network);
+      } else if (baseAddress is P2wpkhAddress) {
+        recoveredAddress = recoveredPub.toP2wpkhAddress().toAddress(network);
+      }
+
+      if (recoveredAddress == address) {
+        return true;
+      }
+    }
+
+    return false;
+  }
 }
diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml
index 449833220..2af1ac54e 100644
--- a/cw_bitcoin/pubspec.yaml
+++ b/cw_bitcoin/pubspec.yaml
@@ -25,10 +25,6 @@ dependencies:
       ref: Add-Support-For-OP-Return-data
   rxdart: ^0.27.5
   cryptography: ^2.0.5
-  bitcoin_base:
-    git:
-      url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v4
   blockchain_utils:
     git:
       url: https://github.com/cake-tech/blockchain_utils
@@ -57,6 +53,10 @@ dependency_overrides:
       url: https://github.com/cake-tech/ledger-flutter.git
       ref: cake-v3
   watcher: ^1.1.0
+  bitcoin_base:
+    git:
+      url: https://github.com/cake-tech/bitcoin_base
+      ref: cake-update-v5
 
 # For information on the generic Dart part of this file, see the
 # following page: https://dart.dev/tools/pub/pubspec
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
index a59569ae6..5659528c0 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
@@ -202,11 +202,12 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
 
   @override
   Future<String> signMessage(String message, {String? address = null}) async {
-    final index = address != null
-        ? walletAddresses.allAddresses
-            .firstWhere((element) => element.address == AddressUtils.toLegacyAddress(address))
-            .index
-        : null;
+    int? index;
+    try {
+      index = address != null
+          ? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
+          : null;
+    } catch (_) {}
     final HD = index == null ? hd : hd.childKey(Bip32KeyIndex(index));
     final priv = ECPrivate.fromWif(
       WifEncoder.encode(HD.privateKey.raw, netVer: network.wifNetVer),
diff --git a/cw_bitcoin_cash/pubspec.yaml b/cw_bitcoin_cash/pubspec.yaml
index 3728bafc5..64bd38b1d 100644
--- a/cw_bitcoin_cash/pubspec.yaml
+++ b/cw_bitcoin_cash/pubspec.yaml
@@ -25,10 +25,6 @@ dependencies:
     git:
       url: https://github.com/cake-tech/bitbox-flutter.git
       ref: Add-Support-For-OP-Return-data
-  bitcoin_base:
-    git:
-      url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v4
   blockchain_utils:
     git:
       url: https://github.com/cake-tech/blockchain_utils
@@ -43,6 +39,10 @@ dev_dependencies:
 
 dependency_overrides:
   watcher: ^1.1.0
+  bitcoin_base:
+    git:
+      url: https://github.com/cake-tech/bitcoin_base
+      ref: cake-update-v5
 
 # For information on the generic Dart part of this file, see the
 # following page: https://dart.dev/tools/pub/pubspec
diff --git a/cw_core/lib/wallet_base.dart b/cw_core/lib/wallet_base.dart
index f7af15224..14ba898a7 100644
--- a/cw_core/lib/wallet_base.dart
+++ b/cw_core/lib/wallet_base.dart
@@ -69,7 +69,6 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
 
   int calculateEstimatedFee(TransactionPriority priority, int? amount);
 
-
   // void fetchTransactionsAsync(
   //     void Function(TransactionType transaction) onTransactionLoaded,
   //     {void Function() onFinished});
@@ -92,7 +91,9 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
 
   Future<void> renameWalletFiles(String newWalletName);
 
-  Future<String> signMessage(String message, {String? address = null}) => throw UnimplementedError();
+  Future<String> signMessage(String message, {String? address = null});
+
+  Future<bool> verifyMessage(String message, String signature, {String? address = null});
 
   bool? isTestnet;
 }
diff --git a/cw_evm/lib/evm_chain_wallet.dart b/cw_evm/lib/evm_chain_wallet.dart
index 80a366e6f..bbf972f0d 100644
--- a/cw_evm/lib/evm_chain_wallet.dart
+++ b/cw_evm/lib/evm_chain_wallet.dart
@@ -35,6 +35,7 @@ import 'package:mobx/mobx.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 import 'package:web3dart/crypto.dart';
 import 'package:web3dart/web3dart.dart';
+import 'package:eth_sig_util/eth_sig_util.dart';
 
 import 'evm_chain_transaction_info.dart';
 import 'evm_erc20_balance.dart';
@@ -500,7 +501,7 @@ abstract class EVMChainWalletBase
     }
 
     final methodSignature =
-    transactionInput.length >= 10 ? transactionInput.substring(0, 10) : null;
+        transactionInput.length >= 10 ? transactionInput.substring(0, 10) : null;
 
     return methodSignatureToType[methodSignature];
   }
@@ -692,8 +693,21 @@ abstract class EVMChainWalletBase
   }
 
   @override
-  Future<String> signMessage(String message, {String? address}) async =>
-      bytesToHex(await _evmChainPrivateKey.signPersonalMessage(ascii.encode(message)));
+  Future<String> signMessage(String message, {String? address}) async {
+    return bytesToHex(await _evmChainPrivateKey.signPersonalMessage(ascii.encode(message)));
+  }
+
+  @override
+  Future<bool> verifyMessage(String message, String signature, {String? address}) async {
+    if (address == null) {
+      return false;
+    }
+    final recoveredAddress = EthSigUtil.recoverPersonalSignature(
+      message: ascii.encode(message),
+      signature: signature,
+    );
+    return recoveredAddress.toUpperCase() == address.toUpperCase();
+  }
 
   Web3Client? getWeb3Client() => _client.getWeb3Client();
 
diff --git a/cw_evm/pubspec.yaml b/cw_evm/pubspec.yaml
index b24e375a7..3e12834b1 100644
--- a/cw_evm/pubspec.yaml
+++ b/cw_evm/pubspec.yaml
@@ -13,6 +13,8 @@ dependencies:
   flutter:
     sdk: flutter
   web3dart: ^2.7.1
+  eth_sig_util: ^0.0.9
+  erc20: ^1.0.1
   bip39: ^1.0.6
   bip32: ^2.0.0
   hex: ^0.2.0
diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart
index 1a6e5315d..b493e536e 100644
--- a/cw_monero/lib/api/wallet.dart
+++ b/cw_monero/lib/api/wallet.dart
@@ -316,3 +316,7 @@ Future<bool> trustedDaemon() async => monero.Wallet_trustedDaemon(wptr!);
 String signMessage(String message, {String address = ""}) {
   return monero.Wallet_signMessage(wptr!, message: message, address: address);
 }
+
+bool verifyMessage(String message, String address, String signature) {
+  return monero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature);
+}
\ No newline at end of file
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index 31e09ca2d..f5fa0ec7e 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -783,4 +783,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
     final useAddress = address ?? "";
     return monero_wallet.signMessage(message, address: useAddress);
   }
+
+  @override
+  Future<bool> verifyMessage(String message, String signature, {String? address = null}) async {
+    if (address == null) return false;
+
+    return monero_wallet.verifyMessage(message, address, signature);
+  }
+
 }
diff --git a/cw_nano/lib/nano_block_info_response.dart b/cw_nano/lib/nano_block_info_response.dart
new file mode 100644
index 000000000..d2f000b9d
--- /dev/null
+++ b/cw_nano/lib/nano_block_info_response.dart
@@ -0,0 +1,37 @@
+class BlockContentsResponse {
+  String type;
+  String account;
+  String previous;
+  String representative;
+  String balance;
+  String link;
+  String linkAsAccount;
+  String signature;
+  String work;
+
+  BlockContentsResponse({
+    required this.type,
+    required this.account,
+    required this.previous,
+    required this.representative,
+    required this.balance,
+    required this.link,
+    required this.linkAsAccount,
+    required this.signature,
+    required this.work,
+  });
+
+  factory BlockContentsResponse.fromJson(Map<String, dynamic> json) {
+    return BlockContentsResponse(
+      type: json['type'] as String,
+      account: json['account'] as String,
+      previous: json['previous'] as String,
+      representative: json['representative'] as String,
+      balance: json['balance'] as String,
+      link: json['link'] as String,
+      linkAsAccount: json['link_as_account'] as String,
+      signature: json['signature'] as String,
+      work: json['work'] as String,
+    );
+  }
+}
diff --git a/cw_nano/lib/nano_client.dart b/cw_nano/lib/nano_client.dart
index 8d8bef13d..478a6c125 100644
--- a/cw_nano/lib/nano_client.dart
+++ b/cw_nano/lib/nano_client.dart
@@ -2,11 +2,11 @@ import 'dart:async';
 import 'dart:convert';
 
 import 'package:cw_core/nano_account_info_response.dart';
+import 'package:cw_nano/nano_block_info_response.dart';
 import 'package:cw_core/n2_node.dart';
 import 'package:cw_nano/nano_balance.dart';
 import 'package:cw_nano/nano_transaction_model.dart';
 import 'package:http/http.dart' as http;
-import 'package:nanodart/nanodart.dart';
 import 'package:cw_core/node.dart';
 import 'package:nanoutil/nanoutil.dart';
 import 'package:shared_preferences/shared_preferences.dart';
@@ -111,6 +111,27 @@ class NanoClient {
     }
   }
 
+  Future<BlockContentsResponse?> getBlockContents(String block) async {
+    try {
+      final response = await http.post(
+        _node!.uri,
+        headers: CAKE_HEADERS,
+        body: jsonEncode(
+          {
+            "action": "block_info",
+            "json_block": "true",
+            "hash": block,
+          },
+        ),
+      );
+      final data = await jsonDecode(response.body);
+      return BlockContentsResponse.fromJson(data["contents"] as Map<String, dynamic>);
+    } catch (e) {
+      print("error while getting block info $e");
+      return null;
+    }
+  }
+
   Future<String> changeRep({
     required String privateKey,
     required String repAddress,
@@ -135,8 +156,8 @@ class NanoClient {
     };
 
     // sign the change block:
-    final String hash = NanoBlocks.computeStateHash(
-      NanoAccountType.NANO,
+    final String hash = NanoSignatures.computeStateHash(
+      NanoBasedCurrency.NANO,
       changeBlock["account"]!,
       changeBlock["previous"]!,
       changeBlock["representative"]!,
@@ -248,7 +269,7 @@ class NanoClient {
     }
     final String representative = infoResponse.representative;
     // link = destination address:
-    final String link = NanoAccounts.extractPublicKey(destinationAddress);
+    final String link = NanoDerivations.addressToPublicKey(destinationAddress);
     final String linkAsAccount = destinationAddress;
 
     // construct the send block:
@@ -262,8 +283,8 @@ class NanoClient {
     };
 
     // sign the send block:
-    final String hash = NanoBlocks.computeStateHash(
-      NanoAccountType.NANO,
+    final String hash = NanoSignatures.computeStateHash(
+      NanoBasedCurrency.NANO,
       sendBlock["account"]!,
       sendBlock["previous"]!,
       sendBlock["representative"]!,
@@ -285,7 +306,6 @@ class NanoClient {
 
   Future<void> receiveBlock({
     required String blockHash,
-    required String source,
     required String amountRaw,
     required String destinationAddress,
     required String privateKey,
@@ -310,15 +330,56 @@ class NanoClient {
       representative = infoData.representative;
     }
 
+    if ((BigInt.tryParse(amountRaw) ?? BigInt.zero) <= BigInt.zero) {
+      throw Exception("amountRaw must be greater than zero");
+    }
+
+    BlockContentsResponse? frontierContents;
+
+    if (!openBlock) {
+      // get the block info of the frontier block:
+      frontierContents = await getBlockContents(frontier);
+
+      if (frontierContents == null) {
+        throw Exception("error while getting frontier block info");
+      }
+
+      final String frontierHash = NanoSignatures.computeStateHash(
+        NanoBasedCurrency.NANO,
+        frontierContents.account,
+        frontierContents.previous,
+        frontierContents.representative,
+        BigInt.parse(frontierContents.balance),
+        frontierContents.link,
+      );
+
+      bool valid = await NanoSignatures.verify(
+        frontierHash,
+        frontierContents.signature,
+        destinationAddress,
+      );
+
+      if (!valid) {
+        throw Exception(
+            "Frontier block signature is invalid! Potentially malicious block detected!");
+      }
+    }
+
     // first get the account balance:
-    final BigInt currentBalance = (await getBalance(destinationAddress)).currentBalance;
+    late BigInt currentBalance;
+    if (!openBlock) {
+      currentBalance = BigInt.parse(frontierContents!.balance);
+    } else {
+      currentBalance = BigInt.zero;
+    }
     final BigInt txAmount = BigInt.parse(amountRaw);
     final BigInt balanceAfterTx = currentBalance + txAmount;
 
     // link = send block hash:
     final String link = blockHash;
     // this "linkAsAccount" is meaningless:
-    final String linkAsAccount = NanoAccounts.createAccount(NanoAccountType.NANO, blockHash);
+    final String linkAsAccount =
+        NanoDerivations.publicKeyToAddress(blockHash, currency: NanoBasedCurrency.NANO);
 
     // construct the receive block:
     Map<String, String> receiveBlock = {
@@ -332,8 +393,8 @@ class NanoClient {
     };
 
     // sign the receive block:
-    final String hash = NanoBlocks.computeStateHash(
-      NanoAccountType.NANO,
+    final String hash = NanoSignatures.computeStateHash(
+      NanoBasedCurrency.NANO,
       receiveBlock["account"]!,
       receiveBlock["previous"]!,
       receiveBlock["representative"]!,
@@ -345,7 +406,7 @@ class NanoClient {
     // get PoW for the receive block:
     String? work;
     if (openBlock) {
-      work = await requestWork(NanoAccounts.extractPublicKey(destinationAddress));
+      work = await requestWork(NanoDerivations.addressToPublicKey(destinationAddress));
     } else {
       work = await requestWork(frontier);
     }
@@ -409,10 +470,8 @@ class NanoClient {
     for (final blockHash in blocks.keys) {
       final block = blocks[blockHash];
       final String amountRaw = block["amount"] as String;
-      final String source = block["source"] as String;
       await receiveBlock(
         blockHash: blockHash,
-        source: source,
         amountRaw: amountRaw,
         privateKey: privateKey,
         destinationAddress: destinationAddress,
diff --git a/cw_nano/lib/nano_wallet.dart b/cw_nano/lib/nano_wallet.dart
index cba8d09a0..700710c2e 100644
--- a/cw_nano/lib/nano_wallet.dart
+++ b/cw_nano/lib/nano_wallet.dart
@@ -27,7 +27,6 @@ import 'package:cw_nano/nano_wallet_addresses.dart';
 import 'package:cw_nano/nano_wallet_keys.dart';
 import 'package:cw_nano/pending_nano_transaction.dart';
 import 'package:mobx/mobx.dart';
-import 'package:nanodart/nanodart.dart';
 import 'package:nanoutil/nanoutil.dart';
 
 part 'nano_wallet.g.dart';
@@ -107,7 +106,6 @@ abstract class NanoWalletBase
     if (_derivationType == DerivationType.unknown) {
       _derivationType = DerivationType.nano;
     }
-    final String type = (_derivationType == DerivationType.nano) ? "standard" : "hd";
 
     // our "mnemonic" is actually a hex form seed:
     if (!_mnemonic.contains(' ')) {
@@ -122,8 +120,10 @@ abstract class NanoWalletBase
         _hexSeed = await NanoDerivations.hdMnemonicListToSeed(_mnemonic.split(' '));
       }
     }
-    NanoDerivationType derivationType =
-        type == "standard" ? NanoDerivationType.STANDARD : NanoDerivationType.HD;
+
+    final String type = (_derivationType == DerivationType.nano) ? "standard" : "hd";
+    NanoDerivationType derivationType = NanoDerivations.stringToType(type);
+
     _privateKey = await NanoDerivations.universalSeedToPrivate(
       _hexSeed!,
       index: 0,
@@ -216,8 +216,8 @@ abstract class NanoWalletBase
         balanceAfterTx: runningBalance,
         previousHash: previousHash,
       );
-      previousHash = NanoBlocks.computeStateHash(
-        NanoAccountType.NANO,
+      previousHash = NanoSignatures.computeStateHash(
+        NanoBasedCurrency.NANO,
         block["account"]!,
         block["previous"]!,
         block["representative"]!,
@@ -535,4 +535,17 @@ abstract class NanoWalletBase
     // Delete old name's dir and files
     await Directory(currentDirPath).delete(recursive: true);
   }
+
+  @override
+  Future<String> signMessage(String message, {String? address = null}) async {
+    return NanoSignatures.signMessage(message, privateKey!);
+  }
+
+  @override
+  Future<bool> verifyMessage(String message, String signature, {String? address = null}) async {
+    if (address == null) {
+      return false;
+    }
+    return await NanoSignatures.verifyMessage(message, signature, address);
+  }
 }
diff --git a/cw_nano/pubspec.lock b/cw_nano/pubspec.lock
index bbe909199..ef9de14f9 100644
--- a/cw_nano/pubspec.lock
+++ b/cw_nano/pubspec.lock
@@ -513,7 +513,7 @@ packages:
     source: hosted
     version: "2.3.0"
   nanodart:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: nanodart
       sha256: "4b2f42d60307b54e8cf384d6193a567d07f8efd773858c0d5948246153c13282"
@@ -524,11 +524,11 @@ packages:
     dependency: "direct main"
     description:
       path: "."
-      ref: c37e72817cf0a28162f43124f79661d6c8e0098f
-      resolved-ref: c37e72817cf0a28162f43124f79661d6c8e0098f
+      ref: c01a9c552917008d8fbc6b540db657031625b04f
+      resolved-ref: c01a9c552917008d8fbc6b540db657031625b04f
       url: "https://github.com/perishllc/nanoutil.git"
     source: git
-    version: "1.0.0"
+    version: "1.0.3"
   package_config:
     dependency: transitive
     description:
diff --git a/cw_nano/pubspec.yaml b/cw_nano/pubspec.yaml
index 6fae6a895..3ddd9769e 100644
--- a/cw_nano/pubspec.yaml
+++ b/cw_nano/pubspec.yaml
@@ -15,7 +15,6 @@ dependencies:
   mobx: ^2.0.7+4
   bip39: ^1.0.6
   bip32: ^2.0.0
-  nanodart: ^2.0.0
   decimal: ^2.3.3
   libcrypto: ^0.2.2
   ed25519_hd_key: ^2.2.0
@@ -25,7 +24,7 @@ dependencies:
   nanoutil:
     git:
       url: https://github.com/perishllc/nanoutil.git
-      ref: c37e72817cf0a28162f43124f79661d6c8e0098f
+      ref: c01a9c552917008d8fbc6b540db657031625b04f
   cw_core:
     path: ../cw_core
 
diff --git a/cw_solana/lib/solana_wallet.dart b/cw_solana/lib/solana_wallet.dart
index 66b8bca42..4e69db3b8 100644
--- a/cw_solana/lib/solana_wallet.dart
+++ b/cw_solana/lib/solana_wallet.dart
@@ -32,6 +32,8 @@ import 'package:shared_preferences/shared_preferences.dart';
 import 'package:solana/base58.dart';
 import 'package:solana/metaplex.dart' as metaplex;
 import 'package:solana/solana.dart';
+import 'package:solana/src/crypto/ed25519_hd_keypair.dart';
+import 'package:cryptography/cryptography.dart';
 
 part 'solana_wallet.g.dart';
 
@@ -571,17 +573,59 @@ abstract class SolanaWalletBase
     });
   }
 
-  Future<String> signSolanaMessage(String message) async {
+  @override
+  Future<String> signMessage(String message, {String? address}) async {
     // Convert the message to bytes
     final messageBytes = utf8.encode(message);
 
     // Sign the message bytes with the wallet's private key
-    final signature = await _walletKeyPair!.sign(messageBytes);
+    final signature = (await _walletKeyPair!.sign(messageBytes)).toString();
 
-    // Convert the signature to a hexadecimal string
-    final hex = HEX.encode(signature.bytes);
+    return HEX.encode(utf8.encode(signature)).toUpperCase();
+  }
 
-    return hex;
+  List<List<int>> bytesFromSigString(String signatureString) {
+    final regex = RegExp(r'Signature\(\[(.+)\], publicKey: (.+)\)');
+    final match = regex.firstMatch(signatureString);
+
+    if (match != null) {
+      final bytesString = match.group(1)!;
+      final base58EncodedPublicKeyString = match.group(2)!;
+      final sigBytes = bytesString.split(', ').map(int.parse).toList();
+
+      List<int> pubKeyBytes = base58decode(base58EncodedPublicKeyString);
+
+      return [sigBytes, pubKeyBytes];
+    } else {
+      throw const FormatException('Invalid Signature string format');
+    }
+  }
+
+  @override
+  Future<bool> verifyMessage(String message, String signature, {String? address}) async {
+    String signatureString = utf8.decode(HEX.decode(signature));
+
+    List<List<int>> bytes = bytesFromSigString(signatureString);
+
+    final messageBytes = utf8.encode(message);
+    final sigBytes = bytes[0];
+    final pubKeyBytes = bytes[1];
+
+    if (address == null) {
+      return false;
+    }
+
+    // make sure the address derived from the public key provided matches the one we expect
+    final pub = Ed25519HDPublicKey(pubKeyBytes);
+    if (address != pub.toBase58()) {
+      return false;
+    }
+
+    return await verifySignature(
+      message: messageBytes,
+      signature: sigBytes,
+      publicKey: Ed25519HDPublicKey(pubKeyBytes),
+    );
   }
 
   SolanaClient? get solanaClient => _client.getSolanaClient;
diff --git a/cw_tron/lib/tron_wallet.dart b/cw_tron/lib/tron_wallet.dart
index 7dc43b4bb..f5841d894 100644
--- a/cw_tron/lib/tron_wallet.dart
+++ b/cw_tron/lib/tron_wallet.dart
@@ -580,8 +580,18 @@ abstract class TronWalletBase
   }
 
   @override
-  Future<String> signMessage(String message, {String? address}) async =>
-      _tronPrivateKey.signPersonalMessage(ascii.encode(message));
+  Future<String> signMessage(String message, {String? address}) async {
+    return _tronPrivateKey.signPersonalMessage(ascii.encode(message));
+  }
+
+  @override
+  Future<bool> verifyMessage(String message, String signature, {String? address}) async {
+    if (address == null) {
+      return false;
+    }
+    TronPublicKey pubKey = TronPublicKey.fromPersonalSignature(ascii.encode(message), signature)!;
+    return pubKey.toAddress().toString() == address;
+  }
 
   String getTronBase58AddressFromHex(String hexAddress) => TronAddress(hexAddress).toAddress();
 
diff --git a/cw_wownero/lib/api/wallet.dart b/cw_wownero/lib/api/wallet.dart
index 0a06a9950..56f54dfac 100644
--- a/cw_wownero/lib/api/wallet.dart
+++ b/cw_wownero/lib/api/wallet.dart
@@ -320,3 +320,7 @@ Future<bool> trustedDaemon() async => wownero.Wallet_trustedDaemon(wptr!);
 String signMessage(String message, {String address = ""}) {
   return wownero.Wallet_signMessage(wptr!, message: message, address: address);
 }
+
+bool verifyMessage(String message, String address, String signature) {
+  return wownero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature);
+}
\ No newline at end of file
diff --git a/cw_wownero/lib/wownero_wallet.dart b/cw_wownero/lib/wownero_wallet.dart
index 85f5e4b2f..c3f4bcb69 100644
--- a/cw_wownero/lib/wownero_wallet.dart
+++ b/cw_wownero/lib/wownero_wallet.dart
@@ -743,4 +743,11 @@ abstract class WowneroWalletBase
     final useAddress = address ?? "";
     return wownero_wallet.signMessage(message, address: useAddress);
   }
+
+  @override
+  Future<bool> verifyMessage(String message, String signature, {String? address = null}) async {
+    if (address == null) return false;
+
+    return wownero_wallet.verifyMessage(message, address, signature);
+  }
 }
diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart
index 989cd2b35..e87773f97 100644
--- a/lib/bitcoin/cw_bitcoin.dart
+++ b/lib/bitcoin/cw_bitcoin.dart
@@ -275,7 +275,7 @@ class CWBitcoin extends Bitcoin {
     return [DerivationType.bip39, DerivationType.electrum];
   }
 
-  int _countOccurrences(String str, String charToCount) {
+  int _countCharOccurrences(String str, String charToCount) {
     int count = 0;
     for (int i = 0; i < str.length; i++) {
       if (str[i] == charToCount) {
@@ -330,7 +330,7 @@ class CWBitcoin extends Bitcoin {
           );
 
           String balancePath = dInfoCopy.derivationPath!;
-          int derivationDepth = _countOccurrences(balancePath, "/");
+          int derivationDepth = _countCharOccurrences(balancePath, '/');
 
           // for BIP44
           if (derivationDepth == 3 || derivationDepth == 1) {
diff --git a/lib/buy/dfx/dfx_buy_provider.dart b/lib/buy/dfx/dfx_buy_provider.dart
index 2a7e2ab13..b3ed72498 100644
--- a/lib/buy/dfx/dfx_buy_provider.dart
+++ b/lib/buy/dfx/dfx_buy_provider.dart
@@ -124,12 +124,12 @@ class DFXBuyProvider extends BuyProvider {
     switch (wallet.type) {
       case WalletType.ethereum:
       case WalletType.polygon:
-        return wallet.signMessage(message);
+        return await wallet.signMessage(message);
       case WalletType.monero:
       case WalletType.litecoin:
       case WalletType.bitcoin:
       case WalletType.bitcoinCash:
-        return wallet.signMessage(message, address: walletAddress);
+        return await wallet.signMessage(message, address: walletAddress);
       default:
         throw Exception("WalletType is not available for DFX ${wallet.type}");
     }
diff --git a/lib/buy/robinhood/robinhood_buy_provider.dart b/lib/buy/robinhood/robinhood_buy_provider.dart
index ab58754dd..2d809772e 100644
--- a/lib/buy/robinhood/robinhood_buy_provider.dart
+++ b/lib/buy/robinhood/robinhood_buy_provider.dart
@@ -37,15 +37,15 @@ class RobinhoodBuyProvider extends BuyProvider {
 
   String get _apiSecret => secrets.exchangeHelperApiKey;
 
-  Future<String> getSignature(String message) {
+  Future<String> getSignature(String message) async {
     switch (wallet.type) {
       case WalletType.ethereum:
       case WalletType.polygon:
-        return wallet.signMessage(message);
+        return await wallet.signMessage(message);
       case WalletType.litecoin:
       case WalletType.bitcoin:
       case WalletType.bitcoinCash:
-        return wallet.signMessage(message, address: wallet.walletAddresses.address);
+        return await wallet.signMessage(message, address: wallet.walletAddresses.address);
       default:
         throw Exception("WalletType is not available for Robinhood ${wallet.type}");
     }
diff --git a/lib/di.dart b/lib/di.dart
index 7c22e809c..1967c9227 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -30,6 +30,12 @@ import 'package:cake_wallet/entities/contact.dart';
 import 'package:cake_wallet/entities/contact_record.dart';
 import 'package:cake_wallet/entities/exchange_api_mode.dart';
 import 'package:cake_wallet/entities/parse_address_from_domain.dart';
+import 'package:cake_wallet/src/screens/receive/address_list_page.dart';
+import 'package:cake_wallet/view_model/link_view_model.dart';
+import 'package:cake_wallet/tron/tron.dart';
+import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
+import 'package:cake_wallet/view_model/dashboard/sign_view_model.dart';
+import 'package:cw_core/receive_page_option.dart';
 import 'package:cake_wallet/entities/preferences_key.dart';
 import 'package:cake_wallet/entities/qr_view_data.dart';
 import 'package:cake_wallet/entities/template.dart';
@@ -159,7 +165,6 @@ import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/transaction_info.dart';
 import 'package:cw_core/node.dart';
 import 'package:cake_wallet/src/screens/trade_details/trade_details_page.dart';
-import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
 import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart';
 import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
 import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
@@ -179,7 +184,6 @@ import 'package:cake_wallet/store/templates/exchange_template_store.dart';
 import 'package:cake_wallet/store/templates/send_template_store.dart';
 import 'package:cake_wallet/store/wallet_list_store.dart';
 import 'package:cake_wallet/store/yat/yat_store.dart';
-import 'package:cake_wallet/tron/tron.dart';
 import 'package:cake_wallet/view_model/auth_view_model.dart';
 import 'package:cake_wallet/view_model/backup_view_model.dart';
 import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart';
@@ -193,7 +197,6 @@ import 'package:cake_wallet/view_model/edit_backup_password_view_model.dart';
 import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart';
 import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
-import 'package:cake_wallet/view_model/link_view_model.dart';
 import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
 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';
@@ -224,7 +227,6 @@ import 'package:cake_wallet/view_model/wallet_unlock_loadable_view_model.dart';
 import 'package:cake_wallet/view_model/wallet_unlock_verifiable_view_model.dart';
 import 'package:cake_wallet/wownero/wownero.dart';
 import 'package:cw_core/crypto_currency.dart';
-import 'package:cw_core/receive_page_option.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:flutter/foundation.dart';
@@ -853,6 +855,8 @@ Future<void> setup({
   getIt.registerFactoryParam<ContactPage, ContactRecord?, void>(
       (ContactRecord? contact, _) => ContactPage(getIt.get<ContactViewModel>(param1: contact)));
 
+  getIt.registerFactory(() => AddressListPage(getIt.get<WalletAddressListViewModel>()));
+
   getIt.registerFactory(() {
     final appStore = getIt.get<AppStore>();
     return NodeListViewModel(_nodeSource, appStore);
@@ -1271,9 +1275,11 @@ Future<void> setup({
 
   getIt.registerFactory(
       () => WalletConnectConnectionsView(web3walletService: getIt.get<Web3WalletService>()));
-
+  
   getIt.registerFactory(() => NFTViewModel(appStore, getIt.get<BottomSheetService>()));
   getIt.registerFactory<TorPage>(() => TorPage(getIt.get<AppStore>()));
 
+  getIt.registerFactory(() => SignViewModel(getIt.get<AppStore>().wallet!));
+
   _isSetupFinished = true;
 }
diff --git a/lib/router.dart b/lib/router.dart
index 498077511..25af39043 100644
--- a/lib/router.dart
+++ b/lib/router.dart
@@ -27,6 +27,7 @@ import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart';
 import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart';
 import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart';
 import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart';
+import 'package:cake_wallet/src/screens/dashboard/sign_page.dart';
 import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
 import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart';
 import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
@@ -42,6 +43,8 @@ import 'package:cake_wallet/src/screens/new_wallet/new_wallet_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/pow_node_create_or_edit_page.dart';
+import 'package:cake_wallet/src/screens/receive/address_list_page.dart';
+import 'package:cake_wallet/src/screens/restore/sweeping_wallet_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/receive/anonpay_invoice_page.dart';
@@ -99,6 +102,7 @@ import 'package:cake_wallet/utils/payment_request.dart';
 import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
 import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
 import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
+import 'package:cake_wallet/view_model/dashboard/sign_view_model.dart';
 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
 import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
 import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
@@ -465,6 +469,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
       return MaterialPageRoute<void>(
           builder: (_) => getIt.get<ContactListPage>(param1: selectedCurrency));
 
+    case Routes.pickerWalletAddress:
+      return MaterialPageRoute<void>(builder: (_) => getIt.get<AddressListPage>());
+
     case Routes.addressBookAddContact:
       return CupertinoPageRoute<void>(
           builder: (_) => getIt.get<ContactPage>(param1: settings.arguments as ContactRecord?));
@@ -696,6 +703,13 @@ Route<dynamic> createRoute(RouteSettings settings) {
     case Routes.torPage:
       return MaterialPageRoute<void>(builder: (_) => getIt.get<TorPage>());
 
+    case Routes.signPage:
+      return MaterialPageRoute<void>(
+        builder: (_) => SignPage(
+          getIt.get<SignViewModel>(),
+        ),
+      );
+    
     case Routes.connectDevices:
       final params = settings.arguments as ConnectDevicePageParams;
       return MaterialPageRoute<void>(
diff --git a/lib/routes.dart b/lib/routes.dart
index caa7eb39e..9c421cab5 100644
--- a/lib/routes.dart
+++ b/lib/routes.dart
@@ -31,6 +31,7 @@ class Routes {
   static const nanoAccountCreation = '/nano_account_new';
   static const addressBook = '/address_book';
   static const pickerAddressBook = '/picker_address_book';
+  static const pickerWalletAddress = '/picker_wallet_address';
   static const addressBookAddContact = '/address_book_add_contact';
   static const showKeys = '/show_keys';
   static const exchangeConfirm = '/exchange_confirm';
@@ -103,5 +104,6 @@ class Routes {
   static const nftDetailsPage = '/nft_details_page';
   static const importNFTPage = '/import_nft_page';
   static const torPage = '/tor_page';
+  static const signPage = '/sign_page';
   static const connectDevices = '/device/connect';
 }
diff --git a/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart b/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart
index 02ddf037d..81f6a354f 100644
--- a/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart
+++ b/lib/src/screens/cake_pay/cards/cake_pay_confirm_purchase_card_page.dart
@@ -322,31 +322,31 @@ class CakePayBuyCardDetailPage extends BasePage {
 
     await showPopUp<void>(
       context: context,
-      builder: (_) {
+      builder: (popupContext) {
         return Observer(
             builder: (_) => ConfirmSendingAlert(
-                alertTitle: S.of(context).confirm_sending,
-                paymentId: S.of(context).payment_id,
+                alertTitle: S.of(popupContext).confirm_sending,
+                paymentId: S.of(popupContext).payment_id,
                 paymentIdValue: order?.orderId,
                 expirationTime: cakePayPurchaseViewModel.formattedRemainingTime,
                 onDispose: () => _handleDispose(disposer),
-                amount: S.of(context).send_amount,
+                amount: S.of(popupContext).send_amount,
                 amountValue: pendingTransaction.amountFormatted,
                 fiatAmountValue:
                     cakePayPurchaseViewModel.sendViewModel.pendingTransactionFiatAmountFormatted,
-                fee: S.of(context).send_fee,
+                fee: S.of(popupContext).send_fee,
                 feeValue: pendingTransaction.feeFormatted,
                 feeFiatAmount:
                     cakePayPurchaseViewModel.sendViewModel.pendingTransactionFeeFiatAmountFormatted,
                 feeRate: pendingTransaction.feeRate,
                 outputs: cakePayPurchaseViewModel.sendViewModel.outputs,
-                rightButtonText: S.of(context).send,
-                leftButtonText: S.of(context).cancel,
+                rightButtonText: S.of(popupContext).send,
+                leftButtonText: S.of(popupContext).cancel,
                 actionRightButton: () async {
-                  Navigator.of(context).pop();
+                  Navigator.of(popupContext).pop();
                   await cakePayPurchaseViewModel.sendViewModel.commitTransaction();
                 },
-                actionLeftButton: () => Navigator.of(context).pop()));
+                actionLeftButton: () => Navigator.of(popupContext).pop()));
       },
     );
   }
diff --git a/lib/src/screens/dashboard/pages/cake_features_page.dart b/lib/src/screens/dashboard/pages/cake_features_page.dart
index b034fb799..0c953c892 100644
--- a/lib/src/screens/dashboard/pages/cake_features_page.dart
+++ b/lib/src/screens/dashboard/pages/cake_features_page.dart
@@ -8,6 +8,7 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
 import 'package:url_launcher/url_launcher.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 
@@ -64,6 +65,19 @@ class CakeFeaturesPage extends StatelessWidget {
                       subTitle: S.of(context).nanogpt_subtitle,
                       onTap: () => _launchUrl("cake.nano-gpt.com"),
                     ),
+                    SizedBox(height: 20),
+                    Observer(
+                      builder: (context) {
+                        if (!dashboardViewModel.hasSignMessages) {
+                          return const SizedBox();
+                        }
+                        return DashBoardRoundedCardWidget(
+                          onTap: () => Navigator.of(context).pushNamed(Routes.signPage),
+                          title: S.current.sign_verify_message,
+                          subTitle: S.current.sign_verify_message_sub,
+                        );
+                      },
+                    ),
                   ],
                 ),
               ),
diff --git a/lib/src/screens/dashboard/sign_page.dart b/lib/src/screens/dashboard/sign_page.dart
new file mode 100644
index 000000000..05cf63728
--- /dev/null
+++ b/lib/src/screens/dashboard/sign_page.dart
@@ -0,0 +1,202 @@
+import 'package:cake_wallet/core/execution_state.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/screens/dashboard/widgets/sign_form.dart';
+import 'package:cake_wallet/src/screens/dashboard/widgets/verify_form.dart';
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
+import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
+import 'package:cake_wallet/src/widgets/primary_button.dart';
+import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
+import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cake_wallet/view_model/dashboard/sign_view_model.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+import 'package:keyboard_actions/keyboard_actions.dart';
+import 'package:mobx/mobx.dart';
+import 'package:smooth_page_indicator/smooth_page_indicator.dart';
+
+class SignPage extends BasePage {
+  SignPage(this.signViewModel)
+      : signFormKey = GlobalKey<SignFormState>(),
+        verifyFormKey = GlobalKey<VerifyFormState>(),
+        _pages = [],
+        _controller = PageController(initialPage: 0) {
+    _pages.add(SignForm(
+      key: signFormKey,
+      type: signViewModel.wallet.type,
+      includeAddress: signViewModel.signIncludesAddress,
+    ));
+    _pages.add(VerifyForm(
+      key: verifyFormKey,
+      type: signViewModel.wallet.type,
+    ));
+  }
+
+  @override
+  Widget middle(BuildContext context) => Observer(
+      builder: (_) => Text(
+            S.current.sign_verify_title,
+            style: TextStyle(
+              fontSize: 18.0,
+              fontWeight: FontWeight.bold,
+              fontFamily: 'Lato',
+              color: titleColor(context),
+            ),
+          ));
+
+  final SignViewModel signViewModel;
+  final PageController _controller;
+  final List<Widget> _pages;
+  final GlobalKey<SignFormState> signFormKey;
+  final GlobalKey<VerifyFormState> verifyFormKey;
+  bool _isEffectsInstalled = false;
+
+  @override
+  Widget body(BuildContext context) {
+    _setEffects(context);
+
+    return KeyboardActions(
+      config: KeyboardActionsConfig(
+        keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
+        keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
+        nextFocus: false,
+        actions: [
+          KeyboardActionsItem(
+            focusNode: FocusNode(),
+            toolbarButtons: [(_) => KeyboardDoneButton()],
+          )
+        ],
+      ),
+      child: Container(
+        height: 0,
+        color: Theme.of(context).colorScheme.background,
+        child: Center(
+          child: ConstrainedBox(
+            constraints:
+                BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                Expanded(
+                  child: PageView.builder(
+                    onPageChanged: (page) {
+                      signViewModel.isSigning = page == 0;
+                    },
+                    controller: _controller,
+                    itemCount: _pages.length,
+                    itemBuilder: (_, index) => SingleChildScrollView(child: _pages[index]),
+                  ),
+                ),
+                if (_pages.length > 1)
+                  Padding(
+                    padding: EdgeInsets.only(top: 10),
+                    child: SmoothPageIndicator(
+                      controller: _controller,
+                      count: _pages.length,
+                      effect: ColorTransitionEffect(
+                        spacing: 6.0,
+                        radius: 6.0,
+                        dotWidth: 6.0,
+                        dotHeight: 6.0,
+                        dotColor: Theme.of(context).hintColor.withOpacity(0.5),
+                        activeDotColor: Theme.of(context).hintColor,
+                      ),
+                    ),
+                  ),
+                Padding(
+                  padding: EdgeInsets.only(top: 20, bottom: 24, left: 24, right: 24),
+                  child: Column(
+                    children: [
+                      Observer(
+                        builder: (context) {
+                          return LoadingPrimaryButton(
+                            onPressed: () async {
+                              await _confirmForm(context);
+                            },
+                            text: signViewModel.isSigning
+                                ? S.current.sign_message
+                                : S.current.verify_message,
+                            color: Theme.of(context)
+                                .extension<WalletListTheme>()!
+                                .createNewWalletButtonBackgroundColor,
+                            textColor: Theme.of(context)
+                                .extension<WalletListTheme>()!
+                                .restoreWalletButtonTextColor,
+                            isLoading: signViewModel.state is IsExecutingState,
+                            isDisabled: signViewModel.state is IsExecutingState,
+                          );
+                        },
+                      ),
+                    ],
+                  ),
+                )
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+
+  void _setEffects(BuildContext context) async {
+    if (_isEffectsInstalled) {
+      return;
+    }
+    _isEffectsInstalled = true;
+
+    reaction((_) => signViewModel.state, (ExecutionState state) {
+      if (state is FailureState) {
+        WidgetsBinding.instance.addPostFrameCallback((_) {
+          showPopUp<void>(
+              context: context,
+              builder: (_) {
+                return AlertWithOneAction(
+                  alertTitle: S.current.error,
+                  alertContent: state.error,
+                  buttonText: S.of(context).ok,
+                  buttonAction: () => Navigator.of(context).pop(),
+                );
+              });
+        });
+      }
+      if (state is ExecutedSuccessfullyState) {
+        if (signViewModel.isSigning) {
+          signFormKey.currentState!.signatureController.text = state.payload as String;
+        } else {
+          WidgetsBinding.instance.addPostFrameCallback((_) {
+            showPopUp<void>(
+                context: context,
+                builder: (_) {
+                  return AlertWithOneAction(
+                    alertTitle: S.current.successful,
+                    alertContent: S.current.message_verified,
+                    buttonText: S.of(context).ok,
+                    buttonAction: () => Navigator.of(context).pop(),
+                  );
+                });
+          });
+        }
+      }
+    });
+  }
+
+  Future<void> _confirmForm(BuildContext context) async {
+    FocusManager.instance.primaryFocus?.unfocus();
+
+    if (signViewModel.isSigning) {
+      String message = signFormKey.currentState!.messageController.text;
+      String? address;
+      if (signViewModel.signIncludesAddress) {
+        address = signFormKey.currentState!.addressController.text;
+      }
+      await signViewModel.sign(message, address: address);
+    } else {
+      String message = verifyFormKey.currentState!.messageController.text;
+      String signature = verifyFormKey.currentState!.signatureController.text;
+      String address = verifyFormKey.currentState!.addressController.text;
+      await signViewModel.verify(message, signature, address: address);
+    }
+  }
+}
diff --git a/lib/src/screens/dashboard/widgets/sign_form.dart b/lib/src/screens/dashboard/widgets/sign_form.dart
new file mode 100644
index 000000000..c0f8ba328
--- /dev/null
+++ b/lib/src/screens/dashboard/widgets/sign_form.dart
@@ -0,0 +1,98 @@
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/widgets/address_text_field.dart';
+import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
+import 'package:cake_wallet/utils/show_bar.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+class SignForm extends StatefulWidget {
+  SignForm({
+    Key? key,
+    required this.type,
+    required this.includeAddress,
+  }) : super(key: key);
+
+  final WalletType type;
+  final bool includeAddress;
+
+  @override
+  SignFormState createState() => SignFormState();
+}
+
+class SignFormState extends State<SignForm> {
+  SignFormState()
+      : formKey = GlobalKey<FormState>(),
+        messageController = TextEditingController(),
+        addressController = TextEditingController(),
+        signatureController = TextEditingController();
+
+  final TextEditingController messageController;
+  final TextEditingController addressController;
+  final TextEditingController signatureController;
+  final GlobalKey<FormState> formKey;
+
+  @override
+  void initState() {
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      padding: EdgeInsets.only(left: 24, right: 24),
+      child: Column(
+        children: [
+          Form(
+              key: formKey,
+              child: Column(
+                children: [
+                  AddressTextField(
+                    controller: messageController,
+                    placeholder: S.current.message,
+                    options: [AddressTextFieldOption.paste],
+                    buttonColor: Theme.of(context).hintColor,
+                  ),
+                  if (widget.includeAddress) ...[
+                    const SizedBox(height: 20),
+                    AddressTextField(
+                      controller: addressController,
+                      options: [
+                        AddressTextFieldOption.paste,
+                        AddressTextFieldOption.walletAddresses
+                      ],
+                      buttonColor: Theme.of(context).hintColor,
+                      onSelectedContact: (contact) {
+                        addressController.text = contact.address;
+                      },
+                      selectedCurrency: walletTypeToCryptoCurrency(widget.type),
+                    ),
+                  ],
+                ],
+              )),
+          const SizedBox(height: 20),
+          GestureDetector(
+            onTap: () async {
+              final text = signatureController.text;
+              if (text.isEmpty) {
+                return;
+              }
+              Clipboard.setData(ClipboardData(text: text));
+              showBar<void>(context, S.of(context).transaction_details_copied(text));
+            },
+            child: BaseTextFormField(
+              enabled: false,
+              controller: signatureController,
+              hintText: S.current.signature,
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/src/screens/dashboard/widgets/verify_form.dart b/lib/src/screens/dashboard/widgets/verify_form.dart
new file mode 100644
index 000000000..d59261494
--- /dev/null
+++ b/lib/src/screens/dashboard/widgets/verify_form.dart
@@ -0,0 +1,92 @@
+import 'package:cake_wallet/core/wallet_name_validator.dart';
+import 'package:cake_wallet/entities/generate_name.dart';
+import 'package:cake_wallet/entities/seed_type.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/widgets/address_text_field.dart';
+import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
+import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
+import 'package:cake_wallet/src/widgets/picker.dart';
+import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
+import 'package:cake_wallet/src/widgets/seed_widget.dart';
+import 'package:cake_wallet/themes/extensions/address_theme.dart';
+import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
+import 'package:cake_wallet/utils/show_bar.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cake_wallet/view_model/seed_type_view_model.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:mobx/mobx.dart';
+import 'package:polyseed/polyseed.dart';
+
+class VerifyForm extends StatefulWidget {
+  VerifyForm({
+    Key? key,
+    required this.type,
+  }) : super(key: key);
+
+  final WalletType type;
+
+  @override
+  VerifyFormState createState() => VerifyFormState();
+}
+
+class VerifyFormState extends State<VerifyForm> {
+  VerifyFormState()
+      : formKey = GlobalKey<FormState>(),
+        messageController = TextEditingController(),
+        addressController = TextEditingController(),
+        signatureController = TextEditingController();
+
+  final TextEditingController messageController;
+  final TextEditingController addressController;
+  final TextEditingController signatureController;
+  final GlobalKey<FormState> formKey;
+
+  @override
+  void initState() {
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      padding: EdgeInsets.only(left: 24, right: 24),
+      child: Form(
+        key: formKey,
+        child: Column(
+          children: [
+            AddressTextField(
+              controller: messageController,
+              placeholder: S.current.message,
+              options: [AddressTextFieldOption.paste],
+              buttonColor: Theme.of(context).hintColor,
+            ),
+            const SizedBox(height: 20),
+            AddressTextField(
+              controller: addressController,
+              options: [AddressTextFieldOption.paste, AddressTextFieldOption.walletAddresses],
+              buttonColor: Theme.of(context).hintColor,
+              onSelectedContact: (contact) {
+                addressController.text = contact.address;
+              },
+              selectedCurrency: walletTypeToCryptoCurrency(widget.type),
+            ),
+            const SizedBox(height: 20),
+            AddressTextField(
+              controller: signatureController,
+              placeholder: S.current.signature,
+              options: [AddressTextFieldOption.paste],
+              buttonColor: Theme.of(context).hintColor,
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/src/screens/receive/address_list_page.dart b/lib/src/screens/receive/address_list_page.dart
new file mode 100644
index 000000000..5f6794715
--- /dev/null
+++ b/lib/src/screens/receive/address_list_page.dart
@@ -0,0 +1,31 @@
+import 'package:cake_wallet/src/screens/receive/widgets/address_list.dart';
+import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/src/screens/base_page.dart';
+
+class AddressListPage extends BasePage {
+  AddressListPage(this.addressListViewModel);
+
+  final WalletAddressListViewModel addressListViewModel;
+
+  @override
+  String get title => S.current.accounts_subaddresses;
+
+  @override
+  Widget body(BuildContext context) {
+    return SingleChildScrollView(
+      child: Column(
+        children: <Widget>[
+          AddressList(
+            addressListViewModel: addressListViewModel,
+            onSelect: (String address) async {
+              Navigator.of(context).pop(address);
+            },
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/src/screens/receive/receive_page.dart b/lib/src/screens/receive/receive_page.dart
index 03524ef79..724e5c3bd 100644
--- a/lib/src/screens/receive/receive_page.dart
+++ b/lib/src/screens/receive/receive_page.dart
@@ -1,4 +1,5 @@
 import 'package:cake_wallet/src/screens/nano_accounts/nano_account_list_page.dart';
+import 'package:cake_wallet/src/screens/receive/widgets/address_list.dart';
 import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
 import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
 import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
@@ -122,108 +123,7 @@ class ReceivePage extends BasePage {
                     amountController: _amountController,
                     isLight: currentTheme.type == ThemeType.light),
               ),
-              Observer(
-                  builder: (_) => ListView.separated(
-                      padding: EdgeInsets.all(0),
-                      separatorBuilder: (context, _) => const HorizontalSectionDivider(),
-                      shrinkWrap: true,
-                      physics: NeverScrollableScrollPhysics(),
-                      itemCount: addressListViewModel.items.length,
-                      itemBuilder: (context, index) {
-                        final item = addressListViewModel.items[index];
-                        Widget cell = Container();
-
-                        if (item is WalletAccountListHeader) {
-                          cell = HeaderTile(
-                              showTrailingButton: true,
-                              walletAddressListViewModel: addressListViewModel,
-                              trailingButtonTap: () async {
-                                if (addressListViewModel.type == WalletType.monero ||
-                                    addressListViewModel.type == WalletType.wownero ||
-                                    addressListViewModel.type == WalletType.haven) {
-                                  await showPopUp<void>(
-                                      context: context,
-                                      builder: (_) => getIt.get<MoneroAccountListPage>());
-                                } else {
-                                  await showPopUp<void>(
-                                      context: context,
-                                      builder: (_) => getIt.get<NanoAccountListPage>());
-                                }
-                              },
-                              title: S.of(context).accounts,
-                              trailingIcon: Icon(
-                                Icons.arrow_forward_ios,
-                                size: 14,
-                                color: Theme.of(context).extension<ReceivePageTheme>()!.iconsColor,
-                              ));
-                        }
-
-                        if (item is WalletAddressListHeader) {
-                          final hasTitle = item.title != null;
-
-                          cell = HeaderTile(
-                            title: hasTitle ? item.title! : S.of(context).addresses,
-                            walletAddressListViewModel: addressListViewModel,
-                            showTrailingButton:
-                                !addressListViewModel.isAutoGenerateSubaddressEnabled && !hasTitle,
-                            showSearchButton: true,
-                            trailingButtonTap: () =>
-                                Navigator.of(context).pushNamed(Routes.newSubaddress),
-                            trailingIcon: hasTitle
-                                ? null
-                                : Icon(
-                                    Icons.add,
-                                    size: 20,
-                                    color:
-                                        Theme.of(context).extension<ReceivePageTheme>()!.iconsColor,
-                                  ),
-                          );
-                        }
-
-                        if (item is WalletAddressListItem) {
-                          cell = Observer(builder: (_) {
-                            final isCurrent = item.address == addressListViewModel.address.address;
-                            final backgroundColor = isCurrent
-                                ? Theme.of(context)
-                                    .extension<ReceivePageTheme>()!
-                                    .currentTileBackgroundColor
-                                : Theme.of(context)
-                                    .extension<ReceivePageTheme>()!
-                                    .tilesBackgroundColor;
-                            final textColor = isCurrent
-                                ? Theme.of(context)
-                                    .extension<ReceivePageTheme>()!
-                                    .currentTileTextColor
-                                : Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor;
-
-                            return AddressCell.fromItem(
-                              item,
-                              isCurrent: isCurrent,
-                              hasBalance: addressListViewModel.isElectrumWallet,
-                              backgroundColor: backgroundColor,
-                              textColor: textColor,
-                              onTap: item.isOneTimeReceiveAddress == true
-                                  ? null
-                                  : (_) => addressListViewModel.setAddress(item),
-                              onEdit: item.isOneTimeReceiveAddress == true || item.isPrimary
-                                  ? null
-                                  : () => Navigator.of(context)
-                                      .pushNamed(Routes.newSubaddress, arguments: item),
-                              onDelete: !addressListViewModel.isSilentPayments || item.isPrimary
-                                  ? null
-                                  : () => addressListViewModel.deleteAddress(item),
-                            );
-                          });
-                        }
-
-                        return index != 0
-                            ? cell
-                            : ClipRRect(
-                                borderRadius: BorderRadius.only(
-                                    topLeft: Radius.circular(30), topRight: Radius.circular(30)),
-                                child: cell,
-                              );
-                      })),
+              AddressList(addressListViewModel: addressListViewModel),
               Padding(
                 padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
                 child: Text(
diff --git a/lib/src/screens/receive/widgets/address_list.dart b/lib/src/screens/receive/widgets/address_list.dart
new file mode 100644
index 000000000..8dfbedec1
--- /dev/null
+++ b/lib/src/screens/receive/widgets/address_list.dart
@@ -0,0 +1,120 @@
+import 'package:cake_wallet/di.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/routes.dart';
+import 'package:cake_wallet/src/screens/monero_accounts/monero_account_list_page.dart';
+import 'package:cake_wallet/src/screens/nano_accounts/nano_account_list_page.dart';
+import 'package:cake_wallet/src/screens/receive/widgets/address_cell.dart';
+import 'package:cake_wallet/src/screens/receive/widgets/header_tile.dart';
+import 'package:cake_wallet/src/widgets/section_divider.dart';
+import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cake_wallet/view_model/wallet_address_list/wallet_account_list_header.dart';
+import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_header.dart';
+import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
+import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+
+class AddressList extends StatelessWidget {
+  const AddressList({
+    super.key,
+    required this.addressListViewModel,
+    this.onSelect,
+  });
+
+  final WalletAddressListViewModel addressListViewModel;
+  final Function(String)? onSelect;
+
+  @override
+  Widget build(BuildContext context) {
+    bool editable = onSelect == null;
+    return Observer(
+      builder: (_) => ListView.separated(
+        padding: EdgeInsets.all(0),
+        separatorBuilder: (context, _) => const HorizontalSectionDivider(),
+        shrinkWrap: true,
+        physics: NeverScrollableScrollPhysics(),
+        itemCount: addressListViewModel.items.length,
+        itemBuilder: (context, index) {
+          final item = addressListViewModel.items[index];
+          Widget cell = Container();
+
+          if (item is WalletAccountListHeader) {
+            cell = HeaderTile(
+                showTrailingButton: true,
+                walletAddressListViewModel: addressListViewModel,
+                trailingButtonTap: () async {
+                  if (addressListViewModel.type == WalletType.monero ||
+                      addressListViewModel.type == WalletType.haven) {
+                    await showPopUp<void>(
+                        context: context, builder: (_) => getIt.get<MoneroAccountListPage>());
+                  } else {
+                    await showPopUp<void>(
+                        context: context, builder: (_) => getIt.get<NanoAccountListPage>());
+                  }
+                },
+                title: S.of(context).accounts,
+                trailingIcon: Icon(
+                  Icons.arrow_forward_ios,
+                  size: 14,
+                  color: Theme.of(context).extension<ReceivePageTheme>()!.iconsColor,
+                ));
+          }
+
+          if (item is WalletAddressListHeader) {
+            cell = HeaderTile(
+                title: S.of(context).addresses,
+                walletAddressListViewModel: addressListViewModel,
+                showTrailingButton: !addressListViewModel.isAutoGenerateSubaddressEnabled,
+                showSearchButton: true,
+                trailingButtonTap: () => Navigator.of(context).pushNamed(Routes.newSubaddress),
+                trailingIcon: Icon(
+                  Icons.add,
+                  size: 20,
+                  color: Theme.of(context).extension<ReceivePageTheme>()!.iconsColor,
+                ));
+          }
+
+          if (item is WalletAddressListItem) {
+            cell = Observer(builder: (_) {
+              final isCurrent = item.address == addressListViewModel.address.address && editable;
+              final backgroundColor = isCurrent
+                  ? Theme.of(context).extension<ReceivePageTheme>()!.currentTileBackgroundColor
+                  : Theme.of(context).extension<ReceivePageTheme>()!.tilesBackgroundColor;
+              final textColor = isCurrent
+                  ? Theme.of(context).extension<ReceivePageTheme>()!.currentTileTextColor
+                  : Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor;
+
+              return AddressCell.fromItem(
+                item,
+                isCurrent: isCurrent,
+                hasBalance: addressListViewModel.isElectrumWallet,
+                backgroundColor: backgroundColor,
+                textColor: textColor,
+                onTap: (_) {
+                  if (onSelect != null) {
+                    onSelect!(item.address);
+                    return;
+                  }
+                  addressListViewModel.setAddress(item);
+                },
+                onEdit: editable
+                    ? () => Navigator.of(context).pushNamed(Routes.newSubaddress, arguments: item)
+                    : null,
+              );
+            });
+          }
+
+          return index != 0
+              ? cell
+              : ClipRRect(
+                  borderRadius: BorderRadius.only(
+                      topLeft: Radius.circular(30), topRight: Radius.circular(30)),
+                  child: cell,
+                );
+        },
+      ),
+    );
+  }
+}
diff --git a/lib/src/widgets/address_text_field.dart b/lib/src/widgets/address_text_field.dart
index f79da8069..f229ea8ef 100644
--- a/lib/src/widgets/address_text_field.dart
+++ b/lib/src/widgets/address_text_field.dart
@@ -12,7 +12,7 @@ import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
 import 'package:cake_wallet/utils/permission_handler.dart';
 import 'package:permission_handler/permission_handler.dart';
 
-enum AddressTextFieldOption { paste, qrCode, addressBook }
+enum AddressTextFieldOption { paste, qrCode, addressBook, walletAddresses }
 
 class AddressTextField extends StatelessWidget {
   AddressTextField(
@@ -34,6 +34,7 @@ class AddressTextField extends StatelessWidget {
       this.validator,
       this.onPushPasteButton,
       this.onPushAddressBookButton,
+      this.onPushAddressPickerButton,
       this.onSelectedContact,
       this.selectedCurrency});
 
@@ -56,6 +57,7 @@ class AddressTextField extends StatelessWidget {
   final FocusNode? focusNode;
   final Function(BuildContext context)? onPushPasteButton;
   final Function(BuildContext context)? onPushAddressBookButton;
+  final Function(BuildContext context)? onPushAddressPickerButton;
   final Function(ContactBase contact)? onSelectedContact;
   final CryptoCurrency? selectedCurrency;
 
@@ -70,16 +72,13 @@ class AddressTextField extends StatelessWidget {
           enabled: isActive,
           controller: controller,
           focusNode: focusNode,
-        
           style: textStyle ??
               TextStyle(
                   fontSize: 16, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
           decoration: InputDecoration(
-          
             suffixIcon: SizedBox(
               width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length),
             ),
-         
             hintStyle: hintStyle ?? TextStyle(fontSize: 16, color: Theme.of(context).hintColor),
             hintText: placeholder ?? S.current.widgets_address,
             focusedBorder: isBorderExist
@@ -104,90 +103,122 @@ class AddressTextField extends StatelessWidget {
             top: 2,
             right: 0,
             child: SizedBox(
-              width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length),
+              width:
+                  (prefixIconWidth * options.length) + (spaceBetweenPrefixIcons * options.length),
               child: Row(
                 mainAxisAlignment: responsiveLayoutUtil.shouldRenderMobileUI
                     ? MainAxisAlignment.spaceBetween
                     : MainAxisAlignment.end,
                 children: [
-                  SizedBox(width: 5),
                   if (this.options.contains(AddressTextFieldOption.paste)) ...[
+                    SizedBox(width: 5),
                     Container(
-                        width: prefixIconWidth,
-                        height: prefixIconHeight,
-                        padding: EdgeInsets.only(top: 0),
-                        child: Semantics(
-                          label: S.of(context).paste,
-                          child: InkWell(
-                            onTap: () async => _pasteAddress(context),
-                            child: Container(
-                                padding: EdgeInsets.all(8),
-                                decoration: BoxDecoration(
-                                    color: buttonColor ??
-                                        Theme.of(context).dialogTheme.backgroundColor,
-                                    borderRadius: BorderRadius.all(Radius.circular(6))),
-                                child: Image.asset(
-                                  'assets/images/paste_ios.png',
-                                  color: iconColor ??
-                                      Theme.of(context)
-                                          .extension<SendPageTheme>()!
-                                          .textFieldButtonIconColor,
-                                )),
-                          ),
-                        )),
+                      width: prefixIconWidth,
+                      height: prefixIconHeight,
+                      padding: EdgeInsets.only(top: 0),
+                      child: Semantics(
+                        label: S.of(context).paste,
+                        child: InkWell(
+                          onTap: () async => _pasteAddress(context),
+                          child: Container(
+                              padding: EdgeInsets.all(8),
+                              decoration: BoxDecoration(
+                                  color:
+                                      buttonColor ?? Theme.of(context).dialogTheme.backgroundColor,
+                                  borderRadius: BorderRadius.all(Radius.circular(6))),
+                              child: Image.asset(
+                                'assets/images/paste_ios.png',
+                                color: iconColor ??
+                                    Theme.of(context)
+                                        .extension<SendPageTheme>()!
+                                        .textFieldButtonIconColor,
+                              )),
+                        ),
+                      ),
+                    ),
                   ],
                   if (this.options.contains(AddressTextFieldOption.qrCode) &&
                       DeviceInfo.instance.isMobile) ...[
-                    Container(
-                        width: prefixIconWidth,
-                        height: prefixIconHeight,
-                        padding: EdgeInsets.only(top: 0),
-                        child: Semantics(
-                          label: S.of(context).scan_qr_code,
-                          child: InkWell(
-                            onTap: () async => _presentQRScanner(context),
-                            child: Container(
-                                padding: EdgeInsets.all(8),
-                                decoration: BoxDecoration(
-                                    color: buttonColor ??
-                                        Theme.of(context).dialogTheme.backgroundColor,
-                                    borderRadius: BorderRadius.all(Radius.circular(6))),
-                                child: Image.asset(
-                                  'assets/images/qr_code_icon.png',
-                                  color: iconColor ??
-                                      Theme.of(context)
-                                          .extension<SendPageTheme>()!
-                                          .textFieldButtonIconColor,
-                                )),
-                          ),
-                        ))
-                  ] else
                     SizedBox(width: 5),
-                  if (this.options.contains(AddressTextFieldOption.addressBook)) ...[
                     Container(
-                        width: prefixIconWidth,
-                        height: prefixIconHeight,
-                        padding: EdgeInsets.only(top: 0),
-                        child: Semantics(
-                          label: S.of(context).address_book,
-                          child: InkWell(
-                            onTap: () async => _presetAddressBookPicker(context),
-                            child: Container(
-                                padding: EdgeInsets.all(8),
-                                decoration: BoxDecoration(
-                                    color: buttonColor ??
-                                        Theme.of(context).dialogTheme.backgroundColor,
-                                    borderRadius: BorderRadius.all(Radius.circular(6))),
-                                child: Image.asset(
-                                  'assets/images/open_book.png',
-                                  color: iconColor ??
-                                      Theme.of(context)
-                                          .extension<SendPageTheme>()!
-                                          .textFieldButtonIconColor,
-                                )),
-                          ),
-                        ))
-                  ]
+                      width: prefixIconWidth,
+                      height: prefixIconHeight,
+                      padding: EdgeInsets.only(top: 0),
+                      child: Semantics(
+                        label: S.of(context).scan_qr_code,
+                        child: InkWell(
+                          onTap: () async => _presentQRScanner(context),
+                          child: Container(
+                              padding: EdgeInsets.all(8),
+                              decoration: BoxDecoration(
+                                  color:
+                                      buttonColor ?? Theme.of(context).dialogTheme.backgroundColor,
+                                  borderRadius: BorderRadius.all(Radius.circular(6))),
+                              child: Image.asset(
+                                'assets/images/qr_code_icon.png',
+                                color: iconColor ??
+                                    Theme.of(context)
+                                        .extension<SendPageTheme>()!
+                                        .textFieldButtonIconColor,
+                              )),
+                        ),
+                      ),
+                    ),
+                  ],
+                  if (this.options.contains(AddressTextFieldOption.addressBook)) ...[
+                    SizedBox(width: 5),
+                    Container(
+                      width: prefixIconWidth,
+                      height: prefixIconHeight,
+                      padding: EdgeInsets.only(top: 0),
+                      child: Semantics(
+                        label: S.of(context).address_book,
+                        child: InkWell(
+                          onTap: () async => _presetAddressBookPicker(context),
+                          child: Container(
+                              padding: EdgeInsets.all(8),
+                              decoration: BoxDecoration(
+                                  color:
+                                      buttonColor ?? Theme.of(context).dialogTheme.backgroundColor,
+                                  borderRadius: BorderRadius.all(Radius.circular(6))),
+                              child: Image.asset(
+                                'assets/images/open_book.png',
+                                color: iconColor ??
+                                    Theme.of(context)
+                                        .extension<SendPageTheme>()!
+                                        .textFieldButtonIconColor,
+                              )),
+                        ),
+                      ),
+                    ),
+                  ],
+                  if (this.options.contains(AddressTextFieldOption.walletAddresses)) ...[
+                    SizedBox(width: 5),
+                    Container(
+                      width: prefixIconWidth,
+                      height: prefixIconHeight,
+                      padding: EdgeInsets.only(top: 0),
+                      child: Semantics(
+                        label: S.of(context).address_book,
+                        child: InkWell(
+                          onTap: () async => _presetWalletAddressPicker(context),
+                          child: Container(
+                              padding: EdgeInsets.all(8),
+                              decoration: BoxDecoration(
+                                  color:
+                                      buttonColor ?? Theme.of(context).dialogTheme.backgroundColor,
+                                  borderRadius: BorderRadius.all(Radius.circular(6))),
+                              child: Image.asset(
+                                'assets/images/open_book.png',
+                                color: iconColor ??
+                                    Theme.of(context)
+                                        .extension<SendPageTheme>()!
+                                        .textFieldButtonIconColor,
+                              )),
+                        ),
+                      ),
+                    )
+                  ],
                 ],
               ),
             ))
@@ -197,7 +228,7 @@ class AddressTextField extends StatelessWidget {
 
   Future<void> _presentQRScanner(BuildContext context) async {
     bool isCameraPermissionGranted =
-    await PermissionHandler.checkPermission(Permission.camera, context);
+        await PermissionHandler.checkPermission(Permission.camera, context);
     if (!isCameraPermissionGranted) return;
     final code = await presentQRScanner();
     if (code.isEmpty) {
@@ -224,6 +255,15 @@ class AddressTextField extends StatelessWidget {
     }
   }
 
+  Future<void> _presetWalletAddressPicker(BuildContext context) async {
+    final address = await Navigator.of(context).pushNamed(Routes.pickerWalletAddress);
+
+    if (address is String) {
+      controller?.text = address;
+      onPushAddressPickerButton?.call(context);
+    }
+  }
+
   Future<void> _pasteAddress(BuildContext context) async {
     final clipboard = await Clipboard.getData('text/plain');
     final address = clipboard?.text ?? '';
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index e98412dce..56a0e061b 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -182,7 +182,8 @@ abstract class DashboardViewModelBase with Store {
 
       final _accountTransactions = _wallet.transactionHistory.transactions.values
           .where((tx) =>
-              wow.wownero!.getTransactionInfoAccountId(tx) == wow.wownero!.getCurrentAccount(wallet).id)
+              wow.wownero!.getTransactionInfoAccountId(tx) ==
+              wow.wownero!.getCurrentAccount(wallet).id)
           .toList();
 
       final sortedTransactions = [..._accountTransactions];
@@ -482,6 +483,27 @@ abstract class DashboardViewModelBase with Store {
   @computed
   bool get hasPowNodes => wallet.type == WalletType.nano || wallet.type == WalletType.banano;
 
+  @computed
+  bool get hasSignMessages {
+    switch (wallet.type) {
+      case WalletType.monero:
+      case WalletType.litecoin:
+      case WalletType.bitcoin:
+      case WalletType.bitcoinCash:
+      case WalletType.ethereum:
+      case WalletType.polygon:
+      case WalletType.solana:
+      case WalletType.nano:
+      case WalletType.banano:
+      case WalletType.tron:
+      case WalletType.wownero:
+        return true;
+      case WalletType.haven:
+      case WalletType.none:
+        return false;
+    }
+  }
+
   bool get showRepWarning {
     if (wallet.type != WalletType.nano) {
       return false;
@@ -575,7 +597,8 @@ abstract class DashboardViewModelBase with Store {
       }
 
       if (wallet.type == WalletType.wownero) {
-        return wow.wownero!.getTransactionInfoAccountId(tx) == wow.wownero!.getCurrentAccount(wallet).id;
+        return wow.wownero!.getTransactionInfoAccountId(tx) ==
+            wow.wownero!.getCurrentAccount(wallet).id;
       }
 
       return true;
@@ -600,8 +623,8 @@ abstract class DashboardViewModelBase with Store {
           .getTransactionHistory(wallet)
           .transactions
           .values
-          .where(
-              (tx) => monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id)
+          .where((tx) =>
+              monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id)
           .toList();
 
       transactions.addAll(_accountTransactions.map((transaction) => TransactionListItem(
@@ -613,8 +636,9 @@ abstract class DashboardViewModelBase with Store {
           .getTransactionHistory(wallet)
           .transactions
           .values
-          .where(
-              (tx) => wow.wownero!.getTransactionInfoAccountId(tx) == wow.wownero!.getCurrentAccount(wallet).id)
+          .where((tx) =>
+              wow.wownero!.getTransactionInfoAccountId(tx) ==
+              wow.wownero!.getCurrentAccount(wallet).id)
           .toList();
 
       transactions.addAll(_accountTransactions.map((transaction) => TransactionListItem(
diff --git a/lib/view_model/dashboard/sign_view_model.dart b/lib/view_model/dashboard/sign_view_model.dart
new file mode 100644
index 000000000..5b1b4fc00
--- /dev/null
+++ b/lib/view_model/dashboard/sign_view_model.dart
@@ -0,0 +1,55 @@
+import 'package:cake_wallet/core/execution_state.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cw_core/wallet_base.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:mobx/mobx.dart';
+
+part 'sign_view_model.g.dart';
+
+class SignViewModel = SignViewModelBase with _$SignViewModel;
+
+abstract class SignViewModelBase with Store {
+  SignViewModelBase(this.wallet) : state = InitialExecutionState();
+
+  final WalletBase wallet;
+
+  @observable
+  ExecutionState state;
+
+  @observable
+  bool isSigning = true;
+
+  bool get signIncludesAddress => [
+        WalletType.monero,
+        WalletType.bitcoin,
+        WalletType.bitcoinCash,
+        WalletType.litecoin,
+        WalletType.haven,
+      ].contains(wallet.type);
+
+  @action
+  Future<void> sign(String message, {String? address}) async {
+    state = IsExecutingState();
+    try {
+      final signature = await wallet.signMessage(message, address: address);
+      state = ExecutedSuccessfullyState(payload: signature);
+    } catch (e) {
+      state = FailureState(e.toString());
+    }
+  }
+
+  @action
+  Future<void> verify(String message, String signature, {String? address}) async {
+    state = IsExecutingState();
+    try {
+      final sig = await wallet.verifyMessage(message, signature, address: address);
+      if (sig) {
+        state = ExecutedSuccessfullyState();
+      } else {
+        state = FailureState(S.current.signature_invalid_error);
+      }
+    } catch (e) {
+      state = FailureState(e.toString());
+    }
+  }
+}
diff --git a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
index 6c274bb7b..0bd936720 100644
--- a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
+++ b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
@@ -6,6 +6,7 @@ import 'package:cake_wallet/ethereum/ethereum.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/haven/haven.dart';
 import 'package:cake_wallet/monero/monero.dart';
+import 'package:cake_wallet/nano/nano.dart';
 import 'package:cake_wallet/polygon/polygon.dart';
 import 'package:cake_wallet/solana/solana.dart';
 import 'package:cake_wallet/store/app_store.dart';
@@ -438,6 +439,14 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
       addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress));
     }
 
+    if (wallet.type == WalletType.nano) {
+      addressList.add(WalletAddressListItem(
+        isPrimary: true,
+        name: null,
+        address: wallet.walletAddresses.address,
+      ));
+    }
+    
     if (wallet.type == WalletType.tron) {
       final primaryAddress = tron!.getAddress(wallet);
 
diff --git a/lib/view_model/wallet_creation_vm.dart b/lib/view_model/wallet_creation_vm.dart
index 5a9a1d093..e14934986 100644
--- a/lib/view_model/wallet_creation_vm.dart
+++ b/lib/view_model/wallet_creation_vm.dart
@@ -117,9 +117,7 @@ abstract class WalletCreationVMBase with Store {
   DerivationInfo? getDefaultDerivation() {
     switch (this.type) {
       case WalletType.nano:
-        return DerivationInfo(
-          derivationType: DerivationType.nano,
-        );
+        return DerivationInfo(derivationType: DerivationType.nano);
       case WalletType.bitcoin:
       case WalletType.litecoin:
         return bitcoin!.getElectrumDerivations()[DerivationType.electrum]!.first;
@@ -131,9 +129,7 @@ abstract class WalletCreationVMBase with Store {
   DerivationInfo? getCommonRestoreDerivation() {
     switch (this.type) {
       case WalletType.nano:
-        return DerivationInfo(
-          derivationType: DerivationType.nano,
-        );
+        return DerivationInfo(derivationType: DerivationType.nano);
       case WalletType.bitcoin:
         return DerivationInfo(
           derivationType: DerivationType.bip39,
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index a2f346bae..07dc7f5af 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -103,7 +103,7 @@ dependencies:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v4
+      ref: cake-update-v5
   ledger_flutter: ^1.0.1
   hashlib: 1.12.0
 
@@ -138,6 +138,10 @@ dependency_overrides:
       url: https://github.com/cake-tech/web3dart.git
       ref: cake
   flutter_secure_storage_platform_interface: 1.0.2
+  bitcoin_base:
+    git:
+      url: https://github.com/cake-tech/bitcoin_base
+      ref: cake-update-v5
 
 flutter_icons:
   image_path: "assets/images/app_logo.png"
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index a73067383..f84f6102b 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -370,6 +370,7 @@
   "max_value": "الحد الأقصى: ${value} ${currency}",
   "memo": "مذكرة:",
   "message": "ﺔﻟﺎﺳﺭ",
+  "message_verified": "تم التحقق من الرسالة بنجاح",
   "methods": " ﻕﺮﻃُ",
   "min_amount": "الحد الأدنى: ${value}",
   "min_value": "الحد الأدنى: ${value} ${currency}",
@@ -661,7 +662,13 @@
   "show_keys": "اظهار السييد / المفاتيح",
   "show_market_place": "إظهار السوق",
   "show_seed": "عرض السييد",
+  "sign_message": "تسجيل رسالة",
   "sign_up": "اشتراك",
+  "sign_verify_message": "توقيع أو التحقق من الرسالة",
+  "sign_verify_message_sub": "قم بتوقيع أو التحقق من رسالة باستخدام المفتاح الخاص بك",
+  "sign_verify_title": "تسجيل / تحقق",
+  "signature": "إمضاء",
+  "signature_invalid_error": "التوقيع غير صالح للرسالة المقدمة",
   "signTransaction": " ﺔﻠﻣﺎﻌﻤﻟﺍ ﻊﻴﻗﻮﺗ",
   "signup_for_card_accept_terms": "قم بالتسجيل للحصول على البطاقة وقبول الشروط.",
   "silent_payments": "مدفوعات صامتة",
@@ -822,6 +829,7 @@
   "value_type": "نوع القيمة",
   "variable_pair_not_supported": "هذا الزوج المتغير غير مدعوم في التبادلات المحددة",
   "verification": "تَحَقّق",
+  "verify_message": "تحقق من الرسالة",
   "verify_with_2fa": "تحقق مع Cake 2FA",
   "version": "الإصدار ${currentVersion}",
   "view_all": "مشاهدة الكل",
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index b60cbc55c..0b6b688bb 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -370,6 +370,7 @@
   "max_value": "Макс: ${value} ${currency}",
   "memo": "Мемо:",
   "message": "Съобщение",
+  "message_verified": "Съобщението беше успешно проверено",
   "methods": "Методи",
   "min_amount": "Мин: ${value}",
   "min_value": "Мин: ${value} ${currency}",
@@ -661,7 +662,13 @@
   "show_keys": "Покажи seed/keys",
   "show_market_place": "Покажи пазар",
   "show_seed": "Покажи seed",
+  "sign_message": "Съобщение за подписване",
   "sign_up": "Регистрация",
+  "sign_verify_message": "Подпишете или проверете съобщението",
+  "sign_verify_message_sub": "Подпишете или проверете съобщение с помощта на вашия личен ключ",
+  "sign_verify_title": "Подпишете / проверете",
+  "signature": "Подпис",
+  "signature_invalid_error": "Подписът не е валиден за даденото съобщение",
   "signTransaction": "Подпишете транзакция",
   "signup_for_card_accept_terms": "Регистрайте се за картата и приемете условията.",
   "silent_payments": "Мълчаливи плащания",
@@ -822,6 +829,7 @@
   "value_type": "Тип стойност",
   "variable_pair_not_supported": "Този variable pair не се поддържа от избраната борса",
   "verification": "Потвърждаване",
+  "verify_message": "Проверете съобщението",
   "verify_with_2fa": "Проверете с Cake 2FA",
   "version": "Версия ${currentVersion}",
   "view_all": "Виж всички",
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index 537695dd9..ef225041d 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -370,6 +370,7 @@
   "max_value": "Max: ${value} ${currency}",
   "memo": "Memo:",
   "message": "Zpráva",
+  "message_verified": "Zpráva byla úspěšně ověřena",
   "methods": "Metody",
   "min_amount": "Min: ${value}",
   "min_value": "Min: ${value} ${currency}",
@@ -661,7 +662,13 @@
   "show_keys": "Zobrazit seed/klíče",
   "show_market_place": "Zobrazit trh",
   "show_seed": "Zobrazit seed",
+  "sign_message": "Podepsat zprávu",
   "sign_up": "Registrovat se",
+  "sign_verify_message": "Podepište nebo ověřte zprávu",
+  "sign_verify_message_sub": "Podepište nebo ověřte zprávu pomocí soukromého klíče",
+  "sign_verify_title": "Podepsat / ověřit",
+  "signature": "Podpis",
+  "signature_invalid_error": "Podpis není platný pro danou zprávu",
   "signTransaction": "Podepsat transakci",
   "signup_for_card_accept_terms": "Zaregistrujte se pro kartu a souhlaste s podmínkami.",
   "silent_payments": "Tiché platby",
@@ -822,6 +829,7 @@
   "value_type": "Typ hodnoty",
   "variable_pair_not_supported": "Tento pár s tržním kurzem není ve zvolené směnárně podporován",
   "verification": "Ověření",
+  "verify_message": "Ověřit zprávu",
   "verify_with_2fa": "Ověřte pomocí Cake 2FA",
   "version": "Verze ${currentVersion}",
   "view_all": "Zobrazit vše",
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 052015367..393c3d928 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -370,6 +370,7 @@
   "max_value": "Max: ${value} ${currency}",
   "memo": "Memo:",
   "message": "Nachricht",
+  "message_verified": "Die Nachricht wurde erfolgreich überprüft",
   "methods": "Methoden",
   "min_amount": "Min: ${value}",
   "min_value": "Min: ${value} ${currency}",
@@ -662,7 +663,13 @@
   "show_keys": "Seed/Schlüssel anzeigen",
   "show_market_place": "Marktplatz anzeigen",
   "show_seed": "Seed zeigen",
+  "sign_message": "Nachricht unterschreiben",
   "sign_up": "Anmelden",
+  "sign_verify_message": "Nachricht unterschreiben oder überprüfen",
+  "sign_verify_message_sub": "Unterschreiben oder überprüfen Sie eine Nachricht mit Ihrem privaten Schlüssel",
+  "sign_verify_title": "Zeichen / überprüfen",
+  "signature": "Signatur",
+  "signature_invalid_error": "Die Signatur gilt nicht für die angegebene Nachricht",
   "signTransaction": "Transaktion unterzeichnen",
   "signup_for_card_accept_terms": "Melden Sie sich für die Karte an und akzeptieren Sie die Bedingungen.",
   "silent_payments": "Stille Zahlungen",
@@ -824,6 +831,7 @@
   "value_type": "Werttyp",
   "variable_pair_not_supported": "Dieses Variablenpaar wird von den ausgewählten Börsen nicht unterstützt",
   "verification": "Verifizierung",
+  "verify_message": "Nachricht überprüfen",
   "verify_with_2fa": "Verifizieren Sie mit Cake 2FA",
   "version": "Version ${currentVersion}",
   "view_all": "Alle anzeigen",
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 0f0ebd470..4ac7dd8fd 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -370,6 +370,7 @@
   "max_value": "Max: ${value} ${currency}",
   "memo": "Memo:",
   "message": "Message",
+  "message_verified": "The message was successfully verified",
   "methods": "Methods",
   "min_amount": "Min: ${value}",
   "min_value": "Min: ${value} ${currency}",
@@ -662,7 +663,13 @@
   "show_keys": "Show seed/keys",
   "show_market_place": "Show Marketplace",
   "show_seed": "Show seed",
+  "sign_message": "Sign Message",
   "sign_up": "Sign Up",
+  "sign_verify_message": "Sign or verify message",
+  "sign_verify_message_sub": "Sign or verify a message using your private key",
+  "sign_verify_title": "Sign / Verify",
+  "signature": "Signature",
+  "signature_invalid_error": "The signature is not valid for the message given",
   "signTransaction": "Sign Transaction",
   "signup_for_card_accept_terms": "Sign up for the card and accept the terms.",
   "silent_payments": "Silent Payments",
@@ -823,6 +830,7 @@
   "value_type": "Value Type",
   "variable_pair_not_supported": "This variable pair is not supported with the selected exchanges",
   "verification": "Verification",
+  "verify_message": "Verify Message",
   "verify_with_2fa": "Verify with Cake 2FA",
   "version": "Version ${currentVersion}",
   "view_all": "View all",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 1e6eeae59..02d17ac96 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -370,6 +370,7 @@
   "max_value": "Max: ${value} ${currency}",
   "memo": "Memorándum:",
   "message": "Mensaje",
+  "message_verified": "El mensaje fue verificado con éxito",
   "methods": "Métodos",
   "min_amount": "Mínimo: ${value}",
   "min_value": "Min: ${value} ${currency}",
@@ -662,7 +663,13 @@
   "show_keys": "Mostrar semilla/claves",
   "show_market_place": "Mostrar mercado",
   "show_seed": "Mostrar semilla",
+  "sign_message": "Mensaje de firma",
   "sign_up": "Registrarse",
+  "sign_verify_message": "Firmar o verificar el mensaje",
+  "sign_verify_message_sub": "Firmar o verificar un mensaje usando su clave privada",
+  "sign_verify_title": "Firmar / verificar",
+  "signature": "Firma",
+  "signature_invalid_error": "La firma no es válida para el mensaje dado",
   "signTransaction": "Firmar transacción",
   "signup_for_card_accept_terms": "Regístrese para obtener la tarjeta y acepte los términos.",
   "silent_payments": "Pagos silenciosos",
@@ -823,6 +830,7 @@
   "value_type": "Tipo de valor",
   "variable_pair_not_supported": "Este par de variables no es compatible con los intercambios seleccionados",
   "verification": "Verificación",
+  "verify_message": "Mensaje de verificación",
   "verify_with_2fa": "Verificar con Cake 2FA",
   "version": "Versión ${currentVersion}",
   "view_all": "Ver todo",
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index a64a69514..4bc5c9809 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -370,6 +370,7 @@
   "max_value": "Max: ${value} ${currency}",
   "memo": "Mémo :",
   "message": "Message",
+  "message_verified": "Le message a été vérifié avec succès",
   "methods": "Méthodes",
   "min_amount": "Min : ${value}",
   "min_value": "Min: ${value} ${currency}",
@@ -661,7 +662,13 @@
   "show_keys": "Visualiser la phrase secrète (seed) et les clefs",
   "show_market_place": "Afficher la place de marché",
   "show_seed": "Visualiser la phrase secrète (seed)",
+  "sign_message": "Signer le message",
   "sign_up": "S'inscrire",
+  "sign_verify_message": "Signer ou vérifier le message",
+  "sign_verify_message_sub": "Signez ou vérifiez un message en utilisant votre clé privée",
+  "sign_verify_title": "Signe / vérifier",
+  "signature": "Signature",
+  "signature_invalid_error": "La signature n'est pas valable pour le message donné",
   "signTransaction": "Signer une transaction",
   "signup_for_card_accept_terms": "Inscrivez-vous pour la carte et acceptez les conditions.",
   "silent_payments": "Paiements silencieux",
@@ -822,6 +829,7 @@
   "value_type": "Type de valeur",
   "variable_pair_not_supported": "Cette paire variable n'est pas prise en charge avec les échanges sélectionnés",
   "verification": "Vérification",
+  "verify_message": "Vérifier le message",
   "verify_with_2fa": "Vérifier avec Cake 2FA",
   "version": "Version ${currentVersion}",
   "view_all": "Voir tout",
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index 219b3c939..025a33f6b 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -370,6 +370,7 @@
   "max_value": "Max: ${value} ${currency}",
   "memo": "Memo:",
   "message": "Sako",
+  "message_verified": "An yi nasarar tabbatar da sakon",
   "methods": "Hanyoyin",
   "min_amount": "Min: ${value}",
   "min_value": "Min: ${value} ${currency}",
@@ -663,7 +664,13 @@
   "show_keys": "Nuna iri/maɓallai",
   "show_market_place": "Nuna dan kasuwa",
   "show_seed": "Nuna iri",
+  "sign_message": "Sa hannu",
   "sign_up": "Shiga",
+  "sign_verify_message": "Shiga ko Tabbatar da Saƙo",
+  "sign_verify_message_sub": "Shiga ko tabbatar da saƙo ta amfani da Maɓallinku na sirri",
+  "sign_verify_title": "Sa hannu / Tabbatar",
+  "signature": "Sa hannu",
+  "signature_invalid_error": "Sa hannu ba shi da inganci ga sakon da aka bayar",
   "signTransaction": "Sa hannu Ma'amala",
   "signup_for_card_accept_terms": "Yi rajista don katin kuma karɓi sharuɗɗan.",
   "silent_payments": "Biya silent",
@@ -824,6 +831,7 @@
   "value_type": "Nau'in darajar",
   "variable_pair_not_supported": "Ba a samun goyan bayan wannan m biyu tare da zaɓaɓɓun musayar",
   "verification": "tabbatar",
+  "verify_message": "Tabbatar saƙon",
   "verify_with_2fa": "Tabbatar da Cake 2FA",
   "version": "Sigar ${currentVersion}",
   "view_all": "Duba duka",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index b711939a4..346c420a9 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -370,6 +370,7 @@
   "max_value": "मैक्स: ${value} ${currency}",
   "memo": "ज्ञापन:",
   "message": "संदेश",
+  "message_verified": "संदेश को सफलतापूर्वक सत्यापित किया गया था",
   "methods": "तरीकों",
   "min_amount": "न्यूनतम: ${value}",
   "min_value": "मिन: ${value} ${currency}",
@@ -663,7 +664,13 @@
   "show_keys": "बीज / कुंजियाँ दिखाएँ",
   "show_market_place": "बाज़ार दिखाएँ",
   "show_seed": "बीज दिखाओ",
+  "sign_message": "हस्ताक्षर संदेश",
   "sign_up": "साइन अप करें",
+  "sign_verify_message": "संदेश पर हस्ताक्षर या सत्यापित करें",
+  "sign_verify_message_sub": "अपनी निजी कुंजी का उपयोग करके किसी संदेश पर हस्ताक्षर या सत्यापित करें",
+  "sign_verify_title": "हस्ताक्षर / सत्यापित करें",
+  "signature": "हस्ताक्षर",
+  "signature_invalid_error": "हस्ताक्षर दिए गए संदेश के लिए मान्य नहीं है",
   "signTransaction": "लेन-देन पर हस्ताक्षर करें",
   "signup_for_card_accept_terms": "कार्ड के लिए साइन अप करें और शर्तें स्वीकार करें।",
   "silent_payments": "मूक भुगतान",
@@ -824,6 +831,7 @@
   "value_type": "मान प्रकार",
   "variable_pair_not_supported": "यह परिवर्तनीय जोड़ी चयनित एक्सचेंजों के साथ समर्थित नहीं है",
   "verification": "सत्यापन",
+  "verify_message": "संदेश सत्यापित करें",
   "verify_with_2fa": "केक 2FA के साथ सत्यापित करें",
   "version": "संस्करण ${currentVersion}",
   "view_all": "सभी देखें",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 401514735..6f5bc88a6 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -370,6 +370,7 @@
   "max_value": "Maks.: ${value} ${currency}",
   "memo": "Memo:",
   "message": "Poruka",
+  "message_verified": "Poruka je uspješno provjerena",
   "methods": "Metode",
   "min_amount": "Minimalno: ${value}",
   "min_value": "Min.: ${value} ${currency}",
@@ -661,7 +662,13 @@
   "show_keys": "Prikaži pristupni izraz/ključ",
   "show_market_place": "Prikaži tržište",
   "show_seed": "Prikaži pristupni izraz",
+  "sign_message": "Poruka",
   "sign_up": "Prijavite se",
+  "sign_verify_message": "Potpisati ili provjeriti poruku",
+  "sign_verify_message_sub": "Potpišite ili provjerite poruku pomoću privatnog ključa",
+  "sign_verify_title": "Potpisati / provjeriti",
+  "signature": "Potpis",
+  "signature_invalid_error": "Potpis ne vrijedi za danu poruku",
   "signTransaction": "Potpišite transakciju",
   "signup_for_card_accept_terms": "Prijavite se za karticu i prihvatite uvjete.",
   "silent_payments": "Tiha plaćanja",
@@ -822,6 +829,7 @@
   "value_type": "Tipa vrijednosti",
   "variable_pair_not_supported": "Ovaj par varijabli nije podržan s odabranim burzama",
   "verification": "Potvrda",
+  "verify_message": "Provjerite poruku",
   "verify_with_2fa": "Provjerite s Cake 2FA",
   "version": "Verzija ${currentVersion}",
   "view_all": "Prikaži sve",
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index b6210b5dd..2bc298aa7 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -370,6 +370,7 @@
   "max_value": "Max: ${value} ${currency}",
   "memo": "Memo:",
   "message": "Pesan",
+  "message_verified": "Pesan itu berhasil diverifikasi",
   "methods": "Metode",
   "min_amount": "Min: ${value}",
   "min_value": "Min: ${value} ${currency}",
@@ -664,7 +665,13 @@
   "show_keys": "Tampilkan seed/kunci",
   "show_market_place": "Tampilkan Pasar",
   "show_seed": "Tampilkan seed",
+  "sign_message": "Pesan tanda",
   "sign_up": "Daftar",
+  "sign_verify_message": "Tanda tangan atau verifikasi pesan",
+  "sign_verify_message_sub": "Menandatangani atau memverifikasi pesan menggunakan kunci pribadi Anda",
+  "sign_verify_title": "Tanda / verifikasi",
+  "signature": "Tanda tangan",
+  "signature_invalid_error": "Tanda tangan tidak valid untuk pesan yang diberikan",
   "signTransaction": "Tandatangani Transaksi",
   "signup_for_card_accept_terms": "Daftar untuk kartu dan terima syarat dan ketentuan.",
   "silent_payments": "Pembayaran diam",
@@ -825,6 +832,7 @@
   "value_type": "Jenis Nilai",
   "variable_pair_not_supported": "Pasangan variabel ini tidak didukung dengan bursa yang dipilih",
   "verification": "Verifikasi",
+  "verify_message": "Verifikasi pesan",
   "verify_with_2fa": "Verifikasi dengan Cake 2FA",
   "version": "Versi ${currentVersion}",
   "view_all": "Lihat Semua",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index fc4abf7c4..0548b0ad2 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -371,6 +371,7 @@
   "max_value": "Max: ${value} ${currency}",
   "memo": "Memo:",
   "message": "Messaggio",
+  "message_verified": "Il messaggio è stato verificato con successo",
   "methods": "Metodi",
   "min_amount": "Min: ${value}",
   "min_value": "Min: ${value} ${currency}",
@@ -663,7 +664,13 @@
   "show_keys": "Mostra seme/chiavi",
   "show_market_place": "Mostra mercato",
   "show_seed": "Mostra seme",
+  "sign_message": "Messaggio di firma",
   "sign_up": "Registrati",
+  "sign_verify_message": "Firmare o verificare il messaggio",
+  "sign_verify_message_sub": "Firma o verifica un messaggio utilizzando la chiave privata",
+  "sign_verify_title": "Firmare / verificare",
+  "signature": "Firma",
+  "signature_invalid_error": "La firma non è valida per il messaggio dato",
   "signTransaction": "Firma la transazione",
   "signup_for_card_accept_terms": "Registrati per la carta e accetta i termini.",
   "silent_payments": "Pagamenti silenziosi",
@@ -824,6 +831,7 @@
   "value_type": "Tipo di valore",
   "variable_pair_not_supported": "Questa coppia di variabili non è supportata con gli scambi selezionati",
   "verification": "Verifica",
+  "verify_message": "Verificare il messaggio",
   "verify_with_2fa": "Verifica con Cake 2FA",
   "version": "Versione ${currentVersion}",
   "view_all": "Visualizza tutto",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index 98495fc8b..c53a6d001 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -371,6 +371,7 @@
   "max_value": "マックス: ${value} ${currency}",
   "memo": "メモ:",
   "message": "メッセージ",
+  "message_verified": "メッセージは正常に検証されました",
   "methods": "メソッド",
   "min_amount": "最小: ${value}",
   "min_value": "分: ${value} ${currency}",
@@ -662,7 +663,13 @@
   "show_keys": "シード/キーを表示する",
   "show_market_place": "マーケットプレイスを表示",
   "show_seed": "シードを表示",
+  "sign_message": "署名メッセージ",
   "sign_up": "サインアップ",
+  "sign_verify_message": "メッセージに署名または確認します",
+  "sign_verify_message_sub": "秘密鍵を使用してメッセージに署名または確認します",
+  "sign_verify_title": "署名 /検証",
+  "signature": "サイン",
+  "signature_invalid_error": "署名は、指定されたメッセージに対して無効です",
   "signTransaction": "トランザクションに署名する",
   "signup_for_card_accept_terms": "カードにサインアップして、利用規約に同意してください。",
   "silent_payments": "サイレント支払い",
@@ -823,6 +830,7 @@
   "value_type": "値タイプ",
   "variable_pair_not_supported": "この変数ペアは、選択した取引所ではサポートされていません",
   "verification": "検証",
+  "verify_message": "メッセージを確認します",
   "verify_with_2fa": "Cake 2FA で検証する",
   "version": "バージョン ${currentVersion}",
   "view_all": "すべて表示",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 60c52b21f..be6757d99 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -370,6 +370,7 @@
   "max_value": "맥스: ${value} ${currency}",
   "memo": "메모:",
   "message": "메시지",
+  "message_verified": "메시지가 성공적으로 확인되었습니다",
   "methods": "행동 양식",
   "min_amount": "최소: ${value}",
   "min_value": "최소: ${value} ${currency}",
@@ -662,7 +663,13 @@
   "show_keys": "시드 / 키 표시",
   "show_market_place": "마켓플레이스 표시",
   "show_seed": "종자 표시",
+  "sign_message": "서명 메시지",
   "sign_up": "가입",
+  "sign_verify_message": "메시지에 서명하거나 확인하십시오",
+  "sign_verify_message_sub": "개인 키를 사용하여 메시지에 서명하거나 확인하십시오",
+  "sign_verify_title": "서명 / 확인",
+  "signature": "서명",
+  "signature_invalid_error": "서명은 주어진 메시지에 유효하지 않습니다",
   "signTransaction": "거래 서명",
   "signup_for_card_accept_terms": "카드에 가입하고 약관에 동의합니다.",
   "silent_payments": "조용한 지불",
@@ -823,6 +830,7 @@
   "value_type": "가치 유형",
   "variable_pair_not_supported": "이 변수 쌍은 선택한 교환에서 지원되지 않습니다.",
   "verification": "검증",
+  "verify_message": "메시지를 확인하십시오",
   "verify_with_2fa": "케이크 2FA로 확인",
   "version": "버전 ${currentVersion}",
   "view_all": "모두 보기",
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index 42643be48..c53dffb6b 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -370,6 +370,7 @@
   "max_value": "အများဆုံး- ${value} ${currency}",
   "memo": "မှတ်စုတို:",
   "message": "မက်ဆေ့ချ်",
+  "message_verified": "မက်ဆေ့ခ်ျကိုအောင်မြင်စွာအတည်ပြုခဲ့သည်",
   "methods": "နည်းလမ်းများ",
   "min_amount": "အနည်းဆုံး- ${value}",
   "min_value": "အနည်းဆုံး- ${value} ${currency}",
@@ -661,7 +662,13 @@
   "show_keys": "မျိုးစေ့ /သော့များကို ပြပါ။",
   "show_market_place": "စျေးကွက်ကိုပြသပါ။",
   "show_seed": "မျိုးစေ့ကိုပြပါ။",
+  "sign_message": "လက်မှတ်စာ",
   "sign_up": "ဆိုင်းအပ်",
+  "sign_verify_message": "မက်ဆေ့ခ်ျကိုလက်မှတ်ထိုးသို့မဟုတ်အတည်ပြုရန်",
+  "sign_verify_message_sub": "သင်၏ကိုယ်ပိုင်သော့ကို သုံး. မက်ဆေ့ခ်ျကိုလက်မှတ်ထိုးပါ",
+  "sign_verify_title": "လက်မှတ်ထိုး / အတည်ပြုရန်",
+  "signature": "လက်မှတ်",
+  "signature_invalid_error": "အဆိုပါလက်မှတ်ပေးထားသောမက်ဆေ့ခ်ျကိုများအတွက်မမှန်ကန်ပါ",
   "signTransaction": "ငွေလွှဲဝင်ပါ။",
   "signup_for_card_accept_terms": "ကတ်အတွက် စာရင်းသွင်းပြီး စည်းကမ်းချက်များကို လက်ခံပါ။",
   "silent_payments": "အသံတိတ်ငွေပေးချေမှု",
@@ -822,6 +829,7 @@
   "value_type": "Value အမျိုးအစား",
   "variable_pair_not_supported": "ရွေးချယ်ထားသော ဖလှယ်မှုများဖြင့် ဤပြောင်းလဲနိုင်သောအတွဲကို ပံ့ပိုးမထားပါ။",
   "verification": "စိစစ်ခြင်း။",
+  "verify_message": "မက်ဆေ့ခ်ျကိုအတည်ပြုရန်",
   "verify_with_2fa": "Cake 2FA ဖြင့် စစ်ဆေးပါ။",
   "version": "ဗားရှင်း ${currentVersion}",
   "view_all": "အားလုံးကိုကြည့်ရှုပါ။",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index 0f6149182..2d55344f5 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -370,6 +370,7 @@
   "max_value": "Max: ${value} ${currency}",
   "memo": "Memo:",
   "message": "Bericht",
+  "message_verified": "Het bericht is succesvol geverifieerd",
   "methods": "Methoden",
   "min_amount": "Min: ${value}",
   "min_value": "Min: ${value} ${currency}",
@@ -661,7 +662,13 @@
   "show_keys": "Toon zaad/sleutels",
   "show_market_place": "Toon Marktplaats",
   "show_seed": "Toon zaad",
+  "sign_message": "Aanmeldingsbericht",
   "sign_up": "Aanmelden",
+  "sign_verify_message": "Teken of verifieer bericht",
+  "sign_verify_message_sub": "Teken of verifieer een bericht met uw privésleutel",
+  "sign_verify_title": "Ondertekenen / verifiëren",
+  "signature": "Handtekening",
+  "signature_invalid_error": "De handtekening is niet geldig voor het gegeven bericht",
   "signTransaction": "Transactie ondertekenen",
   "signup_for_card_accept_terms": "Meld je aan voor de kaart en accepteer de voorwaarden.",
   "silent_payments": "Stille betalingen",
@@ -822,6 +829,7 @@
   "value_type": "Waarde type",
   "variable_pair_not_supported": "Dit variabelenpaar wordt niet ondersteund met de geselecteerde uitwisselingen",
   "verification": "Verificatie",
+  "verify_message": "Verifieer bericht",
   "verify_with_2fa": "Controleer met Cake 2FA",
   "version": "Versie ${currentVersion}",
   "view_all": "Alles bekijken",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 48d6e38f6..833fc0308 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -370,6 +370,7 @@
   "max_value": "Max: ${value} ${currency}",
   "memo": "Notatka:",
   "message": "Wiadomość",
+  "message_verified": "Wiadomość została pomyślnie zweryfikowana",
   "methods": "Metody",
   "min_amount": "Min: ${value}",
   "min_value": "Min: ${value} ${currency}",
@@ -661,7 +662,13 @@
   "show_keys": "Pokaż seed/klucze",
   "show_market_place": "Pokaż rynek",
   "show_seed": "Pokaż frazy seed",
+  "sign_message": "Podpisuj wiadomość",
   "sign_up": "Zarejestruj się",
+  "sign_verify_message": "Podpisz lub zweryfikuj wiadomość",
+  "sign_verify_message_sub": "Podpisz lub zweryfikuj wiadomość za pomocą klucza prywatnego",
+  "sign_verify_title": "Podpisać / weryfikować",
+  "signature": "Podpis",
+  "signature_invalid_error": "Podpis nie jest ważny dla podanej wiadomości",
   "signTransaction": "Podpisz transakcję",
   "signup_for_card_accept_terms": "Zarejestruj się, aby otrzymać kartę i zaakceptuj warunki.",
   "silent_payments": "Ciche płatności",
@@ -822,6 +829,7 @@
   "value_type": "Typ wartości",
   "variable_pair_not_supported": "Ta para zmiennych nie jest obsługiwana na wybranych giełdach",
   "verification": "Weryfikacja",
+  "verify_message": "Sprawdź wiadomość",
   "verify_with_2fa": "Sprawdź za pomocą Cake 2FA",
   "version": "Wersja ${currentVersion}",
   "view_all": "Wyświetl wszystko",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 070f3f776..bd6d9b506 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -371,6 +371,7 @@
   "max_value": "Máx: ${value} ${currency}",
   "memo": "Memorando:",
   "message": "Mensagem",
+  "message_verified": "A mensagem foi verificada com sucesso",
   "methods": "Métodos",
   "min_amount": "Mínimo: ${valor}",
   "min_value": "Mín: ${value} ${currency}",
@@ -663,7 +664,13 @@
   "show_keys": "Mostrar semente/chaves",
   "show_market_place": "Mostrar mercado",
   "show_seed": "Mostrar semente",
+  "sign_message": "Mensagem de assinar",
   "sign_up": "Inscrever-se",
+  "sign_verify_message": "Assinar ou verificar mensagem",
+  "sign_verify_message_sub": "Assine ou verifique uma mensagem usando sua chave privada",
+  "sign_verify_title": "Assinar / verificar",
+  "signature": "Assinatura",
+  "signature_invalid_error": "A assinatura não é válida para a mensagem dada",
   "signTransaction": "Assinar transação",
   "signup_for_card_accept_terms": "Cadastre-se no cartão e aceite os termos.",
   "silent_payments": "Pagamentos silenciosos",
@@ -824,6 +831,7 @@
   "value_type": "Tipo de valor",
   "variable_pair_not_supported": "Este par de variáveis não é compatível com as trocas selecionadas",
   "verification": "Verificação",
+  "verify_message": "Verifique a mensagem",
   "verify_with_2fa": "Verificar com Cake 2FA",
   "version": "Versão ${currentVersion}",
   "view_all": "Ver todos",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index 695877c77..d43572351 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -370,6 +370,7 @@
   "max_value": "Макс: ${value} ${currency}",
   "memo": "Памятка:",
   "message": "Сообщение",
+  "message_verified": "Сообщение было успешно проверено",
   "methods": "Методы",
   "min_amount": "Минимум: ${value}",
   "min_value": "Мин: ${value} ${currency}",
@@ -662,7 +663,13 @@
   "show_keys": "Показать мнемоническую фразу/ключи",
   "show_market_place": "Показать торговую площадку",
   "show_seed": "Показать мнемоническую фразу",
+  "sign_message": "Сообщение о знаке",
   "sign_up": "Зарегистрироваться",
+  "sign_verify_message": "Подписать или проверить сообщение",
+  "sign_verify_message_sub": "Подписать или проверить сообщение, используя свой закрытый ключ",
+  "sign_verify_title": "Знак / проверка",
+  "signature": "Подпись",
+  "signature_invalid_error": "Подпись недопустима для данного сообщения",
   "signTransaction": "Подписать транзакцию",
   "signup_for_card_accept_terms": "Подпишитесь на карту и примите условия.",
   "silent_payments": "Молчаливые платежи",
@@ -823,6 +830,7 @@
   "value_type": "Тип значения",
   "variable_pair_not_supported": "Эта пара переменных не поддерживается выбранными биржами.",
   "verification": "Проверка",
+  "verify_message": "Проверьте сообщение",
   "verify_with_2fa": "Подтвердить с помощью Cake 2FA",
   "version": "Версия ${currentVersion}",
   "view_all": "Просмотреть все",
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index 5757eed0b..d948ba6d6 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -370,6 +370,7 @@
   "max_value": "ขั้นสูง: ${value} ${currency}",
   "memo": "หมายเหตุ:",
   "message": "ข้อความ",
+  "message_verified": "ข้อความได้รับการตรวจสอบอย่างประสบความสำเร็จ",
   "methods": "วิธีการ",
   "min_amount": "จำนวนขั้นต่ำ: ${value}",
   "min_value": "ขั้นต่ำ: ${value} ${currency}",
@@ -661,7 +662,13 @@
   "show_keys": "แสดงซีด/คีย์",
   "show_market_place": "แสดงตลาดกลาง",
   "show_seed": "แสดงซีด",
+  "sign_message": "ลงนามข้อความ",
   "sign_up": "สมัครสมาชิก",
+  "sign_verify_message": "ลงชื่อเข้าใช้หรือตรวจสอบข้อความ",
+  "sign_verify_message_sub": "ลงชื่อเข้าใช้หรือตรวจสอบข้อความโดยใช้คีย์ส่วนตัวของคุณ",
+  "sign_verify_title": "ลงชื่อ / ตรวจสอบ",
+  "signature": "ลายเซ็น",
+  "signature_invalid_error": "ลายเซ็นไม่ถูกต้องสำหรับข้อความที่ให้ไว้",
   "signTransaction": "ลงนามในการทำธุรกรรม",
   "signup_for_card_accept_terms": "ลงทะเบียนสำหรับบัตรและยอมรับเงื่อนไข",
   "silent_payments": "การชำระเงินเงียบ",
@@ -822,6 +829,7 @@
   "value_type": "ประเภทค่า",
   "variable_pair_not_supported": "คู่ความสัมพันธ์ที่เปลี่ยนแปลงได้นี้ไม่สนับสนุนกับหุ้นที่เลือก",
   "verification": "การตรวจสอบ",
+  "verify_message": "ยืนยันข้อความ",
   "verify_with_2fa": "ตรวจสอบกับ Cake 2FA",
   "version": "เวอร์ชัน ${currentVersion}",
   "view_all": "ดูทั้งหมด",
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index 7fc83afd8..a0ab030c8 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -370,6 +370,7 @@
   "max_value": "Max: ${value} ${currency}",
   "memo": "Memo:",
   "message": "Mensahe",
+  "message_verified": "Ang mensahe ay matagumpay na na -verify",
   "methods": "Mga Paraan",
   "min_amount": "Min: ${value}",
   "min_value": "Min: ${value} ${currency}",
@@ -660,6 +661,12 @@
   "show_details": "Ipakita ang mga detalye",
   "show_keys": "Ipakita ang mga seed/key",
   "show_market_place": "Ipakita ang Marketplace",
+  "sign_message": "Mag -sign Message",
+  "sign_verify_message": "Mag -sign o i -verify ang mensahe",
+  "sign_verify_message_sub": "Mag -sign o i -verify ang isang mensahe gamit ang iyong pribadong key",
+  "sign_verify_title": "Mag -sign / Mag -verify",
+  "signature": "Lagda",
+  "signature_invalid_error": "Ang lagda ay hindi wasto para sa ibinigay na mensahe",
   "show_seed": "Ipakita ang seed",
   "sign_up": "Mag-sign Up",
   "signTransaction": "Mag-sign ang Transaksyon",
@@ -820,6 +827,7 @@
   "use_testnet": "Gumamit ng testnet",
   "value": "Halaga",
   "value_type": "Uri ng halaga",
+  "verify_message": "I -verify ang mensahe",
   "variable_pair_not_supported": "Ang variable na pares na ito ay hindi suportado sa mga napiling exchange",
   "verification": "Pag-verify",
   "verify_with_2fa": "Mag-verify sa Cake 2FA",
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index 4d1aa43e4..e7cdc5b12 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -370,6 +370,7 @@
   "max_value": "En fazla: ${value} ${currency}",
   "memo": "Memo:",
   "message": "İleti",
+  "message_verified": "Mesaj başarıyla doğrulandı",
   "methods": "Yöntemler",
   "min_amount": "Min: ${value}",
   "min_value": "En az: ${value} ${currency}",
@@ -661,7 +662,13 @@
   "show_keys": "Tohumları/anahtarları göster",
   "show_market_place": "Pazar Yerini Göster",
   "show_seed": "Tohumları göster",
+  "sign_message": "İşaret mesajı",
   "sign_up": "Kaydol",
+  "sign_verify_message": "Mesajı işaretleyin veya doğrulayın",
+  "sign_verify_message_sub": "Özel anahtarınızı kullanarak bir mesajı imzalayın veya doğrulayın",
+  "sign_verify_title": "İşaretle / Doğrula",
+  "signature": "İmza",
+  "signature_invalid_error": "İmza verilen mesaj için geçerli değil",
   "signTransaction": "İşlem İmzala",
   "signup_for_card_accept_terms": "Kart için kaydol ve koşulları kabul et.",
   "silent_payments": "Sessiz ödemeler",
@@ -822,6 +829,7 @@
   "value_type": "Değer türü",
   "variable_pair_not_supported": "Bu değişken paritesi seçilen borsalarda desteklenmemekte",
   "verification": "Doğrulama",
+  "verify_message": "Mesajı Doğrula",
   "verify_with_2fa": "Cake 2FA ile Doğrulayın",
   "version": "Sürüm ${currentVersion}",
   "view_all": "Hepsini göster",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 22edec0d5..91b5b5266 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -370,6 +370,7 @@
   "max_value": "Макс: ${value} ${currency}",
   "memo": "Пам’ятка:",
   "message": "повідомлення",
+  "message_verified": "Повідомлення було успішно перевірено",
   "methods": "методи",
   "min_amount": "Мінімум: ${value}",
   "min_value": "Мін: ${value} ${currency}",
@@ -662,7 +663,13 @@
   "show_keys": "Показати мнемонічну фразу/ключі",
   "show_market_place": "Відображати маркетплейс",
   "show_seed": "Показати мнемонічну фразу",
+  "sign_message": "Підпишіть повідомлення",
   "sign_up": "Зареєструватися",
+  "sign_verify_message": "Підпишіть або перевірити повідомлення",
+  "sign_verify_message_sub": "Підпишіть або перевірте повідомлення за допомогою вашого приватного ключа",
+  "sign_verify_title": "Знак / Перевірка",
+  "signature": "Підпис",
+  "signature_invalid_error": "Підпис не є дійсним для наведеного повідомлення",
   "signTransaction": "Підписати транзакцію",
   "signup_for_card_accept_terms": "Зареєструйтеся на картку та прийміть умови.",
   "silent_payments": "Мовчазні платежі",
@@ -823,6 +830,7 @@
   "value_type": "Тип значення",
   "variable_pair_not_supported": "Ця пара змінних не підтримується вибраними біржами",
   "verification": "Перевірка",
+  "verify_message": "Перевірте повідомлення",
   "verify_with_2fa": "Перевірте за допомогою Cake 2FA",
   "version": "Версія ${currentVersion}",
   "view_all": "Переглянути все",
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index 590f344d8..e54a0db34 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -370,6 +370,7 @@
   "max_value": "زیادہ سے زیادہ: ${value} ${currency}",
   "memo": "میمو:",
   "message": "ﻡﺎﻐﯿﭘ",
+  "message_verified": "پیغام کی کامیابی کے ساتھ تصدیق کی گئی",
   "methods": "ﮯﻘﯾﺮﻃ",
   "min_amount": "کم سے کم: ${value}",
   "min_value": "کم سے کم: ${value} ${currency}",
@@ -663,7 +664,13 @@
   "show_keys": "بیج / چابیاں دکھائیں۔",
   "show_market_place": "بازار دکھائیں۔",
   "show_seed": "بیج دکھائیں۔",
+  "sign_message": "سائن پیغام",
   "sign_up": "سائن اپ",
+  "sign_verify_message": "پیغام پر دستخط کریں یا تصدیق کریں",
+  "sign_verify_message_sub": "اپنی نجی کلید کا استعمال کرتے ہوئے کسی پیغام پر دستخط کریں یا اس کی تصدیق کریں",
+  "sign_verify_title": "سائن / تصدیق کریں",
+  "signature": "دستخط",
+  "signature_invalid_error": "دستخط دیئے گئے پیغام کے لئے درست نہیں ہے",
   "signTransaction": "۔ﮟﯾﺮﮐ ﻂﺨﺘﺳﺩ ﺮﭘ ﻦﯾﺩ ﻦﯿﻟ",
   "signup_for_card_accept_terms": "کارڈ کے لیے سائن اپ کریں اور شرائط کو قبول کریں۔",
   "silent_payments": "خاموش ادائیگی",
@@ -824,6 +831,7 @@
   "value_type": "قدر کی قسم",
   "variable_pair_not_supported": "یہ متغیر جوڑا منتخب ایکسچینجز کے ساتھ تعاون یافتہ نہیں ہے۔",
   "verification": "تصدیق",
+  "verify_message": "پیغام کی تصدیق کریں",
   "verify_with_2fa": "کیک 2FA سے تصدیق کریں۔",
   "version": "ورژن ${currentVersion}",
   "view_all": "سب دیکھیں",
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index e5cf3d3f9..8f47d8543 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -371,6 +371,7 @@
   "max_value": "kò gbọ́dọ̀ tóbi ju ${value} ${currency}",
   "memo": "Àkọsílẹ̀:",
   "message": "Ifiranṣẹ",
+  "message_verified": "Ifiranṣẹ naa ni aṣeyọri ni ifijišẹ",
   "methods": "Awọn ọna",
   "min_amount": "kò kéré ju: ${value}",
   "min_value": "kò gbọ́dọ̀ kéré ju ${value} ${currency}",
@@ -662,7 +663,13 @@
   "show_keys": "Wo hóró / àwọn kọ́kọ́rọ́",
   "show_market_place": "Wa Sopọ Pataki",
   "show_seed": "Wo hóró",
+  "sign_message": "Ifiranṣẹ Ami",
   "sign_up": "Forúkọ sílẹ̀",
+  "sign_verify_message": "Ami tabi ṣayẹwo ifiranṣẹ",
+  "sign_verify_message_sub": "Wọle tabi ṣayẹwo ifiranṣẹ kan nipa lilo bọtini ikọkọ rẹ",
+  "sign_verify_title": "Ami / Daju",
+  "signature": "Ibọwọlu",
+  "signature_invalid_error": "Ibuwọlu ko wulo fun ifiranṣẹ ti a fun",
   "signTransaction": "Wole Idunadura",
   "signup_for_card_accept_terms": "Ẹ f'orúkọ sílẹ̀ láti gba káàdì àti àjọrò.",
   "silent_payments": "Awọn sisanwo ipalọlọ",
@@ -823,6 +830,7 @@
   "value_type": "Iru iye",
   "variable_pair_not_supported": "A kì í ṣe k'á fi àwọn ilé pàṣípààrọ̀ yìí ṣe pàṣípààrọ̀ irú owó méji yìí",
   "verification": "Ìjẹ́rìísí",
+  "verify_message": "Daju ifiranṣẹ",
   "verify_with_2fa": "Ṣeẹda pẹlu Cake 2FA",
   "version": "Àtúnse ${currentVersion}",
   "view_all": "Wo gbogbo nǹkan kan",
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index 25024d0ed..c864a529b 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -370,6 +370,7 @@
   "max_value": "最大: ${value} ${currency}",
   "memo": "备忘录:",
   "message": "信息",
+  "message_verified": "该消息已成功验证",
   "methods": "方法",
   "min_amount": "最小值: ${value}",
   "min_value": "最小: ${value} ${currency}",
@@ -661,7 +662,13 @@
   "show_keys": "显示种子/密钥",
   "show_market_place": "显示市场",
   "show_seed": "显示种子",
+  "sign_message": "标志消息",
   "sign_up": "注册",
+  "sign_verify_message": "签名或验证消息",
+  "sign_verify_message_sub": "使用您的私钥签名或验证消息",
+  "sign_verify_title": "签名 /验证",
+  "signature": "签名",
+  "signature_invalid_error": "签名对于给出的消息无效",
   "signTransaction": "签署交易",
   "signup_for_card_accept_terms": "注册卡并接受条款。",
   "silent_payments": "无声付款",
@@ -822,6 +829,7 @@
   "value_type": "值类型",
   "variable_pair_not_supported": "所选交易所不支持此变量对",
   "verification": "验证",
+  "verify_message": "验证消息",
   "verify_with_2fa": "用 Cake 2FA 验证",
   "version": "版本 ${currentVersion}",
   "view_all": "查看全部",

From 7c9b72483a66e113db6fee8c23d3b8616c76c41f Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Sat, 17 Aug 2024 19:28:45 -0400
Subject: [PATCH 51/81] Socket null handling (#1610)

* return null if in connection failure state

* reconnect on connection failure

* better connection handling

* probably not necessary but just incase

* connection handling updates

* add cancelOnError: true
---
 cw_bitcoin/lib/electrum.dart        | 54 +++++++++++++++++------------
 cw_bitcoin/lib/electrum_wallet.dart | 22 +++++-------
 2 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart
index 69b07d7c1..28043d0c0 100644
--- a/cw_bitcoin/lib/electrum.dart
+++ b/cw_bitcoin/lib/electrum.dart
@@ -66,6 +66,7 @@ class ElectrumClient {
 
     try {
       await socket?.close();
+      socket = null;
     } catch (_) {}
 
     try {
@@ -90,33 +91,40 @@ class ElectrumClient {
     }
     _setConnectionStatus(ConnectionStatus.connected);
 
-    socket!.listen((Uint8List event) {
-      try {
-        final msg = utf8.decode(event.toList());
-        final messagesList = msg.split("\n");
-        for (var message in messagesList) {
-          if (message.isEmpty) {
-            continue;
+    socket!.listen(
+      (Uint8List event) {
+        try {
+          final msg = utf8.decode(event.toList());
+          final messagesList = msg.split("\n");
+          for (var message in messagesList) {
+            if (message.isEmpty) {
+              continue;
+            }
+            _parseResponse(message);
           }
-          _parseResponse(message);
+        } catch (e) {
+          print(e.toString());
         }
-      } catch (e) {
-        print(e.toString());
-      }
-    }, onError: (Object error) {
-      final errorMsg = error.toString();
-      print(errorMsg);
-      unterminatedString = '';
+      },
+      onError: (Object error) {
+        socket = null;
+        final errorMsg = error.toString();
+        print(errorMsg);
+        unterminatedString = '';
 
-      final currentHost = socket?.address.host;
-      final isErrorForCurrentHost = errorMsg.contains(" ${currentHost} ");
+        final currentHost = socket?.address.host;
+        final isErrorForCurrentHost = errorMsg.contains(" ${currentHost} ");
 
-      if (currentHost != null && isErrorForCurrentHost)
-        _setConnectionStatus(ConnectionStatus.failed);
-    }, onDone: () {
-      unterminatedString = '';
-      if (host == socket?.address.host) _setConnectionStatus(ConnectionStatus.disconnected);
-    });
+        if (currentHost != null && isErrorForCurrentHost)
+          _setConnectionStatus(ConnectionStatus.failed);
+      },
+      onDone: () {
+        socket = null;
+        unterminatedString = '';
+        if (host == socket?.address.host) _setConnectionStatus(ConnectionStatus.disconnected);
+      },
+      cancelOnError: true,
+    );
 
     keepAlive();
   }
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 8f2360f26..b8d9adb14 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -218,10 +218,7 @@ abstract class ElectrumWalletBase
       if (electrumClient.isConnected) {
         syncStatus = SyncedSyncStatus();
       } else {
-        if (electrumClient.uri != null) {
-          await electrumClient.connectToUri(electrumClient.uri!, useSSL: electrumClient.useSSL);
-          startSync();
-        }
+        syncStatus = NotConnectedSyncStatus();
       }
     }
   }
@@ -265,6 +262,7 @@ abstract class ElectrumWalletBase
   Future<Isolate>? _isolate;
 
   void Function(FlutterErrorDetails)? _onError;
+  Timer? _reconnectTimer;
   Timer? _autoSaveTimer;
   static const int _autoSaveInterval = 30;
 
@@ -1980,13 +1978,6 @@ abstract class ElectrumWalletBase
         break;
       case ConnectionStatus.failed:
         syncStatus = LostConnectionSyncStatus();
-        // wait for 5 seconds and then try to reconnect:
-        Future.delayed(Duration(seconds: 5), () {
-          electrumClient.connectToUri(
-            node!.uri,
-            useSSL: node!.useSSL ?? false,
-          );
-        });
         break;
       case ConnectionStatus.connecting:
         syncStatus = ConnectingSyncStatus();
@@ -1996,7 +1987,11 @@ abstract class ElectrumWalletBase
   }
 
   void _syncStatusReaction(SyncStatus syncStatus) async {
-    if (syncStatus is NotConnectedSyncStatus) {
+    if (syncStatus is SyncingSyncStatus) {
+      return;
+    }
+
+    if (syncStatus is NotConnectedSyncStatus || syncStatus is LostConnectionSyncStatus) {
       // Needs to re-subscribe to all scripthashes when reconnected
       _scripthashesUpdateSubject = {};
 
@@ -2004,7 +1999,8 @@ abstract class ElectrumWalletBase
 
       _isTryingToConnect = true;
 
-      Future.delayed(Duration(seconds: 10), () {
+      _reconnectTimer?.cancel();
+      _reconnectTimer = Timer(Duration(seconds: 10), () {
         if (this.syncStatus is! SyncedSyncStatus && this.syncStatus is! SyncedTipSyncStatus) {
           this.electrumClient.connectToUri(
                 node!.uri,

From c59d39d42d4a8a27208ea3bad5144781801823a5 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Sun, 18 Aug 2024 03:37:15 +0300
Subject: [PATCH 52/81] Generic fixes (#1619)

* update fee rates

* periodically update fees

* minor enhancements

* minor enhancements

* some improvements
add solana node

* handle empty hex as null

* minor improvement

* fix imports

* fix app hanging on splash screen

* update app versions
temporarily disable sign/verify for hardware wallets
---
 assets/solana_node_list.yml                   |  3 +++
 assets/text/Monerocom_Release_Notes.txt       |  5 ++---
 assets/text/Release_Notes.txt                 |  7 ++-----
 cw_bitcoin/lib/electrum_wallet.dart           | 12 +++++++++---
 cw_evm/lib/evm_chain_wallet.dart              |  5 ++++-
 cw_monero/lib/monero_wallet_service.dart      |  6 +++---
 cw_monero/pubspec.lock                        | 15 +++++++--------
 cw_monero/pubspec.yaml                        |  5 +----
 cw_wownero/pubspec.lock                       | 19 +++++++++----------
 cw_wownero/pubspec.yaml                       |  5 +----
 lib/core/wallet_loading_service.dart          |  8 ++++++--
 lib/reactions/bootstrap.dart                  |  2 +-
 .../on_authentication_state_change.dart       | 17 ++++-------------
 .../screens/dashboard/pages/balance_page.dart |  4 ++--
 .../dashboard/dashboard_view_model.dart       |  4 +++-
 .../exchange/exchange_view_model.dart         |  9 +++++++++
 macos/Podfile.lock                            | 18 ++++++------------
 pubspec_base.yaml                             |  7 ++-----
 scripts/android/app_env.sh                    |  8 ++++----
 scripts/ios/app_env.sh                        |  8 ++++----
 scripts/linux/app_env.sh                      |  4 ++--
 scripts/macos/app_env.sh                      |  8 ++++----
 scripts/windows/build_exe_installer.iss       |  2 +-
 23 files changed, 89 insertions(+), 92 deletions(-)

diff --git a/assets/solana_node_list.yml b/assets/solana_node_list.yml
index 4a2e12161..e3ff9138e 100644
--- a/assets/solana_node_list.yml
+++ b/assets/solana_node_list.yml
@@ -1,4 +1,7 @@
 -
   uri: rpc.ankr.com
   is_default: true
+  useSSL: true
+-
+  uri: api.mainnet-beta.solana.com:443
   useSSL: true
\ No newline at end of file
diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt
index c90d54524..11a3ad803 100644
--- a/assets/text/Monerocom_Release_Notes.txt
+++ b/assets/text/Monerocom_Release_Notes.txt
@@ -1,4 +1,3 @@
-Monero synchronization improvements
-Enhance error handling
-UI enhancements
+Scan and verify messages
+Synchronization enhancements
 Bug fixes
\ No newline at end of file
diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt
index 34bca2e5e..11a3ad803 100644
--- a/assets/text/Release_Notes.txt
+++ b/assets/text/Release_Notes.txt
@@ -1,6 +1,3 @@
-Wallets enhancements
-Monero synchronization improvements
-Improve wallet backups
-Enhance error handling
-UI enhancements
+Scan and verify messages
+Synchronization enhancements
 Bug fixes
\ No newline at end of file
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index b8d9adb14..2d0b989d7 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -264,7 +264,8 @@ abstract class ElectrumWalletBase
   void Function(FlutterErrorDetails)? _onError;
   Timer? _reconnectTimer;
   Timer? _autoSaveTimer;
-  static const int _autoSaveInterval = 30;
+  Timer? _updateFeeRateTimer;
+  static const int _autoSaveInterval = 1;
 
   Future<void> init() async {
     await walletAddresses.init();
@@ -272,7 +273,7 @@ abstract class ElectrumWalletBase
     await save();
 
     _autoSaveTimer =
-        Timer.periodic(Duration(seconds: _autoSaveInterval), (_) async => await save());
+        Timer.periodic(Duration(minutes: _autoSaveInterval), (_) async => await save());
   }
 
   @action
@@ -425,6 +426,10 @@ abstract class ElectrumWalletBase
       await updateTransactions();
       await updateAllUnspents();
       await updateBalance();
+      updateFeeRates();
+
+      _updateFeeRateTimer ??=
+          Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
 
       if (alwaysScan == true) {
         _setListeners(walletInfo.restoreHeight);
@@ -1213,6 +1218,7 @@ abstract class ElectrumWalletBase
       await electrumClient.close();
     } catch (_) {}
     _autoSaveTimer?.cancel();
+    _updateFeeRateTimer?.cancel();
   }
 
   @action
@@ -1371,7 +1377,7 @@ abstract class ElectrumWalletBase
 
     if (confirmations > 0) return false;
 
-    if (transactionHex == null) {
+    if (transactionHex == null || transactionHex.isEmpty) {
       return false;
     }
 
diff --git a/cw_evm/lib/evm_chain_wallet.dart b/cw_evm/lib/evm_chain_wallet.dart
index bbf972f0d..0ade2215e 100644
--- a/cw_evm/lib/evm_chain_wallet.dart
+++ b/cw_evm/lib/evm_chain_wallet.dart
@@ -113,6 +113,8 @@ abstract class EVMChainWalletBase
   int? gasBaseFee = 0;
   int estimatedGasUnits = 0;
 
+  Timer? _updateFeesTimer;
+
   bool _isTransactionUpdating;
 
   // TODO: remove after integrating our own node and having eth_newPendingTransactionFilter
@@ -263,6 +265,7 @@ abstract class EVMChainWalletBase
   void close() {
     _client.stop();
     _transactionsUpdateTimer?.cancel();
+    _updateFeesTimer?.cancel();
   }
 
   @action
@@ -297,7 +300,7 @@ abstract class EVMChainWalletBase
 
       await _updateEstimatedGasFeeParams();
 
-      Timer.periodic(const Duration(seconds: 10), (timer) async {
+      _updateFeesTimer ??= Timer.periodic(const Duration(seconds: 30), (timer) async {
         await _updateEstimatedGasFeeParams();
       });
 
diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart
index d771d1815..f9973f430 100644
--- a/cw_monero/lib/monero_wallet_service.dart
+++ b/cw_monero/lib/monero_wallet_service.dart
@@ -119,7 +119,7 @@ class MoneroWalletService extends WalletService<
   }
 
   @override
-  Future<MoneroWallet> openWallet(String name, String password) async {
+  Future<MoneroWallet> openWallet(String name, String password, {bool? retryOnFailure}) async {
     MoneroWallet? wallet;
     try {
       final path = await pathForWallet(name: name, type: getType());
@@ -181,12 +181,12 @@ class MoneroWalletService extends WalletService<
           wallet.onError != null) {
         wallet.onError!(FlutterErrorDetails(exception: e, stack: s));
       }
-      if (invalidPassword) {
+      if (invalidPassword || retryOnFailure == false) {
         rethrow;
       }
 
       await restoreOrResetWalletFiles(name);
-      return openWallet(name, password);
+      return openWallet(name, password, retryOnFailure: false);
     }
   }
 
diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock
index 51efd4076..13c70cfad 100644
--- a/cw_monero/pubspec.lock
+++ b/cw_monero/pubspec.lock
@@ -295,10 +295,10 @@ packages:
     dependency: transitive
     description:
       name: hashlib
-      sha256: "5037d3b8c36384c03a728543ae67d962a56970c5432a50862279fe68ee4c8411"
+      sha256: d41795742c10947930630118c6836608deeb9047cd05aee32d2baeb697afd66a
       url: "https://pub.dev"
     source: hosted
-    version: "1.19.1"
+    version: "1.19.2"
   hashlib_codecs:
     dependency: transitive
     description:
@@ -575,12 +575,11 @@ packages:
   polyseed:
     dependency: "direct main"
     description:
-      path: "."
-      ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
-      resolved-ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
-      url: "https://github.com/mrcyjanek/polyseed_dart"
-    source: git
-    version: "0.0.5"
+      name: polyseed
+      sha256: "11d4dbee409db053c5e9cd77382b2f5115f43fc2529158a826a96f3ba505d770"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.0.6"
   pool:
     dependency: transitive
     description:
diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml
index 7f5da2621..3053977de 100644
--- a/cw_monero/pubspec.yaml
+++ b/cw_monero/pubspec.yaml
@@ -19,10 +19,7 @@ dependencies:
   flutter_mobx: ^2.0.6+1
   intl: ^0.18.0
   encrypt: ^5.0.1
-  polyseed:
-    git:
-      url: https://github.com/mrcyjanek/polyseed_dart
-      ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
+  polyseed: ^0.0.6
   cw_core:
     path: ../cw_core
   monero:
diff --git a/cw_wownero/pubspec.lock b/cw_wownero/pubspec.lock
index f164b3086..58831085f 100644
--- a/cw_wownero/pubspec.lock
+++ b/cw_wownero/pubspec.lock
@@ -295,18 +295,18 @@ packages:
     dependency: transitive
     description:
       name: hashlib
-      sha256: "71bf102329ddb8e50c8a995ee4645ae7f1728bb65e575c17196b4d8262121a96"
+      sha256: d41795742c10947930630118c6836608deeb9047cd05aee32d2baeb697afd66a
       url: "https://pub.dev"
     source: hosted
-    version: "1.12.0"
+    version: "1.19.2"
   hashlib_codecs:
     dependency: transitive
     description:
       name: hashlib_codecs
-      sha256: "49e2a471f74b15f1854263e58c2ac11f2b631b5b12c836f9708a35397d36d626"
+      sha256: "2b570061f5a4b378425be28a576c1e11783450355ad4345a19f606ff3d96db0f"
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.0"
+    version: "2.5.0"
   hive:
     dependency: transitive
     description:
@@ -567,12 +567,11 @@ packages:
   polyseed:
     dependency: "direct main"
     description:
-      path: "."
-      ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
-      resolved-ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
-      url: "https://github.com/mrcyjanek/polyseed_dart"
-    source: git
-    version: "0.0.5"
+      name: polyseed
+      sha256: "11d4dbee409db053c5e9cd77382b2f5115f43fc2529158a826a96f3ba505d770"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.0.6"
   pool:
     dependency: transitive
     description:
diff --git a/cw_wownero/pubspec.yaml b/cw_wownero/pubspec.yaml
index eb14286a9..b9306711d 100644
--- a/cw_wownero/pubspec.yaml
+++ b/cw_wownero/pubspec.yaml
@@ -19,10 +19,7 @@ dependencies:
   flutter_mobx: ^2.0.6+1
   intl: ^0.18.0
   encrypt: ^5.0.1
-  polyseed:
-    git:
-      url: https://github.com/mrcyjanek/polyseed_dart
-      ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
+  polyseed: ^0.0.6
   cw_core:
     path: ../cw_core
   monero:
diff --git a/lib/core/wallet_loading_service.dart b/lib/core/wallet_loading_service.dart
index 2b570f14c..0087b1332 100644
--- a/lib/core/wallet_loading_service.dart
+++ b/lib/core/wallet_loading_service.dart
@@ -60,7 +60,9 @@ class WalletLoadingService {
       String corruptedWalletsSeeds = "Corrupted wallets seeds (if retrievable, empty otherwise):";
       try {
         corruptedWalletsSeeds += await _getCorruptedWalletSeeds(name, type);
-      } catch (_) {}
+      } catch (e) {
+        corruptedWalletsSeeds += "\nFailed to  fetch $name seeds: $e";
+      }
 
       // try opening another wallet that is not corrupted to give user access to the app
       final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
@@ -90,7 +92,9 @@ class WalletLoadingService {
             if (!corruptedWalletsSeeds.contains(seeds)) {
               corruptedWalletsSeeds += seeds;
             }
-          } catch (_) {}
+          } catch (e) {
+            corruptedWalletsSeeds += "\nFailed to  fetch $name seeds: $e";
+          }
         }
       }
 
diff --git a/lib/reactions/bootstrap.dart b/lib/reactions/bootstrap.dart
index 5b1a0ace7..bf045c0dd 100644
--- a/lib/reactions/bootstrap.dart
+++ b/lib/reactions/bootstrap.dart
@@ -27,7 +27,7 @@ Future<void> bootstrap(GlobalKey<NavigatorState> navigatorKey) async {
     authenticationStore.installed();
   }
 
-  await startAuthenticationStateChange(authenticationStore, navigatorKey);
+  startAuthenticationStateChange(authenticationStore, navigatorKey);
   startCurrentWalletChangeReaction(appStore, settingsStore, fiatConversionStore);
   startCurrentFiatChangeReaction(appStore, settingsStore, fiatConversionStore);
   startCurrentFiatApiModeChangeReaction(appStore, settingsStore, fiatConversionStore);
diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart
index 014306b98..1aa0a12c6 100644
--- a/lib/reactions/on_authentication_state_change.dart
+++ b/lib/reactions/on_authentication_state_change.dart
@@ -7,26 +7,17 @@ import 'package:flutter/widgets.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cake_wallet/entities/load_current_wallet.dart';
 import 'package:cake_wallet/store/authentication_store.dart';
+import 'package:rxdart/subjects.dart';
 
 ReactionDisposer? _onAuthenticationStateChange;
 
 dynamic loginError;
-StreamController<dynamic> authenticatedErrorStreamController = StreamController<dynamic>();
+StreamController<dynamic> authenticatedErrorStreamController = BehaviorSubject<dynamic>();
 
-Future<void> reInitializeStreamController() async {
-  if (!authenticatedErrorStreamController.isClosed) {
-    await authenticatedErrorStreamController.close();
-  }
-
-  authenticatedErrorStreamController = StreamController<dynamic>();
-}
-
-Future<void> startAuthenticationStateChange(
+void startAuthenticationStateChange(
   AuthenticationStore authenticationStore,
   GlobalKey<NavigatorState> navigatorKey,
-) async {
-  await reInitializeStreamController();
-
+) {
   authenticatedErrorStreamController.stream.listen((event) {
     if (authenticationStore.state == AuthenticationState.allowed) {
       ExceptionHandler.showError(event.toString(), delayInSeconds: 3);
diff --git a/lib/src/screens/dashboard/pages/balance_page.dart b/lib/src/screens/dashboard/pages/balance_page.dart
index 770cda6f9..57f908986 100644
--- a/lib/src/screens/dashboard/pages/balance_page.dart
+++ b/lib/src/screens/dashboard/pages/balance_page.dart
@@ -287,8 +287,8 @@ class CryptoBalanceWidget extends StatelessWidget {
                       padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
                       child: DashBoardRoundedCardWidget(
                         customBorder: 30,
-                        title: "Monero wallet is broken",
-                        subTitle: "Here are the things that are broken:\n - "
+                        title: "This wallet has encountered an issue",
+                        subTitle: "Here are the things that you should note:\n - "
                         +dashboardViewModel.isMoneroWalletBrokenReasons.join("\n - ")
                         +"\n\nPlease restart your wallet and if it doesn't help contact our support.",
                         onTap: () {},
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index 56a0e061b..d58d7535c 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -32,7 +32,6 @@ import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
 import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
 import 'package:cake_wallet/view_model/settings/sync_mode.dart';
 import 'package:cake_wallet/wallet_type_utils.dart';
-import 'package:cake_wallet/wownero/wownero.dart' as wow;
 import 'package:cryptography/cryptography.dart';
 import 'package:cw_core/balance.dart';
 import 'package:cw_core/cake_hive.dart';
@@ -485,6 +484,9 @@ abstract class DashboardViewModelBase with Store {
 
   @computed
   bool get hasSignMessages {
+    if (wallet.isHardwareWallet) {
+      return false;
+    }
     switch (wallet.type) {
       case WalletType.monero:
       case WalletType.litecoin:
diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart
index 3e45e8ba1..f2ea8eeb4 100644
--- a/lib/view_model/exchange/exchange_view_model.dart
+++ b/lib/view_model/exchange/exchange_view_model.dart
@@ -142,8 +142,17 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
       _bestRate = 0;
       _calculateBestRate();
     });
+
+    if (isElectrumWallet) {
+      bitcoin!.updateFeeRates(wallet);
+    }
   }
 
+  bool get isElectrumWallet =>
+      wallet.type == WalletType.bitcoin ||
+      wallet.type == WalletType.litecoin ||
+      wallet.type == WalletType.bitcoinCash;
+
   bool _useTorOnly;
   final Box<Trade> trades;
   final ExchangeTemplateStore _exchangeTemplateStore;
diff --git a/macos/Podfile.lock b/macos/Podfile.lock
index c2f37a3f3..8951a2dd1 100644
--- a/macos/Podfile.lock
+++ b/macos/Podfile.lock
@@ -17,15 +17,13 @@ PODS:
   - in_app_review (0.2.0):
     - FlutterMacOS
   - OrderedSet (5.0.0)
-  - package_info (0.0.1):
-    - FlutterMacOS
   - package_info_plus (0.0.1):
     - FlutterMacOS
   - path_provider_foundation (0.0.1):
     - Flutter
     - FlutterMacOS
   - ReachabilitySwift (5.0.0)
-  - share_plus_macos (0.0.1):
+  - share_plus (0.0.1):
     - FlutterMacOS
   - shared_preferences_foundation (0.0.1):
     - Flutter
@@ -46,10 +44,9 @@ DEPENDENCIES:
   - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`)
   - FlutterMacOS (from `Flutter/ephemeral`)
   - in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`)
-  - package_info (from `Flutter/ephemeral/.symlinks/plugins/package_info/macos`)
   - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
   - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
-  - share_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos`)
+  - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`)
   - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
   - sp_scanner (from `Flutter/ephemeral/.symlinks/plugins/sp_scanner/macos`)
   - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
@@ -77,14 +74,12 @@ EXTERNAL SOURCES:
     :path: Flutter/ephemeral
   in_app_review:
     :path: Flutter/ephemeral/.symlinks/plugins/in_app_review/macos
-  package_info:
-    :path: Flutter/ephemeral/.symlinks/plugins/package_info/macos
   package_info_plus:
     :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
   path_provider_foundation:
     :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
-  share_plus_macos:
-    :path: Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos
+  share_plus:
+    :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos
   shared_preferences_foundation:
     :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
   sp_scanner:
@@ -104,11 +99,10 @@ SPEC CHECKSUMS:
   FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
   in_app_review: a850789fad746e89bce03d4aeee8078b45a53fd0
   OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
-  package_info: 6eba2fd8d3371dda2d85c8db6fe97488f24b74b2
-  package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
+  package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
   path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
   ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
-  share_plus_macos: 853ee48e7dce06b633998ca0735d482dd671ade4
+  share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf
   shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
   sp_scanner: 269d96e0ec3173e69156be7239b95182be3b8303
   url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 07dc7f5af..0d99c1c8c 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -94,10 +94,7 @@ dependencies:
 #      ref: main
   socks5_proxy: ^1.0.4
   flutter_svg: ^2.0.9
-  polyseed:
-    git:
-      url: https://github.com/mrcyjanek/polyseed_dart
-      ref: f9adc68dbf879fefadeae8e86d1c2983f5a2cc3f
+  polyseed: ^0.0.6
   nostr_tools: ^1.0.9
   solana: ^0.30.1
   bitcoin_base:
@@ -105,7 +102,7 @@ dependencies:
       url: https://github.com/cake-tech/bitcoin_base
       ref: cake-update-v5
   ledger_flutter: ^1.0.1
-  hashlib: 1.12.0
+  hashlib: ^1.19.2
 
 dev_dependencies:
   flutter_test:
diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index c91f24622..324d2d2ae 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
 APP_ANDROID_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.16.3"
-MONERO_COM_BUILD_NUMBER=97
+MONERO_COM_VERSION="1.16.4"
+MONERO_COM_BUILD_NUMBER=98
 MONERO_COM_BUNDLE_ID="com.monero.app"
 MONERO_COM_PACKAGE="com.monero.app"
 MONERO_COM_SCHEME="monero.com"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.19.3"
-CAKEWALLET_BUILD_NUMBER=224
+CAKEWALLET_VERSION="4.19.4"
+CAKEWALLET_BUILD_NUMBER=225
 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
 CAKEWALLET_SCHEME="cakewallet"
diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh
index e32b3e9f3..1405f7939 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.16.3"
-MONERO_COM_BUILD_NUMBER=95
+MONERO_COM_VERSION="1.16.4"
+MONERO_COM_BUILD_NUMBER=96
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.19.3"
-CAKEWALLET_BUILD_NUMBER=262
+CAKEWALLET_VERSION="4.19.4"
+CAKEWALLET_BUILD_NUMBER=263
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 HAVEN_NAME="Haven"
diff --git a/scripts/linux/app_env.sh b/scripts/linux/app_env.sh
index 729cf376b..bc2965193 100755
--- a/scripts/linux/app_env.sh
+++ b/scripts/linux/app_env.sh
@@ -14,8 +14,8 @@ if [ -n "$1" ]; then
 fi
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="1.9.2"
-CAKEWALLET_BUILD_NUMBER=30
+CAKEWALLET_VERSION="1.9.4"
+CAKEWALLET_BUILD_NUMBER=31
 
 if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
     echo "Wrong app type."
diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh
index 2f6d51a93..9487be2c8 100755
--- a/scripts/macos/app_env.sh
+++ b/scripts/macos/app_env.sh
@@ -16,13 +16,13 @@ if [ -n "$1" ]; then
 fi
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.6.2"
-MONERO_COM_BUILD_NUMBER=27
+MONERO_COM_VERSION="1.6.4"
+MONERO_COM_BUILD_NUMBER=28
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="1.12.2"
-CAKEWALLET_BUILD_NUMBER=83
+CAKEWALLET_VERSION="1.12.4"
+CAKEWALLET_BUILD_NUMBER=84
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then
diff --git a/scripts/windows/build_exe_installer.iss b/scripts/windows/build_exe_installer.iss
index 216f367ca..4d7838723 100644
--- a/scripts/windows/build_exe_installer.iss
+++ b/scripts/windows/build_exe_installer.iss
@@ -1,5 +1,5 @@
 #define MyAppName "Cake Wallet"
-#define MyAppVersion "0.0.4"
+#define MyAppVersion "0.0.5"
 #define MyAppPublisher "Cake Labs LLC"
 #define MyAppURL "https://cakewallet.com/"
 #define MyAppExeName "CakeWallet.exe"

From fe4b3e4eb05ca5037500778102e031a67243a9ee Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Sun, 18 Aug 2024 03:48:25 +0300
Subject: [PATCH 53/81] push haven fix

---
 cw_bitcoin/pubspec.lock        |  6 +++---
 cw_haven/lib/haven_wallet.dart | 13 ++++++++++---
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock
index 12274c1e6..cdb88946e 100644
--- a/cw_bitcoin/pubspec.lock
+++ b/cw_bitcoin/pubspec.lock
@@ -67,11 +67,11 @@ packages:
     source: git
     version: "1.0.1"
   bitcoin_base:
-    dependency: "direct main"
+    dependency: "direct overridden"
     description:
       path: "."
-      ref: cake-update-v4
-      resolved-ref: "574486bfcdbbaf978dcd006b46fc8716f880da29"
+      ref: cake-update-v5
+      resolved-ref: ff2b10eb27b0254ce4518d054332d97d77d9b380
       url: "https://github.com/cake-tech/bitcoin_base"
     source: git
     version: "4.7.0"
diff --git a/cw_haven/lib/haven_wallet.dart b/cw_haven/lib/haven_wallet.dart
index c0ecbca68..317d9dc65 100644
--- a/cw_haven/lib/haven_wallet.dart
+++ b/cw_haven/lib/haven_wallet.dart
@@ -10,10 +10,8 @@ import 'package:cw_haven/haven_transaction_info.dart';
 import 'package:cw_haven/haven_wallet_addresses.dart';
 import 'package:cw_core/monero_wallet_utils.dart';
 import 'package:cw_haven/api/structs/pending_transaction.dart';
-import 'package:flutter/foundation.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cw_haven/api/transaction_history.dart' as haven_transaction_history;
-//import 'package:cw_haven/wallet.dart';
 import 'package:cw_haven/api/wallet.dart' as haven_wallet;
 import 'package:cw_haven/api/transaction_history.dart' as transaction_history;
 import 'package:cw_haven/api/monero_output.dart';
@@ -123,7 +121,8 @@ abstract class HavenWalletBase
           login: node.login,
           password: node.password,
           useSSL: node.useSSL ?? false,
-          isLightWallet: false, // FIXME: hardcoded value
+          isLightWallet: false,
+          // FIXME: hardcoded value
           socksProxyAddress: node.socksProxyAddress);
 
       haven_wallet.setTrustedDaemon(node.trusted);
@@ -419,4 +418,12 @@ abstract class HavenWalletBase
 
   @override
   String get password => _password;
+
+  @override
+  Future<String> signMessage(String message, {String? address = null}) =>
+      throw UnimplementedError();
+
+  @override
+  Future<bool> verifyMessage(String message, String signature, {String? address = null}) =>
+      throw UnimplementedError();
 }

From 4071e460f687d4fe2e72368dfd3ed5a30ca2ca1f Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Sun, 18 Aug 2024 14:25:44 +0200
Subject: [PATCH 54/81] fix universal build (#1621)

---
 scripts/macos/build_monero_all.sh | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/scripts/macos/build_monero_all.sh b/scripts/macos/build_monero_all.sh
index c934b4667..edc8efe81 100755
--- a/scripts/macos/build_monero_all.sh
+++ b/scripts/macos/build_monero_all.sh
@@ -23,12 +23,14 @@ then
     done
 else
     if [[ "x$1" == "xuniversal" ]]; then
-	ARCHS=(arm64 x86_64)
+	ARCHS=(x86_64 arm64)
     else
 	ARCHS=$(uname -m)
     fi
     for COIN in monero wownero;
     do
+        MONERO_LIBS=""
+        WOWNERO_LIBS=""
 	for ARCH in "${ARCHS[@]}";
 	do
 	    if [[ "$ARCH" == "arm64" ]]; then
@@ -39,17 +41,19 @@ else
 		HOST="${ARCH}-host-apple-darwin"
 	    fi
 
-	    MONERO_LIBS=" -arch ${ARCH} ${MONEROC_RELEASE_DIR}/${HOST}_libwallet2_api_c.dylib"
-	    WOWNERO_LIBS=" -arch ${ARCH} ${WOWNEROC_RELEASE_DIR}/${HOST}_libwallet2_api_c.dylib"
+            MONERO_LIBS="$MONERO_LIBS -arch ${ARCH} ${MONEROC_RELEASE_DIR}/${HOST}_libwallet2_api_c.dylib"
+            WOWNERO_LIBS="$WOWNERO_LIBS -arch ${ARCH} ${WOWNEROC_RELEASE_DIR}/${HOST}_libwallet2_api_c.dylib"
 
-	    if [[ ! $(uname -m) == $ARCH ]]; then
-			PRC="arch -${ARCH}"
-	    fi
+            if [[ ! $(uname -m) == $ARCH ]]; then
+                PRC="arch -${ARCH}"
+            else
+                PRC=""
+            fi
 
-		pushd ../monero_c
-            $PRC ./build_single.sh ${COIN} ${HOST} $NPROC
-	    	unxz -f ./release/${COIN}/${HOST}_libwallet2_api_c.dylib.xz
-		popd
+            pushd ../monero_c
+                $PRC ./build_single.sh ${COIN} ${HOST} $NPROC
+                unxz -f ./release/${COIN}/${HOST}_libwallet2_api_c.dylib.xz
+	    popd
 	done
     done
 fi

From 19c600ba10c4d72c984388073b0820e362c12bc6 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Sun, 18 Aug 2024 17:15:23 +0300
Subject: [PATCH 55/81] update macos build number minor fixes

---
 .../desktop_widgets/desktop_wallet_selection_dropdown.dart    | 4 ++--
 lib/src/screens/dashboard/edit_token_page.dart                | 2 +-
 lib/src/screens/exchange_trade/exchange_trade_page.dart       | 2 +-
 lib/src/screens/new_wallet/new_wallet_page.dart               | 2 +-
 lib/src/screens/root/root.dart                                | 2 +-
 lib/src/screens/send/widgets/send_card.dart                   | 2 +-
 scripts/macos/app_env.sh                                      | 2 +-
 7 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
index 94489a945..fd0eecac3 100644
--- a/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
+++ b/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
@@ -200,14 +200,14 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
       }
 
         try {
-          if (context.mounted) {
+          if (mounted) {
             changeProcessText(S.of(context).wallet_list_loading_wallet(wallet.name));
           }
           await widget.walletListViewModel.loadWallet(wallet);
           hideProgressText();
           setState(() {});
         } catch (e) {
-          if (context.mounted) {
+          if (mounted) {
             changeProcessText(S.of(context).wallet_list_failed_to_load(wallet.name, e.toString()));
           }
         }
diff --git a/lib/src/screens/dashboard/edit_token_page.dart b/lib/src/screens/dashboard/edit_token_page.dart
index 59f7de9e5..dbb5f1aae 100644
--- a/lib/src/screens/dashboard/edit_token_page.dart
+++ b/lib/src/screens/dashboard/edit_token_page.dart
@@ -206,7 +206,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
                           ),
                           contractAddress: _contractAddressController.text,
                         );
-                        if (context.mounted) {
+                        if (mounted) {
                           Navigator.pop(context);
                         }
                       }
diff --git a/lib/src/screens/exchange_trade/exchange_trade_page.dart b/lib/src/screens/exchange_trade/exchange_trade_page.dart
index 4d3334f9f..0766a4562 100644
--- a/lib/src/screens/exchange_trade/exchange_trade_page.dart
+++ b/lib/src/screens/exchange_trade/exchange_trade_page.dart
@@ -284,7 +284,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
 
       if (state is TransactionCommitted) {
         WidgetsBinding.instance.addPostFrameCallback((_) {
-          if (context.mounted) {
+          if (mounted) {
             showPopUp<void>(
                 context: context,
                 builder: (BuildContext popupContext) {
diff --git a/lib/src/screens/new_wallet/new_wallet_page.dart b/lib/src/screens/new_wallet/new_wallet_page.dart
index cb451c056..471240877 100644
--- a/lib/src/screens/new_wallet/new_wallet_page.dart
+++ b/lib/src/screens/new_wallet/new_wallet_page.dart
@@ -95,7 +95,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
 
       if (state is FailureState) {
         WidgetsBinding.instance.addPostFrameCallback((_) {
-          if (context.mounted) {
+          if (mounted) {
             showPopUp<void>(
                 context: context,
                 builder: (_) {
diff --git a/lib/src/screens/root/root.dart b/lib/src/screens/root/root.dart
index 8ce0ddde9..76c6c5cfd 100644
--- a/lib/src/screens/root/root.dart
+++ b/lib/src/screens/root/root.dart
@@ -219,7 +219,7 @@ class RootState extends State<Root> with WidgetsBindingObserver {
 
   void waitForWalletInstance(BuildContext context) {
     WidgetsBinding.instance.addPostFrameCallback((_) {
-      if (context.mounted) {
+      if (mounted) {
         _walletReactionDisposer = reaction(
           (_) => widget.appStore.wallet,
           (WalletBase? wallet) {
diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart
index 0a3de3e58..214d162ed 100644
--- a/lib/src/screens/send/widgets/send_card.dart
+++ b/lib/src/screens/send/widgets/send_card.dart
@@ -82,7 +82,7 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
     if (initialPaymentRequest != null &&
         sendViewModel.walletCurrencyName != initialPaymentRequest!.scheme.toLowerCase()) {
       WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
-        if (context.mounted) {
+        if (mounted) {
           showPopUp<void>(
               context: context,
               builder: (BuildContext context) {
diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh
index 9487be2c8..342831d65 100755
--- a/scripts/macos/app_env.sh
+++ b/scripts/macos/app_env.sh
@@ -22,7 +22,7 @@ MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
 CAKEWALLET_VERSION="1.12.4"
-CAKEWALLET_BUILD_NUMBER=84
+CAKEWALLET_BUILD_NUMBER=85
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then

From 5449b94ba42c4e60d8cfd2a55696ee0f288a767a Mon Sep 17 00:00:00 2001
From: Konstantin Ullrich <konstantinullrich12@gmail.com>
Date: Mon, 19 Aug 2024 16:06:57 +0200
Subject: [PATCH 56/81] Windows fix (#1624)

* CW-488 Fix missing Wownero logo

* Temporary fix for windows
---
 .../desktop_wallet_selection_dropdown.dart    | 29 +++++++++----------
 lib/store/settings_store.dart                 | 10 +++++--
 2 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
index fd0eecac3..0dd3458b6 100644
--- a/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
+++ b/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
@@ -1,5 +1,4 @@
 import 'package:another_flushbar/flushbar.dart';
-import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cake_wallet/core/auth_service.dart';
 import 'package:cake_wallet/entities/desktop_dropdown_item.dart';
 import 'package:cake_wallet/generated/i18n.dart';
@@ -8,8 +7,9 @@ import 'package:cake_wallet/src/screens/auth/auth_page.dart';
 import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart';
 import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
-import 'package:cake_wallet/themes/extensions/menu_theme.dart';
 import 'package:cake_wallet/store/settings_store.dart';
+import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
+import 'package:cake_wallet/themes/extensions/menu_theme.dart';
 import 'package:cake_wallet/utils/show_bar.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
@@ -122,9 +122,7 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
   }
 
   void _onSelectedWallet(WalletListItem selectedWallet) async {
-    if (selectedWallet.isCurrent || !selectedWallet.isEnabled) {
-      return;
-    }
+    if (selectedWallet.isCurrent || !selectedWallet.isEnabled) return;
 
     WidgetsBinding.instance.addPostFrameCallback((_) async {
       final confirmed = await showPopUp<bool>(
@@ -149,9 +147,7 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
   Image _imageFor({required WalletType type, bool? isTestnet}) {
     switch (type) {
       case WalletType.bitcoin:
-        if (isTestnet == true) {
-          return tBitcoinIcon;
-        }
+        if (isTestnet == true) return tBitcoinIcon;
         return bitcoinIcon;
       case WalletType.monero:
         return moneroIcon;
@@ -173,6 +169,8 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
         return solanaIcon;
       case WalletType.tron:
         return tronIcon;
+      case WalletType.wownero:
+        return wowneroIcon;
       default:
         return nonWalletTypeIcon;
     }
@@ -180,24 +178,23 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
 
   Future<void> _loadWallet(WalletListItem wallet) async {
     if (SettingsStoreBase.walletPasswordDirectInput) {
-      Navigator.of(context).pushNamed(
-          Routes.walletUnlockLoadable,
+      Navigator.of(context).pushNamed(Routes.walletUnlockLoadable,
           arguments: WalletUnlockArguments(
               callback: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
                 if (isAuthenticatedSuccessfully) {
                   auth.close();
                   setState(() {});
                 }
-              }, walletName: wallet.name,
+              },
+              walletName: wallet.name,
               walletType: wallet.type));
       return;
     }
 
-    widget._authService.authenticateAction(context,
-        onAuthSuccess: (isAuthenticatedSuccessfully) async {
-      if (!isAuthenticatedSuccessfully) {
-        return;
-      }
+    widget._authService.authenticateAction(
+      context,
+      onAuthSuccess: (isAuthenticatedSuccessfully) async {
+        if (!isAuthenticatedSuccessfully) return;
 
         try {
           if (mounted) {
diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart
index df2c7767f..ee145195c 100644
--- a/lib/store/settings_store.dart
+++ b/lib/store/settings_store.dart
@@ -1549,8 +1549,14 @@ abstract class SettingsStoreBase with Store {
       final macInfo = await deviceInfoPlugin.macOsInfo;
       deviceName = macInfo.computerName;
     } else if (Platform.isWindows) {
-      final windowsInfo = await deviceInfoPlugin.windowsInfo;
-      deviceName = windowsInfo.productName;
+      try {
+        final windowsInfo = await deviceInfoPlugin.windowsInfo;
+        deviceName = windowsInfo.productName;
+      } catch (e) {
+        print(e);
+        print('likely digitalProductId is null wait till https://github.com/fluttercommunity/plus_plugins/pull/3188 is merged');
+        deviceName = "Windows Device";
+      }
     }
 
     return deviceName;

From 7d36da91fa79d4a649977767c6462c6c0b528387 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Mon, 19 Aug 2024 12:30:25 -0400
Subject: [PATCH 57/81] small fix

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

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 288b7809b..fb7dad986 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -1,4 +1,5 @@
 import 'dart:async';
+import 'dart:convert';
 import 'dart:math';
 import 'package:collection/collection.dart';
 import 'package:convert/convert.dart' as convert;
@@ -23,7 +24,6 @@ import 'package:cw_core/pending_transaction.dart';
 import 'package:cw_core/sync_status.dart';
 import 'package:cw_core/transaction_direction.dart';
 import 'package:cw_core/encryption_file_utils.dart';
-import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_bitcoin/electrum_balance.dart';
 import 'package:cw_bitcoin/electrum_wallet.dart';

From d315617efa1d805273b8b5c2082878fbc594e5e0 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Mon, 19 Aug 2024 12:31:50 -0400
Subject: [PATCH 58/81] small fix

---
 cw_bitcoin/lib/litecoin_wallet.dart | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index fb7dad986..9449e6599 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -2,7 +2,6 @@ import 'dart:async';
 import 'dart:convert';
 import 'dart:math';
 import 'package:collection/collection.dart';
-import 'package:convert/convert.dart' as convert;
 import 'package:crypto/crypto.dart';
 import 'package:cw_core/cake_hive.dart';
 import 'package:cw_core/mweb_utxo.dart';
@@ -468,7 +467,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     if (status.mwebUtxosHeight != height) return;
     int amount = 0;
     Set<String> inputAddresses = {};
-    var output = convert.AccumulatorSink<Digest>();
+    var output = AccumulatorSink<Digest>();
     var input = sha256.startChunkedConversion(output);
     for (final outputId in spent) {
       final utxo = mwebUtxosBox.get(outputId);

From 501e4998c78d010063d8aa366c9702fecf9ccb60 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Mon, 19 Aug 2024 13:14:00 -0400
Subject: [PATCH 59/81] fix

---
 cw_bitcoin/lib/litecoin_wallet.dart | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 9449e6599..14662e7a8 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -1,5 +1,6 @@
 import 'dart:async';
 import 'dart:convert';
+import 'dart:convert' as convert;
 import 'dart:math';
 import 'package:collection/collection.dart';
 import 'package:crypto/crypto.dart';
@@ -467,7 +468,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     if (status.mwebUtxosHeight != height) return;
     int amount = 0;
     Set<String> inputAddresses = {};
-    var output = AccumulatorSink<Digest>();
+    var output = convert.AccumulatorSink<Digest>();
     var input = sha256.startChunkedConversion(output);
     for (final outputId in spent) {
       final utxo = mwebUtxosBox.get(outputId);

From c620d6d5a86c32790af6decc8098e4c3592427d8 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Mon, 19 Aug 2024 14:33:05 -0400
Subject: [PATCH 60/81] dart:convert != package:convert

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

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 14662e7a8..7d8e70c41 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -1,6 +1,6 @@
 import 'dart:async';
 import 'dart:convert';
-import 'dart:convert' as convert;
+import 'package:convert/convert.dart' as convert;
 import 'dart:math';
 import 'package:collection/collection.dart';
 import 'package:crypto/crypto.dart';

From ef077c864763488cc25f6b0cc985971c8c0f6c10 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Mon, 19 Aug 2024 15:11:08 -0400
Subject: [PATCH 61/81] change address fixes

---
 cw_bitcoin/lib/litecoin_wallet.dart           |  2 ++
 cw_bitcoin/lib/litecoin_wallet_addresses.dart | 15 ++++++++-------
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 7d8e70c41..bb1023164 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -83,6 +83,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       sideHd: accountHD.childKey(Bip32KeyIndex(1)),
       network: network,
       mwebHd: mwebHd,
+      mwebEnabled: mwebEnabled,
     );
     autorun((_) {
       this.walletAddresses.isEnabledAutoGenerateSubaddress = this.isEnabledAutoGenerateSubaddress;
@@ -822,6 +823,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     }
 
     mwebEnabled = enabled;
+    (walletAddresses as LitecoinWalletAddresses).mwebEnabled = enabled;
     stopSync();
     startSync();
   }
diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
index 46ab1d12a..24cdd04d8 100644
--- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
@@ -17,8 +17,9 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
     WalletInfo walletInfo, {
     required super.mainHd,
     required super.sideHd,
-    required this.mwebHd,
     required super.network,
+    required this.mwebHd,
+    required this.mwebEnabled,
     super.initialAddresses,
     super.initialRegularAddressIndex,
     super.initialChangeAddressIndex,
@@ -27,6 +28,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
   }
 
   final Bip32Slip10Secp256k1 mwebHd;
+  bool mwebEnabled;
 
   List<int> get scanSecret => mwebHd.childKey(Bip32KeyIndex(0x80000000)).privateKey.privKey.raw;
   List<int> get spendPubkey =>
@@ -78,11 +80,10 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
   @action
   @override
   Future<String> getChangeAddress() async {
-    // super.getChangeAddress();
-    // updateChangeAddresses();
-    // print("getChangeAddress @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
-    // this means all change addresses used will be mweb addresses!:
-    await topUpMweb(0);
-    return mwebAddrs[0];
+    if (mwebEnabled) {
+      await topUpMweb(0);
+      return mwebAddrs[0];
+    }
+    return super.getChangeAddress();
   }
 }

From e0a0b7ab5dc0a77375c35205e914a23235eb012b Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Mon, 19 Aug 2024 16:20:54 -0400
Subject: [PATCH 62/81] update bitcoin_base to fix mweb address program
 checking

---
 cw_bitcoin/pubspec.yaml      | 2 +-
 cw_bitcoin_cash/pubspec.yaml | 2 +-
 pubspec_base.yaml            | 6 +-----
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml
index 2901bf0f5..cd7440c53 100644
--- a/cw_bitcoin/pubspec.yaml
+++ b/cw_bitcoin/pubspec.yaml
@@ -59,7 +59,7 @@ dependency_overrides:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v5
+      ref: cake-update-v6
   pointycastle: 3.7.4
 
 # For information on the generic Dart part of this file, see the
diff --git a/cw_bitcoin_cash/pubspec.yaml b/cw_bitcoin_cash/pubspec.yaml
index 64bd38b1d..dcf6584b8 100644
--- a/cw_bitcoin_cash/pubspec.yaml
+++ b/cw_bitcoin_cash/pubspec.yaml
@@ -42,7 +42,7 @@ dependency_overrides:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v5
+      ref: cake-update-v6
 
 # For information on the generic Dart part of this file, see the
 # following page: https://dart.dev/tools/pub/pubspec
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 3ea8c24e4..6e07b989b 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -97,10 +97,6 @@ dependencies:
   polyseed: ^0.0.6
   nostr_tools: ^1.0.9
   solana: ^0.30.1
-  bitcoin_base:
-    git:
-      url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v5
   ledger_flutter: ^1.0.1
   hashlib: ^1.19.2
 
@@ -139,7 +135,7 @@ dependency_overrides:
   bitcoin_base:
     git:
       url: https://github.com/cake-tech/bitcoin_base
-      ref: cake-update-v5
+      ref: cake-update-v6
 
 flutter_icons:
   image_path: "assets/images/app_logo.png"

From 49d2560eb94d97285fe9f594f7643f4c2265006e Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Wed, 21 Aug 2024 15:49:47 -0400
Subject: [PATCH 63/81] fix (#1633)

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

diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 2d0b989d7..047e5551d 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -1005,7 +1005,7 @@ abstract class ElectrumWalletBase
         if (estimatedTx.inputPrivKeyInfos.isEmpty) {
           error += "\nNo private keys generated.";
         } else {
-          error += "\nAddress: ${utxo.ownerDetails.address.toAddress()}";
+          error += "\nAddress: ${utxo.ownerDetails.address.toAddress(network)}";
 
           key = estimatedTx.inputPrivKeyInfos.firstWhereOrNull((element) {
             final elemPubkey = element.privkey.getPublic().toHex();

From c0e0cf02aa582e477d0602156a3b01fb4c9db771 Mon Sep 17 00:00:00 2001
From: Rafael <github@rafael.saes.dev>
Date: Wed, 21 Aug 2024 19:31:20 -0300
Subject: [PATCH 64/81] Fix testnet (#1632)

* fix: failed connection and misc changes

* default isTestnet to false

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
---
 cw_bitcoin/lib/electrum.dart                       |  6 ++++--
 cw_bitcoin/lib/electrum_wallet.dart                | 12 +++++++-----
 cw_core/lib/wallet_base.dart                       |  2 +-
 lib/bitcoin/cw_bitcoin.dart                        |  2 +-
 lib/view_model/node_list/node_list_view_model.dart |  2 +-
 lib/view_model/transaction_details_view_model.dart |  2 +-
 6 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart
index 28043d0c0..6ac8edd1a 100644
--- a/cw_bitcoin/lib/electrum.dart
+++ b/cw_bitcoin/lib/electrum.dart
@@ -119,9 +119,11 @@ class ElectrumClient {
           _setConnectionStatus(ConnectionStatus.failed);
       },
       onDone: () {
-        socket = null;
         unterminatedString = '';
-        if (host == socket?.address.host) _setConnectionStatus(ConnectionStatus.disconnected);
+        if (host == socket?.address.host) {
+          socket = null;
+          _setConnectionStatus(ConnectionStatus.disconnected);
+        }
       },
       cancelOnError: true,
     );
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 047e5551d..da91a29e4 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -42,7 +42,6 @@ import 'package:flutter/foundation.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:rxdart/subjects.dart';
-import 'package:http/http.dart' as http;
 import 'package:sp_scanner/sp_scanner.dart';
 
 part 'electrum_wallet.g.dart';
@@ -89,7 +88,7 @@ abstract class ElectrumWalletBase
               }
             : {}),
         this.unspentCoinsInfo = unspentCoinsInfo,
-        this.isTestnet = network == BitcoinNetwork.testnet,
+        this.isTestnet = !network.isMainnet,
         this._mnemonic = mnemonic,
         super(walletInfo) {
     this.electrumClient = electrumClient ?? ElectrumClient();
@@ -182,7 +181,7 @@ abstract class ElectrumWalletBase
   BasedUtxoNetwork network;
 
   @override
-  bool? isTestnet;
+  bool isTestnet;
 
   bool get hasSilentPaymentsScanning => type == WalletType.bitcoin;
 
@@ -426,7 +425,7 @@ abstract class ElectrumWalletBase
       await updateTransactions();
       await updateAllUnspents();
       await updateBalance();
-      updateFeeRates();
+      await updateFeeRates();
 
       _updateFeeRateTimer ??=
           Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
@@ -448,6 +447,8 @@ abstract class ElectrumWalletBase
     final feeRates = await electrumClient.feeRates(network: network);
     if (feeRates != [0, 0, 0]) {
       _feeRates = feeRates;
+    } else if (isTestnet) {
+      _feeRates = [1, 1, 1];
     }
   }
 
@@ -1944,8 +1945,9 @@ abstract class ElectrumWalletBase
   Future<void> _setInitialHeight() async {
     if (_chainTipUpdateSubject != null) return;
 
+    _currentChainTip = await getUpdatedChainTip();
+
     if ((_currentChainTip == null || _currentChainTip! == 0) && walletInfo.restoreHeight == 0) {
-      await getUpdatedChainTip();
       await walletInfo.updateRestoreHeight(_currentChainTip!);
     }
 
diff --git a/cw_core/lib/wallet_base.dart b/cw_core/lib/wallet_base.dart
index 14ba898a7..f55816bb7 100644
--- a/cw_core/lib/wallet_base.dart
+++ b/cw_core/lib/wallet_base.dart
@@ -95,5 +95,5 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
 
   Future<bool> verifyMessage(String message, String signature, {String? address = null});
 
-  bool? isTestnet;
+  bool isTestnet = false;
 }
diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart
index e87773f97..5a71e3549 100644
--- a/lib/bitcoin/cw_bitcoin.dart
+++ b/lib/bitcoin/cw_bitcoin.dart
@@ -516,7 +516,7 @@ class CWBitcoin extends Bitcoin {
   @override
   bool isTestnet(Object wallet) {
     final bitcoinWallet = wallet as ElectrumWallet;
-    return bitcoinWallet.isTestnet ?? false;
+    return bitcoinWallet.isTestnet;
   }
 
   @override
diff --git a/lib/view_model/node_list/node_list_view_model.dart b/lib/view_model/node_list/node_list_view_model.dart
index ea1dd574e..2721fd7b3 100644
--- a/lib/view_model/node_list/node_list_view_model.dart
+++ b/lib/view_model/node_list/node_list_view_model.dart
@@ -52,7 +52,7 @@ abstract class NodeListViewModelBase with Store {
 
     switch (_appStore.wallet!.type) {
       case WalletType.bitcoin:
-        if (_appStore.wallet!.isTestnet == true) {
+        if (_appStore.wallet!.isTestnet) {
           node = getBitcoinTestnetDefaultElectrumServer(nodes: _nodeSource)!;
         } else {
           node = getBitcoinDefaultElectrumServer(nodes: _nodeSource)!;
diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart
index ef6474974..18715e508 100644
--- a/lib/view_model/transaction_details_view_model.dart
+++ b/lib/view_model/transaction_details_view_model.dart
@@ -152,7 +152,7 @@ abstract class TransactionDetailsViewModelBase with Store {
       case WalletType.monero:
         return 'https://monero.com/tx/${txId}';
       case WalletType.bitcoin:
-        return 'https://mempool.space/${wallet.isTestnet == true ? "testnet/" : ""}tx/${txId}';
+        return 'https://mempool.space/${wallet.isTestnet ? "testnet/" : ""}tx/${txId}';
       case WalletType.litecoin:
         return 'https://blockchair.com/litecoin/transaction/${txId}';
       case WalletType.bitcoinCash:

From 3cefe3b28847000d29fa97fb29415c20d51b8605 Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Thu, 22 Aug 2024 02:36:11 +0200
Subject: [PATCH 65/81] update setup-java and switch distribution (#1629)

---
 .github/workflows/cache_dependencies.yml    | 5 +++--
 .github/workflows/pr_test_build_android.yml | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml
index 902a44a42..c0042bf5c 100644
--- a/.github/workflows/cache_dependencies.yml
+++ b/.github/workflows/cache_dependencies.yml
@@ -23,9 +23,10 @@ jobs:
           docker-images: true
 
       - uses: actions/checkout@v2
-      - uses: actions/setup-java@v1
+      - uses: actions/setup-java@v2
         with:
-          java-version: "17.x"
+          distribution: "temurin"
+          java-version: "17"
       - name: Configure placeholder git details
         run: |
           git config --global user.email "CI@cakewallet.com"
diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml
index 5dbf1610f..b7b2aaa71 100644
--- a/.github/workflows/pr_test_build_android.yml
+++ b/.github/workflows/pr_test_build_android.yml
@@ -39,9 +39,10 @@ jobs:
           docker-images: true
 
       - uses: actions/checkout@v2
-      - uses: actions/setup-java@v1
+      - uses: actions/setup-java@v2
         with:
-          java-version: "17.x"
+          distribution: "temurin"
+          java-version: "17"
       - name: Configure placeholder git details
         run: |
           git config --global user.email "CI@cakewallet.com"

From 799ddcdc6faa0e094f46bd1c37b068d3d8d721e3 Mon Sep 17 00:00:00 2001
From: Jorge <jorgesumle@freakspot.net>
Date: Thu, 22 Aug 2024 02:45:16 +0200
Subject: [PATCH 66/81] Fix Spanish string (#1622)

---
 res/values/strings_es.arb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 02d17ac96..c308f045a 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -387,7 +387,7 @@
   "nano_current_rep": "Representante actual",
   "nano_gpt_thanks_message": "¡Gracias por usar nanogpt! ¡Recuerde regresar al navegador después de que se complete su transacción!",
   "nano_pick_new_rep": "Elija un nuevo representante",
-  "nanogpt_subtitle": "Todos los modelos más nuevos (GPT-4, Claude). \\ Nno suscripción, pague con cripto.",
+  "nanogpt_subtitle": "Todos los modelos más nuevos (GPT-4, Claude). \\nSin suscripción, pague con cripto.",
   "narrow": "Angosto",
   "new_first_wallet_text": "Mantenga fácilmente su criptomoneda segura",
   "new_node_testing": "Prueba de nuevos nodos",
@@ -894,4 +894,4 @@
   "you_will_get": "Convertir a",
   "you_will_send": "Convertir de",
   "yy": "YY"
-}
\ No newline at end of file
+}

From 92f87a53661b5b105c14e5fc27b6664e76083b5f Mon Sep 17 00:00:00 2001
From: smgthbusr <85361717+smgthbusr@users.noreply.github.com>
Date: Thu, 22 Aug 2024 02:47:30 +0200
Subject: [PATCH 67/81] Add Armenian language (#1623)

* Add Armenian strings

* Add Armenian

* Add Armenian flag
---
 assets/images/flags/arm.png        | Bin 0 -> 4846 bytes
 lib/entities/language_service.dart |   2 +
 res/values/strings_hy.arb          | 897 +++++++++++++++++++++++++++++
 3 files changed, 899 insertions(+)
 create mode 100644 assets/images/flags/arm.png
 create mode 100644 res/values/strings_hy.arb

diff --git a/assets/images/flags/arm.png b/assets/images/flags/arm.png
new file mode 100644
index 0000000000000000000000000000000000000000..7bdabd4ee76f5e86f5aa3c8722a2867cabe683dc
GIT binary patch
literal 4846
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
KQ3n@%kpFL7qruVu

literal 0
HcmV?d00001

diff --git a/lib/entities/language_service.dart b/lib/entities/language_service.dart
index 23d27dd38..bb60c5cce 100644
--- a/lib/entities/language_service.dart
+++ b/lib/entities/language_service.dart
@@ -30,6 +30,7 @@ class LanguageService {
     'yo': 'Yorùbá (Yoruba)',
     'ha': 'Hausa Najeriya (Nigeria)',
     'tl': 'Filipino (Tagalog)'
+    'hy': 'Հայերեն (Armenian)',
   };
 
   static const Map<String, String> localeCountryCode = {
@@ -59,6 +60,7 @@ class LanguageService {
     'yo': 'nga',
     'ha': 'hau',
     'tl': 'phl'
+    'hy': 'arm'
   };
 
   static final list = <String, String>{};
diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb
new file mode 100644
index 000000000..826bfa99a
--- /dev/null
+++ b/res/values/strings_hy.arb
@@ -0,0 +1,897 @@
+{
+  "about_cake_pay": "Cake Pay-ը Ձեզ թույլ է տալիս հեշտությամբ գնել նվեր քարտեր վիրտուալ ակտիվներով, որոնք անմիջապես ծախսվում են ԱՄՆ-ի 150,000-ից ավելի առևտրականների մոտ:",
+  "account": "Հաշիվ",
+  "accounts": "Հաշիվներ",
+  "accounts_subaddresses": "Հաշիվներ և ենթահասցեներ",
+  "activate": "Ակտիվացնել",
+  "active": "Ակտիվ",
+  "active_cards": "Ակտիվ քարտեր",
+  "activeConnectionsPrompt": "Ակտիվ կապերը կհայտնվեն այստեղ",
+  "add": "Ավելացնել",
+  "add_contact": "Ավելացնել կոնտակտ",
+  "add_contact_to_address_book": "Ուզում եք ավելացնել այս կոնտակտը Ձեր հասցեների գրքում?",
+  "add_custom_node": "Ավելացնել նոր պատվերով հանգույց",
+  "add_custom_redemption": "Ավելացնել պատվերով փրկագնում",
+  "add_fund_to_card": "Ավելացնել նախավճար քարտերի վրա (մինչև ${value})",
+  "add_new_node": "Ավելացնել նոր հանգույց",
+  "add_new_word": "Ավելացնել նոր բառ",
+  "add_receiver": "Ավելացնել ևս մեկ ստացող (ընտրովի)",
+  "add_secret_code": "Կամ ավելացրեք այս գաղտնի կոդը վավերացնող հավելվածում",
+  "add_tip": "Ավելացնել Թեյավճար",
+  "add_token_disclaimer_check": "Ես հաստատել եմ token-ի պայմանագրի հասցեն և տեղեկատվությունը վստահելի աղբյուրի օգտագործմամբ: Վնասակար կամ սխալ տեղեկատվության ավելացումը կարող է հանգեցնել միջոցների կորստի:",
+  "add_token_warning": "Մի խմբագրեք կամ ավելացրեք token-ներ, ինչպես կոչ են անում խարդախները:\nՄիշտ հաստատեք Token-ների հասցեները վստահելի աղբյուրներով:",
+  "add_value": "Ավելացնել արժեք",
+  "address": "Հասցե",
+  "address_book": "Հասցեագիրք",
+  "address_book_menu": "Հասցեագիրք",
+  "address_detected": "Հասցեն հայտնաբերված է",
+  "address_from_domain": "Այս հասցեն է ${domain} Unstoppable Domains-ից",
+  "address_from_yat": "Այս հասցեն է ${emoji} Yat-ից",
+  "address_label": "Հասցեի պիտակ",
+  "address_remove_contact": "Հեռացնել կոնտակտը",
+  "address_remove_content": "Վստահ եք, որ ուզում եք հեռացնել ընտրված կոնտակտը?",
+  "addresses": "Հասցեներ",
+  "advanced_settings": "Առաջադեմ կարգավորումներ",
+  "aggressive": "Ագրեսիվ",
+  "agree": "Համաձայն եմ",
+  "agree_and_continue": "Համաձայն եմ և շարունակեմ",
+  "agree_to": "Ստեղծելով հաշիվ դուք համաձայնում եք ",
+  "all": "Բոլորը",
+  "all_trades": "Բոլոր գործարքները",
+  "all_transactions": "Բոլոր գործառնությունները",
+  "alphabetical": "Այբբենական",
+  "already_have_account": "Արդեն ունե՞ք հաշիվ?",
+  "always": "Միշտ",
+  "amount": "Քանակ՝ ",
+  "amount_is_below_minimum_limit": "Ձեր հաշվի մնացորդը կազմում է ավելի քիչ, քան փոխանակման համար անհրաժեշտ նվազագույն վճարը (${min})",
+  "amount_is_estimate": "Ստացվող գումարը մոտավոր է",
+  "amount_is_guaranteed": "Ստացվող գումարը երաշխավորված է",
+  "and": "և",
+  "anonpay_description": "${type} ստեղծել: Ստացողը կարող է ${method} ցանկացած աջակցվող կրիպտոարժույթով, և դուք կստանաք միջոցներ այս դրամապանակում։",
+  "apk_update": "APK թարմացում",
+  "approve": "Հաստատել",
+  "arrive_in_this_address": "${currency} ${tag}կժամանի այս հասցեում",
+  "ascending": "Աճող",
+  "ask_each_time": "Հարցնել ամեն անգամ",
+  "auth_store_ban_timeout": "արգելափակման ժամանակ",
+  "auth_store_banned_for": "Արգելափակված է ",
+  "auth_store_banned_minutes": " րոպե",
+  "auth_store_incorrect_password": "Սխալ PIN",
+  "authenticated": "Վավերացված",
+  "authentication": "Վավերացում",
+  "auto_generate_addresses": "Ավտոմատ հասցեներ ստեղծել",
+  "auto_generate_subaddresses": "Ավտոմատ ենթահասցեներ ստեղծել",
+  "automatic": "Ավտոմատ",
+  "available_balance": "Հասանելի մնացորդ",
+  "available_balance_description": "«Հասանելի մնացորդ» կամ «Հաստատված մնացորդ»-ը միջոցներ են, որոնք կարող են անմիջապես ծախսվել։ Եթե միջոցները հայտնվում են ստորին մնացորդում, բայց ոչ վերևի մնացորդում, ապա դուք պետք է մի քանի րոպե սպասեք, մինչև ներգաղթող միջոցները ավելի ցանցի հաստատումներ ստանան։ Հաստատումներ ստանալուց հետո դրանք կարող են ծախսվել։",
+  "avg_savings": "Միջին խնայողություն",
+  "awaitDAppProcessing": "Խնդրեմ սպասեք, մինչև դիմումը կավարտի մշակումը։",
+  "awaiting_payment_confirmation": "Վճարման հաստատման սպասում",
+  "background_sync_mode": "Հետին պլանի համաժամացման ռեժիմ",
+  "backup": "Կրկնօրինակ",
+  "backup_file": "Կրկնօրինակի ֆայլ",
+  "backup_password": "Կրկնօրինակի գաղտնաբառ",
+  "balance": "Հաշվեկշիռ",
+  "balance_page": "Հաշվեկշռի էջ",
+  "bill_amount": "Հաշիվը",
+  "billing_address_info": "Եթե խնդրեն հաշվեվճարի հասցե, ապա տրամադրեք ձեր առաքման հասցեն",
+  "biometric_auth_reason": "Սկանավեք ձեր մատնահետքը նույնականացման համար",
+  "bitcoin_dark_theme": "Bitcoin մութ տեսք",
+  "bitcoin_light_theme": "Bitcoin պայծառ տեսք",
+  "bitcoin_payments_require_1_confirmation": "Bitcoin վճարումները պահանջում են 1 հաստատում, որը կարող է տևել 20 րոպե կամ ավելի: Շնորհակալություն ձեր համբերության համար: Դուք էլ. նամակ կստանաք, երբ վճարումը հաստատվի։",
+  "block_remaining": "1 Բլոկ է մնացել",
+  "Blocks_remaining": "${status} Բլոկ է մնացել",
+  "bluetooth": "Bluetooth",
+  "bright_theme": "Պայծառ",
+  "bump_fee": "Բարձրացնել միջնորդավճարը",
+  "buy": "Գնել",
+  "buy_alert_content": "Այժմ մենք աջակցում ենք միայն Bitcoin, Ethereum, Litecoin և Monero արժույթների գնմանը: Խնդրում ենք ստեղծել կամ վերածանցել Bitcoin, Ethereum, Litecoin կամ Monero արժույթների հաշիվը։",
+  "buy_bitcoin": "Գնել Bitcoin",
+  "buy_now": "Գնել հիմա",
+  "buy_provider_unavailable": "Տվյալ պահին մատակարարը անհասանելի է։",
+  "buy_with": "Գնել",
+  "by_cake_pay": "Cake Pay-ով",
+  "cake_2fa_preset": "Cake 2FA նախապես կանխորոշված",
+  "cake_dark_theme": "Cake մութ տեսք",
+  "cake_pay_account_note": "Գրանցվեք միայն էլ. փոստի միջոցով, որպեսզի տեսնեք և գնեք քարտեր: Որոշ քարտեր հասանելի են նույնիսկ զեղչով:",
+  "cake_pay_learn_more": "Վայրկյանապես գնեք և փոխանակեք նվեր քարտերը հավելվածում:\nՍահեցրեք ձախից աջ՝ ավելին իմանալու համար:",
+  "cake_pay_save_order": "Քարտը պետք է ուղարկված լինի ձեր էլ. փոստին 1 աշխատանքային օրվա ընթացքում \n Պահպանեք Ձեր պատվերի համարը՝",
+  "cake_pay_subtitle": "Գնեք համաշխարհային նախավճարային քարտեր և նվեր քարտեր",
+  "cake_pay_web_cards_subtitle": "Գնեք համաշխարհային նախավճարային քարտեր և նվեր քարտեր",
+  "cake_pay_web_cards_title": "Cake Pay Վեբ Քարտեր",
+  "cake_wallet": "Cake Գաղտնապահոց",
+  "cakepay_prepaid_card": "CakePay Նախավճարային Դեբետային Քարտ",
+  "camera_consent": "Ձեր տեսախցիկը կօգտագործվի ${provider}-ի կողմից ինքնությունը հաստատելու նպատակով: Խնդրում ենք ծանոթանալ նրանց Գաղտնիության Քաղաքականության հետ:",
+  "camera_permission_is_required": "Տեսախցիկի թույլտվություն է պահանջվում: \nԽնդրում ենք այն ակտիվացնել հավելվածի կարգավորումներից:",
+  "cancel": "Չեղարկել",
+  "card_address": "Հասցե։",
+  "cardholder_agreement": "Քարտապանի Պայմանագիր",
+  "cards": "Քարտեր",
+  "chains": "Շղթաներ",
+  "change": "Փոփոխել",
+  "change_backup_password_alert": "Ձեր նախորդ կրկնօրինակ ֆայլերը չեն հասանելի լինի ներմուծել նոր կրկնօրինակի գաղտնաբառով: Նոր կրկնօրինակի գաղտնաբառը կօգտագործվի միայն նոր կրկնօրինակ ֆայլերի համար: Վստահ եք, որ ցանկանում եք փոխել կրկնօրինակի գաղտնաբառը?",
+  "change_currency": "Փոխել արժույթը",
+  "change_current_node": "Վստահ եք, որ ցանկանում եք փոխել ընթացիկ հանգույցը ${node}?",
+  "change_current_node_title": "Փոխել ընթացիկ հանգույցը",
+  "change_exchange_provider": "Փոխել փոխանակման մատակարարին",
+  "change_language": "Փոխել լեզուն",
+  "change_language_to": "Փոխել լեզուն ${language}?",
+  "change_password": "Փոխել գաղտնաբառը",
+  "change_rep": "Փոխել ներկայացուցչին",
+  "change_rep_message": "Վստահ եք, որ ցանկանում եք փոխել ներկայացուցիչներին?",
+  "change_rep_successful": "Ներկայացուցչի փոփոխությունը հաջողությամբ կատարվեց",
+  "change_wallet_alert_content": "Ցանկանում եք փոխել ընթացիկ դրամապանակը ${wallet_name}?",
+  "change_wallet_alert_title": "Փոխել ընթացիկ դրամապանակը",
+  "choose_account": "Ընտրեք հաշիվը",
+  "choose_address": "\n\nԽնդրում ենք ընտրեք հասցեն",
+  "choose_card_value": "Ընտրեք քարտի արժեք",
+  "choose_derivation": "Ընտրեք դրամապանակի ածանցում",
+  "choose_from_available_options": "Ընտրեք առկա տարբերակներից",
+  "choose_one": "Ընտրեք մեկը",
+  "choose_relay": "Խնդրում ենք ընտրեք փոխանցման կետ",
+  "choose_wallet_currency": "Խնդրում ենք ընտրեք դրամապանակի արժույթը",
+  "clear": "Մաքրել",
+  "clearnet_link": "Բաց ցանցի հղում",
+  "close": "Փակել",
+  "coin_control": "Մետաղադրամի վերահսկում (ըստ ցանկության)",
+  "cold_or_recover_wallet": "Ավելացնել սառը դրամապանակ կամ վերականգնել թղթային դրամապանակ",
+  "color_theme": "Գույների տեսք",
+  "commit_transaction_amount_fee": "Հաստատել գործարքը\nՍկզբնական գումար. ${amount}\nՄիջնորդավճար. ${fee}",
+  "confirm": "Հաստատել",
+  "confirm_delete_template": "Այս գործողությունը կջնջի այս ձևանմուշը: Ցանկանու՞մ եք շարունակել։",
+  "confirm_delete_wallet": "Այս գործողությունը կջնջի այս դրամապանակը: Ցանկանու՞մ եք շարունակել։",
+  "confirm_fee_deduction": "Հաստատեք միջնորդավճար հանումը",
+  "confirm_fee_deduction_content": "Դուք համաձայն եք միջնորդավճար հանել արդյունքից?",
+  "confirm_sending": "Հաստատեք ուղարկումը",
+  "confirm_silent_payments_switch_node": "Ձեր ընթացիկ հանգույցը չի աջակցում Լուռ վճարումներին\nCake Wallet-ը կանցնի համատեղելի հանգույց, միայն սկանավորման համար",
+  "confirmations": "Հաստատումներ",
+  "confirmed": "Հաստատված մնացորդ",
+  "confirmed_tx": "Հաստատված",
+  "congratulations": "Շնորհավորանք!",
+  "connect_an_existing_yat": "Միացրեք գոյություն ունեցող Yat-ը",
+  "connect_yats": "Միացրեք Yat-ները",
+  "connect_your_hardware_wallet": "Միացրեք ձեր ապարատային դրամապանակը Bluetooth-ի կամ USB-ի միջոցով",
+  "connect_your_hardware_wallet_ios": "Միացրեք ձեր ապարատային դրամապանակը Bluetooth-ի միջոցով",
+  "connection_sync": "Կապ և սինխրոնիզացիա",
+  "connectWalletPrompt": "Միացրեք ձեր դրամապանակը WalletConnect-ի միջոցով գործարքներ կատարելու համար",
+  "contact": "Կոնտակտ",
+  "contact_list_contacts": "Կոնտակտներ",
+  "contact_list_wallets": "Իմ դրամապանակներ",
+  "contact_name": "Կոնտակտի անուն",
+  "contact_support": "Հետադարձ կապ",
+  "continue_text": "Շարունակել",
+  "contractName": "Գործարքի անուն",
+  "contractSymbol": "Գործարքի Նշան",
+  "copied_key_to_clipboard": "${key} պատճենված է տեքստի բուֆերում",
+  "copied_to_clipboard": "Պատճենված է տեքստի բուֆերում",
+  "copy": "Պատճենել",
+  "copy_address": "Պատճենել հասցեն",
+  "copy_id": "Պատճենել ID",
+  "copyWalletConnectLink": "Պատճենել WalletConnect հղումը dApp-ից և տեղադրել այստեղ",
+  "countries": "Երկրներ",
+  "create_account": "Ստեղծել հաշիվ",
+  "create_backup": "Ստեղծել կրկնօրինակ",
+  "create_donation_link": "Ստեղծել նվիրատվության հղում",
+  "create_invoice": "Ստեղծել հաշիվ-ապրանքագիր",
+  "create_new": "Ստեղծել նոր դրամապանակ",
+  "create_new_account": "Ստեղծել նոր հաշիվ",
+  "creating_new_wallet": "Նոր դրամապանակ ստեղծվում է",
+  "creating_new_wallet_error": "Սխալ: ${description}",
+  "creation_date": "Ստեղծման ամսաթիվ",
+  "custom": "Պատվերով",
+  "custom_drag": "Պատվերով (Պահել և Գցել)",
+  "custom_redeem_amount": "Պատվերով Փրկագնման Գումար",
+  "custom_value": "Պատվերով Արժեք",
+  "dark_theme": "Մութ",
+  "debit_card": "Դեբետային քարտ",
+  "debit_card_terms": "Ձեր վճարային քարտի համարի (և ձեր վճարային քարտի համարի համապատասխան վկայականներ) պահպանումն ու օգտագործումը այս թվային դրամապանակում ենթակա են վճարային քարտ թողարկող կողմի գործող պայմանների և պայմանագրի",
+  "decimal_places_error": "Խմբակային տեղերի սխալ",
+  "decimals_cannot_be_zero": "Խմբակային տեղերը չեն կարող լինել զրո",
+  "default_buy_provider": "Լռելյայն գնման մատակարար",
+  "default_sell_provider": "Լռելյայն վաճառքի մատակարար",
+  "delete": "Ջնջել",
+  "delete_account": "Ջնջել հաշիվը",
+  "delete_wallet": "Ջնջել դրամապանակը",
+  "delete_wallet_confirm_message": "Դուք վստահ եք, որ ուզում եք ջնջել ${wallet_name} դրամապանակը?",
+  "deleteConnectionConfirmationPrompt": "Դուք վստահ եք, որ ուզում եք ջնջել կապը",
+  "denominations": "Անվանակարգեր",
+  "descending": "Նվազող",
+  "description": "Նկարագրություն",
+  "destination_tag": "Նպատակակետի պիտակ:",
+  "dfx_option_description": "Գնեք կրիպտոարժույթ EUR և CHF: Կորպորատիվ և մանրածախ հաճախորդների համար Եվրոպայում",
+  "didnt_get_code": "Չեք ստացել կոդը?",
+  "digit_pin": "-նիշ ՊԻՆ",
+  "digital_and_physical_card": " թվային և ֆիզիկական նախավճարային դեբետային քարտ",
+  "disable": "Անջատել",
+  "disable_bulletin": "Անջատել ծառայության վիճակի տեղեկագիրը",
+  "disable_buy": "Անջատել գնում գործողությունը",
+  "disable_cake_2fa": "Անջատել Cake 2FA",
+  "disable_exchange": "Անջատել փոխանակումը",
+  "disable_fiat": "Անջատել ֆիատ",
+  "disable_sell": "Անջատել վաճառք գործողությունը",
+  "disableBatteryOptimization": "Անջատել մարտկոցի օպտիմիզացիան",
+  "disableBatteryOptimizationDescription": "Դուք ցանկանում եք անջատել մարտկոցի օպտիմիզացիան ֆոնային համաժամացման ավելի ազատ և հարթ ընթացքի համար?",
+  "disabled": "Անջատված",
+  "discount": "Խնայեք ${value}%",
+  "display_settings": "Ցուցադրման կարգավորումներ",
+  "displayable": "Ցուցադրվող",
+  "do_not_have_enough_gas_asset": "Դուք չունեք բավարար ${currency} տրանզակցիան կատարելու համար ընթացիկ բլոկչեյն ցանցի պայմաններում: Դուք պետք է ունենաք ավելի շատ ${currency} blockchain ցանցի միջնորդավճարները վճարելու համար, նույնիսկ եթե դուք այլ ակտիվ եք ուղարկում:",
+  "do_not_send": "Մի ուղարկեք",
+  "do_not_share_warning_text": "Մի կիսեք այս տեղեկատվությունը որևէ մեկի հետ, այդ թվում նաև աջակցության հետ: \n\nՁեր միջոցները կարող են գողանալ կորցնել!",
+  "do_not_show_me": "Մի ցուցադրեք ինձ նորից",
+  "domain_looks_up": "Դոմեյնի որոնում",
+  "donation_link_details": "Նվիրատվության հղումի մանրամասներ",
+  "e_sign_consent": "Էլեկտրոնային ստորագրության համաձայնություն",
+  "edit": "Խմբագրել",
+  "edit_backup_password": "Փոփոխել Կրկնօրինակի Գաղտնաբառը",
+  "edit_node": "Փոփոխել հանգույց",
+  "edit_token": "Փոփոխել տոկեն",
+  "electrum_address_disclaimer": "Մենք ստեղծում ենք նոր հասցե ամեն անգամ, երբ դուք օգտագործում եք այն, բայց նախորդ հասցեները շարունակում են աշխատել",
+  "email_address": "Էլ. փոստի հասցե",
+  "enable_replace_by_fee": "Միացնել փոխարինումը միջնորդավճարով",
+  "enable_silent_payments_scanning": "Միացնել Լուռ Վճարումների սկանավորումը",
+  "enabled": "Միացված",
+  "enter_amount": "Մուտքագրեք գումար",
+  "enter_backup_password": "Մուտքագրեք կրկնօրինակի գաղտնաբառը",
+  "enter_code": "Մուտքագրեք կոդը",
+  "enter_seed_phrase": "Մուտքագրեք սերմի արտահայտությունը",
+  "enter_totp_code": "Մուտքագրեք TOTP կոդը",
+  "enter_wallet_password": "Մուտքագրեք դրամապանակի գաղտնաբառը",
+  "enter_your_note": "Մուտքագրեք ձեր նշումը…",
+  "enter_your_pin": "Մուտքագրեք ձեր PIN-ը",
+  "enter_your_pin_again": "Մուտքագրեք ձեր PIN-ը կրկին",
+  "enterTokenID": "Մուտքագրեք Token ID֊ն",
+  "enterWalletConnectURI": "Մուտքագրեք WalletConnect URI",
+  "error": "Սխալ",
+  "error_dialog_content": "Օպս, մենք սխալ ենք ստացել: \n\nԽնդրում ենք ուղարկել սխալի հաշվետվությունը մեր աջակցության թիմին ծրագիրը բարելավելու համար:",
+  "error_text_account_name": "Հաշվի անունը կարող է պարունակել միայն տառեր և թվեր և պետք է լինի 1-15 նիշ",
+  "error_text_address": "Դրամապանակի հասցեն պետք է համապատասխանի կրիպտոարժույթի տեսակին",
+  "error_text_amount": "Գումարը կարող է պարունակել միայն թվեր",
+  "error_text_contact_name": "Կոնտակտի անունը չի կարող պարունակել ` , '' \" սիմվոլներ և պետք է լինի 1-32 նիշ",
+  "error_text_crypto_currency": "Կոտորակային մասը պետք է լինի 12 նիշից ցածր կամ հավասար",
+  "error_text_fiat": "Գումարը չի կարող գերազանցել մնացորդը: Կոտորակային մասը պետք է լինի 2 նիշից ցածր կամ հավասար",
+  "error_text_input_above_maximum_limit": "Գումարը ավելի է, քան առավելագույնը",
+  "error_text_input_below_minimum_limit": "Գումարը ցածր է, քան նվազագույնը",
+  "error_text_keys": "Դրամապանակի բանալիները կարող են պարունակել միայն 64 նիշ հեքսային կոդով",
+  "error_text_limits_loading_failed": "Առևտրի համար ${provider} չի ստեղծվել: Սահմանների բեռնում ձախողվել է",
+  "error_text_maximum_limit": "Առևտրի համար ${provider} չի ստեղծվել: Գումարը ավելի է, քան առավելագույն ${max} ${currency}",
+  "error_text_minimal_limit": "Առևտրի համար ${provider} չի ստեղծվել: Գումարը ցածր է, քան նվազագույն ${min} ${currency}",
+  "error_text_node_address": "Խնդրում ենք մուտքագրել iPv4 հասցե",
+  "error_text_node_port": "Հանգույցի պորտը կարող է պարունակել միայն թվեր 0-65535 միջակայքում",
+  "error_text_node_proxy_address": "Խնդրում ենք մուտքագրել <IPv4 հասցե>:<պորտ>, օրինակ 127.0.0.1:9050",
+  "error_text_payment_id": "Վճարման ID-ն կարող է պարունակել 16-64 նիշ հեքսային կոդով",
+  "error_text_subaddress_name": "Ենթահասցեի անունը չի կարող պարունակել , '' \" նշանները\nև պետք է լինի 1-ից 20 նիշ երկարությամբ",
+  "error_text_template": "Տեսակի անունը և հասցեն չեն կարող պարունակել , '' \" նշանները\nև պետք է լինի 1-ից 106 նիշ երկարությամբ",
+  "error_text_wallet_name": "Գաղտնաբառը կարող է պարունակել միայն տառեր, թվեր, _ - նշաններ\nև պետք է լինի 1-ից 33 նիշ երկարությամբ",
+  "error_text_xmr": "XMR արժեքը չի կարող գերազանցել հասանելի մնացորդը:\nԿոտորակային թվերի քանակը պետք է լինի 12-ից պակաս կամ հավասար",
+  "errorGettingCredentials": "Սխալ. ծանրաբեռնված վստահագրեր ստանալիս",
+  "errorSigningTransaction": "Սխալ է տեղի ունեցել գործարքը ստորագրելիս",
+  "estimated": "Գնահատված",
+  "estimated_new_fee": "Գնահատված նոր միջնորդավճար",
+  "estimated_receive_amount": "Գնահատված ստացված գումար",
+  "etherscan_history": "Etherscan պատմություն",
+  "event": "Իրադարձություն",
+  "events": "Իրադարձություններ",
+  "exchange": "Փոխել",
+  "exchange_incorrect_current_wallet_for_xmr": "Եթե դուք ցանկանում եք փոխանակել XMR ձեր Cake Wallet Monero հաշվեհամարից, խնդրում ենք անցնել ձեր Monero հաշվեհամարին",
+  "exchange_new_template": "Նոր տեսակ",
+  "exchange_provider_unsupported": "${providerName} այլևս չի ապահովվում",
+  "exchange_result_confirm": "Սեղմելով հաստատել, դուք կուղարկեք ${fetchingLabel} ${from} ձեր հաշվեհամարից ${walletName} հետևյալ հասցեին: Կամ կարող եք ուղարկել ձեր արտաքին հաշվեհամարից հետևյալ հասցեին/QR կոդին:\n\nԽնդրում ենք սեղմել հաստատել կամ վերադառնալ գումարը փոխելու համար",
+  "exchange_result_description": "Դուք պետք է ուղարկեք նվազագույնը ${fetchingLabel} ${from} հետևյալ էջում ցուցադրված հասցեին: Եթե դուք ուղարկում եք ավելի ցածր գումար, քան ${fetchingLabel} ${from} այն կարող է չփոխանակվել և չվերադարձվել",
+  "exchange_result_write_down_ID": "*Խնդրում ենք պատճենել կամ գրել ձեր ID-ն վերևում",
+  "exchange_result_write_down_trade_id": "Խնդրում ենք պատճենել կամ գրել առևտրի ID-ն շարունակելու համար",
+  "exchange_sync_alert_content": "Խնդրում ենք սպասել մինչև ձեր հաշվեհամարը համաժամացվի",
+  "expired": "Վավերականությունը լրացել է",
+  "expires": "Վավերականությունը լրանում է",
+  "expiresOn": "Վավերականությունը լրանում է",
+  "expiry_and_validity": "Վավերականություն և լրացում",
+  "export_backup": "Արտահանել կրկնօրինակը",
+  "extra_id": "Լրացուցիչ ID",
+  "extracted_address_content": "Դուք կուղարկեք գումար ${recipient_name}",
+  "failed_authentication": "Վավերացումը ձախողվեց. ${state_error}",
+  "faq": "Հաճախ տրվող հարցեր",
+  "features": "Հատկանիշներ",
+  "fetching": "Ստացվում է",
+  "fiat_api": "Fiat API",
+  "fiat_balance": "Fiat մնացորդ",
+  "field_required": "Այս դաշտը պարտադիր է",
+  "fill_code": "Խնդրում ենք լրացնել հաստատման կոդը ձեր էլեկտրոնային փոստում",
+  "filter_by": "Ֆիլտրել ըստ",
+  "first_wallet_text": "Հիանալի հաշվեհամար Monero, Bitcoin, Ethereum, Litecoin և Haven արժույթների համար",
+  "fixed_pair_not_supported": "Այս ֆիքսված զույգը չի ապահովվում ընտրված փոխանակման կետերում",
+  "fixed_rate": "Ֆիքսված փոխարժեք",
+  "fixed_rate_alert": "Դուք կկարողանաք մուտքագրել ստացվող գումարը, երբ ֆիքսված փոխարժեքի ռեժիմը միացված է: Դուք ցանկանում եք անցնել ֆիքսված փոխարժեքի ռեժիմին?",
+  "forgot_password": "Մոռացել եմ գաղտնաբառը",
+  "freeze": "Կասեցնել",
+  "frequently_asked_questions": "Հաճախ տրվող հարցեր",
+  "frozen": "Կասեցված",
+  "full_balance": "Լրիվ մնացորդ",
+  "generate_name": "Գեներացնել անուն",
+  "generating_gift_card": "Գեներացնում է նվեր քարտ",
+  "get_a": "Ստանալ ",
+  "get_card_note": " որը կարող եք լրացնել թվային արժույթներով: Հավելյալ տեղեկատվություն պետք չէ!",
+  "get_your_yat": "Ստանալ ձեր Yat",
+  "gift_card_amount": "Նվեր քարտի չափ",
+  "gift_card_balance_note": "Նվեր քարտերը մնացորդով կհայտնվեն այստեղ",
+  "gift_card_is_generated": "Նվեր քարտ գեներացված է",
+  "gift_card_number": "Նվեր քարտի համար",
+  "gift_card_redeemed_note": "Նվեր քարտերը, որ դուք գնել եք, կհայտնվեն այստեղ",
+  "gift_cards": "Նվեր քարտեր",
+  "gift_cards_unavailable": "Նվեր քարտերը հասանելի են միայն Monero, Bitcoin և Litecoin արժույթների համար",
+  "got_it": "Հասկացա",
+  "gross_balance": "Ընդհանուր մնացորդ",
+  "group_by_type": "Խմբավորել ըստ տեսակի",
+  "haven_app": "Haven ծրագիր",
+  "haven_app_wallet_text": "Հիանալի հաշվեհամար Haven համար",
+  "help": "Օգնություն",
+  "hidden_balance": "Թաքնված մնացորդ",
+  "hide_details": "Թաքցնել մանրամասները",
+  "high_contrast_theme": "Բարձր հակադրության տեսք",
+  "home_screen_settings": "Գլխավոր էկրանի կարգավորումներ",
+  "how_to_use": "Ինչպես օգտագործել",
+  "how_to_use_card": "Ինչպես օգտագործել այս քարտը",
+  "id": "ID: ",
+  "ignor": "Անտեսել",
+  "import": "Ներմուծել",
+  "importNFTs": "Ներմուծել NFT-ներ",
+  "in_store": "Տեղում",
+  "incoming": "Մուտքային",
+  "incorrect_seed": "Տեքստը սխալ է",
+  "inputs": "Մուտքեր",
+  "insufficient_lamport_for_tx": "Դուք չունեք բավարար SOL՝ գործարքն և գործարքի վարձը ծածկելու համար։ Խնդրում ենք ավելացնել ավելի շատ SOL ձեր դրամապանակում կամ նվազեցնել ուղարկվող SOL-ի քանակը։",
+  "insufficient_lamports": "Դուք չունեք բավարար SOL՝ գործարքն և գործարքի վարձը ծածկելու համար։ Ձեզ անհրաժեշտ է առնվազն ${solValueNeeded} SOL։ Խնդրում ենք ավելացնել ավելի շատ SOL ձեր դրամապանակում կամ նվազեցնել ուղարկվող SOL-ի քանակը։",
+  "insufficientFundsForRentError": "Ձեր մնացորդը բավարար չէ վարձակալության համար: Խնդրում ենք ավելացնել մնացորդը կամ նվազեցնել ուղարկվող գումարը",
+  "introducing_cake_pay": "Ներկայացնում ենք Cake Pay!",
+  "invalid_input": "Սխալ մուտք",
+  "invalid_password": "Սխալ գաղտնաբառ",
+  "invoice_details": "Հաշիվ-ապրանքագրի մանրամասներ",
+  "is_percentage": "կազմում է",
+  "last_30_days": "Վերջին 30 օրը",
+  "learn_more": "Տեղեկանալ ավելին",
+  "ledger_connection_error": "Չկարողացանք կապ հաստատել Ledger-ի հետ: Խնդրում ենք փորձել նորից",
+  "ledger_error_device_locked": "Ledger-ը արգելափակված է",
+  "ledger_error_tx_rejected_by_user": "Գործարքը մերժված է օգտատերի կողմից",
+  "ledger_error_wrong_app": "Խնդրում ենք համոզվել, որ դուք բացել եք ճիշտ ծրագիրը ձեր Ledger-ում",
+  "ledger_please_enable_bluetooth": "Խնդրում ենք միացնել Bluetooth-ը ձեր Ledger-ը հայտնաբերելու համար",
+  "light_theme": "Լուսավոր",
+  "load_more": "Բեռնել ավելին",
+  "loading_your_wallet": "Ձեր հաշվեհամարը բեռնում է",
+  "login": "Մուտք",
+  "logout": "Ելք",
+  "low_fee": "Ցածր միջնորդավճար",
+  "low_fee_alert": "Դուք ներկայումս օգտագործում եք ցածր ցանցային միջնորդավճար: Սա կարող է հանգեցնել երկար սպասելու ժամանակի, տարբեր փոխարժեքների կամ չեղարկված առևտրի: Մենք առաջարկում ենք սահմանել ավելի բարձր միջնորդավճար ավելի լավ փորձ ունենալու համար",
+  "manage_nodes": "Կարգավորել հանգույցները",
+  "manage_pow_nodes": "Կարգավորել PoW հանգույցները",
+  "manage_yats": "Կառավարել Yats",
+  "mark_as_redeemed": "Նշել որպես մարված",
+  "market_place": "Շուկա",
+  "matrix_green_dark_theme": "Matrix Կանաչ Մութ տեսք",
+  "max_amount": "Առավելագույն գումար: ${value}",
+  "max_value": "Առավելագույն արժեք: ${value} ${currency}",
+  "memo": "Մեմո:",
+  "message": "Հաղորդագրություն",
+  "message_verified": "Հաղորդագրությունը հաջողությամբ հաստատվեց",
+  "methods": "Մեթոդներ",
+  "min_amount": "Նվազը: ${value}",
+  "min_value": "Նվազը: ${value} ${currency}",
+  "minutes_to_pin_code": "${minute} րոպե",
+  "mm": "ԱԱ",
+  "modify_2fa": "Փոփոխել Cake 2FA",
+  "monero_com": "Monero.com by Cake Wallet",
+  "monero_com_wallet_text": "Անհավանական դրամապանակ Monero-ի համար",
+  "monero_dark_theme": "Monero մութ տեսք",
+  "monero_light_theme": "Monero պայծառ տեսք",
+  "moonpay_alert_text": "Գումարի արժեքը պետք է լինի հավասար կամ ավելի քան ${minAmount} ${fiatCurrency}",
+  "more_options": "Այլ տարբերակներ",
+  "name": "Անուն",
+  "nano_current_rep": "Ընթացիկ ներկայացուցիչ",
+  "nano_gpt_thanks_message": "Շնորհակալություն NanoGPT-ն օգտագործելու համար: Հիշեք վերադառնալ դիտարկիչ ձեր փոխանցումն ավարտելուց հետո",
+  "nano_pick_new_rep": "Ընտրեք նոր ներկայացուցիչ",
+  "nanogpt_subtitle": "Բոլոր ամենանոր մոդելներ (GPT-4, Claude).\\nԱռանց բաժանորդագրության, վճարեք կրիպտոարժույթով",
+  "narrow": "Նեղ",
+  "new_first_wallet_text": "Ինչպես պահել ձեր կրիպտոգրաֆիան անվտանգ, կարկանդակ",
+  "new_node_testing": "Նոր հանգույցի փորձարկում",
+  "new_subaddress_create": "Ստեղծել",
+  "new_subaddress_label_name": "Պիտակի անուն",
+  "new_subaddress_title": "Նոր հասցե",
+  "new_template": "Նոր նմուշ",
+  "new_wallet": "Նոր դրամապանակ",
+  "newConnection": "Նոր կապ",
+  "no_cards_found": "Ոչ մի քարտ չի գտնվել",
+  "no_id_needed": "Ոչ մի փաստաթուղթ չի պահանջվում!",
+  "no_id_required": "Ոչ մի փաստաթուղթ չի պահանջվում։ Լրացրեք և ծախսեք ամենուր",
+  "no_relay_on_domain": "Տիրույթի համար ընդունող չկա կամ անհասանելի է։ Խնդրում ենք ընտրել ընդունող",
+  "no_relays": "Ընդունողներ չկան",
+  "no_relays_message": "Մենք գտել ենք Nostr NIP-05 գրառում այս օգտատիրոջ համար, բայց այն չի պարունակում ոչ մի ընդունող։ Խնդրում ենք հրահանգել ստացողին ավելացնել ընդունողներ իր Nostr գրառման մեջ",
+  "node_address": "Հանգույցի հասցե",
+  "node_connection_failed": "Հանգույցի միացումը ձախողվեց",
+  "node_connection_successful": "Հանգույցի միացումը հաջող է",
+  "node_new": "Նոր հանգույց",
+  "node_port": "Հանգույցի պորտ",
+  "node_reset_settings_title": "Հանգույցի կարգավորումների վերակայում",
+  "node_test": "Փորձարկում",
+  "nodes": "Հանգույցներ",
+  "nodes_list_reset_to_default_message": "Վերակայվում եք կարգավորումները լռությամբ?",
+  "none_of_selected_providers_can_exchange": "Ոչ մի ընտրված մատակարար չի կարող այս փոխանակումը կատարել",
+  "noNFTYet": "Դեռ ոչ մի NFT",
+  "normal": "Նորմալ",
+  "note_optional": "Նշում (ոչ պարտադիր)",
+  "note_tap_to_change": "Նշում (սեղմեք փոխելու համար)",
+  "nullURIError": "URI-ն դատարկ է",
+  "offer_expires_in": "Առաջարկը վաղեմության է հասնում ",
+  "offline": "Անցանց",
+  "ok": "Լավ",
+  "old_fee": "Հին վճար",
+  "onion_link": "Onion հղում",
+  "online": "Առցանց",
+  "onramper_option_description": "Արագ գնեք կրիպտոցուլեր շատ վճարման մեթոդներով։ Հասանելի է մեծ մասամբ երկրներում։ Տարածված և վճարները փոփոխվում են",
+  "open_gift_card": "Բացեք նվեր քարտ",
+  "optional_description": "Ոչ պարտադիր նկարագրություն",
+  "optional_email_hint": "Ոչ պարտադիր վճարողի ծանուցման էլեկտրոնային փոստ",
+  "optional_name": "Ոչ պարտադիր ստացողի անուն",
+  "optionally_order_card": "Ոչ պարտադիր պատվեր ֆիզիկական քարտ",
+  "orbot_running_alert": "Խնդրում ենք համոզվել, որ Orbot-ը աշխատում է այս հանգույցին միանալուց առաջ",
+  "order_by": "Պատվեր ըստ",
+  "order_id": "Պատվերի հերթական համար",
+  "order_physical_card": "Պատվիրել ֆիզիկական քարտ",
+  "other_settings": "Այլ կարգավորումներ",
+  "outdated_electrum_wallet_description": "Cake-ում ստեղծված նոր Bitcoin դրամապանակները ներկայում 24 բառանոց սերմ ունեն։ Դուք պետք է ստեղծեք նոր Bitcoin դրամապանակ և տեղափոխեք բոլոր միջոցները նոր 24 բառանոց դրամապանակ, և դադարեցրեք օգտագործել 12 բառանոց դրամապանակներ",
+  "outdated_electrum_wallet_receive_warning": "Եթե այս դրամապանակը 12 բառանոց սերմ ունի և ստեղծվել է Cake-ում, Bitcoin մուծել այս դրամապանակ մի տեղափոխեք։ Որեւէ Bitcoin այս դրամապանակ տեղափոխվել կարող է կորած լինել։ Ստեղծեք նոր 24-բառանոց Bitcoin դրամապանակ (սեղմեք վերևի աջ մենյուն, ընտրեք Դրամապանակներ, ընտրեք Նոր Դրամապանակ, ապա ընտրեք Bitcoin) և տեղափոխեք ձեր ԲԻՏԿ-ն այնտեղ",
+  "outgoing": "Ելքային",
+  "outputs": "Ելքեր",
+  "overwrite_amount": "Գրեք գումարը",
+  "pairingInvalidEvent": "Սխալ միացում",
+  "passphrase": "Պարող արտահայտություն (Ոչ պարտադիր)",
+  "password": "Գաղտնաբառ",
+  "paste": "Տեղադրել",
+  "pause_wallet_creation": "Հնարավորություն ստեղծել Haven Դրամապանակ ընթացիկ դադարեցված է",
+  "payment_id": "Վճարման հերթական համար",
+  "payment_was_received": "Վճարումը ստացված է",
+  "pending": " (մշակվում է)",
+  "percentageOf": "${amount}-ի տոկոս",
+  "pin_at_top": "${token} պին վերևում",
+  "pin_is_incorrect": "Պին-կոդը սխալ է",
+  "pin_number": "Պին-կոդ",
+  "placeholder_contacts": "Ձեր կոնտակտները այստեղ կցուցադրվեն",
+  "placeholder_transactions": "Ձեր գործարքները այստեղ կցուցադրվեն",
+  "please_fill_totp": "Խնդրում ենք լրացնել 8-նիշյա կոդը, որը կա ձեր այլ սարքի վրա",
+  "please_make_selection": "Խնդրում ենք ընտրություն կատարել ներքևում ձեր դրամապանակը ստեղծելու կամ վերականգնելու համար",
+  "please_reference_document": "Խնդրում ենք դիտել ներքևի փաստաթղթերը ավելի շատ տեղեկատվության համար",
+  "please_select": "Խնդրում ենք ընտրել",
+  "please_select_backup_file": "Խնդրում ենք ընտրել կրկնօրինակի ֆայլը և մուտքագրել կրկնօրինակի գաղտնաբառը",
+  "please_try_to_connect_to_another_node": "Խնդրում ենք փորձել միանալ այլ հանգույցի",
+  "please_wait": "Խնդրում ենք սպասել",
+  "polygonscan_history": "PolygonScan պատմություն",
+  "powered_by": "${title} կողմից ապահովված",
+  "pre_seed_button_text": "Ես հասկանում եմ։ Ցույց տվեք իմ սերմը",
+  "pre_seed_description": "Հաջորդ էջում դուք կտեսնեք ${words} բառերի շարք։ Սա ձեր յուրահատուկ և գաղտնի սերմն է, որը ձեր դրամապանակը վերականգնելու միակ միջոցն է կորուստի կամ սխալ գործարքի դեպքում։ Դուք պատասխանատու եք այն գրառել և ապահով վայրում պահել Cake Wallet հավելվածից դուրս",
+  "pre_seed_title": "ԿԱՐԵՎՈՐ",
+  "prepaid_cards": "Նախավճարային քարտեր",
+  "prevent_screenshots": "Կանխել էկրանի պատկերները և տեսագրությունը",
+  "privacy": "Գաղտնիություն",
+  "privacy_policy": "Գաղտնիության քաղաքականություն",
+  "privacy_settings": "Գաղտնիության կարգավորումներ",
+  "private_key": "Գաղտնի բանալի",
+  "proceed_after_one_minute": "Եթե էկրանը 1 րոպեից ավել չի անցնում, ստուգեք ձեր էլեկտրոնային փոստը",
+  "proceed_on_device": "Շարունակեք ձեր սարքի վրա",
+  "proceed_on_device_description": "Խնդրում ենք հետևել ձեր սարքի վրա ցուցադրվող հրահանգներին",
+  "profile": "Պրոֆիլ",
+  "provider_error": "${provider} սխալ",
+  "public_key": "Հանրային բանալի",
+  "purchase_gift_card": "Նվեր քարտ գնել",
+  "purple_dark_theme": "Մանուշակագույն մութ տեսք",
+  "qr_fullscreen": "Սեղմեք այստեղ բացելու ամբողջ էկրանը QR կոդ",
+  "qr_payment_amount": "Այս QR կոդը պարունակում է վճարման գումար։ Ուզում եք թարմացնել ընթացիկ արժեքը?",
+  "quantity": "Քանակ",
+  "question_to_disable_2fa": "Դուք վստահ եք, որ ուզում եք անջատել Cake 2FA-ն? 2FA կոդը այլևս չի պահանջվի դրամապանակ մուտք գործելու և որոշ ֆունկցիաներ օգտագործելու համար",
+  "receivable_balance": "Ստացվող հաշվեկշիռ",
+  "receive": "Ստանալ",
+  "receive_amount": "Գումար",
+  "received": "Ստացված",
+  "recipient_address": "Ստացողի հասցե",
+  "reconnect": "Վերակապվել",
+  "reconnect_alert_text": "Դուք վստահ եք, որ ուզում եք վերակապվել?",
+  "reconnection": "Վերակապում",
+  "red_dark_theme": "Կարմիր մութ տեսք",
+  "red_light_theme": "Կարմիր պայծառ տեսք",
+  "redeemed": "Փոխանակված",
+  "refund_address": "Վերադարձի հասցե",
+  "reject": "Մերժել",
+  "remaining": "Մնացած",
+  "remove": "Հեռացնել",
+  "remove_node": "Հեռացնել հանգույց",
+  "remove_node_message": "Դուք վստահ եք, որ ուզում եք հեռացնել ընտրված հանգույցը?",
+  "rename": "Վերանվանել",
+  "rep_warning": "Ներկայացուցիչ նախազգուշացում",
+  "rep_warning_sub": "Ձեր ներկայացուցիչը չի հայտնվում լավ վիճակում։ Սեղմեք այստեղ նոր ներկայացուցիչ ընտրելու համար",
+  "repeat_wallet_password": "Վերականգնել դրամապանակի գաղտնաբառ",
+  "repeated_password_is_incorrect": "Վերականգնված գաղտնաբառը սխալ է։ Խնդրում ենք վերականգնել դրամապանակի գաղտնաբառը",
+  "require_for_adding_contacts": "Պահանջվում է կոնտակտներ ավելացնելու համար",
+  "require_for_all_security_and_backup_settings": "Պահանջվում է բոլոր անվտանգության և կրկնօրինակման կարգավորումների համար",
+  "require_for_assessing_wallet": "Պահանջվում է դրամապանակ մուտք գործելու համար",
+  "require_for_creating_new_wallets": "Պահանջվում է նոր դրամապանակներ ստեղծելու համար",
+  "require_for_exchanges_to_external_wallets": "Պահանջվում է արտաքին դրամապանակների հետ փոխանակության համար",
+  "require_for_exchanges_to_internal_wallets": "Պահանջվում է ներքին դրամապանակների հետ փոխանակության համար",
+  "require_for_sends_to_contacts": "Պահանջվում է կոնտակտներին ուղարկելու համար",
+  "require_for_sends_to_internal_wallets": "Պահանջվում է ներքին դրամապանակներ ուղարկելու համար",
+  "require_for_sends_to_non_contacts": "Պահանջվում է ոչ կոնտակտ անձանց ուղարկելու համար",
+  "require_pin_after": "Պահանջվում է PIN-ը հետո",
+  "rescan": "Վերասկանավորել",
+  "resend_code": "Խնդրում ենք կրկին ուղարկել",
+  "reset": "Վերասահմանել",
+  "reset_password": "Վերասահմանել գաղտնաբառը",
+  "restore_active_seed": "Ակտիվ սերմ",
+  "restore_address": "Հասցե",
+  "restore_bitcoin_description_from_keys": "Վերականգնեք ձեր դրամապանակը ձեր գախտնի բանալիներից ստացված WIF տողից",
+  "restore_bitcoin_description_from_seed": "Վերականգնեք ձեր դրամապանակը 24 բառերի համադրությամբ",
+  "restore_bitcoin_title_from_keys": "Վերականգնել WIF-ից",
+  "restore_description_from_backup": "Դուք կարող եք վերականգնել ամբողջ Cake Wallet հավելվածը ձեր կրկնօրինակ ֆայլից",
+  "restore_description_from_hardware_wallet": "Վերականգնեք Ledger հարդվերային դրամապանակից",
+  "restore_description_from_keys": "Վերականգնեք ձեր դրամապանակը ձեր գախտնի բանալիների հիման վրա ստեղծված մուտքագրումներից",
+  "restore_description_from_seed": "Վերականգնեք ձեր դրամապպանակը 25 բառերի կամ 13 բառերի համադրությամբ",
+  "restore_description_from_seed_keys": "Վերականգնեք ձեր դրամապանակը սերմից/բանալիներից, որը դուք պահպանել եք ապահով վայրում",
+  "restore_from_date_or_blockheight": "Խնդրում ենք մուտքագրել այն ամսաթիվը, երբ դուք ստեղծել եք այս դրամապանակը։ Կամ, եթե դուք գիտեք բլոկի բարձրությունը, խնդրում ենք մուտքագրել այն",
+  "restore_from_seed_placeholder": "Խնդրում ենք մուտքագրել կամ տեղադրել ձեր սերմը այստեղ",
+  "restore_new_seed": "Նոր սերմ",
+  "restore_next": "Հաջորդ",
+  "restore_recover": "Վերականգնել",
+  "restore_restore_wallet": "Վերականգնել դրամապանակ",
+  "restore_seed_keys_restore": "Սերմ/բանալիներ վերականգնել",
+  "restore_spend_key_private": "Վճարման բանալի (գախտնի)",
+  "restore_title_from_backup": "Վերականգնել կրկնօրինակ ֆայլից",
+  "restore_title_from_hardware_wallet": "Վերականգնել հարդվերային դրամապանակից",
+  "restore_title_from_keys": "Վերականգնել բանալիներից",
+  "restore_title_from_seed": "Վերականգնել սերմից",
+  "restore_title_from_seed_keys": "Վերականգնել սերմ/բանալիներից",
+  "restore_view_key_private": "Տեսողական բանալի (գախտնի)",
+  "restore_wallet": "Վերականգնել դրամապանակ",
+  "restore_wallet_name": "Դրամապանակի անվանում",
+  "restore_wallet_restore_description": "Դրամապանակի վերականգնման նկարագրություն",
+  "robinhood_option_description": "Գնեք և տեղափոխեք ակնթարթորեն ձեր դեբետային քարտով, բանկային հաշվով կամ Robinhood հաշվեկշռով։ Միայն ԱՄՆ-ում։",
+  "router_no_route": "Ոչ մի երթուղի չի սահմանված ${name}",
+  "save": "Պահպանել",
+  "save_backup_password": "Խնդրում ենք հաստատել, որ դուք պահպանել եք ձեր կրկնօրինակի գաղտնաբառը։ Դուք չեք կարող ներմուծել ձեր կրկնօրինակ ֆայլերը առանց դրա։",
+  "save_backup_password_alert": "Պահպանել կրկնօրինակի գաղտնաբառը",
+  "save_to_downloads": "Պահպանել ներբեռնումներում",
+  "saved_the_trade_id": "Ես պահպանել եմ առևտրի ID-ն",
+  "scan_one_block": "Սկանավորել մեկ բլոկ",
+  "scan_qr_code": "Սկանավորել QR կոդ",
+  "scan_qr_code_to_get_address": "Սկանավորել QR կոդը հասցեն ստանալու համար",
+  "scan_qr_on_device": "Սկանավորել այս QR կոդը այլ սարքի վրա",
+  "search": "Որոնել",
+  "search_add_token": "Որոնել / Ավելացնել token",
+  "search_category": "Որոնել կատեգորիա",
+  "search_currency": "Որոնել արժույթ",
+  "search_language": "Որոնել լեզու",
+  "second_intro_content": "Ձեր Yat-ը միակ եզակի էմոջի հասցե է, որը փոխարինում է ձեր բոլոր արժույթների համար ձեր բոլոր երկար հեքսադեցիմալ հասցեները",
+  "second_intro_title": "Մի էմոջի հասցե, որը կառավարում է դրանք բոլորը",
+  "security_and_backup": "Անվտանգություն և կրկնօրինակ",
+  "seed_alert_back": "Վերադառնալ",
+  "seed_alert_content": "Սերմը վերականգնելու ձեր դրամապանակի միակ միջոցն է։ Դուք արդեն գրի եք առել այն?",
+  "seed_alert_title": "Ուշադրություն",
+  "seed_alert_yes": "Այո, ես արդեն գրի եմ առել այն",
+  "seed_choose": "Ընտրել սերմի լեզուն",
+  "seed_hex_form": "Դրամապանակի սերմ (hex ֆորմատ)",
+  "seed_key": "Սերմի բանալի",
+  "seed_language": "Սերմի լեզու",
+  "seed_language_chinese": "Չինարեն",
+  "seed_language_chinese_traditional": "Չինարեն (ավանդական)",
+  "seed_language_czech": "Չեխերեն",
+  "seed_language_dutch": "Հոլանդերեն",
+  "seed_language_english": "Անգլերեն",
+  "seed_language_french": "Ֆրանսերեն",
+  "seed_language_german": "Գերմաներեն",
+  "seed_language_italian": "Իտալերեն",
+  "seed_language_japanese": "Ճապոներեն",
+  "seed_language_korean": "Կորեերեն",
+  "seed_language_next": "Հաջորդ",
+  "seed_language_portuguese": "Պորտուգալերեն",
+  "seed_language_russian": "Ռուսերեն",
+  "seed_language_spanish": "Իսպաներեն",
+  "seed_phrase_length": "Սերմի արտահայտության երկարություն",
+  "seed_reminder": "Խնդրում ենք գրի առնել այս տեղեկությունը, եթե դուք կորցնեք կամ ջնջեք ձեր հեռախոսը",
+  "seed_share": "Կիսվել սերմով",
+  "seed_title": "Սերմ",
+  "seedtype": "Սերմի տեսակ",
+  "seedtype_legacy": "Legacy (25 բառ)",
+  "seedtype_polyseed": "Polyseed (16 բառ)",
+  "seedtype_wownero": "Wownero (14 բառ)",
+  "select_backup_file": "Ընտրել կրկնօրինակ ֆայլ",
+  "select_buy_provider_notice": "Ընտրեք գնման մատակարարը վերևում։ Դուք կարող եք բաց թողնել այս էկրանը ձեր լռելայն գնման մատակարարը հավելվածի կարգավորումներում սահմանելով",
+  "select_destination": "Խնդրում ենք ընտրել կրկնօրինակ ֆայլի նպատակակետը",
+  "select_sell_provider_notice": "Ընտրեք վաճառքի մատակարարը վերևում։ Դուք կարող եք բաց թողնել այս էկրանը ձեր լռելայն վաճառքի մատակարարը հավելվածի կարգավորումներում սահմանելով",
+  "sell": "Ծախել",
+  "sell_alert_content": "Մենք ներկայումս պաշտպանում ենք միայն Bitcoin, Ethereum և Litecoin վաճառքը։ Խնդրում ենք ստեղծել կամ միացնել ձեր Bitcoin, Ethereum կամ Litecoin դրամապանակը",
+  "sell_monero_com_alert_content": "Monero-ի վաճառքը դեռ չի պաշտպանվում",
+  "send": "Ուղարկել",
+  "send_address": "${cryptoCurrency} հասցե",
+  "send_amount": "Քանակ՝",
+  "send_creating_transaction": "Ստեղծել գործարք",
+  "send_error_currency": "Արժույթը կարող է պարունակել միայն թվեր",
+  "send_error_minimum_value": "Քանակի նվազագույն արժեքը 0.01 է",
+  "send_estimated_fee": "Գնահատված վարձը՝",
+  "send_fee": "Վարձը՝",
+  "send_name": "Անվանում",
+  "send_new": "Նոր",
+  "send_payment_id": "Վճարման ID (կամավոր)",
+  "send_priority": "Ներկայումս վարձը սահմանված է ${transactionPriority} առաջնահերթությամբ։ Գործարքի առաջնահերթությունը կարող է կարգավորվել կարգավորումներում",
+  "send_sending": "Ուղարկվում է...",
+  "send_success": "Ձեր ${crypto}-ն հաջողությամբ ուղարկվել է",
+  "send_templates": "Տեղակալներ",
+  "send_title": "Ուղարկել",
+  "send_to_this_address": "Ուղարկել ${currency} ${tag} այս հասցեով",
+  "send_xmr": "Ուղարկել XMR",
+  "send_your_wallet": "Ձեր դրամապանակ",
+  "sending": "Ուղարկում",
+  "sent": "Ուղարկված",
+  "service_health_disabled": "Ծառայության առողջությունը անջատված է",
+  "service_health_disabled_message": "Սա ծառայության առողջության էջն է, դուք կարող եք այս էջը միացնել Կարգավորումներ -> Գաղտնիություն",
+  "settings": "Կարգավորումներ",
+  "settings_all": "Բոլորը",
+  "settings_allow_biometrical_authentication": "Թույլատրել կենսաչափական վավերացում",
+  "settings_can_be_changed_later": "Այս կարգավորումները կարող են փոխվել ավելի ուշ հավելվածի կարգավորումներում",
+  "settings_change_language": "Փոխել լեզուն",
+  "settings_change_pin": "Փոխել PIN-ը",
+  "settings_currency": "Արժույթ",
+  "settings_current_node": "Ներկայիս հանգույց",
+  "settings_dark_mode": "Մութ ռեժիմ",
+  "settings_display_balance": "Ցուցադրել հաշիվը",
+  "settings_display_on_dashboard_list": "Ցուցադրել վահանակի ցանկում",
+  "settings_fee_priority": "Վարձի առաջնահերթություն",
+  "settings_nodes": "Հանգույցներ",
+  "settings_none": "Ոչինչ",
+  "settings_only_trades": "Միայն առևտուր",
+  "settings_only_transactions": "Միայն փոխանցումներ",
+  "settings_personal": "Անձնական",
+  "settings_save_recipient_address": "Պահպանել ստացողի հասցե",
+  "settings_support": "Աջակցություն",
+  "settings_terms_and_conditions": "Պայմաններ և պայմանավորվածություններ",
+  "settings_title": "Կարգավորումներ",
+  "settings_trades": "Առևտուր",
+  "settings_transactions": "Փոխանցումներ",
+  "settings_wallets": "Դրամապանակներ",
+  "setup_2fa": "Հավատարմագրել 2FA",
+  "setup_2fa_text": "Cake 2FA-ն աշխատում է TOTP-ի հետ որպես երկրորդ հավատարմագրման գործոն։\n\nCake 2FA-ի TOTP-ը պահանջում է SHA-512 և 8 թվանշանների աջակցություն; դա ավելի մեծ անվտանգություն է ապահովում։ Ավելի շատ տեղեկություն և աջակցվող հավելվածներ կարելի է գտնել ուղեցույցում։",
+  "setup_pin": "Հավատարմագրել PIN",
+  "setup_successful": "Ձեր PIN-ը հաջողությամբ հավատարմագրվել է!",
+  "setup_totp_recommended": "Հավատարմագրել TOTP",
+  "setup_warning_2fa_text": "Cake 2FA-ն երկրորդ վավերացում է որոշակի գործողությունների համար դրամապանակում։ Այն նույն անվտանգ չէ, ինչ ցուրտ պահեստավորումը.\n\nԵթե դուք կորցնեք ձեր 2FA հավելվածի կամատեղությունը կամ TOTP բանալիները, դուք կկորցնեք այս դրամապանակի հասանելիությունը։ Դուք կստիպվեք վերականգնել ձեր դրամապանակը մնեմոնիկ սերմերի միջոցով։\n\nCake աջակցությունը չի կարող օգնել ձեզ, եթե դուք կորցնեք ձեր 2FA կամ մնեմոնիկ սերմերը։ Խնդրում ենք կարդալ ուղեցույցը, նախքան Cake 2FA-ն օգտագործելը",
+  "setup_your_debit_card": "Հավատարմագրել ձեր դեբետային քարտ",
+  "share": "Կիսվել",
+  "share_address": "Կիսվել հասցեով",
+  "show_details": "Ցուցադրել մանրամասներ",
+  "show_keys": "Ցուցադրել բանալիներ",
+  "show_market_place": "Ցուցադրել շուկան",
+  "show_seed": "Ցուցադրել սերմ",
+  "sign_message": "Կնքել հաղորդագրություն",
+  "sign_up": "Գրանցվել",
+  "sign_verify_message": "Կնքել կամ ստուգել հաղորդագրություն",
+  "sign_verify_message_sub": "Կնքել կամ ստուգել հաղորդագրությունը ձեր գախտնի բանալիով",
+  "sign_verify_title": "Կնքել / Ստուգել",
+  "signature": "Կնիք",
+  "signature_invalid_error": "Կնիքը անվավեր է տրված հաղորդագրության համար",
+  "signTransaction": "Կնքել Գործարք",
+  "signup_for_card_accept_terms": "Գրանցվել քարտի համար և ընդունել պայմանները",
+  "silent_payments": "Լուռ Վճարումներ",
+  "silent_payments_always_scan": "Միացնել Լուռ Վճարումներ մշտական սկանավորումը",
+  "silent_payments_disclaimer": "Նոր հասցեները նոր ինքնություն չեն։ Դա այլ պիտակով գոյություն ունեցող ինքնության վերագործածում է",
+  "silent_payments_display_card": "Ցուցադրել Լուռ Վճարումներ քարտը",
+  "silent_payments_scan_from_date": "Սկանավորել ամսաթվից",
+  "silent_payments_scan_from_date_or_blockheight": "Խնդրում ենք մուտքագրել բլոկի բարձրությունը, որտեղից դուք ցանկանում եք սկսել սկանավորել մուտքային Լուռ Վճարումները կամ տեղափոխել ամսաթվի փոխարեն։ Դուք կարող եք ընտրել, արդյոք դրամապանակը շարունակելու է սկանավորել ամեն բլոկ կամ ստուգել միայն սահմանված բարձրությունը",
+  "silent_payments_scan_from_height": "Բլոկի բարձրությունից սկանավորել",
+  "silent_payments_scanned_tip": "ՍԿԱՆԱՎՈՐՎԵՑ ԹԵՅԱՎՃԱՐ! (${tip})",
+  "silent_payments_scanning": "Լուռ Վճարումներ Սկանավորում",
+  "silent_payments_settings": "Լուռ Վճարումներ Կարգավորումներ",
+  "slidable": "Սահելի",
+  "sort_by": "Դասավորել ըստ",
+  "spend_key_private": "Վճարման բանալի (գախտնի)",
+  "spend_key_public": "Վճարման բանալի (հանրային)",
+  "status": "Կարգավիճակ՝ ",
+  "string_default": "Լռելայն",
+  "subaddress_title": "Ենթահասցեների ցանկ",
+  "subaddresses": "Ենթահասցեներ",
+  "submit_request": "Ուղարկել հարցում",
+  "successful": "Հաջողված",
+  "support_description_guides": "Տարածված խնդիրների փաստաթղթավորում և աջակցություն",
+  "support_description_live_chat": "Անվճար և արագ աջակցություն! Պատրաստված մասնագետները պատրաստ են օգնել",
+  "support_description_other_links": "Միացեք մեր համայնքին կամ հասեք մեզ այլ միջոցներով",
+  "support_title_guides": "Cake Wallet ուղեցույց",
+  "support_title_live_chat": "Անմիջական աջակցություն",
+  "support_title_other_links": "Այլ աջակցության հղումներ",
+  "sweeping_wallet": "Դրամապանակը մաքրվում է",
+  "sweeping_wallet_alert": "Սա չի տևի երկար։ Խնդրում ենք չլքել այս էկրանը կամ մաքրված միջոցները կկորչեն։",
+  "switchToETHWallet": "Խնդրում ենք անցնել Ethereum դրամապանակ և փորձել կրկին",
+  "switchToEVMCompatibleWallet": "Խնդրում ենք անցնել EVM համատեղելի դրամապանակ և փորձել կրկին (Ethereum, Polygon)",
+  "symbol": "Նշան",
+  "sync_all_wallets": "Համաժամեցնել բոլոր դրամապանակները",
+  "sync_status_attempting_sync": "ՀԱՄԱԺԱՄԵՑՄԱՆ ՓՈՐՁ",
+  "sync_status_connected": "ՄԻԱՑՎԱԾԷ",
+  "sync_status_connecting": "ՄԻԱՑՎՈՒՄ Է",
+  "sync_status_failed_connect": "ՉՄԻԱՑԱՎ",
+  "sync_status_not_connected": "ՄԻԱՑՎԱԾ ՉԷ",
+  "sync_status_starting_scan": "ՍԿԱՆԱՎՈՐՈՒՄԸ ՍԿՍՎՈՒՄ Է",
+  "sync_status_starting_sync": "ՀԱՄԱԺԱՄԵՑՈՒՄԸ ՍԿՍՎՈՒՄ Է",
+  "sync_status_syncronized": "ՀԱՄԱԺԱՄԵՑՎԱԾԷ",
+  "sync_status_syncronizing": "ՀԱՄԱԺԱՄԵՑՎՈՒՄ Է",
+  "sync_status_timed_out": "Ժամանակը սպառվեց",
+  "sync_status_unsupported": "ՉԱՋԱԿՑՎՈՂ ՀԱՆԳՈՒՅՑ,",
+  "syncing_wallet_alert_content": "Ձեր հաշիվը և գործարքների ցանկը կարող են լինել անավարտ մինչև վերին մասում գրված լինի “ՀԱՂՈՒՄ”։ Սեղմեք/դիպեք ուսումնասիրելու համար։",
+  "syncing_wallet_alert_title": "Ձեր դրամապանակը համաժամացվում է",
+  "template": "Տարբերակ",
+  "template_name": "Տարբերակի անուն",
+  "testnet_coins_no_value": "Testnet արժույթները չունեն արժեք",
+  "third_intro_content": "Yats-ը ապրում է Cake Wallet-ի դրսում ևս: Երկրի ցանկացած դրամապանակի հասցե կարող է փոխարինվել Yat-ով!",
+  "third_intro_title": "Yat-ը լավ է համագործակցում ուրիշների հետ",
+  "thorchain_contract_address_not_supported": "THORChain-ը չի աջակցում պայմանագրի հասցե ուղարկելուն",
+  "thorchain_taproot_address_not_supported": "ThorChain մատակարարը չի աջակցում Taproot հասցեները: Խնդրում ենք փոխել հասցեն կամ ընտրել այլ մատակարար:",
+  "time": "${minutes}ր ${seconds}վ",
+  "tip": "Թեյավճար",
+  "today": "Այսօր",
+  "token_contract_address": "Token-ի պայմանագրի հասցե",
+  "token_decimal": "Token-ի տասանիշ",
+  "token_name": "Token-ի անուն, օրինակ՝ Tether",
+  "token_symbol": "Token-ի նշան, օրինակ՝ USDT",
+  "tokenID": "ID",
+  "tor_connection": "Tor կապ",
+  "tor_only": "Միայն Tor",
+  "total": "Ընդհանուր",
+  "total_saving": "Ընդհանուր խնայողություն",
+  "totp_2fa_failure": "Սխալ կոդ: Խնդրում ենք փորձել այլ կոդ կամ ստեղծել նոր գաղտնի բանալի: Օգտագործեք համատեղելի 2FA ծրագիր, որը աջակցում է 8-նիշերի կոդեր և SHA512:",
+  "totp_2fa_success": "Հաջողություն: Cake 2FA-ն ակտիվացված է այս դրամապանակի համար: Հիշեք Ձեր մնեմոնիկ սերմը, եթե կորցնեք դրամապանակի հասանելիությունը:",
+  "totp_auth_url": "TOTP հեղինակավորման URL",
+  "totp_code": "TOTP կոդ",
+  "totp_secret_code": "TOTP գաղտնի կոդ",
+  "totp_verification_success": "Ստուգումը հաջողվել է",
+  "track": "Հետևել",
+  "trade_details_copied": "${title} պատճենված է գրանցամատյան",
+  "trade_details_created_at": "Ստեղծվել է",
+  "trade_details_fetching": "Բեռնում",
+  "trade_details_id": "ID",
+  "trade_details_pair": "Զույգ",
+  "trade_details_provider": "Մատակարար",
+  "trade_details_state": "Կարգավիճակ",
+  "trade_details_title": "Գործարքի մանրամասներ",
+  "trade_for_not_created": "${title} գործարք չի ստեղծվել",
+  "trade_history_title": "Գործարքների պատմություն",
+  "trade_id": "Գործարքի ID",
+  "trade_id_not_found": "${tradeId} ${title} գործարք չի գտնվել",
+  "trade_is_powered_by": "Այս գործարքը աջակցվում է ${provider} կողմից",
+  "trade_not_created": "Գործարք չի ստեղծվել",
+  "trade_not_found": "Գործարք չի գտնվել",
+  "trade_state_btc_sent": "BTC ուղարկված է",
+  "trade_state_complete": "Ավարտված է",
+  "trade_state_confirming": "Հաստատվում է",
+  "trade_state_created": "Ստեղծված է",
+  "trade_state_finished": "Ավարտված է",
+  "trade_state_paid": "Վճարված է",
+  "trade_state_paid_unconfirmed": "Վճարված է, բայց չի հաստատվել",
+  "trade_state_pending": "Սպասման մեջ է",
+  "trade_state_timeout": "Ժամանակը սպառվել է",
+  "trade_state_to_be_created": "Ստեղծվելու է",
+  "trade_state_traded": "Գործարք է կատարվել",
+  "trade_state_trading": "Գործարք է կատարվում",
+  "trade_state_underpaid": "Վճարված է, բայց ոչ ամբողջությամբ",
+  "trade_state_unpaid": "Վճարված չէ",
+  "trades": "Գործարքներ",
+  "transaction_details_amount": "Գումար",
+  "transaction_details_copied": "${title} պատճենված է գրանցամատյան",
+  "transaction_details_date": "Ամսաթիվ",
+  "transaction_details_fee": "Տուրք",
+  "transaction_details_height": "Բլոկի համար",
+  "transaction_details_recipient_address": "Ստացողի հասցե",
+  "transaction_details_source_address": "Ուղարկողի հասցե",
+  "transaction_details_title": "Գործարքի մանրամասներ",
+  "transaction_details_transaction_id": "Գործարքի ID",
+  "transaction_key": "Գործարքի բանալի",
+  "transaction_priority_fast": "Արագ",
+  "transaction_priority_fastest": "Ամենաարագ",
+  "transaction_priority_medium": "Միջին",
+  "transaction_priority_regular": "Սովորական",
+  "transaction_priority_slow": "Դանդաղ",
+  "transaction_sent": "Փոխանցումն ուղարկված է",
+  "transaction_sent_notice": "Եթե էկրանը 1 րոպեի ընթացքում չի թարմանում, խնդրում ենք ստուգել բլոկի բացահայտիչը և Ձեր էլ. փոստը",
+  "transactions": "Փոխանցումներ",
+  "transactions_by_date": "Փոխանցումներ ամսաթվով",
+  "trongrid_history": "TronGrid պատմություն",
+  "trusted": "Վստահելի",
+  "tx_commit_exception_no_dust_on_change": "Փոխանցումը մերժվել է այս գումարով: Այս արժույթներով կարող եք ուղարկել ${min} առանց փոփոխության կամ ${max} որը վերադարձնում է փոփոխությունը",
+  "tx_commit_failed": "Փոխանցումը ձախողվել է: Խնդրում ենք դիմել աջակցությանը",
+  "tx_invalid_input": "Դուք օգտագործում եք սխալ մուտքային տիպ այս տեսակի վճարման համար",
+  "tx_no_dust_exception": "Փոխանցումը մերժվել է շատ փոքր գումարով: Խնդրում ենք փորձել ավելացնել գումարը",
+  "tx_not_enough_inputs_exception": "Չկան բավարար մուտքեր: Խնդրում ենք ընտրել ավելին Coin Control֊ում",
+  "tx_rejected_bip68_final": "Փոխանցումը մերժվել է չհաստատված մուտքերով և ձախողվել է փոխարինել վճարման համար",
+  "tx_rejected_dust_change": "Փոխանցումը մերժվել է ցածր փոփոխության գումարով (փոշի): Փորձեք ուղարկել ԲՈԼՈՐ կամ նվազեցնել գումարը",
+  "tx_rejected_dust_output": "Փոխանցումը մերժվել է ցածր ելքային գումարով (փոշի): Խնդրում ենք ավելացնել գումարը",
+  "tx_rejected_dust_output_send_all": "Փոխանցումը մերժվել է ցածր ելքային գումարով (փոշի): Խնդրում ենք ստուգել արժույթների հաշիվը մուտքային վերահսկողության տակ",
+  "tx_rejected_vout_negative": "Բավարար մնացորդ չկա այս փոխանցման վճարների համար։ Խնդրում ենք ստուգել արժույթների մնացորդը Coin Control-ում։",
+  "tx_wrong_balance_exception": "Դուք չունեք բավարար ${currency} այս գումարը ուղարկելու համար։",
+  "tx_wrong_balance_with_amount_exception": "Դուք չունեք բավարար ${currency} ${amount} գումարը ուղարկելու համար։",
+  "tx_zero_fee_exception": "Չի կարող ուղարկվել Փոխանցումը առանց վճարի։ Փորձեք բարձրացնել գինը կամ ստուգել ձեր կապը վերջին գնահատականների համար։",
+  "unavailable_balance": "Անհասանելի մնացորդ",
+  "unavailable_balance_description": "Անհասանելի մնացորդ: Այս ընդհանուր գումարը ներառում է այն միջոցները, որոնք արգելափակված են ընթացիկ գործարքներում և նրանք, որոնք դուք ակտիվորեն սառեցրել եք արժույթների վերահսկման կարգավորումների մեջ։ Արգելափակված մնացորդները կդառնան հասանելի, երբ համապատասխան գործարքները կավարտվեն, մինչդեռ սառեցված մնացորդները կմնան անհասանելի մինչև դուք որոշեք դրանք ապասառեցնել։",
+  "unconfirmed": "Չհաստատված մնացորդ",
+  "understand": "Ես հասկանում եմ",
+  "unlock": "Բացել",
+  "unmatched_currencies": "Ձեր ընթացիկ դրամապանակի արժույթը չի համապատասխանում սկանավորված QR կոդի արժույթին",
+  "unspent_change": "Մնացորդ",
+  "unspent_coins_details_title": "Չծախսված արժույթների մանրամասները",
+  "unspent_coins_title": "Չծախսված արժույթներ",
+  "unsupported_asset": "Մենք չենք աջակցում այս գործողությունը այս ակտիվի համար։ Խնդրում ենք ստեղծել կամ անցնել աջակցվող ակտիվի տեսակին համապատասխան դրամապանակի։",
+  "uptime": "Աշխատանքային ժամանակ",
+  "upto": "մինչև ${value}",
+  "usb": "USB",
+  "use": "Փոխեք ",
+  "use_card_info_three": "Օգտագործեք թվային քարտը առցանց կամ անշփման վճարման մեթոդներով։",
+  "use_card_info_two": "Միջոցները փոխարկվում են ԱՄՆ դոլար երբ դրանք պահվում են կանխավճարային հաշվեկշռում, ոչ թե թվային արժույթներում։",
+  "use_ssl": "Օգտագործել SSL",
+  "use_suggested": "Օգտագործել առաջարկվածը",
+  "use_testnet": "Օգտագործել Testnet",
+  "value": "Արժեք",
+  "value_type": "Արժեքի տեսակ",
+  "variable_pair_not_supported": "Այս փոփոխականի զույգը չի աջակցվում ընտրված բորսաների հետ",
+  "verification": "Ստուգում",
+  "verify_message": "Ստուգել հաղորդագրությունը",
+  "verify_with_2fa": "Ստուգեք Cake 2FA-ով",
+  "version": "Տարբերակ ${currentVersion}",
+  "view_all": "Դիտել բոլորը",
+  "view_in_block_explorer": "Դիտել Block Explorer-ում",
+  "view_key_private": "Դիտել բանալին (գախտնի)",
+  "view_key_public": "Դիտել բանալին (հանրային)",
+  "view_transaction_on": "Դիտել Գործարքը ",
+  "voting_weight": "Քվեարկության Քաշ",
+  "waitFewSecondForTxUpdate": "Խնդրում ենք սպասել մի քանի վայրկյան, որպեսզի գործարքը արտացոլվի գործարքների պատմության մեջ",
+  "wallet_keys": "Դրամապանակի սերմ/բանալիներ",
+  "wallet_list_create_new_wallet": "Ստեղծել Նոր Դրամապանակ",
+  "wallet_list_edit_wallet": "Խմբագրել դրամապանակը",
+  "wallet_list_failed_to_load": "Չհաջողվեց բեռնել ${wallet_name} դրամապանակը։ ${error}",
+  "wallet_list_failed_to_remove": "Չհաջողվեց հեռացնել ${wallet_name} դրամապանակը։ ${error}",
+  "wallet_list_load_wallet": "Բեռնել դրամապանակը",
+  "wallet_list_loading_wallet": "Բեռնվում է ${wallet_name} դրամապանակը",
+  "wallet_list_removing_wallet": "Հեռացվում է ${wallet_name} դրամապանակը",
+  "wallet_list_restore_wallet": "Վերականգնել դրամապանակը",
+  "wallet_list_title": "Monero Դրամապանակ",
+  "wallet_list_wallet_name": "Դրամապանակի անունը",
+  "wallet_menu": "Մենյու",
+  "wallet_name": "Դրամապանակի անունը",
+  "wallet_name_exists": "Այդ անունով դրամապանակ արդեն կա։ Խնդրում ենք ընտրել այլ անուն կամ վերանվանել մյուս դրամապանակը։",
+  "wallet_password_is_empty": "Դրամապանակի գաղտնաբառը դատարկ է։ Դրամապանակի գաղտնաբառը չպետք է դատարկ լինի",
+  "wallet_recovery_height": "Վերականգնման բարձրություն",
+  "wallet_restoration_store_incorrect_seed_length": "Սերմի երկարությունը սխալ է",
+  "wallet_seed": "Դրամապանակի սերմ",
+  "wallet_seed_legacy": "Legacy դրամապանակի սերմ",
+  "wallet_store_monero_wallet": "Monero Դրամապանակ",
+  "walletConnect": "WalletConnect",
+  "wallets": "Դրամապանակներ",
+  "warning": "Զգուշացում",
+  "welcome": "Բարի գալուստ",
+  "welcome_to_cakepay": "Բարի գալուստ Cake Pay!",
+  "what_is_silent_payments": "Ի՞նչ է Լուռ Վճարումները:",
+  "widgets_address": "Հասցե",
+  "widgets_or": "կամ",
+  "widgets_restore_from_blockheight": "Վերականգնել բլոկի բարձրությունից",
+  "widgets_restore_from_date": "Վերականգնել ամսաթվից",
+  "widgets_seed": "Սերմ",
+  "wouoldLikeToConnect": "ցանկանում է միանալ",
+  "write_down_backup_password": "Խնդրում ենք գրանցել ձեր կրկնօրինակի գաղտնաբառը, որը օգտագործվում է կրկնօրինակ ֆայլերի ներմուծման համար։",
+  "xlm_extra_info": "Խնդրում ենք չմոռանալ նշել Memo ID-ն երբ ուղարկում եք XLM գործարք փոխանակման համար",
+  "xmr_available_balance": "Հասանելի մնացորդ",
+  "xmr_full_balance": "Լրիվ մնացորդ",
+  "xmr_hidden": "Թաքնված",
+  "xmr_to_error": "XMR.TO սխալ",
+  "xmr_to_error_description": "Սխալ գումար։ Առավելագույն սահմանը 8 թվանշան է կետից հետո",
+  "xrp_extra_info": "Խնդրում ենք չմոռանալ նշել Destination Tag-ը երբ ուղարկում եք XRP գործարք փոխանակման համար",
+  "yat": "Yat",
+  "yat_address": "Yat Հասցե",
+  "yat_alert_content": "Cake Wallet-ի օգտատերերը այժմ կարող են ուղարկել և ստանալ իրենց սիրած արժույթները emoji-ների հիման վրա օգտագործվող անունով։",
+  "yat_alert_title": "Ուղարկել և ստանալ կրիպտո ավելի հեշտությամբ Yat-ի միջոցով",
+  "yat_error": "Yat սխալ",
+  "yat_error_content": "Այս Yat-ի հետ կապված հասցեներ չկան։ Փորձեք այլ Yat",
+  "yat_popup_content": "Այժմ դուք կարող եք ուղարկել և ստանալ կրիպտո Cake Wallet-ում ձեր Yat-ով՝ կարճ, emoji-ների վրա հիմնված օգտագործողի անունով։ Կառավարեք Yat-երը ցանկացած ժամանակ կարգավորումների էկրանին",
+  "yat_popup_title": "Ձեր դրամապանակի հասցեն կարող է emoji-ացվել։",
+  "yesterday": "Երեկ",
+  "you_now_have_debit_card": "Դուք այժմ ունեք դեբետային քարտ",
+  "you_pay": "Դուք վճարում եք",
+  "you_will_get": "Ստացեք",
+  "you_will_send": "Փոխանակեք",
+  "yy": "ՏՏ"
+}
\ No newline at end of file

From 47ca649060a48f98469fcaf93de6196c8104b2d6 Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Thu, 22 Aug 2024 03:55:23 +0300
Subject: [PATCH 68/81] update translations

---
 README.md                                         | 4 +++-
 tool/utils/translation/translation_constants.dart | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 6e507bfcd..1c28f92a2 100644
--- a/README.md
+++ b/README.md
@@ -161,7 +161,9 @@ The only parts to be translated, if needed, are the values m and s after the var
 
 4. Add the language to `lib/entities/language_service.dart` under both `supportedLocales` and `localeCountryCode`. Use the name of the language in the local language and in English in parentheses after for `supportedLocales`. Use the [ISO 3166-1 alpha-3 code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3) for `localeCountryCode`. You must choose one country, so choose the country with the most native speakers of this language or is otherwise best associated with this language.
 
-5. Add a relevant flag to `assets/images/flags/XXXX.png`, replacing XXXX with the 3 digit localeCountryCode. The image must be 42x26 pixels with a 3 pixels of transparent margin on all 4 sides. You can resize the flag with [paint.net](https://www.getpaint.net/) to 36x20 pixels, expand the canvas to 42x26 pixels with the flag anchored in the middle, and then manually delete the 3 pixels on each side to make transparent. Or you can use another program like Photoshop.
+5. Add a relevant flag to `assets/images/flags/XXXX.png`, replacing XXXX with the 3 letters localeCountryCode. The image must be 42x26 pixels with a 3 pixels of transparent margin on all 4 sides. You can resize the flag with [paint.net](https://www.getpaint.net/) to 36x20 pixels, expand the canvas to 42x26 pixels with the flag anchored in the middle, and then manually delete the 3 pixels on each side to make transparent. Or you can use another program like Photoshop.
+
+6. Add the new language code to `tool/utils/translation/translation_constants.dart`
 
 ## Add a new fiat currency
 
diff --git a/tool/utils/translation/translation_constants.dart b/tool/utils/translation/translation_constants.dart
index 3a472d8c4..3d1afe142 100644
--- a/tool/utils/translation/translation_constants.dart
+++ b/tool/utils/translation/translation_constants.dart
@@ -1,6 +1,6 @@
 const defaultLang = "en";
 const langs = [
-  "ar", "bg", "cs", "de", "en", "es", "fr", "ha", "hi", "hr", "id", "it",
+  "ar", "bg", "cs", "de", "en", "es", "fr", "ha", "hi", "hr", "hy", "id", "it",
   "ja", "ko", "my", "nl", "pl", "pt", "ru", "th", "tl", "tr", "uk", "ur", "yo",
   "zh-cn" // zh, but Google Translate uses zh-cn for Chinese (Simplified)
 ];

From 9c3f0b329bba802787123d7c9ac5c745bf56121f Mon Sep 17 00:00:00 2001
From: OmarHatem <omarh.ismail1@gmail.com>
Date: Thu, 22 Aug 2024 15:34:31 +0300
Subject: [PATCH 69/81] minor fix

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

diff --git a/lib/entities/language_service.dart b/lib/entities/language_service.dart
index bb60c5cce..260c8a27f 100644
--- a/lib/entities/language_service.dart
+++ b/lib/entities/language_service.dart
@@ -29,7 +29,7 @@ class LanguageService {
     'id': 'Bahasa Indonesia (Indonesian)',
     'yo': 'Yorùbá (Yoruba)',
     'ha': 'Hausa Najeriya (Nigeria)',
-    'tl': 'Filipino (Tagalog)'
+    'tl': 'Filipino (Tagalog)',
     'hy': 'Հայերեն (Armenian)',
   };
 
@@ -59,7 +59,7 @@ class LanguageService {
     'id': 'idn',
     'yo': 'nga',
     'ha': 'hau',
-    'tl': 'phl'
+    'tl': 'phl',
     'hy': 'arm'
   };
 

From 9cab9b9bc2a471a27efd4f06f8b84e116966a2a6 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Thu, 22 Aug 2024 11:49:05 -0400
Subject: [PATCH 70/81] fix ios xcode project [skip ci]

---
 ios/Runner.xcodeproj/project.pbxproj | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index 850b634b7..10cc6434d 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -28,8 +28,6 @@
 		A3D5E17CC53DF13FA740DEFA /* RedeemSwap.swift in Resources */ = {isa = PBXBuildFile; fileRef = 9D2F2C9F2555316C95EE7EA3 /* RedeemSwap.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
 		B6C6E59403ACDE44724C12F4 /* ServiceConfig.swift in Resources */ = {isa = PBXBuildFile; fileRef = B3D5E78267F5F18D882FDC3B /* ServiceConfig.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
 		CE291CFE2C15DB9A00B9F709 /* WowneroWallet.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE291CFD2C15DB9A00B9F709 /* WowneroWallet.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
-		CEAFE49E2C539250009FF3AD /* Mwebd.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEAFE49D2C539250009FF3AD /* Mwebd.xcframework */; };
-		CEAFE49F2C539250009FF3AD /* Mwebd.xcframework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CEAFE49D2C539250009FF3AD /* Mwebd.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		CEAFE4A02C53926F009FF3AD /* libresolv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = C58D93382C00FAC6004BCF69 /* libresolv.tbd */; };
 		CFEFC24F82F78FE747DF1D22 /* LnurlPayInfo.swift in Resources */ = {isa = PBXBuildFile; fileRef = 58C22CBD8C22B9D6023D59F8 /* LnurlPayInfo.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
 		D0D7A0D4E13F31C4E02E235B /* ReceivePayment.swift in Resources */ = {isa = PBXBuildFile; fileRef = 91C524F800843E0A3F17E004 /* ReceivePayment.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
@@ -46,7 +44,6 @@
 			files = (
 				CE291CFE2C15DB9A00B9F709 /* WowneroWallet.framework in CopyFiles */,
 				0C50DFB92BF3CB56002B0EB3 /* MoneroWallet.framework in CopyFiles */,
-				CEAFE49F2C539250009FF3AD /* Mwebd.xcframework in CopyFiles */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -101,7 +98,6 @@
 			buildActionMask = 2147483647;
 			files = (
 				4DFD1BB54A3A50573E19A583 /* Pods_Runner.framework in Frameworks */,
-				CEAFE49E2C539250009FF3AD /* Mwebd.xcframework in Frameworks */,
 				CEAFE4A02C53926F009FF3AD /* libresolv.tbd in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;

From 4c2d0613635a1457c2a63ba788f15dae170fcae9 Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Fri, 23 Aug 2024 16:19:42 +0300
Subject: [PATCH 71/81] rbf fixes issues sum utxo and fee calculation (#1625)

* total out amount issue

* fix empty inputs and outputs addresses for new tx

* fix sum value of utxo not spending

* Update configure.dart

* Update electrum_wallet.dart

* receiving address

* review fixes
---
 cw_bitcoin/lib/electrum_transaction_info.dart |   2 +-
 cw_bitcoin/lib/electrum_wallet.dart           | 133 +++++++++++-------
 lib/bitcoin/cw_bitcoin.dart                   |   5 +-
 lib/view_model/send/send_view_model.dart      |  44 ++++--
 .../transaction_details_view_model.dart       |  23 +--
 tool/configure.dart                           |   3 +-
 6 files changed, 132 insertions(+), 78 deletions(-)

diff --git a/cw_bitcoin/lib/electrum_transaction_info.dart b/cw_bitcoin/lib/electrum_transaction_info.dart
index ea4a3de33..ee3daa0e0 100644
--- a/cw_bitcoin/lib/electrum_transaction_info.dart
+++ b/cw_bitcoin/lib/electrum_transaction_info.dart
@@ -235,6 +235,6 @@ class ElectrumTransactionInfo extends TransactionInfo {
   }
 
   String toString() {
-    return 'ElectrumTransactionInfo(id: $id, height: $height, amount: $amount, fee: $fee, direction: $direction, date: $date, isPending: $isPending, confirmations: $confirmations, to: $to, unspent: $unspents)';
+    return 'ElectrumTransactionInfo(id: $id, height: $height, amount: $amount, fee: $fee, direction: $direction, date: $date, isPending: $isPending, confirmations: $confirmations, to: $to, unspent: $unspents, inputAddresses: $inputAddresses, outputAddresses: $outputAddresses)';
   }
 }
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index da91a29e4..2a57c8d5c 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -132,6 +132,7 @@ abstract class ElectrumWalletBase
   final String? _mnemonic;
 
   Bip32Slip10Secp256k1 get hd => accountHD.childKey(Bip32KeyIndex(0));
+
   Bip32Slip10Secp256k1 get sideHd => accountHD.childKey(Bip32KeyIndex(1));
 
   final EncryptionFileUtils encryptionFileUtils;
@@ -1363,26 +1364,15 @@ abstract class ElectrumWalletBase
     }
   }
 
-  Future<bool> canReplaceByFee(String hash) async {
-    final verboseTransaction = await electrumClient.getTransactionVerbose(hash: hash);
-
-    final String? transactionHex;
-    int confirmations = 0;
-
-    if (verboseTransaction.isEmpty) {
-      transactionHex = await electrumClient.getTransactionHex(hash: hash);
-    } else {
-      confirmations = verboseTransaction['confirmations'] as int? ?? 0;
-      transactionHex = verboseTransaction['hex'] as String?;
-    }
-
-    if (confirmations > 0) return false;
-
-    if (transactionHex == null || transactionHex.isEmpty) {
+  Future<bool> canReplaceByFee(ElectrumTransactionInfo tx) async {
+    try {
+      final bundle = await getTransactionExpanded(hash: tx.txHash);
+      _updateInputsAndOutputs(tx, bundle);
+      if (bundle.confirmations > 0) return false;
+      return bundle.originalTransaction.canReplaceByFee;
+    } catch (e) {
       return false;
     }
-
-    return BtcTransaction.fromRaw(transactionHex).canReplaceByFee;
   }
 
   Future<bool> isChangeSufficientForFee(String txId, int newFee) async {
@@ -1458,47 +1448,59 @@ abstract class ElectrumWalletBase
         );
       }
 
-      int totalOutAmount = bundle.originalTransaction.outputs
-          .fold<int>(0, (previousValue, element) => previousValue + element.amount.toInt());
-
-      var currentFee = allInputsAmount - totalOutAmount;
-      int remainingFee = newFee - currentFee;
-
+      // Create a list of available outputs
       final outputs = <BitcoinOutput>[];
-
-      // Add outputs and deduct the fees from it
-      for (int i = bundle.originalTransaction.outputs.length - 1; i >= 0; i--) {
-        final out = bundle.originalTransaction.outputs[i];
+      for (final out in bundle.originalTransaction.outputs) {
         final address = addressFromOutputScript(out.scriptPubKey, network);
         final btcAddress = addressTypeFromStr(address, network);
+        outputs.add(BitcoinOutput(address: btcAddress, value: BigInt.from(out.amount.toInt())));
+      }
 
-        int newAmount;
-        if (out.amount.toInt() >= remainingFee) {
-          newAmount = out.amount.toInt() - remainingFee;
-          remainingFee = 0;
+      // Calculate the total amount and fees
+      int totalOutAmount =
+          outputs.fold<int>(0, (previousValue, output) => previousValue + output.value.toInt());
+      int currentFee = allInputsAmount - totalOutAmount;
+      int remainingFee = newFee - currentFee;
 
-          // if new amount of output is less than dust amount, then don't add this output as well
-          if (newAmount <= _dustAmount) {
-            continue;
+      if (remainingFee <= 0) {
+        throw Exception("New fee must be higher than the current fee.");
+      }
+
+      // Deduct Remaining Fee from Main Outputs
+      if (remainingFee > 0) {
+        for (int i = outputs.length - 1; i >= 0; i--) {
+          int outputAmount = outputs[i].value.toInt();
+
+          if (outputAmount > _dustAmount) {
+            int deduction = (outputAmount - _dustAmount >= remainingFee)
+                ? remainingFee
+                : outputAmount - _dustAmount;
+            outputs[i] = BitcoinOutput(
+                address: outputs[i].address, value: BigInt.from(outputAmount - deduction));
+            remainingFee -= deduction;
+
+            if (remainingFee <= 0) break;
           }
-        } else {
-          remainingFee -= out.amount.toInt();
-          continue;
         }
-
-        outputs.add(BitcoinOutput(address: btcAddress, value: BigInt.from(newAmount)));
       }
 
+      // Final check if the remaining fee couldn't be deducted
+      if (remainingFee > 0) {
+        throw Exception("Not enough funds to cover the fee.");
+      }
+
+      // Identify all change outputs
       final changeAddresses = walletAddresses.allAddresses.where((element) => element.isHidden);
+      final List<BitcoinOutput> changeOutputs = outputs
+          .where((output) => changeAddresses
+              .any((element) => element.address == output.address.toAddress(network)))
+          .toList();
 
-      // look for a change address in the outputs
-      final changeOutput = outputs.firstWhereOrNull((output) =>
-          changeAddresses.any((element) => element.address == output.address.toAddress(network)));
+      int totalChangeAmount =
+          changeOutputs.fold<int>(0, (sum, output) => sum + output.value.toInt());
 
-      // deduct the change amount from the output amount
-      if (changeOutput != null) {
-        totalOutAmount -= changeOutput.value.toInt();
-      }
+      // The final amount that the receiver will receive
+      int sendingAmount = allInputsAmount - newFee - totalChangeAmount;
 
       final txb = BitcoinTransactionBuilder(
         utxos: utxos,
@@ -1527,10 +1529,10 @@ abstract class ElectrumWalletBase
         transaction,
         type,
         electrumClient: electrumClient,
-        amount: totalOutAmount,
+        amount: sendingAmount,
         fee: newFee,
         network: network,
-        hasChange: changeOutput != null,
+        hasChange: changeOutputs.isNotEmpty,
         feeRate: newFee.toString(),
       )..addListener((transaction) async {
           transactionHistory.addOne(transaction);
@@ -2026,6 +2028,39 @@ abstract class ElectrumWalletBase
       });
     }
   }
+
+  void _updateInputsAndOutputs(ElectrumTransactionInfo tx, ElectrumTransactionBundle bundle) {
+    tx.inputAddresses = tx.inputAddresses?.where((address) => address.isNotEmpty).toList();
+
+    if (tx.inputAddresses == null ||
+        tx.inputAddresses!.isEmpty ||
+        tx.outputAddresses == null ||
+        tx.outputAddresses!.isEmpty) {
+      List<String> inputAddresses = [];
+      List<String> outputAddresses = [];
+
+      for (int i = 0; i < bundle.originalTransaction.inputs.length; i++) {
+        final input = bundle.originalTransaction.inputs[i];
+        final inputTransaction = bundle.ins[i];
+        final vout = input.txIndex;
+        final outTransaction = inputTransaction.outputs[vout];
+        final address = addressFromOutputScript(outTransaction.scriptPubKey, network);
+
+        if (address.isNotEmpty) inputAddresses.add(address);
+      }
+
+      for (int i = 0; i < bundle.originalTransaction.outputs.length; i++) {
+        final out = bundle.originalTransaction.outputs[i];
+        final address = addressFromOutputScript(out.scriptPubKey, network);
+
+        if (address.isNotEmpty) outputAddresses.add(address);
+      }
+      tx.inputAddresses = inputAddresses;
+      tx.outputAddresses = outputAddresses;
+
+      transactionHistory.addOne(tx);
+    }
+  }
 }
 
 class ScanNode {
diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart
index 5a71e3549..d979f9281 100644
--- a/lib/bitcoin/cw_bitcoin.dart
+++ b/lib/bitcoin/cw_bitcoin.dart
@@ -398,9 +398,10 @@ class CWBitcoin extends Bitcoin {
   }
 
   @override
-  Future<bool> canReplaceByFee(Object wallet, String transactionHash) async {
+  Future<bool> canReplaceByFee(Object wallet, Object transactionInfo) async {
     final bitcoinWallet = wallet as ElectrumWallet;
-    return bitcoinWallet.canReplaceByFee(transactionHash);
+    final tx = transactionInfo as ElectrumTransactionInfo;
+    return bitcoinWallet.canReplaceByFee(tx);
   }
 
   @override
diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart
index 863c83957..22c083455 100644
--- a/lib/view_model/send/send_view_model.dart
+++ b/lib/view_model/send/send_view_model.dart
@@ -18,6 +18,7 @@ import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
 import 'package:cake_wallet/wownero/wownero.dart';
 import 'package:cw_core/exceptions.dart';
+import 'package:cw_core/transaction_info.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';
@@ -392,25 +393,38 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
   }
 
   @action
-  Future<void> replaceByFee(String txId, String newFee) async {
+  Future<void> replaceByFee(TransactionInfo tx, String newFee) async {
     state = IsExecutingState();
 
-    final isSufficient = await bitcoin!.isChangeSufficientForFee(wallet, txId, newFee);
+    try {
+      final isSufficient = await bitcoin!.isChangeSufficientForFee(wallet, tx.id, newFee);
 
-    if (!isSufficient) {
-      state = AwaitingConfirmationState(
-          title: S.current.confirm_fee_deduction,
-          message: S.current.confirm_fee_deduction_content,
-          onConfirm: () async {
-            pendingTransaction = await bitcoin!.replaceByFee(wallet, txId, newFee);
-            state = ExecutedSuccessfullyState();
-          },
-          onCancel: () {
-            state = FailureState('Insufficient change for fee');
-          });
-    } else {
-      pendingTransaction = await bitcoin!.replaceByFee(wallet, txId, newFee);
+      if (!isSufficient) {
+        state = AwaitingConfirmationState(
+            title: S.current.confirm_fee_deduction,
+            message: S.current.confirm_fee_deduction_content,
+            onConfirm: () async => await _executeReplaceByFee(tx, newFee),
+            onCancel: () => state = FailureState('Insufficient change for fee'));
+      } else {
+        await _executeReplaceByFee(tx, newFee);
+      }
+    } catch (e) {
+      state = FailureState(e.toString());
+    }
+  }
+
+  Future<void> _executeReplaceByFee(TransactionInfo tx, String newFee) async {
+
+
+    clearOutputs();
+    final output = outputs.first;
+    output.address = tx.outputAddresses?.first ?? '';
+
+    try {
+      pendingTransaction = await bitcoin!.replaceByFee(wallet, tx.id, newFee);
       state = ExecutedSuccessfullyState();
+    } catch (e) {
+      state = FailureState(e.toString());
     }
   }
 
diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart
index 18715e508..aa63ce860 100644
--- a/lib/view_model/transaction_details_view_model.dart
+++ b/lib/view_model/transaction_details_view_model.dart
@@ -52,7 +52,7 @@ abstract class TransactionDetailsViewModelBase with Store {
       case WalletType.bitcoin:
         _addElectrumListItems(tx, dateFormat);
         _addBumpFeesListItems(tx);
-        _checkForRBF();
+        _checkForRBF(tx);
         break;
       case WalletType.litecoin:
       case WalletType.bitcoinCash:
@@ -349,12 +349,15 @@ abstract class TransactionDetailsViewModelBase with Store {
 
   void _addBumpFeesListItems(TransactionInfo tx) {
     transactionPriority = bitcoin!.getBitcoinTransactionPriorityMedium();
+    final inputsCount = (transactionInfo.inputAddresses?.isEmpty ?? true)
+        ? 1
+        : transactionInfo.inputAddresses!.length;
+    final outputsCount = (transactionInfo.outputAddresses?.isEmpty ?? true)
+        ? 1
+        : transactionInfo.outputAddresses!.length;
 
     newFee = bitcoin!.getFeeAmountForPriority(
-        wallet,
-        bitcoin!.getBitcoinTransactionPriorityMedium(),
-        transactionInfo.inputAddresses?.length ?? 1,
-        transactionInfo.outputAddresses?.length ?? 1);
+        wallet, bitcoin!.getBitcoinTransactionPriorityMedium(), inputsCount, outputsCount);
 
     RBFListItems.add(StandartListItem(title: S.current.old_fee, value: tx.feeFormatted() ?? '0.0'));
 
@@ -383,12 +386,12 @@ abstract class TransactionDetailsViewModelBase with Store {
           return setNewFee(value: sliderValue, priority: transactionPriority!);
         }));
 
-    if (transactionInfo.inputAddresses != null) {
+    if (transactionInfo.inputAddresses != null && transactionInfo.inputAddresses!.isNotEmpty) {
       RBFListItems.add(StandardExpandableListItem(
           title: S.current.inputs, expandableItems: transactionInfo.inputAddresses!));
     }
 
-    if (transactionInfo.outputAddresses != null) {
+    if (transactionInfo.outputAddresses != null && transactionInfo.outputAddresses!.isNotEmpty) {
       RBFListItems.add(StandardExpandableListItem(
           title: S.current.outputs, expandableItems: transactionInfo.outputAddresses!));
     }
@@ -416,10 +419,10 @@ abstract class TransactionDetailsViewModelBase with Store {
   }
 
   @action
-  Future<void> _checkForRBF() async {
+  Future<void> _checkForRBF(TransactionInfo tx) async {
     if (wallet.type == WalletType.bitcoin &&
         transactionInfo.direction == TransactionDirection.outgoing) {
-      if (await bitcoin!.canReplaceByFee(wallet, transactionInfo.id)) {
+      if (await bitcoin!.canReplaceByFee(wallet, tx)) {
         _canReplaceByFee = true;
       }
     }
@@ -441,7 +444,7 @@ abstract class TransactionDetailsViewModelBase with Store {
     return bitcoin!.formatterBitcoinAmountToString(amount: newFee);
   }
 
-  void replaceByFee(String newFee) => sendViewModel.replaceByFee(transactionInfo.id, newFee);
+  void replaceByFee(String newFee) => sendViewModel.replaceByFee(transactionInfo, newFee,);
 
   @computed
   String get pendingTransactionFiatAmountValueFormatted => sendViewModel.isFiatDisabled
diff --git a/tool/configure.dart b/tool/configure.dart
index a0104c34e..c9b6bbdda 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -79,6 +79,7 @@ import 'dart:typed_data';
 import 'package:bitcoin_base/bitcoin_base.dart';
 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
 import 'package:cake_wallet/view_model/send/output.dart';
+import 'package:cw_bitcoin/electrum_transaction_info.dart';
 import 'package:cw_core/hardware/hardware_account_data.dart';
 import 'package:cw_core/node.dart';
 import 'package:cw_core/output_info.dart';
@@ -204,7 +205,7 @@ abstract class Bitcoin {
   bool isTestnet(Object wallet);
 
   Future<PendingTransaction> replaceByFee(Object wallet, String transactionHash, String fee);
-  Future<bool> canReplaceByFee(Object wallet, String transactionHash);
+  Future<bool> canReplaceByFee(Object wallet, Object tx);
   Future<bool> isChangeSufficientForFee(Object wallet, String txId, String newFee);
   int getFeeAmountForPriority(Object wallet, TransactionPriority priority, int inputsCount, int outputsCount, {int? size});
   int getEstimatedFeeWithFeeRate(Object wallet, int feeRate, int? amount,

From 527983af4f9c328a844de77fe16efc2d18e7723d Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Fri, 23 Aug 2024 15:17:28 -0400
Subject: [PATCH 72/81] updates

---
 cw_bitcoin/lib/electrum_wallet.dart           | 102 +++++++----------
 cw_bitcoin/lib/litecoin_wallet.dart           | 104 +++++++++---------
 .../unspent_coins_list_view_model.dart        |  19 +++-
 3 files changed, 110 insertions(+), 115 deletions(-)

diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 4e447814a..3da039afe 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -424,9 +424,7 @@ abstract class ElectrumWalletBase
   @override
   Future<void> startSync() async {
     try {
-      if (this is! LitecoinWallet) {
-        syncStatus = SyncronizingSyncStatus();
-      }
+      syncStatus = SyncronizingSyncStatus();
 
       if (hasSilentPaymentsScanning) {
         await _setInitialHeight();
@@ -1262,69 +1260,51 @@ abstract class ElectrumWalletBase
       updatedUnspentCoins.addAll(await fetchUnspent(address));
     }));
 
-    unspentCoins = updatedUnspentCoins;
-  }
-
-  Future<void> updateUnspent() async {
-    await updateAllUnspents();
-
-    if (unspentCoinsInfo.length != unspentCoins.length) {
-      unspentCoins.forEach((coin) => addCoinInfo(coin));
-      return;
-    }
-
-    if (unspentCoins.isNotEmpty) {
-      unspentCoins.forEach((coin) {
-        final coinInfoList = unspentCoinsInfo.values.where((element) =>
-            element.walletId.contains(id) &&
-            element.hash.contains(coin.hash) &&
-            element.vout == coin.vout);
-
-        if (coinInfoList.isNotEmpty) {
-          final coinInfo = coinInfoList.first;
-
-          coin.isFrozen = coinInfo.isFrozen;
-          coin.isSending = coinInfo.isSending;
-          coin.note = coinInfo.note;
-          if (coin.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord)
-            coin.bitcoinAddressRecord.balance += coinInfo.value;
-        } else {
-          addCoinInfo(coin);
-        }
-      });
+    if (unspentCoinsInfo.length != updatedUnspentCoins.length) {
+      updatedUnspentCoins.forEach((coin) => addCoinInfo(coin));
     }
 
+    await updateCoins(updatedUnspentCoins, set: true);
     await _refreshUnspentCoinsInfo();
   }
 
-  @action
-  Future<void> updateUnspents(BitcoinAddressRecord address) async {
-    final newUnspentCoins = await fetchUnspent(address);
-
-    if (newUnspentCoins.isNotEmpty) {
-      unspentCoins.addAll(newUnspentCoins);
-
-      newUnspentCoins.forEach((coin) {
-        final coinInfoList = unspentCoinsInfo.values.where(
-          (element) =>
-              element.walletId.contains(id) &&
-              element.hash.contains(coin.hash) &&
-              element.vout == coin.vout,
-        );
-
-        if (coinInfoList.isNotEmpty) {
-          final coinInfo = coinInfoList.first;
-
-          coin.isFrozen = coinInfo.isFrozen;
-          coin.isSending = coinInfo.isSending;
-          coin.note = coinInfo.note;
-          if (coin.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord)
-            coin.bitcoinAddressRecord.balance += coinInfo.value;
-        } else {
-          addCoinInfo(coin);
-        }
-      });
+  Future<void> updateCoins(List<BitcoinUnspent> newUnspentCoins, {bool set = false}) async {
+    if (newUnspentCoins.isEmpty) {
+      return;
     }
+
+    if (set) {
+      unspentCoins = newUnspentCoins;
+    } else {
+      unspentCoins.addAll(newUnspentCoins);
+    }
+
+    newUnspentCoins.forEach((coin) {
+      final coinInfoList = unspentCoinsInfo.values.where(
+        (element) =>
+            element.walletId.contains(id) &&
+            element.hash.contains(coin.hash) &&
+            element.vout == coin.vout,
+      );
+
+      if (coinInfoList.isNotEmpty) {
+        final coinInfo = coinInfoList.first;
+
+        coin.isFrozen = coinInfo.isFrozen;
+        coin.isSending = coinInfo.isSending;
+        coin.note = coinInfo.note;
+        if (coin.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord)
+          coin.bitcoinAddressRecord.balance += coinInfo.value;
+      } else {
+        addCoinInfo(coin);
+      }
+    });
+  }
+
+  @action
+  Future<void> updateUnspentsForAddress(BitcoinAddressRecord address) async {
+    final newUnspentCoins = await fetchUnspent(address);
+    await updateCoins(newUnspentCoins);
   }
 
   @action
@@ -1819,7 +1799,7 @@ abstract class ElectrumWalletBase
       _scripthashesUpdateSubject[sh] = await electrumClient.scripthashUpdate(sh);
       _scripthashesUpdateSubject[sh]?.listen((event) async {
         try {
-          await updateUnspents(address);
+          await updateUnspentsForAddress(address);
 
           await updateBalance();
 
diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index bb1023164..c5e6a6df3 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -202,14 +202,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   @override
   Future<void> startSync() async {
     print("STARTING SYNC");
-    if (!mwebEnabled) {
-      syncStatus = SyncronizingSyncStatus();
-      await subscribeForUpdates();
-      await updateTransactions();
-      syncStatus = SyncedSyncStatus();
-      return;
-    }
-
+    syncStatus = SyncronizingSyncStatus();
     await subscribeForUpdates();
     await updateTransactions();
     await updateFeeRates();
@@ -218,6 +211,16 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     _feeRatesTimer =
         Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
 
+    if (!mwebEnabled) {
+      await super.updateAllUnspents();
+      await updateBalance();
+      syncStatus = SyncedSyncStatus();
+      return;
+    }
+
+    await updateUnspent();
+    await updateBalance();
+
     _stub = await CwMweb.stub();
     _syncTimer?.cancel();
     _syncTimer = Timer.periodic(const Duration(milliseconds: 1500), (timer) async {
@@ -255,8 +258,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
         }
       }
     });
-    updateUnspent();
-    fetchBalances();
     // this runs in the background and processes new utxos as they come in:
     processMwebUtxos();
   }
@@ -538,62 +539,60 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     return true;
   }
 
-  @override
   Future<void> updateUnspent() async {
-    await super.updateUnspent();
     await checkMwebUtxosSpent();
+    await updateAllUnspents();
   }
 
   @override
   @action
   Future<void> updateAllUnspents() async {
-    List<BitcoinUnspent> updatedUnspentCoins = [];
+    // get ltc unspents:
+    await super.updateAllUnspents();
 
-    await Future.wait(walletAddresses.allAddresses.map((address) async {
-      updatedUnspentCoins.addAll(await fetchUnspent(address));
-    }));
-
-    if (mwebEnabled) {
-      // update mweb unspents:
-      final mwebAddrs = (walletAddresses as LitecoinWalletAddresses).mwebAddrs;
-      mwebUtxosBox.keys.forEach((dynamic oId) {
-        final String outputId = oId as String;
-        final utxo = mwebUtxosBox.get(outputId);
-        if (utxo == null) {
-          return;
-        }
-        if (utxo.address.isEmpty) {
-          // not sure if a bug or a special case but we definitely ignore these
-          return;
-        }
-        final addressRecord = walletAddresses.allAddresses
-            .firstWhereOrNull((addressRecord) => addressRecord.address == utxo.address);
-
-        if (addressRecord == null) {
-          print("utxo contains an address that is not in the wallet: ${utxo.address}");
-          return;
-        }
-        final unspent = BitcoinUnspent(
-          addressRecord,
-          outputId,
-          utxo.value.toInt(),
-          mwebAddrs.indexOf(utxo.address),
-        );
-        if (unspent.vout == 0) {
-          unspent.isChange = true;
-        }
-        updatedUnspentCoins.add(unspent);
-      });
+    if (!mwebEnabled) {
+      return;
     }
+    // add the mweb unspents to the list:
+    List<BitcoinUnspent> mwebUnspentCoins = [];
+    // update mweb unspents:
+    final mwebAddrs = (walletAddresses as LitecoinWalletAddresses).mwebAddrs;
+    mwebUtxosBox.keys.forEach((dynamic oId) {
+      final String outputId = oId as String;
+      final utxo = mwebUtxosBox.get(outputId);
+      if (utxo == null) {
+        return;
+      }
+      if (utxo.address.isEmpty) {
+        // not sure if a bug or a special case but we definitely ignore these
+        return;
+      }
+      final addressRecord = walletAddresses.allAddresses
+          .firstWhereOrNull((addressRecord) => addressRecord.address == utxo.address);
 
-    unspentCoins = updatedUnspentCoins;
+      if (addressRecord == null) {
+        print("utxo contains an address that is not in the wallet: ${utxo.address}");
+        return;
+      }
+      final unspent = BitcoinUnspent(
+        addressRecord,
+        outputId,
+        utxo.value.toInt(),
+        mwebAddrs.indexOf(utxo.address),
+      );
+      if (unspent.vout == 0) {
+        unspent.isChange = true;
+      }
+      mwebUnspentCoins.add(unspent);
+    });
+    unspentCoins.addAll(mwebUnspentCoins);
   }
 
   @override
   Future<ElectrumBalance> fetchBalances() async {
     final balance = await super.fetchBalances();
-    var confirmed = balance.confirmed;
-    var unconfirmed = balance.unconfirmed;
+    int confirmed = balance.confirmed;
+    int unconfirmed = balance.unconfirmed;
     mwebUtxosBox.values.forEach((utxo) {
       if (utxo.height > 0) {
         confirmed += utxo.value.toInt();
@@ -640,6 +639,9 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     // to have an accurate count, we should just keep it in sync with what we know from the tx history:
     for (final tx in transactionHistory.transactions.values) {
       // if (tx.isPending) continue;
+      if (tx.inputAddresses == null || tx.outputAddresses == null) {
+        continue;
+      }
       final txAddresses = tx.inputAddresses! + tx.outputAddresses!;
       for (final address in txAddresses) {
         final addressRecord = walletAddresses.allAddresses
diff --git a/lib/view_model/unspent_coins/unspent_coins_list_view_model.dart b/lib/view_model/unspent_coins/unspent_coins_list_view_model.dart
index 5b6e6140f..72dcdb27b 100644
--- a/lib/view_model/unspent_coins/unspent_coins_list_view_model.dart
+++ b/lib/view_model/unspent_coins/unspent_coins_list_view_model.dart
@@ -38,6 +38,10 @@ abstract class UnspentCoinsListViewModelBase with Store {
       final info =
           getUnspentCoinInfo(item.hash, item.address, item.amountRaw, item.vout, item.keyImage);
 
+      if (info == null) {
+        return;
+      }
+
       info.isFrozen = item.isFrozen;
       info.isSending = item.isSending;
       info.note = item.note;
@@ -50,15 +54,21 @@ abstract class UnspentCoinsListViewModelBase with Store {
     }
   }
 
-  UnspentCoinsInfo getUnspentCoinInfo(
-          String hash, String address, int value, int vout, String? keyImage) =>
-      _unspentCoinsInfo.values.firstWhere((element) =>
+  UnspentCoinsInfo? getUnspentCoinInfo(
+      String hash, String address, int value, int vout, String? keyImage) {
+    try {
+      return _unspentCoinsInfo.values.firstWhere((element) =>
           element.walletId == wallet.id &&
           element.hash == hash &&
           element.address == address &&
           element.value == value &&
           element.vout == vout &&
           element.keyImage == keyImage);
+    } catch (e) {
+      print("UnspentCoinsInfo not found for coin: $e");
+      return null;
+    }
+  }
 
   String formatAmountToString(int fullBalance) {
     if (wallet.type == WalletType.monero)
@@ -108,6 +118,9 @@ abstract class UnspentCoinsListViewModelBase with Store {
       try {
         final info =
             getUnspentCoinInfo(elem.hash, elem.address, elem.value, elem.vout, elem.keyImage);
+        if (info == null) {
+          return;
+        }
 
         unspents.add(UnspentCoinsItem(
           address: elem.address,

From 10c235328810047a4cd64335c185caa42a5fb669 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Fri, 23 Aug 2024 17:25:33 -0400
Subject: [PATCH 73/81] more fixes

---
 cw_bitcoin/lib/litecoin_wallet.dart | 35 ++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index c5e6a6df3..5a5e3bc28 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -212,9 +212,15 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
         Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
 
     if (!mwebEnabled) {
-      await super.updateAllUnspents();
-      await updateBalance();
-      syncStatus = SyncedSyncStatus();
+      try {
+        await updateAllUnspents();
+        await updateBalance();
+        syncStatus = SyncedSyncStatus();
+      } catch (e, s) {
+        print(e);
+        print(s);
+        syncStatus = FailedSyncStatus();
+      }
       return;
     }
 
@@ -480,7 +486,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
           .firstWhere((addressRecord) => addressRecord.address == utxo.address);
       if (!inputAddresses.contains(utxo.address)) {
         addressRecord.txCount++;
-        // print("COUNT UPDATED HERE 3!!!!! ${addressRecord.address} ${addressRecord.txCount} !!!!!!");
       }
       addressRecord.balance -= utxo.value.toInt();
       amount += utxo.value.toInt();
@@ -593,13 +598,15 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     final balance = await super.fetchBalances();
     int confirmed = balance.confirmed;
     int unconfirmed = balance.unconfirmed;
-    mwebUtxosBox.values.forEach((utxo) {
-      if (utxo.height > 0) {
-        confirmed += utxo.value.toInt();
-      } else {
-        unconfirmed += utxo.value.toInt();
-      }
-    });
+    try {
+      mwebUtxosBox.values.forEach((utxo) {
+        if (utxo.height > 0) {
+          confirmed += utxo.value.toInt();
+        } else {
+          unconfirmed += utxo.value.toInt();
+        }
+      });
+    } catch (_) {}
 
     // update unspent balances:
 
@@ -609,6 +616,9 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     //     coin.bitcoinAddressRecord.balance = 0;
     //   coin.bitcoinAddressRecord.txCount = 0;
     // });
+
+    await updateUnspent();
+    
     for (var addressRecord in walletAddresses.allAddresses) {
       addressRecord.balance = 0;
       addressRecord.txCount = 0;
@@ -653,7 +663,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       }
     }
 
-    await updateUnspent();
+    
 
     return ElectrumBalance(confirmed: confirmed, unconfirmed: unconfirmed, frozen: balance.frozen);
   }
@@ -814,7 +824,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   @override
   Future<void> close() async {
     await super.close();
-    await mwebUtxosBox.close();
     _syncTimer?.cancel();
     _utxoStream?.cancel();
   }

From a0c315c4cf42a62c510c4cb14bc4e47233a1e160 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Fri, 23 Aug 2024 17:52:40 -0400
Subject: [PATCH 74/81] more fixes

---
 cw_bitcoin/lib/litecoin_wallet.dart           | 20 +++++++++++--------
 cw_bitcoin/lib/litecoin_wallet_addresses.dart | 12 ++++++++---
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 5a5e3bc28..cd20a5b24 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -88,9 +88,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     autorun((_) {
       this.walletAddresses.isEnabledAutoGenerateSubaddress = this.isEnabledAutoGenerateSubaddress;
     });
-    CwMweb.stub().then((value) {
-      _stub = value;
-    });
   }
   late final Bip32Slip10Secp256k1 mwebHd;
   late final Box<MwebUtxo> mwebUtxosBox;
@@ -201,7 +198,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   @action
   @override
   Future<void> startSync() async {
-    print("STARTING SYNC");
+    print("STARTING SYNC - MWEB ENABLED: $mwebEnabled");
     syncStatus = SyncronizingSyncStatus();
     await subscribeForUpdates();
     await updateTransactions();
@@ -211,6 +208,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     _feeRatesTimer =
         Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
 
+
     if (!mwebEnabled) {
       try {
         await updateAllUnspents();
@@ -224,10 +222,10 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       return;
     }
 
+    await getStub();
     await updateUnspent();
     await updateBalance();
 
-    _stub = await CwMweb.stub();
     _syncTimer?.cancel();
     _syncTimer = Timer.periodic(const Duration(milliseconds: 1500), (timer) async {
       if (syncStatus is FailedSyncStatus) return;
@@ -596,6 +594,10 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   @override
   Future<ElectrumBalance> fetchBalances() async {
     final balance = await super.fetchBalances();
+    if (!mwebEnabled) {
+      return balance;
+    }
+    
     int confirmed = balance.confirmed;
     int unconfirmed = balance.unconfirmed;
     try {
@@ -618,7 +620,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     // });
 
     await updateUnspent();
-    
+
     for (var addressRecord in walletAddresses.allAddresses) {
       addressRecord.balance = 0;
       addressRecord.txCount = 0;
@@ -663,8 +665,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       }
     }
 
-    
-
     return ElectrumBalance(confirmed: confirmed, unconfirmed: unconfirmed, frozen: balance.frozen);
   }
 
@@ -835,6 +835,10 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
 
     mwebEnabled = enabled;
     (walletAddresses as LitecoinWalletAddresses).mwebEnabled = enabled;
+    if (enabled) {
+      // generate inital mweb addresses:
+      (walletAddresses as LitecoinWalletAddresses).topUpMweb(0);
+    }
     stopSync();
     startSync();
   }
diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
index 24cdd04d8..12140472c 100644
--- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
@@ -24,7 +24,9 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
     super.initialRegularAddressIndex,
     super.initialChangeAddressIndex,
   }) : super(walletInfo) {
-    topUpMweb(0);
+    if (mwebEnabled) {
+      topUpMweb(0);
+    }
   }
 
   final Bip32Slip10Secp256k1 mwebHd;
@@ -58,7 +60,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
     required Bip32Slip10Secp256k1 hd,
     BitcoinAddressType? addressType,
   }) {
-    if (addressType == SegwitAddresType.mweb) {
+    if (addressType == SegwitAddresType.mweb && mwebEnabled) {
       topUpMweb(index);
       return hd == sideHd ? mwebAddrs[0] : mwebAddrs[index + 1];
     }
@@ -71,7 +73,11 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
     required Bip32Slip10Secp256k1 hd,
     BitcoinAddressType? addressType,
   }) async {
-    if (addressType == SegwitAddresType.mweb) {
+    // if mweb isn't enabled we'll just return the regular address type which does effectively nothing
+    // sort of a hack but easier than trying to pull the mweb setting into the electrum_wallet_addresses initialization code
+    // (we want to avoid initializing the mweb.stub() if it's not enabled or we'd be starting the whole server for no reason and it's slow)
+    // TODO: find a way to do address generation without starting the whole mweb server
+    if (addressType == SegwitAddresType.mweb && mwebEnabled) {
       await topUpMweb(index);
     }
     return getAddress(index: index, hd: hd, addressType: addressType);

From 2552fb9552ff48379baefb220e759f44b2f334c4 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Fri, 23 Aug 2024 18:04:26 -0400
Subject: [PATCH 75/81] ensure we don't initialize mweb until we really have to

---
 cw_bitcoin/lib/litecoin_wallet.dart | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index cd20a5b24..ea3c395cc 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -208,7 +208,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     _feeRatesTimer =
         Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
 
-
     if (!mwebEnabled) {
       try {
         await updateAllUnspents();
@@ -556,6 +555,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     if (!mwebEnabled) {
       return;
     }
+    await getStub();
+
     // add the mweb unspents to the list:
     List<BitcoinUnspent> mwebUnspentCoins = [];
     // update mweb unspents:
@@ -597,7 +598,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     if (!mwebEnabled) {
       return balance;
     }
-    
+    await getStub();
+
     int confirmed = balance.confirmed;
     int unconfirmed = balance.unconfirmed;
     try {
@@ -758,6 +760,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       if (!mwebEnabled) {
         return tx;
       }
+      await getStub();
 
       final resp = await _stub.create(CreateRequest(
         rawTx: hex.decode(tx.hex),

From 8524e238b0b726ed5b71ebc38ae3b8d0477b2f66 Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Sat, 24 Aug 2024 03:42:50 +0200
Subject: [PATCH 76/81] make analyzer less red (#1628)

* remove cw_*.dart files from analyzer

* Run gen_framework.sh on iOS
---
 analysis_options.yaml                | 13 ++++++++++++-
 tool/download_moneroc_prebuilds.dart | 10 ++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/analysis_options.yaml b/analysis_options.yaml
index 396904041..2063b5a8c 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -10,7 +10,18 @@ analyzer:
     lib/generated/*.dart,
     cw_monero/ios/External/**,
     cw_shared_external/**,
-    shared_external/**]
+    shared_external/**,
+    lib/bitcoin/cw_bitcoin.dart,
+    lib/bitcoin_cash/cw_bitcoin_cash.dart,
+    lib/ethereum/cw_ethereum.dart,
+    lib/haven/cw_haven.dart,
+    lib/monero/cw_monero.dart,
+    lib/nano/cw_nano.dart,
+    lib/polygon/cw_polygon.dart,
+    lib/solana/cw_solana.dart,
+    lib/tron/cw_tron.dart,
+    lib/wownero/cw_wownero.dart,
+    ]
   language:
     strict-casts: true
     strict-raw-types: true
diff --git a/tool/download_moneroc_prebuilds.dart b/tool/download_moneroc_prebuilds.dart
index 58e8d4b03..9df0b4e7b 100644
--- a/tool/download_moneroc_prebuilds.dart
+++ b/tool/download_moneroc_prebuilds.dart
@@ -1,3 +1,5 @@
+import 'dart:io';
+
 import 'package:dio/dio.dart';
 import 'package:archive/archive_io.dart';
 
@@ -47,4 +49,12 @@ Future<void> main() async {
       outputStream.writeBytes(archive);
     }
   }
+  if (Platform.isMacOS) {
+    print("Generating ios framework");
+    final result = Process.runSync("bash", [
+      "-c",
+      "cd scripts/ios && ./gen_framework.sh && cd ../.."
+    ]);
+    print((result.stdout+result.stderr).toString().trim());
+  }
 }
\ No newline at end of file

From 40f85d215b2a4064c3586ededd57dba67336af4e Mon Sep 17 00:00:00 2001
From: Serhii <borodenko.sv@gmail.com>
Date: Sat, 24 Aug 2024 16:30:01 +0300
Subject: [PATCH 77/81] Rbf fixes issues op return data plus ThorChain (#1648)

* total out amount issue

* fix empty inputs and outputs addresses for new tx

* fix sum value of utxo not spending

* Update configure.dart

* Update electrum_wallet.dart

* receiving address

* review fixes

* add op_return data

* fix rbf transaction with a memo

* add memo check for ThorChain trade

* code enhancement [skip ci]

* code enhancement [skip ci]

* directly use fromElectrumBundle function to update transaction info

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 cw_bitcoin/lib/electrum_transaction_info.dart | 23 ++++++++-
 cw_bitcoin/lib/electrum_wallet.dart           | 48 +++++++++++--------
 .../exchange/exchange_view_model.dart         |  7 +++
 .../transaction_details_view_model.dart       | 11 ++++-
 4 files changed, 65 insertions(+), 24 deletions(-)

diff --git a/cw_bitcoin/lib/electrum_transaction_info.dart b/cw_bitcoin/lib/electrum_transaction_info.dart
index ee3daa0e0..ebd90ff2b 100644
--- a/cw_bitcoin/lib/electrum_transaction_info.dart
+++ b/cw_bitcoin/lib/electrum_transaction_info.dart
@@ -1,3 +1,5 @@
+import 'dart:convert';
+
 import 'package:bitcoin_base/bitcoin_base.dart';
 import 'package:cw_bitcoin/address_from_output.dart';
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
@@ -7,10 +9,12 @@ import 'package:cw_core/transaction_direction.dart';
 import 'package:cw_core/transaction_info.dart';
 import 'package:cw_core/format_amount.dart';
 import 'package:cw_core/wallet_type.dart';
+import 'package:hex/hex.dart';
 
 class ElectrumTransactionBundle {
   ElectrumTransactionBundle(this.originalTransaction,
       {required this.ins, required this.confirmations, this.time});
+
   final BtcTransaction originalTransaction;
   final List<BtcTransaction> ins;
   final int? time;
@@ -125,7 +129,24 @@ class ElectrumTransactionInfo extends TransactionInfo {
     for (final out in bundle.originalTransaction.outputs) {
       totalOutAmount += out.amount.toInt();
       final addressExists = addresses.contains(addressFromOutputScript(out.scriptPubKey, network));
-      outputAddresses.add(addressFromOutputScript(out.scriptPubKey, network));
+      final address = addressFromOutputScript(out.scriptPubKey, network);
+
+      if (address.isNotEmpty) outputAddresses.add(address);
+
+      // Check if the script contains OP_RETURN
+      final script = out.scriptPubKey.script;
+      if (script.contains('OP_RETURN')) {
+        final index = script.indexOf('OP_RETURN');
+        if (index + 1 <= script.length) {
+          try {
+            final opReturnData = script[index + 1].toString();
+            final decodedString = utf8.decode(HEX.decode(opReturnData));
+            outputAddresses.add('OP_RETURN:$decodedString');
+          } catch (_) {
+            outputAddresses.add('OP_RETURN:');
+          }
+        }
+      }
 
       if (addressExists) {
         receivedAmounts.add(out.amount.toInt());
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 2a57c8d5c..b763b175b 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -43,6 +43,7 @@ import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:rxdart/subjects.dart';
 import 'package:sp_scanner/sp_scanner.dart';
+import 'package:hex/hex.dart';
 
 part 'electrum_wallet.g.dart';
 
@@ -1413,6 +1414,7 @@ abstract class ElectrumWalletBase
       List<ECPrivate> privateKeys = [];
 
       var allInputsAmount = 0;
+      String? memo;
 
       // Add inputs
       for (var i = 0; i < bundle.originalTransaction.inputs.length; i++) {
@@ -1451,6 +1453,22 @@ abstract class ElectrumWalletBase
       // Create a list of available outputs
       final outputs = <BitcoinOutput>[];
       for (final out in bundle.originalTransaction.outputs) {
+
+        // Check if the script contains OP_RETURN
+        final script = out.scriptPubKey.script;
+        if (script.contains('OP_RETURN') && memo == null) {
+          final index = script.indexOf('OP_RETURN');
+          if (index + 1 <= script.length) {
+            try {
+              final opReturnData = script[index + 1].toString();
+              memo = utf8.decode(HEX.decode(opReturnData));
+              continue;
+            } catch (_) {
+              throw Exception('Cannot decode OP_RETURN data');
+            }
+          }
+        }
+
         final address = addressFromOutputScript(out.scriptPubKey, network);
         final btcAddress = addressTypeFromStr(address, network);
         outputs.add(BitcoinOutput(address: btcAddress, value: BigInt.from(out.amount.toInt())));
@@ -1507,6 +1525,8 @@ abstract class ElectrumWalletBase
         outputs: outputs,
         fee: BigInt.from(newFee),
         network: network,
+        memo: memo,
+        outputOrdering: BitcoinOrdering.none,
         enableRBF: true,
       );
 
@@ -2036,27 +2056,13 @@ abstract class ElectrumWalletBase
         tx.inputAddresses!.isEmpty ||
         tx.outputAddresses == null ||
         tx.outputAddresses!.isEmpty) {
-      List<String> inputAddresses = [];
-      List<String> outputAddresses = [];
-
-      for (int i = 0; i < bundle.originalTransaction.inputs.length; i++) {
-        final input = bundle.originalTransaction.inputs[i];
-        final inputTransaction = bundle.ins[i];
-        final vout = input.txIndex;
-        final outTransaction = inputTransaction.outputs[vout];
-        final address = addressFromOutputScript(outTransaction.scriptPubKey, network);
-
-        if (address.isNotEmpty) inputAddresses.add(address);
-      }
-
-      for (int i = 0; i < bundle.originalTransaction.outputs.length; i++) {
-        final out = bundle.originalTransaction.outputs[i];
-        final address = addressFromOutputScript(out.scriptPubKey, network);
-
-        if (address.isNotEmpty) outputAddresses.add(address);
-      }
-      tx.inputAddresses = inputAddresses;
-      tx.outputAddresses = outputAddresses;
+      tx = ElectrumTransactionInfo.fromElectrumBundle(
+        bundle,
+        walletInfo.type,
+        network,
+        addresses: addressesSet,
+        height: tx.height,
+      );
 
       transactionHistory.addOne(tx);
     }
diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart
index f2ea8eeb4..2bbe9954e 100644
--- a/lib/view_model/exchange/exchange_view_model.dart
+++ b/lib/view_model/exchange/exchange_view_model.dart
@@ -845,6 +845,13 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
         );
       }
 
+      if ((trade.memo == null || trade.memo!.isEmpty)) {
+        return CreateTradeResult(
+          result: false,
+          errorMessage: 'Memo is required for Thorchain trade',
+        );
+      }
+
       final currenciesToCheckPattern = RegExp('0x[0-9a-zA-Z]');
 
       // Perform checks for payOutAddress
diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart
index aa63ce860..e4f9c3786 100644
--- a/lib/view_model/transaction_details_view_model.dart
+++ b/lib/view_model/transaction_details_view_model.dart
@@ -392,8 +392,15 @@ abstract class TransactionDetailsViewModelBase with Store {
     }
 
     if (transactionInfo.outputAddresses != null && transactionInfo.outputAddresses!.isNotEmpty) {
-      RBFListItems.add(StandardExpandableListItem(
-          title: S.current.outputs, expandableItems: transactionInfo.outputAddresses!));
+      final outputAddresses = transactionInfo.outputAddresses!.map((element) {
+        if (element.contains('OP_RETURN:') && element.length > 40) {
+            return element.substring(0, 40) + '...';
+        }
+        return element;
+      }).toList();
+
+      RBFListItems.add(
+          StandardExpandableListItem(title: S.current.outputs, expandableItems: outputAddresses));
     }
   }
 

From ce21098e9824edf4f8d828f127e4d1aaeefee213 Mon Sep 17 00:00:00 2001
From: Konstantin Ullrich <konstantinullrich12@gmail.com>
Date: Mon, 26 Aug 2024 19:06:54 +0200
Subject: [PATCH 78/81] Cw 488 seed offset (#1631)

* CW-488 minor code cleanup

* Add Derivation Path selector for BTC and LTC

* CW-488 Initial Passphrase Impl

* CW-488 Final Passphrase Impl

* Quick Fix of language Service

* CW-488 Implement PR Suggestions

* CW-488 Implement PR Suggestions

* CW-488 Implement Passphrase for Bitcoin Cash

* CW-488 Implement Passphrase for Bitcoin Cash

* CW-488 Implement Passphrase for Bitcoin Cash

* remove monero and wownero support for passphrase until merged [skip ci]

* CW-488 Apply requested change

* CW-488 Add Passphrase to QR

* CW-488 Fix Seed generation

* CW-488 Implement Electrum Passphrases

* CW-488 Add Seed Length Selector to BIP39 Seeds

* CW-488 Minor fix [skip ci]

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 cw_bitcoin/lib/bitcoin_mnemonic.dart          |  18 +-
 .../lib/bitcoin_mnemonics_bip39.dart          |   3 +-
 cw_bitcoin/lib/bitcoin_wallet.dart            |   4 +-
 .../bitcoin_wallet_creation_credentials.dart  |  16 +-
 cw_bitcoin/lib/bitcoin_wallet_service.dart    |  16 +-
 cw_bitcoin/lib/electrum_derivations.dart      |   3 +-
 cw_bitcoin/lib/electrum_wallet.dart           |   2 +
 cw_bitcoin/lib/litecoin_wallet.dart           |  34 +++-
 cw_bitcoin/lib/litecoin_wallet_service.dart   |  16 +-
 .../lib/src/bitcoin_cash_base.dart            |   1 -
 .../lib/src/bitcoin_cash_wallet.dart          |  14 +-
 ...coin_cash_wallet_creation_credentials.dart |  18 +-
 .../lib/src/bitcoin_cash_wallet_service.dart  |  30 ++--
 cw_core/lib/wallet_base.dart                  |   2 +
 lib/bitcoin/cw_bitcoin.dart                   |  11 +-
 lib/bitcoin_cash/cw_bitcoin_cash.dart         |   8 +-
 lib/core/wallet_creation_service.dart         |   6 +-
 lib/di.dart                                   |  34 ++--
 lib/entities/language_service.dart            |   2 +-
 lib/entities/preferences_key.dart             |   1 +
 lib/entities/seed_type.dart                   |  46 +++--
 lib/router.dart                               |  97 +++++------
 .../dashboard/widgets/verify_form.dart        |  16 --
 .../advanced_privacy_settings_page.dart       | 140 ++++++++++-----
 .../screens/new_wallet/new_wallet_page.dart   |  61 ++++---
 .../wallet_restore_from_seed_form.dart        | 164 ++++++++++--------
 .../screens/restore/wallet_restore_page.dart  |  13 +-
 lib/src/widgets/seed_language_picker.dart     |  34 ++--
 lib/src/widgets/seed_language_selector.dart   |   4 +-
 lib/store/seed_settings_store.dart            |  11 ++
 lib/store/settings_store.dart                 |  77 +++++---
 .../advanced_privacy_settings_view_model.dart |  18 +-
 .../restore/restore_from_qr_vm.dart           |   5 +-
 lib/view_model/seed_settings_view_model.dart  |  34 ++++
 lib/view_model/seed_type_view_model.dart      |  19 --
 lib/view_model/wallet_creation_vm.dart        |  42 +++--
 .../wallet_hardware_restore_view_model.dart   |  12 +-
 lib/view_model/wallet_keys_view_model.dart    |   3 +-
 lib/view_model/wallet_new_vm.dart             |  66 ++++---
 lib/view_model/wallet_restore_view_model.dart |  40 +++--
 res/values/strings_ar.arb                     |   1 +
 res/values/strings_bg.arb                     |   1 +
 res/values/strings_cs.arb                     |   1 +
 res/values/strings_de.arb                     |   1 +
 res/values/strings_en.arb                     |   1 +
 res/values/strings_es.arb                     |   1 +
 res/values/strings_fr.arb                     |   1 +
 res/values/strings_ha.arb                     |   1 +
 res/values/strings_hi.arb                     |   1 +
 res/values/strings_hr.arb                     |   1 +
 res/values/strings_id.arb                     |   1 +
 res/values/strings_it.arb                     |   1 +
 res/values/strings_ja.arb                     |   1 +
 res/values/strings_ko.arb                     |   1 +
 res/values/strings_my.arb                     |   1 +
 res/values/strings_nl.arb                     |   1 +
 res/values/strings_pl.arb                     |   1 +
 res/values/strings_pt.arb                     |   1 +
 res/values/strings_ru.arb                     |   1 +
 res/values/strings_th.arb                     |   1 +
 res/values/strings_tl.arb                     |   7 +-
 res/values/strings_tr.arb                     |   1 +
 res/values/strings_uk.arb                     |   1 +
 res/values/strings_ur.arb                     |   1 +
 res/values/strings_yo.arb                     |   1 +
 res/values/strings_zh.arb                     |   1 +
 tool/configure.dart                           |   6 +-
 67 files changed, 741 insertions(+), 438 deletions(-)
 rename cw_bitcoin_cash/lib/src/mnemonic.dart => cw_bitcoin/lib/bitcoin_mnemonics_bip39.dart (65%)
 create mode 100644 lib/store/seed_settings_store.dart
 create mode 100644 lib/view_model/seed_settings_view_model.dart
 delete mode 100644 lib/view_model/seed_type_view_model.dart

diff --git a/cw_bitcoin/lib/bitcoin_mnemonic.dart b/cw_bitcoin/lib/bitcoin_mnemonic.dart
index 905aece28..0749627e9 100644
--- a/cw_bitcoin/lib/bitcoin_mnemonic.dart
+++ b/cw_bitcoin/lib/bitcoin_mnemonic.dart
@@ -1,6 +1,7 @@
 import 'dart:convert';
 import 'dart:math';
 import 'dart:typed_data';
+
 import 'package:crypto/crypto.dart';
 import 'package:cryptography/cryptography.dart' as cryptography;
 import 'package:cw_core/sec_random_native.dart';
@@ -59,11 +60,7 @@ void maskBytes(Uint8List bytes, int bits) {
   }
 }
 
-String bufferToBin(Uint8List data) {
-  final q1 = data.map((e) => e.toRadixString(2).padLeft(8, '0'));
-  final q2 = q1.join('');
-  return q2;
-}
+String bufferToBin(Uint8List data) => data.map((e) => e.toRadixString(2).padLeft(8, '0')).join('');
 
 String encode(Uint8List data) {
   final dataBitLen = data.length * 8;
@@ -112,17 +109,18 @@ Future<bool> checkIfMnemonicIsElectrum2(String mnemonic) async {
 Future<String> getMnemonicHash(String mnemonic) async {
   final hmacSha512 = Hmac(sha512, utf8.encode('Seed version'));
   final digest = hmacSha512.convert(utf8.encode(normalizeText(mnemonic)));
-  final hx = digest.toString();
-  return hx;
+  return digest.toString();
 }
 
-Future<Uint8List> mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) async {
+Future<Uint8List> mnemonicToSeedBytes(String mnemonic,
+    {String prefix = segwit, String passphrase = ''}) async {
   final pbkdf2 =
       cryptography.Pbkdf2(macAlgorithm: cryptography.Hmac.sha512(), iterations: 2048, bits: 512);
   final text = normalizeText(mnemonic);
-  // pbkdf2.deriveKey(secretKey: secretKey, nonce: nonce)
+  final passphraseBytes = utf8.encode(normalizeText(passphrase));
   final key = await pbkdf2.deriveKey(
-      secretKey: cryptography.SecretKey(text.codeUnits), nonce: 'electrum'.codeUnits);
+      secretKey: cryptography.SecretKey(text.codeUnits),
+      nonce: [...'electrum'.codeUnits, ...passphraseBytes]);
   final bytes = await key.extractBytes();
   return Uint8List.fromList(bytes);
 }
diff --git a/cw_bitcoin_cash/lib/src/mnemonic.dart b/cw_bitcoin/lib/bitcoin_mnemonics_bip39.dart
similarity index 65%
rename from cw_bitcoin_cash/lib/src/mnemonic.dart
rename to cw_bitcoin/lib/bitcoin_mnemonics_bip39.dart
index 7aac1d5c4..ff02e875c 100644
--- a/cw_bitcoin_cash/lib/src/mnemonic.dart
+++ b/cw_bitcoin/lib/bitcoin_mnemonics_bip39.dart
@@ -7,5 +7,6 @@ class MnemonicBip39 {
   static String generate({int strength = 128}) => bip39.generateMnemonic(strength: strength);
 
   /// Create root seed from mnemonic
-  static Uint8List toSeed(String mnemonic) => bip39.mnemonicToSeed(mnemonic);
+  static Uint8List toSeed(String mnemonic, {String? passphrase}) =>
+      bip39.mnemonicToSeed(mnemonic, passphrase: passphrase ?? '');
 }
diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart
index e2e537ee8..30f04667a 100644
--- a/cw_bitcoin/lib/bitcoin_wallet.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet.dart
@@ -115,7 +115,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
         break;
       case DerivationType.electrum:
       default:
-        seedBytes = await mnemonicToSeedBytes(mnemonic);
+        seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
         break;
     }
     return BitcoinWallet(
@@ -195,7 +195,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
     if (mnemonic != null) {
       switch (walletInfo.derivationInfo!.derivationType) {
         case DerivationType.electrum:
-          seedBytes = await mnemonicToSeedBytes(mnemonic);
+          seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
           break;
         case DerivationType.bip39:
         default:
diff --git a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
index 91b8e4ae2..5c276390a 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
@@ -3,16 +3,18 @@ import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 
 class BitcoinNewWalletCredentials extends WalletCredentials {
-  BitcoinNewWalletCredentials(
-      {required String name,
-      WalletInfo? walletInfo,
-      String? password,
-      DerivationType? derivationType,
-      String? derivationPath})
-      : super(
+  BitcoinNewWalletCredentials({
+    required String name,
+    WalletInfo? walletInfo,
+    String? password,
+    DerivationType? derivationType,
+    String? derivationPath,
+    String? passphrase,
+  }) : super(
           name: name,
           walletInfo: walletInfo,
           password: password,
+          passphrase: passphrase,
         );
 }
 
diff --git a/cw_bitcoin/lib/bitcoin_wallet_service.dart b/cw_bitcoin/lib/bitcoin_wallet_service.dart
index d6d97f3de..9f67f7807 100644
--- a/cw_bitcoin/lib/bitcoin_wallet_service.dart
+++ b/cw_bitcoin/lib/bitcoin_wallet_service.dart
@@ -1,6 +1,7 @@
 import 'dart:io';
 import 'package:bitcoin_base/bitcoin_base.dart';
 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
+import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart';
 import 'package:cw_bitcoin/mnemonic_is_incorrect_exception.dart';
 import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart';
 import 'package:cw_core/encryption_file_utils.dart';
@@ -35,8 +36,21 @@ class BitcoinWalletService extends WalletService<
     final network = isTestnet == true ? BitcoinNetwork.testnet : BitcoinNetwork.mainnet;
     credentials.walletInfo?.network = network.value;
 
+    final String mnemonic;
+    switch ( credentials.walletInfo?.derivationInfo?.derivationType) {
+      case DerivationType.bip39:
+        final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
+
+        mnemonic = await MnemonicBip39.generate(strength: strength);
+        break;
+      case DerivationType.electrum:
+      default:
+        mnemonic = await generateElectrumMnemonic();
+        break;
+    }
+
     final wallet = await BitcoinWalletBase.create(
-      mnemonic: await generateElectrumMnemonic(),
+      mnemonic: mnemonic,
       password: credentials.password!,
       passphrase: credentials.passphrase,
       walletInfo: credentials.walletInfo!,
diff --git a/cw_bitcoin/lib/electrum_derivations.dart b/cw_bitcoin/lib/electrum_derivations.dart
index 749e5c7af..81a3626d2 100644
--- a/cw_bitcoin/lib/electrum_derivations.dart
+++ b/cw_bitcoin/lib/electrum_derivations.dart
@@ -109,5 +109,4 @@ Map<DerivationType, List<DerivationInfo>> electrum_derivations = {
   ],
 };
 
-
-String electrum_path = electrum_derivations[DerivationType.electrum]!.first.derivationPath!;
\ No newline at end of file
+String electrum_path = electrum_derivations[DerivationType.electrum]!.first.derivationPath!;
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index b763b175b..0ce4844c6 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -137,6 +137,8 @@ abstract class ElectrumWalletBase
   Bip32Slip10Secp256k1 get sideHd => accountHD.childKey(Bip32KeyIndex(1));
 
   final EncryptionFileUtils encryptionFileUtils;
+
+  @override
   final String? passphrase;
 
   @override
diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 890d98342..12a43dbe6 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -7,6 +7,7 @@ import 'package:bip39/bip39.dart' as bip39;
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
 import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
+import 'package:cw_bitcoin/electrum_derivations.dart';
 import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/unspent_coins_info.dart';
@@ -36,6 +37,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     required Box<UnspentCoinsInfo> unspentCoinsInfo,
     required Uint8List seedBytes,
     required EncryptionFileUtils encryptionFileUtils,
+    String? passphrase,
     String? addressPageType,
     List<BitcoinAddressRecord>? initialAddresses,
     ElectrumBalance? initialBalance,
@@ -51,6 +53,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
             initialBalance: initialBalance,
             seedBytes: seedBytes,
             encryptionFileUtils: encryptionFileUtils,
+            passphrase: passphrase,
             currency: CryptoCurrency.ltc) {
     walletAddresses = LitecoinWalletAddresses(
       walletInfo,
@@ -89,7 +92,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
         break;
       case DerivationType.electrum:
       default:
-        seedBytes = await mnemonicToSeedBytes(mnemonic);
+        seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
         break;
     }
     return LitecoinWallet(
@@ -100,6 +103,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       initialAddresses: initialAddresses,
       initialBalance: initialBalance,
       encryptionFileUtils: encryptionFileUtils,
+      passphrase: passphrase,
       seedBytes: seedBytes,
       initialRegularAddressIndex: initialRegularAddressIndex,
       initialChangeAddressIndex: initialChangeAddressIndex,
@@ -143,6 +147,31 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       );
     }
 
+    walletInfo.derivationInfo ??= DerivationInfo();
+
+    // set the default if not present:
+    walletInfo.derivationInfo!.derivationPath ??= snp?.derivationPath ?? electrum_path;
+    walletInfo.derivationInfo!.derivationType ??= snp?.derivationType ?? DerivationType.electrum;
+
+    Uint8List? seedBytes = null;
+    final mnemonic = keysData.mnemonic;
+    final passphrase = keysData.passphrase;
+
+    if (mnemonic != null) {
+      switch (walletInfo.derivationInfo?.derivationType) {
+        case DerivationType.bip39:
+          seedBytes = await bip39.mnemonicToSeed(
+            mnemonic,
+            passphrase: passphrase ?? "",
+          );
+          break;
+        case DerivationType.electrum:
+        default:
+          seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
+          break;
+      }
+    }
+
     return LitecoinWallet(
       mnemonic: keysData.mnemonic!,
       password: password,
@@ -150,7 +179,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
       unspentCoinsInfo: unspentCoinsInfo,
       initialAddresses: snp?.addresses,
       initialBalance: snp?.balance,
-      seedBytes: await mnemonicToSeedBytes(keysData.mnemonic!),
+      seedBytes: seedBytes!,
+      passphrase: passphrase,
       encryptionFileUtils: encryptionFileUtils,
       initialRegularAddressIndex: snp?.regularAddressIndex,
       initialChangeAddressIndex: snp?.changeAddressIndex,
diff --git a/cw_bitcoin/lib/litecoin_wallet_service.dart b/cw_bitcoin/lib/litecoin_wallet_service.dart
index a46b12a2e..c13265934 100644
--- a/cw_bitcoin/lib/litecoin_wallet_service.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_service.dart
@@ -1,4 +1,5 @@
 import 'dart:io';
+import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart';
 import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:hive/hive.dart';
@@ -30,8 +31,21 @@ class LitecoinWalletService extends WalletService<
 
   @override
   Future<LitecoinWallet> create(BitcoinNewWalletCredentials credentials, {bool? isTestnet}) async {
+    final String mnemonic;
+    switch ( credentials.walletInfo?.derivationInfo?.derivationType) {
+      case DerivationType.bip39:
+        final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
+
+        mnemonic = await MnemonicBip39.generate(strength: strength);
+        break;
+      case DerivationType.electrum:
+      default:
+        mnemonic = await generateElectrumMnemonic();
+        break;
+    }
+
     final wallet = await LitecoinWalletBase.create(
-      mnemonic: await generateElectrumMnemonic(),
+      mnemonic: mnemonic,
       password: credentials.password!,
       passphrase: credentials.passphrase,
       walletInfo: credentials.walletInfo!,
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_base.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_base.dart
index 4699b1649..950b440e7 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_base.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_base.dart
@@ -3,5 +3,4 @@ export 'bitcoin_cash_wallet_addresses.dart';
 export 'bitcoin_cash_wallet_creation_credentials.dart';
 export 'bitcoin_cash_wallet_service.dart';
 export 'exceptions/exceptions.dart';
-export 'mnemonic.dart';
 export 'bitcoin_cash_address_utils.dart';
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
index 5659528c0..b1e5e7bf6 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
@@ -1,13 +1,14 @@
 import 'package:bitbox/bitbox.dart' as bitbox;
 import 'package:bitcoin_base/bitcoin_base.dart';
 import 'package:blockchain_utils/blockchain_utils.dart';
-import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_bitcoin/bitcoin_address_record.dart';
+import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart';
 import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
 import 'package:cw_bitcoin/electrum_balance.dart';
 import 'package:cw_bitcoin/electrum_wallet.dart';
 import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
 import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/transaction_priority.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_info.dart';
@@ -30,6 +31,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
     required Box<UnspentCoinsInfo> unspentCoinsInfo,
     required Uint8List seedBytes,
     required EncryptionFileUtils encryptionFileUtils,
+    String? passphrase,
     BitcoinAddressType? addressPageType,
     List<BitcoinAddressRecord>? initialAddresses,
     ElectrumBalance? initialBalance,
@@ -45,7 +47,8 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
             initialBalance: initialBalance,
             seedBytes: seedBytes,
             currency: CryptoCurrency.bch,
-            encryptionFileUtils: encryptionFileUtils) {
+            encryptionFileUtils: encryptionFileUtils,
+            passphrase: passphrase) {
     walletAddresses = BitcoinCashWalletAddresses(
       walletInfo,
       initialAddresses: initialAddresses,
@@ -67,6 +70,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
       required WalletInfo walletInfo,
       required Box<UnspentCoinsInfo> unspentCoinsInfo,
       required EncryptionFileUtils encryptionFileUtils,
+      String? passphrase,
       String? addressPageType,
       List<BitcoinAddressRecord>? initialAddresses,
       ElectrumBalance? initialBalance,
@@ -79,11 +83,12 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
       unspentCoinsInfo: unspentCoinsInfo,
       initialAddresses: initialAddresses,
       initialBalance: initialBalance,
-      seedBytes: await MnemonicBip39.toSeed(mnemonic),
+      seedBytes: await MnemonicBip39.toSeed(mnemonic, passphrase: passphrase),
       encryptionFileUtils: encryptionFileUtils,
       initialRegularAddressIndex: initialRegularAddressIndex,
       initialChangeAddressIndex: initialChangeAddressIndex,
       addressPageType: P2pkhAddressType.p2pkh,
+      passphrase: passphrase,
     );
   }
 
@@ -150,11 +155,12 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
         }
       }).toList(),
       initialBalance: snp?.balance,
-      seedBytes: await MnemonicBip39.toSeed(keysData.mnemonic!),
+      seedBytes: await MnemonicBip39.toSeed(keysData.mnemonic!, passphrase: keysData.passphrase),
       encryptionFileUtils: encryptionFileUtils,
       initialRegularAddressIndex: snp?.regularAddressIndex,
       initialChangeAddressIndex: snp?.changeAddressIndex,
       addressPageType: P2pkhAddressType.p2pkh,
+      passphrase: keysData.passphrase,
     );
   }
 
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_creation_credentials.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_creation_credentials.dart
index 017040c5d..bb93656f1 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_creation_credentials.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_creation_credentials.dart
@@ -2,17 +2,19 @@ import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 
 class BitcoinCashNewWalletCredentials extends WalletCredentials {
-  BitcoinCashNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password})
-      : super(name: name, walletInfo: walletInfo, password: password);
+  BitcoinCashNewWalletCredentials(
+      {required String name, WalletInfo? walletInfo, String? password, String? passphrase})
+      : super(name: name, walletInfo: walletInfo, password: password, passphrase: passphrase);
 }
 
 class BitcoinCashRestoreWalletFromSeedCredentials extends WalletCredentials {
-  BitcoinCashRestoreWalletFromSeedCredentials(
-      {required String name,
-      required String password,
-      required this.mnemonic,
-      WalletInfo? walletInfo})
-      : super(name: name, password: password, walletInfo: walletInfo);
+  BitcoinCashRestoreWalletFromSeedCredentials({
+    required String name,
+    required String password,
+    required this.mnemonic,
+    WalletInfo? walletInfo,
+    String? passphrase,
+  }) : super(name: name, password: password, walletInfo: walletInfo, passphrase: passphrase);
 
   final String mnemonic;
 }
diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
index a970be261..f004356b5 100644
--- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
+++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
@@ -1,6 +1,8 @@
 import 'dart:io';
 
 import 'package:bip39/bip39.dart';
+import 'package:collection/collection.dart';
+import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart';
 import 'package:cw_bitcoin_cash/cw_bitcoin_cash.dart';
 import 'package:cw_core/encryption_file_utils.dart';
 import 'package:cw_core/pathForWallet.dart';
@@ -9,7 +11,6 @@ import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/wallet_type.dart';
-import 'package:collection/collection.dart';
 import 'package:hive/hive.dart';
 
 class BitcoinCashWalletService extends WalletService<
@@ -35,11 +36,12 @@ class BitcoinCashWalletService extends WalletService<
     final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
 
     final wallet = await BitcoinCashWalletBase.create(
-        mnemonic: await MnemonicBip39.generate(strength: strength),
+      mnemonic: await MnemonicBip39.generate(strength: strength),
       password: credentials.password!,
       walletInfo: credentials.walletInfo!,
       unspentCoinsInfo: unspentCoinsInfoSource,
       encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+      passphrase: credentials.passphrase,
     );
     await wallet.save();
     await wallet.init();
@@ -54,11 +56,11 @@ class BitcoinCashWalletService extends WalletService<
 
     try {
       final wallet = await BitcoinCashWalletBase.open(
-          password: password,
-          name: name,
-          walletInfo: walletInfo,
-          unspentCoinsInfo: unspentCoinsInfoSource,
-          encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+        password: password,
+        name: name,
+        walletInfo: walletInfo,
+        unspentCoinsInfo: unspentCoinsInfoSource,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
       await wallet.init();
       saveBackup(name);
@@ -66,11 +68,11 @@ class BitcoinCashWalletService extends WalletService<
     } catch (_) {
       await restoreWalletFilesFromBackup(name);
       final wallet = await BitcoinCashWalletBase.open(
-          password: password,
-          name: name,
-          walletInfo: walletInfo,
-          unspentCoinsInfo: unspentCoinsInfoSource,
-          encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+        password: password,
+        name: name,
+        walletInfo: walletInfo,
+        unspentCoinsInfo: unspentCoinsInfoSource,
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
       );
       await wallet.init();
       return wallet;
@@ -130,7 +132,9 @@ class BitcoinCashWalletService extends WalletService<
         mnemonic: credentials.mnemonic,
         walletInfo: credentials.walletInfo!,
         unspentCoinsInfo: unspentCoinsInfoSource,
-        encryptionFileUtils: encryptionFileUtilsFor(isDirect));
+        encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+        passphrase: credentials.passphrase
+    );
     await wallet.save();
     await wallet.init();
     return wallet;
diff --git a/cw_core/lib/wallet_base.dart b/cw_core/lib/wallet_base.dart
index f55816bb7..48ea90f7c 100644
--- a/cw_core/lib/wallet_base.dart
+++ b/cw_core/lib/wallet_base.dart
@@ -46,6 +46,8 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
 
   String? get hexSeed => null;
 
+  String? get passphrase => null;
+
   Object get keys;
 
   WalletAddresses get walletAddresses;
diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart
index d979f9281..c016c1f2a 100644
--- a/lib/bitcoin/cw_bitcoin.dart
+++ b/lib/bitcoin/cw_bitcoin.dart
@@ -29,8 +29,9 @@ class CWBitcoin extends Bitcoin {
 
   @override
   WalletCredentials createBitcoinNewWalletCredentials(
-          {required String name, WalletInfo? walletInfo, String? password}) =>
-      BitcoinNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
+          {required String name, WalletInfo? walletInfo, String? password, String? passphrase}) =>
+      BitcoinNewWalletCredentials(
+          name: name, walletInfo: walletInfo, password: password, passphrase: passphrase);
 
   @override
   WalletCredentials createBitcoinHardwareWalletCredentials(
@@ -202,8 +203,8 @@ class CWBitcoin extends Bitcoin {
     await bitcoinWallet.updateAllUnspents();
   }
 
-  WalletService createBitcoinWalletService(
-      Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan, bool isDirect) {
+  WalletService createBitcoinWalletService(Box<WalletInfo> walletInfoSource,
+      Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan, bool isDirect) {
     return BitcoinWalletService(walletInfoSource, unspentCoinSource, alwaysScan, isDirect);
   }
 
@@ -315,7 +316,7 @@ class CWBitcoin extends Bitcoin {
     for (DerivationType dType in electrum_derivations.keys) {
       late Uint8List seedBytes;
       if (dType == DerivationType.electrum) {
-        seedBytes = await mnemonicToSeedBytes(mnemonic);
+        seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
       } else if (dType == DerivationType.bip39) {
         seedBytes = bip39.mnemonicToSeed(mnemonic, passphrase: passphrase ?? '');
       }
diff --git a/lib/bitcoin_cash/cw_bitcoin_cash.dart b/lib/bitcoin_cash/cw_bitcoin_cash.dart
index fcb34a286..62ec1539b 100644
--- a/lib/bitcoin_cash/cw_bitcoin_cash.dart
+++ b/lib/bitcoin_cash/cw_bitcoin_cash.dart
@@ -15,14 +15,16 @@ class CWBitcoinCash extends BitcoinCash {
     required String name,
     WalletInfo? walletInfo,
     String? password,
+    String? passphrase,
   }) =>
-      BitcoinCashNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
+      BitcoinCashNewWalletCredentials(
+          name: name, walletInfo: walletInfo, password: password, passphrase: passphrase);
 
   @override
   WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials(
-          {required String name, required String mnemonic, required String password}) =>
+          {required String name, required String mnemonic, required String password, String? passphrase}) =>
       BitcoinCashRestoreWalletFromSeedCredentials(
-          name: name, mnemonic: mnemonic, password: password);
+          name: name, mnemonic: mnemonic, password: password, passphrase: passphrase);
 
   @override
   TransactionPriority deserializeBitcoinCashTransactionPriority(int raw) =>
diff --git a/lib/core/wallet_creation_service.dart b/lib/core/wallet_creation_service.dart
index 1e9299282..3ee630b33 100644
--- a/lib/core/wallet_creation_service.dart
+++ b/lib/core/wallet_creation_service.dart
@@ -75,8 +75,10 @@ class WalletCreationService {
 
   bool get _hasSeedPhraseLengthOption {
     switch (type) {
-      case WalletType.ethereum:
+      case WalletType.bitcoin:
+      case WalletType.litecoin:
       case WalletType.bitcoinCash:
+      case WalletType.ethereum:
       case WalletType.polygon:
       case WalletType.solana:
       case WalletType.tron:
@@ -84,8 +86,6 @@ class WalletCreationService {
       case WalletType.monero:
       case WalletType.wownero:
       case WalletType.none:
-      case WalletType.bitcoin:
-      case WalletType.litecoin:
       case WalletType.haven:
       case WalletType.nano:
       case WalletType.banano:
diff --git a/lib/di.dart b/lib/di.dart
index 1967c9227..8d8c5a368 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -146,7 +146,7 @@ import 'package:cake_wallet/view_model/cake_pay/cake_pay_purchase_view_model.dar
 import 'package:cake_wallet/view_model/nano_account_list/nano_account_edit_or_create_view_model.dart';
 import 'package:cake_wallet/view_model/nano_account_list/nano_account_list_view_model.dart';
 import 'package:cake_wallet/view_model/node_list/pow_node_list_view_model.dart';
-import 'package:cake_wallet/view_model/seed_type_view_model.dart';
+import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
 import 'package:cake_wallet/view_model/set_up_2fa_viewmodel.dart';
 import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart';
 import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
@@ -179,6 +179,7 @@ import 'package:cake_wallet/store/dashboard/trades_store.dart';
 import 'package:cake_wallet/store/dashboard/transaction_filter_store.dart';
 import 'package:cake_wallet/store/node_list_store.dart';
 import 'package:cake_wallet/store/secret_store.dart';
+import 'package:cake_wallet/store/seed_settings_store.dart';
 import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/store/templates/exchange_template_store.dart';
 import 'package:cake_wallet/store/templates/send_template_store.dart';
@@ -331,6 +332,7 @@ Future<void> setup({
       YatStore(appStore: getIt.get<AppStore>(), secureStorage: getIt.get<SecureStorage>())..init());
   getIt.registerSingleton<AnonpayTransactionsStore>(
       AnonpayTransactionsStore(anonpayInvoiceInfoSource: _anonpayInvoiceInfoSource));
+  getIt.registerSingleton<SeedSettingsStore>(SeedSettingsStore());
 
   getIt.registerLazySingleton(() => LedgerViewModel());
 
@@ -361,6 +363,7 @@ Future<void> setup({
       getIt.get<WalletCreationService>(param1: type),
       _walletInfoSource,
       getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
+      getIt.get<SeedSettingsViewModel>(),
       type: type));
 
   getIt.registerFactoryParam<WalletUnlockPage, WalletUnlockArguments, bool>((args, closable) {
@@ -422,14 +425,21 @@ Future<void> setup({
       walletType: args.walletType ?? currentWalletType);
   });
 
-  getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) {
-    return WalletRestorationFromQRVM(getIt.get<AppStore>(),
-        getIt.get<WalletCreationService>(param1: type), _walletInfoSource, type);
-  });
+  getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) =>
+      WalletRestorationFromQRVM(
+          getIt.get<AppStore>(),
+          getIt.get<WalletCreationService>(param1: type),
+          _walletInfoSource,
+          type,
+          getIt.get<SeedSettingsViewModel>()));
 
   getIt.registerFactoryParam<WalletHardwareRestoreViewModel, WalletType, void>((type, _) =>
-      WalletHardwareRestoreViewModel(getIt.get<LedgerViewModel>(), getIt.get<AppStore>(),
-          getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
+      WalletHardwareRestoreViewModel(
+          getIt.get<LedgerViewModel>(),
+          getIt.get<AppStore>(),
+          getIt.get<WalletCreationService>(param1: type),
+          _walletInfoSource,
+          getIt.get<SeedSettingsViewModel>(),
           type: type));
 
   getIt.registerFactory<WalletAddressListViewModel>(() => WalletAddressListViewModel(
@@ -833,7 +843,7 @@ Future<void> setup({
 
   getIt.registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
 
-  getIt.registerFactory<SeedTypeViewModel>(() => SeedTypeViewModel(getIt.get<AppStore>()));
+  getIt.registerFactory<SeedSettingsViewModel>(() => SeedSettingsViewModel(getIt.get<AppStore>(), getIt.get<SeedSettingsStore>()));
 
   getIt.registerFactoryParam<WalletSeedPage, bool, void>((bool isWalletCreated, _) =>
       WalletSeedPage(getIt.get<WalletSeedViewModel>(), isNewWalletCreated: isWalletCreated));
@@ -1018,12 +1028,12 @@ Future<void> setup({
   getIt.registerFactory(() => FaqPage(getIt.get<SettingsStore>()));
 
   getIt.registerFactoryParam<WalletRestoreViewModel, WalletType, void>((type, _) =>
-      WalletRestoreViewModel(
-          getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
+      WalletRestoreViewModel(getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type),
+          _walletInfoSource, getIt.get<SeedSettingsViewModel>(),
           type: type));
 
   getIt.registerFactoryParam<WalletRestorePage, WalletType, void>((type, _) => WalletRestorePage(
-      getIt.get<WalletRestoreViewModel>(param1: type), getIt.get<SeedTypeViewModel>()));
+      getIt.get<WalletRestoreViewModel>(param1: type), getIt.get<SeedSettingsViewModel>()));
 
   getIt.registerFactoryParam<WalletRestoreChooseDerivationViewModel, List<DerivationInfo>, void>(
       (derivations, _) => WalletRestoreChooseDerivationViewModel(derivationInfos: derivations));
@@ -1275,7 +1285,7 @@ Future<void> setup({
 
   getIt.registerFactory(
       () => WalletConnectConnectionsView(web3walletService: getIt.get<Web3WalletService>()));
-  
+
   getIt.registerFactory(() => NFTViewModel(appStore, getIt.get<BottomSheetService>()));
   getIt.registerFactory<TorPage>(() => TorPage(getIt.get<AppStore>()));
 
diff --git a/lib/entities/language_service.dart b/lib/entities/language_service.dart
index 260c8a27f..4a6b358e1 100644
--- a/lib/entities/language_service.dart
+++ b/lib/entities/language_service.dart
@@ -60,7 +60,7 @@ class LanguageService {
     'yo': 'nga',
     'ha': 'hau',
     'tl': 'phl',
-    'hy': 'arm'
+    'hy': 'arm',
   };
 
   static final list = <String, String>{};
diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart
index e1ee0ada3..743357f92 100644
--- a/lib/entities/preferences_key.dart
+++ b/lib/entities/preferences_key.dart
@@ -77,6 +77,7 @@ class PreferencesKey {
   static const exchangeProvidersSelection = 'exchange-providers-selection';
   static const autoGenerateSubaddressStatusKey = 'auto_generate_subaddress_status';
   static const moneroSeedType = 'monero_seed_type';
+  static const bitcoinSeedType = 'bitcoin_seed_type';
   static const clearnetDonationLink = 'clearnet_donation_link';
   static const onionDonationLink = 'onion_donation_link';
   static const donationLinkWalletName = 'donation_link_wallet_name';
diff --git a/lib/entities/seed_type.dart b/lib/entities/seed_type.dart
index bc2f6cff7..f941c8a2d 100644
--- a/lib/entities/seed_type.dart
+++ b/lib/entities/seed_type.dart
@@ -1,18 +1,19 @@
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cw_core/enumerable_item.dart';
+import 'package:cw_core/wallet_info.dart';
 
-class SeedType extends EnumerableItem<int> with Serializable<int> {
-  const SeedType({required String title, required int raw}) : super(title: title, raw: raw);
+class MoneroSeedType extends EnumerableItem<int> with Serializable<int> {
+  const MoneroSeedType({required String title, required int raw}) : super(title: title, raw: raw);
 
-  static const all = [SeedType.legacy, SeedType.polyseed];
+  static const all = [MoneroSeedType.legacy, MoneroSeedType.polyseed];
 
   static const defaultSeedType = polyseed;
 
-  static const legacy = SeedType(raw: 0, title: 'Legacy (25 words)');
-  static const polyseed = SeedType(raw: 1, title: 'Polyseed (16 words)');
-  static const wowneroSeed = SeedType(raw: 2, title: 'Wownero (14 words)');
+  static const legacy = MoneroSeedType(raw: 0, title: 'Legacy (25 words)');
+  static const polyseed = MoneroSeedType(raw: 1, title: 'Polyseed (16 words)');
+  static const wowneroSeed = MoneroSeedType(raw: 2, title: 'Wownero (14 words)');
 
-  static SeedType deserialize({required int raw}) {
+  static MoneroSeedType deserialize({required int raw}) {
     switch (raw) {
       case 0:
         return legacy;
@@ -28,14 +29,39 @@ class SeedType extends EnumerableItem<int> with Serializable<int> {
   @override
   String toString() {
     switch (this) {
-      case SeedType.legacy:
+      case MoneroSeedType.legacy:
         return S.current.seedtype_legacy;
-      case SeedType.polyseed:
+      case MoneroSeedType.polyseed:
         return S.current.seedtype_polyseed;
-      case SeedType.wowneroSeed:
+      case MoneroSeedType.wowneroSeed:
         return S.current.seedtype_wownero;
       default:
         return '';
     }
   }
 }
+
+class BitcoinSeedType extends EnumerableItem<int> with Serializable<int> {
+  const BitcoinSeedType(this.type, {required String title, required int raw})
+      : super(title: title, raw: raw);
+
+  final DerivationType type;
+
+  static const all = [BitcoinSeedType.electrum, BitcoinSeedType.bip39];
+
+  static const defaultDerivationType = bip39;
+
+  static const electrum = BitcoinSeedType(DerivationType.electrum, raw: 0, title: 'Electrum');
+  static const bip39 = BitcoinSeedType(DerivationType.bip39, raw: 1, title: 'BIP39');
+
+  static BitcoinSeedType deserialize({required int raw}) {
+    switch (raw) {
+      case 0:
+        return electrum;
+      case 1:
+        return bip39;
+      default:
+        throw Exception('Unexpected token: $raw for SeedType deserialize');
+    }
+  }
+}
diff --git a/lib/router.dart b/lib/router.dart
index 25af39043..281d50b69 100644
--- a/lib/router.dart
+++ b/lib/router.dart
@@ -17,6 +17,8 @@ import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
 import 'package:cake_wallet/src/screens/buy/buy_options_page.dart';
 import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
 import 'package:cake_wallet/src/screens/buy/webview_page.dart';
+import 'package:cake_wallet/src/screens/cake_pay/auth/cake_pay_account_page.dart';
+import 'package:cake_wallet/src/screens/cake_pay/cake_pay.dart';
 import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart';
 import 'package:cake_wallet/src/screens/connect_device/select_hardware_wallet_account_page.dart';
 import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
@@ -27,8 +29,8 @@ import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart';
 import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart';
 import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart';
 import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart';
-import 'package:cake_wallet/src/screens/dashboard/sign_page.dart';
 import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
+import 'package:cake_wallet/src/screens/dashboard/sign_page.dart';
 import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart';
 import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
 import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
@@ -43,10 +45,9 @@ import 'package:cake_wallet/src/screens/new_wallet/new_wallet_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/pow_node_create_or_edit_page.dart';
-import 'package:cake_wallet/src/screens/receive/address_list_page.dart';
-import 'package:cake_wallet/src/screens/restore/sweeping_wallet_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/receive/address_list_page.dart';
 import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart';
 import 'package:cake_wallet/src/screens/receive/anonpay_receive_page.dart';
 import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart';
@@ -69,11 +70,9 @@ import 'package:cake_wallet/src/screens/settings/manage_nodes_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/cake_pay/auth/cake_pay_account_page.dart';
 import 'package:cake_wallet/src/screens/settings/silent_payments_settings.dart';
 import 'package:cake_wallet/src/screens/settings/tor_page.dart';
 import 'package:cake_wallet/src/screens/settings/trocador_providers_page.dart';
-import 'package:cake_wallet/src/screens/settings/tor_page.dart';
 import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart';
 import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
 import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart';
@@ -85,19 +84,18 @@ import 'package:cake_wallet/src/screens/support/support_page.dart';
 import 'package:cake_wallet/src/screens/support_chat/support_chat_page.dart';
 import 'package:cake_wallet/src/screens/support_other_links/support_other_links_page.dart';
 import 'package:cake_wallet/src/screens/trade_details/trade_details_page.dart';
-import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart';
 import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
+import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart';
 import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
 import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
 import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart';
 import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart';
 import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
 import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
+import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
 import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_page.dart';
 import 'package:cake_wallet/src/screens/welcome/create_welcome_page.dart';
 import 'package:cake_wallet/store/settings_store.dart';
-import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
-import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/utils/payment_request.dart';
 import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
 import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
@@ -106,7 +104,7 @@ import 'package:cake_wallet/view_model/dashboard/sign_view_model.dart';
 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
 import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
 import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
-import 'package:cake_wallet/view_model/seed_type_view_model.dart';
+import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
 import 'package:cake_wallet/view_model/wallet_hardware_restore_view_model.dart';
 import 'package:cake_wallet/view_model/wallet_new_vm.dart';
 import 'package:cake_wallet/wallet_type_utils.dart';
@@ -120,7 +118,7 @@ import 'package:cw_core/wallet_type.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-import 'package:cake_wallet/src/screens/cake_pay/cake_pay.dart';
+
 import 'src/screens/dashboard/pages/nft_import_page.dart';
 
 late RouteSettings currentRouteSettings;
@@ -135,7 +133,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
     case Routes.newWalletFromWelcome:
       if (SettingsStoreBase.walletPasswordDirectInput) {
         if (availableWalletTypes.length == 1) {
-          return createRoute(RouteSettings(name: Routes.newWallet, arguments: availableWalletTypes.first));
+          return createRoute(
+              RouteSettings(name: Routes.newWallet, arguments: availableWalletTypes.first));
         } else {
           return createRoute(RouteSettings(name: Routes.newWalletType));
         }
@@ -162,10 +161,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
     case Routes.newWallet:
       final type = settings.arguments as WalletType;
       final walletNewVM = getIt.get<WalletNewVM>(param1: type);
-      final seedTypeViewModel = getIt.get<SeedTypeViewModel>();
+      final seedSettingsViewModel = getIt.get<SeedSettingsViewModel>();
 
       return CupertinoPageRoute<void>(
-          builder: (_) => NewWalletPage(walletNewVM, seedTypeViewModel));
+          builder: (_) => NewWalletPage(walletNewVM, seedSettingsViewModel));
 
     case Routes.chooseHardwareWalletAccount:
       final arguments = settings.arguments as List<dynamic>;
@@ -348,16 +347,14 @@ Route<dynamic> createRoute(RouteSettings settings) {
     case Routes.auth:
       return MaterialPageRoute<void>(
           fullscreenDialog: true,
-          builder: (_)
-            => SettingsStoreBase.walletPasswordDirectInput
-                ? getIt.get<WalletUnlockPage>(
-                    param1: WalletUnlockArguments(
+          builder: (_) => SettingsStoreBase.walletPasswordDirectInput
+              ? getIt.get<WalletUnlockPage>(
+                  param1: WalletUnlockArguments(
                       callback: settings.arguments as OnAuthenticationFinished),
-                      instanceName: 'wallet_unlock_verifiable',
-                    param2: true)
-                : getIt.get<AuthPage>(
-                    param1: settings.arguments as OnAuthenticationFinished,
-                    param2: true));
+                  instanceName: 'wallet_unlock_verifiable',
+                  param2: true)
+              : getIt.get<AuthPage>(
+                  param1: settings.arguments as OnAuthenticationFinished, param2: true));
 
     case Routes.totpAuthCodePage:
       final args = settings.arguments as TotpAuthArgumentsModel;
@@ -371,28 +368,25 @@ Route<dynamic> createRoute(RouteSettings settings) {
     case Routes.walletUnlockLoadable:
       return MaterialPageRoute<void>(
           fullscreenDialog: true,
-          builder: (_)
-            => getIt.get<WalletUnlockPage>(
+          builder: (_) => getIt.get<WalletUnlockPage>(
               param1: settings.arguments as WalletUnlockArguments,
-                instanceName: 'wallet_unlock_loadable',
+              instanceName: 'wallet_unlock_loadable',
               param2: true));
 
     case Routes.unlock:
       return MaterialPageRoute<void>(
           fullscreenDialog: true,
-          builder: (_)
-            => SettingsStoreBase.walletPasswordDirectInput
-                ? WillPopScope(
-                    child: getIt.get<WalletUnlockPage>(
+          builder: (_) => SettingsStoreBase.walletPasswordDirectInput
+              ? WillPopScope(
+                  child: getIt.get<WalletUnlockPage>(
                       param1: WalletUnlockArguments(
-                        callback: settings.arguments as OnAuthenticationFinished),
+                          callback: settings.arguments as OnAuthenticationFinished),
                       param2: false,
                       instanceName: 'wallet_unlock_verifiable'),
-                    onWillPop: () async => false)
-                : WillPopScope(
-                    child: getIt.get<AuthPage>(
-                      param1: settings.arguments as OnAuthenticationFinished,
-                      param2: false),
+                  onWillPop: () async => false)
+              : WillPopScope(
+                  child: getIt.get<AuthPage>(
+                      param1: settings.arguments as OnAuthenticationFinished, param2: false),
                   onWillPop: () async => false));
 
     case Routes.silentPaymentsSettings:
@@ -437,11 +431,12 @@ Route<dynamic> createRoute(RouteSettings settings) {
       return CupertinoPageRoute<void>(
           builder: (context) => WillPopScope(
               child: SettingsStoreBase.walletPasswordDirectInput
-                ? getIt.get<WalletUnlockPage>(instanceName: 'wallet_password_login')
-                : getIt.get<AuthPage>(instanceName: 'login'),
+                  ? getIt.get<WalletUnlockPage>(instanceName: 'wallet_password_login')
+                  : getIt.get<AuthPage>(instanceName: 'login'),
               onWillPop: () async =>
-              // FIX-ME: Additional check does it works correctly
-                  (await SystemChannels.platform.invokeMethod<bool>('SystemNavigator.pop') ?? false)),
+                  // FIX-ME: Additional check does it works correctly
+                  (await SystemChannels.platform.invokeMethod<bool>('SystemNavigator.pop') ??
+                      false)),
           fullscreenDialog: true);
 
     case Routes.newPowNode:
@@ -537,8 +532,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
 
     case Routes.support:
       return CupertinoPageRoute<void>(
-          fullscreenDialog: true,
-          builder: (_) => getIt.get<SupportPage>());
+          fullscreenDialog: true, builder: (_) => getIt.get<SupportPage>());
 
     case Routes.supportLiveChat:
       return CupertinoPageRoute<void>(builder: (_) => getIt.get<SupportChatPage>());
@@ -567,8 +561,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
 
     case Routes.cakePayBuyCardPage:
       final args = settings.arguments as List;
-      return CupertinoPageRoute<void>(
-          builder: (_) => getIt.get<CakePayBuyCardPage>(param1: args));
+      return CupertinoPageRoute<void>(builder: (_) => getIt.get<CakePayBuyCardPage>(param1: args));
 
     case Routes.cakePayBuyCardDetailPage:
       final args = settings.arguments as List;
@@ -582,7 +575,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
 
     case Routes.cakePayVerifyOtpPage:
       final args = settings.arguments as List;
-      return CupertinoPageRoute<void>(builder: (_) => getIt.get<CakePayVerifyOtpPage>(param1: args));
+      return CupertinoPageRoute<void>(
+          builder: (_) => getIt.get<CakePayVerifyOtpPage>(param1: args));
 
     case Routes.cakePayAccountPage:
       return CupertinoPageRoute<void>(builder: (_) => getIt.get<CakePayAccountPage>());
@@ -597,16 +591,19 @@ Route<dynamic> createRoute(RouteSettings settings) {
     case Routes.advancedPrivacySettings:
       final args = settings.arguments as Map<String, dynamic>;
       final type = args['type'] as WalletType;
+      final isFromRestore = args['isFromRestore'] as bool? ?? false;
       final useTestnet = args['useTestnet'] as bool;
       final toggleTestnet = args['toggleTestnet'] as Function(bool? val);
 
       return CupertinoPageRoute<void>(
           builder: (_) => AdvancedPrivacySettingsPage(
-                useTestnet,
-                toggleTestnet,
-                getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
-                getIt.get<NodeCreateOrEditViewModel>(param1: type, param2: false),
-                getIt.get<SeedTypeViewModel>(),
+                isFromRestore: isFromRestore,
+                useTestnet: useTestnet,
+                toggleUseTestnet: toggleTestnet,
+                advancedPrivacySettingsViewModel:
+                    getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
+                nodeViewModel: getIt.get<NodeCreateOrEditViewModel>(param1: type, param2: false),
+                seedSettingsViewModel: getIt.get<SeedSettingsViewModel>(),
               ));
 
     case Routes.anonPayInvoicePage:
@@ -709,7 +706,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
           getIt.get<SignViewModel>(),
         ),
       );
-    
+
     case Routes.connectDevices:
       final params = settings.arguments as ConnectDevicePageParams;
       return MaterialPageRoute<void>(
diff --git a/lib/src/screens/dashboard/widgets/verify_form.dart b/lib/src/screens/dashboard/widgets/verify_form.dart
index d59261494..bf6809586 100644
--- a/lib/src/screens/dashboard/widgets/verify_form.dart
+++ b/lib/src/screens/dashboard/widgets/verify_form.dart
@@ -1,23 +1,7 @@
-import 'package:cake_wallet/core/wallet_name_validator.dart';
-import 'package:cake_wallet/entities/generate_name.dart';
-import 'package:cake_wallet/entities/seed_type.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/src/widgets/address_text_field.dart';
-import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
-import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
-import 'package:cake_wallet/src/widgets/picker.dart';
-import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
-import 'package:cake_wallet/src/widgets/seed_widget.dart';
-import 'package:cake_wallet/themes/extensions/address_theme.dart';
-import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
-import 'package:cake_wallet/utils/show_bar.dart';
-import 'package:cake_wallet/utils/show_pop_up.dart';
-import 'package:cake_wallet/view_model/seed_type_view_model.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
-import 'package:mobx/mobx.dart';
-import 'package:polyseed/polyseed.dart';
 
 class VerifyForm extends StatefulWidget {
   VerifyForm({
diff --git a/lib/src/screens/new_wallet/advanced_privacy_settings_page.dart b/lib/src/screens/new_wallet/advanced_privacy_settings_page.dart
index 881d9f95a..ff8ec3dd2 100644
--- a/lib/src/screens/new_wallet/advanced_privacy_settings_page.dart
+++ b/lib/src/screens/new_wallet/advanced_privacy_settings_page.dart
@@ -3,52 +3,61 @@ import 'package:cake_wallet/entities/exchange_api_mode.dart';
 import 'package:cake_wallet/entities/fiat_api_mode.dart';
 import 'package:cake_wallet/entities/seed_phrase_length.dart';
 import 'package:cake_wallet/entities/seed_type.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_form.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/extensions/new_wallet_theme.dart';
-import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
-import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
-import 'package:cake_wallet/view_model/seed_type_view_model.dart';
-import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
-import 'package:cw_core/wallet_type.dart';
-import 'package:flutter_mobx/flutter_mobx.dart';
-import 'package:flutter/material.dart';
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
 import 'package:cake_wallet/src/widgets/primary_button.dart';
 import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
+import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
+import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
+import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
+import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
+import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
 
 class AdvancedPrivacySettingsPage extends BasePage {
-  AdvancedPrivacySettingsPage(this.useTestnet, this.toggleUseTestnet,
-      this.advancedPrivacySettingsViewModel, this.nodeViewModel, this.seedTypeViewModel);
+  AdvancedPrivacySettingsPage({
+    required this.isFromRestore,
+    required this.useTestnet,
+    required this.toggleUseTestnet,
+    required this.advancedPrivacySettingsViewModel,
+    required this.nodeViewModel,
+    required this.seedSettingsViewModel,
+  });
 
   final AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel;
   final NodeCreateOrEditViewModel nodeViewModel;
-  final SeedTypeViewModel seedTypeViewModel;
+  final SeedSettingsViewModel seedSettingsViewModel;
 
   @override
   String get title => S.current.privacy_settings;
 
+  final bool isFromRestore;
   final bool useTestnet;
   final Function(bool? val) toggleUseTestnet;
 
   @override
-  Widget body(BuildContext context) => AdvancedPrivacySettingsBody(useTestnet, toggleUseTestnet,
-      advancedPrivacySettingsViewModel, nodeViewModel, seedTypeViewModel);
+  Widget body(BuildContext context) => _AdvancedPrivacySettingsBody(isFromRestore, useTestnet,
+      toggleUseTestnet, advancedPrivacySettingsViewModel, nodeViewModel, seedSettingsViewModel);
 }
 
-class AdvancedPrivacySettingsBody extends StatefulWidget {
-  const AdvancedPrivacySettingsBody(this.useTestnet, this.toggleUseTestnet,
+class _AdvancedPrivacySettingsBody extends StatefulWidget {
+  const _AdvancedPrivacySettingsBody(this.isFromRestore, this.useTestnet, this.toggleUseTestnet,
       this.privacySettingsViewModel, this.nodeViewModel, this.seedTypeViewModel,
       {Key? key})
       : super(key: key);
 
   final AdvancedPrivacySettingsViewModel privacySettingsViewModel;
   final NodeCreateOrEditViewModel nodeViewModel;
-  final SeedTypeViewModel seedTypeViewModel;
+  final SeedSettingsViewModel seedTypeViewModel;
 
+  final bool isFromRestore;
   final bool useTestnet;
   final Function(bool? val) toggleUseTestnet;
 
@@ -56,15 +65,23 @@ class AdvancedPrivacySettingsBody extends StatefulWidget {
   _AdvancedPrivacySettingsBodyState createState() => _AdvancedPrivacySettingsBodyState();
 }
 
-class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBody> {
-  _AdvancedPrivacySettingsBodyState();
-
+class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBody> {
+  final TextEditingController passphraseController = TextEditingController();
   final _formKey = GlobalKey<FormState>();
   bool? testnetValue;
 
+  @override
+  void initState() {
+    passphraseController.text = widget.seedTypeViewModel.passphrase ?? '';
+
+    passphraseController
+        .addListener(() => widget.seedTypeViewModel.setPassphrase(passphraseController.text));
+    super.initState();
+  }
+
   @override
   Widget build(BuildContext context) {
-    if (testnetValue == null && widget.useTestnet != null) {
+    if (testnetValue == null && widget.useTestnet) {
       testnetValue = widget.useTestnet;
     }
 
@@ -97,6 +114,52 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
                 ),
               );
             }),
+            if (widget.privacySettingsViewModel.hasSeedTypeOption)
+              Observer(builder: (_) {
+                return SettingsChoicesCell(
+                  ChoicesListItem<MoneroSeedType>(
+                    title: S.current.seedtype,
+                    items: MoneroSeedType.all,
+                    selectedItem: widget.seedTypeViewModel.moneroSeedType,
+                    onItemSelected: widget.seedTypeViewModel.setMoneroSeedType,
+                  ),
+                );
+              }),
+            if ([WalletType.bitcoin, WalletType.litecoin]
+                .contains(widget.privacySettingsViewModel.type))
+              Observer(builder: (_) {
+                return SettingsChoicesCell(
+                  ChoicesListItem<BitcoinSeedType>(
+                    title: S.current.seedtype,
+                    items: BitcoinSeedType.all,
+                    selectedItem: widget.seedTypeViewModel.bitcoinSeedType,
+                    onItemSelected: widget.seedTypeViewModel.setBitcoinSeedType,
+                  ),
+                );
+              }),
+            if (!widget.isFromRestore) ...[
+                Observer(builder: (_) {
+              if (widget.privacySettingsViewModel.hasSeedPhraseLengthOption)
+                return SettingsPickerCell<SeedPhraseLength>(
+                  title: S.current.seed_phrase_length,
+                  items: SeedPhraseLength.values,
+                  selectedItem: widget.privacySettingsViewModel.seedPhraseLength,
+                  onItemSelected: (SeedPhraseLength length) {
+                    widget.privacySettingsViewModel.setSeedPhraseLength(length);
+                  },
+                );
+              return Container();
+            }),
+            if (widget.privacySettingsViewModel.hasPassphraseOption)
+              Padding(
+                padding: EdgeInsets.all(24),
+                child: BaseTextFormField(
+                  hintText: S.current.passphrase,
+                  controller: passphraseController,
+                  obscureText: true,
+                ),
+              ),
+            ],
             Observer(builder: (_) {
               return Column(
                 children: [
@@ -122,31 +185,9 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
                 ],
               );
             }),
-            if (widget.privacySettingsViewModel.hasSeedPhraseLengthOption)
-              Observer(builder: (_) {
-                return SettingsPickerCell<SeedPhraseLength>(
-                  title: S.current.seed_phrase_length,
-                  items: SeedPhraseLength.values,
-                  selectedItem: widget.privacySettingsViewModel.seedPhraseLength,
-                  onItemSelected: (SeedPhraseLength length) {
-                    widget.privacySettingsViewModel.setSeedPhraseLength(length);
-                  },
-                );
-              }),
-            if (widget.privacySettingsViewModel.hasSeedTypeOption)
-              Observer(builder: (_) {
-                return SettingsChoicesCell(
-                  ChoicesListItem<SeedType>(
-                    title: S.current.seedtype,
-                    items: SeedType.all,
-                    selectedItem: widget.seedTypeViewModel.moneroSeedType,
-                    onItemSelected: widget.seedTypeViewModel.setMoneroSeedType,
-                  ),
-                );
-              }),
             if (widget.privacySettingsViewModel.type == WalletType.bitcoin)
               Builder(builder: (_) {
-                final val = testnetValue!;
+                final val = testnetValue ?? false;
                 return SettingsSwitcherCell(
                     title: S.current.use_testnet,
                     value: val,
@@ -154,7 +195,7 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
                       setState(() {
                         testnetValue = !val;
                       });
-                      widget.toggleUseTestnet!.call(testnetValue);
+                      widget.toggleUseTestnet.call(testnetValue);
                     });
               }),
           ],
@@ -203,4 +244,11 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
       ),
     );
   }
+
+  @override
+  void dispose() {
+    passphraseController
+        .removeListener(() => widget.seedTypeViewModel.setPassphrase(passphraseController.text));
+    super.dispose();
+  }
 }
diff --git a/lib/src/screens/new_wallet/new_wallet_page.dart b/lib/src/screens/new_wallet/new_wallet_page.dart
index 471240877..8f61ebb38 100644
--- a/lib/src/screens/new_wallet/new_wallet_page.dart
+++ b/lib/src/screens/new_wallet/new_wallet_page.dart
@@ -1,36 +1,35 @@
+import 'package:cake_wallet/core/execution_state.dart';
+import 'package:cake_wallet/core/wallet_name_validator.dart';
 import 'package:cake_wallet/entities/generate_name.dart';
-import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
-import 'package:cake_wallet/src/widgets/picker.dart';
-import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
+import 'package:cake_wallet/entities/seed_type.dart';
+import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/main.dart';
 import 'package:cake_wallet/routes.dart';
-import 'package:cake_wallet/themes/theme_base.dart';
-import 'package:cake_wallet/utils/responsive_layout_util.dart';
-import 'package:cake_wallet/utils/show_pop_up.dart';
-import 'package:cake_wallet/view_model/seed_type_view_model.dart';
-import 'package:mobx/mobx.dart';
-import 'package:flutter_mobx/flutter_mobx.dart';
-import 'package:flutter/material.dart';
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/core/wallet_name_validator.dart';
-import 'package:cake_wallet/src/widgets/seed_language_selector.dart';
 import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
+import 'package:cake_wallet/src/widgets/picker.dart';
 import 'package:cake_wallet/src/widgets/primary_button.dart';
 import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
 import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
-import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
-import 'package:cake_wallet/core/execution_state.dart';
-import 'package:cake_wallet/view_model/wallet_new_vm.dart';
+import 'package:cake_wallet/src/widgets/seed_language_selector.dart';
+import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
 import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
-import 'package:cake_wallet/entities/seed_type.dart';
-
+import 'package:cake_wallet/themes/theme_base.dart';
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
+import 'package:cake_wallet/view_model/wallet_new_vm.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+import 'package:mobx/mobx.dart';
 
 class NewWalletPage extends BasePage {
-  NewWalletPage(this._walletNewVM, this._seedTypeViewModel);
+  NewWalletPage(this._walletNewVM, this._seedSettingsViewModel);
 
   final WalletNewVM _walletNewVM;
-  final SeedTypeViewModel _seedTypeViewModel;
+  final SeedSettingsViewModel _seedSettingsViewModel;
 
   final walletNameImage = Image.asset('assets/images/wallet_name.png');
 
@@ -51,15 +50,15 @@ class NewWalletPage extends BasePage {
   Widget body(BuildContext context) => WalletNameForm(
       _walletNewVM,
       currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage,
-      _seedTypeViewModel);
+      _seedSettingsViewModel);
 }
 
 class WalletNameForm extends StatefulWidget {
-  WalletNameForm(this._walletNewVM, this.walletImage, this._seedTypeViewModel);
+  WalletNameForm(this._walletNewVM, this.walletImage, this._seedSettingsViewModel);
 
   final WalletNewVM _walletNewVM;
   final Image walletImage;
-  final SeedTypeViewModel _seedTypeViewModel;
+  final SeedSettingsViewModel _seedSettingsViewModel;
 
   @override
   _WalletNameFormState createState() => _WalletNameFormState(_walletNewVM);
@@ -110,7 +109,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
       }
     });
 
-    _setSeedType(SeedType.defaultSeedType);
+    _setSeedType(MoneroSeedType.defaultSeedType);
     super.initState();
   }
 
@@ -285,12 +284,12 @@ class _WalletNameFormState extends State<WalletNameForm> {
                         builder: (BuildContext build) => Padding(
                           padding: EdgeInsets.only(top: 24),
                           child: SelectButton(
-                            text: widget._seedTypeViewModel.moneroSeedType.title,
+                            text: widget._seedSettingsViewModel.moneroSeedType.title,
                             onTap: () async {
                               await showPopUp<void>(
                                 context: context,
                                 builder: (_) => Picker(
-                                  items: SeedType.all,
+                                  items: MoneroSeedType.all,
                                   selectedAtIndex: isPolyseed ? 1 : 0,
                                   onItemSelected: _setSeedType,
                                   isSeparated: false,
@@ -308,8 +307,8 @@ class _WalletNameFormState extends State<WalletNameForm> {
                           key: _languageSelectorKey,
                           initialSelected: defaultSeedLanguage,
                           seedType: _walletNewVM.hasSeedType
-                              ? widget._seedTypeViewModel.moneroSeedType
-                              : SeedType.legacy,
+                              ? widget._seedSettingsViewModel.moneroSeedType
+                              : MoneroSeedType.legacy,
                         ),
                       ),
                     )
@@ -380,10 +379,10 @@ class _WalletNameFormState extends State<WalletNameForm> {
     _formProcessing = false;
   }
 
-  bool get isPolyseed => widget._seedTypeViewModel.moneroSeedType == SeedType.polyseed;
+  bool get isPolyseed => widget._seedSettingsViewModel.moneroSeedType == MoneroSeedType.polyseed;
 
-  void _setSeedType(SeedType item) {
-    widget._seedTypeViewModel.setMoneroSeedType(item);
+  void _setSeedType(MoneroSeedType item) {
+    widget._seedSettingsViewModel.setMoneroSeedType(item);
     _languageSelectorKey.currentState?.selected = defaultSeedLanguage; // Reset Seed language
   }
 }
diff --git a/lib/src/screens/restore/wallet_restore_from_seed_form.dart b/lib/src/screens/restore/wallet_restore_from_seed_form.dart
index ec40eb1c1..f295aab13 100644
--- a/lib/src/screens/restore/wallet_restore_from_seed_form.dart
+++ b/lib/src/screens/restore/wallet_restore_from_seed_form.dart
@@ -9,35 +9,34 @@ import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
 import 'package:cake_wallet/src/widgets/seed_widget.dart';
 import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
-import 'package:cake_wallet/view_model/seed_type_view_model.dart';
+import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:flutter/material.dart';
 import 'package:mobx/mobx.dart';
 import 'package:polyseed/polyseed.dart';
 
 class WalletRestoreFromSeedForm extends StatefulWidget {
-  WalletRestoreFromSeedForm(
-      {Key? key,
-      required this.displayLanguageSelector,
-      required this.displayBlockHeightSelector,
-      required this.displayPassphrase,
-      required this.type,
-      required this.displayWalletPassword,
-      required this.seedTypeViewModel,
-      this.blockHeightFocusNode,
-      this.onHeightOrDateEntered,
-      this.onSeedChange,
-      this.onLanguageChange,
-      this.onPasswordChange,
-      this.onRepeatedPasswordChange})
-      : super(key: key);
+  WalletRestoreFromSeedForm({Key? key,
+    required this.displayLanguageSelector,
+    required this.displayBlockHeightSelector,
+    required this.displayPassphrase,
+    required this.type,
+    required this.displayWalletPassword,
+    required this.seedSettingsViewModel,
+    this.blockHeightFocusNode,
+    this.onHeightOrDateEntered,
+    this.onSeedChange,
+    this.onLanguageChange,
+    this.onPasswordChange,
+    this.onRepeatedPasswordChange,
+  }) : super(key: key);
 
   final WalletType type;
   final bool displayLanguageSelector;
   final bool displayBlockHeightSelector;
   final bool displayWalletPassword;
   final bool displayPassphrase;
-  final SeedTypeViewModel seedTypeViewModel;
+  final SeedSettingsViewModel seedSettingsViewModel;
   final FocusNode? blockHeightFocusNode;
   final Function(bool)? onHeightOrDateEntered;
   final void Function(String)? onSeedChange;
@@ -58,7 +57,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
         languageController = TextEditingController(),
         nameTextEditingController = TextEditingController(),
         passwordTextEditingController = displayWalletPassword ? TextEditingController() : null,
-        repeatedPasswordTextEditingController = displayWalletPassword ? TextEditingController() : null,
+        repeatedPasswordTextEditingController = displayWalletPassword
+            ? TextEditingController()
+            : null,
         passphraseController = TextEditingController(),
         seedTypeController = TextEditingController();
 
@@ -75,10 +76,11 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
   String language;
   void Function()? passwordListener;
   void Function()? repeatedPasswordListener;
+  void Function()? passphraseListener;
 
   @override
   void initState() {
-    _setSeedType(widget.seedTypeViewModel.moneroSeedType);
+    _setSeedType(widget.seedSettingsViewModel.moneroSeedType);
     _setLanguageLabel(language);
 
     if (passwordTextEditingController != null) {
@@ -87,14 +89,19 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
     }
 
     if (repeatedPasswordTextEditingController != null) {
-      repeatedPasswordListener = () => widget.onRepeatedPasswordChange?.call(repeatedPasswordTextEditingController!.text);
+      repeatedPasswordListener =
+          () => widget.onRepeatedPasswordChange?.call(repeatedPasswordTextEditingController!.text);
       repeatedPasswordTextEditingController?.addListener(repeatedPasswordListener!);
     }
+
+    passphraseListener = () => widget.seedSettingsViewModel.setPassphrase(passphraseController.text);
+    passphraseController.addListener(passphraseListener!);
+
     moneroSeedTypeReaction =
-        reaction((_) => widget.seedTypeViewModel.moneroSeedType, (SeedType item) {
-      _setSeedType(item);
-      _changeLanguage('English');
-    });
+        reaction((_) => widget.seedSettingsViewModel.moneroSeedType, (MoneroSeedType item) {
+          _setSeedType(item);
+          _changeLanguage('English');
+        });
 
     super.initState();
   }
@@ -110,6 +117,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
     if (repeatedPasswordListener != null) {
       repeatedPasswordTextEditingController?.removeListener(repeatedPasswordListener!);
     }
+
+    passphraseController.removeListener(passphraseListener!);
+
     super.dispose();
   }
 
@@ -118,11 +128,13 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
         Polyseed.isValidSeed(seed)) {
       final lang = PolyseedLang.getByPhrase(seed);
 
-      _changeSeedType(SeedType.polyseed);
+      _changeSeedType(MoneroSeedType.polyseed);
       _changeLanguage(lang.nameEnglish);
     }
-    if (widget.type == WalletType.wownero && seed.split(" ").length == 14) {
-      _changeSeedType(SeedType.wowneroSeed);
+    if (widget.type == WalletType.wownero && seed
+        .split(" ")
+        .length == 14) {
+      _changeSeedType(MoneroSeedType.wowneroSeed);
       _changeLanguage("English");
     }
     widget.onSeedChange?.call(seed);
@@ -140,7 +152,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
                 children: [
                   BaseTextFormField(
                     controller: nameTextEditingController,
-                    hintText: S.of(context).wallet_name,
+                    hintText: S
+                        .of(context)
+                        .wallet_name,
                     suffixIcon: IconButton(
                       onPressed: () async {
                         final rName = await generateName();
@@ -156,7 +170,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
                         padding: const EdgeInsets.all(8),
                         decoration: BoxDecoration(
                           borderRadius: BorderRadius.circular(6.0),
-                          color: Theme.of(context).hintColor,
+                          color: Theme
+                              .of(context)
+                              .hintColor,
                         ),
                         width: 34,
                         height: 34,
@@ -183,13 +199,14 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
               onTap: () async {
                 await showPopUp<void>(
                     context: context,
-                    builder: (_) => Picker(
+                    builder: (_) =>
+                        Picker(
                           items: _getItems(),
                           selectedAtIndex: isPolyseed
                               ? 1
                               : seedTypeController.value.text.contains("14")
-                                  ? 2
-                                  : 0,
+                              ? 2
+                              : 0,
                           mainAxisAlignment: MainAxisAlignment.start,
                           onItemSelected: _changeSeedType,
                           isSeparated: false,
@@ -211,37 +228,43 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
           if (widget.displayWalletPassword)
             ...[BaseTextFormField(
                 controller: passwordTextEditingController,
-                hintText: S.of(context).password,
+                hintText: S
+                    .of(context)
+                    .password,
                 obscureText: true),
               BaseTextFormField(
                   controller: repeatedPasswordTextEditingController,
-                  hintText: S.of(context).repeat_wallet_password,
-                  obscureText: true)],
+                  hintText: S
+                      .of(context)
+                      .repeat_wallet_password,
+                  obscureText: true)
+            ],
           if (widget.displayLanguageSelector)
-          if (!seedTypeController.value.text.contains("14") && widget.displayLanguageSelector)
-            GestureDetector(
-              onTap: () async {
-                await showPopUp<void>(
-                    context: context,
-                    builder: (_) => SeedLanguagePicker(
-                          selected: language,
-                          onItemSelected: _changeLanguage,
-                          seedType: isPolyseed ? SeedType.polyseed : SeedType.legacy,
-                        ));
-              },
-              child: Container(
-                color: Colors.transparent,
-                padding: EdgeInsets.only(top: 20.0),
-                child: IgnorePointer(
-                  child: BaseTextFormField(
-                    controller: languageController,
-                    enableInteractiveSelection: false,
-                    readOnly: true,
-                    suffixIcon: expandIcon,
+            if (!seedTypeController.value.text.contains("14") && widget.displayLanguageSelector)
+              GestureDetector(
+                onTap: () async {
+                  await showPopUp<void>(
+                      context: context,
+                      builder: (_) =>
+                          SeedLanguagePicker(
+                            selected: language,
+                            onItemSelected: _changeLanguage,
+                            seedType: isPolyseed ? MoneroSeedType.polyseed : MoneroSeedType.legacy,
+                          ));
+                },
+                child: Container(
+                  color: Colors.transparent,
+                  padding: EdgeInsets.only(top: 20.0),
+                  child: IgnorePointer(
+                    child: BaseTextFormField(
+                      controller: languageController,
+                      enableInteractiveSelection: false,
+                      readOnly: true,
+                      suffixIcon: expandIcon,
+                    ),
                   ),
                 ),
               ),
-            ),
           if ((!isPolyseed) && widget.displayBlockHeightSelector)
             BlockchainHeightWidget(
               focusNode: widget.blockHeightFocusNode,
@@ -262,17 +285,20 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
   }
 
   bool get isPolyseed =>
-      widget.seedTypeViewModel.moneroSeedType == SeedType.polyseed &&
-      (widget.type == WalletType.monero || widget.type == WalletType.wownero);
+      widget.seedSettingsViewModel.moneroSeedType == MoneroSeedType.polyseed &&
+          (widget.type == WalletType.monero || widget.type == WalletType.wownero);
 
-  Widget get expandIcon => Container(
+  Widget get expandIcon =>
+      Container(
         padding: EdgeInsets.all(18),
         width: 24,
         height: 24,
         child: Image.asset(
           'assets/images/arrow_bottom_purple_icon.png',
           height: 8,
-          color: Theme.of(context).hintColor,
+          color: Theme
+              .of(context)
+              .hintColor,
         ),
       );
 
@@ -280,8 +306,8 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
     final setLang = isPolyseed
         ? "POLYSEED_$language"
         : seedTypeController.value.text.contains("14")
-            ? "WOWSEED_" + language
-            : language;
+        ? "WOWSEED_" + language
+        : language;
     setState(() {
       this.language = setLang;
       seedWidgetStateKey.currentState!.changeSeedLanguage(setLang);
@@ -293,24 +319,24 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
   void _setLanguageLabel(String language) =>
       languageController.text = '${language.replaceAll("POLYSEED_", "")} (Seed language)';
 
-  void _changeSeedType(SeedType item) {
+  void _changeSeedType(MoneroSeedType item) {
     _setSeedType(item);
     _changeLanguage('English');
-    widget.seedTypeViewModel.setMoneroSeedType(item);
+    widget.seedSettingsViewModel.setMoneroSeedType(item);
   }
 
-  void _setSeedType(SeedType item) {
+  void _setSeedType(MoneroSeedType item) {
     seedTypeController.text = item.toString();
   }
 
-  List<SeedType> _getItems() {
+  List<MoneroSeedType> _getItems() {
     switch (widget.type) {
       case WalletType.monero:
-        return [SeedType.legacy, SeedType.polyseed];
+        return [MoneroSeedType.legacy, MoneroSeedType.polyseed];
       case WalletType.wownero:
-        return [SeedType.legacy, SeedType.polyseed, SeedType.wowneroSeed];
+        return [MoneroSeedType.legacy, MoneroSeedType.polyseed, MoneroSeedType.wowneroSeed];
       default:
-        return [SeedType.legacy];
+        return [MoneroSeedType.legacy];
     }
   }
 }
diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart
index c8fa3665e..741befbc0 100644
--- a/lib/src/screens/restore/wallet_restore_page.dart
+++ b/lib/src/screens/restore/wallet_restore_page.dart
@@ -12,7 +12,7 @@ import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:cake_wallet/view_model/restore/restore_mode.dart';
-import 'package:cake_wallet/view_model/seed_type_view_model.dart';
+import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
 import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -23,7 +23,7 @@ import 'package:mobx/mobx.dart';
 import 'package:smooth_page_indicator/smooth_page_indicator.dart';
 
 class WalletRestorePage extends BasePage {
-  WalletRestorePage(this.walletRestoreViewModel, this.seedTypeViewModel)
+  WalletRestorePage(this.walletRestoreViewModel, this.seedSettingsViewModel)
       : walletRestoreFromSeedFormKey = GlobalKey<WalletRestoreFromSeedFormState>(),
         walletRestoreFromKeysFormKey = GlobalKey<WalletRestoreFromKeysFromState>(),
         _pages = [],
@@ -33,7 +33,7 @@ class WalletRestorePage extends BasePage {
       switch (mode) {
         case WalletRestoreMode.seed:
           _pages.add(WalletRestoreFromSeedForm(
-              seedTypeViewModel: seedTypeViewModel,
+              seedSettingsViewModel: seedSettingsViewModel,
               displayBlockHeightSelector:
                   walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
               displayLanguageSelector: walletRestoreViewModel.hasSeedLanguageSelector,
@@ -96,7 +96,7 @@ class WalletRestorePage extends BasePage {
           ));
 
   final WalletRestoreViewModel walletRestoreViewModel;
-  final SeedTypeViewModel seedTypeViewModel;
+  final SeedSettingsViewModel seedSettingsViewModel;
   final PageController _controller;
   final List<Widget> _pages;
   final GlobalKey<WalletRestoreFromSeedFormState> walletRestoreFromSeedFormKey;
@@ -233,6 +233,7 @@ class WalletRestorePage extends BasePage {
                         onTap: () {
                           Navigator.of(context)
                               .pushNamed(Routes.advancedPrivacySettings, arguments: {
+                            'isFromRestore': true,
                             'type': walletRestoreViewModel.type,
                             'useTestnet': walletRestoreViewModel.useTestnet,
                             'toggleTestnet': walletRestoreViewModel.toggleUseTestnet
@@ -322,8 +323,7 @@ class WalletRestorePage extends BasePage {
       }
 
       if (walletRestoreViewModel.hasPassphrase) {
-        credentials['passphrase'] =
-            walletRestoreFromSeedFormKey.currentState!.passphraseController.text;
+        credentials['passphrase'] = seedSettingsViewModel.passphrase;
       }
 
       credentials['name'] =
@@ -426,6 +426,7 @@ class WalletRestorePage extends BasePage {
       }
 
       await walletRestoreViewModel.create(options: _credentials());
+      seedSettingsViewModel.setPassphrase(null);
     } catch (e) {
       _formProcessing = false;
       rethrow;
diff --git a/lib/src/widgets/seed_language_picker.dart b/lib/src/widgets/seed_language_picker.dart
index 5cb8f2fd3..4a63e3092 100644
--- a/lib/src/widgets/seed_language_picker.dart
+++ b/lib/src/widgets/seed_language_picker.dart
@@ -11,36 +11,36 @@ class SeedLanguagePickerOption {
   final String name;
   final String nameLocalized;
   final Image image;
-  final List<SeedType> supportedSeedTypes;
+  final List<MoneroSeedType> supportedSeedTypes;
 }
 
 final List<SeedLanguagePickerOption> seedLanguages = [
   SeedLanguagePickerOption('English', S.current.seed_language_english,
-      Image.asset('assets/images/flags/usa.png'), [SeedType.legacy, SeedType.polyseed]),
+      Image.asset('assets/images/flags/usa.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
   SeedLanguagePickerOption('Chinese (Simplified)', S.current.seed_language_chinese,
-      Image.asset('assets/images/flags/chn.png'), [SeedType.legacy, SeedType.polyseed]),
+      Image.asset('assets/images/flags/chn.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
   SeedLanguagePickerOption('Chinese (Traditional)', S.current.seed_language_chinese_traditional,
-      Image.asset('assets/images/flags/chn.png'), [SeedType.polyseed]),
+      Image.asset('assets/images/flags/chn.png'), [MoneroSeedType.polyseed]),
   SeedLanguagePickerOption('Dutch', S.current.seed_language_dutch,
-      Image.asset('assets/images/flags/nld.png'), [SeedType.legacy]),
+      Image.asset('assets/images/flags/nld.png'), [MoneroSeedType.legacy]),
   SeedLanguagePickerOption('German', S.current.seed_language_german,
-      Image.asset('assets/images/flags/deu.png'), [SeedType.legacy]),
+      Image.asset('assets/images/flags/deu.png'), [MoneroSeedType.legacy]),
   SeedLanguagePickerOption('Japanese', S.current.seed_language_japanese,
-      Image.asset('assets/images/flags/jpn.png'), [SeedType.legacy, SeedType.polyseed]),
+      Image.asset('assets/images/flags/jpn.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
   SeedLanguagePickerOption('Korean', S.current.seed_language_korean,
-      Image.asset('assets/images/flags/kor.png'), [SeedType.polyseed]),
+      Image.asset('assets/images/flags/kor.png'), [MoneroSeedType.polyseed]),
   SeedLanguagePickerOption('Portuguese', S.current.seed_language_portuguese,
-      Image.asset('assets/images/flags/prt.png'), [SeedType.legacy, SeedType.polyseed]),
+      Image.asset('assets/images/flags/prt.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
   SeedLanguagePickerOption('Russian', S.current.seed_language_russian,
-      Image.asset('assets/images/flags/rus.png'), [SeedType.legacy]),
+      Image.asset('assets/images/flags/rus.png'), [MoneroSeedType.legacy]),
   SeedLanguagePickerOption('Czech', S.current.seed_language_czech,
-      Image.asset('assets/images/flags/czk.png'), [SeedType.polyseed]),
+      Image.asset('assets/images/flags/czk.png'), [MoneroSeedType.polyseed]),
   SeedLanguagePickerOption('Spanish', S.current.seed_language_spanish,
-      Image.asset('assets/images/flags/esp.png'), [SeedType.legacy, SeedType.polyseed]),
+      Image.asset('assets/images/flags/esp.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
   SeedLanguagePickerOption('French', S.current.seed_language_french,
-      Image.asset('assets/images/flags/fra.png'), [SeedType.legacy, SeedType.polyseed]),
+      Image.asset('assets/images/flags/fra.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
   SeedLanguagePickerOption('Italian', S.current.seed_language_italian,
-      Image.asset('assets/images/flags/ita.png'), [SeedType.legacy, SeedType.polyseed]),
+      Image.asset('assets/images/flags/ita.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
 ];
 
 const defaultSeedLanguage = 'English';
@@ -51,11 +51,11 @@ class SeedLanguagePicker extends StatefulWidget {
   SeedLanguagePicker(
       {Key? key,
       this.selected = defaultSeedLanguage,
-      this.seedType = SeedType.defaultSeedType,
+      this.seedType = MoneroSeedType.defaultSeedType,
       required this.onItemSelected})
       : super(key: key);
 
-  final SeedType seedType;
+  final MoneroSeedType seedType;
   final String selected;
   final Function(String) onItemSelected;
 
@@ -68,7 +68,7 @@ class SeedLanguagePickerState extends State<SeedLanguagePicker> {
   SeedLanguagePickerState(
       {required this.selected, required this.onItemSelected, required this.seedType});
 
-  final SeedType seedType;
+  final MoneroSeedType seedType;
   final String selected;
   final Function(String) onItemSelected;
 
diff --git a/lib/src/widgets/seed_language_selector.dart b/lib/src/widgets/seed_language_selector.dart
index dde78c58c..87f3aa573 100644
--- a/lib/src/widgets/seed_language_selector.dart
+++ b/lib/src/widgets/seed_language_selector.dart
@@ -7,11 +7,11 @@ import 'package:flutter/material.dart';
 
 class SeedLanguageSelector extends StatefulWidget {
   SeedLanguageSelector(
-      {Key? key, required this.initialSelected, this.seedType = SeedType.defaultSeedType})
+      {Key? key, required this.initialSelected, this.seedType = MoneroSeedType.defaultSeedType})
       : super(key: key);
 
   final String initialSelected;
-  final SeedType seedType;
+  final MoneroSeedType seedType;
 
   @override
   SeedLanguageSelectorState createState() => SeedLanguageSelectorState(selected: initialSelected);
diff --git a/lib/store/seed_settings_store.dart b/lib/store/seed_settings_store.dart
new file mode 100644
index 000000000..90c02ba97
--- /dev/null
+++ b/lib/store/seed_settings_store.dart
@@ -0,0 +1,11 @@
+import 'package:mobx/mobx.dart';
+
+part 'seed_settings_store.g.dart';
+
+class SeedSettingsStore = SeedSettingsStoreBase with _$SeedSettingsStore;
+
+abstract class SeedSettingsStoreBase with Store {
+
+  @observable
+  String? passphrase;
+}
diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart
index ee145195c..ea5f43d98 100644
--- a/lib/store/settings_store.dart
+++ b/lib/store/settings_store.dart
@@ -1,45 +1,46 @@
 import 'dart:io';
+
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
 import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
 import 'package:cake_wallet/core/secure_storage.dart';
+import 'package:cake_wallet/di.dart';
+import 'package:cake_wallet/entities/action_list_display_mode.dart';
 import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
-import 'package:cake_wallet/entities/provider_types.dart';
-import 'package:cake_wallet/entities/cake_2fa_preset_options.dart';
 import 'package:cake_wallet/entities/background_tasks.dart';
+import 'package:cake_wallet/entities/balance_display_mode.dart';
+import 'package:cake_wallet/entities/cake_2fa_preset_options.dart';
 import 'package:cake_wallet/entities/exchange_api_mode.dart';
+import 'package:cake_wallet/entities/fiat_api_mode.dart';
+import 'package:cake_wallet/entities/fiat_currency.dart';
+import 'package:cake_wallet/entities/language_service.dart';
 import 'package:cake_wallet/entities/pin_code_required_duration.dart';
 import 'package:cake_wallet/entities/preferences_key.dart';
+import 'package:cake_wallet/entities/provider_types.dart';
 import 'package:cake_wallet/entities/secret_store_key.dart';
 import 'package:cake_wallet/entities/seed_phrase_length.dart';
 import 'package:cake_wallet/entities/seed_type.dart';
 import 'package:cake_wallet/entities/sort_balance_types.dart';
 import 'package:cake_wallet/entities/wallet_list_order_types.dart';
-import 'package:cake_wallet/polygon/polygon.dart';
-import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
-import 'package:cake_wallet/view_model/settings/sync_mode.dart';
-import 'package:cake_wallet/utils/device_info.dart';
 import 'package:cake_wallet/ethereum/ethereum.dart';
-import 'package:cake_wallet/wallet_type_utils.dart';
-import 'package:cake_wallet/wownero/wownero.dart';
-import 'package:cw_core/transaction_priority.dart';
+import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
+import 'package:cake_wallet/monero/monero.dart';
+import 'package:cake_wallet/polygon/polygon.dart';
 import 'package:cake_wallet/themes/theme_base.dart';
 import 'package:cake_wallet/themes/theme_list.dart';
+import 'package:cake_wallet/utils/device_info.dart';
+import 'package:cake_wallet/utils/package_info.dart';
+import 'package:cake_wallet/view_model/settings/sync_mode.dart';
+import 'package:cake_wallet/wallet_type_utils.dart';
+import 'package:cake_wallet/wownero/wownero.dart';
+import 'package:cw_core/node.dart';
+import 'package:cw_core/set_app_secure_native.dart';
+import 'package:cw_core/transaction_priority.dart';
+import 'package:cw_core/wallet_type.dart';
 import 'package:device_info_plus/device_info_plus.dart';
 import 'package:flutter/material.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/utils/package_info.dart';
-import 'package:cake_wallet/di.dart';
-import 'package:cw_core/wallet_type.dart';
 import 'package:shared_preferences/shared_preferences.dart';
-import 'package:cake_wallet/entities/language_service.dart';
-import 'package:cake_wallet/entities/balance_display_mode.dart';
-import 'package:cake_wallet/entities/fiat_currency.dart';
-import 'package:cw_core/node.dart';
-import 'package:cake_wallet/monero/monero.dart';
-import 'package:cake_wallet/entities/action_list_display_mode.dart';
-import 'package:cake_wallet/entities/fiat_api_mode.dart';
-import 'package:cw_core/set_app_secure_native.dart';
 
 part 'settings_store.g.dart';
 
@@ -55,7 +56,8 @@ abstract class SettingsStoreBase with Store {
       required BalanceDisplayMode initialBalanceDisplayMode,
       required bool initialSaveRecipientAddress,
       required AutoGenerateSubaddressStatus initialAutoGenerateSubaddressStatus,
-      required SeedType initialMoneroSeedType,
+      required MoneroSeedType initialMoneroSeedType,
+      required BitcoinSeedType initialBitcoinSeedType,
       required bool initialAppSecure,
       required bool initialDisableBuy,
       required bool initialDisableSell,
@@ -128,6 +130,7 @@ abstract class SettingsStoreBase with Store {
         shouldSaveRecipientAddress = initialSaveRecipientAddress,
         autoGenerateSubaddressStatus = initialAutoGenerateSubaddressStatus,
         moneroSeedType = initialMoneroSeedType,
+        bitcoinSeedType = initialBitcoinSeedType,
         fiatApiMode = initialFiatMode,
         allowBiometricalAuthentication = initialAllowBiometricalAuthentication,
         selectedCake2FAPreset = initialCake2FAPresetOptions,
@@ -329,9 +332,14 @@ abstract class SettingsStoreBase with Store {
 
     reaction(
         (_) => moneroSeedType,
-        (SeedType moneroSeedType) =>
+        (MoneroSeedType moneroSeedType) =>
             sharedPreferences.setInt(PreferencesKey.moneroSeedType, moneroSeedType.raw));
 
+    reaction(
+        (_) => bitcoinSeedType,
+        (BitcoinSeedType bitcoinSeedType) => sharedPreferences.setInt(
+            PreferencesKey.bitcoinSeedType, bitcoinSeedType.raw));
+
     reaction(
         (_) => fiatApiMode,
         (FiatApiMode mode) =>
@@ -555,7 +563,8 @@ abstract class SettingsStoreBase with Store {
   static const defaultAutoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.initialized;
   static final walletPasswordDirectInput = Platform.isLinux;
   static const defaultSeedPhraseLength = SeedPhraseLength.twelveWords;
-  static const defaultMoneroSeedType = SeedType.defaultSeedType;
+  static const defaultMoneroSeedType = MoneroSeedType.defaultSeedType;
+  static const defaultBitcoinSeedType = BitcoinSeedType.defaultDerivationType;
 
   @observable
   FiatCurrency fiatCurrency;
@@ -585,7 +594,10 @@ abstract class SettingsStoreBase with Store {
   AutoGenerateSubaddressStatus autoGenerateSubaddressStatus;
 
   @observable
-  SeedType moneroSeedType;
+  MoneroSeedType moneroSeedType;
+
+  @observable
+  BitcoinSeedType bitcoinSeedType;
 
   @observable
   bool isAppSecure;
@@ -945,9 +957,15 @@ abstract class SettingsStoreBase with Store {
     final _moneroSeedType = sharedPreferences.getInt(PreferencesKey.moneroSeedType);
 
     final moneroSeedType = _moneroSeedType != null
-        ? SeedType.deserialize(raw: _moneroSeedType)
+        ? MoneroSeedType.deserialize(raw: _moneroSeedType)
         : defaultMoneroSeedType;
 
+    final _bitcoinSeedType = sharedPreferences.getInt(PreferencesKey.bitcoinSeedType);
+
+    final bitcoinSeedType = _bitcoinSeedType != null
+        ? BitcoinSeedType.deserialize(raw: _bitcoinSeedType)
+        : defaultBitcoinSeedType;
+
     final nodes = <WalletType, Node>{};
     final powNodes = <WalletType, Node>{};
 
@@ -1111,6 +1129,7 @@ abstract class SettingsStoreBase with Store {
       initialSaveRecipientAddress: shouldSaveRecipientAddress,
       initialAutoGenerateSubaddressStatus: autoGenerateSubaddressStatus,
       initialMoneroSeedType: moneroSeedType,
+      initialBitcoinSeedType: bitcoinSeedType,
       initialAppSecure: isAppSecure,
       initialDisableBuy: disableBuy,
       initialDisableSell: disableSell,
@@ -1233,9 +1252,15 @@ abstract class SettingsStoreBase with Store {
     final _moneroSeedType = sharedPreferences.getInt(PreferencesKey.moneroSeedType);
 
     moneroSeedType = _moneroSeedType != null
-        ? SeedType.deserialize(raw: _moneroSeedType)
+        ? MoneroSeedType.deserialize(raw: _moneroSeedType)
         : defaultMoneroSeedType;
 
+    final _bitcoinSeedType = sharedPreferences.getInt(PreferencesKey.bitcoinSeedType);
+
+    bitcoinSeedType = _bitcoinSeedType != null
+        ? BitcoinSeedType.deserialize(raw: _bitcoinSeedType)
+        : defaultBitcoinSeedType;
+
     balanceDisplayMode = BalanceDisplayMode.deserialize(
         raw: sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey)!);
     shouldSaveRecipientAddress =
diff --git a/lib/view_model/advanced_privacy_settings_view_model.dart b/lib/view_model/advanced_privacy_settings_view_model.dart
index 73308f15a..da294cdea 100644
--- a/lib/view_model/advanced_privacy_settings_view_model.dart
+++ b/lib/view_model/advanced_privacy_settings_view_model.dart
@@ -30,6 +30,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
 
   final SettingsStore _settingsStore;
 
+  @computed
   bool get hasSeedPhraseLengthOption {
     // convert to switch case so that it give a syntax error when adding a new wallet type
     // thus we don't forget about it
@@ -40,11 +41,14 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
       case WalletType.solana:
       case WalletType.tron:
         return true;
+
+      case WalletType.bitcoin:
+      case WalletType.litecoin:
+        return _settingsStore.bitcoinSeedType == BitcoinSeedType.bip39;
+
       case WalletType.monero:
       case WalletType.wownero:
       case WalletType.none:
-      case WalletType.bitcoin:
-      case WalletType.litecoin:
       case WalletType.haven:
       case WalletType.nano:
       case WalletType.banano:
@@ -52,7 +56,13 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
     }
   }
 
-  bool get hasSeedTypeOption => type == WalletType.monero || type == WalletType.wownero;
+  bool get hasSeedTypeOption => [WalletType.monero, WalletType.wownero].contains(type);
+
+  bool get hasPassphraseOption => [
+        WalletType.bitcoin,
+        WalletType.litecoin,
+        WalletType.bitcoinCash,
+      ].contains(type);
 
   @computed
   bool get addCustomNode => _addCustomNode;
@@ -61,7 +71,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
   SeedPhraseLength get seedPhraseLength => _settingsStore.seedPhraseLength;
 
   @computed
-  bool get isPolySeed => _settingsStore.moneroSeedType == SeedType.polyseed;
+  bool get isPolySeed => _settingsStore.moneroSeedType == MoneroSeedType.polyseed;
 
   @action
   void setFiatApiMode(FiatApiMode fiatApiMode) => _settingsStore.fiatApiMode = fiatApiMode;
diff --git a/lib/view_model/restore/restore_from_qr_vm.dart b/lib/view_model/restore/restore_from_qr_vm.dart
index f5938911b..789d7da52 100644
--- a/lib/view_model/restore/restore_from_qr_vm.dart
+++ b/lib/view_model/restore/restore_from_qr_vm.dart
@@ -7,6 +7,7 @@ import 'package:cake_wallet/solana/solana.dart';
 import 'package:cake_wallet/tron/tron.dart';
 import 'package:cake_wallet/view_model/restore/restore_mode.dart';
 import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
+import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
 import 'package:cake_wallet/wownero/wownero.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
@@ -26,13 +27,13 @@ class WalletRestorationFromQRVM = WalletRestorationFromQRVMBase with _$WalletRes
 
 abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store {
   WalletRestorationFromQRVMBase(AppStore appStore, WalletCreationService walletCreationService,
-      Box<WalletInfo> walletInfoSource, WalletType type)
+      Box<WalletInfo> walletInfoSource, WalletType type, SeedSettingsViewModel seedSettingsViewModel)
       : height = 0,
         viewKey = '',
         spendKey = '',
         wif = '',
         address = '',
-        super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
+        super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel, type: type, isRecovery: true);
 
   @observable
   int height;
diff --git a/lib/view_model/seed_settings_view_model.dart b/lib/view_model/seed_settings_view_model.dart
new file mode 100644
index 000000000..3a9536885
--- /dev/null
+++ b/lib/view_model/seed_settings_view_model.dart
@@ -0,0 +1,34 @@
+import 'package:cake_wallet/entities/seed_type.dart';
+import 'package:cake_wallet/store/app_store.dart';
+import 'package:cake_wallet/store/seed_settings_store.dart';
+import 'package:mobx/mobx.dart';
+
+part 'seed_settings_view_model.g.dart';
+
+class SeedSettingsViewModel = SeedSettingsViewModelBase with _$SeedSettingsViewModel;
+
+abstract class SeedSettingsViewModelBase with Store {
+  SeedSettingsViewModelBase(this._appStore, this._seedSettingsStore);
+
+  @computed
+  MoneroSeedType get moneroSeedType => _appStore.settingsStore.moneroSeedType;
+
+  @action
+  void setMoneroSeedType(MoneroSeedType seedType) => _appStore.settingsStore.moneroSeedType = seedType;
+
+  @computed
+  BitcoinSeedType get bitcoinSeedType => _appStore.settingsStore.bitcoinSeedType;
+
+  @action
+  void setBitcoinSeedType(BitcoinSeedType derivationType) =>
+      _appStore.settingsStore.bitcoinSeedType = derivationType;
+
+  @computed
+  String? get passphrase => this._seedSettingsStore.passphrase;
+
+  @action
+  void setPassphrase(String? passphrase) => this._seedSettingsStore.passphrase = passphrase;
+
+  final AppStore _appStore;
+  final SeedSettingsStore _seedSettingsStore;
+}
diff --git a/lib/view_model/seed_type_view_model.dart b/lib/view_model/seed_type_view_model.dart
deleted file mode 100644
index e3597be1c..000000000
--- a/lib/view_model/seed_type_view_model.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-import 'package:cake_wallet/entities/seed_type.dart';
-import 'package:cake_wallet/store/app_store.dart';
-import 'package:mobx/mobx.dart';
-
-part 'seed_type_view_model.g.dart';
-
-class SeedTypeViewModel = SeedTypeViewModelBase with _$SeedTypeViewModel;
-
-abstract class SeedTypeViewModelBase with Store {
-  SeedTypeViewModelBase(this._appStore);
-
-  @computed
-  SeedType get moneroSeedType => _appStore.settingsStore.moneroSeedType;
-
-  @action
-  void setMoneroSeedType(SeedType seedType) => _appStore.settingsStore.moneroSeedType = seedType;
-
-  final AppStore _appStore;
-}
diff --git a/lib/view_model/wallet_creation_vm.dart b/lib/view_model/wallet_creation_vm.dart
index e14934986..5760f5eec 100644
--- a/lib/view_model/wallet_creation_vm.dart
+++ b/lib/view_model/wallet_creation_vm.dart
@@ -1,20 +1,21 @@
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
+import 'package:cake_wallet/core/execution_state.dart';
 import 'package:cake_wallet/core/wallet_creation_service.dart';
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/di.dart';
 import 'package:cake_wallet/entities/background_tasks.dart';
+import 'package:cake_wallet/entities/generate_name.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/store/app_store.dart';
+import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
-import 'package:hive/hive.dart';
-import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/core/execution_state.dart';
+import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
+import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_credentials.dart';
-import 'package:cw_core/pathForWallet.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_type.dart';
-import 'package:cake_wallet/store/app_store.dart';
-import 'package:cake_wallet/entities/generate_name.dart';
+import 'package:hive/hive.dart';
+import 'package:mobx/mobx.dart';
 import 'package:polyseed/polyseed.dart';
 
 part 'wallet_creation_vm.g.dart';
@@ -23,6 +24,7 @@ class WalletCreationVM = WalletCreationVMBase with _$WalletCreationVM;
 
 abstract class WalletCreationVMBase with Store {
   WalletCreationVMBase(this._appStore, this._walletInfoSource, this.walletCreationService,
+      this.seedSettingsViewModel,
       {required this.type, required this.isRecovery})
       : state = InitialExecutionState(),
         name = '';
@@ -44,7 +46,6 @@ abstract class WalletCreationVMBase with Store {
 
   @observable
   String? repeatedWalletPassword;
-
   bool get hasWalletPassword => SettingsStoreBase.walletPasswordDirectInput;
 
   WalletType type;
@@ -52,6 +53,7 @@ abstract class WalletCreationVMBase with Store {
   final WalletCreationService walletCreationService;
   final Box<WalletInfo> _walletInfoSource;
   final AppStore _appStore;
+  final SeedSettingsViewModel seedSettingsViewModel;
 
   bool isPolyseed(String seed) =>
       (type == WalletType.monero || type == WalletType.wownero) &&
@@ -109,17 +111,35 @@ abstract class WalletCreationVMBase with Store {
       getIt.get<BackgroundTasks>().registerSyncTask();
       _appStore.authenticationStore.allowed();
       state = ExecutedSuccessfullyState();
-    } catch (e, s) {
+    } catch (e, _) {
       state = FailureState(e.toString());
     }
   }
 
   DerivationInfo? getDefaultDerivation() {
-    switch (this.type) {
+    final useBip39 = seedSettingsViewModel.bitcoinSeedType.type == DerivationType.bip39;
+    switch (type) {
       case WalletType.nano:
         return DerivationInfo(derivationType: DerivationType.nano);
       case WalletType.bitcoin:
+        if (useBip39) {
+          return DerivationInfo(
+            derivationType: DerivationType.bip39,
+            derivationPath: "m/84'/0'/0'",
+            description: "Standard BIP84 native segwit",
+            scriptType: "p2wpkh",
+          );
+        }
+        return bitcoin!.getElectrumDerivations()[DerivationType.electrum]!.first;
       case WalletType.litecoin:
+        if (useBip39) {
+          return DerivationInfo(
+            derivationType: DerivationType.bip39,
+            derivationPath: "m/84'/2'/0'",
+            description: "Default Litecoin",
+            scriptType: "p2wpkh",
+          );
+        }
         return bitcoin!.getElectrumDerivations()[DerivationType.electrum]!.first;
       default:
         return null;
diff --git a/lib/view_model/wallet_hardware_restore_view_model.dart b/lib/view_model/wallet_hardware_restore_view_model.dart
index 804ef7e3c..68bc95a00 100644
--- a/lib/view_model/wallet_hardware_restore_view_model.dart
+++ b/lib/view_model/wallet_hardware_restore_view_model.dart
@@ -5,6 +5,7 @@ import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/polygon/polygon.dart';
 import 'package:cake_wallet/store/app_store.dart';
 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
+import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
 import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
 import 'package:cw_core/hardware/hardware_account_data.dart';
 import 'package:cw_core/wallet_base.dart';
@@ -25,10 +26,15 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with
 
   int _nextIndex = 0;
 
-  WalletHardwareRestoreViewModelBase(this.ledgerViewModel, AppStore appStore,
-      WalletCreationService walletCreationService, Box<WalletInfo> walletInfoSource,
+  WalletHardwareRestoreViewModelBase(
+      this.ledgerViewModel,
+      AppStore appStore,
+      WalletCreationService walletCreationService,
+      Box<WalletInfo> walletInfoSource,
+      SeedSettingsViewModel seedSettingsViewModel,
       {required WalletType type})
-      : super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
+      : super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel,
+            type: type, isRecovery: true);
 
   @observable
   String name = "";
diff --git a/lib/view_model/wallet_keys_view_model.dart b/lib/view_model/wallet_keys_view_model.dart
index 1d5c27fed..9921ae30a 100644
--- a/lib/view_model/wallet_keys_view_model.dart
+++ b/lib/view_model/wallet_keys_view_model.dart
@@ -276,7 +276,8 @@ abstract class WalletKeysViewModelBase with Store {
       if (_appStore.wallet!.seed == null &&
           _appStore.wallet!.privateKey != null)
         'private_key': _appStore.wallet!.privateKey!,
-      if (restoreHeightResult != null) ...{'height': restoreHeightResult}
+      if (restoreHeightResult != null) ...{'height': restoreHeightResult},
+      if (_appStore.wallet!.passphrase != null) 'passphrase': _appStore.wallet!.passphrase!
     };
   }
 
diff --git a/lib/view_model/wallet_new_vm.dart b/lib/view_model/wallet_new_vm.dart
index a618695b1..8c0f4f95f 100644
--- a/lib/view_model/wallet_new_vm.dart
+++ b/lib/view_model/wallet_new_vm.dart
@@ -1,35 +1,42 @@
-import 'package:cake_wallet/ethereum/ethereum.dart';
+import 'package:cake_wallet/bitcoin/bitcoin.dart';
 import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
-import 'package:cake_wallet/solana/solana.dart';
-import 'package:cake_wallet/tron/tron.dart';
-import 'package:cake_wallet/wownero/wownero.dart';
-import 'package:hive/hive.dart';
-import 'package:mobx/mobx.dart';
+import 'package:cake_wallet/core/wallet_creation_service.dart';
+import 'package:cake_wallet/entities/seed_type.dart';
+import 'package:cake_wallet/ethereum/ethereum.dart';
+import 'package:cake_wallet/haven/haven.dart';
 import 'package:cake_wallet/monero/monero.dart';
 import 'package:cake_wallet/nano/nano.dart';
+import 'package:cake_wallet/solana/solana.dart';
 import 'package:cake_wallet/store/app_store.dart';
+import 'package:cake_wallet/tron/tron.dart';
+import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
+import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
+import 'package:cake_wallet/wownero/wownero.dart';
 import 'package:cw_core/wallet_base.dart';
-import 'package:cake_wallet/core/wallet_creation_service.dart';
 import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_type.dart';
-import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
-import 'package:cake_wallet/bitcoin/bitcoin.dart';
-import 'package:cake_wallet/haven/haven.dart';
-import 'advanced_privacy_settings_view_model.dart';
+import 'package:hive/hive.dart';
+import 'package:mobx/mobx.dart';
 
 import '../polygon/polygon.dart';
+import 'advanced_privacy_settings_view_model.dart';
 
 part 'wallet_new_vm.g.dart';
 
 class WalletNewVM = WalletNewVMBase with _$WalletNewVM;
 
 abstract class WalletNewVMBase extends WalletCreationVM with Store {
-  WalletNewVMBase(AppStore appStore, WalletCreationService walletCreationService,
-      Box<WalletInfo> walletInfoSource, this.advancedPrivacySettingsViewModel,
+  WalletNewVMBase(
+      AppStore appStore,
+      WalletCreationService walletCreationService,
+      Box<WalletInfo> walletInfoSource,
+      this.advancedPrivacySettingsViewModel,
+      SeedSettingsViewModel seedSettingsViewModel,
       {required WalletType type})
       : selectedMnemonicLanguage = '',
-        super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: false);
+        super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel,
+            type: type, isRecovery: false);
 
   final AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel;
 
@@ -37,47 +44,58 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
   String selectedMnemonicLanguage;
 
   bool get hasLanguageSelector =>
-      type == WalletType.monero || type == WalletType.haven || type == WalletType.wownero;
+      [WalletType.monero, WalletType.haven, WalletType.wownero].contains(type);
 
   int get seedPhraseWordsLength {
     switch (type) {
       case WalletType.monero:
       case WalletType.wownero:
-        if (advancedPrivacySettingsViewModel.isPolySeed) {
-          return 16;
-        }
-        return 25;
+        return advancedPrivacySettingsViewModel.isPolySeed ? 16 : 25;
       case WalletType.tron:
       case WalletType.solana:
       case WalletType.polygon:
       case WalletType.ethereum:
       case WalletType.bitcoinCash:
         return advancedPrivacySettingsViewModel.seedPhraseLength.value;
+      case WalletType.bitcoin:
+      case WalletType.litecoin:
+        return seedSettingsViewModel.bitcoinSeedType == BitcoinSeedType.bip39
+            ? advancedPrivacySettingsViewModel.seedPhraseLength.value
+            : 24;
       default:
         return 24;
     }
   }
 
-  bool get hasSeedType => type == WalletType.monero || type == WalletType.wownero;
+  bool get hasSeedType => [WalletType.monero, WalletType.wownero].contains(type);
 
   @override
   WalletCredentials getCredentials(dynamic _options) {
     final options = _options as List<dynamic>?;
+    final passphrase = seedSettingsViewModel.passphrase;
+    seedSettingsViewModel.setPassphrase(null);
+
     switch (type) {
       case WalletType.monero:
         return monero!.createMoneroNewWalletCredentials(
-            name: name, language: options!.first as String, password: walletPassword, isPolyseed: options.last as bool);
+            name: name,
+            language: options!.first as String,
+            password: walletPassword,
+            isPolyseed: options.last as bool);
       case WalletType.bitcoin:
-        return bitcoin!.createBitcoinNewWalletCredentials(name: name, password: walletPassword);
+        return bitcoin!.createBitcoinNewWalletCredentials(
+            name: name, password: walletPassword, passphrase: passphrase);
       case WalletType.litecoin:
-        return bitcoin!.createBitcoinNewWalletCredentials(name: name, password: walletPassword);
+        return bitcoin!.createBitcoinNewWalletCredentials(
+            name: name, password: walletPassword, passphrase: passphrase);
       case WalletType.haven:
         return haven!.createHavenNewWalletCredentials(
             name: name, language: options!.first as String, password: walletPassword);
       case WalletType.ethereum:
         return ethereum!.createEthereumNewWalletCredentials(name: name, password: walletPassword);
       case WalletType.bitcoinCash:
-        return bitcoinCash!.createBitcoinCashNewWalletCredentials(name: name, password: walletPassword);
+        return bitcoinCash!.createBitcoinCashNewWalletCredentials(
+            name: name, password: walletPassword, passphrase: passphrase);
       case WalletType.nano:
       case WalletType.banano:
         return nano!.createNanoNewWalletCredentials(name: name);
diff --git a/lib/view_model/wallet_restore_view_model.dart b/lib/view_model/wallet_restore_view_model.dart
index a38baabd8..a365a2040 100644
--- a/lib/view_model/wallet_restore_view_model.dart
+++ b/lib/view_model/wallet_restore_view_model.dart
@@ -1,25 +1,26 @@
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
-import 'package:cake_wallet/di.dart';
-import 'package:cake_wallet/nano/nano.dart';
-import 'package:cake_wallet/ethereum/ethereum.dart';
-import 'package:cake_wallet/wownero/wownero.dart';
 import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
-import 'package:cake_wallet/polygon/polygon.dart';
-import 'package:cake_wallet/solana/solana.dart';
-import 'package:cake_wallet/tron/tron.dart';
-import 'package:hive/hive.dart';
-import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/store/app_store.dart';
-import 'package:cw_core/wallet_base.dart';
 import 'package:cake_wallet/core/generate_wallet_password.dart';
 import 'package:cake_wallet/core/wallet_creation_service.dart';
-import 'package:cw_core/wallet_credentials.dart';
-import 'package:cw_core/wallet_type.dart';
-import 'package:cw_core/wallet_info.dart';
-import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
-import 'package:cake_wallet/monero/monero.dart';
+import 'package:cake_wallet/di.dart';
+import 'package:cake_wallet/ethereum/ethereum.dart';
 import 'package:cake_wallet/haven/haven.dart';
+import 'package:cake_wallet/monero/monero.dart';
+import 'package:cake_wallet/nano/nano.dart';
+import 'package:cake_wallet/polygon/polygon.dart';
+import 'package:cake_wallet/solana/solana.dart';
+import 'package:cake_wallet/store/app_store.dart';
+import 'package:cake_wallet/tron/tron.dart';
 import 'package:cake_wallet/view_model/restore/restore_mode.dart';
+import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
+import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
+import 'package:cake_wallet/wownero/wownero.dart';
+import 'package:cw_core/wallet_base.dart';
+import 'package:cw_core/wallet_credentials.dart';
+import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:hive/hive.dart';
+import 'package:mobx/mobx.dart';
 
 part 'wallet_restore_view_model.g.dart';
 
@@ -27,7 +28,7 @@ class WalletRestoreViewModel = WalletRestoreViewModelBase with _$WalletRestoreVi
 
 abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
   WalletRestoreViewModelBase(AppStore appStore, WalletCreationService walletCreationService,
-      Box<WalletInfo> walletInfoSource,
+      Box<WalletInfo> walletInfoSource, SeedSettingsViewModel seedSettingsViewModel,
       {required WalletType type})
       : hasSeedLanguageSelector =
             type == WalletType.monero || type == WalletType.haven || type == WalletType.wownero,
@@ -41,7 +42,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
             type == WalletType.tron,
         isButtonEnabled = false,
         mode = WalletRestoreMode.seed,
-        super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true) {
+        super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel, type: type, isRecovery: true) {
     switch (type) {
       case WalletType.monero:
         availableModes = WalletRestoreMode.values;
@@ -76,7 +77,8 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
   final bool hasBlockchainHeightLanguageSelector;
   final bool hasRestoreFromPrivateKey;
 
-  bool get hasPassphrase => [WalletType.bitcoin, WalletType.litecoin].contains(type);
+  bool get hasPassphrase =>
+      [WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(type);
 
   @observable
   WalletRestoreMode mode;
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index f84f6102b..89068d2d0 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "هل أنت متأكد أنك تريد حذف محفظة ${wallet_name}؟",
   "deleteConnectionConfirmationPrompt": "ـﺑ ﻝﺎﺼﺗﻻﺍ ﻑﺬﺣ ﺪﻳﺮﺗ ﻚﻧﺃ ﺪﻛﺄﺘﻣ ﺖﻧﺃ ﻞﻫ",
   "denominations": "الطوائف",
+  "derivationpath": "مسار الاشتقاق",
   "descending": "النزول",
   "description": "ﻒﺻﻭ",
   "destination_tag": "علامة الوجهة:",
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index 0b6b688bb..1ff8fdf85 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Сигурни ли сте, че искате да изтриете протфейла ${wallet_name}?",
   "deleteConnectionConfirmationPrompt": "Сигурни ли сте, че искате да изтриете връзката към",
   "denominations": "Деноминации",
+  "derivationpath": "Пътят на производно",
   "descending": "Низходящ",
   "description": "Описание",
   "destination_tag": "Destination tag:",
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index ef225041d..904c6d8e4 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Opravdu chcete smazat ${wallet_name} peněženku?",
   "deleteConnectionConfirmationPrompt": "Jste si jisti, že chcete smazat připojení k?",
   "denominations": "Označení",
+  "derivationpath": "Derivační cesta",
   "descending": "Klesající",
   "description": "Popis",
   "destination_tag": "Destination Tag:",
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 393c3d928..860d4114d 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Sind Sie sicher, dass Sie das ${wallet_name} Wallet löschen möchten?",
   "deleteConnectionConfirmationPrompt": "Sind Sie sicher, dass Sie die Verbindung zu löschen möchten?",
   "denominations": "Konfessionen",
+  "derivationpath": "Ableitungspfad",
   "descending": "Absteigend",
   "description": "Beschreibung",
   "destination_tag": "Ziel-Tag:",
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 4ac7dd8fd..9f89eb6ab 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Are you sure that you want to delete ${wallet_name} wallet?",
   "deleteConnectionConfirmationPrompt": "Are you sure that you want to delete the connection to",
   "denominations": "Denominations",
+  "derivationpath": "Derivation Path",
   "descending": "Descending",
   "description": "Description",
   "destination_tag": "Destination tag:",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index c308f045a..250decfc4 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "¿Está seguro de que desea eliminar la billetera ${wallet_name}?",
   "deleteConnectionConfirmationPrompt": "¿Está seguro de que desea eliminar la conexión a",
   "denominations": "Denominaciones",
+  "derivationpath": "Ruta de derivación",
   "descending": "Descendente",
   "description": "Descripción",
   "destination_tag": "Etiqueta de destino:",
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index 4bc5c9809..297019aa0 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Êtes-vous sûr de vouloir supprimer le portefeuille (wallet) ${wallet_name}?",
   "deleteConnectionConfirmationPrompt": "Êtes-vous sûr de vouloir supprimer la connexion à",
   "denominations": "Dénominations",
+  "derivationpath": "Chemin de dérivation",
   "descending": "Descendant",
   "description": "Description",
   "destination_tag": "Tag de destination :",
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index 025a33f6b..05cdf27d4 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Shin kun tabbata cewa kuna son share jakar ${wallet_name}?",
   "deleteConnectionConfirmationPrompt": "Shin kun tabbata cewa kuna son share haɗin zuwa",
   "denominations": "Denominations",
+  "derivationpath": "Hanyar Nasara",
   "descending": "Saukowa",
   "description": "Bayani",
   "destination_tag": "Tambarin makoma:",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index 346c420a9..30f86d9ae 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "क्या आप वाकई ${wallet_name} वॉलेट हटाना चाहते हैं?",
   "deleteConnectionConfirmationPrompt": "क्या आप वाकई कनेक्शन हटाना चाहते हैं?",
   "denominations": "मूल्यवर्ग",
+  "derivationpath": "व्युत्पत्ति पथ",
   "descending": "अवरोही",
   "description": "विवरण",
   "destination_tag": "गंतव्य टैग:",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 6f5bc88a6..0d6e9a0d8 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Jeste li sigurni da želite izbrisati ${wallet_name} novčanik?",
   "deleteConnectionConfirmationPrompt": "Jeste li sigurni da želite izbrisati vezu s",
   "denominations": "Denominacije",
+  "derivationpath": "Put derivacije",
   "descending": "Silazni",
   "description": "Opis",
   "destination_tag": "Odredišna oznaka:",
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index 2bc298aa7..65703e0bc 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Apakah Anda yakin ingin menghapus dompet ${wallet_name}?",
   "deleteConnectionConfirmationPrompt": "Apakah Anda yakin ingin menghapus koneksi ke",
   "denominations": "Denominasi",
+  "derivationpath": "Jalur derivasi",
   "descending": "Menurun",
   "description": "Keterangan",
   "destination_tag": "Tag tujuan:",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index 0548b0ad2..c2ba20ce0 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -196,6 +196,7 @@
   "delete_wallet_confirm_message": "Sei sicuro di voler eliminare il portafoglio ${wallet_name}?",
   "deleteConnectionConfirmationPrompt": "Sei sicuro di voler eliminare la connessione a",
   "denominations": "Denominazioni",
+  "derivationpath": "Percorso di derivazione",
   "descending": "Discendente",
   "description": "Descrizione",
   "destination_tag": "Tag destinazione:",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index c53a6d001..ab6605257 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "${wallet_name} ウォレットを削除してもよろしいですか?",
   "deleteConnectionConfirmationPrompt": "への接続を削除してもよろしいですか?",
   "denominations": "宗派",
+  "derivationpath": "派生パス",
   "descending": "下降",
   "description": "説明",
   "destination_tag": "宛先タグ:",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index be6757d99..da10162ad 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "${wallet_name} 지갑을 삭제하시겠습니까?",
   "deleteConnectionConfirmationPrompt": "다음 연결을 삭제하시겠습니까?",
   "denominations": "교파",
+  "derivationpath": "파생 경로",
   "descending": "내림차순",
   "description": "설명",
   "destination_tag": "목적지 태그:",
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index c53dffb6b..e04c75d62 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "${wallet_name} ပိုက်ဆံအိတ်ကို ဖျက်လိုသည်မှာ သေချာပါသလား။",
   "deleteConnectionConfirmationPrompt": "ချိတ်ဆက်မှုကို ဖျက်လိုသည်မှာ သေချာပါသလား။",
   "denominations": "ဂိုဏ်းချုပ်ပစ္စည်းများ",
+  "derivationpath": "derivation လမ်းကြောင်း",
   "descending": "ဆင်း",
   "description": "ဖော်ပြချက်",
   "destination_tag": "ခရီးဆုံးအမှတ်-",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index 2d55344f5..dfa7c2d8f 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Weet u zeker dat u de portemonnee van ${wallet_name} wilt verwijderen?",
   "deleteConnectionConfirmationPrompt": "Weet u zeker dat u de verbinding met",
   "denominations": "Denominaties",
+  "derivationpath": "Afleidingspad",
   "descending": "Aflopend",
   "description": "Beschrijving",
   "destination_tag": "Bestemmingstag:",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 833fc0308..397ea2bcb 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Czy na pewno chcesz usunąć portfel ${wallet_name}?",
   "deleteConnectionConfirmationPrompt": "Czy na pewno chcesz usunąć połączenie z",
   "denominations": "Wyznaczenia",
+  "derivationpath": "Ścieżka pochodna",
   "descending": "Schodzenie",
   "description": "Opis",
   "destination_tag": "Tag docelowy:",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index bd6d9b506..cbe66715a 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Tem certeza de que deseja excluir a carteira ${wallet_name}?",
   "deleteConnectionConfirmationPrompt": "Tem certeza de que deseja excluir a conexão com",
   "denominations": "Denominações",
+  "derivationpath": "Caminho de derivação",
   "descending": "descendente",
   "description": "Descrição",
   "destination_tag": "Tag de destino:",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index d43572351..9976de9f8 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Вы уверены, что хотите удалить кошелек ${wallet_name}?",
   "deleteConnectionConfirmationPrompt": "Вы уверены, что хотите удалить подключение к",
   "denominations": "Деноминации",
+  "derivationpath": "Путь получения",
   "descending": "Нисходящий",
   "description": "Описание",
   "destination_tag": "Целевой тег:",
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index d948ba6d6..e873fe5eb 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "คุณแน่ใจหรือว่าต้องการลบกระเป๋า${wallet_name}?",
   "deleteConnectionConfirmationPrompt": "คุณแน่ใจหรือไม่ว่าต้องการลบการเชื่อมต่อไปยัง",
   "denominations": "นิกาย",
+  "derivationpath": "เส้นทางที่ได้มา",
   "descending": "ลงมา",
   "description": "คำอธิบาย",
   "destination_tag": "แท็กปลายทาง:",
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index a0ab030c8..c1bd2bae7 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Sigurado ka ba na gusto mong tanggalin ang iyong ${wallet_name} wallet?",
   "deleteConnectionConfirmationPrompt": "Sigurado ka bang gusto mong tanggalin ang koneksyon sa",
   "denominations": "Mga Denominasyon",
+  "derivationpath": "Landas ng derivation",
   "descending": "Pababang",
   "description": "Paglalarawan",
   "destination_tag": "Tag ng patutunguhan:",
@@ -661,14 +662,14 @@
   "show_details": "Ipakita ang mga detalye",
   "show_keys": "Ipakita ang mga seed/key",
   "show_market_place": "Ipakita ang Marketplace",
+  "show_seed": "Ipakita ang seed",
   "sign_message": "Mag -sign Message",
+  "sign_up": "Mag-sign Up",
   "sign_verify_message": "Mag -sign o i -verify ang mensahe",
   "sign_verify_message_sub": "Mag -sign o i -verify ang isang mensahe gamit ang iyong pribadong key",
   "sign_verify_title": "Mag -sign / Mag -verify",
   "signature": "Lagda",
   "signature_invalid_error": "Ang lagda ay hindi wasto para sa ibinigay na mensahe",
-  "show_seed": "Ipakita ang seed",
-  "sign_up": "Mag-sign Up",
   "signTransaction": "Mag-sign ang Transaksyon",
   "signup_for_card_accept_terms": "Mag-sign up para sa card at tanggapin ang mga tuntunin.",
   "silent_payments": "Tahimik na pagbabayad",
@@ -827,9 +828,9 @@
   "use_testnet": "Gumamit ng testnet",
   "value": "Halaga",
   "value_type": "Uri ng halaga",
-  "verify_message": "I -verify ang mensahe",
   "variable_pair_not_supported": "Ang variable na pares na ito ay hindi suportado sa mga napiling exchange",
   "verification": "Pag-verify",
+  "verify_message": "I -verify ang mensahe",
   "verify_with_2fa": "Mag-verify sa Cake 2FA",
   "version": "Bersyon ${currentVersion}",
   "view_all": "Tingnan lahat",
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index e7cdc5b12..ff7d9a120 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "${wallet_name} isimli cüzdanını silmek istediğinden emin misin?",
   "deleteConnectionConfirmationPrompt": "Bağlantıyı silmek istediğinizden emin misiniz?",
   "denominations": "Mezhepler",
+  "derivationpath": "Türev yolu",
   "descending": "Azalan",
   "description": "Tanım",
   "destination_tag": "Hedef Etiketi:",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 91b5b5266..95a3a38d8 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Ви впевнені, що хочете видалити гаманець ${wallet_name}?",
   "deleteConnectionConfirmationPrompt": "Ви впевнені, що хочете видалити з’єднання з",
   "denominations": "Конфесія",
+  "derivationpath": "Шлях виведення",
   "descending": "Низхідний",
   "description": "опис",
   "destination_tag": "Тег призначення:",
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index e54a0db34..5be1cb7a0 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "کیا آپ واقعی ${wallet_name} والیٹ کو حذف کرنا چاہتے ہیں؟",
   "deleteConnectionConfirmationPrompt": "۔ﮟﯿﮨ ﮯﺘﮨﺎﭼ ﺎﻧﺮﮐ ﻑﺬﺣ ﻮﮐ ﻦﺸﮑﻨﮐ ﭖﺁ ﮧﮐ ﮯﮨ ﻦﯿﻘﯾ ﻮﮐ ﭖﺁ ﺎﯿﮐ",
   "denominations": "فرق",
+  "derivationpath": "مشتق راستہ",
   "descending": "اترتے ہوئے",
   "description": "ﻞﯿﺼﻔﺗ",
   "destination_tag": "منزل کا ٹیگ:",
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index 8f47d8543..81d784d7f 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "Ṣó dá ẹ lójú pé ẹ fẹ́ pa àpamọ́wọ́ ${wallet_name}?",
   "deleteConnectionConfirmationPrompt": "Ṣe o da ọ loju pe o fẹ paarẹ asopọ si",
   "denominations": "Awọn ede",
+  "derivationpath": "Ọna Deriji",
   "descending": "Sọkalẹ",
   "description": "Apejuwe",
   "destination_tag": "Orúkọ tí ìbí tó a ránṣẹ́ sí:",
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index c864a529b..876c3bbfb 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -195,6 +195,7 @@
   "delete_wallet_confirm_message": "您确定要删除 ${wallet_name} 钱包吗?",
   "deleteConnectionConfirmationPrompt": "您确定要删除与",
   "denominations": "教派",
+  "derivationpath": "推导路径",
   "descending": "下降",
   "description": "描述",
   "destination_tag": "目标Tag:",
diff --git a/tool/configure.dart b/tool/configure.dart
index c9b6bbdda..b3194c4c8 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -151,7 +151,7 @@ abstract class Bitcoin {
     String? passphrase,
   });
   WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo});
-  WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password});
+  WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? passphrase});
   WalletCredentials createBitcoinHardwareWalletCredentials({required String name, required HardwareAccountData accountData, WalletInfo? walletInfo});
   List<String> getWordList();
   Map<String, String> getWalletKeys(Object wallet);
@@ -1021,10 +1021,10 @@ abstract class BitcoinCash {
       Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
 
   WalletCredentials createBitcoinCashNewWalletCredentials(
-      {required String name, WalletInfo? walletInfo, String? password});
+      {required String name, WalletInfo? walletInfo, String? password, String? passphrase});
 
   WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials(
-      {required String name, required String mnemonic, required String password});
+      {required String name, required String mnemonic, required String password, String? passphrase});
 
   TransactionPriority deserializeBitcoinCashTransactionPriority(int raw);
 

From 518bfbe40d1a70f08e9c25b0cf957f2b30eda282 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Mon, 26 Aug 2024 20:07:25 +0300
Subject: [PATCH 79/81] fetch accurate fee rates from Cake's mempool api
 (#1649)

* fetch accurate fee rates from mempool api

* remove duplicate exception handler onError call [skip ci]

* add the domain name
---
 cw_bitcoin/lib/electrum_wallet.dart           | 69 ++++++++++++++++---
 cw_bitcoin/pubspec.lock                       | 63 ++++++++++++++++-
 cw_bitcoin/pubspec.yaml                       |  1 +
 cw_monero/lib/monero_wallet_service.dart      | 38 +---------
 lib/entities/preferences_key.dart             |  1 +
 lib/src/screens/settings/privacy_page.dart    | 29 ++++++++
 lib/store/settings_store.dart                 | 10 +++
 lib/utils/exception_handler.dart              |  7 ++
 .../settings/privacy_settings_view_model.dart | 11 +++
 res/values/strings_ar.arb                     |  2 +
 res/values/strings_bg.arb                     |  2 +
 res/values/strings_cs.arb                     |  2 +
 res/values/strings_de.arb                     |  2 +
 res/values/strings_en.arb                     |  2 +
 res/values/strings_es.arb                     |  4 +-
 res/values/strings_fr.arb                     |  2 +
 res/values/strings_ha.arb                     |  2 +
 res/values/strings_hi.arb                     |  2 +
 res/values/strings_hr.arb                     |  2 +
 res/values/strings_hy.arb                     |  2 +
 res/values/strings_id.arb                     |  2 +
 res/values/strings_it.arb                     |  2 +
 res/values/strings_ja.arb                     |  2 +
 res/values/strings_ko.arb                     |  2 +
 res/values/strings_my.arb                     |  2 +
 res/values/strings_nl.arb                     |  2 +
 res/values/strings_pl.arb                     |  2 +
 res/values/strings_pt.arb                     |  2 +
 res/values/strings_ru.arb                     |  2 +
 res/values/strings_th.arb                     |  2 +
 res/values/strings_tl.arb                     |  2 +
 res/values/strings_tr.arb                     |  2 +
 res/values/strings_uk.arb                     |  2 +
 res/values/strings_ur.arb                     |  2 +
 res/values/strings_yo.arb                     |  2 +
 res/values/strings_zh.arb                     |  2 +
 36 files changed, 239 insertions(+), 46 deletions(-)

diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 0ce4844c6..be4cee4d8 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -5,6 +5,7 @@ import 'dart:isolate';
 import 'dart:math';
 
 import 'package:bitcoin_base/bitcoin_base.dart';
+import 'package:shared_preferences/shared_preferences.dart';
 import 'package:cw_core/encryption_file_utils.dart';
 import 'package:blockchain_utils/blockchain_utils.dart';
 import 'package:collection/collection.dart';
@@ -44,6 +45,7 @@ import 'package:mobx/mobx.dart';
 import 'package:rxdart/subjects.dart';
 import 'package:sp_scanner/sp_scanner.dart';
 import 'package:hex/hex.dart';
+import 'package:http/http.dart' as http;
 
 part 'electrum_wallet.g.dart';
 
@@ -101,6 +103,8 @@ abstract class ElectrumWalletBase
     );
 
     reaction((_) => syncStatus, _syncStatusReaction);
+
+    sharedPrefs.complete(SharedPreferences.getInstance());
   }
 
   static Bip32Slip10Secp256k1 getAccountHDWallet(CryptoCurrency? currency, BasedUtxoNetwork network,
@@ -196,6 +200,13 @@ abstract class ElectrumWalletBase
 
   bool _isTryingToConnect = false;
 
+  Completer<SharedPreferences> sharedPrefs = Completer();
+
+  Future<bool> checkIfMempoolAPIIsEnabled() async {
+    bool isMempoolAPIEnabled = (await sharedPrefs.future).getBool("use_mempool_fee_api") ?? true;
+    return isMempoolAPIEnabled;
+  }
+
   @action
   Future<void> setSilentPaymentsScanning(bool active) async {
     silentPaymentsScanningActive = active;
@@ -448,6 +459,20 @@ abstract class ElectrumWalletBase
 
   @action
   Future<void> updateFeeRates() async {
+    if (await checkIfMempoolAPIIsEnabled()) {
+      try {
+        final response =
+            await http.get(Uri.parse("http://mempool.cakewallet.com:8999/api/v1/fees/recommended"));
+
+        final result = json.decode(response.body) as Map<String, num>;
+        final slowFee = result['economyFee']?.toInt() ?? 0;
+        final mediumFee = result['hourFee']?.toInt() ?? 0;
+        final fastFee = result['fastestFee']?.toInt() ?? 0;
+        _feeRates = [slowFee, mediumFee, fastFee];
+        return;
+      } catch (_) {}
+    }
+
     final feeRates = await electrumClient.feeRates(network: network);
     if (feeRates != [0, 0, 0]) {
       _feeRates = feeRates;
@@ -1455,7 +1480,6 @@ abstract class ElectrumWalletBase
       // Create a list of available outputs
       final outputs = <BitcoinOutput>[];
       for (final out in bundle.originalTransaction.outputs) {
-
         // Check if the script contains OP_RETURN
         final script = out.scriptPubKey.script;
         if (script.contains('OP_RETURN') && memo == null) {
@@ -2058,13 +2082,42 @@ abstract class ElectrumWalletBase
         tx.inputAddresses!.isEmpty ||
         tx.outputAddresses == null ||
         tx.outputAddresses!.isEmpty) {
-      tx = ElectrumTransactionInfo.fromElectrumBundle(
-        bundle,
-        walletInfo.type,
-        network,
-        addresses: addressesSet,
-        height: tx.height,
-      );
+      List<String> inputAddresses = [];
+      List<String> outputAddresses = [];
+
+      for (int i = 0; i < bundle.originalTransaction.inputs.length; i++) {
+        final input = bundle.originalTransaction.inputs[i];
+        final inputTransaction = bundle.ins[i];
+        final vout = input.txIndex;
+        final outTransaction = inputTransaction.outputs[vout];
+        final address = addressFromOutputScript(outTransaction.scriptPubKey, network);
+
+        if (address.isNotEmpty) inputAddresses.add(address);
+      }
+
+      for (int i = 0; i < bundle.originalTransaction.outputs.length; i++) {
+        final out = bundle.originalTransaction.outputs[i];
+        final address = addressFromOutputScript(out.scriptPubKey, network);
+
+        if (address.isNotEmpty) outputAddresses.add(address);
+
+        // Check if the script contains OP_RETURN
+        final script = out.scriptPubKey.script;
+        if (script.contains('OP_RETURN')) {
+          final index = script.indexOf('OP_RETURN');
+          if (index + 1 <= script.length) {
+            try {
+              final opReturnData = script[index + 1].toString();
+              final decodedString = utf8.decode(HEX.decode(opReturnData));
+              outputAddresses.add('OP_RETURN:$decodedString');
+            } catch (_) {
+              outputAddresses.add('OP_RETURN:');
+            }
+          }
+        }
+      }
+      tx.inputAddresses = inputAddresses;
+      tx.outputAddresses = outputAddresses;
 
       transactionHistory.addOne(tx);
     }
diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock
index cdb88946e..b5e59cd88 100644
--- a/cw_bitcoin/pubspec.lock
+++ b/cw_bitcoin/pubspec.lock
@@ -350,6 +350,11 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  flutter_web_plugins:
+    dependency: transitive
+    description: flutter
+    source: sdk
+    version: "0.0.0"
   frontend_server_client:
     dependency: transitive
     description:
@@ -736,6 +741,62 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "0.27.7"
+  shared_preferences:
+    dependency: "direct main"
+    description:
+      name: shared_preferences
+      sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.3"
+  shared_preferences_android:
+    dependency: transitive
+    description:
+      name: shared_preferences_android
+      sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.2"
+  shared_preferences_foundation:
+    dependency: transitive
+    description:
+      name: shared_preferences_foundation
+      sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.5.2"
+  shared_preferences_linux:
+    dependency: transitive
+    description:
+      name: shared_preferences_linux
+      sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.4.1"
+  shared_preferences_platform_interface:
+    dependency: transitive
+    description:
+      name: shared_preferences_platform_interface
+      sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.4.1"
+  shared_preferences_web:
+    dependency: transitive
+    description:
+      name: shared_preferences_web
+      sha256: "59dc807b94d29d52ddbb1b3c0d3b9d0a67fc535a64e62a5542c8db0513fcb6c2"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.4.1"
+  shared_preferences_windows:
+    dependency: transitive
+    description:
+      name: shared_preferences_windows
+      sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.4.1"
   shelf:
     dependency: transitive
     description:
@@ -944,4 +1005,4 @@ packages:
     version: "2.2.1"
 sdks:
   dart: ">=3.3.0 <4.0.0"
-  flutter: ">=3.16.6"
+  flutter: ">=3.19.0"
diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml
index 2af1ac54e..84164b884 100644
--- a/cw_bitcoin/pubspec.yaml
+++ b/cw_bitcoin/pubspec.yaml
@@ -17,6 +17,7 @@ dependencies:
   mobx: ^2.0.7+4
   flutter_mobx: ^2.0.6+1
   intl: ^0.18.0
+  shared_preferences: ^2.0.15
   cw_core:
     path: ../cw_core
   bitbox:
diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart
index f9973f430..7f4672d43 100644
--- a/cw_monero/lib/monero_wallet_service.dart
+++ b/cw_monero/lib/monero_wallet_service.dart
@@ -9,11 +9,9 @@ import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:cw_core/get_height_by_date.dart';
-import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
 import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
 import 'package:cw_monero/api/wallet_manager.dart';
 import 'package:cw_monero/monero_wallet.dart';
-import 'package:flutter/widgets.dart';
 import 'package:hive/hive.dart';
 import 'package:polyseed/polyseed.dart';
 import 'package:monero/monero.dart' as monero;
@@ -120,7 +118,6 @@ class MoneroWalletService extends WalletService<
 
   @override
   Future<MoneroWallet> openWallet(String name, String password, {bool? retryOnFailure}) async {
-    MoneroWallet? wallet;
     try {
       final path = await pathForWallet(name: name, type: getType());
 
@@ -147,41 +144,10 @@ class MoneroWalletService extends WalletService<
       await wallet.init();
 
       return wallet;
-    } catch (e, s) {
+    } catch (e) {
       // TODO: Implement Exception for wallet list service.
 
-      final bool isBadAlloc = e.toString().contains('bad_alloc') ||
-          (e is WalletOpeningException &&
-              (e.message == 'std::bad_alloc' || e.message.contains('bad_alloc')));
-
-      final bool doesNotCorrespond = e.toString().contains('does not correspond') ||
-          (e is WalletOpeningException && e.message.contains('does not correspond'));
-
-      final bool isMissingCacheFilesIOS = e.toString().contains('basic_string') ||
-          (e is WalletOpeningException && e.message.contains('basic_string'));
-
-      final bool isMissingCacheFilesAndroid = e.toString().contains('input_stream') ||
-          e.toString().contains('input stream error') ||
-          (e is WalletOpeningException &&
-              (e.message.contains('input_stream') || e.message.contains('input stream error')));
-
-      final bool invalidSignature = e.toString().contains('invalid signature') ||
-          (e is WalletOpeningException && e.message.contains('invalid signature'));
-
-      final bool invalidPassword = e.toString().contains('invalid password') ||
-          (e is WalletOpeningException && e.message.contains('invalid password'));
-
-      if (!isBadAlloc &&
-          !doesNotCorrespond &&
-          !isMissingCacheFilesIOS &&
-          !isMissingCacheFilesAndroid &&
-          !invalidSignature &&
-          !invalidPassword &&
-          wallet != null &&
-          wallet.onError != null) {
-        wallet.onError!(FlutterErrorDetails(exception: e, stack: s));
-      }
-      if (invalidPassword || retryOnFailure == false) {
+      if (retryOnFailure == false) {
         rethrow;
       }
 
diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart
index 743357f92..714612ff1 100644
--- a/lib/entities/preferences_key.dart
+++ b/lib/entities/preferences_key.dart
@@ -61,6 +61,7 @@ class PreferencesKey {
   static const useEtherscan = 'use_etherscan';
   static const usePolygonScan = 'use_polygonscan';
   static const useTronGrid = 'use_trongrid';
+  static const useMempoolFeeAPI = 'use_mempool_fee_api';
   static const defaultNanoRep = 'default_nano_representative';
   static const defaultBananoRep = 'default_banano_representative';
   static const lookupsTwitter = 'looks_up_twitter';
diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart
index 0eaf3ffbd..7db244460 100644
--- a/lib/src/screens/settings/privacy_page.dart
+++ b/lib/src/screens/settings/privacy_page.dart
@@ -6,7 +6,9 @@ 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_choices_cell.dart';
 import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
+import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
 import 'package:cake_wallet/utils/device_info.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
 import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart';
 import 'package:flutter/material.dart';
@@ -111,6 +113,33 @@ class PrivacyPage extends BasePage {
                     _privacySettingsViewModel.setUseTronGrid(value);
                   },
                 ),
+              if (_privacySettingsViewModel.canUseMempoolFeeAPI)
+                SettingsSwitcherCell(
+                  title: S.current.live_fee_rates,
+                  value: _privacySettingsViewModel.useMempoolFeeAPI,
+                  onValueChange: (BuildContext _, bool isEnabled) async {
+                    if (!isEnabled) {
+                      final bool confirmation = await showPopUp<bool>(
+                          context: context,
+                          builder: (BuildContext context) {
+                            return AlertWithTwoActions(
+                                alertTitle: S.of(context).warning,
+                                alertContent: S.of(context).disable_fee_api_warning,
+                                rightButtonText: S.of(context).confirm,
+                                leftButtonText: S.of(context).cancel,
+                                actionRightButton: () => Navigator.of(context).pop(true),
+                                actionLeftButton: () => Navigator.of(context).pop(false));
+                          }) ??
+                          false;
+                      if (confirmation) {
+                        _privacySettingsViewModel.setUseMempoolFeeAPI(isEnabled);
+                      }
+                      return;
+                    }
+
+                    _privacySettingsViewModel.setUseMempoolFeeAPI(isEnabled);
+                  },
+                ),
               SettingsCellWithArrow(
                 title: S.current.domain_looks_up,
                 handler: (context) => Navigator.of(context).pushNamed(Routes.domainLookupsPage),
diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart
index ea5f43d98..f2738a293 100644
--- a/lib/store/settings_store.dart
+++ b/lib/store/settings_store.dart
@@ -101,6 +101,7 @@ abstract class SettingsStoreBase with Store {
       required this.useEtherscan,
       required this.usePolygonScan,
       required this.useTronGrid,
+      required this.useMempoolFeeAPI,
       required this.defaultNanoRep,
       required this.defaultBananoRep,
       required this.lookupsTwitter,
@@ -416,6 +417,9 @@ abstract class SettingsStoreBase with Store {
     reaction((_) => useTronGrid,
         (bool useTronGrid) => _sharedPreferences.setBool(PreferencesKey.useTronGrid, useTronGrid));
 
+    reaction((_) => useMempoolFeeAPI,
+        (bool useMempoolFeeAPI) => _sharedPreferences.setBool(PreferencesKey.useMempoolFeeAPI, useMempoolFeeAPI));
+
     reaction((_) => defaultNanoRep,
         (String nanoRep) => _sharedPreferences.setString(PreferencesKey.defaultNanoRep, nanoRep));
 
@@ -707,6 +711,9 @@ abstract class SettingsStoreBase with Store {
   @observable
   bool useTronGrid;
 
+  @observable
+  bool useMempoolFeeAPI;
+
   @observable
   String defaultNanoRep;
 
@@ -892,6 +899,7 @@ abstract class SettingsStoreBase with Store {
     final useEtherscan = sharedPreferences.getBool(PreferencesKey.useEtherscan) ?? true;
     final usePolygonScan = sharedPreferences.getBool(PreferencesKey.usePolygonScan) ?? true;
     final useTronGrid = sharedPreferences.getBool(PreferencesKey.useTronGrid) ?? true;
+    final useMempoolFeeAPI = sharedPreferences.getBool(PreferencesKey.useMempoolFeeAPI) ?? true;
     final defaultNanoRep = sharedPreferences.getString(PreferencesKey.defaultNanoRep) ?? "";
     final defaultBananoRep = sharedPreferences.getString(PreferencesKey.defaultBananoRep) ?? "";
     final lookupsTwitter = sharedPreferences.getBool(PreferencesKey.lookupsTwitter) ?? true;
@@ -1154,6 +1162,7 @@ abstract class SettingsStoreBase with Store {
       useEtherscan: useEtherscan,
       usePolygonScan: usePolygonScan,
       useTronGrid: useTronGrid,
+      useMempoolFeeAPI: useMempoolFeeAPI,
       defaultNanoRep: defaultNanoRep,
       defaultBananoRep: defaultBananoRep,
       lookupsTwitter: lookupsTwitter,
@@ -1307,6 +1316,7 @@ abstract class SettingsStoreBase with Store {
     useEtherscan = sharedPreferences.getBool(PreferencesKey.useEtherscan) ?? true;
     usePolygonScan = sharedPreferences.getBool(PreferencesKey.usePolygonScan) ?? true;
     useTronGrid = sharedPreferences.getBool(PreferencesKey.useTronGrid) ?? true;
+    useMempoolFeeAPI = sharedPreferences.getBool(PreferencesKey.useMempoolFeeAPI) ?? true;
     defaultNanoRep = sharedPreferences.getString(PreferencesKey.defaultNanoRep) ?? "";
     defaultBananoRep = sharedPreferences.getString(PreferencesKey.defaultBananoRep) ?? "";
     lookupsTwitter = sharedPreferences.getBool(PreferencesKey.lookupsTwitter) ?? true;
diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart
index 5e0c83f88..8fc8a8c0e 100644
--- a/lib/utils/exception_handler.dart
+++ b/lib/utils/exception_handler.dart
@@ -174,6 +174,13 @@ class ExceptionHandler {
     "ClientException: Write failed, uri=http",
     "Connection terminated during handshake",
     "Corrupted wallets seeds",
+    "bad_alloc",
+    "does not correspond",
+    "basic_string",
+    "input_stream",
+    "input stream error",
+    "invalid signature",
+    "invalid password",
   ];
 
   static Future<void> _addDeviceInfo(File file) async {
diff --git a/lib/view_model/settings/privacy_settings_view_model.dart b/lib/view_model/settings/privacy_settings_view_model.dart
index 90511af8e..c1e0fb1ce 100644
--- a/lib/view_model/settings/privacy_settings_view_model.dart
+++ b/lib/view_model/settings/privacy_settings_view_model.dart
@@ -1,3 +1,4 @@
+import 'package:cake_wallet/bitcoin/bitcoin.dart';
 import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
 import 'package:cake_wallet/entities/exchange_api_mode.dart';
 import 'package:cake_wallet/ethereum/ethereum.dart';
@@ -75,6 +76,9 @@ abstract class PrivacySettingsViewModelBase with Store {
   @computed
   bool get useTronGrid => _settingsStore.useTronGrid;
 
+  @computed
+  bool get useMempoolFeeAPI => _settingsStore.useMempoolFeeAPI;
+
   @computed
   bool get lookupTwitter => _settingsStore.lookupsTwitter;
 
@@ -99,6 +103,8 @@ abstract class PrivacySettingsViewModelBase with Store {
 
   bool get canUseTronGrid => _wallet.type == WalletType.tron;
 
+  bool get canUseMempoolFeeAPI => _wallet.type == WalletType.bitcoin;
+
   @action
   void setShouldSaveRecipientAddress(bool value) =>
       _settingsStore.shouldSaveRecipientAddress = value;
@@ -156,4 +162,9 @@ abstract class PrivacySettingsViewModelBase with Store {
     _settingsStore.useTronGrid = value;
     tron!.updateTronGridUsageState(_wallet, value);
   }
+
+  @action
+  void setUseMempoolFeeAPI(bool value) {
+    _settingsStore.useMempoolFeeAPI = value;
+  }
 }
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index 89068d2d0..0b238ad23 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -208,6 +208,7 @@
   "disable_buy": "تعطيل إجراء الشراء",
   "disable_cake_2fa": "تعطيل 2 عامل المصادقة",
   "disable_exchange": "تعطيل التبادل",
+  "disable_fee_api_warning": "من خلال إيقاف تشغيل هذا ، قد تكون معدلات الرسوم غير دقيقة في بعض الحالات ، لذلك قد ينتهي بك الأمر إلى دفع مبالغ زائدة أو دفع رسوم المعاملات الخاصة بك",
   "disable_fiat": "تعطيل fiat",
   "disable_sell": "قم بتعطيل إجراء البيع",
   "disableBatteryOptimization": "تعطيل تحسين البطارية",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "يرجى التأكد",
   "ledger_please_enable_bluetooth": "يرجى تمكين البلوتوث للكشف عن دفتر الأستاذ الخاص بك",
   "light_theme": "فاتح",
+  "live_fee_rates": "أسعار الرسوم المباشرة عبر API",
   "load_more": "تحميل المزيد",
   "loading_your_wallet": "يتم تحميل محفظتك",
   "login": "تسجيل الدخول",
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index 1ff8fdf85..c13d6d7d6 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Деактивирайте действието за покупка",
   "disable_cake_2fa": "Деактивирайте Cake 2FA",
   "disable_exchange": "Деактивиране на борса",
+  "disable_fee_api_warning": "Като изключите това, таксите могат да бъдат неточни в някои случаи, така че може да се препланите или да не плащате таксите за вашите транзакции",
   "disable_fiat": "Деактивиране на fiat",
   "disable_sell": "Деактивирайте действието за продажба",
   "disableBatteryOptimization": "Деактивирайте оптимизацията на батерията",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Моля, уверете се, че сте отворили правилното приложение на вашата книга",
   "ledger_please_enable_bluetooth": "Моля, активирайте Bluetooth да открие вашата книга",
   "light_theme": "Светло",
+  "live_fee_rates": "Цени на таксите на живо чрез API",
   "load_more": "Зареди още",
   "loading_your_wallet": "Зареждане на портфейл",
   "login": "Влизане",
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index 904c6d8e4..49bc856fd 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Zakázat akci nákupu",
   "disable_cake_2fa": "Zakázat Cake 2FA",
   "disable_exchange": "Zakázat směnárny",
+  "disable_fee_api_warning": "Tímto vypnutím by sazby poplatků mohly být v některých případech nepřesné, takže byste mohli skončit přepláváním nebo nedoplatkem poplatků za vaše transakce",
   "disable_fiat": "Zakázat fiat",
   "disable_sell": "Zakázat akci prodeje",
   "disableBatteryOptimization": "Zakázat optimalizaci baterie",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Ujistěte se, že se na své knize otevřete správnou aplikaci",
   "ledger_please_enable_bluetooth": "Umožněte prosím Bluetooth detekovat vaši knihu",
   "light_theme": "Světlý",
+  "live_fee_rates": "Živé sazby poplatků prostřednictvím API",
   "load_more": "Načíst další",
   "loading_your_wallet": "Načítám peněženku",
   "login": "Login",
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 860d4114d..19b7fbc90 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Kaufaktion deaktivieren",
   "disable_cake_2fa": "Cake 2FA deaktivieren",
   "disable_exchange": "Exchange deaktivieren",
+  "disable_fee_api_warning": "Wenn dies ausgeschaltet wird, sind die Gebührenquoten in einigen Fällen möglicherweise ungenau, sodass Sie die Gebühren für Ihre Transaktionen möglicherweise überbezahlt oder unterzahlt",
   "disable_fiat": "Fiat deaktivieren",
   "disable_sell": "Verkaufsaktion deaktivieren",
   "disableBatteryOptimization": "Batterieoptimierung deaktivieren",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Bitte stellen Sie sicher, dass Sie die richtige App auf Ihrem Ledger geöffnet haben",
   "ledger_please_enable_bluetooth": "Bitte aktivieren Sie Bluetooth um sich mit Ihren Ledger zu verbinden.",
   "light_theme": "Hell",
+  "live_fee_rates": "Live -Gebührenpreise über API",
   "load_more": "Mehr laden",
   "loading_your_wallet": "Wallet wird geladen",
   "login": "Einloggen",
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 9f89eb6ab..75c0fc9c0 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Disable buy action",
   "disable_cake_2fa": "Disable Cake 2FA",
   "disable_exchange": "Disable exchange",
+  "disable_fee_api_warning": "By turning this off, the fee rates might be inaccurate in some cases, so you might end up overpaying or underpaying the fees for your transactions",
   "disable_fiat": "Disable fiat",
   "disable_sell": "Disable sell action",
   "disableBatteryOptimization": "Disable Battery Optimization",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Please make sure you opend the right app on your ledger",
   "ledger_please_enable_bluetooth": "Please enable Bluetooth to detect your Ledger",
   "light_theme": "Light",
+  "live_fee_rates": "Live fee rates via API",
   "load_more": "Load more",
   "loading_your_wallet": "Loading your wallet",
   "login": "Login",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 250decfc4..73a2e77b9 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Desactivar acción de compra",
   "disable_cake_2fa": "Desactivar pastel 2FA",
   "disable_exchange": "Deshabilitar intercambio",
+  "disable_fee_api_warning": "Al apagar esto, las tasas de tarifas pueden ser inexactas en algunos casos, por lo que puede terminar pagando en exceso o pagando menos las tarifas por sus transacciones",
   "disable_fiat": "Deshabilitar fiat",
   "disable_sell": "Desactivar acción de venta",
   "disableBatteryOptimization": "Deshabilitar la optimización de la batería",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Por favor, asegúrese de abrir la aplicación correcta en su libro mayor.",
   "ledger_please_enable_bluetooth": "Habilite Bluetooth para detectar su libro mayor",
   "light_theme": "Ligera",
+  "live_fee_rates": "Tasas de tarifas en vivo a través de API",
   "load_more": "Carga más",
   "loading_your_wallet": "Cargando tu billetera",
   "login": "Iniciar sesión",
@@ -895,4 +897,4 @@
   "you_will_get": "Convertir a",
   "you_will_send": "Convertir de",
   "yy": "YY"
-}
+}
\ No newline at end of file
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index 297019aa0..e1f557060 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Désactiver l'action d'achat",
   "disable_cake_2fa": "Désactiver Cake 2FA",
   "disable_exchange": "Désactiver l'échange",
+  "disable_fee_api_warning": "En désactivant cela, les taux de frais peuvent être inexacts dans certains cas, vous pourriez donc finir par payer trop ou sous-paiement les frais pour vos transactions",
   "disable_fiat": "Désactiver les montants en fiat",
   "disable_sell": "Désactiver l'action de vente",
   "disableBatteryOptimization": "Désactiver l'optimisation de la batterie",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Veuillez vous assurer d'ouvrir la bonne application sur votre grand livre",
   "ledger_please_enable_bluetooth": "Veuillez activer Bluetooth pour détecter votre grand livre",
   "light_theme": "Clair",
+  "live_fee_rates": "Taux de frais en direct via l'API",
   "load_more": "Charger plus",
   "loading_your_wallet": "Chargement de votre portefeuille (wallet)",
   "login": "Utilisateur",
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index 05cdf27d4..4e0eb83f9 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Kashe alama",
   "disable_cake_2fa": "Musaki Cake 2FA",
   "disable_exchange": "Kashe musanya",
+  "disable_fee_api_warning": "Ta hanyar juya wannan kashe, kudaden da zai iya zama ba daidai ba a wasu halaye, saboda haka zaku iya ƙare da overpaying ko a ƙarƙashin kudaden don ma'amaloli",
   "disable_fiat": "Dakatar da fiat",
   "disable_sell": "Kashe karbuwa",
   "disableBatteryOptimization": "Kashe ingantawa baturi",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Da fatan za a tabbata kun yi amfani da app ɗin dama akan dillalarku",
   "ledger_please_enable_bluetooth": "Da fatan za a kunna Bluetooth don gano Ledger ɗinku",
   "light_theme": "Haske",
+  "live_fee_rates": "Kudin Kiɗa ta API",
   "load_more": "Like more",
   "loading_your_wallet": "Ana loda walat ɗin ku",
   "login": "Shiga",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index 30f86d9ae..f77547992 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -208,6 +208,7 @@
   "disable_buy": "खरीद कार्रवाई अक्षम करें",
   "disable_cake_2fa": "केक 2FA अक्षम करें",
   "disable_exchange": "एक्सचेंज अक्षम करें",
+  "disable_fee_api_warning": "इसे बंद करने से, कुछ मामलों में शुल्क दरें गलत हो सकती हैं, इसलिए आप अपने लेनदेन के लिए फीस को कम कर सकते हैं या कम कर सकते हैं",
   "disable_fiat": "िएट को अक्षम करें",
   "disable_sell": "बेचने की कार्रवाई अक्षम करें",
   "disableBatteryOptimization": "बैटरी अनुकूलन अक्षम करें",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "कृपया सुनिश्चित करें कि आप अपने लेजर पर सही ऐप को खोलते हैं",
   "ledger_please_enable_bluetooth": "कृपया अपने बहीखाने का पता लगाने के लिए ब्लूटूथ को सक्षम करें",
   "light_theme": "रोशनी",
+  "live_fee_rates": "एपीआई के माध्यम से लाइव शुल्क दरें",
   "load_more": "और लोड करें",
   "loading_your_wallet": "अपना बटुआ लोड कर रहा है",
   "login": "लॉग इन करें",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 0d6e9a0d8..db02c5552 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Onemogući kupnju",
   "disable_cake_2fa": "Onemogući Cake 2FA",
   "disable_exchange": "Onemogući exchange",
+  "disable_fee_api_warning": "Isključivanjem ovoga, stope naknade u nekim bi slučajevima mogle biti netočne, tako da biste mogli preplatiti ili predati naknadu za vaše transakcije",
   "disable_fiat": "Isključi, fiat",
   "disable_sell": "Onemogući akciju prodaje",
   "disableBatteryOptimization": "Onemogući optimizaciju baterije",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Obavezno obavezno otvorite pravu aplikaciju na knjizi",
   "ledger_please_enable_bluetooth": "Omogućite Bluetooth da otkrije svoju knjigu",
   "light_theme": "Svijetla",
+  "live_fee_rates": "Stope naknada uživo putem API -ja",
   "load_more": "Učitaj više",
   "loading_your_wallet": "Novčanik se učitava",
   "login": "Prijava",
diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb
index 826bfa99a..178254bba 100644
--- a/res/values/strings_hy.arb
+++ b/res/values/strings_hy.arb
@@ -207,6 +207,7 @@
   "disable_buy": "Անջատել գնում գործողությունը",
   "disable_cake_2fa": "Անջատել Cake 2FA",
   "disable_exchange": "Անջատել փոխանակումը",
+  "disable_fee_api_warning": "Դրանից անջատելով, վճարների տեմպերը որոշ դեպքերում կարող են անճիշտ լինել, այնպես որ դուք կարող եք վերջ տալ ձեր գործարքների համար վճարների գերավճարների կամ գերավճարների վրա",
   "disable_fiat": "Անջատել ֆիատ",
   "disable_sell": "Անջատել վաճառք գործողությունը",
   "disableBatteryOptimization": "Անջատել մարտկոցի օպտիմիզացիան",
@@ -354,6 +355,7 @@
   "ledger_error_wrong_app": "Խնդրում ենք համոզվել, որ դուք բացել եք ճիշտ ծրագիրը ձեր Ledger-ում",
   "ledger_please_enable_bluetooth": "Խնդրում ենք միացնել Bluetooth-ը ձեր Ledger-ը հայտնաբերելու համար",
   "light_theme": "Լուսավոր",
+  "live_fee_rates": "Ապակի վարձավճարներ API- ի միջոցով",
   "load_more": "Բեռնել ավելին",
   "loading_your_wallet": "Ձեր հաշվեհամարը բեռնում է",
   "login": "Մուտք",
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index 65703e0bc..e67402de2 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Nonaktifkan tindakan beli",
   "disable_cake_2fa": "Nonaktifkan Kue 2FA",
   "disable_exchange": "Nonaktifkan pertukaran",
+  "disable_fee_api_warning": "Dengan mematikan ini, tarif biaya mungkin tidak akurat dalam beberapa kasus, jadi Anda mungkin akan membayar lebih atau membayar biaya untuk transaksi Anda",
   "disable_fiat": "Nonaktifkan fiat",
   "disable_sell": "Nonaktifkan aksi jual",
   "disableBatteryOptimization": "Nonaktifkan optimasi baterai",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Pastikan Anda membuka aplikasi yang tepat di buku besar Anda",
   "ledger_please_enable_bluetooth": "Harap aktifkan Bluetooth untuk mendeteksi buku besar Anda",
   "light_theme": "Terang",
+  "live_fee_rates": "Tarif biaya langsung melalui API",
   "load_more": "Muat lebih banyak",
   "loading_your_wallet": "Memuat dompet Anda",
   "login": "Masuk",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index c2ba20ce0..a764520d8 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -209,6 +209,7 @@
   "disable_buy": "Disabilita l'azione di acquisto",
   "disable_cake_2fa": "Disabilita Cake 2FA",
   "disable_exchange": "Disabilita scambio",
+  "disable_fee_api_warning": "Disattivando questo, i tassi delle commissioni potrebbero essere inaccurati in alcuni casi, quindi potresti finire in eccesso o sostenere le commissioni per le transazioni",
   "disable_fiat": "Disabilita fiat",
   "disable_sell": "Disabilita l'azione di vendita",
   "disableBatteryOptimization": "Disabilita l'ottimizzazione della batteria",
@@ -356,6 +357,7 @@
   "ledger_error_wrong_app": "Assicurati di aprire l'app giusta sul libro mastro",
   "ledger_please_enable_bluetooth": "Si prega di consentire al Bluetooth di rilevare il libro mastro",
   "light_theme": "Bianco",
+  "live_fee_rates": "Tariffe delle commissioni dal vivo tramite API",
   "load_more": "Carica di più",
   "loading_your_wallet": "Caricamento portafoglio",
   "login": "Accedi",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index ab6605257..bda62536e 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -208,6 +208,7 @@
   "disable_buy": "購入アクションを無効にする",
   "disable_cake_2fa": "Cake 2FA を無効にする",
   "disable_exchange": "交換を無効にする",
+  "disable_fee_api_warning": "これをオフにすることで、料金金利は場合によっては不正確になる可能性があるため、取引の費用が過払いまたは不足している可能性があります",
   "disable_fiat": "フィアットを無効にする",
   "disable_sell": "販売アクションを無効にする",
   "disableBatteryOptimization": "バッテリーの最適化を無効にします",
@@ -356,6 +357,7 @@
   "ledger_error_wrong_app": "元帳に適切なアプリを開始するようにしてください",
   "ledger_please_enable_bluetooth": "Bluetoothが元帳を検出できるようにしてください",
   "light_theme": "光",
+  "live_fee_rates": "API経由のライブ料金",
   "load_more": "もっと読み込む",
   "loading_your_wallet": "ウォレットをロードしています",
   "login": "ログイン",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index da10162ad..df339df55 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -208,6 +208,7 @@
   "disable_buy": "구매 행동 비활성화",
   "disable_cake_2fa": "케이크 2FA 비활성화",
   "disable_exchange": "교환 비활성화",
+  "disable_fee_api_warning": "이것을 끄면 경우에 따라 수수료가 부정확 할 수 있으므로 거래 수수료를 초과 지불하거나 지불 할 수 있습니다.",
   "disable_fiat": "법정화폐 비활성화",
   "disable_sell": "판매 조치 비활성화",
   "disableBatteryOptimization": "배터리 최적화를 비활성화합니다",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "원장에서 올바른 앱을 반대하는지 확인하십시오.",
   "ledger_please_enable_bluetooth": "Bluetooth가 원장을 감지 할 수 있도록하십시오",
   "light_theme": "빛",
+  "live_fee_rates": "API를 통한 라이브 요금 요금",
   "load_more": "더로드하십시오",
   "loading_your_wallet": "지갑 넣기",
   "login": "로그인",
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index e04c75d62..e988c6c8d 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -208,6 +208,7 @@
   "disable_buy": "ဝယ်ယူမှု လုပ်ဆောင်ချက်ကို ပိတ်ပါ။",
   "disable_cake_2fa": "ကိတ်မုန့် 2FA ကို ပိတ်ပါ။",
   "disable_exchange": "လဲလှယ်မှုကို ပိတ်ပါ။",
+  "disable_fee_api_warning": "ဤအရာကိုဖွင့်ခြင်းအားဖြင့်အချို့သောကိစ္စရပ်များတွင်အခကြေးငွေနှုန်းထားများသည်တိကျမှုရှိနိုင်သည်,",
   "disable_fiat": "Fiat ကိုပိတ်ပါ။",
   "disable_sell": "ရောင်းချခြင်းလုပ်ဆောင်ချက်ကို ပိတ်ပါ။",
   "disableBatteryOptimization": "ဘက်ထရီ optimization ကိုပိတ်ပါ",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "ကျေးဇူးပြု. သင့်လက်ျာအက်ပ်ကိုသင်၏ Ledger တွင်ဖွင့်ရန်သေချာစေပါ",
   "ledger_please_enable_bluetooth": "သင်၏ Ledger ကိုရှာဖွေရန် Bluetooth ကိုဖွင့်ပါ",
   "light_theme": "အလင်း",
+  "live_fee_rates": "API မှတစ်ဆင့် Live အခကြေးငွေနှုန်းထားများ",
   "load_more": "ပိုပြီး load",
   "loading_your_wallet": "သင့်ပိုက်ဆံအိတ်ကို ဖွင့်နေသည်။",
   "login": "လော့ဂ်အင်",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index dfa7c2d8f..d1f6032e5 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Koopactie uitschakelen",
   "disable_cake_2fa": "Taart 2FA uitschakelen",
   "disable_exchange": "Uitwisseling uitschakelen",
+  "disable_fee_api_warning": "Door dit uit te schakelen, kunnen de tarieven in sommige gevallen onnauwkeurig zijn, dus u kunt de vergoedingen voor uw transacties te veel betalen of te weinig betalen",
   "disable_fiat": "Schakel Fiat uit",
   "disable_sell": "Verkoopactie uitschakelen",
   "disableBatteryOptimization": "Schakel de batterijoptimalisatie uit",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Zorg ervoor dat u de juiste app op uw grootboek opent",
   "ledger_please_enable_bluetooth": "Schakel Bluetooth in staat om uw grootboek te detecteren",
   "light_theme": "Licht",
+  "live_fee_rates": "Live -tarieven via API",
   "load_more": "Meer laden",
   "loading_your_wallet": "Uw portemonnee laden",
   "login": "Log in",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 397ea2bcb..3b4e0f81f 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Wyłącz akcję kupna",
   "disable_cake_2fa": "Wyłącz Cake 2FA",
   "disable_exchange": "Wyłącz wymianę",
+  "disable_fee_api_warning": "Wyłączając to, stawki opłaty mogą być w niektórych przypadkach niedokładne, więc możesz skończyć się przepłaceniem lub wynagrodzeniem opłat za transakcje",
   "disable_fiat": "Wyłącz waluty FIAT",
   "disable_sell": "Wyłącz akcję sprzedaży",
   "disableBatteryOptimization": "Wyłącz optymalizację baterii",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Upewnij się, że opisz odpowiednią aplikację na swojej księdze",
   "ledger_please_enable_bluetooth": "Włącz Bluetooth wykrywanie księgi",
   "light_theme": "Jasny",
+  "live_fee_rates": "Stawki opłaty na żywo za pośrednictwem API",
   "load_more": "Załaduj więcej",
   "loading_your_wallet": "Ładowanie portfela",
   "login": "Login",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index cbe66715a..6b9e4bf77 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Desativar ação de compra",
   "disable_cake_2fa": "Desabilitar o Cake 2FA",
   "disable_exchange": "Desativar troca",
+  "disable_fee_api_warning": "Ao desativar isso, as taxas de taxas podem ser imprecisas em alguns casos, para que você possa acabar pagando demais ou pagando as taxas por suas transações",
   "disable_fiat": "Desativar fiat",
   "disable_sell": "Desativar ação de venda",
   "disableBatteryOptimization": "Desative a otimização da bateria",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Por favor, certifique -se de optar pelo aplicativo certo no seu livro",
   "ledger_please_enable_bluetooth": "Ative o Bluetooth para detectar seu livro",
   "light_theme": "Luz",
+  "live_fee_rates": "Taxas de taxas ao vivo via API",
   "load_more": "Carregue mais",
   "loading_your_wallet": "Abrindo sua carteira",
   "login": "Login",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index 9976de9f8..a8def9179 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Отключить действие покупки",
   "disable_cake_2fa": "Отключить торт 2FA",
   "disable_exchange": "Отключить обмен",
+  "disable_fee_api_warning": "Выключив это, в некоторых случаях ставки платы могут быть неточными, так что вы можете в конечном итоге переплачивать или недоплачивать сборы за ваши транзакции",
   "disable_fiat": "Отключить фиат",
   "disable_sell": "Отключить действие продажи",
   "disableBatteryOptimization": "Отключить оптимизацию батареи",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Пожалуйста, убедитесь, что вы предлагаете правильное приложение в своей бухгалтерской книге",
   "ledger_please_enable_bluetooth": "Пожалуйста, включите Bluetooth обнаружить вашу бухгалтерскую книгу",
   "light_theme": "Светлая",
+  "live_fee_rates": "Ставки по сбору вживую через API",
   "load_more": "Загрузи больше",
   "loading_your_wallet": "Загрузка кошелька",
   "login": "Логин",
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index e873fe5eb..02480d6fd 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -208,6 +208,7 @@
   "disable_buy": "ปิดการใช้งานการซื้อ",
   "disable_cake_2fa": "ปิดการใช้งานเค้ก 2FA",
   "disable_exchange": "ปิดใช้งานการแลกเปลี่ยน",
+  "disable_fee_api_warning": "โดยการปิดสิ่งนี้อัตราค่าธรรมเนียมอาจไม่ถูกต้องในบางกรณีดังนั้นคุณอาจจบลงด้วยการจ่ายเงินมากเกินไปหรือจ่ายค่าธรรมเนียมสำหรับการทำธุรกรรมของคุณมากเกินไป",
   "disable_fiat": "ปิดใช้งานสกุลเงินตรา",
   "disable_sell": "ปิดการใช้งานการขาย",
   "disableBatteryOptimization": "ปิดใช้งานการเพิ่มประสิทธิภาพแบตเตอรี่",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "โปรดตรวจสอบให้แน่ใจว่าคุณเปิดแอพที่เหมาะสมในบัญชีแยกประเภทของคุณ",
   "ledger_please_enable_bluetooth": "โปรดเปิดใช้งานบลูทู ธ ในการตรวจจับบัญชีแยกประเภทของคุณ",
   "light_theme": "สว่าง",
+  "live_fee_rates": "อัตราค่าธรรมเนียมสดผ่าน API",
   "load_more": "โหลดมากขึ้น",
   "loading_your_wallet": "กำลังโหลดกระเป๋าของคุณ",
   "login": "เข้าสู่ระบบ",
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index c1bd2bae7..2307cc62b 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Huwag paganahin ang pagkilos ng pagbili",
   "disable_cake_2fa": "Huwag paganahin ang Cake 2FA",
   "disable_exchange": "Huwag paganahin ang palitan",
+  "disable_fee_api_warning": "Sa pamamagitan ng pag -off nito, ang mga rate ng bayad ay maaaring hindi tumpak sa ilang mga kaso, kaya maaari mong tapusin ang labis na bayad o pagsuporta sa mga bayarin para sa iyong mga transaksyon",
   "disable_fiat": "Huwag paganahin ang fiat",
   "disable_sell": "Huwag paganahin ang pagkilos ng pagbebenta",
   "disableBatteryOptimization": "Huwag Paganahin ang Pag-optimize ng Baterya",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Mangyaring tiyaking pinipili mo ang tamang app sa iyong Ledger",
   "ledger_please_enable_bluetooth": "Mangyaring paganahin ang Bluetooth upang makita ang iyong Ledger",
   "light_theme": "Light",
+  "live_fee_rates": "Mga rate ng live na bayad sa pamamagitan ng API",
   "load_more": "Mag-load pa",
   "loading_your_wallet": "Naglo-load ng iyong wallet",
   "login": "Mag-login",
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index ff7d9a120..8346703bc 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Satın alma işlemini devre dışı bırak",
   "disable_cake_2fa": "Cake 2FA'yı Devre Dışı Bırak",
   "disable_exchange": "Borsayı devre dışı bırak",
+  "disable_fee_api_warning": "Bunu kapatarak, ücret oranları bazı durumlarda yanlış olabilir, bu nedenle işlemleriniz için ücretleri fazla ödeyebilir veya az ödeyebilirsiniz.",
   "disable_fiat": "İtibari paraları devre dışı bırak",
   "disable_sell": "Satış işlemini devre dışı bırak",
   "disableBatteryOptimization": "Pil optimizasyonunu devre dışı bırakın",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Lütfen defterinizde doğru uygulamayı açtığınızdan emin olun",
   "ledger_please_enable_bluetooth": "Defterinizi algılamak için lütfen Bluetooth'u etkinleştirin",
   "light_theme": "Aydınlık",
+  "live_fee_rates": "API üzerinden canlı ücret oranları",
   "load_more": "Daha fazla yükle",
   "loading_your_wallet": "Cüzdanın yükleniyor",
   "login": "Login",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 95a3a38d8..ec2324544 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Вимкнути дію покупки",
   "disable_cake_2fa": "Вимкнути Cake 2FA",
   "disable_exchange": "Вимкнути exchange",
+  "disable_fee_api_warning": "Вимкнувши це, ставки плати в деяких випадках можуть бути неточними, тому ви можете переплатити або недооплатити плату за свої транзакції",
   "disable_fiat": "Вимкнути фиат",
   "disable_sell": "Вимкнути дію продажу",
   "disableBatteryOptimization": "Вимкнути оптимізацію акумулятора",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "Будь ласка, переконайтеся, що ви відкриваєте потрібну програму на своїй книзі",
   "ledger_please_enable_bluetooth": "Будь ласка, ввімкніть Bluetooth виявити свою книгу",
   "light_theme": "Світла",
+  "live_fee_rates": "Ставки плати за живий через API",
   "load_more": "Завантажити ще",
   "loading_your_wallet": "Завантаження гаманця",
   "login": "Логін",
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index 5be1cb7a0..bc5fc332c 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -208,6 +208,7 @@
   "disable_buy": "خرید ایکشن کو غیر فعال کریں۔",
   "disable_cake_2fa": "کیک 2FA کو غیر فعال کریں۔",
   "disable_exchange": "تبادلے کو غیر فعال کریں۔",
+  "disable_fee_api_warning": "اس کو بند کرنے سے ، کچھ معاملات میں فیس کی شرح غلط ہوسکتی ہے ، لہذا آپ اپنے لین دین کے لئے فیسوں کو زیادہ ادائیگی یا ادائیگی ختم کرسکتے ہیں۔",
   "disable_fiat": "فیاٹ کو غیر فعال کریں۔",
   "disable_sell": "فروخت کی کارروائی کو غیر فعال کریں۔",
   "disableBatteryOptimization": "بیٹری کی اصلاح کو غیر فعال کریں",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "براہ کرم یقینی بنائیں کہ آپ اپنے لیجر پر صحیح ایپ کو کھولتے ہیں",
   "ledger_please_enable_bluetooth": "براہ کرم بلوٹوتھ کو اپنے لیجر کا پتہ لگانے کے لئے اہل بنائیں",
   "light_theme": "روشنی",
+  "live_fee_rates": "API کے ذریعے براہ راست فیس کی شرح",
   "load_more": "مزید لوڈ کریں",
   "loading_your_wallet": "آپ کا بٹوہ لوڈ ہو رہا ہے۔",
   "login": "لاگ ان کریں",
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index 81d784d7f..e13d79b6b 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -208,6 +208,7 @@
   "disable_buy": "Ko iṣọrọ ọja",
   "disable_cake_2fa": "Ko 2FA Cake sii",
   "disable_exchange": "Pa ilé pàṣípààrọ̀",
+  "disable_fee_api_warning": "Nipa yiyi eyi kuro, awọn oṣuwọn owo naa le jẹ aiṣe deede ni awọn ọrọ kan, nitorinaa o le pari apọju tabi awọn idiyele ti o ni agbara fun awọn iṣowo rẹ",
   "disable_fiat": "Pa owó tí ìjọba pàṣẹ wa lò",
   "disable_sell": "Ko iṣọrọ iṣọrọ",
   "disableBatteryOptimization": "Mu Ifasi batiri",
@@ -356,6 +357,7 @@
   "ledger_error_wrong_app": "Jọwọ rii daju pe iwọ yoo sọ app ti o tọ loju omi rẹ",
   "ledger_please_enable_bluetooth": "Jọwọ jẹ ki Bluetooth lati rii iṣupọ rẹ",
   "light_theme": "Funfun bí eérú",
+  "live_fee_rates": "Awọn oṣuwọn Owo laaye laaye nipasẹ API",
   "load_more": "Ẹru diẹ sii",
   "loading_your_wallet": "A ń ṣí àpamọ́wọ́ yín",
   "login": "Orúkọ",
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index 876c3bbfb..a26edec4e 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -208,6 +208,7 @@
   "disable_buy": "禁用购买操作",
   "disable_cake_2fa": "禁用蛋糕 2FA",
   "disable_exchange": "禁用交换",
+  "disable_fee_api_warning": "通过将其关闭,在某些情况下,收费率可能不准确,因此您最终可能会超额付款或支付交易费用",
   "disable_fiat": "禁用法令",
   "disable_sell": "禁用卖出操作",
   "disableBatteryOptimization": "禁用电池优化",
@@ -355,6 +356,7 @@
   "ledger_error_wrong_app": "请确保您在分类帐中操作正确的应用程序",
   "ledger_please_enable_bluetooth": "请启用蓝牙来检测您的分类帐",
   "light_theme": "艳丽",
+  "live_fee_rates": "通过API的实时费率",
   "load_more": "装载更多",
   "loading_your_wallet": "加载您的钱包",
   "login": "登录",

From 4c795ea5c26f2b5ba88317cf6d02fd284bc420fb Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Tue, 27 Aug 2024 01:40:20 +0200
Subject: [PATCH 80/81] subaddress fix (#1620)

* subaddress fix

* fix subaddress generation

* rewrite usedAddresses for xmr and wow

* [skip ci] remove print statements
---
 cw_monero/lib/api/transaction_history.dart   | 27 ++++++++++++++++----
 cw_monero/lib/monero_subaddress_list.dart    |  9 ++++---
 cw_monero/lib/monero_wallet.dart             |  5 ++++
 cw_monero/lib/monero_wallet_addresses.dart   | 20 +++++++++++++++
 cw_wownero/lib/api/transaction_history.dart  | 23 +++++++++++++----
 cw_wownero/lib/wownero_subaddress_list.dart  |  4 +++
 cw_wownero/lib/wownero_wallet.dart           |  6 +++++
 cw_wownero/lib/wownero_wallet_addresses.dart | 18 +++++++++++++
 8 files changed, 99 insertions(+), 13 deletions(-)

diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart
index b416e1b4e..1f00b082f 100644
--- a/cw_monero/lib/api/transaction_history.dart
+++ b/cw_monero/lib/api/transaction_history.dart
@@ -45,6 +45,8 @@ List<Transaction> getAllTransactions() {
             confirmations: 0,
             blockheight: 0,
             accountIndex: i,
+            addressIndex: 0,
+            addressIndexList: [0],
             paymentId: "",
             amount: fullBalance - availBalance,
             isSpend: false,
@@ -245,19 +247,30 @@ Future<PendingTransactionDescription> createTransactionMultDest(
 
 class Transaction {
   final String displayLabel;
-  String subaddressLabel = monero.Wallet_getSubaddressLabel(wptr!, accountIndex: 0, addressIndex: 0);
-  late final String address = monero.Wallet_address(
+  String get subaddressLabel => monero.Wallet_getSubaddressLabel(
     wptr!,
-    accountIndex: 0,
-    addressIndex: 0,
+    accountIndex: accountIndex,
+    addressIndex: addressIndex,
   );
+  String get address => monero.Wallet_address(
+    wptr!,
+    accountIndex: accountIndex,
+    addressIndex: addressIndex,
+  );
+  List<String> get addressList => List.generate(addressIndexList.length, (index) =>
+    monero.Wallet_address(
+      wptr!,
+      accountIndex: accountIndex,
+      addressIndex: addressIndexList[index],
+    ));
   final String description;
   final int fee;
   final int confirmations;
   late final bool isPending = confirmations < 10;
   final int blockheight;
-  final int addressIndex = 0;
+  final int addressIndex;
   final int accountIndex;
+  final List<int> addressIndexList;
   final String paymentId;
   final int amount;
   final bool isSpend;
@@ -303,6 +316,8 @@ class Transaction {
         amount = monero.TransactionInfo_amount(txInfo),
         paymentId = monero.TransactionInfo_paymentId(txInfo),
         accountIndex = monero.TransactionInfo_subaddrAccount(txInfo),
+        addressIndex = int.tryParse(monero.TransactionInfo_subaddrIndex(txInfo).split(", ")[0]) ?? 0,
+        addressIndexList = monero.TransactionInfo_subaddrIndex(txInfo).split(", ").map((e) => int.tryParse(e) ?? 0).toList(),
         blockheight = monero.TransactionInfo_blockHeight(txInfo),
         confirmations = monero.TransactionInfo_confirmations(txInfo),
         fee = monero.TransactionInfo_fee(txInfo),
@@ -316,6 +331,8 @@ class Transaction {
     required this.confirmations,
     required this.blockheight,
     required this.accountIndex,
+    required this.addressIndexList,
+    required this.addressIndex,
     required this.paymentId,
     required this.amount,
     required this.isSpend,
diff --git a/cw_monero/lib/monero_subaddress_list.dart b/cw_monero/lib/monero_subaddress_list.dart
index c35afb282..fe85bef3b 100644
--- a/cw_monero/lib/monero_subaddress_list.dart
+++ b/cw_monero/lib/monero_subaddress_list.dart
@@ -1,6 +1,7 @@
 import 'package:cw_core/subaddress.dart';
 import 'package:cw_monero/api/coins_info.dart';
 import 'package:cw_monero/api/subaddress_list.dart' as subaddress_list;
+import 'package:cw_monero/api/wallet.dart';
 import 'package:flutter/services.dart';
 import 'package:mobx/mobx.dart';
 
@@ -103,6 +104,9 @@ abstract class MoneroSubaddressListBase with Store {
     required List<String> usedAddresses,
   }) async {
     _usedAddresses.addAll(usedAddresses);
+    final _all = _usedAddresses.toSet().toList();
+    _usedAddresses.clear();
+    _usedAddresses.addAll(_all);
     if (_isUpdating) {
       return;
     }
@@ -124,7 +128,7 @@ abstract class MoneroSubaddressListBase with Store {
   Future<List<Subaddress>> _getAllUnusedAddresses(
       {required int accountIndex, required String label}) async {
     final allAddresses = subaddress_list.getAllSubaddresses();
-    if (allAddresses.isEmpty || _usedAddresses.contains(allAddresses.last)) {
+    if (allAddresses.isEmpty || _usedAddresses.contains(allAddresses.first.address)) {
       final isAddressUnused = await _newSubaddress(accountIndex: accountIndex, label: label);
       if (!isAddressUnused) {
         return await _getAllUnusedAddresses(accountIndex: accountIndex, label: label);
@@ -143,8 +147,7 @@ abstract class MoneroSubaddressListBase with Store {
                     label.toLowerCase() == 'Primary account'.toLowerCase()
                 ? 'Primary address'
                 : label);
-      })
-        .toList();
+      }).toList().reversed.toList();
   }
 
   Future<bool> _newSubaddress({required int accountIndex, required String label}) async {
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index f5fa0ec7e..483ee8868 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -88,6 +88,9 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
     reaction((_) => isEnabledAutoGenerateSubaddress, (bool enabled) {
       _updateSubAddress(enabled, account: walletAddresses.account);
     });
+    reaction((_) => transactionHistory, (__) {
+      _updateSubAddress(isEnabledAutoGenerateSubaddress, account: walletAddresses.account);
+    });
   }
 
   static const int _autoSaveInterval = 30;
@@ -130,6 +133,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
 
   monero_wallet.SyncListener? _listener;
   ReactionDisposer? _onAccountChangeReaction;
+  ReactionDisposer? _onTxHistoryChangeReaction;
   bool _isTransactionUpdating;
   bool _hasSyncAfterStartup;
   Timer? _autoSaveTimer;
@@ -169,6 +173,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
   void close() async {
     _listener?.stop();
     _onAccountChangeReaction?.reaction.dispose();
+    _onTxHistoryChangeReaction?.reaction.dispose();
     _autoSaveTimer?.cancel();
   }
 
diff --git a/cw_monero/lib/monero_wallet_addresses.dart b/cw_monero/lib/monero_wallet_addresses.dart
index d4f22e46f..41e22aef2 100644
--- a/cw_monero/lib/monero_wallet_addresses.dart
+++ b/cw_monero/lib/monero_wallet_addresses.dart
@@ -3,6 +3,7 @@ import 'package:cw_core/address_info.dart';
 import 'package:cw_core/subaddress.dart';
 import 'package:cw_core/wallet_addresses.dart';
 import 'package:cw_core/wallet_info.dart';
+import 'package:cw_monero/api/transaction_history.dart';
 import 'package:cw_monero/api/wallet.dart';
 import 'package:cw_monero/monero_account_list.dart';
 import 'package:cw_monero/monero_subaddress_list.dart';
@@ -37,6 +38,25 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
 
   MoneroAccountList accountList;
 
+  @override
+  Set<String> get usedAddresses {
+    final txs = getAllTransactions();
+    final adds = _originalUsedAddresses.toList();
+    for (var i = 0; i < txs.length; i++) {
+      for (var j = 0; j < txs[i].addressList.length; j++) {
+        adds.add(txs[i].addressList[j]);
+      }
+    }
+    return adds.toSet();
+  }
+
+  Set<String> _originalUsedAddresses = Set();
+
+  @override
+  set usedAddresses(Set<String> _usedAddresses) {
+    _originalUsedAddresses = _usedAddresses;
+  }
+
   @override
   Future<void> init() async {
     accountList.update();
diff --git a/cw_wownero/lib/api/transaction_history.dart b/cw_wownero/lib/api/transaction_history.dart
index a1e1e3c9b..020c47df6 100644
--- a/cw_wownero/lib/api/transaction_history.dart
+++ b/cw_wownero/lib/api/transaction_history.dart
@@ -45,6 +45,8 @@ List<Transaction> getAllTransactions() {
             confirmations: 0,
             blockheight: 0,
             accountIndex: i,
+            addressIndex: 0,
+            addressIndexList: [0],
             paymentId: "",
             amount: fullBalance - availBalance,
             isSpend: false,
@@ -243,19 +245,26 @@ Future<PendingTransactionDescription> createTransactionMultDest(
 
 class Transaction {
   final String displayLabel;
-  String subaddressLabel = wownero.Wallet_getSubaddressLabel(wptr!, accountIndex: 0, addressIndex: 0);
-  late final String address = wownero.Wallet_address(
+  String get subaddressLabel => wownero.Wallet_getSubaddressLabel(wptr!, accountIndex: 0, addressIndex: 0);
+  String get address => wownero.Wallet_address(
     wptr!,
-    accountIndex: 0,
-    addressIndex: 0,
+    accountIndex: accountIndex,
+    addressIndex: addressIndex,
   );
+  List<String> get addressList => List.generate(addressIndexList.length, (index) =>
+    wownero.Wallet_address(
+      wptr!,
+      accountIndex: accountIndex,
+      addressIndex: addressIndexList[index],
+    ));
   final String description;
   final int fee;
   final int confirmations;
   late final bool isPending = confirmations < 3;
   final int blockheight;
-  final int addressIndex = 0;
+  final int addressIndex;
   final int accountIndex;
+  final List<int> addressIndexList;
   final String paymentId;
   final int amount;
   final bool isSpend;
@@ -301,6 +310,8 @@ class Transaction {
         amount = wownero.TransactionInfo_amount(txInfo),
         paymentId = wownero.TransactionInfo_paymentId(txInfo),
         accountIndex = wownero.TransactionInfo_subaddrAccount(txInfo),
+        addressIndex = int.tryParse(wownero.TransactionInfo_subaddrIndex(txInfo).split(", ")[0]) ?? 0,
+        addressIndexList = wownero.TransactionInfo_subaddrIndex(txInfo).split(", ").map((e) => int.tryParse(e) ?? 0).toList(),
         blockheight = wownero.TransactionInfo_blockHeight(txInfo),
         confirmations = wownero.TransactionInfo_confirmations(txInfo),
         fee = wownero.TransactionInfo_fee(txInfo),
@@ -314,6 +325,8 @@ class Transaction {
     required this.confirmations,
     required this.blockheight,
     required this.accountIndex,
+    required this.addressIndex,
+    required this.addressIndexList,
     required this.paymentId,
     required this.amount,
     required this.isSpend,
diff --git a/cw_wownero/lib/wownero_subaddress_list.dart b/cw_wownero/lib/wownero_subaddress_list.dart
index 61fd09ef9..5c026cc86 100644
--- a/cw_wownero/lib/wownero_subaddress_list.dart
+++ b/cw_wownero/lib/wownero_subaddress_list.dart
@@ -1,6 +1,7 @@
 import 'package:cw_core/subaddress.dart';
 import 'package:cw_wownero/api/coins_info.dart';
 import 'package:cw_wownero/api/subaddress_list.dart' as subaddress_list;
+import 'package:cw_wownero/api/wallet.dart';
 import 'package:flutter/services.dart';
 import 'package:mobx/mobx.dart';
 
@@ -103,6 +104,9 @@ abstract class WowneroSubaddressListBase with Store {
     required List<String> usedAddresses,
   }) async {
     _usedAddresses.addAll(usedAddresses);
+    final _all = _usedAddresses.toSet().toList();
+    _usedAddresses.clear();
+    _usedAddresses.addAll(_all);
     if (_isUpdating) {
       return;
     }
diff --git a/cw_wownero/lib/wownero_wallet.dart b/cw_wownero/lib/wownero_wallet.dart
index c3f4bcb69..ab7691dd6 100644
--- a/cw_wownero/lib/wownero_wallet.dart
+++ b/cw_wownero/lib/wownero_wallet.dart
@@ -82,6 +82,10 @@ abstract class WowneroWalletBase
     reaction((_) => isEnabledAutoGenerateSubaddress, (bool enabled) {
       _updateSubAddress(enabled, account: walletAddresses.account);
     });
+
+    _onTxHistoryChangeReaction = reaction((_) => transactionHistory, (__) {
+      _updateSubAddress(isEnabledAutoGenerateSubaddress, account: walletAddresses.account);
+    });
   }
 
   static const int _autoSaveInterval = 30;
@@ -123,6 +127,7 @@ abstract class WowneroWalletBase
 
   wownero_wallet.SyncListener? _listener;
   ReactionDisposer? _onAccountChangeReaction;
+  ReactionDisposer? _onTxHistoryChangeReaction;
   bool _isTransactionUpdating;
   bool _hasSyncAfterStartup;
   Timer? _autoSaveTimer;
@@ -158,6 +163,7 @@ abstract class WowneroWalletBase
   void close() async {
     _listener?.stop();
     _onAccountChangeReaction?.reaction.dispose();
+    _onTxHistoryChangeReaction?.reaction.dispose();
     _autoSaveTimer?.cancel();
   }
 
diff --git a/cw_wownero/lib/wownero_wallet_addresses.dart b/cw_wownero/lib/wownero_wallet_addresses.dart
index 9eeb182eb..b36c0e9ec 100644
--- a/cw_wownero/lib/wownero_wallet_addresses.dart
+++ b/cw_wownero/lib/wownero_wallet_addresses.dart
@@ -3,6 +3,7 @@ import 'package:cw_core/address_info.dart';
 import 'package:cw_core/subaddress.dart';
 import 'package:cw_core/wallet_addresses.dart';
 import 'package:cw_core/wallet_info.dart';
+import 'package:cw_wownero/api/transaction_history.dart';
 import 'package:cw_wownero/api/wallet.dart';
 import 'package:cw_wownero/wownero_account_list.dart';
 import 'package:cw_wownero/wownero_subaddress_list.dart';
@@ -36,7 +37,24 @@ abstract class WowneroWalletAddressesBase extends WalletAddresses with Store {
   WowneroSubaddressList subaddressList;
 
   WowneroAccountList accountList;
+  @override
+  Set<String> get usedAddresses {
+    final txs = getAllTransactions();
+    final adds = _originalUsedAddresses.toList();
+    for (var i = 0; i < txs.length; i++) {
+      for (var j = 0; j < txs[i].addressList.length; j++) {
+        adds.add(txs[i].addressList[j]);
+      }
+    }
+    return adds.toSet();
+  }
 
+  Set<String> _originalUsedAddresses = Set();
+
+  @override
+  set usedAddresses(Set<String> _usedAddresses) {
+    _originalUsedAddresses = _usedAddresses;
+  }
   @override
   Future<void> init() async {
     accountList.update();

From dadae35c955fa77074ebdbae2a0a7ed00391af82 Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Tue, 27 Aug 2024 11:44:18 -0400
Subject: [PATCH 81/81] fix regression

---
 cw_bitcoin/lib/electrum_wallet.dart | 24 +++++------
 cw_bitcoin/lib/litecoin_wallet.dart | 66 +++++++++++++++--------------
 2 files changed, 45 insertions(+), 45 deletions(-)

diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 1952c78da..f1aea380c 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -1262,23 +1262,20 @@ abstract class ElectrumWalletBase
       updatedUnspentCoins.addAll(await fetchUnspent(address));
     }));
 
+    unspentCoins = updatedUnspentCoins;
+
     if (unspentCoinsInfo.length != updatedUnspentCoins.length) {
-      updatedUnspentCoins.forEach((coin) => addCoinInfo(coin));
-    }
-
-    await updateCoins(updatedUnspentCoins, set: true);
-    await _refreshUnspentCoinsInfo();
-  }
-
-  Future<void> updateCoins(List<BitcoinUnspent> newUnspentCoins, {bool set = false}) async {
-    if (newUnspentCoins.isEmpty) {
+      unspentCoins.forEach((coin) => addCoinInfo(coin));
       return;
     }
 
-    if (set) {
-      unspentCoins = newUnspentCoins;
-    } else {
-      unspentCoins.addAll(newUnspentCoins);
+    await updateCoins(unspentCoins);
+    await _refreshUnspentCoinsInfo();
+  }
+
+  Future<void> updateCoins(List<BitcoinUnspent> newUnspentCoins) async {
+    if (newUnspentCoins.isEmpty) {
+      return;
     }
 
     newUnspentCoins.forEach((coin) {
@@ -1467,7 +1464,6 @@ abstract class ElectrumWalletBase
       // Create a list of available outputs
       final outputs = <BitcoinOutput>[];
       for (final out in bundle.originalTransaction.outputs) {
-
         // Check if the script contains OP_RETURN
         final script = out.scriptPubKey.script;
         if (script.contains('OP_RETURN') && memo == null) {
diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index ea3c395cc..824d8d6da 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -226,40 +226,43 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
     await updateBalance();
 
     _syncTimer?.cancel();
-    _syncTimer = Timer.periodic(const Duration(milliseconds: 1500), (timer) async {
-      if (syncStatus is FailedSyncStatus) return;
-      final nodeHeight = await electrumClient.getCurrentBlockChainTip() ?? 0;
-      final resp = await _stub.status(StatusRequest());
+    // delay the timer by a second so we don't overrride the restoreheight if one is set
+    Timer(const Duration(seconds: 1), () async {
+      _syncTimer = Timer.periodic(const Duration(milliseconds: 1500), (timer) async {
+        if (syncStatus is FailedSyncStatus) return;
+        final nodeHeight = await electrumClient.getCurrentBlockChainTip() ?? 0;
+        final resp = await _stub.status(StatusRequest());
 
-      if (resp.blockHeaderHeight < nodeHeight) {
-        int h = resp.blockHeaderHeight;
-        syncStatus = SyncingSyncStatus(nodeHeight - h, h / nodeHeight);
-      } else if (resp.mwebHeaderHeight < nodeHeight) {
-        int h = resp.mwebHeaderHeight;
-        syncStatus = SyncingSyncStatus(nodeHeight - h, h / nodeHeight);
-      } else if (resp.mwebUtxosHeight < nodeHeight) {
-        syncStatus = SyncingSyncStatus(1, 0.999);
-      } else {
-        // prevent unnecessary reaction triggers:
-        if (syncStatus is! SyncedSyncStatus) {
-          syncStatus = SyncedSyncStatus();
-        }
-
-        if (resp.mwebUtxosHeight > walletInfo.restoreHeight) {
-          await walletInfo.updateRestoreHeight(resp.mwebUtxosHeight);
-          await checkMwebUtxosSpent();
-          // update the confirmations for each transaction:
-          for (final transaction in transactionHistory.transactions.values) {
-            if (transaction.isPending) continue;
-            int txHeight = transaction.height ?? resp.mwebUtxosHeight;
-            final confirmations = (resp.mwebUtxosHeight - txHeight) + 1;
-            if (transaction.confirmations == confirmations) continue;
-            transaction.confirmations = confirmations;
-            transactionHistory.addOne(transaction);
+        if (resp.blockHeaderHeight < nodeHeight) {
+          int h = resp.blockHeaderHeight;
+          syncStatus = SyncingSyncStatus(nodeHeight - h, h / nodeHeight);
+        } else if (resp.mwebHeaderHeight < nodeHeight) {
+          int h = resp.mwebHeaderHeight;
+          syncStatus = SyncingSyncStatus(nodeHeight - h, h / nodeHeight);
+        } else if (resp.mwebUtxosHeight < nodeHeight) {
+          syncStatus = SyncingSyncStatus(1, 0.999);
+        } else {
+          // prevent unnecessary reaction triggers:
+          if (syncStatus is! SyncedSyncStatus) {
+            syncStatus = SyncedSyncStatus();
+          }
+
+          if (resp.mwebUtxosHeight > walletInfo.restoreHeight) {
+            await walletInfo.updateRestoreHeight(resp.mwebUtxosHeight);
+            await checkMwebUtxosSpent();
+            // update the confirmations for each transaction:
+            for (final transaction in transactionHistory.transactions.values) {
+              if (transaction.isPending) continue;
+              int txHeight = transaction.height ?? resp.mwebUtxosHeight;
+              final confirmations = (resp.mwebUtxosHeight - txHeight) + 1;
+              if (transaction.confirmations == confirmations) continue;
+              transaction.confirmations = confirmations;
+              transactionHistory.addOne(transaction);
+            }
+            await transactionHistory.save();
           }
-          await transactionHistory.save();
         }
-      }
+      });
     });
     // this runs in the background and processes new utxos as they come in:
     processMwebUtxos();
@@ -305,6 +308,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   }) async {
     await mwebUtxosBox.clear();
     transactionHistory.clear();
+    _syncTimer?.cancel();
     await walletInfo.updateRestoreHeight(height);
 
     // reset coin balances and txCount to 0: