diff --git a/lib/common/injector.dart b/lib/common/injector.dart index 8190ea90f..68ae0255b 100644 --- a/lib/common/injector.dart +++ b/lib/common/injector.dart @@ -44,6 +44,7 @@ import 'package:autonomy_flutter/service/activation_service.dart'; import 'package:autonomy_flutter/service/address_service.dart'; import 'package:autonomy_flutter/service/airdrop_service.dart'; import 'package:autonomy_flutter/service/audit_service.dart'; +import 'package:autonomy_flutter/service/auth_firebase_service.dart'; import 'package:autonomy_flutter/service/auth_service.dart'; import 'package:autonomy_flutter/service/autonomy_service.dart'; import 'package:autonomy_flutter/service/backup_service.dart'; @@ -170,8 +171,10 @@ Future setup() async { () => NftCollection.database.predefinedCollectionDao); injector.registerLazySingleton(() => cloudDB); + injector + .registerLazySingleton(() => AuthFirebaseService()); injector.registerLazySingleton( - () => CloudFirestoreService(FirebaseFirestore.instance)); + () => CloudFirestoreService(FirebaseFirestore.instance, injector())); injector.registerLazySingleton( () => FirestorePersonaDaoImp(injector())); diff --git a/lib/database/dao/firestore_persona_dao.dart b/lib/database/dao/firestore_persona_dao.dart index 38ed75294..b180730d7 100644 --- a/lib/database/dao/firestore_persona_dao.dart +++ b/lib/database/dao/firestore_persona_dao.dart @@ -46,10 +46,17 @@ class FirestorePersonaDaoImp implements FirestorePersonaDao { ); @override - Future> getDefaultPersonas() async => - _collectionRef.where('defaultAccount', isEqualTo: 1).get().then( - (snapshot) => snapshot.docs.map((e) => e.data()).toList(), - ); + Future> getDefaultPersonas() async { + try { + final personas = + await _collectionRef.where('defaultAccount', isEqualTo: 1).get().then( + (snapshot) => snapshot.docs.map((e) => e.data()).toList(), + ); + return personas; + } catch (e) { + return []; + } + } @override Future getPersonasCount() async => _collectionRef.get().then( diff --git a/lib/main.dart b/lib/main.dart index c1a153a84..7b76ef1ae 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -14,6 +14,7 @@ import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/firebase_options.dart'; import 'package:autonomy_flutter/model/eth_pending_tx_amount.dart'; import 'package:autonomy_flutter/screen/app_router.dart'; +import 'package:autonomy_flutter/service/auth_firebase_service.dart'; import 'package:autonomy_flutter/service/cloud_firestore_service.dart'; import 'package:autonomy_flutter/service/configuration_service.dart'; import 'package:autonomy_flutter/service/deeplink_service.dart'; @@ -83,7 +84,7 @@ void main() async { await _setupApp(); }, (Object error, StackTrace stackTrace) async { /// Check error is Database issue - if (error.toString().contains("DatabaseException")) { + if (error.toString().contains('DatabaseException')) { log.info('[DatabaseException] Remove local database and resume app'); await _deleteLocalDatabase(); @@ -104,17 +105,18 @@ void _registerHiveAdapter() { ..registerAdapter(EthereumPendingTxListAdapter()); } -_setupApp() async { +Future _setupApp() async { await setup(); await DeviceInfo.instance.init(); await injector().initService(); + await injector().initService(); final metricClient = injector.get(); await metricClient.initService(); await injector().loadConfigs(); final countOpenApp = injector().countOpenApp() ?? 0; - injector().setCountOpenApp(countOpenApp + 1); + unawaited(injector().setCountOpenApp(countOpenApp + 1)); final packageInfo = await PackageInfo.fromPlatform(); await injector().setVersionInfo(packageInfo.version); final notificationService = injector(); @@ -126,10 +128,11 @@ _setupApp() async { await SentryFlutter.init( (options) { - options.dsn = Environment.sentryDSN; - options.enableAutoSessionTracking = true; - options.tracesSampleRate = 0.25; - options.attachStacktrace = true; + options + ..dsn = Environment.sentryDSN + ..enableAutoSessionTracking = true + ..tracesSampleRate = 0.25 + ..attachStacktrace = true; }, appRunner: () => runApp(EasyLocalization( supportedLocales: const [Locale('en', 'US')], @@ -141,7 +144,7 @@ _setupApp() async { Sentry.configureScope((scope) async { final deviceID = await getDeviceID(); if (deviceID != null) { - scope.setUser(SentryUser(id: deviceID)); + unawaited(scope.setUser(SentryUser(id: deviceID))); } }); FlutterNativeSplash.remove(); @@ -154,9 +157,9 @@ _setupApp() async { Future _deleteLocalDatabase() async { String appDatabaseMainnet = - await sqfliteDatabaseFactory.getDatabasePath("app_database_mainnet.db"); + await sqfliteDatabaseFactory.getDatabasePath('app_database_mainnet.db'); String appDatabaseTestnet = - await sqfliteDatabaseFactory.getDatabasePath("app_database_testnet.db"); + await sqfliteDatabaseFactory.getDatabasePath('app_database_testnet.db'); await sqfliteDatabaseFactory.deleteDatabase(appDatabaseMainnet); await sqfliteDatabaseFactory.deleteDatabase(appDatabaseTestnet); } @@ -196,7 +199,7 @@ class AutonomyApp extends StatelessWidget { final RouteObserver> routeObserver = CustomRouteObserver>(); -var memoryValues = MemoryValues( +MemoryValues memoryValues = MemoryValues( branchDeeplinkData: ValueNotifier(null), deepLink: ValueNotifier(null), irlLink: ValueNotifier(null)); @@ -233,10 +236,6 @@ class MemoryValues { ); } -enum HomePageTab { - HOME, -} - enum HomeNavigatorTab { collection, organization, @@ -251,5 +250,3 @@ void downloadCallback(String id, int status, int progress) { IsolateNameServer.lookupPortByName('downloader_send_port'); send?.send([id, status, progress]); } - -void imageError(Object exception, StackTrace? stackTrace) {} diff --git a/lib/screen/app_router.dart b/lib/screen/app_router.dart index 61910f2be..262e8221f 100644 --- a/lib/screen/app_router.dart +++ b/lib/screen/app_router.dart @@ -886,7 +886,11 @@ class AppRouter { return CupertinoPageRoute( settings: settings, builder: (context) => BlocProvider( - create: (_) => KeySyncBloc(injector(), injector()), + create: (_) => KeySyncBloc( + injector(), + injector(), + injector(), + ), child: const KeySyncPage(), )); diff --git a/lib/screen/bloc/router/router_bloc.dart b/lib/screen/bloc/router/router_bloc.dart index c7c7139d7..54d2bcea4 100644 --- a/lib/screen/bloc/router/router_bloc.dart +++ b/lib/screen/bloc/router/router_bloc.dart @@ -63,42 +63,43 @@ class RouterBloc extends AuBloc { if (state.onboardingStep != OnboardingStep.undefined) { return; } + final defaultPersona = await _accountService.getDefaultPersona(); + if (defaultPersona != null) { + await _cloudFirestoreService.authFiresabeService + .signInWithPersona(defaultPersona); + await migrationUtil.migrateIfNeeded(); - await migrationUtil.migrateIfNeeded(); - - // Check and restore full accounts from cloud if existing - await migrationUtil.migrationFromKeychain(); - await _accountService.androidRestoreKeys(); + // Check and restore full accounts from cloud if existing + await migrationUtil.migrationFromKeychain(); + await _accountService.androidRestoreKeys(); - if (_configurationService.isDoneOnboarding()) { - emit(RouterState(onboardingStep: OnboardingStep.dashboard)); - return; - } - - //Soft delay 1s waiting for database synchronizing - await Future.delayed(const Duration(seconds: 1)); - - if (await hasAccounts()) { - unawaited(_configurationService.setOldUser()); - final backupVersion = await _backupService - .fetchBackupVersion(await _accountService.getDefaultAccount()); - if (backupVersion.isNotEmpty) { - log.info('[DefineViewRoutingEvent] have backup version'); - //restore backup database - emit(RouterState( - onboardingStep: OnboardingStep.restore, - backupVersion: backupVersion)); - add(RestoreCloudDatabaseRoutingEvent(backupVersion)); - return; - } else { - await _cloudFirestoreService.setAlreadyBackupFromSqlite(); - await _configurationService.setDoneOnboarding(true); - unawaited(injector() - .mixPanelClient - .initIfDefaultAccount()); + if (_configurationService.isDoneOnboarding()) { emit(RouterState(onboardingStep: OnboardingStep.dashboard)); return; } + + //Soft delay 1s waiting for database synchronizing + await Future.delayed(const Duration(seconds: 1)); + + if (await hasAccounts()) { + unawaited(_configurationService.setOldUser()); + final backupVersion = await _backupService + .fetchBackupVersion(await _accountService.getDefaultAccount()); + if (backupVersion.isNotEmpty) { + log.info('[DefineViewRoutingEvent] have backup version'); + //restore backup database + emit(RouterState( + onboardingStep: OnboardingStep.restore, + backupVersion: backupVersion)); + add(RestoreCloudDatabaseRoutingEvent(backupVersion)); + return; + } else { + await _cloudFirestoreService.setAlreadyBackupFromSqlite(); + await _configurationService.setDoneOnboarding(true); + emit(RouterState(onboardingStep: OnboardingStep.dashboard)); + return; + } + } } else { emit(RouterState(onboardingStep: OnboardingStep.startScreen)); } @@ -132,9 +133,9 @@ class RouterBloc extends AuBloc { return; } await _configurationService.setDoneOnboarding(true); - unawaited(injector() - .mixPanelClient - .initIfDefaultAccount()); + // unawaited(injector() + // .mixPanelClient + // .initIfDefaultAccount()); emit(RouterState(onboardingStep: OnboardingStep.dashboard)); } await migrationUtil.migrateIfNeeded(); diff --git a/lib/screen/claim/activation/claim_activation_page.dart b/lib/screen/claim/activation/claim_activation_page.dart index 161fbdc61..ef22dcdb5 100644 --- a/lib/screen/claim/activation/claim_activation_page.dart +++ b/lib/screen/claim/activation/claim_activation_page.dart @@ -1,5 +1,7 @@ // ignore_for_file: discarded_futures, unawaited_futures +import 'dart:async'; + import 'package:auto_size_text/auto_size_text.dart'; import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/gateway/activation_api.dart'; @@ -161,8 +163,8 @@ class _ClaimActivationPageState extends State { minFontSize: 14, maxLines: 2, ), - onTap: () { - Navigator.push( + onTap: () async { + await Navigator.push( context, MaterialPageRoute( builder: (context) => @@ -224,12 +226,12 @@ class _ClaimActivationPageState extends State { enabled: !_processing, isProcessing: _processing, onTap: () async { - _metricClient.addEvent( + unawaited(_metricClient.addEvent( MixpanelEvent.acceptOwnership, data: { 'id': widget.payload.assetToken.id, }, - ); + )); setState(() { _processing = true; }); @@ -247,7 +249,7 @@ class _ClaimActivationPageState extends State { ? WalletType.Tezos : WalletType.Ethereum); await _configService.setDoneOnboarding(true); - _metricClient.mixPanelClient.initIfDefaultAccount(); + //_metricClient.mixPanelClient.initIfDefaultAccount(); await _configService.setPendingSettings(true); address = walletAddress.first.address; } else if (addresses.length == 1) { @@ -267,7 +269,7 @@ class _ClaimActivationPageState extends State { } if (address != null && mounted) { - _claimActivation( + await _claimActivation( context: context, activationID: widget.payload.activationID, receiveAddress: address, @@ -303,12 +305,12 @@ class _ClaimActivationPageState extends State { enabled: !_processing, color: theme.colorScheme.primary, onTap: () { - _metricClient.addEvent( + unawaited(_metricClient.addEvent( MixpanelEvent.declineOwnership, data: { 'id': widget.payload.assetToken.id, }, - ); + )); memoryValues.branchDeeplinkData.value = null; Navigator.of(context).pop(false); }, @@ -334,12 +336,12 @@ class _ClaimActivationPageState extends State { ), assetToken: assetToken, ); - _metricClient.addEvent( + unawaited(_metricClient.addEvent( MixpanelEvent.acceptOwnershipSuccess, data: { 'id': widget.payload.assetToken.id, }, - ); + )); } catch (e) { setState(() { _processing = false; @@ -350,7 +352,7 @@ class _ClaimActivationPageState extends State { _processing = false; }); if (mounted) { - Navigator.of(context).pushNamedAndRemoveUntil( + await Navigator.of(context).pushNamedAndRemoveUntil( AppRouter.homePage, (route) => false, ); @@ -358,7 +360,10 @@ class _ClaimActivationPageState extends State { .add(GetTokensByOwnerEvent(pageKey: PageKey.init())); final token = widget.payload.assetToken; const caption = ''; - Navigator.of(context).pushNamed(AppRouter.artworkDetailsPage, + if (!mounted) { + return; + } + await Navigator.of(context).pushNamed(AppRouter.artworkDetailsPage, arguments: ArtworkDetailPayload( [ArtworkIdentity(token.id, receiveAddress)], 0, twitterCaption: caption)); diff --git a/lib/screen/claim/airdrop/claim_airdrop_page.dart b/lib/screen/claim/airdrop/claim_airdrop_page.dart index a71f70337..009e1e0fc 100644 --- a/lib/screen/claim/airdrop/claim_airdrop_page.dart +++ b/lib/screen/claim/airdrop/claim_airdrop_page.dart @@ -268,8 +268,7 @@ class _ClaimAirdropPageState extends State { ? WalletType.Tezos : WalletType.Ethereum); await _configService.setDoneOnboarding(true); - unawaited(_metricClient.mixPanelClient - .initIfDefaultAccount()); + //_metricClient.mixPanelClient.initIfDefaultAccount(); await _configService.setPendingSettings(true); address = walletAddress.first.address; } else if (addresses.length == 1) { @@ -323,8 +322,8 @@ class _ClaimAirdropPageState extends State { theme.textTheme.ppMori400Grey12, ), recognizer: TapGestureRecognizer() - ..onTap = () { - _openFFArtistCollector(); + ..onTap = () async { + await _openFFArtistCollector(); }), TextSpan( text: '.', @@ -409,10 +408,10 @@ class _ClaimAirdropPageState extends State { } } - void _openFFArtistCollector() { + Future _openFFArtistCollector() async { String uri = (widget.payload.series.exhibition?.id == null) ? FF_ARTIST_COLLECTOR : '$FF_ARTIST_COLLECTOR/${widget.payload.series.exhibition?.id}'; - unawaited(launchUrl(Uri.parse(uri), mode: LaunchMode.externalApplication)); + await launchUrl(Uri.parse(uri), mode: LaunchMode.externalApplication); } } diff --git a/lib/screen/claim/claim_token_page.dart b/lib/screen/claim/claim_token_page.dart index 9577cbe98..3cfa56ed7 100644 --- a/lib/screen/claim/claim_token_page.dart +++ b/lib/screen/claim/claim_token_page.dart @@ -279,9 +279,9 @@ class _ClaimTokenPageState extends State { final configService = injector(); await configService.setDoneOnboarding(true); - unawaited(injector() - .mixPanelClient - .initIfDefaultAccount()); + // injector() + // .mixPanelClient + // .initIfDefaultAccount(); await configService.setPendingSettings(true); address = walletAddress.first.address; } else if (addresses.length == 1) { @@ -332,7 +332,7 @@ class _ClaimTokenPageState extends State { theme.textTheme.ppMori400Grey12, ), recognizer: TapGestureRecognizer() - ..onTap = () { + ..onTap = () async { _openFFArtistCollector(); }), TextSpan( diff --git a/lib/screen/interactive_postcard/claim_empty_postcard/claim_empty_postcard_bloc.dart b/lib/screen/interactive_postcard/claim_empty_postcard/claim_empty_postcard_bloc.dart index 2b26ecdb3..84fb025f1 100644 --- a/lib/screen/interactive_postcard/claim_empty_postcard/claim_empty_postcard_bloc.dart +++ b/lib/screen/interactive_postcard/claim_empty_postcard/claim_empty_postcard_bloc.dart @@ -8,7 +8,6 @@ import 'package:autonomy_flutter/model/postcard_metadata.dart'; import 'package:autonomy_flutter/screen/app_router.dart'; import 'package:autonomy_flutter/service/account_service.dart'; import 'package:autonomy_flutter/service/configuration_service.dart'; -import 'package:autonomy_flutter/service/metric_client_service.dart'; import 'package:autonomy_flutter/service/navigation_service.dart'; import 'package:autonomy_flutter/service/postcard_service.dart'; import 'package:autonomy_flutter/util/log.dart'; @@ -119,9 +118,9 @@ class ClaimEmptyPostCardBloc final defaultPersona = await accountService.getOrCreateDefaultPersona(); await configService.setDoneOnboarding(true); await configService.setPendingSettings(true); - await injector() - .mixPanelClient - .initIfDefaultAccount(); + // await injector() + // .mixPanelClient + // .initIfDefaultAccount(); final walletAddress = await defaultPersona.insertNextAddress(WalletType.Tezos); diff --git a/lib/screen/migration/key_sync_bloc.dart b/lib/screen/migration/key_sync_bloc.dart index bef54440e..7bfb496d5 100644 --- a/lib/screen/migration/key_sync_bloc.dart +++ b/lib/screen/migration/key_sync_bloc.dart @@ -8,13 +8,16 @@ import 'package:autonomy_flutter/au_bloc.dart'; import 'package:autonomy_flutter/database/cloud_database.dart'; import 'package:autonomy_flutter/screen/migration/key_sync_state.dart'; +import 'package:autonomy_flutter/service/auth_firebase_service.dart'; import 'package:autonomy_flutter/service/backup_service.dart'; class KeySyncBloc extends AuBloc { final BackupService _backupService; final CloudDatabase _cloudDatabase; + final AuthFirebaseService _authFirebaseService; - KeySyncBloc(this._backupService, this._cloudDatabase) + KeySyncBloc( + this._backupService, this._cloudDatabase, this._authFirebaseService) : super(KeySyncState(true, null, true)) { on((event, emit) async { emit(state.copyWith(isLocalSelected: state.isLocalSelectedTmp)); @@ -28,19 +31,23 @@ class KeySyncBloc extends AuBloc { emit(state.copyWith( isProcessing: true, isLocalSelectedTmp: state.isLocalSelected)); - final accounts = await _cloudDatabase.personaDao.getDefaultPersonas(); - if (accounts.length < 2) return; + final defaultPersonaes = + await _cloudDatabase.personaDao.getDefaultPersonas(); + if (defaultPersonaes.length < 2) { + return; + } + final localDefaultPersona = defaultPersonaes[0]; + final cloudDefaultPersona = defaultPersonaes[1]; - final cloudWallet = accounts[1].wallet(); + final cloudWallet = cloudDefaultPersona.wallet(); + final localWallet = localDefaultPersona.wallet(); if (state.isLocalSelected) { - final cloudDefaultPersona = accounts[1]; await _backupService.deleteAllProfiles(cloudWallet); cloudDefaultPersona.defaultAccount = null; await _cloudDatabase.personaDao.updatePersona(cloudDefaultPersona); } else { - final localDefaultPersona = accounts[0]; - await _backupService.deleteAllProfiles(localDefaultPersona.wallet()); + await _backupService.deleteAllProfiles(localWallet); localDefaultPersona.defaultAccount = null; await _cloudDatabase.personaDao.updatePersona(localDefaultPersona); } diff --git a/lib/screen/migration/key_sync_page.dart b/lib/screen/migration/key_sync_page.dart index 099297784..839b3d6e2 100644 --- a/lib/screen/migration/key_sync_page.dart +++ b/lib/screen/migration/key_sync_page.dart @@ -80,8 +80,8 @@ class KeySyncPage extends StatelessWidget { borderRadius: const BorderRadius.all(Radius.circular(5))), child: GestureDetector( - onTap: () { - UIHelper.showDialog( + onTap: () async { + await UIHelper.showDialog( context, 'select_wallet_type'.tr(), SelectKeychainView( @@ -147,7 +147,7 @@ class KeySyncPage extends StatelessWidget { ), const SizedBox(height: 12), TextButton( - onPressed: () => Navigator.of(context) + onPressed: () async => Navigator.of(context) .pushNamed(AppRouter.autonomySecurityPage), style: TextButton.styleFrom( minimumSize: Size.zero, diff --git a/lib/screen/onboarding/view_address/view_existing_address_bloc.dart b/lib/screen/onboarding/view_address/view_existing_address_bloc.dart index c52e67939..0ea3cb664 100644 --- a/lib/screen/onboarding/view_address/view_existing_address_bloc.dart +++ b/lib/screen/onboarding/view_address/view_existing_address_bloc.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:autonomy_flutter/au_bloc.dart'; +import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/model/address.dart'; import 'package:autonomy_flutter/screen/onboarding/view_address/view_existing_address_state.dart'; import 'package:autonomy_flutter/service/account_service.dart'; @@ -59,6 +60,7 @@ class ViewExistingAddressBloc )); try { + await injector().getOrCreateDefaultPersona(); final connection = await _accountService.linkManuallyAddress( state.address, state.type!, name: state.domain); diff --git a/lib/screen/settings/data_management/data_management_page.dart b/lib/screen/settings/data_management/data_management_page.dart index 82cef5113..919025454 100644 --- a/lib/screen/settings/data_management/data_management_page.dart +++ b/lib/screen/settings/data_management/data_management_page.dart @@ -115,6 +115,7 @@ class _DataManagementPageState extends State { injector(), injector().database, injector(), + injector(), injector()), child: const ForgetExistView(), ), diff --git a/lib/screen/settings/forget_exist/forget_exist_bloc.dart b/lib/screen/settings/forget_exist/forget_exist_bloc.dart index b80745a67..279ccc52a 100644 --- a/lib/screen/settings/forget_exist/forget_exist_bloc.dart +++ b/lib/screen/settings/forget_exist/forget_exist_bloc.dart @@ -16,6 +16,7 @@ import 'package:autonomy_flutter/gateway/iap_api.dart'; import 'package:autonomy_flutter/main.dart'; import 'package:autonomy_flutter/screen/settings/forget_exist/forget_exist_state.dart'; import 'package:autonomy_flutter/service/account_service.dart'; +import 'package:autonomy_flutter/service/auth_firebase_service.dart'; import 'package:autonomy_flutter/service/auth_service.dart'; import 'package:autonomy_flutter/service/autonomy_service.dart'; import 'package:autonomy_flutter/service/cloud_firestore_service.dart'; @@ -37,6 +38,7 @@ class ForgetExistBloc extends AuBloc { final NftCollectionDatabase _nftCollectionDatabase; final ConfigurationService _configurationService; final CloudFirestoreService _cloudFirestoreService; + final AuthFirebaseService _authFirebaseService; ForgetExistBloc( this._authService, @@ -47,7 +49,8 @@ class ForgetExistBloc extends AuBloc { this._appDatabase, this._nftCollectionDatabase, this._configurationService, - this._cloudFirestoreService) + this._cloudFirestoreService, + this._authFirebaseService) : super(ForgetExistState(false, null)) { on((event, emit) async { emit(ForgetExistState(event.isChecked, state.isProcessing)); @@ -72,6 +75,7 @@ class ForgetExistBloc extends AuBloc { await _cloudDatabase.removeAll(); await _cloudFirestoreService.removeAll(); + await _authFirebaseService.signOut(); await _appDatabase.removeAll(); await _nftCollectionDatabase.removeAll(); await _configurationService.removeAll(); diff --git a/lib/screen/wallet_connect/wc_connect_page.dart b/lib/screen/wallet_connect/wc_connect_page.dart index ffffae1ed..ecdf81e52 100644 --- a/lib/screen/wallet_connect/wc_connect_page.dart +++ b/lib/screen/wallet_connect/wc_connect_page.dart @@ -676,7 +676,7 @@ class _WCConnectPageState extends State ? WalletType.Tezos : WalletType.Ethereum); unawaited(configurationService.setDoneOnboarding(true)); - unawaited(metricClient.mixPanelClient.initIfDefaultAccount()); + // unawaited(metricClient.mixPanelClient.initIfDefaultAccount()); if (!mounted) { return; } diff --git a/lib/service/account_service.dart b/lib/service/account_service.dart index b3dee8f53..3b930f849 100644 --- a/lib/service/account_service.dart +++ b/lib/service/account_service.dart @@ -18,6 +18,7 @@ import 'package:autonomy_flutter/model/wc2_request.dart'; import 'package:autonomy_flutter/screen/app_router.dart'; import 'package:autonomy_flutter/screen/bloc/scan_wallet/scan_wallet_state.dart'; import 'package:autonomy_flutter/service/audit_service.dart'; +import 'package:autonomy_flutter/service/auth_firebase_service.dart'; import 'package:autonomy_flutter/service/autonomy_service.dart'; import 'package:autonomy_flutter/service/backup_service.dart'; import 'package:autonomy_flutter/service/configuration_service.dart'; @@ -45,6 +46,8 @@ import 'package:uuid/uuid.dart'; abstract class AccountService { Future getDefaultAccount(); + Future getDefaultPersona(); + Future getOrCreateDefaultPersona(); Future getCurrentDefaultAccount(); @@ -115,6 +118,8 @@ class AccountServiceImpl extends AccountService { final AutonomyService _autonomyService; final AddressService _addressService; final BackupService _backupService; + final AuthFirebaseService _authFirebaseService = + injector(); final _defaultAccountLock = Lock(); @@ -128,14 +133,31 @@ class AccountServiceImpl extends AccountService { this._backupService, ); + MigrationUtil get _migrationUtil => MigrationUtil( + _configurationService, + _cloudDB, + injector(), + _auditService, + injector(), + this, + ); + @override Future createPersona( - {String name = '', bool isDefault = false}) async { + {String name = '', bool isDefault = false, String? words}) async { final uuid = const Uuid().v4(); final walletStorage = LibAukDart.getWallet(uuid); - await walletStorage.createKey(name); + if (words != null) { + await walletStorage.importKey( + words, '', DateTime.now().microsecondsSinceEpoch); + } else { + await walletStorage.createKey(name); + } final persona = Persona.newPersona( uuid: uuid, defaultAccount: isDefault ? 1 : null, name: name); + if (!_authFirebaseService.isSignedIn) { + await _authFirebaseService.signInWithPersona(persona); + } await _cloudDB.personaDao.insertPersona(persona); await androidBackupKeys(); await _auditService.auditPersonaAction('create', persona); @@ -150,11 +172,13 @@ class AccountServiceImpl extends AccountService { @override Future importPersona(String words, {WalletType walletType = WalletType.Autonomy}) async { - final personas = await _cloudDB.personaDao.getPersonas(); - for (final persona in personas) { - final mnemonic = await persona.wallet().exportMnemonicWords(); - if (mnemonic == words) { - return persona; + if (_authFirebaseService.isSignedIn) { + final personas = await _cloudDB.personaDao.getPersonas(); + for (final persona in personas) { + final mnemonic = await persona.wallet().exportMnemonicWords(); + if (mnemonic == words) { + return persona; + } } } @@ -164,6 +188,9 @@ class AccountServiceImpl extends AccountService { words, '', DateTime.now().microsecondsSinceEpoch); final persona = Persona.newPersona(uuid: uuid); + if (!_authFirebaseService.isSignedIn) { + await _authFirebaseService.signInWithPersona(persona); + } await _cloudDB.personaDao.insertPersona(persona); await androidBackupKeys(); await _auditService.auditPersonaAction('import', persona); @@ -176,6 +203,46 @@ class AccountServiceImpl extends AccountService { return persona; } + Future _getDefaultPersonaFromKeychainAndroid() async { + if (!Platform.isAndroid) { + return null; + } + + final accounts = await _backupChannel.restoreKeys(); + if (accounts.isEmpty) { + return null; + } + for (var account in accounts) { + final backupVersion = await _backupService + .fetchBackupVersion(LibAukDart.getWallet(account.uuid)); + if (backupVersion.isNotEmpty) { + return Persona.newPersona( + uuid: account.uuid, + name: account.name, + createdAt: DateTime.now(), + defaultAccount: 1, + ); + } + } + + return Persona.newPersona( + uuid: accounts.first.uuid, + name: accounts.first.name, + createdAt: DateTime.now(), + defaultAccount: 1, + ); + } + + @override + Future getDefaultPersonaFromKeychain() async { + if (Platform.isAndroid) { + return _getDefaultPersonaFromKeychainAndroid(); + } else if (Platform.isIOS) { + return _migrationUtil.getDefaultPersonaFromKeychainIOS(); + } + return null; + } + @override Future getDefaultAccount() async => _defaultAccountLock.synchronized(() async => await _getDefaultAccount()); @@ -246,32 +313,40 @@ class AccountServiceImpl extends AccountService { } @override - Future getOrCreateDefaultPersona() async { - var personas = await _cloudDB.personaDao.getDefaultPersonas(); - - if (personas.isEmpty) { - await MigrationUtil(_configurationService, _cloudDB, injector(), - _auditService, _backupService, this) - .migrationFromKeychain(); - await androidRestoreKeys(); + Future getDefaultPersona() async { + if (!_authFirebaseService.isSignedIn) { + final defaultPersona = await getDefaultPersonaFromKeychain(); + return defaultPersona; + } else { + var personas = await _cloudDB.personaDao.getDefaultPersonas(); - await Future.delayed(const Duration(seconds: 1)); - personas = await _cloudDB.personaDao.getDefaultPersonas(); - } + if (personas.isEmpty) { + await MigrationUtil(_configurationService, _cloudDB, injector(), + _auditService, _backupService, this) + .migrationFromKeychain(); + await androidRestoreKeys(); - final Persona defaultPersona; - if (personas.isEmpty) { - personas = await _cloudDB.personaDao.getPersonas(); - if (personas.isNotEmpty) { - defaultPersona = personas.first..defaultAccount = 1; - await _cloudDB.personaDao.updatePersona(defaultPersona); + await Future.delayed(const Duration(seconds: 1)); + personas = await _cloudDB.personaDao.getDefaultPersonas(); + } + Persona? defaultPersona; + if (personas.isEmpty) { + personas = await _cloudDB.personaDao.getPersonas(); + if (personas.isNotEmpty) { + defaultPersona = personas.first..defaultAccount = 1; + await _cloudDB.personaDao.updatePersona(defaultPersona); + } } else { - log.info('[AccountService] create default account'); - defaultPersona = await createPersona(isDefault: true); + defaultPersona = personas.first; } - } else { - defaultPersona = personas.first; + return defaultPersona; } + } + + @override + Future getOrCreateDefaultPersona() async { + Persona? defaultPersona = + await getDefaultPersona() ?? await createPersona(); return defaultPersona; } @@ -417,7 +492,10 @@ class AccountServiceImpl extends AccountService { if (Platform.isAndroid) { final accounts = await _backupChannel.restoreKeys(); - final personas = await _cloudDB.personaDao.getPersonas(); + List personas = []; + if (_authFirebaseService.isSignedIn) { + personas = await _cloudDB.personaDao.getPersonas(); + } if (personas.length == accounts.length && personas.every((element) => accounts.map((e) => e.uuid).contains(element.uuid))) { @@ -425,25 +503,27 @@ class AccountServiceImpl extends AccountService { return; } + List restoredPersonas = []; + //Import persona to database if needed for (var account in accounts) { - final existingAccount = - await _cloudDB.personaDao.findById(account.uuid); - if (existingAccount == null) { - final backupVersion = await _backupService - .fetchBackupVersion(LibAukDart.getWallet(account.uuid)); - final defaultAccount = backupVersion.isNotEmpty ? 1 : null; - - final persona = Persona.newPersona( - uuid: account.uuid, - name: account.name, - createdAt: DateTime.now(), - defaultAccount: defaultAccount, - ); - await _cloudDB.personaDao.insertPersona(persona); - await _auditService.auditPersonaAction( - '[androidRestoreKeys] insert', persona); + final backupVersion = await _backupService + .fetchBackupVersion(LibAukDart.getWallet(account.uuid)); + final defaultAccount = backupVersion.isNotEmpty ? 1 : null; + + final persona = Persona.newPersona( + uuid: account.uuid, + name: account.name, + createdAt: DateTime.now(), + defaultAccount: defaultAccount, + ); + if (defaultAccount == 1 && !_authFirebaseService.isSignedIn) { + await _authFirebaseService.signInWithPersona(persona); } + restoredPersonas.add(persona); + await _cloudDB.personaDao.insertPersona(persona); + await _auditService.auditPersonaAction( + '[androidRestoreKeys] insert', persona); } //Cleanup broken personas @@ -706,9 +786,9 @@ class AccountServiceImpl extends AccountService { } await _cloudDB.connectionDao.getUpdatedLinkedAccounts(); unawaited(_configurationService.setDoneOnboarding(true)); - await injector() - .mixPanelClient - .initIfDefaultAccount(); + // await injector() + // .mixPanelClient + // .initIfDefaultAccount(); unawaited(injector() .navigateTo(AppRouter.homePageNoTransition)); } @@ -717,9 +797,9 @@ class AccountServiceImpl extends AccountService { final persona = await createPersona(); await persona.insertNextAddress(WalletType.Tezos); await persona.insertNextAddress(WalletType.Ethereum); - unawaited(injector() - .mixPanelClient - .initIfDefaultAccount()); + // unawaited(injector() + // .mixPanelClient + // .initIfDefaultAccount()); unawaited(injector() .navigateTo(AppRouter.homePageNoTransition)); } diff --git a/lib/service/auth_firebase_service.dart b/lib/service/auth_firebase_service.dart new file mode 100644 index 000000000..5110e10e3 --- /dev/null +++ b/lib/service/auth_firebase_service.dart @@ -0,0 +1,81 @@ +import 'dart:convert'; + +import 'package:autonomy_flutter/common/environment.dart'; +import 'package:autonomy_flutter/common/injector.dart'; +import 'package:autonomy_flutter/database/entity/persona.dart'; +import 'package:autonomy_flutter/gateway/iap_api.dart'; +import 'package:autonomy_flutter/service/mix_panel_client_service.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:http/http.dart' as http; +import 'package:libauk_dart/libauk_dart.dart'; + +class AuthFirebaseService { + static User? _user; + + // init service + Future initService() async { + addAuthChangeListener(); + } + + IAPApi get _iapApi => injector.get(); + + bool get isSignedIn => _user != null && _user!.uid.isNotEmpty; + + Future getJWTToken(Persona persona) async { + final endpoint = Environment.autonomyAuthURL; + final account = persona.wallet(); + final authToken = await getAuthToken(account); + + final response = await http + .get(Uri.parse('$endpoint/apis/v1/me/jwts/firebase'), headers: { + 'Authorization': 'Bearer $authToken', + 'Content-Type': 'application/json' + }); + final bodyBytes = response.bodyBytes; + final bodyJson = json.decode(utf8.decode(bodyBytes)); + return bodyJson['jwt']; + } + + Future getAuthToken(WalletStorage account) async { + final message = DateTime.now().millisecondsSinceEpoch.toString(); + final accountDID = await account.getAccountDID(); + final signature = await account.getAccountDIDSignature(message); + + Map payload = { + 'requester': accountDID, + 'timestamp': message, + 'signature': signature, + }; + + final jwt = await _iapApi.auth(payload); + return jwt.jwtToken; + } + + static void addAuthChangeListener() { + FirebaseAuth.instance.authStateChanges().listen((User? user) { + if (user != null) { + _user = user; + } else { + _user = null; + } + }); + } + + User? get user => _user; + + Future signInWithPersona(Persona persona) async { + final auth = FirebaseAuth.instance; + final jwt = await getJWTToken(persona); + final userCredential = await auth.signInWithCustomToken(jwt); + _user = userCredential.user; + final mixPanelClientService = injector.get(); + await mixPanelClientService.initIfDefaultAccount(); + return user; + } + + Future signOut() async { + final auth = FirebaseAuth.instance; + await auth.signOut(); + _user = null; + } +} diff --git a/lib/service/auth_service.dart b/lib/service/auth_service.dart index ae1b1a59a..1bdbbaa94 100644 --- a/lib/service/auth_service.dart +++ b/lib/service/auth_service.dart @@ -12,6 +12,7 @@ import 'package:autonomy_flutter/gateway/iap_api.dart'; import 'package:autonomy_flutter/model/jwt.dart'; import 'package:autonomy_flutter/service/account_service.dart'; import 'package:autonomy_flutter/service/configuration_service.dart'; +import 'package:libauk_dart/libauk_dart.dart'; class AuthService { final IAPApi _authApi; @@ -32,12 +33,13 @@ class AuthService { Future getAuthToken( {String? messageToSign, String? receiptData, - bool forceRefresh = false}) async { + bool forceRefresh = false, + WalletStorage? defaultAccount}) async { if (!forceRefresh && _jwt != null && _jwt!.isValid()) { return _jwt!; } - final account = await _accountService.getDefaultAccount(); + final account = defaultAccount ?? await _accountService.getDefaultAccount(); final message = messageToSign ?? DateTime.now().millisecondsSinceEpoch.toString(); diff --git a/lib/service/cloud_firestore_service.dart b/lib/service/cloud_firestore_service.dart index c32522e87..c8cb01387 100644 --- a/lib/service/cloud_firestore_service.dart +++ b/lib/service/cloud_firestore_service.dart @@ -3,6 +3,8 @@ import 'dart:async'; import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/database/cloud_database.dart'; import 'package:autonomy_flutter/database/sqlite_cloud_database.dart'; +import 'package:autonomy_flutter/service/auth_firebase_service.dart'; +import 'package:autonomy_flutter/service/settings_data_service.dart'; import 'package:autonomy_flutter/util/cloud_firestore.dart'; import 'package:autonomy_flutter/util/log.dart'; import 'package:autonomy_flutter/util/migration/migration_util.dart'; @@ -11,9 +13,11 @@ import 'package:package_info_plus/package_info_plus.dart'; class CloudFirestoreService { FirebaseFirestore fireBaseFirestore; + AuthFirebaseService authFiresabeService; + String? deviceId; - CloudFirestoreService(this.fireBaseFirestore); + CloudFirestoreService(this.fireBaseFirestore, this.authFiresabeService); // init service Future initService() async { @@ -44,12 +48,15 @@ class CloudFirestoreService { return data?['backup'] ?? false; } - CollectionReference _userCollection() => fireBaseFirestore - .collection('$mobileAppCloudDatabase/$virtualDocumentId/$deviceId'); + DocumentReference _userDocument() { + final userID = authFiresabeService.user?.uid; + return fireBaseFirestore + .doc('$mobileAppCloudDatabase/$virtualDocumentId/users/$userID'); + } CollectionReference getCollection(FirestoreCollection collection) => - fireBaseFirestore.collection( - '${_userCollection().path}/$virtualDocumentId/${collection.name}'); + fireBaseFirestore + .collection('${_userDocument().path}/${collection.name}'); // method getBatch WriteBatch getBatch() => fireBaseFirestore.batch(); @@ -76,15 +83,12 @@ class CloudFirestoreService { log.info('[BackupService] done database backup'); } - Future removeAll() { - final collection = _userCollection(); - return collection.get().then((snapshot) { - final batch = getBatch(); - for (var doc in snapshot.docs) { - batch.delete(doc.reference); - } - return batch.commit(); - }); + Future removeAll() async { + final document = _userDocument(); + final cloudFirestoreDatabase = injector(); + await cloudFirestoreDatabase.removeAll(); + await injector().removeAll(); + await document.delete(); } } diff --git a/lib/service/mix_panel_client_service.dart b/lib/service/mix_panel_client_service.dart index f30589dd9..1dea7940c 100644 --- a/lib/service/mix_panel_client_service.dart +++ b/lib/service/mix_panel_client_service.dart @@ -29,9 +29,10 @@ class MixPanelClientService { Future initService() async { mixpanel = await Mixpanel.init(Environment.mixpanelKey, trackAutomaticEvents: true); - await initIfDefaultAccount(); - mixpanel.setLoggingEnabled(false); - mixpanel.setUseIpAddressForGeolocation(true); + // await _initIfDefaultAccount(); + mixpanel + ..setLoggingEnabled(false) + ..setUseIpAddressForGeolocation(true); mixpanel .getPeople() @@ -39,7 +40,7 @@ class MixPanelClientService { mixpanel.getPeople().set(MixpanelProp.enableNotification, _configurationService.isNotificationEnabled() ?? false); mixpanel.registerSuperPropertiesOnce({ - MixpanelProp.client: "Autonomy Wallet", + MixpanelProp.client: 'Autonomy Wallet', }); configHiveBox = await Hive.openBox(MIXPANEL_HIVE_BOX); } @@ -51,8 +52,7 @@ class MixPanelClientService { return; } final defaultDID = await defaultAccount.getAccountDID(); - final hashedUserID = - '${sha256.convert(utf8.encode(defaultDID)).toString()}_test'; + final hashedUserID = '${sha256.convert(utf8.encode(defaultDID))}_test'; final distinctId = await mixpanel.getDistinctId(); if (hashedUserID != distinctId) { mixpanel.alias(hashedUserID, distinctId); @@ -70,7 +70,7 @@ class MixPanelClientService { mixpanel.reset(); } - timerEvent(String name) { + void timerEvent(String name) { mixpanel.timeEvent(name.snakeToCapital()); } @@ -80,15 +80,15 @@ class MixPanelClientService { Map data = const {}, Map hashedData = const {}, }) async { - if (_configurationService.isAnalyticsEnabled() == false) { + if (!_configurationService.isAnalyticsEnabled()) { return; } // track with Mixpanel if (hashedData.isNotEmpty) { hashedData = hashedData.map((key, value) { - final salt = DateFormat("yyyy-MM-dd").format(DateTime.now()).toString(); - final valueWithSalt = "$value$salt"; + final salt = DateFormat('yyyy-MM-dd').format(DateTime.now()); + final valueWithSalt = '$value$salt'; return MapEntry( key, sha256.convert(utf8.encode(valueWithSalt)).toString()); }); @@ -107,12 +107,13 @@ class MixPanelClientService { Future sendData() async { try { - mixpanel.flush(); + await mixpanel.flush(); } catch (e) { log(e.toString()); } } + // ignore: avoid_annotating_with_dynamic void setLabel(String prop, dynamic value) { mixpanel.getPeople().set(prop, value); } @@ -158,10 +159,11 @@ class MixPanelClientService { } } - dynamic getConfig(String key, {dynamic defaultValue}) { - return configHiveBox.get(key, defaultValue: defaultValue); - } + // ignore: avoid_annotating_with_dynamic + dynamic getConfig(String key, {dynamic defaultValue}) => + configHiveBox.get(key, defaultValue: defaultValue); + // ignore: avoid_annotating_with_dynamic Future setConfig(String key, dynamic value) async { await configHiveBox.put(key, value); } diff --git a/lib/service/settings_data_service.dart b/lib/service/settings_data_service.dart index 7b6e6b080..62fd4786e 100644 --- a/lib/service/settings_data_service.dart +++ b/lib/service/settings_data_service.dart @@ -5,6 +5,7 @@ // that can be found in the LICENSE file. // +import 'dart:async'; import 'dart:convert'; import 'dart:io'; @@ -15,6 +16,7 @@ import 'package:autonomy_flutter/service/account_service.dart'; import 'package:autonomy_flutter/service/cloud_firestore_service.dart'; import 'package:autonomy_flutter/service/configuration_service.dart'; import 'package:autonomy_flutter/util/log.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:crypto/crypto.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:path_provider/path_provider.dart'; @@ -30,6 +32,8 @@ abstract class SettingsDataService { Future restoreSettingsData(); Future restoreSettingsDataFromFirestore(); + + Future removeAll(); } class SettingsDataServiceImpl implements SettingsDataService { @@ -40,7 +44,7 @@ class SettingsDataServiceImpl implements SettingsDataService { final CloudFirestoreService _cloudFirestoreService; final _collection = FirestoreCollection.settingsData; - var latestDataHash = ''; + String latestDataHash = ''; SettingsDataServiceImpl( this._configurationService, @@ -79,6 +83,14 @@ class SettingsDataServiceImpl implements SettingsDataService { ); } + CollectionReference get _collectionRef => + _cloudFirestoreService + .getCollection(_collection) + .withConverter( + fromFirestore: (snapshot, _) => + SettingsDataBackup.fromJson(snapshot.data()!), + toFirestore: (data, _) => data.toJson()); + @override Future backup() async { await firestoreBackup(); @@ -104,14 +116,14 @@ class SettingsDataServiceImpl implements SettingsDataService { _requester, _filename, _version, backupFile); isSuccess = true; } catch (exception) { - Sentry.captureException(exception); + unawaited(Sentry.captureException(exception)); } } latestDataHash = dataHash; if (_numberOfCallingBackups == 1) { - backupFile.delete(); + unawaited(backupFile.delete()); } _numberOfCallingBackups -= 1; @@ -122,70 +134,48 @@ class SettingsDataServiceImpl implements SettingsDataService { @override Future firestoreBackup() async { final data = await _getSettingsDataBackup(); - final collection = _cloudFirestoreService - .getCollection(_collection) - .withConverter( - fromFirestore: (snapshot, _) => - SettingsDataBackup.fromJson(snapshot.data()!), - toFirestore: (data, _) => data.toJson()); - await collection.doc(collection.id).set(data); + + await _collectionRef.doc(_collectionRef.id).set(data); } @override Future restoreSettingsData() async { await restoreSettingsDataFromFirestore(); return; - log.info('[SettingsDataService][Start] restoreSettingsData'); - final response = - await _iapApi.getProfileData(_requester, _filename, _version); - final data = SettingsDataBackup.fromJson(json.decode(response)); - - _configurationService.setAnalyticEnabled(data.isAnalyticsEnabled); + } - await _configurationService.updateTempStorageHiddenTokenIDs( - data.hiddenMainnetTokenIDs, true, - override: true); + @override + Future restoreSettingsDataFromFirestore() => + _collectionRef.doc(_collectionRef.id).get().then((snapshot) async { + if (snapshot.exists) { + final data = snapshot.data()!; + await _configurationService + .setAnalyticEnabled(data.isAnalyticsEnabled); - await Future.wait((data.hiddenAddressesFromGallery ?? []) - .map((e) => _cloudDB.addressDao.setAddressIsHidden(e, true))); + await _configurationService.updateTempStorageHiddenTokenIDs( + data.hiddenMainnetTokenIDs, true, + override: true); - await _configurationService.setHideLinkedAccountInGallery( - data.hiddenLinkedAccountsFromGallery, true, - override: true); + await Future.wait((data.hiddenAddressesFromGallery ?? []) + .map((e) => _cloudDB.addressDao.setAddressIsHidden(e, true))); - await _configurationService.setPlayList(data.playlists, override: true); + await _configurationService.setHideLinkedAccountInGallery( + data.hiddenLinkedAccountsFromGallery, true, + override: true); - log.info('[SettingsDataService][Done] restoreSettingsData'); - } + await _configurationService.setPlayList(data.playlists, + override: true); + } + }); @override - Future restoreSettingsDataFromFirestore() { - final collection = _cloudFirestoreService - .getCollection(_collection) - .withConverter( - fromFirestore: (snapshot, _) => - SettingsDataBackup.fromJson(snapshot.data()!), - toFirestore: (data, _) => data.toJson()); - return collection.doc(collection.id).get().then((snapshot) async { - if (snapshot.exists) { - final data = snapshot.data()!; - await _configurationService.setAnalyticEnabled(data.isAnalyticsEnabled); - - await _configurationService.updateTempStorageHiddenTokenIDs( - data.hiddenMainnetTokenIDs, true, - override: true); - - await Future.wait((data.hiddenAddressesFromGallery ?? []) - .map((e) => _cloudDB.addressDao.setAddressIsHidden(e, true))); - - await _configurationService.setHideLinkedAccountInGallery( - data.hiddenLinkedAccountsFromGallery, true, - override: true); - - await _configurationService.setPlayList(data.playlists, override: true); - } - }); - } + Future removeAll() => _collectionRef.get().then((snapshot) { + final batch = _cloudFirestoreService.getBatch(); + for (final doc in snapshot.docs) { + batch.delete(doc.reference); + } + return batch.commit(); + }); } @JsonSerializable() diff --git a/lib/util/migration/migration_util.dart b/lib/util/migration/migration_util.dart index 620793de7..2c22ce787 100644 --- a/lib/util/migration/migration_util.dart +++ b/lib/util/migration/migration_util.dart @@ -104,6 +104,30 @@ class MigrationUtil { } } + Future getDefaultPersonaFromKeychainIOS() async { + if (!Platform.isIOS) { + return null; + } + final List personaUUIDs = + await _channel.invokeMethod('getWalletUUIDsFromKeychain', {}); + for (var personaUUID in personaUUIDs) { + final uuid = personaUUID.toLowerCase(); + final wallet = Persona.newPersona(uuid: uuid).wallet(); + final name = await wallet.getName(); + + final backupVersion = await _backupService.fetchBackupVersion(wallet); + final isDefaultAccount = backupVersion.isNotEmpty; + if (isDefaultAccount) { + return Persona.newPersona( + uuid: uuid, + name: name, + createdAt: DateTime.now(), + ); + } + } + return null; + } + Future migrationFromKeychain() async { if (!Platform.isIOS) { return; diff --git a/lib/util/ui_helper.dart b/lib/util/ui_helper.dart index 5cf913a5d..bf64d786e 100644 --- a/lib/util/ui_helper.dart +++ b/lib/util/ui_helper.dart @@ -54,6 +54,8 @@ import 'package:flutter_vibrate/flutter_vibrate.dart'; import 'package:jiffy/jiffy.dart'; import 'package:share_plus/share_plus.dart'; +// ignore_for_file: constant_identifier_names + enum ActionState { notRequested, loading, error, done } const SHOW_DIALOG_DURATION = Duration(seconds: 2); @@ -63,8 +65,7 @@ Future doneOnboarding(BuildContext context) async { unawaited(injector().restore()); await injector().setPendingSettings(true); await injector().setDoneOnboarding(true); - unawaited( - injector().mixPanelClient.initIfDefaultAccount()); + // injector().mixPanelClient.initIfDefaultAccount(); await injector() .navigateUntil(AppRouter.homePage, (route) => false); } diff --git a/pubspec.lock b/pubspec.lock index 2f21d509f..b082c6af7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: dd68ecea9f1e3556d385521bd21c7bafd6311a8c1e11abe2595ca27974f468ee + sha256: f5628cd9c92ed11083f425fd1f8f1bc60ecdda458c81d73b143aeda036c35fe7 url: "https://pub.dev" source: hosted - version: "1.3.13" + version: "1.3.16" after_layout: dependency: "direct main" description: @@ -644,14 +644,38 @@ packages: url: "https://pub.dev" source: hosted version: "0.9.3" + firebase_auth: + dependency: "direct main" + description: + name: firebase_auth + sha256: "88f88d541a2c1903c023355e13d077835573a200bbf57e12a6a2c24bf99665a1" + url: "https://pub.dev" + source: hosted + version: "4.15.3" + firebase_auth_platform_interface: + dependency: transitive + description: + name: firebase_auth_platform_interface + sha256: "3c9cfaccb7549492edf5b0c67c6dd1c6727c7830891aa6727f2fb225f0226626" + url: "https://pub.dev" + source: hosted + version: "7.0.9" + firebase_auth_web: + dependency: transitive + description: + name: firebase_auth_web + sha256: c09515414c07c11bb133aec4baae9a74c6ff1f62bf05ace54564db82b8c87852 + url: "https://pub.dev" + source: hosted + version: "5.8.12" firebase_core: dependency: "direct main" description: name: firebase_core - sha256: "471b46ea6a9af503184d4de691566887daedd312aec5baac5baa42d819f56446" + sha256: "96607c0e829a581c2a483c658f04e8b159964c3bae2730f73297070bc85d40bb" url: "https://pub.dev" source: hosted - version: "2.23.0" + version: "2.24.2" firebase_core_platform_interface: dependency: transitive description: @@ -664,10 +688,10 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: "0631a2ec971dbc540275e2fa00c3a8a2676f0a7adbc3c197d6fba569db689d97" + sha256: d585bdf3c656c3f7821ba1bd44da5f13365d22fcecaf5eb75c4295246aaa83c0 url: "https://pub.dev" source: hosted - version: "2.8.1" + version: "2.10.0" fixnum: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 363dd47b7..0955cfe15 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -166,6 +166,7 @@ dependencies: flutter_pdfview: ^1.3.2 cloud_firestore: ^4.13.2 firebase_core: ^2.23.0 + firebase_auth: ^4.15.3 dependency_overrides: intl: 0.18.0