mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 20:39:51 +00:00
Enhance background sync and wallet initialization across multiple wallet types
- Improve error handling and status checks during background sync - Modify zano init method to not conflict with default init() - Add dev tools for background sync monitoring and manual rescan
This commit is contained in:
parent
6c046662a9
commit
fcc2769597
10 changed files with 266 additions and 23 deletions
|
@ -137,7 +137,7 @@ abstract class HavenWalletBase
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> startSync() async {
|
||||
Future<void> startSync({bool isBackgroundSync = false}) async {
|
||||
try {
|
||||
_setInitialHeight();
|
||||
} catch (_) {}
|
||||
|
|
|
@ -37,7 +37,7 @@ List<monero.SubaddressAccountRow> getAllAccount() {
|
|||
int size = monero.SubaddressAccount_getAll_size(subaddressAccount!);
|
||||
if (size == 0) {
|
||||
monero.Wallet_addSubaddressAccount(wptr!);
|
||||
return getAllAccount();
|
||||
return [];
|
||||
}
|
||||
return List.generate(size, (index) {
|
||||
return monero.SubaddressAccount_getAll_byIndex(subaddressAccount!, index: index);
|
||||
|
|
|
@ -106,10 +106,9 @@ String getAddress({int accountIndex = 0, int addressIndex = 0}) {
|
|||
int count = 0;
|
||||
|
||||
while (monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex) - 1 < addressIndex) {
|
||||
printV("adding subaddress");
|
||||
monero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex);
|
||||
if (count > 50) {
|
||||
throw Exception("Failed to add subaddress");
|
||||
if (count > 10) {
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
@ -198,15 +197,6 @@ void setupBackgroundSync(
|
|||
backgroundCachePassword: backgroundCachePassword);
|
||||
}
|
||||
|
||||
bool isBackgroundSyncing() => monero.Wallet_isBackgroundSyncing(wptr!);
|
||||
|
||||
void startBackgroundSync() {
|
||||
monero.Wallet_startBackgroundSync(wptr!);
|
||||
}
|
||||
|
||||
void stopBackgroundSync(String walletPassword) {
|
||||
monero.Wallet_stopBackgroundSync(wptr!, walletPassword);
|
||||
}
|
||||
|
||||
void stopSync() {
|
||||
monero.Wallet_init(wptr!, daemonAddress: "");
|
||||
|
|
|
@ -232,10 +232,22 @@ abstract class MoneroWalletBase
|
|||
walletPassword: password,
|
||||
backgroundCachePassword: "testing-cache-password",
|
||||
);
|
||||
monero_wallet.startBackgroundSync();
|
||||
monero.Wallet_startBackgroundSync(wptr!);
|
||||
final status = monero.Wallet_status(wptr!);
|
||||
if (status != 0) {
|
||||
final err = monero.Wallet_errorString(wptr!);
|
||||
printV("unable to start background sync: $err");
|
||||
throw Exception("unable to start background sync: $err");
|
||||
}
|
||||
isBackgroundSyncing = true;
|
||||
} else {
|
||||
monero_wallet.stopBackgroundSync(password);
|
||||
monero.Wallet_stopBackgroundSync(wptr!, password);
|
||||
final status = monero.Wallet_status(wptr!);
|
||||
if (status != 0) {
|
||||
final err = monero.Wallet_errorString(wptr!);
|
||||
printV("unable to stop background sync: $err");
|
||||
throw Exception("unable to stop background sync: $err");
|
||||
}
|
||||
isBackgroundSyncing = false;
|
||||
}
|
||||
monero_wallet.startRefresh();
|
||||
|
@ -291,14 +303,20 @@ abstract class MoneroWalletBase
|
|||
|
||||
@override
|
||||
Future<void> stopSync({bool isBackgroundSync = false}) async {
|
||||
syncStatus = NotConnectedSyncStatus();
|
||||
_listener?.stop();
|
||||
if (isBackgroundSync) {
|
||||
print("Stopping background sync");
|
||||
monero.Wallet_stopBackgroundSync(wptr!, password);
|
||||
final status = monero.Wallet_status(wptr!);
|
||||
if (status != 0) {
|
||||
final err = monero.Wallet_errorString(wptr!);
|
||||
printV("unable to stop background sync: $err");
|
||||
throw Exception("unable to stop background sync: $err");
|
||||
}
|
||||
isBackgroundSyncing = false;
|
||||
monero_wallet.stopWallet();
|
||||
monero_wallet.stopBackgroundSync(password);
|
||||
return;
|
||||
}
|
||||
syncStatus = NotConnectedSyncStatus();
|
||||
_listener?.stop();
|
||||
monero_wallet.stopSync();
|
||||
_autoSaveTimer?.cancel();
|
||||
monero_wallet.closeCurrentWallet();
|
||||
|
|
11
lib/di.dart
11
lib/di.dart
|
@ -37,6 +37,7 @@ import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart';
|
|||
import 'package:cake_wallet/entities/wallet_manager.dart';
|
||||
import 'package:cake_wallet/src/screens/buy/buy_sell_options_page.dart';
|
||||
import 'package:cake_wallet/src/screens/buy/payment_method_options_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
|
||||
import 'package:cake_wallet/src/screens/receive/address_list_page.dart';
|
||||
import 'package:cake_wallet/src/screens/seed/seed_verification/seed_verification_page.dart';
|
||||
import 'package:cake_wallet/src/screens/send/transaction_success_info_page.dart';
|
||||
|
@ -45,6 +46,7 @@ import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
|
|||
import 'package:cake_wallet/src/screens/settings/mweb_logs_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/mweb_node_page.dart';
|
||||
import 'package:cake_wallet/src/screens/welcome/welcome_page.dart';
|
||||
import 'package:cake_wallet/view_model/dev/monero_background_sync.dart';
|
||||
import 'package:cake_wallet/view_model/link_view_model.dart';
|
||||
import 'package:cake_wallet/tron/tron.dart';
|
||||
import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
|
||||
|
@ -905,8 +907,9 @@ Future<void> setup({
|
|||
|
||||
getIt.registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
|
||||
|
||||
getIt.registerFactory<SeedSettingsViewModel>(
|
||||
() => SeedSettingsViewModel(getIt.get<AppStore>(), getIt.get<SeedSettingsStore>()));
|
||||
getIt.registerFactory(() => DevMoneroBackgroundSync(getIt.get<AppStore>().wallet!));
|
||||
|
||||
getIt.registerFactory<SeedSettingsViewModel>(() => SeedSettingsViewModel(getIt.get<AppStore>(), getIt.get<SeedSettingsStore>()));
|
||||
|
||||
getIt.registerFactoryParam<WalletSeedPage, bool, void>((bool isWalletCreated, _) =>
|
||||
WalletSeedPage(getIt.get<WalletSeedViewModel>(), isNewWalletCreated: isWalletCreated));
|
||||
|
@ -1416,7 +1419,9 @@ Future<void> setup({
|
|||
|
||||
getIt.registerFactory(() => SignViewModel(getIt.get<AppStore>().wallet!));
|
||||
|
||||
getIt.registerFactory(() => SeedVerificationPage(getIt.get<WalletSeedViewModel>()));
|
||||
getIt.registerFactory(() => SeedVerificationPage(getIt.get<WalletSeedViewModel>()));
|
||||
|
||||
getIt.registerFactory(() => DevMoneroBackgroundSyncPage(getIt.get<DevMoneroBackgroundSync>()));
|
||||
|
||||
_isSetupFinished = true;
|
||||
}
|
|
@ -36,6 +36,7 @@ import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart';
|
|||
import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/sign_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
|
||||
import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
|
||||
|
@ -818,6 +819,11 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
|||
return CupertinoPageRoute<void>(
|
||||
fullscreenDialog: true, builder: (_) => getIt.get<BackgroundSyncPage>());
|
||||
|
||||
case Routes.devMoneroBackgroundSync:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => getIt.get<DevMoneroBackgroundSyncPage>(),
|
||||
);
|
||||
|
||||
default:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => Scaffold(
|
||||
|
|
|
@ -119,4 +119,6 @@ class Routes {
|
|||
static const walletGroupDescription = '/wallet_group_description';
|
||||
static const walletGroupExistingSeedDescriptionPage = '/wallet_group_existing_seed_description_page';
|
||||
static const walletSeedVerificationPage = '/wallet_seed_verification_page';
|
||||
|
||||
static const devMoneroBackgroundSync = '/dev/monero_background_sync';
|
||||
}
|
||||
|
|
112
lib/src/screens/dev/monero_background_sync.dart
Normal file
112
lib/src/screens/dev/monero_background_sync.dart
Normal file
|
@ -0,0 +1,112 @@
|
|||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/view_model/dev/monero_background_sync.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
|
||||
class DevMoneroBackgroundSyncPage extends BasePage {
|
||||
final DevMoneroBackgroundSync viewModel;
|
||||
|
||||
DevMoneroBackgroundSyncPage(this.viewModel);
|
||||
|
||||
@override
|
||||
String? get title => "[dev] xmr background sync";
|
||||
|
||||
Widget _buildSingleCell(String title, String value) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.grey),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(title, style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
Text(value, maxLines: 1, overflow: TextOverflow.ellipsis),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return Observer(
|
||||
builder: (_) {
|
||||
return GridView.count(
|
||||
padding: const EdgeInsets.all(16),
|
||||
crossAxisCount: 2,
|
||||
childAspectRatio: 25/9,
|
||||
crossAxisSpacing: 16,
|
||||
mainAxisSpacing: 16,
|
||||
children: [
|
||||
_buildSingleCell('Height (local)', viewModel.localBlockHeight ?? ''),
|
||||
_buildSingleCell('Height (node)', viewModel.nodeBlockHeight ?? ''),
|
||||
_buildSingleCell('Time', viewModel.tick.toString()),
|
||||
_buildSingleCell('Background Sync', viewModel.isBackgroundSyncing ? 'Enabled' : 'Disabled'),
|
||||
_buildSingleCell('Public View Key', viewModel.publicViewKey ?? ''),
|
||||
_buildSingleCell('Private View Key', viewModel.privateViewKey ?? ''),
|
||||
_buildSingleCell('Public Spend Key', viewModel.publicSpendKey ?? ''),
|
||||
_buildSingleCell('Private Spend Key', viewModel.privateSpendKey ?? ''),
|
||||
_buildSingleCell('Primary Address', viewModel.primaryAddress ?? ''),
|
||||
_buildSingleCell('Passphrase', viewModel.passphrase ?? ''),
|
||||
_buildSingleCell('Seed', viewModel.seed ?? ''),
|
||||
_buildSingleCell('Seed Legacy', viewModel.seedLegacy ?? ''),
|
||||
_enableBackgroundSyncButton(),
|
||||
_disableBackgroundSyncButton(),
|
||||
_refreshButton(),
|
||||
_manualRescanButton(),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
PrimaryButton _enableBackgroundSyncButton() {
|
||||
return PrimaryButton(
|
||||
text: "Enable background sync",
|
||||
color: Colors.purple,
|
||||
textColor: Colors.white,
|
||||
onPressed: () {
|
||||
viewModel.startBackgroundSync();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
PrimaryButton _disableBackgroundSyncButton() {
|
||||
return PrimaryButton(
|
||||
text: "Disable background sync",
|
||||
color: Colors.purple,
|
||||
textColor: Colors.white,
|
||||
onPressed: () {
|
||||
viewModel.stopBackgroundSync();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
PrimaryButton _refreshButton() {
|
||||
return PrimaryButton(
|
||||
text: viewModel.refreshTimer == null ? "Enable refresh" : "Disable refresh",
|
||||
color: Colors.purple,
|
||||
textColor: Colors.white,
|
||||
onPressed: () {
|
||||
if (viewModel.refreshTimer == null) {
|
||||
viewModel.startRefreshTimer();
|
||||
} else {
|
||||
viewModel.stopRefreshTimer();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
PrimaryButton _manualRescanButton() {
|
||||
return PrimaryButton(
|
||||
text: "Manual rescan",
|
||||
color: Colors.purple,
|
||||
textColor: Colors.white,
|
||||
onPressed: () {
|
||||
viewModel.manualRescan();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.
|
|||
import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.dart';
|
||||
import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
|
||||
|
@ -63,6 +64,12 @@ class OtherSettingsPage extends BasePage {
|
|||
handler: (BuildContext context) =>
|
||||
Navigator.of(context).pushNamed(Routes.readDisclaimer),
|
||||
),
|
||||
if (kDebugMode && _otherSettingsViewModel.walletType == WalletType.monero)
|
||||
SettingsCellWithArrow(
|
||||
title: '[dev] monero background sync',
|
||||
handler: (BuildContext context) =>
|
||||
Navigator.of(context).pushNamed(Routes.devMoneroBackgroundSync),
|
||||
),
|
||||
Spacer(),
|
||||
SettingsVersionCell(
|
||||
title: S.of(context).version(_otherSettingsViewModel.currentVersion)),
|
||||
|
|
103
lib/view_model/dev/monero_background_sync.dart
Normal file
103
lib/view_model/dev/monero_background_sync.dart
Normal file
|
@ -0,0 +1,103 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cw_monero/monero_wallet.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
|
||||
part 'monero_background_sync.g.dart';
|
||||
|
||||
class DevMoneroBackgroundSync = DevMoneroBackgroundSyncBase with _$DevMoneroBackgroundSync;
|
||||
|
||||
abstract class DevMoneroBackgroundSyncBase with Store {
|
||||
DevMoneroBackgroundSyncBase(WalletBase wallet) : wallet = wallet;
|
||||
|
||||
final WalletBase wallet;
|
||||
|
||||
@observable
|
||||
Timer? refreshTimer;
|
||||
|
||||
@observable
|
||||
String? localBlockHeight;
|
||||
|
||||
@observable
|
||||
String? nodeBlockHeight;
|
||||
|
||||
@observable
|
||||
String? primaryAddress;
|
||||
|
||||
@observable
|
||||
String? publicViewKey;
|
||||
|
||||
@observable
|
||||
String? privateViewKey;
|
||||
|
||||
@observable
|
||||
String? publicSpendKey;
|
||||
|
||||
@observable
|
||||
String? privateSpendKey;
|
||||
|
||||
@observable
|
||||
String? passphrase;
|
||||
|
||||
@observable
|
||||
String? seed;
|
||||
|
||||
@observable
|
||||
String? seedLegacy;
|
||||
|
||||
@observable
|
||||
int tick = -1;
|
||||
|
||||
@observable
|
||||
bool isBackgroundSyncing = false;
|
||||
|
||||
Future<void> _setValues() async {
|
||||
final w = (wallet as MoneroWallet);
|
||||
localBlockHeight = (await monero!.getCurrentHeight()).toString();
|
||||
nodeBlockHeight = (await w.getNodeHeight()).toString();
|
||||
final keys = w.keys;
|
||||
primaryAddress = keys.primaryAddress;
|
||||
publicViewKey = keys.publicViewKey;
|
||||
privateViewKey = keys.privateViewKey;
|
||||
publicSpendKey = keys.publicSpendKey;
|
||||
privateSpendKey = keys.privateSpendKey;
|
||||
passphrase = keys.passphrase;
|
||||
seed = w.seed;
|
||||
seedLegacy = w.seedLegacy("English");
|
||||
tick = refreshTimer?.tick ?? -1;
|
||||
isBackgroundSyncing = w.isBackgroundSyncing;
|
||||
}
|
||||
|
||||
@action
|
||||
void manualRescan() async {
|
||||
final w = (wallet as MoneroWallet);
|
||||
wallet.rescan(height: await w.getNodeHeight() - 10000);
|
||||
}
|
||||
|
||||
@action
|
||||
void startRefreshTimer() {
|
||||
refreshTimer = Timer.periodic(Duration(seconds: 1), (timer) async {
|
||||
await _setValues();
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
void stopRefreshTimer() {
|
||||
refreshTimer?.cancel();
|
||||
refreshTimer = null;
|
||||
}
|
||||
|
||||
@action
|
||||
void startBackgroundSync() {
|
||||
final w = (wallet as MoneroWallet);
|
||||
w.startSync(isBackgroundSync: true);
|
||||
}
|
||||
|
||||
@action
|
||||
void stopBackgroundSync() {
|
||||
final w = (wallet as MoneroWallet);
|
||||
w.stopSync(isBackgroundSync: true);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue