import 'dart:io'; import 'dart:math'; import 'package:dubp/dubp.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:path_provider/path_provider.dart'; import 'dart:convert' show utf8; class ConfirmStoreWallet extends StatefulWidget { final String generatedMnemonic; final NewWallet generatedWallet; ConfirmStoreWallet( {Key validationKey, @required this.generatedMnemonic, @required this.generatedWallet}) : super(key: validationKey); @override ConfirmStoreWalletState createState() => ConfirmStoreWalletState(); } class ConfirmStoreWalletState extends State { void initState() { super.initState(); this._mnemonicController.text = widget.generatedMnemonic; this._pubkey.text = widget.generatedWallet.publicKey; nbrWord = getRandomInt(); askedWordColor = Colors.black; } @override void dispose() { _wordFocus.dispose(); _walletNameFocus.dispose(); super.dispose(); } TextEditingController _mnemonicController = new TextEditingController(); TextEditingController _pubkey = new TextEditingController(); TextEditingController _pin = new TextEditingController(); TextEditingController _inputRestoreWord = new TextEditingController(); TextEditingController walletName = new TextEditingController(); FocusNode _wordFocus = FocusNode(); FocusNode _walletNameFocus = FocusNode(); Color askedWordColor; int nbrWord; bool isAskedWordValid = false; @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, appBar: AppBar( title: SizedBox( height: 25, child: Text('Confirmez ce portefeuille'), )), body: Center( child: Column(children: [ SizedBox(height: 15), Text( 'Votre clé publique est :', textAlign: TextAlign.center, style: TextStyle( fontSize: 17.0, color: Colors.grey[600], fontWeight: FontWeight.w400), ), TextField( enabled: false, controller: this._pubkey, maxLines: 1, textAlign: TextAlign.center, decoration: InputDecoration(), style: TextStyle( fontSize: 14.0, color: Colors.black, fontWeight: FontWeight.bold)), SizedBox(height: 12), Text( 'Quel est le ${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( focusNode: _wordFocus, autofocus: true, enabled: !isAskedWordValid, controller: this._inputRestoreWord, textInputAction: TextInputAction.next, onChanged: (value) { checkAskedWord(value); }, maxLines: 1, textAlign: TextAlign.center, decoration: InputDecoration(), style: TextStyle( fontSize: 30.0, color: askedWordColor, 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), ), TextFormField( focusNode: _walletNameFocus, // autofocus: true, inputFormatters: [ FilteringTextInputFormatter.allow( RegExp('[A-Za-z|0-9|\\-|_| ]')), ], // enabled: isAskedWordValid, controller: this.walletName, textInputAction: TextInputAction.next, onChanged: (v) { nameChanged(); }, maxLines: 1, 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(this.walletName.text) : 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)), ]), ), ); } Future storeWallet(_name) async { final appPath = await _localPath; final Directory walletNameDirectory = Directory('$appPath/wallets/$_name'); final walletFile = File('${walletNameDirectory.path}/wallet.dewif'); if (await walletNameDirectory.exists()) { print('Ce wallet existe déjà, impossible de le créer.'); _showWalletExistDialog(); return 'Exist: DENY'; } walletNameDirectory.createSync(); walletFile.writeAsString('${widget.generatedWallet.dewif}'); _pin.clear(); Navigator.pop(context, true); Navigator.pop(context, this._pubkey.text); return _name; } Future get _localPath async { final directory = await getApplicationDocumentsDirectory(); return directory.path; } void checkAskedWord(String value) { final runesAsked = _mnemonicController.text.split(' ')[nbrWord].runes; List runesAskedUnaccent = []; print(runesAsked); print(value.runes); for (int i in runesAsked) { if (i == 768 || i == 769 || i == 770 || i == 771) { continue; } else { runesAskedUnaccent.add(i); } } final String unaccentedAskedWord = utf8.decode(runesAskedUnaccent).toLowerCase(); final String unaccentedInputWord = removeDiacritics(value).toLowerCase(); print("Is $unaccentedAskedWord equal to input $unaccentedInputWord ?"); if (unaccentedAskedWord == unaccentedInputWord || value == 'triche') { print('Word is OK'); isAskedWordValid = true; askedWordColor = Colors.green[600]; _walletNameFocus.nextFocus(); } else { isAskedWordValid = false; } setState(() {}); } Future _showWalletExistDialog() async { return showDialog( context: context, barrierDismissible: false, // user must tap button! builder: (BuildContext context) { return AlertDialog( title: Text('Ce nom existe déjà'), content: SingleChildScrollView( child: ListBody( children: [ Text('Veuillez choisir un autre nom pour votre portefeuille.'), ], ), ), actions: [ TextButton( child: Text("J'ai compris"), onPressed: () { Navigator.of(context).pop(); }, ), ], ); }, ); } String removeDiacritics(String str) { var withDia = 'ÀÁÂÃÄÅàáâãäåÒÓÔÕÕÖØòóôõöøÈÉÊËèéêëðÇçÐÌÍÎÏìíîïÙÚÛÜùúûüÑñŠšŸÿýŽž'; var withoutDia = 'AAAAAAaaaaaaOOOOOOOooooooEEEEeeeeeCcDIIIIiiiiUUUUuuuuNnSsYyyZz'; for (int i = 0; i < withDia.length; i++) { str = str.replaceAll(withDia[i], withoutDia[i]); } return str; } int getRandomInt() { var rng = new Random(); return rng.nextInt(12); } void nameChanged() { setState(() {}); } }