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:
parent
f05c335073
commit
24d2ca5d0a
|
@ -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');
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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('/'),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
|
@ -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),
|
||||
]),
|
||||
));
|
||||
}
|
||||
}
|
|
@ -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('/'),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
]),
|
||||
);
|
||||
}),
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 = '');
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue