show Zano keys properly in the keys tab (#2004)

Omar Hatem committed Feb 4, 2025 at 23:11 UTC e88b6b2bcfb6f0c60403912863f138467a7e7796
4 files changed +160 -230
lib/src/screens/wallet_keys/wallet_keys_page.dart
+83 -87
@@ -1,5 +1,3 @@
1 -import 'dart:math';
2 -
1 import 'package:cake_wallet/entities/qr_view_data.dart';
2 import 'package:cake_wallet/generated/i18n.dart';
3 import 'package:cake_wallet/routes.dart';
@@ -18,7 +16,6 @@ import 'package:cake_wallet/view_model/wallet_keys_view_model.dart';
16 import 'package:flutter/material.dart';
17 import 'package:flutter/services.dart';
18 import 'package:flutter_mobx/flutter_mobx.dart';
21 -import 'package:mobx/mobx.dart';
19 import 'package:qr_flutter/qr_flutter.dart';
20
21 class WalletKeysPage extends BasePage {
@@ -35,14 +32,14 @@ class WalletKeysPage extends BasePage {
32 padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
33 child: Column(
34 children: [
38 - Padding(
39 - padding: EdgeInsets.only(left: 14, right: 14, bottom: 8),
40 - child: WarningBox(
41 - key: const ValueKey('wallet_keys_page_share_warning_text_key'),
42 - content: S.of(context).do_not_share_warning_text.toUpperCase(),
43 - currentTheme: currentTheme,
35 + Padding(
36 + padding: EdgeInsets.only(left: 14, right: 14, bottom: 8),
37 + child: WarningBox(
38 + key: const ValueKey('wallet_keys_page_share_warning_text_key'),
39 + content: S.of(context).do_not_share_warning_text.toUpperCase(),
40 + currentTheme: currentTheme,
41 + ),
42 ),
45 - ),
43 Expanded(
44 child: WalletKeysPageBody(
45 walletKeysViewModel: walletKeysViewModel,
@@ -102,36 +99,36 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
99 children: [
100 Padding(
101 padding: const EdgeInsets.only(left: 22, right: 22, top: 0),
105 - child: TabBar(
106 - controller: _tabController,
107 - splashFactory: NoSplash.splashFactory,
108 - indicatorSize: TabBarIndicatorSize.label,
109 - isScrollable: true,
110 - labelStyle: TextStyle(
111 - fontSize: 18,
112 - fontFamily: 'Lato',
113 - fontWeight: FontWeight.w600,
114 - color: Theme.of(context).appBarTheme.titleTextStyle!.color,
115 - ),
116 - unselectedLabelStyle: TextStyle(
117 - fontSize: 18,
118 - fontFamily: 'Lato',
119 - fontWeight: FontWeight.w600,
120 - color: Theme.of(context).appBarTheme.titleTextStyle!.color?.withOpacity(0.5),
102 + child: TabBar(
103 + controller: _tabController,
104 + splashFactory: NoSplash.splashFactory,
105 + indicatorSize: TabBarIndicatorSize.label,
106 + isScrollable: true,
107 + labelStyle: TextStyle(
108 + fontSize: 18,
109 + fontFamily: 'Lato',
110 + fontWeight: FontWeight.w600,
111 + color: Theme.of(context).appBarTheme.titleTextStyle!.color,
112 + ),
113 + unselectedLabelStyle: TextStyle(
114 + fontSize: 18,
115 + fontFamily: 'Lato',
116 + fontWeight: FontWeight.w600,
117 + color: Theme.of(context).appBarTheme.titleTextStyle!.color?.withOpacity(0.5),
118 + ),
119 + labelColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
120 + indicatorColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
121 + indicatorPadding: EdgeInsets.zero,
122 + labelPadding: const EdgeInsets.only(right: 24),
123 + tabAlignment: TabAlignment.start,
124 + dividerColor: Colors.transparent,
125 + padding: EdgeInsets.zero,
126 + tabs: [
127 + Tab(text: S.of(context).widgets_seed),
128 + if (showKeyTab) Tab(text: S.of(context).keys),
129 + if (showLegacySeedTab) Tab(text: S.of(context).legacy),
130 + ],
131 ),
122 - labelColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
123 - indicatorColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
124 - indicatorPadding: EdgeInsets.zero,
125 - labelPadding: const EdgeInsets.only(right: 24),
126 - tabAlignment: TabAlignment.start,
127 - dividerColor: Colors.transparent,
128 - padding: EdgeInsets.zero,
129 - tabs: [
130 - Tab(text: S.of(context).widgets_seed),
131 - if (showKeyTab) Tab(text: S.of(context).keys),
132 - if (showLegacySeedTab) Tab(text: S.of(context).legacy),
133 - ],
134 - ),
132 ),
133 const SizedBox(height: 20),
134 Expanded(
@@ -139,14 +136,14 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
136 controller: _tabController,
137 children: [
138 Padding(
142 - padding: const EdgeInsets.only(left: 22, right: 22,),
139 + padding: const EdgeInsets.only(left: 22, right: 22),
140 child: _buildSeedTab(context, false),
141 ),
142 if (showKeyTab)
146 - Padding(
147 - padding: const EdgeInsets.only(left: 22, right: 22),
148 - child: _buildKeysTab(context),
149 - ),
143 + Padding(
144 + padding: const EdgeInsets.only(left: 22, right: 22),
145 + child: _buildKeysTab(context),
146 + ),
147 if (showLegacySeedTab)
148 Padding(
149 padding: const EdgeInsets.only(left: 22, right: 22),
@@ -155,7 +152,6 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
152 ],
153 ),
154 ),
158 -
155 ],
156 ),
157 );
@@ -268,7 +264,6 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
264 ),
265 );
266 }
271 -
267
268 Widget? _buildPassphraseBox() {
269 if (widget.walletKeysViewModel.passphrase.isEmpty) return null;
@@ -297,9 +292,9 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
292 children: [
293 Observer(builder: (BuildContext context) {
294 return Text(
300 - (widget.walletKeysViewModel.obscurePassphrase) ?
301 - "*****" :
302 - widget.walletKeysViewModel.passphrase,
295 + (widget.walletKeysViewModel.obscurePassphrase)
296 + ? "*****"
297 + : widget.walletKeysViewModel.passphrase,
298 style: TextStyle(
299 fontSize: 14,
300 fontWeight: FontWeight.w500,
@@ -308,16 +303,18 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
303 );
304 }),
305 Observer(builder: (BuildContext context) {
311 - return GestureDetector(
312 - onTap: () {
313 - widget.walletKeysViewModel.obscurePassphrase = !widget.walletKeysViewModel.obscurePassphrase;
314 - },
315 - child: Icon(
316 - widget.walletKeysViewModel.obscurePassphrase ? Icons.visibility_off : Icons.visibility,
317 - size: 16,
318 - color: Theme.of(context).textTheme.bodyLarge?.color?.withOpacity(0.7),
319 - )
320 - );
306 + return GestureDetector(
307 + onTap: () {
308 + widget.walletKeysViewModel.obscurePassphrase =
309 + !widget.walletKeysViewModel.obscurePassphrase;
310 + },
311 + child: Icon(
312 + widget.walletKeysViewModel.obscurePassphrase
313 + ? Icons.visibility_off
314 + : Icons.visibility,
315 + size: 16,
316 + color: Theme.of(context).textTheme.bodyLarge?.color?.withOpacity(0.7),
317 + ));
318 }),
319 ],
320 ),
@@ -327,7 +324,6 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
324 );
325 }
326
330 -
327 Widget _buildBottomActionPanel({
328 required String titleForClipboard,
329 required String dataToCopy,
@@ -337,37 +333,37 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
333 children: [
334 Padding(
335 padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
340 - child: Row(
341 - mainAxisSize: MainAxisSize.max,
342 - children: [
343 - Flexible(
344 - child: Container(
345 - padding: const EdgeInsets.only(right: 8.0, top: 8.0),
346 - child: PrimaryButton(
347 - key: const ValueKey('wallet_keys_page_copy_seeds_button_key'),
348 - onPressed: () => _onCopy(titleForClipboard, dataToCopy, context),
349 - text: S.of(context).copy,
350 - color: Theme.of(context).cardColor,
351 - textColor: widget.currentTheme.type == ThemeType.dark
352 - ? Theme.of(context).extension<DashboardPageTheme>()!.textColor
353 - : Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
336 + child: Row(
337 + mainAxisSize: MainAxisSize.max,
338 + children: [
339 + Flexible(
340 + child: Container(
341 + padding: const EdgeInsets.only(right: 8.0, top: 8.0),
342 + child: PrimaryButton(
343 + key: const ValueKey('wallet_keys_page_copy_seeds_button_key'),
344 + onPressed: () => _onCopy(titleForClipboard, dataToCopy, context),
345 + text: S.of(context).copy,
346 + color: Theme.of(context).cardColor,
347 + textColor: widget.currentTheme.type == ThemeType.dark
348 + ? Theme.of(context).extension<DashboardPageTheme>()!.textColor
349 + : Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
350 + ),
351 ),
352 ),
356 - ),
357 - Flexible(
358 - child: Container(
359 - padding: const EdgeInsets.only(left: 8.0, top: 8.0),
360 - child: PrimaryButton(
361 - key: const ValueKey('wallet_keys_page_show_qr_seeds_button_key'),
362 - onPressed: onShowQR,
363 - text: S.current.show + ' QR',
364 - color: Theme.of(context).primaryColor,
365 - textColor: Colors.white,
353 + Flexible(
354 + child: Container(
355 + padding: const EdgeInsets.only(left: 8.0, top: 8.0),
356 + child: PrimaryButton(
357 + key: const ValueKey('wallet_keys_page_show_qr_seeds_button_key'),
358 + onPressed: onShowQR,
359 + text: S.current.show + ' QR',
360 + color: Theme.of(context).primaryColor,
361 + textColor: Colors.white,
362 + ),
363 ),
364 ),
368 - ),
369 - ],
370 - ),
365 + ],
366 + ),
367 ),
368 const SizedBox(height: 12),
369 ],
lib/view_model/wallet_keys_view_model.dart
+65 -132
@@ -1,10 +1,10 @@
1 import 'package:cake_wallet/generated/i18n.dart';
2 import 'package:cake_wallet/haven/haven.dart';
3 import 'package:cake_wallet/monero/monero.dart';
4 -import 'package:cake_wallet/reactions/wallet_connect.dart';
4 import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
5 import 'package:cake_wallet/store/app_store.dart';
6 import 'package:cake_wallet/wownero/wownero.dart';
7 +import 'package:cake_wallet/zano/zano.dart';
8 import 'package:cw_core/transaction_direction.dart';
9 import 'package:cw_core/transaction_info.dart';
10 import 'package:cw_core/wallet_base.dart';
@@ -64,8 +64,8 @@ abstract class WalletKeysViewModelBase with Store {
64
65 bool get isLegacySeedOnly =>
66 (_wallet.type == WalletType.monero || _wallet.type == WalletType.wownero) &&
67 - _wallet.seed != null &&
68 - !Polyseed.isValidSeed(_wallet.seed!);
67 + _wallet.seed != null &&
68 + !Polyseed.isValidSeed(_wallet.seed!);
69
70 String get legacySeed {
71 if ((_wallet.type == WalletType.monero || _wallet.type == WalletType.wownero) &&
@@ -92,11 +92,9 @@ abstract class WalletKeysViewModelBase with Store {
92 return '';
93 }
94
95 -
96 -
95 @observable
96 bool obscurePassphrase = true;
99 -
97 +
98 String get passphrase {
99 return _wallet.passphrase ?? '';
100 }
@@ -111,81 +109,70 @@ abstract class WalletKeysViewModelBase with Store {
109 void _populateKeysItems() {
110 items.clear();
111
114 - if (_wallet.type == WalletType.monero) {
115 - final keys = monero!.getKeys(_wallet);
112 + Map<String, String>? keys;
113
117 - items.addAll([
118 - if (keys['primaryAddress'] != null)
119 - StandartListItem(
120 - key: ValueKey('${_walletName}_wallet_primary_address_item_key'),
121 - title: S.current.primary_address,
122 - value: keys['primaryAddress']!),
123 - if (keys['publicSpendKey'] != null)
124 - StandartListItem(
125 - key: ValueKey('${_walletName}_wallet_public_spend_key_item_key'),
126 - title: S.current.spend_key_public,
127 - value: keys['publicSpendKey']!,
128 - ),
129 - if (keys['privateSpendKey'] != null)
130 - StandartListItem(
131 - key: ValueKey('${_walletName}_wallet_private_spend_key_item_key'),
132 - title: S.current.spend_key_private,
133 - value: keys['privateSpendKey']!,
134 - ),
135 - if (keys['publicViewKey'] != null)
136 - StandartListItem(
137 - key: ValueKey('${_walletName}_wallet_public_view_key_item_key'),
138 - title: S.current.view_key_public,
139 - value: keys['publicViewKey']!,
140 - ),
141 - if (keys['privateViewKey'] != null)
142 - StandartListItem(
143 - key: ValueKey('${_walletName}_wallet_private_view_key_item_key'),
144 - title: S.current.view_key_private,
145 - value: keys['privateViewKey']!,
146 - ),
147 - ]);
148 - }
149 -
150 - if (_wallet.type == WalletType.haven) {
151 - final keys = haven!.getKeys(_wallet);
152 -
153 - items.addAll([
154 - if (keys['primaryAddress'] != null)
155 - StandartListItem(
156 - key: ValueKey('${_walletName}_wallet_primary_address_item_key'),
157 - title: S.current.primary_address,
158 - value: keys['primaryAddress']!),
159 - if (keys['publicSpendKey'] != null)
160 - StandartListItem(
161 - key: ValueKey('${_walletName}_wallet_public_spend_key_item_key'),
162 - title: S.current.spend_key_public,
163 - value: keys['publicSpendKey']!,
164 - ),
165 - if (keys['privateSpendKey'] != null)
166 - StandartListItem(
167 - key: ValueKey('${_walletName}_wallet_private_spend_key_item_key'),
168 - title: S.current.spend_key_private,
169 - value: keys['privateSpendKey']!,
170 - ),
171 - if (keys['publicViewKey'] != null)
172 - StandartListItem(
173 - key: ValueKey('${_walletName}_wallet_public_view_key_item_key'),
174 - title: S.current.view_key_public,
175 - value: keys['publicViewKey']!,
176 - ),
177 - if (keys['privateViewKey'] != null)
178 - StandartListItem(
179 - key: ValueKey('${_walletName}_wallet_private_view_key_item_key'),
180 - title: S.current.view_key_private,
181 - value: keys['privateViewKey']!,
182 - ),
183 - ]);
114 + switch (_wallet.type) {
115 + case WalletType.monero:
116 + keys = monero!.getKeys(_wallet);
117 + break;
118 + case WalletType.haven:
119 + keys = haven!.getKeys(_wallet);
120 + break;
121 + case WalletType.wownero:
122 + keys = wownero!.getKeys(_wallet);
123 + break;
124 + case WalletType.zano:
125 + keys = zano!.getKeys(_wallet);
126 + break;
127 + case WalletType.ethereum:
128 + case WalletType.polygon:
129 + case WalletType.solana:
130 + case WalletType.tron:
131 + items.addAll([
132 + if (_wallet.privateKey != null)
133 + StandartListItem(
134 + key: ValueKey('${_walletName}_wallet_private_key_item_key'),
135 + title: S.current.private_key,
136 + value: _wallet.privateKey!,
137 + ),
138 + ]);
139 + break;
140 + case WalletType.nano:
141 + case WalletType.banano:
142 + // we always have the hex version of the seed and private key:
143 + items.addAll([
144 + if (_wallet.hexSeed != null)
145 + StandartListItem(
146 + key: ValueKey('${_walletName}_wallet_hex_seed_key'),
147 + title: S.current.seed_hex_form,
148 + value: _wallet.hexSeed!,
149 + ),
150 + if (_wallet.privateKey != null)
151 + StandartListItem(
152 + key: ValueKey('${_walletName}_wallet_private_key_item_key'),
153 + title: S.current.private_key,
154 + value: _wallet.privateKey!,
155 + ),
156 + ]);
157 + break;
158 + case WalletType.bitcoin:
159 + case WalletType.litecoin:
160 + case WalletType.bitcoinCash:
161 + case WalletType.none:
162 + // final keys = bitcoin!.getWalletKeys(_appStore.wallet!);
163 + //
164 + // items.addAll([
165 + // if (keys['wif'] != null)
166 + // StandartListItem(title: "WIF", value: keys['wif']!),
167 + // if (keys['privateKey'] != null)
168 + // StandartListItem(title: S.current.private_key, value: keys['privateKey']!),
169 + // if (keys['publicKey'] != null)
170 + // StandartListItem(title: S.current.public_key, value: keys['publicKey']!),
171 + // ]);
172 + break;
173 }
174
186 - if (_wallet.type == WalletType.wownero) {
187 - final keys = wownero!.getKeys(_wallet);
188 -
175 + if (keys != null) {
176 items.addAll([
177 if (keys['primaryAddress'] != null)
178 StandartListItem(
@@ -218,60 +205,6 @@ abstract class WalletKeysViewModelBase with Store {
205 ),
206 ]);
207 }
221 -
222 - // if (_wallet.type == WalletType.bitcoin ||
223 - // _wallet.type == WalletType.litecoin ||
224 - // _wallet.type == WalletType.bitcoinCash) {
225 - // final keys = bitcoin!.getWalletKeys(_appStore.wallet!);
226 - //
227 - // items.addAll([
228 - // if (keys['wif'] != null)
229 - // StandartListItem(title: "WIF", value: keys['wif']!),
230 - // if (keys['privateKey'] != null)
231 - // StandartListItem(title: S.current.private_key, value: keys['privateKey']!),
232 - // if (keys['publicKey'] != null)
233 - // StandartListItem(title: S.current.public_key, value: keys['publicKey']!),
234 - // ]);
235 - // }
236 -
237 - if (isEVMCompatibleChain(_wallet.type) ||
238 - _wallet.type == WalletType.solana ||
239 - _wallet.type == WalletType.tron) {
240 - items.addAll([
241 - if (_wallet.privateKey != null)
242 - StandartListItem(
243 - key: ValueKey('${_walletName}_wallet_private_key_item_key'),
244 - title: S.current.private_key,
245 - value: _wallet.privateKey!,
246 - ),
247 - ]);
248 - }
249 -
250 - bool nanoBased = _wallet.type == WalletType.nano || _wallet.type == WalletType.banano;
251 -
252 - if (nanoBased) {
253 - // we always have the hex version of the seed and private key:
254 - items.addAll([
255 - if (_wallet.hexSeed != null)
256 - StandartListItem(
257 - key: ValueKey('${_walletName}_wallet_hex_seed_key'),
258 - title: S.current.seed_hex_form,
259 - value: _wallet.hexSeed!,
260 - ),
261 - if (_wallet.privateKey != null)
262 - StandartListItem(
263 - key: ValueKey('${_walletName}_wallet_private_key_item_key'),
264 - title: S.current.private_key,
265 - value: _wallet.privateKey!,
266 - ),
267 - ]);
268 - }
269 -
270 - if (_appStore.wallet!.type == WalletType.zano) {
271 - items.addAll([
272 - StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
273 - ]);
274 - }
208 }
209
210 Future<int?> _currentHeight() async {
lib/zano/cw_zano.dart
+11 -11
@@ -57,17 +57,17 @@ class CWZano extends Zano {
57 return ZanoNewWalletCredentials(name: name, password: password);
58 }
59
60 - // @override
61 - // Map<String, String> getKeys(Object wallet) {
62 - // final zanoWallet = wallet as ZanoWallet;
63 - // final keys = zanoWallet.keys;
64 - // return <String, String>{
65 - // 'privateSpendKey': keys.privateSpendKey,
66 - // 'privateViewKey': keys.privateViewKey,
67 - // 'publicSpendKey': keys.publicSpendKey,
68 - // 'publicViewKey': keys.publicViewKey
69 - // };
70 - // }
60 + @override
61 + Map<String, String> getKeys(Object wallet) {
62 + final zanoWallet = wallet as ZanoWallet;
63 + final keys = zanoWallet.keys;
64 + return <String, String>{
65 + 'privateSpendKey': keys.privateSpendKey,
66 + 'privateViewKey': keys.privateViewKey,
67 + 'publicSpendKey': keys.publicSpendKey,
68 + 'publicViewKey': keys.publicViewKey
69 + };
70 + }
71
72 @override
73 Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency}) {
tool/configure.dart
+1
@@ -1444,6 +1444,7 @@ abstract class Zano {
1444
1445 WalletCredentials createZanoRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic});
1446 WalletCredentials createZanoNewWalletCredentials({required String name, required String? password});
1447 + Map<String, String> getKeys(Object wallet);
1448 Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency});
1449 double formatterIntAmountToDouble({required int amount, required CryptoCurrency currency, required bool forFee});
1450 int formatterParseAmount({required String amount, required CryptoCurrency currency});