diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml
index d57281447..5373bbc87 100644
--- a/.github/workflows/cache_dependencies.yml
+++ b/.github/workflows/cache_dependencies.yml
@@ -1,6 +1,7 @@
 name: Cache Dependencies
 
 on:
+  workflow_dispatch:
   push:
     branches: [ main ]
 
@@ -45,7 +46,7 @@ jobs:
             /opt/android/cake_wallet/cw_monero/android/.cxx
             /opt/android/cake_wallet/cw_monero/ios/External
             /opt/android/cake_wallet/cw_shared_external/ios/External
-          key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh') }}
+          key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh', '**/monero_api.cpp') }}
 
       - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
         name: Generate Externals
diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index ff18ad043..98b9490e9 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -55,7 +55,7 @@ jobs:
             /opt/android/cake_wallet/cw_monero/android/.cxx
             /opt/android/cake_wallet/cw_monero/ios/External
             /opt/android/cake_wallet/cw_shared_external/ios/External
-          key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh') }}
+          key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh', '**/monero_api.cpp') }}
 
       - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
         name: Generate Externals
@@ -163,7 +163,11 @@ jobs:
 
       - name: Send Test APK
         continue-on-error: true
-        run: |
-          cd /opt/android/cake_wallet
-          var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/$GITHUB_HEAD_REF.apk -H "Max-Days: 10")
-          curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}'
+        uses: adrey/slack-file-upload-action@1.0.5
+        with:
+          token: ${{ secrets.SLACK_APP_TOKEN }}
+          path: /opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk
+          channel: ${{ secrets.SLACK_APK_CHANNEL }}
+          title: '${{github.head_ref}}.apk'
+          filename: ${{github.head_ref}}.apk
+          initial_comment: ${{ github.event.head_commit.message }}
diff --git a/cw_bitcoin/lib/bitcoin_transaction_no_inputs_exception.dart b/cw_bitcoin/lib/bitcoin_transaction_no_inputs_exception.dart
index d4397dead..fac7e93c4 100644
--- a/cw_bitcoin/lib/bitcoin_transaction_no_inputs_exception.dart
+++ b/cw_bitcoin/lib/bitcoin_transaction_no_inputs_exception.dart
@@ -1,4 +1,4 @@
 class BitcoinTransactionNoInputsException implements Exception {
   @override
-  String toString() => 'Not enough inputs available';
+  String toString() => 'Not enough inputs available. Please select more under Coin Control';
 }
diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock
index 4bce06bab..843daa771 100644
--- a/cw_bitcoin/pubspec.lock
+++ b/cw_bitcoin/pubspec.lock
@@ -21,10 +21,10 @@ packages:
     dependency: transitive
     description:
       name: args
-      sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440"
+      sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611"
       url: "https://pub.dev"
     source: hosted
-    version: "2.4.0"
+    version: "2.3.2"
   asn1lib:
     dependency: transitive
     description:
@@ -37,19 +37,19 @@ packages:
     dependency: transitive
     description:
       name: async
-      sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
+      sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
       url: "https://pub.dev"
     source: hosted
-    version: "2.10.0"
+    version: "2.11.0"
   bech32:
     dependency: transitive
     description:
       path: "."
-      ref: "cake-0.2.1"
-      resolved-ref: cafd1c270641e95017d57d69f55cca9831d4db56
+      ref: "cake-0.2.2"
+      resolved-ref: "05755063b593aa6cca0a4820a318e0ce17de6192"
       url: "https://github.com/cake-tech/bech32.git"
     source: git
-    version: "0.2.1"
+    version: "0.2.2"
   bip32:
     dependency: transitive
     description:
@@ -70,8 +70,8 @@ packages:
     dependency: "direct main"
     description:
       path: "."
-      ref: cake-update-v2
-      resolved-ref: "8f86453761c0c26e368392d0ff2c6f12f3b7397b"
+      ref: cake-update-v3
+      resolved-ref: df9204144011ed9419eff7d9ef3143102a40252d
       url: "https://github.com/cake-tech/bitcoin_flutter.git"
     source: git
     version: "2.0.2"
@@ -111,10 +111,10 @@ packages:
     dependency: transitive
     description:
       name: build_daemon
-      sha256: "757153e5d9cd88253cb13f28c2fb55a537dc31fefd98137549895b5beb7c6169"
+      sha256: "6bc5544ea6ce4428266e7ea680e945c68806c4aae2da0eb5e9ccf38df8d6acbf"
       url: "https://pub.dev"
     source: hosted
-    version: "3.1.1"
+    version: "3.1.0"
   build_resolvers:
     dependency: "direct dev"
     description:
@@ -151,27 +151,18 @@ packages:
     dependency: transitive
     description:
       name: built_value
-      sha256: "31b7c748fd4b9adf8d25d72a4c4a59ef119f12876cf414f94f8af5131d5fa2b0"
+      sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725"
       url: "https://pub.dev"
     source: hosted
-    version: "8.4.4"
-  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"
+    version: "8.4.3"
   characters:
     dependency: transitive
     description:
       name: characters
-      sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
+      sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.1"
+    version: "1.3.0"
   checked_yaml:
     dependency: transitive
     description:
@@ -200,18 +191,18 @@ packages:
     dependency: transitive
     description:
       name: collection
-      sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
+      sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
       url: "https://pub.dev"
     source: hosted
-    version: "1.17.0"
+    version: "1.17.1"
   convert:
     dependency: transitive
     description:
       name: convert
-      sha256: "196284f26f69444b7f5c50692b55ec25da86d9e500451dc09333bf2e3ad69259"
+      sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.2"
+    version: "3.1.1"
   crypto:
     dependency: transitive
     description:
@@ -224,18 +215,10 @@ packages:
     dependency: "direct main"
     description:
       name: cryptography
-      sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35
+      sha256: e0e37f79665cd5c86e8897f9abe1accfe813c0cc5299dab22256e22fddc1fef8
       url: "https://pub.dev"
     source: hosted
-    version: "2.5.0"
-  cupertino_icons:
-    dependency: transitive
-    description:
-      name: cupertino_icons
-      sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
-      url: "https://pub.dev"
-    source: hosted
-    version: "1.0.5"
+    version: "2.0.5"
   cw_core:
     dependency: "direct main"
     description:
@@ -287,10 +270,10 @@ packages:
     dependency: transitive
     description:
       name: fixnum
-      sha256: "04be3e934c52e082558cc9ee21f42f5c1cd7a1262f4c63cd0357c08d5bba81ec"
+      sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
       url: "https://pub.dev"
     source: hosted
-    version: "1.0.1"
+    version: "1.1.0"
   flutter:
     dependency: "direct main"
     description: flutter
@@ -361,10 +344,10 @@ packages:
     dependency: "direct main"
     description:
       name: http
-      sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
+      sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
       url: "https://pub.dev"
     source: hosted
-    version: "0.13.5"
+    version: "1.1.0"
   http_multi_server:
     dependency: transitive
     description:
@@ -385,10 +368,10 @@ packages:
     dependency: "direct main"
     description:
       name: intl
-      sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
+      sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
       url: "https://pub.dev"
     source: hosted
-    version: "0.17.0"
+    version: "0.18.1"
   io:
     dependency: transitive
     description:
@@ -401,10 +384,10 @@ packages:
     dependency: transitive
     description:
       name: js
-      sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
+      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
       url: "https://pub.dev"
     source: hosted
-    version: "0.6.5"
+    version: "0.6.7"
   json_annotation:
     dependency: transitive
     description:
@@ -425,10 +408,10 @@ packages:
     dependency: transitive
     description:
       name: matcher
-      sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
+      sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
       url: "https://pub.dev"
     source: hosted
-    version: "0.12.13"
+    version: "0.12.15"
   material_color_utilities:
     dependency: transitive
     description:
@@ -441,10 +424,10 @@ packages:
     dependency: transitive
     description:
       name: meta
-      sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
+      sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
       url: "https://pub.dev"
     source: hosted
-    version: "1.8.0"
+    version: "1.9.1"
   mime:
     dependency: transitive
     description:
@@ -457,10 +440,10 @@ packages:
     dependency: "direct main"
     description:
       name: mobx
-      sha256: "6738620307a424d2c9ad8b873f4dce391c44e9135eb4e75668ac8202fec7a9b8"
+      sha256: f1862bd92c6a903fab67338f27e2f731117c3cb9ea37cee1a487f9e4e0de314a
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.4"
+    version: "2.1.3+1"
   mobx_codegen:
     dependency: "direct dev"
     description:
@@ -481,58 +464,58 @@ packages:
     dependency: transitive
     description:
       name: path
-      sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
+      sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
       url: "https://pub.dev"
     source: hosted
-    version: "1.8.2"
+    version: "1.8.3"
   path_provider:
     dependency: "direct main"
     description:
       name: path_provider
-      sha256: "04890b994ee89bfa80bf3080bfec40d5a92c5c7a785ebb02c13084a099d2b6f9"
+      sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.13"
+    version: "2.0.12"
   path_provider_android:
     dependency: transitive
     description:
       name: path_provider_android
-      sha256: "019f18c9c10ae370b08dce1f3e3b73bc9f58e7f087bb5e921f06529438ac0ae7"
+      sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.24"
+    version: "2.0.22"
   path_provider_foundation:
     dependency: transitive
     description:
       name: path_provider_foundation
-      sha256: "026b97a6c29da75181a37aae2eba9227f5fe13cb2838c6b975ce209328b8ab4e"
+      sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.3"
+    version: "2.1.1"
   path_provider_linux:
     dependency: transitive
     description:
       name: path_provider_linux
-      sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1"
+      sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.10"
+    version: "2.1.7"
   path_provider_platform_interface:
     dependency: transitive
     description:
       name: path_provider_platform_interface
-      sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec"
+      sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.6"
+    version: "2.0.5"
   path_provider_windows:
     dependency: transitive
     description:
       name: path_provider_windows
-      sha256: f53720498d5a543f9607db4b0e997c4b5438884de25b0f73098cc2671a51b130
+      sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.5"
+    version: "2.1.3"
   platform:
     dependency: transitive
     description:
@@ -545,10 +528,10 @@ packages:
     dependency: transitive
     description:
       name: plugin_platform_interface
-      sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc"
+      sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.4"
+    version: "2.1.3"
   pointycastle:
     dependency: transitive
     description:
@@ -585,10 +568,10 @@ packages:
     dependency: transitive
     description:
       name: pubspec_parse
-      sha256: ec85d7d55339d85f44ec2b682a82fea340071e8978257e5a43e69f79e98ef50c
+      sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a"
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.2"
+    version: "1.2.1"
   rxdart:
     dependency: "direct main"
     description:
@@ -686,10 +669,10 @@ packages:
     dependency: transitive
     description:
       name: test_api
-      sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
+      sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
       url: "https://pub.dev"
     source: hosted
-    version: "0.4.16"
+    version: "0.5.1"
   timing:
     dependency: transitive
     description:
@@ -698,14 +681,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.1"
-  tuple:
-    dependency: transitive
-    description:
-      name: tuple
-      sha256: "0ea99cd2f9352b2586583ab2ce6489d1f95a5f6de6fb9492faaf97ae2060f0aa"
-      url: "https://pub.dev"
-    source: hosted
-    version: "2.0.1"
   typed_data:
     dependency: transitive
     description:
@@ -758,10 +733,10 @@ packages:
     dependency: transitive
     description:
       name: xdg_directories
-      sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1
+      sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86
       url: "https://pub.dev"
     source: hosted
-    version: "1.0.0"
+    version: "0.2.0+3"
   yaml:
     dependency: transitive
     description:
@@ -771,5 +746,5 @@ packages:
     source: hosted
     version: "3.1.1"
 sdks:
-  dart: ">=2.19.0 <3.0.0"
+  dart: ">=3.0.0 <4.0.0"
   flutter: ">=3.0.0"
diff --git a/cw_core/lib/address_info.dart b/cw_core/lib/address_info.dart
new file mode 100644
index 000000000..63dc023ab
--- /dev/null
+++ b/cw_core/lib/address_info.dart
@@ -0,0 +1,21 @@
+import 'package:cw_core/hive_type_ids.dart';
+import 'package:hive/hive.dart';
+
+part 'address_info.g.dart';
+
+@HiveType(typeId: ADDRESS_INFO_TYPE_ID)
+class AddressInfo extends HiveObject {
+  AddressInfo({required this.address, this.accountIndex, required this.label});
+
+  static const typeId = ADDRESS_INFO_TYPE_ID;
+  static const boxName = 'AddressInfo';
+
+  @HiveField(0)
+  int? accountIndex;
+
+  @HiveField(1, defaultValue: '')
+  String address;
+
+  @HiveField(2, defaultValue: '')
+  String label;
+}
diff --git a/cw_core/lib/hive_type_ids.dart b/cw_core/lib/hive_type_ids.dart
new file mode 100644
index 000000000..950f39e1f
--- /dev/null
+++ b/cw_core/lib/hive_type_ids.dart
@@ -0,0 +1,13 @@
+const CONTACT_TYPE_ID               = 0;
+const NODE_TYPE_ID                  = 1;
+const TRANSACTION_TYPE_ID           = 2;
+const TRADE_TYPE_ID                 = 3;
+const WALLET_INFO_TYPE_ID           = 4;
+const WALLET_TYPE_TYPE_ID           = 5;
+const TEMPLATE_TYPE_ID              = 6;
+const EXCHANGE_TEMPLATE_TYPE_ID     = 7;
+const ORDER_TYPE_ID                 = 8;
+const UNSPENT_COINS_INFO_TYPE_ID    = 9;
+const ANONPAY_INVOICE_INFO_TYPE_ID  = 10;
+const ADDRESS_INFO_TYPE_ID          = 11;
+const ERC20_TOKEN_TYPE_ID           = 12;
diff --git a/cw_core/lib/monero_balance.dart b/cw_core/lib/monero_balance.dart
index 7d569ef2f..bf30110a3 100644
--- a/cw_core/lib/monero_balance.dart
+++ b/cw_core/lib/monero_balance.dart
@@ -2,24 +2,31 @@ import 'package:cw_core/balance.dart';
 import 'package:cw_core/monero_amount_format.dart';
 
 class MoneroBalance extends Balance {
-  MoneroBalance({required this.fullBalance, required this.unlockedBalance})
+  MoneroBalance({required this.fullBalance, required this.unlockedBalance, this.frozenBalance = 0})
       : formattedFullBalance = moneroAmountToString(amount: fullBalance),
-        formattedUnlockedBalance =
-            moneroAmountToString(amount: unlockedBalance),
+        formattedUnlockedBalance = moneroAmountToString(amount: unlockedBalance),
+        frozenFormatted = moneroAmountToString(amount: frozenBalance),
         super(unlockedBalance, fullBalance);
 
   MoneroBalance.fromString(
       {required this.formattedFullBalance,
-      required this.formattedUnlockedBalance})
+      required this.formattedUnlockedBalance,
+      this.frozenFormatted = '0.0'})
       : fullBalance = moneroParseAmount(amount: formattedFullBalance),
         unlockedBalance = moneroParseAmount(amount: formattedUnlockedBalance),
+        frozenBalance = moneroParseAmount(amount: frozenFormatted),
         super(moneroParseAmount(amount: formattedUnlockedBalance),
             moneroParseAmount(amount: formattedFullBalance));
 
   final int fullBalance;
   final int unlockedBalance;
+  final int frozenBalance;
   final String formattedFullBalance;
   final String formattedUnlockedBalance;
+  final String frozenFormatted;
+
+  @override
+  String get formattedFrozenBalance => frozenFormatted == '0.0' ? '' : frozenFormatted;
 
   @override
   String get formattedAvailableBalance => formattedUnlockedBalance;
diff --git a/cw_core/lib/unspent_coins_info.dart b/cw_core/lib/unspent_coins_info.dart
index 75c13f2cd..6fd682c06 100644
--- a/cw_core/lib/unspent_coins_info.dart
+++ b/cw_core/lib/unspent_coins_info.dart
@@ -12,7 +12,9 @@ class UnspentCoinsInfo extends HiveObject {
     required this.noteRaw,
     required this.address,
     required this.vout,
-    required this.value});
+    required this.value,
+    this.keyImage = null
+  });
 
   static const typeId = 9;
   static const boxName = 'Unspent';
@@ -42,6 +44,9 @@ class UnspentCoinsInfo extends HiveObject {
   @HiveField(7, defaultValue: 0)
   int vout;
 
+  @HiveField(8, defaultValue: null)
+  String? keyImage;
+
   String get note => noteRaw ?? '';
 
   set note(String value) => noteRaw = value;
diff --git a/cw_core/lib/wallet_addresses.dart b/cw_core/lib/wallet_addresses.dart
index a34101a88..27b5468c5 100644
--- a/cw_core/lib/wallet_addresses.dart
+++ b/cw_core/lib/wallet_addresses.dart
@@ -1,8 +1,10 @@
+import 'package:cw_core/address_info.dart';
 import 'package:cw_core/wallet_info.dart';
 
 abstract class WalletAddresses {
   WalletAddresses(this.walletInfo)
-    : addressesMap = {};
+    : addressesMap = {},
+      addressInfos = {};
 
   final WalletInfo walletInfo;
 
@@ -12,6 +14,10 @@ abstract class WalletAddresses {
 
   Map<String, String> addressesMap;
 
+  Map<int, List<AddressInfo>> addressInfos;
+
+  Set<String> usedAddresses = {};
+
   Future<void> init();
 
   Future<void> updateAddressesInBox();
@@ -20,6 +26,8 @@ abstract class WalletAddresses {
     try {
       walletInfo.address = address;
       walletInfo.addresses = addressesMap;
+      walletInfo.addressInfos = addressInfos;
+      walletInfo.usedAddresses = usedAddresses.toList();
 
       if (walletInfo.isInBox) {
         await walletInfo.save();
diff --git a/cw_core/lib/wallet_base.dart b/cw_core/lib/wallet_base.dart
index 18c456cae..cefc3c2fa 100644
--- a/cw_core/lib/wallet_base.dart
+++ b/cw_core/lib/wallet_base.dart
@@ -42,7 +42,9 @@ abstract class WalletBase<
 
   set syncStatus(SyncStatus status);
 
-  String get seed;
+  String? get seed;
+
+  String? get privateKey => null;
 
   Object get keys;
 
@@ -50,6 +52,10 @@ abstract class WalletBase<
 
   late HistoryType transactionHistory;
 
+  set isEnabledAutoGenerateSubaddress(bool value) {}
+
+  bool get isEnabledAutoGenerateSubaddress => false;
+
   Future<void> connectToNode({required Node node});
 
   Future<void> startSync();
diff --git a/cw_core/lib/wallet_info.dart b/cw_core/lib/wallet_info.dart
index a25702cf7..210adb9a4 100644
--- a/cw_core/lib/wallet_info.dart
+++ b/cw_core/lib/wallet_info.dart
@@ -1,7 +1,8 @@
-import 'package:flutter/foundation.dart';
-import 'package:hive/hive.dart';
-import 'package:cw_core/wallet_type.dart';
 import 'dart:async';
+import 'package:cw_core/address_info.dart';
+import 'package:cw_core/hive_type_ids.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:hive/hive.dart';
 
 part 'wallet_info.g.dart';
 
@@ -30,7 +31,7 @@ class WalletInfo extends HiveObject {
         yatEid, yatLastUsedAddressRaw, showIntroCakePayCard);
   }
 
-  static const typeId = 4;
+  static const typeId = WALLET_INFO_TYPE_ID;
   static const boxName = 'WalletInfo';
 
   @HiveField(0, defaultValue: '')
@@ -72,6 +73,12 @@ class WalletInfo extends HiveObject {
   @HiveField(13)
   bool? showIntroCakePayCard;
 
+  @HiveField(14)
+  Map<int, List<AddressInfo>>? addressInfos;
+
+  @HiveField(15)
+  List<String>? usedAddresses;
+
   String get yatLastUsedAddress => yatLastUsedAddressRaw ?? '';
 
   set yatLastUsedAddress(String address) {
diff --git a/cw_core/pubspec.lock b/cw_core/pubspec.lock
index b0fb67435..e399526fd 100644
--- a/cw_core/pubspec.lock
+++ b/cw_core/pubspec.lock
@@ -5,191 +5,218 @@ packages:
     dependency: transitive
     description:
       name: _fe_analyzer_shared
-      url: "https://pub.dartlang.org"
+      sha256: "4897882604d919befd350648c7f91926a9d5de99e67b455bf0917cc2362f4bb8"
+      url: "https://pub.dev"
     source: hosted
     version: "47.0.0"
   analyzer:
     dependency: transitive
     description:
       name: analyzer
-      url: "https://pub.dartlang.org"
+      sha256: "690e335554a8385bc9d787117d9eb52c0c03ee207a607e593de3c9d71b1cfe80"
+      url: "https://pub.dev"
     source: hosted
     version: "4.7.0"
   args:
     dependency: transitive
     description:
       name: args
-      url: "https://pub.dartlang.org"
+      sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611"
+      url: "https://pub.dev"
     source: hosted
-    version: "2.4.0"
+    version: "2.3.2"
   asn1lib:
     dependency: transitive
     description:
       name: asn1lib
-      url: "https://pub.dartlang.org"
+      sha256: ab96a1cb3beeccf8145c52e449233fe68364c9641623acd3adad66f8184f1039
+      url: "https://pub.dev"
     source: hosted
     version: "1.4.0"
   async:
     dependency: transitive
     description:
       name: async
-      url: "https://pub.dartlang.org"
+      sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
+      url: "https://pub.dev"
     source: hosted
-    version: "2.9.0"
+    version: "2.11.0"
   boolean_selector:
     dependency: transitive
     description:
       name: boolean_selector
-      url: "https://pub.dartlang.org"
+      sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
+      url: "https://pub.dev"
     source: hosted
-    version: "2.1.0"
+    version: "2.1.1"
   build:
     dependency: transitive
     description:
       name: build
-      url: "https://pub.dartlang.org"
+      sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777"
+      url: "https://pub.dev"
     source: hosted
     version: "2.3.1"
   build_config:
     dependency: transitive
     description:
       name: build_config
-      url: "https://pub.dartlang.org"
+      sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
+      url: "https://pub.dev"
     source: hosted
     version: "1.1.1"
   build_daemon:
     dependency: transitive
     description:
       name: build_daemon
-      url: "https://pub.dartlang.org"
+      sha256: "6bc5544ea6ce4428266e7ea680e945c68806c4aae2da0eb5e9ccf38df8d6acbf"
+      url: "https://pub.dev"
     source: hosted
-    version: "3.1.1"
+    version: "3.1.0"
   build_resolvers:
     dependency: "direct dev"
     description:
       name: build_resolvers
-      url: "https://pub.dartlang.org"
+      sha256: "687cf90a3951affac1bd5f9ecb5e3e90b60487f3d9cdc359bb310f8876bb02a6"
+      url: "https://pub.dev"
     source: hosted
     version: "2.0.10"
   build_runner:
     dependency: "direct dev"
     description:
       name: build_runner
-      url: "https://pub.dartlang.org"
+      sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727
+      url: "https://pub.dev"
     source: hosted
     version: "2.3.3"
   build_runner_core:
     dependency: transitive
     description:
       name: build_runner_core
-      url: "https://pub.dartlang.org"
+      sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292"
+      url: "https://pub.dev"
     source: hosted
     version: "7.2.7"
   built_collection:
     dependency: transitive
     description:
       name: built_collection
-      url: "https://pub.dartlang.org"
+      sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
+      url: "https://pub.dev"
     source: hosted
     version: "5.1.1"
   built_value:
     dependency: transitive
     description:
       name: built_value
-      url: "https://pub.dartlang.org"
+      sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725"
+      url: "https://pub.dev"
     source: hosted
-    version: "8.4.4"
+    version: "8.4.3"
   characters:
     dependency: transitive
     description:
       name: characters
-      url: "https://pub.dartlang.org"
+      sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
+      url: "https://pub.dev"
     source: hosted
-    version: "1.2.1"
+    version: "1.3.0"
   checked_yaml:
     dependency: transitive
     description:
       name: checked_yaml
-      url: "https://pub.dartlang.org"
+      sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311"
+      url: "https://pub.dev"
     source: hosted
     version: "2.0.2"
   clock:
     dependency: transitive
     description:
       name: clock
-      url: "https://pub.dartlang.org"
+      sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
+      url: "https://pub.dev"
     source: hosted
     version: "1.1.1"
   code_builder:
     dependency: transitive
     description:
       name: code_builder
-      url: "https://pub.dartlang.org"
+      sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe"
+      url: "https://pub.dev"
     source: hosted
     version: "4.4.0"
   collection:
     dependency: transitive
     description:
       name: collection
-      url: "https://pub.dartlang.org"
+      sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
+      url: "https://pub.dev"
     source: hosted
-    version: "1.16.0"
+    version: "1.17.1"
   convert:
     dependency: transitive
     description:
       name: convert
-      url: "https://pub.dartlang.org"
+      sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
+      url: "https://pub.dev"
     source: hosted
     version: "3.1.1"
   crypto:
     dependency: transitive
     description:
       name: crypto
-      url: "https://pub.dartlang.org"
+      sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
+      url: "https://pub.dev"
     source: hosted
     version: "3.0.2"
   dart_style:
     dependency: transitive
     description:
       name: dart_style
-      url: "https://pub.dartlang.org"
+      sha256: "7a03456c3490394c8e7665890333e91ae8a49be43542b616e414449ac358acd4"
+      url: "https://pub.dev"
     source: hosted
     version: "2.2.4"
   encrypt:
     dependency: "direct main"
     description:
       name: encrypt
-      url: "https://pub.dartlang.org"
+      sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb"
+      url: "https://pub.dev"
     source: hosted
     version: "5.0.1"
   fake_async:
     dependency: transitive
     description:
       name: fake_async
-      url: "https://pub.dartlang.org"
+      sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
+      url: "https://pub.dev"
     source: hosted
     version: "1.3.1"
   ffi:
     dependency: transitive
     description:
       name: ffi
-      url: "https://pub.dartlang.org"
+      sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
+      url: "https://pub.dev"
     source: hosted
     version: "2.0.1"
   file:
     dependency: "direct main"
     description:
       name: file
-      url: "https://pub.dartlang.org"
+      sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
+      url: "https://pub.dev"
     source: hosted
     version: "6.1.4"
   fixnum:
     dependency: transitive
     description:
       name: fixnum
-      url: "https://pub.dartlang.org"
+      sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
+      url: "https://pub.dev"
     source: hosted
-    version: "1.0.1"
+    version: "1.1.0"
   flutter:
     dependency: "direct main"
     description: flutter
@@ -199,7 +226,8 @@ packages:
     dependency: "direct main"
     description:
       name: flutter_mobx
-      url: "https://pub.dartlang.org"
+      sha256: "0da4add0016387a7bf309a0d0c41d36c6b3ae25ed7a176409267f166509e723e"
+      url: "https://pub.dev"
     source: hosted
     version: "2.0.6+5"
   flutter_test:
@@ -211,252 +239,288 @@ packages:
     dependency: transitive
     description:
       name: frontend_server_client
-      url: "https://pub.dartlang.org"
+      sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
+      url: "https://pub.dev"
     source: hosted
     version: "3.2.0"
   glob:
     dependency: transitive
     description:
       name: glob
-      url: "https://pub.dartlang.org"
+      sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c"
+      url: "https://pub.dev"
     source: hosted
     version: "2.1.1"
   graphs:
     dependency: transitive
     description:
       name: graphs
-      url: "https://pub.dartlang.org"
+      sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2
+      url: "https://pub.dev"
     source: hosted
     version: "2.2.0"
   hive:
     dependency: transitive
     description:
       name: hive
-      url: "https://pub.dartlang.org"
+      sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
+      url: "https://pub.dev"
     source: hosted
     version: "2.2.3"
   hive_generator:
     dependency: "direct dev"
     description:
       name: hive_generator
-      url: "https://pub.dartlang.org"
+      sha256: "81fd20125cb2ce8fd23623d7744ffbaf653aae93706c9bd3bf7019ea0ace3938"
+      url: "https://pub.dev"
     source: hosted
     version: "1.1.3"
   http:
     dependency: "direct main"
     description:
       name: http
-      url: "https://pub.dartlang.org"
+      sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
+      url: "https://pub.dev"
     source: hosted
-    version: "0.13.5"
+    version: "1.1.0"
   http_multi_server:
     dependency: transitive
     description:
       name: http_multi_server
-      url: "https://pub.dartlang.org"
+      sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
+      url: "https://pub.dev"
     source: hosted
     version: "3.2.1"
   http_parser:
     dependency: transitive
     description:
       name: http_parser
-      url: "https://pub.dartlang.org"
+      sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
+      url: "https://pub.dev"
     source: hosted
     version: "4.0.2"
   intl:
     dependency: "direct main"
     description:
       name: intl
-      url: "https://pub.dartlang.org"
+      sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
+      url: "https://pub.dev"
     source: hosted
-    version: "0.17.0"
+    version: "0.18.1"
   io:
     dependency: transitive
     description:
       name: io
-      url: "https://pub.dartlang.org"
+      sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
+      url: "https://pub.dev"
     source: hosted
     version: "1.0.4"
   js:
     dependency: transitive
     description:
       name: js
-      url: "https://pub.dartlang.org"
+      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
+      url: "https://pub.dev"
     source: hosted
-    version: "0.6.5"
+    version: "0.6.7"
   json_annotation:
     dependency: transitive
     description:
       name: json_annotation
-      url: "https://pub.dartlang.org"
+      sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317
+      url: "https://pub.dev"
     source: hosted
     version: "4.8.0"
   logging:
     dependency: transitive
     description:
       name: logging
-      url: "https://pub.dartlang.org"
+      sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d"
+      url: "https://pub.dev"
     source: hosted
     version: "1.1.1"
   matcher:
     dependency: transitive
     description:
       name: matcher
-      url: "https://pub.dartlang.org"
+      sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
+      url: "https://pub.dev"
     source: hosted
-    version: "0.12.12"
+    version: "0.12.15"
   material_color_utilities:
     dependency: transitive
     description:
       name: material_color_utilities
-      url: "https://pub.dartlang.org"
+      sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
+      url: "https://pub.dev"
     source: hosted
-    version: "0.1.5"
+    version: "0.2.0"
   meta:
     dependency: transitive
     description:
       name: meta
-      url: "https://pub.dartlang.org"
+      sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
+      url: "https://pub.dev"
     source: hosted
-    version: "1.8.0"
+    version: "1.9.1"
   mime:
     dependency: transitive
     description:
       name: mime
-      url: "https://pub.dartlang.org"
+      sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
+      url: "https://pub.dev"
     source: hosted
     version: "1.0.4"
   mobx:
     dependency: "direct main"
     description:
       name: mobx
-      url: "https://pub.dartlang.org"
+      sha256: f1862bd92c6a903fab67338f27e2f731117c3cb9ea37cee1a487f9e4e0de314a
+      url: "https://pub.dev"
     source: hosted
-    version: "2.1.4"
+    version: "2.1.3+1"
   mobx_codegen:
     dependency: "direct dev"
     description:
       name: mobx_codegen
-      url: "https://pub.dartlang.org"
+      sha256: "86122e410d8ea24dda0c69adb5c2a6ccadd5ce02ad46e144764e0d0184a06181"
+      url: "https://pub.dev"
     source: hosted
     version: "2.1.1"
   package_config:
     dependency: transitive
     description:
       name: package_config
-      url: "https://pub.dartlang.org"
+      sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
+      url: "https://pub.dev"
     source: hosted
     version: "2.1.0"
   path:
     dependency: transitive
     description:
       name: path
-      url: "https://pub.dartlang.org"
+      sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
+      url: "https://pub.dev"
     source: hosted
-    version: "1.8.2"
+    version: "1.8.3"
   path_provider:
     dependency: "direct main"
     description:
       name: path_provider
-      url: "https://pub.dartlang.org"
+      sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95
+      url: "https://pub.dev"
     source: hosted
-    version: "2.0.13"
+    version: "2.0.12"
   path_provider_android:
     dependency: transitive
     description:
       name: path_provider_android
-      url: "https://pub.dartlang.org"
+      sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e
+      url: "https://pub.dev"
     source: hosted
-    version: "2.0.24"
+    version: "2.0.22"
   path_provider_foundation:
     dependency: transitive
     description:
       name: path_provider_foundation
-      url: "https://pub.dartlang.org"
+      sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74"
+      url: "https://pub.dev"
     source: hosted
-    version: "2.1.3"
+    version: "2.1.1"
   path_provider_linux:
     dependency: transitive
     description:
       name: path_provider_linux
-      url: "https://pub.dartlang.org"
+      sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379
+      url: "https://pub.dev"
     source: hosted
-    version: "2.1.10"
+    version: "2.1.7"
   path_provider_platform_interface:
     dependency: transitive
     description:
       name: path_provider_platform_interface
-      url: "https://pub.dartlang.org"
+      sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76
+      url: "https://pub.dev"
     source: hosted
-    version: "2.0.6"
+    version: "2.0.5"
   path_provider_windows:
     dependency: transitive
     description:
       name: path_provider_windows
-      url: "https://pub.dartlang.org"
+      sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c
+      url: "https://pub.dev"
     source: hosted
-    version: "2.1.5"
+    version: "2.1.3"
   platform:
     dependency: transitive
     description:
       name: platform
-      url: "https://pub.dartlang.org"
+      sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
+      url: "https://pub.dev"
     source: hosted
     version: "3.1.0"
   plugin_platform_interface:
     dependency: transitive
     description:
       name: plugin_platform_interface
-      url: "https://pub.dartlang.org"
+      sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
+      url: "https://pub.dev"
     source: hosted
-    version: "2.1.4"
+    version: "2.1.3"
   pointycastle:
     dependency: transitive
     description:
       name: pointycastle
-      url: "https://pub.dartlang.org"
+      sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346
+      url: "https://pub.dev"
     source: hosted
     version: "3.6.2"
   pool:
     dependency: transitive
     description:
       name: pool
-      url: "https://pub.dartlang.org"
+      sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
+      url: "https://pub.dev"
     source: hosted
     version: "1.5.1"
   process:
     dependency: transitive
     description:
       name: process
-      url: "https://pub.dartlang.org"
+      sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
+      url: "https://pub.dev"
     source: hosted
     version: "4.2.4"
   pub_semver:
     dependency: transitive
     description:
       name: pub_semver
-      url: "https://pub.dartlang.org"
+      sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17"
+      url: "https://pub.dev"
     source: hosted
     version: "2.1.3"
   pubspec_parse:
     dependency: transitive
     description:
       name: pubspec_parse
-      url: "https://pub.dartlang.org"
+      sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a"
+      url: "https://pub.dev"
     source: hosted
-    version: "1.2.2"
+    version: "1.2.1"
   shelf:
     dependency: transitive
     description:
       name: shelf
-      url: "https://pub.dartlang.org"
+      sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c
+      url: "https://pub.dev"
     source: hosted
     version: "1.4.0"
   shelf_web_socket:
     dependency: transitive
     description:
       name: shelf_web_socket
-      url: "https://pub.dartlang.org"
+      sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8
+      url: "https://pub.dev"
     source: hosted
     version: "1.0.3"
   sky_engine:
@@ -468,121 +532,138 @@ packages:
     dependency: transitive
     description:
       name: source_gen
-      url: "https://pub.dartlang.org"
+      sha256: "2d79738b6bbf38a43920e2b8d189e9a3ce6cc201f4b8fc76be5e4fe377b1c38d"
+      url: "https://pub.dev"
     source: hosted
     version: "1.2.6"
   source_helper:
     dependency: transitive
     description:
       name: source_helper
-      url: "https://pub.dartlang.org"
+      sha256: "3b67aade1d52416149c633ba1bb36df44d97c6b51830c2198e934e3fca87ca1f"
+      url: "https://pub.dev"
     source: hosted
     version: "1.3.3"
   source_span:
     dependency: transitive
     description:
       name: source_span
-      url: "https://pub.dartlang.org"
+      sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
+      url: "https://pub.dev"
     source: hosted
-    version: "1.9.0"
+    version: "1.9.1"
   stack_trace:
     dependency: transitive
     description:
       name: stack_trace
-      url: "https://pub.dartlang.org"
+      sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
+      url: "https://pub.dev"
     source: hosted
-    version: "1.10.0"
+    version: "1.11.0"
   stream_channel:
     dependency: transitive
     description:
       name: stream_channel
-      url: "https://pub.dartlang.org"
+      sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
+      url: "https://pub.dev"
     source: hosted
-    version: "2.1.0"
+    version: "2.1.1"
   stream_transform:
     dependency: transitive
     description:
       name: stream_transform
-      url: "https://pub.dartlang.org"
+      sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
+      url: "https://pub.dev"
     source: hosted
     version: "2.1.0"
   string_scanner:
     dependency: transitive
     description:
       name: string_scanner
-      url: "https://pub.dartlang.org"
+      sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+      url: "https://pub.dev"
     source: hosted
-    version: "1.1.1"
+    version: "1.2.0"
   term_glyph:
     dependency: transitive
     description:
       name: term_glyph
-      url: "https://pub.dartlang.org"
+      sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+      url: "https://pub.dev"
     source: hosted
     version: "1.2.1"
   test_api:
     dependency: transitive
     description:
       name: test_api
-      url: "https://pub.dartlang.org"
+      sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
+      url: "https://pub.dev"
     source: hosted
-    version: "0.4.12"
+    version: "0.5.1"
   timing:
     dependency: transitive
     description:
       name: timing
-      url: "https://pub.dartlang.org"
+      sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
+      url: "https://pub.dev"
     source: hosted
     version: "1.0.1"
   typed_data:
     dependency: transitive
     description:
       name: typed_data
-      url: "https://pub.dartlang.org"
+      sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
+      url: "https://pub.dev"
     source: hosted
     version: "1.3.1"
   vector_math:
     dependency: transitive
     description:
       name: vector_math
-      url: "https://pub.dartlang.org"
+      sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+      url: "https://pub.dev"
     source: hosted
-    version: "2.1.2"
+    version: "2.1.4"
   watcher:
     dependency: transitive
     description:
       name: watcher
-      url: "https://pub.dartlang.org"
+      sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0"
+      url: "https://pub.dev"
     source: hosted
     version: "1.0.2"
   web_socket_channel:
     dependency: transitive
     description:
       name: web_socket_channel
-      url: "https://pub.dartlang.org"
+      sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b
+      url: "https://pub.dev"
     source: hosted
     version: "2.3.0"
   win32:
     dependency: transitive
     description:
       name: win32
-      url: "https://pub.dartlang.org"
+      sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46
+      url: "https://pub.dev"
     source: hosted
     version: "3.1.3"
   xdg_directories:
     dependency: transitive
     description:
       name: xdg_directories
-      url: "https://pub.dartlang.org"
+      sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86
+      url: "https://pub.dev"
     source: hosted
-    version: "1.0.0"
+    version: "0.2.0+3"
   yaml:
     dependency: transitive
     description:
       name: yaml
-      url: "https://pub.dartlang.org"
+      sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370"
+      url: "https://pub.dev"
     source: hosted
     version: "3.1.1"
 sdks:
-  dart: ">=2.19.0 <3.0.0"
+  dart: ">=3.0.0 <4.0.0"
   flutter: ">=3.0.0"
diff --git a/cw_ethereum/lib/ethereum_wallet.dart b/cw_ethereum/lib/ethereum_wallet.dart
index fb3be4d44..d8c236657 100644
--- a/cw_ethereum/lib/ethereum_wallet.dart
+++ b/cw_ethereum/lib/ethereum_wallet.dart
@@ -44,13 +44,15 @@ abstract class EthereumWalletBase
     with Store {
   EthereumWalletBase({
     required WalletInfo walletInfo,
-    required String mnemonic,
+    String? mnemonic,
+    String? privateKey,
     required String password,
     required EncryptionFileUtils encryptionFileUtils,
     ERC20Balance? initialBalance,
   })  : syncStatus = NotConnectedSyncStatus(),
         _password = password,
         _mnemonic = mnemonic,
+        _hexPrivateKey = privateKey,
         _isTransactionUpdating = false,
         _encryptionFileUtils = encryptionFileUtils,
         _client = EthereumClient(),
@@ -72,14 +74,15 @@ abstract class EthereumWalletBase
     _sharedPrefs.complete(SharedPreferences.getInstance());
   }
 
-  final String _mnemonic;
+  final String? _mnemonic;
+  final String? _hexPrivateKey;
   final String _password;
 
   final EncryptionFileUtils _encryptionFileUtils;
 
   late final Box<Erc20Token> erc20TokensBox;
 
-  late final EthPrivateKey _privateKey;
+  late final EthPrivateKey _ethPrivateKey;
 
   late EthereumClient _client;
 
@@ -107,8 +110,12 @@ abstract class EthereumWalletBase
     erc20TokensBox = await Hive.openBox<Erc20Token>(Erc20Token.boxName);
     await walletAddresses.init();
     await transactionHistory.init();
-    _privateKey = await getPrivateKey(_mnemonic, _password);
-    walletAddresses.address = _privateKey.address.toString();
+    _ethPrivateKey = await getPrivateKey(
+      mnemonic: _mnemonic,
+      privateKey: _hexPrivateKey,
+      password: _password,
+    );
+    walletAddresses.address = _ethPrivateKey.address.toString();
     await save();
   }
 
@@ -116,8 +123,7 @@ abstract class EthereumWalletBase
   int calculateEstimatedFee(TransactionPriority priority, int? amount) {
     try {
       if (priority is EthereumTransactionPriority) {
-        final priorityFee =
-            EtherAmount.fromUnitAndValue(EtherUnit.gwei, priority.tip).getInWei.toInt();
+        final priorityFee = EtherAmount.fromInt(EtherUnit.gwei, priority.tip).getInWei.toInt();
         return (_gasPrice! + priorityFee) * (_estimatedGas ?? 0);
       }
 
@@ -150,7 +156,7 @@ abstract class EthereumWalletBase
         throw Exception("Ethereum Node connection failed");
       }
 
-      _client.setListeners(_privateKey.address, _onNewTransaction);
+      _client.setListeners(_ethPrivateKey.address, _onNewTransaction);
 
       _setTransactionUpdateTimer();
 
@@ -210,7 +216,7 @@ abstract class EthereumWalletBase
     }
 
     final pendingEthereumTransaction = await _client.signTransaction(
-      privateKey: _privateKey,
+      privateKey: _ethPrivateKey,
       toAddress: _credentials.outputs.first.isParsedAddress
           ? _credentials.outputs.first.extractedAddress!
           : _credentials.outputs.first.address,
@@ -248,7 +254,7 @@ abstract class EthereumWalletBase
 
   @override
   Future<Map<String, EthereumTransactionInfo>> fetchTransactions() async {
-    final address = _privateKey.address.hex;
+    final address = _ethPrivateKey.address.hex;
     final transactions = await _client.fetchTransactions(address);
 
     final List<Future<List<EthereumTransactionModel>>> erc20TokensTransactions = [];
@@ -308,7 +314,10 @@ abstract class EthereumWalletBase
   }
 
   @override
-  String get seed => _mnemonic;
+  String? get seed => _mnemonic;
+
+  @override
+  String get privateKey => HEX.encode(_ethPrivateKey.privateKey);
 
   @action
   @override
@@ -335,6 +344,7 @@ abstract class EthereumWalletBase
 
   String toJSON() => json.encode({
         'mnemonic': _mnemonic,
+        'private_key': privateKey,
         'balance': balance[currency]!.toJSON(),
       });
 
@@ -347,13 +357,15 @@ abstract class EthereumWalletBase
     final path = await pathForWallet(name: name, type: walletInfo.type);
     final jsonSource = await encryptionFileUtils.read(path: path, password: password);
     final data = json.decode(jsonSource) as Map;
-    final mnemonic = data['mnemonic'] as String;
+    final mnemonic = data['mnemonic'] as String?;
+    final privateKey = data['private_key'] as String?;
     final balance = ERC20Balance.fromJSON(data['balance'] as String) ?? ERC20Balance(BigInt.zero);
 
     return EthereumWallet(
       walletInfo: walletInfo,
       password: password,
       mnemonic: mnemonic,
+      privateKey: privateKey,
       initialBalance: balance,
       encryptionFileUtils: encryptionFileUtils,
     );
@@ -367,7 +379,7 @@ abstract class EthereumWalletBase
   }
 
   Future<ERC20Balance> _fetchEthBalance() async {
-    final balance = await _client.getBalance(_privateKey.address);
+    final balance = await _client.getBalance(_ethPrivateKey.address);
     return ERC20Balance(balance.getInWei);
   }
 
@@ -376,7 +388,7 @@ abstract class EthereumWalletBase
       try {
         if (token.enabled) {
           balance[token] = await _client.fetchERC20Balances(
-            _privateKey.address,
+            _ethPrivateKey.address,
             token.contractAddress,
           );
         } else {
@@ -386,8 +398,15 @@ abstract class EthereumWalletBase
     }
   }
 
-  Future<EthPrivateKey> getPrivateKey(String mnemonic, String password) async {
-    final seed = bip39.mnemonicToSeed(mnemonic);
+  Future<EthPrivateKey> getPrivateKey(
+      {String? mnemonic, String? privateKey, required String password}) async {
+    assert(mnemonic != null || privateKey != null);
+
+    if (privateKey != null) {
+      return EthPrivateKey.fromHex(privateKey);
+    }
+
+    final seed = bip39.mnemonicToSeed(mnemonic!);
 
     final root = bip32.BIP32.fromSeed(seed);
 
@@ -423,7 +442,7 @@ abstract class EthereumWalletBase
 
     if (_token.enabled) {
       balance[_token] = await _client.fetchERC20Balances(
-        _privateKey.address,
+        _ethPrivateKey.address,
         _token.contractAddress,
       );
     } else {
diff --git a/cw_ethereum/lib/ethereum_wallet_creation_credentials.dart b/cw_ethereum/lib/ethereum_wallet_creation_credentials.dart
index c1fc43fa3..3d1efa54a 100644
--- a/cw_ethereum/lib/ethereum_wallet_creation_credentials.dart
+++ b/cw_ethereum/lib/ethereum_wallet_creation_credentials.dart
@@ -8,16 +8,22 @@ class EthereumNewWalletCredentials extends WalletCredentials {
 
 class EthereumRestoreWalletFromSeedCredentials extends WalletCredentials {
   EthereumRestoreWalletFromSeedCredentials(
-      {required String name, required String password, required this.mnemonic, WalletInfo? walletInfo})
+      {required String name,
+      required String password,
+      required this.mnemonic,
+      WalletInfo? walletInfo})
       : super(name: name, password: password, walletInfo: walletInfo);
 
   final String mnemonic;
 }
 
-class EthereumRestoreWalletFromWIFCredentials extends WalletCredentials {
-  EthereumRestoreWalletFromWIFCredentials(
-      {required String name, required String password, required this.wif, WalletInfo? walletInfo})
+class EthereumRestoreWalletFromPrivateKey extends WalletCredentials {
+  EthereumRestoreWalletFromPrivateKey(
+      {required String name,
+      required String password,
+      required this.privateKey,
+      WalletInfo? walletInfo})
       : super(name: name, password: password, walletInfo: walletInfo);
 
-  final String wif;
+  final String privateKey;
 }
diff --git a/cw_ethereum/lib/ethereum_wallet_service.dart b/cw_ethereum/lib/ethereum_wallet_service.dart
index 9ff44276b..289e7d25b 100644
--- a/cw_ethereum/lib/ethereum_wallet_service.dart
+++ b/cw_ethereum/lib/ethereum_wallet_service.dart
@@ -14,7 +14,7 @@ import 'package:bip39/bip39.dart' as bip39;
 import 'package:collection/collection.dart';
 
 class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
-    EthereumRestoreWalletFromSeedCredentials, EthereumRestoreWalletFromWIFCredentials> {
+    EthereumRestoreWalletFromSeedCredentials, EthereumRestoreWalletFromPrivateKey> {
   EthereumWalletService(this.walletInfoSource, this.isDirect);
 
   final Box<WalletInfo> walletInfoSource;
@@ -70,8 +70,19 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
   }
 
   @override
-  Future<EthereumWallet> restoreFromKeys(credentials) {
-    throw UnimplementedError();
+  Future<EthereumWallet> restoreFromKeys(EthereumRestoreWalletFromPrivateKey credentials) async {
+    final wallet = EthereumWallet(
+      password: credentials.password!,
+      privateKey: credentials.privateKey,
+      walletInfo: credentials.walletInfo!,
+      encryptionFileUtils: encryptionFileUtilsFor(isDirect),
+    );
+
+    await wallet.init();
+    wallet.addInitialTokens();
+    await wallet.save();
+
+    return wallet;
   }
 
   @override
diff --git a/cw_haven/lib/haven_wallet.dart b/cw_haven/lib/haven_wallet.dart
index 226ace6a1..e639be4b9 100644
--- a/cw_haven/lib/haven_wallet.dart
+++ b/cw_haven/lib/haven_wallet.dart
@@ -12,8 +12,7 @@ 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/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;
@@ -37,8 +36,8 @@ const moneroBlockSize = 1000;
 
 class HavenWallet = HavenWalletBase with _$HavenWallet;
 
-abstract class HavenWalletBase extends WalletBase<MoneroBalance,
-    HavenTransactionHistory, HavenTransactionInfo> with Store {
+abstract class HavenWalletBase
+    extends WalletBase<MoneroBalance, HavenTransactionHistory, HavenTransactionInfo> with Store {
   HavenWalletBase({required WalletInfo walletInfo})
       : balance = ObservableMap.of(getHavenBalance(accountIndex: 0)),
         _isTransactionUpdating = false,
@@ -47,8 +46,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
         syncStatus = NotConnectedSyncStatus(),
         super(walletInfo) {
     transactionHistory = HavenTransactionHistory();
-    _onAccountChangeReaction = reaction((_) => walletAddresses.account,
-            (Account? account) {
+    _onAccountChangeReaction = reaction((_) => walletAddresses.account, (Account? account) {
       if (account == null) {
         return;
       }
@@ -96,14 +94,12 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
       haven_wallet.setRecoveringFromSeed(isRecovery: walletInfo.isRecovery);
 
       if (haven_wallet.getCurrentHeight() <= 1) {
-        haven_wallet.setRefreshFromBlockHeight(
-            height: walletInfo.restoreHeight);
+        haven_wallet.setRefreshFromBlockHeight(height: walletInfo.restoreHeight);
       }
     }
 
-    _autoSaveTimer = Timer.periodic(
-       Duration(seconds: _autoSaveInterval),
-       (_) async => await save());
+    _autoSaveTimer =
+        Timer.periodic(Duration(seconds: _autoSaveInterval), (_) async => await save());
   }
 
   @override
@@ -115,7 +111,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
     _onAccountChangeReaction?.reaction.dispose();
     _autoSaveTimer?.cancel();
   }
-
+  
   @override
   Future<void> connectToNode({required Node node}) async {
     try {
@@ -170,26 +166,25 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
     }
 
     if (hasMultiDestination) {
-      if (outputs.any((item) => item.sendAll
-          || (item.formattedCryptoAmount ?? 0) <= 0)) {
-        throw HavenTransactionCreationException('You do not have enough coins to send this amount.');
+      if (outputs.any((item) => item.sendAll || (item.formattedCryptoAmount ?? 0) <= 0)) {
+        throw HavenTransactionCreationException(
+            'You do not have enough coins to send this amount.');
       }
 
-      final int totalAmount = outputs.fold(0, (acc, value) =>
-          acc + (value.formattedCryptoAmount ?? 0));
+      final int totalAmount =
+          outputs.fold(0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0));
 
       if (unlockedBalance < totalAmount) {
-        throw HavenTransactionCreationException('You do not have enough coins to send this amount.');
+        throw HavenTransactionCreationException(
+            'You do not have enough coins to send this amount.');
       }
 
-      final moneroOutputs = outputs.map((output) =>
-          MoneroOutput(
-              address: output.address,
-              amount: output.cryptoAmount!.replaceAll(',', '.')))
+      final moneroOutputs = outputs
+          .map((output) => MoneroOutput(
+              address: output.address, amount: output.cryptoAmount!.replaceAll(',', '.')))
           .toList();
 
-      pendingTransactionDescription =
-      await transaction_history.createTransactionMultDest(
+      pendingTransactionDescription = await transaction_history.createTransactionMultDest(
           outputs: moneroOutputs,
           priorityRaw: _credentials.priority.serialize(),
           accountIndex: walletAddresses.account!.id);
@@ -198,12 +193,8 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
       final address = output.isParsedAddress && (output.extractedAddress?.isNotEmpty ?? false)
           ? output.extractedAddress!
           : output.address;
-      final amount = output.sendAll
-          ? null
-          : output.cryptoAmount!.replaceAll(',', '.');
-      final int? formattedAmount = output.sendAll
-          ? null
-          : output.formattedCryptoAmount;
+      final amount = output.sendAll ? null : output.cryptoAmount!.replaceAll(',', '.');
+      final int? formattedAmount = output.sendAll ? null : output.formattedCryptoAmount;
 
       if ((formattedAmount != null && unlockedBalance < formattedAmount) ||
           (formattedAmount == null && unlockedBalance <= 0)) {
@@ -213,8 +204,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
             'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.');
       }
 
-      pendingTransactionDescription =
-      await transaction_history.createTransaction(
+      pendingTransactionDescription = await transaction_history.createTransaction(
           address: address,
           assetType: _credentials.assetType,
           amount: amount,
@@ -307,16 +297,14 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
   }
 
   String getTransactionAddress(int accountIndex, int addressIndex) =>
-      haven_wallet.getAddress(
-          accountIndex: accountIndex,
-          addressIndex: addressIndex);
+      haven_wallet.getAddress(accountIndex: accountIndex, addressIndex: addressIndex);
 
   @override
   Future<Map<String, HavenTransactionInfo>> fetchTransactions() async {
     haven_transaction_history.refreshTransactions();
-    return _getAllTransactions(null).fold<Map<String, HavenTransactionInfo>>(
-        <String, HavenTransactionInfo>{},
-        (Map<String, HavenTransactionInfo> acc, HavenTransactionInfo tx) {
+    return _getAllTransactions(null)
+        .fold<Map<String, HavenTransactionInfo>>(<String, HavenTransactionInfo>{},
+            (Map<String, HavenTransactionInfo> acc, HavenTransactionInfo tx) {
       acc[tx.id] = tx;
       return acc;
     });
@@ -340,9 +328,9 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
   }
 
   List<HavenTransactionInfo> _getAllTransactions(dynamic _) => haven_transaction_history
-          .getAllTransations()
-          .map((row) => HavenTransactionInfo.fromRow(row))
-          .toList();
+      .getAllTransations()
+      .map((row) => HavenTransactionInfo.fromRow(row))
+      .toList();
 
   void _setListeners() {
     _listener?.stop();
@@ -364,8 +352,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
   }
 
   int _getHeightDistance(DateTime date) {
-    final distance =
-        DateTime.now().millisecondsSinceEpoch - date.millisecondsSinceEpoch;
+    final distance = DateTime.now().millisecondsSinceEpoch - date.millisecondsSinceEpoch;
     final daysTmp = (distance / 86400).round();
     final days = daysTmp < 1 ? 1 : daysTmp;
 
@@ -386,8 +373,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
   void _askForUpdateBalance() =>
       balance.addAll(getHavenBalance(accountIndex: walletAddresses.account!.id));
 
-  Future<void> _askForUpdateTransactionHistory() async =>
-      await updateTransactions();
+  Future<void> _askForUpdateTransactionHistory() async => await updateTransactions();
 
   void _onNewBlock(int height, int blocksLeft, double ptc) async {
     try {
@@ -404,9 +390,9 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
         syncStatus = SyncedSyncStatus();
 
         if (!_hasSyncAfterStartup) {
-           _hasSyncAfterStartup = true;
-           await save();
-         }
+          _hasSyncAfterStartup = true;
+          await save();
+        }
 
         if (walletInfo.isRecovery) {
           await setAsRecovered();
diff --git a/cw_haven/pubspec.lock b/cw_haven/pubspec.lock
index a79d2d3cf..a63aa3237 100644
--- a/cw_haven/pubspec.lock
+++ b/cw_haven/pubspec.lock
@@ -37,10 +37,10 @@ packages:
     dependency: transitive
     description:
       name: async
-      sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
+      sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
       url: "https://pub.dev"
     source: hosted
-    version: "2.10.0"
+    version: "2.11.0"
   boolean_selector:
     dependency: transitive
     description:
@@ -117,10 +117,10 @@ packages:
     dependency: transitive
     description:
       name: characters
-      sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
+      sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.1"
+    version: "1.3.0"
   checked_yaml:
     dependency: transitive
     description:
@@ -149,10 +149,10 @@ packages:
     dependency: transitive
     description:
       name: collection
-      sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
+      sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
       url: "https://pub.dev"
     source: hosted
-    version: "1.17.0"
+    version: "1.17.1"
   convert:
     dependency: transitive
     description:
@@ -286,10 +286,10 @@ packages:
     dependency: "direct main"
     description:
       name: http
-      sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
+      sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
       url: "https://pub.dev"
     source: hosted
-    version: "0.13.5"
+    version: "1.1.0"
   http_multi_server:
     dependency: transitive
     description:
@@ -310,10 +310,10 @@ packages:
     dependency: "direct main"
     description:
       name: intl
-      sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
+      sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
       url: "https://pub.dev"
     source: hosted
-    version: "0.17.0"
+    version: "0.18.1"
   io:
     dependency: transitive
     description:
@@ -326,10 +326,10 @@ packages:
     dependency: transitive
     description:
       name: js
-      sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
+      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
       url: "https://pub.dev"
     source: hosted
-    version: "0.6.5"
+    version: "0.6.7"
   json_annotation:
     dependency: transitive
     description:
@@ -350,10 +350,10 @@ packages:
     dependency: transitive
     description:
       name: matcher
-      sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
+      sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
       url: "https://pub.dev"
     source: hosted
-    version: "0.12.13"
+    version: "0.12.15"
   material_color_utilities:
     dependency: transitive
     description:
@@ -366,10 +366,10 @@ packages:
     dependency: transitive
     description:
       name: meta
-      sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
+      sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
       url: "https://pub.dev"
     source: hosted
-    version: "1.8.0"
+    version: "1.9.1"
   mime:
     dependency: transitive
     description:
@@ -406,10 +406,10 @@ packages:
     dependency: transitive
     description:
       name: path
-      sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
+      sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
       url: "https://pub.dev"
     source: hosted
-    version: "1.8.2"
+    version: "1.8.3"
   path_provider:
     dependency: "direct main"
     description:
@@ -603,10 +603,10 @@ packages:
     dependency: transitive
     description:
       name: test_api
-      sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
+      sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
       url: "https://pub.dev"
     source: hosted
-    version: "0.4.16"
+    version: "0.5.1"
   timing:
     dependency: transitive
     description:
@@ -672,5 +672,5 @@ packages:
     source: hosted
     version: "3.1.1"
 sdks:
-  dart: ">=2.19.0 <3.0.0"
+  dart: ">=3.0.0 <4.0.0"
   flutter: ">=3.0.0"
diff --git a/cw_monero/example/pubspec.lock b/cw_monero/example/pubspec.lock
index f4c36e69c..1aae6b0c9 100644
--- a/cw_monero/example/pubspec.lock
+++ b/cw_monero/example/pubspec.lock
@@ -21,10 +21,10 @@ packages:
     dependency: transitive
     description:
       name: async
-      sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
+      sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
       url: "https://pub.dev"
     source: hosted
-    version: "2.10.0"
+    version: "2.11.0"
   boolean_selector:
     dependency: transitive
     description:
@@ -37,10 +37,10 @@ packages:
     dependency: transitive
     description:
       name: characters
-      sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
+      sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.1"
+    version: "1.3.0"
   clock:
     dependency: transitive
     description:
@@ -53,10 +53,10 @@ packages:
     dependency: transitive
     description:
       name: collection
-      sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
+      sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
       url: "https://pub.dev"
     source: hosted
-    version: "1.17.0"
+    version: "1.17.1"
   convert:
     dependency: transitive
     description:
@@ -157,10 +157,10 @@ packages:
     dependency: transitive
     description:
       name: http
-      sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
+      sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
       url: "https://pub.dev"
     source: hosted
-    version: "0.13.5"
+    version: "1.1.0"
   http_parser:
     dependency: transitive
     description:
@@ -173,18 +173,18 @@ packages:
     dependency: transitive
     description:
       name: intl
-      sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
+      sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
       url: "https://pub.dev"
     source: hosted
-    version: "0.17.0"
+    version: "0.18.1"
   js:
     dependency: transitive
     description:
       name: js
-      sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
+      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
       url: "https://pub.dev"
     source: hosted
-    version: "0.6.5"
+    version: "0.6.7"
   lints:
     dependency: transitive
     description:
@@ -197,10 +197,10 @@ packages:
     dependency: transitive
     description:
       name: matcher
-      sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
+      sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
       url: "https://pub.dev"
     source: hosted
-    version: "0.12.13"
+    version: "0.12.15"
   material_color_utilities:
     dependency: transitive
     description:
@@ -213,10 +213,10 @@ packages:
     dependency: transitive
     description:
       name: meta
-      sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
+      sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
       url: "https://pub.dev"
     source: hosted
-    version: "1.8.0"
+    version: "1.9.1"
   mobx:
     dependency: transitive
     description:
@@ -229,10 +229,10 @@ packages:
     dependency: transitive
     description:
       name: path
-      sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
+      sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
       url: "https://pub.dev"
     source: hosted
-    version: "1.8.2"
+    version: "1.8.3"
   path_provider:
     dependency: transitive
     description:
@@ -362,10 +362,10 @@ packages:
     dependency: transitive
     description:
       name: test_api
-      sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
+      sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
       url: "https://pub.dev"
     source: hosted
-    version: "0.4.16"
+    version: "0.5.1"
   typed_data:
     dependency: transitive
     description:
@@ -399,5 +399,5 @@ packages:
     source: hosted
     version: "0.2.0+3"
 sdks:
-  dart: ">=2.18.1 <3.0.0"
+  dart: ">=3.0.0 <4.0.0"
   flutter: ">=3.0.0"
diff --git a/cw_monero/ios/Classes/monero_api.cpp b/cw_monero/ios/Classes/monero_api.cpp
index a83447405..010763bc2 100644
--- a/cw_monero/ios/Classes/monero_api.cpp
+++ b/cw_monero/ios/Classes/monero_api.cpp
@@ -6,6 +6,7 @@
 #include <fstream>
 #include <unistd.h>
 #include <mutex>
+#include <list>
 #include "thread"
 #include "CwWalletListener.h"
 #if __APPLE__
@@ -144,7 +145,7 @@ extern "C"
         int8_t direction;
         int8_t isPending;
         uint32_t subaddrIndex;
-        
+
         char *hash;
         char *paymentId;
 
@@ -160,7 +161,7 @@ extern "C"
             std::set<uint32_t>::iterator it = subIndex.begin();
             subaddrIndex = *it;
             confirmations = transaction->confirmations();
-            datetime = static_cast<int64_t>(transaction->timestamp());            
+            datetime = static_cast<int64_t>(transaction->timestamp());
             direction = transaction->direction();
             isPending = static_cast<int8_t>(transaction->isPending());
             std::string *hash_str = new std::string(transaction->hash());
@@ -189,6 +190,62 @@ extern "C"
         }
     };
 
+    struct CoinsInfoRow
+    {
+        uint64_t blockHeight;
+        char *hash;
+        uint64_t internalOutputIndex;
+        uint64_t globalOutputIndex;
+        bool spent;
+        bool frozen;
+        uint64_t spentHeight;
+        uint64_t amount;
+        bool rct;
+        bool keyImageKnown;
+        uint64_t pkIndex;
+        uint32_t subaddrIndex;
+        uint32_t subaddrAccount;
+        char *address;
+        char *addressLabel;
+        char *keyImage;
+        uint64_t unlockTime;
+        bool unlocked;
+        char *pubKey;
+        bool coinbase;
+        char *description;
+
+        CoinsInfoRow(Monero::CoinsInfo *coinsInfo)
+        {
+            blockHeight = coinsInfo->blockHeight();
+             std::string *hash_str = new std::string(coinsInfo->hash());
+            hash = strdup(hash_str->c_str());
+            internalOutputIndex = coinsInfo->internalOutputIndex();
+            globalOutputIndex = coinsInfo->globalOutputIndex();
+            spent = coinsInfo->spent();
+            frozen = coinsInfo->frozen();
+            spentHeight = coinsInfo->spentHeight();
+            amount = coinsInfo->amount();
+            rct = coinsInfo->rct();
+            keyImageKnown = coinsInfo->keyImageKnown();
+            pkIndex = coinsInfo->pkIndex();
+            subaddrIndex = coinsInfo->subaddrIndex();
+            subaddrAccount = coinsInfo->subaddrAccount();
+            address =  strdup(coinsInfo->address().c_str()) ;
+            addressLabel = strdup(coinsInfo->addressLabel().c_str());
+            keyImage = strdup(coinsInfo->keyImage().c_str());
+            unlockTime = coinsInfo->unlockTime();
+            unlocked = coinsInfo->unlocked();
+            pubKey = strdup(coinsInfo->pubKey().c_str());
+            coinbase = coinsInfo->coinbase();
+            description = strdup(coinsInfo->description().c_str());
+        }
+
+        void setUnlocked(bool unlocked);
+
+    };
+
+    Monero::Coins *m_coins;
+
     Monero::Wallet *m_wallet;
     Monero::TransactionHistory *m_transaction_history;
     MoneroWalletListener *m_listener;
@@ -196,6 +253,7 @@ extern "C"
     Monero::SubaddressAccount *m_account;
     uint64_t m_last_known_wallet_height;
     uint64_t m_cached_syncing_blockchain_height = 0;
+    std::list<Monero::CoinsInfo*> m_coins_info;
     std::mutex store_lock;
     bool is_storing = false;
 
@@ -204,7 +262,7 @@ extern "C"
     {
         m_wallet = wallet;
         m_listener = nullptr;
-        
+
 
         if (wallet != nullptr)
         {
@@ -232,6 +290,17 @@ extern "C"
         {
             m_subaddress = nullptr;
         }
+
+        m_coins_info = std::list<Monero::CoinsInfo*>();
+
+        if (wallet != nullptr)
+        {
+            m_coins = wallet->coins();
+        }
+        else
+        {
+            m_coins = nullptr;
+        }
     }
 
     Monero::Wallet *get_current_wallet()
@@ -436,7 +505,7 @@ extern "C"
     {
         nice(19);
         Monero::Wallet *wallet = get_current_wallet();
-        
+
         std::string _login = "";
         std::string _password = "";
         std::string _socksProxyAddress = "";
@@ -520,10 +589,19 @@ extern "C"
 
     FUNCTION_VISABILITY_ATTRIBUTE
     bool transaction_create(char *address, char *payment_id, char *amount,
-                                              uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction)
+                            uint8_t priority_raw, uint32_t subaddr_account,
+                            char **preferred_inputs, uint32_t preferred_inputs_size,
+                            Utf8Box &error, PendingTransactionRaw &pendingTransaction)
     {
         nice(19);
-        
+
+        std::set<std::string> _preferred_inputs;
+
+        for (int i = 0; i < preferred_inputs_size; i++) {
+            _preferred_inputs.insert(std::string(*preferred_inputs));
+            preferred_inputs++;
+        }
+
         auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
         std::string _payment_id;
         Monero::PendingTransaction *transaction;
@@ -536,13 +614,13 @@ extern "C"
         if (amount != nullptr)
         {
             uint64_t _amount = Monero::Wallet::amountFromString(std::string(amount));
-            transaction = m_wallet->createTransaction(std::string(address), _payment_id, _amount, m_wallet->defaultMixin(), priority, subaddr_account);
+            transaction = m_wallet->createTransaction(std::string(address), _payment_id, _amount, m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
         }
         else
         {
-            transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional<uint64_t>(), m_wallet->defaultMixin(), priority, subaddr_account);
+            transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional<uint64_t>(), m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
         }
-        
+
         int status = transaction->status();
 
         if (status == Monero::PendingTransaction::Status::Status_Error || status == Monero::PendingTransaction::Status::Status_Critical)
@@ -561,7 +639,9 @@ extern "C"
 
     FUNCTION_VISABILITY_ATTRIBUTE
     bool transaction_create_mult_dest(char **addresses, char *payment_id, char **amounts, uint32_t size,
-                                                  uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction)
+                                      uint8_t priority_raw, uint32_t subaddr_account,
+                                      char **preferred_inputs, uint32_t preferred_inputs_size,
+                                      Utf8Box &error, PendingTransactionRaw &pendingTransaction)
     {
         nice(19);
 
@@ -575,6 +655,13 @@ extern "C"
             amounts++;
         }
 
+        std::set<std::string> _preferred_inputs;
+
+        for (int i = 0; i < preferred_inputs_size; i++) {
+            _preferred_inputs.insert(std::string(*preferred_inputs));
+            preferred_inputs++;
+        }
+
         auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
         std::string _payment_id;
         Monero::PendingTransaction *transaction;
@@ -861,6 +948,91 @@ extern "C"
         return m_wallet->trustedDaemon();
     }
 
+    CoinsInfoRow* coin(int index)
+    {
+        if (index >= 0 && index < m_coins_info.size()) {
+            std::list<Monero::CoinsInfo*>::iterator it = m_coins_info.begin();
+            std::advance(it, index);
+            Monero::CoinsInfo* element = *it;
+            std::cout << "Element at index " << index << ": " << element << std::endl;
+            return new CoinsInfoRow(element);
+        } else {
+            std::cout << "Invalid index." << std::endl;
+            return nullptr; // Return a default value (nullptr) for invalid index
+        }
+    }
+
+    void refresh_coins(uint32_t accountIndex)
+    {
+        m_coins_info.clear();
+
+        m_coins->refresh();
+        for (const auto i : m_coins->getAll()) {
+            if (i->subaddrAccount() == accountIndex && !(i->spent())) {
+                m_coins_info.push_back(i);
+            }
+        }
+    }
+
+    uint64_t coins_count()
+    {
+        return m_coins_info.size();
+    }
+
+    CoinsInfoRow** coins_from_account(uint32_t accountIndex)
+    {
+        std::vector<CoinsInfoRow*> matchingCoins;
+
+        for (int i = 0; i < coins_count(); i++) {
+            CoinsInfoRow* coinInfo = coin(i);
+            if (coinInfo->subaddrAccount == accountIndex) {
+                matchingCoins.push_back(coinInfo);
+            }
+        }
+
+        CoinsInfoRow** result = new CoinsInfoRow*[matchingCoins.size()];
+        std::copy(matchingCoins.begin(), matchingCoins.end(), result);
+        return result;
+    }
+
+    CoinsInfoRow** coins_from_txid(const char* txid, size_t* count)
+    {
+        std::vector<CoinsInfoRow*> matchingCoins;
+
+        for (int i = 0; i < coins_count(); i++) {
+            CoinsInfoRow* coinInfo = coin(i);
+            if (std::string(coinInfo->hash) == txid) {
+                matchingCoins.push_back(coinInfo);
+            }
+        }
+
+        *count = matchingCoins.size();
+        CoinsInfoRow** result = new CoinsInfoRow*[*count];
+        std::copy(matchingCoins.begin(), matchingCoins.end(), result);
+        return result;
+    }
+
+    CoinsInfoRow** coins_from_key_image(const char** keyimages, size_t keyimageCount, size_t* count)
+    {
+        std::vector<CoinsInfoRow*> matchingCoins;
+
+        for (int i = 0; i < coins_count(); i++) {
+            CoinsInfoRow* coinsInfoRow = coin(i);
+            for (size_t j = 0; j < keyimageCount; j++) {
+                if (coinsInfoRow->keyImageKnown && std::string(coinsInfoRow->keyImage) == keyimages[j]) {
+                    matchingCoins.push_back(coinsInfoRow);
+                    break;
+                }
+            }
+        }
+
+        *count = matchingCoins.size();
+        CoinsInfoRow** result = new CoinsInfoRow*[*count];
+        std::copy(matchingCoins.begin(), matchingCoins.end(), result);
+        return result;
+    }
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cw_monero/lib/api/coins_info.dart b/cw_monero/lib/api/coins_info.dart
new file mode 100644
index 000000000..9a5303f9d
--- /dev/null
+++ b/cw_monero/lib/api/coins_info.dart
@@ -0,0 +1,23 @@
+import 'dart:ffi';
+import 'package:cw_monero/api/signatures.dart';
+import 'package:cw_monero/api/structs/coins_info_row.dart';
+import 'package:cw_monero/api/types.dart';
+import 'package:cw_monero/api/monero_api.dart';
+
+final refreshCoinsNative = moneroApi
+    .lookup<NativeFunction<refresh_coins>>('refresh_coins')
+    .asFunction<RefreshCoins>();
+
+final coinsCountNative = moneroApi
+    .lookup<NativeFunction<coins_count>>('coins_count')
+    .asFunction<CoinsCount>();
+
+final coinNative = moneroApi
+    .lookup<NativeFunction<coin>>('coin')
+    .asFunction<GetCoin>();
+
+void refreshCoins(int accountIndex) => refreshCoinsNative(accountIndex);
+
+int countOfCoins() => coinsCountNative();
+
+CoinsInfoRow getCoin(int index) => coinNative(index).ref;
diff --git a/cw_monero/lib/api/signatures.dart b/cw_monero/lib/api/signatures.dart
index 82bc7801e..e208414c8 100644
--- a/cw_monero/lib/api/signatures.dart
+++ b/cw_monero/lib/api/signatures.dart
@@ -1,4 +1,5 @@
 import 'dart:ffi';
+import 'package:cw_monero/api/structs/coins_info_row.dart';
 import 'package:cw_monero/api/structs/pending_transaction.dart';
 import 'package:cw_monero/api/structs/ut8_box.dart';
 import 'package:ffi/ffi.dart';
@@ -9,8 +10,8 @@ typedef create_wallet = Int8 Function(
 typedef restore_wallet_from_seed = Int8 Function(
     Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>);
 
-typedef restore_wallet_from_keys = Int8 Function(Pointer<Utf8>, Pointer<Utf8>,
-    Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>);
+typedef restore_wallet_from_keys = Int8 Function(Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>,
+    Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>);
 
 typedef is_wallet_exist = Int8 Function(Pointer<Utf8>);
 
@@ -63,8 +64,7 @@ typedef subaddrress_refresh = Void Function(Int32);
 
 typedef subaddress_get_all = Pointer<Int64> Function();
 
-typedef subaddress_add_new = Void Function(
-    Int32 accountIndex, Pointer<Utf8> label);
+typedef subaddress_add_new = Void Function(Int32 accountIndex, Pointer<Utf8> label);
 
 typedef subaddress_set_label = Void Function(
     Int32 accountIndex, Int32 addressIndex, Pointer<Utf8> label);
@@ -77,8 +77,7 @@ typedef account_get_all = Pointer<Int64> Function();
 
 typedef account_add_new = Void Function(Pointer<Utf8> label);
 
-typedef account_set_label = Void Function(
-    Int32 accountIndex, Pointer<Utf8> label);
+typedef account_set_label = Void Function(Int32 accountIndex, Pointer<Utf8> label);
 
 typedef transactions_refresh = Void Function();
 
@@ -94,6 +93,8 @@ typedef transaction_create = Int8 Function(
     Pointer<Utf8> amount,
     Int8 priorityRaw,
     Int32 subaddrAccount,
+    Pointer<Pointer<Utf8>> preferredInputs,
+    Int32 preferredInputsSize,
     Pointer<Utf8Box> error,
     Pointer<PendingTransactionRaw> pendingTransaction);
 
@@ -104,6 +105,8 @@ typedef transaction_create_mult_dest = Int8 Function(
     Int32 size,
     Int8 priorityRaw,
     Int32 subaddrAccount,
+    Pointer<Pointer<Utf8>> preferredInputs,
+    Int32 preferredInputsSize,
     Pointer<Utf8Box> error,
     Pointer<PendingTransactionRaw> pendingTransaction);
 
@@ -123,10 +126,16 @@ typedef on_startup = Void Function();
 
 typedef rescan_blockchain = Void Function();
 
-typedef get_subaddress_label = Pointer<Utf8> Function(
-    Int32 accountIndex,
-    Int32 addressIndex);
+typedef get_subaddress_label = Pointer<Utf8> Function(Int32 accountIndex, Int32 addressIndex);
 
 typedef set_trusted_daemon = Void Function(Int8 trusted);
 
-typedef trusted_daemon = Int8 Function();
\ No newline at end of file
+typedef trusted_daemon = Int8 Function();
+
+typedef refresh_coins = Void Function(Int32 accountIndex);
+
+typedef coins_count = Int64 Function();
+
+// typedef coins_from_txid = Pointer<CoinsInfoRow> Function(Pointer<Utf8> txid);
+
+typedef coin = Pointer<CoinsInfoRow> Function(Int32 index);
diff --git a/cw_monero/lib/api/structs/coins_info_row.dart b/cw_monero/lib/api/structs/coins_info_row.dart
new file mode 100644
index 000000000..ff6f6ce73
--- /dev/null
+++ b/cw_monero/lib/api/structs/coins_info_row.dart
@@ -0,0 +1,73 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+class CoinsInfoRow extends Struct {
+  @Int64()
+  external int blockHeight;
+
+  external Pointer<Utf8> hash;
+
+  @Uint64()
+  external int internalOutputIndex;
+
+  @Uint64()
+  external int globalOutputIndex;
+
+  @Int8()
+  external int spent;
+
+  @Int8()
+  external int frozen;
+
+  @Uint64()
+  external int spentHeight;
+
+  @Uint64()
+  external int amount;
+
+  @Int8()
+  external int rct;
+
+  @Int8()
+  external int keyImageKnown;
+
+  @Uint64()
+  external int pkIndex;
+
+  @Uint32()
+  external int subaddrIndex;
+
+  @Uint32()
+  external int subaddrAccount;
+
+  external Pointer<Utf8> address;
+
+  external Pointer<Utf8> addressLabel;
+
+  external Pointer<Utf8> keyImage;
+
+  @Uint64()
+  external int unlockTime;
+
+  @Int8()
+  external int unlocked;
+
+  external Pointer<Utf8> pubKey;
+
+  @Int8()
+  external int coinbase;
+
+  external Pointer<Utf8> description;
+
+  String getHash() => hash.toDartString();
+
+  String getAddress() => address.toDartString();
+
+  String getAddressLabel() => addressLabel.toDartString();
+
+  String getKeyImage() => keyImage.toDartString();
+
+  String getPubKey() => pubKey.toDartString();
+
+  String getDescription() => description.toDartString();
+}
diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart
index 0fc507500..6f848cb3d 100644
--- a/cw_monero/lib/api/transaction_history.dart
+++ b/cw_monero/lib/api/transaction_history.dart
@@ -35,9 +35,8 @@ final transactionCommitNative = moneroApi
     .lookup<NativeFunction<transaction_commit>>('transaction_commit')
     .asFunction<TransactionCommit>();
 
-final getTxKeyNative = moneroApi
-    .lookup<NativeFunction<get_tx_key>>('get_tx_key')
-    .asFunction<GetTxKey>();
+final getTxKeyNative =
+    moneroApi.lookup<NativeFunction<get_tx_key>>('get_tx_key').asFunction<GetTxKey>();
 
 String getTxKey(String txId) {
   final txIdPointer = txId.toNativeUtf8();
@@ -71,10 +70,21 @@ PendingTransactionDescription createTransactionSync(
     required String paymentId,
     required int priorityRaw,
     String? amount,
-    int accountIndex = 0}) {
+    int accountIndex = 0,
+    List<String> preferredInputs = const []}) {
   final addressPointer = address.toNativeUtf8();
   final paymentIdPointer = paymentId.toNativeUtf8();
   final amountPointer = amount != null ? amount.toNativeUtf8() : nullptr;
+
+  final int preferredInputsSize = preferredInputs.length;
+  final List<Pointer<Utf8>> preferredInputsPointers =
+      preferredInputs.map((output) => output.toNativeUtf8()).toList();
+  final Pointer<Pointer<Utf8>> preferredInputsPointerPointer = calloc(preferredInputsSize);
+
+  for (int i = 0; i < preferredInputsSize; i++) {
+    preferredInputsPointerPointer[i] = preferredInputsPointers[i];
+  }
+
   final errorMessagePointer = calloc<Utf8Box>();
   final pendingTransactionRawPointer = calloc<PendingTransactionRaw>();
   final created = transactionCreateNative(
@@ -83,10 +93,16 @@ PendingTransactionDescription createTransactionSync(
           amountPointer,
           priorityRaw,
           accountIndex,
+          preferredInputsPointerPointer,
+          preferredInputsSize,
           errorMessagePointer,
           pendingTransactionRawPointer) !=
       0;
 
+  calloc.free(preferredInputsPointerPointer);
+
+  preferredInputsPointers.forEach((element) => calloc.free(element));
+
   calloc.free(addressPointer);
   calloc.free(paymentIdPointer);
 
@@ -111,15 +127,16 @@ PendingTransactionDescription createTransactionSync(
 
 PendingTransactionDescription createTransactionMultDestSync(
     {required List<MoneroOutput> outputs,
-      required String paymentId,
-      required int priorityRaw,
-      int accountIndex = 0}) {
+    required String paymentId,
+    required int priorityRaw,
+    int accountIndex = 0,
+    List<String> preferredInputs = const []}) {
   final int size = outputs.length;
-  final List<Pointer<Utf8>> addressesPointers = outputs.map((output) =>
-      output.address.toNativeUtf8()).toList();
+  final List<Pointer<Utf8>> addressesPointers =
+      outputs.map((output) => output.address.toNativeUtf8()).toList();
   final Pointer<Pointer<Utf8>> addressesPointerPointer = calloc(size);
-  final List<Pointer<Utf8>> amountsPointers = outputs.map((output) =>
-      output.amount.toNativeUtf8()).toList();
+  final List<Pointer<Utf8>> amountsPointers =
+      outputs.map((output) => output.amount.toNativeUtf8()).toList();
   final Pointer<Pointer<Utf8>> amountsPointerPointer = calloc(size);
 
   for (int i = 0; i < size; i++) {
@@ -127,25 +144,38 @@ PendingTransactionDescription createTransactionMultDestSync(
     amountsPointerPointer[i] = amountsPointers[i];
   }
 
+  final int preferredInputsSize = preferredInputs.length;
+  final List<Pointer<Utf8>> preferredInputsPointers =
+      preferredInputs.map((output) => output.toNativeUtf8()).toList();
+  final Pointer<Pointer<Utf8>> preferredInputsPointerPointer = calloc(preferredInputsSize);
+
+  for (int i = 0; i < preferredInputsSize; i++) {
+    preferredInputsPointerPointer[i] = preferredInputsPointers[i];
+  }
+
   final paymentIdPointer = paymentId.toNativeUtf8();
   final errorMessagePointer = calloc<Utf8Box>();
   final pendingTransactionRawPointer = calloc<PendingTransactionRaw>();
   final created = transactionCreateMultDestNative(
-      addressesPointerPointer,
-      paymentIdPointer,
-      amountsPointerPointer,
-      size,
-      priorityRaw,
-      accountIndex,
-      errorMessagePointer,
-      pendingTransactionRawPointer) !=
+          addressesPointerPointer,
+          paymentIdPointer,
+          amountsPointerPointer,
+          size,
+          priorityRaw,
+          accountIndex,
+          preferredInputsPointerPointer,
+          preferredInputsSize,
+          errorMessagePointer,
+          pendingTransactionRawPointer) !=
       0;
 
   calloc.free(addressesPointerPointer);
   calloc.free(amountsPointerPointer);
+  calloc.free(preferredInputsPointerPointer);
 
   addressesPointers.forEach((element) => calloc.free(element));
   amountsPointers.forEach((element) => calloc.free(element));
+  preferredInputsPointers.forEach((element) => calloc.free(element));
 
   calloc.free(paymentIdPointer);
 
@@ -164,13 +194,12 @@ PendingTransactionDescription createTransactionMultDestSync(
       pointerAddress: pendingTransactionRawPointer.address);
 }
 
-void commitTransactionFromPointerAddress({required int address}) => commitTransaction(
-    transactionPointer: Pointer<PendingTransactionRaw>.fromAddress(address));
+void commitTransactionFromPointerAddress({required int address}) =>
+    commitTransaction(transactionPointer: Pointer<PendingTransactionRaw>.fromAddress(address));
 
 void commitTransaction({required Pointer<PendingTransactionRaw> transactionPointer}) {
   final errorMessagePointer = calloc<Utf8Box>();
-  final isCommited =
-      transactionCommitNative(transactionPointer, errorMessagePointer) != 0;
+  final isCommited = transactionCommitNative(transactionPointer, errorMessagePointer) != 0;
 
   if (!isCommited) {
     final message = errorMessagePointer.ref.getValue();
@@ -185,13 +214,15 @@ PendingTransactionDescription _createTransactionSync(Map args) {
   final amount = args['amount'] as String?;
   final priorityRaw = args['priorityRaw'] as int;
   final accountIndex = args['accountIndex'] as int;
+  final preferredInputs = args['preferredInputs'] as List<String>;
 
   return createTransactionSync(
       address: address,
       paymentId: paymentId,
       amount: amount,
       priorityRaw: priorityRaw,
-      accountIndex: accountIndex);
+      accountIndex: accountIndex,
+      preferredInputs: preferredInputs);
 }
 
 PendingTransactionDescription _createTransactionMultDestSync(Map args) {
@@ -199,12 +230,14 @@ PendingTransactionDescription _createTransactionMultDestSync(Map args) {
   final paymentId = args['paymentId'] as String;
   final priorityRaw = args['priorityRaw'] as int;
   final accountIndex = args['accountIndex'] as int;
+  final preferredInputs = args['preferredInputs'] as List<String>;
 
   return createTransactionMultDestSync(
       outputs: outputs,
       paymentId: paymentId,
       priorityRaw: priorityRaw,
-      accountIndex: accountIndex);
+      accountIndex: accountIndex,
+      preferredInputs: preferredInputs);
 }
 
 Future<PendingTransactionDescription> createTransaction(
@@ -212,23 +245,27 @@ Future<PendingTransactionDescription> createTransaction(
         required int priorityRaw,
         String? amount,
         String paymentId = '',
-        int accountIndex = 0}) =>
+        int accountIndex = 0,
+        List<String> preferredInputs = const []}) =>
     compute(_createTransactionSync, {
       'address': address,
       'paymentId': paymentId,
       'amount': amount,
       'priorityRaw': priorityRaw,
-      'accountIndex': accountIndex
+      'accountIndex': accountIndex,
+      'preferredInputs': preferredInputs
     });
 
 Future<PendingTransactionDescription> createTransactionMultDest(
-    {required List<MoneroOutput> outputs,
-      required int priorityRaw,
-      String paymentId = '',
-      int accountIndex = 0}) =>
+        {required List<MoneroOutput> outputs,
+        required int priorityRaw,
+        String paymentId = '',
+        int accountIndex = 0,
+        List<String> preferredInputs = const []}) =>
     compute(_createTransactionMultDestSync, {
       'outputs': outputs,
       'paymentId': paymentId,
       'priorityRaw': priorityRaw,
-      'accountIndex': accountIndex
+      'accountIndex': accountIndex,
+      'preferredInputs': preferredInputs
     });
diff --git a/cw_monero/lib/api/types.dart b/cw_monero/lib/api/types.dart
index 051f317c9..2c92f2d80 100644
--- a/cw_monero/lib/api/types.dart
+++ b/cw_monero/lib/api/types.dart
@@ -1,4 +1,5 @@
 import 'dart:ffi';
+import 'package:cw_monero/api/structs/coins_info_row.dart';
 import 'package:cw_monero/api/structs/pending_transaction.dart';
 import 'package:cw_monero/api/structs/ut8_box.dart';
 import 'package:ffi/ffi.dart';
@@ -92,6 +93,8 @@ typedef TransactionCreate = int Function(
     Pointer<Utf8> amount,
     int priorityRaw,
     int subaddrAccount,
+    Pointer<Pointer<Utf8>> preferredInputs,
+    int preferredInputsSize,
     Pointer<Utf8Box> error,
     Pointer<PendingTransactionRaw> pendingTransaction);
 
@@ -102,6 +105,8 @@ typedef TransactionCreateMultDest = int Function(
     int size,
     int priorityRaw,
     int subaddrAccount,
+    Pointer<Pointer<Utf8>> preferredInputs,
+    int preferredInputsSize,
     Pointer<Utf8Box> error,
     Pointer<PendingTransactionRaw> pendingTransaction);
 
@@ -127,4 +132,10 @@ typedef GetSubaddressLabel = Pointer<Utf8> Function(
 
 typedef SetTrustedDaemon = void Function(int);
 
-typedef TrustedDaemon = int Function();
\ No newline at end of file
+typedef TrustedDaemon = int Function();
+
+typedef RefreshCoins = void Function(int);
+
+typedef CoinsCount = int Function();
+
+typedef GetCoin = Pointer<CoinsInfoRow> Function(int);
diff --git a/cw_monero/lib/monero_transaction_creation_exception.dart b/cw_monero/lib/exceptions/monero_transaction_creation_exception.dart
similarity index 100%
rename from cw_monero/lib/monero_transaction_creation_exception.dart
rename to cw_monero/lib/exceptions/monero_transaction_creation_exception.dart
diff --git a/cw_monero/lib/exceptions/monero_transaction_no_inputs_exception.dart b/cw_monero/lib/exceptions/monero_transaction_no_inputs_exception.dart
new file mode 100644
index 000000000..5d808be8f
--- /dev/null
+++ b/cw_monero/lib/exceptions/monero_transaction_no_inputs_exception.dart
@@ -0,0 +1,4 @@
+class MoneroTransactionNoInputsException implements Exception {
+  @override
+  String toString() => 'Not enough inputs available. Please select more under Coin Control';
+}
diff --git a/cw_monero/lib/monero_subaddress_list.dart b/cw_monero/lib/monero_subaddress_list.dart
index 8d8eeb469..dbd1a89ae 100644
--- a/cw_monero/lib/monero_subaddress_list.dart
+++ b/cw_monero/lib/monero_subaddress_list.dart
@@ -1,19 +1,20 @@
-import 'package:cw_monero/api/structs/subaddress_row.dart';
 import 'package:flutter/services.dart';
 import 'package:mobx/mobx.dart';
+import 'package:cw_monero/api/coins_info.dart';
 import 'package:cw_monero/api/subaddress_list.dart' as subaddress_list;
 import 'package:cw_core/subaddress.dart';
 
 part 'monero_subaddress_list.g.dart';
 
-class MoneroSubaddressList = MoneroSubaddressListBase
-    with _$MoneroSubaddressList;
+class MoneroSubaddressList = MoneroSubaddressListBase with _$MoneroSubaddressList;
 
 abstract class MoneroSubaddressListBase with Store {
   MoneroSubaddressListBase()
-    : _isRefreshing = false,
-      _isUpdating = false,
-      subaddresses = ObservableList<Subaddress>();
+      : _isRefreshing = false,
+        _isUpdating = false,
+        subaddresses = ObservableList<Subaddress>();
+
+  final List<String> _usedAddresses = [];
 
   @observable
   ObservableList<Subaddress> subaddresses;
@@ -22,6 +23,8 @@ abstract class MoneroSubaddressListBase with Store {
   bool _isUpdating;
 
   void update({required int accountIndex}) {
+    refreshCoins(accountIndex);
+
     if (_isUpdating) {
       return;
     }
@@ -47,20 +50,24 @@ abstract class MoneroSubaddressListBase with Store {
       subaddresses = [primary] + rest.toList();
     }
 
-    return subaddresses
-        .map((subaddressRow) => Subaddress(
+    return subaddresses.map((subaddressRow) {
+      final hasDefaultAddressName =
+          subaddressRow.getLabel().toLowerCase() == 'Primary account'.toLowerCase() ||
+              subaddressRow.getLabel().toLowerCase() == 'Untitled account'.toLowerCase();
+      final isPrimaryAddress = subaddressRow.getId() == 0 && hasDefaultAddressName;
+      return Subaddress(
           id: subaddressRow.getId(),
           address: subaddressRow.getAddress(),
-          label: subaddressRow.getId() == 0 &&
-                subaddressRow.getLabel().toLowerCase() == 'Primary account'.toLowerCase()
-            ? 'Primary address'
-            : subaddressRow.getLabel()))
-        .toList();
+          label: isPrimaryAddress
+              ? 'Primary address'
+              : hasDefaultAddressName
+                  ? ''
+                  : subaddressRow.getLabel());
+    }).toList();
   }
 
   Future<void> addSubaddress({required int accountIndex, required String label}) async {
-    await subaddress_list.addSubaddress(
-        accountIndex: accountIndex, label: label);
+    await subaddress_list.addSubaddress(accountIndex: accountIndex, label: label);
     update(accountIndex: accountIndex);
   }
 
@@ -86,4 +93,59 @@ abstract class MoneroSubaddressListBase with Store {
       rethrow;
     }
   }
+
+  Future<void> updateWithAutoGenerate({
+    required int accountIndex,
+    required String defaultLabel,
+    required List<String> usedAddresses,
+  }) async {
+    _usedAddresses.addAll(usedAddresses);
+    if (_isUpdating) {
+      return;
+    }
+
+    try {
+      _isUpdating = true;
+      refresh(accountIndex: accountIndex);
+      subaddresses.clear();
+      final newSubAddresses =
+          await _getAllUnusedAddresses(accountIndex: accountIndex, label: defaultLabel);
+      subaddresses.addAll(newSubAddresses);
+    } catch (e) {
+      rethrow;
+    } finally {
+      _isUpdating = false;
+    }
+  }
+
+  Future<List<Subaddress>> _getAllUnusedAddresses(
+      {required int accountIndex, required String label}) async {
+    final allAddresses = subaddress_list.getAllSubaddresses();
+
+    if (allAddresses.isEmpty || _usedAddresses.contains(allAddresses.last.getAddress())) {
+      final isAddressUnused = await _newSubaddress(accountIndex: accountIndex, label: label);
+      if (!isAddressUnused) {
+        return await _getAllUnusedAddresses(accountIndex: accountIndex, label: label);
+      }
+    }
+
+    return allAddresses
+        .map((subaddressRow) => Subaddress(
+            id: subaddressRow.getId(),
+            address: subaddressRow.getAddress(),
+            label: subaddressRow.getId() == 0 &&
+                    subaddressRow.getLabel().toLowerCase() == 'Primary account'.toLowerCase()
+                ? 'Primary address'
+                : subaddressRow.getLabel()))
+        .toList();
+  }
+
+  Future<bool> _newSubaddress({required int accountIndex, required String label}) async {
+    await subaddress_list.addSubaddress(accountIndex: accountIndex, label: label);
+
+    return subaddress_list
+        .getAllSubaddresses()
+        .where((subaddressRow) => !_usedAddresses.contains(subaddressRow.getAddress()))
+        .isNotEmpty;
+  }
 }
diff --git a/cw_monero/lib/monero_unspent.dart b/cw_monero/lib/monero_unspent.dart
new file mode 100644
index 000000000..c2ff9f9db
--- /dev/null
+++ b/cw_monero/lib/monero_unspent.dart
@@ -0,0 +1,28 @@
+import 'package:cw_monero/api/structs/coins_info_row.dart';
+
+class MoneroUnspent {
+  MoneroUnspent(this.address, this.hash, this.keyImage, this.value, this.isFrozen, this.isUnlocked)
+      : isSending = true,
+        note = '';
+
+  MoneroUnspent.fromCoinsInfoRow(CoinsInfoRow coinsInfoRow)
+      : address = coinsInfoRow.getAddress(),
+        hash = coinsInfoRow.getHash(),
+        keyImage = coinsInfoRow.getKeyImage(),
+        value = coinsInfoRow.amount,
+        isFrozen = coinsInfoRow.frozen == 1,
+        isUnlocked = coinsInfoRow.unlocked == 1,
+        isSending = true,
+        note = '';
+
+  final String address;
+  final String hash;
+  final String keyImage;
+  final int value;
+
+  final bool isUnlocked;
+
+  bool isFrozen;
+  bool isSending;
+  String note;
+}
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index bc455531c..e55348edb 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -1,33 +1,35 @@
 import 'dart:async';
 import 'dart:io';
-import 'package:cw_core/pathForWallet.dart';
-import 'package:cw_core/transaction_priority.dart';
-import 'package:cw_core/monero_amount_format.dart';
-import 'package:cw_monero/monero_transaction_creation_exception.dart';
-import 'package:cw_monero/monero_transaction_info.dart';
-import 'package:cw_monero/monero_wallet_addresses.dart';
-import 'package:cw_core/monero_wallet_utils.dart';
-import 'package:cw_monero/api/structs/pending_transaction.dart';
-import 'package:mobx/mobx.dart';
-import 'package:cw_monero/api/transaction_history.dart'
-    as monero_transaction_history;
-import 'package:cw_monero/api/wallet.dart';
-import 'package:cw_monero/api/wallet.dart' as monero_wallet;
-import 'package:cw_monero/api/transaction_history.dart' as transaction_history;
-import 'package:cw_monero/api/monero_output.dart';
-import 'package:cw_monero/monero_transaction_creation_credentials.dart';
-import 'package:cw_monero/pending_monero_transaction.dart';
-import 'package:cw_core/monero_wallet_keys.dart';
-import 'package:cw_core/monero_balance.dart';
-import 'package:cw_monero/monero_transaction_history.dart';
 import 'package:cw_core/account.dart';
-import 'package:cw_core/pending_transaction.dart';
-import 'package:cw_core/wallet_base.dart';
-import 'package:cw_core/sync_status.dart';
-import 'package:cw_core/wallet_info.dart';
-import 'package:cw_core/node.dart';
-import 'package:cw_core/monero_transaction_priority.dart';
 import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/monero_amount_format.dart';
+import 'package:cw_core/monero_balance.dart';
+import 'package:cw_core/monero_transaction_priority.dart';
+import 'package:cw_core/monero_wallet_keys.dart';
+import 'package:cw_core/monero_wallet_utils.dart';
+import 'package:cw_core/node.dart';
+import 'package:cw_core/pathForWallet.dart';
+import 'package:cw_core/pending_transaction.dart';
+import 'package:cw_core/sync_status.dart';
+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/coins_info.dart';
+import 'package:cw_monero/api/monero_output.dart';
+import 'package:cw_monero/api/structs/pending_transaction.dart';
+import 'package:cw_monero/api/transaction_history.dart' as transaction_history;
+import 'package:cw_monero/api/wallet.dart' as monero_wallet;
+import 'package:cw_monero/exceptions/monero_transaction_creation_exception.dart';
+import 'package:cw_monero/exceptions/monero_transaction_no_inputs_exception.dart';
+import 'package:cw_monero/pending_monero_transaction.dart';
+import 'package:cw_monero/monero_transaction_creation_credentials.dart';
+import 'package:cw_monero/monero_transaction_history.dart';
+import 'package:cw_monero/monero_transaction_info.dart';
+import 'package:cw_monero/monero_unspent.dart';
+import 'package:cw_monero/monero_wallet_addresses.dart';
+import 'package:mobx/mobx.dart';
+import 'package:hive/hive.dart';
 
 part 'monero_wallet.g.dart';
 
@@ -39,40 +41,52 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
     MoneroTransactionHistory, MoneroTransactionInfo> with Store {
   MoneroWalletBase({
       required WalletInfo walletInfo,
+      required Box<UnspentCoinsInfo> unspentCoinsInfo,
       required String password})
       : balance = ObservableMap<CryptoCurrency, MoneroBalance>.of({
-            CryptoCurrency.xmr: MoneroBalance(
+          CryptoCurrency.xmr: MoneroBalance(
               fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
               unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0))
-            }),
+        }),
         _isTransactionUpdating = false,
         _hasSyncAfterStartup = false,
+        isEnabledAutoGenerateSubaddress = false,
         _password = password,
-        walletAddresses = MoneroWalletAddresses(walletInfo),
         syncStatus = NotConnectedSyncStatus(),
+        unspentCoins = [],
+        this.unspentCoinsInfo = unspentCoinsInfo,
         super(walletInfo) {
     transactionHistory = MoneroTransactionHistory();
-    _onAccountChangeReaction = reaction((_) => walletAddresses.account,
-            (Account? account) {
+    walletAddresses = MoneroWalletAddresses(walletInfo, transactionHistory);
+
+    _onAccountChangeReaction = reaction((_) => walletAddresses.account, (Account? account) {
       if (account == null) {
         return;
       }
 
-      balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(
-        <CryptoCurrency, MoneroBalance>{
-          currency: MoneroBalance(
+      balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(<CryptoCurrency, MoneroBalance>{
+        currency: MoneroBalance(
             fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
-            unlockedBalance:
-                monero_wallet.getUnlockedBalance(accountIndex: account.id))
-        });
-      walletAddresses.updateSubaddressList(accountIndex: account.id);
+            unlockedBalance: monero_wallet.getUnlockedBalance(accountIndex: account.id))
+      });
+      _updateSubAddress(isEnabledAutoGenerateSubaddress, account: account);
+    });
+
+    reaction((_) => isEnabledAutoGenerateSubaddress, (bool enabled) {
+      _updateSubAddress(enabled, account: walletAddresses.account);
     });
   }
 
   static const int _autoSaveInterval = 30;
 
+  Box<UnspentCoinsInfo> unspentCoinsInfo;
+
   @override
-  MoneroWalletAddresses walletAddresses;
+  late MoneroWalletAddresses walletAddresses;
+
+  @override
+  @observable
+  bool isEnabledAutoGenerateSubaddress;
 
   @override
   @observable
@@ -95,11 +109,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
       publicSpendKey: monero_wallet.getPublicSpendKey(),
       publicViewKey: monero_wallet.getPublicViewKey());
 
-  SyncListener? _listener;
+  monero_wallet.SyncListener? _listener;
   ReactionDisposer? _onAccountChangeReaction;
   bool _isTransactionUpdating;
   bool _hasSyncAfterStartup;
   Timer? _autoSaveTimer;
+  List<MoneroUnspent> unspentCoins;
   String _password;
 
   Future<void> init() async {
@@ -177,10 +192,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
   @override
   Future<PendingTransaction> createTransaction(Object credentials) async {
     final _credentials = credentials as MoneroTransactionCreationCredentials;
+    final inputs = <String>[];
     final outputs = _credentials.outputs;
     final hasMultiDestination = outputs.length > 1;
     final unlockedBalance =
     monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id);
+    var allInputsAmount = 0;
 
     PendingTransactionDescription pendingTransactionDescription;
 
@@ -188,6 +205,21 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
       throw MoneroTransactionCreationException('The wallet is not synced.');
     }
 
+    if (unspentCoins.isEmpty) {
+      await updateUnspent();
+    }
+
+    for (final utx in unspentCoins) {
+      if (utx.isSending) {
+        allInputsAmount += utx.value;
+        inputs.add(utx.keyImage);
+      }
+    }
+
+    if (inputs.isEmpty) {
+      throw MoneroTransactionNoInputsException();
+    }
+
     if (hasMultiDestination) {
       if (outputs.any((item) => item.sendAll
           || (item.formattedCryptoAmount ?? 0) <= 0)) {
@@ -215,7 +247,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
       await transaction_history.createTransactionMultDest(
           outputs: moneroOutputs,
           priorityRaw: _credentials.priority.serialize(),
-          accountIndex: walletAddresses.account!.id);
+          accountIndex: walletAddresses.account!.id,
+          preferredInputs: inputs);
     } else {
       final output = outputs.first;
       final address = output.isParsedAddress
@@ -236,12 +269,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
             'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.');
       }
 
-      pendingTransactionDescription =
-      await transaction_history.createTransaction(
+      pendingTransactionDescription = await transaction_history.createTransaction(
           address: address!,
           amount: amount,
           priorityRaw: _credentials.priority.serialize(),
-          accountIndex: walletAddresses.account!.id);
+          accountIndex: walletAddresses.account!.id,
+          preferredInputs: inputs);
     }
 
     return PendingMoneroTransaction(pendingTransactionDescription);
@@ -271,6 +304,14 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
 
   @override
   Future<void> save() async {
+    await walletAddresses.updateUsedSubaddress();
+
+    if (isEnabledAutoGenerateSubaddress) {
+      walletAddresses.updateUnusedSubaddress(
+          accountIndex: walletAddresses.account?.id ?? 0,
+          defaultLabel: walletAddresses.account?.label ?? '');
+    }
+
     await walletAddresses.updateAddressesInBox();
     await backupWalletFiles(name);
     await monero_wallet.store();
@@ -362,6 +403,85 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
     await walletInfo.save();
   }
 
+  Future<void> updateUnspent() async {
+    refreshCoins(walletAddresses.account!.id);
+
+    unspentCoins.clear();
+
+    final coinCount = countOfCoins();
+    for (var i = 0; i < coinCount; i++) {
+      final coin = getCoin(i);
+      if (coin.spent == 0) {
+        unspentCoins.add(MoneroUnspent.fromCoinsInfoRow(coin));
+      }
+    }
+
+    if (unspentCoinsInfo.isEmpty) {
+      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));
+
+        if (coinInfoList.isNotEmpty) {
+          final coinInfo = coinInfoList.first;
+
+          coin.isFrozen = coinInfo.isFrozen;
+          coin.isSending = coinInfo.isSending;
+          coin.note = coinInfo.note;
+        } else {
+          _addCoinInfo(coin);
+        }
+      });
+    }
+
+    await _refreshUnspentCoinsInfo();
+    _askForUpdateBalance();
+  }
+
+  Future<void> _addCoinInfo(MoneroUnspent coin) async {
+    final newInfo = UnspentCoinsInfo(
+      walletId: id,
+      hash: coin.hash,
+      isFrozen: coin.isFrozen,
+      isSending: coin.isSending,
+      noteRaw: coin.note,
+      address: coin.address,
+      value: coin.value,
+      vout: 0,
+      keyImage: coin.keyImage
+    );
+
+    await unspentCoinsInfo.add(newInfo);
+  }
+
+  Future<void> _refreshUnspentCoinsInfo() async {
+    try {
+      final List<dynamic> keys = <dynamic>[];
+      final currentWalletUnspentCoins = unspentCoinsInfo.values
+          .where((element) => element.walletId.contains(id));
+
+      if (currentWalletUnspentCoins.isNotEmpty) {
+        currentWalletUnspentCoins.forEach((element) {
+          final existUnspentCoins = unspentCoins.where((coin) => element.hash.contains(coin.hash));
+
+          if (existUnspentCoins.isEmpty) {
+            keys.add(element.key);
+          }
+        });
+      }
+
+      if (keys.isNotEmpty) {
+        await unspentCoinsInfo.deleteAll(keys);
+      }
+    } catch (e) {
+      print(e.toString());
+    }
+  }
+
   String getTransactionAddress(int accountIndex, int addressIndex) =>
       monero_wallet.getAddress(
           accountIndex: accountIndex,
@@ -369,7 +489,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
 
   @override
   Future<Map<String, MoneroTransactionInfo>> fetchTransactions() async {
-    monero_transaction_history.refreshTransactions();
+    transaction_history.refreshTransactions();
     return _getAllTransactions(null).fold<Map<String, MoneroTransactionInfo>>(
         <String, MoneroTransactionInfo>{},
         (Map<String, MoneroTransactionInfo> acc, MoneroTransactionInfo tx) {
@@ -400,7 +520,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
   }
 
   List<MoneroTransactionInfo> _getAllTransactions(dynamic _) =>
-      monero_transaction_history
+      transaction_history
           .getAllTransations()
           .map((row) => MoneroTransactionInfo.fromRow(row))
           .toList();
@@ -415,7 +535,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
       return;
     }
 
-    final currentHeight = getCurrentHeight();
+    final currentHeight = monero_wallet.getCurrentHeight();
 
     if (currentHeight <= 1) {
       final height = _getHeightByDate(walletInfo.date);
@@ -447,11 +567,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
   void _askForUpdateBalance() {
     final unlockedBalance = _getUnlockedBalance();
     final fullBalance = _getFullBalance();
+    final frozenBalance = _getFrozenBalance();
 
     if (balance[currency]!.fullBalance != fullBalance ||
-        balance[currency]!.unlockedBalance != unlockedBalance) {
+        balance[currency]!.unlockedBalance != unlockedBalance ||
+        balance[currency]!.frozenBalance != frozenBalance) {
       balance[currency] = MoneroBalance(
-          fullBalance: fullBalance, unlockedBalance: unlockedBalance);
+          fullBalance: fullBalance, unlockedBalance: unlockedBalance, frozenBalance: frozenBalance);
     }
   }
 
@@ -464,6 +586,17 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
   int _getUnlockedBalance() =>
       monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id);
 
+  int _getFrozenBalance() {
+    var frozenBalance = 0;
+
+    for (var coin in unspentCoinsInfo.values) {
+      if (coin.isFrozen)
+        frozenBalance += coin.value;
+    }
+
+    return frozenBalance;
+  }
+
   void _onNewBlock(int height, int blocksLeft, double ptc) async {
     try {
       if (walletInfo.isRecovery) {
@@ -503,4 +636,15 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
       print(e.toString());
     }
   }
+
+  void _updateSubAddress(bool enableAutoGenerate, {Account? account}) {
+    if (enableAutoGenerate) {
+         walletAddresses.updateUnusedSubaddress(
+          accountIndex: account?.id ?? 0,
+          defaultLabel: account?.label ?? '',
+        );
+      } else {
+        walletAddresses.updateSubaddressList(accountIndex: account?.id ?? 0);
+      }
+  }
 }
diff --git a/cw_monero/lib/monero_wallet_addresses.dart b/cw_monero/lib/monero_wallet_addresses.dart
index 2002e789a..a9da3d5d4 100644
--- a/cw_monero/lib/monero_wallet_addresses.dart
+++ b/cw_monero/lib/monero_wallet_addresses.dart
@@ -1,27 +1,32 @@
+import 'package:cw_core/address_info.dart';
 import 'package:cw_core/wallet_addresses.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/account.dart';
+import 'package:cw_monero/api/wallet.dart';
 import 'package:cw_monero/monero_account_list.dart';
 import 'package:cw_monero/monero_subaddress_list.dart';
 import 'package:cw_core/subaddress.dart';
+import 'package:cw_monero/monero_transaction_history.dart';
 import 'package:mobx/mobx.dart';
 
 part 'monero_wallet_addresses.g.dart';
 
-class MoneroWalletAddresses = MoneroWalletAddressesBase
-    with _$MoneroWalletAddresses;
+class MoneroWalletAddresses = MoneroWalletAddressesBase with _$MoneroWalletAddresses;
 
 abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
-  MoneroWalletAddressesBase(WalletInfo walletInfo)
-    : accountList = MoneroAccountList(),
-      subaddressList = MoneroSubaddressList(),
-      address = '',
-      super(walletInfo);
+  MoneroWalletAddressesBase(
+      WalletInfo walletInfo, MoneroTransactionHistory moneroTransactionHistory)
+      : accountList = MoneroAccountList(),
+        _moneroTransactionHistory = moneroTransactionHistory,
+        subaddressList = MoneroSubaddressList(),
+        address = '',
+        super(walletInfo);
 
+  final MoneroTransactionHistory _moneroTransactionHistory;
   @override
   @observable
   String address;
-  
+
   @observable
   Account? account;
 
@@ -46,11 +51,15 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
       final _subaddressList = MoneroSubaddressList();
 
       addressesMap.clear();
+      addressInfos.clear();
 
       accountList.accounts.forEach((account) {
         _subaddressList.update(accountIndex: account.id);
         _subaddressList.subaddresses.forEach((subaddress) {
           addressesMap[subaddress.address] = subaddress.label;
+          addressInfos[account.id] ??= [];
+          addressInfos[account.id]?.add(AddressInfo(
+              address: subaddress.address, label: subaddress.label, accountIndex: account.id));
         });
       });
 
@@ -62,14 +71,14 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
 
   bool validate() {
     accountList.update();
-    final accountListLength = accountList.accounts.length ?? 0;
+    final accountListLength = accountList.accounts.length;
 
     if (accountListLength <= 0) {
       return false;
     }
 
     subaddressList.update(accountIndex: accountList.accounts.first.id);
-    final subaddressListLength = subaddressList.subaddresses.length ?? 0;
+    final subaddressListLength = subaddressList.subaddresses.length;
 
     if (subaddressListLength <= 0) {
       return false;
@@ -83,4 +92,24 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
     subaddress = subaddressList.subaddresses.first;
     address = subaddress!.address;
   }
-}
\ No newline at end of file
+
+  Future<void> updateUsedSubaddress() async {
+    final transactions = _moneroTransactionHistory.transactions.values.toList();
+
+    transactions.forEach((element) {
+      final accountIndex = element.accountIndex;
+      final addressIndex = element.addressIndex;
+      usedAddresses.add(getAddress(accountIndex: accountIndex, addressIndex: addressIndex));
+    });
+  }
+
+  Future<void> updateUnusedSubaddress(
+      {required int accountIndex, required String defaultLabel}) async {
+    await subaddressList.updateWithAutoGenerate(
+        accountIndex: accountIndex,
+        defaultLabel: defaultLabel,
+        usedAddresses: usedAddresses.toList());
+    subaddress = subaddressList.subaddresses.last;
+    address = subaddress!.address;
+  }
+}
diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart
index 6f5645f66..fb9bd3768 100644
--- a/cw_monero/lib/monero_wallet_service.dart
+++ b/cw_monero/lib/monero_wallet_service.dart
@@ -1,15 +1,15 @@
 import 'dart:io';
-import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/monero_wallet_utils.dart';
-import 'package:hive/hive.dart';
-import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
-import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
-import 'package:cw_monero/monero_wallet.dart';
-import 'package:cw_core/wallet_credentials.dart';
-import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/pathForWallet.dart';
+import 'package:cw_core/unspent_coins_info.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_service.dart';
 import 'package:cw_core/wallet_type.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/monero_wallet.dart';
 
 class MoneroNewWalletCredentials extends WalletCredentials {
   MoneroNewWalletCredentials({required String name, required this.language, String? password})
@@ -52,10 +52,11 @@ class MoneroWalletService extends WalletService<
     MoneroNewWalletCredentials,
     MoneroRestoreWalletFromSeedCredentials,
     MoneroRestoreWalletFromKeysCredentials> {
-  MoneroWalletService(this.walletInfoSource);
+  MoneroWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
 
   final Box<WalletInfo> walletInfoSource;
-  
+  final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
+
   static bool walletFilesExist(String path) =>
       !File(path).existsSync() && !File('$path.keys').existsSync();
 
@@ -71,8 +72,9 @@ class MoneroWalletService extends WalletService<
           password: credentials.password!,
           language: credentials.language);
       final wallet = MoneroWallet(
-        walletInfo: credentials.walletInfo!,
-        password: credentials.password!);
+          walletInfo: credentials.walletInfo!,
+          unspentCoinsInfo: unspentCoinsInfoSource,
+          password: credentials.password!);
       await wallet.init();
 
       return wallet;
@@ -110,6 +112,7 @@ class MoneroWalletService extends WalletService<
           (info) => info.id == WalletBase.idFor(name, getType()));
       final wallet = MoneroWallet(
         walletInfo: walletInfo,
+        unspentCoinsInfo: unspentCoinsInfoSource,
         password: password);
       final isValid = wallet.walletAddresses.validate();
 
@@ -125,13 +128,20 @@ class MoneroWalletService extends WalletService<
     } catch (e) {
       // TODO: Implement Exception for wallet list service.
 
-      if ((e.toString().contains('bad_alloc') ||
+      final bool isBadAlloc = e.toString().contains('bad_alloc') ||
           (e is WalletOpeningException &&
-              (e.message == 'std::bad_alloc' ||
-                  e.message.contains('bad_alloc')))) ||
-          (e.toString().contains('does not correspond') ||
-          (e is WalletOpeningException &&
-            e.message.contains('does not correspond')))) {
+              (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 is WalletOpeningException && e.message.contains('input_stream'));
+
+      if (isBadAlloc || doesNotCorrespond || isMissingCacheFilesIOS || isMissingCacheFilesAndroid) {
         await restoreOrResetWalletFiles(name);
         return openWallet(name, password);
       }
@@ -160,7 +170,10 @@ class MoneroWalletService extends WalletService<
       String currentName, String password, String newName) async {
     final currentWalletInfo = walletInfoSource.values.firstWhere(
         (info) => info.id == WalletBase.idFor(currentName, getType()));
-    final currentWallet = MoneroWallet(walletInfo: currentWalletInfo, password: password);
+    final currentWallet = MoneroWallet(
+        walletInfo: currentWalletInfo,
+        unspentCoinsInfo: unspentCoinsInfoSource,
+        password: password);
 
     await currentWallet.renameWalletFiles(newName);
 
@@ -186,6 +199,7 @@ class MoneroWalletService extends WalletService<
           spendKey: credentials.spendKey);
       final wallet = MoneroWallet(
         walletInfo: credentials.walletInfo!,
+        unspentCoinsInfo: unspentCoinsInfoSource,
         password: credentials.password!);
       await wallet.init();
 
@@ -209,6 +223,7 @@ class MoneroWalletService extends WalletService<
           restoreHeight: credentials.height!);
       final wallet = MoneroWallet(
         walletInfo: credentials.walletInfo!,
+        unspentCoinsInfo: unspentCoinsInfoSource,
         password: credentials.password!);
       await wallet.init();
 
diff --git a/cw_monero/macos/Classes/monero_api.cpp b/cw_monero/macos/Classes/monero_api.cpp
index e1cbb5b59..7185bf581 100644
--- a/cw_monero/macos/Classes/monero_api.cpp
+++ b/cw_monero/macos/Classes/monero_api.cpp
@@ -3,8 +3,10 @@
 #include <chrono>
 #include <functional>
 #include <iostream>
+#include <fstream>
 #include <unistd.h>
 #include <mutex>
+#include <list>
 #include "thread"
 #include "CwWalletListener.h"
 #if __APPLE__
@@ -135,7 +137,7 @@ extern "C"
         int8_t direction;
         int8_t isPending;
         uint32_t subaddrIndex;
-        
+
         char *hash;
         char *paymentId;
 
@@ -151,7 +153,7 @@ extern "C"
             std::set<uint32_t>::iterator it = subIndex.begin();
             subaddrIndex = *it;
             confirmations = transaction->confirmations();
-            datetime = static_cast<int64_t>(transaction->timestamp());            
+            datetime = static_cast<int64_t>(transaction->timestamp());
             direction = transaction->direction();
             isPending = static_cast<int8_t>(transaction->isPending());
             std::string *hash_str = new std::string(transaction->hash());
@@ -180,6 +182,62 @@ extern "C"
         }
     };
 
+    struct CoinsInfoRow
+    {
+        uint64_t blockHeight;
+        char *hash;
+        uint64_t internalOutputIndex;
+        uint64_t globalOutputIndex;
+        bool spent;
+        bool frozen;
+        uint64_t spentHeight;
+        uint64_t amount;
+        bool rct;
+        bool keyImageKnown;
+        uint64_t pkIndex;
+        uint32_t subaddrIndex;
+        uint32_t subaddrAccount;
+        char *address;
+        char *addressLabel;
+        char *keyImage;
+        uint64_t unlockTime;
+        bool unlocked;
+        char *pubKey;
+        bool coinbase;
+        char *description;
+
+        CoinsInfoRow(Monero::CoinsInfo *coinsInfo)
+        {
+            blockHeight = coinsInfo->blockHeight();
+             std::string *hash_str = new std::string(coinsInfo->hash());
+            hash = strdup(hash_str->c_str());
+            internalOutputIndex = coinsInfo->internalOutputIndex();
+            globalOutputIndex = coinsInfo->globalOutputIndex();
+            spent = coinsInfo->spent();
+            frozen = coinsInfo->frozen();
+            spentHeight = coinsInfo->spentHeight();
+            amount = coinsInfo->amount();
+            rct = coinsInfo->rct();
+            keyImageKnown = coinsInfo->keyImageKnown();
+            pkIndex = coinsInfo->pkIndex();
+            subaddrIndex = coinsInfo->subaddrIndex();
+            subaddrAccount = coinsInfo->subaddrAccount();
+            address =  strdup(coinsInfo->address().c_str()) ;
+            addressLabel = strdup(coinsInfo->addressLabel().c_str());
+            keyImage = strdup(coinsInfo->keyImage().c_str());
+            unlockTime = coinsInfo->unlockTime();
+            unlocked = coinsInfo->unlocked();
+            pubKey = strdup(coinsInfo->pubKey().c_str());
+            coinbase = coinsInfo->coinbase();
+            description = strdup(coinsInfo->description().c_str());
+        }
+
+        void setUnlocked(bool unlocked);
+
+    };
+
+    Monero::Coins *m_coins;
+
     Monero::Wallet *m_wallet;
     Monero::TransactionHistory *m_transaction_history;
     MoneroWalletListener *m_listener;
@@ -187,6 +245,7 @@ extern "C"
     Monero::SubaddressAccount *m_account;
     uint64_t m_last_known_wallet_height;
     uint64_t m_cached_syncing_blockchain_height = 0;
+    std::list<Monero::CoinsInfo*> m_coins_info;
     std::mutex store_lock;
     bool is_storing = false;
 
@@ -194,7 +253,7 @@ extern "C"
     {
         m_wallet = wallet;
         m_listener = nullptr;
-        
+
 
         if (wallet != nullptr)
         {
@@ -222,6 +281,17 @@ extern "C"
         {
             m_subaddress = nullptr;
         }
+
+        m_coins_info = std::list<Monero::CoinsInfo*>();
+
+        if (wallet != nullptr)
+        {
+            m_coins = wallet->coins();
+        }
+        else
+        {
+            m_coins = nullptr;
+        }
     }
 
     Monero::Wallet *get_current_wallet()
@@ -404,13 +474,14 @@ extern "C"
         return is_connected;
     }
 
-    bool setup_node(char *address, char *login, char *password, bool use_ssl, bool is_light_wallet, char *error)
+    bool setup_node(char *address, char *login, char *password, bool use_ssl, bool is_light_wallet, char *socksProxyAddress, char *error)
     {
         nice(19);
         Monero::Wallet *wallet = get_current_wallet();
-        
+
         std::string _login = "";
         std::string _password = "";
+        std::string _socksProxyAddress = "";
 
         if (login != nullptr)
         {
@@ -422,7 +493,12 @@ extern "C"
             _password = std::string(password);
         }
 
-        bool inited = wallet->init(std::string(address), 0, _login, _password, use_ssl, is_light_wallet);
+        if (socksProxyAddress != nullptr)
+                {
+                    _socksProxyAddress = std::string(socksProxyAddress);
+                }
+
+        bool inited = wallet->init(std::string(address), 0, _login, _password, use_ssl, is_light_wallet, _socksProxyAddress);
 
         if (!inited)
         {
@@ -479,10 +555,19 @@ extern "C"
     }
 
     bool transaction_create(char *address, char *payment_id, char *amount,
-                                              uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction)
+                            uint8_t priority_raw, uint32_t subaddr_account,
+                            char **preferred_inputs, uint32_t preferred_inputs_size,
+                            Utf8Box &error, PendingTransactionRaw &pendingTransaction)
     {
         nice(19);
-        
+
+        std::set<std::string> _preferred_inputs;
+
+        for (int i = 0; i < preferred_inputs_size; i++) {
+            _preferred_inputs.insert(std::string(*preferred_inputs));
+            preferred_inputs++;
+        }
+
         auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
         std::string _payment_id;
         Monero::PendingTransaction *transaction;
@@ -495,13 +580,13 @@ extern "C"
         if (amount != nullptr)
         {
             uint64_t _amount = Monero::Wallet::amountFromString(std::string(amount));
-            transaction = m_wallet->createTransaction(std::string(address), _payment_id, _amount, m_wallet->defaultMixin(), priority, subaddr_account);
+            transaction = m_wallet->createTransaction(std::string(address), _payment_id, _amount, m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
         }
         else
         {
-            transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional<uint64_t>(), m_wallet->defaultMixin(), priority, subaddr_account);
+            transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional<uint64_t>(), m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
         }
-        
+
         int status = transaction->status();
 
         if (status == Monero::PendingTransaction::Status::Status_Error || status == Monero::PendingTransaction::Status::Status_Critical)
@@ -519,7 +604,9 @@ extern "C"
     }
 
     bool transaction_create_mult_dest(char **addresses, char *payment_id, char **amounts, uint32_t size,
-                                                  uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction)
+                                      uint8_t priority_raw, uint32_t subaddr_account,
+                                      char **preferred_inputs, uint32_t preferred_inputs_size,
+                                      Utf8Box &error, PendingTransactionRaw &pendingTransaction)
     {
         nice(19);
 
@@ -533,6 +620,13 @@ extern "C"
             amounts++;
         }
 
+        std::set<std::string> _preferred_inputs;
+
+        for (int i = 0; i < preferred_inputs_size; i++) {
+            _preferred_inputs.insert(std::string(*preferred_inputs));
+            preferred_inputs++;
+        }
+
         auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
         std::string _payment_id;
         Monero::PendingTransaction *transaction;
@@ -792,6 +886,91 @@ extern "C"
         return m_wallet->trustedDaemon();
     }
 
+    CoinsInfoRow* coin(int index)
+    {
+        if (index >= 0 && index < m_coins_info.size()) {
+            std::list<Monero::CoinsInfo*>::iterator it = m_coins_info.begin();
+            std::advance(it, index);
+            Monero::CoinsInfo* element = *it;
+            std::cout << "Element at index " << index << ": " << element << std::endl;
+            return new CoinsInfoRow(element);
+        } else {
+            std::cout << "Invalid index." << std::endl;
+            return nullptr; // Return a default value (nullptr) for invalid index
+        }
+    }
+
+    void refresh_coins(uint32_t accountIndex)
+    {
+        m_coins_info.clear();
+
+        m_coins->refresh();
+        for (const auto i : m_coins->getAll()) {
+            if (i->subaddrAccount() == accountIndex && !(i->spent())) {
+                m_coins_info.push_back(i);
+            }
+        }
+    }
+
+    uint64_t coins_count()
+    {
+        return m_coins_info.size();
+    }
+
+    CoinsInfoRow** coins_from_account(uint32_t accountIndex)
+    {
+        std::vector<CoinsInfoRow*> matchingCoins;
+
+        for (int i = 0; i < coins_count(); i++) {
+            CoinsInfoRow* coinInfo = coin(i);
+            if (coinInfo->subaddrAccount == accountIndex) {
+                matchingCoins.push_back(coinInfo);
+            }
+        }
+
+        CoinsInfoRow** result = new CoinsInfoRow*[matchingCoins.size()];
+        std::copy(matchingCoins.begin(), matchingCoins.end(), result);
+        return result;
+    }
+
+    CoinsInfoRow** coins_from_txid(const char* txid, size_t* count)
+    {
+        std::vector<CoinsInfoRow*> matchingCoins;
+
+        for (int i = 0; i < coins_count(); i++) {
+            CoinsInfoRow* coinInfo = coin(i);
+            if (std::string(coinInfo->hash) == txid) {
+                matchingCoins.push_back(coinInfo);
+            }
+        }
+
+        *count = matchingCoins.size();
+        CoinsInfoRow** result = new CoinsInfoRow*[*count];
+        std::copy(matchingCoins.begin(), matchingCoins.end(), result);
+        return result;
+    }
+
+    CoinsInfoRow** coins_from_key_image(const char** keyimages, size_t keyimageCount, size_t* count)
+    {
+        std::vector<CoinsInfoRow*> matchingCoins;
+
+        for (int i = 0; i < coins_count(); i++) {
+            CoinsInfoRow* coinsInfoRow = coin(i);
+            for (size_t j = 0; j < keyimageCount; j++) {
+                if (coinsInfoRow->keyImageKnown && std::string(coinsInfoRow->keyImage) == keyimages[j]) {
+                    matchingCoins.push_back(coinsInfoRow);
+                    break;
+                }
+            }
+        }
+
+        *count = matchingCoins.size();
+        CoinsInfoRow** result = new CoinsInfoRow*[*count];
+        std::copy(matchingCoins.begin(), matchingCoins.end(), result);
+        return result;
+    }
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock
index 437184a7d..37e08e7ca 100644
--- a/cw_monero/pubspec.lock
+++ b/cw_monero/pubspec.lock
@@ -37,10 +37,10 @@ packages:
     dependency: transitive
     description:
       name: async
-      sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
+      sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
       url: "https://pub.dev"
     source: hosted
-    version: "2.10.0"
+    version: "2.11.0"
   boolean_selector:
     dependency: transitive
     description:
@@ -117,10 +117,10 @@ packages:
     dependency: transitive
     description:
       name: characters
-      sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
+      sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.1"
+    version: "1.3.0"
   checked_yaml:
     dependency: transitive
     description:
@@ -149,10 +149,10 @@ packages:
     dependency: transitive
     description:
       name: collection
-      sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
+      sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
       url: "https://pub.dev"
     source: hosted
-    version: "1.17.0"
+    version: "1.17.1"
   convert:
     dependency: transitive
     description:
@@ -286,10 +286,10 @@ packages:
     dependency: "direct main"
     description:
       name: http
-      sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
+      sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
       url: "https://pub.dev"
     source: hosted
-    version: "0.13.5"
+    version: "1.1.0"
   http_multi_server:
     dependency: transitive
     description:
@@ -310,10 +310,10 @@ packages:
     dependency: "direct main"
     description:
       name: intl
-      sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
+      sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
       url: "https://pub.dev"
     source: hosted
-    version: "0.17.0"
+    version: "0.18.1"
   io:
     dependency: transitive
     description:
@@ -326,10 +326,10 @@ packages:
     dependency: transitive
     description:
       name: js
-      sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
+      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
       url: "https://pub.dev"
     source: hosted
-    version: "0.6.5"
+    version: "0.6.7"
   json_annotation:
     dependency: transitive
     description:
@@ -350,10 +350,10 @@ packages:
     dependency: transitive
     description:
       name: matcher
-      sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
+      sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
       url: "https://pub.dev"
     source: hosted
-    version: "0.12.13"
+    version: "0.12.15"
   material_color_utilities:
     dependency: transitive
     description:
@@ -366,10 +366,10 @@ packages:
     dependency: transitive
     description:
       name: meta
-      sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
+      sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
       url: "https://pub.dev"
     source: hosted
-    version: "1.8.0"
+    version: "1.9.1"
   mime:
     dependency: transitive
     description:
@@ -406,10 +406,10 @@ packages:
     dependency: transitive
     description:
       name: path
-      sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
+      sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
       url: "https://pub.dev"
     source: hosted
-    version: "1.8.2"
+    version: "1.8.3"
   path_provider:
     dependency: "direct main"
     description:
@@ -603,10 +603,10 @@ packages:
     dependency: transitive
     description:
       name: test_api
-      sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
+      sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
       url: "https://pub.dev"
     source: hosted
-    version: "0.4.16"
+    version: "0.5.1"
   timing:
     dependency: transitive
     description:
@@ -672,5 +672,5 @@ packages:
     source: hosted
     version: "3.1.1"
 sdks:
-  dart: ">=2.19.0 <3.0.0"
+  dart: ">=3.0.0 <4.0.0"
   flutter: ">=3.0.0"
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index f13c68629..6f441c587 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -174,12 +174,12 @@ DEPENDENCIES:
   - in_app_review (from `.symlinks/plugins/in_app_review/ios`)
   - local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`)
   - package_info (from `.symlinks/plugins/package_info/ios`)
-  - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
+  - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
   - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
   - platform_device_id (from `.symlinks/plugins/platform_device_id/ios`)
   - 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/ios`)
+  - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
   - uni_links (from `.symlinks/plugins/uni_links/ios`)
   - UnstoppableDomainsResolution (~> 4.0.0)
   - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
@@ -236,7 +236,7 @@ EXTERNAL SOURCES:
   package_info:
     :path: ".symlinks/plugins/package_info/ios"
   path_provider_foundation:
-    :path: ".symlinks/plugins/path_provider_foundation/ios"
+    :path: ".symlinks/plugins/path_provider_foundation/darwin"
   permission_handler_apple:
     :path: ".symlinks/plugins/permission_handler_apple/ios"
   platform_device_id:
@@ -246,7 +246,7 @@ EXTERNAL SOURCES:
   share_plus:
     :path: ".symlinks/plugins/share_plus/ios"
   shared_preferences_foundation:
-    :path: ".symlinks/plugins/shared_preferences_foundation/ios"
+    :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
   uni_links:
     :path: ".symlinks/plugins/uni_links/ios"
   url_launcher_ios:
diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart
index e1c1e137c..f03e47460 100644
--- a/lib/bitcoin/cw_bitcoin.dart
+++ b/lib/bitcoin/cw_bitcoin.dart
@@ -129,7 +129,8 @@ class CWBitcoin extends Bitcoin {
 				bitcoinUnspent.address.address,
 				bitcoinUnspent.hash,
 				bitcoinUnspent.value,
-				bitcoinUnspent.vout))
+				bitcoinUnspent.vout,
+				null))
 			.toList();
 	}
 
@@ -161,4 +162,4 @@ class CWBitcoin extends Bitcoin {
   @override
   TransactionPriority getLitecoinTransactionPrioritySlow()
     => LitecoinTransactionPriority.slow;
-}
\ No newline at end of file
+}
diff --git a/lib/buy/onramper/onramper_buy_provider.dart b/lib/buy/onramper/onramper_buy_provider.dart
index 68be59f4e..cf4cbd124 100644
--- a/lib/buy/onramper/onramper_buy_provider.dart
+++ b/lib/buy/onramper/onramper_buy_provider.dart
@@ -1,8 +1,10 @@
 import 'package:cake_wallet/.secrets.g.dart' as secrets;
+import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/store/settings_store.dart';
-import 'package:cake_wallet/themes/theme_base.dart';
+import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/wallet_base.dart';
+import 'package:flutter/material.dart';
 
 class OnRamperBuyProvider {
   OnRamperBuyProvider({required SettingsStore settingsStore, required WalletBase wallet})
@@ -27,7 +29,11 @@ class OnRamperBuyProvider {
     }
   }
 
-  Uri requestUrl() {
+  String getColorStr(Color color) {
+    return color.value.toRadixString(16).replaceAll(RegExp(r'^ff'), "");
+  }
+
+  Uri requestUrl(BuildContext context) {
     String primaryColor,
         secondaryColor,
         primaryTextColor,
@@ -35,31 +41,16 @@ class OnRamperBuyProvider {
         containerColor,
         cardColor;
 
-    switch (_settingsStore.currentTheme.type) {
-      case ThemeType.bright:
-        primaryColor = '815dfbff';
-        secondaryColor = 'ffffff';
-        primaryTextColor = '141519';
-        secondaryTextColor = '6b6f80';
-        containerColor = 'ffffff';
-        cardColor = 'f2f0faff';
-        break;
-      case ThemeType.light:
-        primaryColor = '2194ffff';
-        secondaryColor = 'ffffff';
-        primaryTextColor = '141519';
-        secondaryTextColor = '6b6f80';
-        containerColor = 'ffffff';
-        cardColor = 'e5f7ff';
-        break;
-      case ThemeType.dark:
-        primaryColor = '456effff';
-        secondaryColor = '1b2747ff';
-        primaryTextColor = 'ffffff';
-        secondaryTextColor = 'ffffff';
-        containerColor = '19233C';
-        cardColor = '232f4fff';
-        break;
+    primaryColor = getColorStr(Theme.of(context).primaryColor);
+    secondaryColor = getColorStr(Theme.of(context).colorScheme.background);
+    primaryTextColor = getColorStr(Theme.of(context).extension<CakeTextTheme>()!.titleColor);
+    secondaryTextColor =
+        getColorStr(Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor);
+    containerColor = getColorStr(Theme.of(context).colorScheme.background);
+    cardColor = getColorStr(Theme.of(context).cardColor);
+
+    if (_settingsStore.currentTheme.title == S.current.high_contrast_theme) {
+      cardColor = getColorStr(Colors.white);
     }
 
     final networkName = _wallet.currency.fullName?.toUpperCase().replaceAll(" ", "");
diff --git a/lib/core/backup_service.dart b/lib/core/backup_service.dart
index 03581f156..6e7bd67da 100644
--- a/lib/core/backup_service.dart
+++ b/lib/core/backup_service.dart
@@ -246,6 +246,7 @@ class BackupService {
     final useEtherscan = data[PreferencesKey.useEtherscan] as bool?;
     final syncAll = data[PreferencesKey.syncAllKey] as bool?;
     final syncMode = data[PreferencesKey.syncModeKey] as int?;
+    final autoGenerateSubaddressStatus = data[PreferencesKey.autoGenerateSubaddressStatusKey] as int?;
 
     await _sharedPreferences.setString(PreferencesKey.currentWalletName, currentWalletName);
 
@@ -296,6 +297,9 @@ class BackupService {
 
     if (fiatApiMode != null)
       await _sharedPreferences.setInt(PreferencesKey.currentFiatApiModeKey, fiatApiMode);
+    if (autoGenerateSubaddressStatus != null)
+      await _sharedPreferences.setInt(PreferencesKey.autoGenerateSubaddressStatusKey,
+          autoGenerateSubaddressStatus);
 
     if (currentPinLength != null)
       await _sharedPreferences.setInt(PreferencesKey.currentPinLength, currentPinLength);
@@ -523,6 +527,8 @@ class BackupService {
           _sharedPreferences.getInt(PreferencesKey.syncModeKey),
       PreferencesKey.syncAllKey:
           _sharedPreferences.getBool(PreferencesKey.syncAllKey),
+      PreferencesKey.autoGenerateSubaddressStatusKey:
+          _sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey),
     };
 
     return json.encode(preferences);
diff --git a/lib/core/fiat_conversion_service.dart b/lib/core/fiat_conversion_service.dart
index 9690c430a..479aa3b82 100644
--- a/lib/core/fiat_conversion_service.dart
+++ b/lib/core/fiat_conversion_service.dart
@@ -21,7 +21,7 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
     'key': secrets.fiatApiKey,
   };
 
-  double price = 0.0;
+  num price = 0.0;
 
   try {
     late final Uri uri;
@@ -41,12 +41,12 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
     final results = responseJSON['results'] as Map<String, dynamic>;
 
     if (results.isNotEmpty) {
-      price = results.values.first as double;
+      price = results.values.first as num;
     }
 
-    return price;
+    return price.toDouble();
   } catch (e) {
-    return price;
+    return price.toDouble();
   }
 }
 
diff --git a/lib/core/wallet_change_listener_view_model.dart b/lib/core/wallet_change_listener_view_model.dart
new file mode 100644
index 000000000..6735afee5
--- /dev/null
+++ b/lib/core/wallet_change_listener_view_model.dart
@@ -0,0 +1,30 @@
+import 'package:cw_core/balance.dart';
+import 'package:cw_core/transaction_history.dart';
+import 'package:cw_core/transaction_info.dart';
+import 'package:mobx/mobx.dart';
+import 'package:cw_core/wallet_base.dart';
+import 'package:cake_wallet/store/app_store.dart';
+
+part 'wallet_change_listener_view_model.g.dart';
+
+class WalletChangeListenerViewModel = WalletChangeListenerViewModelBase
+    with _$WalletChangeListenerViewModel;
+
+abstract class WalletChangeListenerViewModelBase with Store {
+  WalletChangeListenerViewModelBase({
+    required AppStore appStore,
+  }) : _wallet = appStore.wallet! {
+    reaction((_) => appStore.wallet, (WalletBase? wallet) {
+      _wallet = wallet!;
+      onWalletChange(wallet);
+    });
+  }
+
+  void onWalletChange(WalletBase wallet) {}
+
+  @observable
+  WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> _wallet;
+  @computed
+  WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> get wallet =>
+      _wallet;
+}
diff --git a/lib/di.dart b/lib/di.dart
index 1c81f33fc..be6f9f4e3 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -9,6 +9,7 @@ import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
 import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart';
 import 'package:cake_wallet/core/yat_service.dart';
 import 'package:cake_wallet/entities/background_tasks.dart';
+import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
 import 'package:cake_wallet/entities/exchange_api_mode.dart';
 import 'package:cake_wallet/entities/receive_page_option.dart';
 import 'package:cake_wallet/ethereum/ethereum.dart';
@@ -183,8 +184,6 @@ import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 import 'package:cake_wallet/core/secure_storage.dart';
-import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
-import 'package:cake_wallet/view_model/wallet_restoration_from_keys_vm.dart';
 import 'package:cake_wallet/core/wallet_creation_service.dart';
 import 'package:cake_wallet/store/app_store.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -225,10 +224,10 @@ late Box<Template> _templates;
 late Box<ExchangeTemplate> _exchangeTemplates;
 late Box<TransactionDescription> _transactionDescriptionBox;
 late Box<Order> _ordersSource;
-late Box<UnspentCoinsInfo>? _unspentCoinsInfoSource;
+late Box<UnspentCoinsInfo> _unspentCoinsInfoSource;
 late Box<AnonpayInvoiceInfo> _anonpayInvoiceInfoSource;
 
-Future setup({
+Future<void> setup({
   required Box<WalletInfo> walletInfoSource,
   required Box<Node> nodeSource,
   required Box<Contact> contactSource,
@@ -237,7 +236,7 @@ Future setup({
   required Box<ExchangeTemplate> exchangeTemplates,
   required Box<TransactionDescription> transactionDescriptionBox,
   required Box<Order> ordersSource,
-  Box<UnspentCoinsInfo>? unspentCoinsInfoSource,
+  required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
   required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource,
 }) async {
   _walletInfoSource = walletInfoSource;
@@ -254,7 +253,6 @@ Future setup({
   if (!_isSetupFinished) {
     getIt.registerSingletonAsync<SharedPreferences>(() => SharedPreferences.getInstance());
   }
-
   if (!_isSetupFinished) {
     getIt.registerFactory(() => BackgroundTasks());
   }
@@ -326,25 +324,6 @@ Future setup({
       getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
       type: type));
 
-  getIt.registerFactoryParam<WalletRestorationFromSeedVM, List, void>((args, _) {
-    final type = args.first as WalletType;
-    final language = args[1] as String;
-    final mnemonic = args[2] as String;
-
-    return WalletRestorationFromSeedVM(
-        getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
-        type: type, language: language, seed: mnemonic);
-  });
-
-  getIt.registerFactoryParam<WalletRestorationFromKeysVM, List, void>((args, _) {
-    final type = args.first as WalletType;
-    final language = args[1] as String;
-
-    return WalletRestorationFromKeysVM(
-        getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
-        type: type, language: language);
-  });
-
   getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) {
     return WalletRestorationFromQRVM(getIt.get<AppStore>(),
         getIt.get<WalletCreationService>(param1: type), _walletInfoSource, type);
@@ -550,8 +529,7 @@ Future setup({
 
   getIt.registerFactory<SendViewModel>(
     () => SendViewModel(
-      getIt.get<AppStore>().wallet!,
-      getIt.get<AppStore>().settingsStore,
+      getIt.get<AppStore>(),
       getIt.get<SendTemplateViewModel>(),
       getIt.get<FiatConversionStore>(),
       getIt.get<BalanceViewModel>(),
@@ -729,7 +707,7 @@ Future setup({
       ));
 
   getIt.registerFactory(() => ExchangeViewModel(
-      getIt.get<AppStore>().wallet!,
+      getIt.get<AppStore>(),
       _tradesSource,
       getIt.get<ExchangeTemplateStore>(),
       getIt.get<TradesStore>(),
@@ -758,7 +736,7 @@ Future setup({
       case WalletType.haven:
         return haven!.createHavenWalletService(_walletInfoSource);
       case WalletType.monero:
-        return monero!.createMoneroWalletService(_walletInfoSource);
+        return monero!.createMoneroWalletService(_walletInfoSource, _unspentCoinsInfoSource);
       case WalletType.bitcoin:
         return bitcoin!.createBitcoinWalletService(
             _walletInfoSource, _unspentCoinsInfoSource!,
diff --git a/lib/entities/auto_generate_subaddress_status.dart b/lib/entities/auto_generate_subaddress_status.dart
new file mode 100644
index 000000000..6d6cc406c
--- /dev/null
+++ b/lib/entities/auto_generate_subaddress_status.dart
@@ -0,0 +1,13 @@
+
+enum AutoGenerateSubaddressStatus { 
+  initialized(1), 
+  enabled(2), 
+  disabled(3);
+
+  const AutoGenerateSubaddressStatus(this.value);
+  final int value;
+
+  static AutoGenerateSubaddressStatus deserialize({required int raw}) => 
+      AutoGenerateSubaddressStatus.values.firstWhere((e) => e.value == raw);
+  
+}
\ No newline at end of file
diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart
index 42b6d5324..a76376755 100644
--- a/lib/entities/default_settings_migration.dart
+++ b/lib/entities/default_settings_migration.dart
@@ -1,12 +1,11 @@
-import 'dart:io' show File, Platform;
+import 'dart:io' show Directory, File, Platform;
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
 import 'package:cake_wallet/entities/exchange_api_mode.dart';
 import 'package:cw_core/pathForWallet.dart';
 import 'package:cake_wallet/entities/secret_store_key.dart';
-import 'package:flutter/foundation.dart';
 import 'package:cake_wallet/core/secure_storage.dart';
 import 'package:hive/hive.dart';
-import 'package:share_plus/share_plus.dart';
+import 'package:path_provider/path_provider.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 import 'package:cake_wallet/entities/preferences_key.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -28,7 +27,7 @@ const cakeWalletLitecoinElectrumUri = 'ltc-electrum.cakewallet.com:50002';
 const havenDefaultNodeUri = 'nodes.havenprotocol.org:443';
 const ethereumDefaultNodeUri = 'ethereum.publicnode.com';
 
-Future defaultSettingsMigration(
+Future<void> defaultSettingsMigration(
     {required int version,
     required SharedPreferences sharedPreferences,
     required SecureStorage secureStorage,
@@ -43,6 +42,8 @@ Future defaultSettingsMigration(
   // check current nodes for nullability regardless of the version
   await checkCurrentNodes(nodes, sharedPreferences);
 
+  await _validateWalletInfoBoxData(walletInfoSource);
+
   final isNewInstall = sharedPreferences
       .getInt(PreferencesKey.currentDefaultSettingsMigrationVersion) == null;
 
@@ -179,6 +180,66 @@ Future defaultSettingsMigration(
       PreferencesKey.currentDefaultSettingsMigrationVersion, version);
 }
 
+Future<void> _validateWalletInfoBoxData(Box<WalletInfo> walletInfoSource) async {
+  final root = await getApplicationDocumentsDirectory();
+
+  for (var type in WalletType.values) {
+    if (type == WalletType.none) {
+      continue;
+    }
+
+    String prefix = walletTypeToString(type).toLowerCase();
+    Directory walletsDir = Directory('${root.path}/wallets/$prefix/');
+
+    if (!walletsDir.existsSync()) {
+      continue;
+    }
+
+    List<String> walletNames = walletsDir.listSync().map((e) => e.path.split("/").last).toList();
+
+    for (var name in walletNames) {
+      final dir = Directory(await pathForWalletDir(name: name, type: type));
+
+      final walletFiles = dir.listSync();
+      final hasCacheFile = walletFiles.any((element) => element.path.contains("$name/$name"));
+
+      if (!hasCacheFile) {
+        continue;
+      }
+
+      if (type == WalletType.monero || type == WalletType.haven) {
+        final hasKeysFile = walletFiles.any((element) => element.path.contains(".keys"));
+
+        if (!hasKeysFile) {
+          continue;
+        }
+      }
+
+      final id = prefix + '_' + name;
+      final exist = walletInfoSource.values.any((el) => el.id == id);
+
+      if (exist) {
+        continue;
+      }
+
+      final walletInfo = WalletInfo.external(
+        id: id,
+        type: type,
+        name: name,
+        isRecovery: true,
+        restoreHeight: 0,
+        date: DateTime.now(),
+        dirPath: dir.path,
+        path: '${dir.path}/$name',
+        address: '',
+        showIntroCakePayCard: false,
+      );
+
+      walletInfoSource.add(walletInfo);
+    }
+  }
+}
+
 Future<void> validateBitcoinSavedTransactionPriority(SharedPreferences sharedPreferences) async {
   if (bitcoin == null) {
     return;
@@ -226,7 +287,7 @@ Future<void> changeMoneroCurrentNodeToDefault(
     {required SharedPreferences sharedPreferences,
     required Box<Node> nodes}) async {
   final node = getMoneroDefaultNode(nodes: nodes);
-  final nodeId = node?.key as int ?? 0; // 0 - England
+  final nodeId = node.key as int? ?? 0; // 0 - England
 
   await sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, nodeId);
 }
@@ -279,7 +340,7 @@ Future<void> changeBitcoinCurrentElectrumServerToDefault(
     {required SharedPreferences sharedPreferences,
     required Box<Node> nodes}) async {
   final server = getBitcoinDefaultElectrumServer(nodes: nodes);
-  final serverId = server?.key as int ?? 0;
+  final serverId = server?.key as int? ?? 0;
 
   await sharedPreferences.setInt(PreferencesKey.currentBitcoinElectrumSererIdKey, serverId);
 }
@@ -288,7 +349,7 @@ Future<void> changeLitecoinCurrentElectrumServerToDefault(
     {required SharedPreferences sharedPreferences,
     required Box<Node> nodes}) async {
   final server = getLitecoinDefaultElectrumServer(nodes: nodes);
-  final serverId = server?.key as int ?? 0;
+  final serverId = server?.key as int? ?? 0;
 
   await sharedPreferences.setInt(PreferencesKey.currentLitecoinElectrumSererIdKey, serverId);
 }
@@ -297,7 +358,7 @@ Future<void> changeHavenCurrentNodeToDefault(
     {required SharedPreferences sharedPreferences,
     required Box<Node> nodes}) async {
   final node = getHavenDefaultNode(nodes: nodes);
-  final nodeId = node?.key as int ?? 0;
+  final nodeId = node?.key as int? ?? 0;
 
   await sharedPreferences.setInt(PreferencesKey.currentHavenNodeIdKey, nodeId);
 }
diff --git a/lib/entities/main_actions.dart b/lib/entities/main_actions.dart
index 912269d8e..2d91983d4 100644
--- a/lib/entities/main_actions.dart
+++ b/lib/entities/main_actions.dart
@@ -49,7 +49,7 @@ class MainActions {
         case WalletType.ethereum:
         case WalletType.monero:
           if (viewModel.isEnabledBuyAction) {
-            final uri = getIt.get<OnRamperBuyProvider>().requestUrl();
+            final uri = getIt.get<OnRamperBuyProvider>().requestUrl(context);
             if (DeviceInfo.instance.isMobile) {
               Navigator.of(context)
                   .pushNamed(Routes.webViewPage, arguments: [S.of(context).buy, uri]);
diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart
index c50629c1b..7b4d3d0dc 100644
--- a/lib/entities/preferences_key.dart
+++ b/lib/entities/preferences_key.dart
@@ -50,6 +50,7 @@ class PreferencesKey {
       '${PreferencesKey.moneroWalletPasswordUpdateV1Base}_${name}';
 
   static const exchangeProvidersSelection = 'exchange-providers-selection';
+  static const autoGenerateSubaddressStatusKey = 'auto_generate_subaddress_status';
   static const clearnetDonationLink = 'clearnet_donation_link';
   static const onionDonationLink = 'onion_donation_link';
   static const lastSeenAppVersion = 'last_seen_app_version';
diff --git a/lib/entities/unspent_transaction_output.dart b/lib/entities/unspent_transaction_output.dart
new file mode 100644
index 000000000..6827f4c01
--- /dev/null
+++ b/lib/entities/unspent_transaction_output.dart
@@ -0,0 +1,18 @@
+class Unspent {
+  Unspent(this.address, this.hash, this.value, this.vout, this.keyImage)
+      : isSending = true,
+        isFrozen = false,
+        note = '';
+
+  final String address;
+  final String hash;
+  final int value;
+  final int vout;
+  final String? keyImage;
+
+  bool isSending;
+  bool isFrozen;
+  String note;
+
+  bool get isP2wpkh => address.startsWith('bc') || address.startsWith('ltc');
+}
diff --git a/lib/ethereum/cw_ethereum.dart b/lib/ethereum/cw_ethereum.dart
index 3c819ebc9..cb13b30d2 100644
--- a/lib/ethereum/cw_ethereum.dart
+++ b/lib/ethereum/cw_ethereum.dart
@@ -23,6 +23,14 @@ class CWEthereum extends Ethereum {
   }) =>
       EthereumRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
 
+  @override
+  WalletCredentials createEthereumRestoreWalletFromPrivateKey({
+    required String name,
+    required String privateKey,
+    required String password,
+  }) =>
+      EthereumRestoreWalletFromPrivateKey(name: name, password: password, privateKey: privateKey);
+
   @override
   String getAddress(WalletBase wallet) => (wallet as EthereumWallet).walletAddresses.address;
 
diff --git a/lib/exchange/changenow/changenow_exchange_provider.dart b/lib/exchange/changenow/changenow_exchange_provider.dart
index a3a70db1f..da4e7eccb 100644
--- a/lib/exchange/changenow/changenow_exchange_provider.dart
+++ b/lib/exchange/changenow/changenow_exchange_provider.dart
@@ -68,14 +68,12 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
       required CryptoCurrency to,
       required bool isFixedRateMode}) async {
     final headers = {apiHeaderKey: apiKey};
-    final normalizedFrom = normalizeCryptoCurrency(from);
-    final normalizedTo = normalizeCryptoCurrency(to);
     final flow = getFlow(isFixedRateMode);
     final params = <String, String>{
-      'fromCurrency': normalizedFrom,
-      'toCurrency': normalizedTo,
-      'fromNetwork': networkFor(from),
-      'toNetwork': networkFor(to),
+      'fromCurrency': _normalizeCurrency(from),
+      'toCurrency': _normalizeCurrency(to),
+      'fromNetwork': _networkFor(from),
+      'toNetwork': _networkFor(to),
       'flow': flow
     };
     final uri = Uri.https(apiAuthority, rangePath, params);
@@ -112,10 +110,10 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
     final flow = getFlow(isFixedRateMode);
     final type = isFixedRateMode ? 'reverse' : 'direct';
     final body = <String, dynamic>{
-      'fromCurrency': normalizeCryptoCurrency(_request.from),
-      'toCurrency': normalizeCryptoCurrency(_request.to),
-      'fromNetwork': networkFor(_request.from),
-      'toNetwork': networkFor(_request.to),
+      'fromCurrency': _normalizeCurrency(_request.from),
+      'toCurrency':  _normalizeCurrency(_request.to),
+      'fromNetwork': _networkFor(_request.from),
+      'toNetwork': _networkFor(_request.to),
       if (!isFixedRateMode) 'fromAmount': _request.fromAmount,
       if (isFixedRateMode) 'toAmount': _request.toAmount,
       'address': _request.address,
@@ -241,10 +239,10 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
       final type = isReverse ? 'reverse' : 'direct';
       final flow = getFlow(isFixedRateMode);
       final params = <String, String>{
-        'fromCurrency': normalizeCryptoCurrency(from),
-        'toCurrency': normalizeCryptoCurrency(to),
-        'fromNetwork': networkFor(from),
-        'toNetwork': networkFor(to),
+        'fromCurrency': _normalizeCurrency(from),
+        'toCurrency': _normalizeCurrency(to),
+        'fromNetwork': _networkFor(from),
+        'toNetwork': _networkFor(to),
         'type': type,
         'flow': flow
       };
@@ -273,25 +271,34 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
     }
   }
 
-  String networkFor(CryptoCurrency currency) {
+  String _networkFor(CryptoCurrency currency) {
     switch (currency) {
       case CryptoCurrency.usdt:
-        return CryptoCurrency.btc.title.toLowerCase();
+        return 'btc';
       default:
-        return currency.tag != null ? currency.tag!.toLowerCase() : currency.title.toLowerCase();
+        return currency.tag != null ? _normalizeTag(currency.tag!) : currency.title.toLowerCase();
     }
   }
-}
 
-String normalizeCryptoCurrency(CryptoCurrency currency) {
-  switch (currency) {
-    case CryptoCurrency.zec:
-      return 'zec';
-    case CryptoCurrency.usdcpoly:
-      return 'usdcmatic';
-    case CryptoCurrency.maticpoly:
-      return 'maticmainnet';
-    default:
-      return currency.title.toLowerCase();
+  String _normalizeCurrency(CryptoCurrency currency) {
+    switch (currency) {
+      case CryptoCurrency.zec:
+        return 'zec';
+      default:
+        return currency.title.toLowerCase();
+    }
   }
-}
+
+  String _normalizeTag(String tag) {
+    switch (tag) {
+      case 'POLY':
+        return 'matic';
+      case 'LN':
+        return 'lightning';
+      case 'AVAXC':
+        return 'cchain';
+      default:
+        return tag.toLowerCase();
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/exchange/sideshift/sideshift_exchange_provider.dart b/lib/exchange/sideshift/sideshift_exchange_provider.dart
index a5b0c990f..884899e54 100644
--- a/lib/exchange/sideshift/sideshift_exchange_provider.dart
+++ b/lib/exchange/sideshift/sideshift_exchange_provider.dart
@@ -28,7 +28,6 @@ class SideShiftExchangeProvider extends ExchangeProvider {
     CryptoCurrency.xhv,
     CryptoCurrency.dcr,
     CryptoCurrency.kmd,
-    CryptoCurrency.mkr,
     CryptoCurrency.oxt,
     CryptoCurrency.pivx,
     CryptoCurrency.rune,
diff --git a/lib/exchange/trocador/trocador_exchange_provider.dart b/lib/exchange/trocador/trocador_exchange_provider.dart
index fb6109bdf..b42291ed7 100644
--- a/lib/exchange/trocador/trocador_exchange_provider.dart
+++ b/lib/exchange/trocador/trocador_exchange_provider.dart
@@ -20,7 +20,6 @@ class TrocadorExchangeProvider extends ExchangeProvider {
   bool useTorOnly;
 
   static const List<CryptoCurrency> _notSupported = [
-    CryptoCurrency.scrt,
     CryptoCurrency.stx,
     CryptoCurrency.zaddr,
   ];
@@ -60,8 +59,8 @@ class TrocadorExchangeProvider extends ExchangeProvider {
   }) async {
     final params = <String, String>{
       'api_key': apiKey,
-      'ticker_from': request.from.title.toLowerCase(),
-      'ticker_to': request.to.title.toLowerCase(),
+      'ticker_from': _normalizeCurrency(request.from),
+      'ticker_to': _normalizeCurrency(request.to),
       'network_from': _networkFor(request.from),
       'network_to': _networkFor(request.to),
       'payment': isFixedRateMode ? 'True' : 'False',
@@ -137,7 +136,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
       required bool isFixedRateMode}) async {
     final params = <String, String>{
       'api_key': apiKey,
-      'ticker': from.title.toLowerCase(),
+      'ticker': _normalizeCurrency(from),
       'name': from.name,
     };
 
@@ -177,8 +176,8 @@ class TrocadorExchangeProvider extends ExchangeProvider {
 
       final params = <String, String>{
         'api_key': apiKey,
-        'ticker_from': from.title.toLowerCase(),
-        'ticker_to': to.title.toLowerCase(),
+        'ticker_from': _normalizeCurrency(from),
+        'ticker_to': _normalizeCurrency(to),
         'network_from': _networkFor(from),
         'network_to': _networkFor(to),
         if (!isFixedRateMode) 'amount_from': amount.toString(),
@@ -279,6 +278,15 @@ class TrocadorExchangeProvider extends ExchangeProvider {
     }
   }
 
+  String _normalizeCurrency(CryptoCurrency currency) {
+    switch (currency) {
+      case CryptoCurrency.zec:
+        return 'zec';
+      default:
+        return currency.title.toLowerCase();
+    }
+  }
+
   String _normalizeTag(String tag) {
     switch (tag) {
       case 'ETH':
diff --git a/lib/main.dart b/lib/main.dart
index aa11fa97e..6b7669d6e 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -6,9 +6,10 @@ import 'package:cake_wallet/buy/order.dart';
 import 'package:cake_wallet/locales/locale.dart';
 import 'package:cake_wallet/store/yat/yat_store.dart';
 import 'package:cake_wallet/utils/exception_handler.dart';
+import 'package:cw_core/address_info.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
 import 'package:cw_core/root_dir.dart';
-import 'package:cake_wallet/utils/responsive_layout_util.dart';
+import 'package:cw_core/hive_type_ids.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
@@ -40,6 +41,7 @@ import 'package:uni_links/uni_links.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cake_wallet/monero/monero.dart';
 import 'package:cake_wallet/wallet_type_utils.dart';
+import 'package:cw_core/cake_hive.dart';
 
 final navigatorKey = GlobalKey<NavigatorState>();
 final rootKey = GlobalKey<RootState>();
@@ -58,7 +60,8 @@ Future<void> main() async {
 
       return true;
     };
-    await Hive.close();
+
+    await CakeHive.close();
 
     await initializeAppConfigs();
 
@@ -71,74 +74,74 @@ Future<void> main() async {
 Future<void> initializeAppConfigs() async {
   setRootDirFromEnv();
   final appDir = await getAppDir();
-  Hive.init(appDir.path);
+  CakeHive.init(appDir.path);
 
-  if (!Hive.isAdapterRegistered(Contact.typeId)) {
-    Hive.registerAdapter(ContactAdapter());
+  if (!CakeHive.isAdapterRegistered(Contact.typeId)) {
+    CakeHive.registerAdapter(ContactAdapter());
   }
 
-  if (!Hive.isAdapterRegistered(Node.typeId)) {
-    Hive.registerAdapter(NodeAdapter());
+  if (!CakeHive.isAdapterRegistered(Node.typeId)) {
+    CakeHive.registerAdapter(NodeAdapter());
   }
 
-  if (!Hive.isAdapterRegistered(TransactionDescription.typeId)) {
-    Hive.registerAdapter(TransactionDescriptionAdapter());
+  if (!CakeHive.isAdapterRegistered(TransactionDescription.typeId)) {
+    CakeHive.registerAdapter(TransactionDescriptionAdapter());
   }
 
-  if (!Hive.isAdapterRegistered(Trade.typeId)) {
-    Hive.registerAdapter(TradeAdapter());
+  if (!CakeHive.isAdapterRegistered(Trade.typeId)) {
+    CakeHive.registerAdapter(TradeAdapter());
   }
 
-  if (!Hive.isAdapterRegistered(WalletInfo.typeId)) {
-    Hive.registerAdapter(WalletInfoAdapter());
+  if (!CakeHive.isAdapterRegistered(AddressInfo.typeId)) {
+    CakeHive.registerAdapter(AddressInfoAdapter());
   }
 
-  if (!Hive.isAdapterRegistered(walletTypeTypeId)) {
-    Hive.registerAdapter(WalletTypeAdapter());
+  if (!CakeHive.isAdapterRegistered(WalletInfo.typeId)) {
+    CakeHive.registerAdapter(WalletInfoAdapter());
   }
 
-  if (!Hive.isAdapterRegistered(Template.typeId)) {
-    Hive.registerAdapter(TemplateAdapter());
+  if (!CakeHive.isAdapterRegistered(WALLET_TYPE_TYPE_ID)) {
+    CakeHive.registerAdapter(WalletTypeAdapter());
   }
 
-  if (!Hive.isAdapterRegistered(ExchangeTemplate.typeId)) {
-    Hive.registerAdapter(ExchangeTemplateAdapter());
+  if (!CakeHive.isAdapterRegistered(Template.typeId)) {
+    CakeHive.registerAdapter(TemplateAdapter());
   }
 
-  if (!Hive.isAdapterRegistered(Order.typeId)) {
-    Hive.registerAdapter(OrderAdapter());
+  if (!CakeHive.isAdapterRegistered(ExchangeTemplate.typeId)) {
+    CakeHive.registerAdapter(ExchangeTemplateAdapter());
   }
 
-  if (!isMoneroOnly && !Hive.isAdapterRegistered(UnspentCoinsInfo.typeId)) {
-    Hive.registerAdapter(UnspentCoinsInfoAdapter());
+  if (!CakeHive.isAdapterRegistered(Order.typeId)) {
+    CakeHive.registerAdapter(OrderAdapter());
   }
 
-  if (!Hive.isAdapterRegistered(AnonpayInvoiceInfo.typeId)) {
-    Hive.registerAdapter(AnonpayInvoiceInfoAdapter());
+  if (!isMoneroOnly && !CakeHive.isAdapterRegistered(UnspentCoinsInfo.typeId)) {
+    CakeHive.registerAdapter(UnspentCoinsInfoAdapter());
   }
 
-    final secureStorage = secureStorageShared;
-    final transactionDescriptionsBoxKey =
-        await getEncryptionKey(secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
-    final tradesBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Trade.boxKey);
-    final ordersBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Order.boxKey);
-    final contacts = await Hive.openBox<Contact>(Contact.boxName);
-    final nodes = await Hive.openBox<Node>(Node.boxName);
-    final transactionDescriptions = await Hive.openBox<TransactionDescription>(
-        TransactionDescription.boxName,
-        encryptionKey: transactionDescriptionsBoxKey);
-    final trades = await Hive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
-    final orders = await Hive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
-    final walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
-    final templates = await Hive.openBox<Template>(Template.boxName);
-    final exchangeTemplates = await Hive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
-    final anonpayInvoiceInfo = await Hive.openBox<AnonpayInvoiceInfo>(AnonpayInvoiceInfo.boxName);
-    Box<UnspentCoinsInfo>? unspentCoinsInfoSource;
-
-  if (!isMoneroOnly) {
-    unspentCoinsInfoSource = await Hive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
+  if (!CakeHive.isAdapterRegistered(AnonpayInvoiceInfo.typeId)) {
+    CakeHive.registerAdapter(AnonpayInvoiceInfoAdapter());
   }
 
+  final secureStorage = secureStorageShared;
+  final transactionDescriptionsBoxKey =
+      await getEncryptionKey(secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
+  final tradesBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Trade.boxKey);
+  final ordersBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Order.boxKey);
+  final contacts = await CakeHive.openBox<Contact>(Contact.boxName);
+  final nodes = await CakeHive.openBox<Node>(Node.boxName);
+  final transactionDescriptions = await CakeHive.openBox<TransactionDescription>(
+      TransactionDescription.boxName,
+      encryptionKey: transactionDescriptionsBoxKey);
+  final trades = await CakeHive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
+  final orders = await CakeHive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
+  final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
+  final templates = await CakeHive.openBox<Template>(Template.boxName);
+  final exchangeTemplates = await CakeHive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
+  final anonpayInvoiceInfo = await CakeHive.openBox<AnonpayInvoiceInfo>(AnonpayInvoiceInfo.boxName);
+  final unspentCoinsInfoSource = await CakeHive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
+
   await initialSetup(
       sharedPreferences: await SharedPreferences.getInstance(),
       nodes: nodes,
@@ -169,7 +172,7 @@ Future<void> initialSetup(
     required Box<TransactionDescription> transactionDescriptions,
     required SecureStorage secureStorage,
     required Box<AnonpayInvoiceInfo> anonpayInvoiceInfo,
-    Box<UnspentCoinsInfo>? unspentCoinsInfoSource,
+    required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
     int initialMigrationVersion = 15}) async {
   LanguageService.loadLocaleList();
   await defaultSettingsMigration(
diff --git a/lib/monero/cw_monero.dart b/lib/monero/cw_monero.dart
index 5dfe2e467..4f45bc974 100644
--- a/lib/monero/cw_monero.dart
+++ b/lib/monero/cw_monero.dart
@@ -1,361 +1,363 @@
 part of 'monero.dart';
 
 class CWMoneroAccountList extends MoneroAccountList {
-	CWMoneroAccountList(this._wallet);
-	final Object _wallet;
+  CWMoneroAccountList(this._wallet);
 
-	@override
-	@computed
+  final Object _wallet;
+
+  @override
+  @computed
   ObservableList<Account> get accounts {
-  	final moneroWallet = _wallet as MoneroWallet;
-  	final accounts = moneroWallet.walletAddresses.accountList
-  		.accounts
-  		.map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance))
-  		.toList();
-  	return ObservableList<Account>.of(accounts);
+    final moneroWallet = _wallet as MoneroWallet;
+    final accounts = moneroWallet.walletAddresses.accountList.accounts
+        .map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance))
+        .toList();
+    return ObservableList<Account>.of(accounts);
   }
 
   @override
   void update(Object wallet) {
-  	final moneroWallet = wallet as MoneroWallet;
-  	moneroWallet.walletAddresses.accountList.update();
+    final moneroWallet = wallet as MoneroWallet;
+    moneroWallet.walletAddresses.accountList.update();
   }
 
   @override
-	void refresh(Object wallet) {
-		final moneroWallet = wallet as MoneroWallet;
-  	moneroWallet.walletAddresses.accountList.refresh();
-	}
+  void refresh(Object wallet) {
+    final moneroWallet = wallet as MoneroWallet;
+    moneroWallet.walletAddresses.accountList.refresh();
+  }
 
-	@override
+  @override
   List<Account> getAll(Object wallet) {
-  	final moneroWallet = wallet as MoneroWallet;
-  	return moneroWallet.walletAddresses.accountList
-  		.getAll()
-  		.map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance))
-  		.toList();
+    final moneroWallet = wallet as MoneroWallet;
+    return moneroWallet.walletAddresses.accountList
+        .getAll()
+        .map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance))
+        .toList();
   }
 
   @override
   Future<void> addAccount(Object wallet, {required String label}) async {
-  	final moneroWallet = wallet as MoneroWallet;
-  	await moneroWallet.walletAddresses.accountList.addAccount(label: label);
+    final moneroWallet = wallet as MoneroWallet;
+    await moneroWallet.walletAddresses.accountList.addAccount(label: label);
   }
 
   @override
-  Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label}) async {
-  	final moneroWallet = wallet as MoneroWallet;
-  	await moneroWallet.walletAddresses.accountList
-  		.setLabelAccount(
-  			accountIndex: accountIndex,
-  			label: label);
+  Future<void> setLabelAccount(Object wallet,
+      {required int accountIndex, required String label}) async {
+    final moneroWallet = wallet as MoneroWallet;
+    await moneroWallet.walletAddresses.accountList
+        .setLabelAccount(accountIndex: accountIndex, label: label);
   }
 }
 
 class CWMoneroSubaddressList extends MoneroSubaddressList {
-	CWMoneroSubaddressList(this._wallet);
-	final Object _wallet;
+  CWMoneroSubaddressList(this._wallet);
 
-	@override
-	@computed
+  final Object _wallet;
+
+  @override
+  @computed
   ObservableList<Subaddress> get subaddresses {
-  	final moneroWallet = _wallet as MoneroWallet;
-  	final subAddresses = moneroWallet.walletAddresses.subaddressList
-  		.subaddresses
-  		.map((sub) => Subaddress(
-  			id: sub.id,
-  			address: sub.address,
-  			label: sub.label))
-  		.toList();
-  	return ObservableList<Subaddress>.of(subAddresses);
+    final moneroWallet = _wallet as MoneroWallet;
+    final subAddresses = moneroWallet.walletAddresses.subaddressList.subaddresses
+        .map((sub) => Subaddress(id: sub.id, address: sub.address, label: sub.label))
+        .toList();
+    return ObservableList<Subaddress>.of(subAddresses);
   }
 
   @override
   void update(Object wallet, {required int accountIndex}) {
-  	final moneroWallet = wallet as MoneroWallet;
-  	moneroWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex);
+    final moneroWallet = wallet as MoneroWallet;
+    moneroWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex);
   }
 
   @override
   void refresh(Object wallet, {required int accountIndex}) {
-  	final moneroWallet = wallet as MoneroWallet;
-  	moneroWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex);
+    final moneroWallet = wallet as MoneroWallet;
+    moneroWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex);
   }
 
   @override
   List<Subaddress> getAll(Object wallet) {
-  	final moneroWallet = wallet as MoneroWallet;
-  	return moneroWallet.walletAddresses
-  		.subaddressList
-  		.getAll()
-  		.map((sub) => Subaddress(id: sub.id, label: sub.label, address: sub.address))
-  		.toList();
+    final moneroWallet = wallet as MoneroWallet;
+    return moneroWallet.walletAddresses.subaddressList
+        .getAll()
+        .map((sub) => Subaddress(id: sub.id, label: sub.label, address: sub.address))
+        .toList();
   }
 
   @override
-  Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label}) async {
-  	final moneroWallet = wallet as MoneroWallet;
-  	await moneroWallet.walletAddresses.subaddressList
-  		.addSubaddress(
-  			accountIndex: accountIndex,
-  			label: label);
+  Future<void> addSubaddress(Object wallet,
+      {required int accountIndex, required String label}) async {
+    final moneroWallet = wallet as MoneroWallet;
+    await moneroWallet.walletAddresses.subaddressList
+        .addSubaddress(accountIndex: accountIndex, label: label);
   }
 
   @override
   Future<void> setLabelSubaddress(Object wallet,
       {required int accountIndex, required int addressIndex, required String label}) async {
-  	final moneroWallet = wallet as MoneroWallet;
-  	await moneroWallet.walletAddresses.subaddressList
-  		.setLabelSubaddress(
-  			accountIndex: accountIndex,
-  			addressIndex: addressIndex,
-  			label: label);
+    final moneroWallet = wallet as MoneroWallet;
+    await moneroWallet.walletAddresses.subaddressList
+        .setLabelSubaddress(accountIndex: accountIndex, addressIndex: addressIndex, label: label);
   }
 }
 
 class CWMoneroWalletDetails extends MoneroWalletDetails {
-	CWMoneroWalletDetails(this._wallet);
-	final Object _wallet;
+  CWMoneroWalletDetails(this._wallet);
 
-	@computed
+  final Object _wallet;
+
+  @computed
   @override
   Account get account {
-  	final moneroWallet = _wallet as MoneroWallet;
-  	final acc = moneroWallet.walletAddresses.account;
-  	return Account(id: acc!.id, label: acc.label, balance: acc.balance);
+    final moneroWallet = _wallet as MoneroWallet;
+    final acc = moneroWallet.walletAddresses.account;
+    return Account(id: acc!.id, label: acc.label, balance: acc.balance);
   }
 
   @computed
   @override
-	MoneroBalance get balance {
-		final moneroWallet = _wallet as MoneroWallet;
-  	final balance = moneroWallet.balance;
+  MoneroBalance get balance {
+    final moneroWallet = _wallet as MoneroWallet;
+    final balance = moneroWallet.balance;
     throw Exception('Unimplemented');
-  	// return MoneroBalance();
-  	//return MoneroBalance(
-  	//	fullBalance: balance.fullBalance,
-  	//	unlockedBalance: balance.unlockedBalance);
-	}
+    // return MoneroBalance();
+    //return MoneroBalance(
+    //	fullBalance: balance.fullBalance,
+    //	unlockedBalance: balance.unlockedBalance);
+  }
 }
 
 class CWMonero extends Monero {
   @override
-	MoneroAccountList getAccountList(Object wallet) {
-		return CWMoneroAccountList(wallet);
-	}
-	
-	@override
-	MoneroSubaddressList getSubaddressList(Object wallet) {
-		return CWMoneroSubaddressList(wallet);
-	}
-
-	@override
-	TransactionHistoryBase getTransactionHistory(Object wallet) {
-		final moneroWallet = wallet as MoneroWallet;
-		return moneroWallet.transactionHistory;
-	}
-
-	@override
-	MoneroWalletDetails getMoneroWalletDetails(Object wallet) {
-		return CWMoneroWalletDetails(wallet);
-	}
-
-	@override
-	int getHeigthByDate({required DateTime date}) {
-		return getMoneroHeigthByDate(date: date);
-	}
-	
-	@override
-	TransactionPriority getDefaultTransactionPriority() {
-		return MoneroTransactionPriority.automatic;
-	}
+  MoneroAccountList getAccountList(Object wallet) {
+    return CWMoneroAccountList(wallet);
+  }
 
   @override
-  TransactionPriority getMoneroTransactionPrioritySlow()
-    => MoneroTransactionPriority.slow;
+  MoneroSubaddressList getSubaddressList(Object wallet) {
+    return CWMoneroSubaddressList(wallet);
+  }
 
   @override
-  TransactionPriority getMoneroTransactionPriorityAutomatic()
-    => MoneroTransactionPriority.automatic;
+  TransactionHistoryBase getTransactionHistory(Object wallet) {
+    final moneroWallet = wallet as MoneroWallet;
+    return moneroWallet.transactionHistory;
+  }
 
-	@override
-	TransactionPriority deserializeMoneroTransactionPriority({required int raw}) {
-		return MoneroTransactionPriority.deserialize(raw: raw);
-	}
+  @override
+  MoneroWalletDetails getMoneroWalletDetails(Object wallet) {
+    return CWMoneroWalletDetails(wallet);
+  }
 
-	@override
-	List<TransactionPriority> getTransactionPriorities() {
-		return MoneroTransactionPriority.all;
-	}
+  @override
+  int getHeigthByDate({required DateTime date}) {
+    return getMoneroHeigthByDate(date: date);
+  }
 
-	@override
-	List<String> getMoneroWordList(String language) {
-		switch (language.toLowerCase()) {
-		  case 'english':
-		    return EnglishMnemonics.words;
-		  case 'chinese (simplified)':
-		    return ChineseSimplifiedMnemonics.words;
-		  case 'dutch':
-		    return DutchMnemonics.words;
-		  case 'german':
-		    return GermanMnemonics.words;
-		  case 'japanese':
-		    return JapaneseMnemonics.words;
-		  case 'portuguese':
-		    return PortugueseMnemonics.words;
-		  case 'russian':
-		    return RussianMnemonics.words;
-		  case 'spanish':
-		    return SpanishMnemonics.words;
-		  case 'french':
-		  	return FrenchMnemonics.words;
-		  case 'italian':
-		  	return ItalianMnemonics.words;
-		  default:
-		    return EnglishMnemonics.words;
-		}
-	}
+  @override
+  TransactionPriority getDefaultTransactionPriority() {
+    return MoneroTransactionPriority.automatic;
+  }
 
-	@override
-	WalletCredentials createMoneroRestoreWalletFromKeysCredentials({
-			required String name,
-    	required String spendKey,
-    	required String viewKey,
-    	required String address,
-    	required String password,
-    	required String language,
-    	required int height}) {
-		return MoneroRestoreWalletFromKeysCredentials(
-			name: name,
-			spendKey: spendKey,
-			viewKey: viewKey,
-			address: address,
-			password: password,
-			language: language,
-			height: height);
-	}
-	
-	@override
-	WalletCredentials createMoneroRestoreWalletFromSeedCredentials({
-    required String name,
-    required String password,
-    required int height,
-    required String mnemonic}) {
-		return MoneroRestoreWalletFromSeedCredentials(
-			name: name,
-			password: password,
-			height: height,
-			mnemonic: mnemonic);
-	}
+  @override
+  TransactionPriority getMoneroTransactionPrioritySlow() => MoneroTransactionPriority.slow;
 
-	@override
-	WalletCredentials createMoneroNewWalletCredentials({
+  @override
+  TransactionPriority getMoneroTransactionPriorityAutomatic() =>
+      MoneroTransactionPriority.automatic;
+
+  @override
+  TransactionPriority deserializeMoneroTransactionPriority({required int raw}) {
+    return MoneroTransactionPriority.deserialize(raw: raw);
+  }
+
+  @override
+  List<TransactionPriority> getTransactionPriorities() {
+    return MoneroTransactionPriority.all;
+  }
+
+  @override
+  List<String> getMoneroWordList(String language) {
+    switch (language.toLowerCase()) {
+      case 'english':
+        return EnglishMnemonics.words;
+      case 'chinese (simplified)':
+        return ChineseSimplifiedMnemonics.words;
+      case 'dutch':
+        return DutchMnemonics.words;
+      case 'german':
+        return GermanMnemonics.words;
+      case 'japanese':
+        return JapaneseMnemonics.words;
+      case 'portuguese':
+        return PortugueseMnemonics.words;
+      case 'russian':
+        return RussianMnemonics.words;
+      case 'spanish':
+        return SpanishMnemonics.words;
+      case 'french':
+        return FrenchMnemonics.words;
+      case 'italian':
+        return ItalianMnemonics.words;
+      default:
+        return EnglishMnemonics.words;
+    }
+  }
+
+  @override
+  WalletCredentials createMoneroRestoreWalletFromKeysCredentials(
+      {required String name,
+      required String spendKey,
+      required String viewKey,
+      required String address,
+      required String password,
+      required String language,
+      required int height}) {
+    return MoneroRestoreWalletFromKeysCredentials(
+        name: name,
+        spendKey: spendKey,
+        viewKey: viewKey,
+        address: address,
+        password: password,
+        language: language,
+        height: height);
+  }
+
+  @override
+  WalletCredentials createMoneroRestoreWalletFromSeedCredentials(
+      {required String name,
+      required String password,
+      required int height,
+      required String mnemonic}) {
+    return MoneroRestoreWalletFromSeedCredentials(
+        name: name, password: password, height: height, mnemonic: mnemonic);
+  }
+
+  @override
+  WalletCredentials createMoneroNewWalletCredentials({
     required String name,
     required String language,
-    String? password,}) {
-		return MoneroNewWalletCredentials(
-			name: name,
-			password: password,
-			language: language);
-	}
+    String? password,
+  }) {
+    return MoneroNewWalletCredentials(name: name, password: password, language: language);
+  }
 
-	@override
-	Map<String, String> getKeys(Object wallet) {
-		final moneroWallet = wallet as MoneroWallet;
-		final keys = moneroWallet.keys;
-		return <String, String>{
-			'privateSpendKey': keys.privateSpendKey,
+  @override
+  Map<String, String> getKeys(Object wallet) {
+    final moneroWallet = wallet as MoneroWallet;
+    final keys = moneroWallet.keys;
+    return <String, String>{
+      'privateSpendKey': keys.privateSpendKey,
       'privateViewKey': keys.privateViewKey,
       'publicSpendKey': keys.publicSpendKey,
-      'publicViewKey': keys.publicViewKey};
-	}
+      'publicViewKey': keys.publicViewKey
+    };
+  }
 
-	@override
-	Object createMoneroTransactionCreationCredentials({
-    required List<Output> outputs,
-    required TransactionPriority priority}) {
-		return MoneroTransactionCreationCredentials(
-			outputs: outputs.map((out) => OutputInfo(
-					fiatAmount: out.fiatAmount,
-					cryptoAmount: out.cryptoAmount,
-					address: out.address,
-					note: out.note,
-					sendAll: out.sendAll,
-					extractedAddress: out.extractedAddress,
-					isParsedAddress: out.isParsedAddress,
-					formattedCryptoAmount: out.formattedCryptoAmount))
-				.toList(),
-			priority: priority as MoneroTransactionPriority);
-	}
+  @override
+  Object createMoneroTransactionCreationCredentials(
+      {required List<Output> outputs, required TransactionPriority priority}) {
+    return MoneroTransactionCreationCredentials(
+        outputs: outputs
+            .map((out) => OutputInfo(
+                fiatAmount: out.fiatAmount,
+                cryptoAmount: out.cryptoAmount,
+                address: out.address,
+                note: out.note,
+                sendAll: out.sendAll,
+                extractedAddress: out.extractedAddress,
+                isParsedAddress: out.isParsedAddress,
+                formattedCryptoAmount: out.formattedCryptoAmount))
+            .toList(),
+        priority: priority as MoneroTransactionPriority);
+  }
 
-	@override
-	Object createMoneroTransactionCreationCredentialsRaw({
-    required List<OutputInfo> outputs,
-    required TransactionPriority priority}) {
-		return MoneroTransactionCreationCredentials(
-			outputs: outputs,
-			priority: priority as MoneroTransactionPriority);
-	}
+  @override
+  Object createMoneroTransactionCreationCredentialsRaw(
+      {required List<OutputInfo> outputs, required TransactionPriority priority}) {
+    return MoneroTransactionCreationCredentials(
+        outputs: outputs, priority: priority as MoneroTransactionPriority);
+  }
 
-	@override
-	String formatterMoneroAmountToString({required int amount}) {
-		return moneroAmountToString(amount: amount);
-	}
+  @override
+  String formatterMoneroAmountToString({required int amount}) {
+    return moneroAmountToString(amount: amount);
+  }
 
-	@override
-	double formatterMoneroAmountToDouble({required int amount}) {
-		return moneroAmountToDouble(amount: amount);
-	}
+  @override
+  double formatterMoneroAmountToDouble({required int amount}) {
+    return moneroAmountToDouble(amount: amount);
+  }
 
-	@override
-	int formatterMoneroParseAmount({required String amount}) {
-		return moneroParseAmount(amount: amount);
-	}
+  @override
+  int formatterMoneroParseAmount({required String amount}) {
+    return moneroParseAmount(amount: amount);
+  }
 
-	@override
-	Account getCurrentAccount(Object wallet) {
-		final moneroWallet = wallet as MoneroWallet;
-		final acc = moneroWallet.walletAddresses.account;
-		return Account(id: acc!.id, label: acc.label, balance: acc.balance);
-	}
+  @override
+  Account getCurrentAccount(Object wallet) {
+    final moneroWallet = wallet as MoneroWallet;
+    final acc = moneroWallet.walletAddresses.account;
+    return Account(id: acc!.id, label: acc.label, balance: acc.balance);
+  }
 
-	@override
-	void setCurrentAccount(Object wallet, int id, String label, String? balance) {
-		final moneroWallet = wallet as MoneroWallet;
-		moneroWallet.walletAddresses.account = monero_account.Account(id: id, label: label, balance: balance);
-	}
+  @override
+  void setCurrentAccount(Object wallet, int id, String label, String? balance) {
+    final moneroWallet = wallet as MoneroWallet;
+    moneroWallet.walletAddresses.account =
+        monero_account.Account(id: id, label: label, balance: balance);
+  }
 
-	@override
-	void onStartup() {
-		monero_wallet_api.onStartup();
-	}
+  @override
+  void onStartup() {
+    monero_wallet_api.onStartup();
+  }
 
-	@override
-	int getTransactionInfoAccountId(TransactionInfo tx) {
-		final moneroTransactionInfo = tx as MoneroTransactionInfo;
-		return moneroTransactionInfo.accountIndex;
-	}
+  @override
+  int getTransactionInfoAccountId(TransactionInfo tx) {
+    final moneroTransactionInfo = tx as MoneroTransactionInfo;
+    return moneroTransactionInfo.accountIndex;
+  }
 
-	@override
-	WalletService createMoneroWalletService(Box<WalletInfo> walletInfoSource) {
-		return MoneroWalletService(walletInfoSource);
-	}
+  @override
+  WalletService createMoneroWalletService(
+      Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource) {
+    return MoneroWalletService(walletInfoSource, unspentCoinSource);
+  }
 
-	@override
-	String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) {
-		final moneroWallet = wallet as MoneroWallet;
-		return moneroWallet.getTransactionAddress(accountIndex, addressIndex);
-	}
+  @override
+  String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) {
+    final moneroWallet = wallet as MoneroWallet;
+    return moneroWallet.getTransactionAddress(accountIndex, addressIndex);
+  }
 
-	@override
-	String getSubaddressLabel(Object wallet, int accountIndex, int addressIndex) {
-		final moneroWallet = wallet as MoneroWallet;
-		return moneroWallet.getSubaddressLabel(accountIndex, addressIndex);
-	}
+  @override
+  String getSubaddressLabel(Object wallet, int accountIndex, int addressIndex) {
+    final moneroWallet = wallet as MoneroWallet;
+    return moneroWallet.getSubaddressLabel(accountIndex, addressIndex);
+  }
 
-	@override
-	Map<String, String> pendingTransactionInfo(Object transaction) {
-		final ptx = transaction as PendingMoneroTransaction;
-		return {'id': ptx.id, 'hex': ptx.hex, 'key': ptx.txKey};
-	}
+  @override
+  Map<String, String> pendingTransactionInfo(Object transaction) {
+    final ptx = transaction as PendingMoneroTransaction;
+    return {'id': ptx.id, 'hex': ptx.hex, 'key': ptx.txKey};
+  }
+
+  @override
+  List<Unspent> getUnspents(Object wallet) {
+    final moneroWallet = wallet as MoneroWallet;
+    return moneroWallet.unspentCoins
+        .map((MoneroUnspent moneroUnspent) => Unspent(moneroUnspent.address, moneroUnspent.hash,
+            moneroUnspent.value, 0, moneroUnspent.keyImage))
+        .toList();
+  }
+
+  @override
+  void updateUnspents(Object wallet) async {
+    final moneroWallet = wallet as MoneroWallet;
+    await moneroWallet.updateUnspent();
+  }
 }
diff --git a/lib/reactions/on_current_wallet_change.dart b/lib/reactions/on_current_wallet_change.dart
index 89f39d5f9..95406fb40 100644
--- a/lib/reactions/on_current_wallet_change.dart
+++ b/lib/reactions/on_current_wallet_change.dart
@@ -1,3 +1,4 @@
+import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
 import 'package:cake_wallet/entities/fiat_api_mode.dart';
 import 'package:cake_wallet/entities/update_haven_rate.dart';
 import 'package:cake_wallet/ethereum/ethereum.dart';
@@ -21,36 +22,36 @@ ReactionDisposer? _onCurrentWalletChangeReaction;
 ReactionDisposer? _onCurrentWalletChangeFiatRateUpdateReaction;
 //ReactionDisposer _onCurrentWalletAddressChangeReaction;
 
-void startCurrentWalletChangeReaction(AppStore appStore,
-    SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
+void startCurrentWalletChangeReaction(
+    AppStore appStore, SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
   _onCurrentWalletChangeReaction?.reaction.dispose();
   _onCurrentWalletChangeFiatRateUpdateReaction?.reaction.dispose();
   //_onCurrentWalletAddressChangeReaction?.reaction?dispose();
 
   //_onCurrentWalletAddressChangeReaction = reaction((_) => appStore.wallet.walletAddresses.address,
-    //(String address) async {
-      //if (address == appStore.wallet.walletInfo.yatLastUsedAddress) {
-      //  return;
-      //}
+  //(String address) async {
+  //if (address == appStore.wallet.walletInfo.yatLastUsedAddress) {
+  //  return;
+  //}
 
-      //try {
-      //  final yatStore = getIt.get<YatStore>();
-      //  await updateEmojiIdAddress(
-      //    appStore.wallet.walletInfo.yatEmojiId,
-      //    appStore.wallet.walletAddresses.address,
-      //    yatStore.apiKey,
-      //    appStore.wallet.type
-      //  );
-      //  appStore.wallet.walletInfo.yatLastUsedAddress = address;
-      //  await appStore.wallet.walletInfo.save();
-      //} catch (e) {
-      //  print(e.toString());
-      //}
+  //try {
+  //  final yatStore = getIt.get<YatStore>();
+  //  await updateEmojiIdAddress(
+  //    appStore.wallet.walletInfo.yatEmojiId,
+  //    appStore.wallet.walletAddresses.address,
+  //    yatStore.apiKey,
+  //    appStore.wallet.type
+  //  );
+  //  appStore.wallet.walletInfo.yatLastUsedAddress = address;
+  //  await appStore.wallet.walletInfo.save();
+  //} catch (e) {
+  //  print(e.toString());
+  //}
   //});
 
-  _onCurrentWalletChangeReaction = reaction((_) => appStore.wallet, (WalletBase<
-          Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
-      wallet) async {
+  _onCurrentWalletChangeReaction = reaction((_) => appStore.wallet,
+      (WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
+          wallet) async {
     try {
       if (wallet == null) {
         return;
@@ -59,11 +60,13 @@ void startCurrentWalletChangeReaction(AppStore appStore,
       final node = settingsStore.getCurrentNode(wallet.type);
       startWalletSyncStatusChangeReaction(wallet, fiatConversionStore);
       startCheckConnectionReaction(wallet, settingsStore);
+      await getIt.get<SharedPreferences>().setString(PreferencesKey.currentWalletName, wallet.name);
       await getIt
           .get<SharedPreferences>()
-          .setString(PreferencesKey.currentWalletName, wallet.name);
-      await getIt.get<SharedPreferences>().setInt(
-          PreferencesKey.currentWalletType, serializeToInt(wallet.type));
+          .setInt(PreferencesKey.currentWalletType, serializeToInt(wallet.type));
+      if (wallet.type == WalletType.monero) {
+        _setAutoGenerateSubaddressStatus(wallet, settingsStore);
+      }
       await wallet.connectToNode(node: node);
 
       if (wallet.type == WalletType.haven) {
@@ -82,9 +85,8 @@ void startCurrentWalletChangeReaction(AppStore appStore,
     }
   });
 
-  _onCurrentWalletChangeFiatRateUpdateReaction =
-      reaction((_) => appStore.wallet, (WalletBase<Balance,
-              TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
+  _onCurrentWalletChangeFiatRateUpdateReaction = reaction((_) => appStore.wallet,
+      (WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
           wallet) async {
     try {
       if (wallet == null || settingsStore.fiatApiMode == FiatApiMode.disabled) {
@@ -92,11 +94,10 @@ void startCurrentWalletChangeReaction(AppStore appStore,
       }
 
       fiatConversionStore.prices[wallet.currency] = 0;
-      fiatConversionStore.prices[wallet.currency] =
-          await FiatConversionService.fetchPrice(
-              crypto: wallet.currency,
-              fiat: settingsStore.fiatCurrency,
-              torOnly: settingsStore.fiatApiMode == FiatApiMode.torOnly);
+      fiatConversionStore.prices[wallet.currency] = await FiatConversionService.fetchPrice(
+          crypto: wallet.currency,
+          fiat: settingsStore.fiatCurrency,
+          torOnly: settingsStore.fiatApiMode == FiatApiMode.torOnly);
 
       if (wallet.type == WalletType.ethereum) {
         final currencies =
@@ -116,3 +117,17 @@ void startCurrentWalletChangeReaction(AppStore appStore,
     }
   });
 }
+
+void _setAutoGenerateSubaddressStatus(
+  WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet,
+  SettingsStore settingsStore,
+) async {
+  final walletHasAddresses = await wallet.walletAddresses.addressesMap.length > 1;
+  if (settingsStore.autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.initialized &&
+      walletHasAddresses) {
+    settingsStore.autoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.disabled;
+  }
+  wallet.isEnabledAutoGenerateSubaddress =
+      settingsStore.autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.enabled ||
+          settingsStore.autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.initialized;
+}
diff --git a/lib/router.dart b/lib/router.dart
index 2bb3c9b7e..5d5c64a53 100644
--- a/lib/router.dart
+++ b/lib/router.dart
@@ -57,7 +57,6 @@ import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/di.dart';
 import 'package:cake_wallet/view_model/wallet_new_vm.dart';
-import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
 import 'package:cake_wallet/exchange/trade.dart';
 import 'package:cw_core/transaction_info.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -80,7 +79,6 @@ import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_c
 import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
 import 'package:cake_wallet/src/screens/contact/contact_page.dart';
 import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
-import 'package:cake_wallet/src/screens/restore/restore_wallet_from_seed_details.dart';
 import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
 import 'package:cake_wallet/src/screens/rescan/rescan_page.dart';
 import 'package:cake_wallet/src/screens/faq/faq_page.dart';
@@ -435,16 +433,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
           builder: (_) =>
               getIt.get<BuyWebViewPage>(param1: args));
 
-    case Routes.restoreWalletFromSeedDetails:
-      final args = settings.arguments as List;
-      final walletRestorationFromSeedVM =
-          getIt.get<WalletRestorationFromSeedVM>(param1: args);
-
-      return CupertinoPageRoute<void>(
-          fullscreenDialog: true,
-          builder: (_) => RestoreWalletFromSeedDetailsPage(
-              walletRestorationFromSeedVM: walletRestorationFromSeedVM));
-
     case Routes.exchange:
       return CupertinoPageRoute<void>(
           fullscreenDialog: true,
diff --git a/lib/routes.dart b/lib/routes.dart
index 8cb701a9a..0d3f7e1f6 100644
--- a/lib/routes.dart
+++ b/lib/routes.dart
@@ -30,7 +30,6 @@ class Routes {
   static const tradeDetails = '/trade_details';
   static const exchangeFunds = '/exchange_funds';
   static const exchangeTrade = '/exchange_trade';
-  static const restoreWalletFromSeedDetails = '/restore_from_seed_details';
   static const exchange = '/exchange';
   static const settings = '/settings';
   static const desktop_settings_page = '/desktop_settings_page';
diff --git a/lib/src/screens/backup/backup_page.dart b/lib/src/screens/backup/backup_page.dart
index f7a224aac..5995e71c4 100644
--- a/lib/src/screens/backup/backup_page.dart
+++ b/lib/src/screens/backup/backup_page.dart
@@ -127,9 +127,9 @@ class BackupPage extends BasePage {
         builder: (dialogContext) {
           return AlertWithTwoActions(
               alertTitle: S.of(context).export_backup,
-              alertContent: 'Please select destination for the backup file.',
-              rightButtonText: 'Save to Downloads',
-              leftButtonText: 'Share',
+              alertContent: S.of(context).select_destination,
+              rightButtonText: S.of(context).save_to_downloads,
+              leftButtonText:S.of(context).share,
               actionRightButton: () async {
                 final permission = await Permission.storage.request();
 
diff --git a/lib/src/screens/contact/contact_list_page.dart b/lib/src/screens/contact/contact_list_page.dart
index 6c00b64f9..b551875f9 100644
--- a/lib/src/screens/contact/contact_list_page.dart
+++ b/lib/src/screens/contact/contact_list_page.dart
@@ -1,6 +1,7 @@
 import 'package:cake_wallet/core/auth_service.dart';
 import 'package:cake_wallet/entities/contact_base.dart';
 import 'package:cake_wallet/entities/contact_record.dart';
+import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
 import 'package:cake_wallet/utils/show_bar.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
@@ -39,7 +40,7 @@ class ContactListPage extends BasePage {
           children: <Widget>[
             Icon(
               Icons.add,
-              color: Theme.of(context).dialogTheme.backgroundColor,
+              color: Theme.of(context).appBarTheme.titleTextStyle!.color,
               size: 22.0,
             ),
             ButtonTheme(
@@ -71,7 +72,7 @@ class ContactListPage extends BasePage {
   @override
   Widget body(BuildContext context) {
     return Container(
-        padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
+        padding: EdgeInsets.all(20.0),
         child: Observer(builder: (_) {
           final contacts = contactListViewModel.contactsToShow;
           final walletContacts = contactListViewModel.walletContactsToShow;
@@ -131,7 +132,6 @@ class ContactListPage extends BasePage {
         }
       },
       child: Container(
-        color: Colors.transparent,
         padding: const EdgeInsets.only(top: 16, bottom: 16, right: 24),
         child: Row(
           mainAxisSize: MainAxisSize.min,
@@ -146,7 +146,7 @@ class ContactListPage extends BasePage {
                 style: TextStyle(
                   fontSize: 14,
                   fontWeight: FontWeight.normal,
-                  color: Theme.of(context).dialogTheme.backgroundColor,
+                  color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
                 ),
               ),
             ))
diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart
index ad2291ba5..5e1f8d16a 100644
--- a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart
+++ b/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart
@@ -73,12 +73,12 @@ class DesktopDashboardActions extends StatelessWidget {
                   ),
                 ],
               ),
-              Expanded(
-                child: MarketPlacePage(
-                  dashboardViewModel: dashboardViewModel,
-                  marketPlaceViewModel: getIt.get<MarketPlaceViewModel>(),
-                ),
+            Expanded(
+              child: MarketPlacePage(
+                dashboardViewModel: dashboardViewModel,
+                marketPlaceViewModel: getIt.get<MarketPlaceViewModel>(),
               ),
+            ),
             ],
           );
         }
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 c5899ca68..d2c4a92a4 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
@@ -37,12 +37,14 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
   final havenIcon = Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
   final ethereumIcon = Image.asset('assets/images/eth_icon.png', height: 24, width: 24);
   final nonWalletTypeIcon = Image.asset('assets/images/close.png', height: 24, width: 24);
+
   Image _newWalletImage(BuildContext context) => Image.asset(
         'assets/images/new_wallet.png',
         height: 12,
         width: 12,
         color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
       );
+
   Image _restoreWalletImage(BuildContext context) => Image.asset(
         'assets/images/restore_wallet.png',
         height: 12,
diff --git a/lib/src/screens/dashboard/widgets/address_page.dart b/lib/src/screens/dashboard/widgets/address_page.dart
index d4a10ac7a..388ce0fa5 100644
--- a/lib/src/screens/dashboard/widgets/address_page.dart
+++ b/lib/src/screens/dashboard/widgets/address_page.dart
@@ -1,8 +1,10 @@
 import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
+import 'package:cake_wallet/di.dart';
+import 'package:cake_wallet/src/screens/base_page.dart';
+import 'package:cake_wallet/src/screens/monero_accounts/monero_account_list_page.dart';
 import 'package:cake_wallet/anonpay/anonpay_donation_link_info.dart';
 import 'package:cake_wallet/entities/preferences_key.dart';
 import 'package:cake_wallet/entities/receive_page_option.dart';
-import 'package:cake_wallet/src/screens/base_page.dart';
 import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option_picker.dart';
 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
 import 'package:cake_wallet/src/widgets/gradient_background.dart';
@@ -174,7 +176,11 @@ class AddressPage extends BasePage {
               Observer(builder: (_) {
                 if (addressListViewModel.hasAddressList) {
                   return GestureDetector(
-                    onTap: () => Navigator.of(context).pushNamed(Routes.receive),
+                    onTap: () async => dashboardViewModel.isAutoGenerateSubaddressesEnabled
+                        ? await showPopUp<void>(
+                        context: context,
+                        builder: (_) => getIt.get<MoneroAccountListPage>())
+                        : Navigator.of(context).pushNamed(Routes.receive),
                     child: Container(
                       height: 50,
                       padding: EdgeInsets.only(left: 24, right: 12),
@@ -182,9 +188,8 @@ class AddressPage extends BasePage {
                       decoration: BoxDecoration(
                           borderRadius: BorderRadius.all(Radius.circular(25)),
                           border: Border.all(
-                              color: Theme.of(context)
-                                  .extension<ReceivePageTheme>()!
-                                  .iconsBackgroundColor,
+                              color:
+                                  Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
                               width: 1),
                           color: Theme.of(context)
                               .extension<SyncIndicatorTheme>()!
@@ -194,26 +199,36 @@ class AddressPage extends BasePage {
                         mainAxisAlignment: MainAxisAlignment.spaceBetween,
                         children: <Widget>[
                           Observer(
-                              builder: (_) => Text(
-                                    addressListViewModel.hasAccounts
-                                        ? S.of(context).accounts_subaddresses
-                                        : S.of(context).addresses,
-                                    style: TextStyle(
-                                        fontSize: 14,
-                                        fontWeight: FontWeight.w500,
-                                        color: Theme.of(context).extension<DashboardPageTheme>()!.textColor),
-                                  )),
+                              builder: (_) {
+                                String label = addressListViewModel.hasAccounts
+                                    ? S.of(context).accounts_subaddresses
+                                    : S.of(context).addresses;
+
+                                if (dashboardViewModel.isAutoGenerateSubaddressesEnabled) {
+                                  label = addressListViewModel.hasAccounts
+                                      ? S.of(context).accounts
+                                      : S.of(context).account;
+                                }
+                                return Text(
+                                  label,
+                                  style: TextStyle(
+                                      fontSize: 14,
+                                      fontWeight: FontWeight.w500,
+                                      color: Theme.of(context)
+                                            .extension<SyncIndicatorTheme>()!
+                                            .textColor),
+                                );
+                              },),
                           Icon(
                             Icons.arrow_forward_ios,
                             size: 14,
-                            color:
-                                Theme.of(context).extension<DashboardPageTheme>()!.textColor,
+                            color: Theme.of(context).extension<SyncIndicatorTheme>()!.textColor,
                           )
                         ],
                       ),
                     ),
                   );
-                } else if (addressListViewModel.showElectrumAddressDisclaimer) {
+                } else if (dashboardViewModel.isAutoGenerateSubaddressesEnabled || addressListViewModel.showElectrumAddressDisclaimer) {
                   return Text(S.of(context).electrum_address_disclaimer,
                       textAlign: TextAlign.center,
                       style: TextStyle(
diff --git a/lib/src/screens/dashboard/widgets/balance_page.dart b/lib/src/screens/dashboard/widgets/balance_page.dart
index f799950ea..c8d7faf11 100644
--- a/lib/src/screens/dashboard/widgets/balance_page.dart
+++ b/lib/src/screens/dashboard/widgets/balance_page.dart
@@ -2,7 +2,6 @@ import 'package:cake_wallet/routes.dart';
 import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart';
 import 'package:cake_wallet/store/settings_store.dart';
 import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
-import 'package:cake_wallet/themes/theme_base.dart';
 import 'package:cake_wallet/utils/feature_flag.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:flutter/material.dart';
@@ -77,9 +76,7 @@ class BalancePage extends StatelessWidget {
                   return IntroducingCard(
                       title: S.of(context).introducing_cake_pay,
                       subTitle: S.of(context).cake_pay_learn_more,
-                      borderColor: settingsStore.currentTheme.type == ThemeType.bright
-                          ? Color.fromRGBO(255, 255, 255, 0.2)
-                          : Colors.transparent,
+                      borderColor: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
                       closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard);
                 }
                 return Container();
@@ -139,9 +136,7 @@ class BalancePage extends StatelessWidget {
       decoration: BoxDecoration(
         borderRadius: BorderRadius.circular(30.0),
         border: Border.all(
-          color: settingsStore.currentTheme.type == ThemeType.bright
-              ? Color.fromRGBO(255, 255, 255, 0.2)
-              : Colors.transparent,
+          color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
           width: 1,
         ),
         color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
@@ -282,7 +277,7 @@ class BalancePage extends StatelessWidget {
                       fontSize: 20,
                       fontFamily: 'Lato',
                       fontWeight: FontWeight.w400,
-                      color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
+                      color: Theme.of(context).extension<BalancePageTheme>()!.assetTitleColor,
                       height: 1,
                     ),
                     maxLines: 1,
@@ -296,7 +291,7 @@ class BalancePage extends StatelessWidget {
                       fontSize: 12,
                       fontFamily: 'Lato',
                       fontWeight: FontWeight.w400,
-                      color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
+                      color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
                       height: 1,
                     ),
                   ),
diff --git a/lib/src/screens/dashboard/widgets/market_place_page.dart b/lib/src/screens/dashboard/widgets/market_place_page.dart
index 70098767d..76d0a27ac 100644
--- a/lib/src/screens/dashboard/widgets/market_place_page.dart
+++ b/lib/src/screens/dashboard/widgets/market_place_page.dart
@@ -48,15 +48,15 @@ class MarketPlacePage extends StatelessWidget {
                 child: ListView(
                   controller: _scrollController,
                   children: <Widget>[
-                    SizedBox(height: 20),
-                    DashBoardRoundedCardWidget(
-                      onTap: () => launchUrl(
-                        Uri.parse("https://cakelabs.com/news/cake-pay-mobile-to-shut-down/"),
-                        mode: LaunchMode.externalApplication,
-                      ),
-                      title: S.of(context).cake_pay_title,
-                      subTitle: S.of(context).cake_pay_subtitle,
-                    ),
+                    // SizedBox(height: 20),
+                    // DashBoardRoundedCardWidget(
+                    //   onTap: () => launchUrl(
+                    //     Uri.parse("https://cakelabs.com/news/cake-pay-mobile-to-shut-down/"),
+                    //     mode: LaunchMode.externalApplication,
+                    //   ),
+                    //   title: S.of(context).cake_pay_title,
+                    //   subTitle: S.of(context).cake_pay_subtitle,
+                    // ),
                     SizedBox(height: 20),
                     DashBoardRoundedCardWidget(
                       onTap: () => launchUrl(
diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart
index 972fa0399..7ff9e6c30 100644
--- a/lib/src/screens/exchange/exchange_page.dart
+++ b/lib/src/screens/exchange/exchange_page.dart
@@ -5,6 +5,7 @@ import 'package:cake_wallet/di.dart';
 import 'package:cake_wallet/src/screens/exchange/widgets/desktop_exchange_cards_section.dart';
 import 'package:cake_wallet/src/screens/exchange/widgets/mobile_exchange_cards_section.dart';
 import 'package:cake_wallet/src/widgets/add_template_button.dart';
+import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
 import 'package:cake_wallet/themes/theme_base.dart';
 import 'package:cake_wallet/utils/debounce.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
@@ -629,7 +630,7 @@ class ExchangePage extends BasePage {
               },
               imageArrow: arrowBottomPurple,
               currencyButtonColor: Colors.transparent,
-              addressButtonsColor: Theme.of(context).focusColor,
+              addressButtonsColor: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
               borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderTopPanelColor,
               currencyValueValidator: (value) {
                 return !exchangeViewModel.isFixedRateMode
@@ -677,7 +678,7 @@ class ExchangePage extends BasePage {
                   exchangeViewModel.changeReceiveCurrency(currency: currency),
               imageArrow: arrowBottomCakeGreen,
               currencyButtonColor: Colors.transparent,
-              addressButtonsColor: Theme.of(context).focusColor,
+              addressButtonsColor: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
               borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderBottomPanelColor,
               currencyValueValidator: (value) {
                 return exchangeViewModel.isFixedRateMode
diff --git a/lib/src/screens/monero_accounts/widgets/account_tile.dart b/lib/src/screens/monero_accounts/widgets/account_tile.dart
index fa8221513..3e428f355 100644
--- a/lib/src/screens/monero_accounts/widgets/account_tile.dart
+++ b/lib/src/screens/monero_accounts/widgets/account_tile.dart
@@ -5,13 +5,14 @@ import 'package:flutter_slidable/flutter_slidable.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 
 class AccountTile extends StatelessWidget {
-  AccountTile(
-      {required this.isCurrent,
-      required this.accountName,
-      this.accountBalance,
-      required this.currency,
-      required this.onTap,
-      required this.onEdit});
+  AccountTile({
+    required this.isCurrent,
+    required this.accountName,
+    this.accountBalance,
+    required this.currency,
+    required this.onTap,
+    required this.onEdit,
+  });
 
   final bool isCurrent;
   final String accountName;
diff --git a/lib/src/screens/receive/anonpay_invoice_page.dart b/lib/src/screens/receive/anonpay_invoice_page.dart
index 73ff2a742..deda679c5 100644
--- a/lib/src/screens/receive/anonpay_invoice_page.dart
+++ b/lib/src/screens/receive/anonpay_invoice_page.dart
@@ -87,32 +87,30 @@ class AnonPayInvoicePage extends BasePage {
         config: KeyboardActionsConfig(
             keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
             keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
-            nextFocus: false,
-            actions: [
-              KeyboardActionsItem(
-                focusNode: _amountFocusNode,
-                toolbarButtons: [(_) => KeyboardDoneButton()],
+          nextFocus: false,
+          actions: [
+            KeyboardActionsItem(
+              focusNode: _amountFocusNode,
+              toolbarButtons: [(_) => KeyboardDoneButton()],
+            ),
+          ]),
+      child: Container(
+        color: Theme.of(context).colorScheme.background,
+        child: ScrollableWithBottomSection(
+          contentPadding: EdgeInsets.only(bottom: 24),
+          content: Container(
+            decoration: ResponsiveLayoutUtil.instance.isMobile ? BoxDecoration(
+              borderRadius: BorderRadius.only(
+                  bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
+              gradient: LinearGradient(
+                colors: [
+                  Theme.of(context).extension<ExchangePageTheme>()!.firstGradientTopPanelColor,
+                  Theme.of(context).extension<ExchangePageTheme>()!.secondGradientTopPanelColor,
+                ],
+                begin: Alignment.topLeft,
+                end: Alignment.bottomRight,
               ),
-            ]),
-        child: Container(
-          color: Theme.of(context).colorScheme.background,
-          child: ScrollableWithBottomSection(
-            contentPadding: EdgeInsets.only(bottom: 24),
-            content: Container(
-              decoration: ResponsiveLayoutUtil.instance.isMobile
-                  ? BoxDecoration(
-                      borderRadius: BorderRadius.only(
-                          bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
-                      gradient: LinearGradient(
-                        colors: [
-                          Theme.of(context).extension<ExchangePageTheme>()!.firstGradientTopPanelColor,
-                          Theme.of(context).extension<ExchangePageTheme>()!.secondGradientTopPanelColor,
-                        ],
-                        begin: Alignment.topLeft,
-                        end: Alignment.bottomRight,
-                      ),
-                    )
-                  : null,
+              ) : null,
               child: Observer(builder: (_) {
                 return Padding(
                   padding: EdgeInsets.fromLTRB(24, 120, 24, 0),
diff --git a/lib/src/screens/restore/restore_options_page.dart b/lib/src/screens/restore/restore_options_page.dart
index 93a44c752..8735ff1d3 100644
--- a/lib/src/screens/restore/restore_options_page.dart
+++ b/lib/src/screens/restore/restore_options_page.dart
@@ -75,7 +75,7 @@ class RestoreOptionsPage extends BasePage {
                             await restoreFromQRViewModel.create(restoreWallet: restoreWallet);
                             if (restoreFromQRViewModel.state is FailureState) {
                               _onWalletCreateFailure(context,
-                                  'Create wallet state: ${restoreFromQRViewModel.state.runtimeType.toString()}');
+                                  'Create wallet state: ${(restoreFromQRViewModel.state as FailureState).error}');
                             }
                           } catch (e) {
                             _onWalletCreateFailure(context, e.toString());
diff --git a/lib/src/screens/restore/restore_wallet_from_seed_details.dart b/lib/src/screens/restore/restore_wallet_from_seed_details.dart
deleted file mode 100644
index 8d08c441d..000000000
--- a/lib/src/screens/restore/restore_wallet_from_seed_details.dart
+++ /dev/null
@@ -1,145 +0,0 @@
-import 'package:cake_wallet/utils/show_pop_up.dart';
-import 'package:mobx/mobx.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_mobx/flutter_mobx.dart';
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/core/wallet_name_validator.dart';
-import 'package:cake_wallet/core/execution_state.dart';
-import 'package:cake_wallet/src/screens/base_page.dart';
-import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
-import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
-import 'package:cake_wallet/src/widgets/primary_button.dart';
-import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
-import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
-import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
-
-class RestoreWalletFromSeedDetailsPage extends BasePage {
-  RestoreWalletFromSeedDetailsPage(
-      {required this.walletRestorationFromSeedVM});
-
-  final WalletRestorationFromSeedVM walletRestorationFromSeedVM;
-
-  @override
-  String get title => S.current.restore_wallet_restore_description;
-
-  @override
-  Widget body(BuildContext context) => RestoreFromSeedDetailsForm(
-      walletRestorationFromSeedVM: walletRestorationFromSeedVM);
-}
-
-class RestoreFromSeedDetailsForm extends StatefulWidget {
-  RestoreFromSeedDetailsForm({required this.walletRestorationFromSeedVM});
-
-  final WalletRestorationFromSeedVM walletRestorationFromSeedVM;
-
-  @override
-  _RestoreFromSeedDetailsFormState createState() =>
-      _RestoreFromSeedDetailsFormState();
-}
-
-class _RestoreFromSeedDetailsFormState
-    extends State<RestoreFromSeedDetailsForm> {
-  final _formKey = GlobalKey<FormState>();
-  final _blockchainHeightKey = GlobalKey<BlockchainHeightState>();
-  final _nameController = TextEditingController();
-  ReactionDisposer? _stateReaction;
-
-  @override
-  void initState() {
-    _stateReaction = reaction((_) => widget.walletRestorationFromSeedVM.state,
-        (ExecutionState state) {
-      if (state is ExecutedSuccessfullyState) {
-        Navigator.of(context).popUntil((route) => route.isFirst);
-      }
-
-      if (state is FailureState) {
-        WidgetsBinding.instance.addPostFrameCallback((_) {
-          showPopUp<void>(
-              context: context,
-              builder: (BuildContext context) {
-                return AlertWithOneAction(
-                    alertTitle: S.current.restore_title_from_seed,
-                    alertContent: state.error,
-                    buttonText: S.of(context).ok,
-                    buttonAction: () => Navigator.of(context).pop());
-              });
-        });
-      }
-    });
-
-    _nameController.addListener(
-        () => widget.walletRestorationFromSeedVM.name = _nameController.text);
-    super.initState();
-  }
-
-  @override
-  void dispose() {
-    _nameController.dispose();
-    _stateReaction?.reaction.dispose();
-    super.dispose();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return Container(
-      padding: EdgeInsets.only(left: 24, right: 24),
-      child: ScrollableWithBottomSection(
-        contentPadding: EdgeInsets.only(bottom: 24.0),
-        content: Form(
-          key: _formKey,
-          child: Column(children: <Widget>[
-            Row(
-              children: <Widget>[
-                Flexible(
-                    child: Container(
-                  padding: EdgeInsets.only(top: 20.0),
-                  child: BaseTextFormField(
-                    controller: _nameController,
-                    hintText: S.of(context).restore_wallet_name,
-                    validator: WalletNameValidator(),
-                  ),
-                ))
-              ],
-            ),
-            if (widget.walletRestorationFromSeedVM.hasRestorationHeight) ... [
-              BlockchainHeightWidget(
-                  key: _blockchainHeightKey,
-                  onHeightChange: (height) {
-                    widget.walletRestorationFromSeedVM.height = height;
-                    print(height);
-                  }),
-              Padding(
-                padding: EdgeInsets.only(left: 40, right: 40, top: 24),
-                child: Text(
-                  S.of(context).restore_from_date_or_blockheight,
-                  textAlign: TextAlign.center,
-                  style: TextStyle(
-                      fontSize: 12,
-                      fontWeight: FontWeight.normal,
-                      color: Theme.of(context).hintColor
-                  ),
-                ),
-              )
-            ]
-          ]),
-        ),
-        bottomSectionPadding: EdgeInsets.only(bottom: 24),
-        bottomSection: Observer(builder: (_) {
-          return LoadingPrimaryButton(
-            onPressed: () {
-              if (_formKey.currentState != null && _formKey.currentState!.validate()) {
-                widget.walletRestorationFromSeedVM.create();
-              }
-            },
-            isLoading:
-                widget.walletRestorationFromSeedVM.state is IsExecutingState,
-            text: S.of(context).restore_recover,
-            color: Theme.of(context).primaryColor,
-            textColor: Colors.white,
-            isDisabled: _nameController.text.isNotEmpty,
-          );
-        }),
-      ),
-    );
-  }
-}
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 7c137966e..9db82db0b 100644
--- a/lib/src/screens/restore/wallet_restore_from_keys_form.dart
+++ b/lib/src/screens/restore/wallet_restore_from_keys_form.dart
@@ -1,29 +1,29 @@
+import 'package:cake_wallet/src/widgets/address_text_field.dart';
 import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
 import 'package:cw_core/wallet_type.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
 import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
-import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
-import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/core/wallet_name_validator.dart';
 import 'package:cake_wallet/entities/generate_name.dart';
 import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
+import 'package:flutter/services.dart';
 
 class WalletRestoreFromKeysFrom extends StatefulWidget {
   WalletRestoreFromKeysFrom({
     required this.walletRestoreViewModel,
+    required this.displayPrivateKeyField,
+    required this.onHeightOrDateEntered,
     required this.displayWalletPassword,
     required this.onRepeatedPasswordChange,
     this.onPasswordChange,
     Key? key,
-    this.onHeightOrDateEntered,})
-      : super(key: key);
+  }) : super(key: key);
 
-  final Function(bool)? onHeightOrDateEntered;
+  final Function(bool) onHeightOrDateEntered;
   final WalletRestoreViewModel walletRestoreViewModel;
+  final bool displayPrivateKeyField;
   final bool displayWalletPassword;
   final void Function(String)? onPasswordChange;
   final void Function(String)? onRepeatedPasswordChange;
@@ -41,6 +41,7 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
         addressController = TextEditingController(),
         viewKeyController = TextEditingController(),
         spendKeyController = TextEditingController(),
+        privateKeyController = TextEditingController(),
         nameTextEditingController = TextEditingController(),
         passwordTextEditingController = displayWalletPassword ? TextEditingController() : null,
         repeatedPasswordTextEditingController = displayWalletPassword ? TextEditingController() : null;
@@ -52,6 +53,7 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
   final TextEditingController viewKeyController;
   final TextEditingController spendKeyController;
   final TextEditingController nameTextEditingController;
+  final TextEditingController privateKeyController;
   final TextEditingController? passwordTextEditingController;
   final TextEditingController? repeatedPasswordTextEditingController;
   void Function()? passwordListener;
@@ -69,6 +71,12 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
       repeatedPasswordTextEditingController?.addListener(repeatedPasswordListener!);
     }
     super.initState();
+
+    privateKeyController.addListener(() {
+      if (privateKeyController.text.isNotEmpty) {
+        widget.onHeightOrDateEntered(true);
+      }
+    });
   }
 
 
@@ -78,6 +86,7 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
     addressController.dispose();
     viewKeyController.dispose();
     spendKeyController.dispose();
+    privateKeyController.dispose();
     passwordTextEditingController?.dispose();
     if (passwordListener != null) {
       passwordTextEditingController?.removeListener(passwordListener!);
@@ -92,10 +101,11 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
   @override
   Widget build(BuildContext context) {
     return Container(
-        padding: EdgeInsets.only(left: 24, right: 24),
-        child: Form(
-          key: formKey,
-          child: Column(children: <Widget>[
+      padding: EdgeInsets.only(left: 24, right: 24),
+      child: Form(
+        key: formKey,
+        child: Column(
+          children: <Widget>[
             Stack(
               alignment: Alignment.centerRight,
               children: [
@@ -110,9 +120,8 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
 
                       setState(() {
                         nameTextEditingController.text = rName;
-                        nameTextEditingController.selection =
-                            TextSelection.fromPosition(TextPosition(
-                                offset: nameTextEditingController.text.length));
+                        nameTextEditingController.selection = TextSelection.fromPosition(
+                            TextPosition(offset: nameTextEditingController.text.length));
                       });
                     },
                     icon: Container(
@@ -125,7 +134,8 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
                       height: 34,
                       child: Image.asset(
                         'assets/images/refresh_icon.png',
-                        color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor,
+                        color:
+                            Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor,
                       ),
                     ),
                   ),
@@ -146,29 +156,65 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
                     hintText: S.of(context).repeate_wallet_password,
                     obscureText: true))],
             Container(height: 20),
-            BaseTextFormField(
-                controller: addressController,
-                keyboardType: TextInputType.multiline,
-                maxLines: null,
-                hintText: S.of(context).restore_address),
-            Container(
-                padding: EdgeInsets.only(top: 20.0),
-                child: BaseTextFormField(
-                    controller: viewKeyController,
-                    hintText: S.of(context).restore_view_key_private,
-                    maxLines: null)),
-            Container(
-                padding: EdgeInsets.only(top: 20.0),
-                child: BaseTextFormField(
-                    controller: spendKeyController,
-                    hintText: S.of(context).restore_spend_key_private,
-                    maxLines: null)),
-            BlockchainHeightWidget(
-                key: blockchainHeightKey,
-                hasDatePicker: widget.walletRestoreViewModel.type != WalletType.haven,
-                onHeightChange: (_) => null,
-                onHeightOrDateEntered: widget.onHeightOrDateEntered)
-          ]),
-        ));
+            _restoreFromKeysFormFields(),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget _restoreFromKeysFormFields() {
+    if (widget.displayPrivateKeyField) {
+      return AddressTextField(
+        controller: privateKeyController,
+        placeholder: S.of(context).private_key,
+        options: [AddressTextFieldOption.paste],
+        buttonColor: Theme.of(context).hintColor,
+        onPushPasteButton: (_) {
+          _pasteText();
+        },
+      );
+    }
+
+    return Column(
+      children: [
+        BaseTextFormField(
+          controller: addressController,
+          keyboardType: TextInputType.multiline,
+          maxLines: null,
+          hintText: S.of(context).restore_address,
+        ),
+        Container(
+          padding: EdgeInsets.only(top: 20.0),
+          child: BaseTextFormField(
+            controller: viewKeyController,
+            hintText: S.of(context).restore_view_key_private,
+            maxLines: null,
+          ),
+        ),
+        Container(
+          padding: EdgeInsets.only(top: 20.0),
+          child: BaseTextFormField(
+            controller: spendKeyController,
+            hintText: S.of(context).restore_spend_key_private,
+            maxLines: null,
+          ),
+        ),
+        BlockchainHeightWidget(
+          key: blockchainHeightKey,
+          hasDatePicker: widget.walletRestoreViewModel.type != WalletType.haven,
+          onHeightChange: (_) => null,
+          onHeightOrDateEntered: widget.onHeightOrDateEntered,
+        ),
+      ],
+    );
+  }
+
+  Future<void> _pasteText() async {
+    final value = await Clipboard.getData('text/plain');
+
+    if (value?.text?.isNotEmpty ?? false) {
+      privateKeyController.text = value!.text!;
+    }
   }
 }
diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart
index 8c4dd646d..7c1583b1e 100644
--- a/lib/src/screens/restore/wallet_restore_page.dart
+++ b/lib/src/screens/restore/wallet_restore_page.dart
@@ -1,10 +1,7 @@
 import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
-import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
-import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
 import 'package:cw_core/wallet_type.dart';
-import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:keyboard_actions/keyboard_actions.dart';
 import 'package:mobx/mobx.dart';
@@ -19,10 +16,6 @@ import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.da
 import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
 import 'package:cake_wallet/src/widgets/primary_button.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
-import 'package:cake_wallet/core/validator.dart';
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
-import 'package:cake_wallet/core/seed_validator.dart';
 import 'package:cake_wallet/view_model/restore/restore_mode.dart';
 import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
 
@@ -79,6 +72,7 @@ class WalletRestorePage extends BasePage {
           _pages.add(WalletRestoreFromKeysFrom(
               key: walletRestoreFromKeysFormKey,
               walletRestoreViewModel: walletRestoreViewModel,
+              displayPrivateKeyField: walletRestoreViewModel.hasRestoreFromPrivateKey,
               displayWalletPassword: walletRestoreViewModel.hasWalletPassword,
               onPasswordChange: (String password) => walletRestoreViewModel.walletPassword = password,
               onRepeatedPasswordChange: (String repeatedPassword) => walletRestoreViewModel.repeatedWalletPassword = repeatedPassword,
@@ -201,8 +195,12 @@ class WalletRestorePage extends BasePage {
                       return LoadingPrimaryButton(
                         onPressed: _confirmForm,
                         text: S.of(context).restore_recover,
-                        color: Theme.of(context).extension<WalletListTheme>()!.createNewWalletButtonBackgroundColor,
-                        textColor: Theme.of(context).extension<WalletListTheme>()!.restoreWalletButtonTextColor,
+                        color: Theme.of(context)
+                            .extension<WalletListTheme>()!
+                            .createNewWalletButtonBackgroundColor,
+                        textColor: Theme.of(context)
+                            .extension<WalletListTheme>()!
+                            .restoreWalletButtonTextColor,
                         isLoading: walletRestoreViewModel.state is IsExecutingState,
                         isDisabled: !walletRestoreViewModel.isButtonEnabled,
                       );
@@ -254,11 +252,18 @@ class WalletRestorePage extends BasePage {
       credentials['name'] =
           walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.text;
     } else {
-      credentials['address'] = walletRestoreFromKeysFormKey.currentState!.addressController.text;
-      credentials['viewKey'] = walletRestoreFromKeysFormKey.currentState!.viewKeyController.text;
-      credentials['spendKey'] = walletRestoreFromKeysFormKey.currentState!.spendKeyController.text;
-      credentials['height'] =
-          walletRestoreFromKeysFormKey.currentState!.blockchainHeightKey.currentState!.height;
+      if (walletRestoreViewModel.hasRestoreFromPrivateKey) {
+        credentials['private_key'] =
+            walletRestoreFromKeysFormKey.currentState!.privateKeyController.text;
+      } else {
+        credentials['address'] = walletRestoreFromKeysFormKey.currentState!.addressController.text;
+        credentials['viewKey'] = walletRestoreFromKeysFormKey.currentState!.viewKeyController.text;
+        credentials['spendKey'] =
+            walletRestoreFromKeysFormKey.currentState!.spendKeyController.text;
+        credentials['height'] =
+            walletRestoreFromKeysFormKey.currentState!.blockchainHeightKey.currentState!.height;
+      }
+
       credentials['name'] =
           walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.text;
     }
@@ -267,6 +272,8 @@ class WalletRestorePage extends BasePage {
   }
 
   void _confirmForm() {
+    // Dismissing all visible keyboard to provide context for navigation
+    FocusManager.instance.primaryFocus?.unfocus();
     final formContext = walletRestoreViewModel.mode == WalletRestoreMode.seed
         ? walletRestoreFromSeedFormKey.currentContext
         : walletRestoreFromKeysFormKey.currentContext;
diff --git a/lib/src/screens/restore/widgets/backup_file_button.dart b/lib/src/screens/restore/widgets/backup_file_button.dart
new file mode 100644
index 000000000..e69de29bb
diff --git a/lib/src/screens/restore/widgets/restore_button.dart b/lib/src/screens/restore/widgets/restore_button.dart
index 380f3cd21..c196de059 100644
--- a/lib/src/screens/restore/widgets/restore_button.dart
+++ b/lib/src/screens/restore/widgets/restore_button.dart
@@ -1,14 +1,13 @@
 import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
-import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
 
 class RestoreButton extends StatelessWidget {
-  const RestoreButton({
-    required this.onPressed,
-    required this.image,
-    required this.title,
-    required this.description});
+  const RestoreButton(
+      {required this.onPressed,
+      required this.image,
+      required this.title,
+      required this.description});
 
   final VoidCallback onPressed;
   final Image image;
diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart
index 09df0ba83..82e2842f7 100644
--- a/lib/src/screens/send/send_page.dart
+++ b/lib/src/screens/send/send_page.dart
@@ -100,7 +100,7 @@ class SendPage extends BasePage {
   AppBarStyle get appBarStyle => AppBarStyle.transparent;
 
   double _sendCardHeight(BuildContext context) {
-    final double initialHeight = sendViewModel.isElectrumWallet ? 490 : 465;
+    final double initialHeight = sendViewModel.hasCoinControl ? 490 : 465;
 
     if (!ResponsiveLayoutUtil.instance.isMobile) {
       return initialHeight - 66;
diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart
index 4b2cddeb7..04fded5c8 100644
--- a/lib/src/screens/send/widgets/send_card.dart
+++ b/lib/src/screens/send/widgets/send_card.dart
@@ -496,7 +496,7 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
                         ),
                       ),
                     ),
-                    if (sendViewModel.isElectrumWallet)
+                    if (sendViewModel.hasCoinControl)
                       Padding(
                         padding: EdgeInsets.only(top: 6),
                         child: GestureDetector(
diff --git a/lib/src/screens/settings/display_settings_page.dart b/lib/src/screens/settings/display_settings_page.dart
index b510516dc..6e572abe0 100644
--- a/lib/src/screens/settings/display_settings_page.dart
+++ b/lib/src/screens/settings/display_settings_page.dart
@@ -6,6 +6,7 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.da
 import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
 import 'package:cake_wallet/src/screens/settings/widgets/settings_theme_choice.dart';
 import 'package:cake_wallet/utils/device_info.dart';
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
 import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
@@ -26,11 +27,11 @@ class DisplaySettingsPage extends BasePage {
         child: Column(
           children: [
             SettingsSwitcherCell(
-            title: S.current.settings_display_balance,
-            value:  _displaySettingsViewModel.shouldDisplayBalance,
-            onValueChange: (_, bool value) {
-               _displaySettingsViewModel.setShouldDisplayBalance(value);          
-            }),
+                title: S.current.settings_display_balance,
+                value: _displaySettingsViewModel.shouldDisplayBalance,
+                onValueChange: (_, bool value) {
+                  _displaySettingsViewModel.setShouldDisplayBalance(value);
+                }),
             SettingsSwitcherCell(
               title: S.current.show_market_place,
               value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard,
@@ -39,14 +40,17 @@ class DisplaySettingsPage extends BasePage {
               },
             ),
             //if (!isHaven) it does not work correctly
-            if(!_displaySettingsViewModel.disabledFiatApiMode)
+            if (!_displaySettingsViewModel.disabledFiatApiMode)
               SettingsPickerCell<FiatCurrency>(
                 title: S.current.settings_currency,
                 searchHintText: S.current.search_currency,
                 items: FiatCurrency.all,
                 selectedItem: _displaySettingsViewModel.fiatCurrency,
-                onItemSelected: (FiatCurrency currency) => _displaySettingsViewModel.setFiatCurrency(currency),
-                images: FiatCurrency.all.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png")).toList(),
+                onItemSelected: (FiatCurrency currency) =>
+                    _displaySettingsViewModel.setFiatCurrency(currency),
+                images: FiatCurrency.all
+                    .map((e) => Image.asset("assets/images/flags/${e.countryCode}.png"))
+                    .toList(),
                 isGridView: true,
                 matchingCriteria: (FiatCurrency currency, String searchText) {
                   return currency.title.toLowerCase().contains(searchText) ||
@@ -63,13 +67,14 @@ class DisplaySettingsPage extends BasePage {
               selectedItem: _displaySettingsViewModel.languageCode,
               onItemSelected: _displaySettingsViewModel.onLanguageSelected,
               images: LanguageService.list.keys
-                  .map((e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
+                  .map((e) => Image.asset(
+                      "assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
                   .toList(),
               matchingCriteria: (String code, String searchText) {
                 return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
               },
             ),
-            if (DeviceInfo.instance.isMobile)
+            if (ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile)
               SettingsThemeChoicesCell(_displaySettingsViewModel),
           ],
         ),
diff --git a/lib/src/screens/settings/manage_nodes_page.dart b/lib/src/screens/settings/manage_nodes_page.dart
index 0a67f0502..4b1034f2b 100644
--- a/lib/src/screens/settings/manage_nodes_page.dart
+++ b/lib/src/screens/settings/manage_nodes_page.dart
@@ -42,36 +42,40 @@ class ManageNodesPage extends BasePage {
                     return nodeListViewModel.nodes.length;
                   },
                   itemBuilder: (_, index) {
-                    final node = nodeListViewModel.nodes[index];
-                    final isSelected = node.keyIndex == nodeListViewModel.currentNode.keyIndex;
-                    final nodeListRow = NodeListRow(
-                      title: node.uriRaw,
-                      node: node,
-                      isSelected: isSelected,
-                      onTap: (_) async {
-                        if (isSelected) {
-                          return;
-                        }
+                    return Observer(
+                      builder: (context) {
+                        final node = nodeListViewModel.nodes[index];
+                        final isSelected = node.keyIndex == nodeListViewModel.currentNode.keyIndex;
+                        final nodeListRow = NodeListRow(
+                          title: node.uriRaw,
+                          node: node,
+                          isSelected: isSelected,
+                          onTap: (_) async {
+                            if (isSelected) {
+                              return;
+                            }
 
-                        await showPopUp<void>(
-                            context: context,
-                            builder: (BuildContext context) {
-                              return AlertWithTwoActions(
-                                alertTitle: S.of(context).change_current_node_title,
-                                alertContent: nodeListViewModel.getAlertContent(node.uriRaw),
-                                leftButtonText: S.of(context).cancel,
-                                rightButtonText: S.of(context).change,
-                                actionLeftButton: () => Navigator.of(context).pop(),
-                                actionRightButton: () async {
-                                  await nodeListViewModel.setAsCurrent(node);
-                                  Navigator.of(context).pop();
-                                },
-                              );
-                            });
+                            await showPopUp<void>(
+                              context: context,
+                              builder: (BuildContext context) {
+                                return AlertWithTwoActions(
+                                  alertTitle: S.of(context).change_current_node_title,
+                                  alertContent: nodeListViewModel.getAlertContent(node.uriRaw),
+                                  leftButtonText: S.of(context).cancel,
+                                  rightButtonText: S.of(context).change,
+                                  actionLeftButton: () => Navigator.of(context).pop(),
+                                  actionRightButton: () async {
+                                    await nodeListViewModel.setAsCurrent(node);
+                                    Navigator.of(context).pop();
+                                  },
+                                );
+                              },
+                            );
+                          },
+                        );
+                        return nodeListRow;
                       },
                     );
-
-                    return nodeListRow;
                   },
                 ),
               );
diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart
index ae6bfe6c8..e953fd4ee 100644
--- a/lib/src/screens/settings/privacy_page.dart
+++ b/lib/src/screens/settings/privacy_page.dart
@@ -50,6 +50,14 @@ class PrivacyPage extends BasePage {
                 onValueChange: (BuildContext _, bool value) {
                   _privacySettingsViewModel.setShouldSaveRecipientAddress(value);
                 }),
+            if (_privacySettingsViewModel.isAutoGenerateSubaddressesVisible)
+              SettingsSwitcherCell(
+                title: S.current.auto_generate_subaddresses,
+                value: _privacySettingsViewModel.isAutoGenerateSubaddressesEnabled,
+                onValueChange: (BuildContext _, bool value) {
+                  _privacySettingsViewModel.setAutoGenerateSubaddresses(value);
+                },
+              ),
             if (DeviceInfo.instance.isMobile)
               SettingsSwitcherCell(
                   title: S.current.prevent_screenshots,
diff --git a/lib/src/screens/settings/widgets/settings_cell_with_arrow.dart b/lib/src/screens/settings/widgets/settings_cell_with_arrow.dart
index d11761f67..f0e19a715 100644
--- a/lib/src/screens/settings/widgets/settings_cell_with_arrow.dart
+++ b/lib/src/screens/settings/widgets/settings_cell_with_arrow.dart
@@ -9,4 +9,4 @@ class SettingsCellWithArrow extends StandardListRow {
   @override
   Widget buildTrailing(BuildContext context) => Image.asset('assets/images/select_arrow.png',
       color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor);
-}
\ No newline at end of file
+}
diff --git a/lib/src/screens/transaction_details/transaction_details_page.dart b/lib/src/screens/transaction_details/transaction_details_page.dart
index 96f67424c..a6f60a52d 100644
--- a/lib/src/screens/transaction_details/transaction_details_page.dart
+++ b/lib/src/screens/transaction_details/transaction_details_page.dart
@@ -21,7 +21,6 @@ class TransactionDetailsPage extends BasePage {
 
   @override
   Widget body(BuildContext context) {
-    // FIX-ME: Added `context` it was not used here before, maby bug ?
     return SectionStandardList(
         sectionCount: 1,
         itemCounter: (int _) => transactionDetailsViewModel.items.length,
diff --git a/lib/src/screens/transaction_details/widgets/textfield_list_row.dart b/lib/src/screens/transaction_details/widgets/textfield_list_row.dart
index 2c7934d19..ff5513502 100644
--- a/lib/src/screens/transaction_details/widgets/textfield_list_row.dart
+++ b/lib/src/screens/transaction_details/widgets/textfield_list_row.dart
@@ -6,11 +6,12 @@ import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
 class TextFieldListRow extends StatelessWidget {
   TextFieldListRow(
       {required this.title,
-        required this.value,
-        this.titleFontSize = 14,
-        this.valueFontSize = 16,
-        this.onSubmitted})
-    : _textController = TextEditingController() {
+      required this.value,
+      this.titleFontSize = 14,
+      this.valueFontSize = 16,
+      this.onSubmitted,
+      this.onTapOutside})
+      : _textController = TextEditingController() {
     _textController.text = value;
   }
 
@@ -19,6 +20,7 @@ class TextFieldListRow extends StatelessWidget {
   final double titleFontSize;
   final double valueFontSize;
   final Function(String value)? onSubmitted;
+  final Function(String value)? onTapOutside;
   final TextEditingController _textController;
 
   @override
@@ -58,6 +60,7 @@ class TextFieldListRow extends StatelessWidget {
                         fontWeight: FontWeight.w500,
                         color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor),
                     border: InputBorder.none),
+                onTapOutside: (_) => onTapOutside?.call(_textController.text),
                 onSubmitted: (value) => onSubmitted?.call(value),
               )
             ]),
diff --git a/lib/src/screens/unspent_coins/unspent_coins_details_page.dart b/lib/src/screens/unspent_coins/unspent_coins_details_page.dart
index dfa8e8435..61689b52a 100644
--- a/lib/src/screens/unspent_coins/unspent_coins_details_page.dart
+++ b/lib/src/screens/unspent_coins/unspent_coins_details_page.dart
@@ -24,7 +24,6 @@ class UnspentCoinsDetailsPage extends BasePage {
 
   @override
   Widget body(BuildContext context) {
-    // FIX-ME: Added `context` it was not used here before, maby bug ?
     return SectionStandardList(
         sectionCount: 1,
         itemCounter: (int _) => unspentCoinsDetailsViewModel.items.length,
@@ -45,6 +44,7 @@ class UnspentCoinsDetailsPage extends BasePage {
             return TextFieldListRow(
               title: item.title,
               value: item.value,
+              onTapOutside: item.onSubmitted,
               onSubmitted: item.onSubmitted,
             );
           }
diff --git a/lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart b/lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart
index 154c3a2f5..93cf27af1 100644
--- a/lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart
+++ b/lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart
@@ -94,7 +94,7 @@ class UnspentCoinsListItem extends StatelessWidget {
                       crossAxisAlignment: CrossAxisAlignment.center,
                       children: [
                         AutoSizeText(
-                          address,
+                          '${address.substring(0, 5)}...${address.substring(address.length-5)}', // ToDo: Maybe use address label
                           style: TextStyle(
                             color: addressColor,
                             fontSize: 12,
diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart
index 2c729d20c..a20b534f9 100644
--- a/lib/src/screens/wallet_list/wallet_list_page.dart
+++ b/lib/src/screens/wallet_list/wallet_list_page.dart
@@ -1,10 +1,12 @@
 import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cake_wallet/main.dart';
 import 'package:cake_wallet/src/screens/auth/auth_page.dart';
+import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cake_wallet/core/auth_service.dart';
 import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
 import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
 import 'package:cake_wallet/store/settings_store.dart';
+import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
 import 'package:cake_wallet/utils/responsive_layout_util.dart';
 import 'package:cake_wallet/utils/show_bar.dart';
 import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
diff --git a/lib/src/widgets/search_bar_widget.dart b/lib/src/widgets/search_bar_widget.dart
index bdb520d55..731fbf632 100644
--- a/lib/src/widgets/search_bar_widget.dart
+++ b/lib/src/widgets/search_bar_widget.dart
@@ -17,24 +17,21 @@ class SearchBarWidget extends StatelessWidget {
   Widget build(BuildContext context) {
     return TextFormField(
       controller: searchController,
-      style: TextStyle(
-          color: Theme.of(context).extension<PickerTheme>()!.searchTextColor),
+      style: TextStyle(color: Theme.of(context).extension<PickerTheme>()!.searchTextColor),
       decoration: InputDecoration(
         hintText: hintText ?? S.of(context).search_currency,
-        hintStyle: TextStyle(
-            color: Theme.of(context).extension<PickerTheme>()!.searchHintColor),
+        hintStyle: TextStyle(color: Theme.of(context).extension<PickerTheme>()!.searchHintColor),
         prefixIcon: Image.asset("assets/images/search_icon.png",
             color: Theme.of(context).extension<PickerTheme>()!.searchIconColor),
         filled: true,
-        fillColor: Theme.of(context)
-            .extension<PickerTheme>()!
-            .searchBackgroundFillColor,
+        fillColor: Theme.of(context).extension<PickerTheme>()!.searchBackgroundFillColor,
         alignLabelWithHint: false,
         contentPadding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
         enabledBorder: OutlineInputBorder(
             borderRadius: BorderRadius.circular(borderRadius),
-            borderSide: const BorderSide(
-              color: Colors.transparent,
+            borderSide: BorderSide(
+              color: Theme.of(context).extension<PickerTheme>()!.searchBorderColor ??
+                  Colors.transparent,
             )),
         focusedBorder: OutlineInputBorder(
             borderRadius: BorderRadius.circular(borderRadius),
diff --git a/lib/src/widgets/seed_widget.dart b/lib/src/widgets/seed_widget.dart
index ddafa924b..7015e0acf 100644
--- a/lib/src/widgets/seed_widget.dart
+++ b/lib/src/widgets/seed_widget.dart
@@ -1,16 +1,9 @@
 import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:cake_wallet/src/widgets/validable_annotated_editable_text.dart';
-import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
-import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-import 'package:cake_wallet/palette.dart';
 import 'package:cake_wallet/core/seed_validator.dart';
-import 'package:cake_wallet/src/widgets/primary_button.dart';
-import 'package:cake_wallet/entities/mnemonic_item.dart';
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:flutter/widgets.dart';
 import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
 
 class SeedWidget extends StatefulWidget {
diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart
index 17acf9c59..e04003e61 100644
--- a/lib/store/settings_store.dart
+++ b/lib/store/settings_store.dart
@@ -1,6 +1,7 @@
 import 'dart:io';
 
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
+import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
 import 'package:cake_wallet/entities/cake_2fa_preset_options.dart';
 import 'package:cake_wallet/entities/background_tasks.dart';
 import 'package:cake_wallet/entities/exchange_api_mode.dart';
@@ -43,6 +44,7 @@ abstract class SettingsStoreBase with Store {
       required FiatCurrency initialFiatCurrency,
       required BalanceDisplayMode initialBalanceDisplayMode,
       required bool initialSaveRecipientAddress,
+      required AutoGenerateSubaddressStatus initialAutoGenerateSubaddressStatus,
       required bool initialAppSecure,
       required bool initialDisableBuy,
       required bool initialDisableSell,
@@ -88,6 +90,7 @@ abstract class SettingsStoreBase with Store {
         fiatCurrency = initialFiatCurrency,
         balanceDisplayMode = initialBalanceDisplayMode,
         shouldSaveRecipientAddress = initialSaveRecipientAddress,
+        autoGenerateSubaddressStatus = initialAutoGenerateSubaddressStatus,
         fiatApiMode = initialFiatMode,
         allowBiometricalAuthentication = initialAllowBiometricalAuthentication,
         selectedCake2FAPreset = initialCake2FAPresetOptions,
@@ -198,6 +201,11 @@ abstract class SettingsStoreBase with Store {
         (bool disableSell) =>
             sharedPreferences.setBool(PreferencesKey.disableSellKey, disableSell));
 
+    reaction(
+        (_) => autoGenerateSubaddressStatus,
+        (AutoGenerateSubaddressStatus autoGenerateSubaddressStatus) => sharedPreferences.setInt(
+            PreferencesKey.autoGenerateSubaddressStatusKey, autoGenerateSubaddressStatus.value));
+
     reaction(
         (_) => fiatApiMode,
         (FiatApiMode mode) =>
@@ -339,6 +347,7 @@ abstract class SettingsStoreBase with Store {
   static const defaultActionsMode = 11;
   static const defaultPinCodeTimeOutDuration = PinCodeRequiredDuration.tenminutes;
   static final walletPasswordDirectInput = Platform.isLinux;
+  static const defaultAutoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.initialized;
 
   @observable
   FiatCurrency fiatCurrency;
@@ -361,6 +370,9 @@ abstract class SettingsStoreBase with Store {
   @observable
   bool shouldSaveRecipientAddress;
 
+  @observable
+  AutoGenerateSubaddressStatus autoGenerateSubaddressStatus;
+
   @observable
   bool isAppSecure;
 
@@ -601,14 +613,15 @@ abstract class SettingsStoreBase with Store {
     final litecoinElectrumServer = nodeSource.get(litecoinElectrumServerId);
     final havenNode = nodeSource.get(havenNodeId);
     final ethereumNode = nodeSource.get(ethereumNodeId);
+    final packageInfo = await PackageInfo.fromPlatform();
     final deviceName = await _getDeviceName() ?? '';
     final shouldShowYatPopup = sharedPreferences.getBool(PreferencesKey.shouldShowYatPopup) ?? true;
-    var appVersion = '';
+    final generateSubaddresses =
+        sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey);
 
-    try {
-      final packageInfo = await PackageInfo.fromPlatform();
-      appVersion = packageInfo.version;
-    } catch(_) {}
+    final autoGenerateSubaddressStatus = generateSubaddresses != null
+        ? AutoGenerateSubaddressStatus.deserialize(raw: generateSubaddresses)
+        : defaultAutoGenerateSubaddressStatus;
 
     final nodes = <WalletType, Node>{};
 
@@ -641,12 +654,13 @@ abstract class SettingsStoreBase with Store {
         sharedPreferences: sharedPreferences,
         initialShouldShowMarketPlaceInDashboard: shouldShowMarketPlaceInDashboard,
         nodes: nodes,
-        appVersion: appVersion,
+        appVersion: packageInfo.version,
         deviceName: deviceName,
         isBitcoinBuyEnabled: isBitcoinBuyEnabled,
         initialFiatCurrency: currentFiatCurrency,
         initialBalanceDisplayMode: currentBalanceDisplayMode,
         initialSaveRecipientAddress: shouldSaveRecipientAddress,
+        initialAutoGenerateSubaddressStatus: autoGenerateSubaddressStatus,
         initialAppSecure: isAppSecure,
         initialDisableBuy: disableBuy,
         initialDisableSell: disableSell,
@@ -716,6 +730,13 @@ abstract class SettingsStoreBase with Store {
           priority[WalletType.ethereum]!;
     }
 
+    final generateSubaddresses =
+        sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey);
+
+    autoGenerateSubaddressStatus = generateSubaddresses != null
+        ? AutoGenerateSubaddressStatus.deserialize(raw: generateSubaddresses)
+        : defaultAutoGenerateSubaddressStatus;
+
     balanceDisplayMode = BalanceDisplayMode.deserialize(
         raw: sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey)!);
     shouldSaveRecipientAddress =
@@ -726,8 +747,6 @@ abstract class SettingsStoreBase with Store {
 
     numberOfFailedTokenTrials =
         sharedPreferences.getInt(PreferencesKey.failedTotpTokenTrials) ?? numberOfFailedTokenTrials;
-    sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey) ??
-        shouldSaveRecipientAddress;
     isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? isAppSecure;
     disableBuy = sharedPreferences.getBool(PreferencesKey.disableBuyKey) ?? disableBuy;
     disableSell = sharedPreferences.getBool(PreferencesKey.disableSellKey) ?? disableSell;
diff --git a/lib/themes/extensions/picker_theme.dart b/lib/themes/extensions/picker_theme.dart
index afd2268ec..58c7fa3ff 100644
--- a/lib/themes/extensions/picker_theme.dart
+++ b/lib/themes/extensions/picker_theme.dart
@@ -6,13 +6,15 @@ class PickerTheme extends ThemeExtension<PickerTheme> {
   final Color searchBackgroundFillColor;
   final Color searchTextColor;
   final Color? searchHintColor;
+  final Color? searchBorderColor;
 
   PickerTheme(
       {required this.dividerColor,
       this.searchIconColor,
       required this.searchBackgroundFillColor,
       required this.searchTextColor,
-      this.searchHintColor});
+      this.searchHintColor,
+      this.searchBorderColor});
 
   @override
   PickerTheme copyWith(
@@ -20,14 +22,15 @@ class PickerTheme extends ThemeExtension<PickerTheme> {
           Color? searchIconColor,
           Color? searchBackgroundFillColor,
           Color? searchTextColor,
-          Color? searchHintColor}) =>
+          Color? searchHintColor,
+          Color? searchBorderColor}) =>
       PickerTheme(
           dividerColor: dividerColor ?? this.dividerColor,
           searchIconColor: searchIconColor ?? this.searchIconColor,
-          searchBackgroundFillColor:
-              searchBackgroundFillColor ?? this.searchBackgroundFillColor,
+          searchBackgroundFillColor: searchBackgroundFillColor ?? this.searchBackgroundFillColor,
           searchTextColor: searchTextColor ?? this.searchTextColor,
-          searchHintColor: searchHintColor ?? this.searchHintColor);
+          searchHintColor: searchHintColor ?? this.searchHintColor,
+          searchBorderColor: searchBorderColor ?? this.searchBorderColor);
 
   @override
   PickerTheme lerp(ThemeExtension<PickerTheme>? other, double t) {
@@ -36,19 +39,14 @@ class PickerTheme extends ThemeExtension<PickerTheme> {
     }
 
     return PickerTheme(
-        dividerColor:
-            Color.lerp(dividerColor, other.dividerColor, t) ?? dividerColor,
-        searchIconColor:
-            Color.lerp(searchIconColor, other.searchIconColor, t) ??
-                searchIconColor,
-        searchBackgroundFillColor: Color.lerp(searchBackgroundFillColor,
-                other.searchBackgroundFillColor, t) ??
-            searchBackgroundFillColor,
-        searchTextColor:
-            Color.lerp(searchTextColor, other.searchTextColor, t) ??
-                searchTextColor,
-        searchHintColor:
-            Color.lerp(searchHintColor, other.searchHintColor, t) ??
-                searchHintColor);
+        dividerColor: Color.lerp(dividerColor, other.dividerColor, t) ?? dividerColor,
+        searchIconColor: Color.lerp(searchIconColor, other.searchIconColor, t) ?? searchIconColor,
+        searchBackgroundFillColor:
+            Color.lerp(searchBackgroundFillColor, other.searchBackgroundFillColor, t) ??
+                searchBackgroundFillColor,
+        searchTextColor: Color.lerp(searchTextColor, other.searchTextColor, t) ?? searchTextColor,
+        searchHintColor: Color.lerp(searchHintColor, other.searchHintColor, t) ?? searchHintColor,
+        searchBorderColor:
+            Color.lerp(searchBorderColor, other.searchBorderColor, t) ?? searchBorderColor);
   }
 }
diff --git a/lib/themes/high_contrast_theme.dart b/lib/themes/high_contrast_theme.dart
index e43e63020..0483adb38 100644
--- a/lib/themes/high_contrast_theme.dart
+++ b/lib/themes/high_contrast_theme.dart
@@ -39,14 +39,12 @@ class HighContrastTheme extends MoneroLightTheme {
 
   @override
   CakeTextTheme get cakeTextTheme => super.cakeTextTheme.copyWith(
-      buttonTextColor: Colors.white,
-      buttonSecondaryTextColor: Colors.white.withOpacity(0.5));
+      buttonTextColor: Colors.white, buttonSecondaryTextColor: Colors.white.withOpacity(0.5));
 
   @override
-  SyncIndicatorTheme get syncIndicatorStyle =>
-      super.syncIndicatorStyle.copyWith(
-          textColor: colorScheme.background,
-          syncedBackgroundColor: containerColor);
+  SyncIndicatorTheme get syncIndicatorStyle => super
+      .syncIndicatorStyle
+      .copyWith(textColor: colorScheme.background, syncedBackgroundColor: containerColor);
 
   @override
   BalancePageTheme get balancePageTheme => super.balancePageTheme.copyWith(
@@ -56,32 +54,28 @@ class HighContrastTheme extends MoneroLightTheme {
       balanceAmountColor: Colors.white);
 
   @override
-  DashboardPageTheme get dashboardPageTheme =>
-      super.dashboardPageTheme.copyWith(
-          textColor: Colors.black,
-          cardTextColor: Colors.white,
-          mainActionsIconColor: Colors.white,
-          indicatorDotTheme: IndicatorDotTheme(
-              indicatorColor: Colors.grey, activeIndicatorColor: Colors.black));
+  DashboardPageTheme get dashboardPageTheme => super.dashboardPageTheme.copyWith(
+      textColor: Colors.black,
+      cardTextColor: Colors.white,
+      mainActionsIconColor: Colors.white,
+      indicatorDotTheme:
+          IndicatorDotTheme(indicatorColor: Colors.grey, activeIndicatorColor: Colors.black));
 
   @override
-  ExchangePageTheme get exchangePageTheme => super
-      .exchangePageTheme
-      .copyWith(firstGradientTopPanelColor: containerColor);
+  ExchangePageTheme get exchangePageTheme => super.exchangePageTheme.copyWith(
+      firstGradientTopPanelColor: primaryColor, firstGradientBottomPanelColor: containerColor);
 
   @override
   SendPageTheme get sendPageTheme => super.sendPageTheme.copyWith(
       templateTitleColor: Colors.white,
       templateBackgroundColor: Colors.black,
-      firstGradientColor: containerColor);
+      firstGradientColor: primaryColor);
 
   @override
-  AddressTheme get addressTheme =>
-      super.addressTheme.copyWith(actionButtonColor: Colors.grey);
+  AddressTheme get addressTheme => super.addressTheme.copyWith(actionButtonColor: Colors.grey);
 
   @override
-  FilterTheme get filterTheme =>
-      super.filterTheme.copyWith(iconColor: Colors.white);
+  FilterTheme get filterTheme => super.filterTheme.copyWith(iconColor: Colors.white);
 
   @override
   CakeMenuTheme get menuTheme => super.menuTheme.copyWith(
@@ -91,10 +85,11 @@ class HighContrastTheme extends MoneroLightTheme {
 
   @override
   PickerTheme get pickerTheme => super.pickerTheme.copyWith(
-      searchIconColor: Colors.white,
-      searchHintColor: Colors.white,
-      searchTextColor: Colors.white,
-      searchBackgroundFillColor: Colors.grey);
+      searchIconColor: primaryColor,
+      searchHintColor: primaryColor,
+      searchTextColor: primaryColor,
+      searchBackgroundFillColor: Colors.white,
+      searchBorderColor: primaryColor);
 
   @override
   AccountListTheme get accountListTheme => super.accountListTheme.copyWith(
@@ -106,13 +101,10 @@ class HighContrastTheme extends MoneroLightTheme {
 
   @override
   ReceivePageTheme get receivePageTheme => super.receivePageTheme.copyWith(
-      tilesTextColor: Colors.white,
-      iconsBackgroundColor: Colors.grey,
-      iconsColor: Colors.black);
+      tilesTextColor: Colors.white, iconsBackgroundColor: Colors.grey, iconsColor: Colors.black);
 
   @override
   ThemeData get themeData => super.themeData.copyWith(
       disabledColor: Colors.grey,
-      dialogTheme:
-          super.themeData.dialogTheme.copyWith(backgroundColor: Colors.white));
+      dialogTheme: super.themeData.dialogTheme.copyWith(backgroundColor: Colors.white));
 }
diff --git a/lib/themes/theme_base.dart b/lib/themes/theme_base.dart
index 6151f0e83..b5f42e7de 100644
--- a/lib/themes/theme_base.dart
+++ b/lib/themes/theme_base.dart
@@ -26,7 +26,7 @@ import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
 import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
 import 'package:flutter/material.dart';
 
-enum ThemeType { bright, light, dark }
+enum ThemeType { light, bright, dark }
 
 abstract class ThemeBase {
   ThemeBase({required this.raw}) {
diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart
index a661aaf76..705cac0c2 100644
--- a/lib/utils/exception_handler.dart
+++ b/lib/utils/exception_handler.dart
@@ -149,6 +149,7 @@ class ExceptionHandler {
     "CERTIFICATE_VERIFY_FAILED",
     "Handshake error in client",
     "Error while launching http",
+    "OS Error: Network is unreachable",
   ];
 
   static Future<void> _addDeviceInfo(File file) async {
diff --git a/lib/view_model/contact_list/contact_list_view_model.dart b/lib/view_model/contact_list/contact_list_view_model.dart
index c99984ebc..93b06c378 100644
--- a/lib/view_model/contact_list/contact_list_view_model.dart
+++ b/lib/view_model/contact_list/contact_list_view_model.dart
@@ -1,4 +1,5 @@
 import 'dart:async';
+import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
 import 'package:cake_wallet/entities/contact_base.dart';
 import 'package:cake_wallet/entities/wallet_contact.dart';
 import 'package:cake_wallet/store/settings_store.dart';
@@ -10,6 +11,7 @@ import 'package:cake_wallet/entities/contact_record.dart';
 import 'package:cake_wallet/entities/contact.dart';
 import 'package:cake_wallet/utils/mobx.dart';
 import 'package:cw_core/crypto_currency.dart';
+import 'package:collection/collection.dart';
 
 part 'contact_list_view_model.g.dart';
 
@@ -20,12 +22,26 @@ abstract class ContactListViewModelBase with Store {
   ContactListViewModelBase(this.contactSource, this.walletInfoSource,
       this._currency, this.settingsStore)
       : contacts = ObservableList<ContactRecord>(),
-        walletContacts = [] {
+        walletContacts = [],
+        isAutoGenerateEnabled =
+            settingsStore.autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.enabled {
     walletInfoSource.values.forEach((info) {
-      if (info.addresses?.isNotEmpty ?? false) {
-        info.addresses?.forEach((address, label) {
-          final name = label.isNotEmpty ? info.name + ' ($label)' : info.name;
-
+      if (isAutoGenerateEnabled && info.type == WalletType.monero && info.addressInfos != null) {
+        info.addressInfos!.forEach((key, value) {
+          final nextUnusedAddress = value.firstWhereOrNull(
+              (addressInfo) => !(info.usedAddresses?.contains(addressInfo.address) ?? false));
+          if (nextUnusedAddress != null) {
+            final name = _createName(info.name, nextUnusedAddress.label);
+            walletContacts.add(WalletContact(
+              nextUnusedAddress.address,
+              name,
+              walletTypeToCryptoCurrency(info.type),
+            ));
+          }
+        });
+      } else if (info.addresses?.isNotEmpty == true) {
+        info.addresses!.forEach((address, label) {
+          final name = _createName(info.name, label);
           walletContacts.add(WalletContact(
             address,
             name,
@@ -40,6 +56,11 @@ abstract class ContactListViewModelBase with Store {
         initialFire: true);
   }
 
+  String _createName(String walletName, String label) {
+    return label.isNotEmpty ? '$walletName ($label)' : walletName;
+  }
+
+  final bool isAutoGenerateEnabled;
   final Box<Contact> contactSource;
   final Box<WalletInfo> walletInfoSource;
   final ObservableList<ContactRecord> contacts;
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index c6685b09f..93c12a309 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -1,3 +1,4 @@
+import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
 import 'package:cake_wallet/entities/exchange_api_mode.dart';
 import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
 import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
@@ -107,7 +108,7 @@ abstract class DashboardViewModelBase with Store {
     name = wallet.name;
     type = wallet.type;
     isOutdatedElectrumWallet =
-        wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
+        wallet.type == WalletType.bitcoin && wallet.seed!.split(' ').length < 24;
     isShowFirstYatIntroduction = false;
     isShowSecondYatIntroduction = false;
     isShowThirdYatIntroduction = false;
@@ -235,6 +236,10 @@ abstract class DashboardViewModelBase with Store {
   @computed
   double get price => balanceViewModel.price;
 
+  @computed
+  bool get isAutoGenerateSubaddressesEnabled =>
+      settingsStore.autoGenerateSubaddressStatus != AutoGenerateSubaddressStatus.disabled;
+
   @computed
   List<ActionListItem> get items {
     final _items = <ActionListItem>[];
@@ -328,7 +333,7 @@ abstract class DashboardViewModelBase with Store {
     type = wallet.type;
     name = wallet.name;
     isOutdatedElectrumWallet =
-        wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
+        wallet.type == WalletType.bitcoin && wallet.seed!.split(' ').length < 24;
     updateActions();
 
     if (wallet.type == WalletType.monero) {
diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart
index 162a3d723..4ff3cb390 100644
--- a/lib/view_model/exchange/exchange_view_model.dart
+++ b/lib/view_model/exchange/exchange_view_model.dart
@@ -2,6 +2,7 @@ import 'dart:async';
 import 'dart:collection';
 import 'dart:convert';
 
+import 'package:cake_wallet/core/wallet_change_listener_view_model.dart';
 import 'package:cake_wallet/entities/exchange_api_mode.dart';
 import 'package:cake_wallet/entities/preferences_key.dart';
 import 'package:cake_wallet/entities/wallet_contact.dart';
@@ -13,7 +14,7 @@ import 'package:cake_wallet/exchange/trocador/trocador_exchange_provider.dart';
 import 'package:cake_wallet/exchange/trocador/trocador_request.dart';
 import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
 import 'package:cw_core/transaction_priority.dart';
-import 'package:cw_core/wallet_base.dart';
+import 'package:cake_wallet/store/app_store.dart';
 import 'package:cw_core/crypto_currency.dart';
 import 'package:cw_core/sync_status.dart';
 import 'package:cw_core/wallet_type.dart';
@@ -45,16 +46,22 @@ part 'exchange_view_model.g.dart';
 
 class ExchangeViewModel = ExchangeViewModelBase with _$ExchangeViewModel;
 
-abstract class ExchangeViewModelBase with Store {
+abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with Store {
+  @override
+  void onWalletChange(wallet) {
+    receiveCurrency = wallet.currency;
+    depositCurrency = wallet.currency;
+  }
+
   ExchangeViewModelBase(
-      this.wallet,
-      this.trades,
-      this._exchangeTemplateStore,
-      this.tradesStore,
-      this._settingsStore,
-      this.sharedPreferences,
-      this.contactListViewModel)
-      : _cryptoNumberFormat = NumberFormat(),
+    AppStore appStore,
+    this.trades,
+    this._exchangeTemplateStore,
+    this.tradesStore,
+    this._settingsStore,
+    this.sharedPreferences,
+    this.contactListViewModel,
+  )   : _cryptoNumberFormat = NumberFormat(),
         isFixedRateMode = false,
         isReceiveAmountEntered = false,
         depositAmount = '',
@@ -70,10 +77,11 @@ abstract class ExchangeViewModelBase with Store {
         limits = Limits(min: 0, max: 0),
         tradeState = ExchangeTradeStateInitial(),
         limitsState = LimitsInitialState(),
-        receiveCurrency = wallet.currency,
-        depositCurrency = wallet.currency,
+        receiveCurrency = appStore.wallet!.currency,
+        depositCurrency = appStore.wallet!.currency,
         providerList = [],
-        selectedProviders = ObservableList<ExchangeProvider>() {
+        selectedProviders = ObservableList<ExchangeProvider>(),
+        super(appStore: appStore) {
     _useTorOnly = _settingsStore.exchangeStatus == ExchangeApiMode.torOnly;
     _setProviders();
     const excludeDepositCurrencies = [CryptoCurrency.btt, CryptoCurrency.nano];
@@ -86,10 +94,9 @@ abstract class ExchangeViewModelBase with Store {
     ];
     _initialPairBasedOnWallet();
 
-    final Map<String, dynamic> exchangeProvidersSelection = json.decode(
-        sharedPreferences
-                .getString(PreferencesKey.exchangeProvidersSelection) ??
-            "{}") as Map<String, dynamic>;
+    final Map<String, dynamic> exchangeProvidersSelection =
+        json.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}")
+            as Map<String, dynamic>;
 
     /// if the provider is not in the user settings (user's first time or newly added provider)
     /// then use its default value decided by us
@@ -102,34 +109,28 @@ abstract class ExchangeViewModelBase with Store {
     _setAvailableProviders();
     _calculateBestRate();
 
-    bestRateSync =
-        Timer.periodic(Duration(seconds: 10), (timer) => _calculateBestRate());
+    bestRateSync = Timer.periodic(Duration(seconds: 10), (timer) => _calculateBestRate());
 
     isDepositAddressEnabled = !(depositCurrency == wallet.currency);
     isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
     depositAmount = '';
     receiveAmount = '';
     receiveAddress = '';
-    depositAddress = depositCurrency == wallet.currency
-        ? wallet.walletAddresses.address
-        : '';
+    depositAddress = depositCurrency == wallet.currency ? wallet.walletAddresses.address : '';
     provider = providersForCurrentPair().first;
     final initialProvider = provider;
     provider!.checkIsAvailable().then((bool isAvailable) {
       if (!isAvailable && provider == initialProvider) {
-        provider = providerList.firstWhere(
-            (provider) => provider is ChangeNowExchangeProvider,
+        provider = providerList.firstWhere((provider) => provider is ChangeNowExchangeProvider,
             orElse: () => providerList.last);
         _onPairChange();
       }
     });
     receiveCurrencies = CryptoCurrency.all
-        .where((cryptoCurrency) =>
-            !excludeReceiveCurrencies.contains(cryptoCurrency))
+        .where((cryptoCurrency) => !excludeReceiveCurrencies.contains(cryptoCurrency))
         .toList();
     depositCurrencies = CryptoCurrency.all
-        .where((cryptoCurrency) =>
-            !excludeDepositCurrencies.contains(cryptoCurrency))
+        .where((cryptoCurrency) => !excludeDepositCurrencies.contains(cryptoCurrency))
         .toList();
     _defineIsReceiveAmountEditable();
     loadLimits();
@@ -140,7 +141,6 @@ abstract class ExchangeViewModelBase with Store {
     });
   }
   bool _useTorOnly;
-  final WalletBase wallet;
   final Box<Trade> trades;
   final ExchangeTemplateStore _exchangeTemplateStore;
   final TradesStore tradesStore;
@@ -165,8 +165,7 @@ abstract class ExchangeViewModelBase with Store {
   /// initialize with descending comparator
   /// since we want largest rate first
   final SplayTreeMap<double, ExchangeProvider> _sortedAvailableProviders =
-      SplayTreeMap<double, ExchangeProvider>(
-          (double a, double b) => b.compareTo(a));
+      SplayTreeMap<double, ExchangeProvider>((double a, double b) => b.compareTo(a));
 
   final List<ExchangeProvider> _tradeAvailableProviders = [];
 
@@ -222,21 +221,17 @@ abstract class ExchangeViewModelBase with Store {
   SyncStatus get status => wallet.syncStatus;
 
   @computed
-  ObservableList<ExchangeTemplate> get templates =>
-      _exchangeTemplateStore.templates;
+  ObservableList<ExchangeTemplate> get templates => _exchangeTemplateStore.templates;
 
   @computed
-  List<WalletContact> get walletContactsToShow =>
-      contactListViewModel.walletContacts
-          .where((element) =>
-              receiveCurrency == null || element.type == receiveCurrency)
-          .toList();
+  List<WalletContact> get walletContactsToShow => contactListViewModel.walletContacts
+      .where((element) => receiveCurrency == null || element.type == receiveCurrency)
+      .toList();
 
   @action
   bool checkIfWalletIsAnInternalWallet(String address) {
-    final walletContactList = walletContactsToShow
-        .where((element) => element.address == address)
-        .toList();
+    final walletContactList =
+        walletContactsToShow.where((element) => element.address == address).toList();
 
     return walletContactList.isNotEmpty;
   }
@@ -256,7 +251,6 @@ abstract class ExchangeViewModelBase with Store {
     return false;
   }
 
-
   @computed
   TransactionPriority get transactionPriority {
     final priority = _settingsStore.priority[wallet.type];
@@ -269,7 +263,8 @@ abstract class ExchangeViewModelBase with Store {
   }
 
   bool get hasAllAmount =>
-      (wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin) && depositCurrency == wallet.currency;
+      (wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin) &&
+      depositCurrency == wallet.currency;
 
   bool get isMoneroWallet => wallet.type == WalletType.monero;
 
@@ -277,14 +272,11 @@ abstract class ExchangeViewModelBase with Store {
     switch (wallet.type) {
       case WalletType.monero:
       case WalletType.haven:
-        return transactionPriority ==
-            monero!.getMoneroTransactionPrioritySlow();
+        return transactionPriority == monero!.getMoneroTransactionPrioritySlow();
       case WalletType.bitcoin:
-        return transactionPriority ==
-            bitcoin!.getBitcoinTransactionPrioritySlow();
+        return transactionPriority == bitcoin!.getBitcoinTransactionPrioritySlow();
       case WalletType.litecoin:
-        return transactionPriority ==
-            bitcoin!.getLitecoinTransactionPrioritySlow();
+        return transactionPriority == bitcoin!.getLitecoinTransactionPrioritySlow();
       default:
         return false;
     }
@@ -390,20 +382,18 @@ abstract class ExchangeViewModelBase with Store {
   }
 
   Future<void> _calculateBestRate() async {
-    final amount =
-        double.tryParse(isFixedRateMode ? receiveAmount : depositAmount) ?? 1;
+    final amount = double.tryParse(isFixedRateMode ? receiveAmount : depositAmount) ?? 1;
 
     final _providers = _tradeAvailableProviders
         .where((element) => !isFixedRateMode || element.supportsFixedRate)
         .toList();
 
-    final result = await Future.wait<double>(_providers.map((element) =>
-        element.fetchRate(
-            from: depositCurrency,
-            to: receiveCurrency,
-            amount: amount,
-            isFixedRateMode: isFixedRateMode,
-            isReceiveAmount: isFixedRateMode)));
+    final result = await Future.wait<double>(_providers.map((element) => element.fetchRate(
+        from: depositCurrency,
+        to: receiveCurrency,
+        amount: amount,
+        isFixedRateMode: isFixedRateMode,
+        isReceiveAmount: isFixedRateMode)));
 
     _sortedAvailableProviders.clear();
 
@@ -445,14 +435,13 @@ abstract class ExchangeViewModelBase with Store {
         }
 
         try {
-          final tempLimits = await provider.fetchLimits(
-              from: from, to: to, isFixedRateMode: isFixedRateMode);
+          final tempLimits =
+              await provider.fetchLimits(from: from, to: to, isFixedRateMode: isFixedRateMode);
 
           if (lowestMin != null && (tempLimits.min ?? -1) < lowestMin) {
             lowestMin = tempLimits.min;
           }
-          if (highestMax != null &&
-              (tempLimits.max ?? double.maxFinite) > highestMax) {
+          if (highestMax != null && (tempLimits.max ?? double.maxFinite) > highestMax) {
             highestMax = tempLimits.max;
           }
         } catch (e) {
@@ -568,8 +557,8 @@ abstract class ExchangeViewModelBase with Store {
           } else {
             try {
               tradeState = TradeIsCreating();
-              final trade = await provider.createTrade(
-                  request: request!, isFixedRateMode: isFixedRateMode);
+              final trade =
+                  await provider.createTrade(request: request!, isFixedRateMode: isFixedRateMode);
               trade.walletId = wallet.id;
               tradesStore.setTrade(trade);
               await trades.add(trade);
@@ -604,12 +593,8 @@ abstract class ExchangeViewModelBase with Store {
     isReceiveAmountEntered = false;
     depositAmount = '';
     receiveAmount = '';
-    depositAddress = depositCurrency == wallet.currency
-        ? wallet.walletAddresses.address
-        : '';
-    receiveAddress = receiveCurrency == wallet.currency
-        ? wallet.walletAddresses.address
-        : '';
+    depositAddress = depositCurrency == wallet.currency ? wallet.walletAddresses.address : '';
+    receiveAddress = receiveCurrency == wallet.currency ? wallet.walletAddresses.address : '';
     isDepositAddressEnabled = !(depositCurrency == wallet.currency);
     isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
     isFixedRateMode = false;
@@ -628,8 +613,7 @@ abstract class ExchangeViewModelBase with Store {
       }
 
       final amount = availableBalance - fee;
-      changeDepositAmount(
-          amount: bitcoin!.formatterBitcoinAmountToString(amount: amount));
+      changeDepositAmount(amount: bitcoin!.formatterBitcoinAmountToString(amount: amount));
     }
   }
 
@@ -664,9 +648,8 @@ abstract class ExchangeViewModelBase with Store {
   List<ExchangeProvider> _providersForPair(
       {required CryptoCurrency from, required CryptoCurrency to}) {
     final providers = providerList
-        .where((provider) => provider.pairList
-            .where((pair) => pair.from == from && pair.to == to)
-            .isNotEmpty)
+        .where((provider) =>
+            provider.pairList.where((pair) => pair.from == from && pair.to == to).isNotEmpty)
         .toList();
 
     return providers;
@@ -746,14 +729,12 @@ abstract class ExchangeViewModelBase with Store {
     _bestRate = 0;
     _calculateBestRate();
 
-    final Map<String, dynamic> exchangeProvidersSelection = json.decode(
-        sharedPreferences
-                .getString(PreferencesKey.exchangeProvidersSelection) ??
-            "{}") as Map<String, dynamic>;
+    final Map<String, dynamic> exchangeProvidersSelection =
+        json.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}")
+            as Map<String, dynamic>;
 
     for (var provider in providerList) {
-      exchangeProvidersSelection[provider.title] =
-          selectedProviders.contains(provider);
+      exchangeProvidersSelection[provider.title] = selectedProviders.contains(provider);
     }
 
     sharedPreferences.setString(
@@ -764,15 +745,15 @@ abstract class ExchangeViewModelBase with Store {
 
   bool get isAvailableInSelected {
     final providersForPair = providersForCurrentPair();
-    return selectedProviders.any(
-        (element) => element.isAvailable && providersForPair.contains(element));
+    return selectedProviders
+        .any((element) => element.isAvailable && providersForPair.contains(element));
   }
 
   void _setAvailableProviders() {
     _tradeAvailableProviders.clear();
 
-    _tradeAvailableProviders.addAll(selectedProviders
-        .where((provider) => providersForCurrentPair().contains(provider)));
+    _tradeAvailableProviders.addAll(
+        selectedProviders.where((provider) => providersForCurrentPair().contains(provider)));
   }
 
   @action
@@ -780,16 +761,13 @@ abstract class ExchangeViewModelBase with Store {
     switch (wallet.type) {
       case WalletType.monero:
       case WalletType.haven:
-        _settingsStore.priority[wallet.type] =
-            monero!.getMoneroTransactionPriorityAutomatic();
+        _settingsStore.priority[wallet.type] = monero!.getMoneroTransactionPriorityAutomatic();
         break;
       case WalletType.bitcoin:
-        _settingsStore.priority[wallet.type] =
-            bitcoin!.getBitcoinTransactionPriorityMedium();
+        _settingsStore.priority[wallet.type] = bitcoin!.getBitcoinTransactionPriorityMedium();
         break;
       case WalletType.litecoin:
-        _settingsStore.priority[wallet.type] =
-            bitcoin!.getLitecoinTransactionPriorityMedium();
+        _settingsStore.priority[wallet.type] = bitcoin!.getLitecoinTransactionPriorityMedium();
         break;
       default:
         break;
@@ -798,9 +776,7 @@ abstract class ExchangeViewModelBase with Store {
 
   void _setProviders() {
     if (_settingsStore.exchangeStatus == ExchangeApiMode.torOnly) {
-      providerList = _allProviders
-          .where((provider) => provider.supportsOnionAddress)
-          .toList();
+      providerList = _allProviders.where((provider) => provider.supportsOnionAddress).toList();
     } else {
       providerList = _allProviders;
     }
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 1c81c255b..ea612c63c 100644
--- a/lib/view_model/node_list/node_list_view_model.dart
+++ b/lib/view_model/node_list/node_list_view_model.dart
@@ -76,6 +76,7 @@ abstract class NodeListViewModelBase with Store {
   @action
   Future<void> delete(Node node) async => node.delete();
 
+  @action
   Future<void> setAsCurrent(Node node) async => settingsStore.nodes[_appStore.wallet!.type] = node;
 
   @action
diff --git a/lib/view_model/restore/restore_from_qr_vm.dart b/lib/view_model/restore/restore_from_qr_vm.dart
index 996b3b3fb..39a7b682f 100644
--- a/lib/view_model/restore/restore_from_qr_vm.dart
+++ b/lib/view_model/restore/restore_from_qr_vm.dart
@@ -66,6 +66,9 @@ abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store
           case WalletType.litecoin:
             return bitcoin!.createBitcoinRestoreWalletFromWIFCredentials(
                 name: name, password: password, wif: wif);
+          case WalletType.ethereum:
+            return ethereum!.createEthereumRestoreWalletFromPrivateKey(
+                name: name, password: password, privateKey: restoreWallet.privateKey!);
           default:
             throw Exception('Unexpected type: ${restoreWallet.type.toString()}');
         }
diff --git a/lib/view_model/restore/restore_wallet.dart b/lib/view_model/restore/restore_wallet.dart
index 0f872d8cc..264b3d421 100644
--- a/lib/view_model/restore/restore_wallet.dart
+++ b/lib/view_model/restore/restore_wallet.dart
@@ -13,7 +13,8 @@ class RestoredWallet {
       this.txAmount,
       this.txDescription,
       this.recipientName,
-      this.height});
+      this.height,
+      this.privateKey});
 
   final WalletRestoreMode restoreMode;
   final WalletType type;
@@ -26,6 +27,7 @@ class RestoredWallet {
   final String? txDescription;
   final String? recipientName;
   final int? height;
+  final String? privateKey;
 
   factory RestoredWallet.fromKey(Map<String, dynamic> json) {
     final height = json['height'] as String?;
@@ -36,6 +38,7 @@ class RestoredWallet {
       spendKey: json['spend_key'] as String?,
       viewKey: json['view_key'] as String?,
       height: height != null ? int.parse(height) : 0,
+      privateKey: json['private_key'] as String?,
     );
   }
 
diff --git a/lib/view_model/restore/wallet_restore_from_qr_code.dart b/lib/view_model/restore/wallet_restore_from_qr_code.dart
index c4b772f9c..e9aed55c6 100644
--- a/lib/view_model/restore/wallet_restore_from_qr_code.dart
+++ b/lib/view_model/restore/wallet_restore_from_qr_code.dart
@@ -33,7 +33,10 @@ class WalletRestoreFromQRCode {
         getSeedPhraseFromUrl(queryParameters.toString(), credentials['type'] as WalletType);
     if (seed != null) {
       credentials['seed'] = seed;
+    } else {
+      credentials['private_key'] = queryParameters['private_key'];
     }
+
     credentials.addAll(queryParameters);
     credentials['mode'] = getWalletRestoreMode(credentials);
 
@@ -69,6 +72,8 @@ class WalletRestoreFromQRCode {
       case 'litecoin':
       case 'litecoin-wallet':
         return WalletType.litecoin;
+      case 'ethereum-wallet':
+        return WalletType.ethereum;
       default:
         throw Exception('Unexpected wallet type: ${scheme.toString()}');
     }
@@ -101,6 +106,7 @@ class WalletRestoreFromQRCode {
         }
       case WalletType.bitcoin:
       case WalletType.litecoin:
+      case WalletType.ethereum:
         RegExp regex24 = RegExp(r'\b(\S+\b\s+){23}\S+\b');
         RegExp regex18 = RegExp(r'\b(\S+\b\s+){17}\S+\b');
         RegExp regex12 = RegExp(r'\b(\S+\b\s+){11}\S+\b');
@@ -152,6 +158,14 @@ class WalletRestoreFromQRCode {
           : throw Exception('Unexpected restore mode: spend_key or view_key is invalid');
     }
 
+    if (type == WalletType.ethereum && credentials.containsKey('private_key')) {
+      final privateKey = credentials['private_key'] as String;
+      if (privateKey.isEmpty) {
+        throw Exception('Unexpected restore mode: private_key');
+      }
+      return WalletRestoreMode.keys;
+    }
+
     throw Exception('Unexpected restore mode: restore params are invalid');
   }
 }
diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart
index dfec89f43..329b3c4ad 100644
--- a/lib/view_model/send/send_view_model.dart
+++ b/lib/view_model/send/send_view_model.dart
@@ -1,3 +1,4 @@
+import 'package:cake_wallet/core/wallet_change_listener_view_model.dart';
 import 'package:cake_wallet/entities/contact_record.dart';
 import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
 import 'package:cake_wallet/entities/transaction_description.dart';
@@ -15,7 +16,7 @@ import 'package:cake_wallet/core/address_validator.dart';
 import 'package:cake_wallet/core/amount_validator.dart';
 import 'package:cw_core/pending_transaction.dart';
 import 'package:cake_wallet/core/validator.dart';
-import 'package:cw_core/wallet_base.dart';
+import 'package:cake_wallet/store/app_store.dart';
 import 'package:cake_wallet/core/execution_state.dart';
 import 'package:cake_wallet/monero/monero.dart';
 import 'package:cw_core/sync_status.dart';
@@ -34,30 +35,38 @@ part 'send_view_model.g.dart';
 
 class SendViewModel = SendViewModelBase with _$SendViewModel;
 
-abstract class SendViewModelBase with Store {
-  SendViewModelBase(
-      this._wallet,
-      this._settingsStore,
-      this.sendTemplateViewModel,
-      this._fiatConversationStore,
-      this.balanceViewModel,
-      this.contactListViewModel,
-      this.transactionDescriptionBox)
-      : state = InitialExecutionState(),
-        currencies = _wallet.balance.keys.toList(),
-        selectedCryptoCurrency = _wallet.currency,
-        hasMultipleTokens = _wallet.type == WalletType.ethereum,
-        outputs = ObservableList<Output>(),
-        fiatFromSettings = _settingsStore.fiatCurrency {
-    final priority = _settingsStore.priority[_wallet.type];
-    final priorities = priorityForWalletType(_wallet.type);
+abstract class SendViewModelBase extends WalletChangeListenerViewModel with Store {
+  @override
+  void onWalletChange(wallet) {
+    currencies = wallet.balance.keys.toList();
+    selectedCryptoCurrency = wallet.currency;
+    hasMultipleTokens = wallet.type == WalletType.ethereum;
+  }
 
-    if (!priorityForWalletType(_wallet.type).contains(priority)) {
-      _settingsStore.priority[_wallet.type] = priorities.first;
+  SendViewModelBase(
+    AppStore appStore,
+    this.sendTemplateViewModel,
+    this._fiatConversationStore,
+    this.balanceViewModel,
+    this.contactListViewModel,
+    this.transactionDescriptionBox,
+  )   : state = InitialExecutionState(),
+        currencies = appStore.wallet!.balance.keys.toList(),
+        selectedCryptoCurrency = appStore.wallet!.currency,
+        hasMultipleTokens = appStore.wallet!.type == WalletType.ethereum,
+        outputs = ObservableList<Output>(),
+        _settingsStore = appStore.settingsStore,
+        fiatFromSettings = appStore.settingsStore.fiatCurrency,
+        super(appStore: appStore) {
+    final priority = _settingsStore.priority[wallet.type];
+    final priorities = priorityForWalletType(wallet.type);
+
+    if (!priorityForWalletType(wallet.type).contains(priority)) {
+      _settingsStore.priority[wallet.type] = priorities.first;
     }
 
     outputs
-        .add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
+        .add(Output(wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
   }
 
   @observable
@@ -68,7 +77,7 @@ abstract class SendViewModelBase with Store {
   @action
   void addOutput() {
     outputs
-        .add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
+        .add(Output(wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
   }
 
   @action
@@ -107,9 +116,8 @@ abstract class SendViewModelBase with Store {
   String get pendingTransactionFeeFiatAmount {
     try {
       if (pendingTransaction != null) {
-        final currency = walletType == WalletType.ethereum
-            ? _wallet.currency
-            : selectedCryptoCurrency;
+        final currency =
+            walletType == WalletType.ethereum ? wallet.currency : selectedCryptoCurrency;
         final fiat = calculateFiatAmount(
             price: _fiatConversationStore.prices[currency]!,
             cryptoAmount: pendingTransaction!.feeFormatted);
@@ -125,19 +133,19 @@ abstract class SendViewModelBase with Store {
   FiatCurrency get fiat => _settingsStore.fiatCurrency;
 
   TransactionPriority get transactionPriority {
-    final priority = _settingsStore.priority[_wallet.type];
+    final priority = _settingsStore.priority[wallet.type];
 
     if (priority == null) {
-      throw Exception('Unexpected type ${_wallet.type}');
+      throw Exception('Unexpected type ${wallet.type}');
     }
 
     return priority;
   }
 
-  CryptoCurrency get currency => _wallet.currency;
+  CryptoCurrency get currency => wallet.currency;
 
   Validator<String> get amountValidator =>
-      AmountValidator(currency: walletTypeToCryptoCurrency(_wallet.type));
+      AmountValidator(currency: walletTypeToCryptoCurrency(wallet.type));
 
   Validator<String> get allAmountValidator => AllAmountValidator();
 
@@ -151,7 +159,7 @@ abstract class SendViewModelBase with Store {
   PendingTransaction? pendingTransaction;
 
   @computed
-  String get balance => _wallet.balance[selectedCryptoCurrency]!.formattedAvailableBalance;
+  String get balance => wallet.balance[selectedCryptoCurrency]!.formattedAvailableBalance;
 
   @computed
   bool get isFiatDisabled => balanceViewModel.isFiatDisabled;
@@ -165,53 +173,58 @@ abstract class SendViewModelBase with Store {
       isFiatDisabled ? '' : pendingTransactionFeeFiatAmount + ' ' + fiat.title;
 
   @computed
-  bool get isReadyForSend => _wallet.syncStatus is SyncedSyncStatus;
+  bool get isReadyForSend => wallet.syncStatus is SyncedSyncStatus;
 
   @computed
   List<Template> get templates => sendTemplateViewModel.templates
       .where((template) => _isEqualCurrency(template.cryptoCurrency))
       .toList();
 
+  @computed
+  bool get hasCoinControl =>
+      wallet.type == WalletType.bitcoin ||
+      wallet.type == WalletType.litecoin ||
+      wallet.type == WalletType.monero;
+
   @computed
   bool get isElectrumWallet =>
-      _wallet.type == WalletType.bitcoin || _wallet.type == WalletType.litecoin;
+      wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin;
 
   @observable
   CryptoCurrency selectedCryptoCurrency;
 
   List<CryptoCurrency> currencies;
 
-  bool get hasYat => outputs.any((out) =>
-      out.isParsedAddress &&
-      out.parsedAddress.parseFrom == ParseFrom.yatRecord);
+  bool get hasYat => outputs
+      .any((out) => out.isParsedAddress && out.parsedAddress.parseFrom == ParseFrom.yatRecord);
 
-  WalletType get walletType => _wallet.type;
+  WalletType get walletType => wallet.type;
 
-  String? get walletCurrencyName =>
-      _wallet.currency.fullName?.toLowerCase() ?? _wallet.currency.name;
+  String? get walletCurrencyName => wallet.currency.fullName?.toLowerCase() ?? wallet.currency.name;
 
   bool get hasCurrecyChanger => walletType == WalletType.haven;
 
   @computed
   FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency;
 
-  final WalletBase _wallet;
   final SettingsStore _settingsStore;
   final SendTemplateViewModel sendTemplateViewModel;
   final BalanceViewModel balanceViewModel;
   final ContactListViewModel contactListViewModel;
   final FiatConversionStore _fiatConversationStore;
   final Box<TransactionDescription> transactionDescriptionBox;
-  final bool hasMultipleTokens;
+
+  @observable
+  bool hasMultipleTokens;
 
   @computed
   List<ContactRecord> get contactsToShow => contactListViewModel.contacts
-      .where((element) => selectedCryptoCurrency == null || element.type == selectedCryptoCurrency)
+      .where((element) => element.type == selectedCryptoCurrency)
       .toList();
 
   @computed
   List<WalletContact> get walletContactsToShow => contactListViewModel.walletContacts
-      .where((element) => selectedCryptoCurrency == null || element.type == selectedCryptoCurrency)
+      .where((element) => element.type == selectedCryptoCurrency)
       .toList();
 
   @action
@@ -271,7 +284,7 @@ abstract class SendViewModelBase with Store {
   Future<void> createTransaction() async {
     try {
       state = IsExecutingState();
-      pendingTransaction = await _wallet.createTransaction(_credentials());
+      pendingTransaction = await wallet.createTransaction(_credentials());
       state = ExecutedSuccessfullyState();
     } catch (e) {
       state = FailureState(e.toString());
@@ -318,61 +331,60 @@ abstract class SendViewModelBase with Store {
 
   @action
   void setTransactionPriority(TransactionPriority priority) =>
-      _settingsStore.priority[_wallet.type] = priority;
+      _settingsStore.priority[wallet.type] = priority;
 
   Object _credentials() {
-    switch (_wallet.type) {
+    switch (wallet.type) {
       case WalletType.bitcoin:
-        final priority = _settingsStore.priority[_wallet.type];
+        final priority = _settingsStore.priority[wallet.type];
 
         if (priority == null) {
-          throw Exception('Priority is null for wallet type: ${_wallet.type}');
+          throw Exception('Priority is null for wallet type: ${wallet.type}');
         }
 
         return bitcoin!.createBitcoinTransactionCredentials(outputs, priority: priority);
       case WalletType.litecoin:
-        final priority = _settingsStore.priority[_wallet.type];
+        final priority = _settingsStore.priority[wallet.type];
 
         if (priority == null) {
-          throw Exception('Priority is null for wallet type: ${_wallet.type}');
+          throw Exception('Priority is null for wallet type: ${wallet.type}');
         }
 
         return bitcoin!.createBitcoinTransactionCredentials(outputs, priority: priority);
       case WalletType.monero:
-        final priority = _settingsStore.priority[_wallet.type];
+        final priority = _settingsStore.priority[wallet.type];
 
         if (priority == null) {
-          throw Exception('Priority is null for wallet type: ${_wallet.type}');
+          throw Exception('Priority is null for wallet type: ${wallet.type}');
         }
 
         return monero!
             .createMoneroTransactionCreationCredentials(outputs: outputs, priority: priority);
       case WalletType.haven:
-        final priority = _settingsStore.priority[_wallet.type];
+        final priority = _settingsStore.priority[wallet.type];
 
         if (priority == null) {
-          throw Exception('Priority is null for wallet type: ${_wallet.type}');
+          throw Exception('Priority is null for wallet type: ${wallet.type}');
         }
 
         return haven!.createHavenTransactionCreationCredentials(
             outputs: outputs, priority: priority, assetType: selectedCryptoCurrency.title);
       case WalletType.ethereum:
-        final priority = _settingsStore.priority[_wallet.type];
+        final priority = _settingsStore.priority[wallet.type];
 
         if (priority == null) {
-          throw Exception('Priority is null for wallet type: ${_wallet.type}');
+          throw Exception('Priority is null for wallet type: ${wallet.type}');
         }
 
-        return ethereum!.createEthereumTransactionCredentials(
-            outputs, priority: priority, currency: selectedCryptoCurrency);
+        return ethereum!.createEthereumTransactionCredentials(outputs,
+            priority: priority, currency: selectedCryptoCurrency);
       default:
-        throw Exception('Unexpected wallet type: ${_wallet.type}');
+        throw Exception('Unexpected wallet type: ${wallet.type}');
     }
   }
 
   String displayFeeRate(dynamic priority) {
     final _priority = priority as TransactionPriority;
-    final wallet = _wallet;
 
     if (isElectrumWallet) {
       final rate = bitcoin!.getFeeRate(wallet, _priority);
@@ -383,22 +395,21 @@ abstract class SendViewModelBase with Store {
   }
 
   bool _isEqualCurrency(String currency) =>
-      _wallet.balance.keys.any((e) => currency.toLowerCase() == e.title.toLowerCase());
+      wallet.balance.keys.any((e) => currency.toLowerCase() == e.title.toLowerCase());
 
   @action
   void onClose() => _settingsStore.fiatCurrency = fiatFromSettings;
 
   @action
-  void setFiatCurrency(FiatCurrency fiat) =>
-      _settingsStore.fiatCurrency = fiat;
+  void setFiatCurrency(FiatCurrency fiat) => _settingsStore.fiatCurrency = fiat;
 
   @action
   void setSelectedCryptoCurrency(String cryptoCurrency) {
     try {
-      selectedCryptoCurrency = _wallet.balance.keys
+      selectedCryptoCurrency = wallet.balance.keys
           .firstWhere((e) => cryptoCurrency.toLowerCase() == e.title.toLowerCase());
     } catch (e) {
-      selectedCryptoCurrency = _wallet.currency;
+      selectedCryptoCurrency = wallet.currency;
     }
   }
 }
diff --git a/lib/view_model/set_up_2fa_viewmodel.dart b/lib/view_model/set_up_2fa_viewmodel.dart
index 96a0c4a20..0b4b614ab 100644
--- a/lib/view_model/set_up_2fa_viewmodel.dart
+++ b/lib/view_model/set_up_2fa_viewmodel.dart
@@ -96,9 +96,7 @@ abstract class Setup2FAViewModelBase with Store {
 
   @action
   void _setBase32SecretKey(String value) {
-    if (_settingsStore.totpSecretKey == '') {
-      _settingsStore.totpSecretKey = value;
-    }
+    _settingsStore.totpSecretKey = value;
   }
 
   @action
diff --git a/lib/view_model/settings/privacy_settings_view_model.dart b/lib/view_model/settings/privacy_settings_view_model.dart
index 5dbfd61dd..27ce919df 100644
--- a/lib/view_model/settings/privacy_settings_view_model.dart
+++ b/lib/view_model/settings/privacy_settings_view_model.dart
@@ -1,6 +1,10 @@
+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';
 import 'package:cake_wallet/store/settings_store.dart';
+import 'package:cw_core/balance.dart';
+import 'package:cw_core/transaction_history.dart';
+import 'package:cw_core/transaction_info.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:mobx/mobx.dart';
@@ -14,11 +18,27 @@ abstract class PrivacySettingsViewModelBase with Store {
   PrivacySettingsViewModelBase(this._settingsStore, this._wallet);
 
   final SettingsStore _settingsStore;
-  final WalletBase _wallet;
+  final WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> _wallet;
 
   @computed
   ExchangeApiMode get exchangeStatus => _settingsStore.exchangeStatus;
 
+  @computed
+  bool get isAutoGenerateSubaddressesEnabled =>
+      _settingsStore.autoGenerateSubaddressStatus != AutoGenerateSubaddressStatus.disabled;
+
+  @action
+  void setAutoGenerateSubaddresses(bool value) {
+    _wallet.isEnabledAutoGenerateSubaddress = value;
+    if (value) {
+      _settingsStore.autoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.enabled;
+    } else {
+      _settingsStore.autoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.disabled;
+    }
+  }
+
+  bool get isAutoGenerateSubaddressesVisible => _wallet.type == WalletType.monero;
+
   @computed
   bool get shouldSaveRecipientAddress => _settingsStore.shouldSaveRecipientAddress;
 
diff --git a/lib/view_model/unspent_coins/unspent_coins_details_view_model.dart b/lib/view_model/unspent_coins/unspent_coins_details_view_model.dart
index 098296036..992991147 100644
--- a/lib/view_model/unspent_coins/unspent_coins_details_view_model.dart
+++ b/lib/view_model/unspent_coins/unspent_coins_details_view_model.dart
@@ -23,6 +23,7 @@ abstract class UnspentCoinsDetailsViewModelBase with Store {
         note = unspentCoinsItem.note {
     items = [
       StandartListItem(title: S.current.transaction_details_amount, value: unspentCoinsItem.amount),
+      StandartListItem(title: S.current.transaction_details_transaction_id, value: unspentCoinsItem.hash),
       StandartListItem(title: S.current.widgets_address, value: unspentCoinsItem.address),
       TextFieldListItem(
           title: S.current.note_tap_to_change,
@@ -42,19 +43,22 @@ abstract class UnspentCoinsDetailsViewModelBase with Store {
               unspentCoinsItem.isSending = !value;
             }
             await unspentCoinsListViewModel.saveUnspentCoinInfo(unspentCoinsItem);
-          }),
-      BlockExplorerListItem(
-          title: S.current.view_in_block_explorer,
-          value: _explorerDescription(unspentCoinsListViewModel.wallet.type),
-          onTap: () {
-            try {
-              final url = Uri.parse(
-                  _explorerUrl(unspentCoinsListViewModel.wallet.type, unspentCoinsItem.hash));
-              return launchUrl(url);
-            } catch (e) {}
-
           })
     ];
+
+    if ([WalletType.bitcoin, WalletType.litecoin].contains(unspentCoinsListViewModel.wallet.type)) {
+      items.add(BlockExplorerListItem(
+        title: S.current.view_in_block_explorer,
+        value: _explorerDescription(unspentCoinsListViewModel.wallet.type),
+        onTap: () {
+          try {
+            final url = Uri.parse(
+                _explorerUrl(unspentCoinsListViewModel.wallet.type, unspentCoinsItem.hash));
+            return launchUrl(url);
+          } catch (e) {}
+        },
+      ));
+    }
   }
 
   String _explorerUrl(WalletType type, String txId) {
diff --git a/lib/view_model/unspent_coins/unspent_coins_item.dart b/lib/view_model/unspent_coins/unspent_coins_item.dart
index 2f0d75571..9d1f6c71c 100644
--- a/lib/view_model/unspent_coins/unspent_coins_item.dart
+++ b/lib/view_model/unspent_coins/unspent_coins_item.dart
@@ -13,7 +13,9 @@ abstract class UnspentCoinsItemBase with Store {
     required this.note,
     required this.isSending,
     required this.amountRaw,
-    required this.vout});
+    required this.vout,
+    required this.keyImage
+  });
 
   @observable
   String address;
@@ -38,4 +40,7 @@ abstract class UnspentCoinsItemBase with Store {
 
   @observable
   int vout;
-}
\ No newline at end of file
+
+  @observable
+  String? keyImage;
+}
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 4df4b9a66..9ecb381fd 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
@@ -1,10 +1,15 @@
-import 'package:cw_core/unspent_coins_info.dart';
+import 'package:collection/collection.dart';
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
-import 'package:cw_core/wallet_base.dart';
+import 'package:cake_wallet/entities/unspent_transaction_output.dart';
+import 'package:cake_wallet/monero/monero.dart';
 import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart';
+import 'package:cw_bitcoin/bitcoin_wallet.dart';
+import 'package:cw_core/unspent_coins_info.dart';
+import 'package:cw_core/wallet_base.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:cw_monero/monero_wallet.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
-import 'package:collection/collection.dart';
 
 part 'unspent_coins_list_view_model.g.dart';
 
@@ -14,7 +19,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
   UnspentCoinsListViewModelBase(
       {required this.wallet, required Box<UnspentCoinsInfo> unspentCoinsInfo})
       : _unspentCoinsInfo = unspentCoinsInfo {
-    bitcoin!.updateUnspents(wallet);
+    _updateUnspents();
   }
 
   WalletBase wallet;
@@ -22,11 +27,10 @@ abstract class UnspentCoinsListViewModelBase with Store {
 
   @computed
   ObservableList<UnspentCoinsItem> get items =>
-      ObservableList.of(bitcoin!.getUnspents(wallet).map((elem) {
-        final amount = bitcoin!.formatterBitcoinAmountToString(amount: elem.value) +
-            ' ${wallet.currency.title}';
+      ObservableList.of(_getUnspents().map((elem) {
+        final amount = formatAmountToString(elem.value) + ' ${wallet.currency.title}';
 
-        final info = getUnspentCoinInfo(elem.hash, elem.address, elem.value, elem.vout);
+        final info = getUnspentCoinInfo(elem.hash, elem.address, elem.value, elem.vout, elem.keyImage);
 
         return UnspentCoinsItem(
             address: elem.address,
@@ -36,12 +40,14 @@ abstract class UnspentCoinsListViewModelBase with Store {
             note: info?.note ?? '',
             isSending: info?.isSending ?? true,
             amountRaw: elem.value,
-            vout: elem.vout);
+            vout: elem.vout,
+          keyImage: elem.keyImage
+        );
       }));
 
   Future<void> saveUnspentCoinInfo(UnspentCoinsItem item) async {
     try {
-      final info = getUnspentCoinInfo(item.hash, item.address, item.amountRaw, item.vout);
+      final info = getUnspentCoinInfo(item.hash, item.address, item.amountRaw, item.vout, item.keyImage);
       if (info == null) {
         final newInfo = UnspentCoinsInfo(
             walletId: wallet.id,
@@ -51,10 +57,12 @@ abstract class UnspentCoinsListViewModelBase with Store {
             vout: item.vout,
             isFrozen: item.isFrozen,
             isSending: item.isSending,
-            noteRaw: item.note);
+            noteRaw: item.note,
+            keyImage: item.keyImage
+        );
 
         await _unspentCoinsInfo.add(newInfo);
-        bitcoin!.updateUnspents(wallet);
+        _updateUnspents();
         wallet.updateBalance();
         return;
       }
@@ -63,19 +71,45 @@ abstract class UnspentCoinsListViewModelBase with Store {
       info.note = item.note;
 
       await info.save();
-      bitcoin!.updateUnspents(wallet);
+      _updateUnspents();
       wallet.updateBalance();
     } catch (e) {
       print(e.toString());
     }
   }
 
-  UnspentCoinsInfo? getUnspentCoinInfo(String hash, String address, int value, int vout) {
+  UnspentCoinsInfo? getUnspentCoinInfo(String hash, String address, int value, int vout, String? keyImage) {
     return _unspentCoinsInfo.values.firstWhereOrNull((element) =>
         element.walletId == wallet.id &&
         element.hash == hash &&
         element.address == address &&
         element.value == value &&
-        element.vout == vout);
+        element.vout == vout &&
+        element.keyImage == keyImage
+    );
+  }
+
+  String formatAmountToString(int fullBalance) {
+    if (wallet.type == WalletType.monero)
+      return monero!.formatterMoneroAmountToString(amount: fullBalance);
+    if ([WalletType.bitcoin, WalletType.litecoin].contains(wallet.type))
+      return bitcoin!.formatterBitcoinAmountToString(amount: fullBalance);
+    return '';
+  }
+
+
+  void _updateUnspents() {
+    if (wallet.type == WalletType.monero)
+      return monero!.updateUnspents(wallet);
+    if ([WalletType.bitcoin, WalletType.litecoin].contains(wallet.type))
+      return bitcoin!.updateUnspents(wallet);
+  }
+
+  List<Unspent> _getUnspents() {
+    if (wallet.type == WalletType.monero)
+      return monero!.getUnspents(wallet);
+    if ([WalletType.bitcoin, WalletType.litecoin].contains(wallet.type))
+      return bitcoin!.getUnspents(wallet);
+    return List.empty();
   }
 }
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 d692b4ea8..db45ae117 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
@@ -1,3 +1,4 @@
+import 'package:cake_wallet/core/wallet_change_listener_view_model.dart';
 import 'package:cake_wallet/ethereum/ethereum.dart';
 import 'package:cake_wallet/entities/fiat_currency.dart';
 import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
@@ -5,16 +6,12 @@ import 'package:cake_wallet/store/yat/yat_store.dart';
 import 'package:cw_core/currency.dart';
 import 'package:intl/intl.dart';
 import 'package:mobx/mobx.dart';
-import 'package:cw_core/wallet_base.dart';
 import 'package:cake_wallet/utils/list_item.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:cw_core/wallet_type.dart';
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
-import 'package:cw_core/transaction_history.dart';
-import 'package:cw_core/balance.dart';
-import 'package:cw_core/transaction_info.dart';
 import 'package:cake_wallet/store/app_store.dart';
 import 'package:cake_wallet/monero/monero.dart';
 import 'package:cake_wallet/haven/haven.dart';
@@ -110,29 +107,36 @@ class EthereumURI extends PaymentURI {
   }
 }
 
-abstract class WalletAddressListViewModelBase with Store {
+abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewModel with Store {
   WalletAddressListViewModelBase({
     required AppStore appStore,
     required this.yatStore,
     required this.fiatConversionStore,
-  })  : _appStore = appStore,
-        _baseItems = <ListItem>[],
-        _wallet = appStore.wallet!,
+  })  : _baseItems = <ListItem>[],
         selectedCurrency = walletTypeToCryptoCurrency(appStore.wallet!.type),
         _cryptoNumberFormat = NumberFormat(_cryptoNumberPattern),
         hasAccounts =
             appStore.wallet!.type == WalletType.monero || appStore.wallet!.type == WalletType.haven,
-        amount = '' {
+        amount = '',
+        super(appStore: appStore) {
     _init();
   }
 
+  @override
+  void onWalletChange(wallet) {
+    _init();
+
+    selectedCurrency = walletTypeToCryptoCurrency(wallet.type);
+    hasAccounts = wallet.type == WalletType.monero || wallet.type == WalletType.haven;
+  }
+
   static const String _cryptoNumberPattern = '0.00000000';
 
   final NumberFormat _cryptoNumberFormat;
 
   final FiatConversionStore fiatConversionStore;
 
-  List<Currency> get currencies => [walletTypeToCryptoCurrency(_wallet.type), ...FiatCurrency.all];
+  List<Currency> get currencies => [walletTypeToCryptoCurrency(wallet.type), ...FiatCurrency.all];
 
   @observable
   Currency selectedCurrency;
@@ -144,31 +148,31 @@ abstract class WalletAddressListViewModelBase with Store {
   String amount;
 
   @computed
-  WalletType get type => _wallet.type;
+  WalletType get type => wallet.type;
 
   @computed
   WalletAddressListItem get address =>
-      WalletAddressListItem(address: _wallet.walletAddresses.address, isPrimary: false);
+      WalletAddressListItem(address: wallet.walletAddresses.address, isPrimary: false);
 
   @computed
   PaymentURI get uri {
-    if (_wallet.type == WalletType.monero) {
+    if (wallet.type == WalletType.monero) {
       return MoneroURI(amount: amount, address: address.address);
     }
 
-    if (_wallet.type == WalletType.haven) {
+    if (wallet.type == WalletType.haven) {
       return HavenURI(amount: amount, address: address.address);
     }
 
-    if (_wallet.type == WalletType.bitcoin) {
+    if (wallet.type == WalletType.bitcoin) {
       return BitcoinURI(amount: amount, address: address.address);
     }
 
-    if (_wallet.type == WalletType.litecoin) {
+    if (wallet.type == WalletType.litecoin) {
       return LitecoinURI(amount: amount, address: address.address);
     }
 
-    if (_wallet.type == WalletType.ethereum) {
+    if (wallet.type == WalletType.ethereum) {
       return EthereumURI(amount: amount, address: address.address);
     }
 
@@ -182,7 +186,6 @@ abstract class WalletAddressListViewModelBase with Store {
 
   @computed
   ObservableList<ListItem> get addressList {
-    final wallet = _wallet;
     final addressList = ObservableList<ListItem>();
 
     if (wallet.type == WalletType.monero) {
@@ -237,8 +240,6 @@ abstract class WalletAddressListViewModelBase with Store {
 
   @computed
   String get accountLabel {
-    final wallet = _wallet;
-
     if (wallet.type == WalletType.monero) {
       return monero!.getCurrentAccount(wallet).label;
     }
@@ -251,29 +252,24 @@ abstract class WalletAddressListViewModelBase with Store {
   }
 
   @computed
-  bool get hasAddressList => _wallet.type == WalletType.monero || _wallet.type == WalletType.haven;
+  bool get hasAddressList => wallet.type == WalletType.monero || wallet.type == WalletType.haven;
 
   @computed
   bool get showElectrumAddressDisclaimer =>
-      _wallet.type == WalletType.bitcoin || _wallet.type == WalletType.litecoin;
-
-  @observable
-  WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> _wallet;
+      wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin;
 
   List<ListItem> _baseItems;
 
-  AppStore _appStore;
-
   final YatStore yatStore;
 
   @action
   void setAddress(WalletAddressListItem address) =>
-      _wallet.walletAddresses.address = address.address;
+      wallet.walletAddresses.address = address.address;
 
   void _init() {
     _baseItems = [];
 
-    if (_wallet.type == WalletType.monero || _wallet.type == WalletType.haven) {
+    if (wallet.type == WalletType.monero || wallet.type == WalletType.haven) {
       _baseItems.add(WalletAccountListHeader());
     }
 
@@ -294,7 +290,7 @@ abstract class WalletAddressListViewModelBase with Store {
   }
 
   void _convertAmountToCrypto() {
-    final cryptoCurrency = walletTypeToCryptoCurrency(_wallet.type);
+    final cryptoCurrency = walletTypeToCryptoCurrency(wallet.type);
     try {
       final crypto =
           double.parse(amount.replaceAll(',', '.')) / fiatConversionStore.prices[cryptoCurrency]!;
diff --git a/lib/view_model/wallet_keys_view_model.dart b/lib/view_model/wallet_keys_view_model.dart
index 0a758ccfb..0233e13e9 100644
--- a/lib/view_model/wallet_keys_view_model.dart
+++ b/lib/view_model/wallet_keys_view_model.dart
@@ -69,7 +69,7 @@ abstract class WalletKeysViewModelBase with Store {
           StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']!),
         if (keys['privateViewKey'] != null)
           StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']!),
-        StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed),
+        StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
       ]);
     }
 
@@ -85,15 +85,23 @@ abstract class WalletKeysViewModelBase with Store {
           StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']!),
         if (keys['privateViewKey'] != null)
           StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']!),
-        StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed),
+        StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
       ]);
     }
 
     if (_appStore.wallet!.type == WalletType.bitcoin ||
-        _appStore.wallet!.type == WalletType.litecoin ||
-        _appStore.wallet!.type == WalletType.ethereum) {
+        _appStore.wallet!.type == WalletType.litecoin) {
       items.addAll([
-        StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed),
+        StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
+      ]);
+    }
+
+    if (_appStore.wallet!.type == WalletType.ethereum) {
+      items.addAll([
+        if (_appStore.wallet!.privateKey != null)
+          StandartListItem(title: S.current.private_key, value: _appStore.wallet!.privateKey!),
+        if (_appStore.wallet!.seed != null)
+          StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
       ]);
     }
   }
@@ -139,7 +147,8 @@ abstract class WalletKeysViewModelBase with Store {
   Future<Map<String, String>> get _queryParams async {
     final restoreHeightResult = await restoreHeight;
     return {
-      'seed': _appStore.wallet!.seed,
+      if (_appStore.wallet!.seed != null) 'seed': _appStore.wallet!.seed!,
+      if (_appStore.wallet!.privateKey != null) 'private_key': _appStore.wallet!.privateKey!,
       if (restoreHeightResult != null) ...{'height': restoreHeightResult}
     };
   }
diff --git a/lib/view_model/wallet_restoration_from_keys_vm.dart b/lib/view_model/wallet_restoration_from_keys_vm.dart
deleted file mode 100644
index 97cb8d519..000000000
--- a/lib/view_model/wallet_restoration_from_keys_vm.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
-import 'package:flutter/foundation.dart';
-import 'package:hive/hive.dart';
-import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/monero/monero.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:cake_wallet/view_model/wallet_creation_vm.dart';
-import 'package:cw_core/wallet_info.dart';
-import 'package:cake_wallet/bitcoin/bitcoin.dart';
-
-part 'wallet_restoration_from_keys_vm.g.dart';
-
-class WalletRestorationFromKeysVM = WalletRestorationFromKeysVMBase
-    with _$WalletRestorationFromKeysVM;
-
-abstract class WalletRestorationFromKeysVMBase extends WalletCreationVM
-    with Store {
-  WalletRestorationFromKeysVMBase(AppStore appStore,
-      WalletCreationService walletCreationService, Box<WalletInfo> walletInfoSource,
-      {required WalletType type, required this.language})
-      : height = 0,
-        viewKey = '',
-        spendKey = '',
-        wif = '',
-        address = '',
-        super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
-
-  @observable
-  int height;
-
-  @observable
-  String viewKey;
-
-  @observable
-  String spendKey;
-
-  @observable
-  String wif;
-
-  @observable
-  String address;
-
-  bool get hasRestorationHeight => type == WalletType.monero;
-
-  final String language;
-
-  @override
-  WalletCredentials getCredentials(dynamic options) {
-    final password = generateWalletPassword();
-
-    switch (type) {
-      case WalletType.monero:
-        return monero!.createMoneroRestoreWalletFromKeysCredentials(
-            name: name,
-            password: password,
-            language: language,
-            address: address,
-            viewKey: viewKey,
-            spendKey: spendKey,
-            height: height);
-      case WalletType.bitcoin:
-        return bitcoin!.createBitcoinRestoreWalletFromWIFCredentials(
-            name: name, password: password, wif: wif);
-      default:
-        throw Exception('Unexpected type: ${type.toString()}');
-    }
-  }
-
-  @override
-  Future<WalletBase> process(WalletCredentials credentials) async =>
-      walletCreationService.restoreFromKeys(credentials);
-}
diff --git a/lib/view_model/wallet_restoration_from_seed_vm.dart b/lib/view_model/wallet_restoration_from_seed_vm.dart
deleted file mode 100644
index 0caa7f37d..000000000
--- a/lib/view_model/wallet_restoration_from_seed_vm.dart
+++ /dev/null
@@ -1,58 +0,0 @@
-import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
-import 'package:flutter/foundation.dart';
-import 'package:hive/hive.dart';
-import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/monero/monero.dart';
-import 'package:cake_wallet/store/app_store.dart';
-import 'package:cake_wallet/bitcoin/bitcoin.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:cake_wallet/view_model/wallet_creation_vm.dart';
-import 'package:cw_core/wallet_info.dart';
-
-part 'wallet_restoration_from_seed_vm.g.dart';
-
-class WalletRestorationFromSeedVM = WalletRestorationFromSeedVMBase
-    with _$WalletRestorationFromSeedVM;
-
-abstract class WalletRestorationFromSeedVMBase extends WalletCreationVM
-    with Store {
-  WalletRestorationFromSeedVMBase(AppStore appStore,
-      WalletCreationService walletCreationService, Box<WalletInfo> walletInfoSource,
-      {required WalletType type, required this.language, this.seed = ''})
-      : height = 0,
-        super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
-
-  @observable
-  String seed;
-
-  @observable
-  int height;
-
-  bool get hasRestorationHeight => type == WalletType.monero;
-
-  final String language;
-
-  @override
-  WalletCredentials getCredentials(dynamic options) {
-    final password = generateWalletPassword();
-
-    switch (type) {
-      case WalletType.monero:
-        return monero!.createMoneroRestoreWalletFromSeedCredentials(
-            name: name, height: height, mnemonic: seed, password: password);
-      case WalletType.bitcoin:
-        return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
-            name: name, mnemonic: seed, password: password);
-      default:
-        throw Exception('Unexpected type: ${type.toString()}');
-    }
-  }
-
-  @override
-  Future<WalletBase> process(WalletCredentials credentials) async =>
-      walletCreationService.restoreFromSeed(credentials);
-}
diff --git a/lib/view_model/wallet_restore_view_model.dart b/lib/view_model/wallet_restore_view_model.dart
index 564c31c61..3c51e3e03 100644
--- a/lib/view_model/wallet_restore_view_model.dart
+++ b/lib/view_model/wallet_restore_view_model.dart
@@ -1,7 +1,4 @@
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
-import 'package:cake_wallet/core/mnemonic_length.dart';
-import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
-import 'package:flutter/foundation.dart';
 import 'package:cake_wallet/ethereum/ethereum.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
@@ -19,7 +16,6 @@ import 'package:cake_wallet/view_model/restore/restore_mode.dart';
 
 part 'wallet_restore_view_model.g.dart';
 
-
 class WalletRestoreViewModel = WalletRestoreViewModelBase
     with _$WalletRestoreViewModel;
 
@@ -27,11 +23,13 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
   WalletRestoreViewModelBase(AppStore appStore, WalletCreationService walletCreationService,
       Box<WalletInfo> walletInfoSource,
       {required WalletType type})
-      : availableModes = (type == WalletType.monero || type == WalletType.haven)
-            ? WalletRestoreMode.values
-            : [WalletRestoreMode.seed],
+      : availableModes =
+            (type == WalletType.monero || type == WalletType.haven || type == WalletType.ethereum)
+                ? WalletRestoreMode.values
+                : [WalletRestoreMode.seed],
         hasSeedLanguageSelector = type == WalletType.monero || type == WalletType.haven,
         hasBlockchainHeightLanguageSelector = type == WalletType.monero || type == WalletType.haven,
+        hasRestoreFromPrivateKey = type == WalletType.ethereum,
         isButtonEnabled = false,
         mode = WalletRestoreMode.seed,
         super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true) {
@@ -47,13 +45,14 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
   final List<WalletRestoreMode> availableModes;
   final bool hasSeedLanguageSelector;
   final bool hasBlockchainHeightLanguageSelector;
+  final bool hasRestoreFromPrivateKey;
 
   @observable
   WalletRestoreMode mode;
 
   @observable
   bool isButtonEnabled;
-  
+
   @override
   WalletCredentials getCredentials(dynamic options) {
     final password = walletPassword ?? generateWalletPassword();
@@ -97,17 +96,17 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
     }
 
     if (mode == WalletRestoreMode.keys) {
-      final viewKey = options['viewKey'] as String;
-      final spendKey = options['spendKey'] as String;
-      final address = options['address'] as String;
+      final viewKey = options['viewKey'] as String?;
+      final spendKey = options['spendKey'] as String?;
+      final address = options['address'] as String?;
 
       if (type == WalletType.monero) {
         return monero!.createMoneroRestoreWalletFromKeysCredentials(
             name: name,
             height: height,
-            spendKey: spendKey,
-            viewKey: viewKey,
-            address: address,
+            spendKey: spendKey!,
+            viewKey: viewKey!,
+            address: address!,
             password: password,
             language: 'English');
       }
@@ -116,12 +115,20 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
         return haven!.createHavenRestoreWalletFromKeysCredentials(
             name: name,
             height: height,
-            spendKey: spendKey,
-            viewKey: viewKey,
-            address: address,
+            spendKey: spendKey!,
+            viewKey: viewKey!,
+            address: address!,
             password: password,
             language: 'English');
       }
+
+      if (type == WalletType.ethereum) {
+        return ethereum!.createEthereumRestoreWalletFromPrivateKey(
+          name: name,
+          privateKey: options['private_key'] as String,
+          password: password,
+        );
+      }
     }
 
     throw Exception('Unexpected type: ${type.toString()}');
diff --git a/lib/view_model/wallet_seed_view_model.dart b/lib/view_model/wallet_seed_view_model.dart
index 4a9c0009b..8923a99da 100644
--- a/lib/view_model/wallet_seed_view_model.dart
+++ b/lib/view_model/wallet_seed_view_model.dart
@@ -8,7 +8,7 @@ class WalletSeedViewModel = WalletSeedViewModelBase with _$WalletSeedViewModel;
 abstract class WalletSeedViewModelBase with Store {
   WalletSeedViewModelBase(WalletBase wallet)
       : name = wallet.name,
-        seed = wallet.seed;
+        seed = wallet.seed!;
 
   @observable
   String name;
diff --git a/macos/Podfile.lock b/macos/Podfile.lock
index 6657ec4dc..664a5231b 100644
--- a/macos/Podfile.lock
+++ b/macos/Podfile.lock
@@ -57,11 +57,11 @@ DEPENDENCIES:
   - 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`)
-  - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`)
+  - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
   - platform_device_id (from `Flutter/ephemeral/.symlinks/plugins/platform_device_id/macos`)
   - platform_device_id_macos (from `Flutter/ephemeral/.symlinks/plugins/platform_device_id_macos/macos`)
   - share_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos`)
-  - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos`)
+  - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
   - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
   - wakelock_macos (from `Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos`)
 
@@ -87,7 +87,7 @@ EXTERNAL SOURCES:
   package_info:
     :path: Flutter/ephemeral/.symlinks/plugins/package_info/macos
   path_provider_foundation:
-    :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos
+    :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
   platform_device_id:
     :path: Flutter/ephemeral/.symlinks/plugins/platform_device_id/macos
   platform_device_id_macos:
@@ -95,7 +95,7 @@ EXTERNAL SOURCES:
   share_plus_macos:
     :path: Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos
   shared_preferences_foundation:
-    :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos
+    :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
   url_launcher_macos:
     :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
   wakelock_macos:
diff --git a/pubspec_base.yaml b/pubspec_base.yaml
index 25a73fb9d..0216658be 100644
--- a/pubspec_base.yaml
+++ b/pubspec_base.yaml
@@ -92,7 +92,10 @@ dev_dependencies:
   # check flutter_launcher_icons for usage
   pedantic: ^1.8.0
   # replace https://github.com/dart-lang/lints#migrating-from-packagepedantic
-#  translator: ^0.1.7
+  translator:
+    git:
+      url: https://github.com/cake-tech/google-translator.git
+      version: 1.0.0
 
 flutter_icons:
   image_path: "assets/images/app_logo.png"
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index cd88744e3..10af91655 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -686,5 +686,15 @@
   "monero_light_theme": " ضوء مونيرو",
   "etherscan_history": "Etherscan تاريخ",
   "manage_nodes": "ﺪﻘﻌﻟﺍ ﺓﺭﺍﺩﺇ",
-  "template_name": "اسم القالب"
+  "template_name": "اسم القالب",
+  "support_title_live_chat": "الدعم المباشر",
+  "support_description_live_chat": "حرة وسريعة! ممثلو الدعم المدربين متاحون للمساعدة",
+  "support_title_guides": "أدلة محفظة كعكة",
+  "support_description_guides": "توثيق ودعم القضايا المشتركة",
+  "support_title_other_links": "روابط دعم أخرى",
+  "support_description_other_links": "انضم إلى مجتمعاتنا أو تصل إلينا شركائنا من خلال أساليب أخرى",
+  "select_destination": ".ﻲﻃﺎﻴﺘﺣﻻﺍ ﺦﺴﻨﻟﺍ ﻒﻠﻣ ﺔﻬﺟﻭ ﺪﻳﺪﺤﺗ ءﺎﺟﺮﻟﺍ",
+  "save_to_downloads": "ﺕﻼﻳﺰﻨﺘﻟﺍ ﻲﻓ ﻆﻔﺣ",
+  "support_description_other_links": "انضم إلى مجتمعاتنا أو تصل إلينا شركائنا من خلال أساليب أخرى",
+  "auto_generate_subaddresses": "تلقائي توليد subddresses"
 }
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index a0c372718..b558cd300 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -639,18 +639,19 @@
   "setup_totp_recommended": "Настройка на TOTP (препоръчително)",
   "disable_buy": "Деактивирайте действието за покупка",
   "disable_sell": "Деактивирайте действието за продажба",
-    "cake_2fa_preset" : "Торта 2FA Preset",
+  "auto_generate_subaddresses": "Автоматично генериране на подадреси",
+  "cake_2fa_preset": "Торта 2FA Preset",
   "narrow": "Тесен",
   "normal": "нормално",
   "aggressive": "Прекалено усърден",
   "require_for_assessing_wallet": "Изискване за достъп до портфейла",
-  "require_for_sends_to_non_contacts" : "Изискване за изпращане до лица без контакт",
-  "require_for_sends_to_contacts" : "Изискване за изпращане до контакти",
-  "require_for_sends_to_internal_wallets" : "Изискване за изпращане до вътрешни портфейли",
-  "require_for_exchanges_to_internal_wallets" : "Изискване за обмен към вътрешни портфейли",
-  "require_for_adding_contacts" : "Изисква се за добавяне на контакти",
-  "require_for_creating_new_wallets" : "Изискване за създаване на нови портфейли",
-  "require_for_all_security_and_backup_settings" : "Изисква се за всички настройки за сигурност и архивиране",
+  "require_for_sends_to_non_contacts": "Изискване за изпращане до лица без контакт",
+  "require_for_sends_to_contacts": "Изискване за изпращане до контакти",
+  "require_for_sends_to_internal_wallets": "Изискване за изпращане до вътрешни портфейли",
+  "require_for_exchanges_to_internal_wallets": "Изискване за обмен към вътрешни портфейли",
+  "require_for_adding_contacts": "Изисква се за добавяне на контакти",
+  "require_for_creating_new_wallets": "Изискване за създаване на нови портфейли",
+  "require_for_all_security_and_backup_settings": "Изисква се за всички настройки за сигурност и архивиране",
   "available_balance_description": "Това е балансът, който можете да използвате за покупка на криптовалути. Това не включва замразените средства.",
   "syncing_wallet_alert_title": "Вашият портфейл се синхронизира",
   "syncing_wallet_alert_content": "Списъкът ви с баланс и транзакции може да не е пълен, докато в горната част не пише „СИНХРОНИЗИРАН“. Кликнете/докоснете, за да научите повече.",
@@ -683,5 +684,13 @@
   "monero_light_theme": "Лека тема Monero",
   "etherscan_history": "История на Etherscan",
   "manage_nodes": "Управление на възли",
-  "template_name": "Име на шаблон"
+  "template_name": "Име на шаблон",
+  "support_title_live_chat": "Подкрепа на живо",
+  "support_description_live_chat": "Безплатно и бързо! Обучени представители на подкрепата са на разположение за подпомагане",
+  "support_title_guides": "Ръководства за портфейл за торта",
+  "support_description_guides": "Документация и подкрепа за общи проблеми",
+  "support_title_other_links": "Други връзки за поддръжка",
+  "support_description_other_links": "Присъединете се към нашите общности или се свържете с нас нашите партньори чрез други методи",
+  "select_destination": "Моля, изберете дестинация за архивния файл.",
+  "save_to_downloads": "Запазване в Изтегляния"
 }
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index bde5c29c2..0d2115ab3 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -632,18 +632,19 @@
   "setup_totp_recommended": "Nastavit TOTP (doporučeno)",
   "disable_buy": "Zakázat akci nákupu",
   "disable_sell": "Zakázat akci prodeje",
-  "cake_2fa_preset" : "Předvolba Cake 2FA",
+  "auto_generate_subaddresses": "Automaticky generovat podadresy",
+  "cake_2fa_preset": "Předvolba Cake 2FA",
   "narrow": "Úzký",
   "normal": "Normální",
   "aggressive": "Agresivní",
   "require_for_assessing_wallet": "Vyžadovat pro přístup k peněžence",
-  "require_for_sends_to_non_contacts" : "Vyžadovat pro odesílání nekontaktním osobám",
-  "require_for_sends_to_contacts" : "Vyžadovat pro odeslání kontaktům",
-  "require_for_sends_to_internal_wallets" : "Vyžadovat pro odesílání do interních peněženek",
-  "require_for_exchanges_to_internal_wallets" : "Vyžadovat pro výměny do interních peněženek",
-  "require_for_adding_contacts" : "Vyžadovat pro přidání kontaktů",
-  "require_for_creating_new_wallets" : "Vyžadovat pro vytváření nových peněženek",
-  "require_for_all_security_and_backup_settings" : "Vyžadovat všechna nastavení zabezpečení a zálohování",
+  "require_for_sends_to_non_contacts": "Vyžadovat pro odesílání nekontaktním osobám",
+  "require_for_sends_to_contacts": "Vyžadovat pro odeslání kontaktům",
+  "require_for_sends_to_internal_wallets": "Vyžadovat pro odesílání do interních peněženek",
+  "require_for_exchanges_to_internal_wallets": "Vyžadovat pro výměny do interních peněženek",
+  "require_for_adding_contacts": "Vyžadovat pro přidání kontaktů",
+  "require_for_creating_new_wallets": "Vyžadovat pro vytváření nových peněženek",
+  "require_for_all_security_and_backup_settings": "Vyžadovat všechna nastavení zabezpečení a zálohování",
   "available_balance_description": "Dostupná částka je částka, kterou můžete okamžitě utratit. Zmrazená částka je částka, která ještě není k dispozici, protože ještě nebyla potvrzena síťovým protokolem.",
   "syncing_wallet_alert_title": "Vaše peněženka se synchronizuje",
   "syncing_wallet_alert_content": "Váš seznam zůstatků a transakcí nemusí být úplný, dokud nebude nahoře uvedeno „SYNCHRONIZOVANÉ“. Kliknutím/klepnutím se dozvíte více.",
@@ -676,5 +677,13 @@
   "monero_light_theme": "Světlé téma Monero",
   "manage_nodes": "Spravovat uzly",
   "etherscan_history": "Historie Etherscanu",
-  "template_name": "Název šablony"
+  "template_name": "Název šablony",
+  "support_title_live_chat": "Živá podpora",
+  "support_description_live_chat": "Zdarma a rychle! K dispozici jsou zástupci vyškolených podpůrných podpory",
+  "support_title_guides": "Průvodce peněženkami dortu",
+  "support_description_guides": "Dokumentace a podpora běžných otázek",
+  "support_title_other_links": "Další odkazy na podporu",
+  "support_description_other_links": "Připojte se k našim komunitám nebo se k nám oslovte další metody",
+  "select_destination": "Vyberte cíl pro záložní soubor.",
+  "save_to_downloads": "Uložit do Stažených souborů"
 }
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 92c5a7bb9..5a795e35d 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -5,10 +5,10 @@
   "please_make_selection": "Bitte treffen Sie unten eine Auswahl zum Erstellen oder Wiederherstellen Ihrer Wallet.",
   "create_new": "Neue Wallet erstellen",
   "restore_wallet": "Wallet wiederherstellen",
-  "monero_com": "Monero.com by Cake Wallet",
-  "monero_com_wallet_text": "Awesome wallet for Monero",
-  "haven_app": "Haven by Cake Wallet",
-  "haven_app_wallet_text": "Awesome wallet for Haven",
+  "monero_com": "Monero.com von Cake Wallet",
+  "monero_com_wallet_text": "Eine großartige Wallet für Monero",
+  "haven_app": "Haven von Cake Wallet",
+  "haven_app_wallet_text": "Eine großartige Wallet für Haven",
   "accounts": "Konten",
   "edit": "Bearbeiten",
   "account": "Konto",
@@ -152,10 +152,10 @@
   "restore_wallet_restore_description": "Beschreibung zur Wallet-Wiederherstellung",
   "restore_new_seed": "Neuer Seed",
   "restore_active_seed": "Aktiver Seed",
-  "restore_bitcoin_description_from_seed": "Stellen Sie Ihre Brieftasche aus dem 24-Wort-Kombinationscode wieder her",
-  "restore_bitcoin_description_from_keys": "Stellen Sie Ihre Brieftasche aus der generierten WIF-Zeichenfolge aus Ihren privaten Schlüsseln wieder her",
+  "restore_bitcoin_description_from_seed": "Stellen Sie Ihre Wallet aus dem 24-Wort-Kombinationscode wieder her",
+  "restore_bitcoin_description_from_keys": "Stellen Sie Ihre Wallet aus der generierten WIF-Zeichenfolge aus Ihren privaten Schlüsseln wieder her",
   "restore_bitcoin_title_from_keys": "Aus WIF wiederherstellen",
-  "restore_from_date_or_blockheight": "Bitte geben Sie ein Datum ein, das einige Tage vor dem Erstellen dieser Brieftasche liegt. Oder wenn Sie die Blockhöhe kennen, geben Sie stattdessen diese ein",
+  "restore_from_date_or_blockheight": "Bitte geben Sie ein Datum ein, das einige Tage vor dem Erstellen dieser Wallet liegt. Oder wenn Sie die Blockhöhe kennen, geben Sie stattdessen diese ein",
   "seed_reminder": "Bitte notieren Sie diese für den Fall, dass Sie Ihr Telefon verlieren oder es kaputtgeht",
   "seed_title": "Seed",
   "seed_share": "Seed teilen",
@@ -409,7 +409,7 @@
   "buy_bitcoin": "Bitcoin kaufen",
   "buy_with": "Kaufen mit",
   "moonpay_alert_text": "Der Wert des Betrags muss größer oder gleich ${minAmount} ${fiatCurrency} sein",
-  "outdated_electrum_wallet_receive_warning": "Wenn diese Brieftasche einen 12-Wort-Seed hat und in Cake erstellt wurde, zahlen Sie KEINE Bitcoins in diese Brieftasche ein. Alle auf diese Wallet übertragenen BTC können verloren gehen. Erstellen Sie eine neue 24-Wort-Wallet (tippen Sie auf das Menü oben rechts, wählen Sie Wallets, wählen Sie Neue Wallet erstellen und dann Bitcoin) und verschieben Sie Ihre BTC SOFORT dorthin. Neue (24-Wort-)BTC-Wallets von Cake sind sicher",
+  "outdated_electrum_wallet_receive_warning": "Wenn diese Wallet einen 12-Wort-Seed hat und in Cake erstellt wurde, zahlen Sie KEINE Bitcoins in diese Wallet ein. Alle auf diese Wallet übertragenen BTC können verloren gehen. Erstellen Sie eine neue 24-Wort-Wallet (tippen Sie auf das Menü oben rechts, wählen Sie Wallets, wählen Sie Neue Wallet erstellen und dann Bitcoin) und verschieben Sie Ihre BTC SOFORT dorthin. Neue (24-Wort-)BTC-Wallets von Cake sind sicher",
   "do_not_show_me": "Zeig mir das nicht noch einmal",
   "unspent_coins_title": "Nicht ausgegebene Münzen",
   "unspent_coins_details_title": "Details zu nicht ausgegebenen Münzen",
@@ -602,10 +602,10 @@
   "sweeping_wallet_alert": "Das sollte nicht lange dauern. VERLASSEN SIE DIESEN BILDSCHIRM NICHT, ANDERNFALLS KÖNNEN DIE SWEPT-GELDER VERLOREN GEHEN",
   "decimal_places_error": "Zu viele Nachkommastellen",
   "edit_node": "Knoten bearbeiten",
-  "frozen_balance": "Gefrorenes Gleichgewicht",
+  "frozen_balance": "Gefrorenes Guthaben",
   "invoice_details": "Rechnungs-Details",
   "donation_link_details": "Details zum Spendenlink",
-  "anonpay_description": "Generieren Sie ${type}. Der Empfänger kann ${method} mit jeder unterstützten Kryptowährung verwenden, und Sie erhalten Geld in dieser Brieftasche.",
+  "anonpay_description": "Generieren Sie ${type}. Der Empfänger kann ${method} mit jeder unterstützten Kryptowährung verwenden, und Sie erhalten Geld in dieser Wallet.",
   "create_invoice": "Rechnung erstellen",
   "create_donation_link": "Spendenlink erstellen",
   "optional_email_hint": "Optionale Benachrichtigungs-E-Mail für den Zahlungsempfänger",
@@ -621,22 +621,22 @@
   "prevent_screenshots": "Verhindern Sie Screenshots und Bildschirmaufzeichnungen",
   "profile": "Profil",
   "close": "Schließen",
-  "modify_2fa": "Kuchen 2FA ändern",
-  "disable_cake_2fa": "Kuchen 2FA deaktivieren",
-  "question_to_disable_2fa": "Sind Sie sicher, dass Sie Cake 2FA deaktivieren möchten? Für den Zugriff auf die Brieftasche und bestimmte Funktionen wird kein 2FA-Code mehr benötigt.",
+  "modify_2fa": "Cake 2FA ändern",
+  "disable_cake_2fa": "Cake 2FA deaktivieren",
+  "question_to_disable_2fa": "Sind Sie sicher, dass Sie Cake 2FA deaktivieren möchten? Für den Zugriff auf die Wallet und bestimmte Funktionen wird kein 2FA-Code mehr benötigt.",
   "disable": "Deaktivieren",
-  "setup_2fa": "Setup-Kuchen 2FA",
+  "setup_2fa": "Setup-Cake 2FA",
   "verify_with_2fa": "Verifizieren Sie mit Cake 2FA",
   "totp_code": "TOTP-Code",
   "please_fill_totp": "Bitte geben Sie den 8-stelligen Code ein, der auf Ihrem anderen Gerät vorhanden ist",
-  "totp_2fa_success": "Erfolg! Cake 2FA für dieses Wallet aktiviert. Denken Sie daran, Ihren mnemonischen Seed zu speichern, falls Sie den Zugriff auf die Brieftasche verlieren.",
+  "totp_2fa_success": "Erfolg! Cake 2FA für dieses Wallet aktiviert. Denken Sie daran, Ihren mnemonischen Seed zu speichern, falls Sie den Zugriff auf die Wallet verlieren.",
   "totp_verification_success": "Verifizierung erfolgreich!",
   "totp_2fa_failure": "Falscher Code. Bitte versuchen Sie es mit einem anderen Code oder generieren Sie einen neuen geheimen Schlüssel. Verwenden Sie eine kompatible 2FA-App, die 8-stellige Codes und SHA512 unterstützt.",
   "enter_totp_code": "Bitte geben Sie den TOTP-Code ein.",
   "add_secret_code": "Fügen Sie diesen Geheimcode einem anderen Gerät hinzu",
   "totp_secret_code": "TOTP-Geheimcode",
   "important_note": "Wichtiger Hinweis",
-  "setup_2fa_text": "Cake 2FA ist NICHT so sicher wie eine Kühllagerung. 2FA schützt vor grundlegenden Arten von Angriffen, z. B. wenn Ihr Freund Ihren Fingerabdruck bereitstellt, während Sie schlafen.\n\n Cake 2FA schützt NICHT vor einem kompromittierten Gerät durch einen raffinierten Angreifer.\n\n Wenn Sie den Zugriff auf Ihre 2FA-Codes verlieren , VERLIEREN SIE DEN ZUGANG ZU DIESEM WALLET. Sie müssen Ihre Brieftasche aus mnemonic Seed wiederherstellen. SIE MÜSSEN DESHALB IHRE MNEMONISCHEN SEEDS SICHERN! Außerdem kann jemand mit Zugriff auf Ihre mnemonischen Seed(s) Ihr Geld stehlen und Cake 2FA umgehen.\n\n Cake-Supportmitarbeiter können Ihnen nicht helfen, wenn Sie den Zugriff auf Ihre mnemonischen Seed(s) verlieren, da Cake ein Brieftasche ohne Verwahrung.",
+  "setup_2fa_text": "Cake 2FA ist NICHT so sicher wie eine Kühllagerung. 2FA schützt vor grundlegenden Arten von Angriffen, z. B. wenn Ihr Freund Ihren Fingerabdruck bereitstellt, während Sie schlafen.\n\n Cake 2FA schützt NICHT vor einem kompromittierten Gerät durch einen raffinierten Angreifer.\n\n Wenn Sie den Zugriff auf Ihre 2FA-Codes verlieren , VERLIEREN SIE DEN ZUGANG ZU DIESEM WALLET. Sie müssen Ihre Wallet aus mnemonic Seed wiederherstellen. SIE MÜSSEN DESHALB IHRE MNEMONISCHEN SEEDS SICHERN! Außerdem kann jemand mit Zugriff auf Ihre mnemonischen Seed(s) Ihr Geld stehlen und Cake 2FA umgehen.\n\n Cake-Supportmitarbeiter können Ihnen nicht helfen, wenn Sie den Zugriff auf Ihre mnemonischen Seed(s) verlieren, da Cake Wallet eine Wallet ohne treuhänderische Verwahrung ist.",
   "setup_totp_recommended": "TOTP einrichten (empfohlen)",
   "disable_buy": "Kaufaktion deaktivieren",
   "disable_sell": "Verkaufsaktion deaktivieren",
@@ -646,18 +646,19 @@
   "high_contrast_theme": "Kontrastreiches Thema",
   "matrix_green_dark_theme": "Matrix Green Dark Theme",
   "monero_light_theme": "Monero Light-Thema",
-  "cake_2fa_preset" : "Kuchen 2FA-Voreinstellung",
+  "auto_generate_subaddresses": "Unteradressen automatisch generieren",
+  "cake_2fa_preset" : "Cake 2FA-Voreinstellung",
   "narrow": "Eng",
   "normal": "Normal",
   "aggressive": "Übereifrig",
   "require_for_assessing_wallet": "Für den Zugriff auf die Wallet erforderlich",
-  "require_for_sends_to_non_contacts" : "Erforderlich für Versendungen an Nichtkontakte",
-  "require_for_sends_to_contacts" : "Erforderlich für Versendungen an Kontakte",
-  "require_for_sends_to_internal_wallets" : "Erforderlich für Sendungen an interne Wallets",
-  "require_for_exchanges_to_internal_wallets" : "Erforderlich für den Umtausch in interne Wallets",
-  "require_for_adding_contacts" : "Erforderlich zum Hinzufügen von Kontakten",
-  "require_for_creating_new_wallets" : "Erforderlich zum Erstellen neuer Wallets",
-  "require_for_all_security_and_backup_settings" : "Für alle Sicherheits- und Sicherungseinstellungen erforderlich",
+  "require_for_sends_to_non_contacts": "Erforderlich für Versendungen an Nichtkontakte",
+  "require_for_sends_to_contacts": "Erforderlich für Versendungen an Kontakte",
+  "require_for_sends_to_internal_wallets": "Erforderlich für Sendungen an interne Wallets",
+  "require_for_exchanges_to_internal_wallets": "Erforderlich für den Umtausch in interne Wallets",
+  "require_for_adding_contacts": "Erforderlich zum Hinzufügen von Kontakten",
+  "require_for_creating_new_wallets": "Erforderlich zum Erstellen neuer Wallets",
+  "require_for_all_security_and_backup_settings": "Für alle Sicherheits- und Sicherungseinstellungen erforderlich",
   "available_balance_description": "Verfügbarer Saldo ist der Betrag, den Sie sofort ausgeben können. Dieser Betrag kann sich ändern, wenn Sie eine Transaktion senden oder empfangen.",
   "syncing_wallet_alert_title": "Ihr Wallet wird synchronisiert",
   "syncing_wallet_alert_content": "Ihr Kontostand und Ihre Transaktionsliste sind möglicherweise erst vollständig, wenn oben „SYNCHRONISIERT“ steht. Klicken/tippen Sie, um mehr zu erfahren.",
@@ -684,5 +685,13 @@
   "slidable": "Verschiebbar",
   "manage_nodes": "Knoten verwalten",
   "etherscan_history": "Etherscan-Geschichte",
-  "template_name": "Vorlagenname"
+  "template_name": "Vorlagenname",
+  "support_title_live_chat": "Live Support",
+  "support_description_live_chat": "Kostenlos und schnell! Ausgebildete Mitarbeiter stehen zur Unterstützung bereit, um zu helfen",
+  "support_title_guides": "Cake Wallet Guides",
+  "support_description_guides": "Dokumentation und Hilfe für bekannte Probleme",
+  "support_title_other_links": "Andere Support-Links",
+  "support_description_other_links": "Treten Sie unseren Communities bei oder erreichen Sie uns oder unsere Partner über andere Methoden",
+  "select_destination": "Bitte wählen Sie das Ziel für die Sicherungsdatei aus.",
+  "save_to_downloads": "Unter „Downloads“ speichern"
 }
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 0bf527110..c56fd5e38 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -574,6 +574,7 @@
   "privacy": "Privacy",
   "display_settings": "Display settings",
   "other_settings": "Other settings",
+  "auto_generate_subaddresses": "Auto generate subaddresses",
   "require_pin_after": "Require PIN after",
   "always": "Always",
   "minutes_to_pin_code": "${minute} minutes",
@@ -646,18 +647,18 @@
   "high_contrast_theme": "High Contrast Theme",
   "matrix_green_dark_theme": "Matrix Green Dark Theme",
   "monero_light_theme": "Monero Light Theme",
-  "cake_2fa_preset" : "Cake 2FA Preset",
+  "cake_2fa_preset": "Cake 2FA Preset",
   "narrow": "Narrow",
   "normal": "Normal",
   "aggressive": "Aggressive",
   "require_for_assessing_wallet": "Require for accessing wallet",
-  "require_for_sends_to_non_contacts" : "Require for sends to non-contacts",
-  "require_for_sends_to_contacts" : "Require for sends to contacts",
-  "require_for_sends_to_internal_wallets" : "Require for sends to internal wallets",
-  "require_for_exchanges_to_internal_wallets" : "Require for exchanges to internal wallets",
-  "require_for_adding_contacts" : "Require for adding contacts",
-  "require_for_creating_new_wallets" : "Require for creating new wallets",
-  "require_for_all_security_and_backup_settings" : "Require for all security and backup settings",
+  "require_for_sends_to_non_contacts": "Require for sends to non-contacts",
+  "require_for_sends_to_contacts": "Require for sends to contacts",
+  "require_for_sends_to_internal_wallets": "Require for sends to internal wallets",
+  "require_for_exchanges_to_internal_wallets": "Require for exchanges to internal wallets",
+  "require_for_adding_contacts": "Require for adding contacts",
+  "require_for_creating_new_wallets": "Require for creating new wallets",
+  "require_for_all_security_and_backup_settings": "Require for all security and backup settings",
   "available_balance_description": "The “Available Balance” or “Confirmed Balance” are funds that can be spent immediately. If funds appear in the lower balance but not the top balance, then you must wait a few minutes for the incoming funds to get more network confirmations. After they get more confirmations, they will be spendable.",
   "syncing_wallet_alert_title": "Your wallet is syncing",
   "syncing_wallet_alert_content": "Your balance and transaction list may not be complete until it says “SYNCHRONIZED” at the top. Click/tap to learn more.",
@@ -684,5 +685,13 @@
   "slidable": "Slidable",
   "manage_nodes": "Manage nodes",
   "etherscan_history": "Etherscan history",
-  "template_name": "Template Name"
+  "template_name": "Template Name",
+  "support_title_live_chat": "Live support",
+  "support_description_live_chat": "Free and fast! Trained support representatives are available to assist",
+  "support_title_guides": "Cake Wallet guides",
+  "support_description_guides": "Documentation and support for common issues",
+  "support_title_other_links": "Other support links",
+  "support_description_other_links": "Join our communities or reach us our our partners through other methods",
+  "select_destination": "Please select destination for the backup file.",
+  "save_to_downloads": "Save to Downloads"
 }
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 15bd3645a..59702382b 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -646,18 +646,19 @@
   "high_contrast_theme": "Tema de alto contraste",
   "matrix_green_dark_theme": "Matrix verde oscuro tema",
   "monero_light_theme": "Tema ligero de Monero",
-  "cake_2fa_preset" : "Pastel 2FA preestablecido",
+  "auto_generate_subaddresses": "Generar subdirecciones automáticamente",
+  "cake_2fa_preset": "Pastel 2FA preestablecido",
   "narrow": "Angosto",
   "normal": "Normal",
   "aggressive": "Demasiado entusiasta",
   "require_for_assessing_wallet": "Requerido para acceder a la billetera",
-  "require_for_sends_to_non_contacts" : "Requerido para envíos a no contactos",
-  "require_for_sends_to_contacts" : "Requerir para envíos a contactos",
-  "require_for_sends_to_internal_wallets" : "Requerido para envíos a billeteras internas",
-  "require_for_exchanges_to_internal_wallets" : "Requerido para intercambios a billeteras internas",
-  "require_for_adding_contacts" : "Requerido para agregar contactos",
-  "require_for_creating_new_wallets" : "Requerido para crear nuevas billeteras",
-  "require_for_all_security_and_backup_settings" : "Requerido para todas las configuraciones de seguridad y copia de seguridad",
+  "require_for_sends_to_non_contacts": "Requerido para envíos a no contactos",
+  "require_for_sends_to_contacts": "Requerir para envíos a contactos",
+  "require_for_sends_to_internal_wallets": "Requerido para envíos a billeteras internas",
+  "require_for_exchanges_to_internal_wallets": "Requerido para intercambios a billeteras internas",
+  "require_for_adding_contacts": "Requerido para agregar contactos",
+  "require_for_creating_new_wallets": "Requerido para crear nuevas billeteras",
+  "require_for_all_security_and_backup_settings": "Requerido para todas las configuraciones de seguridad y copia de seguridad",
   "available_balance_description": "Su saldo disponible es la cantidad de fondos que puede gastar. Los fondos que se muestran aquí se pueden gastar inmediatamente.",
   "syncing_wallet_alert_title": "Tu billetera se está sincronizando",
   "syncing_wallet_alert_content": "Es posible que su lista de saldo y transacciones no esté completa hasta que diga \"SINCRONIZADO\" en la parte superior. Haga clic/toque para obtener más información.",
@@ -684,5 +685,13 @@
   "slidable": "deslizable",
   "manage_nodes": "Administrar nodos",
   "etherscan_history": "historia de etherscan",
-  "template_name": "Nombre de la plantilla"
+  "template_name": "Nombre de la plantilla",
+  "support_title_live_chat": "Soporte vital",
+  "support_description_live_chat": "¡GRATIS y RÁPIDO! Los representantes de apoyo capacitado están disponibles para ayudar",
+  "support_title_guides": "Guías de billetera para pastel",
+  "support_description_guides": "Documentación y apoyo para problemas comunes",
+  "support_title_other_links": "Otros enlaces de soporte",
+  "support_description_other_links": "Únase a nuestras comunidades o comuníquese con nosotros nuestros socios a través de otros métodos",
+  "select_destination": "Seleccione el destino del archivo de copia de seguridad.",
+  "save_to_downloads": "Guardar en Descargas"
 }
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index ada4dbbe4..13de4ff95 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -646,18 +646,19 @@
   "high_contrast_theme": "Thème à contraste élevé",
   "matrix_green_dark_theme": "Thème Matrix Green Dark",
   "monero_light_theme": "Thème de lumière Monero",
-  "cake_2fa_preset" : "Gâteau 2FA prédéfini",
+  "auto_generate_subaddresses": "Générer automatiquement des sous-adresses",
+  "cake_2fa_preset": "Gâteau 2FA prédéfini",
   "narrow": "Étroit",
   "normal": "Normal",
   "aggressive": "Trop zélé",
   "require_for_assessing_wallet": "Nécessaire pour accéder au portefeuille",
-  "require_for_sends_to_non_contacts" : "Exiger pour les envois à des non-contacts",
-  "require_for_sends_to_contacts" : "Exiger pour les envois aux contacts",
-  "require_for_sends_to_internal_wallets" : "Exiger pour les envois vers des portefeuilles internes",
-  "require_for_exchanges_to_internal_wallets" : "Exiger pour les échanges vers des portefeuilles internes",
-  "require_for_adding_contacts" : "Requis pour ajouter des contacts",
-  "require_for_creating_new_wallets" : "Nécessaire pour créer de nouveaux portefeuilles",
-  "require_for_all_security_and_backup_settings" : "Exiger pour tous les paramètres de sécurité et de sauvegarde",
+  "require_for_sends_to_non_contacts": "Exiger pour les envois à des non-contacts",
+  "require_for_sends_to_contacts": "Exiger pour les envois aux contacts",
+  "require_for_sends_to_internal_wallets": "Exiger pour les envois vers des portefeuilles internes",
+  "require_for_exchanges_to_internal_wallets": "Exiger pour les échanges vers des portefeuilles internes",
+  "require_for_adding_contacts": "Requis pour ajouter des contacts",
+  "require_for_creating_new_wallets": "Nécessaire pour créer de nouveaux portefeuilles",
+  "require_for_all_security_and_backup_settings": "Exiger pour tous les paramètres de sécurité et de sauvegarde",
   "available_balance_description": "Le solde disponible est le montant que vous pouvez dépenser immédiatement. Il est calculé en soustrayant le solde gelé du solde total.",
   "syncing_wallet_alert_title": "Votre portefeuille est en cours de synchronisation",
   "syncing_wallet_alert_content": "Votre solde et votre liste de transactions peuvent ne pas être complets tant qu'il n'y a pas « SYNCHRONISÉ » en haut. Cliquez/appuyez pour en savoir plus.",
@@ -684,5 +685,13 @@
   "slidable": "Glissable",
   "manage_nodes": "Gérer les nœuds",
   "etherscan_history": "Historique d'Etherscan",
-  "template_name": "Nom du modèle"
+  "template_name": "Nom du modèle",
+  "support_title_live_chat": "Support en direct",
+  "support_description_live_chat": "GRATUIT ET RAPIDE! Des représentants de soutien formé sont disponibles pour aider",
+  "support_title_guides": "Guides de portefeuille à gâteau",
+  "support_description_guides": "Documentation et soutien aux problèmes communs",
+  "support_title_other_links": "Autres liens d'assistance",
+  "support_description_other_links": "Rejoignez nos communautés ou contactez-nous nos partenaires à travers d'autres méthodes",
+  "select_destination": "Veuillez sélectionner la destination du fichier de sauvegarde.",
+  "save_to_downloads": "Enregistrer dans les téléchargements"
 }
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index d01b4e2bd..528ea7c58 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -624,18 +624,19 @@
   "high_contrast_theme": "Babban Jigon Kwatance",
   "matrix_green_dark_theme": "Matrix Green Dark Jigo",
   "monero_light_theme": "Jigon Hasken Monero",
-    "cake_2fa_preset" : "Cake 2FA saiti",
+  "auto_generate_subaddresses": "Saɓaƙa subaddresses ta kai tsaye",
+  "cake_2fa_preset": "Cake 2FA saiti",
   "narrow": "kunkuntar",
   "normal": "Na al'ada",
   "aggressive": "Mai tsananin kishi",
   "require_for_assessing_wallet": "Bukatar samun damar walat",
-  "require_for_sends_to_non_contacts" : "Bukatar aika zuwa waɗanda ba lambobin sadarwa ba",
-  "require_for_sends_to_contacts" : "Bukatar aika zuwa lambobin sadarwa",
-  "require_for_sends_to_internal_wallets" : "Bukatar aika zuwa wallet na ciki",
-  "require_for_exchanges_to_internal_wallets" : "Bukatar musanya zuwa wallet na ciki",
-  "require_for_adding_contacts" : "Bukatar ƙara lambobin sadarwa",
-  "require_for_creating_new_wallets" : "Bukatar ƙirƙirar sabbin wallet",
-  "require_for_all_security_and_backup_settings" : "Bukatar duk tsaro da saitunan wariyar ajiya",
+  "require_for_sends_to_non_contacts": "Bukatar aika zuwa waɗanda ba lambobin sadarwa ba",
+  "require_for_sends_to_contacts": "Bukatar aika zuwa lambobin sadarwa",
+  "require_for_sends_to_internal_wallets": "Bukatar aika zuwa wallet na ciki",
+  "require_for_exchanges_to_internal_wallets": "Bukatar musanya zuwa wallet na ciki",
+  "require_for_adding_contacts": "Bukatar ƙara lambobin sadarwa",
+  "require_for_creating_new_wallets": "Bukatar ƙirƙirar sabbin wallet",
+  "require_for_all_security_and_backup_settings": "Bukatar duk tsaro da saitunan wariyar ajiya",
   "available_balance_description": "Ma'auni mai samuwa” ko ”,Tabbataccen Ma'auni”, kudade ne da za a iya kashewa nan da nan. Idan kudade sun bayyana a cikin ƙananan ma'auni amma ba babban ma'auni ba, to dole ne ku jira 'yan mintoci kaɗan don kudaden shiga don samun ƙarin tabbaci na hanyar sadarwa. Bayan sun sami ƙarin tabbaci, za a kashe su.",
   "syncing_wallet_alert_title": "Walat ɗin ku yana aiki tare",
   "syncing_wallet_alert_content": "Ma'aunin ku da lissafin ma'amala bazai cika ba har sai an ce \"SYNCHRONIZED\" a saman. Danna/matsa don ƙarin koyo.",
@@ -662,5 +663,13 @@
   "slidable": "Mai iya zamewa",
   "etherscan_history": "Etherscan tarihin kowane zamani",
   "manage_nodes": "Sarrafa nodes",
-  "template_name": "Sunan Samfura"
+  "template_name": "Sunan Samfura",
+  "support_title_live_chat": "Tallafi na Live",
+  "support_description_live_chat": "Kyauta da sauri! An horar da wakilan tallafi na tallafi don taimakawa",
+  "support_title_guides": "Jagorar Cake",
+  "support_description_guides": "Tallafi da tallafi don batutuwa na yau da kullun",
+  "support_title_other_links": "Sauran hanyoyin tallafi",
+  "support_description_other_links": "Kasance tare da al'ummominmu ko kuma ka kai mu abokanmu ta hanyar wasu hanyoyi",
+  "select_destination": "Da fatan za a zaɓi wurin da za a yi wa madadin fayil ɗin.",
+  "save_to_downloads": "Ajiye zuwa Zazzagewa"
 }
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index d00a5c468..fee7465a8 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -646,18 +646,19 @@
   "high_contrast_theme": "उच्च कंट्रास्ट थीम",
   "matrix_green_dark_theme": "मैट्रिक्स ग्रीन डार्क थीम",
   "monero_light_theme": "मोनेरो लाइट थीम",
-  "cake_2fa_preset" : "केक 2एफए प्रीसेट",
+  "auto_generate_subaddresses": "स्वचालित रूप से उप-पते उत्पन्न करें",
+  "cake_2fa_preset": "केक 2एफए प्रीसेट",
   "narrow": "सँकरा",
   "normal": "सामान्य",
   "aggressive": "ज्यादा",
   "require_for_assessing_wallet": "वॉलेट तक पहुँचने के लिए आवश्यकता है",
-  "require_for_sends_to_non_contacts" : "गैर-संपर्कों को भेजने की आवश्यकता",
-  "require_for_sends_to_contacts" : "संपर्कों को भेजने के लिए आवश्यक है",
-  "require_for_sends_to_internal_wallets" : "आंतरिक वॉलेट में भेजने की आवश्यकता है",
-  "require_for_exchanges_to_internal_wallets" : "आंतरिक वॉलेट में आदान-प्रदान की आवश्यकता है",
-  "require_for_adding_contacts" : "संपर्क जोड़ने के लिए आवश्यकता है",
-  "require_for_creating_new_wallets" : "नए वॉलेट बनाने की आवश्यकता है",
-  "require_for_all_security_and_backup_settings" : "सभी सुरक्षा और बैकअप सेटिंग्स की आवश्यकता है",
+  "require_for_sends_to_non_contacts": "गैर-संपर्कों को भेजने की आवश्यकता",
+  "require_for_sends_to_contacts": "संपर्कों को भेजने के लिए आवश्यक है",
+  "require_for_sends_to_internal_wallets": "आंतरिक वॉलेट में भेजने की आवश्यकता है",
+  "require_for_exchanges_to_internal_wallets": "आंतरिक वॉलेट में आदान-प्रदान की आवश्यकता है",
+  "require_for_adding_contacts": "संपर्क जोड़ने के लिए आवश्यकता है",
+  "require_for_creating_new_wallets": "नए वॉलेट बनाने की आवश्यकता है",
+  "require_for_all_security_and_backup_settings": "सभी सुरक्षा और बैकअप सेटिंग्स की आवश्यकता है",
   "available_balance_description": "उपलब्ध शेष या ”पुष्टिकृत शेष”, वे धनराशि हैं जिन्हें तुरंत खर्च किया जा सकता है। यदि फंड निचले बैलेंस में दिखाई देते हैं, लेकिन शीर्ष बैलेंस में नहीं, तो आपको आने वाले फंड के लिए अधिक नेटवर्क पुष्टिकरण प्राप्त करने के लिए कुछ मिनट इंतजार करना होगा। अधिक पुष्टि मिलने के बाद, वे खर्च करने योग्य हो जाएंगे।",
   "syncing_wallet_alert_title": "आपका वॉलेट सिंक हो रहा है",
   "syncing_wallet_alert_content": "आपकी शेष राशि और लेनदेन सूची तब तक पूरी नहीं हो सकती जब तक कि शीर्ष पर \"सिंक्रनाइज़्ड\" न लिखा हो। अधिक जानने के लिए क्लिक/टैप करें।",
@@ -684,5 +685,13 @@
   "slidable": "फिसलने लायक",
   "manage_nodes": "नोड्स प्रबंधित करें",
   "etherscan_history": "इथरस्कैन इतिहास",
-  "template_name": "टेम्पलेट नाम"
+  "template_name": "टेम्पलेट नाम",
+  "support_title_live_chat": "लाइव सहायता",
+  "support_description_live_chat": "मुक्त और तेजी से! प्रशिक्षित सहायता प्रतिनिधि सहायता के लिए उपलब्ध हैं",
+  "support_title_guides": "केक वॉलेट गाइड",
+  "support_description_guides": "सामान्य मुद्दों के लिए प्रलेखन और समर्थन",
+  "support_title_other_links": "अन्य समर्थन लिंक",
+  "support_description_other_links": "हमारे समुदायों में शामिल हों या अन्य तरीकों के माध्यम से हमारे साथी तक पहुंचें",
+  "select_destination": "कृपया बैकअप फ़ाइल के लिए गंतव्य का चयन करें।",
+  "save_to_downloads": "डाउनलोड में सहेजें"
 }
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 3c3bad49b..de9526a1c 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -646,18 +646,19 @@
   "high_contrast_theme": "Tema visokog kontrasta",
   "matrix_green_dark_theme": "Matrix Green Dark Theme",
   "monero_light_theme": "Monero lagana tema",
-  "cake_2fa_preset" : "Cake 2FA Preset",
+  "auto_generate_subaddresses": "Automatski generirajte podadrese",
+  "cake_2fa_preset": "Cake 2FA Preset",
   "narrow": "Usko",
   "normal": "Normalno",
   "aggressive": "Preterano",
   "require_for_assessing_wallet": "Potreban za pristup novčaniku",
-  "require_for_sends_to_non_contacts" : "Zahtijeva za slanje nekontaktima",
-  "require_for_sends_to_contacts" : "Zahtijeva za slanje kontaktima",
-  "require_for_sends_to_internal_wallets" : "Zahtijeva za slanje u interne novčanike",
-  "require_for_exchanges_to_internal_wallets" : "Potreban za razmjenu na interne novčanike",
-  "require_for_adding_contacts" : "Zahtijeva za dodavanje kontakata",
-  "require_for_creating_new_wallets" : "Potreban za kreiranje novih novčanika",
-  "require_for_all_security_and_backup_settings" : "Zahtijeva za sve postavke sigurnosti i sigurnosne kopije",
+  "require_for_sends_to_non_contacts": "Zahtijeva za slanje nekontaktima",
+  "require_for_sends_to_contacts": "Zahtijeva za slanje kontaktima",
+  "require_for_sends_to_internal_wallets": "Zahtijeva za slanje u interne novčanike",
+  "require_for_exchanges_to_internal_wallets": "Potreban za razmjenu na interne novčanike",
+  "require_for_adding_contacts": "Zahtijeva za dodavanje kontakata",
+  "require_for_creating_new_wallets": "Potreban za kreiranje novih novčanika",
+  "require_for_all_security_and_backup_settings": "Zahtijeva za sve postavke sigurnosti i sigurnosne kopije",
   "available_balance_description": "Dostupno stanje je iznos koji možete potrošiti. To je vaš saldo minus bilo kakve transakcije koje su još uvijek u tijeku.",
   "syncing_wallet_alert_title": "Vaš novčanik se sinkronizira",
   "syncing_wallet_alert_content": "Vaš saldo i popis transakcija možda neće biti potpuni sve dok na vrhu ne piše \"SINKRONIZIRANO\". Kliknite/dodirnite da biste saznali više.",
@@ -684,5 +685,13 @@
   "slidable": "Klizna",
   "manage_nodes": "Upravljanje čvorovima",
   "etherscan_history": "Etherscan povijest",
-  "template_name": "Naziv predloška"
+  "template_name": "Naziv predloška",
+  "support_title_live_chat": "Podrška uživo",
+  "support_description_live_chat": "Besplatno i brzo! Obučeni predstavnici podrške dostupni su za pomoć",
+  "support_title_guides": "Vodiči za torte",
+  "support_description_guides": "Dokumentacija i podrška za uobičajena pitanja",
+  "support_title_other_links": "Ostale veze za podršku",
+  "support_description_other_links": "Pridružite se našim zajednicama ili nam dosegnu naše partnere drugim metodama",
+  "select_destination": "Odaberite odredište za datoteku sigurnosne kopije.",
+  "save_to_downloads": "Spremi u Preuzimanja"
 }
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index dd8daabf5..75f038f4a 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -629,18 +629,19 @@
   "setup_totp_recommended": "Siapkan TOTP (Disarankan)",
   "disable_buy": "Nonaktifkan tindakan beli",
   "disable_sell": "Nonaktifkan aksi jual",
-  "cake_2fa_preset" : "Preset Kue 2FA",
+  "auto_generate_subaddresses": "Menghasilkan subalamat secara otomatis",
+  "cake_2fa_preset": "Preset Kue 2FA",
   "narrow": "Sempit",
   "normal": "Normal",
   "aggressive": "Terlalu bersemangat",
   "require_for_assessing_wallet": "Diperlukan untuk mengakses dompet",
-  "require_for_sends_to_non_contacts" : "Wajibkan untuk mengirim ke non-kontak",
-  "require_for_sends_to_contacts" : "Membutuhkan untuk mengirim ke kontak",
-  "require_for_sends_to_internal_wallets" : "Diperlukan untuk mengirim ke dompet internal",
-  "require_for_exchanges_to_internal_wallets" : "Diperlukan untuk pertukaran ke dompet internal",
-  "require_for_adding_contacts" : "Membutuhkan untuk menambahkan kontak",
-  "require_for_creating_new_wallets" : "Diperlukan untuk membuat dompet baru",
-  "require_for_all_security_and_backup_settings" : "Memerlukan untuk semua pengaturan keamanan dan pencadangan",
+  "require_for_sends_to_non_contacts": "Wajibkan untuk mengirim ke non-kontak",
+  "require_for_sends_to_contacts": "Membutuhkan untuk mengirim ke kontak",
+  "require_for_sends_to_internal_wallets": "Diperlukan untuk mengirim ke dompet internal",
+  "require_for_exchanges_to_internal_wallets": "Diperlukan untuk pertukaran ke dompet internal",
+  "require_for_adding_contacts": "Membutuhkan untuk menambahkan kontak",
+  "require_for_creating_new_wallets": "Diperlukan untuk membuat dompet baru",
+  "require_for_all_security_and_backup_settings": "Memerlukan untuk semua pengaturan keamanan dan pencadangan",
   "available_balance_description": "“Saldo yang Tersedia” atau “Saldo yang Dikonfirmasi” adalah dana yang dapat langsung dibelanjakan. Jika dana muncul di saldo bawah tetapi tidak di saldo atas, maka Anda harus menunggu beberapa menit agar dana masuk mendapatkan konfirmasi jaringan lainnya. Setelah mereka mendapatkan lebih banyak konfirmasi, mereka akan dapat dibelanjakan.",
   "syncing_wallet_alert_title": "Dompet Anda sedang disinkronkan",
   "syncing_wallet_alert_content": "Saldo dan daftar transaksi Anda mungkin belum lengkap sampai tertulis “SYNCHRONIZED” di bagian atas. Klik/ketuk untuk mempelajari lebih lanjut.",
@@ -673,5 +674,13 @@
   "monero_light_theme": "Tema Cahaya Monero",
   "manage_nodes": "Kelola node",
   "etherscan_history": "Sejarah Etherscan",
-  "template_name": "Nama Templat"
+  "template_name": "Nama Templat",
+  "support_title_live_chat": "Dukungan langsung",
+  "support_description_live_chat": "Gratis dan Cepat! Perwakilan dukungan terlatih tersedia untuk membantu",
+  "support_title_guides": "Panduan Dompet Kue",
+  "support_description_guides": "Dokumentasi dan dukungan untuk masalah umum",
+  "support_title_other_links": "Tautan dukungan lainnya",
+  "support_description_other_links": "Bergabunglah dengan komunitas kami atau hubungi kami mitra kami melalui metode lain",
+  "select_destination": "Silakan pilih tujuan untuk file cadangan.",
+  "save_to_downloads": "Simpan ke Unduhan"
 }
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index a463310d1..ef62d901b 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -640,18 +640,19 @@
   "setup_totp_recommended": "Imposta TOTP (consigliato)",
   "disable_buy": "Disabilita l'azione di acquisto",
   "disable_sell": "Disabilita l'azione di vendita",
-  "cake_2fa_preset" : "Torta 2FA Preset",
+  "auto_generate_subaddresses": "Genera automaticamente sottindirizzi",
+  "cake_2fa_preset": "Torta 2FA Preset",
   "narrow": "Stretto",
   "normal": "Normale",
   "aggressive": "Fervente",
   "require_for_assessing_wallet": "Richiesto per l'accesso al portafoglio",
-  "require_for_sends_to_non_contacts" : "Richiesto per invii a non contatti",
-  "require_for_sends_to_contacts" : "Richiedi per gli invii ai contatti",
-  "require_for_sends_to_internal_wallets" : "Richiesto per invii a portafogli interni",
-  "require_for_exchanges_to_internal_wallets" : "Richiedi per gli scambi ai portafogli interni",
-  "require_for_adding_contacts" : "Richiesto per l'aggiunta di contatti",
-  "require_for_creating_new_wallets" : "Richiesto per la creazione di nuovi portafogli",
-  "require_for_all_security_and_backup_settings" : "Richiedi per tutte le impostazioni di sicurezza e backup",
+  "require_for_sends_to_non_contacts": "Richiesto per invii a non contatti",
+  "require_for_sends_to_contacts": "Richiedi per gli invii ai contatti",
+  "require_for_sends_to_internal_wallets": "Richiesto per invii a portafogli interni",
+  "require_for_exchanges_to_internal_wallets": "Richiedi per gli scambi ai portafogli interni",
+  "require_for_adding_contacts": "Richiesto per l'aggiunta di contatti",
+  "require_for_creating_new_wallets": "Richiesto per la creazione di nuovi portafogli",
+  "require_for_all_security_and_backup_settings": "Richiedi per tutte le impostazioni di sicurezza e backup",
   "available_balance_description": "Il saldo disponibile è il saldo totale meno i fondi congelati. I fondi congelati sono fondi che sono stati inviati ma non sono ancora stati confermati.",
   "syncing_wallet_alert_title": "Il tuo portafoglio si sta sincronizzando",
   "syncing_wallet_alert_content": "Il saldo e l'elenco delle transazioni potrebbero non essere completi fino a quando non viene visualizzato \"SYNCHRONIZED\" in alto. Clicca/tocca per saperne di più.",
@@ -684,5 +685,13 @@
   "monero_light_theme": "Tema leggero Monero",
   "manage_nodes": "Gestisci i nodi",
   "etherscan_history": "Storia Etherscan",
-  "template_name": "Nome modello"
+  "template_name": "Nome modello",
+  "support_title_live_chat": "Supporto dal vivo",
+  "support_description_live_chat": "Gratuito e veloce! I rappresentanti di supporto qualificati sono disponibili per assistere",
+  "support_title_guides": "Guide del portafoglio per torte",
+  "support_description_guides": "Documentazione e supporto per problemi comuni",
+  "support_title_other_links": "Altri collegamenti di supporto",
+  "support_description_other_links": "Unisciti alle nostre comunità o raggiungici i nostri partner attraverso altri metodi",
+  "select_destination": "Seleziona la destinazione per il file di backup.",
+  "save_to_downloads": "Salva in Download"
 }
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index 47606a778..cfb653dbb 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -684,5 +684,14 @@
   "monero_light_theme": "モネロ ライト テーマ",
   "manage_nodes": "ノードの管理",
   "etherscan_history": "イーサスキャンの歴史",
-  "template_name": "テンプレート名"
+  "template_name": "テンプレート名",
+  "support_title_live_chat": "ライブサポート",
+  "support_description_live_chat": "無料で速い!訓練されたサポート担当者が支援することができます",
+  "support_title_guides": "ケーキウォレットガイド",
+  "support_description_guides": "一般的な問題のドキュメントとサポート",
+  "support_title_other_links": "その他のサポートリンク",
+  "support_description_other_links": "私たちのコミュニティに参加するか、他の方法を通して私たちのパートナーに連絡してください",
+  "select_destination": "バックアップファイルの保存先を選択してください。",
+  "save_to_downloads": "ダウンロードに保存",
+  "auto_generate_subaddresses": "Autoはサブアドレスを生成します"
 }
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index c19f31076..80197ca70 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -684,5 +684,14 @@
   "monero_light_theme": "모네로 라이트 테마",
   "manage_nodes": "노드 관리",
   "etherscan_history": "이더스캔 역사",
-  "template_name": "템플릿 이름"
+  "template_name": "템플릿 이름",
+  "support_title_live_chat": "실시간 지원",
+  "support_description_live_chat": "자유롭고 빠릅니다! 훈련 된 지원 담당자가 지원할 수 있습니다",
+  "support_title_guides": "케이크 지갑 가이드",
+  "support_description_guides": "일반적인 문제에 대한 문서화 및 지원",
+  "support_title_other_links": "다른 지원 링크",
+  "support_description_other_links": "다른 방법을 통해 커뮤니티에 가입하거나 파트너에게 연락하십시오.",
+  "select_destination": "백업 파일의 대상을 선택하십시오.",
+  "save_to_downloads": "다운로드에 저장",
+  "auto_generate_subaddresses": "자동 생성 서브 아드 드레스"
 }
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index fca8055c8..519866937 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -682,5 +682,14 @@
   "monero_light_theme": "Monero Light အပြင်အဆင်",
   "manage_nodes": "ဆုံမှတ်များကို စီမံပါ။",
   "etherscan_history": "Etherscan သမိုင်း",
-  "template_name": "နမူနာပုံစံ"
+  "template_name": "နမူနာပုံစံ",
+  "support_title_live_chat": "တိုက်ရိုက်ပံ့ပိုးမှု",
+  "support_description_live_chat": "အခမဲ့နှင့်အစာရှောင်ခြင်း! လေ့ကျင့်ထားသောထောက်ခံသူကိုယ်စားလှယ်များသည်ကူညီနိုင်သည်",
+  "support_title_guides": "ကိတ်မုန့်ပိုက်ဆံအိတ်လမ်းညွှန်များ",
+  "support_description_guides": "ဘုံပြ issues နာများအတွက်စာရွက်စာတမ်းများနှင့်ထောက်ခံမှု",
+  "support_title_other_links": "အခြားအထောက်အပံ့လင့်များ",
+  "support_description_other_links": "ကျွန်ုပ်တို့၏လူမှုအသိုင်းအဝိုင်းများသို့ 0 င်ရောက်ပါ",
+  "select_destination": "အရန်ဖိုင်အတွက် ဦးတည်ရာကို ရွေးပါ။",
+  "save_to_downloads": "ဒေါင်းလုဒ်များထံ သိမ်းဆည်းပါ။",
+  "auto_generate_subaddresses": "အော်တို Generate Subaddresses"
 }
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index a444057bf..4c7f8b298 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -640,18 +640,19 @@
   "setup_totp_recommended": "TOTP instellen (aanbevolen)",
   "disable_buy": "Koopactie uitschakelen",
   "disable_sell": "Verkoopactie uitschakelen",
-  "cake_2fa_preset" : "Taart 2FA Voorinstelling",
+  "auto_generate_subaddresses": "Automatisch subadressen genereren",
+  "cake_2fa_preset": "Taart 2FA Voorinstelling",
   "narrow": "Smal",
   "normal": "Normaal",
   "aggressive": "Overijverig",
   "require_for_assessing_wallet": "Vereist voor toegang tot portemonnee",
-  "require_for_sends_to_non_contacts" : "Vereist voor verzendingen naar niet-contacten",
-  "require_for_sends_to_contacts" : "Vereist voor verzending naar contacten",
-  "require_for_sends_to_internal_wallets" : "Vereist voor verzendingen naar interne portefeuilles",
-  "require_for_exchanges_to_internal_wallets" : "Vereist voor uitwisselingen naar interne portefeuilles",
-  "require_for_adding_contacts" : "Vereist voor het toevoegen van contacten",
-  "require_for_creating_new_wallets" : "Vereist voor het maken van nieuwe portefeuilles",
-  "require_for_all_security_and_backup_settings" : "Vereist voor alle beveiligings- en back-upinstellingen",
+  "require_for_sends_to_non_contacts": "Vereist voor verzendingen naar niet-contacten",
+  "require_for_sends_to_contacts": "Vereist voor verzending naar contacten",
+  "require_for_sends_to_internal_wallets": "Vereist voor verzendingen naar interne portefeuilles",
+  "require_for_exchanges_to_internal_wallets": "Vereist voor uitwisselingen naar interne portefeuilles",
+  "require_for_adding_contacts": "Vereist voor het toevoegen van contacten",
+  "require_for_creating_new_wallets": "Vereist voor het maken van nieuwe portefeuilles",
+  "require_for_all_security_and_backup_settings": "Vereist voor alle beveiligings- en back-upinstellingen",
   "available_balance_description": "Beschikbaar saldo is het saldo dat u kunt uitgeven. Het kan lager zijn dan uw totale saldo als u onlangs geld hebt verzonden.",
   "syncing_wallet_alert_title": "Uw portemonnee wordt gesynchroniseerd",
   "syncing_wallet_alert_content": "Uw saldo- en transactielijst is mogelijk pas compleet als er bovenaan 'GESYNCHRONISEERD' staat. Klik/tik voor meer informatie.",
@@ -684,5 +685,13 @@
   "monero_light_theme": "Monero Light-thema",
   "manage_nodes": "Beheer knooppunten",
   "etherscan_history": "Etherscan-geschiedenis",
-  "template_name": "Sjabloonnaam"
+  "template_name": "Sjabloonnaam",
+  "support_title_live_chat": "Live ondersteuning",
+  "support_description_live_chat": "Gratis en snel! Getrainde ondersteuningsvertegenwoordigers zijn beschikbaar om te helpen",
+  "support_title_guides": "Cake -portemonnee gidsen",
+  "support_description_guides": "Documentatie en ondersteuning voor gemeenschappelijke problemen",
+  "support_title_other_links": "Andere ondersteuningslinks",
+  "support_description_other_links": "Word lid van onze gemeenschappen of bereik ons ​​onze partners via andere methoden",
+  "select_destination": "Selecteer de bestemming voor het back-upbestand.",
+  "save_to_downloads": "Opslaan in downloads"
 }
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index c31221525..e04cd108a 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -640,18 +640,19 @@
   "setup_totp_recommended": "Skonfiguruj TOTP (zalecane)",
   "disable_buy": "Wyłącz akcję kupna",
   "disable_sell": "Wyłącz akcję sprzedaży",
-  "cake_2fa_preset" : "Ciasto 2FA Preset",
+  "auto_generate_subaddresses": "Automatycznie generuj podadresy",
+  "cake_2fa_preset": "Ciasto 2FA Preset",
   "narrow": "Wąski",
   "normal": "Normalna",
   "aggressive": "Nadgorliwy",
   "require_for_assessing_wallet": "Wymagaj dostępu do portfela",
-  "require_for_sends_to_non_contacts" : "Wymagaj wysyłania do osób niekontaktowych",
-  "require_for_sends_to_contacts" : "Wymagaj wysyłania do kontaktów",
-  "require_for_sends_to_internal_wallets" : "Wymagaj wysyłania do portfeli wewnętrznych",
-  "require_for_exchanges_to_internal_wallets" : "Wymagaj wymiany do portfeli wewnętrznych",
-  "require_for_adding_contacts" : "Wymagane do dodania kontaktów",
-  "require_for_creating_new_wallets" : "Wymagane do tworzenia nowych portfeli",
-  "require_for_all_security_and_backup_settings" : "Wymagaj dla wszystkich ustawień zabezpieczeń i kopii zapasowych",
+  "require_for_sends_to_non_contacts": "Wymagaj wysyłania do osób niekontaktowych",
+  "require_for_sends_to_contacts": "Wymagaj wysyłania do kontaktów",
+  "require_for_sends_to_internal_wallets": "Wymagaj wysyłania do portfeli wewnętrznych",
+  "require_for_exchanges_to_internal_wallets": "Wymagaj wymiany do portfeli wewnętrznych",
+  "require_for_adding_contacts": "Wymagane do dodania kontaktów",
+  "require_for_creating_new_wallets": "Wymagane do tworzenia nowych portfeli",
+  "require_for_all_security_and_backup_settings": "Wymagaj dla wszystkich ustawień zabezpieczeń i kopii zapasowych",
   "available_balance_description": "Dostępne saldo jest równoważne z saldem portfela minus zamrożone saldo.",
   "syncing_wallet_alert_title": "Twój portfel się synchronizuje",
   "syncing_wallet_alert_content": "Twoje saldo i lista transakcji mogą nie być kompletne, dopóki u góry nie pojawi się napis „SYNCHRONIZOWANY”. Kliknij/stuknij, aby dowiedzieć się więcej.",
@@ -684,5 +685,13 @@
   "monero_light_theme": "Lekki motyw Monero",
   "manage_nodes": "Zarządzaj węzłami",
   "etherscan_history": "Historia Etherscanu",
-  "template_name": "Nazwa szablonu"
+  "template_name": "Nazwa szablonu",
+  "support_title_live_chat": "Wsparcie na żywo",
+  "support_description_live_chat": "Darmowe i szybkie! Do pomocy są dostępni przeszkoleni przedstawiciele wsparcia",
+  "support_title_guides": "Przewodniki portfela ciasta",
+  "support_description_guides": "Dokumentacja i wsparcie dla typowych problemów",
+  "support_title_other_links": "Inne linki wsparcia",
+  "support_description_other_links": "Dołącz do naszych społeczności lub skontaktuj się z nami naszymi partnerami za pomocą innych metod",
+  "select_destination": "Wybierz miejsce docelowe dla pliku kopii zapasowej.",
+  "save_to_downloads": "Zapisz w Pobranych"
 }
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index 7cc8146e7..c0cfbefe0 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -639,18 +639,19 @@
   "setup_totp_recommended": "Configurar TOTP (recomendado)",
   "disable_buy": "Desativar ação de compra",
   "disable_sell": "Desativar ação de venda",
-  "cake_2fa_preset" : "Predefinição de bolo 2FA",
+  "auto_generate_subaddresses": "Gerar subendereços automaticamente",
+  "cake_2fa_preset": "Predefinição de bolo 2FA",
   "narrow": "Estreito",
   "normal": "Normal",
   "aggressive": "excessivamente zeloso",
   "require_for_assessing_wallet": "Requer para acessar a carteira",
-  "require_for_sends_to_non_contacts" : "Exigir para envios para não-contatos",
-  "require_for_sends_to_contacts" : "Exigir para envios para contatos",
-  "require_for_sends_to_internal_wallets" : "Exigir envios para carteiras internas",
-  "require_for_exchanges_to_internal_wallets" : "Requer trocas para carteiras internas",
-  "require_for_adding_contacts" : "Requer para adicionar contatos",
-  "require_for_creating_new_wallets" : "Requer para criar novas carteiras",
-  "require_for_all_security_and_backup_settings" : "Exigir todas as configurações de segurança e backup",
+  "require_for_sends_to_non_contacts": "Exigir para envios para não-contatos",
+  "require_for_sends_to_contacts": "Exigir para envios para contatos",
+  "require_for_sends_to_internal_wallets": "Exigir envios para carteiras internas",
+  "require_for_exchanges_to_internal_wallets": "Requer trocas para carteiras internas",
+  "require_for_adding_contacts": "Requer para adicionar contatos",
+  "require_for_creating_new_wallets": "Requer para criar novas carteiras",
+  "require_for_all_security_and_backup_settings": "Exigir todas as configurações de segurança e backup",
   "available_balance_description": "Seu saldo disponível é o saldo total menos o saldo congelado. O saldo congelado é o saldo que você não pode gastar, mas que ainda não foi confirmado na blockchain. O saldo congelado é geralmente o resultado de transações recentes.",
   "syncing_wallet_alert_title": "Sua carteira está sincronizando",
   "syncing_wallet_alert_content": "Seu saldo e lista de transações podem não estar completos até que diga “SYNCHRONIZED” no topo. Clique/toque para saber mais.",
@@ -683,5 +684,13 @@
   "monero_light_theme": "Monero Light Theme",
   "manage_nodes": "Gerenciar nós",
   "etherscan_history": "história Etherscan",
-  "template_name": "Nome do modelo"
+  "template_name": "Nome do modelo",
+  "support_title_live_chat": "Apoio ao vivo",
+  "support_description_live_chat": "Livre e rápido! Representantes de suporte treinado estão disponíveis para ajudar",
+  "support_title_guides": "Guias da carteira de bolo",
+  "support_description_guides": "Documentação e suporte para problemas comuns",
+  "support_title_other_links": "Outros links de suporte",
+  "support_description_other_links": "Junte -se às nossas comunidades ou chegue a nós nossos parceiros por meio de outros métodos",
+  "select_destination": "Selecione o destino para o arquivo de backup.",
+  "save_to_downloads": "Salvar em Downloads"
 }
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index 55a697bca..bec7c829a 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -270,7 +270,6 @@
   "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": "Идентификатор платежа может содержать от 16 до 64 символов в hex",
   "error_text_xmr": "Значение XMR не может превышать доступный баланс.\nКоличество цифр после запятой должно быть меньше или равно 12",
   "error_text_fiat": "Значение суммы не может превышать доступный баланс.\nКоличество цифр после запятой должно быть меньше или равно 2",
@@ -641,18 +640,18 @@
   "setup_totp_recommended": "Настроить TOTP (рекомендуется)",
   "disable_buy": "Отключить действие покупки",
   "disable_sell": "Отключить действие продажи",
-  "cake_2fa_preset" : "Торт 2FA Preset",
+  "cake_2fa_preset": "Торт 2FA Preset",
   "narrow": "Узкий",
   "normal": "Нормальный",
   "aggressive": "чрезмерно усердный",
   "require_for_assessing_wallet": "Требовать для доступа к кошельку",
-  "require_for_sends_to_non_contacts" : "Требовать для отправки не контактам",
-  "require_for_sends_to_contacts" : "Требовать для отправки контактам",
-  "require_for_sends_to_internal_wallets" : "Требовать отправки на внутренние кошельки",
-  "require_for_exchanges_to_internal_wallets" : "Требовать для обмена на внутренние кошельки",
-  "require_for_adding_contacts" : "Требовать добавления контактов",
-  "require_for_creating_new_wallets" : "Требовать для создания новых кошельков",
-  "require_for_all_security_and_backup_settings" : "Требовать все настройки безопасности и резервного копирования",
+  "require_for_sends_to_non_contacts": "Требовать для отправки не контактам",
+  "require_for_sends_to_contacts": "Требовать для отправки контактам",
+  "require_for_sends_to_internal_wallets": "Требовать отправки на внутренние кошельки",
+  "require_for_exchanges_to_internal_wallets": "Требовать для обмена на внутренние кошельки",
+  "require_for_adding_contacts": "Требовать добавления контактов",
+  "require_for_creating_new_wallets": "Требовать для создания новых кошельков",
+  "require_for_all_security_and_backup_settings": "Требовать все настройки безопасности и резервного копирования",
   "available_balance_description": "Доступный баланс - это средства, которые вы можете использовать для покупки или продажи криптовалюты.",
   "syncing_wallet_alert_title": "Ваш кошелек синхронизируется",
   "syncing_wallet_alert_content": "Ваш баланс и список транзакций могут быть неполными, пока вверху не будет написано «СИНХРОНИЗИРОВАНО». Щелкните/коснитесь, чтобы узнать больше.",
@@ -685,5 +684,14 @@
   "monero_light_theme": "Светлая тема Monero",
   "manage_nodes": "Управление узлами",
   "etherscan_history": "История Эфириума",
-  "template_name": "Имя Шаблона"
+  "template_name": "Имя Шаблона",
+  "support_title_live_chat": "Живая поддержка",
+  "support_description_live_chat": "Бесплатно и быстро! Обученные представители поддержки доступны для оказания помощи",
+  "support_title_guides": "Корт -гиды",
+  "support_description_guides": "Документация и поддержка общих вопросов",
+  "support_title_other_links": "Другие ссылки на поддержку",
+  "support_description_other_links": "Присоединяйтесь к нашим сообществам или охватите нас наших партнеров с помощью других методов",
+  "select_destination": "Пожалуйста, выберите место для файла резервной копии.",
+  "save_to_downloads": "Сохранить в загрузках",
+  "auto_generate_subaddresses": "Авто генерируйте Subaddresses"
 }
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index 92c249fc1..2f988950b 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -638,18 +638,18 @@
   "setup_totp_recommended": "ตั้งค่า TOTP (แนะนำ)",
   "disable_buy": "ปิดการใช้งานการซื้อ",
   "disable_sell": "ปิดการใช้งานการขาย",
-  "cake_2fa_preset" : "เค้ก 2FA ที่ตั้งไว้ล่วงหน้า",
+  "cake_2fa_preset": "เค้ก 2FA ที่ตั้งไว้ล่วงหน้า",
   "narrow": "แคบ",
   "normal": "ปกติ",
   "aggressive": "กระตือรือร้นมากเกินไป",
   "require_for_assessing_wallet": "จำเป็นสำหรับการเข้าถึงกระเป๋าเงิน",
-  "require_for_sends_to_non_contacts" : "จำเป็นต้องส่งไปยังผู้ที่ไม่ได้ติดต่อ",
-  "require_for_sends_to_contacts" : "จำเป็นต้องส่งไปยังผู้ติดต่อ",
-  "require_for_sends_to_internal_wallets" : "จำเป็นต้องส่งไปยังกระเป๋าเงินภายใน",
-  "require_for_exchanges_to_internal_wallets" : "ต้องการการแลกเปลี่ยนไปยังกระเป๋าเงินภายใน",
-  "require_for_adding_contacts" : "ต้องการสำหรับการเพิ่มผู้ติดต่อ",
-  "require_for_creating_new_wallets" : "จำเป็นสำหรับการสร้างกระเป๋าเงินใหม่",
-  "require_for_all_security_and_backup_settings" : "จำเป็นสำหรับการตั้งค่าความปลอดภัยและการสำรองข้อมูลทั้งหมด",
+  "require_for_sends_to_non_contacts": "จำเป็นต้องส่งไปยังผู้ที่ไม่ได้ติดต่อ",
+  "require_for_sends_to_contacts": "จำเป็นต้องส่งไปยังผู้ติดต่อ",
+  "require_for_sends_to_internal_wallets": "จำเป็นต้องส่งไปยังกระเป๋าเงินภายใน",
+  "require_for_exchanges_to_internal_wallets": "ต้องการการแลกเปลี่ยนไปยังกระเป๋าเงินภายใน",
+  "require_for_adding_contacts": "ต้องการสำหรับการเพิ่มผู้ติดต่อ",
+  "require_for_creating_new_wallets": "จำเป็นสำหรับการสร้างกระเป๋าเงินใหม่",
+  "require_for_all_security_and_backup_settings": "จำเป็นสำหรับการตั้งค่าความปลอดภัยและการสำรองข้อมูลทั้งหมด",
   "available_balance_description": "จำนวนเงินที่คุณสามารถใช้ได้ในการซื้อหรือขาย",
   "syncing_wallet_alert_title": "กระเป๋าสตางค์ของคุณกำลังซิงค์",
   "syncing_wallet_alert_content": "รายการยอดเงินและธุรกรรมของคุณอาจไม่สมบูรณ์จนกว่าจะมีข้อความว่า “ซิงโครไนซ์” ที่ด้านบน คลิก/แตะเพื่อเรียนรู้เพิ่มเติม่",
@@ -682,5 +682,14 @@
   "monero_light_theme": "ธีมแสง Monero",
   "manage_nodes": "จัดการโหนด",
   "etherscan_history": "ประวัติอีเธอร์สแกน",
-  "template_name": "ชื่อแม่แบบ"
+  "template_name": "ชื่อแม่แบบ",
+  "support_title_live_chat": "การสนับสนุนสด",
+  "support_description_live_chat": "ฟรีและรวดเร็ว! ตัวแทนฝ่ายสนับสนุนที่ผ่านการฝึกอบรมพร้อมให้ความช่วยเหลือ",
+  "support_title_guides": "คู่มือกระเป๋าเงินเค้ก",
+  "support_description_guides": "เอกสารและการสนับสนุนสำหรับปัญหาทั่วไป",
+  "support_title_other_links": "ลิงค์สนับสนุนอื่น ๆ",
+  "support_description_other_links": "เข้าร่วมชุมชนของเราหรือเข้าถึงเราพันธมิตรของเราผ่านวิธีการอื่น ๆ",
+  "select_destination": "โปรดเลือกปลายทางสำหรับไฟล์สำรอง",
+  "save_to_downloads": "บันทึกลงดาวน์โหลด",
+  "auto_generate_subaddresses": "Auto สร้าง subaddresses"
 }
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index fdd14a9f6..acb12c50b 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -638,19 +638,19 @@
   "setup_totp_recommended": "TOTP'yi kurun (Önerilir)",
   "disable_buy": "Satın alma işlemini devre dışı bırak",
   "disable_sell": "Satış işlemini devre dışı bırak",
-  "cake_2fa_preset" : "Kek 2FA Ön Ayarı",
+  "auto_generate_subaddresses": "Alt adresleri otomatik olarak oluştur",
+  "cake_2fa_preset": "Kek 2FA Ön Ayarı",
   "narrow": "Dar",
   "normal": "Normal",
   "aggressive": "Aşırı duyarlı",
   "require_for_assessing_wallet": "Cüzdana erişmek için gerekli",
-  "require_for_sends_to_non_contacts" : "Kişi olmayan kişilere göndermeler için gerekli kıl",
-  "require_for_sends_to_contacts" : "Kişilere göndermeler için gerekli kıl",
-  "require_for_sends_to_internal_wallets" : "Dahili cüzdanlara yapılan gönderimler için gereklilik",
-  "require_for_exchanges_to_internal_wallets" : "Dahili cüzdanlara değişim gerektir",
-  "require_for_adding_contacts" : "Kişi eklemek için gerekli",
-  "require_for_creating_new_wallets" : "Yeni cüzdan oluşturmak için gerekli",
-  "require_for_all_security_and_backup_settings" : "Tüm güvenlik ve yedekleme ayarları için iste",
-  "disable_sell": "Satış işlemini devre dışı bırak",
+  "require_for_sends_to_non_contacts": "Kişi olmayan kişilere göndermeler için gerekli kıl",
+  "require_for_sends_to_contacts": "Kişilere göndermeler için gerekli kıl",
+  "require_for_sends_to_internal_wallets": "Dahili cüzdanlara yapılan gönderimler için gereklilik",
+  "require_for_exchanges_to_internal_wallets": "Dahili cüzdanlara değişim gerektir",
+  "require_for_adding_contacts": "Kişi eklemek için gerekli",
+  "require_for_creating_new_wallets": "Yeni cüzdan oluşturmak için gerekli",
+  "require_for_all_security_and_backup_settings": "Tüm güvenlik ve yedekleme ayarları için iste",
   "available_balance_description": "Bu, cüzdanınızda harcayabileceğiniz miktar. Bu miktar, cüzdanınızdan çekilebilecek toplam bakiyeden daha düşük olabilir, çünkü bazı fonlar henüz kullanılamaz durumda olabilir.",
   "syncing_wallet_alert_title": "Cüzdanınız senkronize ediliyor",
   "syncing_wallet_alert_content": "Bakiyeniz ve işlem listeniz, en üstte \"SENKRONİZE EDİLDİ\" yazana kadar tamamlanmamış olabilir. Daha fazla bilgi edinmek için tıklayın/dokunun.",
@@ -683,5 +683,13 @@
   "monero_light_theme": "Monero Hafif Tema",
   "manage_nodes": "Düğümleri yönet",
   "etherscan_history": "Etherscan geçmişi",
-  "template_name": "şablon adı"
+  "template_name": "şablon adı",
+  "support_title_live_chat": "Canlı destek",
+  "support_description_live_chat": "Ücretsiz ve hızlı! Eğitimli destek temsilcileri yardımcı olmak için mevcuttur",
+  "support_title_guides": "Kek Cüzdan Kılavuzları",
+  "support_description_guides": "Ortak sorunlara belge ve destek",
+  "support_title_other_links": "Diğer destek bağlantıları",
+  "support_description_other_links": "Topluluklarımıza katılın veya ortaklarımıza diğer yöntemlerle bize ulaşın",
+  "select_destination": "Lütfen yedekleme dosyası için hedef seçin.",
+  "save_to_downloads": "İndirilenlere Kaydet"
 }
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 2f8c16eea..42c3b50ce 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -640,18 +640,19 @@
   "setup_totp_recommended": "Налаштувати TOTP (рекомендовано)",
   "disable_buy": "Вимкнути дію покупки",
   "disable_sell": "Вимкнути дію продажу",
-  "cake_2fa_preset" : "Торт 2FA Preset",
+  "auto_generate_subaddresses": "Автоматично генерувати підадреси",
+  "cake_2fa_preset": "Торт 2FA Preset",
   "narrow": "вузькі",
   "normal": "нормальний",
   "aggressive": "Надто старанний",
   "require_for_assessing_wallet": "Потрібен доступ до гаманця",
-  "require_for_sends_to_non_contacts" : "Вимагати для надсилання неконтактним особам",
-  "require_for_sends_to_contacts" : "Вимагати для надсилання контактам",
-  "require_for_sends_to_internal_wallets" : "Вимагати надсилання на внутрішні гаманці",
-  "require_for_exchanges_to_internal_wallets" : "Вимагати обміну на внутрішні гаманці",
-  "require_for_adding_contacts" : "Потрібен для додавання контактів",
-  "require_for_creating_new_wallets" : "Потрібно для створення нових гаманців",
-  "require_for_all_security_and_backup_settings" : "Вимагати всіх налаштувань безпеки та резервного копіювання",
+  "require_for_sends_to_non_contacts": "Вимагати для надсилання неконтактним особам",
+  "require_for_sends_to_contacts": "Вимагати для надсилання контактам",
+  "require_for_sends_to_internal_wallets": "Вимагати надсилання на внутрішні гаманці",
+  "require_for_exchanges_to_internal_wallets": "Вимагати обміну на внутрішні гаманці",
+  "require_for_adding_contacts": "Потрібен для додавання контактів",
+  "require_for_creating_new_wallets": "Потрібно для створення нових гаманців",
+  "require_for_all_security_and_backup_settings": "Вимагати всіх налаштувань безпеки та резервного копіювання",
   "available_balance_description": "Це сума, яку ви можете витратити, не включаючи невизначені кошти. Це може бути менше, ніж загальний баланс, якщо ви витратили кошти, які ще не підтверджені.",
   "syncing_wallet_alert_title": "Ваш гаманець синхронізується",
   "syncing_wallet_alert_content": "Ваш баланс та список транзакцій може бути неповним, доки вгорі не буде написано «СИНХРОНІЗОВАНО». Натисніть/торкніться, щоб дізнатися більше.",
@@ -684,5 +685,13 @@
   "monero_light_theme": "Легка тема Monero",
   "manage_nodes": "Керуйте вузлами",
   "etherscan_history": "Історія Etherscan",
-  "template_name": "Назва шаблону"
+  "template_name": "Назва шаблону",
+  "support_title_live_chat": "Жива підтримка",
+  "support_description_live_chat": "Безкоштовно і швидко! Навчені представники підтримки доступні для надання допомоги",
+  "support_title_guides": "Поклики для гаманців тортів",
+  "support_description_guides": "Документація та підтримка загальних питань",
+  "support_title_other_links": "Інші посилання на підтримку",
+  "support_description_other_links": "Приєднуйтесь до наших спільнот або досягайте нас нашими партнерами іншими методами",
+  "select_destination": "Виберіть місце призначення для файлу резервної копії.",
+  "save_to_downloads": "Зберегти до завантажень"
 }
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index ab4460847..fbb7ece78 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -633,18 +633,18 @@
   "setup_totp_recommended": "TOTP ترتیب دیں (تجویز کردہ)",
   "disable_buy": "خرید ایکشن کو غیر فعال کریں۔",
   "disable_sell": "فروخت کی کارروائی کو غیر فعال کریں۔",
-  "cake_2fa_preset" : "کیک 2FA پیش سیٹ",
+  "cake_2fa_preset": "کیک 2FA پیش سیٹ",
   "narrow": "تنگ",
   "normal": "نارمل",
   "aggressive": "حد سے زیادہ پرجوش",
   "require_for_assessing_wallet": "بٹوے تک رسائی کے لیے درکار ہے۔",
-  "require_for_sends_to_non_contacts" : "غیر رابطوں کو بھیجنے کی ضرورت ہے۔",
-  "require_for_sends_to_contacts" : "رابطوں کو بھیجنے کی ضرورت ہے۔",
-  "require_for_sends_to_internal_wallets" : "اندرونی بٹوے پر بھیجنے کے لیے درکار ہے۔",
-  "require_for_exchanges_to_internal_wallets" : "اندرونی بٹوے میں تبادلے کی ضرورت ہے۔",
-  "require_for_adding_contacts" : "رابطوں کو شامل کرنے کی ضرورت ہے۔",
-  "require_for_creating_new_wallets" : "نئے بٹوے بنانے کی ضرورت ہے۔",
-  "require_for_all_security_and_backup_settings" : "تمام سیکورٹی اور بیک اپ کی ترتیبات کے لیے درکار ہے۔",
+  "require_for_sends_to_non_contacts": "غیر رابطوں کو بھیجنے کی ضرورت ہے۔",
+  "require_for_sends_to_contacts": "رابطوں کو بھیجنے کی ضرورت ہے۔",
+  "require_for_sends_to_internal_wallets": "اندرونی بٹوے پر بھیجنے کے لیے درکار ہے۔",
+  "require_for_exchanges_to_internal_wallets": "اندرونی بٹوے میں تبادلے کی ضرورت ہے۔",
+  "require_for_adding_contacts": "رابطوں کو شامل کرنے کی ضرورت ہے۔",
+  "require_for_creating_new_wallets": "نئے بٹوے بنانے کی ضرورت ہے۔",
+  "require_for_all_security_and_backup_settings": "تمام سیکورٹی اور بیک اپ کی ترتیبات کے لیے درکار ہے۔",
   "available_balance_description": "”دستیاب بیلنس” یا ”تصدیق شدہ بیلنس” وہ فنڈز ہیں جو فوری طور پر خرچ کیے جا سکتے ہیں۔ اگر فنڈز کم بیلنس میں ظاہر ہوتے ہیں لیکن اوپر کے بیلنس میں نہیں، تو آپ کو مزید نیٹ ورک کی تصدیقات حاصل کرنے کے لیے آنے والے فنڈز کے لیے چند منٹ انتظار کرنا چاہیے۔ مزید تصدیق حاصل کرنے کے بعد، وہ قابل خرچ ہوں گے۔",
   "syncing_wallet_alert_title": "آپ کا بٹوہ مطابقت پذیر ہو رہا ہے۔",
   "syncing_wallet_alert_content": "آپ کے بیلنس اور لین دین کی فہرست اس وقت تک مکمل نہیں ہو سکتی جب تک کہ یہ سب سے اوپر \"SYNCRONIZED\" نہ کہے۔ مزید جاننے کے لیے کلک/تھپتھپائیں۔",
@@ -677,5 +677,14 @@
   "monero_light_theme": "مونیرو لائٹ تھیم",
   "manage_nodes": "۔ﮟﯾﺮﮐ ﻢﻈﻧ ﺎﮐ ﺱﮈﻮﻧ",
   "etherscan_history": "ﺦﯾﺭﺎﺗ ﯽﮐ ﻦﯿﮑﺳﺍ ﺮﮭﺘﯾﺍ",
-  "template_name": "ٹیمپلیٹ کا نام"
+  "template_name": "ٹیمپلیٹ کا نام",
+  "support_title_live_chat": "براہ راست مدد",
+  "support_description_live_chat": "مفت اور تیز! تربیت یافتہ معاون نمائندے مدد کے لئے دستیاب ہیں",
+  "support_title_guides": "کیک پرس گائڈز",
+  "support_description_guides": "عام مسائل کے لئے دستاویزات اور مدد",
+  "support_title_other_links": "دوسرے سپورٹ لنکس",
+  "support_description_other_links": "ہماری برادریوں میں شامل ہوں یا دوسرے طریقوں سے ہمارے شراکت داروں تک پہنچیں",
+  "select_destination": "۔ﮟﯾﺮﮐ ﺏﺎﺨﺘﻧﺍ ﺎﮐ ﻝﺰﻨﻣ ﮯﯿﻟ ﮯﮐ ﻞﺋﺎﻓ ﭖﺍ ﮏﯿﺑ ﻡﺮﮐ ﮦﺍﺮﺑ",
+  "save_to_downloads": "۔ﮟﯾﺮﮐ ﻅﻮﻔﺤﻣ ﮟﯿﻣ ﺯﮈﻮﻟ ﻥﺅﺍﮈ",
+  "auto_generate_subaddresses": "آٹو سب ایڈریس تیار کرتا ہے"
 }
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index bfbc21802..143fd0ccd 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -628,18 +628,18 @@
   "setup_totp_recommended": "Sọ TOTP (Kẹṣọdọ)",
   "disable_buy": "Ko iṣọrọ ọja",
   "disable_sell": "Ko iṣọrọ iṣọrọ",
-  "cake_2fa_preset" : "Cake 2FA Tito",
+  "cake_2fa_preset": "Cake 2FA Tito",
   "narrow": "Taara",
   "normal": "Deede",
   "aggressive": "Onítara",
   "require_for_assessing_wallet": "Beere fun wiwọle si apamọwọ",
-  "require_for_sends_to_non_contacts" : "Beere fun fifiranṣẹ si awọn ti kii ṣe awọn olubasọrọ",
-  "require_for_sends_to_contacts" : "Beere fun fifiranṣẹ si awọn olubasọrọ",
-  "require_for_sends_to_internal_wallets" : "Beere fun fifiranṣẹ si awọn apamọwọ inu",
-  "require_for_exchanges_to_internal_wallets" : "Beere fun awọn paṣipaarọ si awọn apamọwọ inu",
-  "require_for_adding_contacts" : "Beere fun fifi awọn olubasọrọ kun",
-  "require_for_creating_new_wallets" : "Beere fun ṣiṣẹda titun Woleti",
-  "require_for_all_security_and_backup_settings" : "Beere fun gbogbo aabo ati awọn eto afẹyinti",
+  "require_for_sends_to_non_contacts": "Beere fun fifiranṣẹ si awọn ti kii ṣe awọn olubasọrọ",
+  "require_for_sends_to_contacts": "Beere fun fifiranṣẹ si awọn olubasọrọ",
+  "require_for_sends_to_internal_wallets": "Beere fun fifiranṣẹ si awọn apamọwọ inu",
+  "require_for_exchanges_to_internal_wallets": "Beere fun awọn paṣipaarọ si awọn apamọwọ inu",
+  "require_for_adding_contacts": "Beere fun fifi awọn olubasọrọ kun",
+  "require_for_creating_new_wallets": "Beere fun ṣiṣẹda titun Woleti",
+  "require_for_all_security_and_backup_settings": "Beere fun gbogbo aabo ati awọn eto afẹyinti",
   "available_balance_description": "“Iwọntunwọnsi Wa” tabi “Iwọntunwọnsi Ijẹrisi” jẹ awọn owo ti o le ṣee lo lẹsẹkẹsẹ. Ti awọn owo ba han ni iwọntunwọnsi kekere ṣugbọn kii ṣe iwọntunwọnsi oke, lẹhinna o gbọdọ duro iṣẹju diẹ fun awọn owo ti nwọle lati gba awọn ijẹrisi nẹtiwọọki diẹ sii. Lẹhin ti wọn gba awọn ijẹrisi diẹ sii, wọn yoo jẹ inawo.",
   "syncing_wallet_alert_title": "Apamọwọ rẹ n muṣiṣẹpọ",
   "syncing_wallet_alert_content": "Iwontunws.funfun rẹ ati atokọ idunadura le ma pari titi ti yoo fi sọ “SYNCHRONIZED” ni oke. Tẹ/tẹ ni kia kia lati ni imọ siwaju sii.",
@@ -667,10 +667,19 @@
   "manage_nodes": "Ṣakoso awọn apa",
   "etherscan_history": "Etherscan itan",
   "template_name": "Orukọ Awoṣe",
+  "support_title_live_chat": "Atilẹyin ifiwe",
+  "support_description_live_chat": "Free ati sare! Ti oṣiṣẹ awọn aṣoju wa lati ṣe iranlọwọ",
+  "support_title_guides": "Akara oyinbo Awọn Itọsọna Awọki oyinbo",
+  "support_description_guides": "Iwe ati atilẹyin fun awọn ọran ti o wọpọ",
+  "support_title_other_links": "Awọn ọna asopọ atilẹyin miiran",
+  "support_description_other_links": "Darapọ mọ awọn agbegbe wa tabi de wa awọn alabaṣepọ wa nipasẹ awọn ọna miiran",
   "monero_dark_theme": "Monero Dudu Akori",
   "bitcoin_dark_theme": "Bitcoin Dark Akori",
   "bitcoin_light_theme": "Bitcoin Light Akori",
   "high_contrast_theme": "Akori Iyatọ giga",
   "matrix_green_dark_theme": "Matrix Green Dark Akori",
-  "monero_light_theme": "Monero Light Akori"
+  "monero_light_theme": "Monero Light Akori",
+  "select_destination": "Jọwọ yan ibi ti o nlo fun faili afẹyinti.",
+  "save_to_downloads": "Fipamọ si Awọn igbasilẹ",
+  "auto_generate_subaddresses": "Aṣiṣe Ibi-Afọwọkọ"
 }
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index f28ebc389..210207095 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -639,18 +639,18 @@
   "setup_totp_recommended": "设置 TOTP(推荐)",
   "disable_buy": "禁用购买操作",
   "disable_sell": "禁用卖出操作",
-  "cake_2fa_preset" : "蛋糕 2FA 预设",
+  "cake_2fa_preset": "蛋糕 2FA 预设",
   "narrow": "狭窄的",
   "normal": "普通的",
   "aggressive": "过分热心",
   "require_for_assessing_wallet": "需要访问钱包",
-  "require_for_sends_to_non_contacts" : "需要发送给非联系人",
-  "require_for_sends_to_contacts" : "需要发送给联系人",
-  "require_for_sends_to_internal_wallets" : "需要发送到内部钱包",
-  "require_for_exchanges_to_internal_wallets" : "需要兑换到内部钱包",
-  "require_for_adding_contacts" : "需要添加联系人",
-  "require_for_creating_new_wallets" : "创建新钱包的要求",
-  "require_for_all_security_and_backup_settings" : "需要所有安全和备份设置",
+  "require_for_sends_to_non_contacts": "需要发送给非联系人",
+  "require_for_sends_to_contacts": "需要发送给联系人",
+  "require_for_sends_to_internal_wallets": "需要发送到内部钱包",
+  "require_for_exchanges_to_internal_wallets": "需要兑换到内部钱包",
+  "require_for_adding_contacts": "需要添加联系人",
+  "require_for_creating_new_wallets": "创建新钱包的要求",
+  "require_for_all_security_and_backup_settings": "需要所有安全和备份设置",
   "available_balance_description": "可用余额是您可以使用的金额。冻结余额是您当前正在等待确认的金额。",
   "syncing_wallet_alert_title": "您的钱包正在同步",
   "syncing_wallet_alert_content": "您的余额和交易列表可能不完整,直到顶部显示“已同步”。单击/点击以了解更多信息。",
@@ -678,10 +678,19 @@
   "manage_nodes": "管理节点",
   "etherscan_history": "以太扫描历史",
   "template_name": "模板名称",
+  "support_title_live_chat": "实时支持",
+  "support_description_live_chat": "免费快速!训练有素的支持代表可以协助",
+  "support_title_guides": "蛋糕钱包指南",
+  "support_description_guides": "对常见问题的文档和支持",
+  "support_title_other_links": "其他支持链接",
+  "support_description_other_links": "加入我们的社区或通过其他方法与我们联系我们的合作伙伴",
   "monero_dark_theme": "门罗币深色主题",
   "bitcoin_dark_theme": "比特币黑暗主题",
   "bitcoin_light_theme": "比特币浅色主题",
   "high_contrast_theme": "高对比度主题",
   "matrix_green_dark_theme": "矩阵绿暗主题",
-  "monero_light_theme": "门罗币浅色主题"
+  "monero_light_theme": "门罗币浅色主题",
+  "select_destination": "请选择备份文件的目的地。",
+  "save_to_downloads": "保存到下载",
+  "auto_generate_subaddresses": "自动生成子辅助"
 }
diff --git a/scripts/android/build_haven.sh b/scripts/android/build_haven.sh
index f745e942e..16cf05039 100755
--- a/scripts/android/build_haven.sh
+++ b/scripts/android/build_haven.sh
@@ -5,8 +5,8 @@ HAVEN_VERSION=tags/v3.0.7
 HAVEN_SRC_DIR=${WORKDIR}/haven
 
 git clone https://github.com/haven-protocol-org/haven-main.git ${HAVEN_SRC_DIR}
-git checkout ${HAVEN_VERSION}
 cd $HAVEN_SRC_DIR
+git checkout ${HAVEN_VERSION}
 git submodule init
 git submodule update
 
diff --git a/scripts/docker/.gitignore b/scripts/docker/.gitignore
new file mode 100644
index 000000000..ea1472ec1
--- /dev/null
+++ b/scripts/docker/.gitignore
@@ -0,0 +1 @@
+output/
diff --git a/scripts/docker/Dockerfile b/scripts/docker/Dockerfile
new file mode 100644
index 000000000..eef09a323
--- /dev/null
+++ b/scripts/docker/Dockerfile
@@ -0,0 +1,26 @@
+FROM ubuntu:20.04
+LABEL authors="konsti"
+
+ENV MONERO_BRANCH=release-v0.18.2.2-android
+RUN apt-get update && \
+    echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections && \
+    apt-get install -y dialog apt-utils curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
+
+RUN mkdir /opt/android/
+
+COPY . /opt/android/cakewallet/
+
+WORKDIR /opt/android/cakewallet/
+
+
+RUN ./install_ndk.sh
+
+RUN ./build_iconv.sh
+RUN ./build_boost.sh
+RUN ./build_openssl.sh
+RUN ./build_sodium.sh
+RUN ./build_unbound.sh
+RUN ./build_zmq.sh
+
+
+ENTRYPOINT ["./entrypoint.sh"]
diff --git a/scripts/docker/build_all.sh b/scripts/docker/build_all.sh
new file mode 100644
index 000000000..0acb7fcde
--- /dev/null
+++ b/scripts/docker/build_all.sh
@@ -0,0 +1 @@
+#!/bin/sh

if [ -z "$APP_ANDROID_TYPE" ]; then
	echo "Please set APP_ANDROID_TYPE"
	exit 1
fi

DIR=$(dirname "$0")

case $APP_ANDROID_TYPE in
	"monero.com") $DIR/build_monero_all.sh ;;
	"cakewallet") $DIR/build_monero_all.sh
				  $DIR/build_haven.sh ;;
	"haven")      $DIR/build_haven_all.sh ;;
esac
\ No newline at end of file
diff --git a/scripts/docker/build_boost.sh b/scripts/docker/build_boost.sh
new file mode 100644
index 000000000..2c98afab5
--- /dev/null
+++ b/scripts/docker/build_boost.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+. ./config.sh
+BOOST_SRC_DIR=$WORKDIR/boost_1_72_0
+BOOST_FILENAME=boost_1_72_0.tar.bz2
+BOOST_VERSION=1.72.0
+
+for arch in "aarch" "aarch64" "i686" "x86_64"
+do
+
+PREFIX=$WORKDIR/prefix_${arch}
+PATH="${TOOLCHAIN_BASE_DIR}_${arch}/bin:${ORIGINAL_PATH}"
+./init_boost.sh $arch $PREFIX $BOOST_SRC_DIR $BOOST_FILENAME $BOOST_VERSION
+./finish_boost.sh $arch $PREFIX $BOOST_SRC_DIR $BOOST_SRC_DIR
+
+done
diff --git a/scripts/docker/build_haven.sh b/scripts/docker/build_haven.sh
new file mode 100644
index 000000000..7927c5102
--- /dev/null
+++ b/scripts/docker/build_haven.sh
@@ -0,0 +1 @@
+#!/bin/sh

. ./config.sh
HAVEN_VERSION=tags/v3.0.7
HAVEN_SRC_DIR=${WORKDIR}/haven

git clone https://github.com/haven-protocol-org/haven-main.git ${HAVEN_SRC_DIR}
git checkout ${HAVEN_VERSION}
cd $HAVEN_SRC_DIR
git submodule init
git submodule update

for arch in "aarch" "aarch64" "i686" "x86_64"
do
FLAGS=""
PREFIX=${WORKDIR}/prefix_${arch}
DEST_LIB_DIR=${PREFIX}/lib/haven
DEST_INCLUDE_DIR=${PREFIX}/include/haven
export CMAKE_INCLUDE_PATH="${PREFIX}/include"
export CMAKE_LIBRARY_PATH="${PREFIX}/lib"
ANDROID_STANDALONE_TOOLCHAIN_PATH="${TOOLCHAIN_BASE_DIR}_${arch}"
PATH="${ANDROID_STANDALONE_TOOLCHAIN_PATH}/bin:${ORIGINAL_PATH}"

mkdir -p $DEST_LIB_DIR
mkdir -p $DEST_INCLUDE_DIR

case $arch in
	"aarch"	)
		CLANG=arm-linux-androideabi-clang
 		CXXLANG=arm-linux-androideabi-clang++
		BUILD_64=OFF
		TAG="android-armv7"
		ARCH="armv7-a"
		ARCH_ABI="armeabi-v7a"
		FLAGS="-D CMAKE_ANDROID_ARM_MODE=ON -D NO_AES=true";;
	"aarch64"	)
		CLANG=aarch64-linux-androideabi-clang
 		CXXLANG=aarch64-linux-androideabi-clang++
		BUILD_64=ON
		TAG="android-armv8"
		ARCH="armv8-a"
		ARCH_ABI="arm64-v8a";;
	"i686"		)
		CLANG=i686-linux-androideabi-clang
 		CXXLANG=i686-linux-androideabi-clang++
		BUILD_64=OFF
		TAG="android-x86"
		ARCH="i686"
		ARCH_ABI="x86";;
	"x86_64"	)  
		CLANG=x86_64-linux-androideabi-clang
 		CXXLANG=x86_64-linux-androideabi-clang++
		BUILD_64=ON
		TAG="android-x86_64"
		ARCH="x86-64"
		ARCH_ABI="x86_64";;
esac

cd $HAVEN_SRC_DIR
rm -rf ./build/release
mkdir -p ./build/release
cd ./build/release
CC=${CLANG} CXX=${CXXLANG} cmake -D USE_DEVICE_TREZOR=OFF -D BUILD_GUI_DEPS=1 -D BUILD_TESTS=OFF -D ARCH=${ARCH} -D STATIC=ON -D BUILD_64=${BUILD_64} -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D INSTALL_VENDORED_LIBUNBOUND=ON -D BUILD_TAG=${TAG} -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_STANDALONE_TOOLCHAIN="${ANDROID_STANDALONE_TOOLCHAIN_PATH}" -D CMAKE_ANDROID_ARCH_ABI=${ARCH_ABI} $FLAGS ../..
    
make wallet_api -j$THREADS
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
done
\ No newline at end of file
diff --git a/scripts/docker/build_haven_all.sh b/scripts/docker/build_haven_all.sh
new file mode 100644
index 000000000..4b33ad077
--- /dev/null
+++ b/scripts/docker/build_haven_all.sh
@@ -0,0 +1 @@
+#!/bin/bash

./build_iconv.sh
./build_boost.sh
./build_openssl.sh
./build_sodium.sh
./build_zmq.sh
./build_haven.sh
\ No newline at end of file
diff --git a/scripts/docker/build_iconv.sh b/scripts/docker/build_iconv.sh
new file mode 100644
index 000000000..9edac26b3
--- /dev/null
+++ b/scripts/docker/build_iconv.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+. ./config.sh
+export ICONV_FILENAME=libiconv-1.16.tar.gz
+export ICONV_FILE_PATH=$WORKDIR/$ICONV_FILENAME
+export ICONV_SRC_DIR=$WORKDIR/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
+
+for arch in aarch aarch64 i686 x86_64
+do
+
+PREFIX=${WORKDIR}/prefix_${arch}
+PATH="${TOOLCHAIN_BASE_DIR}_${arch}/bin:${ORIGINAL_PATH}"
+
+case $arch in
+	"aarch"	)
+		CLANG=arm-linux-androideabi-clang
+        CXXLANG=arm-linux-androideabi-clang++
+        HOST="arm-linux-android";;
+	*		)
+		CLANG=${arch}-linux-android-clang
+		CXXLANG=${arch}-linux-android-clang++
+		HOST="${arch}-linux-android";;
+esac 
+
+cd $WORKDIR
+rm -rf $ICONV_SRC_DIR
+tar -xzf $ICONV_FILE_PATH -C $WORKDIR
+cd $ICONV_SRC_DIR
+CC=${CLANG} CXX=${CXXLANG} ./configure --build=x86_64-linux-gnu --host=${HOST} --prefix=${PREFIX} --disable-rpath
+make -j$THREADS
+make install
+
+done
+
diff --git a/scripts/docker/build_monero.sh b/scripts/docker/build_monero.sh
new file mode 100644
index 000000000..d663f5288
--- /dev/null
+++ b/scripts/docker/build_monero.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+. ./config.sh
+
+MONERO_SRC_DIR=${WORKDIR}/monero
+
+git clone https://github.com/cake-tech/monero.git ${MONERO_SRC_DIR} --branch ${MONERO_BRANCH}
+cd $MONERO_SRC_DIR
+git submodule init
+git submodule update
+
+for arch in "aarch" "aarch64" "i686" "x86_64"
+do
+FLAGS=""
+PREFIX=${WORKDIR}/prefix_${arch}
+DEST_LIB_DIR=${PREFIX}/lib/monero
+DEST_INCLUDE_DIR=${PREFIX}/include/monero
+export CMAKE_INCLUDE_PATH="${PREFIX}/include"
+export CMAKE_LIBRARY_PATH="${PREFIX}/lib"
+ANDROID_STANDALONE_TOOLCHAIN_PATH="${TOOLCHAIN_BASE_DIR}_${arch}"
+PATH="${ANDROID_STANDALONE_TOOLCHAIN_PATH}/bin:${ORIGINAL_PATH}"
+
+mkdir -p $DEST_LIB_DIR
+mkdir -p $DEST_INCLUDE_DIR
+
+case $arch in
+	"aarch"	)
+		CLANG=arm-linux-androideabi-clang
+ 		CXXLANG=arm-linux-androideabi-clang++
+		BUILD_64=OFF
+		TAG="android-armv7"
+		ARCH="armv7-a"
+		ARCH_ABI="armeabi-v7a"
+		FLAGS="-D CMAKE_ANDROID_ARM_MODE=ON -D NO_AES=true";;
+	"aarch64"	)
+		CLANG=aarch64-linux-androideabi-clang
+ 		CXXLANG=aarch64-linux-androideabi-clang++
+		BUILD_64=ON
+		TAG="android-armv8"
+		ARCH="armv8-a"
+		ARCH_ABI="arm64-v8a";;
+	"i686"		)
+		CLANG=i686-linux-androideabi-clang
+ 		CXXLANG=i686-linux-androideabi-clang++
+		BUILD_64=OFF
+		TAG="android-x86"
+		ARCH="i686"
+		ARCH_ABI="x86";;
+	"x86_64"	)  
+		CLANG=x86_64-linux-androideabi-clang
+ 		CXXLANG=x86_64-linux-androideabi-clang++
+		BUILD_64=ON
+		TAG="android-x86_64"
+		ARCH="x86-64"
+		ARCH_ABI="x86_64";;
+esac
+
+cd $MONERO_SRC_DIR
+rm -rf ./build/release
+mkdir -p ./build/release
+cd ./build/release
+CC=${CLANG} CXX=${CXXLANG} cmake -D USE_DEVICE_TREZOR=OFF -D BUILD_GUI_DEPS=1 -D BUILD_TESTS=OFF -D ARCH=${ARCH} -D STATIC=ON -D BUILD_64=${BUILD_64} -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D INSTALL_VENDORED_LIBUNBOUND=ON -D BUILD_TAG=${TAG} -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_STANDALONE_TOOLCHAIN="${ANDROID_STANDALONE_TOOLCHAIN_PATH}" -D CMAKE_ANDROID_ARCH_ABI=${ARCH_ABI} $FLAGS ../..
+    
+make wallet_api -j$THREADS
+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
+done
diff --git a/scripts/docker/build_openssl.sh b/scripts/docker/build_openssl.sh
new file mode 100644
index 000000000..685d0a1be
--- /dev/null
+++ b/scripts/docker/build_openssl.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+set -e
+
+. ./config.sh
+OPENSSL_FILENAME=openssl-1.1.1q.tar.gz
+OPENSSL_FILE_PATH=$WORKDIR/$OPENSSL_FILENAME
+OPENSSL_SRC_DIR=$WORKDIR/openssl-1.1.1q
+OPENSSL_SHA256="d7939ce614029cdff0b6c20f0e2e5703158a489a72b2507b8bd51bf8c8fd10ca"
+ZLIB_DIR=$WORKDIR/zlib
+ZLIB_TAG=v1.2.11
+ZLIB_COMMIT_HASH="cacf7f1d4e3d44d871b605da3b647f07d718623f"
+
+rm -rf $ZLIB_DIR
+git clone -b $ZLIB_TAG --depth 1 https://github.com/madler/zlib $ZLIB_DIR
+cd $ZLIB_DIR
+git reset --hard $ZLIB_COMMIT_HASH
+CC=clang CXX=clang++ ./configure --static
+make
+
+curl https://www.openssl.org/source/$OPENSSL_FILENAME -o $OPENSSL_FILE_PATH
+echo $OPENSSL_SHA256 $OPENSSL_FILE_PATH | sha256sum -c - || exit 1
+
+for arch in "aarch" "aarch64" "i686" "x86_64"
+do
+PREFIX=$WORKDIR/prefix_${arch}
+TOOLCHAIN=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64
+PATH="${TOOLCHAIN}/bin:${ORIGINAL_PATH}"
+
+case $arch in
+	"aarch")   X_ARCH="android-arm";;
+	"aarch64") X_ARCH="android-arm64";;
+	"i686")    X_ARCH="android-x86";;
+	"x86_64")  X_ARCH="android-x86_64";;
+	*)	   X_ARCH="android-${arch}";;
+esac 	
+
+cd $WORKDIR
+rm -rf $OPENSSL_SRC_DIR
+tar -xzf $OPENSSL_FILE_PATH -C $WORKDIR
+cd $OPENSSL_SRC_DIR
+
+CC=clang ANDROID_NDK=$TOOLCHAIN \
+	./Configure ${X_ARCH} \
+	no-shared no-tests \
+	--with-zlib-include=${PREFIX}/include \
+	--with-zlib-lib=${PREFIX}/lib \
+	--prefix=${PREFIX} \
+	--openssldir=${PREFIX} \
+	-D__ANDROID_API__=$API 
+make -j$THREADS
+make -j$THREADS install_sw
+
+done
+
diff --git a/scripts/docker/build_sodium.sh b/scripts/docker/build_sodium.sh
new file mode 100644
index 000000000..a934d641b
--- /dev/null
+++ b/scripts/docker/build_sodium.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+. ./config.sh
+SODIUM_SRC_DIR=${WORKDIR}/libsodium
+SODIUM_BRANCH=1.0.16
+
+for arch in "aarch" "aarch64" "i686" "x86_64"
+do
+
+PREFIX=${WORKDIR}/prefix_${arch}
+PATH="${TOOLCHAIN_BASE_DIR}_${arch}/bin:${ORIGINAL_PATH}"
+
+case $arch in
+	"aarch"	) TARGET="arm";;
+	"i686"		) TARGET="x86";;
+	*		) TARGET="${arch}";;
+esac  
+
+HOST="${TARGET}-linux-android"
+cd $WORKDIR
+rm -rf $SODIUM_SRC_DIR
+git clone https://github.com/jedisct1/libsodium.git $SODIUM_SRC_DIR -b $SODIUM_BRANCH
+cd $SODIUM_SRC_DIR
+./autogen.sh
+CC=clang CXX=clang++ ./configure --prefix=${PREFIX} --host=${HOST} --enable-static --disable-shared
+make -j$THREADS
+make install
+
+done
+
diff --git a/scripts/docker/build_unbound.sh b/scripts/docker/build_unbound.sh
new file mode 100644
index 000000000..8786b0f2b
--- /dev/null
+++ b/scripts/docker/build_unbound.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+. ./config.sh
+
+EXPAT_VERSION=R_2_4_8
+EXPAT_HASH="3bab6c09bbe8bf42d84b81563ddbcf4cca4be838"
+EXPAT_SRC_DIR=$WORKDIR/libexpat
+
+for arch in "aarch" "aarch64" "i686" "x86_64"
+do
+PREFIX=$WORKDIR/prefix_${arch}
+TOOLCHAIN=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64
+PATH="${TOOLCHAIN_BASE_DIR}_${arch}/bin:${ORIGINAL_PATH}"
+
+cd $WORKDIR
+rm -rf $EXPAT_SRC_DIR
+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
+
+case $arch in
+	"aarch")   HOST="arm-linux-androideabi";;
+	"i686")    HOST="x86-linux-android";;
+	*)	       HOST="${arch}-linux-android";;
+esac 
+
+./buildconf.sh
+CC=clang CXX=clang++ ./configure --enable-static --disable-shared --prefix=${PREFIX} --host=${HOST}
+make -j$THREADS
+make -j$THREADS install
+done
+
+UNBOUND_VERSION=release-1.16.2
+UNBOUND_HASH="cbed768b8ff9bfcf11089a5f1699b7e5707f1ea5"
+UNBOUND_SRC_DIR=$WORKDIR/unbound-1.16.2
+
+for arch in "aarch" "aarch64" "i686" "x86_64"
+do
+PREFIX=$WORKDIR/prefix_${arch}
+TOOLCHAIN=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64
+
+case $arch in
+	"aarch")   TOOLCHAIN_BIN_PATH=${TOOLCHAIN_BASE_DIR}_${arch}/arm-linux-androideabi/bin;;
+	*)	       TOOLCHAIN_BIN_PATH=${TOOLCHAIN_BASE_DIR}_${arch}/${arch}-linux-android/bin;;
+esac 
+
+PATH="${TOOLCHAIN_BIN_PATH}:${TOOLCHAIN_BASE_DIR}_${arch}/bin:${ORIGINAL_PATH}"
+echo $PATH
+cd $WORKDIR
+rm -rf $UNBOUND_SRC_DIR
+git clone https://github.com/NLnetLabs/unbound.git -b ${UNBOUND_VERSION} ${UNBOUND_SRC_DIR}
+cd $UNBOUND_SRC_DIR
+test `git rev-parse HEAD` = ${UNBOUND_HASH} || exit 1
+
+case $arch in
+	"aarch")   HOST="arm-linux-androideabi";;
+	"i686")    HOST="x86-linux-android";;
+	*)	       HOST="${arch}-linux-android";;
+esac
+
+CC=clang CXX=clang++ ./configure --prefix=${PREFIX} --host=${HOST} --enable-static --disable-shared --disable-flto --with-ssl=${PREFIX} --with-libexpat=${PREFIX}
+make -j$THREADS
+make -j$THREADS install
+done
diff --git a/scripts/docker/build_zmq.sh b/scripts/docker/build_zmq.sh
new file mode 100644
index 000000000..bbff9e41b
--- /dev/null
+++ b/scripts/docker/build_zmq.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+. ./config.sh
+ZMQ_SRC_DIR=$WORKDIR/libzmq
+ZMQ_BRANCH=v4.3.3
+ZMQ_COMMIT_HASH=04f5bbedee58c538934374dc45182d8fc5926fa3
+
+for arch in "aarch" "aarch64" "i686" "x86_64"
+do
+
+PREFIX=$WORKDIR/prefix_${arch}
+PATH="${TOOLCHAIN_BASE_DIR}_${arch}/bin:${ORIGINAL_PATH}"
+
+case $arch in
+	"aarch"	) TARGET="arm";;
+	"i686"		) TARGET="x86";;
+	*		) TARGET="${arch}";;
+esac 
+
+
+HOST="${TARGET}-linux-android"
+cd $WORKDIR
+rm -rf $ZMQ_SRC_DIR
+git clone https://github.com/zeromq/libzmq.git ${ZMQ_SRC_DIR} -b ${ZMQ_BRANCH}
+cd $ZMQ_SRC_DIR
+git checkout ${ZMQ_COMMIT_HASH}
+./autogen.sh
+CC=clang CXX=clang++ ./configure --prefix=${PREFIX} --host=${HOST} --enable-static --disable-shared
+make -j$THREADS
+make install
+
+done
diff --git a/scripts/docker/config.sh b/scripts/docker/config.sh
new file mode 100644
index 000000000..c5067f2c3
--- /dev/null
+++ b/scripts/docker/config.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+export API=21
+export WORKDIR=/opt/android
+export ANDROID_NDK_ZIP=${WORKDIR}/android-ndk-r17c.zip
+export ANDROID_NDK_ROOT=${WORKDIR}/android-ndk-r17c
+export ANDROID_NDK_HOME=$ANDROID_NDK_ROOT
+export TOOLCHAIN_DIR="${WORKDIR}/toolchain"
+export TOOLCHAIN_BASE_DIR=$TOOLCHAIN_DIR
+export ORIGINAL_PATH=$PATH
+export THREADS=4
diff --git a/scripts/docker/copy_haven_deps.sh b/scripts/docker/copy_haven_deps.sh
new file mode 100644
index 000000000..d59e9d7f0
--- /dev/null
+++ b/scripts/docker/copy_haven_deps.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+WORKDIR=/opt/android
+CW_DIR=${WORKDIR}/cake_wallet
+CW_EXRTERNAL_DIR=${CW_DIR}/cw_shared_external/ios/External/android
+CW_HAVEN_EXTERNAL_DIR=${CW_DIR}/cw_haven/ios/External/android
+CW_MONERO_EXTERNAL_DIR=${CW_DIR}/cw_monero/ios/External/android
+for arch in "aarch" "aarch64" "i686" "x86_64"
+do
+
+PREFIX=${WORKDIR}/prefix_${arch}
+ABI=""
+
+case $arch in
+	"aarch"	)
+		ABI="armeabi-v7a";;
+	"aarch64"	)
+		ABI="arm64-v8a";;
+	"i686"		)
+		ABI="x86";;
+	"x86_64"	)
+		ABI="x86_64";;
+esac
+
+LIB_DIR=${CW_EXRTERNAL_DIR}/${ABI}/lib
+INCLUDE_DIR=${CW_EXRTERNAL_DIR}/${ABI}/include
+LIBANBOUND_PATH=${PREFIX}/lib/libunbound.a
+
+mkdir -p $LIB_DIR
+mkdir -p $INCLUDE_DIR
+
+cp -r ${PREFIX}/lib/* $LIB_DIR
+cp -r ${PREFIX}/include/* $INCLUDE_DIR
+
+if [ -f "$LIBANBOUND_PATH" ]; then
+ cp $LIBANBOUND_PATH ${LIB_DIR}/monero
+fi
+
+done
+
+mkdir -p ${CW_HAVEN_EXTERNAL_DIR}/include
+mkdir -p ${CW_MONERO_EXTERNAL_DIR}/include
+
+cp $CW_EXRTERNAL_DIR/x86/include/monero/wallet2_api.h ${CW_MONERO_EXTERNAL_DIR}/include
+cp $CW_EXRTERNAL_DIR/x86/include/haven/wallet2_api.h ${CW_HAVEN_EXTERNAL_DIR}/include
diff --git a/scripts/docker/copy_monero_deps.sh b/scripts/docker/copy_monero_deps.sh
new file mode 100644
index 000000000..e4392186c
--- /dev/null
+++ b/scripts/docker/copy_monero_deps.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+WORKDIR=/opt/android
+CW_EXRTERNAL_DIR=${WORKDIR}/output/android
+
+for arch in "aarch" "aarch64" "i686" "x86_64"
+do
+
+PREFIX=${WORKDIR}/prefix_${arch}
+ABI=""
+
+case $arch in
+	"aarch"	)
+		ABI="armeabi-v7a";;
+	"aarch64"	)
+		ABI="arm64-v8a";;
+	"i686"		)
+		ABI="x86";;
+	"x86_64"	)
+		ABI="x86_64";;
+esac
+
+LIB_DIR=${CW_EXRTERNAL_DIR}/${ABI}/lib
+INCLUDE_DIR=${CW_EXRTERNAL_DIR}/${ABI}/include
+LIBANBOUND_PATH=${PREFIX}/lib/libunbound.a
+
+mkdir -p $LIB_DIR
+mkdir -p $INCLUDE_DIR
+
+cp -r ${PREFIX}/lib/* $LIB_DIR
+cp -r ${PREFIX}/include/* $INCLUDE_DIR
+
+if [ -f "$LIBANBOUND_PATH" ]; then
+ cp $LIBANBOUND_PATH ${LIB_DIR}/monero
+fi
+
+done
diff --git a/scripts/docker/docker-compose.yml b/scripts/docker/docker-compose.yml
new file mode 100644
index 000000000..eaeea0f5b
--- /dev/null
+++ b/scripts/docker/docker-compose.yml
@@ -0,0 +1,9 @@
+version: '3.6'
+
+services:
+  build_deps:
+    image: build_monero_deps
+    environment:
+      MONERO_BRANCH: release-v0.18.2.2-android
+    volumes:
+      - ./output:/opt/android/output
diff --git a/scripts/docker/entrypoint.sh b/scripts/docker/entrypoint.sh
new file mode 100644
index 000000000..e4bdc017c
--- /dev/null
+++ b/scripts/docker/entrypoint.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+./build_monero.sh
+./copy_monero_deps.sh
diff --git a/scripts/docker/finish_boost.sh b/scripts/docker/finish_boost.sh
new file mode 100644
index 000000000..e3f195276
--- /dev/null
+++ b/scripts/docker/finish_boost.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+ARCH=$1
+PREFIX=$2
+BOOST_SRC_DIR=$3
+
+cd $BOOST_SRC_DIR
+
+./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale --build-dir=android --stagedir=android toolset=clang threading=multi threadapi=pthread target-os=android -sICONV_PATH=${PREFIX} -j$THREADS install
diff --git a/scripts/docker/init_boost.sh b/scripts/docker/init_boost.sh
new file mode 100644
index 000000000..ffb7a1416
--- /dev/null
+++ b/scripts/docker/init_boost.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+ARCH=$1
+PREFIX=$2
+BOOST_SRC_DIR=$3
+BOOST_FILENAME=$4
+BOOST_VERSION=$5
+BOOST_FILE_PATH=$WORKDIR/$BOOST_FILENAME
+BOOST_SHA256="59c9b274bc451cf91a9ba1dd2c7fdcaf5d60b1b3aa83f2c9fa143417cc660722"
+
+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 $WORKDIR
+rm -rf $BOOST_SRC_DIR
+rm -rf $PREFIX/include/boost
+tar -xvf $BOOST_FILE_PATH -C $WORKDIR
+cd $BOOST_SRC_DIR
+./bootstrap.sh --prefix=${PREFIX}
diff --git a/scripts/docker/install_ndk.sh b/scripts/docker/install_ndk.sh
new file mode 100644
index 000000000..5f97751e3
--- /dev/null
+++ b/scripts/docker/install_ndk.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+. ./config.sh
+TOOLCHAIN_DIR=${WORKDIR}/toolchain
+TOOLCHAIN_A32_DIR=${TOOLCHAIN_DIR}_aarch
+TOOLCHAIN_A64_DIR=${TOOLCHAIN_DIR}_aarch64
+TOOLCHAIN_x86_DIR=${TOOLCHAIN_DIR}_i686
+TOOLCHAIN_x86_64_DIR=${TOOLCHAIN_DIR}_x86_64
+ANDROID_NDK_SHA256="3f541adbd0330a9205ba12697f6d04ec90752c53d6b622101a2a8a856e816589"
+
+curl https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip -o ${ANDROID_NDK_ZIP}
+echo $ANDROID_NDK_SHA256 $ANDROID_NDK_ZIP | sha256sum -c || exit 1
+unzip $ANDROID_NDK_ZIP -d $WORKDIR
+
+${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py --arch arm64 --api $API --install-dir ${TOOLCHAIN_A64_DIR} --stl=libc++
+${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py --arch arm --api $API --install-dir ${TOOLCHAIN_A32_DIR} --stl=libc++
+${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py --arch x86 --api $API --install-dir ${TOOLCHAIN_x86_DIR} --stl=libc++
+${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py --arch x86_64 --api $API --install-dir ${TOOLCHAIN_x86_64_DIR} --stl=libc++
diff --git a/scripts/ios/build_monero.sh b/scripts/ios/build_monero.sh
index 9a892d8c5..54dda546f 100755
--- a/scripts/ios/build_monero.sh
+++ b/scripts/ios/build_monero.sh
@@ -59,4 +59,4 @@ cp -r ./lib/* $DEST_LIB_DIR
 cp ../../src/wallet/api/wallet2_api.h  $DEST_INCLUDE_DIR
 popd
 
-done
\ No newline at end of file
+done
diff --git a/tool/append_translation.dart b/tool/append_translation.dart
index 080b2c5e7..5c48aceab 100644
--- a/tool/append_translation.dart
+++ b/tool/append_translation.dart
@@ -1,66 +1,22 @@
-// import 'dart:convert';
-// import 'dart:io';
-//
-// import 'package:translator/translator.dart';
-//
-// const defaultLang = "en";
-// const langs = [
-//   "ar", "bg", "cs", "de", "en", "es", "fr", "ha", "hi", "hr", "id", "it",
-//   "ja", "ko", "my", "nl", "pl", "pt", "ru", "th", "tr", "uk", "ur", "yo",
-//   "zh-cn" // zh, but Google Translate uses zh-cn for Chinese (Simplified)
-// ];
-// final translator = GoogleTranslator();
-//
-// void main(List<String> args) async {
-//   if (args.length != 2) {
-//     throw Exception(
-//         'Insufficient arguments!\n\nTry to run `./append_translation.dart greetings "Hello World!"`');
-//   }
-//
-//   final name = args.first;
-//   final text = args.last;
-//
-//   print('Appending "$name": "$text"');
-//
-//   for (var lang in langs) {
-//     final fileName = getFileName(lang);
-//     final translation = await getTranslation(text, lang);
-//
-//     appendArbFile(fileName, name, translation);
-//   }
-// }
-//
-// void appendArbFile(String fileName, String name, String text) {
-//   final file = File(fileName);
-//   final inputContent = file.readAsStringSync();
-//   final arbObj = json.decode(inputContent) as Map<String, dynamic>;
-//
-//   if (arbObj.containsKey(name)) {
-//     print("String $name already exists in $fileName!");
-//     return;
-//   }
-//
-//   arbObj.addAll({name: text});
-//
-//   final outputContent = json
-//       .encode(arbObj)
-//       .replaceAll('","', '",\n  "')
-//       .replaceAll('{"', '{\n  "')
-//       .replaceAll('"}', '"\n}')
-//       .replaceAll('":"', '": "');
-//
-//   file.writeAsStringSync(outputContent);
-// }
-//
-//
-// Future<String> getTranslation(String text, String lang) async {
-//   if (lang == defaultLang) return text;
-//   return (await translator.translate(text, from: defaultLang, to: lang)).text;
-// }
-//
-// String getFileName(String lang) {
-//   final shortLang = lang
-//       .split("-")
-//       .first;
-//   return "./res/values/strings_$shortLang.arb";
-// }
+import 'utils/translation/arb_file_utils.dart';
+import 'utils/translation/translation_constants.dart';
+import 'utils/translation/translation_utils.dart';
+
+void main(List<String> args) async {
+  if (args.length != 2) {
+    throw Exception(
+        'Insufficient arguments!\n\nTry to run `./append_translation.dart greetings "Hello World!"`');
+  }
+
+  final name = args.first;
+  final text = args.last;
+
+  print('Appending "$name": "$text"');
+
+  for (var lang in langs) {
+    final fileName = getArbFileName(lang);
+    final translation = await getTranslation(text, lang);
+
+    appendStringToArbFile(fileName, name, translation);
+  }
+}
diff --git a/tool/configure.dart b/tool/configure.dart
index e84975fd2..0733f4c5b 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -28,6 +28,7 @@ Future<void> main(List<String> args) async {
 Future<void> generateBitcoin(bool hasImplementation) async {
   final outputFile = File(bitcoinOutputPath);
   const bitcoinCommonHeaders = """
+import 'package:cake_wallet/entities/unspent_transaction_output.dart';
 import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/transaction_priority.dart';
@@ -51,24 +52,6 @@ import 'package:cw_bitcoin/litecoin_wallet_service.dart';
 """;
   const bitcoinCwPart = "part 'cw_bitcoin.dart';";
   const bitcoinContent = """
-class Unspent {
-  Unspent(this.address, this.hash, this.value, this.vout)
-      : isSending = true,
-        isFrozen = false,
-        note = '';
-
-  final String address;
-  final String hash;
-  final int value;
-  final int vout;
-  
-  bool isSending;
-  bool isFrozen;
-  String note;
-
-  bool get isP2wpkh => address.startsWith('bc') || address.startsWith('ltc');
-}
-
 abstract class Bitcoin {
   TransactionPriority getMediumTransactionPriority();
 
@@ -125,6 +108,9 @@ abstract class Bitcoin {
 Future<void> generateMonero(bool hasImplementation) async {
   final outputFile = File(moneroOutputPath);
   const moneroCommonHeaders = """
+import 'package:cake_wallet/entities/unspent_transaction_output.dart';
+import 'package:cw_core/unspent_coins_info.dart';
+import 'package:cw_monero/monero_unspent.dart';
 import 'package:mobx/mobx.dart';
 import 'package:flutter/foundation.dart';
 import 'package:cw_core/wallet_credentials.dart';
@@ -234,6 +220,9 @@ abstract class Monero {
   TransactionPriority deserializeMoneroTransactionPriority({required int raw});
   List<TransactionPriority> getTransactionPriorities();
   List<String> getMoneroWordList(String language);
+  
+  List<Unspent> getUnspents(Object wallet);
+  void updateUnspents(Object wallet);
 
   WalletCredentials createMoneroRestoreWalletFromKeysCredentials({
     required String name,
@@ -255,7 +244,7 @@ abstract class Monero {
   void setCurrentAccount(Object wallet, int id, String label, String? balance);
   void onStartup();
   int getTransactionInfoAccountId(TransactionInfo tx);
-  WalletService createMoneroWalletService(Box<WalletInfo> walletInfoSource);
+  WalletService createMoneroWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource);
   Map<String, String> pendingTransactionInfo(Object transaction);
 }
 
@@ -510,6 +499,7 @@ abstract class Ethereum {
   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});
   String getAddress(WalletBase wallet);
   TransactionPriority getDefaultTransactionPriority();
   List<TransactionPriority> getTransactionPriorities();
diff --git a/tool/translation_consistence.dart b/tool/translation_consistence.dart
new file mode 100644
index 000000000..04f64dfc8
--- /dev/null
+++ b/tool/translation_consistence.dart
@@ -0,0 +1,37 @@
+import 'dart:io';
+
+import 'utils/translation/arb_file_utils.dart';
+import 'utils/translation/translation_constants.dart';
+import 'utils/translation/translation_utils.dart';
+
+void main(List<String> args) async {
+  print('Checking Consistency of all arb-files. Default: $defaultLang');
+
+  final doFix = args.contains("--fix");
+
+  if (doFix)
+    print('Auto fixing enabled!\n');
+  else
+    print('Auto fixing disabled!\nRun with arg "--fix" to enable autofix\n');
+
+  final fileName = getArbFileName(defaultLang);
+  final file = File(fileName);
+  final arbObj = readArbFile(file);
+
+  for (var lang in langs) {
+    final fileName = getArbFileName(lang);
+    final missingKeys = getMissingKeysInArbFile(fileName, arbObj.keys);
+    if (missingKeys.isNotEmpty) {
+      final missingDefaults = <String, String>{};
+
+      missingKeys.forEach((key) {
+        print('Missing in "$lang": "$key"');
+        if (doFix)
+          missingDefaults[key] = arbObj[key] as String;
+      });
+
+      if (missingDefaults.isNotEmpty)
+        await appendTranslations(lang, missingDefaults);
+    }
+  }
+}
diff --git a/tool/utils/translation/arb_file_utils.dart b/tool/utils/translation/arb_file_utils.dart
new file mode 100644
index 000000000..693c5b93e
--- /dev/null
+++ b/tool/utils/translation/arb_file_utils.dart
@@ -0,0 +1,66 @@
+import 'dart:convert';
+import 'dart:io';
+
+void appendStringToArbFile(String fileName, String name, String text) {
+  final file = File(fileName);
+  final arbObj = readArbFile(file);
+
+  if (arbObj.containsKey(name)) {
+    print("String $name already exists in $fileName!");
+    return;
+  }
+
+  arbObj.addAll({name: text});
+
+  final outputContent = json
+      .encode(arbObj)
+      .replaceAll('","', '",\n  "')
+      .replaceAll('{"', '{\n  "')
+      .replaceAll('"}', '"\n}')
+      .replaceAll('":"', '": "');
+
+  file.writeAsStringSync(outputContent);
+}
+
+void appendStringsToArbFile(String fileName, Map<String, String> strings) {
+  final file = File(fileName);
+  final arbObj = readArbFile(file);
+
+  arbObj.addAll(strings);
+
+  final outputContent = json
+      .encode(arbObj)
+      .replaceAll('","', '",\n  "')
+      .replaceAll('{"', '{\n  "')
+      .replaceAll('"}', '"\n}')
+      .replaceAll('":"', '": "');
+
+  file.writeAsStringSync(outputContent);
+}
+
+Map<String, dynamic> readArbFile(File file) {
+  final inputContent = file.readAsStringSync();
+
+  return json.decode(inputContent) as Map<String, dynamic>;
+}
+
+String getArbFileName(String lang) {
+  final shortLang = lang
+      .split("-")
+      .first;
+  return "./res/values/strings_$shortLang.arb";
+}
+
+List<String> getMissingKeysInArbFile(String fileName, Iterable<String> langKeys) {
+  final file = File(fileName);
+  final arbObj = readArbFile(file);
+  final results = <String>[];
+
+  for (var langKey in langKeys) {
+    if (!arbObj.containsKey(langKey)) {
+      results.add(langKey);
+    }
+  }
+
+  return results;
+}
diff --git a/tool/utils/translation/translation_constants.dart b/tool/utils/translation/translation_constants.dart
new file mode 100644
index 000000000..6563feb32
--- /dev/null
+++ b/tool/utils/translation/translation_constants.dart
@@ -0,0 +1,6 @@
+const defaultLang = "en";
+const langs = [
+  "ar", "bg", "cs", "de", "en", "es", "fr", "ha", "hi", "hr", "id", "it",
+  "ja", "ko", "my", "nl", "pl", "pt", "ru", "th", "tr", "uk", "ur", "yo",
+  "zh-cn" // zh, but Google Translate uses zh-cn for Chinese (Simplified)
+];
diff --git a/tool/utils/translation/translation_utils.dart b/tool/utils/translation/translation_utils.dart
new file mode 100644
index 000000000..a37838b91
--- /dev/null
+++ b/tool/utils/translation/translation_utils.dart
@@ -0,0 +1,37 @@
+import 'package:translator/translator.dart';
+
+import 'arb_file_utils.dart';
+import 'translation_constants.dart';
+
+final translator = GoogleTranslator();
+
+Future<void> appendTranslation(String lang, String key, String text) async {
+  final fileName = getArbFileName(lang);
+  final translation = await getTranslation(text, lang);
+
+  appendStringToArbFile(fileName, key, translation);
+}
+
+Future<void> appendTranslations(String lang, Map<String, String> defaults) async {
+  final fileName = getArbFileName(lang);
+  final translations = <String, String>{};
+
+  for (var key in defaults.keys) {
+    final value = defaults[key]!;
+
+    if (value.contains("{")) continue;
+    final translation = await getTranslation(value, lang);
+
+    translations[key] = translation;
+  }
+
+  print(translations);
+
+  appendStringsToArbFile(fileName, translations);
+}
+
+Future<String> getTranslation(String text, String lang) async {
+  if (lang == defaultLang) return text;
+  return (await translator.translate(text, from: defaultLang, to: lang)).text;
+}
+