Skip to content

Commit

Permalink
Lazy Restore
Browse files Browse the repository at this point in the history
  • Loading branch information
ppupha committed Sep 9, 2024
1 parent f3ba33d commit d792f99
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 3 deletions.
35 changes: 34 additions & 1 deletion lib/screen/onboarding_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import 'dart:async';
import 'package:autonomy_flutter/common/injector.dart';
import 'package:autonomy_flutter/screen/app_router.dart';
import 'package:autonomy_flutter/service/account_service.dart';
import 'package:autonomy_flutter/service/address_service.dart';
import 'package:autonomy_flutter/service/configuration_service.dart';
import 'package:autonomy_flutter/service/deeplink_service.dart';
import 'package:autonomy_flutter/service/metric_client_service.dart';
import 'package:autonomy_flutter/util/log.dart';
import 'package:autonomy_flutter/util/wallet_utils.dart';
import 'package:autonomy_flutter/view/back_appbar.dart';
import 'package:autonomy_flutter/view/primary_button.dart';
import 'package:autonomy_flutter/view/responsive.dart';
Expand Down Expand Up @@ -71,8 +73,39 @@ class _OnboardingPageState extends State<OnboardingPage>
}
}

/*
- When user did onboarded:
Case 1: user kill app and reopen, we will have restore in background:
Restore mean that we need sync data from keychain and cloud database (that modified in other device)
In this case, we will restore from keychain and cloud in background.
We have to force update because we need to make sure that we have the latest data from cloud
- When user did not onboarded: we will check if user has primary address in keychain
Case 2: Primary Address not found: new user, create default persona:
Case 3: Primary address found: user has backup, we will wait until restore from cloud
*/
Future<void> _createAccountOrRestoreIfNeeded() async {
await injector<AccountService>().restoreIfNeeded();
final isDoneOnboarding =
injector<ConfigurationService>().isDoneNewOnboarding();
if (isDoneOnboarding) {
// existing user
// do this in background, don't await restore
unawaited(injector<AccountService>().restore());
} else {
final primaryAddress =
await injector<AddressService>().getPrimaryAddress();
if (primaryAddress == null) {
// new user
final persona = await injector<AccountService>().createDefaultPersona();
await persona.insertNextAddress(WalletType.Tezos);
await persona.insertNextAddress(WalletType.Ethereum);
} else {
// restore user
// in this case, we have to wait until restore is done
await injector<AccountService>().restoreIfNeeded();
}
}
if (!mounted) {
return;
}
Expand Down
25 changes: 23 additions & 2 deletions lib/service/account_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// that can be found in the LICENSE file.
//

// ignore_for_file: lines_longer_than_80_chars

import 'dart:async';
import 'dart:io';

Expand Down Expand Up @@ -113,6 +115,10 @@ abstract class AccountService {

Future<void> updateAddressPersona(WalletAddress walletAddress);

Future<List<Persona>> restore();

Future<Persona> createDefaultPersona();

Future<void> restoreIfNeeded();

Future<List<Connection>> getAllViewOnlyAddresses();
Expand Down Expand Up @@ -724,13 +730,19 @@ class AccountServiceImpl extends AccountService {
}

@override
Future<void> restoreIfNeeded() async {
final iapService = injector<IAPService>();
Future<List<Persona>> restore() async {
final auditService = injector<AuditService>();
final migrationUtil = MigrationUtil(_cloudDB, auditService);
await androidRestoreKeys();
await migrationUtil.migrationFromKeychain();
final personas = await _cloudDB.personaDao.getPersonas();
return personas;
}

@override
Future<void> restoreIfNeeded() async {
await restore();
final personas = await _cloudDB.personaDao.getPersonas();

final hasPersona = personas.isNotEmpty;
if (!hasPersona) {
Expand Down Expand Up @@ -793,9 +805,18 @@ class AccountServiceImpl extends AccountService {
.initIfDefaultAccount());
}

final iapService = injector<IAPService>();
unawaited(iapService.restore());
}

@override
Future<Persona> createDefaultPersona() async {
final persona = await createPersona(isDefault: true);
await persona.insertNextAddress(WalletType.Tezos);
await persona.insertNextAddress(WalletType.Ethereum);
return persona;
}

@override
Future<WalletAddress?> getAddressPersona(String address) async =>
await _cloudDB.addressDao.findByAddress(address);
Expand Down

0 comments on commit d792f99

Please sign in to comment.