Optimize payments: Use direct mnemonic or cesium seed instead of dewif unlocking; Add screen to choose a wallet other than default wallet for payment; Can restore chest from settings

This commit is contained in:
poka 2021-12-30 00:51:04 +01:00
parent f05c335073
commit 24d2ca5d0a
15 changed files with 608 additions and 275 deletions

View File

@ -1,3 +1,6 @@
import 'dart:typed_data';
import 'package:durt/durt.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:gecko/globals.dart';
@ -6,6 +9,8 @@ import 'package:gecko/models/wallet_data.dart';
class MyWalletsProvider with ChangeNotifier {
List<WalletData> listWallets = [];
late String pinCode;
late String mnemonic;
late Uint8List cesiumSeed;
int? pinLenght;
int? getCurrentChest() {
@ -16,6 +21,24 @@ class MyWalletsProvider with ChangeNotifier {
return configBox.get('currentChest');
}
String dewifToMnemonic(context, WalletData _wallet, String _pin) {
String _mnemonic;
try {
String _localDewif = chestBox.get(_wallet.chest)!.dewif!;
_mnemonic = Dewif()
.mnemonicFromDewif(_localDewif, _pin.toUpperCase(), lang: appLang);
} on ChecksumException catch (e) {
log.e(e.cause);
return 'bad';
} catch (e) {
// _homeProvider.playSound('non', 0.6);
log.e('ERROR READING FILE: $e');
return 'bad';
}
return _mnemonic;
}
bool checkIfWalletExist() {
if (chestBox.isEmpty) {
log.i('No wallets detected');

View File

@ -4,11 +4,11 @@ import 'package:durt/durt.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/screens/wallet_view.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:jdenticon_dart/jdenticon_dart.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:qrscan/qrscan.dart' as scanner;
import 'dart:math';
import 'package:intl/intl.dart';
@ -59,29 +59,32 @@ class WalletsProfilesProvider with ChangeNotifier {
return barcode;
}
Future<String> pay(BuildContext context, String pinCode) async {
MyWalletsProvider _myWalletModel = MyWalletsProvider();
Future<String> pay(BuildContext context, {int? derivation}) async {
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
int? currentChest = configBox.get('currentChest');
WalletData? defaultWallet = _myWalletModel.getDefaultWallet(currentChest);
String dewif = chestBox.get(currentChest)!.dewif!;
int? derivation;
String result;
if (chestBox.get(currentChest)!.isCesium!) {
derivation = -1;
result = await Gva(node: endPointGVA).pay(
recipient: pubkey!,
amount: double.parse(payAmount.text),
cesiumSeed: _myWalletProvider.cesiumSeed,
comment: payComment.text,
derivation: -1,
lang: appLang);
} else {
derivation = defaultWallet!.derivation;
derivation ??=
_myWalletProvider.getDefaultWallet(currentChest)!.derivation!;
result = await Gva(node: endPointGVA).pay(
recipient: pubkey!,
amount: double.parse(payAmount.text),
mnemonic: _myWalletProvider.mnemonic,
comment: payComment.text,
derivation: derivation,
lang: appLang);
}
String result = await Gva(node: endPointGVA).pay(
recipient: pubkey!,
amount: double.parse(payAmount.text),
dewif: dewif,
password: pinCode,
comment: payComment.text,
derivation: derivation,
lang: appLang);
return result;
}

View File

@ -218,30 +218,28 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
return ((dayOfYear - date.weekday + 10) / 7).floor();
}
if (DateTime(date.year, date.month, date.day) ==
DateTime(now.year, now.month, now.day) &&
!isTody) {
final transactionDate = DateTime(date.year, date.month, date.day);
final todayDate = DateTime(now.year, now.month, now.day);
final yesterdayDate = DateTime(now.year, now.month, now.day - 1);
if (transactionDate == todayDate && !isTody) {
dateDelimiter = lastDateDelimiter = "Aujourd'hui";
isTody = true;
} else if (DateTime(date.year, date.month, date.day) ==
DateTime(now.year, now.month, now.day - 1) &&
!isYesterday) {
} else if (transactionDate == yesterdayDate && !isYesterday) {
dateDelimiter = lastDateDelimiter = "Hier";
isYesterday = true;
} else if (weekNumber(date) == weekNumber(now) &&
date.year == now.year &&
lastDateDelimiter != "Cette semaine" &&
DateTime(date.year, date.month, date.day) !=
DateTime(now.year, now.month, now.day - 1) &&
transactionDate != yesterdayDate &&
transactionDate != todayDate &&
!isThisWeek) {
dateDelimiter = lastDateDelimiter = "Cette semaine";
isThisWeek = true;
} else if (lastDateDelimiter != monthsInYear[date.month] &&
lastDateDelimiter != "${monthsInYear[date.month]} ${date.year}" &&
DateTime(date.year, date.month, date.day) !=
DateTime(now.year, now.month, now.day) &&
DateTime(date.year, date.month, date.day) !=
DateTime(now.year, now.month, now.day - 1) &&
transactionDate != todayDate &&
transactionDate != yesterdayDate &&
!(weekNumber(date) == weekNumber(now) && date.year == now.year)) {
if (date.year == now.year) {
dateDelimiter = lastDateDelimiter = monthsInYear[date.month];

View File

@ -65,13 +65,11 @@ class HomeScreen extends StatelessWidget {
);
},
),
ListTile(
title: const Text('A propos'),
onTap: () {
// Update the state of the app.
// ...
},
),
// ListTile(
// title: const Text('A propos'),
// onTap: () {
// },
// ),
])),
Align(
alignment: FractionalOffset.bottomCenter,

View File

@ -16,7 +16,6 @@ import 'package:provider/provider.dart';
import 'package:flutter/services.dart';
import 'package:qr_flutter/qr_flutter.dart';
int _nbrLinesName = 1;
bool _isNewNameValid = false;
class CesiumWalletOptions extends StatelessWidget {
@ -47,13 +46,6 @@ class CesiumWalletOptions extends StatelessWidget {
cesiumWallet.name = _walletOptions.nameController.text;
}
_walletOptions.nameController.text.length >= 15
? _nbrLinesName = 2
: _nbrLinesName = 1;
if (_walletOptions.nameController.text.length >= 26 && isTall) {
_nbrLinesName = 3;
}
return WillPopScope(
onWillPop: () {
_walletOptions.isEditing = false;
@ -102,36 +94,40 @@ class CesiumWalletOptions extends StatelessWidget {
const Color(0xfffafafa),
],
)),
child: Row(children: <Widget>[
const SizedBox(width: 25),
InkWell(
onTap: () async {
File newAvatar = await (_walletOptions.changeAvatar());
cesiumWallet.imageFile = newAvatar;
_walletOptions.reloadBuild();
},
child: cesiumWallet.imageFile == null
? Image.asset(
'assets/chests/${cesiumWallet.imageName}',
width: 110,
)
: Image.file(cesiumWallet.imageFile!, width: 110),
),
InkWell(
onTap: () async {
File newAvatar = await (_walletOptions.changeAvatar());
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
const Spacer(flex: 1),
InkWell(
onTap: () async {
File newAvatar =
await (_walletOptions.changeAvatar());
cesiumWallet.imageFile = newAvatar;
_walletOptions.reloadBuild();
},
child: Column(children: <Widget>[
Image.asset(
'assets/walletOptions/camera.png',
height: 40,
),
const SizedBox(height: 80)
])),
Column(children: <Widget>[
Row(children: <Widget>[
_walletOptions.reloadBuild();
},
child: cesiumWallet.imageFile == null
? Image.asset(
'assets/chests/${cesiumWallet.imageName}',
width: 110,
)
: Image.file(cesiumWallet.imageFile!, width: 110),
),
InkWell(
onTap: () async {
File newAvatar =
await (_walletOptions.changeAvatar());
cesiumWallet.imageFile = newAvatar;
_walletOptions.reloadBuild();
},
child: Column(children: <Widget>[
Image.asset(
'assets/walletOptions/camera.png',
height: 40,
),
const SizedBox(height: 80)
])),
const Spacer(flex: 1),
Column(children: <Widget>[
SizedBox(
width: 260,
@ -141,7 +137,8 @@ class CesiumWalletOptions extends StatelessWidget {
focusNode: _walletOptions.walletNameFocus,
enabled: _walletOptions.isEditing,
controller: _walletOptions.nameController,
maxLines: _nbrLinesName,
minLines: 1,
maxLines: 3,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
@ -151,10 +148,10 @@ class CesiumWalletOptions extends StatelessWidget {
contentPadding: EdgeInsets.all(15.0),
),
style: TextStyle(
fontSize: isTall ? 27 : 23,
color: Colors.black,
fontWeight: FontWeight.w400,
fontFamily: 'Monospace')),
fontSize: isTall ? 27 : 23,
color: Colors.black,
fontWeight: FontWeight.w400,
)),
),
SizedBox(height: isTall ? 5 : 0),
Query(
@ -231,7 +228,6 @@ class CesiumWalletOptions extends StatelessWidget {
),
),
]),
const SizedBox(width: 0),
Column(children: <Widget>[
InkWell(
key: const Key('renameWallet'),
@ -254,10 +250,9 @@ class CesiumWalletOptions extends StatelessWidget {
const SizedBox(
height: 60,
)
])
]),
const Spacer(flex: 3),
]),
]),
]),
);
}),
SizedBox(height: 4 * ratio),

View File

@ -0,0 +1,222 @@
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart';
import 'package:provider/provider.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
// ignore: must_be_immutable
class ChooseWalletScreen extends StatelessWidget {
ChooseWalletScreen({Key? key}) : super(key: key);
int? _derivation;
List<int?>? _selectedId;
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
WalletsProfilesProvider _walletsProfilesProvider =
Provider.of<WalletsProfilesProvider>(context);
return Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: const SizedBox(
height: 22,
child: Text('Choix du portefeuille source'),
)),
body: SafeArea(
child: Stack(children: [
myWalletsTiles(context),
Positioned.fill(
bottom: 60,
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: 470,
height: 70,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () async {
final resultPay = await _walletsProfilesProvider
.pay(context, derivation: _derivation);
await paymentsResult(context, resultPay);
},
child: const Text(
'Valider le paiement',
style:
TextStyle(fontSize: 24, fontWeight: FontWeight.w600),
),
),
),
),
),
// const SizedBox(height: 160),
]),
));
}
Widget myWalletsTiles(BuildContext context) {
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
final bool isWalletsExists = _myWalletProvider.checkIfWalletExist();
WalletData? defaultWallet =
_myWalletProvider.getDefaultWallet(configBox.get('currentChest'));
_selectedId ??= defaultWallet!.id();
_derivation ??= defaultWallet!.derivation!;
_myWalletProvider.readAllWallets(configBox.get('currentChest'));
if (!isWalletsExists) {
return const Text('');
}
if (_myWalletProvider.listWallets.isEmpty) {
return Column(children: const <Widget>[
Center(
child: Text(
'Veuillez générer votre premier portefeuille',
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w500),
)),
]);
}
List _listWallets = _myWalletProvider.listWallets;
final double screenWidth = MediaQuery.of(context).size.width;
int nTule = 2;
if (screenWidth >= 900) {
nTule = 4;
} else if (screenWidth >= 650) {
nTule = 3;
}
return CustomScrollView(slivers: <Widget>[
const SliverToBoxAdapter(child: SizedBox(height: 20)),
SliverGrid.count(
key: const Key('listWallets'),
crossAxisCount: nTule,
childAspectRatio: 1,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
children: <Widget>[
for (WalletData _repository in _listWallets as Iterable<WalletData>)
Padding(
padding: const EdgeInsets.all(16),
child: GestureDetector(
onTap: () {
_derivation = _repository.derivation!;
_selectedId = _repository.id();
_myWalletProvider.rebuildWidget();
},
child: ClipOvalShadow(
shadow: const Shadow(
color: Colors.transparent,
offset: Offset(0, 0),
blurRadius: 5,
),
clipper: CustomClipperOval(),
child: ClipRRect(
borderRadius:
const BorderRadius.all(Radius.circular(12)),
child: Column(children: <Widget>[
Expanded(
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
gradient: RadialGradient(
radius: 0.6,
colors: [
Colors.green[400]!,
const Color(0xFFE7E7A6),
],
)),
child: _repository.imageFile == null
? Image.asset(
'assets/avatars/${_repository.imageName}',
alignment: Alignment.bottomCenter,
scale: 0.5,
)
: Image.file(
_repository.imageFile!,
alignment: Alignment.bottomCenter,
scale: 0.5,
),
)),
ListTile(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
bottom: Radius.circular(12),
),
),
tileColor: _repository.id()[1] == _selectedId![1]
? orangeC
: const Color(0xffFFD58D),
title: Center(
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 5),
child: Text(
_repository.name!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 17.0,
color:
_repository.id()[1] == _selectedId![1]
? const Color(0xffF9F9F1)
: Colors.black,
fontStyle: FontStyle.italic),
),
),
),
onTap: () {
_derivation = _repository.derivation!;
_selectedId = _repository.id();
_myWalletProvider.rebuildWidget();
},
)
]),
),
),
)),
]),
]);
}
}
Future<bool?> paymentsResult(context, String resultPay) {
if (resultPay != "success") log.e(resultPay);
return showDialog<bool>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text(resultPay == "success"
? 'Paiement effecuté avec succès !'
: "Une erreur s'est produite lors du paiement:\n$resultPay"),
content: const SingleChildScrollView(child: Text('')),
actions: <Widget>[
TextButton(
child: const Text("OK"),
onPressed: () {
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
},
),
],
);
},
);
}

View File

@ -0,0 +1,44 @@
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
// ignore: must_be_immutable
class TransactionCommentScreen extends StatelessWidget {
TextEditingController tplController = TextEditingController();
TransactionCommentScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
return Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: const SizedBox(
height: 22,
child: Text('Confirmer le paiement'),
),
),
body: SafeArea(
child: Column(children: <Widget>[
const SizedBox(height: 20),
TextField(
enabled: true,
controller: tplController,
maxLines: 1,
textAlign: TextAlign.center,
decoration: const InputDecoration(
contentPadding: EdgeInsets.all(15.0),
),
style: const TextStyle(
fontSize: 22.0,
color: Colors.black,
fontWeight: FontWeight.w400)),
const SizedBox(height: 20),
]),
));
}
}

View File

@ -1,4 +1,5 @@
import 'dart:async';
import 'package:durt/durt.dart';
import 'package:flutter/services.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/providers/wallets_profiles.dart';
@ -8,6 +9,7 @@ import 'package:gecko/providers/wallet_options.dart';
import 'package:flutter/material.dart';
import 'package:gecko/screens/myWallets/cesium_wallet_options.dart';
import 'package:gecko/screens/myWallets/choose_chest.dart';
import 'package:gecko/screens/myWallets/choose_wallet.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:provider/provider.dart';
@ -26,7 +28,6 @@ class UnlockingWallet extends StatelessWidget {
final formKey = GlobalKey<FormState>();
Color? pinColor = const Color(0xffF9F9F1);
var walletPin = '';
String? resultPay;
@override
Widget build(BuildContext context) {
@ -201,20 +202,38 @@ class UnlockingWallet extends StatelessWidget {
onCompleted: (_pin) async {
log.d("Completed");
_myWalletProvider.pinCode = _pin;
final String? resultWallet = _walletOptions.readLocalWallet(
context, wallet!, _pin.toUpperCase(), _pinLenght);
if (currentChest.isCesium!) {
try {
String _localDewif = chestBox.get(wallet!.chest)!.dewif!;
final cesiumWallet =
CesiumWallet.fromDewif(_localDewif, _pin.toUpperCase());
_walletOptions.pubkey.text = cesiumWallet.pubkey;
_myWalletProvider.cesiumSeed = cesiumWallet.seed;
_myWalletProvider.mnemonic = 'cesium';
} catch (e) {
log.e(e);
_myWalletProvider.mnemonic = 'bad';
}
} else {
_myWalletProvider.mnemonic = _myWalletProvider.dewifToMnemonic(
context, wallet!, _pin.toUpperCase());
}
// final String? resultWallet = _walletOptions.readLocalWallet(
// context, wallet!, _pin.toUpperCase(), _pinLenght);
// _myWalletProvider.pinCode = _pin.toUpperCase();
_myWalletProvider.pinLenght = _pinLenght;
if (resultWallet == 'bad') {
if (_myWalletProvider.mnemonic == 'bad') {
await Future.delayed(const Duration(milliseconds: 50));
errorController.add(ErrorAnimationType
.shake); // Triggering error shake animation
pinColor = Colors.red[600];
_myWalletProvider.pinCode = _myWalletProvider.mnemonic = '';
_walletOptions.reloadBuild();
pinFocus.requestFocus();
} else {
pinColor = Colors.green[400];
// await Future.delayed(Duration(milliseconds: 50));
if (action == "mywallets") {
currentChest.isCesium!
? Navigator.push(
@ -223,17 +242,25 @@ class UnlockingWallet extends StatelessWidget {
return CesiumWalletOptions(
cesiumWallet: currentChest);
}),
)
).then((value) => _myWalletProvider.mnemonic = '')
: Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const WalletsHome();
}),
);
).then((value) => _myWalletProvider.cesiumSeed.clear());
} else if (action == "pay") {
resultPay =
await _historyProvider.pay(context, _pin.toUpperCase());
await _paymentsResult(context);
if (currentChest.isCesium!) {
final resultPay = await _historyProvider.pay(context);
await paymentsResult(context, resultPay);
} else {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return ChooseWalletScreen();
}),
);
}
}
}
},
@ -245,31 +272,4 @@ class UnlockingWallet extends StatelessWidget {
)),
);
}
Future<bool?> _paymentsResult(context) {
if (resultPay != "success") log.i(resultPay);
return showDialog<bool>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text(resultPay == "success"
? 'Paiement effecuté avec succès !'
: "Une erreur s'est produite lors du paiement:\n$resultPay"),
content: const SingleChildScrollView(child: Text('')),
actions: <Widget>[
TextButton(
child: const Text("OK"),
onPressed: () {
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
},
),
],
);
},
);
}
}

View File

@ -83,17 +83,15 @@ class WalletOptions extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
const Spacer(),
const Spacer(flex: 1),
avatar(walletProvider),
const Spacer(),
const Spacer(flex: 1),
Column(children: <Widget>[
walletName(walletProvider, _walletOptions),
SizedBox(height: isTall ? 5 : 0),
balance(walletProvider),
]),
const Spacer(),
const Spacer(),
const Spacer(),
const Spacer(flex: 3),
]),
);
}),

View File

@ -1,3 +1,4 @@
import 'package:durt/durt.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart';
@ -29,6 +30,7 @@ class WalletsHome extends StatelessWidget {
return WillPopScope(
onWillPop: () {
myWalletProvider.pinCode = myWalletProvider.mnemonic = '';
Navigator.popUntil(
context,
ModalRoute.withName('/'),
@ -41,6 +43,7 @@ class WalletsHome extends StatelessWidget {
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
myWalletProvider.pinCode = myWalletProvider.mnemonic = '';
Navigator.popUntil(
context,
ModalRoute.withName('/'),
@ -177,8 +180,11 @@ class WalletsHome extends StatelessWidget {
padding: const EdgeInsets.all(16),
child: GestureDetector(
onTap: () {
_walletOptions.readLocalWallet(context, _repository,
_myWalletProvider.pinCode, pinLength);
// _walletOptions.readLocalWallet(context, _repository,
// _myWalletProvider.pinCode, pinLength);
_walletOptions.pubkey.text =
HdWallet.fromMnemonic(_myWalletProvider.mnemonic)
.getPubkey(_repository.derivation!);
Navigator.push(
context,
SmoothTransition(
@ -264,11 +270,15 @@ class WalletsHome extends StatelessWidget {
),
// dense: true,
onTap: () {
_walletOptions.readLocalWallet(
context,
_repository,
_myWalletProvider.pinCode,
pinLength);
// _walletOptions.readLocalWallet(
// context,
// _repository,
// _myWalletProvider.pinCode,
// pinLength);
_walletOptions.pubkey.text =
HdWallet.fromMnemonic(
_myWalletProvider.mnemonic)
.getPubkey(_repository.derivation!);
Navigator.push(
context,
SmoothTransition(

View File

@ -6,6 +6,7 @@ import 'package:gecko/screens/myWallets/generate_wallets.dart';
import 'dart:io';
import 'package:gecko/screens/myWallets/import_cesium_wallet.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/screens/myWallets/restore_chest.dart';
// ignore: must_be_immutable
class SettingsScreen extends StatelessWidget {
@ -39,43 +40,74 @@ class SettingsScreen extends StatelessWidget {
body: Column(children: <Widget>[
const SizedBox(height: 40),
SizedBox(
height: 70,
width: 500,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 5,
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const ImportWalletScreen();
}),
).then((value) => {
if (value == true) {Navigator.pop(context)}
}),
child: const Text("Importer un portefeuille Cesium",
style: TextStyle(fontSize: 16)))),
height: 70,
width: 500,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 5,
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const ImportWalletScreen();
}),
).then((value) => {
if (value == true) {Navigator.pop(context)}
}),
child: const Text(
"Importer un portefeuille Cesium",
style: TextStyle(fontSize: 16),
),
),
),
const SizedBox(height: 30),
SizedBox(
height: 70,
width: 500,
child: ElevatedButton(
key: const Key('generateKeychain'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return GenerateFastChestScreen();
}),
),
child: const Text("Générer un nouveau trousseau",
style: TextStyle(fontSize: 16)))),
height: 70,
width: 500,
child: ElevatedButton(
key: const Key('generateKeychain'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return GenerateFastChestScreen();
}),
),
child: const Text(
"Générer un nouveau trousseau",
style: TextStyle(fontSize: 16),
),
),
),
const SizedBox(height: 30),
SizedBox(
height: 70,
width: 500,
child: ElevatedButton(
key: const Key('generateKeychain'),
style: ElevatedButton.styleFrom(
elevation: 5,
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const RestoreChest();
}),
),
child: const Text(
"Restaurer un coffre",
style: TextStyle(fontSize: 16),
),
),
),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,

View File

@ -31,6 +31,8 @@ class WalletViewScreen extends StatelessWidget {
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
_historyProvider.pubkey = pubkey!;
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
@ -185,7 +187,8 @@ class WalletViewScreen extends StatelessWidget {
// WalletsProfilesProvider _walletViewProvider =
// Provider.of<WalletsProfilesProvider>(context);
const double shapeSize = 20;
MyWalletsProvider _myWalletProvider = MyWalletsProvider();
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
WalletData? defaultWallet =
_myWalletProvider.getDefaultWallet(configBox.get('currentChest'));
@ -199,111 +202,120 @@ class WalletViewScreen extends StatelessWidget {
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Container(
height: 400,
decoration: const ShapeDecoration(
color: Color(0xffffeed1),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(shapeSize),
topLeft: Radius.circular(shapeSize),
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Container(
height: 400,
decoration: const ShapeDecoration(
color: Color(0xffffeed1),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(shapeSize),
topLeft: Radius.circular(shapeSize),
),
),
),
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text(
'Effectuer un virement',
style: TextStyle(
fontSize: 26, fontWeight: FontWeight.w700),
),
const SizedBox(height: 20),
Text(
'Saisissez dans le champ ci-dessous le montant à virer.',
style: TextStyle(
fontSize: 19,
fontWeight: FontWeight.w500,
color: Colors.grey[600]),
),
const Spacer(),
Center(
child: Column(children: <Widget>[
TextField(
controller: _walletViewProvider.payAmount,
autofocus: true,
maxLines: 1,
textAlign: TextAlign.center,
keyboardType: TextInputType.number,
onChanged: (_) => setState(() {}),
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(
RegExp(r'^\d+\.?\d{0,2}')),
],
// onChanged: (v) => _searchProvider.rebuildWidget(),
decoration: InputDecoration(
hintText: '0.00',
suffix: const Text('Ğ1'),
filled: true,
fillColor: Colors.transparent,
// border: OutlineInputBorder(
// borderSide:
// BorderSide(color: Colors.grey[500], width: 2),
// borderRadius: BorderRadius.circular(8)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.grey[500]!, width: 2),
borderRadius: BorderRadius.circular(8),
),
contentPadding: const EdgeInsets.all(20),
),
style: const TextStyle(
fontSize: 40,
color: Colors.black,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 40),
// const Spacer(),
SizedBox(
width: double.infinity,
height: 60,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed:
_walletViewProvider.payAmount.text != ''
? () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return UnlockingWallet(
wallet: defaultWallet,
action: "pay");
},
),
);
}
: null,
child: const Text(
'Effectuer le virement',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600),
),
),
),
const SizedBox(height: 20),
]),
),
]),
),
),
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text(
'Effectuer un virement',
style: TextStyle(
fontSize: 26, fontWeight: FontWeight.w700),
),
const SizedBox(height: 20),
Text(
'Saisissez dans le champ ci-dessous le montant à virer de ... vers ...',
style: TextStyle(
fontSize: 19,
fontWeight: FontWeight.w500,
color: Colors.grey[600]),
),
const Spacer(),
Center(
child: Column(children: <Widget>[
TextField(
controller: _walletViewProvider.payAmount,
autofocus: true,
maxLines: 1,
textAlign: TextAlign.center,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(
RegExp(r'^\d+\.?\d{0,2}')),
],
// onChanged: (v) => _searchProvider.rebuildWidget(),
decoration: InputDecoration(
hintText: '0.00',
suffix: const Text('Ğ1'),
filled: true,
fillColor: Colors.transparent,
// border: OutlineInputBorder(
// borderSide:
// BorderSide(color: Colors.grey[500], width: 2),
// borderRadius: BorderRadius.circular(8)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.grey[500]!, width: 2),
borderRadius: BorderRadius.circular(8),
),
contentPadding: const EdgeInsets.all(20),
),
style: const TextStyle(
fontSize: 40,
color: Colors.black,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 40),
// const Spacer(),
SizedBox(
width: double.infinity,
height: 60,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return UnlockingWallet(
wallet: defaultWallet, action: "pay");
},
),
);
},
child: const Text(
'Effectuer le virement',
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.w600),
),
),
),
const SizedBox(height: 20),
]),
),
]),
),
),
);
);
});
}).then((value) => _walletViewProvider.payAmount.text = '');
}

View File

@ -301,7 +301,7 @@ packages:
name: durt
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5+7"
version: "0.1.6"
fake_async:
dependency: transitive
description:

View File

@ -5,7 +5,7 @@ description: Pay with G1.
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 0.0.4+6
version: 0.0.4+8
environment:
sdk: '>=2.12.0 <3.0.0'
@ -62,7 +62,7 @@ dependencies:
pull_to_refresh: ^2.0.0
dio: ^4.0.4
desktop_window: ^0.4.0
durt: ^0.1.5+7
durt: ^0.1.6
package_info_plus: ^1.3.0
flutter_icons:

View File

@ -13,8 +13,6 @@ echo "Nom du build final: ${APPNAME}-${VERSION}+${BUILD}.apk"
## To build Rust dependancies
# cargo br
echo "To compile Rust binding, exec: cargo br"
flutter clean
if [[ $1 == "bundle" ]]; then
flutter build appbundle --release --target-platform android-arm,android-arm64 --build-name $VERSION --build-number $BUILD