Generic fixes for payjoin (#2342)
* feat: enhance Payjoin transaction details with block explorer link * feat: enhance Payjoin transaction details with block explorer link * fix: handle connectivity errors in Payjoin session operations
Konstantin Ullrich committed
Jun 27, 2025 at 15:38 UTC
b3c20a5818df13a8c5e4f2839f14ca473f9aa5c0
3 files changed
+24
-4
cw_bitcoin/lib/bitcoin_wallet_addresses.dart
+4
@@ -67,6 +67,8 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
67
payjoinManager.resumeSessions();
68
} catch (e) {
69
printV(e);
70
+ // Ignore Connectivity errors
71
+ if (!e.toString().contains("error sending request for url")) rethrow;
72
}
73
}
74
@@ -79,6 +81,8 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
81
payjoinManager.spawnReceiver(receiver: currentPayjoinReceiver!);
82
} catch (e) {
83
printV(e);
84
+ // Ignore Connectivity errors
85
+ if (!e.toString().contains("error sending request for url")) rethrow;
86
}
87
}
88
}
cw_bitcoin/lib/payjoin/payjoin_send_worker.dart
+2
-2
@@ -106,8 +106,8 @@ class PayjoinSenderWorker {
106
sendPort.send({'type': PayjoinSenderRequestTypes.requestPosted});
107
108
return await postRequest.$2.processResponse(response: response);
109
- } catch (e) {
110
- throw PayjoinSessionError.unrecoverable('Send V1 payjoin error: $e');
109
+ } catch (e, stack) {
110
+ throw PayjoinSessionError.unrecoverable('Send V1 payjoin error: $e, $stack');
111
}
112
}
113
lib/view_model/payjoin_details_view_model.dart
+18
-2
@@ -4,7 +4,9 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart';
4
import 'package:cake_wallet/generated/i18n.dart';
5
import 'package:cake_wallet/src/screens/trade_details/trade_details_list_card.dart';
6
import 'package:cake_wallet/src/screens/trade_details/trade_details_status_item.dart';
7
+import 'package:cake_wallet/src/screens/transaction_details/blockexplorer_list_item.dart';
8
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
9
+import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
10
import 'package:cake_wallet/themes/core/theme_store.dart';
11
import 'package:cake_wallet/utils/date_formatter.dart';
12
import 'package:cw_core/payjoin_session.dart';
@@ -12,6 +14,7 @@ import 'package:cw_core/transaction_info.dart';
14
import 'package:flutter/widgets.dart';
15
import 'package:hive_flutter/hive_flutter.dart';
16
import 'package:mobx/mobx.dart';
17
+import 'package:url_launcher/url_launcher.dart';
18
19
part 'payjoin_details_view_model.g.dart';
20
@@ -40,7 +43,7 @@ abstract class PayjoinDetailsViewModelBase with Store {
43
@observable
44
late PayjoinSession payjoinSession;
45
43
- final ObservableList<StandartListItem> items;
46
+ final ObservableList<TransactionDetailsListItem> items;
47
48
late final StreamSubscription<BoxEvent> listener;
49
@@ -69,12 +72,25 @@ abstract class PayjoinDetailsViewModelBase with Store {
72
title: S.current.error,
73
value: payjoinSession.error!,
74
),
72
- if (payjoinSession.txId?.isNotEmpty == true && transactionInfo != null)
75
+ if (payjoinSession.txId?.isNotEmpty == true && transactionInfo != null) ...[
76
StandartListItem(
77
title: S.current.transaction_details_transaction_id,
78
value: payjoinSession.txId!,
79
key: ValueKey('standard_list_item_transaction_details_id_key'),
80
+ ),
81
+ BlockExplorerListItem(
82
+ title: S.current.view_in_block_explorer,
83
+ value: '${S.current.view_transaction_on}mempool.space',
84
+ onTap: () async {
85
+ try {
86
+ final uri = Uri.parse('https://mempool.cakewallet.com/tx/${payjoinSession.txId!}');
87
+ if (await canLaunchUrl(uri))
88
+ await launchUrl(uri, mode: LaunchMode.externalApplication);
89
+ } catch (e) {}
90
+ },
91
+ key: ValueKey('block_explorer_list_item_wallet_type_key'),
92
)
93
+ ]
94
]);
95
96
if (transactionInfo != null) {