From f072e79bb6ca3f0c9ef65607509d4839d1c4d832 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Tue, 27 Aug 2024 20:49:12 +0300
Subject: [PATCH 1/4] V4.19.5 v1.16.5 (#1654)

* some not enough enhancements for sync status

* update app versions

* minor fix
---
 assets/text/Monerocom_Release_Notes.txt |  5 ++---
 assets/text/Release_Notes.txt           |  7 ++++---
 cw_bitcoin/lib/electrum.dart            | 12 +-----------
 cw_bitcoin/lib/electrum_wallet.dart     | 10 ++++++----
 cw_monero/lib/monero_wallet.dart        |  4 +---
 lib/reactions/check_connection.dart     |  4 +++-
 lib/utils/exception_handler.dart        |  1 -
 scripts/android/app_env.sh              |  8 ++++----
 scripts/ios/app_env.sh                  |  8 ++++----
 scripts/linux/app_env.sh                |  4 ++--
 scripts/macos/app_env.sh                |  8 ++++----
 scripts/windows/build_exe_installer.iss |  2 +-
 tool/configure.dart                     |  2 +-
 13 files changed, 33 insertions(+), 42 deletions(-)

diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt
index 11a3ad803..fec1485ac 100644
--- a/assets/text/Monerocom_Release_Notes.txt
+++ b/assets/text/Monerocom_Release_Notes.txt
@@ -1,3 +1,2 @@
-Scan and verify messages
-Synchronization enhancements
-Bug fixes
\ No newline at end of file
+Enhance auto-address generation for Monero
+Bug fixes and enhancements
\ No newline at end of file
diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt
index 11a3ad803..4e8a79fc1 100644
--- a/assets/text/Release_Notes.txt
+++ b/assets/text/Release_Notes.txt
@@ -1,3 +1,4 @@
-Scan and verify messages
-Synchronization enhancements
-Bug fixes
\ No newline at end of file
+Enable BIP39 by default for wallet creation also on Bitcoin/Litecoin (Electrum seed type is still accessible through advanced settings page)
+Improve fee calculation for Bitcoin to protect against overpaying or underpaying
+Enhance auto-address generation for Monero
+Bug fixes and enhancements
\ No newline at end of file
diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart
index 6ac8edd1a..bc630a4e1 100644
--- a/cw_bitcoin/lib/electrum.dart
+++ b/cw_bitcoin/lib/electrum.dart
@@ -107,16 +107,9 @@ class ElectrumClient {
         }
       },
       onError: (Object error) {
-        socket = null;
         final errorMsg = error.toString();
         print(errorMsg);
         unterminatedString = '';
-
-        final currentHost = socket?.address.host;
-        final isErrorForCurrentHost = errorMsg.contains(" ${currentHost} ");
-
-        if (currentHost != null && isErrorForCurrentHost)
-          _setConnectionStatus(ConnectionStatus.failed);
       },
       onDone: () {
         unterminatedString = '';
@@ -436,7 +429,6 @@ class ElectrumClient {
       {required String id, required String method, List<Object> params = const []}) {
     try {
       if (socket == null) {
-        _setConnectionStatus(ConnectionStatus.failed);
         return null;
       }
       final subscription = BehaviorSubject<T>();
@@ -453,7 +445,6 @@ class ElectrumClient {
   Future<dynamic> call(
       {required String method, List<Object> params = const [], Function(int)? idCallback}) async {
     if (socket == null) {
-      _setConnectionStatus(ConnectionStatus.failed);
       return null;
     }
     final completer = Completer<dynamic>();
@@ -467,10 +458,9 @@ class ElectrumClient {
   }
 
   Future<dynamic> callWithTimeout(
-      {required String method, List<Object> params = const [], int timeout = 4000}) async {
+      {required String method, List<Object> params = const [], int timeout = 5000}) async {
     try {
       if (socket == null) {
-        _setConnectionStatus(ConnectionStatus.failed);
         return null;
       }
       final completer = Completer<dynamic>();
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index be4cee4d8..73ae7c38f 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -276,7 +276,6 @@ abstract class ElectrumWalletBase
   Future<Isolate>? _isolate;
 
   void Function(FlutterErrorDetails)? _onError;
-  Timer? _reconnectTimer;
   Timer? _autoSaveTimer;
   Timer? _updateFeeRateTimer;
   static const int _autoSaveInterval = 1;
@@ -429,6 +428,10 @@ abstract class ElectrumWalletBase
   @override
   Future<void> startSync() async {
     try {
+      if (syncStatus is SyncronizingSyncStatus) {
+        return;
+      }
+
       syncStatus = SyncronizingSyncStatus();
 
       if (hasSilentPaymentsScanning) {
@@ -2055,9 +2058,8 @@ abstract class ElectrumWalletBase
 
       _isTryingToConnect = true;
 
-      _reconnectTimer?.cancel();
-      _reconnectTimer = Timer(Duration(seconds: 10), () {
-        if (this.syncStatus is! SyncedSyncStatus && this.syncStatus is! SyncedTipSyncStatus) {
+      Timer(Duration(seconds: 10), () {
+        if (this.syncStatus is NotConnectedSyncStatus || this.syncStatus is LostConnectionSyncStatus) {
           this.electrumClient.connectToUri(
                 node!.uri,
                 useSSL: node!.useSSL ?? false,
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index 483ee8868..8dc3fdf86 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -13,11 +13,9 @@ 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_direction.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';
@@ -88,7 +86,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
     reaction((_) => isEnabledAutoGenerateSubaddress, (bool enabled) {
       _updateSubAddress(enabled, account: walletAddresses.account);
     });
-    reaction((_) => transactionHistory, (__) {
+    _onTxHistoryChangeReaction = reaction((_) => transactionHistory, (__) {
       _updateSubAddress(isEnabledAutoGenerateSubaddress, account: walletAddresses.account);
     });
   }
diff --git a/lib/reactions/check_connection.dart b/lib/reactions/check_connection.dart
index 3252797dd..812fa9fcd 100644
--- a/lib/reactions/check_connection.dart
+++ b/lib/reactions/check_connection.dart
@@ -24,7 +24,9 @@ void startCheckConnectionReaction(WalletBase wallet, SettingsStore settingsStore
         return;
       }
 
-      if (wallet.syncStatus is LostConnectionSyncStatus || wallet.syncStatus is FailedSyncStatus) {
+      if (wallet.type != WalletType.bitcoin &&
+          (wallet.syncStatus is LostConnectionSyncStatus ||
+              wallet.syncStatus is FailedSyncStatus)) {
         final alive = await settingsStore.getCurrentNode(wallet.type).requestNode();
 
         if (alive) {
diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart
index 8fc8a8c0e..dd58d3e56 100644
--- a/lib/utils/exception_handler.dart
+++ b/lib/utils/exception_handler.dart
@@ -172,7 +172,6 @@ class ExceptionHandler {
     "Error while launching http",
     "OS Error: Network is unreachable",
     "ClientException: Write failed, uri=http",
-    "Connection terminated during handshake",
     "Corrupted wallets seeds",
     "bad_alloc",
     "does not correspond",
diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index 324d2d2ae..59919dcf8 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
 APP_ANDROID_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.16.4"
-MONERO_COM_BUILD_NUMBER=98
+MONERO_COM_VERSION="1.16.5"
+MONERO_COM_BUILD_NUMBER=99
 MONERO_COM_BUNDLE_ID="com.monero.app"
 MONERO_COM_PACKAGE="com.monero.app"
 MONERO_COM_SCHEME="monero.com"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.19.4"
-CAKEWALLET_BUILD_NUMBER=225
+CAKEWALLET_VERSION="4.19.5"
+CAKEWALLET_BUILD_NUMBER=226
 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
 CAKEWALLET_SCHEME="cakewallet"
diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh
index 1405f7939..70530f4e6 100644
--- a/scripts/ios/app_env.sh
+++ b/scripts/ios/app_env.sh
@@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
 APP_IOS_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.16.4"
-MONERO_COM_BUILD_NUMBER=96
+MONERO_COM_VERSION="1.16.5"
+MONERO_COM_BUILD_NUMBER=97
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.19.4"
-CAKEWALLET_BUILD_NUMBER=263
+CAKEWALLET_VERSION="4.19.5"
+CAKEWALLET_BUILD_NUMBER=264
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 HAVEN_NAME="Haven"
diff --git a/scripts/linux/app_env.sh b/scripts/linux/app_env.sh
index bc2965193..7f1b11f3f 100755
--- a/scripts/linux/app_env.sh
+++ b/scripts/linux/app_env.sh
@@ -14,8 +14,8 @@ if [ -n "$1" ]; then
 fi
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="1.9.4"
-CAKEWALLET_BUILD_NUMBER=31
+CAKEWALLET_VERSION="1.9.5"
+CAKEWALLET_BUILD_NUMBER=32
 
 if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
     echo "Wrong app type."
diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh
index 342831d65..165feafe1 100755
--- a/scripts/macos/app_env.sh
+++ b/scripts/macos/app_env.sh
@@ -16,13 +16,13 @@ if [ -n "$1" ]; then
 fi
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.6.4"
-MONERO_COM_BUILD_NUMBER=28
+MONERO_COM_VERSION="1.6.5"
+MONERO_COM_BUILD_NUMBER=30
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="1.12.4"
-CAKEWALLET_BUILD_NUMBER=85
+CAKEWALLET_VERSION="1.12.5"
+CAKEWALLET_BUILD_NUMBER=86
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then
diff --git a/scripts/windows/build_exe_installer.iss b/scripts/windows/build_exe_installer.iss
index 4d7838723..bb13f49ef 100644
--- a/scripts/windows/build_exe_installer.iss
+++ b/scripts/windows/build_exe_installer.iss
@@ -1,5 +1,5 @@
 #define MyAppName "Cake Wallet"
-#define MyAppVersion "0.0.5"
+#define MyAppVersion "0.0.6"
 #define MyAppPublisher "Cake Labs LLC"
 #define MyAppURL "https://cakewallet.com/"
 #define MyAppExeName "CakeWallet.exe"
diff --git a/tool/configure.dart b/tool/configure.dart
index b3194c4c8..1d2166ed6 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -79,7 +79,6 @@ import 'dart:typed_data';
 import 'package:bitcoin_base/bitcoin_base.dart';
 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
 import 'package:cake_wallet/view_model/send/output.dart';
-import 'package:cw_bitcoin/electrum_transaction_info.dart';
 import 'package:cw_core/hardware/hardware_account_data.dart';
 import 'package:cw_core/node.dart';
 import 'package:cw_core/output_info.dart';
@@ -102,6 +101,7 @@ import 'package:bip39/bip39.dart' as bip39;
 import 'package:cw_bitcoin/utils.dart';
 import 'package:cw_bitcoin/electrum_derivations.dart';
 import 'package:cw_bitcoin/electrum.dart';
+import 'package:cw_bitcoin/electrum_transaction_info.dart';
 import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
 import 'package:cw_bitcoin/bitcoin_receive_page_option.dart';
 import 'package:cw_bitcoin/bitcoin_wallet.dart';

From 82f64a42642516d1abed58c12be4018129c6e813 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Thu, 29 Aug 2024 00:52:11 +0300
Subject: [PATCH 2/4] revert subaddress fix (#1656)

add show/hide passphrase
---
 cw_monero/lib/api/transaction_history.dart    | 27 ++--------
 cw_monero/lib/monero_subaddress_list.dart     |  9 ++--
 cw_monero/lib/monero_wallet.dart              |  5 --
 cw_monero/lib/monero_wallet_addresses.dart    | 20 --------
 cw_wownero/lib/api/transaction_history.dart   | 23 ++-------
 cw_wownero/lib/wownero_subaddress_list.dart   |  4 --
 cw_wownero/lib/wownero_wallet.dart            |  6 ---
 cw_wownero/lib/wownero_wallet_addresses.dart  | 18 -------
 .../advanced_privacy_settings_page.dart       | 51 +++++++++++--------
 scripts/android/app_env.sh                    |  4 +-
 scripts/ios/app_env.sh                        |  4 +-
 scripts/linux/app_env.sh                      |  2 +-
 scripts/macos/app_env.sh                      |  4 +-
 13 files changed, 51 insertions(+), 126 deletions(-)

diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart
index 1f00b082f..b416e1b4e 100644
--- a/cw_monero/lib/api/transaction_history.dart
+++ b/cw_monero/lib/api/transaction_history.dart
@@ -45,8 +45,6 @@ List<Transaction> getAllTransactions() {
             confirmations: 0,
             blockheight: 0,
             accountIndex: i,
-            addressIndex: 0,
-            addressIndexList: [0],
             paymentId: "",
             amount: fullBalance - availBalance,
             isSpend: false,
@@ -247,30 +245,19 @@ Future<PendingTransactionDescription> createTransactionMultDest(
 
 class Transaction {
   final String displayLabel;
-  String get subaddressLabel => monero.Wallet_getSubaddressLabel(
+  String subaddressLabel = monero.Wallet_getSubaddressLabel(wptr!, accountIndex: 0, addressIndex: 0);
+  late final String address = monero.Wallet_address(
     wptr!,
-    accountIndex: accountIndex,
-    addressIndex: addressIndex,
+    accountIndex: 0,
+    addressIndex: 0,
   );
-  String get address => monero.Wallet_address(
-    wptr!,
-    accountIndex: accountIndex,
-    addressIndex: addressIndex,
-  );
-  List<String> get addressList => List.generate(addressIndexList.length, (index) =>
-    monero.Wallet_address(
-      wptr!,
-      accountIndex: accountIndex,
-      addressIndex: addressIndexList[index],
-    ));
   final String description;
   final int fee;
   final int confirmations;
   late final bool isPending = confirmations < 10;
   final int blockheight;
-  final int addressIndex;
+  final int addressIndex = 0;
   final int accountIndex;
-  final List<int> addressIndexList;
   final String paymentId;
   final int amount;
   final bool isSpend;
@@ -316,8 +303,6 @@ class Transaction {
         amount = monero.TransactionInfo_amount(txInfo),
         paymentId = monero.TransactionInfo_paymentId(txInfo),
         accountIndex = monero.TransactionInfo_subaddrAccount(txInfo),
-        addressIndex = int.tryParse(monero.TransactionInfo_subaddrIndex(txInfo).split(", ")[0]) ?? 0,
-        addressIndexList = monero.TransactionInfo_subaddrIndex(txInfo).split(", ").map((e) => int.tryParse(e) ?? 0).toList(),
         blockheight = monero.TransactionInfo_blockHeight(txInfo),
         confirmations = monero.TransactionInfo_confirmations(txInfo),
         fee = monero.TransactionInfo_fee(txInfo),
@@ -331,8 +316,6 @@ class Transaction {
     required this.confirmations,
     required this.blockheight,
     required this.accountIndex,
-    required this.addressIndexList,
-    required this.addressIndex,
     required this.paymentId,
     required this.amount,
     required this.isSpend,
diff --git a/cw_monero/lib/monero_subaddress_list.dart b/cw_monero/lib/monero_subaddress_list.dart
index fe85bef3b..c35afb282 100644
--- a/cw_monero/lib/monero_subaddress_list.dart
+++ b/cw_monero/lib/monero_subaddress_list.dart
@@ -1,7 +1,6 @@
 import 'package:cw_core/subaddress.dart';
 import 'package:cw_monero/api/coins_info.dart';
 import 'package:cw_monero/api/subaddress_list.dart' as subaddress_list;
-import 'package:cw_monero/api/wallet.dart';
 import 'package:flutter/services.dart';
 import 'package:mobx/mobx.dart';
 
@@ -104,9 +103,6 @@ abstract class MoneroSubaddressListBase with Store {
     required List<String> usedAddresses,
   }) async {
     _usedAddresses.addAll(usedAddresses);
-    final _all = _usedAddresses.toSet().toList();
-    _usedAddresses.clear();
-    _usedAddresses.addAll(_all);
     if (_isUpdating) {
       return;
     }
@@ -128,7 +124,7 @@ abstract class MoneroSubaddressListBase with Store {
   Future<List<Subaddress>> _getAllUnusedAddresses(
       {required int accountIndex, required String label}) async {
     final allAddresses = subaddress_list.getAllSubaddresses();
-    if (allAddresses.isEmpty || _usedAddresses.contains(allAddresses.first.address)) {
+    if (allAddresses.isEmpty || _usedAddresses.contains(allAddresses.last)) {
       final isAddressUnused = await _newSubaddress(accountIndex: accountIndex, label: label);
       if (!isAddressUnused) {
         return await _getAllUnusedAddresses(accountIndex: accountIndex, label: label);
@@ -147,7 +143,8 @@ abstract class MoneroSubaddressListBase with Store {
                     label.toLowerCase() == 'Primary account'.toLowerCase()
                 ? 'Primary address'
                 : label);
-      }).toList().reversed.toList();
+      })
+        .toList();
   }
 
   Future<bool> _newSubaddress({required int accountIndex, required String label}) async {
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index 8dc3fdf86..8773d694d 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -86,9 +86,6 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
     reaction((_) => isEnabledAutoGenerateSubaddress, (bool enabled) {
       _updateSubAddress(enabled, account: walletAddresses.account);
     });
-    _onTxHistoryChangeReaction = reaction((_) => transactionHistory, (__) {
-      _updateSubAddress(isEnabledAutoGenerateSubaddress, account: walletAddresses.account);
-    });
   }
 
   static const int _autoSaveInterval = 30;
@@ -131,7 +128,6 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
 
   monero_wallet.SyncListener? _listener;
   ReactionDisposer? _onAccountChangeReaction;
-  ReactionDisposer? _onTxHistoryChangeReaction;
   bool _isTransactionUpdating;
   bool _hasSyncAfterStartup;
   Timer? _autoSaveTimer;
@@ -171,7 +167,6 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
   void close() async {
     _listener?.stop();
     _onAccountChangeReaction?.reaction.dispose();
-    _onTxHistoryChangeReaction?.reaction.dispose();
     _autoSaveTimer?.cancel();
   }
 
diff --git a/cw_monero/lib/monero_wallet_addresses.dart b/cw_monero/lib/monero_wallet_addresses.dart
index 41e22aef2..d4f22e46f 100644
--- a/cw_monero/lib/monero_wallet_addresses.dart
+++ b/cw_monero/lib/monero_wallet_addresses.dart
@@ -3,7 +3,6 @@ import 'package:cw_core/address_info.dart';
 import 'package:cw_core/subaddress.dart';
 import 'package:cw_core/wallet_addresses.dart';
 import 'package:cw_core/wallet_info.dart';
-import 'package:cw_monero/api/transaction_history.dart';
 import 'package:cw_monero/api/wallet.dart';
 import 'package:cw_monero/monero_account_list.dart';
 import 'package:cw_monero/monero_subaddress_list.dart';
@@ -38,25 +37,6 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
 
   MoneroAccountList accountList;
 
-  @override
-  Set<String> get usedAddresses {
-    final txs = getAllTransactions();
-    final adds = _originalUsedAddresses.toList();
-    for (var i = 0; i < txs.length; i++) {
-      for (var j = 0; j < txs[i].addressList.length; j++) {
-        adds.add(txs[i].addressList[j]);
-      }
-    }
-    return adds.toSet();
-  }
-
-  Set<String> _originalUsedAddresses = Set();
-
-  @override
-  set usedAddresses(Set<String> _usedAddresses) {
-    _originalUsedAddresses = _usedAddresses;
-  }
-
   @override
   Future<void> init() async {
     accountList.update();
diff --git a/cw_wownero/lib/api/transaction_history.dart b/cw_wownero/lib/api/transaction_history.dart
index 020c47df6..a1e1e3c9b 100644
--- a/cw_wownero/lib/api/transaction_history.dart
+++ b/cw_wownero/lib/api/transaction_history.dart
@@ -45,8 +45,6 @@ List<Transaction> getAllTransactions() {
             confirmations: 0,
             blockheight: 0,
             accountIndex: i,
-            addressIndex: 0,
-            addressIndexList: [0],
             paymentId: "",
             amount: fullBalance - availBalance,
             isSpend: false,
@@ -245,26 +243,19 @@ Future<PendingTransactionDescription> createTransactionMultDest(
 
 class Transaction {
   final String displayLabel;
-  String get subaddressLabel => wownero.Wallet_getSubaddressLabel(wptr!, accountIndex: 0, addressIndex: 0);
-  String get address => wownero.Wallet_address(
+  String subaddressLabel = wownero.Wallet_getSubaddressLabel(wptr!, accountIndex: 0, addressIndex: 0);
+  late final String address = wownero.Wallet_address(
     wptr!,
-    accountIndex: accountIndex,
-    addressIndex: addressIndex,
+    accountIndex: 0,
+    addressIndex: 0,
   );
-  List<String> get addressList => List.generate(addressIndexList.length, (index) =>
-    wownero.Wallet_address(
-      wptr!,
-      accountIndex: accountIndex,
-      addressIndex: addressIndexList[index],
-    ));
   final String description;
   final int fee;
   final int confirmations;
   late final bool isPending = confirmations < 3;
   final int blockheight;
-  final int addressIndex;
+  final int addressIndex = 0;
   final int accountIndex;
-  final List<int> addressIndexList;
   final String paymentId;
   final int amount;
   final bool isSpend;
@@ -310,8 +301,6 @@ class Transaction {
         amount = wownero.TransactionInfo_amount(txInfo),
         paymentId = wownero.TransactionInfo_paymentId(txInfo),
         accountIndex = wownero.TransactionInfo_subaddrAccount(txInfo),
-        addressIndex = int.tryParse(wownero.TransactionInfo_subaddrIndex(txInfo).split(", ")[0]) ?? 0,
-        addressIndexList = wownero.TransactionInfo_subaddrIndex(txInfo).split(", ").map((e) => int.tryParse(e) ?? 0).toList(),
         blockheight = wownero.TransactionInfo_blockHeight(txInfo),
         confirmations = wownero.TransactionInfo_confirmations(txInfo),
         fee = wownero.TransactionInfo_fee(txInfo),
@@ -325,8 +314,6 @@ class Transaction {
     required this.confirmations,
     required this.blockheight,
     required this.accountIndex,
-    required this.addressIndex,
-    required this.addressIndexList,
     required this.paymentId,
     required this.amount,
     required this.isSpend,
diff --git a/cw_wownero/lib/wownero_subaddress_list.dart b/cw_wownero/lib/wownero_subaddress_list.dart
index 5c026cc86..61fd09ef9 100644
--- a/cw_wownero/lib/wownero_subaddress_list.dart
+++ b/cw_wownero/lib/wownero_subaddress_list.dart
@@ -1,7 +1,6 @@
 import 'package:cw_core/subaddress.dart';
 import 'package:cw_wownero/api/coins_info.dart';
 import 'package:cw_wownero/api/subaddress_list.dart' as subaddress_list;
-import 'package:cw_wownero/api/wallet.dart';
 import 'package:flutter/services.dart';
 import 'package:mobx/mobx.dart';
 
@@ -104,9 +103,6 @@ abstract class WowneroSubaddressListBase with Store {
     required List<String> usedAddresses,
   }) async {
     _usedAddresses.addAll(usedAddresses);
-    final _all = _usedAddresses.toSet().toList();
-    _usedAddresses.clear();
-    _usedAddresses.addAll(_all);
     if (_isUpdating) {
       return;
     }
diff --git a/cw_wownero/lib/wownero_wallet.dart b/cw_wownero/lib/wownero_wallet.dart
index ab7691dd6..c3f4bcb69 100644
--- a/cw_wownero/lib/wownero_wallet.dart
+++ b/cw_wownero/lib/wownero_wallet.dart
@@ -82,10 +82,6 @@ abstract class WowneroWalletBase
     reaction((_) => isEnabledAutoGenerateSubaddress, (bool enabled) {
       _updateSubAddress(enabled, account: walletAddresses.account);
     });
-
-    _onTxHistoryChangeReaction = reaction((_) => transactionHistory, (__) {
-      _updateSubAddress(isEnabledAutoGenerateSubaddress, account: walletAddresses.account);
-    });
   }
 
   static const int _autoSaveInterval = 30;
@@ -127,7 +123,6 @@ abstract class WowneroWalletBase
 
   wownero_wallet.SyncListener? _listener;
   ReactionDisposer? _onAccountChangeReaction;
-  ReactionDisposer? _onTxHistoryChangeReaction;
   bool _isTransactionUpdating;
   bool _hasSyncAfterStartup;
   Timer? _autoSaveTimer;
@@ -163,7 +158,6 @@ abstract class WowneroWalletBase
   void close() async {
     _listener?.stop();
     _onAccountChangeReaction?.reaction.dispose();
-    _onTxHistoryChangeReaction?.reaction.dispose();
     _autoSaveTimer?.cancel();
   }
 
diff --git a/cw_wownero/lib/wownero_wallet_addresses.dart b/cw_wownero/lib/wownero_wallet_addresses.dart
index b36c0e9ec..9eeb182eb 100644
--- a/cw_wownero/lib/wownero_wallet_addresses.dart
+++ b/cw_wownero/lib/wownero_wallet_addresses.dart
@@ -3,7 +3,6 @@ import 'package:cw_core/address_info.dart';
 import 'package:cw_core/subaddress.dart';
 import 'package:cw_core/wallet_addresses.dart';
 import 'package:cw_core/wallet_info.dart';
-import 'package:cw_wownero/api/transaction_history.dart';
 import 'package:cw_wownero/api/wallet.dart';
 import 'package:cw_wownero/wownero_account_list.dart';
 import 'package:cw_wownero/wownero_subaddress_list.dart';
@@ -37,24 +36,7 @@ abstract class WowneroWalletAddressesBase extends WalletAddresses with Store {
   WowneroSubaddressList subaddressList;
 
   WowneroAccountList accountList;
-  @override
-  Set<String> get usedAddresses {
-    final txs = getAllTransactions();
-    final adds = _originalUsedAddresses.toList();
-    for (var i = 0; i < txs.length; i++) {
-      for (var j = 0; j < txs[i].addressList.length; j++) {
-        adds.add(txs[i].addressList[j]);
-      }
-    }
-    return adds.toSet();
-  }
 
-  Set<String> _originalUsedAddresses = Set();
-
-  @override
-  set usedAddresses(Set<String> _usedAddresses) {
-    _originalUsedAddresses = _usedAddresses;
-  }
   @override
   Future<void> init() async {
     accountList.update();
diff --git a/lib/src/screens/new_wallet/advanced_privacy_settings_page.dart b/lib/src/screens/new_wallet/advanced_privacy_settings_page.dart
index ff8ec3dd2..7173778cc 100644
--- a/lib/src/screens/new_wallet/advanced_privacy_settings_page.dart
+++ b/lib/src/screens/new_wallet/advanced_privacy_settings_page.dart
@@ -70,6 +70,8 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
   final _formKey = GlobalKey<FormState>();
   bool? testnetValue;
 
+  bool obscurePassphrase = true;
+
   @override
   void initState() {
     passphraseController.text = widget.seedTypeViewModel.passphrase ?? '';
@@ -138,27 +140,36 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
                 );
               }),
             if (!widget.isFromRestore) ...[
-                Observer(builder: (_) {
-              if (widget.privacySettingsViewModel.hasSeedPhraseLengthOption)
-                return SettingsPickerCell<SeedPhraseLength>(
-                  title: S.current.seed_phrase_length,
-                  items: SeedPhraseLength.values,
-                  selectedItem: widget.privacySettingsViewModel.seedPhraseLength,
-                  onItemSelected: (SeedPhraseLength length) {
-                    widget.privacySettingsViewModel.setSeedPhraseLength(length);
-                  },
-                );
-              return Container();
-            }),
-            if (widget.privacySettingsViewModel.hasPassphraseOption)
-              Padding(
-                padding: EdgeInsets.all(24),
-                child: BaseTextFormField(
-                  hintText: S.current.passphrase,
-                  controller: passphraseController,
-                  obscureText: true,
+              Observer(builder: (_) {
+                if (widget.privacySettingsViewModel.hasSeedPhraseLengthOption)
+                  return SettingsPickerCell<SeedPhraseLength>(
+                    title: S.current.seed_phrase_length,
+                    items: SeedPhraseLength.values,
+                    selectedItem: widget.privacySettingsViewModel.seedPhraseLength,
+                    onItemSelected: (SeedPhraseLength length) {
+                      widget.privacySettingsViewModel.setSeedPhraseLength(length);
+                    },
+                  );
+                return Container();
+              }),
+              if (widget.privacySettingsViewModel.hasPassphraseOption)
+                Padding(
+                  padding: EdgeInsets.all(24),
+                  child: BaseTextFormField(
+                    hintText: S.current.passphrase,
+                    controller: passphraseController,
+                    obscureText: obscurePassphrase,
+                    suffixIcon: GestureDetector(
+                      onTap: () => setState(() {
+                        obscurePassphrase = !obscurePassphrase;
+                      }),
+                      child: Icon(
+                        Icons.remove_red_eye,
+                        color: obscurePassphrase ? Colors.black54 : Colors.black26,
+                      ),
+                    ),
+                  ),
                 ),
-              ),
             ],
             Observer(builder: (_) {
               return Column(
diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index 59919dcf8..a60077e82 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -16,14 +16,14 @@ APP_ANDROID_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
 MONERO_COM_VERSION="1.16.5"
-MONERO_COM_BUILD_NUMBER=99
+MONERO_COM_BUILD_NUMBER=100
 MONERO_COM_BUNDLE_ID="com.monero.app"
 MONERO_COM_PACKAGE="com.monero.app"
 MONERO_COM_SCHEME="monero.com"
 
 CAKEWALLET_NAME="Cake Wallet"
 CAKEWALLET_VERSION="4.19.5"
-CAKEWALLET_BUILD_NUMBER=226
+CAKEWALLET_BUILD_NUMBER=227
 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
 CAKEWALLET_SCHEME="cakewallet"
diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh
index 70530f4e6..9df4b685e 100644
--- a/scripts/ios/app_env.sh
+++ b/scripts/ios/app_env.sh
@@ -14,12 +14,12 @@ APP_IOS_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
 MONERO_COM_VERSION="1.16.5"
-MONERO_COM_BUILD_NUMBER=97
+MONERO_COM_BUILD_NUMBER=98
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
 CAKEWALLET_VERSION="4.19.5"
-CAKEWALLET_BUILD_NUMBER=264
+CAKEWALLET_BUILD_NUMBER=266
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 HAVEN_NAME="Haven"
diff --git a/scripts/linux/app_env.sh b/scripts/linux/app_env.sh
index 7f1b11f3f..1c89c6e8a 100755
--- a/scripts/linux/app_env.sh
+++ b/scripts/linux/app_env.sh
@@ -15,7 +15,7 @@ fi
 
 CAKEWALLET_NAME="Cake Wallet"
 CAKEWALLET_VERSION="1.9.5"
-CAKEWALLET_BUILD_NUMBER=32
+CAKEWALLET_BUILD_NUMBER=33
 
 if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
     echo "Wrong app type."
diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh
index 165feafe1..a6afac2cb 100755
--- a/scripts/macos/app_env.sh
+++ b/scripts/macos/app_env.sh
@@ -17,12 +17,12 @@ fi
 
 MONERO_COM_NAME="Monero.com"
 MONERO_COM_VERSION="1.6.5"
-MONERO_COM_BUILD_NUMBER=30
+MONERO_COM_BUILD_NUMBER=31
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
 CAKEWALLET_VERSION="1.12.5"
-CAKEWALLET_BUILD_NUMBER=86
+CAKEWALLET_BUILD_NUMBER=88
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then

From c17f167266185b57822444752817f9ec38adfffb Mon Sep 17 00:00:00 2001
From: Konstantin Ullrich <konstantinullrich12@gmail.com>
Date: Thu, 29 Aug 2024 14:24:24 +0200
Subject: [PATCH 3/4] Fix windows build (#1658)

---
 windows/CMakeLists.txt | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt
index 7d1c03451..09bc8cfb6 100644
--- a/windows/CMakeLists.txt
+++ b/windows/CMakeLists.txt
@@ -87,18 +87,12 @@ install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/monero_c/release/monero/x8
 install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/monero_c/release/wownero/x86_64-w64-mingw32_libwallet2_api_c.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "wownero_libwallet2_api_c.dll"
   COMPONENT Runtime)
 
-install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/monero_c/release/monero/x86_64-w64-mingw32_libgcc_s_seh-1.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libgcc_s_seh-1.dll"
-  COMPONENT Runtime)
-
 install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/monero_c/release/monero/x86_64-w64-mingw32_libpolyseed.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libpolyseed.dll"
   COMPONENT Runtime)
 
 install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/monero_c/release/monero/x86_64-w64-mingw32_libssp-0.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libssp-0.dll"
   COMPONENT Runtime)
 
-install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/monero_c/release/monero/x86_64-w64-mingw32_libstdc++-6.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libstdc++-6.dll"
-  COMPONENT Runtime)
-
 install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/monero_c/release/monero/x86_64-w64-mingw32_libwinpthread-1.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libwinpthread-1.dll"
   COMPONENT Runtime)
 

From d1c85651f29811192c61133e094332bc4499296b Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Tue, 3 Sep 2024 11:05:55 -0700
Subject: [PATCH 4/4] improve mweb reliability

---
 cw_bitcoin/lib/litecoin_wallet.dart                | 14 ++++++++++++++
 cw_bitcoin/lib/litecoin_wallet_addresses.dart      |  7 +++++--
 cw_bitcoin/lib/litecoin_wallet_service.dart        |  6 +++---
 .../kotlin/com/cakewallet/mweb/CwMwebPlugin.kt     |  5 ++++-
 cw_mweb/ios/Classes/CwMwebPlugin.swift             |  1 +
 cw_mweb/lib/cw_mweb.dart                           |  2 ++
 6 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 3204e5cbd..b69ba59dd 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -443,6 +443,10 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   }
 
   Future<void> processMwebUtxos() async {
+    if (!mwebEnabled) {
+      return;
+    }
+
     int restoreHeight = walletInfo.restoreHeight;
     print("SCANNING FROM HEIGHT: $restoreHeight");
     final req = UtxosRequest(scanSecret: scanSecret, fromHeight: restoreHeight);
@@ -502,6 +506,10 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   }
 
   Future<void> checkMwebUtxosSpent() async {
+    if (!mwebEnabled) {
+      return;
+    }
+
     while ((await Future.wait(transactionHistory.transactions.values
             .where((tx) => tx.direction == TransactionDirection.outgoing && tx.isPending)
             .map(checkPendingTransaction)))
@@ -557,6 +565,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   }
 
   Future<bool> checkPendingTransaction(ElectrumTransactionInfo tx) async {
+    if (!mwebEnabled) return false;
     if (!tx.isPending) return false;
     final outputId = <String>[], target = <String>{};
     final isHash = RegExp(r'^[a-f0-9]{64}$').hasMatch;
@@ -755,6 +764,11 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
         vinOutpoints: vinOutpoints,
       );
     }
+
+    if (!mwebEnabled) {
+      throw Exception("MWEB is not enabled! can't calculate fee without starting the mweb server!");
+    }
+
     if (outputs.length == 1 && outputs[0].toOutput.amount == BigInt.zero) {
       outputs = [
         BitcoinScriptOutput(
diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
index 12140472c..7db9d7bae 100644
--- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
@@ -25,7 +25,10 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
     super.initialChangeAddressIndex,
   }) : super(walletInfo) {
     if (mwebEnabled) {
-      topUpMweb(0);
+      // give the server a few seconds to start up before trying to get the addresses:
+      Future.delayed(const Duration(seconds: 5), () async {
+        await topUpMweb(0);
+      });
     }
   }
 
@@ -39,9 +42,9 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
   List<String> mwebAddrs = [];
 
   Future<void> topUpMweb(int index) async {
+    final stub = await CwMweb.stub();
     while (mwebAddrs.length - index < 1000) {
       final length = mwebAddrs.length;
-      final stub = await CwMweb.stub();
       final resp = await stub.addresses(AddressRequest(
         fromIndex: length,
         toIndex: index + 1000,
diff --git a/cw_bitcoin/lib/litecoin_wallet_service.dart b/cw_bitcoin/lib/litecoin_wallet_service.dart
index 72efa41c7..da3602024 100644
--- a/cw_bitcoin/lib/litecoin_wallet_service.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_service.dart
@@ -150,9 +150,9 @@ class LitecoinWalletService extends WalletService<
   @override
   Future<LitecoinWallet> restoreFromSeed(BitcoinRestoreWalletFromSeedCredentials credentials,
       {bool? isTestnet}) async {
-    if (!validateMnemonic(credentials.mnemonic) && !bip39.validateMnemonic(credentials.mnemonic)) {
-      throw LitecoinMnemonicIsIncorrectException();
-    }
+    // if (!validateMnemonic(credentials.mnemonic) && !bip39.validateMnemonic(credentials.mnemonic)) {
+    //   throw LitecoinMnemonicIsIncorrectException();
+    // }
 
     final wallet = await LitecoinWalletBase.create(
       password: credentials.password!,
diff --git a/cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt b/cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt
index 2b366ad76..b1180dd4a 100644
--- a/cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt
+++ b/cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt
@@ -28,9 +28,12 @@ class CwMwebPlugin: FlutterPlugin, MethodCallHandler {
 
   override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
     if (call.method == "start") {
+      server?.stop()
       val dataDir = call.argument("dataDir") ?: ""
+      // server = server ?: Mwebd.newServer("", dataDir, "")
+      // port = port ?: server?.start(0)
       server = server ?: Mwebd.newServer("", dataDir, "")
-      port = port ?: server?.start(0)
+      port = server?.start(0)
       result.success(port)
     } else if (call.method == "stop") {
       server?.stop()
diff --git a/cw_mweb/ios/Classes/CwMwebPlugin.swift b/cw_mweb/ios/Classes/CwMwebPlugin.swift
index fff1283d8..ed08d6748 100644
--- a/cw_mweb/ios/Classes/CwMwebPlugin.swift
+++ b/cw_mweb/ios/Classes/CwMwebPlugin.swift
@@ -18,6 +18,7 @@ public class CwMwebPlugin: NSObject, FlutterPlugin {
         case "getPlatformVersion":
             result("iOS " + UIDevice.current.systemVersion)
         case "start":
+            stopServer()
             let args = call.arguments as? [String: String]
             let dataDir = args?["dataDir"]
             CwMwebPlugin.dataDir = dataDir
diff --git a/cw_mweb/lib/cw_mweb.dart b/cw_mweb/lib/cw_mweb.dart
index 98afc73dd..df3300379 100644
--- a/cw_mweb/lib/cw_mweb.dart
+++ b/cw_mweb/lib/cw_mweb.dart
@@ -1,3 +1,5 @@
+import 'dart:io';
+
 import 'package:grpc/grpc.dart';
 import 'package:path_provider/path_provider.dart';
 import 'cw_mweb_platform_interface.dart';