Complete refactoring of unlocking chests; Can cache pin code 15 minutes

This commit is contained in:
poka 2022-05-31 18:23:56 +02:00
parent d91d2cddb3
commit 8c1383bdd4
22 changed files with 347 additions and 361 deletions

View File

@ -65,7 +65,7 @@ android {
release { release {
// TODO: Add your own signing config for the release build. // TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works. // 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 useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

View File

@ -77,6 +77,8 @@ Future<void> main() async {
HttpOverrides.global = MyHttpOverrides(); HttpOverrides.global = MyHttpOverrides();
if (kReleaseMode && enableSentry) { if (kReleaseMode && enableSentry) {
// CatcherOptions debugOptions = CatcherOptions(DialogReportMode(), [ // CatcherOptions debugOptions = CatcherOptions(DialogReportMode(), [
// SentryHandler(SentryClient(SentryOptions( // SentryHandler(SentryClient(SentryOptions(

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/wallet_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:gecko/providers/substrate_sdk.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -17,6 +18,11 @@ class ChestProvider with ChangeNotifier {
if (_answer ?? false) { if (_answer ?? false) {
await _sub.deleteAccounts(getChestWallets(_chest)); await _sub.deleteAccounts(getChestWallets(_chest));
await chestBox.delete(_chest.key); await chestBox.delete(_chest.key);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
_myWalletProvider.pinCode = '';
if (chestBox.isEmpty) { if (chestBox.isEmpty) {
await configBox.put('currentChest', 0); await configBox.put('currentChest', 0);
} else { } else {

View File

@ -70,6 +70,8 @@ class GenerateWalletsProvider with ChangeNotifier {
} else { } else {
chestName = 'Coffre à Ğecko ${chestNumber + 1}'; chestName = 'Coffre à Ğecko ${chestNumber + 1}';
} }
await configBox.put('currentChest', chestNumber);
ChestData thisChest = ChestData( ChestData thisChest = ChestData(
name: chestName, name: chestName,
defaultWallet: 0, defaultWallet: 0,

View File

@ -11,6 +11,7 @@ import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.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:gecko/screens/search.dart';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:flutter/foundation.dart' show kDebugMode, kIsWeb; import 'package:flutter/foundation.dart' show kDebugMode, kIsWeb;
@ -169,23 +170,32 @@ class HomeProvider with ChangeNotifier {
IconButton( IconButton(
iconSize: 60, iconSize: 60,
icon: const Image(image: AssetImage('assets/wallet.png')), icon: const Image(image: AssetImage('assets/wallet.png')),
onPressed: () { onPressed: () async {
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
WalletData? defaultWallet = _myWalletProvider.getDefaultWallet(); WalletData? defaultWallet = _myWalletProvider.getDefaultWallet();
Navigator.push( String? _pin;
context, if (_myWalletProvider.pinCode == '') {
MaterialPageRoute( _pin = await Navigator.push(
builder: (homeContext) { context,
return UnlockingWallet( MaterialPageRoute(
wallet: defaultWallet, builder: (homeContext) {
action: "mywallets", return UnlockingWallet(wallet: defaultWallet);
); },
}, ),
), );
); }
if (_pin != null || _myWalletProvider.pinCode != '') {
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const WalletsHome();
}),
);
}
}, },
), ),
]), ]),

View File

@ -8,7 +8,7 @@ import 'package:provider/provider.dart';
class MyWalletsProvider with ChangeNotifier { class MyWalletsProvider with ChangeNotifier {
List<WalletData> listWallets = []; List<WalletData> listWallets = [];
late String pinCode; String pinCode = '';
late String mnemonic; late String mnemonic;
int? pinLenght; int? pinLenght;
bool isNewDerivationLoading = false; bool isNewDerivationLoading = false;
@ -82,6 +82,8 @@ class MyWalletsProvider with ChangeNotifier {
Future<int> deleteAllWallet(context) async { Future<int> deleteAllWallet(context) async {
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false); SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
try { try {
log.w('DELETE ALL WALLETS ?'); log.w('DELETE ALL WALLETS ?');
@ -92,6 +94,9 @@ class MyWalletsProvider with ChangeNotifier {
await chestBox.clear(); await chestBox.clear();
await configBox.delete('defaultWallet'); await configBox.delete('defaultWallet');
await _sub.deleteAllAccounts(); await _sub.deleteAllAccounts();
_myWalletProvider.pinCode = '';
await Navigator.of(context).pushNamedAndRemoveUntil( await Navigator.of(context).pushNamedAndRemoveUntil(
'/', '/',
ModalRoute.withName('/'), ModalRoute.withName('/'),
@ -144,6 +149,13 @@ class MyWalletsProvider with ChangeNotifier {
notifyListeners(); 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() { void rebuildWidget() {
notifyListeners(); notifyListeners();
} }

View File

@ -6,6 +6,7 @@ import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/home.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/apiKeyring.dart';
import 'package:polkawallet_sdk/api/types/networkParams.dart'; import 'package:polkawallet_sdk/api/types/networkParams.dart';
import 'package:polkawallet_sdk/api/types/txInfoData.dart'; import 'package:polkawallet_sdk/api/types/txInfoData.dart';
@ -255,10 +256,13 @@ class SubstrateSdk with ChangeNotifier {
return int.parse(deriveNbr); return int.parse(deriveNbr);
} }
Future<KeyPairData?> changePassword( Future<KeyPairData?> changePassword(BuildContext context, String address,
String address, String passOld, String? passNew) async { String passOld, String? passNew) async {
final account = getKeypair(address); final account = getKeypair(address);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
keyring.setCurrent(account); keyring.setCurrent(account);
_myWalletProvider.resetPinCode();
return await sdk.api.keyring.changePassword(keyring, passOld, passNew); return await sdk.api.keyring.changePassword(keyring, passOld, passNew);
} }

View File

@ -232,6 +232,12 @@ class WalletOptionsProvider with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
Future changePinCacheChoice() async {
bool isCacheChecked = configBox.get('isCacheChecked') ?? true;
await configBox.put('isCacheChecked', !isCacheChecked);
notifyListeners();
}
String? getAddress(int chest, int derivation) { String? getAddress(int chest, int derivation) {
String? _address; String? _address;
walletBox.toMap().forEach((key, value) { walletBox.toMap().forEach((key, value) {

View File

@ -11,6 +11,7 @@ import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/restore_chest.dart'; import 'package:gecko/screens/myWallets/restore_chest.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.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/onBoarding/1.dart';
import 'package:gecko/screens/search.dart'; import 'package:gecko/screens/search.dart';
import 'package:gecko/screens/settings.dart'; import 'package:gecko/screens/settings.dart';
@ -289,20 +290,31 @@ Widget geckHome(context) {
image: const AssetImage( image: const AssetImage(
'assets/home/wallet.png'), 'assets/home/wallet.png'),
height: 68 * ratio)), height: 68 * ratio)),
onTap: () { onTap: () async {
WalletData? defaultWallet = WalletData? defaultWallet =
_myWalletProvider.getDefaultWallet(); _myWalletProvider.getDefaultWallet();
Navigator.push( String? _pin;
context, if (_myWalletProvider.pinCode == '') {
MaterialPageRoute( _pin = await Navigator.push(
builder: (context) { context,
return UnlockingWallet( MaterialPageRoute(
wallet: defaultWallet, builder: (homeContext) {
action: "mywallets", return UnlockingWallet(
); wallet: defaultWallet);
}, },
), ),
); );
}
if (_pin != null ||
_myWalletProvider.pinCode != '') {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const WalletsHome();
}),
);
}
// log.d(_myWalletProvider.pinCode);
// Navigator.pushNamed( // Navigator.pushNamed(
// context, '/mywallets'))); // context, '/mywallets')));

View File

@ -6,6 +6,7 @@ import 'package:gecko/models/stateful_wrapper.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'dart:io'; import 'dart:io';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -106,11 +107,24 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
WalletData defaultWallet = WalletData defaultWallet =
_myWalletProvider.getDefaultWallet()!; _myWalletProvider.getDefaultWallet()!;
await _sub.changePassword( String? _pin;
defaultWallet.address!, walletProvider.pinCode, newPin.text); if (_myWalletProvider.pinCode == '') {
walletProvider.pinCode = newPin.text; _pin = await Navigator.push(
newPin.text = ''; context,
Navigator.pop(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( child: const Text(
'Confirmer', 'Confirmer',

View File

@ -2,11 +2,13 @@ import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/chest_provider.dart'; import 'package:gecko/providers/chest_provider.dart';
import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/screens/myWallets/change_pin.dart'; import 'package:gecko/screens/myWallets/change_pin.dart';
import 'package:gecko/screens/myWallets/show_seed.dart'; import 'package:gecko/screens/myWallets/show_seed.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ChestOptions extends StatelessWidget { class ChestOptions extends StatelessWidget {
@ -51,15 +53,32 @@ class ChestOptions extends StatelessWidget {
InkWell( InkWell(
key: const Key('showSeed'), key: const Key('showSeed'),
onTap: () async { onTap: () async {
Navigator.push( MyWalletsProvider _myWalletProvider =
context, Provider.of<MyWalletsProvider>(context, listen: false);
MaterialPageRoute(builder: (context) { WalletData? defaultWallet =
return ShowSeed( _myWalletProvider.getDefaultWallet();
walletName: currentChest.name, String? _pin;
walletProvider: walletProvider, 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( child: SizedBox(
height: 50, height: 50,

View File

@ -6,12 +6,12 @@ import 'package:flutter/material.dart';
import 'package:gecko/screens/myWallets/restore_chest.dart'; import 'package:gecko/screens/myWallets/restore_chest.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:carousel_slider/carousel_slider.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:gecko/screens/onBoarding/5.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ChooseChest extends StatefulWidget { class ChooseChest extends StatefulWidget {
const ChooseChest({this.action, Key? key}) : super(key: key); const ChooseChest({Key? key}) : super(key: key);
final String? action;
@override @override
State<StatefulWidget> createState() { State<StatefulWidget> createState() {
@ -31,8 +31,6 @@ class _ChooseChestState extends State<ChooseChest> {
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
log.d(widget.action);
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
appBar: AppBar( appBar: AppBar(
@ -113,21 +111,33 @@ class _ChooseChestState extends State<ChooseChest> {
primary: orangeC, // background primary: orangeC, // background
onPrimary: Colors.black, // foreground onPrimary: Colors.black, // foreground
), ),
onPressed: () { onPressed: () async {
configBox.put('currentChest', currentChest); await configBox.put('currentChest', currentChest);
_myWalletProvider.pinCode = '';
WalletData? defaultWallet = WalletData? defaultWallet =
_myWalletProvider.getDefaultWallet(); _myWalletProvider.getDefaultWallet();
_myWalletProvider.rebuildWidget(); _myWalletProvider.rebuildWidget();
Navigator.pushAndRemoveUntil(
await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
return UnlockingWallet(wallet: defaultWallet);
},
),
);
Navigator.popUntil(
context, context,
MaterialPageRoute(builder: (context) {
return UnlockingWallet(
wallet: defaultWallet,
action: widget.action ?? "mywallets",
);
}),
ModalRoute.withName('/'), ModalRoute.withName('/'),
); );
if (_myWalletProvider.pinCode != '') {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const WalletsHome();
}),
);
}
}, },
child: Text( child: Text(
'Ouvrir ce coffre', 'Ouvrir ce coffre',

View File

@ -14,9 +14,7 @@ import 'package:provider/provider.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class ChooseWalletScreen extends StatelessWidget { class ChooseWalletScreen extends StatelessWidget {
ChooseWalletScreen({Key? key, required this.chest, required this.pin}) ChooseWalletScreen({Key? key, required this.pin}) : super(key: key);
: super(key: key);
final int chest;
final String pin; final String pin;
WalletData? selectedWallet; WalletData? selectedWallet;
@ -24,6 +22,7 @@ class ChooseWalletScreen extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false); SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
final int chest = configBox.get('currentChest');
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
@ -55,7 +54,7 @@ class ChooseWalletScreen extends StatelessWidget {
// _walletViewProvider.reload(); // _walletViewProvider.reload();
_sub.reload(); _sub.reload();
Navigator.pop(context); // Navigator.pop(context);
Navigator.pop(context); Navigator.pop(context);
Navigator.pop(context); Navigator.pop(context);
}, },

View File

@ -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<GenerateWalletsProvider>(context);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
final int? _currentChest = _myWalletProvider.getCurrentChest();
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
_mnemonicController.text = generatedMnemonic!;
return WillPopScope(
onWillPop: () {
_generateWalletProvider.isAskedWordValid = false;
_generateWalletProvider.askedWordColor = Colors.black;
return Future<bool>.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: <Widget>[
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)),
]),
),
));
}
}

View File

@ -8,24 +8,18 @@ import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/providers/wallet_options.dart';
import 'package:flutter/material.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_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:pin_code_fields/pin_code_fields.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class UnlockingWallet extends StatelessWidget { class UnlockingWallet extends StatelessWidget {
UnlockingWallet( UnlockingWallet({Key? keyUnlockWallet, required this.wallet})
{Key? keyUnlockWallet, required this.wallet, required this.action})
: super(key: keyUnlockWallet); : super(key: keyUnlockWallet);
WalletData? wallet; WalletData? wallet;
late int currentChestNumber; late int currentChestNumber;
late ChestData currentChest; late ChestData currentChest;
String action;
// ignore: close_sinks // ignore: close_sinks
StreamController<ErrorAnimationType>? errorController; StreamController<ErrorAnimationType>? errorController;
@ -43,6 +37,10 @@ class UnlockingWallet extends StatelessWidget {
currentChestNumber = configBox.get('currentChest'); currentChestNumber = configBox.get('currentChest');
currentChest = chestBox.get(currentChestNumber)!; currentChest = chestBox.get(currentChestNumber)!;
if (configBox.get('isCacheChecked') == null) {
configBox.put('isCacheChecked', true);
}
int _pinLenght = _walletOptions.getPinLenght(wallet!.number); int _pinLenght = _walletOptions.getPinLenght(wallet!.number);
errorController = StreamController<ErrorAnimationType>(); errorController = StreamController<ErrorAnimationType>();
@ -107,19 +105,42 @@ class UnlockingWallet extends StatelessWidget {
SizedBox(height: 40 * ratio), SizedBox(height: 40 * ratio),
pinForm(context, _pinLenght), pinForm(context, _pinLenght),
SizedBox(height: 3 * ratio), 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( InkWell(
key: const Key('chooseChest'), key: const Key('chooseChest'),
onTap: () { onTap: () {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return ChooseChest(action: action); return const ChooseChest();
}), }),
); );
}, },
child: SizedBox( child: SizedBox(
width: 400, width: 400,
height: 70, height: 50,
child: Center( child: Center(
child: Text( child: Text(
'Changer de coffre', 'Changer de coffre',
@ -215,62 +236,8 @@ class UnlockingWallet extends StatelessWidget {
pinFocus.requestFocus(); pinFocus.requestFocus();
} else { } else {
pinColor = Colors.green[400]; pinColor = Colors.green[400];
switch (action) { _myWalletProvider.resetPinCode();
case "mywallets": Navigator.pop(context, _pin.toUpperCase());
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<WalletsProfilesProvider>(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<WalletsProfilesProvider>(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;
}
} }
}, },
onChanged: (value) { onChanged: (value) {

View File

@ -11,6 +11,7 @@ import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/chest_options.dart'; import 'package:gecko/screens/myWallets/chest_options.dart';
import 'package:gecko/screens/myWallets/choose_chest.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:gecko/screens/myWallets/wallet_options.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -32,7 +33,7 @@ class WalletsHome extends StatelessWidget {
return WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {
myWalletProvider.pinCode = myWalletProvider.mnemonic = ''; // myWalletProvider.pinCode = myWalletProvider.mnemonic = '';
Navigator.popUntil( Navigator.popUntil(
context, context,
ModalRoute.withName('/'), ModalRoute.withName('/'),
@ -47,7 +48,7 @@ class WalletsHome extends StatelessWidget {
leading: IconButton( leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black), icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () { onPressed: () {
myWalletProvider.pinCode = myWalletProvider.mnemonic = ''; // myWalletProvider.pinCode = myWalletProvider.mnemonic = '';
Navigator.popUntil( Navigator.popUntil(
context, context,
ModalRoute.withName('/'), ModalRoute.withName('/'),
@ -350,8 +351,23 @@ class WalletsHome extends StatelessWidget {
key: const Key('addDerivation'), key: const Key('addDerivation'),
onTap: () async { onTap: () async {
if (!_myWalletProvider.isNewDerivationLoading) { if (!_myWalletProvider.isNewDerivationLoading) {
await _myWalletProvider.generateNewDerivation( WalletData? defaultWallet =
context, _newDerivationName); _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( child: Container(

View File

@ -58,7 +58,29 @@ class OnboardingStepTen extends StatelessWidget {
style: TextStyle(fontSize: 16 * ratio)) style: TextStyle(fontSize: 16 * ratio))
]), ]),
SizedBox(height: isTall ? 80 : 20), 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(); _myWalletProvider.rebuildWidget();
// }); // });
_generateWalletProvider.generatedMnemonic = ''; _generateWalletProvider.generatedMnemonic = '';
_myWalletProvider.resetPinCode();
Navigator.push( Navigator.push(
context, context,
FaderTransition( FaderTransition(

View File

@ -86,9 +86,6 @@ class TransactionInProgress extends StatelessWidget {
_sub.transactionStatus = ''; _sub.transactionStatus = '';
Navigator.pop(context); Navigator.pop(context);
Navigator.pop(context); Navigator.pop(context);
if (transType == 'pay') {
Navigator.pop(context);
}
return Future<bool>.value(true); return Future<bool>.value(true);
}, },
child: Scaffold( child: Scaffold(
@ -191,9 +188,6 @@ class TransactionInProgress extends StatelessWidget {
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);
Navigator.pop(context); Navigator.pop(context);
if (transType == 'pay') {
Navigator.pop(context);
}
}, },
child: Text( child: Text(
'Fermer', 'Fermer',

View File

@ -9,7 +9,9 @@ import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/avatar_fullscreen.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/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/transaction_in_progress.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class WalletViewScreen extends StatelessWidget { class WalletViewScreen extends StatelessWidget {
@ -125,18 +127,40 @@ class WalletViewScreen extends StatelessWidget {
image: AssetImage( image: AssetImage(
'assets/gecko_certify.png')), 'assets/gecko_certify.png')),
), ),
onTap: () { onTap: () async {
Navigator.push( String? _pin;
context, if (_myWalletProvider.pinCode == '') {
MaterialPageRoute( _pin = await Navigator.push(
builder: (context) { context,
return UnlockingWallet( MaterialPageRoute(
wallet: _defaultWallet, builder: (homeContext) {
action: "cert"); return UnlockingWallet(
}, wallet: defaultWallet);
), },
); ),
// _sub.certify(fromAddress, password, toAddress); );
}
if (_pin != null ||
_myWalletProvider.pinCode != '') {
WalletsProfilesProvider
_walletViewProvider =
Provider.of<WalletsProfilesProvider>(
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), const SizedBox(height: 10),
Consumer<SubstrateSdk>(builder: (context, _sub, _) { Consumer<SubstrateSdk>(builder: (context, _sub, _) {
return InkWell( return InkWell(
onTap: () { onTap: () async {
Navigator.push( String? _pin;
context, if (_myWalletProvider.pinCode == '') {
MaterialPageRoute( _pin = await Navigator.push(
builder: (context) { context,
return UnlockingWallet( MaterialPageRoute(
wallet: defaultWallet, builder: (homeContext) {
action: "changeWallet"); return UnlockingWallet(
}, wallet: defaultWallet);
), },
); ),
);
}
if (_pin != null ||
_myWalletProvider.pinCode != '') {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return ChooseWalletScreen(
pin: _pin ?? _myWalletProvider.pinCode);
}),
);
}
}, },
child: Container( child: Container(
width: double.infinity, width: double.infinity,
@ -464,17 +500,50 @@ class WalletViewScreen extends StatelessWidget {
onPrimary: Colors.white, // foreground onPrimary: Colors.white, // foreground
), ),
onPressed: canValidate onPressed: canValidate
? () { ? () async {
Navigator.push( String? _pin;
context, if (_myWalletProvider.pinCode == '') {
MaterialPageRoute( _pin = await Navigator.push(
builder: (context) { context,
return UnlockingWallet( MaterialPageRoute(
wallet: defaultWallet, builder: (homeContext) {
action: "pay"); return UnlockingWallet(
}, wallet: defaultWallet);
), },
); ),
);
}
log.d(_pin);
if (_pin != null ||
_myWalletProvider.pinCode != '') {
// Payment workflow !
WalletsProfilesProvider
_walletViewProvider =
Provider.of<WalletsProfilesProvider>(
context,
listen: false);
SubstrateSdk _sub =
Provider.of<SubstrateSdk>(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, : null,
child: const Text( child: const Text(

Binary file not shown.

View File

@ -253,6 +253,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
cron:
dependency: "direct main"
description:
name: cron
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.0"
cross_file: cross_file:
dependency: transitive dependency: transitive
description: description:

View File

@ -5,7 +5,7 @@ description: Pay with G1.
# pub.dev using `pub publish`. This is preferred for private packages. # 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 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: environment:
sdk: '>=2.12.0 <3.0.0' sdk: '>=2.12.0 <3.0.0'
@ -81,6 +81,7 @@ dependencies:
ref: fixAndroidActivityVersion ref: fixAndroidActivityVersion
dots_indicator: ^2.1.0 dots_indicator: ^2.1.0
web_socket_channel: ^2.2.0 web_socket_channel: ^2.2.0
cron: ^0.5.0
dev_dependencies: dev_dependencies:
# flutter_launcher_icons: ^0.9.2 # flutter_launcher_icons: ^0.9.2