diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt index 557dd8b26..faad67777 100644 --- a/assets/text/Release_Notes.txt +++ b/assets/text/Release_Notes.txt @@ -1,2 +1 @@ -Bitcoin Silent Payments -Bug fixes and generic enhancements +Bug fixes and generic enhancements \ No newline at end of file diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 8862eeab1..2a2542b09 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -1465,7 +1465,7 @@ abstract class ElectrumWalletBase time = status["block_time"] as int?; final height = status["block_height"] as int? ?? 0; - final tip = await getCurrentChainTip(); + final tip = await getUpdatedChainTip(); if (tip > 0) confirmations = height > 0 ? tip - height + 1 : 0; } else { final verboseTransaction = await electrumClient.getTransactionRaw(hash: hash); @@ -1519,6 +1519,23 @@ abstract class ElectrumWalletBase await fetchTransactionsForAddressType(historiesWithDetails, SegwitAddresType.p2wpkh); } + transactionHistory.transactions.values.forEach((tx) async { + final isPendingSilentPaymentUtxo = + (tx.isPending || tx.confirmations == 0) && historiesWithDetails[tx.id] == null; + + if (isPendingSilentPaymentUtxo) { + final info = + await fetchTransactionInfo(hash: tx.id, height: tx.height, retryOnFailure: true); + + if (info != null) { + tx.confirmations = info.confirmations; + tx.isPending = tx.confirmations == 0; + transactionHistory.addOne(tx); + await transactionHistory.save(); + } + } + }); + return historiesWithDetails; } catch (e) { print(e.toString()); diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock index 3eadcb112..997ed9452 100644 --- a/cw_bitcoin/pubspec.lock +++ b/cw_bitcoin/pubspec.lock @@ -793,8 +793,8 @@ packages: dependency: "direct main" description: path: "." - ref: "sp_v1.0.0" - resolved-ref: a9a4c6d051f37a15a3a52cc2a0094f24c68b62c5 + ref: "sp_v2.0.0" + resolved-ref: "62c152b9086cd968019128845371072f7e1168de" url: "https://github.com/cake-tech/sp_scanner" source: git version: "0.0.1" diff --git a/cw_monero/ios/Classes/monero_api.cpp b/cw_monero/ios/Classes/monero_api.cpp index 01a8d9a51..a2a17bd5e 100644 --- a/cw_monero/ios/Classes/monero_api.cpp +++ b/cw_monero/ios/Classes/monero_api.cpp @@ -399,7 +399,6 @@ extern "C" return false; } - wallet->store(std::string(path)); change_current_wallet(wallet); return true; } diff --git a/lib/di.dart b/lib/di.dart index a1c119e78..d14097554 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -584,7 +584,7 @@ Future setup({ getIt.registerFactory( () => Modify2FAPage(setup2FAViewModel: getIt.get())); - getIt.registerFactory(() => DesktopSettingsPage()); + getIt.registerFactory(() => DesktopSettingsPage(getIt.get())); getIt.registerFactoryParam( (pageOption, _) => ReceiveOptionViewModel(getIt.get().wallet!, pageOption)); diff --git a/lib/src/screens/base_page.dart b/lib/src/screens/base_page.dart index 20c918be6..bf60525e4 100644 --- a/lib/src/screens/base_page.dart +++ b/lib/src/screens/base_page.dart @@ -1,4 +1,5 @@ import 'package:cake_wallet/themes/theme_base.dart'; +import 'package:cake_wallet/utils/route_aware.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/di.dart'; @@ -32,6 +33,14 @@ abstract class BasePage extends StatelessWidget { Widget? get endDrawer => null; + Function(BuildContext context)? get pushToWidget => null; + + Function(BuildContext context)? get pushToNextWidget => null; + + Function(BuildContext context)? get popWidget => null; + + Function(BuildContext context)? get popNextWidget => null; + AppBarStyle get appBarStyle => AppBarStyle.regular; Widget Function(BuildContext, Widget)? get rootWrapper => null; @@ -162,15 +171,21 @@ abstract class BasePage extends StatelessWidget { @override Widget build(BuildContext context) { - final root = Scaffold( - key: _scaffoldKey, - backgroundColor: pageBackgroundColor(context), - resizeToAvoidBottomInset: resizeToAvoidBottomInset, - extendBodyBehindAppBar: extendBodyBehindAppBar, - endDrawer: endDrawer, - appBar: appBar(context), - body: body(context), - floatingActionButton: floatingActionButton(context)); + final root = RouteAwareWidget( + child: Scaffold( + key: _scaffoldKey, + backgroundColor: pageBackgroundColor(context), + resizeToAvoidBottomInset: resizeToAvoidBottomInset, + extendBodyBehindAppBar: extendBodyBehindAppBar, + endDrawer: endDrawer, + appBar: appBar(context), + body: body(context), + floatingActionButton: floatingActionButton(context)), + pushToWidget: (context) => pushToWidget?.call(context), + pushToNextWidget: (context) => pushToNextWidget?.call(context), + popWidget: (context) => popWidget?.call(context), + popNextWidget: (context) => popNextWidget?.call(context), + ); return rootWrapper?.call(context, root) ?? root; } diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart index 7ae51d384..c99287b6f 100644 --- a/lib/src/screens/exchange/exchange_page.dart +++ b/lib/src/screens/exchange/exchange_page.dart @@ -99,6 +99,14 @@ class ExchangePage extends BasePage { @override AppBarStyle get appBarStyle => AppBarStyle.transparent; + @override + Function(BuildContext)? get pushToNextWidget => (context) { + FocusScopeNode currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus) { + currentFocus.focusedChild?.unfocus(); + } + }; + @override Widget middle(BuildContext context) => Row( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart b/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart index dba78f557..dcd1d54b4 100644 --- a/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart +++ b/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart @@ -84,12 +84,7 @@ class IoniaGiftCardDetailPage extends BasePage { } }); - return RouteAwareWidget( - pushToWidget: ()=> viewModel.increaseBrightness(), - pushToNextWidget: ()=> DeviceDisplayBrightness.setBrightness(viewModel.brightness), - popNextWidget: ()=> viewModel.increaseBrightness(), - popWidget: ()=> DeviceDisplayBrightness.setBrightness(viewModel.brightness), - child: ScrollableWithBottomSection( + return ScrollableWithBottomSection( contentPadding: EdgeInsets.all(24), content: Column( children: [ @@ -168,7 +163,7 @@ class IoniaGiftCardDetailPage extends BasePage { }, ), ), - )); + ); } Widget buildIoniaTile(BuildContext context, {required String title, required String subTitle}) { diff --git a/lib/src/screens/new_wallet/new_wallet_page.dart b/lib/src/screens/new_wallet/new_wallet_page.dart index 8cc8a138d..8d46827eb 100644 --- a/lib/src/screens/new_wallet/new_wallet_page.dart +++ b/lib/src/screens/new_wallet/new_wallet_page.dart @@ -38,6 +38,14 @@ class NewWalletPage extends BasePage { @override String get title => S.current.new_wallet; + @override + Function(BuildContext)? get pushToNextWidget => (context) { + FocusScopeNode currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus) { + currentFocus.focusedChild?.unfocus(); + } + }; + @override Widget body(BuildContext context) => WalletNameForm( _walletNewVM, diff --git a/lib/src/screens/new_wallet/new_wallet_type_page.dart b/lib/src/screens/new_wallet/new_wallet_type_page.dart index dc22a60db..65c7bd59b 100644 --- a/lib/src/screens/new_wallet/new_wallet_type_page.dart +++ b/lib/src/screens/new_wallet/new_wallet_type_page.dart @@ -34,6 +34,14 @@ class NewWalletTypePage extends BasePage { String get title => isCreate ? S.current.wallet_list_create_new_wallet : S.current.wallet_list_restore_wallet; + @override + Function(BuildContext)? get pushToNextWidget => (context) { + FocusScopeNode currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus) { + currentFocus.focusedChild?.unfocus(); + } + }; + @override Widget body(BuildContext context) => WalletTypeForm( onTypeSelected: onTypeSelected, diff --git a/lib/src/screens/restore/restore_from_backup_page.dart b/lib/src/screens/restore/restore_from_backup_page.dart index f7fddac3f..c5bc2a163 100644 --- a/lib/src/screens/restore/restore_from_backup_page.dart +++ b/lib/src/screens/restore/restore_from_backup_page.dart @@ -21,6 +21,14 @@ class RestoreFromBackupPage extends BasePage { @override String get title => S.current.restore_title_from_backup; + @override + Function(BuildContext)? get pushToNextWidget => (context) { + FocusScopeNode currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus) { + currentFocus.focusedChild?.unfocus(); + } + }; + @override Widget body(BuildContext context) { reaction((_) => restoreFromBackupViewModel.state, (ExecutionState state) { diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart index 422acad4a..f96dcab84 100644 --- a/lib/src/screens/restore/wallet_restore_page.dart +++ b/lib/src/screens/restore/wallet_restore_page.dart @@ -101,6 +101,14 @@ class WalletRestorePage extends BasePage { // String? derivationPath = null; DerivationInfo? derivationInfo; + @override + Function(BuildContext)? get pushToNextWidget => (context) { + FocusScopeNode currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus) { + currentFocus.focusedChild?.unfocus(); + } + }; + @override Widget body(BuildContext context) { reaction((_) => walletRestoreViewModel.state, (ExecutionState state) { diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 438c22c1d..b46a7f3db 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -66,6 +66,14 @@ class SendPage extends BasePage { @override bool get extendBodyBehindAppBar => true; + @override + Function(BuildContext)? get pushToNextWidget => (context) { + FocusScopeNode currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus) { + currentFocus.focusedChild?.unfocus(); + } + }; + @override Widget? leading(BuildContext context) { final _backButton = Icon( diff --git a/lib/src/screens/send/send_template_page.dart b/lib/src/screens/send/send_template_page.dart index 52458942c..76414ecb2 100644 --- a/lib/src/screens/send/send_template_page.dart +++ b/lib/src/screens/send/send_template_page.dart @@ -32,6 +32,14 @@ class SendTemplatePage extends BasePage { @override AppBarStyle get appBarStyle => AppBarStyle.transparent; + @override + Function(BuildContext)? get pushToNextWidget => (context) { + FocusScopeNode currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus) { + currentFocus.focusedChild?.unfocus(); + } + }; + @override Widget trailing(context) => Observer(builder: (_) { return sendTemplateViewModel.recipients.length > 1 diff --git a/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart b/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart index 5355b7bb8..611b2acb7 100644 --- a/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart +++ b/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart @@ -3,6 +3,7 @@ import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/widgets/setting_action_button.dart'; import 'package:cake_wallet/src/widgets/setting_actions.dart'; import 'package:cake_wallet/typography.dart'; +import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/router.dart' as Router; import 'package:cake_wallet/themes/extensions/menu_theme.dart'; @@ -10,7 +11,9 @@ import 'package:cake_wallet/themes/extensions/menu_theme.dart'; final _settingsNavigatorKey = GlobalKey(); class DesktopSettingsPage extends StatefulWidget { - const DesktopSettingsPage({super.key}); + const DesktopSettingsPage(this.dashboardViewModel, {super.key}); + + final DashboardViewModel dashboardViewModel; @override State createState() => _DesktopSettingsPageState(); @@ -51,6 +54,12 @@ class _DesktopSettingsPageState extends State { padding: EdgeInsets.only(top: 0), itemBuilder: (_, index) { final item = SettingActions.desktopSettings[index]; + + if (!widget.dashboardViewModel.hasSilentPayments && + item.name(context) == S.of(context).silent_payments_settings) { + return Container(); + } + final isLastTile = index == itemCount - 1; return SettingActionButton( isLastTile: isLastTile, diff --git a/lib/src/widgets/setting_actions.dart b/lib/src/widgets/setting_actions.dart index 6fbdb6868..272ed57c2 100644 --- a/lib/src/widgets/setting_actions.dart +++ b/lib/src/widgets/setting_actions.dart @@ -29,6 +29,7 @@ class SettingActions { connectionSettingAction, walletSettingAction, addressBookSettingAction, + silentPaymentsSettingAction, securityBackupSettingAction, privacySettingAction, displaySettingAction, diff --git a/lib/utils/route_aware.dart b/lib/utils/route_aware.dart index 28c72c4a4..d1721d912 100644 --- a/lib/utils/route_aware.dart +++ b/lib/utils/route_aware.dart @@ -10,10 +10,10 @@ class RouteAwareWidget extends StatefulWidget { this.popNextWidget}); final Widget child; - final Function()? pushToWidget; - final Function()? pushToNextWidget; - final Function()? popWidget; - final Function()? popNextWidget; + final Function(BuildContext context)? pushToWidget; + final Function(BuildContext context)? pushToNextWidget; + final Function(BuildContext context)? popWidget; + final Function(BuildContext context)? popNextWidget; @override State createState() => RouteAwareWidgetState(); @@ -35,28 +35,28 @@ class RouteAwareWidgetState extends State with RouteAware { @override void didPush() { if (widget.pushToWidget != null) { - widget.pushToWidget!(); + widget.pushToWidget!(context); } } @override void didPushNext() { if (widget.pushToNextWidget != null) { - widget.pushToNextWidget!(); + widget.pushToNextWidget!(context); } } @override void didPop() { if (widget.popWidget != null) { - widget.popWidget!(); + widget.popWidget!(context); } } @override void didPopNext() { if (widget.popNextWidget != null) { - widget.popNextWidget!(); + widget.popNextWidget!(context); } } diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index 4578fd3d3..deceec53e 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.15.0" -MONERO_COM_BUILD_NUMBER=90 +MONERO_COM_VERSION="1.15.1" +MONERO_COM_BUILD_NUMBER=91 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.18.0" -CAKEWALLET_BUILD_NUMBER=216 +CAKEWALLET_VERSION="4.18.1" +CAKEWALLET_BUILD_NUMBER=217 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 ef038b6c7..8893d4842 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.15.0" -MONERO_COM_BUILD_NUMBER=88 +MONERO_COM_VERSION="1.15.1" +MONERO_COM_BUILD_NUMBER=89 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.18.0" -CAKEWALLET_BUILD_NUMBER=248 +CAKEWALLET_VERSION="4.18.1" +CAKEWALLET_BUILD_NUMBER=249 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" HAVEN_NAME="Haven" diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh index a04660514..e648f1aa0 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.5.0" -MONERO_COM_BUILD_NUMBER=21 +MONERO_COM_VERSION="1.5.1" +MONERO_COM_BUILD_NUMBER=22 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.11.0" -CAKEWALLET_BUILD_NUMBER=78 +CAKEWALLET_VERSION="1.11.1" +CAKEWALLET_BUILD_NUMBER=79 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then