diff --git a/lib/application/settings/settings.dart b/lib/application/settings/settings.dart index 6ffcb0256..969ff7650 100644 --- a/lib/application/settings/settings.dart +++ b/lib/application/settings/settings.dart @@ -34,7 +34,6 @@ class SettingsNotifier extends StateNotifier { ), showBalances: true, showPriceChart: true, - testnetEnabled: false, ), ); @@ -47,10 +46,6 @@ class SettingsNotifier extends StateNotifier { state.copyWith(showBalances: showBalances), ); - Future setTestnetEnabled(bool testnetEnabled) => _update( - state.copyWith(testnetEnabled: testnetEnabled), - ); - Future setShowPriceChart(bool showPriceChart) => _update( state.copyWith(showPriceChart: showPriceChart), ); diff --git a/lib/domain/models/settings.dart b/lib/domain/models/settings.dart index 21c781152..ff55eabae 100644 --- a/lib/domain/models/settings.dart +++ b/lib/domain/models/settings.dart @@ -23,7 +23,6 @@ class Settings with _$Settings { required String languageSeed, required bool firstLaunch, required bool showBalances, - required bool testnetEnabled, required bool activeRPCServer, required int mainScreenCurrentPage, required bool showPriceChart, @@ -40,7 +39,6 @@ class Settings with _$Settings { primaryCurrency: AvailablePrimaryCurrency(AvailablePrimaryCurrencyEnum.native), showBalances: true, - testnetEnabled: false, showPriceChart: true, priceChartIntervalOption: aedappfm.MarketPriceHistoryInterval.hour, ); diff --git a/lib/domain/models/settings.freezed.dart b/lib/domain/models/settings.freezed.dart index 88d0bce50..a87bc1eb1 100644 --- a/lib/domain/models/settings.freezed.dart +++ b/lib/domain/models/settings.freezed.dart @@ -23,7 +23,6 @@ mixin _$Settings { String get languageSeed => throw _privateConstructorUsedError; bool get firstLaunch => throw _privateConstructorUsedError; bool get showBalances => throw _privateConstructorUsedError; - bool get testnetEnabled => throw _privateConstructorUsedError; bool get activeRPCServer => throw _privateConstructorUsedError; int get mainScreenCurrentPage => throw _privateConstructorUsedError; bool get showPriceChart => throw _privateConstructorUsedError; @@ -49,7 +48,6 @@ abstract class $SettingsCopyWith<$Res> { String languageSeed, bool firstLaunch, bool showBalances, - bool testnetEnabled, bool activeRPCServer, int mainScreenCurrentPage, bool showPriceChart, @@ -77,7 +75,6 @@ class _$SettingsCopyWithImpl<$Res, $Val extends Settings> Object? languageSeed = null, Object? firstLaunch = null, Object? showBalances = null, - Object? testnetEnabled = null, Object? activeRPCServer = null, Object? mainScreenCurrentPage = null, Object? showPriceChart = null, @@ -108,10 +105,6 @@ class _$SettingsCopyWithImpl<$Res, $Val extends Settings> ? _value.showBalances : showBalances // ignore: cast_nullable_to_non_nullable as bool, - testnetEnabled: null == testnetEnabled - ? _value.testnetEnabled - : testnetEnabled // ignore: cast_nullable_to_non_nullable - as bool, activeRPCServer: null == activeRPCServer ? _value.activeRPCServer : activeRPCServer // ignore: cast_nullable_to_non_nullable @@ -147,7 +140,6 @@ abstract class _$$SettingsImplCopyWith<$Res> String languageSeed, bool firstLaunch, bool showBalances, - bool testnetEnabled, bool activeRPCServer, int mainScreenCurrentPage, bool showPriceChart, @@ -173,7 +165,6 @@ class __$$SettingsImplCopyWithImpl<$Res> Object? languageSeed = null, Object? firstLaunch = null, Object? showBalances = null, - Object? testnetEnabled = null, Object? activeRPCServer = null, Object? mainScreenCurrentPage = null, Object? showPriceChart = null, @@ -204,10 +195,6 @@ class __$$SettingsImplCopyWithImpl<$Res> ? _value.showBalances : showBalances // ignore: cast_nullable_to_non_nullable as bool, - testnetEnabled: null == testnetEnabled - ? _value.testnetEnabled - : testnetEnabled // ignore: cast_nullable_to_non_nullable - as bool, activeRPCServer: null == activeRPCServer ? _value.activeRPCServer : activeRPCServer // ignore: cast_nullable_to_non_nullable @@ -238,7 +225,6 @@ class _$SettingsImpl extends _Settings { required this.languageSeed, required this.firstLaunch, required this.showBalances, - required this.testnetEnabled, required this.activeRPCServer, required this.mainScreenCurrentPage, required this.showPriceChart, @@ -258,8 +244,6 @@ class _$SettingsImpl extends _Settings { @override final bool showBalances; @override - final bool testnetEnabled; - @override final bool activeRPCServer; @override final int mainScreenCurrentPage; @@ -270,7 +254,7 @@ class _$SettingsImpl extends _Settings { @override String toString() { - return 'Settings(primaryCurrency: $primaryCurrency, language: $language, environment: $environment, languageSeed: $languageSeed, firstLaunch: $firstLaunch, showBalances: $showBalances, testnetEnabled: $testnetEnabled, activeRPCServer: $activeRPCServer, mainScreenCurrentPage: $mainScreenCurrentPage, showPriceChart: $showPriceChart, priceChartIntervalOption: $priceChartIntervalOption)'; + return 'Settings(primaryCurrency: $primaryCurrency, language: $language, environment: $environment, languageSeed: $languageSeed, firstLaunch: $firstLaunch, showBalances: $showBalances, activeRPCServer: $activeRPCServer, mainScreenCurrentPage: $mainScreenCurrentPage, showPriceChart: $showPriceChart, priceChartIntervalOption: $priceChartIntervalOption)'; } @override @@ -290,8 +274,6 @@ class _$SettingsImpl extends _Settings { other.firstLaunch == firstLaunch) && (identical(other.showBalances, showBalances) || other.showBalances == showBalances) && - (identical(other.testnetEnabled, testnetEnabled) || - other.testnetEnabled == testnetEnabled) && (identical(other.activeRPCServer, activeRPCServer) || other.activeRPCServer == activeRPCServer) && (identical(other.mainScreenCurrentPage, mainScreenCurrentPage) || @@ -312,7 +294,6 @@ class _$SettingsImpl extends _Settings { languageSeed, firstLaunch, showBalances, - testnetEnabled, activeRPCServer, mainScreenCurrentPage, showPriceChart, @@ -335,7 +316,6 @@ abstract class _Settings extends Settings { required final String languageSeed, required final bool firstLaunch, required final bool showBalances, - required final bool testnetEnabled, required final bool activeRPCServer, required final int mainScreenCurrentPage, required final bool showPriceChart, @@ -356,8 +336,6 @@ abstract class _Settings extends Settings { @override bool get showBalances; @override - bool get testnetEnabled; - @override bool get activeRPCServer; @override int get mainScreenCurrentPage; diff --git a/lib/infrastructure/datasources/preferences.hive.dart b/lib/infrastructure/datasources/preferences.hive.dart index a9428fab4..6ef2f4e42 100644 --- a/lib/infrastructure/datasources/preferences.hive.dart +++ b/lib/infrastructure/datasources/preferences.hive.dart @@ -36,7 +36,6 @@ class PreferencesHiveDatasource { static const String pinLockUntil = 'archethic_wallet_pin_lock_until'; static const String pinPadShuffle = 'archethic_wallet_pinPadShuffle'; static const String showBalances = 'archethic_wallet_showBalances'; - static const String testnetEnabled = 'archethic_wallet_testnetEnabled'; static const String showPriceChart = 'archethic_wallet_showPriceChart'; static const String priceChartScale = 'archethic_wallet_priceChartScale'; static const String activeRPCServer = 'archethic_wallet_activeRPCServer'; @@ -145,11 +144,6 @@ class PreferencesHiveDatasource { bool getShowBalances() => _getValue(showBalances, defaultValue: true); - Future setTestnetEnabled(bool value) => - _setValue(testnetEnabled, value); - - bool getTestnetEnabled() => _getValue(testnetEnabled, defaultValue: false); - Future setActiveRPCServer(bool value) => _setValue(activeRPCServer, value); diff --git a/lib/infrastructure/repositories/settings.dart b/lib/infrastructure/repositories/settings.dart index 02613a0ac..e3c0570fc 100644 --- a/lib/infrastructure/repositories/settings.dart +++ b/lib/infrastructure/repositories/settings.dart @@ -22,7 +22,6 @@ class SettingsRepository implements SettingsRepositoryInterface { environment: loadedPreferences.getEnvironment(), primaryCurrency: loadedPreferences.getPrimaryCurrency(), showBalances: loadedPreferences.getShowBalances(), - testnetEnabled: loadedPreferences.getTestnetEnabled(), showPriceChart: loadedPreferences.getShowPriceChart(), priceChartIntervalOption: loadedPreferences.getPriceChartIntervalOption(), ); @@ -40,7 +39,6 @@ class SettingsRepository implements SettingsRepositoryInterface { await loadedPreferences.setEnvironment(settings.environment); await loadedPreferences.setPrimaryCurrency(settings.primaryCurrency); await loadedPreferences.setShowBalances(settings.showBalances); - await loadedPreferences.setTestnetEnabled(settings.testnetEnabled); await loadedPreferences.setShowPriceChart(settings.showPriceChart); await loadedPreferences .setPriceChartIntervalOption(settings.priceChartIntervalOption); diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 4078d7e39..1a7dac87d 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -203,7 +203,6 @@ "passwordBlank": "Password cannot be empty", "welcomeDisclaimerChoice": "I have read and agree to the privacy policy", "showBalances": "Show balances", - "testnetEnabled": "Testnet enabled", "introNewWalletGetFirstInfosWelcome": "Welcome to Archethic Wallet.", "introNewWalletGetFirstInfosNameRequest": "Let's start by naming your first account, which will be stored on your decentralized keychain", "introNewWalletGetFirstInfosNameInfos": "It will allow you to distinguish this account from other accounts that you can, if you want, create later.\n\nWARNING : This name will be added to your decentralized keychain and cannot be modified.", @@ -673,5 +672,14 @@ } }, "walletNotCreatedTargetEnv": "The wallet has not been created in the {targetEnv} environment.", - "walletChangeLoadingError": "The change of environment encountered an issue." + "walletChangeLoadingError": "The change of environment encountered an issue.", + "switchEnvHeader": "Switch environment", + "switchEnvHeaderInfo": "Switch to an environment other than your current {currentEnv} environment.", + "@switchEnvHeaderInfo": { + "placeholders": { + "currentEnv": { + "type": "String" + } + } + } } \ No newline at end of file diff --git a/lib/l10n/intl_fr.arb b/lib/l10n/intl_fr.arb index 3784e6f26..7d1313ca0 100644 --- a/lib/l10n/intl_fr.arb +++ b/lib/l10n/intl_fr.arb @@ -200,7 +200,6 @@ "passwordStrengthStrong": "Votre mot de passe est fort.", "welcomeDisclaimerChoice": "J'ai lu et j'accepte la politique de confidentialité", "showBalances": "Afficher les balances", - "testnetEnabled": "Testnet activé", "introNewWalletGetFirstInfosWelcome": "Bienvenue dans le Wallet Archethic.", "introNewWalletGetFirstInfosNameRequest": "Commençons par donner un nom à votre premier compte, qui sera stocké sur votre porte-clés décentralisé.", "introNewWalletGetFirstInfosNameInfos": "Il vous permettra de distinguer ce compte avec les autres comptes que vous pourrez, si vous le souhaitez, créer par la suite.\n\nATTENTION : Ce nom sera rattaché à votre porte-clés décentralisé et ne pourra plus être modifié.", @@ -669,5 +668,14 @@ } }, "walletNotCreatedTargetEnv": "Le wallet n'a pas été créé dans l'environnement {targetEnv}.", - "walletChangeLoadingError": "Le changement d'environnement a rencontré un problème." + "walletChangeLoadingError": "Le changement d'environnement a rencontré un problème.", + "switchEnvHeader": "Changer d'environnement", + "switchEnvHeaderInfo": "Permet de basculer sur un autre environnement que votre environnement actuel \"{currentEnv}\"", + "@switchEnvHeaderInfo": { + "placeholders": { + "currentEnv": { + "type": "String" + } + } + } } \ No newline at end of file diff --git a/lib/ui/menu/settings/customization_menu_view.dart b/lib/ui/menu/settings/customization_menu_view.dart index e5b34ed50..8295807fb 100644 --- a/lib/ui/menu/settings/customization_menu_view.dart +++ b/lib/ui/menu/settings/customization_menu_view.dart @@ -43,7 +43,6 @@ class CustomizationMenuView extends ConsumerWidget final localizations = AppLocalizations.of(context)!; final primaryCurrency = ref.watch(selectedPrimaryCurrencyProvider); - final environment = ref.watch(environmentProvider); return DecoratedBox( decoration: BoxDecoration( gradient: LinearGradient( @@ -77,10 +76,6 @@ class CustomizationMenuView extends ConsumerWidget const _SettingsListItem.spacer(), const _ShowPriceChartSettingsListItem(), const _SettingsListItem.spacer(), - if (environment == aedappfm.Environment.mainnet) - const _TestnetEnabledSettingsListItem(), - if (environment == aedappfm.Environment.mainnet) - const _SettingsListItem.spacer(), ], ), ], @@ -153,24 +148,3 @@ class _ShowPriceChartSettingsListItem extends ConsumerWidget { ); } } - -class _TestnetEnabledSettingsListItem extends ConsumerWidget { - const _TestnetEnabledSettingsListItem(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final localizations = AppLocalizations.of(context)!; - final testnetEnabledSetting = ref.watch( - SettingsProviders.settings.select((settings) => settings.testnetEnabled), - ); - final preferencesNotifier = ref.read(SettingsProviders.settings.notifier); - return _SettingsListItem.withSwitch( - heading: localizations.testnetEnabled, - icon: Symbols.deployed_code_account, - isSwitched: testnetEnabledSetting, - onChanged: (testnetEnabled) async { - await preferencesNotifier.setTestnetEnabled(testnetEnabled); - }, - ); - } -} diff --git a/lib/ui/menu/settings/environment_change.dart b/lib/ui/menu/settings/environment_change.dart deleted file mode 100644 index 9ab8314f9..000000000 --- a/lib/ui/menu/settings/environment_change.dart +++ /dev/null @@ -1,243 +0,0 @@ -/// SPDX-License-Identifier: AGPL-3.0-or-later -import 'dart:async'; - -import 'package:aewallet/application/account/accounts_notifier.dart'; -import 'package:aewallet/application/session/session.dart'; -import 'package:aewallet/application/settings/settings.dart'; -import 'package:aewallet/application/usecases.dart'; -import 'package:aewallet/domain/usecases/new_keychain.usecase.dart'; -import 'package:aewallet/modules/aeswap/application/session/provider.dart'; -import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; -import 'package:aewallet/ui/themes/archethic_theme.dart'; -import 'package:aewallet/ui/themes/archethic_theme_base.dart'; -import 'package:aewallet/ui/util/accounts_dialog.dart'; -import 'package:aewallet/ui/util/ui_util.dart'; -import 'package:aewallet/ui/widgets/components/dialog.dart'; -import 'package:aewallet/ui/widgets/dialogs/environment_dialog.dart'; -import 'package:archethic_dapp_framework_flutter/archethic_dapp_framework_flutter.dart' - as aedappfm; -import 'package:archethic_lib_dart/archethic_lib_dart.dart' as archethic; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/localizations.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:go_router/go_router.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -class EnvironmentChange extends ConsumerWidget { - const EnvironmentChange({ - super.key, - }); - @override - Widget build(BuildContext context, WidgetRef ref) { - final environment = ref.watch(environmentProvider); - final selectedAccount = ref.watch( - accountsNotifierProvider.select( - (accounts) => accounts.valueOrNull?.selectedAccount, - ), - ); - final settings = ref.watch(SettingsProviders.settings); - final localizations = AppLocalizations.of(context)!; - - if (selectedAccount == null) return const SizedBox(); - - return InkWell( - onTap: settings.testnetEnabled - ? () async { - final _saveEnvironment = settings.environment; - final _selectedEnvironment = await context - .push(EnvironmentDialog.routerPage) as aedappfm.Environment?; - if (_selectedEnvironment == null) return; - if (_selectedEnvironment != _saveEnvironment) { - final seed = - ref.read(sessionNotifierProvider).loggedIn?.wallet.seed; - - var keychainNetworkExists = false; - - try { - await archethic.ApiService( - _selectedEnvironment.endpoint, - ).getKeychain(seed!); - keychainNetworkExists = true; - // ignore: empty_catches - } catch (e) {} - - if (keychainNetworkExists == false) { - final session = ref.read(sessionNotifierProvider); - - final accounts = await AccountsDialog.selectMultipleAccounts( - context: context, - accounts: session.loggedIn!.wallet.appKeychain.accounts, - confirmBtnLabel: - localizations.networkChangeCreateKeychainBtn, - dialogTitle: localizations.networkChangeHeader, - isModal: true, - header: Padding( - padding: const EdgeInsets.symmetric(vertical: 10), - child: Column( - children: [ - Text( - localizations.networkChangeKeychainNotExists( - _selectedEnvironment.displayName, - ), - style: AppTextStyles.bodySmall(context), - ), - ], - ), - ), - ); - - final nameList = []; - if (accounts == null || accounts.isEmpty) { - return; - } - for (final account in accounts) { - nameList.add(Uri.decodeFull(account.name)); - } - - try { - context.loadingOverlay.show( - title: - AppLocalizations.of(context)!.pleaseWaitChangeNetwork, - ); - final originKeychain = await archethic.ApiService( - _saveEnvironment.endpoint, - ).getKeychain(seed!); - await ref.read(createNewAppWalletCaseProvider).run( - seed, - archethic.ApiService(_selectedEnvironment.endpoint), - nameList, - keychainSeed: originKeychain.seed == null - ? null - : archethic.uint8ListToHex(originKeychain.seed!), - ); - - UIUtil.showSnackbar( - localizations.walletCreatedTargetEnv( - _selectedEnvironment.displayName, - ), - context, - ref, - ArchethicTheme.text, - ArchethicTheme.snackBarShadow, - duration: const Duration(milliseconds: 5000), - icon: Symbols.info, - ); - } catch (e) { - UIUtil.showSnackbar( - '${localizations.walletNotCreatedTargetEnv(_selectedEnvironment.displayName)} (${_getErrorMessage(e)})', - context, - ref, - ArchethicTheme.text, - ArchethicTheme.snackBarShadow, - duration: const Duration(milliseconds: 5000), - ); - - context.loadingOverlay.hide(); - context.pop(); - return; - } - } else { - context.loadingOverlay.show( - title: - AppLocalizations.of(context)!.pleaseWaitChangeNetwork, - ); - } - - try { - final languageSeed = ref.read( - SettingsProviders.settings.select( - (settings) => settings.languageSeed, - ), - ); - await ref - .read(SettingsProviders.settings.notifier) - .setEnvironment(_selectedEnvironment); - - await ref - .read(sessionNotifierProvider.notifier) - .restoreFromSeed( - seed: seed!, - languageCode: languageSeed, - ); - - final accounts = - await ref.read(accountsNotifierProvider.future); - - await ref - .read(accountsNotifierProvider.notifier) - .selectAccount(accounts.first); - - unawaited( - (await ref - .read(accountsNotifierProvider.notifier) - .selectedAccountNotifier) - ?.refreshAll(), - ); - context.loadingOverlay.hide(); - } catch (e) { - UIUtil.showSnackbar( - '${localizations.walletChangeLoadingError} (${_getErrorMessage(e)})', - context, - ref, - ArchethicTheme.text, - ArchethicTheme.snackBarShadow, - duration: const Duration(milliseconds: 5000), - ); - - await ref - .read(SettingsProviders.settings.notifier) - .setEnvironment(_saveEnvironment); - - context.loadingOverlay.hide(); - context.pop(); - } - } - } - : null, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.only(bottom: 10), - child: Align( - child: Text( - environment.label, - style: AppTextStyles.bodyMediumSecondaryColor( - context, - ), - ), - ), - ), - if (settings.testnetEnabled) - Padding( - padding: const EdgeInsets.only(bottom: 8), - child: Row( - children: [ - const SizedBox( - width: 5, - ), - Icon( - Symbols.keyboard_arrow_down, - color: ArchethicThemeBase.neutral0, - ), - ], - ), - ), - ], - ), - ); - } - - String _getErrorMessage(Object e) { - if (e is archethic.ArchethicConnectionException) { - return e.cause; - } else if (e is archethic.ArchethicInvalidResponseException) { - return e.cause; - } else if (e is ArchethicNewKeychainErrorException) { - return e.cause; - } else if (e is ArchethicNewKeychainAccessErrorException) { - return e.cause; - } - return e.toString(); - } -} diff --git a/lib/ui/menu/settings/main_settings_view.dart b/lib/ui/menu/settings/main_settings_view.dart index a8547f294..bf006ba00 100644 --- a/lib/ui/menu/settings/main_settings_view.dart +++ b/lib/ui/menu/settings/main_settings_view.dart @@ -35,6 +35,7 @@ class MainMenuView extends ConsumerWidget { }, ); } + final environment = ref.watch(environmentProvider); return DecoratedBox( decoration: BoxDecoration( @@ -56,7 +57,22 @@ class MainMenuView extends ConsumerWidget { children: [ ListView( children: [ - const EnvironmentChange(), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 10), + child: Align( + child: Text( + environment.label, + style: AppTextStyles.bodyMediumSecondaryColor( + context, + ), + ), + ), + ), + ], + ), const _SettingsListItem.spacer(), _SettingsListItem.title(text: localizations.information), const _SettingsListItem.spacer(), diff --git a/lib/ui/menu/settings/security_menu_view.dart b/lib/ui/menu/settings/security_menu_view.dart index 76e6a3294..bbe60c4ac 100644 --- a/lib/ui/menu/settings/security_menu_view.dart +++ b/lib/ui/menu/settings/security_menu_view.dart @@ -48,6 +48,7 @@ class SecurityMenuView extends ConsumerWidget (settings) => settings.authenticationMethod, ), ); + final settings = ref.watch(SettingsProviders.settings); return DecoratedBox( decoration: BoxDecoration( @@ -80,6 +81,19 @@ class SecurityMenuView extends ConsumerWidget const _SettingsListItem.spacer(), const _BackupSecretPhraseListItem(), const _SettingsListItem.spacer(), + _SettingsListItem.singleLineWithInfos( + heading: localizations.switchEnvHeader, + info: localizations.switchEnvHeaderInfo( + settings.environment.displayName, + ), + headingStyle: + ArchethicThemeStyles.textStyleSize16W600Primary, + icon: Symbols.deployed_code_account, + onPressed: () async { + await _switchEnv(context, ref); + }, + ), + const _SettingsListItem.spacer(), if (ArchethicWebsocketRPCServer.isPlatformCompatible) const _ActiveServerRPCSettingsListItem(), if (ArchethicWebsocketRPCServer.isPlatformCompatible) @@ -115,6 +129,167 @@ class SecurityMenuView extends ConsumerWidget ), ); } + + Future _switchEnv(BuildContext context, WidgetRef ref) async { + final settings = ref.watch(SettingsProviders.settings); + final localizations = AppLocalizations.of(context)!; + + final _saveEnvironment = settings.environment; + final _selectedEnvironment = await context + .push(EnvironmentDialog.routerPage) as aedappfm.Environment?; + if (_selectedEnvironment == null) return; + if (_selectedEnvironment != _saveEnvironment) { + final seed = ref.read(sessionNotifierProvider).loggedIn?.wallet.seed; + + var keychainNetworkExists = false; + + try { + await archethic.ApiService( + _selectedEnvironment.endpoint, + ).getKeychain(seed!); + keychainNetworkExists = true; + // ignore: empty_catches + } catch (e) {} + + if (keychainNetworkExists == false) { + final session = ref.read(sessionNotifierProvider); + + final accounts = await AccountsDialog.selectMultipleAccounts( + context: context, + accounts: session.loggedIn!.wallet.appKeychain.accounts, + confirmBtnLabel: localizations.networkChangeCreateKeychainBtn, + dialogTitle: localizations.networkChangeHeader, + isModal: true, + header: Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Column( + children: [ + Text( + localizations.networkChangeKeychainNotExists( + _selectedEnvironment.displayName, + ), + style: AppTextStyles.bodySmall(context), + ), + ], + ), + ), + ); + + final nameList = []; + if (accounts == null || accounts.isEmpty) { + return; + } + for (final account in accounts) { + nameList.add(Uri.decodeFull(account.name)); + } + + try { + context.loadingOverlay.show( + title: AppLocalizations.of(context)!.pleaseWaitChangeNetwork, + ); + final originKeychain = await archethic.ApiService( + _saveEnvironment.endpoint, + ).getKeychain(seed!); + await ref.read(createNewAppWalletCaseProvider).run( + seed, + archethic.ApiService(_selectedEnvironment.endpoint), + nameList, + keychainSeed: originKeychain.seed == null + ? null + : archethic.uint8ListToHex(originKeychain.seed!), + ); + + UIUtil.showSnackbar( + localizations.walletCreatedTargetEnv( + _selectedEnvironment.displayName, + ), + context, + ref, + ArchethicTheme.text, + ArchethicTheme.snackBarShadow, + duration: const Duration(milliseconds: 5000), + icon: Symbols.info, + ); + } catch (e) { + UIUtil.showSnackbar( + '${localizations.walletNotCreatedTargetEnv(_selectedEnvironment.displayName)} (${_getErrorMessage(e)})', + context, + ref, + ArchethicTheme.text, + ArchethicTheme.snackBarShadow, + duration: const Duration(milliseconds: 5000), + ); + + context.loadingOverlay.hide(); + context.pop(); + return; + } + } else { + context.loadingOverlay.show( + title: AppLocalizations.of(context)!.pleaseWaitChangeNetwork, + ); + } + + try { + final languageSeed = ref.read( + SettingsProviders.settings.select( + (settings) => settings.languageSeed, + ), + ); + await ref + .read(SettingsProviders.settings.notifier) + .setEnvironment(_selectedEnvironment); + + await ref.read(sessionNotifierProvider.notifier).restoreFromSeed( + seed: seed!, + languageCode: languageSeed, + ); + + final accounts = await ref.read(accountsNotifierProvider.future); + + await ref + .read(accountsNotifierProvider.notifier) + .selectAccount(accounts.first); + + unawaited( + (await ref + .read(accountsNotifierProvider.notifier) + .selectedAccountNotifier) + ?.refreshAll(), + ); + context.loadingOverlay.hide(); + } catch (e) { + UIUtil.showSnackbar( + '${localizations.walletChangeLoadingError} (${_getErrorMessage(e)})', + context, + ref, + ArchethicTheme.text, + ArchethicTheme.snackBarShadow, + duration: const Duration(milliseconds: 5000), + ); + + await ref + .read(SettingsProviders.settings.notifier) + .setEnvironment(_saveEnvironment); + + context.loadingOverlay.hide(); + context.pop(); + } + } + } + + String _getErrorMessage(Object e) { + if (e is archethic.ArchethicConnectionException) { + return e.cause; + } else if (e is archethic.ArchethicInvalidResponseException) { + return e.cause; + } else if (e is ArchethicNewKeychainErrorException) { + return e.cause; + } else if (e is ArchethicNewKeychainAccessErrorException) { + return e.cause; + } + return e.toString(); + } } class _AuthMethodSettingsListItem extends ConsumerWidget { diff --git a/lib/ui/menu/settings/settings_sheet.dart b/lib/ui/menu/settings/settings_sheet.dart index 716f9631f..63deb94ac 100644 --- a/lib/ui/menu/settings/settings_sheet.dart +++ b/lib/ui/menu/settings/settings_sheet.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:aewallet/application/account/accounts_notifier.dart'; import 'package:aewallet/application/authentication/authentication.dart'; import 'package:aewallet/application/connectivity_status.dart'; @@ -6,7 +8,9 @@ import 'package:aewallet/application/settings/language.dart'; import 'package:aewallet/application/settings/primary_currency.dart'; import 'package:aewallet/application/settings/settings.dart'; import 'package:aewallet/application/settings/version.dart'; +import 'package:aewallet/application/usecases.dart'; import 'package:aewallet/domain/repositories/features_flags.dart'; +import 'package:aewallet/domain/usecases/new_keychain.usecase.dart'; import 'package:aewallet/infrastructure/datasources/tokens_list.hive.dart'; import 'package:aewallet/infrastructure/rpc/websocket_server.dart'; import 'package:aewallet/model/authentication_method.dart'; @@ -15,10 +19,12 @@ import 'package:aewallet/model/device_lock_timeout.dart'; import 'package:aewallet/model/privacy_mask_option.dart'; import 'package:aewallet/model/setting_item.dart'; import 'package:aewallet/modules/aeswap/application/session/provider.dart'; -import 'package:aewallet/ui/menu/settings/environment_change.dart'; +import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; import 'package:aewallet/ui/themes/archethic_theme.dart'; import 'package:aewallet/ui/themes/archethic_theme_base.dart'; import 'package:aewallet/ui/themes/styles.dart'; +import 'package:aewallet/ui/util/accounts_dialog.dart'; +import 'package:aewallet/ui/util/ui_util.dart'; import 'package:aewallet/ui/views/authenticate/auth_factory.dart'; import 'package:aewallet/ui/views/dapps_board/layouts/dapps_board_sheet.dart'; import 'package:aewallet/ui/views/main/components/sheet_appbar.dart'; @@ -30,6 +36,7 @@ import 'package:aewallet/ui/widgets/components/icon_widget.dart'; import 'package:aewallet/ui/widgets/components/sheet_skeleton.dart'; import 'package:aewallet/ui/widgets/components/sheet_skeleton_interface.dart'; import 'package:aewallet/ui/widgets/dialogs/authentification_method_dialog.dart'; +import 'package:aewallet/ui/widgets/dialogs/environment_dialog.dart'; import 'package:aewallet/ui/widgets/dialogs/language_dialog.dart'; import 'package:aewallet/ui/widgets/dialogs/lock_timeout_dialog.dart'; import 'package:aewallet/ui/widgets/dialogs/primary_currency_dialog.dart'; @@ -40,6 +47,7 @@ import 'package:aewallet/util/mnemonics.dart'; import 'package:aewallet/util/universal_platform.dart'; import 'package:archethic_dapp_framework_flutter/archethic_dapp_framework_flutter.dart' as aedappfm; +import 'package:archethic_lib_dart/archethic_lib_dart.dart' as archethic; import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; diff --git a/lib/ui/views/intro/layouts/intro_new_wallet_get_first_infos.dart b/lib/ui/views/intro/layouts/intro_new_wallet_get_first_infos.dart index d314f357b..4008d4ece 100644 --- a/lib/ui/views/intro/layouts/intro_new_wallet_get_first_infos.dart +++ b/lib/ui/views/intro/layouts/intro_new_wallet_get_first_infos.dart @@ -138,11 +138,6 @@ class _IntroNewWalletDisclaimerState await ref .read(SettingsProviders.settings.notifier) .setEnvironment(environment as aedappfm.Environment); - await ref - .read(SettingsProviders.settings.notifier) - .setTestnetEnabled( - environment != aedappfm.Environment.mainnet, - ); } FocusScope.of(context).requestFocus(nameFocusNode); diff --git a/lib/ui/views/intro/layouts/intro_welcome.dart b/lib/ui/views/intro/layouts/intro_welcome.dart index 1884e86c8..6f8e86fab 100755 --- a/lib/ui/views/intro/layouts/intro_welcome.dart +++ b/lib/ui/views/intro/layouts/intro_welcome.dart @@ -376,11 +376,6 @@ class _ButtonImportWallet extends ConsumerWidget { await ref .read(SettingsProviders.settings.notifier) .setEnvironment(environment as aedappfm.Environment); - await ref - .read(SettingsProviders.settings.notifier) - .setTestnetEnabled( - environment != aedappfm.Environment.mainnet, - ); } context.go(IntroImportSeedPage.routerPage); }