Commit long way after ...

This commit is contained in:
poka 2021-01-26 21:00:26 +01:00
parent 5542a8eea8
commit 5176e76860
11 changed files with 462 additions and 500 deletions

5
lib/globals.dart Normal file
View File

@ -0,0 +1,5 @@
import 'dart:io';
Directory appPath;
Directory walletsDirectory;
String appVersion;

View File

@ -1,5 +1,8 @@
import 'package:dubp/dubp.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/generateWallets.dart';
import 'package:gecko/models/history.dart';
import 'package:gecko/models/home.dart';
import 'package:gecko/models/myWallets.dart';
import 'package:gecko/ui/home.dart';
import 'package:flutter/cupertino.dart';
@ -8,10 +11,6 @@ import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
// import 'package:flutter/services.dart' show rootBundle;
import 'dart:math';
// import 'dart:convert';
final bool enableSentry = true;
@ -19,35 +18,12 @@ final bool enableSentry = true;
// return rootBundle.loadString('config/gva_endpoints.json');
// }
T getRandomElement<T>(List<T> list) {
final random = new Random();
var i = random.nextInt(list.length);
return list[i];
}
Future<String> getRandomEndpoint() async {
// TODO: Improve implemention of getRandomEndpoint()
// final _json = json.decode(await getJsonEndpoints());
// print('JSON !! :');
// print(_json);
// final _list = _json[];
final _listEndpoints = ['https://g1.librelois.fr/gva'];
final _endpoint = getRandomElement(_listEndpoints);
print('ENDPOINT: ' + _endpoint);
// http.post(_endpoint);
final response = await http.post(_endpoint);
if (response.statusCode != 400) {
print('Endpoint statutcode: ' + response.statusCode.toString());
// _endpoint = getRandomElement(_list);
return 'HS';
}
return _endpoint;
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
HomeProvider _homeProvider = HomeProvider();
await _homeProvider.getAppPath();
appVersion = await _homeProvider.getAppVersion();
String randomEndpoint; // = await getRandomEndpoint();
int i = 0;
do {
@ -59,7 +35,7 @@ Future<void> main() async {
print(i.toString() + ' ème essai de recherche de endpoint GVA.');
await Future.delayed(Duration(milliseconds: 300));
}
randomEndpoint = await getRandomEndpoint();
randomEndpoint = await _homeProvider.getRandomEndpoint();
i++;
} while (randomEndpoint == 'HS');
@ -73,16 +49,37 @@ Future<void> main() async {
);
} else {
print('Debug mode enabled: No sentry alerte');
runApp(Gecko(randomEndpoint));
runApp(Gecko(
randomEndpoint,
));
}
}
// ignore: must_be_immutable
class Gecko extends StatelessWidget {
Gecko(this.randomEndpoint);
final String randomEndpoint;
@override
Widget build(BuildContext context) {
// FutureBuilder<dynamic>(
// future: getAppPath(), // async work
// builder: (BuildContext context, AsyncSnapshot snapshot) {
// // switch (snapshot.connectionState) {
// // case ConnectionState.waiting:
// // return Text('Loading....');
// // default:
// // if (snapshot.hasError)
// // return Text('Error: ${snapshot.error}');
// // else
// // return Text('Result: ${snapshot.data}');
// // }
// print('FutureBuilder: ' + appPath.path);
// return;
// },
// );
final _httpLink = HttpLink(
// 'http://192.168.1.91:10060/gva',
randomEndpoint,
@ -119,8 +116,11 @@ class Gecko extends StatelessWidget {
home: MultiProvider(
providers: [
// Provider(create: (context) => HistoryProvider()),
Provider(create: (context) => MyWalletsProvider()),
ChangeNotifierProvider(create: (_) => HistoryProvider(''))
// Provider(create: (context) => MyWalletsProvider()),
ChangeNotifierProvider(create: (_) => HomeProvider()),
ChangeNotifierProvider(create: (_) => HistoryProvider('')),
ChangeNotifierProvider(create: (_) => MyWalletsProvider()),
ChangeNotifierProvider(create: (_) => GenerateWalletsProvider())
],
child: GraphQLProvider(
client: _client,

View File

@ -0,0 +1,181 @@
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:dubp/dubp.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sentry_flutter/sentry_flutter.dart' as sentry;
class GenerateWalletsProvider with ChangeNotifier {
NewWallet generatedWallet;
FocusNode walletNameFocus = FocusNode();
Color askedWordColor = Colors.black;
bool isAskedWordValid = false;
int nbrWord;
String generatedMnemonic;
bool walletIsGenerated = false;
NewWallet actualWallet;
TextEditingController mnemonicController = TextEditingController();
TextEditingController pubkey = TextEditingController();
TextEditingController pin = TextEditingController();
Future storeWallet(_name, _pubkey, BuildContext context) 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(context);
return 'Exist: DENY';
}
walletNameDirectory.createSync();
walletFile.writeAsString('${generatedWallet.dewif}');
Navigator.pop(context, true);
Navigator.pop(context, _pubkey.text);
return _name;
}
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
void checkAskedWord(String value, String _mnemo) {
nbrWord = getRandomInt();
final runesAsked = _mnemo.split(' ')[nbrWord].runes;
List<int> 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;
}
notifyListeners();
}
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() {
notifyListeners();
}
Future<void> _showWalletExistDialog(BuildContext context) async {
return showDialog<void>(
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: <Widget>[
Text('Veuillez choisir un autre nom pour votre portefeuille.'),
],
),
),
actions: <Widget>[
TextButton(
child: Text("J'ai compris"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
Future<String> generateMnemonic() async {
try {
this.generatedMnemonic =
await DubpRust.genMnemonic(language: Language.french);
this.actualWallet = await generateWallet(this.generatedMnemonic);
this.walletIsGenerated = true;
} catch (e, stack) {
print(e);
if (kReleaseMode) {
await sentry.Sentry.captureException(
e,
stackTrace: stack,
);
}
}
// await checkIfWalletExist();
return this.generatedMnemonic;
}
Future<NewWallet> generateWallet(generatedMnemonic) async {
try {
this.actualWallet = await DubpRust.genWalletFromMnemonic(
language: Language.french,
mnemonic: generatedMnemonic,
secretCodeType: SecretCodeType.letters);
} catch (e, stack) {
print(e);
if (kReleaseMode) {
await sentry.Sentry.captureException(
e,
stackTrace: stack,
);
}
}
mnemonicController.text = generatedMnemonic;
pubkey.text = actualWallet.publicKey;
pin.text = actualWallet.pin;
notifyListeners();
return actualWallet;
}
Future<void> changePinCode() async {
this.actualWallet = await DubpRust.changeDewifPin(
dewif: this.actualWallet.dewif,
oldPin: this.actualWallet.pin,
);
pin.text = actualWallet.pin;
notifyListeners();
}
}

71
lib/models/home.dart Normal file
View File

@ -0,0 +1,71 @@
import 'dart:io';
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:gecko/globals.dart';
import 'package:package_info/package_info.dart';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http;
class HomeProvider with ChangeNotifier {
int _currentIndex = 0;
get currentIndex => _currentIndex;
set currentIndex(int index) {
_currentIndex = index;
print('current index setter: ' + index.toString());
notifyListeners();
}
Future getAppVersion() async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String appName = packageInfo.appName;
String version = packageInfo.version;
String buildNumber = packageInfo.buildNumber;
print(appName);
notifyListeners();
return version + '+' + buildNumber;
}
// void onTabTapped(int index) {
// currentIndex = index;
// notifyListeners();
// }
Future<String> getRandomEndpoint() async {
// TODO: Improve implemention of getRandomEndpoint()
// final _json = json.decode(await getJsonEndpoints());
// print('JSON !! :');
// print(_json);
// final _list = _json[];
final _listEndpoints = ['https://g1.librelois.fr/gva'];
final _endpoint = getRandomElement(_listEndpoints);
print('ENDPOINT: ' + _endpoint);
// http.post(_endpoint);
final response = await http.post(_endpoint);
if (response.statusCode != 400) {
print('Endpoint statutcode: ' + response.statusCode.toString());
// _endpoint = getRandomElement(_list);
return 'HS';
}
return _endpoint;
}
Future getAppPath() async {
appPath = await getApplicationDocumentsDirectory();
walletsDirectory = Directory('${appPath.path}/wallets');
print('AAAAPPPATH: ' + appPath.path);
}
T getRandomElement<T>(List<T> list) {
final random = new Random();
var i = random.nextInt(list.length);
return list[i];
}
}

View File

@ -2,17 +2,18 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:gecko/globals.dart';
class MyWalletsProvider with ChangeNotifier {
Directory appPath;
// Directory appPath;
List listWallets = [];
bool checkIfWalletExist() {
if (this.appPath == null) {
if (appPath == null) {
return false;
}
var walletsFolder = new Directory("${this.appPath.path}/wallets/");
var walletsFolder = new Directory("${appPath.path}/wallets/");
bool isWalletFolderExist = walletsFolder.existsSync();
@ -23,12 +24,14 @@ class MyWalletsProvider with ChangeNotifier {
List contents = walletsFolder.listSync();
if (contents.length == 0) {
print('No wallets detected');
notifyListeners();
return false;
} else {
print('Some wallets have been detected:');
for (var _wallets in contents) {
print(_wallets);
}
notifyListeners();
return true;
}
@ -45,10 +48,23 @@ class MyWalletsProvider with ChangeNotifier {
// }
}
Future getAppDirectory() async {
this.appPath = await getApplicationDocumentsDirectory();
notifyListeners();
}
Future importWallet() async {}
List getAllWalletsNames() {
listWallets.clear();
print('1');
print(walletsDirectory.path);
print('2');
walletsDirectory
.listSync(recursive: false, followLinks: false)
.forEach((wallet) {
String _name = wallet.path.split('/').last;
print(_name);
listWallets.add(_name);
});
notifyListeners();
return listWallets;
}
}

View File

@ -8,28 +8,22 @@ import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
import 'package:truncate/truncate.dart';
//ignore: must_be_immutable
// ignore: must_be_immutable
class HistoryScreen extends StatelessWidget with ChangeNotifier {
final TextEditingController _outputPubkey = new TextEditingController();
ScrollController scrollController = new ScrollController();
final TextEditingController _outputPubkey = TextEditingController();
ScrollController scrollController = ScrollController();
final nRepositories = 20;
HistoryProvider _historyProvider;
bool isTheEnd = false;
List _transBC;
FetchMore fetchMore;
FetchMoreOptions opts;
// scrollListener() {
// if (scrollController.offset >= scrollController.position.maxScrollExtent &&
// !scrollController.position.outOfRange) {
// print('On est en bas !!');
// print(opts.document);
// fetchMore(opts);
// notifyListeners();
// }
// }
@override
Widget build(BuildContext context) {
_historyProvider = Provider.of<HistoryProvider>(context);
this._outputPubkey.text = _historyProvider.pubkey;
print('Build pubkey : ' + _historyProvider.pubkey);
// scrollController.addListener(scrollListener);
return Scaffold(
@ -90,7 +84,6 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
variables: <String, dynamic>{
'pubkey': _historyProvider.pubkey,
'number': nRepositories,
// set cursor to null so as to start at the beginning
'cursor': null
},
),
@ -127,50 +120,32 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
final num balance =
removeDecimalZero(result.data['balance']['amount'] / 100);
opts = FetchMoreOptions(
variables: {'cursor': fetchMoreCursor},
updateQuery: (previousResultData, fetchMoreResultData) {
final List<dynamic> repos = [
...previousResultData['txsHistoryBc']['both']['edges']
as List<dynamic>,
...fetchMoreResultData['txsHistoryBc']['both']['edges']
as List<dynamic>
];
if (fetchMoreCursor != null) {
opts = FetchMoreOptions(
variables: {'cursor': fetchMoreCursor},
updateQuery: (previousResultData, fetchMoreResultData) {
final List<dynamic> repos = [
...previousResultData['txsHistoryBc']['both']['edges']
as List<dynamic>,
...fetchMoreResultData['txsHistoryBc']['both']['edges']
as List<dynamic>
];
fetchMoreResultData['txsHistoryBc']['both']['edges'] = repos;
return fetchMoreResultData;
},
);
// _scrollController
// ..addListener(() {
// if (_scrollController.position.pixels ==
// _scrollController.position.maxScrollExtent) {
// if (!result.isLoading) {
// print(
// "DEBUG H fetchMoreCursor in scrollController: $fetchMoreCursor");
// fetchMore(opts);
// }
// }
// });
// s/o : https://stackoverflow.com/questions/54065354/how-to-detect-scroll-position-of-listview-in-flutter/54188385#54188385
// new NotificationListener(
// child: new ListView(
// controller: _scrollController,
// ),
// onNotification: (t) {
// if (t is ScrollEndNotification) {
// fetchMore(opts);
// }
// },
// );
// fetchMore(opts);
fetchMoreResultData['txsHistoryBc']['both']['edges'] = repos;
return fetchMoreResultData;
},
);
}
print(
"###### DEBUG H Parse blockchainTX list. Cursor: $fetchMoreCursor ######");
List _transBC = parseHistory(blockchainTX);
if (fetchMoreCursor != null) {
_transBC = parseHistory(blockchainTX);
isTheEnd = false;
} else {
print("###### DEBUG H - Début de l'historique");
isTheEnd = true;
}
// Build history list
return NotificationListener(
@ -200,9 +175,8 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
style: TextStyle(fontSize: 14.0)),
dense: true,
onTap: () {
this._outputPubkey.text = repository[2];
// this._outputPubkey.text = repository[2];
_historyProvider.isPubkey(repository[2]);
// notifyListeners();
}),
if (result.isLoading)
Row(
@ -211,16 +185,21 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
CircularProgressIndicator(),
],
),
if (isTheEnd)
Column(children: <Widget>[
SizedBox(height: 15),
Text("Début de l'historique.",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20)),
SizedBox(height: 15)
])
],
)),
onNotification: (t) {
// print(scrollController.position.pixels);
// print(scrollController.position.maxScrollExtent);
if (t is ScrollEndNotification &&
scrollController.position.pixels >=
scrollController.position.maxScrollExtent * 0.8) {
fetchMore(opts);
// notifyListeners();
}
return true;
});

View File

@ -1,39 +1,21 @@
import 'package:gecko/globals.dart';
import 'package:gecko/models/home.dart';
import 'package:gecko/ui/historyScreen.dart';
import 'package:flutter/material.dart';
import 'dart:ui';
import 'package:gecko/ui/myWallets/walletsHome.dart';
import 'package:gecko/ui/settingsScreen.dart';
import 'package:package_info/package_info.dart';
import 'package:provider/provider.dart';
//ignore: must_be_immutable
class HomeScreen extends StatefulWidget {
HomeScreen({this.screens});
final List<Widget> screens;
// ignore: must_be_immutable
class HomeScreen extends StatelessWidget {
// HomeProvider _homeProvider = HomeProvider();
@override
HomeScreenState createState() => HomeScreenState();
}
class HomeScreenState extends State<HomeScreen> {
int currentIndex = 0;
Widget currentScreen;
String appName;
String version;
String buildNumber;
void initState() {
super.initState();
getAppVersion();
}
void onTabTapped(int index) {
setState(() {
currentIndex = index;
});
}
var currentTab = [HistoryScreen(), WalletsHome()];
@override
Widget build(BuildContext context) {
var _homeProvider = Provider.of<HomeProvider>(context);
return Scaffold(
drawer: Drawer(
child: Column(
@ -74,7 +56,7 @@ class HomeScreenState extends State<HomeScreen> {
Container(
child: Align(
alignment: FractionalOffset.bottomCenter,
child: Text('Ğecko v${this.version}+${this.buildNumber}'))),
child: Text('Ğecko v$appVersion'))),
SizedBox(height: 20)
],
),
@ -95,22 +77,16 @@ class HomeScreenState extends State<HomeScreen> {
backgroundColor: Color(0xffFFD58D),
),
backgroundColor: Color(0xffF9F9F1),
body: SafeArea(
child: IndexedStack(
index: currentIndex,
children: <Widget>[
HistoryScreen(),
WalletsHome(),
],
),
),
body: currentTab[_homeProvider.currentIndex],
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Color(0xffFFD58D),
fixedColor: Colors.grey[850],
unselectedItemColor: Color(0xffBD935C),
type: BottomNavigationBarType.fixed,
onTap: onTabTapped,
currentIndex: currentIndex,
onTap: (index) {
_homeProvider.currentIndex = index;
},
currentIndex: _homeProvider.currentIndex,
items: [
BottomNavigationBarItem(
icon: new Icon(Icons
@ -125,14 +101,4 @@ class HomeScreenState extends State<HomeScreen> {
),
);
}
Future getAppVersion() async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
this.appName = packageInfo.appName;
this.version = packageInfo.version;
this.buildNumber = packageInfo.buildNumber;
print(this.appName);
setState(() {});
}
}

View File

@ -1,54 +1,37 @@
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;
import 'package:gecko/models/generateWallets.dart';
import 'package:provider/provider.dart';
class ConfirmStoreWallet extends StatefulWidget {
final String generatedMnemonic;
final NewWallet generatedWallet;
// ignore: must_be_immutable
class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
ConfirmStoreWallet({
Key validationKey,
@required this.generatedMnemonic,
@required generatedWallet,
}) : super(key: validationKey);
ConfirmStoreWallet(
{Key validationKey,
@required this.generatedMnemonic,
@required this.generatedWallet})
: super(key: validationKey);
String generatedMnemonic;
@override
ConfirmStoreWalletState createState() => ConfirmStoreWalletState();
}
class ConfirmStoreWalletState extends State<ConfirmStoreWallet> {
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();
}
// @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) {
var _generateWalletProvider = Provider.of<GenerateWalletsProvider>(context);
this._mnemonicController.text = generatedMnemonic;
this._pubkey.text = _generateWalletProvider.generatedWallet.publicKey;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
@ -79,7 +62,7 @@ class ConfirmStoreWalletState extends State<ConfirmStoreWallet> {
fontWeight: FontWeight.bold)),
SizedBox(height: 12),
Text(
'Quel est le ${nbrWord + 1}ème mot de votre phrase de restauration ?',
'Quel est le ${_generateWalletProvider.nbrWord + 1}ème mot de votre phrase de restauration ?',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 17.0,
@ -89,18 +72,19 @@ class ConfirmStoreWalletState extends State<ConfirmStoreWallet> {
TextFormField(
focusNode: _wordFocus,
autofocus: true,
enabled: !isAskedWordValid,
enabled: !_generateWalletProvider.isAskedWordValid,
controller: this._inputRestoreWord,
textInputAction: TextInputAction.next,
onChanged: (value) {
checkAskedWord(value);
_generateWalletProvider.checkAskedWord(
value, _mnemonicController.text);
},
maxLines: 1,
textAlign: TextAlign.center,
decoration: InputDecoration(),
style: TextStyle(
fontSize: 30.0,
color: askedWordColor,
color: _generateWalletProvider.askedWordColor,
fontWeight: FontWeight.w500)),
SizedBox(height: 12),
Text(
@ -112,7 +96,7 @@ class ConfirmStoreWalletState extends State<ConfirmStoreWallet> {
fontWeight: FontWeight.w400),
),
TextFormField(
focusNode: _walletNameFocus,
focusNode: _generateWalletProvider.walletNameFocus,
// autofocus: true,
inputFormatters: [
FilteringTextInputFormatter.allow(
@ -122,7 +106,7 @@ class ConfirmStoreWalletState extends State<ConfirmStoreWallet> {
controller: this.walletName,
textInputAction: TextInputAction.next,
onChanged: (v) {
nameChanged();
_generateWalletProvider.nameChanged();
},
maxLines: 1,
textAlign: TextAlign.center,
@ -144,10 +128,11 @@ class ConfirmStoreWalletState extends State<ConfirmStoreWallet> {
.green[400], //Color(0xffFFD68E), // background
onPrimary: Colors.black, // foreground
),
onPressed:
(isAskedWordValid && this.walletName.text != '')
? () => storeWallet(this.walletName.text)
: null,
onPressed: (_generateWalletProvider.isAskedWordValid &&
this.walletName.text != '')
? () => _generateWalletProvider.storeWallet(
walletName.text, _pubkey.text, context)
: null,
child:
Text('Confirmer', style: TextStyle(fontSize: 28))),
))),
@ -161,107 +146,4 @@ class ConfirmStoreWalletState extends State<ConfirmStoreWallet> {
),
);
}
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<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
void checkAskedWord(String value) {
final runesAsked = _mnemonicController.text.split(' ')[nbrWord].runes;
List<int> 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<void> _showWalletExistDialog() async {
return showDialog<void>(
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: <Widget>[
Text('Veuillez choisir un autre nom pour votre portefeuille.'),
],
),
),
actions: <Widget>[
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(() {});
}
}

View File

@ -1,30 +1,11 @@
import 'package:gecko/models/generateWallets.dart';
import 'package:gecko/ui/myWallets/confirmWalletStorage.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:sentry/sentry.dart' as sentry;
import 'package:dubp/dubp.dart';
import 'package:provider/provider.dart';
import 'package:super_tooltip/super_tooltip.dart';
class GenerateWalletsScreen extends StatefulWidget {
const GenerateWalletsScreen({Key keyGenWallet}) : super(key: keyGenWallet);
@override
GenerateWalletsState createState() => GenerateWalletsState();
}
class GenerateWalletsState extends State<GenerateWalletsScreen> {
// GlobalKey<MyWalletState> _keyMyWallets = GlobalKey();
// GlobalKey<ValidStoreWalletState> _keyValidWallets = GlobalKey();
void initState() {
super.initState();
generateMnemonic();
}
TextEditingController _mnemonicController = new TextEditingController();
TextEditingController _pubkey = new TextEditingController();
TextEditingController _pin = new TextEditingController();
String generatedMnemonic;
bool walletIsGenerated = false;
NewWallet actualWallet;
// ignore: must_be_immutable
class GenerateWalletsScreen extends StatelessWidget {
SuperTooltip tooltip;
// final formKey = GlobalKey<FormState>();
@ -35,6 +16,8 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
@override
Widget build(BuildContext context) {
var _generateWalletProvider = Provider.of<GenerateWalletsProvider>(context);
_generateWalletProvider.generateMnemonic();
return Scaffold(
appBar: AppBar(
title: SizedBox(
@ -47,7 +30,7 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
child: FittedBox(
child: FloatingActionButton(
heroTag: "buttonGenerateWallet",
onPressed: () => generateMnemonic(),
onPressed: () => _generateWalletProvider.generateMnemonic(),
// print(resultScan);
// if (resultScan != 'false') {
// onTabTapped(0);
@ -76,7 +59,7 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
),
TextField(
enabled: false,
controller: this._pubkey,
controller: _generateWalletProvider.pubkey,
maxLines: 1,
textAlign: TextAlign.center,
decoration: InputDecoration(),
@ -98,7 +81,7 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
),
TextField(
enabled: false,
controller: this._mnemonicController,
controller: _generateWalletProvider.mnemonicController,
maxLines: 3,
textAlign: TextAlign.center,
decoration: InputDecoration(
@ -126,7 +109,7 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
children: <Widget>[
TextField(
enabled: false,
controller: this._pin,
controller: _generateWalletProvider.pin,
maxLines: 1,
textAlign: TextAlign.center,
decoration: InputDecoration(),
@ -138,7 +121,7 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
icon: Icon(Icons.replay),
color: Color(0xffD28928),
onPressed: () {
changePinCode();
_generateWalletProvider.changePinCode();
},
),
],
@ -151,15 +134,17 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
primary: Color(0xffFFD68E), // background
onPrimary: Colors.black, // foreground
),
onPressed: walletIsGenerated
onPressed: _generateWalletProvider.walletIsGenerated
? () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return ConfirmStoreWallet(
// validationKey: _keyValidWallets,
generatedMnemonic: this.generatedMnemonic,
generatedWallet: this.actualWallet);
generatedMnemonic:
_generateWalletProvider.generatedMnemonic,
generatedWallet:
_generateWalletProvider.actualWallet);
}),
)
// .then((value) => setState(() {
@ -181,59 +166,4 @@ class GenerateWalletsState extends State<GenerateWalletsScreen> {
]),
));
}
Future<String> generateMnemonic() async {
try {
this.generatedMnemonic =
await DubpRust.genMnemonic(language: Language.french);
this.actualWallet = await generateWallet(this.generatedMnemonic);
this.walletIsGenerated = true;
} catch (e, stack) {
print(e);
if (kReleaseMode) {
await sentry.Sentry.captureException(
e,
stackTrace: stack,
);
}
}
// await checkIfWalletExist();
return this.generatedMnemonic;
}
Future<NewWallet> generateWallet(generatedMnemonic) async {
try {
this.actualWallet = await DubpRust.genWalletFromMnemonic(
language: Language.french,
mnemonic: generatedMnemonic,
secretCodeType: SecretCodeType.letters);
} catch (e, stack) {
print(e);
if (kReleaseMode) {
await sentry.Sentry.captureException(
e,
stackTrace: stack,
);
}
}
setState(() {
this._mnemonicController.text = generatedMnemonic;
this._pubkey.text = actualWallet.publicKey;
this._pin.text = actualWallet.pin;
});
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

@ -1,91 +0,0 @@
// import 'package:gecko/ui/generateWallets.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gecko/ui/myWallets/walletOptions.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class MyWalletsList extends StatefulWidget {
const MyWalletsList({Key keyMyWallets}) : super(key: keyMyWallets);
@override
MyWalletListState createState() => MyWalletListState();
}
class MyWalletListState extends State<MyWalletsList> {
Directory walletsDirectory;
List _listWallets = [];
void initState() {
super.initState();
initAppDirectory();
}
void initAppDirectory() async {
Directory _appPath = await getApplicationDocumentsDirectory();
walletsDirectory = Directory('${_appPath.path}/wallets');
_listWallets = getAllWalletsNames();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Column(children: <Widget>[
SizedBox(height: 8),
for (var repository in this._listWallets)
ListTile(
contentPadding: const EdgeInsets.all(5.0),
leading: Text(repository, style: TextStyle(fontSize: 14.0)),
title: Text(repository, style: TextStyle(fontSize: 14.0)),
subtitle: Text(repository, style: TextStyle(fontSize: 14.0)),
dense: true,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return WalletOptions(walletName: repository);
}),
).then((value) => setState(() {
initAppDirectory();
}));
},
),
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: () {
initAppDirectory();
setState(() {});
},
child: Text('(Refresh)', style: TextStyle(fontSize: 10)))),
]));
}
List getAllWalletsNames() {
this._listWallets.clear();
print(this.walletsDirectory.path);
this
.walletsDirectory
.listSync(recursive: false, followLinks: false)
.forEach((wallet) {
String _name = wallet.path.split('/').last;
print(_name);
this._listWallets.add(_name);
});
// .listen((FileSystemEntity entity) {
// print(entity.path.split('/').last);
// this._listWallets.add(entity.path.split('/').last);
// });
return _listWallets;
// final _local = await _appPath.path.list().toList();
}
}

View File

@ -1,29 +1,20 @@
import 'package:gecko/models/myWallets.dart';
import 'package:gecko/ui/myWallets/generateWalletsScreen.dart';
import 'package:gecko/ui/myWallets/myWalletsList.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:dubp/dubp.dart';
import 'package:gecko/ui/myWallets/walletOptions.dart';
class WalletsHome extends StatelessWidget with ChangeNotifier {
MyWalletsProvider historyProvider = MyWalletsProvider();
String generatedMnemonic;
bool walletIsGenerated = false;
NewWallet actualWallet;
String newWalletName;
bool hasError = false;
String validPin = 'NO PIN';
String currentText = "";
var pinColor = Colors.grey[300];
// ignore: must_be_immutable
class WalletsHome extends StatelessWidget {
MyWalletsProvider myWalletProvider = MyWalletsProvider();
@override
Widget build(BuildContext context) {
historyProvider.getAppDirectory();
print('BUILD: WalletsHome');
myWalletProvider.listWallets = myWalletProvider.getAllWalletsNames();
return Scaffold(
floatingActionButton: Visibility(
visible: (historyProvider
visible: (myWalletProvider
.checkIfWalletExist()), //!checkIfWalletExist('MonWallet') &&
child: Container(
height: 80.0,
@ -48,8 +39,7 @@ class WalletsHome extends StatelessWidget with ChangeNotifier {
body: SafeArea(
child: Column(children: <Widget>[
Visibility(
visible:
(!historyProvider.checkIfWalletExist() && !walletIsGenerated),
visible: (!myWalletProvider.checkIfWalletExist()),
child: Column(children: <Widget>[
SizedBox(height: 120),
Center(
@ -83,13 +73,13 @@ class WalletsHome extends StatelessWidget with ChangeNotifier {
primary: Color(0xffFFD68E), // background
onPrimary: Colors.black, // foreground
),
onPressed: () => historyProvider.importWallet(),
onPressed: () => myWalletProvider.importWallet(),
child: Text('Importer un portefeuille existant',
style: TextStyle(fontSize: 20))),
])),
Visibility(
visible: historyProvider.checkIfWalletExist(),
child: MyWalletsList())
visible: myWalletProvider.checkIfWalletExist(),
child: myWalletsList(context))
])));
}
@ -105,4 +95,37 @@ class WalletsHome extends StatelessWidget with ChangeNotifier {
// });
// }
myWalletsList(BuildContext context) {
return Column(children: <Widget>[
SizedBox(height: 8),
for (var repository in myWalletProvider.listWallets)
ListTile(
contentPadding: const EdgeInsets.all(5.0),
leading: Text(repository, style: TextStyle(fontSize: 14.0)),
title: Text(repository, style: TextStyle(fontSize: 14.0)),
subtitle: Text(repository, style: TextStyle(fontSize: 14.0)),
dense: true,
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
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))))
]);
}
}