diff --git a/cw_core/lib/wallet_base.dart b/cw_core/lib/wallet_base.dart index 16c794a25..02fd43454 100644 --- a/cw_core/lib/wallet_base.dart +++ b/cw_core/lib/wallet_base.dart @@ -60,6 +60,14 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans bool get isHardwareWallet => walletInfo.isHardwareWallet; + bool get hasRescan => + walletInfo.type == WalletType.bitcoin || + walletInfo.type == WalletType.litecoin || + walletInfo.type == WalletType.monero || + walletInfo.type == WalletType.wownero || + walletInfo.type == WalletType.decred || + walletInfo.type == WalletType.haven; + Future<void> connectToNode({required Node node}); // there is a default definition here because only coins with a pow node (nano based) need to override this diff --git a/cw_decred/lib/wallet.dart b/cw_decred/lib/wallet.dart index a0aaaaad5..e151d5a2e 100644 --- a/cw_decred/lib/wallet.dart +++ b/cw_decred/lib/wallet.dart @@ -426,6 +426,9 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance, @override Future<void> save() async {} + @override + bool get hasRescan => walletBirthdayBlockHeight() != -1; + @override Future<void> rescan({required int height}) async { // The required height is not used. A birthday time is recorded in the @@ -433,12 +436,10 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance, // can always rescan from there. var rescanHeight = 0; if (!watchingOnly) { - final res = libdcrwallet.birthState(walletInfo.name); - final decoded = json.decode(res); - if (decoded["setfromheight"] == true || decoded["setfromtime"] == true) { + rescanHeight = walletBirthdayBlockHeight(); + if (rescanHeight == -1) { throw "cannot rescan before the birthday block has been set"; } - rescanHeight = decoded["height"] ?? 0; } libdcrwallet.rescanFromHeight(walletInfo.name, rescanHeight.toString()); } @@ -502,7 +503,7 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance, throw "unable to get an address from unsynced wallet"; } return libdcrwallet.signMessageAsync( - walletInfo.name, message, addr!, _password); + walletInfo.name, message, addr, _password); } List<Unspent> unspents() { @@ -582,6 +583,17 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance, unspentCoinsInfo.add(newInfo); } + // walletBirthdayBlockHeight checks if the wallet birthday is set and returns + // it. Returns -1 if not. + int walletBirthdayBlockHeight() { + final res = libdcrwallet.birthState(walletInfo.name); + final decoded = json.decode(res); + if (decoded["setfromheight"] == true || decoded["setfromtime"] == true) { + return -1; + } + return decoded["height"] ?? 0; + } + @override Future<bool> verifyMessage(String message, String signature, {String? address = null}) { return true; diff --git a/lib/src/screens/rescan/rescan_page.dart b/lib/src/screens/rescan/rescan_page.dart index dcdecf820..289fd4a11 100644 --- a/lib/src/screens/rescan/rescan_page.dart +++ b/lib/src/screens/rescan/rescan_page.dart @@ -25,52 +25,55 @@ class RescanPage extends BasePage { @override Widget body(BuildContext context) { - var child = Padding( - padding: EdgeInsets.only(left: 24, right: 24, bottom: 24), - child: - Column(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Observer( - builder: (_) => BlockchainHeightWidget( - type: this.type, - key: _blockchainHeightWidgetKey, - onHeightOrDateEntered: (value) => - _rescanViewModel.isButtonEnabled = value, - isSilentPaymentsScan: _rescanViewModel.isSilentPaymentsScan, - isMwebScan: _rescanViewModel.isMwebScan, - doSingleScan: _rescanViewModel.doSingleScan, - hasDatePicker: !_rescanViewModel - .isMwebScan, // disable date picker for mweb for now - toggleSingleScan: () => _rescanViewModel.doSingleScan = - !_rescanViewModel.doSingleScan, - walletType: _rescanViewModel.wallet.type, - bitcoinMempoolAPIEnabled: - _rescanViewModel.isBitcoinMempoolAPIEnabled, - )), - Observer( - builder: (_) => LoadingPrimaryButton( - isLoading: - _rescanViewModel.state == RescanWalletState.rescaning, - text: S.of(context).rescan, - onPressed: () async { - if (_rescanViewModel.isSilentPaymentsScan) { - return _toggleSilentPaymentsScanning(context); - } - - _rescanViewModel.rescanCurrentWallet( - restoreHeight: - _blockchainHeightWidgetKey.currentState!.height); - - Navigator.of(context).pop(); - }, - color: Theme.of(context).primaryColor, - textColor: Colors.white, - isDisabled: !_rescanViewModel.isButtonEnabled, - )) - ]), - ); - if (type == WalletType.decred) { + var child; + if (type != WalletType.decred) { child = Padding( padding: EdgeInsets.only(left: 24, right: 24, bottom: 24), + child: + Column(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Observer( + builder: (_) => BlockchainHeightWidget( + type: this.type, + key: _blockchainHeightWidgetKey, + onHeightOrDateEntered: (value) => + _rescanViewModel.isButtonEnabled = value, + isSilentPaymentsScan: _rescanViewModel.isSilentPaymentsScan, + isMwebScan: _rescanViewModel.isMwebScan, + doSingleScan: _rescanViewModel.doSingleScan, + hasDatePicker: !_rescanViewModel + .isMwebScan, // disable date picker for mweb for now + toggleSingleScan: () => _rescanViewModel.doSingleScan = + !_rescanViewModel.doSingleScan, + walletType: _rescanViewModel.wallet.type, + bitcoinMempoolAPIEnabled: + _rescanViewModel.isBitcoinMempoolAPIEnabled, + )), + Observer( + builder: (_) => LoadingPrimaryButton( + isLoading: + _rescanViewModel.state == RescanWalletState.rescaning, + text: S.of(context).rescan, + onPressed: () async { + if (_rescanViewModel.isSilentPaymentsScan) { + return _toggleSilentPaymentsScanning(context); + } + + _rescanViewModel.rescanCurrentWallet( + restoreHeight: + _blockchainHeightWidgetKey.currentState!.height); + + Navigator.of(context).pop(); + }, + color: Theme.of(context).primaryColor, + textColor: Colors.white, + isDisabled: !_rescanViewModel.isButtonEnabled, + )) + ]), + ); + } else { + child = Center( + child: Padding( + padding: EdgeInsets.only(left: 24, right: 24, bottom: 24), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -89,7 +92,7 @@ class RescanPage extends BasePage { textColor: Colors.white, )) ]), - ); + )); } return GestureDetector( behavior: HitTestBehavior.opaque, diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 69e3dcf2f..f84ed6bd2 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -383,13 +383,7 @@ abstract class DashboardViewModelBase with Store { bool get isTestnet => wallet.type == WalletType.bitcoin && bitcoin!.isTestnet(wallet); @computed - bool get hasRescan => - wallet.type == WalletType.bitcoin || - wallet.type == WalletType.monero || - wallet.type == WalletType.litecoin || - wallet.type == WalletType.wownero || - wallet.type == WalletType.decred || - wallet.type == WalletType.haven; + bool get hasRescan => wallet.hasRescan; @computed bool get isMoneroViewOnly {