HQ Wallet workflow is complete
This commit is contained in:
parent
5ec6b715b0
commit
f430facfb5
|
@ -6,7 +6,7 @@ import 'package:gecko/globals.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class MyWalletsProvider with ChangeNotifier {
|
class MyWalletsProvider with ChangeNotifier {
|
||||||
Map listWallets = Map();
|
String listWallets;
|
||||||
|
|
||||||
bool checkIfWalletExist() {
|
bool checkIfWalletExist() {
|
||||||
if (appPath == null) {
|
if (appPath == null) {
|
||||||
|
@ -25,19 +25,28 @@ class MyWalletsProvider with ChangeNotifier {
|
||||||
|
|
||||||
Future importWallet() async {}
|
Future importWallet() async {}
|
||||||
|
|
||||||
Map getAllWalletsNames() {
|
String getAllWalletsNames() {
|
||||||
if (listWallets.isNotEmpty) {
|
if (listWallets != null && listWallets.isNotEmpty) {
|
||||||
listWallets.clear();
|
listWallets = '';
|
||||||
|
}
|
||||||
|
if (listWallets == null) {
|
||||||
|
listWallets = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// int i = 0;
|
// int i = 0;
|
||||||
walletsDirectory
|
walletsDirectory
|
||||||
.listSync(recursive: false, followLinks: false)
|
.listSync(recursive: false, followLinks: false)
|
||||||
.forEach((_wallet) {
|
.forEach((_wallet) {
|
||||||
File('${_wallet.path}/config.txt').readAsLinesSync().forEach((element) {
|
File _walletConfig = File('${_wallet.path}/config.txt');
|
||||||
listWallets[int.parse(element.split(':')[0])] = element.split(':')[1];
|
_walletConfig.readAsLinesSync().forEach((element) {
|
||||||
|
if (listWallets != '') {
|
||||||
|
listWallets += '\n';
|
||||||
|
}
|
||||||
|
listWallets +=
|
||||||
|
"${element.split(':')[0]}:${element.split(':')[1]}:${element.split(':')[2]}";
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return listWallets;
|
return listWallets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +102,26 @@ class MyWalletsProvider with ChangeNotifier {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> generateNewDerivation(
|
||||||
|
context, String _name, int _walletNbr) async {
|
||||||
|
final _walletConfig =
|
||||||
|
File('${walletsDirectory.path}/$_walletNbr/config.txt');
|
||||||
|
|
||||||
|
String _lastWallet =
|
||||||
|
await _walletConfig.readAsLines().then((value) => value.last);
|
||||||
|
int _lastDerivation = int.parse(_lastWallet.split(':')[2]);
|
||||||
|
// print(_lastDerivation);
|
||||||
|
int _newDerivationNbr = _lastDerivation + 3;
|
||||||
|
|
||||||
|
await _walletConfig.writeAsString('\n$_walletNbr:$_name:$_newDerivationNbr',
|
||||||
|
mode: FileMode.append);
|
||||||
|
|
||||||
|
print(await _walletConfig.readAsString());
|
||||||
|
notifyListeners();
|
||||||
|
|
||||||
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
|
|
||||||
void rebuildWidget() {
|
void rebuildWidget() {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
|
|
||||||
Future<NewWallet> get badWallet => null;
|
Future<NewWallet> get badWallet => null;
|
||||||
|
|
||||||
Future _getPubkeyFromDewif(_dewif, _pin, _pinLenght, {derivation}) async {
|
Future _getPubkeyFromDewif(
|
||||||
|
String _dewif, _pin, int _pinLenght, int derivation) async {
|
||||||
String _pubkey;
|
String _pubkey;
|
||||||
RegExp regExp = new RegExp(
|
RegExp regExp = new RegExp(
|
||||||
r'^[A-Z0-9]+$',
|
r'^[A-Z0-9]+$',
|
||||||
|
@ -31,7 +32,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
List _pubkeysTmp = await DubpRust.getBip32DewifAccountsPublicKeys(
|
List _pubkeysTmp = await DubpRust.getBip32DewifAccountsPublicKeys(
|
||||||
dewif: _dewif, secretCode: _pin, accountsIndex: [3]);
|
dewif: _dewif, secretCode: _pin, accountsIndex: [derivation]);
|
||||||
_pubkey = _pubkeysTmp[0];
|
_pubkey = _pubkeysTmp[0];
|
||||||
this.pubkey.text = _pubkey;
|
this.pubkey.text = _pubkey;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
@ -52,8 +53,8 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future readLocalWallet(
|
Future readLocalWallet(int _walletNbr, String _name, String _pin,
|
||||||
int _walletNbr, String _name, String _pin, _pinLenght) async {
|
int _pinLenght, int derivation) async {
|
||||||
isWalletUnlock = false;
|
isWalletUnlock = false;
|
||||||
try {
|
try {
|
||||||
File _walletFile =
|
File _walletFile =
|
||||||
|
@ -61,16 +62,12 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
String _localDewif = await _walletFile.readAsString();
|
String _localDewif = await _walletFile.readAsString();
|
||||||
String _localPubkey;
|
String _localPubkey;
|
||||||
|
|
||||||
if ((_localPubkey =
|
if ((_localPubkey = await _getPubkeyFromDewif(
|
||||||
await _getPubkeyFromDewif(_localDewif, _pin, _pinLenght)) !=
|
_localDewif, _pin, _pinLenght, derivation)) !=
|
||||||
'false') {
|
'false') {
|
||||||
this.pubkey.text = _localPubkey;
|
this.pubkey.text = _localPubkey;
|
||||||
isWalletUnlock = true;
|
isWalletUnlock = true;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
print('GET BIP32 accounts publickeys from this dewif');
|
|
||||||
List _hdWallets = await DubpRust.getBip32DewifAccountsPublicKeys(
|
|
||||||
dewif: _localDewif, secretCode: _pin, accountsIndex: [0, 1, 2]);
|
|
||||||
print(_hdWallets);
|
|
||||||
|
|
||||||
return _localDewif;
|
return _localDewif;
|
||||||
} else {
|
} else {
|
||||||
|
@ -94,17 +91,27 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
return _pinLenght;
|
return _pinLenght;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _renameWallet(_walletName, _newName) async {
|
Future _renameWallet(_walletName, _newName, _walletNbr, _derivation) async {
|
||||||
final _walletFile = Directory('${walletsDirectory.path}/$_walletName');
|
final _walletConfig =
|
||||||
|
File('${walletsDirectory.path}/$_walletNbr/config.txt');
|
||||||
|
|
||||||
try {
|
String newConfig =
|
||||||
_walletFile.rename('${walletsDirectory.path}/$_newName');
|
await _walletConfig.readAsLines().then((List<String> lines) {
|
||||||
} catch (e) {
|
int _index = lines.indexOf('$_walletNbr:$_walletName:$_derivation');
|
||||||
print('ERREUR lors du renommage du wallet: $e');
|
lines.removeWhere(
|
||||||
}
|
(element) => element == '$_walletNbr:$_walletName:$_derivation');
|
||||||
|
lines.insert(_index, '$_walletNbr:$_newName:$_derivation');
|
||||||
|
|
||||||
|
return lines.join('\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
await _walletConfig.delete();
|
||||||
|
await _walletConfig.writeAsString(newConfig);
|
||||||
|
_newWalletName.text = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> renameWalletAlerte(context, _walletName) async {
|
Future<bool> renameWalletAlerte(
|
||||||
|
context, _walletName, _walletNbr, _derivation) async {
|
||||||
return showDialog<bool>(
|
return showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: true, // user must tap button!
|
barrierDismissible: true, // user must tap button!
|
||||||
|
@ -130,12 +137,12 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text("Valider"),
|
child: Text("Valider"),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
_renameWallet(_walletName, this._newWalletName.text);
|
await _renameWallet(_walletName, this._newWalletName.text,
|
||||||
|
_walletNbr, _derivation);
|
||||||
});
|
});
|
||||||
// notifyListeners();
|
// notifyListeners();
|
||||||
Navigator.pop(context, true);
|
Navigator.pop(context, true);
|
||||||
Navigator.pop(context, true);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -144,21 +151,26 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> deleteWallet(context, _name) async {
|
Future<int> deleteWallet(context, _walletNbr, _name, _derivation) async {
|
||||||
try {
|
final bool _answer = await _confirmDeletingWallet(context, _name);
|
||||||
final _walletFile = Directory('${walletsDirectory.path}/$_name');
|
|
||||||
print('DELETE THAT ?: $_walletFile');
|
|
||||||
|
|
||||||
final bool _answer = await _confirmDeletingWallet(context, _name);
|
if (_answer) {
|
||||||
|
final _walletConfig =
|
||||||
|
File('${walletsDirectory.path}/$_walletNbr/config.txt');
|
||||||
|
|
||||||
if (_answer) {
|
String newConfig =
|
||||||
await _walletFile.delete(recursive: true);
|
await _walletConfig.readAsLines().then((List<String> lines) {
|
||||||
Navigator.pop(context);
|
lines.removeWhere(
|
||||||
}
|
(element) => element == '$_walletNbr:$_name:$_derivation');
|
||||||
return 0;
|
|
||||||
} catch (e) {
|
return lines.join('\n');
|
||||||
return 1;
|
});
|
||||||
|
|
||||||
|
await _walletConfig.delete();
|
||||||
|
await _walletConfig.writeAsString(newConfig);
|
||||||
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _confirmDeletingWallet(context, _walletName) async {
|
Future<bool> _confirmDeletingWallet(context, _walletName) async {
|
||||||
|
@ -172,8 +184,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
content: SingleChildScrollView(
|
content: SingleChildScrollView(
|
||||||
child: ListBody(
|
child: ListBody(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text('Vous pourrez restaurer ce portefeuille plus tard.'),
|
||||||
'Vous pourrez restaurer ce portefeuille à tout moment grace à votre phrase de restauration.'),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -128,7 +128,8 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
|
||||||
await _generateWalletProvider.storeWallet(
|
await _generateWalletProvider.storeWallet(
|
||||||
generatedWallet,
|
generatedWallet,
|
||||||
walletName.text,
|
walletName.text,
|
||||||
context);
|
context,
|
||||||
|
isHD: true);
|
||||||
_generateWalletProvider.isAskedWordValid =
|
_generateWalletProvider.isAskedWordValid =
|
||||||
false;
|
false;
|
||||||
_generateWalletProvider.askedWordColor =
|
_generateWalletProvider.askedWordColor =
|
||||||
|
|
|
@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:dubp/dubp.dart';
|
import 'package:dubp/dubp.dart';
|
||||||
import 'package:gecko/models/myWallets.dart';
|
import 'package:gecko/models/myWallets.dart';
|
||||||
import 'package:gecko/models/walletOptions.dart';
|
import 'package:gecko/models/walletOptions.dart';
|
||||||
import 'package:gecko/screens/myWallets/changePin.dart';
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
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';
|
||||||
|
@ -12,10 +11,14 @@ import 'package:flutter/services.dart';
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class WalletOptions extends StatelessWidget with ChangeNotifier {
|
class WalletOptions extends StatelessWidget with ChangeNotifier {
|
||||||
WalletOptions(
|
WalletOptions(
|
||||||
{Key keyMyWallets, @required this.walletNbr, @required this.walletName})
|
{Key keyMyWallets,
|
||||||
|
@required this.walletNbr,
|
||||||
|
@required this.walletName,
|
||||||
|
@required this.derivation})
|
||||||
: super(key: keyMyWallets);
|
: super(key: keyMyWallets);
|
||||||
int walletNbr;
|
int walletNbr;
|
||||||
String walletName;
|
String walletName;
|
||||||
|
int derivation;
|
||||||
|
|
||||||
StreamController<ErrorAnimationType> errorController;
|
StreamController<ErrorAnimationType> errorController;
|
||||||
TextEditingController _enterPin = TextEditingController();
|
TextEditingController _enterPin = TextEditingController();
|
||||||
|
@ -102,7 +105,10 @@ class WalletOptions extends StatelessWidget with ChangeNotifier {
|
||||||
),
|
),
|
||||||
onPressed: () => _walletOptions
|
onPressed: () => _walletOptions
|
||||||
.renameWalletAlerte(
|
.renameWalletAlerte(
|
||||||
context, walletName)
|
context,
|
||||||
|
walletName,
|
||||||
|
walletNbr,
|
||||||
|
derivation)
|
||||||
.then((_result) {
|
.then((_result) {
|
||||||
if (_result == true) {
|
if (_result == true) {
|
||||||
WidgetsBinding.instance
|
WidgetsBinding.instance
|
||||||
|
@ -115,6 +121,8 @@ class WalletOptions extends StatelessWidget with ChangeNotifier {
|
||||||
_myWalletProvider
|
_myWalletProvider
|
||||||
.rebuildWidget();
|
.rebuildWidget();
|
||||||
});
|
});
|
||||||
|
Navigator.pop(
|
||||||
|
context, true);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
child: Text(
|
child: Text(
|
||||||
|
@ -122,30 +130,6 @@ class WalletOptions extends StatelessWidget with ChangeNotifier {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20)))))),
|
fontSize: 20)))))),
|
||||||
SizedBox(height: 30),
|
SizedBox(height: 30),
|
||||||
SizedBox(
|
|
||||||
height: 50,
|
|
||||||
width: 300,
|
|
||||||
child: ElevatedButton(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
elevation: 5,
|
|
||||||
primary: Color(
|
|
||||||
0xffFFD68E), //Color(0xffFFD68E), // background
|
|
||||||
onPrimary: Colors.black, // foreground
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
// changePin(widget.walletName, this.walletPin);
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return ChangePinScreen(
|
|
||||||
walletName: walletName,
|
|
||||||
oldPin: this.walletPin);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: Text('Changer mon code secret',
|
|
||||||
style: TextStyle(fontSize: 20)))),
|
|
||||||
SizedBox(height: 30),
|
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 50,
|
height: 50,
|
||||||
width: 300,
|
width: 300,
|
||||||
|
@ -157,8 +141,8 @@ class WalletOptions extends StatelessWidget with ChangeNotifier {
|
||||||
onPrimary: Colors.black, // foreground
|
onPrimary: Colors.black, // foreground
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await _walletOptions.deleteWallet(
|
await _walletOptions.deleteWallet(context,
|
||||||
context, walletName);
|
walletNbr, walletName, derivation);
|
||||||
WidgetsBinding.instance
|
WidgetsBinding.instance
|
||||||
.addPostFrameCallback((_) {
|
.addPostFrameCallback((_) {
|
||||||
_myWalletProvider.listWallets =
|
_myWalletProvider.listWallets =
|
||||||
|
@ -249,7 +233,8 @@ class WalletOptions extends StatelessWidget with ChangeNotifier {
|
||||||
this.walletNbr,
|
this.walletNbr,
|
||||||
this.walletName,
|
this.walletName,
|
||||||
_pin.toUpperCase(),
|
_pin.toUpperCase(),
|
||||||
_pinLenght);
|
_pinLenght,
|
||||||
|
this.derivation);
|
||||||
if (resultWallet == 'bad') {
|
if (resultWallet == 'bad') {
|
||||||
errorController.add(ErrorAnimationType
|
errorController.add(ErrorAnimationType
|
||||||
.shake); // Triggering error shake animation
|
.shake); // Triggering error shake animation
|
||||||
|
|
|
@ -7,6 +7,9 @@ import 'package:provider/provider.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class WalletsHome extends StatelessWidget {
|
class WalletsHome extends StatelessWidget {
|
||||||
|
final _derivationKey = GlobalKey<FormState>();
|
||||||
|
final TextEditingController _newDerivationName = TextEditingController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
MyWalletsProvider myWalletProvider =
|
MyWalletsProvider myWalletProvider =
|
||||||
|
@ -27,12 +30,11 @@ class WalletsHome extends StatelessWidget {
|
||||||
child: FloatingActionButton(
|
child: FloatingActionButton(
|
||||||
heroTag: "buttonGenerateWallet",
|
heroTag: "buttonGenerateWallet",
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.push(
|
showDialog(
|
||||||
context,
|
context: context,
|
||||||
MaterialPageRoute(builder: (context) {
|
builder: (BuildContext context) {
|
||||||
return GenerateWalletsScreen();
|
return addNewDerivation(context, 1);
|
||||||
}),
|
});
|
||||||
);
|
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 40.0,
|
height: 40.0,
|
||||||
|
@ -89,10 +91,7 @@ class WalletsHome extends StatelessWidget {
|
||||||
MyWalletsProvider myWalletProvider =
|
MyWalletsProvider myWalletProvider =
|
||||||
Provider.of<MyWalletsProvider>(context);
|
Provider.of<MyWalletsProvider>(context);
|
||||||
|
|
||||||
List _listWallets = [];
|
List _listWallets = myWalletProvider.listWallets.split('\n');
|
||||||
myWalletProvider.listWallets.forEach((_nbr, _name) {
|
|
||||||
_listWallets.add('$_nbr:$_name');
|
|
||||||
});
|
|
||||||
|
|
||||||
return Column(children: <Widget>[
|
return Column(children: <Widget>[
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
|
@ -109,10 +108,54 @@ class WalletsHome extends StatelessWidget {
|
||||||
Navigator.push(context, MaterialPageRoute(builder: (context) {
|
Navigator.push(context, MaterialPageRoute(builder: (context) {
|
||||||
return WalletOptions(
|
return WalletOptions(
|
||||||
walletNbr: int.parse(_repository.split(':')[0]),
|
walletNbr: int.parse(_repository.split(':')[0]),
|
||||||
walletName: _repository.split(':')[1]);
|
walletName: _repository.split(':')[1],
|
||||||
|
derivation: int.parse(_repository.split(':')[2]));
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget addNewDerivation(context, int _walletNbr) {
|
||||||
|
MyWalletsProvider _myWalletProvider =
|
||||||
|
Provider.of<MyWalletsProvider>(context);
|
||||||
|
return AlertDialog(
|
||||||
|
content: Stack(
|
||||||
|
overflow: Overflow.visible,
|
||||||
|
children: <Widget>[
|
||||||
|
Form(
|
||||||
|
key: _derivationKey,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
Text('Nom du portefeuille:'),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: TextFormField(
|
||||||
|
controller: _newDerivationName,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
autofocus: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: RaisedButton(
|
||||||
|
child: Text("Créer"),
|
||||||
|
color: Color(0xffFFD68E),
|
||||||
|
onPressed: () async {
|
||||||
|
await _myWalletProvider
|
||||||
|
.generateNewDerivation(
|
||||||
|
context, _newDerivationName.text, _walletNbr)
|
||||||
|
.then((_) => _newDerivationName.text == '');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue