Add button for renew PIN; Add tooltips on walletGeneration page; WIP: Use custom wallet name

This commit is contained in:
poka 2021-01-13 05:36:23 +01:00
parent a2698a244b
commit a8427f5b9d
6 changed files with 220 additions and 71 deletions

View File

@ -1,4 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'dart:math';
import 'package:dubp/dubp.dart'; import 'package:dubp/dubp.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
@ -24,30 +25,34 @@ class ConfirmStoreWalletState extends State<ConfirmStoreWallet> {
// DubpRust.setup(); // DubpRust.setup();
this._mnemonicController.text = widget.generatedMnemonic; this._mnemonicController.text = widget.generatedMnemonic;
this._pubkey.text = widget.generatedWallet.publicKey; this._pubkey.text = widget.generatedWallet.publicKey;
nbrWord = getRandomInt();
} }
TextEditingController _mnemonicController = new TextEditingController(); TextEditingController _mnemonicController = new TextEditingController();
TextEditingController _pubkey = new TextEditingController(); TextEditingController _pubkey = new TextEditingController();
TextEditingController _pin = new TextEditingController(); TextEditingController _pin = new TextEditingController();
String walletName = 'MonWallet'; TextEditingController _inputRestoreWord = new TextEditingController();
List _listWallets = []; TextEditingController walletName = new TextEditingController();
// List _listWallets = [];
int nbrWord;
bool isAskedWordValid = false;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(), appBar: AppBar(),
body: Center( body: Center(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
TextField( SizedBox(height: 15),
enabled: false, Text(
controller: this._mnemonicController, 'Votre clé publique est :',
maxLines: 2, textAlign: TextAlign.center,
textAlign: TextAlign.center, style: TextStyle(
decoration: InputDecoration(), fontSize: 17.0,
style: TextStyle( color: Colors.grey[600],
fontSize: 15.0, fontWeight: FontWeight.w400),
color: Colors.black, ),
fontWeight: FontWeight.bold)),
TextField( TextField(
enabled: false, enabled: false,
controller: this._pubkey, controller: this._pubkey,
@ -58,13 +63,76 @@ class ConfirmStoreWalletState extends State<ConfirmStoreWallet> {
fontSize: 14.0, fontSize: 14.0,
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.bold)), fontWeight: FontWeight.bold)),
new ElevatedButton( SizedBox(height: 12),
style: ElevatedButton.styleFrom( Text(
primary: Color(0xffFFD68E), // background 'Quel est le ${nbrWord + 1}ème mot de votre phrase de restauration ?',
onPrimary: Colors.black, // foreground textAlign: TextAlign.center,
), style: TextStyle(
onPressed: () => storeWallet(), fontSize: 17.0,
child: Text('Confirmer', style: TextStyle(fontSize: 20))), color: Colors.grey[600],
fontWeight: FontWeight.w400),
),
TextField(
enabled: !isAskedWordValid,
controller: this._inputRestoreWord,
onChanged: (value) {
checkAskedWord(value);
},
maxLines: 2,
textAlign: TextAlign.center,
decoration: InputDecoration(),
style: TextStyle(
fontSize: 30.0,
color: Colors.black,
fontWeight: FontWeight.w500)),
SizedBox(height: 12),
Text(
'Choisissez un nom pour votre portefeuille :',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 17.0,
color: Colors.grey[600],
fontWeight: FontWeight.w400),
),
TextField(
enabled: isAskedWordValid,
controller: this.walletName,
onChanged: (v) {
nameChanged();
},
maxLines: 2,
textAlign: TextAlign.center,
decoration: InputDecoration(),
style: TextStyle(
fontSize: 30.0,
color: Colors.black,
fontWeight: FontWeight.w500)),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: 200,
height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 12,
primary: Colors
.green[400], //Color(0xffFFD68E), // background
onPrimary: Colors.black, // foreground
),
onPressed:
(isAskedWordValid && this.walletName.text != '')
? () => storeWallet()
: null,
child:
Text('Confirmer', style: TextStyle(fontSize: 28))),
))),
SizedBox(height: 70),
Text('TRICHE PENDANT ALPHA: ' + this._mnemonicController.text,
style: TextStyle(
fontSize: 10.0,
color: Colors.black,
fontWeight: FontWeight.normal)),
]), ]),
), ),
); );
@ -72,24 +140,27 @@ class ConfirmStoreWalletState extends State<ConfirmStoreWallet> {
Future storeWallet() async { Future storeWallet() async {
final appPath = await _localPath; final appPath = await _localPath;
final walletFile = File('$appPath/wallets/${this.walletName}/wallet.dewif'); final walletFile =
// File('$appPath/wallets/${this.walletName.text}/wallet.dewif');
File('$appPath/wallets/MonWallet/wallet.dewif');
// TODO: Use custom wallet name for storage
final isExist = await Directory('$appPath/wallets').exists(); final isExist = await Directory('$appPath/wallets').exists();
if (isExist == false) { if (isExist == false) {
new Directory('$appPath/wallets').createSync(); new Directory('$appPath/wallets').createSync();
} }
new Directory('$appPath/wallets/${this.walletName}').createSync(); new Directory('$appPath/wallets/${this.walletName.text}').createSync();
walletFile.writeAsString('${widget.generatedWallet.dewif}'); walletFile.writeAsString('${widget.generatedWallet.dewif}');
_pin.clear(); _pin.clear();
await getAllWalletsNames(); // await getAllWalletsNames();
Navigator.pop(context, true);
Navigator.pop(context, true); Navigator.pop(context, true);
Navigator.pop(context, this._pubkey.text);
// setState(() {}); // setState(() {});
// FocusScope.of(context).unfocus(); // FocusScope.of(context).unfocus();
return this.walletName; return this.walletName.text;
} }
Future<String> get _localPath async { Future<String> get _localPath async {
@ -97,21 +168,42 @@ class ConfirmStoreWalletState extends State<ConfirmStoreWallet> {
return directory.path; return directory.path;
} }
Future<List> getAllWalletsNames() async { // Future<List> getAllWalletsNames() async {
final _appPath = await getApplicationDocumentsDirectory(); // final _appPath = await getApplicationDocumentsDirectory();
// List _listWallets = []; // // List _listWallets = [];
// _listWallets.add('tortuuue'); // // _listWallets.add('tortuuue');
this._listWallets.clear(); // this._listWallets.clear();
print(_appPath); // print(_appPath);
_appPath // _appPath
.list(recursive: false, followLinks: false) // .list(recursive: false, followLinks: false)
.listen((FileSystemEntity entity) { // .listen((FileSystemEntity entity) {
print(entity.path.split('/').last); // print(entity.path.split('/').last);
this._listWallets.add(entity.path.split('/').last); // this._listWallets.add(entity.path.split('/').last);
}); // });
return _listWallets; // return _listWallets;
// final _local = await _appPath.path.list().toList(); // // final _local = await _appPath.path.list().toList();
// }
void checkAskedWord(value) {
print(this._mnemonicController.text.split(' ')[nbrWord]);
print(value);
if (this._mnemonicController.text.split(' ')[nbrWord] == value) {
print('Word is OK');
isAskedWordValid = true;
} else {
isAskedWordValid = false;
}
setState(() {});
}
int getRandomInt() {
var rng = new Random();
return rng.nextInt(12);
}
void nameChanged() {
setState(() {});
} }
} }

View File

@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:sentry/sentry.dart' as sentry; import 'package:sentry/sentry.dart' as sentry;
import 'package:dubp/dubp.dart'; import 'package:dubp/dubp.dart';
import 'package:super_tooltip/super_tooltip.dart';
class GenerateWalletsScreen extends StatefulWidget { class GenerateWalletsScreen extends StatefulWidget {
const GenerateWalletsScreen({Key keyGenWallet}) : super(key: keyGenWallet); const GenerateWalletsScreen({Key keyGenWallet}) : super(key: keyGenWallet);
@ -25,6 +26,7 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
String generatedMnemonic; String generatedMnemonic;
bool walletIsGenerated = false; bool walletIsGenerated = false;
NewWallet actualWallet; NewWallet actualWallet;
SuperTooltip tooltip;
// final formKey = GlobalKey<FormState>(); // final formKey = GlobalKey<FormState>();
bool hasError = false; bool hasError = false;
@ -55,12 +57,16 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
body: SafeArea( body: SafeArea(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
SizedBox(height: 20), SizedBox(height: 20),
Text( Tooltip(
'Clé publique:', message:
style: TextStyle( "C'est votre RIB en Ğ1, les gens l'utiliseront pour vous payer",
fontSize: 15.0, child: Text(
color: Colors.grey[600], 'Clé publique:',
fontWeight: FontWeight.w400), style: TextStyle(
fontSize: 15.0,
color: Colors.grey[600],
fontWeight: FontWeight.w400),
),
), ),
TextField( TextField(
enabled: false, enabled: false,
@ -73,12 +79,16 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.bold)), fontWeight: FontWeight.bold)),
SizedBox(height: 8), SizedBox(height: 8),
Text( Tooltip(
'Phrase de restauration:', message:
style: TextStyle( "Notez et gardez cette phrase précieusement sur un papier, elle vous servira à restaurer votre portefeuille sur un autre appareil",
fontSize: 15.0, child: Text(
color: Colors.grey[600], 'Phrase de restauration:',
fontWeight: FontWeight.w400), style: TextStyle(
fontSize: 15.0,
color: Colors.grey[600],
fontWeight: FontWeight.w400),
),
), ),
TextField( TextField(
enabled: false, enabled: false,
@ -93,23 +103,41 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.w400)), fontWeight: FontWeight.w400)),
SizedBox(height: 8), SizedBox(height: 8),
Text( Tooltip(
'Code secret:', message:
style: TextStyle( "Retenez bien votre code secret, il vous sera demandé à chaque paiement, ainsi que pour configurer votre portefeuille",
fontSize: 15.0, child: Text(
color: Colors.grey[600], 'Code secret:',
fontWeight: FontWeight.w400),
),
TextField(
enabled: false,
controller: this._pin,
maxLines: 1,
textAlign: TextAlign.center,
decoration: InputDecoration(),
style: TextStyle( style: TextStyle(
fontSize: 30.0, fontSize: 15.0,
color: Colors.black, color: Colors.grey[600],
fontWeight: FontWeight.bold)), fontWeight: FontWeight.w400),
),
),
Container(
child: Stack(
alignment: Alignment.centerRight,
children: <Widget>[
TextField(
enabled: false,
controller: this._pin,
maxLines: 1,
textAlign: TextAlign.center,
decoration: InputDecoration(),
style: TextStyle(
fontSize: 30.0,
color: Colors.black,
fontWeight: FontWeight.bold)),
IconButton(
icon: Icon(Icons.replay),
color: Color(0xffD28928),
onPressed: () {
changePinCode();
},
),
],
),
),
SizedBox(height: 20), SizedBox(height: 20),
// Expanded(child: Align(alignment: Alignment.bottomCenter)), // Expanded(child: Align(alignment: Alignment.bottomCenter)),
new ElevatedButton( new ElevatedButton(
@ -148,7 +176,7 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
)); ));
} }
Future generateMnemonic() async { Future<String> generateMnemonic() async {
try { try {
this.generatedMnemonic = this.generatedMnemonic =
await DubpRust.genMnemonic(language: Language.french); await DubpRust.genMnemonic(language: Language.french);
@ -167,7 +195,7 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
return this.generatedMnemonic; return this.generatedMnemonic;
} }
Future generateWallet(generatedMnemonic) async { Future<NewWallet> generateWallet(generatedMnemonic) async {
try { try {
this.actualWallet = await DubpRust.genWalletFromMnemonic( this.actualWallet = await DubpRust.genWalletFromMnemonic(
language: Language.french, language: Language.french,
@ -191,4 +219,15 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
return actualWallet; return actualWallet;
} }
Future<void> changePinCode() async {
this.actualWallet = await DubpRust.changeDewifPin(
dewif: this.actualWallet.dewif,
oldPin: this.actualWallet.pin,
);
setState(() {
this._pin.text = actualWallet.pin;
});
}
} }

View File

@ -218,6 +218,8 @@ class MyWalletState extends State<MyWalletsScreen> {
this._listWallets.add(entity.path.split('/').last); this._listWallets.add(entity.path.split('/').last);
}); });
print('Mes wallets: ');
print(_listWallets);
return _listWallets; return _listWallets;
// final _local = await _appPath.path.list().toList(); // final _local = await _appPath.path.list().toList();
@ -236,7 +238,7 @@ class MyWalletState extends State<MyWalletsScreen> {
Future readLocalWallet(String _pin) async { Future readLocalWallet(String _pin) async {
// print(pin); // print(pin);
try { try {
final file = await _localWallet('MonWallet'); final file = await _localWallet('this.walletName');
String _localDewif = await file.readAsString(); String _localDewif = await file.readAsString();
String _localPubkey; String _localPubkey;

View File

@ -28,6 +28,7 @@ class WalletsHomeState extends State<WalletsHome> {
String generatedMnemonic; String generatedMnemonic;
bool walletIsGenerated = false; bool walletIsGenerated = false;
NewWallet actualWallet; NewWallet actualWallet;
String newWalletName;
bool hasError = false; bool hasError = false;
String validPin = 'NO PIN'; String validPin = 'NO PIN';
@ -54,7 +55,10 @@ class WalletsHomeState extends State<WalletsHome> {
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return GenerateWalletsScreen(); return GenerateWalletsScreen();
}), }),
); ).then((value) => setState(() {
this.newWalletName = value;
checkIfWalletExist(value);
}));
}, },
child: Container( child: Container(
height: 40.0, height: 40.0,
@ -83,7 +87,10 @@ class WalletsHomeState extends State<WalletsHome> {
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return GenerateWalletsScreen(); return GenerateWalletsScreen();
}), }),
), ).then((value) => setState(() {
this.newWalletName = value;
checkIfWalletExist(value);
})),
child: Text('Générer un portefeuille', child: Text('Générer un portefeuille',
style: TextStyle(fontSize: 20))), style: TextStyle(fontSize: 20))),
SizedBox(height: 15), SizedBox(height: 15),
@ -121,6 +128,7 @@ class WalletsHomeState extends State<WalletsHome> {
// } // }
bool checkIfWalletExist(_name) { bool checkIfWalletExist(_name) {
print('Nom du wallet: ' + _name);
if (this.appPath == null) { if (this.appPath == null) {
return false; return false;
} }

View File

@ -490,6 +490,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0-nullsafety.3" version: "1.1.0-nullsafety.3"
super_tooltip:
dependency: "direct main"
description:
name: super_tooltip
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.6"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:

View File

@ -27,6 +27,7 @@ dependencies:
path_provider: ^1.6.24 path_provider: ^1.6.24
pin_code_fields: ^6.0.2 pin_code_fields: ^6.0.2
http: ^0.12.2 http: ^0.12.2
super_tooltip: ^0.9.6
flutter_icons: flutter_icons: