From bd93ba91f12c59fca9dba79fca8492cc7c35281f Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Fri, 24 Jan 2025 08:41:44 -0800
Subject: [PATCH] testing branch don't merge

---
 cw_bitcoin/lib/electrum_derivations.dart      |  55 +++--
 cw_bitcoin/lib/electrum_wallet.dart           |   8 +-
 cw_bitcoin/lib/electrum_wallet_addresses.dart |  16 +-
 cw_bitcoin/lib/litecoin_wallet_addresses.dart |  21 +-
 lib/bitcoin/cw_bitcoin.dart                   | 191 +++++++++++++-----
 lib/core/wallet_loading_service.dart          |  26 +--
 .../screens/restore/wallet_restore_page.dart  |   2 +-
 lib/utils/exception_handler.dart              | 109 ++++++++--
 .../unspent_coins_list_view_model.dart        |  11 +-
 lib/view_model/wallet_creation_vm.dart        |   4 +-
 10 files changed, 312 insertions(+), 131 deletions(-)

diff --git a/cw_bitcoin/lib/electrum_derivations.dart b/cw_bitcoin/lib/electrum_derivations.dart
index 81a3626d2..87e18a885 100644
--- a/cw_bitcoin/lib/electrum_derivations.dart
+++ b/cw_bitcoin/lib/electrum_derivations.dart
@@ -8,20 +8,26 @@ Map<DerivationType, List<DerivationInfo>> electrum_derivations = {
       description: "Electrum",
       scriptType: "p2wpkh",
     ),
+    DerivationInfo(
+      derivationType: DerivationType.electrum,
+      derivationPath: "m/1'",
+      description: "Electrum",
+      scriptType: "p2wpkh",
+    ),
   ],
   DerivationType.bip39: [
-    DerivationInfo(
-      derivationType: DerivationType.bip39,
-      derivationPath: "m/44'/0'/0'",
-      description: "Standard BIP44",
-      scriptType: "p2pkh",
-    ),
-    DerivationInfo(
-      derivationType: DerivationType.bip39,
-      derivationPath: "m/49'/0'/0'",
-      description: "Standard BIP49 compatibility segwit",
-      scriptType: "p2wpkh-p2sh",
-    ),
+    // DerivationInfo(
+    //   derivationType: DerivationType.bip39,
+    //   derivationPath: "m/44'/0'/0'",
+    //   description: "Standard BIP44",
+    //   scriptType: "p2pkh",
+    // ),
+    // DerivationInfo(
+    //   derivationType: DerivationType.bip39,
+    //   derivationPath: "m/49'/0'/0'",
+    //   description: "Standard BIP49 compatibility segwit",
+    //   scriptType: "p2wpkh-p2sh",
+    // ),
     DerivationInfo(
       derivationType: DerivationType.bip39,
       derivationPath: "m/84'/0'/0'",
@@ -34,21 +40,27 @@ Map<DerivationType, List<DerivationInfo>> electrum_derivations = {
       description: "Standard BIP86 Taproot",
       scriptType: "p2tr",
     ),
+    // DerivationInfo(
+    //   derivationType: DerivationType.bip39,
+    //   derivationPath: "m/0'",
+    //   description: "Non-standard legacy",
+    //   scriptType: "p2pkh",
+    // ),
+    // DerivationInfo(
+    //   derivationType: DerivationType.bip39,
+    //   derivationPath: "m/0'",
+    //   description: "Non-standard compatibility segwit",
+    //   scriptType: "p2wpkh-p2sh",
+    // ),
     DerivationInfo(
       derivationType: DerivationType.bip39,
       derivationPath: "m/0'",
-      description: "Non-standard legacy",
-      scriptType: "p2pkh",
+      description: "Non-standard native segwit",
+      scriptType: "p2wpkh",
     ),
     DerivationInfo(
       derivationType: DerivationType.bip39,
-      derivationPath: "m/0'",
-      description: "Non-standard compatibility segwit",
-      scriptType: "p2wpkh-p2sh",
-    ),
-    DerivationInfo(
-      derivationType: DerivationType.bip39,
-      derivationPath: "m/0'",
+      derivationPath: "m/1'",
       description: "Non-standard native segwit",
       scriptType: "p2wpkh",
     ),
@@ -106,6 +118,7 @@ Map<DerivationType, List<DerivationInfo>> electrum_derivations = {
       description: "Default Litecoin",
       scriptType: "p2wpkh",
     ),
+
   ],
 };
 
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 9a7e45d05..9a55aab89 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -990,6 +990,11 @@ abstract class ElectrumWalletBase
   @override
   Future<PendingTransaction> createTransaction(Object credentials) async {
     try {
+      _onError?.call(FlutterErrorDetails(
+        exception: "testing exception",
+        stack: StackTrace.current,
+        library: this.runtimeType.toString(),
+      ));
       // start by updating unspent coins
       await updateAllUnspents();
 
@@ -1365,7 +1370,7 @@ abstract class ElectrumWalletBase
     List<BitcoinUnspent> updatedUnspentCoins = [];
 
     final previousUnspentCoins = List<BitcoinUnspent>.from(unspentCoins.where((utxo) =>
-    utxo.bitcoinAddressRecord.type != SegwitAddresType.mweb &&
+        utxo.bitcoinAddressRecord.type != SegwitAddresType.mweb &&
         utxo.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord));
 
     if (hasSilentPaymentsScanning) {
@@ -1423,7 +1428,6 @@ abstract class ElectrumWalletBase
     required List<BitcoinUnspent> updatedUnspentCoins,
     required List<List<BitcoinUnspent>?> results,
   }) {
-
     if (failedCount == results.length) {
       printV("All UTXOs failed to fetch, falling back to previous UTXOs");
       return previousUnspentCoins;
diff --git a/cw_bitcoin/lib/electrum_wallet_addresses.dart b/cw_bitcoin/lib/electrum_wallet_addresses.dart
index 13a32c68c..c8655f5ac 100644
--- a/cw_bitcoin/lib/electrum_wallet_addresses.dart
+++ b/cw_bitcoin/lib/electrum_wallet_addresses.dart
@@ -47,7 +47,6 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
     List<BitcoinAddressRecord>? initialMwebAddresses,
     Bip32Slip10Secp256k1? masterHd,
     BitcoinAddressType? initialAddressPageType,
-
   })  : _addresses = ObservableList<BitcoinAddressRecord>.of((initialAddresses ?? []).toSet()),
         addressesByReceiveType =
             ObservableList<BaseBitcoinAddressRecord>.of((<BitcoinAddressRecord>[]).toSet()),
@@ -187,13 +186,13 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
       return;
     }
     try {
-    final addressRecord = _addresses.firstWhere(
-      (addressRecord) => addressRecord.address == addr,
-    );
+      final addressRecord = _addresses.firstWhere(
+        (addressRecord) => addressRecord.address == addr,
+      );
 
-    previousAddressRecord = addressRecord;
-    receiveAddresses.remove(addressRecord);
-    receiveAddresses.insert(0, addressRecord);
+      previousAddressRecord = addressRecord;
+      receiveAddresses.remove(addressRecord);
+      receiveAddresses.insert(0, addressRecord);
     } catch (e) {
       printV("ElectrumWalletAddressBase: set address ($addr): $e");
     }
@@ -274,7 +273,8 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
   }
 
   @action
-  Future<BitcoinAddressRecord> getChangeAddress({List<BitcoinUnspent>? inputs, List<BitcoinOutput>? outputs, bool isPegIn = false}) async {
+  Future<BitcoinAddressRecord> getChangeAddress(
+      {List<BitcoinUnspent>? inputs, List<BitcoinOutput>? outputs, bool isPegIn = false}) async {
     updateChangeAddresses();
 
     if (changeAddresses.isEmpty) {
diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
index afe3c75b8..27613b19d 100644
--- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
@@ -33,10 +33,10 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
     super.initialRegularAddressIndex,
     super.initialChangeAddressIndex,
   }) : super(walletInfo) {
-    for (int i = 0; i < mwebAddresses.length; i++) {
-      mwebAddrs.add(mwebAddresses[i].address);
-    }
-    printV("initialized with ${mwebAddrs.length} mweb addresses");
+    // for (int i = 0; i < mwebAddresses.length; i++) {
+    //   mwebAddrs.add(mwebAddresses[i].address);
+    // }
+    // printV("initialized with ${mwebAddrs.length} mweb addresses");
   }
 
   final Bip32Slip10Secp256k1? mwebHd;
@@ -62,6 +62,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
   }
 
   Future<void> ensureMwebAddressUpToIndexExists(int index) async {
+    return null;
     if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
       return null;
     }
@@ -127,9 +128,9 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
     required Bip32Slip10Secp256k1 hd,
     BitcoinAddressType? addressType,
   }) {
-    if (addressType == SegwitAddresType.mweb) {
-      return hd == sideHd ? mwebAddrs[0] : mwebAddrs[index + 1];
-    }
+    // if (addressType == SegwitAddresType.mweb) {
+    //   return hd == sideHd ? mwebAddrs[0] : mwebAddrs[index + 1];
+    // }
     return generateP2WPKHAddress(hd: hd, index: index, network: network);
   }
 
@@ -139,9 +140,9 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
     required Bip32Slip10Secp256k1 hd,
     BitcoinAddressType? addressType,
   }) async {
-    if (addressType == SegwitAddresType.mweb) {
-      await ensureMwebAddressUpToIndexExists(index);
-    }
+    // if (addressType == SegwitAddresType.mweb) {
+    //   await ensureMwebAddressUpToIndexExists(index);
+    // }
     return getAddress(index: index, hd: hd, addressType: addressType);
   }
 
diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart
index bf9ec0c4d..e5103a380 100644
--- a/lib/bitcoin/cw_bitcoin.dart
+++ b/lib/bitcoin/cw_bitcoin.dart
@@ -330,9 +330,9 @@ class CWBitcoin extends Bitcoin {
     List<DerivationInfo> list = [];
 
     List<DerivationType> types = await compareDerivationMethods(mnemonic: mnemonic, node: node);
-    if (types.length == 1 && types.first == DerivationType.electrum) {
-      return [getElectrumDerivations()[DerivationType.electrum]!.first];
-    }
+    // if (types.length == 1 && types.first == DerivationType.electrum) {
+    //   return [getElectrumDerivations()[DerivationType.electrum]!.first];
+    // }
 
     final electrumClient = ElectrumClient();
     await electrumClient.connectToUri(node.uri, useSSL: node.useSSL);
@@ -348,66 +348,149 @@ class CWBitcoin extends Bitcoin {
         break;
     }
 
-    for (DerivationType dType in electrum_derivations.keys) {
+    bool found = false;
+    print("types: $types");
+    for (DerivationType typ in types) {
+      if (found) {
+        break;
+      }
+
       late Uint8List seedBytes;
-      if (dType == DerivationType.electrum) {
+      // if (dType == DerivationType.electrum) {
+      //   seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
+      // } else if (dType == DerivationType.bip39) {
+      //   seedBytes = bip39.mnemonicToSeed(mnemonic, passphrase: passphrase ?? '');
+      // }
+
+      if (typ == DerivationType.electrum) {
         seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
-      } else if (dType == DerivationType.bip39) {
+      } else if (typ == DerivationType.bip39) {
         seedBytes = bip39.mnemonicToSeed(mnemonic, passphrase: passphrase ?? '');
       }
 
-      for (DerivationInfo dInfo in electrum_derivations[dType]!) {
-        try {
-          DerivationInfo dInfoCopy = DerivationInfo(
-            derivationType: dInfo.derivationType,
-            derivationPath: dInfo.derivationPath,
-            description: dInfo.description,
-            scriptType: dInfo.scriptType,
-          );
+      String addedPath = "";
+      List<String> addedPaths = [
+        "",
+        "/0",
+        "/1",
+        "/0/1",
+        "/1/0",
+        "/0/0",
+        "/1/1",
+        "/0/0/1",
+        "/1/1/0",
+        "/0'",
+        "/1'",
+        "/0'/0'",
+        "/1'/1'",
+        "/0'/0'/0'",
+        "/1'/1'/1'",
+        "/0'/0",
+        "/1'/1",
+        "/0'/0/0",
+        "/1'/1/1",
+        "/0'/0/1",
+        "/1'/1/0"
+      ];
+      for (String addedPath in addedPaths) {
+        if (found) {
+          print("found!!!!!!!!!!!");
+          break;
+        }
+        var dType = DerivationType.bip39;
+        for (DerivationInfo dInfo in electrum_derivations[dType]!) {
+          try {
+            DerivationInfo dInfoCopy = DerivationInfo(
+              derivationType: dInfo.derivationType,
+              derivationPath: dInfo.derivationPath,
+              description: dInfo.description,
+              scriptType: dInfo.scriptType,
+            );
 
-          String balancePath = dInfoCopy.derivationPath!;
-          int derivationDepth = _countCharOccurrences(balancePath, '/');
+            String balancePath = dInfoCopy.derivationPath!;
+            // int derivationDepth = _countCharOccurrences(balancePath, '/');
 
-          // for BIP44
-          if (derivationDepth == 3 || derivationDepth == 1) {
+            // for BIP44
+            // if (derivationDepth == 3 || derivationDepth == 1) {
             // we add "/0" so that we generate account 0
-            balancePath += "/0";
+            // balancePath += "/0";
+            // }
+
+            balancePath += addedPath;
+
+            final hd = Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath(balancePath)
+                as Bip32Slip10Secp256k1;
+            final sideHd = hd.childKey(Bip32KeyIndex(1));
+
+            print("searching: $typ : add: $addedPath : $balancePath");
+
+            // derive address at index 0:
+            String? address;
+            switch (dInfoCopy.scriptType) {
+              case "p2wpkh":
+                address = generateP2WPKHAddress(hd: hd, network: network, index: 0);
+                break;
+              case "p2pkh":
+                address = generateP2PKHAddress(hd: hd, network: network, index: 0);
+                break;
+              case "p2wpkh-p2sh":
+                address = generateP2SHAddress(hd: hd, network: network, index: 0);
+                break;
+              case "p2tr":
+                address = generateP2TRAddress(hd: hd, network: network, index: 0);
+                break;
+              default:
+                continue;
+            }
+
+            // check if it's the search address:
+            String searchAddress = "ltc1q8t38ltq733p3652sdxqufyet2s9dzdx79rutp7";
+            String searchAddress2 = "ltc1q2qpl43h8sldxtd2l66a7jzmncfgy0n7cl3clt6";
+
+            String searchAddress3 = "ltc1quwvyhz3678u6fgqqtummepqp4l45dl2swm5ksz";
+            String searchAddress4 = "ltc1qvhy3n52mektgnchl9qkdgmffs4yxkk3ejdvv5t";
+            String searchAddress5 = "ltc1qtrnqxc6tf2jfnj35x5dvsk93y6g0ndsn98rcg4";
+            String searchAddress6 = "ltc1q8t38ltq733p3652sdxqufyet2s9dzdx79rutp7";
+            List<String> searchAddresses = [
+              searchAddress,
+              searchAddress2,
+              searchAddress3,
+              searchAddress4,
+              searchAddress5,
+              searchAddress6
+            ];
+
+            for (var i = 0; i < 100; i++) {
+              String indexAddress = generateP2WPKHAddress(hd: hd, network: network, index: i);
+              String indexAddress2 = generateP2WPKHAddress(hd: sideHd, network: network, index: i);
+              if (searchAddresses.contains(indexAddress) || searchAddresses.contains(indexAddress2)) {
+                printV(
+                    "@@@@@@@@@@@@@@@@@@@@@ FOUND ADDRESS @ index: $i @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+                found = true;
+                break;
+              }
+              // if (i == 1000) {
+              //   printV("address: $indexAddress");
+              // }
+            }
+
+            if (found) {
+              break;
+            }
+
+            // final sh = BitcoinAddressUtils.scriptHash(address, network: network);
+            // final history = await electrumClient.getHistory(sh);
+
+            // final balance = await electrumClient.getBalance(sh);
+            // dInfoCopy.balance = balance.entries.firstOrNull?.value.toString() ?? "0";
+            // dInfoCopy.address = address;
+            // dInfoCopy.transactionsCount = history.length;
+
+            list.add(dInfoCopy);
+          } catch (e, s) {
+            printV("derivationInfoError: $e");
+            printV("derivationInfoStack: $s");
           }
-
-          final hd = Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath(balancePath)
-              as Bip32Slip10Secp256k1;
-
-          // derive address at index 0:
-          String? address;
-          switch (dInfoCopy.scriptType) {
-            case "p2wpkh":
-              address = generateP2WPKHAddress(hd: hd, network: network, index: 0);
-              break;
-            case "p2pkh":
-              address = generateP2PKHAddress(hd: hd, network: network, index: 0);
-              break;
-            case "p2wpkh-p2sh":
-              address = generateP2SHAddress(hd: hd, network: network, index: 0);
-              break;
-            case "p2tr":
-              address = generateP2TRAddress(hd: hd, network: network, index: 0);
-              break;
-            default:
-              continue;
-          }
-
-          final sh = BitcoinAddressUtils.scriptHash(address, network: network);
-          final history = await electrumClient.getHistory(sh);
-
-          final balance = await electrumClient.getBalance(sh);
-          dInfoCopy.balance = balance.entries.firstOrNull?.value.toString() ?? "0";
-          dInfoCopy.address = address;
-          dInfoCopy.transactionsCount = history.length;
-
-          list.add(dInfoCopy);
-        } catch (e, s) {
-          printV("derivationInfoError: $e");
-          printV("derivationInfoStack: $s");
         }
       }
     }
diff --git a/lib/core/wallet_loading_service.dart b/lib/core/wallet_loading_service.dart
index f1996bae8..5e49eb1b8 100644
--- a/lib/core/wallet_loading_service.dart
+++ b/lib/core/wallet_loading_service.dart
@@ -79,7 +79,7 @@ class WalletLoadingService {
       final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
       WalletBase? wallet;
       for (var walletInfo in walletInfoSource.values) {
-        try {
+        // try {
           final walletService = walletServiceFactory.call(walletInfo.type);
           final walletPassword = await keyService.getWalletPassword(walletName: walletInfo.name);
           wallet = await walletService.openWallet(walletInfo.name, walletPassword);
@@ -95,18 +95,18 @@ class WalletLoadingService {
 
           // if found a wallet that is not corrupted, then still display the seeds of the corrupted ones
           authenticatedErrorStreamController.add(corruptedWalletsSeeds);
-        } catch (e) {
-          printV(e);
-          // save seeds and show corrupted wallets' seeds to the user
-          try {
-            final seeds = await _getCorruptedWalletSeeds(walletInfo.name, walletInfo.type);
-            if (!corruptedWalletsSeeds.contains(seeds)) {
-              corruptedWalletsSeeds += seeds;
-            }
-          } catch (e) {
-            corruptedWalletsSeeds += "\nFailed to fetch $name seeds: $e";
-          }
-        }
+        // } catch (e) {
+        //   printV(e);
+        //   // save seeds and show corrupted wallets' seeds to the user
+        //   try {
+        //     final seeds = await _getCorruptedWalletSeeds(walletInfo.name, walletInfo.type);
+        //     if (!corruptedWalletsSeeds.contains(seeds)) {
+        //       corruptedWalletsSeeds += seeds;
+        //     }
+        //   } catch (e) {
+        //     corruptedWalletsSeeds += "\nFailed to fetch $name seeds: $e";
+        //   }
+        // }
       }
 
       // if all user's wallets are corrupted throw exception
diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart
index 6215e26c3..44695cb17 100644
--- a/lib/src/screens/restore/wallet_restore_page.dart
+++ b/lib/src/screens/restore/wallet_restore_page.dart
@@ -394,7 +394,7 @@ class WalletRestorePage extends BasePage {
         }
       }
 
-      if (derivationsWithHistory > 1) {
+      if (derivationsWithHistory > 1 || true) {
         dInfo = await Navigator.of(context).pushNamed(
           Routes.restoreWalletChooseDerivation,
           arguments: derivations,
diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart
index b949c9968..08001b2b0 100644
--- a/lib/utils/exception_handler.dart
+++ b/lib/utils/exception_handler.dart
@@ -1,5 +1,6 @@
 import 'dart:io';
 
+import 'package:cake_wallet/core/wallet_loading_service.dart';
 import 'package:cake_wallet/di.dart';
 import 'package:cake_wallet/entities/preferences_key.dart';
 import 'package:cake_wallet/generated/i18n.dart';
@@ -8,8 +9,10 @@ import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
 import 'package:cake_wallet/store/app_store.dart';
 import 'package:cake_wallet/utils/show_bar.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cw_bitcoin/electrum_wallet.dart';
 import 'package:cw_core/root_dir.dart';
 import 'package:cw_core/utils/print_verbose.dart';
+import 'package:cw_core/wallet_type.dart';
 import 'package:device_info_plus/device_info_plus.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
@@ -78,29 +81,36 @@ class ExceptionHandler {
 
       await _addDeviceInfo(_file!);
 
-      // Check if a mail client is available
-      final bool canSend = await FlutterMailer.canSendMail();
+      // await _addElectrumWalletData(_file!);
 
-      if (Platform.isIOS && !canSend) {
-        printV('Mail app is not available');
-        return;
+      // // Check if a mail client is available
+      // final bool canSend = await FlutterMailer.canSendMail();
+
+      // if (Platform.isIOS && !canSend) {
+      //   printV('Mail app is not available');
+      //   return;
+      // }
+
+      // print the file content line by line:
+      for (var line in _file!.readAsLinesSync()) {
+        printV(line);
       }
 
-      final MailOptions mailOptions = MailOptions(
-        subject: 'Mobile App Issue',
-        recipients: ['support@cakewallet.com'],
-        attachments: [_file!.path],
-      );
+      // final MailOptions mailOptions = MailOptions(
+      //   subject: 'Mobile App Issue',
+      //   recipients: ['support@cakewallet.com'],
+      //   attachments: [_file!.path],
+      // );
 
-      final result = await FlutterMailer.send(mailOptions);
+      // final result = await FlutterMailer.send(mailOptions);
 
       // Clear file content if the error was sent or saved.
       // On android we can't know if it was sent or saved
-      if (result.name == MailerResponse.sent.name ||
-          result.name == MailerResponse.saved.name ||
-          result.name == MailerResponse.android.name) {
+      // if (result.name == MailerResponse.sent.name ||
+      //     result.name == MailerResponse.saved.name ||
+      //     result.name == MailerResponse.android.name) {
         _file!.writeAsString("", mode: FileMode.write);
-      }
+      // }
     } catch (e, s) {
       _saveException(e.toString(), s);
     }
@@ -113,8 +123,9 @@ class ExceptionHandler {
 
   static Future<void> onError(FlutterErrorDetails errorDetails) async {
     if (kDebugMode || kProfileMode) {
-      FlutterError.presentError(errorDetails);
-      printV(errorDetails.toString());
+      // FlutterError.presentError(errorDetails);
+      // printV(errorDetails.toString());
+      // _sendExceptionFile();
       return;
     }
 
@@ -255,6 +266,70 @@ class ExceptionHandler {
     );
   }
 
+  static Future<void> _addElectrumWalletData(File file) async {
+    final walletLoadingService = getIt.get<WalletLoadingService>();
+    final walletName = getIt.get<SharedPreferences>().getString(PreferencesKey.currentWalletName);
+    final walletTypeRaw = getIt.get<SharedPreferences>().getInt(PreferencesKey.currentWalletType)!;
+    final walletType = deserializeFromInt(walletTypeRaw);
+    if (walletName == null) return;
+    if (![WalletType.bitcoin, WalletType.litecoin].contains(walletType)) return;
+
+    final loadedWallet = await walletLoadingService.load(walletType, walletName);
+
+    final wallet = loadedWallet as ElectrumWallet;
+
+    await wallet.updateAllUnspents();
+
+    final receiveAddresses =
+        wallet.walletAddresses.receiveAddresses.where((e) => !e.address.contains("mweb")).toList();
+    final changeAddresses =
+        wallet.walletAddresses.changeAddresses.where((e) => !e.address.contains("mweb")).toList();
+    final unspentCoins = wallet.unspentCoins.where((e) => !e.address.contains("mweb")).toList();
+    final unspentCoinsInfo =
+        wallet.unspentCoinsInfo.values.where((e) => !e.address.contains("mweb")).toList();
+
+    String searchAddress = "ltc1q8t38ltq733p3652sdxqufyet2s9dzdx79rutp7";
+
+    await file.writeAsString("Search address: $searchAddress\n", mode: FileMode.append);
+
+    await file.writeAsString("\n\nReceive Addresses:\n", mode: FileMode.append);
+    for (var address in receiveAddresses) {
+      if (address.address == searchAddress) {
+        printV("@@@@@@@@@@@@@@@@@@@@@ FOUND ADDRESS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+      }
+      String addressStr =
+          "address: ${address.address} isHidden: ${address.isHidden ? "1" : "0"} isUsed: ${address.isUsed ? "1" : "0"}";
+      await file.writeAsString("$addressStr\n", mode: FileMode.append);
+    }
+    await file.writeAsString("\n\nChange Addresses:\n", mode: FileMode.append);
+    for (var address in changeAddresses) {
+      if (address.address == searchAddress) {
+        printV("@@@@@@@@@@@@@@@@@@@@@ FOUND ADDRESS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+      }
+      String addressStr =
+          "address: ${address.address} isHidden: ${address.isHidden ? "1" : "0"} isUsed: ${address.isUsed ? "1" : "0"}";
+      await file.writeAsString("$addressStr\n", mode: FileMode.append);
+    }
+    await file.writeAsString("\n\nUnspent Coins:\n", mode: FileMode.append);
+    for (var coin in unspentCoins) {
+      if (coin.address == searchAddress) {
+        printV("@@@@@@@@@@@@@@@@@@@@@ FOUND ADDRESS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+      }
+      String coinStr =
+          "address: ${coin.address} isChange: ${coin.isChange ? "1" : "0"} vout: ${coin.vout} value: ${coin.value}";
+      await file.writeAsString("$coinStr\n", mode: FileMode.append);
+    }
+    await file.writeAsString("\n\nUnspent Coins Info:\n", mode: FileMode.append);
+    for (var info in unspentCoinsInfo) {
+      if (info.address == searchAddress) {
+        printV("@@@@@@@@@@@@@@@@@@@@@ FOUND ADDRESS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+      }
+      String infoStr =
+          "address: ${info.address} isChange: ${info.isChange ? "1" : "0"} vout: ${info.vout} value: ${info.value}";
+      await file.writeAsString("$infoStr\n", mode: FileMode.append);
+    }
+  }
+
   static Map<String, dynamic> _readAndroidBuildData(AndroidDeviceInfo build) {
     return <String, dynamic>{
       'brand': build.brand,
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 52820adcb..46dffd689 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
@@ -68,7 +68,6 @@ abstract class UnspentCoinsListViewModelBase with Store {
 
   bool get hasAdjustableFieldChanged => items.any(_hasAdjustableFieldChanged);
 
-
   Future<void> saveUnspentCoinInfo(UnspentCoinsItem item) async {
     try {
       final existingInfo = _unspentCoinsInfo.values
@@ -79,7 +78,6 @@ abstract class UnspentCoinsListViewModelBase with Store {
       existingInfo.isSending = item.isSending;
       existingInfo.note = item.note;
 
-
       await existingInfo.save();
       _updateUnspentCoinsInfo();
     } catch (e) {
@@ -162,7 +160,14 @@ abstract class UnspentCoinsListViewModelBase with Store {
         .whereType<UnspentCoinsItem>()
         .toList();
 
-    unspents.sort((a, b) => b.value.compareTo(a.value));
+    // sort by hash so that even if the addresses are the same, they don't jump around when selected (because that calls updateBalance)
+    unspents.sort((a, b) => a.hash.compareTo(b.hash));
+
+    // sort unspents by address so that if something changes it's easier to see:
+    unspents.sort((a, b) => a.address.compareTo(b.address));
+
+    // sort change addresses to the end:
+    unspents.sort((a, b) => a.isChange ? 1 : -1);
 
     items.addAll(unspents);
   }
diff --git a/lib/view_model/wallet_creation_vm.dart b/lib/view_model/wallet_creation_vm.dart
index c2cfcbd24..f930062e5 100644
--- a/lib/view_model/wallet_creation_vm.dart
+++ b/lib/view_model/wallet_creation_vm.dart
@@ -206,8 +206,8 @@ abstract class WalletCreationVMBase with Store {
           passphrase: restoreWallet.passphrase,
         );
 
-        if (derivationList.firstOrNull?.transactionsCount == 0 && derivationList.length > 1)
-          return [];
+        // if (derivationList.firstOrNull?.transactionsCount == 0 && derivationList.length > 1)
+        //   return [];
         return derivationList;
 
       case WalletType.nano: