From d53facca05e9a0211e79ae146073d93a51307bfd Mon Sep 17 00:00:00 2001 From: poka Date: Thu, 19 May 2022 13:44:22 +0200 Subject: [PATCH] Can pay with substrate --- lib/providers/substrate_sdk.dart | 64 +++++++++++++++-- lib/providers/wallets_profiles.dart | 46 +++++------- lib/screens/myWallets/choose_wallet.dart | 48 ++++++++----- lib/screens/myWallets/unlocking_wallet.dart | 33 ++++----- lib/screens/myWallets/wallet_options.dart | 6 +- lib/screens/substrate_sandbox.dart | 80 ++++++++++----------- lib/screens/wallet_view.dart | 1 + 7 files changed, 165 insertions(+), 113 deletions(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index e880910..06e5acb 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -204,8 +204,59 @@ class SubstrateSdk with ChangeNotifier { return gen.mnemonic!; } - Future pay(BuildContext context, String address, double amount, - String password) async { + // Future pay(BuildContext context, String address, double amount, + // 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 pay(BuildContext context, + {required String fromAddress, + required String destAddress, + required double amount, + required String password}) async { + setCurrentWallet(fromAddress); + final sender = TxSenderData( keyring.current.address, keyring.current.pubKey, @@ -214,7 +265,7 @@ class SubstrateSdk with ChangeNotifier { try { final hash = await sdk.api.tx.signAndSend( txInfo, - [address, amount * 100], + [destAddress, amount * 100], password, onStatusChange: (status) { print('status: ' + status); @@ -224,10 +275,9 @@ class SubstrateSdk with ChangeNotifier { }, ); print(hash.toString()); - return true; - } catch (err) { - print(err.toString()); - return false; + return 'confirmed'; + } catch (e) { + return e.toString(); } } diff --git a/lib/providers/wallets_profiles.dart b/lib/providers/wallets_profiles.dart index 5284843..015124e 100644 --- a/lib/providers/wallets_profiles.dart +++ b/lib/providers/wallets_profiles.dart @@ -1,14 +1,10 @@ import 'dart:io'; - -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/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,34 +55,24 @@ class WalletsProfilesProvider with ChangeNotifier { return barcode; } - Future pay(BuildContext context, {int? derivation}) async { - MyWalletsProvider _myWalletProvider = - Provider.of(context, listen: false); - int? currentChest = configBox.get('currentChest'); - String result; + // Future pay(BuildContext context, {int? derivation}) async { + // MyWalletsProvider _myWalletProvider = + // Provider.of(context, listen: false); + // int? currentChest = configBox.get('currentChest'); + // String result; - if (chestBox.get(currentChest)!.isCesium!) { - 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 ??= - _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); - } + // 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) { final RegExp regExp = RegExp( diff --git a/lib/screens/myWallets/choose_wallet.dart b/lib/screens/myWallets/choose_wallet.dart index fc97230..ba80d24 100644 --- a/lib/screens/myWallets/choose_wallet.dart +++ b/lib/screens/myWallets/choose_wallet.dart @@ -3,6 +3,7 @@ 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/substrate_sdk.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/myWallets/wallets_home.dart'; import 'package:provider/provider.dart'; @@ -11,17 +12,20 @@ import 'package:provider/provider.dart'; // ignore: must_be_immutable 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; List? _selectedId; @override Widget build(BuildContext context) { SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); + SubstrateSdk _sdk = Provider.of(context, listen: false); + WalletsProfilesProvider _walletViewProvider = + Provider.of(context, listen: false); // HomeProvider _homeProvider = Provider.of(context); - WalletsProfilesProvider _walletsProfilesProvider = - Provider.of(context); - return Scaffold( appBar: AppBar( toolbarHeight: 60 * ratio, @@ -31,7 +35,7 @@ class ChooseWalletScreen extends StatelessWidget { )), body: SafeArea( child: Stack(children: [ - myWalletsTiles(context), + myWalletsTiles(context, chest), Positioned.fill( bottom: 60, child: Align( @@ -46,8 +50,15 @@ class ChooseWalletScreen extends StatelessWidget { onPrimary: Colors.white, // foreground ), onPressed: () async { - final resultPay = await _walletsProfilesProvider - .pay(context, derivation: _derivation); + final acc = _sdk.getCurrentWallet(); + 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); }, child: const Text( @@ -64,17 +75,18 @@ class ChooseWalletScreen extends StatelessWidget { )); } - Widget myWalletsTiles(BuildContext context) { + Widget myWalletsTiles(BuildContext context, int? currentChest) { MyWalletsProvider _myWalletProvider = Provider.of(context); final bool isWalletsExists = _myWalletProvider.checkIfWalletExist(); + SubstrateSdk _sdk = Provider.of(context, listen: false); WalletData? defaultWallet = - _myWalletProvider.getDefaultWallet(configBox.get('currentChest')); + _myWalletProvider.getDefaultWallet(currentChest); _selectedId ??= defaultWallet!.id(); _derivation ??= defaultWallet!.derivation!; - _myWalletProvider.readAllWallets(configBox.get('currentChest')); + _myWalletProvider.readAllWallets(currentChest); if (!isWalletsExists) { return const Text(''); @@ -116,6 +128,7 @@ class ChooseWalletScreen extends StatelessWidget { onTap: () { _derivation = _repository.derivation!; _selectedId = _repository.id(); + _sdk.setCurrentWallet(_repository.address!); _myWalletProvider.rebuildWidget(); }, child: ClipOvalShadow( @@ -182,6 +195,7 @@ class ChooseWalletScreen extends StatelessWidget { onTap: () { _derivation = _repository.derivation!; _selectedId = _repository.id(); + _sdk.setCurrentWallet(_repository.address!); _myWalletProvider.rebuildWidget(); }, ) @@ -201,18 +215,20 @@ Future paymentsResult(context, String resultPay) { barrierDismissible: true, // user must tap button! builder: (BuildContext context) { return AlertDialog( - title: Text(resultPay == "success" + title: Text(resultPay == "confirmed" ? 'Paiement effecuté avec succès !' : "Une erreur s'est produite lors du paiement:\n$resultPay"), content: const SingleChildScrollView(child: Text('')), actions: [ TextButton( child: const Text("OK"), - onPressed: () { - Navigator.popUntil( - context, - ModalRoute.withName('/'), - ); + onPressed: () async { + resultPay == "confirmed" + ? await Navigator.of(context).pushNamedAndRemoveUntil( + '/', + ModalRoute.withName('/'), + ) + : Navigator.pop(context); }, ), ], diff --git a/lib/screens/myWallets/unlocking_wallet.dart b/lib/screens/myWallets/unlocking_wallet.dart index d20f222..14355a3 100644 --- a/lib/screens/myWallets/unlocking_wallet.dart +++ b/lib/screens/myWallets/unlocking_wallet.dart @@ -22,6 +22,8 @@ class UnlockingWallet extends StatelessWidget { {Key? keyUnlockWallet, required this.wallet, required this.action}) : super(key: keyUnlockWallet); WalletData? wallet; + late int currentChestNumber; + late ChestData currentChest; String action; // ignore: close_sinks @@ -37,10 +39,9 @@ class UnlockingWallet extends StatelessWidget { Provider.of(context); // final double statusBarHeight = MediaQuery.of(context).padding.top; - int _pinLenght; - ChestData currentChest = chestBox.get(configBox.get('currentChest'))!; - - _pinLenght = _walletOptions.getPinLenght(wallet!.number); + currentChestNumber = configBox.get('currentChest'); + currentChest = chestBox.get(currentChestNumber)!; + int _pinLenght = _walletOptions.getPinLenght(wallet!.number); errorController = StreamController(); return Scaffold( @@ -102,7 +103,7 @@ class UnlockingWallet extends StatelessWidget { fontWeight: FontWeight.w400), )), SizedBox(height: 40 * ratio), - pinForm(context, _pinLenght, currentChest), + pinForm(context, _pinLenght), SizedBox(height: 3 * ratio), InkWell( key: const Key('chooseChest'), @@ -133,7 +134,7 @@ class UnlockingWallet extends StatelessWidget { )); } - Widget pinForm(context, _pinLenght, ChestData currentChest) { + Widget pinForm(context, _pinLenght) { // var _walletPin = ''; // ignore: close_sinks StreamController errorController = @@ -228,19 +229,13 @@ class UnlockingWallet extends StatelessWidget { }), ).then((value) => _myWalletProvider.cesiumSeed.clear()); } else if (action == "pay") { - if (currentChest.isCesium!) { - //TODO: implement substrate pay - // final resultPay = await _historyProvider.pay(context); - // final resultPay = await _sdk.pay(context); - // await paymentsResult(context, resultPay); - } else { - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return ChooseWalletScreen(); - }), - ); - } + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return ChooseWalletScreen( + chest: currentChestNumber, pin: _pin.toUpperCase()); + }), + ); } } }, diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index 4b1a0ca..5462ce5 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -32,7 +32,11 @@ class WalletOptions extends StatelessWidget { 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( onWillPop: () { diff --git a/lib/screens/substrate_sandbox.dart b/lib/screens/substrate_sandbox.dart index 9daa3c5..64cff88 100644 --- a/lib/screens/substrate_sandbox.dart +++ b/lib/screens/substrate_sandbox.dart @@ -56,46 +56,46 @@ class SubstrateSandBox extends StatelessWidget { ), const SizedBox(width: 10), ]), - FutureBuilder( - future: _sub.getKeyStoreAddress(), - builder: (BuildContext context, - AsyncSnapshot> _data) { - return Column(children: [ - if (_data.data != null) - for (final AddressInfo e in _data.data!) - Row(children: [ - InkWell( - onTap: () => _sub.keyring.setCurrent(_sub - .keyring.keyPairs - .firstWhere((element) => - element.address == e.address!)), - child: Text( - getShortPubkey(e.address!), - style: const TextStyle( - fontFamily: 'Monospace'), - ), - ), - const SizedBox(width: 20), - InkWell( - onTap: () async => await _sub.pay( - context, - e.address!, - 10, - _sub.keystorePassword.text), - child: Text("${e.balance.toString()} ğdev"), - ), - const SizedBox(width: 20), - InkWell( - onTap: () async => await _sub.derive( - context, - e.address!, - 3, - _sub.keystorePassword.text), - child: const Text("Dériver"), - ) - ]) - ]); - }), + // FutureBuilder( + // future: _sub.getKeyStoreAddress(), + // builder: (BuildContext context, + // AsyncSnapshot> _data) { + // return Column(children: [ + // if (_data.data != null) + // for (final AddressInfo addressInfo in _data.data!) + // Row(children: [ + // InkWell( + // onTap: () => _sub.keyring.setCurrent(_sub + // .keyring.keyPairs + // .firstWhere((element) => + // element.address == addressInfo.address!)), + // child: Text( + // getShortPubkey(addressInfo.address!), + // style: const TextStyle( + // fontFamily: 'Monospace'), + // ), + // ), + // const SizedBox(width: 20), + // InkWell( + // onTap: () async => await _sub.pay( + // context, + // addressInfo.address!, + // 10, + // _sub.keystorePassword.text), + // child: Text("${addressInfo.balance.toString()} ğdev"), + // ), + // const SizedBox(width: 20), + // InkWell( + // onTap: () async => await _sub.derive( + // context, + // addressInfo.address!, + // 3, + // _sub.keystorePassword.text), + // child: const Text("Dériver"), + // ) + // ]) + // ]); + // }), const SizedBox(height: 20), const Text('Mot de passe du trousseau:'), TextField( diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index 7444fbf..69d9a91 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -191,6 +191,7 @@ class WalletViewScreen extends StatelessWidget { Provider.of(context, listen: false); WalletData? defaultWallet = _myWalletProvider.getDefaultWallet(configBox.get('currentChest')); + _walletViewProvider.outputPubkey.text = pubkey!; showModalBottomSheet( shape: const RoundedRectangleBorder(