mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-23 02:54:30 +00:00
WIP connect tx flow
This commit is contained in:
parent
0177784c22
commit
e8ef0be977
2 changed files with 159 additions and 22 deletions
|
@ -2,11 +2,18 @@ import 'dart:async';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
import 'package:stackwallet/models/paynym/paynym_account_lite.dart';
|
||||
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
||||
import 'package:stackwallet/pages/paynym/dialogs/confirm_paynym_connect_dialog.dart';
|
||||
import 'package:stackwallet/pages/paynym/subwidgets/paynym_bot.dart';
|
||||
import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart';
|
||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||
import 'package:stackwallet/route_generator.dart';
|
||||
import 'package:stackwallet/services/coins/coin_paynym_extension.dart';
|
||||
import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||
|
@ -14,8 +21,9 @@ import 'package:stackwallet/widgets/custom_buttons/paynym_follow_toggle_button.d
|
|||
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
|
||||
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
||||
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
|
||||
import 'package:stackwallet/widgets/loading_indicator.dart';
|
||||
|
||||
class PaynymDetailsPopup extends StatefulWidget {
|
||||
class PaynymDetailsPopup extends ConsumerStatefulWidget {
|
||||
const PaynymDetailsPopup({
|
||||
Key? key,
|
||||
required this.walletId,
|
||||
|
@ -26,10 +34,103 @@ class PaynymDetailsPopup extends StatefulWidget {
|
|||
final PaynymAccountLite accountLite;
|
||||
|
||||
@override
|
||||
State<PaynymDetailsPopup> createState() => _PaynymDetailsPopupState();
|
||||
ConsumerState<PaynymDetailsPopup> createState() => _PaynymDetailsPopupState();
|
||||
}
|
||||
|
||||
class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> {
|
||||
Future<void> _onConnectPressed() async {
|
||||
bool canPop = false;
|
||||
unawaited(
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (context) => WillPopScope(
|
||||
onWillPop: () async => canPop,
|
||||
child: const LoadingIndicator(
|
||||
width: 200,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final wallet = ref
|
||||
.read(walletsChangeNotifierProvider)
|
||||
.getManager(widget.walletId)
|
||||
.wallet as DogecoinWallet;
|
||||
|
||||
// sanity check to prevent second notifcation tx
|
||||
if (wallet.hasConnectedConfirmed(widget.accountLite.code)) {
|
||||
canPop = true;
|
||||
Navigator.of(context).pop();
|
||||
// TODO show info popup
|
||||
return;
|
||||
} else if (wallet.hasConnected(widget.accountLite.code)) {
|
||||
canPop = true;
|
||||
Navigator.of(context).pop();
|
||||
// TODO show info popup
|
||||
return;
|
||||
}
|
||||
|
||||
final rates = await wallet.fees;
|
||||
|
||||
Map<String, dynamic> preparedTx;
|
||||
|
||||
try {
|
||||
preparedTx = await wallet.buildNotificationTx(
|
||||
selectedTxFeeRate: rates.medium,
|
||||
targetPaymentCodeString: widget.accountLite.code,
|
||||
);
|
||||
} on InsufficientBalanceException catch (e) {
|
||||
if (mounted) {
|
||||
canPop = true;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
// TODO show info popup
|
||||
print(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
// We have enough balance and prepared tx should be good to go.
|
||||
|
||||
canPop = true;
|
||||
// close loading
|
||||
Navigator.of(context).pop();
|
||||
|
||||
// Close details
|
||||
Navigator.of(context).pop();
|
||||
|
||||
// show info pop up
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (context) => ConfirmPaynymConnectDialog(
|
||||
nymName: widget.accountLite.nymName,
|
||||
onConfirmPressed: () {
|
||||
//
|
||||
print("CONFIRM NOTIF TX: $preparedTx");
|
||||
|
||||
Navigator.of(context).push(
|
||||
RouteGenerator.getRoute(
|
||||
builder: (_) => ConfirmTransactionView(
|
||||
walletId: wallet.walletId,
|
||||
transactionInfo: {
|
||||
"hex": preparedTx["hex"],
|
||||
"recipient": preparedTx["recipientPaynym"],
|
||||
"recipientAmt": preparedTx["amount"],
|
||||
"fee": preparedTx["fee"],
|
||||
"vSize": preparedTx["vSize"],
|
||||
"note": "PayNym connect"
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
amount: (preparedTx["amount"] as int) + (preparedTx["fee"] as int),
|
||||
coin: wallet.coin,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PaynymDetailsPopupState extends State<PaynymDetailsPopup> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DesktopDialog(
|
||||
|
@ -75,9 +176,7 @@ class _PaynymDetailsPopupState extends State<PaynymDetailsPopup> {
|
|||
),
|
||||
iconSpacing: 4,
|
||||
width: 86,
|
||||
onPressed: () {
|
||||
// todo notification tx
|
||||
},
|
||||
onPressed: _onConnectPressed,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -15,6 +15,8 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
|||
import 'package:stackwallet/utilities/format.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
import '../../utilities/logger.dart';
|
||||
|
||||
class SWException with Exception {
|
||||
SWException(this.message);
|
||||
|
||||
|
@ -180,7 +182,7 @@ extension PayNym on DogecoinWallet {
|
|||
Map<String, dynamic> transactionObject = {
|
||||
"hex": txn.item1,
|
||||
"recipientPaynym": targetPaymentCodeString,
|
||||
// "recipientAmt": recipientsAmtArray[0],
|
||||
"amount": amountToSend,
|
||||
"fee": feeBeingPaid,
|
||||
"vSize": txn.item2,
|
||||
};
|
||||
|
@ -200,7 +202,7 @@ extension PayNym on DogecoinWallet {
|
|||
Map<String, dynamic> transactionObject = {
|
||||
"hex": txn.item1,
|
||||
"recipientPaynym": targetPaymentCodeString,
|
||||
// "recipientAmt": recipientsAmtArray[0],
|
||||
"amount": amountToSend,
|
||||
"fee": feeBeingPaid,
|
||||
"vSize": txn.item2,
|
||||
};
|
||||
|
@ -221,7 +223,7 @@ extension PayNym on DogecoinWallet {
|
|||
Map<String, dynamic> transactionObject = {
|
||||
"hex": txn.item1,
|
||||
"recipientPaynym": targetPaymentCodeString,
|
||||
// "recipientAmt": recipientsAmtArray[0],
|
||||
"amount": amountToSend,
|
||||
"fee": feeBeingPaid,
|
||||
"vSize": txn.item2,
|
||||
};
|
||||
|
@ -290,7 +292,7 @@ extension PayNym on DogecoinWallet {
|
|||
final notificationScript = bscript.compile([bobP2PKH.output]);
|
||||
|
||||
// build a notification tx
|
||||
final txb = TransactionBuilder();
|
||||
final txb = TransactionBuilder(network: network);
|
||||
txb.setVersion(1);
|
||||
|
||||
txb.addInput(
|
||||
|
@ -330,20 +332,56 @@ extension PayNym on DogecoinWallet {
|
|||
return Tuple2(builtTx.toHex(), builtTx.virtualSize());
|
||||
}
|
||||
|
||||
Future<bool> hasConfirmedNotificationTxSentTo(
|
||||
String paymentCodeString) async {
|
||||
final targetPaymentCode =
|
||||
PaymentCode.fromPaymentCode(paymentCodeString, network);
|
||||
final targetNotificationAddress = targetPaymentCode.notificationAddress();
|
||||
Future<String> confirmNotificationTx(
|
||||
{required Map<String, dynamic> preparedTx}) async {
|
||||
try {
|
||||
Logging.instance.log("confirmNotificationTx txData: $preparedTx",
|
||||
level: LogLevel.Info);
|
||||
final txHash = await electrumXClient.broadcastTransaction(
|
||||
rawTx: preparedTx["hex"] as String);
|
||||
Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info);
|
||||
|
||||
final myTxHistory = (await transactionData)
|
||||
.getAllTransactions()
|
||||
.entries
|
||||
.map((e) => e.value)
|
||||
await updatePaynymNotificationInfo(
|
||||
txid: txHash,
|
||||
confirmed: false,
|
||||
paymentCodeString: preparedTx["paymentCodeString"] as String,
|
||||
);
|
||||
return txHash;
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s",
|
||||
level: LogLevel.Error);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
// Future<bool> hasConfirmedNotificationTxSentTo(
|
||||
// String paymentCodeString) async {
|
||||
// final targetPaymentCode =
|
||||
// PaymentCode.fromPaymentCode(paymentCodeString, network);
|
||||
// final targetNotificationAddress = targetPaymentCode.notificationAddress();
|
||||
//
|
||||
// final myTxHistory = (await transactionData)
|
||||
// .getAllTransactions()
|
||||
// .entries
|
||||
// .map((e) => e.value)
|
||||
// .where((e) =>
|
||||
// e.txType == "Sent" && e.address == targetNotificationAddress);
|
||||
//
|
||||
// return myTxHistory.isNotEmpty;
|
||||
// }
|
||||
|
||||
bool hasConnected(String paymentCodeString) {
|
||||
return getPaynymNotificationTxInfo()
|
||||
.where((e) => e["paymentCodeString"] == paymentCodeString)
|
||||
.isNotEmpty;
|
||||
}
|
||||
|
||||
bool hasConnectedConfirmed(String paymentCodeString) {
|
||||
return getPaynymNotificationTxInfo()
|
||||
.where((e) =>
|
||||
e.txType == "Sent" && e.address == targetNotificationAddress);
|
||||
|
||||
return myTxHistory.isNotEmpty;
|
||||
e["paymentCodeString"] == paymentCodeString &&
|
||||
e["confirmed"] == true)
|
||||
.isNotEmpty;
|
||||
}
|
||||
|
||||
// fetch paynym notification tx meta data
|
||||
|
|
Loading…
Reference in a new issue