From 0a42a17cddf2a608db947e8ec0648fcf58df1c34 Mon Sep 17 00:00:00 2001 From: poka Date: Wed, 6 Jan 2021 21:17:01 +0100 Subject: [PATCH] Store generated wallet; Access it with PIN validation --- lib/home.dart | 12 ++-- lib/main.dart | 21 ++++-- lib/ui/generateWallets.dart | 125 +++++++++++++++++++++++++++++++++--- lib/ui/historyWallets.dart | 12 +++- pubspec.lock | 56 ++++++++++------ pubspec.yaml | 2 + 6 files changed, 184 insertions(+), 44 deletions(-) diff --git a/lib/home.dart b/lib/home.dart index 97c0145..13d70e1 100644 --- a/lib/home.dart +++ b/lib/home.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/foundation.dart'; import 'package:qrscan/qrscan.dart' as scanner; import 'package:gecko/ui/generateWallets.dart'; import 'package:gecko/ui/historyWallets.dart'; @@ -75,7 +76,6 @@ class _HomeScreenState extends State { @override void initState() { - // TODO: implement initState super.initState(); _scrollController = ScrollController(); _scrollController.addListener(_scrollListener); @@ -274,10 +274,12 @@ class _HomeScreenState extends State { barcode = await scanner.scan(); } catch (e, stack) { print(e); - await sentry.Sentry.captureException( - e, - stackTrace: stack, - ); + if (kReleaseMode) { + await sentry.Sentry.captureException( + e, + stackTrace: stack, + ); + } } // this._outputPubkey.text = ""; if (barcode != null) { diff --git a/lib/main.dart b/lib/main.dart index 053b0dd..3707b90 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,17 +3,24 @@ import 'package:flutter/material.dart'; import 'home.dart'; import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:flutter/foundation.dart'; // void main() => runApp(Gecko()); Future main() async { - await SentryFlutter.init( - (options) { - options.dsn = - 'https://c09587b46eaa42e8b9fda28d838ed180@o496840.ingest.sentry.io/5572110'; - }, - appRunner: () => runApp(Gecko()), - ); + if (kReleaseMode) { + print('Release'); + await SentryFlutter.init( + (options) { + options.dsn = + 'https://c09587b46eaa42e8b9fda28d838ed180@o496840.ingest.sentry.io/5572110'; + }, + appRunner: () => runApp(Gecko()), + ); + } else { + print('Debug'); + runApp(Gecko()); + } } class Gecko extends StatelessWidget { diff --git a/lib/ui/generateWallets.dart b/lib/ui/generateWallets.dart index bc7472e..05b258f 100644 --- a/lib/ui/generateWallets.dart +++ b/lib/ui/generateWallets.dart @@ -1,6 +1,10 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:dubp/dubp.dart'; import 'package:sentry/sentry.dart' as sentry; +import 'dart:io'; +import 'package:path_provider/path_provider.dart'; +import 'package:pin_code_fields/pin_code_fields.dart'; class GenerateWalletScreen extends StatefulWidget { @override @@ -17,6 +21,8 @@ class _GenerateWalletScreen extends State { TextEditingController _pubkey = new TextEditingController(); TextEditingController _dewif = new TextEditingController(); TextEditingController _pin = new TextEditingController(); + TextEditingController _enterPin = new TextEditingController(); + String validPin = 'NO PIN'; @override Widget build(BuildContext context) { @@ -59,9 +65,32 @@ class _GenerateWalletScreen extends State { fontSize: 20.0, color: Colors.black, fontWeight: FontWeight.bold)), + SizedBox(height: 12), new RaisedButton( onPressed: () => generateMnemonic(), child: Text('Générer un wallet', style: TextStyle(fontSize: 20))), + SizedBox(height: 20), + TextField( + controller: this._enterPin, + onChanged: (validPin) { + this.validPin = validPin ?? 'NO PIN'; + print('PIN: ' + this.validPin); + }, + maxLines: 1, + textAlign: TextAlign.center, + decoration: InputDecoration( + hintText: 'Tappez votre code PIN', + hintStyle: TextStyle(fontSize: 15), + contentPadding: EdgeInsets.symmetric(horizontal: 7, vertical: 15), + ), + style: TextStyle( + fontSize: 20.0, + color: Colors.black, + fontWeight: FontWeight.bold)), + SizedBox(height: 12), + new RaisedButton( + onPressed: () => readLocalWallet(this.validPin.toUpperCase()), + child: Text('Lire le wallet local', style: TextStyle(fontSize: 20))), ])); } @@ -71,26 +100,31 @@ class _GenerateWalletScreen extends State { generatedMnemonic = await DubpRust.genMnemonic(language: Language.french); } catch (e, stack) { print(e); - await sentry.Sentry.captureException( - e, - stackTrace: stack, - ); + if (kReleaseMode) { + await sentry.Sentry.captureException( + e, + stackTrace: stack, + ); + } } generateWallet(generatedMnemonic); } Future generateWallet(generatedMnemonic) async { + final walletFile = await _localWallet; NewWallet newWallet; try { newWallet = await DubpRust.genWalletFromMnemonic( language: Language.french, mnemonic: generatedMnemonic); } catch (e, stack) { print(e); - await sentry.Sentry.captureException( - e, - stackTrace: stack, - ); + if (kReleaseMode) { + await sentry.Sentry.captureException( + e, + stackTrace: stack, + ); + } } setState(() { @@ -99,5 +133,80 @@ class _GenerateWalletScreen extends State { this._dewif.text = newWallet.dewif; this._pin.text = newWallet.pin; }); + + return walletFile.writeAsString('${newWallet.dewif}'); + } + + Future getPubkeyFromDewif(_dewif, _pin) async { + String _pubkey; + RegExp regExp = new RegExp( + r'^[A-Z0-9]+$', + caseSensitive: false, + multiLine: false, + ); + + if (regExp.hasMatch(_pin) == true && _pin.length == 6) { + print("Le format du code PIN est correct."); + } else { + print('Format de code PIN invalide'); + return 'false'; + } + try { + _pubkey = await DubpRust.getDewifPublicKey(dewif: _dewif, pin: _pin); + setState(() { + this._pubkey.text = _pubkey; + }); + + return _pubkey; + } catch (e, stack) { + print('Bad PIN code !'); + print(e); + if (kReleaseMode) { + await sentry.Sentry.captureException( + e, + stackTrace: stack, + ); + } + return 'false'; + } + } + + Future readLocalWallet(String _pin) async { + // print(pin); + try { + final file = await _localWallet; + String _localDewif = await file.readAsString(); + String _localPubkey; + + // _localPubkey = await getPubkeyFromDewif(_localDewif, _pin)? + + if ((_localPubkey = await getPubkeyFromDewif(_localDewif, _pin)) != + 'false') { + setState(() { + this._mnemonic.text = ''; + this._pubkey.text = _localPubkey; + this._dewif.text = _localDewif; + this._pin.text = _pin; + }); + + return _localDewif; + } else { + throw 'Bad pubkey'; + } + } catch (e) { + print('ERROR READING FILE: $e'); + return 0; + } + } + + Future get _localPath async { + final directory = await getApplicationDocumentsDirectory(); + + return directory.path; + } + + Future get _localWallet async { + final path = await _localPath; + return File('$path/wallet.dewif'); } } diff --git a/lib/ui/historyWallets.dart b/lib/ui/historyWallets.dart index 75ce4df..219d6d2 100644 --- a/lib/ui/historyWallets.dart +++ b/lib/ui/historyWallets.dart @@ -19,6 +19,10 @@ import 'package:truncate/truncate.dart'; // } class HistoryListView extends StatelessWidget { + // const String({this.isPubkey}); + // final PubkeyCallBack isPubkey; + // GlobalKey _myKey = GlobalKey(); + const HistoryListView( {Key key, @required ScrollController scrollController, @@ -55,12 +59,12 @@ class HistoryListView extends StatelessWidget { leading: Text(repository[3].toString()), title: Text(repository[1].toString() + '\n' + - truncate(repository[2].toString(), 17, + truncate(repository[2], 17, omission: "...", position: TruncatePosition.end)), - subtitle: Text(repository[5].toString()), + subtitle: Text(repository[5]), dense: true, // enabled: _act == 2, - onTap: () {/* TODO: Load this history */}), + onTap: () {/* TODO: Load this history: repository[2] */}), if (historyData.isLoading) Row( mainAxisAlignment: MainAxisAlignment.center, @@ -80,3 +84,5 @@ class HistoryListView extends StatelessWidget { ); } } + +// typedef PubkeyCallBack = void Function(String pubkey); \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 0a25695..376b9d0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,42 +21,42 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.1" + version: "2.5.0-nullsafety.3" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.1" + version: "2.1.0-nullsafety.3" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0-nullsafety.5" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0-nullsafety.3" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.1" + version: "1.1.0-nullsafety.3" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.3" + version: "1.15.0-nullsafety.5" connectivity: dependency: transitive description: @@ -112,7 +112,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0-nullsafety.3" ffi: dependency: transitive description: @@ -282,20 +282,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.3" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.3-nullsafety.3" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.1" + version: "0.12.10-nullsafety.3" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0-nullsafety.6" nested: dependency: transitive description: @@ -323,9 +330,9 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.1" + version: "1.8.0-nullsafety.3" path_provider: - dependency: transitive + dependency: "direct main" description: name: path_provider url: "https://pub.dartlang.org" @@ -387,6 +394,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.0" + pin_code_fields: + dependency: "direct main" + description: + name: pin_code_fields + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.2" platform: dependency: transitive description: @@ -454,42 +468,42 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.2" + version: "1.8.0-nullsafety.4" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.1" + version: "1.10.0-nullsafety.6" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.1" + version: "2.1.0-nullsafety.3" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.1" + version: "1.1.0-nullsafety.3" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0-nullsafety.3" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.2" + version: "0.2.19-nullsafety.6" truncate: dependency: "direct main" description: @@ -503,7 +517,7 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0-nullsafety.5" uuid: dependency: transitive description: @@ -524,7 +538,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0-nullsafety.5" websocket: dependency: transitive description: @@ -561,5 +575,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0-110 <2.11.0" - flutter: ">=1.17.0 <2.0.0" + dart: ">=2.12.0-0.0 <3.0.0" + flutter: ">=1.22.0 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 1bc65e7..aaee89e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -34,6 +34,8 @@ dependencies: provider: ^4.3.2+3 truncate: ^2.1.2 sentry_flutter: ^4.0.1 + path_provider: ^1.6.24 + pin_code_fields: ^6.0.2 flutter_icons: