From ce2a9cd99f9d757b890b9f550ca4ef5aaf16115c Mon Sep 17 00:00:00 2001 From: OmarHatem <omarh.ismail1@gmail.com> Date: Tue, 28 May 2024 07:21:07 +0300 Subject: [PATCH] fixes and enhancements --- cw_bitcoin/lib/electrum_wallet.dart | 71 ++++++++--------- cw_bitcoin/lib/electrum_wallet_addresses.dart | 2 +- cw_core/lib/crypto_currency.dart | 6 +- lib/bitcoin/cw_bitcoin.dart | 8 -- lib/di.dart | 3 +- lib/entities/default_settings_migration.dart | 4 +- .../desktop_wallet_selection_dropdown.dart | 77 ++++++++++--------- .../screens/dashboard/pages/balance_page.dart | 7 +- .../dashboard/pages/cake_features_page.dart | 51 +++--------- .../settings/connection_sync_page.dart | 2 +- .../contact_list/contact_list_view_model.dart | 2 +- .../dashboard/balance_view_model.dart | 1 - .../dashboard/dashboard_view_model.dart | 2 +- lib/view_model/rescan_view_model.dart | 5 +- .../unspent_coins_list_view_model.dart | 3 + .../wallet_address_list_view_model.dart | 6 +- tool/configure.dart | 1 - 17 files changed, 110 insertions(+), 141 deletions(-) diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 05ad6aefa..f7aa0bc5d 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -230,7 +230,12 @@ abstract class ElectrumWalletBase int? _currentChainTip; Future<int> getCurrentChainTip() async { - return _currentChainTip ?? await electrumClient.getCurrentBlockChainTip() ?? 0; + if (_currentChainTip != null) { + return _currentChainTip!; + } + _currentChainTip = await electrumClient.getCurrentBlockChainTip() ?? 0; + + return _currentChainTip!; } Future<int> getUpdatedChainTip() async { @@ -248,8 +253,10 @@ abstract class ElectrumWalletBase String _password; List<BitcoinUnspent> unspentCoins; List<int> _feeRates; + // ignore: prefer_final_fields Map<String, BehaviorSubject<Object>?> _scripthashesUpdateSubject; + // ignore: prefer_final_fields BehaviorSubject<Object>? _chainTipUpdateSubject; bool _isTransactionUpdating; @@ -262,6 +269,7 @@ abstract class ElectrumWalletBase Future<void> init() async { await walletAddresses.init(); await transactionHistory.init(); + await save(); _autoSaveTimer = Timer.periodic(Duration(seconds: _autoSaveInterval), (_) async => await save()); @@ -313,30 +321,6 @@ abstract class ElectrumWalletBase final existingTxInfo = transactionHistory.transactions[txid]; final txAlreadyExisted = existingTxInfo != null; - void updateSilentAddressRecord(BitcoinSilentPaymentsUnspent unspent) { - final silentAddress = walletAddresses.silentAddress!; - final silentPaymentAddress = SilentPaymentAddress( - version: silentAddress.version, - B_scan: silentAddress.B_scan, - B_spend: unspent.silentPaymentLabel != null - ? silentAddress.B_spend.tweakAdd( - BigintUtils.fromBytes( - BytesUtils.fromHexString(unspent.silentPaymentLabel!)), - ) - : silentAddress.B_spend, - hrp: silentAddress.hrp, - ); - - final addressRecord = walletAddresses.silentAddresses.firstWhereOrNull( - (address) => address.address == silentPaymentAddress.toString()); - addressRecord?.txCount += 1; - addressRecord?.balance += unspent.value; - - walletAddresses.addSilentAddresses( - [unspent.bitcoinAddressRecord as BitcoinSilentPaymentAddressRecord], - ); - } - // Updating tx after re-scanned if (txAlreadyExisted) { existingTxInfo.amount = tx.amount; @@ -352,7 +336,7 @@ abstract class ElectrumWalletBase .toList(); if (newUnspents.isNotEmpty) { - newUnspents.forEach(updateSilentAddressRecord); + newUnspents.forEach(_updateSilentAddressRecord); existingTxInfo.unspents ??= []; existingTxInfo.unspents!.addAll(newUnspents); @@ -372,7 +356,7 @@ abstract class ElectrumWalletBase } } else { // else: First time seeing this TX after scanning - tx.unspents!.forEach(updateSilentAddressRecord); + tx.unspents!.forEach(_updateSilentAddressRecord); // Add new TX record transactionHistory.addMany(message); @@ -396,6 +380,30 @@ abstract class ElectrumWalletBase } } + void _updateSilentAddressRecord(BitcoinSilentPaymentsUnspent unspent) { + final silentAddress = walletAddresses.silentAddress!; + final silentPaymentAddress = SilentPaymentAddress( + version: silentAddress.version, + B_scan: silentAddress.B_scan, + B_spend: unspent.silentPaymentLabel != null + ? silentAddress.B_spend.tweakAdd( + BigintUtils.fromBytes( + BytesUtils.fromHexString(unspent.silentPaymentLabel!)), + ) + : silentAddress.B_spend, + hrp: silentAddress.hrp, + ); + + final addressRecord = walletAddresses.silentAddresses.firstWhereOrNull( + (address) => address.address == silentPaymentAddress.toString()); + addressRecord?.txCount += 1; + addressRecord?.balance += unspent.value; + + walletAddresses.addSilentAddresses( + [unspent.bitcoinAddressRecord as BitcoinSilentPaymentAddressRecord], + ); + } + @action @override Future<void> startSync() async { @@ -412,7 +420,7 @@ abstract class ElectrumWalletBase await updateAllUnspents(); await updateBalance(); - await updateFeeRates(); + Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates()); if (alwaysScan == true) { _setListeners(walletInfo.restoreHeight); @@ -1712,13 +1720,6 @@ abstract class ElectrumWalletBase confirmed: totalConfirmed, unconfirmed: totalUnconfirmed, frozen: totalFrozen); } - Future<ElectrumBalance> _fetchBalance(String sh) async { - final balance = await electrumClient.getBalance(sh); - final confirmed = balance['confirmed'] as int? ?? 0; - final unconfirmed = balance['unconfirmed'] as int? ?? 0; - return ElectrumBalance(confirmed: confirmed, unconfirmed: unconfirmed, frozen: 0); - } - Future<void> updateBalance() async { balance[currency] = await _fetchBalances(); await save(); diff --git a/cw_bitcoin/lib/electrum_wallet_addresses.dart b/cw_bitcoin/lib/electrum_wallet_addresses.dart index eb804fc21..e0857a6d0 100644 --- a/cw_bitcoin/lib/electrum_wallet_addresses.dart +++ b/cw_bitcoin/lib/electrum_wallet_addresses.dart @@ -29,7 +29,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { Map<String, int>? initialRegularAddressIndex, Map<String, int>? initialChangeAddressIndex, List<BitcoinSilentPaymentAddressRecord>? initialSilentAddresses, - int initialSilentAddressIndex = 1, + int initialSilentAddressIndex = 0, bitcoin.HDWallet? masterHd, BitcoinAddressType? initialAddressPageType, }) : _addresses = ObservableList<BitcoinAddressRecord>.of((initialAddresses ?? []).toSet()), diff --git a/cw_core/lib/crypto_currency.dart b/cw_core/lib/crypto_currency.dart index 0e701188d..81bbc2145 100644 --- a/cw_core/lib/crypto_currency.dart +++ b/cw_core/lib/crypto_currency.dart @@ -29,7 +29,6 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen CryptoCurrency.bch, CryptoCurrency.bnb, CryptoCurrency.btc, - CryptoCurrency.tbtc, CryptoCurrency.dai, CryptoCurrency.dash, CryptoCurrency.eos, @@ -105,6 +104,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen CryptoCurrency.digibyte, CryptoCurrency.usdtSol, CryptoCurrency.usdcTrc20, + CryptoCurrency.tbtc, ]; static const havenCurrencies = [ @@ -129,7 +129,6 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen static const bch = CryptoCurrency(title: 'BCH', fullName: 'Bitcoin Cash', raw: 2, name: 'bch', iconPath: 'assets/images/bch_icon.png', decimals: 8); static const bnb = CryptoCurrency(title: 'BNB', tag: 'BSC', fullName: 'Binance Coin', raw: 3, name: 'bnb', iconPath: 'assets/images/bnb_icon.png', decimals: 8); static const btc = CryptoCurrency(title: 'BTC', fullName: 'Bitcoin', raw: 4, name: 'btc', iconPath: 'assets/images/btc.png', decimals: 8); - static const tbtc = CryptoCurrency(title: 'tBTC', fullName: 'Testnet Bitcoin', raw: 4, name: 'tbtc', iconPath: 'assets/images/tbtc.png', decimals: 8); static const dai = CryptoCurrency(title: 'DAI', tag: 'ETH', fullName: 'Dai', raw: 5, name: 'dai', iconPath: 'assets/images/dai_icon.png', decimals: 18); static const dash = CryptoCurrency(title: 'DASH', fullName: 'Dash', raw: 6, name: 'dash', iconPath: 'assets/images/dash_icon.png', decimals: 8); static const eos = CryptoCurrency(title: 'EOS', fullName: 'EOS', raw: 7, name: 'eos', iconPath: 'assets/images/eos_icon.png', decimals: 4); @@ -220,7 +219,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen static const kaspa = CryptoCurrency(title: 'KAS', fullName: 'Kaspa', raw: 89, name: 'kas', iconPath: 'assets/images/kaspa_icon.png', decimals: 8); static const digibyte = CryptoCurrency(title: 'DGB', fullName: 'DigiByte', raw: 90, name: 'dgb', iconPath: 'assets/images/digibyte.png', decimals: 8); static const usdtSol = CryptoCurrency(title: 'USDT', tag: 'SOL', fullName: 'USDT Tether', raw: 91, name: 'usdtsol', iconPath: 'assets/images/usdt_icon.png', decimals: 6); - static const usdcTrc20 = CryptoCurrency(title: 'USDC', tag: 'TRX', fullName: 'USDC Coin', raw: 92, name: 'usdctrc20', iconPath: 'assets/images/usdc_icon.png', decimals: 6); + static const usdcTrc20 = CryptoCurrency(title: 'USDC', tag: 'TRX', fullName: 'USDC Coin', raw: 92, name: 'usdctrc20', iconPath: 'assets/images/usdc_icon.png', decimals: 6); + static const tbtc = CryptoCurrency(title: 'tBTC', fullName: 'Testnet Bitcoin', raw: 93, name: 'tbtc', iconPath: 'assets/images/tbtc.png', decimals: 8); static final Map<int, CryptoCurrency> _rawCurrencyMap = diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart index 6bdba2c61..27488c87b 100644 --- a/lib/bitcoin/cw_bitcoin.dart +++ b/lib/bitcoin/cw_bitcoin.dart @@ -121,14 +121,6 @@ class CWBitcoin extends Bitcoin { priority: priority != null ? priority as BitcoinTransactionPriority : null, feeRate: feeRate); - @override - List<String> getAddresses(Object wallet) { - final bitcoinWallet = wallet as ElectrumWallet; - return bitcoinWallet.walletAddresses.addressesByReceiveType - .map((BaseBitcoinAddressRecord addr) => addr.address) - .toList(); - } - @override @computed List<ElectrumSubAddress> getSubAddresses(Object wallet) { diff --git a/lib/di.dart b/lib/di.dart index 98ca1f284..d77be7665 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -934,8 +934,7 @@ Future<void> setup({ (onSuccessfulPinSetup, _) => SetupPinCodePage(getIt.get<SetupPinCodeViewModel>(), onSuccessfulPinSetup: onSuccessfulPinSetup)); - getIt.registerFactory( - () => RescanViewModel(getIt.get<AppStore>().wallet!, getIt.get<SettingsStore>())); + getIt.registerFactory(() => RescanViewModel(getIt.get<AppStore>().wallet!)); getIt.registerFactory(() => RescanPage(getIt.get<RescanViewModel>())); diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index 57c6637fc..697685767 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -882,7 +882,7 @@ Future<void> checkCurrentNodes( if (currentLitecoinElectrumServer == null) { final cakeWalletElectrum = - Node(uri: cakeWalletLitecoinElectrumUri, type: WalletType.litecoin, useSSL: true); + Node(uri: cakeWalletLitecoinElectrumUri, type: WalletType.litecoin, useSSL: false); await nodeSource.add(cakeWalletElectrum); await sharedPreferences.setInt( PreferencesKey.currentLitecoinElectrumSererIdKey, cakeWalletElectrum.key as int); @@ -918,7 +918,7 @@ Future<void> checkCurrentNodes( if (currentBitcoinCashNodeServer == null) { final node = - Node(uri: cakeWalletBitcoinCashDefaultNodeUri, type: WalletType.bitcoinCash, useSSL: true); + Node(uri: cakeWalletBitcoinCashDefaultNodeUri, type: WalletType.bitcoinCash, useSSL: false); await nodeSource.add(node); await sharedPreferences.setInt(PreferencesKey.currentBitcoinCashNodeIdKey, node.key as int); } 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 adf0840c9..663675849 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 @@ -30,6 +30,7 @@ class DesktopWalletSelectionDropDown extends StatefulWidget { class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionDropDown> { final moneroIcon = Image.asset('assets/images/monero_logo.png', height: 24, width: 24); final bitcoinIcon = Image.asset('assets/images/bitcoin.png', height: 24, width: 24); + final tBitcoinIcon = Image.asset('assets/images/tbtc.png', height: 24, width: 24); final litecoinIcon = Image.asset('assets/images/litecoin_icon.png', height: 24, width: 24); 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); @@ -68,8 +69,11 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD child: ConstrainedBox( constraints: BoxConstraints(maxWidth: 500), child: DropDownItemWidget( - title: wallet.name, - image: wallet.isEnabled ? _imageFor(type: wallet.type) : nonWalletTypeIcon), + title: wallet.name, + image: wallet.isEnabled + ? _imageFor(type: wallet.type, isTestnet: wallet.isTestnet) + : nonWalletTypeIcon, + ), ), onSelected: () => _onSelectedWallet(wallet), )) @@ -120,16 +124,16 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD WidgetsBinding.instance.addPostFrameCallback((_) async { final confirmed = await showPopUp<bool>( - context: context, - builder: (dialogContext) { - return AlertWithTwoActions( - alertTitle: S.of(context).change_wallet_alert_title, - alertContent: S.of(context).change_wallet_alert_content(selectedWallet.name), - leftButtonText: S.of(context).cancel, - rightButtonText: S.of(context).change, - actionLeftButton: () => Navigator.of(dialogContext).pop(false), - actionRightButton: () => Navigator.of(dialogContext).pop(true)); - }) ?? + context: context, + builder: (dialogContext) { + return AlertWithTwoActions( + alertTitle: S.of(context).change_wallet_alert_title, + alertContent: S.of(context).change_wallet_alert_content(selectedWallet.name), + leftButtonText: S.of(context).cancel, + rightButtonText: S.of(context).change, + actionLeftButton: () => Navigator.of(dialogContext).pop(false), + actionRightButton: () => Navigator.of(dialogContext).pop(true)); + }) ?? false; if (confirmed) { @@ -138,9 +142,12 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD }); } - Image _imageFor({required WalletType type}) { + Image _imageFor({required WalletType type, bool? isTestnet}) { switch (type) { case WalletType.bitcoin: + if (isTestnet == true) { + return tBitcoinIcon; + } return bitcoinIcon; case WalletType.monero: return moneroIcon; @@ -160,7 +167,7 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD return polygonIcon; case WalletType.solana: return solanaIcon; - case WalletType.tron: + case WalletType.tron: return tronIcon; default: return nonWalletTypeIcon; @@ -168,24 +175,25 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD } Future<void> _loadWallet(WalletListItem wallet) async { - widget._authService.authenticateAction(context, - onAuthSuccess: (isAuthenticatedSuccessfully) async { - if (!isAuthenticatedSuccessfully) { - return; - } + widget._authService.authenticateAction( + context, + onAuthSuccess: (isAuthenticatedSuccessfully) async { + if (!isAuthenticatedSuccessfully) { + return; + } - try { - if (context.mounted) { - changeProcessText(S.of(context).wallet_list_loading_wallet(wallet.name)); + try { + if (context.mounted) { + changeProcessText(S.of(context).wallet_list_loading_wallet(wallet.name)); + } + await widget.walletListViewModel.loadWallet(wallet); + hideProgressText(); + setState(() {}); + } catch (e) { + if (context.mounted) { + changeProcessText(S.of(context).wallet_list_failed_to_load(wallet.name, e.toString())); + } } - await widget.walletListViewModel.loadWallet(wallet); - hideProgressText(); - setState(() {}); - } catch (e) { - if (context.mounted) { - changeProcessText(S.of(context).wallet_list_failed_to_load(wallet.name, e.toString())); - } - } }, conditionToDetermineIfToUse2FA: widget.walletListViewModel.shouldRequireTOTP2FAForAccessingWallet, @@ -198,17 +206,16 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD context, route: Routes.newWallet, arguments: widget.walletListViewModel.currentWalletType, - conditionToDetermineIfToUse2FA: widget - .walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets, + conditionToDetermineIfToUse2FA: + widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets, ); } else { widget._authService.authenticateAction( context, route: Routes.newWalletType, - conditionToDetermineIfToUse2FA: widget - .walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets, + conditionToDetermineIfToUse2FA: + widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets, ); - } } diff --git a/lib/src/screens/dashboard/pages/balance_page.dart b/lib/src/screens/dashboard/pages/balance_page.dart index 3ed2a603f..7ffcf918d 100644 --- a/lib/src/screens/dashboard/pages/balance_page.dart +++ b/lib/src/screens/dashboard/pages/balance_page.dart @@ -329,6 +329,8 @@ class CryptoBalanceWidget extends StatelessWidget { final isSilentPaymentsScanningActive = dashboardViewModel.silentPaymentsScanningActive; final newValue = !isSilentPaymentsScanningActive; + dashboardViewModel.silentPaymentsScanningActive = newValue; + final needsToSwitch = !isSilentPaymentsScanningActive && await bitcoin!.getNodeIsElectrsSPEnabled(dashboardViewModel.wallet) == false; @@ -344,7 +346,10 @@ class CryptoBalanceWidget extends StatelessWidget { dashboardViewModel.setSilentPaymentsScanning(newValue); Navigator.of(context).pop(); }, - actionLeftButton: () => Navigator.of(context).pop(), + actionLeftButton: () { + dashboardViewModel.silentPaymentsScanningActive = isSilentPaymentsScanningActive; + Navigator.of(context).pop(); + }, )); } diff --git a/lib/src/screens/dashboard/pages/cake_features_page.dart b/lib/src/screens/dashboard/pages/cake_features_page.dart index c85ef08f8..9ccb7833c 100644 --- a/lib/src/screens/dashboard/pages/cake_features_page.dart +++ b/lib/src/screens/dashboard/pages/cake_features_page.dart @@ -1,15 +1,6 @@ -import 'package:cake_wallet/bitcoin/bitcoin.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart'; -import 'package:cake_wallet/src/widgets/standard_switch.dart'; -import 'package:cake_wallet/themes/extensions/balance_page_theme.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart'; -import 'package:cw_core/wallet_type.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -65,10 +56,7 @@ class CakeFeaturesPage extends StatelessWidget { // ), SizedBox(height: 20), DashBoardRoundedCardWidget( - onTap: () => launchUrl( - Uri.https("buy.cakepay.com"), - mode: LaunchMode.externalApplication, - ), + onTap: () => _launchUrl("buy.cakepay.com"), title: S.of(context).cake_pay_web_cards_title, subTitle: S.of(context).cake_pay_web_cards_subtitle, svgPicture: SvgPicture.asset( @@ -82,10 +70,7 @@ class CakeFeaturesPage extends StatelessWidget { DashBoardRoundedCardWidget( title: "NanoGPT", subTitle: S.of(context).nanogpt_subtitle, - onTap: () => launchUrl( - Uri.https("cake.nano-gpt.com"), - mode: LaunchMode.externalApplication, - ), + onTap: () => _launchUrl("cake.nano-gpt.com"), ), ], ), @@ -97,30 +82,12 @@ class CakeFeaturesPage extends StatelessWidget { ); } - // TODO: Remove ionia flow/files if we will discard it - void _navigatorToGiftCardsPage(BuildContext context) { - final walletType = dashboardViewModel.type; - - switch (walletType) { - case WalletType.haven: - showPopUp<void>( - context: context, - builder: (BuildContext context) { - return AlertWithOneAction( - alertTitle: S.of(context).error, - alertContent: S.of(context).gift_cards_unavailable, - buttonText: S.of(context).ok, - buttonAction: () => Navigator.of(context).pop()); - }); - break; - default: - cakeFeaturesViewModel.isIoniaUserAuthenticated().then((value) { - if (value) { - Navigator.pushNamed(context, Routes.ioniaManageCardsPage); - return; - } - Navigator.of(context).pushNamed(Routes.ioniaWelcomePage); - }); - } + void _launchUrl(String url) { + try { + launchUrl( + Uri.https(url), + mode: LaunchMode.externalApplication, + ); + } catch (_) {} } } diff --git a/lib/src/screens/settings/connection_sync_page.dart b/lib/src/screens/settings/connection_sync_page.dart index 7a5bec581..c4d85a3a5 100644 --- a/lib/src/screens/settings/connection_sync_page.dart +++ b/lib/src/screens/settings/connection_sync_page.dart @@ -39,7 +39,7 @@ class ConnectionSyncPage extends BasePage { ), if (dashboardViewModel.hasRescan) ...[ SettingsCellWithArrow( - title: dashboardViewModel.hasRescan + title: dashboardViewModel.hasSilentPayments ? S.current.silent_payments_scanning : S.current.rescan, handler: (context) => Navigator.of(context).pushNamed(Routes.rescan), 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 f81116506..8dbd97bb9 100644 --- a/lib/view_model/contact_list/contact_list_view_model.dart +++ b/lib/view_model/contact_list/contact_list_view_model.dart @@ -53,7 +53,7 @@ abstract class ContactListViewModelBase with Store { info.network == null ? false : info.network!.toLowerCase().contains("testnet")), )); }); - } else if (info.address != null) { + } else { walletContacts.add(WalletContact( info.address, info.name, diff --git a/lib/view_model/dashboard/balance_view_model.dart b/lib/view_model/dashboard/balance_view_model.dart index 62214e4b1..5ae532bb6 100644 --- a/lib/view_model/dashboard/balance_view_model.dart +++ b/lib/view_model/dashboard/balance_view_model.dart @@ -1,4 +1,3 @@ -import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/entities/fiat_api_mode.dart'; import 'package:cake_wallet/entities/sort_balance_types.dart'; import 'package:cake_wallet/reactions/wallet_connect.dart'; diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index ed8d7593d..0e730f8f6 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -306,7 +306,7 @@ abstract class DashboardViewModelBase with Store { wallet.type == WalletType.haven; @computed - bool get hasSilentPayments => hasRescan && wallet.type == WalletType.bitcoin; + bool get hasSilentPayments => wallet.type == WalletType.bitcoin; @computed bool get showSilentPaymentsCard => hasSilentPayments && settingsStore.silentPaymentsCardDisplay; diff --git a/lib/view_model/rescan_view_model.dart b/lib/view_model/rescan_view_model.dart index f78c51f68..dcc81c0a0 100644 --- a/lib/view_model/rescan_view_model.dart +++ b/lib/view_model/rescan_view_model.dart @@ -1,5 +1,4 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart'; -import 'package:cake_wallet/store/settings_store.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:mobx/mobx.dart'; @@ -11,15 +10,13 @@ class RescanViewModel = RescanViewModelBase with _$RescanViewModel; enum RescanWalletState { rescaning, none } abstract class RescanViewModelBase with Store { - RescanViewModelBase(this.wallet, this.settingsStore) + RescanViewModelBase(this.wallet) : state = RescanWalletState.none, isButtonEnabled = false, doSingleScan = false; final WalletBase wallet; - final SettingsStore settingsStore; - @observable RescanWalletState state; 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 bb04cfe5c..2a4383d38 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,12 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/monero/monero.dart'; +import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/unspent_transaction_output.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_type.dart'; +import 'package:flutter/cupertino.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; @@ -109,6 +111,7 @@ abstract class UnspentCoinsListViewModelBase with Store { } catch (e, s) { print(s); print(e.toString()); + ExceptionHandler.onError(FlutterErrorDetails(exception: e, stack: s)); } }); 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 99bfa1231..f470a06c2 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 @@ -456,9 +456,9 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo wallet.type == WalletType.bitcoin && bitcoin!.hasSelectedSilentPayments(wallet); @computed - bool get isAutoGenerateSubaddressEnabled => wallet.type == WalletType.bitcoin - ? !isSilentPayments - : _settingsStore.autoGenerateSubaddressStatus != AutoGenerateSubaddressStatus.disabled; + bool get isAutoGenerateSubaddressEnabled => + _settingsStore.autoGenerateSubaddressStatus != AutoGenerateSubaddressStatus.disabled && + !isSilentPayments; List<ListItem> _baseItems; diff --git a/tool/configure.dart b/tool/configure.dart index 95b85d121..24819c085 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -166,7 +166,6 @@ abstract class Bitcoin { Object createBitcoinTransactionCredentials(List<Output> outputs, {required TransactionPriority priority, int? feeRate}); Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs, {TransactionPriority? priority, required int feeRate}); - List<String> getAddresses(Object wallet); String getAddress(Object wallet); List<BitcoinSilentPaymentAddressRecord> getSilentPaymentAddresses(Object wallet); List<BitcoinSilentPaymentAddressRecord> getSilentPaymentReceivedAddresses(Object wallet);