Can pay with substrate

This commit is contained in:
poka 2022-05-19 13:44:22 +02:00
parent 48d997c835
commit d53facca05
7 changed files with 165 additions and 113 deletions

View File

@ -204,8 +204,59 @@ class SubstrateSdk with ChangeNotifier {
return gen.mnemonic!; return gen.mnemonic!;
} }
Future<bool> pay(BuildContext context, String address, double amount, // Future<bool> pay(BuildContext context, String address, double amount,
String password) async { // String password) async {
// final sender = TxSenderData(
// keyring.current.address,
// keyring.current.pubKey,
// );
// final txInfo = TxInfoData('balances', 'transfer', sender);
// try {
// final hash = await sdk.api.tx.signAndSend(
// txInfo,
// [address, amount * 100],
// password,
// onStatusChange: (status) {
// print('status: ' + status);
// if (status == 'Ready') {
// snack(context, 'Transaction terminé');
// }
// },
// );
// print(hash.toString());
// return true;
// } catch (err) {
// print(err.toString());
// return false;
// }
// }
String setCurrentWallet(String address) {
try {
final acc = getKeypair(address);
keyring.setCurrent(acc);
return acc.address!;
} catch (e) {
return (e.toString());
}
}
KeyPairData getCurrentWallet() {
try {
final acc = keyring.current;
return acc;
} catch (e) {
return KeyPairData();
}
}
Future<String> pay(BuildContext context,
{required String fromAddress,
required String destAddress,
required double amount,
required String password}) async {
setCurrentWallet(fromAddress);
final sender = TxSenderData( final sender = TxSenderData(
keyring.current.address, keyring.current.address,
keyring.current.pubKey, keyring.current.pubKey,
@ -214,7 +265,7 @@ class SubstrateSdk with ChangeNotifier {
try { try {
final hash = await sdk.api.tx.signAndSend( final hash = await sdk.api.tx.signAndSend(
txInfo, txInfo,
[address, amount * 100], [destAddress, amount * 100],
password, password,
onStatusChange: (status) { onStatusChange: (status) {
print('status: ' + status); print('status: ' + status);
@ -224,10 +275,9 @@ class SubstrateSdk with ChangeNotifier {
}, },
); );
print(hash.toString()); print(hash.toString());
return true; return 'confirmed';
} catch (err) { } catch (e) {
print(err.toString()); return e.toString();
return false;
} }
} }

View File

@ -1,14 +1,10 @@
import 'dart:io'; import 'dart:io';
import 'package:durt/durt.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/screens/wallet_view.dart';
import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:jdenticon_dart/jdenticon_dart.dart'; import 'package:jdenticon_dart/jdenticon_dart.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:qrscan/qrscan.dart' as scanner; import 'package:qrscan/qrscan.dart' as scanner;
import 'dart:math'; import 'dart:math';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
@ -59,34 +55,24 @@ class WalletsProfilesProvider with ChangeNotifier {
return barcode; return barcode;
} }
Future<String> pay(BuildContext context, {int? derivation}) async { // Future<String> pay(BuildContext context, {int? derivation}) async {
MyWalletsProvider _myWalletProvider = // MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); // Provider.of<MyWalletsProvider>(context, listen: false);
int? currentChest = configBox.get('currentChest'); // int? currentChest = configBox.get('currentChest');
String result; // String result;
if (chestBox.get(currentChest)!.isCesium!) { // derivation ??=
result = await Gva(node: endPointGVA).pay( // _myWalletProvider.getDefaultWallet(currentChest)!.derivation!;
recipient: pubkey!, // result = await Gva(node: endPointGVA).pay(
amount: double.parse(payAmount.text), // recipient: pubkey!,
cesiumSeed: _myWalletProvider.cesiumSeed, // amount: double.parse(payAmount.text),
comment: payComment.text, // mnemonic: _myWalletProvider.mnemonic,
derivation: -1, // comment: payComment.text,
lang: appLang); // derivation: derivation,
} else { // lang: appLang);
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);
}
return result; // return result;
} // }
bool isPubkey(pubkey) { bool isPubkey(pubkey) {
final RegExp regExp = RegExp( final RegExp regExp = RegExp(

View File

@ -3,6 +3,7 @@ import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart'; import 'package:gecko/screens/myWallets/wallets_home.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -11,17 +12,20 @@ import 'package:provider/provider.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class ChooseWalletScreen extends StatelessWidget { class ChooseWalletScreen extends StatelessWidget {
ChooseWalletScreen({Key? key}) : super(key: key); ChooseWalletScreen({Key? key, required this.chest, required this.pin})
: super(key: key);
final int chest;
final String pin;
int? _derivation; int? _derivation;
List<int?>? _selectedId; List<int?>? _selectedId;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SubstrateSdk _sdk = Provider.of<SubstrateSdk>(context, listen: false);
WalletsProfilesProvider _walletViewProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context); // HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
WalletsProfilesProvider _walletsProfilesProvider =
Provider.of<WalletsProfilesProvider>(context);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
toolbarHeight: 60 * ratio, toolbarHeight: 60 * ratio,
@ -31,7 +35,7 @@ class ChooseWalletScreen extends StatelessWidget {
)), )),
body: SafeArea( body: SafeArea(
child: Stack(children: [ child: Stack(children: [
myWalletsTiles(context), myWalletsTiles(context, chest),
Positioned.fill( Positioned.fill(
bottom: 60, bottom: 60,
child: Align( child: Align(
@ -46,8 +50,15 @@ class ChooseWalletScreen extends StatelessWidget {
onPrimary: Colors.white, // foreground onPrimary: Colors.white, // foreground
), ),
onPressed: () async { onPressed: () async {
final resultPay = await _walletsProfilesProvider final acc = _sdk.getCurrentWallet();
.pay(context, derivation: _derivation); log.d(
"fromAddress: ${acc.address!},destAddress: ${_walletViewProvider.outputPubkey.text}, amount: ${double.parse(_walletViewProvider.payAmount.text)}, password: $pin");
final resultPay = await _sdk.pay(context,
fromAddress: acc.address!,
destAddress: _walletViewProvider.outputPubkey.text,
amount:
double.parse(_walletViewProvider.payAmount.text),
password: pin);
await paymentsResult(context, resultPay); await paymentsResult(context, resultPay);
}, },
child: const Text( child: const Text(
@ -64,17 +75,18 @@ class ChooseWalletScreen extends StatelessWidget {
)); ));
} }
Widget myWalletsTiles(BuildContext context) { Widget myWalletsTiles(BuildContext context, int? currentChest) {
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
final bool isWalletsExists = _myWalletProvider.checkIfWalletExist(); final bool isWalletsExists = _myWalletProvider.checkIfWalletExist();
SubstrateSdk _sdk = Provider.of<SubstrateSdk>(context, listen: false);
WalletData? defaultWallet = WalletData? defaultWallet =
_myWalletProvider.getDefaultWallet(configBox.get('currentChest')); _myWalletProvider.getDefaultWallet(currentChest);
_selectedId ??= defaultWallet!.id(); _selectedId ??= defaultWallet!.id();
_derivation ??= defaultWallet!.derivation!; _derivation ??= defaultWallet!.derivation!;
_myWalletProvider.readAllWallets(configBox.get('currentChest')); _myWalletProvider.readAllWallets(currentChest);
if (!isWalletsExists) { if (!isWalletsExists) {
return const Text(''); return const Text('');
@ -116,6 +128,7 @@ class ChooseWalletScreen extends StatelessWidget {
onTap: () { onTap: () {
_derivation = _repository.derivation!; _derivation = _repository.derivation!;
_selectedId = _repository.id(); _selectedId = _repository.id();
_sdk.setCurrentWallet(_repository.address!);
_myWalletProvider.rebuildWidget(); _myWalletProvider.rebuildWidget();
}, },
child: ClipOvalShadow( child: ClipOvalShadow(
@ -182,6 +195,7 @@ class ChooseWalletScreen extends StatelessWidget {
onTap: () { onTap: () {
_derivation = _repository.derivation!; _derivation = _repository.derivation!;
_selectedId = _repository.id(); _selectedId = _repository.id();
_sdk.setCurrentWallet(_repository.address!);
_myWalletProvider.rebuildWidget(); _myWalletProvider.rebuildWidget();
}, },
) )
@ -201,18 +215,20 @@ Future<bool?> paymentsResult(context, String resultPay) {
barrierDismissible: true, // user must tap button! barrierDismissible: true, // user must tap button!
builder: (BuildContext context) { builder: (BuildContext context) {
return AlertDialog( return AlertDialog(
title: Text(resultPay == "success" title: Text(resultPay == "confirmed"
? 'Paiement effecuté avec succès !' ? 'Paiement effecuté avec succès !'
: "Une erreur s'est produite lors du paiement:\n$resultPay"), : "Une erreur s'est produite lors du paiement:\n$resultPay"),
content: const SingleChildScrollView(child: Text('')), content: const SingleChildScrollView(child: Text('')),
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
child: const Text("OK"), child: const Text("OK"),
onPressed: () { onPressed: () async {
Navigator.popUntil( resultPay == "confirmed"
context, ? await Navigator.of(context).pushNamedAndRemoveUntil(
ModalRoute.withName('/'), '/',
); ModalRoute.withName('/'),
)
: Navigator.pop(context);
}, },
), ),
], ],

View File

@ -22,6 +22,8 @@ class UnlockingWallet extends StatelessWidget {
{Key? keyUnlockWallet, required this.wallet, required this.action}) {Key? keyUnlockWallet, required this.wallet, required this.action})
: super(key: keyUnlockWallet); : super(key: keyUnlockWallet);
WalletData? wallet; WalletData? wallet;
late int currentChestNumber;
late ChestData currentChest;
String action; String action;
// ignore: close_sinks // ignore: close_sinks
@ -37,10 +39,9 @@ class UnlockingWallet extends StatelessWidget {
Provider.of<WalletOptionsProvider>(context); Provider.of<WalletOptionsProvider>(context);
// final double statusBarHeight = MediaQuery.of(context).padding.top; // final double statusBarHeight = MediaQuery.of(context).padding.top;
int _pinLenght; currentChestNumber = configBox.get('currentChest');
ChestData currentChest = chestBox.get(configBox.get('currentChest'))!; currentChest = chestBox.get(currentChestNumber)!;
int _pinLenght = _walletOptions.getPinLenght(wallet!.number);
_pinLenght = _walletOptions.getPinLenght(wallet!.number);
errorController = StreamController<ErrorAnimationType>(); errorController = StreamController<ErrorAnimationType>();
return Scaffold( return Scaffold(
@ -102,7 +103,7 @@ class UnlockingWallet extends StatelessWidget {
fontWeight: FontWeight.w400), fontWeight: FontWeight.w400),
)), )),
SizedBox(height: 40 * ratio), SizedBox(height: 40 * ratio),
pinForm(context, _pinLenght, currentChest), pinForm(context, _pinLenght),
SizedBox(height: 3 * ratio), SizedBox(height: 3 * ratio),
InkWell( InkWell(
key: const Key('chooseChest'), key: const Key('chooseChest'),
@ -133,7 +134,7 @@ class UnlockingWallet extends StatelessWidget {
)); ));
} }
Widget pinForm(context, _pinLenght, ChestData currentChest) { Widget pinForm(context, _pinLenght) {
// var _walletPin = ''; // var _walletPin = '';
// ignore: close_sinks // ignore: close_sinks
StreamController<ErrorAnimationType> errorController = StreamController<ErrorAnimationType> errorController =
@ -228,19 +229,13 @@ class UnlockingWallet extends StatelessWidget {
}), }),
).then((value) => _myWalletProvider.cesiumSeed.clear()); ).then((value) => _myWalletProvider.cesiumSeed.clear());
} else if (action == "pay") { } else if (action == "pay") {
if (currentChest.isCesium!) { Navigator.push(
//TODO: implement substrate pay context,
// final resultPay = await _historyProvider.pay(context); MaterialPageRoute(builder: (context) {
// final resultPay = await _sdk.pay(context); return ChooseWalletScreen(
// await paymentsResult(context, resultPay); chest: currentChestNumber, pin: _pin.toUpperCase());
} else { }),
Navigator.push( );
context,
MaterialPageRoute(builder: (context) {
return ChooseWalletScreen();
}),
);
}
} }
} }
}, },

View File

@ -32,7 +32,11 @@ class WalletOptions extends StatelessWidget {
final int _currentChest = _myWalletProvider.getCurrentChest()!; final int _currentChest = _myWalletProvider.getCurrentChest()!;
log.d("Wallet options: $_currentChest:${wallet.number}"); //TODO: Debug multichest
// final currentWallet = _myWalletProvider.getDefaultWallet(_currentChest);
// log.d(_walletOptions.getAddress(_currentChest, 3));
// log.d("Wallet options: $_currentChest:${wallet.number}");
return WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {

View File

@ -56,46 +56,46 @@ class SubstrateSandBox extends StatelessWidget {
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
]), ]),
FutureBuilder( // FutureBuilder(
future: _sub.getKeyStoreAddress(), // future: _sub.getKeyStoreAddress(),
builder: (BuildContext context, // builder: (BuildContext context,
AsyncSnapshot<List<AddressInfo>> _data) { // AsyncSnapshot<List<AddressInfo>> _data) {
return Column(children: [ // return Column(children: [
if (_data.data != null) // if (_data.data != null)
for (final AddressInfo e in _data.data!) // for (final AddressInfo addressInfo in _data.data!)
Row(children: [ // Row(children: [
InkWell( // InkWell(
onTap: () => _sub.keyring.setCurrent(_sub // onTap: () => _sub.keyring.setCurrent(_sub
.keyring.keyPairs // .keyring.keyPairs
.firstWhere((element) => // .firstWhere((element) =>
element.address == e.address!)), // element.address == addressInfo.address!)),
child: Text( // child: Text(
getShortPubkey(e.address!), // getShortPubkey(addressInfo.address!),
style: const TextStyle( // style: const TextStyle(
fontFamily: 'Monospace'), // fontFamily: 'Monospace'),
), // ),
), // ),
const SizedBox(width: 20), // const SizedBox(width: 20),
InkWell( // InkWell(
onTap: () async => await _sub.pay( // onTap: () async => await _sub.pay(
context, // context,
e.address!, // addressInfo.address!,
10, // 10,
_sub.keystorePassword.text), // _sub.keystorePassword.text),
child: Text("${e.balance.toString()} ğdev"), // child: Text("${addressInfo.balance.toString()} ğdev"),
), // ),
const SizedBox(width: 20), // const SizedBox(width: 20),
InkWell( // InkWell(
onTap: () async => await _sub.derive( // onTap: () async => await _sub.derive(
context, // context,
e.address!, // addressInfo.address!,
3, // 3,
_sub.keystorePassword.text), // _sub.keystorePassword.text),
child: const Text("Dériver"), // child: const Text("Dériver"),
) // )
]) // ])
]); // ]);
}), // }),
const SizedBox(height: 20), const SizedBox(height: 20),
const Text('Mot de passe du trousseau:'), const Text('Mot de passe du trousseau:'),
TextField( TextField(

View File

@ -191,6 +191,7 @@ class WalletViewScreen extends StatelessWidget {
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
WalletData? defaultWallet = WalletData? defaultWallet =
_myWalletProvider.getDefaultWallet(configBox.get('currentChest')); _myWalletProvider.getDefaultWallet(configBox.get('currentChest'));
_walletViewProvider.outputPubkey.text = pubkey!;
showModalBottomSheet<void>( showModalBottomSheet<void>(
shape: const RoundedRectangleBorder( shape: const RoundedRectangleBorder(