From fe5abfd39e1247e13b2e6bb8cd33035b0b531449 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Wed, 21 Aug 2024 14:18:51 +0200 Subject: [PATCH] refactor address handling --- cw_bitcoin/lib/electrum_wallet.dart | 3 +- cw_core/lib/wallet_addresses.dart | 25 ++++++++- cw_core/lib/wallet_info.dart | 6 ++ ios/Podfile.lock | 55 +------------------ lib/core/wallet_loading_service.dart | 2 +- lib/monero/cw_monero.dart | 2 +- .../screens/receive/widgets/address_list.dart | 5 +- .../exchange/exchange_view_model.dart | 3 + ...let_address_edit_or_create_view_model.dart | 5 ++ .../wallet_address_list_item.dart | 6 +- .../wallet_address_list_view_model.dart | 25 +++++++++ 11 files changed, 76 insertions(+), 61 deletions(-) diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 2d0b989d7..4e2555149 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -1661,7 +1661,8 @@ abstract class ElectrumWalletBase final addressesByType = walletAddresses.allAddresses.where((addr) => addr.type == type); final hiddenAddresses = addressesByType.where((addr) => addr.isHidden == true); final receiveAddresses = addressesByType.where((addr) => addr.isHidden == false); - + walletAddresses.hiddenAddresses.addAll(hiddenAddresses.map((e) => e.address)); + await walletAddresses.saveAddressesInBox(); await Future.wait(addressesByType.map((addressRecord) async { final history = await _fetchAddressHistory(addressRecord, await getCurrentChainTip()); diff --git a/cw_core/lib/wallet_addresses.dart b/cw_core/lib/wallet_addresses.dart index e987b5d0e..9c8022320 100644 --- a/cw_core/lib/wallet_addresses.dart +++ b/cw_core/lib/wallet_addresses.dart @@ -5,7 +5,10 @@ abstract class WalletAddresses { WalletAddresses(this.walletInfo) : addressesMap = {}, allAddressesMap = {}, - addressInfos = {}; + addressInfos = {}, + usedAddresses = {}, + hiddenAddresses = walletInfo.hiddenAddresses?.toSet() ?? {}, + manualAddresses = walletInfo.manualAddresses?.toSet() ?? {}; final WalletInfo walletInfo; @@ -18,9 +21,25 @@ abstract class WalletAddresses { Map addressesMap; Map allAddressesMap; + Map get usableAddressesMap { + final tmp = addressesMap.map((key, value) => MapEntry(key, value)); // copy address map + tmp.removeWhere((key, value) => hiddenAddresses.contains(key)); + return tmp; + } + + Map get usableAllAddressesMap { + final tmp = allAddressesMap.map((key, value) => MapEntry(key, value)); // copy address map + tmp.removeWhere((key, value) => hiddenAddresses.contains(key)); + return tmp; + } + Map> addressInfos; - Set usedAddresses = {}; + Set usedAddresses; + + Set hiddenAddresses; + + Set manualAddresses; Future init(); @@ -32,6 +51,8 @@ abstract class WalletAddresses { walletInfo.addresses = addressesMap; walletInfo.addressInfos = addressInfos; walletInfo.usedAddresses = usedAddresses.toList(); + walletInfo.hiddenAddresses = hiddenAddresses.toList(); + walletInfo.manualAddresses = manualAddresses.toList(); if (walletInfo.isInBox) { await walletInfo.save(); diff --git a/cw_core/lib/wallet_info.dart b/cw_core/lib/wallet_info.dart index ff0c011bb..9aca9b8a9 100644 --- a/cw_core/lib/wallet_info.dart +++ b/cw_core/lib/wallet_info.dart @@ -184,6 +184,12 @@ class WalletInfo extends HiveObject { @HiveField(21) HardwareWalletType? hardwareWalletType; + @HiveField(22) + List? hiddenAddresses; + + @HiveField(23) + List? manualAddresses; + String get yatLastUsedAddress => yatLastUsedAddressRaw ?? ''; set yatLastUsedAddress(String address) { diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 212d1ec1c..39dcd8b80 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -3,41 +3,10 @@ PODS: - Flutter - MTBBarcodeScanner - SwiftProtobuf - - BigInt (5.2.0) - connectivity_plus (0.0.1): - Flutter - ReachabilitySwift - CryptoSwift (1.8.2) - - cw_haven (0.0.1): - - cw_haven/Boost (= 0.0.1) - - cw_haven/Haven (= 0.0.1) - - cw_haven/OpenSSL (= 0.0.1) - - cw_haven/Sodium (= 0.0.1) - - cw_shared_external - - Flutter - - cw_haven/Boost (0.0.1): - - cw_shared_external - - Flutter - - cw_haven/Haven (0.0.1): - - cw_shared_external - - Flutter - - cw_haven/OpenSSL (0.0.1): - - cw_shared_external - - Flutter - - cw_haven/Sodium (0.0.1): - - cw_shared_external - - Flutter - - cw_shared_external (0.0.1): - - cw_shared_external/Boost (= 0.0.1) - - cw_shared_external/OpenSSL (= 0.0.1) - - cw_shared_external/Sodium (= 0.0.1) - - Flutter - - cw_shared_external/Boost (0.0.1): - - Flutter - - cw_shared_external/OpenSSL (0.0.1): - - Flutter - - cw_shared_external/Sodium (0.0.1): - - Flutter - device_display_brightness (0.0.1): - Flutter - device_info_plus (0.0.1): @@ -99,8 +68,6 @@ PODS: - Flutter - MTBBarcodeScanner (5.0.11) - OrderedSet (5.0.0) - - package_info (0.0.1): - - Flutter - package_info_plus (0.4.5): - Flutter - path_provider_foundation (0.0.1): @@ -131,9 +98,6 @@ PODS: - Toast (4.1.1) - uni_links (0.0.1): - Flutter - - UnstoppableDomainsResolution (4.0.0): - - BigInt - - CryptoSwift - url_launcher_ios (0.0.1): - Flutter - wakelock_plus (0.0.1): @@ -145,8 +109,6 @@ DEPENDENCIES: - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`) - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - CryptoSwift - - cw_haven (from `.symlinks/plugins/cw_haven/ios`) - - cw_shared_external (from `.symlinks/plugins/cw_shared_external/ios`) - device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - devicelocale (from `.symlinks/plugins/devicelocale/ios`) @@ -158,7 +120,6 @@ DEPENDENCIES: - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - in_app_review (from `.symlinks/plugins/in_app_review/ios`) - - package_info (from `.symlinks/plugins/package_info/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) @@ -168,14 +129,12 @@ DEPENDENCIES: - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - sp_scanner (from `.symlinks/plugins/sp_scanner/ios`) - uni_links (from `.symlinks/plugins/uni_links/ios`) - - UnstoppableDomainsResolution (~> 4.0.0) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`) - workmanager (from `.symlinks/plugins/workmanager/ios`) SPEC REPOS: https://github.com/CocoaPods/Specs.git: - - BigInt - CryptoSwift - DKImagePickerController - DKPhotoGallery @@ -187,17 +146,12 @@ SPEC REPOS: - SwiftProtobuf - SwiftyGif - Toast - - UnstoppableDomainsResolution EXTERNAL SOURCES: barcode_scan2: :path: ".symlinks/plugins/barcode_scan2/ios" connectivity_plus: :path: ".symlinks/plugins/connectivity_plus/ios" - cw_haven: - :path: ".symlinks/plugins/cw_haven/ios" - cw_shared_external: - :path: ".symlinks/plugins/cw_shared_external/ios" device_display_brightness: :path: ".symlinks/plugins/device_display_brightness/ios" device_info_plus: @@ -220,8 +174,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/fluttertoast/ios" in_app_review: :path: ".symlinks/plugins/in_app_review/ios" - package_info: - :path: ".symlinks/plugins/package_info/ios" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: @@ -249,11 +201,8 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0 - BigInt: f668a80089607f521586bbe29513d708491ef2f7 connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d CryptoSwift: c63a805d8bb5e5538e88af4e44bb537776af11ea - cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a - cw_shared_external: 2972d872b8917603478117c9957dfca611845a92 device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7 device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 devicelocale: b22617f40038496deffba44747101255cee005b0 @@ -269,7 +218,6 @@ SPEC CHECKSUMS: in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c - package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 @@ -285,11 +233,10 @@ SPEC CHECKSUMS: SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e uni_links: d97da20c7701486ba192624d99bffaaffcfc298a - UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841 url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1 workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6 -PODFILE CHECKSUM: a2fe518be61cdbdc5b0e2da085ab543d556af2d3 +PODFILE CHECKSUM: e448f662d4c41f0c0b1ccbb78afd57dbf895a597 COCOAPODS: 1.15.2 diff --git a/lib/core/wallet_loading_service.dart b/lib/core/wallet_loading_service.dart index 0087b1332..ada9d1f29 100644 --- a/lib/core/wallet_loading_service.dart +++ b/lib/core/wallet_loading_service.dart @@ -57,7 +57,7 @@ class WalletLoadingService { ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack)); // try fetching the seeds of the corrupted wallet to show it to the user - String corruptedWalletsSeeds = "Corrupted wallets seeds (if retrievable, empty otherwise):"; + String corruptedWalletsSeeds = "$error, $stack\nCorrupted wallets seeds (if retrievable, empty otherwise):"; try { corruptedWalletsSeeds += await _getCorruptedWalletSeeds(name, type); } catch (e) { diff --git a/lib/monero/cw_monero.dart b/lib/monero/cw_monero.dart index 1f1888b44..0e5c9bf64 100644 --- a/lib/monero/cw_monero.dart +++ b/lib/monero/cw_monero.dart @@ -91,7 +91,7 @@ class CWMoneroSubaddressList extends MoneroSubaddressList { Future addSubaddress(Object wallet, {required int accountIndex, required String label}) async { final moneroWallet = wallet as MoneroWallet; - await moneroWallet.walletAddresses.subaddressList + return await moneroWallet.walletAddresses.subaddressList .addSubaddress(accountIndex: accountIndex, label: label); } diff --git a/lib/src/screens/receive/widgets/address_list.dart b/lib/src/screens/receive/widgets/address_list.dart index 8dfbedec1..5d344f385 100644 --- a/lib/src/screens/receive/widgets/address_list.dart +++ b/lib/src/screens/receive/widgets/address_list.dart @@ -90,7 +90,10 @@ class AddressList extends StatelessWidget { item, isCurrent: isCurrent, hasBalance: addressListViewModel.isElectrumWallet, - backgroundColor: backgroundColor, + backgroundColor: item.isHidden ? + Theme.of(context).colorScheme.error : + item.isManual ? Theme.of(context).colorScheme.error.withBlue(255) : + backgroundColor, textColor: textColor, onTap: (_) { if (onSelect != null) { diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index f2ea8eeb4..be3dfc230 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -536,6 +536,9 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with isFixedRate: isFixedRateMode, ); + wallet.walletAddresses.hiddenAddresses.add(depositAddress); + await wallet.walletAddresses.saveAddressesInBox(); + var amount = isFixedRateMode ? receiveAmount : depositAmount; amount = amount.replaceAll(',', '.'); diff --git a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart index 2edda3d29..74b37f6fd 100644 --- a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart +++ b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart @@ -78,6 +78,11 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store { wallet, accountIndex: monero!.getCurrentAccount(wallet).id, label: label); + wallet.walletAddresses.manualAddresses.add( + await monero!.getSubaddressList(wallet).subaddresses.last.address + ); + print("hidden"); + await wallet.walletAddresses.saveAddressesInBox(); await wallet.save(); } diff --git a/lib/view_model/wallet_address_list/wallet_address_list_item.dart b/lib/view_model/wallet_address_list/wallet_address_list_item.dart index 6a6e34113..725b1ddbf 100644 --- a/lib/view_model/wallet_address_list/wallet_address_list_item.dart +++ b/lib/view_model/wallet_address_list/wallet_address_list_item.dart @@ -1,7 +1,7 @@ import 'package:cake_wallet/utils/list_item.dart'; class WalletAddressListItem extends ListItem { - const WalletAddressListItem({ + WalletAddressListItem({ required this.address, required this.isPrimary, this.id, @@ -11,6 +11,8 @@ class WalletAddressListItem extends ListItem { this.isChange = false, // Address that is only ever used once, shouldn't be used to receive funds, copy and paste, share etc this.isOneTimeReceiveAddress = false, + this.isHidden = false, + this.isManual = false, }) : super(); final int? id; @@ -20,6 +22,8 @@ class WalletAddressListItem extends ListItem { final int? txCount; final String? balance; final bool isChange; + bool isHidden; + bool isManual; final bool? isOneTimeReceiveAddress; @override 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 0bd936720..6036584f5 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 @@ -22,6 +22,7 @@ import 'package:cake_wallet/wownero/wownero.dart'; import 'package:cw_core/amount_converter.dart'; import 'package:cw_core/currency.dart'; import 'package:cw_core/wallet_type.dart'; +import 'package:flutter/foundation.dart'; import 'package:intl/intl.dart'; import 'package:mobx/mobx.dart'; @@ -462,6 +463,30 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo })); } + if (!kDebugMode) { + addressList.removeWhere((element) { + if (!(element is WalletAddressListItem)) return false; + return wallet.walletAddresses.hiddenAddresses.contains(element.address); + }); + } else { + for (var i = 0; i < addressList.length; i++) { + if (!(addressList[i] is WalletAddressListItem)) continue; + (addressList[i] as WalletAddressListItem).isHidden = wallet.walletAddresses.hiddenAddresses.contains((addressList[i] as WalletAddressListItem).address); + } + } + + if (!kDebugMode) { + addressList.removeWhere((element) { + if (!(element is WalletAddressListItem)) return false; + return wallet.walletAddresses.manualAddresses.contains(element.address); + }); + } else { + for (var i = 0; i < addressList.length; i++) { + if (!(addressList[i] is WalletAddressListItem)) continue; + (addressList[i] as WalletAddressListItem).isManual = wallet.walletAddresses.manualAddresses.contains((addressList[i] as WalletAddressListItem).address); + } + } + return addressList; }