diff --git a/lib/models/myWallets.dart b/lib/models/myWallets.dart index c4bc26d..f1d1faa 100644 --- a/lib/models/myWallets.dart +++ b/lib/models/myWallets.dart @@ -6,7 +6,7 @@ import 'package:gecko/globals.dart'; import 'package:provider/provider.dart'; class MyWalletsProvider with ChangeNotifier { - Map listWallets = Map(); + String listWallets; bool checkIfWalletExist() { if (appPath == null) { @@ -25,19 +25,28 @@ class MyWalletsProvider with ChangeNotifier { Future importWallet() async {} - Map getAllWalletsNames() { - if (listWallets.isNotEmpty) { - listWallets.clear(); + String getAllWalletsNames() { + if (listWallets != null && listWallets.isNotEmpty) { + listWallets = ''; + } + if (listWallets == null) { + listWallets = ''; } // int i = 0; walletsDirectory .listSync(recursive: false, followLinks: false) .forEach((_wallet) { - File('${_wallet.path}/config.txt').readAsLinesSync().forEach((element) { - listWallets[int.parse(element.split(':')[0])] = element.split(':')[1]; + File _walletConfig = File('${_wallet.path}/config.txt'); + _walletConfig.readAsLinesSync().forEach((element) { + if (listWallets != '') { + listWallets += '\n'; + } + listWallets += + "${element.split(':')[0]}:${element.split(':')[1]}:${element.split(':')[2]}"; }); }); + return listWallets; } @@ -93,6 +102,26 @@ class MyWalletsProvider with ChangeNotifier { ); } + Future 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() { notifyListeners(); } diff --git a/lib/models/walletOptions.dart b/lib/models/walletOptions.dart index 84764ef..65c15a0 100644 --- a/lib/models/walletOptions.dart +++ b/lib/models/walletOptions.dart @@ -15,7 +15,8 @@ class WalletOptionsProvider with ChangeNotifier { Future get badWallet => null; - Future _getPubkeyFromDewif(_dewif, _pin, _pinLenght, {derivation}) async { + Future _getPubkeyFromDewif( + String _dewif, _pin, int _pinLenght, int derivation) async { String _pubkey; RegExp regExp = new RegExp( r'^[A-Z0-9]+$', @@ -31,7 +32,7 @@ class WalletOptionsProvider with ChangeNotifier { } try { List _pubkeysTmp = await DubpRust.getBip32DewifAccountsPublicKeys( - dewif: _dewif, secretCode: _pin, accountsIndex: [3]); + dewif: _dewif, secretCode: _pin, accountsIndex: [derivation]); _pubkey = _pubkeysTmp[0]; this.pubkey.text = _pubkey; notifyListeners(); @@ -52,8 +53,8 @@ class WalletOptionsProvider with ChangeNotifier { } } - Future readLocalWallet( - int _walletNbr, String _name, String _pin, _pinLenght) async { + Future readLocalWallet(int _walletNbr, String _name, String _pin, + int _pinLenght, int derivation) async { isWalletUnlock = false; try { File _walletFile = @@ -61,16 +62,12 @@ class WalletOptionsProvider with ChangeNotifier { String _localDewif = await _walletFile.readAsString(); String _localPubkey; - if ((_localPubkey = - await _getPubkeyFromDewif(_localDewif, _pin, _pinLenght)) != + if ((_localPubkey = await _getPubkeyFromDewif( + _localDewif, _pin, _pinLenght, derivation)) != 'false') { this.pubkey.text = _localPubkey; isWalletUnlock = true; 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; } else { @@ -94,17 +91,27 @@ class WalletOptionsProvider with ChangeNotifier { return _pinLenght; } - Future _renameWallet(_walletName, _newName) async { - final _walletFile = Directory('${walletsDirectory.path}/$_walletName'); + Future _renameWallet(_walletName, _newName, _walletNbr, _derivation) async { + final _walletConfig = + File('${walletsDirectory.path}/$_walletNbr/config.txt'); - try { - _walletFile.rename('${walletsDirectory.path}/$_newName'); - } catch (e) { - print('ERREUR lors du renommage du wallet: $e'); - } + String newConfig = + await _walletConfig.readAsLines().then((List lines) { + int _index = lines.indexOf('$_walletNbr:$_walletName:$_derivation'); + 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 renameWalletAlerte(context, _walletName) async { + Future renameWalletAlerte( + context, _walletName, _walletNbr, _derivation) async { return showDialog( context: context, barrierDismissible: true, // user must tap button! @@ -130,12 +137,12 @@ class WalletOptionsProvider with ChangeNotifier { TextButton( child: Text("Valider"), onPressed: () { - WidgetsBinding.instance.addPostFrameCallback((_) { - _renameWallet(_walletName, this._newWalletName.text); + WidgetsBinding.instance.addPostFrameCallback((_) async { + await _renameWallet(_walletName, this._newWalletName.text, + _walletNbr, _derivation); }); // notifyListeners(); Navigator.pop(context, true); - Navigator.pop(context, true); }, ), ], @@ -144,21 +151,26 @@ class WalletOptionsProvider with ChangeNotifier { ); } - Future deleteWallet(context, _name) async { - try { - final _walletFile = Directory('${walletsDirectory.path}/$_name'); - print('DELETE THAT ?: $_walletFile'); + Future deleteWallet(context, _walletNbr, _name, _derivation) async { + final bool _answer = await _confirmDeletingWallet(context, _name); - final bool _answer = await _confirmDeletingWallet(context, _name); + if (_answer) { + final _walletConfig = + File('${walletsDirectory.path}/$_walletNbr/config.txt'); - if (_answer) { - await _walletFile.delete(recursive: true); - Navigator.pop(context); - } - return 0; - } catch (e) { - return 1; + String newConfig = + await _walletConfig.readAsLines().then((List lines) { + lines.removeWhere( + (element) => element == '$_walletNbr:$_name:$_derivation'); + + return lines.join('\n'); + }); + + await _walletConfig.delete(); + await _walletConfig.writeAsString(newConfig); + Navigator.pop(context); } + return 0; } Future _confirmDeletingWallet(context, _walletName) async { @@ -172,8 +184,7 @@ class WalletOptionsProvider with ChangeNotifier { content: SingleChildScrollView( child: ListBody( children: [ - Text( - 'Vous pourrez restaurer ce portefeuille à tout moment grace à votre phrase de restauration.'), + Text('Vous pourrez restaurer ce portefeuille plus tard.'), ], ), ), diff --git a/lib/screens/myWallets/confirmWalletStorage.dart b/lib/screens/myWallets/confirmWalletStorage.dart index 0130fa8..7bcc095 100644 --- a/lib/screens/myWallets/confirmWalletStorage.dart +++ b/lib/screens/myWallets/confirmWalletStorage.dart @@ -128,7 +128,8 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier { await _generateWalletProvider.storeWallet( generatedWallet, walletName.text, - context); + context, + isHD: true); _generateWalletProvider.isAskedWordValid = false; _generateWalletProvider.askedWordColor = diff --git a/lib/screens/myWallets/walletOptions.dart b/lib/screens/myWallets/walletOptions.dart index 6a8a775..0f21b6f 100644 --- a/lib/screens/myWallets/walletOptions.dart +++ b/lib/screens/myWallets/walletOptions.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:dubp/dubp.dart'; import 'package:gecko/models/myWallets.dart'; import 'package:gecko/models/walletOptions.dart'; -import 'package:gecko/screens/myWallets/changePin.dart'; import 'dart:async'; import 'package:pin_code_fields/pin_code_fields.dart'; import 'package:provider/provider.dart'; @@ -12,10 +11,14 @@ import 'package:flutter/services.dart'; // ignore: must_be_immutable class WalletOptions extends StatelessWidget with ChangeNotifier { WalletOptions( - {Key keyMyWallets, @required this.walletNbr, @required this.walletName}) + {Key keyMyWallets, + @required this.walletNbr, + @required this.walletName, + @required this.derivation}) : super(key: keyMyWallets); int walletNbr; String walletName; + int derivation; StreamController errorController; TextEditingController _enterPin = TextEditingController(); @@ -102,7 +105,10 @@ class WalletOptions extends StatelessWidget with ChangeNotifier { ), onPressed: () => _walletOptions .renameWalletAlerte( - context, walletName) + context, + walletName, + walletNbr, + derivation) .then((_result) { if (_result == true) { WidgetsBinding.instance @@ -115,6 +121,8 @@ class WalletOptions extends StatelessWidget with ChangeNotifier { _myWalletProvider .rebuildWidget(); }); + Navigator.pop( + context, true); } }), child: Text( @@ -122,30 +130,6 @@ class WalletOptions extends StatelessWidget with ChangeNotifier { style: TextStyle( fontSize: 20)))))), 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( height: 50, width: 300, @@ -157,8 +141,8 @@ class WalletOptions extends StatelessWidget with ChangeNotifier { onPrimary: Colors.black, // foreground ), onPressed: () async { - await _walletOptions.deleteWallet( - context, walletName); + await _walletOptions.deleteWallet(context, + walletNbr, walletName, derivation); WidgetsBinding.instance .addPostFrameCallback((_) { _myWalletProvider.listWallets = @@ -249,7 +233,8 @@ class WalletOptions extends StatelessWidget with ChangeNotifier { this.walletNbr, this.walletName, _pin.toUpperCase(), - _pinLenght); + _pinLenght, + this.derivation); if (resultWallet == 'bad') { errorController.add(ErrorAnimationType .shake); // Triggering error shake animation diff --git a/lib/screens/myWallets/walletsHome.dart b/lib/screens/myWallets/walletsHome.dart index cec0c8e..b5a2d91 100644 --- a/lib/screens/myWallets/walletsHome.dart +++ b/lib/screens/myWallets/walletsHome.dart @@ -7,6 +7,9 @@ import 'package:provider/provider.dart'; // ignore: must_be_immutable class WalletsHome extends StatelessWidget { + final _derivationKey = GlobalKey(); + final TextEditingController _newDerivationName = TextEditingController(); + @override Widget build(BuildContext context) { MyWalletsProvider myWalletProvider = @@ -27,12 +30,11 @@ class WalletsHome extends StatelessWidget { child: FloatingActionButton( heroTag: "buttonGenerateWallet", onPressed: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return GenerateWalletsScreen(); - }), - ); + showDialog( + context: context, + builder: (BuildContext context) { + return addNewDerivation(context, 1); + }); }, child: Container( height: 40.0, @@ -89,10 +91,7 @@ class WalletsHome extends StatelessWidget { MyWalletsProvider myWalletProvider = Provider.of(context); - List _listWallets = []; - myWalletProvider.listWallets.forEach((_nbr, _name) { - _listWallets.add('$_nbr:$_name'); - }); + List _listWallets = myWalletProvider.listWallets.split('\n'); return Column(children: [ SizedBox(height: 8), @@ -109,10 +108,54 @@ class WalletsHome extends StatelessWidget { Navigator.push(context, MaterialPageRoute(builder: (context) { return WalletOptions( 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(context); + return AlertDialog( + content: Stack( + overflow: Overflow.visible, + children: [ + Form( + key: _derivationKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + 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 == ''); + }, + ), + ) + ], + ), + ), + ], + ), + ); + } }