diff --git a/docs/building.md b/docs/building.md index b56a87899..e7128df2e 100644 --- a/docs/building.md +++ b/docs/building.md @@ -123,7 +123,7 @@ flutter run android Note on Emulators: Only x86_64 emulators are supported, x86 emulators will not work #### Linux -Plug in your android device or use the emulator available via Android Studio and then run the following commands: +Run the following commands or launch via Android Studio: ``` flutter pub get flutter run linux diff --git a/lib/electrumx_rpc/cached_electrumx.dart b/lib/electrumx_rpc/cached_electrumx.dart index 8366e259f..cb5237bab 100644 --- a/lib/electrumx_rpc/cached_electrumx.dart +++ b/lib/electrumx_rpc/cached_electrumx.dart @@ -9,6 +9,7 @@ */ import 'dart:convert'; +import 'dart:math'; import 'package:stackwallet/db/hive/db.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; @@ -157,7 +158,6 @@ class CachedElectrumX { Future> getUsedCoinSerials({ required Coin coin, - int startNumber = 0, }) async { try { final box = await DB.instance.getUsedSerialsCacheBox(coin: coin); @@ -168,7 +168,7 @@ class CachedElectrumX { _list == null ? {} : List.from(_list).toSet(); final startNumber = - cachedSerials.length - 10; // 10 being some arbitrary buffer + max(0, cachedSerials.length - 100); // 100 being some arbitrary buffer final serials = await electrumXClient.getUsedCoinSerials( startNumber: startNumber, diff --git a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart index 4e04fcb80..f07941e36 100644 --- a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart +++ b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart @@ -14,6 +14,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/coin_image.dart'; +import 'package:stackwallet/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart'; import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart'; import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/exit_to_my_stack_button.dart'; @@ -336,46 +337,60 @@ class _NameYourWalletViewState extends ConsumerState { ref.read(walletsServiceChangeNotifierProvider); final name = textEditingController.text; - if (await walletsService.checkForDuplicate(name)) { - unawaited(showFloatingFlushBar( - type: FlushBarType.warning, - message: "Wallet name already in use.", - iconAsset: Assets.svg.circleAlert, - context: context, - )); - } else { - // hide keyboard if has focus - if (FocusScope.of(context).hasFocus) { - FocusScope.of(context).unfocus(); - await Future.delayed( - const Duration(milliseconds: 50)); - } + final hasDuplicateName = + await walletsService.checkForDuplicate(name); - if (mounted) { - switch (widget.addWalletType) { - case AddWalletType.New: - unawaited(Navigator.of(context).pushNamed( - NewWalletRecoveryPhraseWarningView.routeName, - arguments: Tuple2( - name, - coin, - ), - )); - break; - case AddWalletType.Restore: - ref - .read(mnemonicWordCountStateProvider.state) - .state = Constants.possibleLengthsForCoin( - coin) - .first; - unawaited(Navigator.of(context).pushNamed( - RestoreOptionsView.routeName, - arguments: Tuple2( - name, - coin, - ), - )); - break; + if (mounted) { + if (hasDuplicateName) { + unawaited(showFloatingFlushBar( + type: FlushBarType.warning, + message: "Wallet name already in use.", + iconAsset: Assets.svg.circleAlert, + context: context, + )); + } else { + // hide keyboard if has focus + if (FocusScope.of(context).hasFocus) { + FocusScope.of(context).unfocus(); + await Future.delayed( + const Duration(milliseconds: 50)); + } + + if (mounted) { + ref + .read(mnemonicWordCountStateProvider.state) + .state = + Constants.possibleLengthsForCoin(coin).last; + ref.read(pNewWalletOptions.notifier).state = null; + + switch (widget.addWalletType) { + case AddWalletType.New: + unawaited( + Navigator.of(context).pushNamed( + coin.hasMnemonicPassphraseSupport + ? NewWalletOptionsView.routeName + : NewWalletRecoveryPhraseWarningView + .routeName, + arguments: Tuple2( + name, + coin, + ), + ), + ); + break; + + case AddWalletType.Restore: + unawaited( + Navigator.of(context).pushNamed( + RestoreOptionsView.routeName, + arguments: Tuple2( + name, + coin, + ), + ), + ); + break; + } } } } diff --git a/lib/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart b/lib/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart new file mode 100644 index 000000000..3b50f8035 --- /dev/null +++ b/lib/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart @@ -0,0 +1,410 @@ +import 'package:dropdown_button2/dropdown_button2.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/coin_image.dart'; +import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart'; +import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/mobile_mnemonic_length_selector.dart'; +import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widgets/mnemonic_word_count_select_sheet.dart'; +import 'package:stackwallet/pages_desktop_specific/my_stack_view/exit_to_my_stack_button.dart'; +import 'package:stackwallet/providers/ui/verify_recovery_phrase/mnemonic_word_count_state_provider.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/background.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'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:stackwallet/widgets/stack_text_field.dart'; +import 'package:tuple/tuple.dart'; + +final pNewWalletOptions = + StateProvider<({String mnemonicPassphrase, int mnemonicWordsCount})?>( + (ref) => null); + +enum NewWalletOptions { + Default, + Advanced; +} + +class NewWalletOptionsView extends ConsumerStatefulWidget { + const NewWalletOptionsView({ + Key? key, + required this.walletName, + required this.coin, + }) : super(key: key); + + static const routeName = "/newWalletOptionsView"; + + final String walletName; + final Coin coin; + + @override + ConsumerState createState() => + _NewWalletOptionsViewState(); +} + +class _NewWalletOptionsViewState extends ConsumerState { + late final FocusNode passwordFocusNode; + late final TextEditingController passwordController; + + bool hidePassword = true; + NewWalletOptions _selectedOptions = NewWalletOptions.Default; + + @override + void initState() { + passwordController = TextEditingController(); + passwordFocusNode = FocusNode(); + + super.initState(); + } + + @override + void dispose() { + passwordController.dispose(); + passwordFocusNode.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final lengths = Constants.possibleLengthsForCoin(widget.coin).toList(); + return ConditionalParent( + condition: Util.isDesktop, + builder: (child) => DesktopScaffold( + background: Theme.of(context).extension()!.background, + appBar: const DesktopAppBar( + isCompactHeight: false, + leading: AppBarBackButton(), + trailing: ExitToMyStackButton(), + ), + body: SizedBox( + width: 480, + child: child, + ), + ), + child: ConditionalParent( + condition: !Util.isDesktop, + builder: (child) => Background( + child: Scaffold( + backgroundColor: + Theme.of(context).extension()!.background, + appBar: AppBar( + leading: const AppBarBackButton(), + title: Text( + "Wallet Options", + style: STextStyles.navBarTitle(context), + ), + ), + body: SafeArea( + child: LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: child, + ), + ), + ), + ); + }, + ), + ), + ), + ), + child: Column( + children: [ + if (Util.isDesktop) + const Spacer( + flex: 10, + ), + if (!Util.isDesktop) + const SizedBox( + height: 16, + ), + if (!Util.isDesktop) + CoinImage( + coin: widget.coin, + height: 100, + width: 100, + ), + if (Util.isDesktop) + Text( + "Wallet options", + textAlign: TextAlign.center, + style: Util.isDesktop + ? STextStyles.desktopH2(context) + : STextStyles.pageTitleH1(context), + ), + SizedBox( + height: Util.isDesktop ? 32 : 16, + ), + DropdownButtonHideUnderline( + child: DropdownButton2( + value: _selectedOptions, + items: [ + ...NewWalletOptions.values.map( + (e) => DropdownMenuItem( + value: e, + child: Text( + e.name, + style: STextStyles.desktopTextMedium(context), + ), + ), + ), + ], + onChanged: (value) { + if (value is NewWalletOptions) { + setState(() { + _selectedOptions = value; + }); + } + }, + isExpanded: true, + iconStyleData: IconStyleData( + icon: SvgPicture.asset( + Assets.svg.chevronDown, + width: 12, + height: 6, + color: Theme.of(context) + .extension()! + .textFieldActiveSearchIconRight, + ), + ), + dropdownStyleData: DropdownStyleData( + offset: const Offset(0, -10), + elevation: 0, + decoration: BoxDecoration( + color: Theme.of(context) + .extension()! + .textFieldDefaultBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + ), + menuItemStyleData: const MenuItemStyleData( + padding: EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + ), + ), + ), + const SizedBox( + height: 24, + ), + if (_selectedOptions == NewWalletOptions.Advanced) + Column( + children: [ + if (Util.isDesktop) + DropdownButtonHideUnderline( + child: DropdownButton2( + value: ref + .watch(mnemonicWordCountStateProvider.state) + .state, + items: [ + ...lengths.map( + (e) => DropdownMenuItem( + value: e, + child: Text( + "$e word seed", + style: STextStyles.desktopTextMedium(context), + ), + ), + ), + ], + onChanged: (value) { + if (value is int) { + ref + .read(mnemonicWordCountStateProvider.state) + .state = value; + } + }, + isExpanded: true, + iconStyleData: IconStyleData( + icon: SvgPicture.asset( + Assets.svg.chevronDown, + width: 12, + height: 6, + color: Theme.of(context) + .extension()! + .textFieldActiveSearchIconRight, + ), + ), + dropdownStyleData: DropdownStyleData( + offset: const Offset(0, -10), + elevation: 0, + decoration: BoxDecoration( + color: Theme.of(context) + .extension()! + .textFieldDefaultBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + ), + menuItemStyleData: const MenuItemStyleData( + padding: EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + ), + ), + ), + if (!Util.isDesktop) + MobileMnemonicLengthSelector( + chooseMnemonicLength: () { + showModalBottomSheet( + backgroundColor: Colors.transparent, + context: context, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(20), + ), + ), + builder: (_) { + return MnemonicWordCountSelectSheet( + lengthOptions: lengths, + ); + }, + ); + }, + ), + const SizedBox( + height: 24, + ), + RoundedWhiteContainer( + child: Center( + child: Text( + "You may add a BIP39 passphrase. This is optional. " + "You will need BOTH you seed and your passphrase to recover the wallet.", + style: Util.isDesktop + ? STextStyles.desktopTextExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ) + : STextStyles.itemSubtitle(context), + ), + ), + ), + const SizedBox( + height: 8, + ), + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + key: const Key("mnemonicPassphraseFieldKey1"), + focusNode: passwordFocusNode, + controller: passwordController, + style: Util.isDesktop + ? STextStyles.desktopTextMedium(context).copyWith( + height: 2, + ) + : STextStyles.field(context), + obscureText: hidePassword, + enableSuggestions: false, + autocorrect: false, + decoration: standardInputDecoration( + "BIP39 passphrase", + passwordFocusNode, + context, + ).copyWith( + suffixIcon: UnconstrainedBox( + child: ConditionalParent( + condition: Util.isDesktop, + builder: (child) => SizedBox( + height: 70, + child: child, + ), + child: Row( + children: [ + SizedBox( + width: Util.isDesktop ? 24 : 16, + ), + GestureDetector( + key: const Key( + "mnemonicPassphraseFieldShowPasswordButtonKey"), + onTap: () async { + setState(() { + hidePassword = !hidePassword; + }); + }, + child: SvgPicture.asset( + hidePassword + ? Assets.svg.eye + : Assets.svg.eyeSlash, + color: Theme.of(context) + .extension()! + .textDark3, + width: Util.isDesktop ? 24 : 16, + height: Util.isDesktop ? 24 : 16, + ), + ), + const SizedBox( + width: 12, + ), + ], + ), + ), + ), + ), + ), + ), + ], + ), + if (!Util.isDesktop) const Spacer(), + SizedBox( + height: Util.isDesktop ? 32 : 16, + ), + PrimaryButton( + label: "Continue", + onPressed: () { + if (_selectedOptions == NewWalletOptions.Advanced) { + ref.read(pNewWalletOptions.notifier).state = ( + mnemonicWordsCount: + ref.read(mnemonicWordCountStateProvider.state).state, + mnemonicPassphrase: passwordController.text, + ); + } else { + ref.read(pNewWalletOptions.notifier).state = null; + } + + Navigator.of(context).pushNamed( + NewWalletRecoveryPhraseWarningView.routeName, + arguments: Tuple2( + widget.walletName, + widget.coin, + ), + ); + }, + ), + if (!Util.isDesktop) + const SizedBox( + height: 16, + ), + if (Util.isDesktop) + const Spacer( + flex: 15, + ), + ], + ), + ), + ); + } +} 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 e373e817b..d843f6ec8 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 @@ -13,6 +13,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:stackwallet/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart'; import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart'; import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/recovery_phrase_explanation_dialog.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/exit_to_my_stack_button.dart'; @@ -38,7 +39,7 @@ import 'package:stackwallet/widgets/rounded_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:tuple/tuple.dart'; -class NewWalletRecoveryPhraseWarningView extends StatefulWidget { +class NewWalletRecoveryPhraseWarningView extends ConsumerStatefulWidget { const NewWalletRecoveryPhraseWarningView({ Key? key, required this.coin, @@ -51,12 +52,12 @@ class NewWalletRecoveryPhraseWarningView extends StatefulWidget { final String walletName; @override - State createState() => + ConsumerState createState() => _NewWalletRecoveryPhraseWarningViewState(); } class _NewWalletRecoveryPhraseWarningViewState - extends State { + extends ConsumerState { late final Coin coin; late final String walletName; late final bool isDesktop; @@ -72,6 +73,10 @@ class _NewWalletRecoveryPhraseWarningViewState @override Widget build(BuildContext context) { debugPrint("BUILD: $runtimeType"); + final options = ref.read(pNewWalletOptions.state).state; + + final seedCount = options?.mnemonicWordsCount ?? + Constants.defaultSeedPhraseLengthFor(coin: coin); return MasterScaffold( isDesktop: isDesktop, @@ -172,7 +177,7 @@ class _NewWalletRecoveryPhraseWarningViewState child: isDesktop ? Text( "On the next screen you will see " - "${Constants.defaultSeedPhraseLengthFor(coin: coin)} " + "$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" @@ -216,9 +221,7 @@ class _NewWalletRecoveryPhraseWarningViewState ), ), TextSpan( - text: - "${Constants.defaultSeedPhraseLengthFor(coin: coin)}" - " words", + text: "$seedCount words", style: STextStyles.desktopH3(context).copyWith( color: Theme.of(context) .extension()! @@ -496,7 +499,24 @@ class _NewWalletRecoveryPhraseWarningViewState final manager = Manager(wallet); - await manager.initializeNew(); + if (coin.hasMnemonicPassphraseSupport && + ref + .read(pNewWalletOptions.state) + .state != + null) { + await manager.initializeNew(( + mnemonicPassphrase: ref + .read(pNewWalletOptions.state) + .state! + .mnemonicPassphrase, + wordCount: ref + .read(pNewWalletOptions.state) + .state! + .mnemonicWordsCount, + )); + } else { + await manager.initializeNew(null); + } // pop progress dialog if (mounted) { diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart index 59d1c0a8f..44ac51aac 100644 --- a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart +++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart @@ -535,7 +535,7 @@ class _RestoreOptionsViewState extends ConsumerState { enableSuggestions: false, autocorrect: false, decoration: standardInputDecoration( - "Recovery phrase password", + "BIP39 passphrase", passwordFocusNode, context, ).copyWith( @@ -586,7 +586,9 @@ class _RestoreOptionsViewState extends ConsumerState { RoundedWhiteContainer( child: Center( child: Text( - "If the recovery phrase you are about to restore was created with an optional passphrase you can enter it here.", + "If the recovery phrase you are about to restore " + "was created with an optional BIP39 passphrase " + "you can enter it here.", style: isDesktop ? STextStyles.desktopTextExtraSmall(context) .copyWith( diff --git a/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_mnemonic_passphrase_dialog.dart b/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_mnemonic_passphrase_dialog.dart new file mode 100644 index 000000000..bae25a7e1 --- /dev/null +++ b/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_mnemonic_passphrase_dialog.dart @@ -0,0 +1,218 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/stack_dialog.dart'; +import 'package:stackwallet/widgets/stack_text_field.dart'; + +class VerifyMnemonicPassphraseDialog extends ConsumerStatefulWidget { + const VerifyMnemonicPassphraseDialog({super.key}); + + @override + ConsumerState createState() => + _VerifyMnemonicPassphraseDialogState(); +} + +class _VerifyMnemonicPassphraseDialogState + extends ConsumerState { + late final FocusNode passwordFocusNode; + late final TextEditingController passwordController; + + bool hidePassword = true; + + bool _verifyLock = false; + + void _verify() { + if (_verifyLock) { + return; + } + _verifyLock = true; + + if (passwordController.text == + ref.read(pNewWalletOptions.state).state!.mnemonicPassphrase) { + Navigator.of(context, rootNavigator: Util.isDesktop).pop("verified"); + } else { + showFloatingFlushBar( + type: FlushBarType.warning, + message: "Passphrase does not match", + context: context, + ); + } + + _verifyLock = false; + } + + @override + void initState() { + passwordController = TextEditingController(); + passwordFocusNode = FocusNode(); + + super.initState(); + } + + @override + void dispose() { + passwordController.dispose(); + passwordFocusNode.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ConditionalParent( + condition: Util.isDesktop, + builder: (child) => DesktopDialog( + maxHeight: double.infinity, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only( + left: 32, + ), + child: Text( + "Verify mnemonic passphrase", + style: STextStyles.desktopH3(context), + ), + ), + const DesktopDialogCloseButton(), + ], + ), + Padding( + padding: const EdgeInsets.only( + left: 32, + right: 32, + bottom: 32, + ), + child: child, + ), + ], + ), + ), + child: ConditionalParent( + condition: !Util.isDesktop, + builder: (child) => StackDialogBase( + keyboardPaddingAmount: MediaQuery.of(context).viewInsets.bottom, + child: child, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (!Util.isDesktop) + Text( + "Verify BIP39 passphrase", + style: STextStyles.pageTitleH2(context), + ), + const SizedBox( + height: 24, + ), + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + key: const Key("mnemonicPassphraseFieldKey1"), + focusNode: passwordFocusNode, + controller: passwordController, + style: Util.isDesktop + ? STextStyles.desktopTextMedium(context).copyWith( + height: 2, + ) + : STextStyles.field(context), + obscureText: hidePassword, + enableSuggestions: false, + autocorrect: false, + decoration: standardInputDecoration( + "Enter your BIP39 passphrase", + passwordFocusNode, + context, + ).copyWith( + suffixIcon: UnconstrainedBox( + child: ConditionalParent( + condition: Util.isDesktop, + builder: (child) => SizedBox( + height: 70, + child: child, + ), + child: Row( + children: [ + SizedBox( + width: Util.isDesktop ? 24 : 16, + ), + GestureDetector( + key: const Key( + "mnemonicPassphraseFieldShowPasswordButtonKey"), + onTap: () async { + setState(() { + hidePassword = !hidePassword; + }); + }, + child: SvgPicture.asset( + hidePassword + ? Assets.svg.eye + : Assets.svg.eyeSlash, + color: Theme.of(context) + .extension()! + .textDark3, + width: Util.isDesktop ? 24 : 16, + height: Util.isDesktop ? 24 : 16, + ), + ), + const SizedBox( + width: 12, + ), + ], + ), + ), + ), + ), + ), + ), + SizedBox( + height: Util.isDesktop ? 48 : 24, + ), + ConditionalParent( + condition: !Util.isDesktop, + builder: (child) => Row( + children: [ + Expanded( + child: SecondaryButton( + label: "Cancel", + onPressed: Navigator.of( + context, + rootNavigator: Util.isDesktop, + ).pop, + ), + ), + const SizedBox( + width: 16, + ), + Expanded( + child: child, + ), + ], + ), + child: PrimaryButton( + label: "Verify", + onPressed: _verify, + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart b/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart index fda4419d9..0d0083cc6 100644 --- a/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart +++ b/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart @@ -16,9 +16,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/add_wallet_views/add_token_view/edit_wallet_tokens_view.dart'; +import 'package:stackwallet/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart'; import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart'; import 'package:stackwallet/pages/add_wallet_views/select_wallet_for_token_view.dart'; import 'package:stackwallet/pages/add_wallet_views/verify_recovery_phrase_view/sub_widgets/word_table.dart'; +import 'package:stackwallet/pages/add_wallet_views/verify_recovery_phrase_view/verify_mnemonic_passphrase_dialog.dart'; import 'package:stackwallet/pages/home_view/home_view.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_home_view.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/exit_to_my_stack_button.dart'; @@ -98,8 +100,25 @@ class _VerifyRecoveryPhraseViewState // } // } + Future _verifyMnemonicPassphrase() async { + final result = await showDialog( + context: context, + builder: (_) => const VerifyMnemonicPassphraseDialog(), + ); + + return result == "verified"; + } + Future _continue(bool isMatch) async { if (isMatch) { + if (ref.read(pNewWalletOptions.state).state != null) { + final passphraseVerified = await _verifyMnemonicPassphrase(); + + if (!passphraseVerified) { + return; + } + } + await ref.read(walletsServiceChangeNotifierProvider).setMnemonicVerified( walletId: _manager.walletId, ); diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart index 4bd42f70b..c4c10a618 100644 --- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart +++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart @@ -1,6 +1,6 @@ -/* +/* * This file is part of Stack Wallet. - * + * * Copyright (c) 2023 Cypher Stack * All Rights Reserved. * The code is distributed under GPLv3 license, see LICENSE file for details. @@ -27,6 +27,7 @@ import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/test_epic_box_connection.dart'; import 'package:stackwallet/utilities/test_monero_node_connection.dart'; +import 'package:stackwallet/utilities/test_stellar_node_connection.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/background.dart'; @@ -193,11 +194,16 @@ class _AddEditNodeViewState extends ConsumerState { try { // await client.getSyncStatus(); } catch (_) {} + break; + case Coin.stellar: + case Coin.stellarTestnet: + try { + testPassed = await testStellarNodeConnection(formData.host!, formData.port!); + } catch(_) {} + break; case Coin.nano: case Coin.banano: - case Coin.stellar: - case Coin.stellarTestNet: throw UnimplementedError(); //TODO: check network/node case Coin.tezos: @@ -732,18 +738,18 @@ class _NodeFormState extends ConsumerState { case Coin.namecoin: case Coin.bitcoincash: case Coin.particl: - case Coin.stellar: case Coin.tezos: case Coin.bitcoinTestNet: case Coin.litecoinTestNet: case Coin.bitcoincashTestnet: case Coin.firoTestNet: case Coin.dogecoinTestNet: - case Coin.stellarTestNet: case Coin.epicCash: case Coin.nano: case Coin.banano: case Coin.eCash: + case Coin.stellar: + case Coin.stellarTestnet: return false; case Coin.ethereum: diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart index d22af6e25..0b339469e 100644 --- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart +++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart @@ -1,6 +1,6 @@ -/* +/* * This file is part of Stack Wallet. - * + * * Copyright (c) 2023 Cypher Stack * All Rights Reserved. * The code is distributed under GPLv3 license, see LICENSE file for details. @@ -175,8 +175,17 @@ class _NodeDetailsViewState extends ConsumerState { case Coin.tezos: case Coin.stellar: case Coin.stellarTestNet: + try { + testPassed = await testStellarNodeConnection(node!.host, node.port); + } catch(_) { + testPassed = false; + } + break; + case Coin.nano: + case Coin.banano: + throw UnimplementedError(); - //TODO: check network/node + //TODO: check network/node } if (testPassed) { diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart index fcacc60d4..6b7e57bef 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart @@ -13,6 +13,7 @@ import 'dart:async'; import 'package:event_bus/event_bus.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:stackwallet/db/hive/db.dart'; import 'package:stackwallet/models/epicbox_config_model.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/address_book_views/address_book_view.dart'; @@ -36,11 +37,14 @@ import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/show_loading.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:stackwallet/widgets/stack_dialog.dart'; import 'package:tuple/tuple.dart'; /// [eventBus] should only be set during testing @@ -306,6 +310,61 @@ class _WalletSettingsViewState extends ConsumerState { ); }, ), + if (coin == Coin.firo) + const SizedBox( + height: 8, + ), + if (coin == Coin.firo) + Consumer( + builder: (_, ref, __) { + return SettingsListButton( + iconAssetName: Assets.svg.eye, + title: "Clear electrumx cache", + onPressed: () async { + String? result; + await showDialog( + useSafeArea: false, + barrierDismissible: true, + context: context, + builder: (_) => StackOkDialog( + title: + "Are you sure you want to clear " + "${coin.prettyName} electrumx cache?", + onOkPressed: (value) { + result = value; + }, + leftButton: SecondaryButton( + label: "Cancel", + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ), + ); + + if (result == "OK" && mounted) { + await showLoading( + whileFuture: Future.wait( + [ + Future.delayed( + const Duration( + milliseconds: 1500, + ), + ), + DB.instance + .clearSharedTransactionCache( + coin: coin, + ), + ], + ), + context: context, + message: "Clearing cache...", + ); + } + }, + ); + }, + ), if (coin == Coin.nano || coin == Coin.banano) const SizedBox( height: 8, diff --git a/lib/pages/wallet_view/sub_widgets/tx_icon.dart b/lib/pages/wallet_view/sub_widgets/tx_icon.dart index d86ad6e8d..46972c49b 100644 --- a/lib/pages/wallet_view/sub_widgets/tx_icon.dart +++ b/lib/pages/wallet_view/sub_widgets/tx_icon.dart @@ -35,6 +35,7 @@ class TxIcon extends ConsumerWidget { String _getAssetName( bool isCancelled, bool isReceived, bool isPending, IThemeAssets assets) { + if (!isReceived && transaction.subType == TransactionSubType.mint) { if (isCancelled) { return Assets.svg.anonymizeFailed; @@ -47,7 +48,7 @@ class TxIcon extends ConsumerWidget { if (isReceived) { if (isCancelled) { - return assets.receive; + return assets.receiveCancelled; } if (isPending) { return assets.receivePending; diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart index 2b1ba62c4..88d0d8b1a 100644 --- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart @@ -358,8 +358,6 @@ class _TransactionDetailsViewState final currentHeight = ref.watch(walletsChangeNotifierProvider .select((value) => value.getManager(walletId).currentHeight)); - print("THIS TRANSACTION IS $_transaction"); - return ConditionalParent( condition: !isDesktop, builder: (child) => Background( @@ -1584,8 +1582,7 @@ class _TransactionDetailsViewState coin.requiredConfirmations, ) == false && - _transaction.isCancelled == false && - _transaction.type == TransactionType.outgoing) + _transaction.isCancelled == false) ? ConditionalParent( condition: isDesktop, builder: (child) => Padding( diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 2b7aa662d..344eb7876 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -27,6 +27,7 @@ import 'package:stackwallet/pages/add_wallet_views/add_token_view/edit_wallet_to import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart'; import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart'; import 'package:stackwallet/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart'; +import 'package:stackwallet/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart'; import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart'; import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart'; import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart'; @@ -1101,6 +1102,21 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case NewWalletOptionsView.routeName: + if (args is Tuple2) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => NewWalletOptionsView( + walletName: args.item1, + coin: args.item2, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case RestoreWalletView.routeName: if (args is Tuple5) { return getRoute( diff --git a/lib/services/coins/banano/banano_wallet.dart b/lib/services/coins/banano/banano_wallet.dart index e2032aa09..50b4a3f9e 100644 --- a/lib/services/coins/banano/banano_wallet.dart +++ b/lib/services/coins/banano/banano_wallet.dart @@ -600,7 +600,9 @@ class BananoWallet extends CoinServiceAPI with WalletCache, WalletDB { } @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { if ((await mnemonicString) != null || (await mnemonicPassphrase) != null) { throw Exception( "Attempted to overwrite mnemonic on generate new wallet!"); diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index f40be0e3c..cb8eadeef 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -1290,7 +1290,9 @@ class BitcoinWallet extends CoinServiceAPI bool get isConnected => _isConnected; @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("Generating new ${coin.prettyName} wallet.", level: LogLevel.Info); @@ -1301,7 +1303,7 @@ class BitcoinWallet extends CoinServiceAPI await _prefs.init(); try { - await _generateNewWallet(); + await _generateNewWallet(data); } catch (e, s) { Logging.instance.log("Exception rethrown from initializeNew(): $e\n$s", level: LogLevel.Fatal); @@ -1499,7 +1501,9 @@ class BitcoinWallet extends CoinServiceAPI } } - Future _generateNewWallet() async { + Future _generateNewWallet( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); if (!integrationTestFlag) { @@ -1533,10 +1537,21 @@ class BitcoinWallet extends CoinServiceAPI throw Exception( "Attempted to overwrite mnemonic on generate new wallet!"); } + final int strength; + if (data == null || data.wordCount == 12) { + strength = 128; + } else if (data.wordCount == 24) { + strength = 256; + } else { + throw Exception("Invalid word count"); + } await _secureStore.write( key: '${_walletId}_mnemonic', - value: bip39.generateMnemonic(strength: 128)); - await _secureStore.write(key: '${_walletId}_mnemonicPassphrase', value: ""); + value: bip39.generateMnemonic(strength: strength)); + await _secureStore.write( + key: '${_walletId}_mnemonicPassphrase', + value: data?.mnemonicPassphrase ?? "", + ); // Generate and add addresses to relevant arrays final initialAddresses = await Future.wait([ diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index d0b360b0c..1f4057353 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -1161,7 +1161,9 @@ class BitcoinCashWallet extends CoinServiceAPI bool get isConnected => _isConnected; @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("Generating new ${coin.prettyName} wallet.", level: LogLevel.Info); @@ -1171,7 +1173,7 @@ class BitcoinCashWallet extends CoinServiceAPI } await _prefs.init(); try { - await _generateNewWallet(); + await _generateNewWallet(data); } catch (e, s) { Logging.instance.log("Exception rethrown from initializeNew(): $e\n$s", level: LogLevel.Fatal); @@ -1402,7 +1404,9 @@ class BitcoinCashWallet extends CoinServiceAPI } } - Future _generateNewWallet() async { + Future _generateNewWallet( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); if (!integrationTestFlag) { @@ -1436,10 +1440,21 @@ class BitcoinCashWallet extends CoinServiceAPI throw Exception( "Attempted to overwrite mnemonic on generate new wallet!"); } + final int strength; + if (data == null || data.wordCount == 12) { + strength = 128; + } else if (data.wordCount == 24) { + strength = 256; + } else { + throw Exception("Invalid word count"); + } await _secureStore.write( key: '${_walletId}_mnemonic', - value: bip39.generateMnemonic(strength: 128)); - await _secureStore.write(key: '${_walletId}_mnemonicPassphrase', value: ""); + value: bip39.generateMnemonic(strength: strength)); + await _secureStore.write( + key: '${_walletId}_mnemonicPassphrase', + value: data?.mnemonicPassphrase ?? "", + ); // Generate and add addresses to relevant arrays final initialAddresses = await Future.wait([ diff --git a/lib/services/coins/coin_service.dart b/lib/services/coins/coin_service.dart index 9ee397e0d..72478b353 100644 --- a/lib/services/coins/coin_service.dart +++ b/lib/services/coins/coin_service.dart @@ -358,7 +358,9 @@ abstract class CoinServiceAPI { required int height, }); - Future initializeNew(); + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ); Future initializeExisting(); Future exit(); diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 754834ad1..3d6ae5794 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -1147,7 +1147,9 @@ class DogecoinWallet extends CoinServiceAPI bool get isConnected => _isConnected; @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("Generating new ${coin.prettyName} wallet.", level: LogLevel.Info); @@ -1157,7 +1159,7 @@ class DogecoinWallet extends CoinServiceAPI } await _prefs.init(); try { - await _generateNewWallet(); + await _generateNewWallet(data); } catch (e, s) { Logging.instance.log("Exception rethrown from initializeNew(): $e\n$s", level: LogLevel.Fatal); @@ -1349,7 +1351,9 @@ class DogecoinWallet extends CoinServiceAPI } } - Future _generateNewWallet() async { + Future _generateNewWallet( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); if (!integrationTestFlag) { @@ -1383,12 +1387,20 @@ class DogecoinWallet extends CoinServiceAPI throw Exception( "Attempted to overwrite mnemonic on generate new wallet!"); } + final int strength; + if (data == null || data.wordCount == 12) { + strength = 128; + } else if (data.wordCount == 24) { + strength = 256; + } else { + throw Exception("Invalid word count"); + } await _secureStore.write( key: '${_walletId}_mnemonic', - value: bip39.generateMnemonic(strength: 128)); + value: bip39.generateMnemonic(strength: strength)); await _secureStore.write( key: '${_walletId}_mnemonicPassphrase', - value: "", + value: data?.mnemonicPassphrase ?? "", ); // Generate and add addresses diff --git a/lib/services/coins/ecash/ecash_wallet.dart b/lib/services/coins/ecash/ecash_wallet.dart index e891db692..c35f7f4c6 100644 --- a/lib/services/coins/ecash/ecash_wallet.dart +++ b/lib/services/coins/ecash/ecash_wallet.dart @@ -506,7 +506,9 @@ class ECashWallet extends CoinServiceAPI } } - Future _generateNewWallet() async { + Future _generateNewWallet( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); if (!integrationTestFlag) { @@ -544,10 +546,21 @@ class ECashWallet extends CoinServiceAPI throw Exception( "Attempted to overwrite mnemonic on generate new wallet!"); } + final int strength; + if (data == null || data.wordCount == 12) { + strength = 128; + } else if (data.wordCount == 24) { + strength = 256; + } else { + throw Exception("Invalid word count"); + } await _secureStore.write( key: '${_walletId}_mnemonic', - value: bip39.generateMnemonic(strength: 128)); - await _secureStore.write(key: '${_walletId}_mnemonicPassphrase', value: ""); + value: bip39.generateMnemonic(strength: strength)); + await _secureStore.write( + key: '${_walletId}_mnemonicPassphrase', + value: data?.mnemonicPassphrase ?? "", + ); const int startingIndex = 0; const int receiveChain = 0; @@ -2778,7 +2791,9 @@ class ECashWallet extends CoinServiceAPI bool get isConnected => _isConnected; @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("Generating new ${coin.prettyName} wallet.", level: LogLevel.Info); @@ -2789,7 +2804,7 @@ class ECashWallet extends CoinServiceAPI await _prefs.init(); try { - await _generateNewWallet(); + await _generateNewWallet(data); } catch (e, s) { Logging.instance.log("Exception rethrown from initializeNew(): $e\n$s", level: LogLevel.Fatal); diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart index b62129248..9d25a5a47 100644 --- a/lib/services/coins/epiccash/epiccash_wallet.dart +++ b/lib/services/coins/epiccash/epiccash_wallet.dart @@ -766,7 +766,9 @@ class EpicCashWallet extends CoinServiceAPI } @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { await _prefs.init(); await updateNode(false); final mnemonic = await _getMnemonicList(); @@ -1738,7 +1740,6 @@ class EpicCashWallet extends CoinServiceAPI final isIncoming = (tx["tx_type"] == "TxReceived" || tx["tx_type"] == "TxReceivedCancelled"); - final txn = isar_models.Transaction( walletId: walletId, txid: commitId ?? tx["id"].toString(), @@ -1763,7 +1764,9 @@ class EpicCashWallet extends CoinServiceAPI otherData: tx['onChainNote'].toString(), inputs: [], outputs: [], - numberOfMessages: ((tx["numberOfMessages"] == null) ? 0 : tx["numberOfMessages"]) as int, + numberOfMessages: ((tx["numberOfMessages"] == null) + ? 0 + : tx["numberOfMessages"]) as int, ); // txn.address = diff --git a/lib/services/coins/ethereum/ethereum_wallet.dart b/lib/services/coins/ethereum/ethereum_wallet.dart index 62f3020e0..b3800a4e4 100644 --- a/lib/services/coins/ethereum/ethereum_wallet.dart +++ b/lib/services/coins/ethereum/ethereum_wallet.dart @@ -310,7 +310,9 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { } @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance.log( "Generating new ${coin.prettyName} wallet.", level: LogLevel.Info, @@ -324,7 +326,7 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { await _prefs.init(); try { - await _generateNewWallet(); + await _generateNewWallet(data); } catch (e, s) { Logging.instance.log( "Exception rethrown from initializeNew(): $e\n$s", @@ -338,7 +340,9 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { ]); } - Future _generateNewWallet() async { + Future _generateNewWallet( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { // Logging.instance // .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); // if (!integrationTestFlag) { @@ -366,14 +370,23 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { "Attempted to overwrite mnemonic on generate new wallet!"); } - final String mnemonic = bip39.generateMnemonic(strength: 128); + final int strength; + if (data == null || data.wordCount == 12) { + strength = 128; + } else if (data.wordCount == 24) { + strength = 256; + } else { + throw Exception("Invalid word count"); + } + final String mnemonic = bip39.generateMnemonic(strength: strength); + final String passphrase = data?.mnemonicPassphrase ?? ""; await _secureStore.write(key: '${_walletId}_mnemonic', value: mnemonic); await _secureStore.write( key: '${_walletId}_mnemonicPassphrase', - value: "", + value: passphrase, ); - await _generateAndSaveAddress(mnemonic, ""); + await _generateAndSaveAddress(mnemonic, passphrase); Logging.instance.log("_generateNewWalletFinished", level: LogLevel.Info); } diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index a4cea6393..d58cf4402 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -1875,7 +1875,9 @@ class FiroWallet extends CoinServiceAPI } @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("Generating new ${coin.prettyName} wallet.", level: LogLevel.Info); @@ -1886,7 +1888,7 @@ class FiroWallet extends CoinServiceAPI await _prefs.init(); try { - await _generateNewWallet(); + await _generateNewWallet(data); } catch (e, s) { Logging.instance.log("Exception rethrown from initializeNew(): $e\n$s", level: LogLevel.Fatal); @@ -2124,7 +2126,9 @@ class FiroWallet extends CoinServiceAPI } /// Generates initial wallet values such as mnemonic, chain (receive/change) arrays and indexes. - Future _generateNewWallet() async { + Future _generateNewWallet( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); if (!integrationTestFlag) { @@ -2158,12 +2162,20 @@ class FiroWallet extends CoinServiceAPI longMutex = false; throw Exception("Attempted to overwrite mnemonic on initialize new!"); } + final int strength; + if (data == null || data.wordCount == 12) { + strength = 128; + } else if (data.wordCount == 24) { + strength = 256; + } else { + throw Exception("Invalid word count"); + } await _secureStore.write( key: '${_walletId}_mnemonic', - value: bip39.generateMnemonic(strength: 128)); + value: bip39.generateMnemonic(strength: strength)); await _secureStore.write( key: '${_walletId}_mnemonicPassphrase', - value: "", + value: data?.mnemonicPassphrase ?? "", ); // Generate and add addresses to relevant arrays diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index 703ec5cf6..26718bc4e 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -1285,7 +1285,9 @@ class LitecoinWallet extends CoinServiceAPI bool get isConnected => _isConnected; @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("Generating new ${coin.prettyName} wallet.", level: LogLevel.Info); @@ -1296,7 +1298,7 @@ class LitecoinWallet extends CoinServiceAPI await _prefs.init(); try { - await _generateNewWallet(); + await _generateNewWallet(data); } catch (e, s) { Logging.instance.log("Exception rethrown from initializeNew(): $e\n$s", level: LogLevel.Fatal); @@ -1535,7 +1537,9 @@ class LitecoinWallet extends CoinServiceAPI } } - Future _generateNewWallet() async { + Future _generateNewWallet( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); if (!integrationTestFlag) { @@ -1570,12 +1574,20 @@ class LitecoinWallet extends CoinServiceAPI throw Exception( "Attempted to overwrite mnemonic on generate new wallet!"); } + final int strength; + if (data == null || data.wordCount == 12) { + strength = 128; + } else if (data.wordCount == 24) { + strength = 256; + } else { + throw Exception("Invalid word count"); + } await _secureStore.write( key: '${_walletId}_mnemonic', - value: bip39.generateMnemonic(strength: 128)); + value: bip39.generateMnemonic(strength: strength)); await _secureStore.write( key: '${_walletId}_mnemonicPassphrase', - value: "", + value: data?.mnemonicPassphrase ?? "", ); // Generate and add addresses to relevant arrays diff --git a/lib/services/coins/manager.dart b/lib/services/coins/manager.dart index 1f5ae55f3..05f27d503 100644 --- a/lib/services/coins/manager.dart +++ b/lib/services/coins/manager.dart @@ -180,7 +180,9 @@ class Manager with ChangeNotifier { Future testNetworkConnection() => _currentWallet.testNetworkConnection(); - Future initializeNew() => _currentWallet.initializeNew(); + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + _currentWallet.initializeNew(data); Future initializeExisting() => _currentWallet.initializeExisting(); Future recoverFromMnemonic({ required String mnemonic, diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart index 5911e8592..a5284cc60 100644 --- a/lib/services/coins/monero/monero_wallet.dart +++ b/lib/services/coins/monero/monero_wallet.dart @@ -307,7 +307,9 @@ class MoneroWallet extends CoinServiceAPI with WalletCache, WalletDB { } @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { await _prefs.init(); // this should never fail diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index d0f30ecac..8b27fe426 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -1268,7 +1268,9 @@ class NamecoinWallet extends CoinServiceAPI bool get isConnected => _isConnected; @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("Generating new ${coin.prettyName} wallet.", level: LogLevel.Info); @@ -1279,7 +1281,7 @@ class NamecoinWallet extends CoinServiceAPI await _prefs.init(); try { - await _generateNewWallet(); + await _generateNewWallet(data); } catch (e, s) { Logging.instance.log("Exception rethrown from initializeNew(): $e\n$s", level: LogLevel.Fatal); @@ -1517,7 +1519,9 @@ class NamecoinWallet extends CoinServiceAPI } } - Future _generateNewWallet() async { + Future _generateNewWallet( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); if (!integrationTestFlag) { @@ -1544,12 +1548,20 @@ class NamecoinWallet extends CoinServiceAPI throw Exception( "Attempted to overwrite mnemonic on generate new wallet!"); } + final int strength; + if (data == null || data.wordCount == 12) { + strength = 128; + } else if (data.wordCount == 24) { + strength = 256; + } else { + throw Exception("Invalid word count"); + } await _secureStore.write( key: '${_walletId}_mnemonic', - value: bip39.generateMnemonic(strength: 128)); + value: bip39.generateMnemonic(strength: strength)); await _secureStore.write( key: '${_walletId}_mnemonicPassphrase', - value: "", + value: data?.mnemonicPassphrase ?? "", ); // Generate and add addresses to relevant arrays diff --git a/lib/services/coins/nano/nano_wallet.dart b/lib/services/coins/nano/nano_wallet.dart index 391303675..34de1034d 100644 --- a/lib/services/coins/nano/nano_wallet.dart +++ b/lib/services/coins/nano/nano_wallet.dart @@ -607,7 +607,9 @@ class NanoWallet extends CoinServiceAPI with WalletCache, WalletDB { } @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { if ((await mnemonicString) != null || (await mnemonicPassphrase) != null) { throw Exception( "Attempted to overwrite mnemonic on generate new wallet!"); diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index 324e8d9e5..33064ef85 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -1195,7 +1195,9 @@ class ParticlWallet extends CoinServiceAPI bool get isConnected => _isConnected; @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("Generating new ${coin.prettyName} wallet.", level: LogLevel.Info); @@ -1206,7 +1208,7 @@ class ParticlWallet extends CoinServiceAPI await _prefs.init(); try { - await _generateNewWallet(); + await _generateNewWallet(data); } catch (e, s) { Logging.instance.log("Exception rethrown from initializeNew(): $e\n$s", level: LogLevel.Fatal); @@ -1432,7 +1434,9 @@ class ParticlWallet extends CoinServiceAPI } } - Future _generateNewWallet() async { + Future _generateNewWallet( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { Logging.instance .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); if (!integrationTestFlag) { @@ -1459,12 +1463,20 @@ class ParticlWallet extends CoinServiceAPI throw Exception( "Attempted to overwrite mnemonic on generate new wallet!"); } + final int strength; + if (data == null || data.wordCount == 12) { + strength = 128; + } else if (data.wordCount == 24) { + strength = 256; + } else { + throw Exception("Invalid word count"); + } await _secureStore.write( key: '${_walletId}_mnemonic', - value: bip39.generateMnemonic(strength: 128)); + value: bip39.generateMnemonic(strength: strength)); await _secureStore.write( key: '${_walletId}_mnemonicPassphrase', - value: "", + value: data?.mnemonicPassphrase ?? "", ); // Generate and add addresses to relevant arrays diff --git a/lib/services/coins/stellar/stellar_wallet.dart b/lib/services/coins/stellar/stellar_wallet.dart index c4c92373f..a9f9d97df 100644 --- a/lib/services/coins/stellar/stellar_wallet.dart +++ b/lib/services/coins/stellar/stellar_wallet.dart @@ -1,5 +1,5 @@ import 'dart:async'; - +import 'package:bip39/bip39.dart' as bip39; import 'package:http/http.dart' as http; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; @@ -37,6 +37,7 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB { late StellarSDK stellarSdk; late Network stellarNetwork; + StellarWallet({ required String walletId, required String walletName, @@ -53,20 +54,26 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB { initCache(walletId, coin); initWalletDB(mockableOverride: mockableOverride); - if (coin.name == "stellarTestnet") { - stellarSdk = StellarSDK.TESTNET; + + if (coin.isTestNet) { stellarNetwork = Network.TESTNET; } else { - stellarSdk = StellarSDK.PUBLIC; stellarNetwork = Network.PUBLIC; } + + _updateNode(); + } + + void _updateNode() { + _xlmNode = NodeService(secureStorageInterface: _secureStore) + .getPrimaryNodeFor(coin: coin) ?? + DefaultNodes.getNodeFor(coin); + stellarSdk = StellarSDK("${_xlmNode!.host}:${_xlmNode!.port}"); } late final TransactionNotificationTracker txTracker; late SecureStorageInterface _secureStore; - // final StellarSDK stellarSdk = StellarSDK.PUBLIC; - @override bool get isFavorite => _isFavorite ??= getCachedIsFavorite(); bool? _isFavorite; @@ -206,10 +213,12 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB { transaction.sign(senderKeyPair, stellarNetwork); try { SubmitTransactionResponse response = - await stellarSdk.submitTransaction(transaction); - + await stellarSdk.submitTransaction(transaction).onError((error, stackTrace) => throw (error.toString())); if (!response.success) { - throw ("Unable to send transaction"); + throw ( + "${response.extras?.resultCodes?.transactionResultCode}" + " ::: ${response.extras?.resultCodes?.operationsResultCodes}" + ); } return response.hash!; } catch (e, s) { @@ -232,32 +241,14 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB { (await _currentReceivingAddress)?.value ?? await getAddressSW(); Future getBaseFee() async { - // final nodeURI = Uri.parse("${getCurrentNode().host}:${getCurrentNode().port}"); - final nodeURI = Uri.parse(getCurrentNode().host); - final httpClient = http.Client(); - FeeStatsResponse fsp = - await FeeStatsRequestBuilder(httpClient, nodeURI).execute(); - return int.parse(fsp.lastLedgerBaseFee); + var fees = await stellarSdk.feeStats.execute(); + return int.parse(fees.lastLedgerBaseFee); } @override Future estimateFeeFor(Amount amount, int feeRate) async { var baseFee = await getBaseFee(); - int fee = 100; - switch (feeRate) { - case 0: - fee = baseFee * 10; - case 1: - case 2: - fee = baseFee * 50; - case 3: - fee = baseFee * 100; - case 4: - fee = baseFee * 200; - default: - fee = baseFee * 50; - } - return Amount(rawValue: BigInt.from(fee), fractionDigits: coin.decimals); + return Amount(rawValue: BigInt.from(baseFee), fractionDigits: coin.decimals); } @override @@ -285,20 +276,15 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB { @override Future get fees async { - // final nodeURI = Uri.parse("${getCurrentNode().host}:${getCurrentNode().port}"); - final nodeURI = Uri.parse(getCurrentNode().host); - - final httpClient = http.Client(); - FeeStatsResponse fsp = - await FeeStatsRequestBuilder(httpClient, nodeURI).execute(); + int fee = await getBaseFee(); return FeeObject( - numberOfBlocksFast: 0, - numberOfBlocksAverage: 0, - numberOfBlocksSlow: 0, - fast: int.parse(fsp.lastLedgerBaseFee) * 100, - medium: int.parse(fsp.lastLedgerBaseFee) * 50, - slow: int.parse(fsp.lastLedgerBaseFee) * 10); + numberOfBlocksFast: 10, + numberOfBlocksAverage: 10, + numberOfBlocksSlow: 10, + fast: fee, + medium: fee, + slow: fee); } @override @@ -326,7 +312,9 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB { } @override - Future initializeNew() async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) async { if ((await mnemonicString) != null || (await mnemonicPassphrase) != null) { throw Exception( "Attempted to overwrite mnemonic on generate new wallet!"); @@ -334,11 +322,26 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB { await _prefs.init(); - String mnemonic = await Wallet.generate24WordsMnemonic(); + final int strength; + if (data == null || data.wordCount == 12) { + strength = 128; + } else if (data.wordCount == 24) { + strength = 256; + } else { + throw Exception("Invalid word count"); + } + final String mnemonic = bip39.generateMnemonic(strength: strength); + final String passphrase = data?.mnemonicPassphrase ?? ""; await _secureStore.write(key: '${_walletId}_mnemonic', value: mnemonic); - await _secureStore.write(key: '${_walletId}_mnemonicPassphrase', value: ""); + await _secureStore.write( + key: '${_walletId}_mnemonicPassphrase', + value: passphrase, + ); - Wallet wallet = await Wallet.from(mnemonic); + Wallet wallet = await Wallet.from( + mnemonic, + passphrase: passphrase, + ); KeyPair keyPair = await wallet.getKeyPair(index: 0); String address = keyPair.accountId; String secretSeed = @@ -399,6 +402,7 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB { {required String address, required Amount amount, Map? args}) async { + try { final feeRate = args?["feeRate"]; var fee = 1000; @@ -495,13 +499,6 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB { if (response is PaymentOperationResponse) { PaymentOperationResponse por = response; - Logging.instance.log( - "ALL TRANSACTIONS IS ${por.transactionSuccessful}", - level: LogLevel.Info); - - Logging.instance.log("THIS TX HASH IS ${por.transactionHash}", - level: LogLevel.Info); - SWTransaction.TransactionType type; if (por.sourceAccount == await getAddressSW()) { type = SWTransaction.TransactionType.outgoing; @@ -750,10 +747,7 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB { @override Future updateNode(bool shouldRefresh) async { - _xlmNode = NodeService(secureStorageInterface: _secureStore) - .getPrimaryNodeFor(coin: coin) ?? - DefaultNodes.getNodeFor(coin); - + _updateNode(); if (shouldRefresh) { unawaited(refresh()); } diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart index 6f0863334..7b3691846 100644 --- a/lib/services/coins/wownero/wownero_wallet.dart +++ b/lib/services/coins/wownero/wownero_wallet.dart @@ -333,7 +333,10 @@ class WowneroWallet extends CoinServiceAPI with WalletCache, WalletDB { } @override - Future initializeNew({int seedWordsLength = 14}) async { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, { + int seedWordsLength = 14, + }) async { await _prefs.init(); // this should never fail diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart index 8db5d4843..f4a4ca28f 100644 --- a/lib/utilities/enums/coin_enum.dart +++ b/lib/utilities/enums/coin_enum.dart @@ -245,6 +245,35 @@ extension CoinExt on Coin { } } + bool get hasMnemonicPassphraseSupport { + switch (this) { + case Coin.bitcoin: + case Coin.bitcoinTestNet: + case Coin.litecoin: + case Coin.litecoinTestNet: + case Coin.bitcoincash: + case Coin.bitcoincashTestnet: + case Coin.dogecoin: + case Coin.dogecoinTestNet: + case Coin.firo: + case Coin.firoTestNet: + case Coin.namecoin: + case Coin.particl: + case Coin.ethereum: + case Coin.eCash: + case Coin.stellar: + case Coin.stellarTestnet: + return true; + + case Coin.epicCash: + case Coin.monero: + case Coin.wownero: + case Coin.nano: + case Coin.banano: + return false; + } + } + bool get hasBuySupport { switch (this) { case Coin.bitcoin: diff --git a/lib/utilities/test_stellar_node_connection.dart b/lib/utilities/test_stellar_node_connection.dart new file mode 100644 index 000000000..683d946c9 --- /dev/null +++ b/lib/utilities/test_stellar_node_connection.dart @@ -0,0 +1,34 @@ +import 'dart:convert'; + +import 'package:http/http.dart' as http; +import 'package:stellar_flutter_sdk/stellar_flutter_sdk.dart'; + +Future testStellarNodeConnection(String host, int port) async { + + final client = http.Client(); + Uri uri = Uri.parse("$host:$port"); + final response = await client.get( + uri, + headers: {'Content-Type': 'application/json'}, + ).timeout(const Duration(milliseconds: 2000), + onTimeout: () async => http.Response('Error', 408)); + + if (response.statusCode == 200) { + //Get chain height for sdk + StellarSDK stellarSdk = StellarSDK(host); + final height = await stellarSdk.ledgers + .order(RequestBuilderOrder.DESC) + .limit(1) + .execute() + .then((value) => value.records!.first.sequence) + .onError((error, stackTrace) => throw ("Error getting chain height")); + + if (height > 0) { + return true; + } else { + return false; + } + } else { + return false; + } +} \ No newline at end of file diff --git a/lib/widgets/node_card.dart b/lib/widgets/node_card.dart index 8d4c29ac2..a75b09c64 100644 --- a/lib/widgets/node_card.dart +++ b/lib/widgets/node_card.dart @@ -1,6 +1,6 @@ -/* +/* * This file is part of Stack Wallet. - * + * * Copyright (c) 2023 Cypher Stack * All Rights Reserved. * The code is distributed under GPLv3 license, see LICENSE file for details. @@ -197,6 +197,15 @@ class _NodeCardState extends ConsumerState { case Coin.tezos: case Coin.stellar: case Coin.stellarTestNet: + try { + testPassed = await testStellarNodeConnection(node.host, node.port); + } catch(_) { + testPassed = false; + } + break; + + case Coin.nano: + case Coin.banano: throw UnimplementedError(); //TODO: check network/node } diff --git a/lib/widgets/stack_dialog.dart b/lib/widgets/stack_dialog.dart index fead6a00a..be7f22ed9 100644 --- a/lib/widgets/stack_dialog.dart +++ b/lib/widgets/stack_dialog.dart @@ -18,15 +18,22 @@ class StackDialogBase extends StatelessWidget { Key? key, this.child, this.padding = const EdgeInsets.all(24), + this.keyboardPaddingAmount = 0, }) : super(key: key); final EdgeInsets padding; final Widget? child; + final double keyboardPaddingAmount; @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.all(16), + padding: EdgeInsets.only( + top: 16, + left: 16, + right: 16, + bottom: 16 + keyboardPaddingAmount, + ), child: Column( mainAxisAlignment: !Util.isDesktop ? MainAxisAlignment.end : MainAxisAlignment.center, diff --git a/pubspec.yaml b/pubspec.yaml index 03eeea12e..dbb5ecfe5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.7.17+185 +version: 1.7.19+187 environment: sdk: ">=3.0.2 <4.0.0" diff --git a/test/pages/send_view/send_view_test.mocks.dart b/test/pages/send_view/send_view_test.mocks.dart index c9414583d..52bc87fee 100644 --- a/test/pages/send_view/send_view_test.mocks.dart +++ b/test/pages/send_view/send_view_test.mocks.dart @@ -1283,10 +1283,12 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future initializeNew() => (super.noSuchMethod( + _i23.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i23.Future.value(), returnValueForMissingStub: _i23.Future.value(), @@ -3062,10 +3064,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i23.Future.value(false), ) as _i23.Future); @override - _i23.Future initializeNew() => (super.noSuchMethod( + _i23.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i23.Future.value(), returnValueForMissingStub: _i23.Future.value(), @@ -3415,10 +3419,12 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValueForMissingStub: _i23.Future.value(), ) as _i23.Future); @override - _i23.Future initializeNew() => (super.noSuchMethod( + _i23.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i23.Future.value(), returnValueForMissingStub: _i23.Future.value(), diff --git a/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart index 5edc4c538..29318d2c5 100644 --- a/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart @@ -492,10 +492,12 @@ class MockManager extends _i1.Mock implements _i12.Manager { returnValue: _i9.Future.value(false), ) as _i9.Future); @override - _i9.Future initializeNew() => (super.noSuchMethod( + _i9.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), diff --git a/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart index a84bb6a51..cd9108d2a 100644 --- a/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart @@ -453,10 +453,12 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart index f44df83ca..65ab3b1f2 100644 --- a/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart @@ -451,10 +451,12 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/lockscreen_view_screen_test.mocks.dart b/test/screen_tests/lockscreen_view_screen_test.mocks.dart index 35a1a5f20..dd8f32b04 100644 --- a/test/screen_tests/lockscreen_view_screen_test.mocks.dart +++ b/test/screen_tests/lockscreen_view_screen_test.mocks.dart @@ -771,10 +771,12 @@ class MockManager extends _i1.Mock implements _i13.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart b/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart index 8526c77f3..87686d271 100644 --- a/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart +++ b/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart @@ -558,10 +558,12 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: _i7.Future.value(false), ) as _i7.Future); @override - _i7.Future initializeNew() => (super.noSuchMethod( + _i7.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i7.Future.value(), returnValueForMissingStub: _i7.Future.value(), diff --git a/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart b/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart index ba9350c78..221cbb329 100644 --- a/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart +++ b/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart @@ -558,10 +558,12 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: _i7.Future.value(false), ) as _i7.Future); @override - _i7.Future initializeNew() => (super.noSuchMethod( + _i7.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i7.Future.value(), returnValueForMissingStub: _i7.Future.value(), diff --git a/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart b/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart index 5f8055c5a..abb608127 100644 --- a/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart +++ b/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart @@ -558,10 +558,12 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: _i7.Future.value(false), ) as _i7.Future); @override - _i7.Future initializeNew() => (super.noSuchMethod( + _i7.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i7.Future.value(), returnValueForMissingStub: _i7.Future.value(), diff --git a/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart b/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart index d621a4ae0..b60b30832 100644 --- a/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart @@ -325,10 +325,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart b/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart index 6802650ab..90907cd14 100644 --- a/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart @@ -556,10 +556,12 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: _i7.Future.value(false), ) as _i7.Future); @override - _i7.Future initializeNew() => (super.noSuchMethod( + _i7.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i7.Future.value(), returnValueForMissingStub: _i7.Future.value(), diff --git a/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart b/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart index a9b4549a0..460a35f50 100644 --- a/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart @@ -771,10 +771,12 @@ class MockManager extends _i1.Mock implements _i13.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart b/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart index a33b13e7a..b4a8329da 100644 --- a/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart @@ -612,10 +612,12 @@ class MockManager extends _i1.Mock implements _i13.Manager { returnValue: _i9.Future.value(false), ) as _i9.Future); @override - _i9.Future initializeNew() => (super.noSuchMethod( + _i9.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), diff --git a/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart b/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart index e372e3781..25241ab80 100644 --- a/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart @@ -325,10 +325,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart index ece50ef76..d77078d9c 100644 --- a/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart @@ -325,10 +325,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart index b56c08998..0b8976a88 100644 --- a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart @@ -540,10 +540,12 @@ class MockManager extends _i1.Mock implements _i12.Manager { returnValue: _i9.Future.value(false), ) as _i9.Future); @override - _i9.Future initializeNew() => (super.noSuchMethod( + _i9.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), diff --git a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart index 5e62fd6d4..803ef81c6 100644 --- a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart @@ -540,10 +540,12 @@ class MockManager extends _i1.Mock implements _i12.Manager { returnValue: _i9.Future.value(false), ) as _i9.Future); @override - _i9.Future initializeNew() => (super.noSuchMethod( + _i9.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart index 671af0d4b..4e59b2a40 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart @@ -325,10 +325,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart index e3a475bdd..151ecd1ab 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart @@ -325,10 +325,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart index 439dd35ca..d9e9603d3 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart @@ -556,10 +556,12 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: _i7.Future.value(false), ) as _i7.Future); @override - _i7.Future initializeNew() => (super.noSuchMethod( + _i7.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i7.Future.value(), returnValueForMissingStub: _i7.Future.value(), diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart index cc20dce98..268529741 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart @@ -154,18 +154,12 @@ class MockCachedElectrumX extends _i1.Mock implements _i7.CachedElectrumX { _i8.Future>.value({}), ) as _i8.Future>); @override - _i8.Future> getUsedCoinSerials({ - required _i9.Coin? coin, - int? startNumber = 0, - }) => + _i8.Future> getUsedCoinSerials({required _i9.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getUsedCoinSerials, [], - { - #coin: coin, - #startNumber: startNumber, - }, + {#coin: coin}, ), returnValue: _i8.Future>.value([]), ) as _i8.Future>); @@ -792,10 +786,12 @@ class MockManager extends _i1.Mock implements _i15.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart index 4cfabb7bc..97837b511 100644 --- a/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart @@ -556,10 +556,12 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: _i7.Future.value(false), ) as _i7.Future); @override - _i7.Future initializeNew() => (super.noSuchMethod( + _i7.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i7.Future.value(), returnValueForMissingStub: _i7.Future.value(), diff --git a/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart b/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart index b48b433a9..97563c8ad 100644 --- a/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart +++ b/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart @@ -327,10 +327,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart index df0e2d613..bab69e5d2 100644 --- a/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart @@ -326,10 +326,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart index e00ef1039..75c6d795e 100644 --- a/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart @@ -325,10 +325,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart index e5e86bf6e..eb261af73 100644 --- a/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart @@ -367,10 +367,12 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart index 674ad6549..d43cb5430 100644 --- a/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart @@ -327,10 +327,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i8.Future.value(false), ) as _i8.Future); @override - _i8.Future initializeNew() => (super.noSuchMethod( + _i8.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), diff --git a/test/services/coins/bitcoin/bitcoin_wallet_test.mocks.dart b/test/services/coins/bitcoin/bitcoin_wallet_test.mocks.dart index 32719f306..80b582256 100644 --- a/test/services/coins/bitcoin/bitcoin_wallet_test.mocks.dart +++ b/test/services/coins/bitcoin/bitcoin_wallet_test.mocks.dart @@ -485,18 +485,12 @@ class MockCachedElectrumX extends _i1.Mock implements _i5.CachedElectrumX { _i4.Future>.value({}), ) as _i4.Future>); @override - _i4.Future> getUsedCoinSerials({ - required _i6.Coin? coin, - int? startNumber = 0, - }) => + _i4.Future> getUsedCoinSerials({required _i6.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getUsedCoinSerials, [], - { - #coin: coin, - #startNumber: startNumber, - }, + {#coin: coin}, ), returnValue: _i4.Future>.value([]), ) as _i4.Future>); diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart index 661c9a1b7..f3598dfa1 100644 --- a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart +++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart @@ -626,7 +626,8 @@ void main() async { await Hive.openBox(testWalletId); await Hive.openBox(DB.boxNamePrefs); - await expectLater(() => bch?.initializeNew(), throwsA(isA())) + await expectLater( + () => bch?.initializeNew(null), throwsA(isA())) .then((_) { expect(secureStore.interactions, 2); verifyNever(client?.ping()).called(0); diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart index 5599f3a29..52ae05ecd 100644 --- a/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart +++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart @@ -485,18 +485,12 @@ class MockCachedElectrumX extends _i1.Mock implements _i5.CachedElectrumX { _i4.Future>.value({}), ) as _i4.Future>); @override - _i4.Future> getUsedCoinSerials({ - required _i6.Coin? coin, - int? startNumber = 0, - }) => + _i4.Future> getUsedCoinSerials({required _i6.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getUsedCoinSerials, [], - { - #coin: coin, - #startNumber: startNumber, - }, + {#coin: coin}, ), returnValue: _i4.Future>.value([]), ) as _i4.Future>); diff --git a/test/services/coins/dogecoin/dogecoin_wallet_test.dart b/test/services/coins/dogecoin/dogecoin_wallet_test.dart index 712000aae..32872dd04 100644 --- a/test/services/coins/dogecoin/dogecoin_wallet_test.dart +++ b/test/services/coins/dogecoin/dogecoin_wallet_test.dart @@ -483,7 +483,8 @@ void main() { await Hive.openBox(testWalletId); await Hive.openBox(DB.boxNamePrefs); - await expectLater(() => doge?.initializeNew(), throwsA(isA())) + await expectLater( + () => doge?.initializeNew(null), throwsA(isA())) .then((_) { expect(secureStore.interactions, 2); verifyNever(client?.ping()).called(0); diff --git a/test/services/coins/dogecoin/dogecoin_wallet_test.mocks.dart b/test/services/coins/dogecoin/dogecoin_wallet_test.mocks.dart index b084875f5..1027d0592 100644 --- a/test/services/coins/dogecoin/dogecoin_wallet_test.mocks.dart +++ b/test/services/coins/dogecoin/dogecoin_wallet_test.mocks.dart @@ -485,18 +485,12 @@ class MockCachedElectrumX extends _i1.Mock implements _i5.CachedElectrumX { _i4.Future>.value({}), ) as _i4.Future>); @override - _i4.Future> getUsedCoinSerials({ - required _i6.Coin? coin, - int? startNumber = 0, - }) => + _i4.Future> getUsedCoinSerials({required _i6.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getUsedCoinSerials, [], - { - #coin: coin, - #startNumber: startNumber, - }, + {#coin: coin}, ), returnValue: _i4.Future>.value([]), ) as _i4.Future>); diff --git a/test/services/coins/fake_coin_service_api.dart b/test/services/coins/fake_coin_service_api.dart index ea70545d1..413c493ab 100644 --- a/test/services/coins/fake_coin_service_api.dart +++ b/test/services/coins/fake_coin_service_api.dart @@ -88,7 +88,9 @@ class FakeCoinServiceAPI extends CoinServiceAPI { } @override - Future initializeNew() { + Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data, + ) { // TODO: implement initializeNew throw UnimplementedError(); } diff --git a/test/services/coins/firo/firo_wallet_test.dart b/test/services/coins/firo/firo_wallet_test.dart index 05b4aeeff..2bda494fc 100644 --- a/test/services/coins/firo/firo_wallet_test.dart +++ b/test/services/coins/firo/firo_wallet_test.dart @@ -2286,8 +2286,8 @@ void main() { when(cachedClient.getAnonymitySet( groupId: "1", blockhash: "", coin: Coin.firo)) .thenAnswer((_) async => GetAnonymitySetSampleData.data); - when(cachedClient.getUsedCoinSerials(startNumber: 0, coin: Coin.firo)) - .thenAnswer((_) async => List.from( + when(cachedClient.getUsedCoinSerials(coin: Coin.firo)).thenAnswer( + (_) async => List.from( GetUsedSerialsSampleData.serials['serials'] as List)); final firo = FiroWallet( diff --git a/test/services/coins/firo/firo_wallet_test.mocks.dart b/test/services/coins/firo/firo_wallet_test.mocks.dart index 0f7a0b0a3..de0ee0bcb 100644 --- a/test/services/coins/firo/firo_wallet_test.mocks.dart +++ b/test/services/coins/firo/firo_wallet_test.mocks.dart @@ -512,18 +512,12 @@ class MockCachedElectrumX extends _i1.Mock implements _i6.CachedElectrumX { _i5.Future>.value({}), ) as _i5.Future>); @override - _i5.Future> getUsedCoinSerials({ - required _i7.Coin? coin, - int? startNumber = 0, - }) => + _i5.Future> getUsedCoinSerials({required _i7.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getUsedCoinSerials, [], - { - #coin: coin, - #startNumber: startNumber, - }, + {#coin: coin}, ), returnValue: _i5.Future>.value([]), ) as _i5.Future>); diff --git a/test/services/coins/manager_test.mocks.dart b/test/services/coins/manager_test.mocks.dart index ba4c8eb37..17d9efd5f 100644 --- a/test/services/coins/manager_test.mocks.dart +++ b/test/services/coins/manager_test.mocks.dart @@ -304,6 +304,11 @@ class MockFiroWallet extends _i1.Mock implements _i10.FiroWallet { ), ) as _i5.CachedElectrumX); @override + bool get lelantusCoinIsarRescanRequired => (super.noSuchMethod( + Invocation.getter(#lelantusCoinIsarRescanRequired), + returnValue: false, + ) as bool); + @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), returnValue: false, @@ -552,15 +557,35 @@ class MockFiroWallet extends _i1.Mock implements _i10.FiroWallet { returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); @override - _i11.Future initializeNew() => (super.noSuchMethod( + _i11.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, + [data], + ), + returnValue: _i11.Future.value(), + returnValueForMissingStub: _i11.Future.value(), + ) as _i11.Future); + @override + _i11.Future setLelantusCoinIsarRescanRequiredDone() => + (super.noSuchMethod( + Invocation.method( + #setLelantusCoinIsarRescanRequiredDone, [], ), returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); @override + _i11.Future firoRescanRecovery() => (super.noSuchMethod( + Invocation.method( + #firoRescanRecovery, + [], + ), + returnValue: _i11.Future.value(false), + ) as _i11.Future); + @override _i11.Future initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, diff --git a/test/services/coins/namecoin/namecoin_wallet_test.mocks.dart b/test/services/coins/namecoin/namecoin_wallet_test.mocks.dart index ea48f7e85..403199041 100644 --- a/test/services/coins/namecoin/namecoin_wallet_test.mocks.dart +++ b/test/services/coins/namecoin/namecoin_wallet_test.mocks.dart @@ -485,18 +485,12 @@ class MockCachedElectrumX extends _i1.Mock implements _i5.CachedElectrumX { _i4.Future>.value({}), ) as _i4.Future>); @override - _i4.Future> getUsedCoinSerials({ - required _i6.Coin? coin, - int? startNumber = 0, - }) => + _i4.Future> getUsedCoinSerials({required _i6.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getUsedCoinSerials, [], - { - #coin: coin, - #startNumber: startNumber, - }, + {#coin: coin}, ), returnValue: _i4.Future>.value([]), ) as _i4.Future>); diff --git a/test/services/coins/particl/particl_wallet_test.mocks.dart b/test/services/coins/particl/particl_wallet_test.mocks.dart index 862c352d2..a93cde382 100644 --- a/test/services/coins/particl/particl_wallet_test.mocks.dart +++ b/test/services/coins/particl/particl_wallet_test.mocks.dart @@ -485,18 +485,12 @@ class MockCachedElectrumX extends _i1.Mock implements _i5.CachedElectrumX { _i4.Future>.value({}), ) as _i4.Future>); @override - _i4.Future> getUsedCoinSerials({ - required _i6.Coin? coin, - int? startNumber = 0, - }) => + _i4.Future> getUsedCoinSerials({required _i6.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getUsedCoinSerials, [], - { - #coin: coin, - #startNumber: startNumber, - }, + {#coin: coin}, ), returnValue: _i4.Future>.value([]), ) as _i4.Future>); diff --git a/test/widget_tests/managed_favorite_test.mocks.dart b/test/widget_tests/managed_favorite_test.mocks.dart index f81f66ebd..e980b67ee 100644 --- a/test/widget_tests/managed_favorite_test.mocks.dart +++ b/test/widget_tests/managed_favorite_test.mocks.dart @@ -1078,10 +1078,12 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future initializeNew() => (super.noSuchMethod( + _i23.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i23.Future.value(), returnValueForMissingStub: _i23.Future.value(), @@ -3056,10 +3058,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i23.Future.value(false), ) as _i23.Future); @override - _i23.Future initializeNew() => (super.noSuchMethod( + _i23.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i23.Future.value(), returnValueForMissingStub: _i23.Future.value(), @@ -3409,10 +3413,12 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValueForMissingStub: _i23.Future.value(), ) as _i23.Future); @override - _i23.Future initializeNew() => (super.noSuchMethod( + _i23.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i23.Future.value(), returnValueForMissingStub: _i23.Future.value(), diff --git a/test/widget_tests/table_view/table_view_row_test.mocks.dart b/test/widget_tests/table_view/table_view_row_test.mocks.dart index 2079f64b0..982bd16b1 100644 --- a/test/widget_tests/table_view/table_view_row_test.mocks.dart +++ b/test/widget_tests/table_view/table_view_row_test.mocks.dart @@ -1162,10 +1162,12 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i22.Future initializeNew() => (super.noSuchMethod( + _i22.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i22.Future.value(), returnValueForMissingStub: _i22.Future.value(), @@ -2302,10 +2304,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i22.Future.value(false), ) as _i22.Future); @override - _i22.Future initializeNew() => (super.noSuchMethod( + _i22.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i22.Future.value(), returnValueForMissingStub: _i22.Future.value(), @@ -2655,10 +2659,12 @@ class MockCoinServiceAPI extends _i1.Mock implements _i19.CoinServiceAPI { returnValueForMissingStub: _i22.Future.value(), ) as _i22.Future); @override - _i22.Future initializeNew() => (super.noSuchMethod( + _i22.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i22.Future.value(), returnValueForMissingStub: _i22.Future.value(), diff --git a/test/widget_tests/transaction_card_test.mocks.dart b/test/widget_tests/transaction_card_test.mocks.dart index 66bd37cf0..90afc98be 100644 --- a/test/widget_tests/transaction_card_test.mocks.dart +++ b/test/widget_tests/transaction_card_test.mocks.dart @@ -689,10 +689,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i19.Future.value(false), ) as _i19.Future); @override - _i19.Future initializeNew() => (super.noSuchMethod( + _i19.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i19.Future.value(), returnValueForMissingStub: _i19.Future.value(), @@ -1046,10 +1048,12 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI { returnValueForMissingStub: _i19.Future.value(), ) as _i19.Future); @override - _i19.Future initializeNew() => (super.noSuchMethod( + _i19.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i19.Future.value(), returnValueForMissingStub: _i19.Future.value(), @@ -1313,6 +1317,11 @@ class MockFiroWallet extends _i1.Mock implements _i23.FiroWallet { ), ) as _i13.CachedElectrumX); @override + bool get lelantusCoinIsarRescanRequired => (super.noSuchMethod( + Invocation.getter(#lelantusCoinIsarRescanRequired), + returnValue: false, + ) as bool); + @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), returnValue: false, @@ -1561,15 +1570,35 @@ class MockFiroWallet extends _i1.Mock implements _i23.FiroWallet { returnValueForMissingStub: _i19.Future.value(), ) as _i19.Future); @override - _i19.Future initializeNew() => (super.noSuchMethod( + _i19.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, + [data], + ), + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); + @override + _i19.Future setLelantusCoinIsarRescanRequiredDone() => + (super.noSuchMethod( + Invocation.method( + #setLelantusCoinIsarRescanRequiredDone, [], ), returnValue: _i19.Future.value(), returnValueForMissingStub: _i19.Future.value(), ) as _i19.Future); @override + _i19.Future firoRescanRecovery() => (super.noSuchMethod( + Invocation.method( + #firoRescanRecovery, + [], + ), + returnValue: _i19.Future.value(false), + ) as _i19.Future); + @override _i19.Future initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, diff --git a/test/widget_tests/wallet_card_test.mocks.dart b/test/widget_tests/wallet_card_test.mocks.dart index f2d6e83b1..14744fc3f 100644 --- a/test/widget_tests/wallet_card_test.mocks.dart +++ b/test/widget_tests/wallet_card_test.mocks.dart @@ -817,10 +817,12 @@ class MockBitcoinWallet extends _i1.Mock implements _i24.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i21.Future initializeNew() => (super.noSuchMethod( + _i21.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i21.Future.value(), returnValueForMissingStub: _i21.Future.value(), diff --git a/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart b/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart index 36d369769..ef519d4c9 100644 --- a/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart +++ b/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart @@ -1072,10 +1072,12 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future initializeNew() => (super.noSuchMethod( + _i23.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i23.Future.value(), returnValueForMissingStub: _i23.Future.value(), @@ -2411,10 +2413,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i23.Future.value(false), ) as _i23.Future); @override - _i23.Future initializeNew() => (super.noSuchMethod( + _i23.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i23.Future.value(), returnValueForMissingStub: _i23.Future.value(), @@ -2764,10 +2768,12 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValueForMissingStub: _i23.Future.value(), ) as _i23.Future); @override - _i23.Future initializeNew() => (super.noSuchMethod( + _i23.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i23.Future.value(), returnValueForMissingStub: _i23.Future.value(), diff --git a/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart b/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart index 357672d7a..16b4aa49e 100644 --- a/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart +++ b/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart @@ -1174,10 +1174,12 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future initializeNew() => (super.noSuchMethod( + _i23.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i23.Future.value(), returnValueForMissingStub: _i23.Future.value(), @@ -2514,10 +2516,12 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: _i23.Future.value(false), ) as _i23.Future); @override - _i23.Future initializeNew() => (super.noSuchMethod( + _i23.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i23.Future.value(), returnValueForMissingStub: _i23.Future.value(), @@ -2867,10 +2871,12 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValueForMissingStub: _i23.Future.value(), ) as _i23.Future); @override - _i23.Future initializeNew() => (super.noSuchMethod( + _i23.Future initializeNew( + ({String mnemonicPassphrase, int wordCount})? data) => + (super.noSuchMethod( Invocation.method( #initializeNew, - [], + [data], ), returnValue: _i23.Future.value(), returnValueForMissingStub: _i23.Future.value(),