Migrate all widget to stateless with provider fine

This commit is contained in:
poka 2021-01-28 15:10:09 +01:00
parent 3d501f4544
commit caf35fe19f
13 changed files with 430 additions and 501 deletions

View File

@ -4,6 +4,7 @@ import 'package:gecko/models/generateWallets.dart';
import 'package:gecko/models/history.dart'; import 'package:gecko/models/history.dart';
import 'package:gecko/models/home.dart'; import 'package:gecko/models/home.dart';
import 'package:gecko/models/myWallets.dart'; import 'package:gecko/models/myWallets.dart';
import 'package:gecko/models/walletOptions.dart';
import 'package:gecko/ui/home.dart'; import 'package:gecko/ui/home.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -93,39 +94,32 @@ class Gecko extends StatelessWidget {
); );
DubpRust.setup(); DubpRust.setup();
return return MultiProvider(
// MultiProvider( providers: [
// providers: [ // Provider(create: (context) => HistoryProvider()),
// Provider(create: (context) => HistoryProvider()), // Provider(create: (context) => MyWalletsProvider()),
// Provider(create: (context) => MyWalletsProvider()), ChangeNotifierProvider(create: (_) => HomeProvider()),
// ], ChangeNotifierProvider(create: (_) => HistoryProvider('')),
// child: ChangeNotifierProvider(create: (_) => MyWalletsProvider()),
MaterialApp( ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()),
title: 'Ğecko', ChangeNotifierProvider(create: (_) => WalletOptionsProvider())
theme: ThemeData( ],
primaryColor: Color(0xffFFD58D), child: GraphQLProvider(
accentColor: Colors.grey[850], client: _client,
textTheme: TextTheme( child: MaterialApp(
bodyText1: TextStyle(), title: 'Ğecko',
bodyText2: TextStyle(), theme: ThemeData(
).apply( primaryColor: Color(0xffFFD58D),
bodyColor: Color(0xff855F2D), accentColor: Colors.grey[850],
// displayColor: Colors.blue, textTheme: TextTheme(
bodyText1: TextStyle(),
bodyText2: TextStyle(),
).apply(
bodyColor: Color(0xff855F2D),
// displayColor: Colors.blue,
),
), ),
), home: HomeScreen(),
home: MultiProvider( )));
providers: [
// Provider(create: (context) => HistoryProvider()),
// Provider(create: (context) => MyWalletsProvider()),
ChangeNotifierProvider(create: (_) => HomeProvider()),
ChangeNotifierProvider(create: (_) => HistoryProvider('')),
ChangeNotifierProvider(create: (_) => MyWalletsProvider()),
ChangeNotifierProvider(create: (_) => GenerateWalletsProvider())
],
child: GraphQLProvider(
client: _client,
child: HomeScreen(),
),
));
} }
} }

View File

@ -8,21 +8,23 @@ import 'package:path_provider/path_provider.dart';
import 'package:sentry_flutter/sentry_flutter.dart' as sentry; import 'package:sentry_flutter/sentry_flutter.dart' as sentry;
class GenerateWalletsProvider with ChangeNotifier { class GenerateWalletsProvider with ChangeNotifier {
NewWallet generatedWallet; GenerateWalletsProvider();
// NewWallet generatedWallet;
NewWallet actualWallet;
FocusNode walletNameFocus = FocusNode(); FocusNode walletNameFocus = FocusNode();
Color askedWordColor = Colors.black; Color askedWordColor = Colors.black;
bool isAskedWordValid = false; bool isAskedWordValid = false;
int nbrWord; int nbrWord;
String generatedMnemonic; String generatedMnemonic;
bool walletIsGenerated = false; bool walletIsGenerated = true;
NewWallet actualWallet;
TextEditingController mnemonicController = TextEditingController(); TextEditingController mnemonicController = TextEditingController();
TextEditingController pubkey = TextEditingController(); TextEditingController pubkey = TextEditingController();
TextEditingController pin = TextEditingController(); TextEditingController pin = TextEditingController();
Future storeWallet(_name, _pubkey, BuildContext context) async { Future storeWallet(NewWallet wallet, _name, BuildContext context) async {
final appPath = await _localPath; final appPath = await _localPath;
final Directory walletNameDirectory = Directory('$appPath/wallets/$_name'); final Directory walletNameDirectory = Directory('$appPath/wallets/$_name');
final walletFile = File('${walletNameDirectory.path}/wallet.dewif'); final walletFile = File('${walletNameDirectory.path}/wallet.dewif');
@ -34,10 +36,11 @@ class GenerateWalletsProvider with ChangeNotifier {
} }
walletNameDirectory.createSync(); walletNameDirectory.createSync();
walletFile.writeAsString('${generatedWallet.dewif}'); walletFile.writeAsString('${wallet.dewif}');
Navigator.pop(context, true); Navigator.pop(context, true);
Navigator.pop(context, _pubkey.text); Navigator.pop(context, wallet.publicKey);
// notifyListeners();
return _name; return _name;
} }
@ -48,7 +51,7 @@ class GenerateWalletsProvider with ChangeNotifier {
} }
void checkAskedWord(String value, String _mnemo) { void checkAskedWord(String value, String _mnemo) {
nbrWord = getRandomInt(); // nbrWord = getRandomInt();
final runesAsked = _mnemo.split(' ')[nbrWord].runes; final runesAsked = _mnemo.split(' ')[nbrWord].runes;
List<int> runesAskedUnaccent = []; List<int> runesAskedUnaccent = [];
@ -71,10 +74,11 @@ class GenerateWalletsProvider with ChangeNotifier {
isAskedWordValid = true; isAskedWordValid = true;
askedWordColor = Colors.green[600]; askedWordColor = Colors.green[600];
walletNameFocus.nextFocus(); walletNameFocus.nextFocus();
notifyListeners();
} else { } else {
isAskedWordValid = false; isAskedWordValid = false;
} }
notifyListeners(); // notifyListeners();
} }
String removeDiacritics(String str) { String removeDiacritics(String str) {
@ -118,6 +122,8 @@ class GenerateWalletsProvider with ChangeNotifier {
child: Text("J'ai compris"), child: Text("J'ai compris"),
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
askedWordColor = Colors.green[500];
isAskedWordValid = true;
}, },
), ),
], ],
@ -128,10 +134,10 @@ class GenerateWalletsProvider with ChangeNotifier {
Future<String> generateMnemonic() async { Future<String> generateMnemonic() async {
try { try {
this.generatedMnemonic = generatedMnemonic = await DubpRust.genMnemonic(language: Language.french);
await DubpRust.genMnemonic(language: Language.french);
this.actualWallet = await generateWallet(this.generatedMnemonic); this.actualWallet = await generateWallet(this.generatedMnemonic);
this.walletIsGenerated = true; walletIsGenerated = true;
// notifyListeners();
} catch (e, stack) { } catch (e, stack) {
print(e); print(e);
if (kReleaseMode) { if (kReleaseMode) {
@ -142,7 +148,7 @@ class GenerateWalletsProvider with ChangeNotifier {
} }
} }
// await checkIfWalletExist(); // await checkIfWalletExist();
return this.generatedMnemonic; return generatedMnemonic;
} }
Future<NewWallet> generateWallet(generatedMnemonic) async { Future<NewWallet> generateWallet(generatedMnemonic) async {
@ -162,11 +168,11 @@ class GenerateWalletsProvider with ChangeNotifier {
} }
mnemonicController.text = generatedMnemonic; mnemonicController.text = generatedMnemonic;
pubkey.text = actualWallet.publicKey; pubkey.text = this.actualWallet.publicKey;
pin.text = actualWallet.pin; pin.text = this.actualWallet.pin;
notifyListeners(); // notifyListeners();
return actualWallet; return this.actualWallet;
} }
Future<void> changePinCode() async { Future<void> changePinCode() async {
@ -175,7 +181,7 @@ class GenerateWalletsProvider with ChangeNotifier {
oldPin: this.actualWallet.pin, oldPin: this.actualWallet.pin,
); );
pin.text = actualWallet.pin; pin.text = this.actualWallet.pin;
notifyListeners(); // notifyListeners();
} }
} }

View File

@ -10,9 +10,6 @@ class HistoryProvider with ChangeNotifier {
final TextEditingController _outputPubkey = new TextEditingController(); final TextEditingController _outputPubkey = new TextEditingController();
// String pubkey = 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'; // For debug // String pubkey = 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'; // For debug
// FetchMoreOptions opts;
// ScrollController scrollController = new ScrollController();
Future scan() async { Future scan() async {
await Permission.camera.request(); await Permission.camera.request();
String barcode; String barcode;
@ -28,7 +25,6 @@ class HistoryProvider with ChangeNotifier {
} }
return 'false'; return 'false';
} }
// this._outputPubkey.text = "";
if (barcode != null) { if (barcode != null) {
this._outputPubkey.text = barcode; this._outputPubkey.text = barcode;
isPubkey(barcode); isPubkey(barcode);
@ -59,13 +55,4 @@ class HistoryProvider with ChangeNotifier {
return ''; return '';
} }
// scrollListener() {
// if (scrollController.offset >= scrollController.position.maxScrollExtent &&
// !scrollController.position.outOfRange) {
// print('On est en bas !!');
// // fetchMore(opts);
// notifyListeners();
// }
// }
} }

View File

@ -3,9 +3,9 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'dart:async'; import 'dart:async';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:provider/provider.dart';
class MyWalletsProvider with ChangeNotifier { class MyWalletsProvider with ChangeNotifier {
// Directory appPath;
List listWallets = []; List listWallets = [];
bool checkIfWalletExist() { bool checkIfWalletExist() {
@ -24,28 +24,14 @@ class MyWalletsProvider with ChangeNotifier {
List contents = walletsFolder.listSync(); List contents = walletsFolder.listSync();
if (contents.length == 0) { if (contents.length == 0) {
print('No wallets detected'); print('No wallets detected');
notifyListeners();
return false; return false;
} else { } else {
print('Some wallets have been detected:'); print('Some wallets have been detected:');
for (var _wallets in contents) { for (var _wallets in contents) {
print(_wallets); print(_wallets);
} }
notifyListeners();
return true; return true;
} }
// final bool isExist =
// File('${walletsFolder.path}/$name/wallet.dewif').existsSync();
// print(this.appPath.path);
// print('Wallet existe ? : ' + isExist.toString());
// print('Is wallet generated ? : ' + walletIsGenerated.toString());
// if (isExist) {
// print('Un wallet existe !');
// return true;
// } else {
// return false;
// }
} }
Future importWallet() async {} Future importWallet() async {}
@ -63,8 +49,62 @@ class MyWalletsProvider with ChangeNotifier {
print(_name); print(_name);
listWallets.add(_name); listWallets.add(_name);
}); });
notifyListeners();
return listWallets; return listWallets;
} }
Future<int> deleteAllWallet(context) async {
try {
print('DELETE THAT ?: $walletsDirectory');
final bool _answer = await _confirmDeletingAllWallets(context);
if (_answer) {
walletsDirectory.deleteSync(recursive: true);
walletsDirectory.createSync();
Navigator.pop(context);
}
return 0;
} catch (e) {
return 1;
}
}
Future<bool> _confirmDeletingAllWallets(context) async {
return showDialog<bool>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
return AlertDialog(
title: Text(
'Êtes-vous sûr de vouloir supprimer tous vos portefeuilles ?'),
content: SingleChildScrollView(child: Text('')),
actions: <Widget>[
TextButton(
child: Text("Non"),
onPressed: () {
Navigator.pop(context, false);
},
),
TextButton(
child: Text("Oui"),
onPressed: () {
WidgetsBinding.instance.addPostFrameCallback((_) {
_myWalletProvider.listWallets =
_myWalletProvider.getAllWalletsNames();
_myWalletProvider.rebuildWidget();
});
Navigator.pop(context, true);
},
),
],
);
},
);
}
void rebuildWidget() {
notifyListeners();
}
} }

View File

@ -0,0 +1,211 @@
import 'dart:io';
import 'package:dubp/dubp.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:sentry/sentry.dart' as sentry;
import 'package:gecko/globals.dart';
class WalletOptionsProvider with ChangeNotifier {
TextEditingController pubkey = new TextEditingController();
TextEditingController _newWalletName = new TextEditingController();
bool isWalletUnlock = false;
bool ischangedPin = false;
TextEditingController newPin = new TextEditingController();
Future<NewWallet> get badWallet => null;
Future _getPubkeyFromDewif(_dewif, _pin) async {
String _pubkey;
RegExp regExp = new RegExp(
r'^[A-Z0-9]+$',
caseSensitive: false,
multiLine: false,
);
if (regExp.hasMatch(_pin) == true && _pin.length == 6) {
print("Le format du code PIN est correct.");
} else {
print('Format de code PIN invalide');
return 'false';
}
try {
_pubkey = await DubpRust.getDewifPublicKey(dewif: _dewif, pin: _pin);
this.pubkey.text = _pubkey;
notifyListeners();
return _pubkey;
} catch (e, stack) {
print('Bad PIN code !');
print(e);
if (kReleaseMode) {
await sentry.Sentry.captureException(
e,
stackTrace: stack,
);
}
notifyListeners();
return 'false';
}
}
Future readLocalWallet(String _name, String _pin) async {
print('NOM: ' + _name);
try {
File _walletFile = File('${walletsDirectory.path}/$_name/wallet.dewif');
String _localDewif = await _walletFile.readAsString();
String _localPubkey;
if ((_localPubkey = await _getPubkeyFromDewif(_localDewif, _pin)) !=
'false') {
this.pubkey.text = _localPubkey;
isWalletUnlock = true;
notifyListeners();
return _localDewif;
} else {
throw 'Bad pubkey';
}
} catch (e) {
print('ERROR READING FILE: $e');
this.pubkey.clear();
return 'bad';
}
}
Future _renameWallet(_walletName, _newName) async {
final _walletFile = Directory('${walletsDirectory.path}/$_walletName');
try {
_walletFile.rename('${walletsDirectory.path}/$_newName');
} catch (e) {
print('ERREUR lors du renommage du wallet: $e');
}
}
Future<bool> renameWalletAlerte(context, _walletName) async {
return showDialog<bool>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Choisissez un nouveau nom pour ce portefeuille'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
TextField(
controller: this._newWalletName,
maxLines: 1,
textAlign: TextAlign.center,
decoration: InputDecoration(),
style: TextStyle(
fontSize: 14.0,
color: Colors.black,
fontWeight: FontWeight.bold)),
],
),
),
actions: <Widget>[
TextButton(
child: Text("Valider"),
onPressed: () {
WidgetsBinding.instance.addPostFrameCallback((_) {
_renameWallet(_walletName, this._newWalletName.text);
});
notifyListeners();
Navigator.pop(context, true);
},
),
],
);
},
);
}
Future<int> deleteWallet(context, _name) async {
try {
final _walletFile = Directory('${walletsDirectory.path}/$_name');
print('DELETE THAT ?: $_walletFile');
final bool _answer = await _confirmDeletingWallet(context, _name);
if (_answer) {
_walletFile.deleteSync(recursive: true);
isWalletUnlock = false;
Navigator.pop(context);
}
return 0;
} catch (e) {
return 1;
}
}
Future<bool> _confirmDeletingWallet(context, _walletName) async {
return showDialog<bool>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text(
'Êtes-vous sûr de vouloir supprimer le portefeuille "$_walletName" ?'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'Vous pourrez restaurer ce portefeuille à tout moment grace à votre phrase de restauration.'),
],
),
),
actions: <Widget>[
TextButton(
child: Text("Non"),
onPressed: () {
Navigator.pop(context, false);
},
),
TextButton(
child: Text("Oui"),
onPressed: () {
Navigator.pop(context, true);
},
),
],
);
},
);
}
Future<NewWallet> changePin(_name, _oldPin) async {
try {
final _walletFile = Directory('${walletsDirectory.path}/$_name');
final _dewif =
File(_walletFile.path + '/wallet.dewif').readAsLinesSync()[0];
NewWallet newWalletFile = await DubpRust.changeDewifPin(
dewif: _dewif,
oldPin: _oldPin,
);
newPin.text = newWalletFile.pin;
ischangedPin = true;
// notifyListeners();
return newWalletFile;
} catch (e) {
print('Impossible de changer le code PIN.');
return badWallet;
}
}
Future storeWallet(context, _name, _newWalletFile) async {
final Directory walletNameDirectory =
Directory('${walletsDirectory.path}/$_name');
final walletFile = File('${walletNameDirectory.path}/wallet.dewif');
walletFile.writeAsString('${_newWalletFile.dewif}');
Navigator.pop(context);
return _name;
}
}

View File

@ -25,7 +25,6 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
_historyProvider = Provider.of<HistoryProvider>(context); _historyProvider = Provider.of<HistoryProvider>(context);
this._outputPubkey.text = _historyProvider.pubkey; this._outputPubkey.text = _historyProvider.pubkey;
print('Build pubkey : ' + _historyProvider.pubkey); print('Build pubkey : ' + _historyProvider.pubkey);
// scrollController.addListener(scrollListener);
return Scaffold( return Scaffold(
floatingActionButton: Container( floatingActionButton: Container(
height: 80.0, height: 80.0,

View File

@ -9,8 +9,6 @@ import 'package:provider/provider.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class HomeScreen extends StatelessWidget { class HomeScreen extends StatelessWidget {
// HomeProvider _homeProvider = HomeProvider();
var currentTab = [HistoryScreen(), WalletsHome()]; var currentTab = [HistoryScreen(), WalletsHome()];
@override @override
@ -89,8 +87,7 @@ class HomeScreen extends StatelessWidget {
currentIndex: _homeProvider.currentIndex, currentIndex: _homeProvider.currentIndex,
items: [ items: [
BottomNavigationBarItem( BottomNavigationBarItem(
icon: new Icon(Icons icon: new Icon(Icons.format_list_bulleted),
.format_list_bulleted), //Icons.person_add_alt_1_rounded //Icons.lock
label: 'Accueil', label: 'Accueil',
), ),
BottomNavigationBarItem( BottomNavigationBarItem(

View File

@ -1,42 +1,33 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:dubp/dubp.dart'; import 'package:dubp/dubp.dart';
import 'package:gecko/models/walletOptions.dart';
import 'dart:io'; import 'dart:io';
import 'dart:async'; import 'dart:async';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
class ChangePinScreen extends StatefulWidget { // ignore: must_be_immutable
const ChangePinScreen( class ChangePinScreen extends StatelessWidget with ChangeNotifier {
ChangePinScreen(
{Key keyMyWallets, @required this.walletName, @required this.oldPin}) {Key keyMyWallets, @required this.walletName, @required this.oldPin})
: super(key: keyMyWallets); : super(key: keyMyWallets);
final String walletName; final String walletName;
final oldPin; final oldPin;
@override
ChangePinScreenState createState() => ChangePinScreenState();
}
class ChangePinScreenState extends State<ChangePinScreen> {
Directory appPath; Directory appPath;
TextEditingController _newPin = new TextEditingController(); NewWallet _newWalletFile;
bool ischangedPin = false;
NewWallet newWalletFile;
Future<NewWallet> get badWallet => null;
void initState() {
super.initState();
changePin(widget.walletName, widget.oldPin);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
_walletOptions.changePin(walletName, oldPin);
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
appBar: AppBar( appBar: AppBar(
title: SizedBox( title: SizedBox(
height: 22, height: 22,
child: Text(widget.walletName), child: Text(walletName),
)), )),
body: Center( body: Center(
child: SafeArea( child: SafeArea(
@ -57,7 +48,7 @@ class ChangePinScreenState extends State<ChangePinScreen> {
children: <Widget>[ children: <Widget>[
TextField( TextField(
enabled: true, enabled: true,
controller: this._newPin, controller: _walletOptions.newPin,
maxLines: 1, maxLines: 1,
textAlign: TextAlign.center, textAlign: TextAlign.center,
decoration: InputDecoration(), decoration: InputDecoration(),
@ -68,8 +59,9 @@ class ChangePinScreenState extends State<ChangePinScreen> {
IconButton( IconButton(
icon: Icon(Icons.replay), icon: Icon(Icons.replay),
color: Color(0xffD28928), color: Color(0xffD28928),
onPressed: () { onPressed: () async {
changePin(widget.walletName, widget.oldPin); _newWalletFile =
await _walletOptions.changePin(walletName, oldPin);
}, },
), ),
], ],
@ -85,50 +77,10 @@ class ChangePinScreenState extends State<ChangePinScreen> {
primary: Colors.green[400], //Color(0xffFFD68E), // background primary: Colors.green[400], //Color(0xffFFD68E), // background
onPrimary: Colors.black, // foreground onPrimary: Colors.black, // foreground
), ),
onPressed: (ischangedPin) onPressed: () => _walletOptions.storeWallet(
? () => storeWallet(widget.walletName) context, walletName, _newWalletFile),
: null,
child: Text('Confirmer', style: TextStyle(fontSize: 28))), child: Text('Confirmer', style: TextStyle(fontSize: 28))),
) )
])))); ]))));
} }
Future<NewWallet> changePin(_name, _oldPin) async {
try {
final appPath = await _localPath;
final _walletFile = Directory('$appPath/wallets/$_name');
final _dewif =
File(_walletFile.path + '/wallet.dewif').readAsLinesSync()[0];
newWalletFile = await DubpRust.changeDewifPin(
dewif: _dewif,
oldPin: _oldPin,
);
_newPin.text = newWalletFile.pin;
ischangedPin = true;
setState(() {});
return newWalletFile;
} catch (e) {
print('Impossible de changer le code PIN.');
return badWallet;
}
}
Future storeWallet(_name) async {
final appPath = await _localPath;
final Directory walletNameDirectory = Directory('$appPath/wallets/$_name');
final walletFile = File('${walletNameDirectory.path}/wallet.dewif');
walletFile.writeAsString('${this.newWalletFile.dewif}');
Navigator.pop(context);
return _name;
}
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
} }

View File

@ -1,6 +1,8 @@
import 'package:dubp/dubp.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/models/generateWallets.dart'; import 'package:gecko/models/generateWallets.dart';
import 'package:gecko/models/myWallets.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
@ -8,37 +10,42 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
ConfirmStoreWallet({ ConfirmStoreWallet({
Key validationKey, Key validationKey,
@required this.generatedMnemonic, @required this.generatedMnemonic,
@required generatedWallet, @required this.generatedWallet,
}) : super(key: validationKey); }) : super(key: validationKey);
String generatedMnemonic; String generatedMnemonic;
NewWallet generatedWallet;
// @override TextEditingController _mnemonicController = TextEditingController();
// void dispose() { TextEditingController _pubkey = TextEditingController();
// _wordFocus.dispose(); TextEditingController _inputRestoreWord = TextEditingController();
// _walletNameFocus.dispose(); TextEditingController walletName = TextEditingController();
// super.dispose();
// }
TextEditingController _mnemonicController = new TextEditingController();
TextEditingController _pubkey = new TextEditingController();
TextEditingController _inputRestoreWord = new TextEditingController();
TextEditingController walletName = new TextEditingController();
FocusNode _wordFocus = FocusNode(); FocusNode _wordFocus = FocusNode();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var _generateWalletProvider = Provider.of<GenerateWalletsProvider>(context); GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
print("JE BUILD !!!");
this._mnemonicController.text = generatedMnemonic; this._mnemonicController.text = generatedMnemonic;
this._pubkey.text = _generateWalletProvider.generatedWallet.publicKey; this._pubkey.text = generatedWallet.publicKey;
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
appBar: AppBar( appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
Navigator.of(context).pop();
_generateWalletProvider.isAskedWordValid = false;
_generateWalletProvider.askedWordColor = Colors.black;
}),
title: SizedBox( title: SizedBox(
height: 22, height: 22,
child: Text('Confirmez ce portefeuille'), child: Text('Confirmez ce portefeuille'),
)), )),
body: Center( body: Center(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
SizedBox(height: 15), SizedBox(height: 15),
@ -97,12 +104,10 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
), ),
TextFormField( TextFormField(
focusNode: _generateWalletProvider.walletNameFocus, focusNode: _generateWalletProvider.walletNameFocus,
// autofocus: true,
inputFormatters: [ inputFormatters: [
FilteringTextInputFormatter.allow( FilteringTextInputFormatter.allow(
RegExp('[A-Za-z|0-9|\\-|_| ]')), RegExp('[A-Za-z|0-9|\\-|_| ]')),
], ],
// enabled: isAskedWordValid,
controller: this.walletName, controller: this.walletName,
textInputAction: TextInputAction.next, textInputAction: TextInputAction.next,
onChanged: (v) { onChanged: (v) {
@ -130,8 +135,20 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
), ),
onPressed: (_generateWalletProvider.isAskedWordValid && onPressed: (_generateWalletProvider.isAskedWordValid &&
this.walletName.text != '') this.walletName.text != '')
? () => _generateWalletProvider.storeWallet( ? () {
walletName.text, _pubkey.text, context) _generateWalletProvider.storeWallet(
generatedWallet, walletName.text, context);
_generateWalletProvider.isAskedWordValid =
false;
_generateWalletProvider.askedWordColor =
Colors.black;
WidgetsBinding.instance
.addPostFrameCallback((_) {
_myWalletProvider.listWallets =
_myWalletProvider.getAllWalletsNames();
_myWalletProvider.rebuildWidget();
});
}
: null, : null,
child: child:
Text('Confirmer', style: TextStyle(fontSize: 28))), Text('Confirmer', style: TextStyle(fontSize: 28))),

View File

@ -7,8 +7,6 @@ import 'package:super_tooltip/super_tooltip.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class GenerateWalletsScreen extends StatelessWidget { class GenerateWalletsScreen extends StatelessWidget {
SuperTooltip tooltip; SuperTooltip tooltip;
// final formKey = GlobalKey<FormState>();
bool hasError = false; bool hasError = false;
String validPin = 'NO PIN'; String validPin = 'NO PIN';
String currentText = ""; String currentText = "";
@ -16,8 +14,11 @@ class GenerateWalletsScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var _generateWalletProvider = Provider.of<GenerateWalletsProvider>(context); GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
_generateWalletProvider.generateMnemonic(); _generateWalletProvider.generateMnemonic();
print('IS GENERATED ? : ' +
_generateWalletProvider.walletIsGenerated.toString());
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: SizedBox( title: SizedBox(
@ -31,10 +32,6 @@ class GenerateWalletsScreen extends StatelessWidget {
child: FloatingActionButton( child: FloatingActionButton(
heroTag: "buttonGenerateWallet", heroTag: "buttonGenerateWallet",
onPressed: () => _generateWalletProvider.generateMnemonic(), onPressed: () => _generateWalletProvider.generateMnemonic(),
// print(resultScan);
// if (resultScan != 'false') {
// onTabTapped(0);
// }
child: Container( child: Container(
height: 40.0, height: 40.0,
width: 40.0, width: 40.0,
@ -128,7 +125,6 @@ class GenerateWalletsScreen extends StatelessWidget {
), ),
), ),
SizedBox(height: 20), SizedBox(height: 20),
// Expanded(child: Align(alignment: Alignment.bottomCenter)),
new ElevatedButton( new ElevatedButton(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: Color(0xffFFD68E), // background primary: Color(0xffFFD68E), // background
@ -136,28 +132,18 @@ class GenerateWalletsScreen extends StatelessWidget {
), ),
onPressed: _generateWalletProvider.walletIsGenerated onPressed: _generateWalletProvider.walletIsGenerated
? () { ? () {
_generateWalletProvider.nbrWord =
_generateWalletProvider.getRandomInt();
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return ConfirmStoreWallet( return ConfirmStoreWallet(
// validationKey: _keyValidWallets,
generatedMnemonic: generatedMnemonic:
_generateWalletProvider.generatedMnemonic, _generateWalletProvider.generatedMnemonic,
generatedWallet: generatedWallet:
_generateWalletProvider.actualWallet); _generateWalletProvider.actualWallet);
}), }),
) );
// .then((value) => setState(() {
// if (value != null) {
// _pin.clear();
// _mnemonicController.clear();
// _pubkey.clear();
// this.generatedMnemonic = null;
// this.actualWallet = null;
// this.walletIsGenerated = false;
// }
// }))
;
} }
: null, : null,
child: Text('Enregistrer ce portefeuille', child: Text('Enregistrer ce portefeuille',

View File

@ -1,57 +1,54 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:dubp/dubp.dart'; import 'package:dubp/dubp.dart';
import 'package:gecko/models/walletOptions.dart';
import 'package:gecko/ui/myWallets/changePin.dart'; import 'package:gecko/ui/myWallets/changePin.dart';
import 'dart:io'; import 'dart:io';
import 'dart:async'; import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:pin_code_fields/pin_code_fields.dart'; import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:sentry/sentry.dart' as sentry; import 'package:provider/provider.dart';
class WalletOptions extends StatefulWidget { // ignore: must_be_immutable
const WalletOptions({Key keyMyWallets, @required this.walletName}) class WalletOptions extends StatelessWidget with ChangeNotifier {
WalletOptions({Key keyMyWallets, @required this.walletName})
: super(key: keyMyWallets); : super(key: keyMyWallets);
String walletName;
final String walletName;
@override
WalletOptionsState createState() => WalletOptionsState();
}
class WalletOptionsState extends State<WalletOptions> {
StreamController<ErrorAnimationType> errorController; StreamController<ErrorAnimationType> errorController;
Directory appPath; Directory appPath;
TextEditingController _pubkey = new TextEditingController();
TextEditingController _enterPin = new TextEditingController(); TextEditingController _enterPin = new TextEditingController();
TextEditingController _newWalletName = new TextEditingController();
final formKey = GlobalKey<FormState>(); final formKey = GlobalKey<FormState>();
bool hasError = false; bool hasError = false;
String validPin = 'NO PIN'; String validPin = 'NO PIN';
var pinColor = Color(0xffF9F9F1); var pinColor = Color(0xffF9F9F1);
bool isWalletUnlock = false;
var walletPin = ''; var walletPin = '';
Future<NewWallet> get badWallet => null; Future<NewWallet> get badWallet => null;
void initState() {
super.initState();
errorController = StreamController<ErrorAnimationType>();
isWalletUnlock = false;
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
errorController = StreamController<ErrorAnimationType>();
// _walletOptions.isWalletUnlock = false;
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
appBar: AppBar( appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
Navigator.of(context).pop();
_walletOptions.isWalletUnlock = false;
}),
title: SizedBox( title: SizedBox(
height: 22, height: 22,
child: Text(widget.walletName), child: Text(walletName),
)), )),
body: Center( body: Center(
child: SafeArea( child: SafeArea(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
Visibility( Visibility(
visible: isWalletUnlock, visible: _walletOptions.isWalletUnlock,
child: Expanded( child: Expanded(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
SizedBox(height: 15), SizedBox(height: 15),
@ -64,7 +61,7 @@ class WalletOptionsState extends State<WalletOptions> {
), ),
SizedBox(height: 15), SizedBox(height: 15),
Text( Text(
this._pubkey.text, _walletOptions.pubkey.text,
style: TextStyle( style: TextStyle(
fontSize: 14.0, fontSize: 14.0,
color: Colors.black, color: Colors.black,
@ -83,9 +80,10 @@ class WalletOptionsState extends State<WalletOptions> {
0xffFFD68E), //Color(0xffFFD68E), // background 0xffFFD68E), //Color(0xffFFD68E), // background
onPrimary: Colors.black, // foreground onPrimary: Colors.black, // foreground
), ),
onPressed: () => onPressed: () => _walletOptions
_renameWalletAlerte().then((_) { .renameWalletAlerte(context, walletName)
setState(() {}); .then((_) {
notifyListeners();
}), }),
child: Text('Renommer ce portefeuille', child: Text('Renommer ce portefeuille',
style: TextStyle(fontSize: 20)))))), style: TextStyle(fontSize: 20)))))),
@ -106,7 +104,7 @@ class WalletOptionsState extends State<WalletOptions> {
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return ChangePinScreen( return ChangePinScreen(
walletName: widget.walletName, walletName: walletName,
oldPin: this.walletPin); oldPin: this.walletPin);
}), }),
); );
@ -125,7 +123,7 @@ class WalletOptionsState extends State<WalletOptions> {
onPrimary: Colors.black, // foreground onPrimary: Colors.black, // foreground
), ),
onPressed: () { onPressed: () {
_deleteWallet(widget.walletName); _walletOptions.deleteWallet(context, walletName);
}, },
child: Text('Supprimer ce portefeuille', child: Text('Supprimer ce portefeuille',
style: TextStyle(fontSize: 20)))), style: TextStyle(fontSize: 20)))),
@ -140,7 +138,7 @@ class WalletOptionsState extends State<WalletOptions> {
SizedBox(height: 10) SizedBox(height: 10)
]))), ]))),
Visibility( Visibility(
visible: !isWalletUnlock, visible: !_walletOptions.isWalletUnlock,
child: Expanded( child: Expanded(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
SizedBox(height: 80), SizedBox(height: 80),
@ -202,28 +200,26 @@ class WalletOptionsState extends State<WalletOptions> {
onCompleted: (_pin) async { onCompleted: (_pin) async {
print("Completed"); print("Completed");
final resultWallet = final resultWallet =
await _readLocalWallet(_pin.toUpperCase()); await _walletOptions.readLocalWallet(
this.walletName, _pin.toUpperCase());
if (resultWallet == 'bad') { if (resultWallet == 'bad') {
errorController.add(ErrorAnimationType errorController.add(ErrorAnimationType
.shake); // Triggering error shake animation .shake); // Triggering error shake animation
setState(() { hasError = true;
hasError = true; pinColor = Colors.red[200];
pinColor = Colors.red[200]; notifyListeners();
});
} else { } else {
pinColor = Colors.green[200]; pinColor = Colors.green[200];
// setState(() {}); // setState(() {});
// await Future.delayed(Duration(milliseconds: 50)); // await Future.delayed(Duration(milliseconds: 50));
this.walletPin = _pin.toUpperCase(); this.walletPin = _pin.toUpperCase();
isWalletUnlock = true; // isWalletUnlock = true;
setState(() {}); notifyListeners();
} }
}, },
onChanged: (value) { onChanged: (value) {
if (pinColor != Color(0xffF9F9F1)) { if (pinColor != Color(0xffF9F9F1)) {
setState(() { pinColor = Color(0xffF9F9F1);
pinColor = Color(0xffF9F9F1);
});
} }
print(value); print(value);
}, },
@ -232,174 +228,4 @@ class WalletOptionsState extends State<WalletOptions> {
]))), ]))),
])))); ]))));
} }
Future _getPubkeyFromDewif(_dewif, _pin) async {
String _pubkey;
RegExp regExp = new RegExp(
r'^[A-Z0-9]+$',
caseSensitive: false,
multiLine: false,
);
if (regExp.hasMatch(_pin) == true && _pin.length == 6) {
print("Le format du code PIN est correct.");
} else {
print('Format de code PIN invalide');
return 'false';
}
try {
_pubkey = await DubpRust.getDewifPublicKey(dewif: _dewif, pin: _pin);
setState(() {
this._pubkey.text = _pubkey;
});
return _pubkey;
} catch (e, stack) {
print('Bad PIN code !');
print(e);
if (kReleaseMode) {
await sentry.Sentry.captureException(
e,
stackTrace: stack,
);
}
return 'false';
}
}
Future _readLocalWallet(String _pin) async {
// print(pin);
try {
final file = await _localWallet(widget.walletName);
String _localDewif = await file.readAsString();
String _localPubkey;
if ((_localPubkey = await _getPubkeyFromDewif(_localDewif, _pin)) !=
'false') {
setState(() {
this._pubkey.text = _localPubkey;
});
return _localDewif;
} else {
throw 'Bad pubkey';
}
} catch (e) {
print('ERROR READING FILE: $e');
setState(() {
this._pubkey.clear();
});
return 'bad';
}
}
Future _renameWallet(_newName) async {
final appPath = await _localPath;
final _walletFile = Directory('$appPath/wallets/${widget.walletName}');
try {
_walletFile.rename('$appPath/wallets/$_newName');
} catch (e) {
print('ERREUR lors du renommage du wallet: $e');
}
}
Future<bool> _renameWalletAlerte() async {
return showDialog<bool>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Choisissez un nouveau nom pour ce portefeuille'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
TextField(
controller: this._newWalletName,
maxLines: 1,
textAlign: TextAlign.center,
decoration: InputDecoration(),
style: TextStyle(
fontSize: 14.0,
color: Colors.black,
fontWeight: FontWeight.bold)),
],
),
),
actions: <Widget>[
TextButton(
child: Text("Valider"),
onPressed: () {
_renameWallet(this._newWalletName.text);
Navigator.pop(context, true);
},
),
],
);
},
);
}
Future<int> _deleteWallet(_name) async {
try {
final appPath = await _localPath;
final _walletFile = Directory('$appPath/wallets/$_name');
print('DELETE THAT ?: $_walletFile');
final bool _answer = await _confirmDeletingWallet();
if (_answer) {
_walletFile.deleteSync(recursive: true);
Navigator.pop(context);
}
return 0;
} catch (e) {
return 1;
}
}
Future<bool> _confirmDeletingWallet() async {
return showDialog<bool>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text(
'Êtes-vous sûr de vouloir supprimer le portefeuille "${widget.walletName}" ?'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'Vous pourrez restaurer ce portefeuille à tout moment grace à votre phrase de restauration.'),
],
),
),
actions: <Widget>[
TextButton(
child: Text("Non"),
onPressed: () {
Navigator.pop(context, false);
},
),
TextButton(
child: Text("Oui"),
onPressed: () {
Navigator.pop(context, true);
},
),
],
);
},
);
}
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<File> _localWallet(_name) async {
final path = await _localPath;
return File('$path/wallets/$_name/wallet.dewif');
}
} }

View File

@ -2,21 +2,21 @@ import 'package:gecko/models/myWallets.dart';
import 'package:gecko/ui/myWallets/generateWalletsScreen.dart'; import 'package:gecko/ui/myWallets/generateWalletsScreen.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/ui/myWallets/walletOptions.dart'; import 'package:gecko/ui/myWallets/walletOptions.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class WalletsHome extends StatelessWidget { class WalletsHome extends StatelessWidget {
MyWalletsProvider myWalletProvider = MyWalletsProvider();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context);
print('BUILD: WalletsHome'); print('BUILD: WalletsHome');
myWalletProvider.checkIfWalletExist(); myWalletProvider.checkIfWalletExist();
myWalletProvider.listWallets = myWalletProvider.getAllWalletsNames(); myWalletProvider.listWallets = myWalletProvider.getAllWalletsNames();
return Scaffold( return Scaffold(
floatingActionButton: Visibility( floatingActionButton: Visibility(
visible: (myWalletProvider visible: (myWalletProvider.checkIfWalletExist()),
.checkIfWalletExist()), //!checkIfWalletExist('MonWallet') &&
child: Container( child: Container(
height: 80.0, height: 80.0,
width: 80.0, width: 80.0,
@ -84,19 +84,9 @@ class WalletsHome extends StatelessWidget {
]))); ])));
} }
// Future resetWalletState() async {
// final bool _isExist = await checkIfWalletExist('MonWallet');
// print('The wallet exist in resetWalletState(): ' + _isExist.toString());
// // initState();
// // _keyMyWallets.currentState.setState(() {});
// // _keyMyWallets.currentState.initAppDirectory();
// setState(() {
// // getAllWalletsNames();
// // this.walletIsGenerated = true;
// });
// }
myWalletsList(BuildContext context) { myWalletsList(BuildContext context) {
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context);
return Column(children: <Widget>[ return Column(children: <Widget>[
SizedBox(height: 8), SizedBox(height: 8),
for (var repository in myWalletProvider.listWallets) for (var repository in myWalletProvider.listWallets)
@ -111,22 +101,7 @@ class WalletsHome extends StatelessWidget {
return WalletOptions(walletName: repository); return WalletOptions(walletName: repository);
})); }));
}, },
), )
SizedBox(height: 20),
SizedBox(
width: 75.0,
height: 25.0,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 2,
primary: Color(0xffFFD68E), //Color(0xffFFD68E), // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
myWalletProvider.listWallets =
myWalletProvider.getAllWalletsNames();
},
child: Text('(Refresh)', style: TextStyle(fontSize: 10))))
]); ]);
} }
} }

View File

@ -1,21 +1,10 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:dubp/dubp.dart'; import 'package:dubp/dubp.dart';
import 'package:gecko/models/myWallets.dart';
import 'dart:io'; import 'dart:io';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
class SettingsScreen extends StatefulWidget {
const SettingsScreen({Key keyGenWallet}) : super(key: keyGenWallet);
@override
_SettingsScreenState createState() => _SettingsScreenState();
}
class _SettingsScreenState extends State<SettingsScreen> {
void initState() {
super.initState();
}
// ignore: must_be_immutable
class SettingsScreen extends StatelessWidget {
String generatedMnemonic; String generatedMnemonic;
bool walletIsGenerated = false; bool walletIsGenerated = false;
NewWallet actualWallet; NewWallet actualWallet;
@ -27,6 +16,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
var pinColor = Colors.grey[300]; var pinColor = Colors.grey[300];
Directory appPath; Directory appPath;
MyWalletsProvider _myWallets = MyWalletsProvider();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// getAppDirectory(); // getAppDirectory();
@ -53,7 +44,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
), ),
onPressed: () => { onPressed: () => {
print('Suppression de tous les wallets'), print('Suppression de tous les wallets'),
_deleteWallet() _myWallets.deleteAllWallet(context)
}, },
child: Text( child: Text(
"EFFACER TOUS MES PORTEFEUILLES, LE TEMPS DE L'ALPHA", "EFFACER TOUS MES PORTEFEUILLES, LE TEMPS DE L'ALPHA",
@ -61,56 +52,4 @@ class _SettingsScreenState extends State<SettingsScreen> {
SizedBox(height: 50), SizedBox(height: 50),
])); ]));
} }
Future<int> _deleteWallet() async {
try {
final appPath = await _localPath;
final _walletsFolder = Directory('$appPath/wallets');
print('DELETE THAT ?: $_walletsFolder');
final bool _answer = await _confirmDeletingWallets();
if (_answer) {
_walletsFolder.deleteSync(recursive: true);
_walletsFolder.createSync();
Navigator.pop(context);
}
return 0;
} catch (e) {
return 1;
}
}
Future<bool> _confirmDeletingWallets() async {
return showDialog<bool>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text(
'Êtes-vous sûr de vouloir supprimer tous vos portefeuilles ?'),
content: SingleChildScrollView(child: Text('')),
actions: <Widget>[
TextButton(
child: Text("Non"),
onPressed: () {
Navigator.pop(context, false);
},
),
TextButton(
child: Text("Oui"),
onPressed: () {
Navigator.pop(context, true);
},
),
],
);
},
);
}
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
} }