From 8c1383bdd487232566522f8798eab16e3c6137b5 Mon Sep 17 00:00:00 2001 From: poka Date: Tue, 31 May 2022 18:23:56 +0200 Subject: [PATCH] Complete refactoring of unlocking chests; Can cache pin code 15 minutes --- android/app/build.gradle | 2 +- lib/main.dart | 2 + lib/providers/chest_provider.dart | 6 + lib/providers/generate_wallets.dart | 2 + lib/providers/home.dart | 42 ++-- lib/providers/my_wallets.dart | 14 +- lib/providers/substrate_sdk.dart | 8 +- lib/providers/wallet_options.dart | 6 + lib/screens/home.dart | 36 ++-- lib/screens/myWallets/change_pin.dart | 24 ++- lib/screens/myWallets/chest_options.dart | 37 +++- lib/screens/myWallets/choose_chest.dart | 36 ++-- lib/screens/myWallets/choose_wallet.dart | 7 +- .../myWallets/confirm_wallet_storage.dart | 187 ------------------ lib/screens/myWallets/unlocking_wallet.dart | 97 +++------ lib/screens/myWallets/wallets_home.dart | 24 ++- lib/screens/onBoarding/10.dart | 25 ++- lib/screens/transaction_in_progress.dart | 6 - lib/screens/wallet_view.dart | 137 +++++++++---- output.zip | Bin 2972 -> 0 bytes pubspec.lock | 7 + pubspec.yaml | 3 +- 22 files changed, 347 insertions(+), 361 deletions(-) delete mode 100644 lib/screens/myWallets/confirm_wallet_storage.dart delete mode 100644 output.zip diff --git a/android/app/build.gradle b/android/app/build.gradle index af26637..76c91a5 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -65,7 +65,7 @@ android { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.release + signingConfig signingConfigs.release //poka: comment this to build unsigned release, or set to signingConfigs.debug to sign with debug keys useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' diff --git a/lib/main.dart b/lib/main.dart index fba4194..7bb8f98 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -77,6 +77,8 @@ Future main() async { HttpOverrides.global = MyHttpOverrides(); + + if (kReleaseMode && enableSentry) { // CatcherOptions debugOptions = CatcherOptions(DialogReportMode(), [ // SentryHandler(SentryClient(SentryOptions( diff --git a/lib/providers/chest_provider.dart b/lib/providers/chest_provider.dart index bc337e2..cccc2ec 100644 --- a/lib/providers/chest_provider.dart +++ b/lib/providers/chest_provider.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:provider/provider.dart'; @@ -17,6 +18,11 @@ class ChestProvider with ChangeNotifier { if (_answer ?? false) { await _sub.deleteAccounts(getChestWallets(_chest)); await chestBox.delete(_chest.key); + MyWalletsProvider _myWalletProvider = + Provider.of(context, listen: false); + + _myWalletProvider.pinCode = ''; + if (chestBox.isEmpty) { await configBox.put('currentChest', 0); } else { diff --git a/lib/providers/generate_wallets.dart b/lib/providers/generate_wallets.dart index af03416..b0176ff 100644 --- a/lib/providers/generate_wallets.dart +++ b/lib/providers/generate_wallets.dart @@ -70,6 +70,8 @@ class GenerateWalletsProvider with ChangeNotifier { } else { chestName = 'Coffre à Ğecko ${chestNumber + 1}'; } + await configBox.put('currentChest', chestNumber); + ChestData thisChest = ChestData( name: chestName, defaultWallet: 0, diff --git a/lib/providers/home.dart b/lib/providers/home.dart index a228db0..2731b64 100644 --- a/lib/providers/home.dart +++ b/lib/providers/home.dart @@ -11,6 +11,7 @@ import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; +import 'package:gecko/screens/myWallets/wallets_home.dart'; import 'package:gecko/screens/search.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:flutter/foundation.dart' show kDebugMode, kIsWeb; @@ -169,23 +170,32 @@ class HomeProvider with ChangeNotifier { IconButton( iconSize: 60, icon: const Image(image: AssetImage('assets/wallet.png')), - onPressed: () { - Navigator.popUntil( - context, - ModalRoute.withName('/'), - ); + onPressed: () async { WalletData? defaultWallet = _myWalletProvider.getDefaultWallet(); - Navigator.push( - context, - MaterialPageRoute( - builder: (homeContext) { - return UnlockingWallet( - wallet: defaultWallet, - action: "mywallets", - ); - }, - ), - ); + String? _pin; + if (_myWalletProvider.pinCode == '') { + _pin = await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet(wallet: defaultWallet); + }, + ), + ); + } + + if (_pin != null || _myWalletProvider.pinCode != '') { + Navigator.popUntil( + context, + ModalRoute.withName('/'), + ); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return const WalletsHome(); + }), + ); + } }, ), ]), diff --git a/lib/providers/my_wallets.dart b/lib/providers/my_wallets.dart index 6c9600e..169dfb6 100644 --- a/lib/providers/my_wallets.dart +++ b/lib/providers/my_wallets.dart @@ -8,7 +8,7 @@ import 'package:provider/provider.dart'; class MyWalletsProvider with ChangeNotifier { List listWallets = []; - late String pinCode; + String pinCode = ''; late String mnemonic; int? pinLenght; bool isNewDerivationLoading = false; @@ -82,6 +82,8 @@ class MyWalletsProvider with ChangeNotifier { Future deleteAllWallet(context) async { SubstrateSdk _sub = Provider.of(context, listen: false); + MyWalletsProvider _myWalletProvider = + Provider.of(context, listen: false); try { log.w('DELETE ALL WALLETS ?'); @@ -92,6 +94,9 @@ class MyWalletsProvider with ChangeNotifier { await chestBox.clear(); await configBox.delete('defaultWallet'); await _sub.deleteAllAccounts(); + + _myWalletProvider.pinCode = ''; + await Navigator.of(context).pushNamedAndRemoveUntil( '/', ModalRoute.withName('/'), @@ -144,6 +149,13 @@ class MyWalletsProvider with ChangeNotifier { notifyListeners(); } + Future resetPinCode([int minutes = 15]) async { + await Future.delayed( + Duration(seconds: configBox.get('isCacheChecked') ? minutes * 60 : 1)); + log.i('reset pin code ...'); + pinCode = ''; + } + void rebuildWidget() { notifyListeners(); } diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 7b130fb..6bee52c 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -6,6 +6,7 @@ import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/home.dart'; +import 'package:gecko/providers/my_wallets.dart'; import 'package:polkawallet_sdk/api/apiKeyring.dart'; import 'package:polkawallet_sdk/api/types/networkParams.dart'; import 'package:polkawallet_sdk/api/types/txInfoData.dart'; @@ -255,10 +256,13 @@ class SubstrateSdk with ChangeNotifier { return int.parse(deriveNbr); } - Future changePassword( - String address, String passOld, String? passNew) async { + Future changePassword(BuildContext context, String address, + String passOld, String? passNew) async { final account = getKeypair(address); + MyWalletsProvider _myWalletProvider = + Provider.of(context, listen: false); keyring.setCurrent(account); + _myWalletProvider.resetPinCode(); return await sdk.api.keyring.changePassword(keyring, passOld, passNew); } diff --git a/lib/providers/wallet_options.dart b/lib/providers/wallet_options.dart index 111fe0f..7f3f33d 100644 --- a/lib/providers/wallet_options.dart +++ b/lib/providers/wallet_options.dart @@ -232,6 +232,12 @@ class WalletOptionsProvider with ChangeNotifier { notifyListeners(); } + Future changePinCacheChoice() async { + bool isCacheChecked = configBox.get('isCacheChecked') ?? true; + await configBox.put('isCacheChecked', !isCacheChecked); + notifyListeners(); + } + String? getAddress(int chest, int derivation) { String? _address; walletBox.toMap().forEach((key, value) { diff --git a/lib/screens/home.dart b/lib/screens/home.dart index defe4d9..28a4ac4 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -11,6 +11,7 @@ import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/myWallets/restore_chest.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; +import 'package:gecko/screens/myWallets/wallets_home.dart'; import 'package:gecko/screens/onBoarding/1.dart'; import 'package:gecko/screens/search.dart'; import 'package:gecko/screens/settings.dart'; @@ -289,20 +290,31 @@ Widget geckHome(context) { image: const AssetImage( 'assets/home/wallet.png'), height: 68 * ratio)), - onTap: () { + onTap: () async { WalletData? defaultWallet = _myWalletProvider.getDefaultWallet(); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) { - return UnlockingWallet( - wallet: defaultWallet, - action: "mywallets", - ); - }, - ), - ); + String? _pin; + if (_myWalletProvider.pinCode == '') { + _pin = await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet( + wallet: defaultWallet); + }, + ), + ); + } + if (_pin != null || + _myWalletProvider.pinCode != '') { + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return const WalletsHome(); + }), + ); + } + // log.d(_myWalletProvider.pinCode); // Navigator.pushNamed( // context, '/mywallets'))); diff --git a/lib/screens/myWallets/change_pin.dart b/lib/screens/myWallets/change_pin.dart index 52e88dd..24c0308 100644 --- a/lib/screens/myWallets/change_pin.dart +++ b/lib/screens/myWallets/change_pin.dart @@ -6,6 +6,7 @@ import 'package:gecko/models/stateful_wrapper.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; +import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'dart:io'; import 'package:provider/provider.dart'; @@ -106,11 +107,24 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier { WalletData defaultWallet = _myWalletProvider.getDefaultWallet()!; - await _sub.changePassword( - defaultWallet.address!, walletProvider.pinCode, newPin.text); - walletProvider.pinCode = newPin.text; - newPin.text = ''; - Navigator.pop(context); + String? _pin; + if (_myWalletProvider.pinCode == '') { + _pin = await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet(wallet: defaultWallet); + }, + ), + ); + } + if (_pin != null || _myWalletProvider.pinCode != '') { + await _sub.changePassword(context, defaultWallet.address!, + walletProvider.pinCode, newPin.text); + walletProvider.pinCode = newPin.text; + newPin.text = ''; + Navigator.pop(context); + } }, child: const Text( 'Confirmer', diff --git a/lib/screens/myWallets/chest_options.dart b/lib/screens/myWallets/chest_options.dart index 5a4d7ee..cffe800 100644 --- a/lib/screens/myWallets/chest_options.dart +++ b/lib/screens/myWallets/chest_options.dart @@ -2,11 +2,13 @@ import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; import 'package:flutter/services.dart'; +import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/chest_provider.dart'; import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/screens/myWallets/change_pin.dart'; import 'package:gecko/screens/myWallets/show_seed.dart'; +import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:provider/provider.dart'; class ChestOptions extends StatelessWidget { @@ -51,15 +53,32 @@ class ChestOptions extends StatelessWidget { InkWell( key: const Key('showSeed'), onTap: () async { - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return ShowSeed( - walletName: currentChest.name, - walletProvider: walletProvider, - ); - }), - ); + MyWalletsProvider _myWalletProvider = + Provider.of(context, listen: false); + WalletData? defaultWallet = + _myWalletProvider.getDefaultWallet(); + String? _pin; + if (_myWalletProvider.pinCode == '') { + _pin = await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet(wallet: defaultWallet); + }, + ), + ); + } + if (_pin != null || _myWalletProvider.pinCode != '') { + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return ShowSeed( + walletName: currentChest.name, + walletProvider: walletProvider, + ); + }), + ); + } }, child: SizedBox( height: 50, diff --git a/lib/screens/myWallets/choose_chest.dart b/lib/screens/myWallets/choose_chest.dart index 5805e0c..de15755 100644 --- a/lib/screens/myWallets/choose_chest.dart +++ b/lib/screens/myWallets/choose_chest.dart @@ -6,12 +6,12 @@ import 'package:flutter/material.dart'; import 'package:gecko/screens/myWallets/restore_chest.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:carousel_slider/carousel_slider.dart'; +import 'package:gecko/screens/myWallets/wallets_home.dart'; import 'package:gecko/screens/onBoarding/5.dart'; import 'package:provider/provider.dart'; class ChooseChest extends StatefulWidget { - const ChooseChest({this.action, Key? key}) : super(key: key); - final String? action; + const ChooseChest({Key? key}) : super(key: key); @override State createState() { @@ -31,8 +31,6 @@ class _ChooseChestState extends State { MyWalletsProvider _myWalletProvider = Provider.of(context); - log.d(widget.action); - return Scaffold( backgroundColor: backgroundColor, appBar: AppBar( @@ -113,21 +111,33 @@ class _ChooseChestState extends State { primary: orangeC, // background onPrimary: Colors.black, // foreground ), - onPressed: () { - configBox.put('currentChest', currentChest); + onPressed: () async { + await configBox.put('currentChest', currentChest); + _myWalletProvider.pinCode = ''; WalletData? defaultWallet = _myWalletProvider.getDefaultWallet(); _myWalletProvider.rebuildWidget(); - Navigator.pushAndRemoveUntil( + + await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet(wallet: defaultWallet); + }, + ), + ); + Navigator.popUntil( context, - MaterialPageRoute(builder: (context) { - return UnlockingWallet( - wallet: defaultWallet, - action: widget.action ?? "mywallets", - ); - }), ModalRoute.withName('/'), ); + if (_myWalletProvider.pinCode != '') { + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return const WalletsHome(); + }), + ); + } }, child: Text( 'Ouvrir ce coffre', diff --git a/lib/screens/myWallets/choose_wallet.dart b/lib/screens/myWallets/choose_wallet.dart index 1f6ebad..ab4f790 100644 --- a/lib/screens/myWallets/choose_wallet.dart +++ b/lib/screens/myWallets/choose_wallet.dart @@ -14,9 +14,7 @@ import 'package:provider/provider.dart'; // ignore: must_be_immutable class ChooseWalletScreen extends StatelessWidget { - ChooseWalletScreen({Key? key, required this.chest, required this.pin}) - : super(key: key); - final int chest; + ChooseWalletScreen({Key? key, required this.pin}) : super(key: key); final String pin; WalletData? selectedWallet; @@ -24,6 +22,7 @@ class ChooseWalletScreen extends StatelessWidget { Widget build(BuildContext context) { SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SubstrateSdk _sub = Provider.of(context, listen: false); + final int chest = configBox.get('currentChest'); return Scaffold( backgroundColor: backgroundColor, @@ -55,7 +54,7 @@ class ChooseWalletScreen extends StatelessWidget { // _walletViewProvider.reload(); _sub.reload(); - Navigator.pop(context); + // Navigator.pop(context); Navigator.pop(context); Navigator.pop(context); }, diff --git a/lib/screens/myWallets/confirm_wallet_storage.dart b/lib/screens/myWallets/confirm_wallet_storage.dart deleted file mode 100644 index 74d23c0..0000000 --- a/lib/screens/myWallets/confirm_wallet_storage.dart +++ /dev/null @@ -1,187 +0,0 @@ -import 'dart:async'; -import 'package:durt/durt.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:gecko/globals.dart'; -import 'package:gecko/providers/generate_wallets.dart'; -import 'package:gecko/providers/my_wallets.dart'; -import 'package:gecko/providers/substrate_sdk.dart'; -import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; -import 'package:provider/provider.dart'; - -// ignore: must_be_immutable -class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier { - ConfirmStoreWallet({ - Key? validationKey, - required this.generatedMnemonic, - required this.generatedWallet, - }) : super(key: validationKey); - - String? generatedMnemonic; - NewWallet? generatedWallet; - - final TextEditingController _mnemonicController = TextEditingController(); - final TextEditingController _inputRestoreWord = TextEditingController(); - TextEditingController walletName = TextEditingController(); - final FocusNode _wordFocus = FocusNode(); - - @override - Widget build(BuildContext context) { - SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); - GenerateWalletsProvider _generateWalletProvider = - Provider.of(context); - MyWalletsProvider _myWalletProvider = - Provider.of(context); - final int? _currentChest = _myWalletProvider.getCurrentChest(); - SubstrateSdk _sub = Provider.of(context, listen: false); - - _mnemonicController.text = generatedMnemonic!; - return WillPopScope( - onWillPop: () { - _generateWalletProvider.isAskedWordValid = false; - _generateWalletProvider.askedWordColor = Colors.black; - return Future.value(true); - }, - child: Scaffold( - resizeToAvoidBottomInset: false, - appBar: AppBar( - toolbarHeight: 60 * ratio, - leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), - onPressed: () { - Navigator.of(context).pop(); - _generateWalletProvider.isAskedWordValid = false; - _generateWalletProvider.askedWordColor = Colors.black; - }), - title: const SizedBox( - height: 22, - child: Text('Enregistrer ce coffre'), - )), - body: Center( - child: Column(children: [ - const SizedBox(height: 15), - SizedBox( - width: 360, - child: Text( - 'Quel est le ${_generateWalletProvider.nbrWord + 1}ème mot de votre phrase de restauration ?', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 17.0, - color: Colors.grey[600], - fontWeight: FontWeight.w400), - )), - TextFormField( - key: const Key('askedWord'), - focusNode: _wordFocus, - autofocus: true, - enabled: !_generateWalletProvider.isAskedWordValid, - controller: _inputRestoreWord, - textInputAction: TextInputAction.next, - onChanged: (value) { - _generateWalletProvider.checkAskedWord( - value, _mnemonicController.text); - }, - maxLines: 1, - textAlign: TextAlign.center, - decoration: const InputDecoration(), - style: TextStyle( - fontSize: 30.0, - color: _generateWalletProvider.askedWordColor, - fontWeight: FontWeight.w500)), - const SizedBox(height: 12), - SizedBox( - width: 360, - child: Text( - 'Choisissez un nom pour votre premier portefeuille :', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 17.0, - color: Colors.grey[600], - fontWeight: FontWeight.w400), - )), - TextFormField( - key: const Key('walletName'), - focusNode: _generateWalletProvider.walletNameFocus, - inputFormatters: [ - FilteringTextInputFormatter.allow( - RegExp('[A-Za-z|0-9|\\-|_| ]')), - ], - controller: walletName, - textInputAction: TextInputAction.next, - onChanged: (v) { - _generateWalletProvider.nameChanged(); - }, - maxLines: 1, - textAlign: TextAlign.center, - decoration: const InputDecoration(), - style: const TextStyle( - fontSize: 30.0, - color: Colors.black, - fontWeight: FontWeight.w500)), - Expanded( - child: Align( - alignment: Alignment.bottomCenter, - child: SizedBox( - width: 200, - height: 50, - child: ElevatedButton( - key: const Key('confirmStorage'), - style: ElevatedButton.styleFrom( - elevation: 12, - primary: Colors - .green[400], //smoothYellow, // background - onPrimary: Colors.black, // foreground - ), - onPressed: (_generateWalletProvider - .isAskedWordValid && - walletName.text != '') - ? () async { - final address = await _sub.importAccount( - fromMnemonic: true, - mnemonic: _generateWalletProvider - .generatedMnemonic!, - password: _generateWalletProvider - .pin.text - .toUpperCase(), - derivePath: '//2'); - await _generateWalletProvider.storeHDWChest( - address, - 'Mon portefeuille courant', - context); - _generateWalletProvider.isAskedWordValid = - false; - _generateWalletProvider.askedWordColor = - Colors.black; - _myWalletProvider.listWallets = - _myWalletProvider - .readAllWallets(_currentChest); - await Future.delayed( - const Duration(milliseconds: 50)); - _myWalletProvider.rebuildWidget(); - _generateWalletProvider.pin.text = ''; - _generateWalletProvider - .mnemonicController.text = ''; - Navigator.pushAndRemoveUntil(context, - MaterialPageRoute(builder: (context) { - return UnlockingWallet( - wallet: _myWalletProvider - .getDefaultWallet(), - action: "mywallets", - ); - }), ModalRoute.withName('/')); - } - : null, - child: const Text('Confirmer', - style: TextStyle(fontSize: 28))), - ))), - const SizedBox(height: 70), - Text('TRICHE PENDANT ALPHA: ' + _mnemonicController.text, - style: const TextStyle( - fontSize: 10.0, - color: Colors.black, - fontWeight: FontWeight.normal)), - ]), - ), - )); - } -} diff --git a/lib/screens/myWallets/unlocking_wallet.dart b/lib/screens/myWallets/unlocking_wallet.dart index 4d39e12..e5749e1 100644 --- a/lib/screens/myWallets/unlocking_wallet.dart +++ b/lib/screens/myWallets/unlocking_wallet.dart @@ -8,24 +8,18 @@ import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/wallet_options.dart'; import 'package:flutter/material.dart'; -import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/myWallets/choose_chest.dart'; -import 'package:gecko/screens/myWallets/choose_wallet.dart'; -import 'package:gecko/screens/myWallets/wallets_home.dart'; -import 'package:gecko/screens/transaction_in_progress.dart'; import 'package:pin_code_fields/pin_code_fields.dart'; import 'package:provider/provider.dart'; import 'package:gecko/globals.dart'; // ignore: must_be_immutable class UnlockingWallet extends StatelessWidget { - UnlockingWallet( - {Key? keyUnlockWallet, required this.wallet, required this.action}) + UnlockingWallet({Key? keyUnlockWallet, required this.wallet}) : super(key: keyUnlockWallet); WalletData? wallet; late int currentChestNumber; late ChestData currentChest; - String action; // ignore: close_sinks StreamController? errorController; @@ -43,6 +37,10 @@ class UnlockingWallet extends StatelessWidget { currentChestNumber = configBox.get('currentChest'); currentChest = chestBox.get(currentChestNumber)!; + if (configBox.get('isCacheChecked') == null) { + configBox.put('isCacheChecked', true); + } + int _pinLenght = _walletOptions.getPinLenght(wallet!.number); errorController = StreamController(); @@ -107,19 +105,42 @@ class UnlockingWallet extends StatelessWidget { SizedBox(height: 40 * ratio), pinForm(context, _pinLenght), SizedBox(height: 3 * ratio), + InkWell( + onTap: () { + _walletOptions.changePinCacheChoice(); + }, + child: Row(children: [ + const SizedBox(height: 30), + const Spacer(), + Icon( + configBox.get('isCacheChecked') + ? Icons.check_box + : Icons.check_box_outline_blank, + color: orangeC, + ), + const SizedBox(width: 8), + Text( + 'Garder ce code en mémoire 15 minutes', + style: + TextStyle(fontSize: 16, color: Colors.grey[700]), + ), + const Spacer() + ]), + ), + const SizedBox(height: 10), InkWell( key: const Key('chooseChest'), onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) { - return ChooseChest(action: action); + return const ChooseChest(); }), ); }, child: SizedBox( width: 400, - height: 70, + height: 50, child: Center( child: Text( 'Changer de coffre', @@ -215,62 +236,8 @@ class UnlockingWallet extends StatelessWidget { pinFocus.requestFocus(); } else { pinColor = Colors.green[400]; - switch (action) { - case "mywallets": - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return const WalletsHome(); - }), - ); - break; - case "changeWallet": - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return ChooseWalletScreen( - chest: currentChestNumber, pin: _pin.toUpperCase()); - }), - ); - break; - case "pay": - // Payment workflow ! - WalletsProfilesProvider _walletViewProvider = - Provider.of(context, - listen: false); - final acc = _sub.getCurrentWallet(); - log.d( - "fromAddress: ${acc.address!},destAddress: ${_walletViewProvider.address!}, amount: ${double.parse(_walletViewProvider.payAmount.text)}, password: $_pin"); - _sub.pay( - fromAddress: acc.address!, - destAddress: _walletViewProvider.address!, - amount: - double.parse(_walletViewProvider.payAmount.text), - password: _pin.toUpperCase()); - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return const TransactionInProgress(); - }), - ); - break; - case "cert": - WalletsProfilesProvider _walletViewProvider = - Provider.of(context, - listen: false); - final acc = _sub.getCurrentWallet(); - _sub.certify(acc.address!, _pin.toUpperCase(), - _walletViewProvider.address!); - - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return const TransactionInProgress(transType: 'cert'); - }), - ); - - break; - } + _myWalletProvider.resetPinCode(); + Navigator.pop(context, _pin.toUpperCase()); } }, onChanged: (value) { diff --git a/lib/screens/myWallets/wallets_home.dart b/lib/screens/myWallets/wallets_home.dart index 7cf4a3c..8f8eefb 100644 --- a/lib/screens/myWallets/wallets_home.dart +++ b/lib/screens/myWallets/wallets_home.dart @@ -11,6 +11,7 @@ import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/myWallets/chest_options.dart'; import 'package:gecko/screens/myWallets/choose_chest.dart'; +import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/myWallets/wallet_options.dart'; import 'package:provider/provider.dart'; @@ -32,7 +33,7 @@ class WalletsHome extends StatelessWidget { return WillPopScope( onWillPop: () { - myWalletProvider.pinCode = myWalletProvider.mnemonic = ''; + // myWalletProvider.pinCode = myWalletProvider.mnemonic = ''; Navigator.popUntil( context, ModalRoute.withName('/'), @@ -47,7 +48,7 @@ class WalletsHome extends StatelessWidget { leading: IconButton( icon: const Icon(Icons.arrow_back, color: Colors.black), onPressed: () { - myWalletProvider.pinCode = myWalletProvider.mnemonic = ''; + // myWalletProvider.pinCode = myWalletProvider.mnemonic = ''; Navigator.popUntil( context, ModalRoute.withName('/'), @@ -350,8 +351,23 @@ class WalletsHome extends StatelessWidget { key: const Key('addDerivation'), onTap: () async { if (!_myWalletProvider.isNewDerivationLoading) { - await _myWalletProvider.generateNewDerivation( - context, _newDerivationName); + WalletData? defaultWallet = + _myWalletProvider.getDefaultWallet(); + String? _pin; + if (_myWalletProvider.pinCode == '') { + _pin = await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet(wallet: defaultWallet); + }, + ), + ); + } + if (_pin != null || _myWalletProvider.pinCode != '') { + await _myWalletProvider.generateNewDerivation( + context, _newDerivationName); + } } }, child: Container( diff --git a/lib/screens/onBoarding/10.dart b/lib/screens/onBoarding/10.dart index 5e71855..3d67a9f 100644 --- a/lib/screens/onBoarding/10.dart +++ b/lib/screens/onBoarding/10.dart @@ -58,7 +58,29 @@ class OnboardingStepTen extends StatelessWidget { style: TextStyle(fontSize: 16 * ratio)) ]), SizedBox(height: isTall ? 80 : 20), - pinForm(context, _walletOptions, _pinLenght, 1, 2) + pinForm(context, _walletOptions, _pinLenght, 1, 2), + InkWell( + onTap: () { + _walletOptions.changePinCacheChoice(); + }, + child: Row(children: [ + const SizedBox(height: 30), + const Spacer(), + Icon( + configBox.get('isCacheChecked') + ? Icons.check_box + : Icons.check_box_outline_blank, + color: orangeC, + ), + const SizedBox(width: 8), + Text( + 'Garder ce code en mémoire 15 minutes', + style: TextStyle(fontSize: 16, color: Colors.grey[700]), + ), + const Spacer() + ]), + ), + const SizedBox(height: 10), ]), )); } @@ -144,6 +166,7 @@ class OnboardingStepTen extends StatelessWidget { _myWalletProvider.rebuildWidget(); // }); _generateWalletProvider.generatedMnemonic = ''; + _myWalletProvider.resetPinCode(); Navigator.push( context, FaderTransition( diff --git a/lib/screens/transaction_in_progress.dart b/lib/screens/transaction_in_progress.dart index 756bda9..1beb5a4 100644 --- a/lib/screens/transaction_in_progress.dart +++ b/lib/screens/transaction_in_progress.dart @@ -86,9 +86,6 @@ class TransactionInProgress extends StatelessWidget { _sub.transactionStatus = ''; Navigator.pop(context); Navigator.pop(context); - if (transType == 'pay') { - Navigator.pop(context); - } return Future.value(true); }, child: Scaffold( @@ -191,9 +188,6 @@ class TransactionInProgress extends StatelessWidget { onPressed: () { Navigator.pop(context); Navigator.pop(context); - if (transType == 'pay') { - Navigator.pop(context); - } }, child: Text( 'Fermer', diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index 89e7ea8..0218d7b 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -9,7 +9,9 @@ import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/avatar_fullscreen.dart'; +import 'package:gecko/screens/myWallets/choose_wallet.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; +import 'package:gecko/screens/transaction_in_progress.dart'; import 'package:provider/provider.dart'; class WalletViewScreen extends StatelessWidget { @@ -125,18 +127,40 @@ class WalletViewScreen extends StatelessWidget { image: AssetImage( 'assets/gecko_certify.png')), ), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) { - return UnlockingWallet( - wallet: _defaultWallet, - action: "cert"); - }, - ), - ); - // _sub.certify(fromAddress, password, toAddress); + onTap: () async { + String? _pin; + if (_myWalletProvider.pinCode == '') { + _pin = await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet( + wallet: defaultWallet); + }, + ), + ); + } + if (_pin != null || + _myWalletProvider.pinCode != '') { + WalletsProfilesProvider + _walletViewProvider = + Provider.of( + context, + listen: false); + final acc = _sub.getCurrentWallet(); + _sub.certify( + acc.address!, + _pin ?? _myWalletProvider.pinCode, + _walletViewProvider.address!); + + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return const TransactionInProgress( + transType: 'cert'); + }), + ); + } }), ), ), @@ -331,17 +355,29 @@ class WalletViewScreen extends StatelessWidget { const SizedBox(height: 10), Consumer(builder: (context, _sub, _) { return InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) { - return UnlockingWallet( - wallet: defaultWallet, - action: "changeWallet"); - }, - ), - ); + onTap: () async { + String? _pin; + if (_myWalletProvider.pinCode == '') { + _pin = await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet( + wallet: defaultWallet); + }, + ), + ); + } + if (_pin != null || + _myWalletProvider.pinCode != '') { + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return ChooseWalletScreen( + pin: _pin ?? _myWalletProvider.pinCode); + }), + ); + } }, child: Container( width: double.infinity, @@ -464,17 +500,50 @@ class WalletViewScreen extends StatelessWidget { onPrimary: Colors.white, // foreground ), onPressed: canValidate - ? () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) { - return UnlockingWallet( - wallet: defaultWallet, - action: "pay"); - }, - ), - ); + ? () async { + String? _pin; + if (_myWalletProvider.pinCode == '') { + _pin = await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet( + wallet: defaultWallet); + }, + ), + ); + } + log.d(_pin); + if (_pin != null || + _myWalletProvider.pinCode != '') { + // Payment workflow ! + WalletsProfilesProvider + _walletViewProvider = + Provider.of( + context, + listen: false); + SubstrateSdk _sub = + Provider.of(context, + listen: false); + final acc = _sub.getCurrentWallet(); + log.d( + "fromAddress: ${acc.address!},destAddress: ${_walletViewProvider.address!}, amount: ${double.parse(_walletViewProvider.payAmount.text)}, password: $_pin"); + _sub.pay( + fromAddress: acc.address!, + destAddress: + _walletViewProvider.address!, + amount: double.parse( + _walletViewProvider + .payAmount.text), + password: _pin ?? + _myWalletProvider.pinCode); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return const TransactionInProgress(); + }), + ); + } } : null, child: const Text( diff --git a/output.zip b/output.zip deleted file mode 100644 index 17a4a18b1618cd195bf9b8a8816b5ce544a5bdc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2972 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 diff --git a/pubspec.lock b/pubspec.lock index 374a0c2..588d418 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -253,6 +253,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + cron: + dependency: "direct main" + description: + name: cron + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.0" cross_file: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b053df2..c9130f5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ description: Pay with G1. # pub.dev using `pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 0.0.7+7 +version: 0.0.7+8 environment: sdk: '>=2.12.0 <3.0.0' @@ -81,6 +81,7 @@ dependencies: ref: fixAndroidActivityVersion dots_indicator: ^2.1.0 web_socket_channel: ^2.2.0 + cron: ^0.5.0 dev_dependencies: # flutter_launcher_icons: ^0.9.2