dev
dart 199 lines 6.05 KB
Raw
1 import 'package:cake_wallet/di.dart';
2 import 'package:cake_wallet/generated/i18n.dart';
3 import 'package:cake_wallet/new-ui/widgets/new_primary_button.dart';
4 import 'package:cake_wallet/src/screens/base_page.dart';
5 import 'package:cake_wallet/src/screens/wallet_connect/services/walletkit_service.dart';
6 import 'package:cake_wallet/src/screens/wallet_connect/utils/wc_permissions_mapper.dart';
7 import 'package:cake_wallet/src/screens/wallet_connect/widgets/wc_dapp_card.dart';
8 import 'package:cake_wallet/src/screens/wallet_connect/widgets/wc_permissions_card.dart';
9 import 'package:cake_wallet/src/screens/wallet_connect/widgets/wc_wallet_card.dart';
10 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
11 import 'package:cake_wallet/store/app_store.dart';
12 import 'package:cake_wallet/utils/show_pop_up.dart';
13 import 'package:flutter/material.dart';
14 import 'package:reown_walletkit/reown_walletkit.dart';
15
16 class WalletConnectPairingDetailsPage extends StatefulWidget {
17 final PairingInfo pairing;
18 final WalletKitService walletKitService;
19
20 const WalletConnectPairingDetailsPage({
21 required this.pairing,
22 required this.walletKitService,
23 super.key,
24 });
25
26 @override
27 WalletConnectPairingDetailsPageState createState() => WalletConnectPairingDetailsPageState();
28 }
29
30 class WalletConnectPairingDetailsPageState extends State<WalletConnectPairingDetailsPage> {
31 late String expiryDate;
32 List<SessionData> sessions = const [];
33
34 @override
35 void initState() {
36 super.initState();
37 initDateTime();
38 WidgetsBinding.instance.addPostFrameCallback((_) {
39 if (!mounted) return;
40 setState(() {
41 sessions = widget.walletKitService.getSessionsForPairingInfo(widget.pairing);
42 });
43 });
44 }
45
46 void initDateTime() {
47 final dateTime = DateTime.fromMillisecondsSinceEpoch(widget.pairing.expiry * 1000);
48 expiryDate = '${dateTime.year}-'
49 '${dateTime.month.toString().padLeft(2, '0')}-'
50 '${dateTime.day.toString().padLeft(2, '0')}';
51 }
52
53 @override
54 Widget build(BuildContext context) {
55 return WCCDetailsWidget(
56 pairing: widget.pairing,
57 expiryDate: expiryDate,
58 sessions: sessions,
59 walletKitService: widget.walletKitService,
60 );
61 }
62 }
63
64 class WCCDetailsWidget extends BasePage {
65 WCCDetailsWidget({
66 required this.pairing,
67 required this.expiryDate,
68 required this.sessions,
69 required this.walletKitService,
70 });
71
72 final PairingInfo pairing;
73 final String expiryDate;
74 final List<SessionData> sessions;
75 final WalletKitService walletKitService;
76
77 @override
78 Widget body(BuildContext context) {
79 final colors = Theme.of(context).colorScheme;
80 final metadata = pairing.peerMetadata;
81 if (metadata == null) {
82 return const SizedBox.shrink();
83 }
84
85 final iconUrl = metadata.icons.isNotEmpty ? metadata.icons.first : null;
86 final walletName = getIt.get<AppStore>().wallet?.name ?? '';
87
88 return SafeArea(
89 child: SingleChildScrollView(
90 padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
91 child: Column(
92 crossAxisAlignment: CrossAxisAlignment.stretch,
93 children: [
94 WCDappCard(
95 name: metadata.name,
96 iconUrl: iconUrl,
97 subtitle: metadata.url,
98 action: WCDappCardAction.connected,
99 ),
100 const SizedBox(height: 12),
101 Text(
102 '${S.of(context).expiresOn}: $expiryDate',
103 textAlign: TextAlign.center,
104 style: Theme.of(context).textTheme.bodySmall!.copyWith(
105 color: colors.onSurfaceVariant,
106 ),
107 ),
108 const SizedBox(height: 24),
109 for (final session in sessions) ...[
110 _SessionSection(
111 session: session,
112 walletName: walletName,
113 ),
114 const SizedBox(height: 24),
115 ],
116 const SizedBox(height: 24),
117 NewPrimaryButton(
118 onPressed: () => _onDeleteButtonPressed(context, metadata.name, walletKitService),
119 text: S.current.delete,
120 color: colors.error,
121 textColor: colors.onError,
122 ),
123 const SizedBox(height: 12),
124 ],
125 ),
126 ),
127 );
128 }
129
130 Future<void> _onDeleteButtonPressed(
131 BuildContext context,
132 String dAppName,
133 WalletKitService walletKitService,
134 ) async {
135 bool confirmed = false;
136
137 await showPopUp<void>(
138 context: context,
139 builder: (BuildContext dialogContext) {
140 return AlertWithTwoActions(
141 alertTitle: S.of(context).delete,
142 alertContent: '${S.current.deleteConnectionConfirmationPrompt} $dAppName?',
143 leftButtonText: S.of(context).cancel,
144 rightButtonText: S.of(context).delete,
145 actionLeftButton: () => Navigator.of(dialogContext).pop(),
146 actionRightButton: () {
147 confirmed = true;
148 Navigator.of(dialogContext).pop();
149 },
150 );
151 },
152 );
153 if (confirmed) {
154 try {
155 await walletKitService.deletePairing(topic: pairing.topic);
156
157 if (Navigator.canPop(context)) {
158 Navigator.pop(context);
159 }
160 } catch (e) {
161 debugPrint(e.toString());
162 }
163 }
164 }
165 }
166
167 class _SessionSection extends StatelessWidget {
168 const _SessionSection({
169 required this.session,
170 required this.walletName,
171 });
172
173 final SessionData session;
174 final String walletName;
175
176 String _firstAddress() {
177 for (final namespace in session.namespaces.values) {
178 if (namespace.accounts.isNotEmpty) {
179 return NamespaceUtils.getAccount(namespace.accounts.first);
180 }
181 }
182 return '';
183 }
184
185 @override
186 Widget build(BuildContext context) {
187 final permissions = WCPermissionsMapper.fromGeneratedNamespaces(session.namespaces);
188 final address = _firstAddress();
189
190 return Column(
191 crossAxisAlignment: CrossAxisAlignment.stretch,
192 children: [
193 WCWalletCard(walletName: walletName, address: address),
194 const SizedBox(height: 24),
195 WCPermissionsCard(permissions: permissions),
196 ],
197 );
198 }
199 }