From 9f03f7cfdcf5f67311ab9ba6fedc49b3133f9b53 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Mon, 29 Jan 2024 13:06:04 -0600 Subject: [PATCH 1/2] Revert "Merge pull request #732 from cypherstack/ui" This reverts commit 3c8e220303ecd87600c9dec44308e979504b39ec, reversing changes made to 0f8d3eb12227cbcd5722f8741e4a76eaa9195947. --- ...w_wallet_recovery_phrase_warning_view.dart | 1160 ++++++++--------- 1 file changed, 556 insertions(+), 604 deletions(-) diff --git a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart index 3c37f2628..9a1303978 100644 --- a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart +++ b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart @@ -35,6 +35,7 @@ import 'package:stackwallet/wallets/crypto_currency/coins/tezos.dart'; import 'package:stackwallet/wallets/isar/models/wallet_info.dart'; import 'package:stackwallet/wallets/wallet/wallet.dart'; import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; @@ -77,626 +78,577 @@ class _NewWalletRecoveryPhraseWarningViewState @override Widget build(BuildContext context) { debugPrint("BUILD: $runtimeType"); - - return MasterScaffold( - isDesktop: isDesktop, - appBar: _buildAppBar(context), - body: _buildBody(context), - ); - } - - Widget _buildAppBar(BuildContext context) { - return isDesktop - ? const DesktopAppBar( - isCompactHeight: false, - leading: AppBarBackButton(), - trailing: ExitToMyStackButton(), - ) - : AppBar( - leading: const AppBarBackButton(), - actions: [ - Padding( - padding: const EdgeInsets.only( - top: 10, - bottom: 10, - right: 10, - ), - child: AppBarIconButton( - semanticsLabel: - "Question Button. Opens A Dialog For Recovery Phrase Explanation.", - icon: SvgPicture.asset( - Assets.svg.circleQuestion, - width: 20, - height: 20, - color: Theme.of(context) - .extension()! - .accentColorDark, - ), - onPressed: () async { - await showDialog( - context: context, - builder: (context) => - const RecoveryPhraseExplanationDialog(), - ); - }, - ), - ) - ], - ); - } - - Widget _buildBody(BuildContext context) { final options = ref.read(pNewWalletOptions.state).state; final seedCount = options?.mnemonicWordsCount ?? Constants.defaultSeedPhraseLengthFor(coin: coin); - return SingleChildScrollView( - child: Center( - child: ConstrainedBox( - constraints: - BoxConstraints(maxWidth: isDesktop ? 480 : double.infinity), - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (isDesktop) - // TODO vertical centering/alignment. - /*const Spacer( - flex: 10, - ),*/ - if (!isDesktop) - const SizedBox( - height: 4, - ), - if (!isDesktop) - Text( - walletName, - textAlign: TextAlign.center, - style: STextStyles.label(context).copyWith( - fontSize: 12, - ), - ), - if (!isDesktop) - const SizedBox( - height: 4, - ), - Text( - "Recovery Phrase", - textAlign: TextAlign.center, + return MasterScaffold( + isDesktop: isDesktop, + appBar: isDesktop + ? const DesktopAppBar( + isCompactHeight: false, + leading: AppBarBackButton(), + trailing: ExitToMyStackButton(), + ) + : AppBar( + leading: const AppBarBackButton(), + actions: [ + Padding( + padding: const EdgeInsets.only( + top: 10, + bottom: 10, + right: 10, + ), + child: AppBarIconButton( + semanticsLabel: + "Question Button. Opens A Dialog For Recovery Phrase Explanation.", + icon: SvgPicture.asset( + Assets.svg.circleQuestion, + width: 20, + height: 20, + color: Theme.of(context) + .extension()! + .accentColorDark, + ), + onPressed: () async { + await showDialog( + context: context, + builder: (context) => + const RecoveryPhraseExplanationDialog(), + ); + }, + ), + ) + ], + ), + body: ConditionalParent( + condition: !isDesktop, + builder: (child) => LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.all(16), + child: child, + ), + ), + ), + ); + }, + ), + child: Column( + crossAxisAlignment: isDesktop + ? CrossAxisAlignment.center + : CrossAxisAlignment.stretch, + children: [ + if (isDesktop) + const Spacer( + flex: 10, + ), + if (!isDesktop) + const SizedBox( + height: 4, + ), + if (!isDesktop) + Text( + walletName, + textAlign: TextAlign.center, + style: STextStyles.label(context).copyWith( + fontSize: 12, + ), + ), + if (!isDesktop) + const SizedBox( + height: 4, + ), + Text( + "Recovery Phrase", + textAlign: TextAlign.center, + style: isDesktop + ? STextStyles.desktopH2(context) + : STextStyles.pageTitleH1(context), + ), + SizedBox( + height: isDesktop ? 32 : 16, + ), + RoundedWhiteContainer( + padding: const EdgeInsets.all(32), + width: isDesktop ? 480 : null, + child: isDesktop + ? Text( + "On the next screen you will see " + "$seedCount " + "words that make up your recovery phrase.\n\nPlease " + "write it down. Keep it safe and never share it with " + "anyone. Your recovery phrase is the only way you can" + " access your funds if you forget your PIN, lose your" + " phone, etc.\n\nStack Wallet does not keep nor is " + "able to restore your recover phrase. Only you have " + "access to your wallet.", style: isDesktop - ? STextStyles.desktopH2(context) - : STextStyles.pageTitleH1(context), - ), - SizedBox( - height: isDesktop ? 32 : 16, - ), - RoundedWhiteContainer( - padding: const EdgeInsets.all(32), - width: isDesktop ? 480 : null, - child: isDesktop - ? Text( - "On the next screen you will see " - "$seedCount " - "words that make up your recovery phrase.\n\nPlease " - "write it down. Keep it safe and never share it with " - "anyone. Your recovery phrase is the only way you can" - " access your funds if you forget your PIN, lose your" - " phone, etc.\n\nStack Wallet does not keep nor is " - "able to restore your recover phrase. Only you have " - "access to your wallet.", - style: isDesktop - ? STextStyles.desktopTextMediumRegular( - context) - : STextStyles.subtitle(context).copyWith( - fontSize: 12, - ), - ) - : Column( - children: [ - Text( - "Important", - style: - STextStyles.desktopH3(context).copyWith( - color: Theme.of(context) - .extension()! - .accentColorBlue, - ), - ), - const SizedBox( - height: 24, - ), - RichText( - textAlign: TextAlign.center, - text: TextSpan( - style: STextStyles.desktopH3(context) - .copyWith(fontSize: 18), - children: [ - TextSpan( - text: - "On the next screen you will be given ", - style: STextStyles.desktopH3(context) - .copyWith( - color: Theme.of(context) - .extension()! - .textDark, - fontSize: 18, - height: 1.3, - ), - ), - TextSpan( - text: "$seedCount words", - style: STextStyles.desktopH3(context) - .copyWith( - color: Theme.of(context) - .extension()! - .accentColorBlue, - fontSize: 18, - height: 1.3, - ), - ), - TextSpan( - text: ". They are your ", - style: STextStyles.desktopH3(context) - .copyWith( - color: Theme.of(context) - .extension()! - .textDark, - fontSize: 18, - height: 1.3, - ), - ), - TextSpan( - text: "recovery phrase", - style: STextStyles.desktopH3(context) - .copyWith( - color: Theme.of(context) - .extension()! - .accentColorBlue, - fontSize: 18, - height: 1.3, - ), - ), - TextSpan( - text: ".", - style: STextStyles.desktopH3(context) - .copyWith( - color: Theme.of(context) - .extension()! - .textDark, - fontSize: 18, - height: 1.3, - ), - ), - ], - ), - ), - const SizedBox( - height: 40, - ), - Column( - children: [ - Row( - children: [ - SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - radiusMultiplier: 20, - padding: const EdgeInsets.all(9), - color: Theme.of(context) - .extension()! - .buttonBackSecondary, - child: SvgPicture.asset( - Assets.svg.pencil, - color: Theme.of(context) - .extension()! - .accentColorDark, - ), - ), - ), - const SizedBox( - width: 20, - ), - Text( - "Write them down.", - style: - STextStyles.navBarTitle(context), - ), - ], - ), - const SizedBox( - height: 30, - ), - Row( - children: [ - SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - radiusMultiplier: 20, - padding: const EdgeInsets.all(8), - color: Theme.of(context) - .extension()! - .buttonBackSecondary, - child: SvgPicture.asset( - Assets.svg.lock, - color: Theme.of(context) - .extension()! - .accentColorDark, - ), - ), - ), - const SizedBox( - width: 20, - ), - Text( - "Keep them safe.", - style: - STextStyles.navBarTitle(context), - ), - ], - ), - const SizedBox( - height: 30, - ), - Row( - children: [ - SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - radiusMultiplier: 20, - padding: const EdgeInsets.all(8), - color: Theme.of(context) - .extension()! - .buttonBackSecondary, - child: SvgPicture.asset( - Assets.svg.eyeSlash, - color: Theme.of(context) - .extension()! - .accentColorDark, - ), - ), - ), - const SizedBox( - width: 20, - ), - Expanded( - child: Text( - "Do not show them to anyone.", - style: STextStyles.navBarTitle( - context), - ), - ), - ], - ), - ], - ) - ], + ? STextStyles.desktopTextMediumRegular(context) + : STextStyles.subtitle(context).copyWith( + fontSize: 12, ), - ), - if (!isDesktop) const Spacer(), - if (!isDesktop) - const SizedBox( - height: 16, - ), - if (isDesktop) - const SizedBox( - height: 32, - ), - ConstrainedBox( - constraints: BoxConstraints( - maxWidth: isDesktop ? 480 : 0, - ), - child: Consumer( - builder: (_, ref, __) { - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisSize: MainAxisSize.min, + ) + : Column( + children: [ + Text( + "Important", + style: STextStyles.desktopH3(context).copyWith( + color: Theme.of(context) + .extension()! + .accentColorBlue, + ), + ), + const SizedBox( + height: 24, + ), + RichText( + textAlign: TextAlign.center, + text: TextSpan( + style: STextStyles.desktopH3(context) + .copyWith(fontSize: 18), children: [ - GestureDetector( - onTap: () { - final value = ref - .read(checkBoxStateProvider.state) - .state; - ref.read(checkBoxStateProvider.state).state = - !value; - }, - child: Container( - color: Colors.transparent, - child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SizedBox( - width: 24, - height: 24, - child: Checkbox( - materialTapTargetSize: - MaterialTapTargetSize.shrinkWrap, - value: ref - .watch( - checkBoxStateProvider.state) - .state, - onChanged: (newValue) { - ref - .read( - checkBoxStateProvider.state) - .state = newValue!; - }, - ), - ), - SizedBox( - width: isDesktop ? 20 : 10, - ), - Flexible( - child: Text( - "I understand that Stack Wallet does not keep and cannot restore my recovery phrase, and If I lose my recovery phrase, I will not be able to access my funds.", - style: isDesktop - ? STextStyles.desktopTextMedium( - context) - : STextStyles.baseXS(context) - .copyWith( - height: 1.3, - ), - ), - ), - ], - ), + TextSpan( + text: "On the next screen you will be given ", + style: STextStyles.desktopH3(context).copyWith( + color: Theme.of(context) + .extension()! + .textDark, + fontSize: 18, + height: 1.3, ), ), - SizedBox( - height: isDesktop ? 32 : 16, - ), - ConstrainedBox( - constraints: BoxConstraints( - minHeight: isDesktop ? 70 : 0, + TextSpan( + text: "$seedCount words", + style: STextStyles.desktopH3(context).copyWith( + color: Theme.of(context) + .extension()! + .accentColorBlue, + fontSize: 18, + height: 1.3, ), - child: TextButton( - onPressed: ref - .read(checkBoxStateProvider.state) - .state - ? () async { - try { - unawaited(showDialog( - context: context, - barrierDismissible: false, - useSafeArea: true, - builder: (ctx) { - return const Center( - child: LoadingIndicator( - width: 50, - height: 50, - ), - ); - }, - )); - String? otherDataJsonString; - if (widget.coin == Coin.tezos) { - otherDataJsonString = jsonEncode({ - WalletInfoKeys - .tezosDerivationPath: - Tezos.standardDerivationPath - .value, - }); - // }//todo: probably not needed (broken anyways) - // else if (widget.coin == Coin.epicCash) { - // final int secondsSinceEpoch = - // DateTime.now().millisecondsSinceEpoch ~/ 1000; - // const int epicCashFirstBlock = 1565370278; - // const double overestimateSecondsPerBlock = 61; - // int chosenSeconds = secondsSinceEpoch - epicCashFirstBlock; - // int approximateHeight = chosenSeconds ~/ overestimateSecondsPerBlock; - // / - // // debugPrint( - // // "approximate height: $approximateHeight chosen_seconds: $chosenSeconds"); - // height = approximateHeight; - // if (height < 0) { - // height = 0; - // } - // - // otherDataJsonString = jsonEncode( - // { - // WalletInfoKeys.epiccashData: jsonEncode( - // ExtraEpiccashWalletInfo( - // receivingIndex: 0, - // changeIndex: 0, - // slatesToAddresses: {}, - // slatesToCommits: {}, - // lastScannedBlock: epicCashFirstBlock, - // restoreHeight: height, - // creationHeight: height, - // ).toMap(), - // ), - // }, - // ); - } else if (widget.coin == - Coin.firo) { - otherDataJsonString = jsonEncode( - { - WalletInfoKeys - .lelantusCoinIsarRescanRequired: - false, - }, - ); - } - - final info = WalletInfo.createNew( - coin: widget.coin, - name: widget.walletName, - otherDataJsonString: - otherDataJsonString, - ); - - var node = ref - .read( - nodeServiceChangeNotifierProvider) - .getPrimaryNodeFor(coin: coin); - - if (node == null) { - node = - DefaultNodes.getNodeFor(coin); - await ref - .read( - nodeServiceChangeNotifierProvider) - .setPrimaryNodeFor( - coin: coin, - node: node, - ); - } - - final txTracker = - TransactionNotificationTracker( - walletId: info.walletId, - ); - - int? wordCount; - String? mnemonicPassphrase; - String? mnemonic; - String? privateKey; - - wordCount = Constants - .defaultSeedPhraseLengthFor( - coin: info.coin, - ); - - if (coin == Coin.monero || - coin == Coin.wownero) { - // currently a special case due to the - // xmr/wow libraries handling their - // own mnemonic generation - } else if (wordCount > 0) { - if (ref - .read(pNewWalletOptions - .state) - .state != - null) { - if (coin - .hasMnemonicPassphraseSupport) { - mnemonicPassphrase = ref - .read(pNewWalletOptions - .state) - .state! - .mnemonicPassphrase; - } else {} - - wordCount = ref - .read( - pNewWalletOptions.state) - .state! - .mnemonicWordsCount; - } else { - mnemonicPassphrase = ""; - } - - if (wordCount < 12 || - 24 < wordCount || - wordCount % 3 != 0) { - throw Exception( - "Invalid word count"); - } - - final strength = - (wordCount ~/ 3) * 32; - - mnemonic = bip39.generateMnemonic( - strength: strength, - ); - } - - final wallet = await Wallet.create( - walletInfo: info, - mainDB: ref.read(mainDBProvider), - secureStorageInterface: - ref.read(secureStoreProvider), - nodeService: ref.read( - nodeServiceChangeNotifierProvider), - prefs: ref.read( - prefsChangeNotifierProvider), - mnemonicPassphrase: - mnemonicPassphrase, - mnemonic: mnemonic, - privateKey: privateKey, - ); - - await wallet.init(); - - // pop progress dialog - if (mounted) { - Navigator.pop(context); - } - // set checkbox back to unchecked to annoy users to agree again :P - ref - .read( - checkBoxStateProvider.state) - .state = false; - - if (mounted) { - unawaited(Navigator.of(context) - .pushNamed( - NewWalletRecoveryPhraseView - .routeName, - arguments: Tuple2( - wallet, - await (wallet - as MnemonicInterface) - .getMnemonicAsWords(), - ), - )); - } - } catch (e, s) { - Logging.instance.log("$e\n$s", - level: LogLevel.Fatal); - // TODO: handle gracefully - // any network/socket exception here will break new wallet creation - rethrow; - } - } - : null, - style: ref - .read(checkBoxStateProvider.state) - .state - ? Theme.of(context) - .extension()! - .getPrimaryEnabledButtonStyle(context) - : Theme.of(context) - .extension()! - .getPrimaryDisabledButtonStyle( - context), - child: Text( - "View recovery phrase", - style: isDesktop - ? ref - .read( - checkBoxStateProvider.state) - .state - ? STextStyles.desktopButtonEnabled( - context) - : STextStyles.desktopButtonDisabled( - context) - : STextStyles.button(context), - ), + ), + TextSpan( + text: ". They are your ", + style: STextStyles.desktopH3(context).copyWith( + color: Theme.of(context) + .extension()! + .textDark, + fontSize: 18, + height: 1.3, + ), + ), + TextSpan( + text: "recovery phrase", + style: STextStyles.desktopH3(context).copyWith( + color: Theme.of(context) + .extension()! + .accentColorBlue, + fontSize: 18, + height: 1.3, + ), + ), + TextSpan( + text: ".", + style: STextStyles.desktopH3(context).copyWith( + color: Theme.of(context) + .extension()! + .textDark, + fontSize: 18, + height: 1.3, ), ), ], - ); - }, - ), + ), + ), + const SizedBox( + height: 40, + ), + Column( + children: [ + Row( + children: [ + SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + radiusMultiplier: 20, + padding: const EdgeInsets.all(9), + color: Theme.of(context) + .extension()! + .buttonBackSecondary, + child: SvgPicture.asset( + Assets.svg.pencil, + color: Theme.of(context) + .extension()! + .accentColorDark, + ), + ), + ), + const SizedBox( + width: 20, + ), + Text( + "Write them down.", + style: STextStyles.navBarTitle(context), + ), + ], + ), + const SizedBox( + height: 30, + ), + Row( + children: [ + SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + radiusMultiplier: 20, + padding: const EdgeInsets.all(8), + color: Theme.of(context) + .extension()! + .buttonBackSecondary, + child: SvgPicture.asset( + Assets.svg.lock, + color: Theme.of(context) + .extension()! + .accentColorDark, + ), + ), + ), + const SizedBox( + width: 20, + ), + Text( + "Keep them safe.", + style: STextStyles.navBarTitle(context), + ), + ], + ), + const SizedBox( + height: 30, + ), + Row( + children: [ + SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + radiusMultiplier: 20, + padding: const EdgeInsets.all(8), + color: Theme.of(context) + .extension()! + .buttonBackSecondary, + child: SvgPicture.asset( + Assets.svg.eyeSlash, + color: Theme.of(context) + .extension()! + .accentColorDark, + ), + ), + ), + const SizedBox( + width: 20, + ), + Expanded( + child: Text( + "Do not show them to anyone.", + style: STextStyles.navBarTitle(context), + ), + ), + ], + ), + ], + ) + ], ), - /*if (isDesktop) - const Spacer( - flex: 15, - ),*/ - ], - ), - ], ), - ), + if (!isDesktop) const Spacer(), + if (!isDesktop) + const SizedBox( + height: 16, + ), + if (isDesktop) + const SizedBox( + height: 32, + ), + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: isDesktop ? 480 : 0, + ), + child: Consumer( + builder: (_, ref, __) { + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisSize: MainAxisSize.min, + children: [ + GestureDetector( + onTap: () { + final value = + ref.read(checkBoxStateProvider.state).state; + ref.read(checkBoxStateProvider.state).state = !value; + }, + child: Container( + color: Colors.transparent, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 24, + height: 24, + child: Checkbox( + materialTapTargetSize: + MaterialTapTargetSize.shrinkWrap, + value: ref + .watch(checkBoxStateProvider.state) + .state, + onChanged: (newValue) { + ref + .read(checkBoxStateProvider.state) + .state = newValue!; + }, + ), + ), + SizedBox( + width: isDesktop ? 20 : 10, + ), + Flexible( + child: Text( + "I understand that Stack Wallet does not keep and cannot restore my recovery phrase, and If I lose my recovery phrase, I will not be able to access my funds.", + style: isDesktop + ? STextStyles.desktopTextMedium(context) + : STextStyles.baseXS(context).copyWith( + height: 1.3, + ), + ), + ), + ], + ), + ), + ), + SizedBox( + height: isDesktop ? 32 : 16, + ), + ConstrainedBox( + constraints: BoxConstraints( + minHeight: isDesktop ? 70 : 0, + ), + child: TextButton( + onPressed: ref.read(checkBoxStateProvider.state).state + ? () async { + try { + unawaited(showDialog( + context: context, + barrierDismissible: false, + useSafeArea: true, + builder: (ctx) { + return const Center( + child: LoadingIndicator( + width: 50, + height: 50, + ), + ); + }, + )); + String? otherDataJsonString; + if (widget.coin == Coin.tezos) { + otherDataJsonString = jsonEncode({ + WalletInfoKeys.tezosDerivationPath: + Tezos.standardDerivationPath.value, + }); + // }//todo: probably not needed (broken anyways) + // else if (widget.coin == Coin.epicCash) { + // final int secondsSinceEpoch = + // DateTime.now().millisecondsSinceEpoch ~/ 1000; + // const int epicCashFirstBlock = 1565370278; + // const double overestimateSecondsPerBlock = 61; + // int chosenSeconds = secondsSinceEpoch - epicCashFirstBlock; + // int approximateHeight = chosenSeconds ~/ overestimateSecondsPerBlock; + // / + // // debugPrint( + // // "approximate height: $approximateHeight chosen_seconds: $chosenSeconds"); + // height = approximateHeight; + // if (height < 0) { + // height = 0; + // } + // + // otherDataJsonString = jsonEncode( + // { + // WalletInfoKeys.epiccashData: jsonEncode( + // ExtraEpiccashWalletInfo( + // receivingIndex: 0, + // changeIndex: 0, + // slatesToAddresses: {}, + // slatesToCommits: {}, + // lastScannedBlock: epicCashFirstBlock, + // restoreHeight: height, + // creationHeight: height, + // ).toMap(), + // ), + // }, + // ); + } else if (widget.coin == Coin.firo) { + otherDataJsonString = jsonEncode( + { + WalletInfoKeys + .lelantusCoinIsarRescanRequired: + false, + }, + ); + } + + final info = WalletInfo.createNew( + coin: widget.coin, + name: widget.walletName, + otherDataJsonString: otherDataJsonString, + ); + + var node = ref + .read(nodeServiceChangeNotifierProvider) + .getPrimaryNodeFor(coin: coin); + + if (node == null) { + node = DefaultNodes.getNodeFor(coin); + await ref + .read( + nodeServiceChangeNotifierProvider) + .setPrimaryNodeFor( + coin: coin, + node: node, + ); + } + + final txTracker = + TransactionNotificationTracker( + walletId: info.walletId, + ); + + int? wordCount; + String? mnemonicPassphrase; + String? mnemonic; + String? privateKey; + + wordCount = + Constants.defaultSeedPhraseLengthFor( + coin: info.coin, + ); + + if (coin == Coin.monero || + coin == Coin.wownero) { + // currently a special case due to the + // xmr/wow libraries handling their + // own mnemonic generation + } else if (wordCount > 0) { + if (ref + .read(pNewWalletOptions.state) + .state != + null) { + if (coin.hasMnemonicPassphraseSupport) { + mnemonicPassphrase = ref + .read(pNewWalletOptions.state) + .state! + .mnemonicPassphrase; + } else {} + + wordCount = ref + .read(pNewWalletOptions.state) + .state! + .mnemonicWordsCount; + } else { + mnemonicPassphrase = ""; + } + + if (wordCount < 12 || + 24 < wordCount || + wordCount % 3 != 0) { + throw Exception("Invalid word count"); + } + + final strength = (wordCount ~/ 3) * 32; + + mnemonic = bip39.generateMnemonic( + strength: strength, + ); + } + + final wallet = await Wallet.create( + walletInfo: info, + mainDB: ref.read(mainDBProvider), + secureStorageInterface: + ref.read(secureStoreProvider), + nodeService: ref.read( + nodeServiceChangeNotifierProvider), + prefs: + ref.read(prefsChangeNotifierProvider), + mnemonicPassphrase: mnemonicPassphrase, + mnemonic: mnemonic, + privateKey: privateKey, + ); + + await wallet.init(); + + // pop progress dialog + if (mounted) { + Navigator.pop(context); + } + // set checkbox back to unchecked to annoy users to agree again :P + ref + .read(checkBoxStateProvider.state) + .state = false; + + if (mounted) { + unawaited(Navigator.of(context).pushNamed( + NewWalletRecoveryPhraseView.routeName, + arguments: Tuple2( + wallet, + await (wallet as MnemonicInterface) + .getMnemonicAsWords(), + ), + )); + } + } catch (e, s) { + Logging.instance + .log("$e\n$s", level: LogLevel.Fatal); + // TODO: handle gracefully + // any network/socket exception here will break new wallet creation + rethrow; + } + } + : null, + style: ref.read(checkBoxStateProvider.state).state + ? Theme.of(context) + .extension()! + .getPrimaryEnabledButtonStyle(context) + : Theme.of(context) + .extension()! + .getPrimaryDisabledButtonStyle(context), + child: Text( + "View recovery phrase", + style: isDesktop + ? ref.read(checkBoxStateProvider.state).state + ? STextStyles.desktopButtonEnabled(context) + : STextStyles.desktopButtonDisabled(context) + : STextStyles.button(context), + ), + ), + ), + ], + ); + }, + ), + ), + if (isDesktop) + const Spacer( + flex: 15, + ), + ], ), ), ); From 10a6706ec08c5ec1e3f6c67880d51a50aae3d2f9 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Mon, 29 Jan 2024 13:22:37 -0600 Subject: [PATCH 2/2] wrap recovery phrase warning view in scroll and center views --- ...w_wallet_recovery_phrase_warning_view.dart | 1071 +++++++++-------- 1 file changed, 554 insertions(+), 517 deletions(-) diff --git a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart index 9a1303978..8e3f8750f 100644 --- a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart +++ b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart @@ -35,7 +35,6 @@ import 'package:stackwallet/wallets/crypto_currency/coins/tezos.dart'; import 'package:stackwallet/wallets/isar/models/wallet_info.dart'; import 'package:stackwallet/wallets/wallet/wallet.dart'; import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart'; -import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; @@ -122,533 +121,571 @@ class _NewWalletRecoveryPhraseWarningViewState ) ], ), - body: ConditionalParent( - condition: !isDesktop, - builder: (child) => LayoutBuilder( - builder: (context, constraints) { - return SingleChildScrollView( - child: ConstrainedBox( - constraints: BoxConstraints( - minHeight: constraints.maxHeight, - ), - child: IntrinsicHeight( - child: Padding( - padding: const EdgeInsets.all(16), - child: child, - ), - ), - ), - ); - }, - ), - child: Column( - crossAxisAlignment: isDesktop - ? CrossAxisAlignment.center - : CrossAxisAlignment.stretch, - children: [ - if (isDesktop) - const Spacer( - flex: 10, - ), - if (!isDesktop) - const SizedBox( - height: 4, - ), - if (!isDesktop) - Text( - walletName, - textAlign: TextAlign.center, - style: STextStyles.label(context).copyWith( - fontSize: 12, - ), - ), - if (!isDesktop) - const SizedBox( - height: 4, - ), - Text( - "Recovery Phrase", - textAlign: TextAlign.center, - style: isDesktop - ? STextStyles.desktopH2(context) - : STextStyles.pageTitleH1(context), - ), - SizedBox( - height: isDesktop ? 32 : 16, - ), - RoundedWhiteContainer( - padding: const EdgeInsets.all(32), - width: isDesktop ? 480 : null, - child: isDesktop - ? Text( - "On the next screen you will see " - "$seedCount " - "words that make up your recovery phrase.\n\nPlease " - "write it down. Keep it safe and never share it with " - "anyone. Your recovery phrase is the only way you can" - " access your funds if you forget your PIN, lose your" - " phone, etc.\n\nStack Wallet does not keep nor is " - "able to restore your recover phrase. Only you have " - "access to your wallet.", + body: SingleChildScrollView( + child: ConstrainedBox( + constraints: + BoxConstraints(maxWidth: isDesktop ? 480 : double.infinity), + child: IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.all(16), + child: Center( + child: Column( + crossAxisAlignment: isDesktop + ? CrossAxisAlignment.center + : CrossAxisAlignment.stretch, + children: [ + /*if (isDesktop) + const Spacer( + flex: 10, + ),*/ + if (!isDesktop) + const SizedBox( + height: 4, + ), + if (!isDesktop) + Text( + walletName, + textAlign: TextAlign.center, + style: STextStyles.label(context).copyWith( + fontSize: 12, + ), + ), + if (!isDesktop) + const SizedBox( + height: 4, + ), + Text( + "Recovery Phrase", + textAlign: TextAlign.center, style: isDesktop - ? STextStyles.desktopTextMediumRegular(context) - : STextStyles.subtitle(context).copyWith( - fontSize: 12, - ), - ) - : Column( - children: [ - Text( - "Important", - style: STextStyles.desktopH3(context).copyWith( - color: Theme.of(context) - .extension()! - .accentColorBlue, - ), - ), - const SizedBox( - height: 24, - ), - RichText( - textAlign: TextAlign.center, - text: TextSpan( - style: STextStyles.desktopH3(context) - .copyWith(fontSize: 18), - children: [ - TextSpan( - text: "On the next screen you will be given ", - style: STextStyles.desktopH3(context).copyWith( - color: Theme.of(context) - .extension()! - .textDark, - fontSize: 18, - height: 1.3, - ), - ), - TextSpan( - text: "$seedCount words", - style: STextStyles.desktopH3(context).copyWith( - color: Theme.of(context) - .extension()! - .accentColorBlue, - fontSize: 18, - height: 1.3, - ), - ), - TextSpan( - text: ". They are your ", - style: STextStyles.desktopH3(context).copyWith( - color: Theme.of(context) - .extension()! - .textDark, - fontSize: 18, - height: 1.3, - ), - ), - TextSpan( - text: "recovery phrase", - style: STextStyles.desktopH3(context).copyWith( - color: Theme.of(context) - .extension()! - .accentColorBlue, - fontSize: 18, - height: 1.3, - ), - ), - TextSpan( - text: ".", - style: STextStyles.desktopH3(context).copyWith( - color: Theme.of(context) - .extension()! - .textDark, - fontSize: 18, - height: 1.3, - ), - ), - ], - ), - ), - const SizedBox( - height: 40, - ), - Column( - children: [ - Row( - children: [ - SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - radiusMultiplier: 20, - padding: const EdgeInsets.all(9), - color: Theme.of(context) - .extension()! - .buttonBackSecondary, - child: SvgPicture.asset( - Assets.svg.pencil, - color: Theme.of(context) - .extension()! - .accentColorDark, - ), - ), - ), - const SizedBox( - width: 20, - ), - Text( - "Write them down.", - style: STextStyles.navBarTitle(context), - ), - ], - ), - const SizedBox( - height: 30, - ), - Row( - children: [ - SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - radiusMultiplier: 20, - padding: const EdgeInsets.all(8), - color: Theme.of(context) - .extension()! - .buttonBackSecondary, - child: SvgPicture.asset( - Assets.svg.lock, - color: Theme.of(context) - .extension()! - .accentColorDark, - ), - ), - ), - const SizedBox( - width: 20, - ), - Text( - "Keep them safe.", - style: STextStyles.navBarTitle(context), - ), - ], - ), - const SizedBox( - height: 30, - ), - Row( - children: [ - SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - radiusMultiplier: 20, - padding: const EdgeInsets.all(8), - color: Theme.of(context) - .extension()! - .buttonBackSecondary, - child: SvgPicture.asset( - Assets.svg.eyeSlash, - color: Theme.of(context) - .extension()! - .accentColorDark, - ), - ), - ), - const SizedBox( - width: 20, - ), - Expanded( - child: Text( - "Do not show them to anyone.", - style: STextStyles.navBarTitle(context), - ), - ), - ], - ), - ], - ) - ], + ? STextStyles.desktopH2(context) + : STextStyles.pageTitleH1(context), ), - ), - if (!isDesktop) const Spacer(), - if (!isDesktop) - const SizedBox( - height: 16, - ), - if (isDesktop) - const SizedBox( - height: 32, - ), - ConstrainedBox( - constraints: BoxConstraints( - maxWidth: isDesktop ? 480 : 0, - ), - child: Consumer( - builder: (_, ref, __) { - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisSize: MainAxisSize.min, - children: [ - GestureDetector( - onTap: () { - final value = - ref.read(checkBoxStateProvider.state).state; - ref.read(checkBoxStateProvider.state).state = !value; - }, - child: Container( - color: Colors.transparent, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - width: 24, - height: 24, - child: Checkbox( - materialTapTargetSize: - MaterialTapTargetSize.shrinkWrap, - value: ref - .watch(checkBoxStateProvider.state) - .state, - onChanged: (newValue) { - ref - .read(checkBoxStateProvider.state) - .state = newValue!; - }, + SizedBox( + height: isDesktop ? 32 : 16, + ), + RoundedWhiteContainer( + padding: const EdgeInsets.all(32), + width: isDesktop ? 480 : null, + child: isDesktop + ? Text( + "On the next screen you will see " + "$seedCount " + "words that make up your recovery phrase.\n\nPlease " + "write it down. Keep it safe and never share it with " + "anyone. Your recovery phrase is the only way you can" + " access your funds if you forget your PIN, lose your" + " phone, etc.\n\nStack Wallet does not keep nor is " + "able to restore your recover phrase. Only you have " + "access to your wallet.", + style: isDesktop + ? STextStyles.desktopTextMediumRegular( + context) + : STextStyles.subtitle(context).copyWith( + fontSize: 12, + ), + ) + : Column( + children: [ + Text( + "Important", + style: + STextStyles.desktopH3(context).copyWith( + color: Theme.of(context) + .extension()! + .accentColorBlue, + ), ), - ), - SizedBox( - width: isDesktop ? 20 : 10, - ), - Flexible( - child: Text( - "I understand that Stack Wallet does not keep and cannot restore my recovery phrase, and If I lose my recovery phrase, I will not be able to access my funds.", - style: isDesktop - ? STextStyles.desktopTextMedium(context) - : STextStyles.baseXS(context).copyWith( + const SizedBox( + height: 24, + ), + RichText( + textAlign: TextAlign.center, + text: TextSpan( + style: STextStyles.desktopH3(context) + .copyWith(fontSize: 18), + children: [ + TextSpan( + text: + "On the next screen you will be given ", + style: STextStyles.desktopH3(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + fontSize: 18, height: 1.3, ), + ), + TextSpan( + text: "$seedCount words", + style: STextStyles.desktopH3(context) + .copyWith( + color: Theme.of(context) + .extension()! + .accentColorBlue, + fontSize: 18, + height: 1.3, + ), + ), + TextSpan( + text: ". They are your ", + style: STextStyles.desktopH3(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + fontSize: 18, + height: 1.3, + ), + ), + TextSpan( + text: "recovery phrase", + style: STextStyles.desktopH3(context) + .copyWith( + color: Theme.of(context) + .extension()! + .accentColorBlue, + fontSize: 18, + height: 1.3, + ), + ), + TextSpan( + text: ".", + style: STextStyles.desktopH3(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + fontSize: 18, + height: 1.3, + ), + ), + ], + ), + ), + const SizedBox( + height: 40, + ), + Column( + children: [ + Row( + children: [ + SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + radiusMultiplier: 20, + padding: const EdgeInsets.all(9), + color: Theme.of(context) + .extension()! + .buttonBackSecondary, + child: SvgPicture.asset( + Assets.svg.pencil, + color: Theme.of(context) + .extension()! + .accentColorDark, + ), + ), + ), + const SizedBox( + width: 20, + ), + Text( + "Write them down.", + style: + STextStyles.navBarTitle(context), + ), + ], + ), + const SizedBox( + height: 30, + ), + Row( + children: [ + SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + radiusMultiplier: 20, + padding: const EdgeInsets.all(8), + color: Theme.of(context) + .extension()! + .buttonBackSecondary, + child: SvgPicture.asset( + Assets.svg.lock, + color: Theme.of(context) + .extension()! + .accentColorDark, + ), + ), + ), + const SizedBox( + width: 20, + ), + Text( + "Keep them safe.", + style: + STextStyles.navBarTitle(context), + ), + ], + ), + const SizedBox( + height: 30, + ), + Row( + children: [ + SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + radiusMultiplier: 20, + padding: const EdgeInsets.all(8), + color: Theme.of(context) + .extension()! + .buttonBackSecondary, + child: SvgPicture.asset( + Assets.svg.eyeSlash, + color: Theme.of(context) + .extension()! + .accentColorDark, + ), + ), + ), + const SizedBox( + width: 20, + ), + Expanded( + child: Text( + "Do not show them to anyone.", + style: STextStyles.navBarTitle( + context), + ), + ), + ], + ), + ], + ) + ], + ), + ), + if (!isDesktop) const Spacer(), + if (!isDesktop) + const SizedBox( + height: 16, + ), + if (isDesktop) + const SizedBox( + height: 32, + ), + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: isDesktop ? 480 : 0, + ), + child: Consumer( + builder: (_, ref, __) { + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisSize: MainAxisSize.min, + children: [ + GestureDetector( + onTap: () { + final value = ref + .read(checkBoxStateProvider.state) + .state; + ref.read(checkBoxStateProvider.state).state = + !value; + }, + child: Container( + color: Colors.transparent, + child: Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + SizedBox( + width: 24, + height: 24, + child: Checkbox( + materialTapTargetSize: + MaterialTapTargetSize.shrinkWrap, + value: ref + .watch( + checkBoxStateProvider.state) + .state, + onChanged: (newValue) { + ref + .read( + checkBoxStateProvider.state) + .state = newValue!; + }, + ), + ), + SizedBox( + width: isDesktop ? 20 : 10, + ), + Flexible( + child: Text( + "I understand that Stack Wallet does not keep and cannot restore my recovery phrase, and If I lose my recovery phrase, I will not be able to access my funds.", + style: isDesktop + ? STextStyles.desktopTextMedium( + context) + : STextStyles.baseXS(context) + .copyWith( + height: 1.3, + ), + ), + ), + ], + ), + ), + ), + SizedBox( + height: isDesktop ? 32 : 16, + ), + ConstrainedBox( + constraints: BoxConstraints( + minHeight: isDesktop ? 70 : 0, + ), + child: TextButton( + onPressed: ref + .read(checkBoxStateProvider.state) + .state + ? () async { + try { + unawaited(showDialog( + context: context, + barrierDismissible: false, + useSafeArea: true, + builder: (ctx) { + return const Center( + child: LoadingIndicator( + width: 50, + height: 50, + ), + ); + }, + )); + String? otherDataJsonString; + if (widget.coin == Coin.tezos) { + otherDataJsonString = jsonEncode({ + WalletInfoKeys + .tezosDerivationPath: + Tezos.standardDerivationPath + .value, + }); + // }//todo: probably not needed (broken anyways) + // else if (widget.coin == Coin.epicCash) { + // final int secondsSinceEpoch = + // DateTime.now().millisecondsSinceEpoch ~/ 1000; + // const int epicCashFirstBlock = 1565370278; + // const double overestimateSecondsPerBlock = 61; + // int chosenSeconds = secondsSinceEpoch - epicCashFirstBlock; + // int approximateHeight = chosenSeconds ~/ overestimateSecondsPerBlock; + // / + // // debugPrint( + // // "approximate height: $approximateHeight chosen_seconds: $chosenSeconds"); + // height = approximateHeight; + // if (height < 0) { + // height = 0; + // } + // + // otherDataJsonString = jsonEncode( + // { + // WalletInfoKeys.epiccashData: jsonEncode( + // ExtraEpiccashWalletInfo( + // receivingIndex: 0, + // changeIndex: 0, + // slatesToAddresses: {}, + // slatesToCommits: {}, + // lastScannedBlock: epicCashFirstBlock, + // restoreHeight: height, + // creationHeight: height, + // ).toMap(), + // ), + // }, + // ); + } else if (widget.coin == + Coin.firo) { + otherDataJsonString = jsonEncode( + { + WalletInfoKeys + .lelantusCoinIsarRescanRequired: + false, + }, + ); + } + + final info = WalletInfo.createNew( + coin: widget.coin, + name: widget.walletName, + otherDataJsonString: + otherDataJsonString, + ); + + var node = ref + .read( + nodeServiceChangeNotifierProvider) + .getPrimaryNodeFor(coin: coin); + + if (node == null) { + node = + DefaultNodes.getNodeFor(coin); + await ref + .read( + nodeServiceChangeNotifierProvider) + .setPrimaryNodeFor( + coin: coin, + node: node, + ); + } + + final txTracker = + TransactionNotificationTracker( + walletId: info.walletId, + ); + + int? wordCount; + String? mnemonicPassphrase; + String? mnemonic; + String? privateKey; + + wordCount = Constants + .defaultSeedPhraseLengthFor( + coin: info.coin, + ); + + if (coin == Coin.monero || + coin == Coin.wownero) { + // currently a special case due to the + // xmr/wow libraries handling their + // own mnemonic generation + } else if (wordCount > 0) { + if (ref + .read(pNewWalletOptions + .state) + .state != + null) { + if (coin + .hasMnemonicPassphraseSupport) { + mnemonicPassphrase = ref + .read(pNewWalletOptions + .state) + .state! + .mnemonicPassphrase; + } else {} + + wordCount = ref + .read( + pNewWalletOptions.state) + .state! + .mnemonicWordsCount; + } else { + mnemonicPassphrase = ""; + } + + if (wordCount < 12 || + 24 < wordCount || + wordCount % 3 != 0) { + throw Exception( + "Invalid word count"); + } + + final strength = + (wordCount ~/ 3) * 32; + + mnemonic = bip39.generateMnemonic( + strength: strength, + ); + } + + final wallet = await Wallet.create( + walletInfo: info, + mainDB: ref.read(mainDBProvider), + secureStorageInterface: + ref.read(secureStoreProvider), + nodeService: ref.read( + nodeServiceChangeNotifierProvider), + prefs: ref.read( + prefsChangeNotifierProvider), + mnemonicPassphrase: + mnemonicPassphrase, + mnemonic: mnemonic, + privateKey: privateKey, + ); + + await wallet.init(); + + // pop progress dialog + if (mounted) { + Navigator.pop(context); + } + // set checkbox back to unchecked to annoy users to agree again :P + ref + .read( + checkBoxStateProvider.state) + .state = false; + + if (mounted) { + unawaited(Navigator.of(context) + .pushNamed( + NewWalletRecoveryPhraseView + .routeName, + arguments: Tuple2( + wallet, + await (wallet + as MnemonicInterface) + .getMnemonicAsWords(), + ), + )); + } + } catch (e, s) { + Logging.instance.log("$e\n$s", + level: LogLevel.Fatal); + // TODO: handle gracefully + // any network/socket exception here will break new wallet creation + rethrow; + } + } + : null, + style: ref + .read(checkBoxStateProvider.state) + .state + ? Theme.of(context) + .extension()! + .getPrimaryEnabledButtonStyle(context) + : Theme.of(context) + .extension()! + .getPrimaryDisabledButtonStyle( + context), + child: Text( + "View recovery phrase", + style: isDesktop + ? ref + .read( + checkBoxStateProvider.state) + .state + ? STextStyles.desktopButtonEnabled( + context) + : STextStyles.desktopButtonDisabled( + context) + : STextStyles.button(context), + ), ), ), ], - ), - ), + ); + }, ), - SizedBox( - height: isDesktop ? 32 : 16, - ), - ConstrainedBox( - constraints: BoxConstraints( - minHeight: isDesktop ? 70 : 0, - ), - child: TextButton( - onPressed: ref.read(checkBoxStateProvider.state).state - ? () async { - try { - unawaited(showDialog( - context: context, - barrierDismissible: false, - useSafeArea: true, - builder: (ctx) { - return const Center( - child: LoadingIndicator( - width: 50, - height: 50, - ), - ); - }, - )); - String? otherDataJsonString; - if (widget.coin == Coin.tezos) { - otherDataJsonString = jsonEncode({ - WalletInfoKeys.tezosDerivationPath: - Tezos.standardDerivationPath.value, - }); - // }//todo: probably not needed (broken anyways) - // else if (widget.coin == Coin.epicCash) { - // final int secondsSinceEpoch = - // DateTime.now().millisecondsSinceEpoch ~/ 1000; - // const int epicCashFirstBlock = 1565370278; - // const double overestimateSecondsPerBlock = 61; - // int chosenSeconds = secondsSinceEpoch - epicCashFirstBlock; - // int approximateHeight = chosenSeconds ~/ overestimateSecondsPerBlock; - // / - // // debugPrint( - // // "approximate height: $approximateHeight chosen_seconds: $chosenSeconds"); - // height = approximateHeight; - // if (height < 0) { - // height = 0; - // } - // - // otherDataJsonString = jsonEncode( - // { - // WalletInfoKeys.epiccashData: jsonEncode( - // ExtraEpiccashWalletInfo( - // receivingIndex: 0, - // changeIndex: 0, - // slatesToAddresses: {}, - // slatesToCommits: {}, - // lastScannedBlock: epicCashFirstBlock, - // restoreHeight: height, - // creationHeight: height, - // ).toMap(), - // ), - // }, - // ); - } else if (widget.coin == Coin.firo) { - otherDataJsonString = jsonEncode( - { - WalletInfoKeys - .lelantusCoinIsarRescanRequired: - false, - }, - ); - } - - final info = WalletInfo.createNew( - coin: widget.coin, - name: widget.walletName, - otherDataJsonString: otherDataJsonString, - ); - - var node = ref - .read(nodeServiceChangeNotifierProvider) - .getPrimaryNodeFor(coin: coin); - - if (node == null) { - node = DefaultNodes.getNodeFor(coin); - await ref - .read( - nodeServiceChangeNotifierProvider) - .setPrimaryNodeFor( - coin: coin, - node: node, - ); - } - - final txTracker = - TransactionNotificationTracker( - walletId: info.walletId, - ); - - int? wordCount; - String? mnemonicPassphrase; - String? mnemonic; - String? privateKey; - - wordCount = - Constants.defaultSeedPhraseLengthFor( - coin: info.coin, - ); - - if (coin == Coin.monero || - coin == Coin.wownero) { - // currently a special case due to the - // xmr/wow libraries handling their - // own mnemonic generation - } else if (wordCount > 0) { - if (ref - .read(pNewWalletOptions.state) - .state != - null) { - if (coin.hasMnemonicPassphraseSupport) { - mnemonicPassphrase = ref - .read(pNewWalletOptions.state) - .state! - .mnemonicPassphrase; - } else {} - - wordCount = ref - .read(pNewWalletOptions.state) - .state! - .mnemonicWordsCount; - } else { - mnemonicPassphrase = ""; - } - - if (wordCount < 12 || - 24 < wordCount || - wordCount % 3 != 0) { - throw Exception("Invalid word count"); - } - - final strength = (wordCount ~/ 3) * 32; - - mnemonic = bip39.generateMnemonic( - strength: strength, - ); - } - - final wallet = await Wallet.create( - walletInfo: info, - mainDB: ref.read(mainDBProvider), - secureStorageInterface: - ref.read(secureStoreProvider), - nodeService: ref.read( - nodeServiceChangeNotifierProvider), - prefs: - ref.read(prefsChangeNotifierProvider), - mnemonicPassphrase: mnemonicPassphrase, - mnemonic: mnemonic, - privateKey: privateKey, - ); - - await wallet.init(); - - // pop progress dialog - if (mounted) { - Navigator.pop(context); - } - // set checkbox back to unchecked to annoy users to agree again :P - ref - .read(checkBoxStateProvider.state) - .state = false; - - if (mounted) { - unawaited(Navigator.of(context).pushNamed( - NewWalletRecoveryPhraseView.routeName, - arguments: Tuple2( - wallet, - await (wallet as MnemonicInterface) - .getMnemonicAsWords(), - ), - )); - } - } catch (e, s) { - Logging.instance - .log("$e\n$s", level: LogLevel.Fatal); - // TODO: handle gracefully - // any network/socket exception here will break new wallet creation - rethrow; - } - } - : null, - style: ref.read(checkBoxStateProvider.state).state - ? Theme.of(context) - .extension()! - .getPrimaryEnabledButtonStyle(context) - : Theme.of(context) - .extension()! - .getPrimaryDisabledButtonStyle(context), - child: Text( - "View recovery phrase", - style: isDesktop - ? ref.read(checkBoxStateProvider.state).state - ? STextStyles.desktopButtonEnabled(context) - : STextStyles.desktopButtonDisabled(context) - : STextStyles.button(context), - ), - ), - ), - ], - ); - }, + ), + /*if (isDesktop) + const Spacer( + flex: 15, + ),*/ + ], + ), ), ), - if (isDesktop) - const Spacer( - flex: 15, - ), - ], + ), ), ), );