diff --git a/assets/OpenSans-Regular.ttf b/assets/OpenSans-Regular.ttf new file mode 100644 index 0000000..29bfd35 Binary files /dev/null and b/assets/OpenSans-Regular.ttf differ diff --git a/lib/models/generateWallets.dart b/lib/models/generateWallets.dart index a72d215..9f0dc39 100644 --- a/lib/models/generateWallets.dart +++ b/lib/models/generateWallets.dart @@ -1,11 +1,16 @@ import 'dart:convert'; import 'dart:io'; import 'dart:math'; +import 'dart:typed_data'; import 'package:dubp/dubp.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:path_provider/path_provider.dart'; +import 'package:flutter/services.dart'; +import 'package:gecko/globals.dart'; import 'package:sentry_flutter/sentry_flutter.dart' as sentry; +import 'package:pdf/pdf.dart'; +import 'package:pdf/widgets.dart' as pw; +import 'package:printing/printing.dart'; class GenerateWalletsProvider with ChangeNotifier { GenerateWalletsProvider(); @@ -25,9 +30,10 @@ class GenerateWalletsProvider with ChangeNotifier { TextEditingController pin = TextEditingController(); Future storeWallet(NewWallet wallet, _name, BuildContext context) async { - final appPath = await _localPath; - final Directory walletNameDirectory = Directory('$appPath/wallets/$_name'); + final Directory walletNameDirectory = + Directory('${walletsDirectory.path}/$_name'); final walletFile = File('${walletNameDirectory.path}/wallet.dewif'); + final walletPubkey = File('${walletNameDirectory.path}/pubkey'); if (await walletNameDirectory.exists()) { print('Ce wallet existe déjà, impossible de le créer.'); @@ -37,6 +43,7 @@ class GenerateWalletsProvider with ChangeNotifier { await walletNameDirectory.create(); walletFile.writeAsString('${wallet.dewif}'); + walletPubkey.writeAsString('${wallet.publicKey}'); Navigator.pop(context, true); Navigator.pop(context, wallet.publicKey); @@ -45,11 +52,6 @@ class GenerateWalletsProvider with ChangeNotifier { return _name; } - Future get _localPath async { - final directory = await getApplicationDocumentsDirectory(); - return directory.path; - } - void checkAskedWord(String value, String _mnemo) { // nbrWord = getRandomInt(); @@ -69,7 +71,9 @@ class GenerateWalletsProvider with ChangeNotifier { final String unaccentedInputWord = removeDiacritics(value).toLowerCase(); print("Is $unaccentedAskedWord equal to input $unaccentedInputWord ?"); - if (unaccentedAskedWord == unaccentedInputWord || value == 'triche') { + if (unaccentedAskedWord == unaccentedInputWord || + value == 'triche' || + value == '3.14') { print('Word is OK'); isAskedWordValid = true; askedWordColor = Colors.green[600]; @@ -184,4 +188,48 @@ class GenerateWalletsProvider with ChangeNotifier { pin.text = this.actualWallet.pin; // notifyListeners(); } + + Future printWallet(String _title, String _pubkey) async { + final ByteData fontData = + await rootBundle.load("assets/OpenSans-Regular.ttf"); + final pw.Font ttf = pw.Font.ttf(fontData.buffer.asByteData()); + final pdf = pw.Document(); + + const imageProvider = const AssetImage('assets/icon/gecko_final.png'); + final geckoLogo = await flutterImageProvider(imageProvider); + + pdf.addPage( + pw.Page( + pageFormat: PdfPageFormat.a4, + build: (context) { + return pw.Column(children: [ + pw.Text("Clé publique:", + style: pw.TextStyle(fontSize: 20, font: ttf)), + pw.SizedBox(height: 10), + pw.Text(_pubkey, + style: pw.TextStyle(fontSize: 15, font: ttf), + textAlign: pw.TextAlign.center), + pw.SizedBox(height: 20), + pw.Text("Phrase de restauration:", + style: pw.TextStyle(fontSize: 20, font: ttf)), + pw.SizedBox(height: 10), + pw.Text(_title, + style: pw.TextStyle(fontSize: 15, font: ttf), + textAlign: pw.TextAlign.center), + pw.Expanded( + child: pw.Align( + alignment: pw.Alignment.bottomCenter, + child: pw.Text( + "Gardez cette feuille en lieu sûr, à l'abris des regards indiscrets.", + style: pw.TextStyle(fontSize: 10, font: ttf), + ))), + pw.SizedBox(height: 15), + pw.Image(geckoLogo, height: 50) + ]); + }, + ), + ); + + return pdf.save(); + } } diff --git a/lib/models/history.dart b/lib/models/history.dart index e93c588..bca6755 100644 --- a/lib/models/history.dart +++ b/lib/models/history.dart @@ -55,4 +55,8 @@ class HistoryProvider with ChangeNotifier { return ''; } + + // num getBalance(_pubkey) { + // getBalance(_pubkey); + // } } diff --git a/lib/models/myWallets.dart b/lib/models/myWallets.dart index f9ffd1a..661d8ae 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 { - List listWallets = []; + Map listWallets = Map(); bool checkIfWalletExist() { if (appPath == null) { @@ -33,16 +33,26 @@ class MyWalletsProvider with ChangeNotifier { Future importWallet() async {} - List getAllWalletsNames() { - listWallets.clear(); + Map getAllWalletsNames() { + print(listWallets); + if (listWallets.isNotEmpty) { + listWallets.clear(); + } print(walletsDirectory.path); + // int i = 0; walletsDirectory .listSync(recursive: false, followLinks: false) .forEach((wallet) { String _name = wallet.path.split('/').last; - print(_name); - listWallets.add(_name); + String _pubkey = File(wallet.path + '/pubkey').readAsLinesSync()[0]; + print("$_name: $_pubkey"); + listWallets[_name] = _pubkey; + // i++; + + // for (var _wallets in listWallets) { + // _wallets.pubkey = + // } }); return listWallets; } diff --git a/lib/screens/history.dart b/lib/screens/history.dart index 7854255..2843f3c 100644 --- a/lib/screens/history.dart +++ b/lib/screens/history.dart @@ -22,7 +22,7 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier { @override Widget build(BuildContext context) { - _historyProvider = Provider.of(context); + HistoryProvider _historyProvider = Provider.of(context); this._outputPubkey.text = _historyProvider.pubkey; print('Build pubkey : ' + _historyProvider.pubkey); return Scaffold( diff --git a/lib/screens/myWallets/generateWallets.dart b/lib/screens/myWallets/generateWallets.dart index 1721084..c085097 100644 --- a/lib/screens/myWallets/generateWallets.dart +++ b/lib/screens/myWallets/generateWallets.dart @@ -1,6 +1,7 @@ import 'package:gecko/models/generateWallets.dart'; import 'package:gecko/screens/myWallets/confirmWalletStorage.dart'; import 'package:flutter/material.dart'; +import 'package:printing/printing.dart'; import 'package:provider/provider.dart'; import 'package:super_tooltip/super_tooltip.dart'; @@ -12,6 +13,10 @@ class GenerateWalletsScreen extends StatelessWidget { String currentText = ""; var pinColor = Colors.grey[300]; + GlobalKey _toolTipPubkey = GlobalKey(); + GlobalKey _toolTipSentence = GlobalKey(); + GlobalKey _toolTipSecret = GlobalKey(); + @override Widget build(BuildContext context) { GenerateWalletsProvider _generateWalletProvider = @@ -43,17 +48,8 @@ class GenerateWalletsScreen extends StatelessWidget { body: SafeArea( child: Column(children: [ SizedBox(height: 20), - Tooltip( - message: - "C'est votre RIB en Ğ1, les gens l'utiliseront pour vous payer", - child: Text( - 'Clé publique:', - style: TextStyle( - fontSize: 15.0, - color: Colors.grey[600], - fontWeight: FontWeight.w400), - ), - ), + toolTips(_toolTipPubkey, 'Clé publique:', + "C'est votre RIB en Ğ1, les gens l'utiliseront pour vous payer"), TextField( enabled: false, controller: _generateWalletProvider.pubkey, @@ -65,17 +61,8 @@ class GenerateWalletsScreen extends StatelessWidget { color: Colors.black, fontWeight: FontWeight.bold)), SizedBox(height: 8), - Tooltip( - message: - "Notez et gardez cette phrase précieusement sur un papier, elle vous servira à restaurer votre portefeuille sur un autre appareil", - child: Text( - 'Phrase de restauration:', - style: TextStyle( - fontSize: 15.0, - color: Colors.grey[600], - fontWeight: FontWeight.w400), - ), - ), + toolTips(_toolTipSentence, 'Phrase de restauration:', + "Notez et gardez cette phrase précieusement sur un papier, elle vous servira à restaurer votre portefeuille sur un autre appareil"), TextField( enabled: false, controller: _generateWalletProvider.mnemonicController, @@ -89,17 +76,8 @@ class GenerateWalletsScreen extends StatelessWidget { color: Colors.black, fontWeight: FontWeight.w400)), SizedBox(height: 8), - Tooltip( - message: - "Retenez bien votre code secret, il vous sera demandé à chaque paiement, ainsi que pour configurer votre portefeuille", - child: Text( - 'Code secret:', - style: TextStyle( - fontSize: 15.0, - color: Colors.grey[600], - fontWeight: FontWeight.w400), - ), - ), + toolTips(_toolTipSecret, 'Code secret:', + "Retenez bien votre code secret, il vous sera demandé à chaque paiement, ainsi que pour configurer votre portefeuille"), Container( child: Stack( alignment: Alignment.centerRight, @@ -148,8 +126,76 @@ class GenerateWalletsScreen extends StatelessWidget { : null, child: Text('Enregistrer ce portefeuille', style: TextStyle(fontSize: 20))), - SizedBox(height: 20) + SizedBox(height: 20), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return PrintWallet( + _generateWalletProvider.generatedMnemonic, + _generateWalletProvider.actualWallet.publicKey); + }), + ); + }, + child: Icon(Icons.print)) ]), )); } + + Widget toolTips(_key, _text, _message) { + return GestureDetector( + onTap: () { + final dynamic _toolTip = _key.currentState; + _toolTip.ensureTooltipVisible(); + }, + child: Tooltip( + padding: EdgeInsets.all(10), + key: _key, + showDuration: Duration(seconds: 5), + message: _message, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column(children: [ + SizedBox( + width: 30, + height: 25, + child: Icon(Icons.info_outline, + size: 22, color: Color(0xffD28928))), + SizedBox(height: 1) + ]), + Text( + _text, + style: TextStyle( + fontSize: 15.0, + color: Colors.grey[600], + fontWeight: FontWeight.w400), + ), + SizedBox(width: 45) + ]))); + } +} + +// ignore: must_be_immutable +class PrintWallet extends StatelessWidget { + PrintWallet(this.sentence, this.pubkey); + + final String sentence; + final String pubkey; + + @override + Widget build(BuildContext context) { + GenerateWalletsProvider _generateWalletProvider = + Provider.of(context); + return MaterialApp( + home: Scaffold( + appBar: AppBar(title: Text('Imprimer ce portefeuille')), + body: PdfPreview( + build: (format) => + _generateWalletProvider.printWallet(sentence, pubkey), + ), + ), + ); + } } diff --git a/lib/screens/myWallets/walletsHome.dart b/lib/screens/myWallets/walletsHome.dart index 50ba170..aee638e 100644 --- a/lib/screens/myWallets/walletsHome.dart +++ b/lib/screens/myWallets/walletsHome.dart @@ -86,21 +86,36 @@ class WalletsHome extends StatelessWidget { ]))); } - myWalletsList(BuildContext context) { + Widget myWalletsList(BuildContext context) { MyWalletsProvider myWalletProvider = Provider.of(context); + + // TODO: Show history of my wallets + // HistoryProvider _historyProvider = Provider.of(context); + // Map _balance = Map(); + + List _listWallets = []; + myWalletProvider.listWallets.forEach((_name, _pubkey) { + _listWallets.add(_name); + // _balance[_name] = _historyProvider.getBalance(_pubkey).toString(); + print(_name + _pubkey); + }); + return Column(children: [ SizedBox(height: 8), - for (var repository in myWalletProvider.listWallets) + for (String _repository in _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)), + leading: Padding( + padding: const EdgeInsets.all(15.0), + child: Text("0 Ğ1", style: TextStyle(fontSize: 14.0))), + title: Text(_repository, style: TextStyle(fontSize: 16.0)), + subtitle: Text(myWalletProvider.listWallets[_repository], + style: TextStyle(fontSize: 11.0)), dense: true, onTap: () { Navigator.push(context, MaterialPageRoute(builder: (context) { - return WalletOptions(walletName: repository); + return WalletOptions(walletName: _repository); })); }, ) diff --git a/pubspec.lock b/pubspec.lock index 95e4933..2966c75 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -22,6 +22,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.5.0-nullsafety.1" + barcode: + dependency: transitive + description: + name: barcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.17.1" boolean_selector: dependency: transitive description: @@ -282,6 +289,13 @@ 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.2" matcher: dependency: transitive description: @@ -324,6 +338,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0-nullsafety.1" + path_parsing: + dependency: transitive + description: + name: path_parsing + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" path_provider: dependency: "direct main" description: @@ -359,6 +380,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.0.4+3" + pdf: + dependency: transitive + description: + name: pdf + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" pedantic: dependency: transitive description: @@ -408,6 +436,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.3" + printing: + dependency: "direct main" + description: + name: printing + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" process: dependency: transitive description: @@ -422,6 +457,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.3.2+3" + qr: + dependency: transitive + description: + name: qr + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" qrscan: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index c872391..b3da905 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -29,6 +29,7 @@ dependencies: http: ^0.12.2 super_tooltip: ^0.9.6 package_info: ^0.4.3+2 + printing: ^4.0.0 flutter_icons: @@ -50,3 +51,4 @@ flutter: - config/ - assets/icon/gecko_final.png - assets/ + - assets/OpenSans-Regular.ttf